blob: da114c2f0dbed91e55c5049d60f4bf54781b4b2e [file] [log] [blame]
Sujith55624202010-01-08 10:36:02 +05301/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
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
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090017#include <linux/slab.h>
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +010018#include <linux/ath9k_platform.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090019
Sujith55624202010-01-08 10:36:02 +053020#include "ath9k.h"
21
22static char *dev_info = "ath9k";
23
24MODULE_AUTHOR("Atheros Communications");
25MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
26MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
27MODULE_LICENSE("Dual BSD/GPL");
28
29static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
30module_param_named(debug, ath9k_debug, uint, 0);
31MODULE_PARM_DESC(debug, "Debugging mask");
32
John W. Linville3e6109c2011-01-05 09:39:17 -050033int ath9k_modparam_nohwcrypt;
34module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
Sujith55624202010-01-08 10:36:02 +053035MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
36
Vivek Natarajan93dbbcc2010-08-25 19:34:52 +053037int led_blink;
Vivek Natarajan9a75c2f2010-06-22 11:52:37 +053038module_param_named(blink, led_blink, int, 0444);
39MODULE_PARM_DESC(blink, "Enable LED blink on activity");
40
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -080041static int ath9k_btcoex_enable;
42module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
43MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
44
Rajkumar Manoharand5847472010-12-20 14:39:51 +053045bool is_ath9k_unloaded;
Sujith55624202010-01-08 10:36:02 +053046/* We use the hw_value as an index into our private channel structure */
47
48#define CHAN2G(_freq, _idx) { \
Mohammed Shafi Shajakhanb1c1d002010-12-17 20:44:36 +053049 .band = IEEE80211_BAND_2GHZ, \
Sujith55624202010-01-08 10:36:02 +053050 .center_freq = (_freq), \
51 .hw_value = (_idx), \
52 .max_power = 20, \
53}
54
55#define CHAN5G(_freq, _idx) { \
56 .band = IEEE80211_BAND_5GHZ, \
57 .center_freq = (_freq), \
58 .hw_value = (_idx), \
59 .max_power = 20, \
60}
61
62/* Some 2 GHz radios are actually tunable on 2312-2732
63 * on 5 MHz steps, we support the channels which we know
64 * we have calibration data for all cards though to make
65 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020066static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053067 CHAN2G(2412, 0), /* Channel 1 */
68 CHAN2G(2417, 1), /* Channel 2 */
69 CHAN2G(2422, 2), /* Channel 3 */
70 CHAN2G(2427, 3), /* Channel 4 */
71 CHAN2G(2432, 4), /* Channel 5 */
72 CHAN2G(2437, 5), /* Channel 6 */
73 CHAN2G(2442, 6), /* Channel 7 */
74 CHAN2G(2447, 7), /* Channel 8 */
75 CHAN2G(2452, 8), /* Channel 9 */
76 CHAN2G(2457, 9), /* Channel 10 */
77 CHAN2G(2462, 10), /* Channel 11 */
78 CHAN2G(2467, 11), /* Channel 12 */
79 CHAN2G(2472, 12), /* Channel 13 */
80 CHAN2G(2484, 13), /* Channel 14 */
81};
82
83/* Some 5 GHz radios are actually tunable on XXXX-YYYY
84 * on 5 MHz steps, we support the channels which we know
85 * we have calibration data for all cards though to make
86 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020087static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053088 /* _We_ call this UNII 1 */
89 CHAN5G(5180, 14), /* Channel 36 */
90 CHAN5G(5200, 15), /* Channel 40 */
91 CHAN5G(5220, 16), /* Channel 44 */
92 CHAN5G(5240, 17), /* Channel 48 */
93 /* _We_ call this UNII 2 */
94 CHAN5G(5260, 18), /* Channel 52 */
95 CHAN5G(5280, 19), /* Channel 56 */
96 CHAN5G(5300, 20), /* Channel 60 */
97 CHAN5G(5320, 21), /* Channel 64 */
98 /* _We_ call this "Middle band" */
99 CHAN5G(5500, 22), /* Channel 100 */
100 CHAN5G(5520, 23), /* Channel 104 */
101 CHAN5G(5540, 24), /* Channel 108 */
102 CHAN5G(5560, 25), /* Channel 112 */
103 CHAN5G(5580, 26), /* Channel 116 */
104 CHAN5G(5600, 27), /* Channel 120 */
105 CHAN5G(5620, 28), /* Channel 124 */
106 CHAN5G(5640, 29), /* Channel 128 */
107 CHAN5G(5660, 30), /* Channel 132 */
108 CHAN5G(5680, 31), /* Channel 136 */
109 CHAN5G(5700, 32), /* Channel 140 */
110 /* _We_ call this UNII 3 */
111 CHAN5G(5745, 33), /* Channel 149 */
112 CHAN5G(5765, 34), /* Channel 153 */
113 CHAN5G(5785, 35), /* Channel 157 */
114 CHAN5G(5805, 36), /* Channel 161 */
115 CHAN5G(5825, 37), /* Channel 165 */
116};
117
118/* Atheros hardware rate code addition for short premble */
119#define SHPCHECK(__hw_rate, __flags) \
120 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
121
122#define RATE(_bitrate, _hw_rate, _flags) { \
123 .bitrate = (_bitrate), \
124 .flags = (_flags), \
125 .hw_value = (_hw_rate), \
126 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
127}
128
129static struct ieee80211_rate ath9k_legacy_rates[] = {
130 RATE(10, 0x1b, 0),
131 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
132 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
133 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
134 RATE(60, 0x0b, 0),
135 RATE(90, 0x0f, 0),
136 RATE(120, 0x0a, 0),
137 RATE(180, 0x0e, 0),
138 RATE(240, 0x09, 0),
139 RATE(360, 0x0d, 0),
140 RATE(480, 0x08, 0),
141 RATE(540, 0x0c, 0),
142};
143
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100144#ifdef CONFIG_MAC80211_LEDS
145static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
146 { .throughput = 0 * 1024, .blink_time = 334 },
147 { .throughput = 1 * 1024, .blink_time = 260 },
148 { .throughput = 5 * 1024, .blink_time = 220 },
149 { .throughput = 10 * 1024, .blink_time = 190 },
150 { .throughput = 20 * 1024, .blink_time = 170 },
151 { .throughput = 50 * 1024, .blink_time = 150 },
152 { .throughput = 70 * 1024, .blink_time = 130 },
153 { .throughput = 100 * 1024, .blink_time = 110 },
154 { .throughput = 200 * 1024, .blink_time = 80 },
155 { .throughput = 300 * 1024, .blink_time = 50 },
156};
157#endif
158
Sujith285f2dd2010-01-08 10:36:07 +0530159static void ath9k_deinit_softc(struct ath_softc *sc);
Sujith55624202010-01-08 10:36:02 +0530160
161/*
162 * Read and write, they both share the same lock. We do this to serialize
163 * reads and writes on Atheros 802.11n PCI devices only. This is required
164 * as the FIFO on these devices can only accept sanely 2 requests.
165 */
166
167static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
168{
169 struct ath_hw *ah = (struct ath_hw *) hw_priv;
170 struct ath_common *common = ath9k_hw_common(ah);
171 struct ath_softc *sc = (struct ath_softc *) common->priv;
172
173 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
174 unsigned long flags;
175 spin_lock_irqsave(&sc->sc_serial_rw, flags);
176 iowrite32(val, sc->mem + reg_offset);
177 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
178 } else
179 iowrite32(val, sc->mem + reg_offset);
180}
181
182static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
183{
184 struct ath_hw *ah = (struct ath_hw *) hw_priv;
185 struct ath_common *common = ath9k_hw_common(ah);
186 struct ath_softc *sc = (struct ath_softc *) common->priv;
187 u32 val;
188
189 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
190 unsigned long flags;
191 spin_lock_irqsave(&sc->sc_serial_rw, flags);
192 val = ioread32(sc->mem + reg_offset);
193 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
194 } else
195 val = ioread32(sc->mem + reg_offset);
196 return val;
197}
198
Sujith55624202010-01-08 10:36:02 +0530199/**************************/
200/* Initialization */
201/**************************/
202
203static void setup_ht_cap(struct ath_softc *sc,
204 struct ieee80211_sta_ht_cap *ht_info)
205{
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200206 struct ath_hw *ah = sc->sc_ah;
207 struct ath_common *common = ath9k_hw_common(ah);
Sujith55624202010-01-08 10:36:02 +0530208 u8 tx_streams, rx_streams;
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200209 int i, max_streams;
Sujith55624202010-01-08 10:36:02 +0530210
211 ht_info->ht_supported = true;
212 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
213 IEEE80211_HT_CAP_SM_PS |
214 IEEE80211_HT_CAP_SGI_40 |
215 IEEE80211_HT_CAP_DSSSCCK40;
216
Luis R. Rodriguezb0a33442010-04-15 17:39:39 -0400217 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
218 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
219
Vasanthakumar Thiagarajan6473d242010-05-13 18:42:38 -0700220 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
221 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
222
Sujith55624202010-01-08 10:36:02 +0530223 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
224 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
225
Vasanthakumar Thiagarajan7f1c7a62010-12-06 04:27:41 -0800226 if (AR_SREV_9485(ah))
227 max_streams = 1;
228 else if (AR_SREV_9300_20_OR_LATER(ah))
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200229 max_streams = 3;
230 else
231 max_streams = 2;
232
Felix Fietkau7a370812010-09-22 12:34:52 +0200233 if (AR_SREV_9280_20_OR_LATER(ah)) {
Felix Fietkau074a8c02010-04-19 19:57:36 +0200234 if (max_streams >= 2)
235 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
236 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
237 }
238
Sujith55624202010-01-08 10:36:02 +0530239 /* set up supported mcs set */
240 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
Sujith61389f32010-06-02 15:53:37 +0530241 tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
242 rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200243
Joe Perches226afe62010-12-02 19:12:37 -0800244 ath_dbg(common, ATH_DBG_CONFIG,
245 "TX streams %d, RX streams: %d\n",
246 tx_streams, rx_streams);
Sujith55624202010-01-08 10:36:02 +0530247
248 if (tx_streams != rx_streams) {
Sujith55624202010-01-08 10:36:02 +0530249 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
250 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
251 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
252 }
253
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200254 for (i = 0; i < rx_streams; i++)
255 ht_info->mcs.rx_mask[i] = 0xff;
Sujith55624202010-01-08 10:36:02 +0530256
257 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
258}
259
260static int ath9k_reg_notifier(struct wiphy *wiphy,
261 struct regulatory_request *request)
262{
263 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
Felix Fietkau9ac58612011-01-24 19:23:18 +0100264 struct ath_softc *sc = hw->priv;
Sujith55624202010-01-08 10:36:02 +0530265 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
266
267 return ath_reg_notifier_apply(wiphy, request, reg);
268}
269
270/*
271 * This function will allocate both the DMA descriptor structure, and the
272 * buffers it contains. These are used to contain the descriptors used
273 * by the system.
274*/
275int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
276 struct list_head *head, const char *name,
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400277 int nbuf, int ndesc, bool is_tx)
Sujith55624202010-01-08 10:36:02 +0530278{
279#define DS2PHYS(_dd, _ds) \
280 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
281#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
282#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
283 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400284 u8 *ds;
Sujith55624202010-01-08 10:36:02 +0530285 struct ath_buf *bf;
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400286 int i, bsize, error, desc_len;
Sujith55624202010-01-08 10:36:02 +0530287
Joe Perches226afe62010-12-02 19:12:37 -0800288 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
289 name, nbuf, ndesc);
Sujith55624202010-01-08 10:36:02 +0530290
291 INIT_LIST_HEAD(head);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400292
293 if (is_tx)
294 desc_len = sc->sc_ah->caps.tx_desc_len;
295 else
296 desc_len = sizeof(struct ath_desc);
297
Sujith55624202010-01-08 10:36:02 +0530298 /* ath_desc must be a multiple of DWORDs */
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400299 if ((desc_len % 4) != 0) {
Joe Perches38002762010-12-02 19:12:36 -0800300 ath_err(common, "ath_desc not DWORD aligned\n");
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400301 BUG_ON((desc_len % 4) != 0);
Sujith55624202010-01-08 10:36:02 +0530302 error = -ENOMEM;
303 goto fail;
304 }
305
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400306 dd->dd_desc_len = desc_len * nbuf * ndesc;
Sujith55624202010-01-08 10:36:02 +0530307
308 /*
309 * Need additional DMA memory because we can't use
310 * descriptors that cross the 4K page boundary. Assume
311 * one skipped descriptor per 4K page.
312 */
313 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
314 u32 ndesc_skipped =
315 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
316 u32 dma_len;
317
318 while (ndesc_skipped) {
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400319 dma_len = ndesc_skipped * desc_len;
Sujith55624202010-01-08 10:36:02 +0530320 dd->dd_desc_len += dma_len;
321
322 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
Joe Perchesee289b62010-05-17 22:47:34 -0700323 }
Sujith55624202010-01-08 10:36:02 +0530324 }
325
326 /* allocate descriptors */
327 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
328 &dd->dd_desc_paddr, GFP_KERNEL);
329 if (dd->dd_desc == NULL) {
330 error = -ENOMEM;
331 goto fail;
332 }
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400333 ds = (u8 *) dd->dd_desc;
Joe Perches226afe62010-12-02 19:12:37 -0800334 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
335 name, ds, (u32) dd->dd_desc_len,
336 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
Sujith55624202010-01-08 10:36:02 +0530337
338 /* allocate buffers */
339 bsize = sizeof(struct ath_buf) * nbuf;
340 bf = kzalloc(bsize, GFP_KERNEL);
341 if (bf == NULL) {
342 error = -ENOMEM;
343 goto fail2;
344 }
345 dd->dd_bufptr = bf;
346
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400347 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
Sujith55624202010-01-08 10:36:02 +0530348 bf->bf_desc = ds;
349 bf->bf_daddr = DS2PHYS(dd, ds);
350
351 if (!(sc->sc_ah->caps.hw_caps &
352 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
353 /*
354 * Skip descriptor addresses which can cause 4KB
355 * boundary crossing (addr + length) with a 32 dword
356 * descriptor fetch.
357 */
358 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
359 BUG_ON((caddr_t) bf->bf_desc >=
360 ((caddr_t) dd->dd_desc +
361 dd->dd_desc_len));
362
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400363 ds += (desc_len * ndesc);
Sujith55624202010-01-08 10:36:02 +0530364 bf->bf_desc = ds;
365 bf->bf_daddr = DS2PHYS(dd, ds);
366 }
367 }
368 list_add_tail(&bf->list, head);
369 }
370 return 0;
371fail2:
372 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
373 dd->dd_desc_paddr);
374fail:
375 memset(dd, 0, sizeof(*dd));
376 return error;
377#undef ATH_DESC_4KB_BOUND_CHECK
378#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
379#undef DS2PHYS
380}
381
Mohammed Shafi Shajakhandb7ec382010-12-22 12:20:12 +0530382void ath9k_init_crypto(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530383{
Sujith285f2dd2010-01-08 10:36:07 +0530384 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
385 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530386
387 /* Get the hardware key cache size. */
Sujith285f2dd2010-01-08 10:36:07 +0530388 common->keymax = sc->sc_ah->caps.keycache_size;
Sujith55624202010-01-08 10:36:02 +0530389 if (common->keymax > ATH_KEYMAX) {
Joe Perches226afe62010-12-02 19:12:37 -0800390 ath_dbg(common, ATH_DBG_ANY,
391 "Warning, using only %u entries in %u key cache\n",
392 ATH_KEYMAX, common->keymax);
Sujith55624202010-01-08 10:36:02 +0530393 common->keymax = ATH_KEYMAX;
394 }
395
396 /*
397 * Reset the key cache since some parts do not
398 * reset the contents on initial power up.
399 */
400 for (i = 0; i < common->keymax; i++)
Bruno Randolf040e5392010-09-08 16:05:04 +0900401 ath_hw_keyreset(common, (u16) i);
Sujith55624202010-01-08 10:36:02 +0530402
Felix Fietkau716f7fc2010-06-12 17:22:28 +0200403 /*
Sujith55624202010-01-08 10:36:02 +0530404 * Check whether the separate key cache entries
405 * are required to handle both tx+rx MIC keys.
406 * With split mic keys the number of stations is limited
407 * to 27 otherwise 59.
408 */
Bruno Randolf117675d2010-09-08 16:04:54 +0900409 if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
410 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
Sujith285f2dd2010-01-08 10:36:07 +0530411}
Sujith55624202010-01-08 10:36:02 +0530412
Sujith285f2dd2010-01-08 10:36:07 +0530413static int ath9k_init_btcoex(struct ath_softc *sc)
414{
Felix Fietkau066dae92010-11-07 14:59:39 +0100415 struct ath_txq *txq;
416 int r;
Sujith285f2dd2010-01-08 10:36:07 +0530417
418 switch (sc->sc_ah->btcoex_hw.scheme) {
419 case ATH_BTCOEX_CFG_NONE:
420 break;
421 case ATH_BTCOEX_CFG_2WIRE:
422 ath9k_hw_btcoex_init_2wire(sc->sc_ah);
423 break;
424 case ATH_BTCOEX_CFG_3WIRE:
425 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
426 r = ath_init_btcoex_timer(sc);
427 if (r)
428 return -1;
Felix Fietkau066dae92010-11-07 14:59:39 +0100429 txq = sc->tx.txq_map[WME_AC_BE];
430 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
Sujith285f2dd2010-01-08 10:36:07 +0530431 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
432 break;
433 default:
434 WARN_ON(1);
435 break;
Sujith55624202010-01-08 10:36:02 +0530436 }
437
Sujith285f2dd2010-01-08 10:36:07 +0530438 return 0;
439}
Sujith55624202010-01-08 10:36:02 +0530440
Sujith285f2dd2010-01-08 10:36:07 +0530441static int ath9k_init_queues(struct ath_softc *sc)
442{
Sujith285f2dd2010-01-08 10:36:07 +0530443 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530444
Sujith285f2dd2010-01-08 10:36:07 +0530445 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
Sujith285f2dd2010-01-08 10:36:07 +0530446 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
Sujith55624202010-01-08 10:36:02 +0530447
Sujith285f2dd2010-01-08 10:36:07 +0530448 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
449 ath_cabq_update(sc);
450
Ben Greear60f2d1d2011-01-09 23:11:52 -0800451 for (i = 0; i < WME_NUM_AC; i++) {
Felix Fietkau066dae92010-11-07 14:59:39 +0100452 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
Ben Greear60f2d1d2011-01-09 23:11:52 -0800453 sc->tx.txq_map[i]->mac80211_qnum = i;
454 }
Sujith285f2dd2010-01-08 10:36:07 +0530455 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530456}
457
Felix Fietkauf209f522010-10-01 01:06:53 +0200458static int ath9k_init_channels_rates(struct ath_softc *sc)
Sujith285f2dd2010-01-08 10:36:07 +0530459{
Felix Fietkauf209f522010-10-01 01:06:53 +0200460 void *channels;
461
Felix Fietkaucac42202010-10-09 02:39:30 +0200462 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
463 ARRAY_SIZE(ath9k_5ghz_chantable) !=
464 ATH9K_NUM_CHANNELS);
465
Felix Fietkaud4659912010-10-14 16:02:39 +0200466 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200467 channels = kmemdup(ath9k_2ghz_chantable,
468 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
469 if (!channels)
470 return -ENOMEM;
471
472 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530473 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
474 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
475 ARRAY_SIZE(ath9k_2ghz_chantable);
476 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
477 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
478 ARRAY_SIZE(ath9k_legacy_rates);
479 }
480
Felix Fietkaud4659912010-10-14 16:02:39 +0200481 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200482 channels = kmemdup(ath9k_5ghz_chantable,
483 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
484 if (!channels) {
485 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
486 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
487 return -ENOMEM;
488 }
489
490 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530491 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
492 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
493 ARRAY_SIZE(ath9k_5ghz_chantable);
494 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
495 ath9k_legacy_rates + 4;
496 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
497 ARRAY_SIZE(ath9k_legacy_rates) - 4;
498 }
Felix Fietkauf209f522010-10-01 01:06:53 +0200499 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530500}
Sujith55624202010-01-08 10:36:02 +0530501
Sujith285f2dd2010-01-08 10:36:07 +0530502static void ath9k_init_misc(struct ath_softc *sc)
503{
504 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
505 int i = 0;
506
Sujith285f2dd2010-01-08 10:36:07 +0530507 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
508
509 sc->config.txpowlimit = ATH_TXPOWER_MAX;
510
511 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
512 sc->sc_flags |= SC_OP_TXAGGR;
513 sc->sc_flags |= SC_OP_RXAGGR;
Sujith55624202010-01-08 10:36:02 +0530514 }
515
Sujith285f2dd2010-01-08 10:36:07 +0530516 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
517 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
518
Luis R. Rodriguez8fe65362010-04-15 17:38:14 -0400519 ath9k_hw_set_diversity(sc->sc_ah, true);
Sujith285f2dd2010-01-08 10:36:07 +0530520 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
521
Felix Fietkau364734f2010-09-14 20:22:44 +0200522 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
Sujith285f2dd2010-01-08 10:36:07 +0530523
524 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
525
Felix Fietkau7545daf2011-01-24 19:23:16 +0100526 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
Sujith285f2dd2010-01-08 10:36:07 +0530527 sc->beacon.bslot[i] = NULL;
Vasanthakumar Thiagarajan102885a2010-09-02 01:34:43 -0700528
529 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
530 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
Sujith285f2dd2010-01-08 10:36:07 +0530531}
532
533static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
534 const struct ath_bus_ops *bus_ops)
535{
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +0100536 struct ath9k_platform_data *pdata = sc->dev->platform_data;
Sujith285f2dd2010-01-08 10:36:07 +0530537 struct ath_hw *ah = NULL;
538 struct ath_common *common;
539 int ret = 0, i;
540 int csz = 0;
541
Sujith285f2dd2010-01-08 10:36:07 +0530542 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
543 if (!ah)
544 return -ENOMEM;
545
Ben Greear233536e2011-01-09 23:11:44 -0800546 ah->hw = sc->hw;
Sujith285f2dd2010-01-08 10:36:07 +0530547 ah->hw_version.devid = devid;
548 ah->hw_version.subsysid = subsysid;
Felix Fietkauf9f84e92011-03-23 20:57:24 +0100549 ah->reg_ops.read = ath9k_ioread32;
550 ah->reg_ops.write = ath9k_iowrite32;
Sujith285f2dd2010-01-08 10:36:07 +0530551 sc->sc_ah = ah;
552
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100553 if (!pdata) {
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100554 ah->ah_flags |= AH_USE_EEPROM;
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100555 sc->sc_ah->led_pin = -1;
556 } else {
557 sc->sc_ah->gpio_mask = pdata->gpio_mask;
558 sc->sc_ah->gpio_val = pdata->gpio_val;
559 sc->sc_ah->led_pin = pdata->led_pin;
560 }
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100561
Sujith285f2dd2010-01-08 10:36:07 +0530562 common = ath9k_hw_common(ah);
Felix Fietkauf9f84e92011-03-23 20:57:24 +0100563 common->ops = &ah->reg_ops;
Sujith285f2dd2010-01-08 10:36:07 +0530564 common->bus_ops = bus_ops;
565 common->ah = ah;
566 common->hw = sc->hw;
567 common->priv = sc;
568 common->debug_mask = ath9k_debug;
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -0800569 common->btcoex_enabled = ath9k_btcoex_enable == 1;
Ben Greear20b257442010-10-15 15:04:09 -0700570 spin_lock_init(&common->cc_lock);
Sujith285f2dd2010-01-08 10:36:07 +0530571
Sujith285f2dd2010-01-08 10:36:07 +0530572 spin_lock_init(&sc->sc_serial_rw);
573 spin_lock_init(&sc->sc_pm_lock);
574 mutex_init(&sc->mutex);
Ben Greear7f010c92011-01-09 23:11:49 -0800575#ifdef CONFIG_ATH9K_DEBUGFS
576 spin_lock_init(&sc->nodes_lock);
577 INIT_LIST_HEAD(&sc->nodes);
578#endif
Sujith285f2dd2010-01-08 10:36:07 +0530579 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
580 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
581 (unsigned long)sc);
582
583 /*
584 * Cache line size is used to size and align various
585 * structures used to communicate with the hardware.
586 */
587 ath_read_cachesize(common, &csz);
588 common->cachelsz = csz << 2; /* convert to bytes */
589
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400590 /* Initializes the hardware for all supported chipsets */
Sujith285f2dd2010-01-08 10:36:07 +0530591 ret = ath9k_hw_init(ah);
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400592 if (ret)
Sujith285f2dd2010-01-08 10:36:07 +0530593 goto err_hw;
Sujith285f2dd2010-01-08 10:36:07 +0530594
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +0100595 if (pdata && pdata->macaddr)
596 memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
597
Sujith285f2dd2010-01-08 10:36:07 +0530598 ret = ath9k_init_queues(sc);
599 if (ret)
600 goto err_queues;
601
602 ret = ath9k_init_btcoex(sc);
603 if (ret)
604 goto err_btcoex;
605
Felix Fietkauf209f522010-10-01 01:06:53 +0200606 ret = ath9k_init_channels_rates(sc);
607 if (ret)
608 goto err_btcoex;
609
Sujith285f2dd2010-01-08 10:36:07 +0530610 ath9k_init_crypto(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530611 ath9k_init_misc(sc);
612
Sujith55624202010-01-08 10:36:02 +0530613 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530614
615err_btcoex:
Sujith55624202010-01-08 10:36:02 +0530616 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
617 if (ATH_TXQ_SETUP(sc, i))
618 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
Sujith285f2dd2010-01-08 10:36:07 +0530619err_queues:
Sujith285f2dd2010-01-08 10:36:07 +0530620 ath9k_hw_deinit(ah);
621err_hw:
Sujith55624202010-01-08 10:36:02 +0530622
Sujith285f2dd2010-01-08 10:36:07 +0530623 kfree(ah);
624 sc->sc_ah = NULL;
625
626 return ret;
Sujith55624202010-01-08 10:36:02 +0530627}
628
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200629static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
630{
631 struct ieee80211_supported_band *sband;
632 struct ieee80211_channel *chan;
633 struct ath_hw *ah = sc->sc_ah;
634 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
635 int i;
636
637 sband = &sc->sbands[band];
638 for (i = 0; i < sband->n_channels; i++) {
639 chan = &sband->channels[i];
640 ah->curchan = &ah->channels[chan->hw_value];
641 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
642 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
643 chan->max_power = reg->max_power_level / 2;
644 }
645}
646
647static void ath9k_init_txpower_limits(struct ath_softc *sc)
648{
649 struct ath_hw *ah = sc->sc_ah;
650 struct ath9k_channel *curchan = ah->curchan;
651
652 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
653 ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
654 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
655 ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
656
657 ah->curchan = curchan;
658}
659
Sujith285f2dd2010-01-08 10:36:07 +0530660void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
Sujith55624202010-01-08 10:36:02 +0530661{
Sujith285f2dd2010-01-08 10:36:07 +0530662 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
663
Sujith55624202010-01-08 10:36:02 +0530664 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
665 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
666 IEEE80211_HW_SIGNAL_DBM |
Sujith55624202010-01-08 10:36:02 +0530667 IEEE80211_HW_SUPPORTS_PS |
668 IEEE80211_HW_PS_NULLFUNC_STACK |
Vivek Natarajan05df4982010-02-09 11:34:50 +0530669 IEEE80211_HW_SPECTRUM_MGMT |
Mohammed Shafi Shajakhanbd8027a2010-12-30 12:18:01 +0530670 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
Sujith55624202010-01-08 10:36:02 +0530671
Luis R. Rodriguez5ffaf8a2010-02-02 11:58:33 -0500672 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
673 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
674
John W. Linville3e6109c2011-01-05 09:39:17 -0500675 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
Sujith55624202010-01-08 10:36:02 +0530676 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
677
678 hw->wiphy->interface_modes =
Johannes Bergc426ee22010-11-26 11:38:04 +0100679 BIT(NL80211_IFTYPE_P2P_GO) |
680 BIT(NL80211_IFTYPE_P2P_CLIENT) |
Sujith55624202010-01-08 10:36:02 +0530681 BIT(NL80211_IFTYPE_AP) |
Bill Jordane51f3ef2010-10-01 11:20:39 -0400682 BIT(NL80211_IFTYPE_WDS) |
Sujith55624202010-01-08 10:36:02 +0530683 BIT(NL80211_IFTYPE_STATION) |
684 BIT(NL80211_IFTYPE_ADHOC) |
685 BIT(NL80211_IFTYPE_MESH_POINT);
686
Luis R. Rodriguez008443d2010-09-16 15:12:36 -0400687 if (AR_SREV_5416(sc->sc_ah))
688 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
Sujith55624202010-01-08 10:36:02 +0530689
Jouni Malinencfdc9a82011-03-23 14:52:19 +0200690 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
691
Sujith55624202010-01-08 10:36:02 +0530692 hw->queues = 4;
693 hw->max_rates = 4;
694 hw->channel_change_time = 5000;
695 hw->max_listen_interval = 10;
Felix Fietkau65896512010-01-24 03:26:11 +0100696 hw->max_rate_tries = 10;
Sujith55624202010-01-08 10:36:02 +0530697 hw->sta_data_size = sizeof(struct ath_node);
698 hw->vif_data_size = sizeof(struct ath_vif);
699
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200700#ifdef CONFIG_ATH9K_RATE_CONTROL
Sujith55624202010-01-08 10:36:02 +0530701 hw->rate_control_algorithm = "ath9k_rate_control";
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200702#endif
Sujith55624202010-01-08 10:36:02 +0530703
Felix Fietkaud4659912010-10-14 16:02:39 +0200704 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith55624202010-01-08 10:36:02 +0530705 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
706 &sc->sbands[IEEE80211_BAND_2GHZ];
Felix Fietkaud4659912010-10-14 16:02:39 +0200707 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith55624202010-01-08 10:36:02 +0530708 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
709 &sc->sbands[IEEE80211_BAND_5GHZ];
Sujith285f2dd2010-01-08 10:36:07 +0530710
711 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
Felix Fietkaud4659912010-10-14 16:02:39 +0200712 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530713 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
Felix Fietkaud4659912010-10-14 16:02:39 +0200714 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530715 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
716 }
717
718 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
Sujith55624202010-01-08 10:36:02 +0530719}
720
Sujith285f2dd2010-01-08 10:36:07 +0530721int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
Sujith55624202010-01-08 10:36:02 +0530722 const struct ath_bus_ops *bus_ops)
723{
724 struct ieee80211_hw *hw = sc->hw;
725 struct ath_common *common;
726 struct ath_hw *ah;
Sujith285f2dd2010-01-08 10:36:07 +0530727 int error = 0;
Sujith55624202010-01-08 10:36:02 +0530728 struct ath_regulatory *reg;
729
Sujith285f2dd2010-01-08 10:36:07 +0530730 /* Bring up device */
731 error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
Sujith55624202010-01-08 10:36:02 +0530732 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530733 goto error_init;
Sujith55624202010-01-08 10:36:02 +0530734
735 ah = sc->sc_ah;
736 common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530737 ath9k_set_hw_capab(sc, hw);
Sujith55624202010-01-08 10:36:02 +0530738
Sujith285f2dd2010-01-08 10:36:07 +0530739 /* Initialize regulatory */
Sujith55624202010-01-08 10:36:02 +0530740 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
741 ath9k_reg_notifier);
742 if (error)
Sujith285f2dd2010-01-08 10:36:07 +0530743 goto error_regd;
Sujith55624202010-01-08 10:36:02 +0530744
745 reg = &common->regulatory;
746
Sujith285f2dd2010-01-08 10:36:07 +0530747 /* Setup TX DMA */
Sujith55624202010-01-08 10:36:02 +0530748 error = ath_tx_init(sc, ATH_TXBUF);
749 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530750 goto error_tx;
Sujith55624202010-01-08 10:36:02 +0530751
Sujith285f2dd2010-01-08 10:36:07 +0530752 /* Setup RX DMA */
Sujith55624202010-01-08 10:36:02 +0530753 error = ath_rx_init(sc, ATH_RXBUF);
754 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530755 goto error_rx;
756
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200757 ath9k_init_txpower_limits(sc);
758
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100759#ifdef CONFIG_MAC80211_LEDS
760 /* must be initialized before ieee80211_register_hw */
761 sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
762 IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
763 ARRAY_SIZE(ath9k_tpt_blink));
764#endif
765
Sujith285f2dd2010-01-08 10:36:07 +0530766 /* Register with mac80211 */
767 error = ieee80211_register_hw(hw);
768 if (error)
769 goto error_register;
770
Ben Greeareb272442010-11-29 14:13:22 -0800771 error = ath9k_init_debug(ah);
772 if (error) {
Joe Perches38002762010-12-02 19:12:36 -0800773 ath_err(common, "Unable to create debugfs files\n");
Ben Greeareb272442010-11-29 14:13:22 -0800774 goto error_world;
775 }
776
Sujith285f2dd2010-01-08 10:36:07 +0530777 /* Handle world regulatory */
778 if (!ath_is_world_regd(reg)) {
779 error = regulatory_hint(hw->wiphy, reg->alpha2);
780 if (error)
781 goto error_world;
782 }
Sujith55624202010-01-08 10:36:02 +0530783
Felix Fietkau347809f2010-07-02 00:09:52 +0200784 INIT_WORK(&sc->hw_check_work, ath_hw_check);
Felix Fietkau9f42c2b2010-06-12 00:34:01 -0400785 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
Felix Fietkau9ac58612011-01-24 19:23:18 +0100786 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
Sujith55624202010-01-08 10:36:02 +0530787
Sujith55624202010-01-08 10:36:02 +0530788 ath_init_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530789 ath_start_rfkill_poll(sc);
790
791 return 0;
792
Sujith285f2dd2010-01-08 10:36:07 +0530793error_world:
794 ieee80211_unregister_hw(hw);
795error_register:
796 ath_rx_cleanup(sc);
797error_rx:
798 ath_tx_cleanup(sc);
799error_tx:
800 /* Nothing */
801error_regd:
802 ath9k_deinit_softc(sc);
803error_init:
Sujith55624202010-01-08 10:36:02 +0530804 return error;
805}
806
807/*****************************/
808/* De-Initialization */
809/*****************************/
810
Sujith285f2dd2010-01-08 10:36:07 +0530811static void ath9k_deinit_softc(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530812{
Sujith285f2dd2010-01-08 10:36:07 +0530813 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530814
Felix Fietkauf209f522010-10-01 01:06:53 +0200815 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
816 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
817
818 if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
819 kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
820
Sujith285f2dd2010-01-08 10:36:07 +0530821 if ((sc->btcoex.no_stomp_timer) &&
822 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
823 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
Sujith55624202010-01-08 10:36:02 +0530824
Sujith285f2dd2010-01-08 10:36:07 +0530825 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
826 if (ATH_TXQ_SETUP(sc, i))
827 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
828
Sujith285f2dd2010-01-08 10:36:07 +0530829 ath9k_hw_deinit(sc->sc_ah);
830
Sujith736b3a22010-03-17 14:25:24 +0530831 kfree(sc->sc_ah);
832 sc->sc_ah = NULL;
Sujith55624202010-01-08 10:36:02 +0530833}
834
Sujith285f2dd2010-01-08 10:36:07 +0530835void ath9k_deinit_device(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530836{
837 struct ieee80211_hw *hw = sc->hw;
Sujith55624202010-01-08 10:36:02 +0530838
839 ath9k_ps_wakeup(sc);
840
Sujith55624202010-01-08 10:36:02 +0530841 wiphy_rfkill_stop_polling(sc->hw->wiphy);
Sujith285f2dd2010-01-08 10:36:07 +0530842 ath_deinit_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530843
Rajkumar Manoharanc7c18062011-01-27 18:39:38 +0530844 ath9k_ps_restore(sc);
845
Sujith55624202010-01-08 10:36:02 +0530846 ieee80211_unregister_hw(hw);
847 ath_rx_cleanup(sc);
848 ath_tx_cleanup(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530849 ath9k_deinit_softc(sc);
Sujith55624202010-01-08 10:36:02 +0530850}
851
852void ath_descdma_cleanup(struct ath_softc *sc,
853 struct ath_descdma *dd,
854 struct list_head *head)
855{
856 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
857 dd->dd_desc_paddr);
858
859 INIT_LIST_HEAD(head);
860 kfree(dd->dd_bufptr);
861 memset(dd, 0, sizeof(*dd));
862}
863
Sujith55624202010-01-08 10:36:02 +0530864/************************/
865/* Module Hooks */
866/************************/
867
868static int __init ath9k_init(void)
869{
870 int error;
871
872 /* Register rate control algorithm */
873 error = ath_rate_control_register();
874 if (error != 0) {
875 printk(KERN_ERR
876 "ath9k: Unable to register rate control "
877 "algorithm: %d\n",
878 error);
879 goto err_out;
880 }
881
Sujith55624202010-01-08 10:36:02 +0530882 error = ath_pci_init();
883 if (error < 0) {
884 printk(KERN_ERR
885 "ath9k: No PCI devices found, driver not installed.\n");
886 error = -ENODEV;
Ben Greeareb272442010-11-29 14:13:22 -0800887 goto err_rate_unregister;
Sujith55624202010-01-08 10:36:02 +0530888 }
889
890 error = ath_ahb_init();
891 if (error < 0) {
892 error = -ENODEV;
893 goto err_pci_exit;
894 }
895
896 return 0;
897
898 err_pci_exit:
899 ath_pci_exit();
900
Sujith55624202010-01-08 10:36:02 +0530901 err_rate_unregister:
902 ath_rate_control_unregister();
903 err_out:
904 return error;
905}
906module_init(ath9k_init);
907
908static void __exit ath9k_exit(void)
909{
Rajkumar Manoharand5847472010-12-20 14:39:51 +0530910 is_ath9k_unloaded = true;
Sujith55624202010-01-08 10:36:02 +0530911 ath_ahb_exit();
912 ath_pci_exit();
Sujith55624202010-01-08 10:36:02 +0530913 ath_rate_control_unregister();
914 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
915}
916module_exit(ath9k_exit);