blob: 79aec983279ff3d6ada9020054034af96c0c5578 [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>
18
Sujith55624202010-01-08 10:36:02 +053019#include "ath9k.h"
20
21static char *dev_info = "ath9k";
22
23MODULE_AUTHOR("Atheros Communications");
24MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
25MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
26MODULE_LICENSE("Dual BSD/GPL");
27
28static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
29module_param_named(debug, ath9k_debug, uint, 0);
30MODULE_PARM_DESC(debug, "Debugging mask");
31
John W. Linville3e6109c2011-01-05 09:39:17 -050032int ath9k_modparam_nohwcrypt;
33module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
Sujith55624202010-01-08 10:36:02 +053034MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
35
Vivek Natarajan93dbbcc2010-08-25 19:34:52 +053036int led_blink;
Vivek Natarajan9a75c2f2010-06-22 11:52:37 +053037module_param_named(blink, led_blink, int, 0444);
38MODULE_PARM_DESC(blink, "Enable LED blink on activity");
39
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -080040static int ath9k_btcoex_enable;
41module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
42MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
43
Rajkumar Manoharand5847472010-12-20 14:39:51 +053044bool is_ath9k_unloaded;
Sujith55624202010-01-08 10:36:02 +053045/* We use the hw_value as an index into our private channel structure */
46
47#define CHAN2G(_freq, _idx) { \
Mohammed Shafi Shajakhanb1c1d002010-12-17 20:44:36 +053048 .band = IEEE80211_BAND_2GHZ, \
Sujith55624202010-01-08 10:36:02 +053049 .center_freq = (_freq), \
50 .hw_value = (_idx), \
51 .max_power = 20, \
52}
53
54#define CHAN5G(_freq, _idx) { \
55 .band = IEEE80211_BAND_5GHZ, \
56 .center_freq = (_freq), \
57 .hw_value = (_idx), \
58 .max_power = 20, \
59}
60
61/* Some 2 GHz radios are actually tunable on 2312-2732
62 * on 5 MHz steps, we support the channels which we know
63 * we have calibration data for all cards though to make
64 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020065static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053066 CHAN2G(2412, 0), /* Channel 1 */
67 CHAN2G(2417, 1), /* Channel 2 */
68 CHAN2G(2422, 2), /* Channel 3 */
69 CHAN2G(2427, 3), /* Channel 4 */
70 CHAN2G(2432, 4), /* Channel 5 */
71 CHAN2G(2437, 5), /* Channel 6 */
72 CHAN2G(2442, 6), /* Channel 7 */
73 CHAN2G(2447, 7), /* Channel 8 */
74 CHAN2G(2452, 8), /* Channel 9 */
75 CHAN2G(2457, 9), /* Channel 10 */
76 CHAN2G(2462, 10), /* Channel 11 */
77 CHAN2G(2467, 11), /* Channel 12 */
78 CHAN2G(2472, 12), /* Channel 13 */
79 CHAN2G(2484, 13), /* Channel 14 */
80};
81
82/* Some 5 GHz radios are actually tunable on XXXX-YYYY
83 * on 5 MHz steps, we support the channels which we know
84 * we have calibration data for all cards though to make
85 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020086static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053087 /* _We_ call this UNII 1 */
88 CHAN5G(5180, 14), /* Channel 36 */
89 CHAN5G(5200, 15), /* Channel 40 */
90 CHAN5G(5220, 16), /* Channel 44 */
91 CHAN5G(5240, 17), /* Channel 48 */
92 /* _We_ call this UNII 2 */
93 CHAN5G(5260, 18), /* Channel 52 */
94 CHAN5G(5280, 19), /* Channel 56 */
95 CHAN5G(5300, 20), /* Channel 60 */
96 CHAN5G(5320, 21), /* Channel 64 */
97 /* _We_ call this "Middle band" */
98 CHAN5G(5500, 22), /* Channel 100 */
99 CHAN5G(5520, 23), /* Channel 104 */
100 CHAN5G(5540, 24), /* Channel 108 */
101 CHAN5G(5560, 25), /* Channel 112 */
102 CHAN5G(5580, 26), /* Channel 116 */
103 CHAN5G(5600, 27), /* Channel 120 */
104 CHAN5G(5620, 28), /* Channel 124 */
105 CHAN5G(5640, 29), /* Channel 128 */
106 CHAN5G(5660, 30), /* Channel 132 */
107 CHAN5G(5680, 31), /* Channel 136 */
108 CHAN5G(5700, 32), /* Channel 140 */
109 /* _We_ call this UNII 3 */
110 CHAN5G(5745, 33), /* Channel 149 */
111 CHAN5G(5765, 34), /* Channel 153 */
112 CHAN5G(5785, 35), /* Channel 157 */
113 CHAN5G(5805, 36), /* Channel 161 */
114 CHAN5G(5825, 37), /* Channel 165 */
115};
116
117/* Atheros hardware rate code addition for short premble */
118#define SHPCHECK(__hw_rate, __flags) \
119 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
120
121#define RATE(_bitrate, _hw_rate, _flags) { \
122 .bitrate = (_bitrate), \
123 .flags = (_flags), \
124 .hw_value = (_hw_rate), \
125 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
126}
127
128static struct ieee80211_rate ath9k_legacy_rates[] = {
129 RATE(10, 0x1b, 0),
130 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
131 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
132 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
133 RATE(60, 0x0b, 0),
134 RATE(90, 0x0f, 0),
135 RATE(120, 0x0a, 0),
136 RATE(180, 0x0e, 0),
137 RATE(240, 0x09, 0),
138 RATE(360, 0x0d, 0),
139 RATE(480, 0x08, 0),
140 RATE(540, 0x0c, 0),
141};
142
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100143#ifdef CONFIG_MAC80211_LEDS
144static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
145 { .throughput = 0 * 1024, .blink_time = 334 },
146 { .throughput = 1 * 1024, .blink_time = 260 },
147 { .throughput = 5 * 1024, .blink_time = 220 },
148 { .throughput = 10 * 1024, .blink_time = 190 },
149 { .throughput = 20 * 1024, .blink_time = 170 },
150 { .throughput = 50 * 1024, .blink_time = 150 },
151 { .throughput = 70 * 1024, .blink_time = 130 },
152 { .throughput = 100 * 1024, .blink_time = 110 },
153 { .throughput = 200 * 1024, .blink_time = 80 },
154 { .throughput = 300 * 1024, .blink_time = 50 },
155};
156#endif
157
Sujith285f2dd2010-01-08 10:36:07 +0530158static void ath9k_deinit_softc(struct ath_softc *sc);
Sujith55624202010-01-08 10:36:02 +0530159
160/*
161 * Read and write, they both share the same lock. We do this to serialize
162 * reads and writes on Atheros 802.11n PCI devices only. This is required
163 * as the FIFO on these devices can only accept sanely 2 requests.
164 */
165
166static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
167{
168 struct ath_hw *ah = (struct ath_hw *) hw_priv;
169 struct ath_common *common = ath9k_hw_common(ah);
170 struct ath_softc *sc = (struct ath_softc *) common->priv;
171
172 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
173 unsigned long flags;
174 spin_lock_irqsave(&sc->sc_serial_rw, flags);
175 iowrite32(val, sc->mem + reg_offset);
176 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
177 } else
178 iowrite32(val, sc->mem + reg_offset);
179}
180
181static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
182{
183 struct ath_hw *ah = (struct ath_hw *) hw_priv;
184 struct ath_common *common = ath9k_hw_common(ah);
185 struct ath_softc *sc = (struct ath_softc *) common->priv;
186 u32 val;
187
188 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
189 unsigned long flags;
190 spin_lock_irqsave(&sc->sc_serial_rw, flags);
191 val = ioread32(sc->mem + reg_offset);
192 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
193 } else
194 val = ioread32(sc->mem + reg_offset);
195 return val;
196}
197
198static const struct ath_ops ath9k_common_ops = {
199 .read = ath9k_ioread32,
200 .write = ath9k_iowrite32,
201};
202
203/**************************/
204/* Initialization */
205/**************************/
206
207static void setup_ht_cap(struct ath_softc *sc,
208 struct ieee80211_sta_ht_cap *ht_info)
209{
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200210 struct ath_hw *ah = sc->sc_ah;
211 struct ath_common *common = ath9k_hw_common(ah);
Sujith55624202010-01-08 10:36:02 +0530212 u8 tx_streams, rx_streams;
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200213 int i, max_streams;
Sujith55624202010-01-08 10:36:02 +0530214
215 ht_info->ht_supported = true;
216 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
217 IEEE80211_HT_CAP_SM_PS |
218 IEEE80211_HT_CAP_SGI_40 |
219 IEEE80211_HT_CAP_DSSSCCK40;
220
Luis R. Rodriguezb0a33442010-04-15 17:39:39 -0400221 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
222 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
223
Vasanthakumar Thiagarajan6473d242010-05-13 18:42:38 -0700224 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
225 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
226
Sujith55624202010-01-08 10:36:02 +0530227 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
228 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
229
Vasanthakumar Thiagarajan7f1c7a62010-12-06 04:27:41 -0800230 if (AR_SREV_9485(ah))
231 max_streams = 1;
232 else if (AR_SREV_9300_20_OR_LATER(ah))
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200233 max_streams = 3;
234 else
235 max_streams = 2;
236
Felix Fietkau7a370812010-09-22 12:34:52 +0200237 if (AR_SREV_9280_20_OR_LATER(ah)) {
Felix Fietkau074a8c02010-04-19 19:57:36 +0200238 if (max_streams >= 2)
239 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
240 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
241 }
242
Sujith55624202010-01-08 10:36:02 +0530243 /* set up supported mcs set */
244 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
Sujith61389f32010-06-02 15:53:37 +0530245 tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
246 rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200247
Joe Perches226afe62010-12-02 19:12:37 -0800248 ath_dbg(common, ATH_DBG_CONFIG,
249 "TX streams %d, RX streams: %d\n",
250 tx_streams, rx_streams);
Sujith55624202010-01-08 10:36:02 +0530251
252 if (tx_streams != rx_streams) {
Sujith55624202010-01-08 10:36:02 +0530253 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
254 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
255 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
256 }
257
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200258 for (i = 0; i < rx_streams; i++)
259 ht_info->mcs.rx_mask[i] = 0xff;
Sujith55624202010-01-08 10:36:02 +0530260
261 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
262}
263
264static int ath9k_reg_notifier(struct wiphy *wiphy,
265 struct regulatory_request *request)
266{
267 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
Felix Fietkau9ac586152011-01-24 19:23:18 +0100268 struct ath_softc *sc = hw->priv;
Sujith55624202010-01-08 10:36:02 +0530269 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
270
271 return ath_reg_notifier_apply(wiphy, request, reg);
272}
273
274/*
275 * This function will allocate both the DMA descriptor structure, and the
276 * buffers it contains. These are used to contain the descriptors used
277 * by the system.
278*/
279int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
280 struct list_head *head, const char *name,
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400281 int nbuf, int ndesc, bool is_tx)
Sujith55624202010-01-08 10:36:02 +0530282{
283#define DS2PHYS(_dd, _ds) \
284 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
285#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
286#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
287 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400288 u8 *ds;
Sujith55624202010-01-08 10:36:02 +0530289 struct ath_buf *bf;
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400290 int i, bsize, error, desc_len;
Sujith55624202010-01-08 10:36:02 +0530291
Joe Perches226afe62010-12-02 19:12:37 -0800292 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
293 name, nbuf, ndesc);
Sujith55624202010-01-08 10:36:02 +0530294
295 INIT_LIST_HEAD(head);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400296
297 if (is_tx)
298 desc_len = sc->sc_ah->caps.tx_desc_len;
299 else
300 desc_len = sizeof(struct ath_desc);
301
Sujith55624202010-01-08 10:36:02 +0530302 /* ath_desc must be a multiple of DWORDs */
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400303 if ((desc_len % 4) != 0) {
Joe Perches38002762010-12-02 19:12:36 -0800304 ath_err(common, "ath_desc not DWORD aligned\n");
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400305 BUG_ON((desc_len % 4) != 0);
Sujith55624202010-01-08 10:36:02 +0530306 error = -ENOMEM;
307 goto fail;
308 }
309
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400310 dd->dd_desc_len = desc_len * nbuf * ndesc;
Sujith55624202010-01-08 10:36:02 +0530311
312 /*
313 * Need additional DMA memory because we can't use
314 * descriptors that cross the 4K page boundary. Assume
315 * one skipped descriptor per 4K page.
316 */
317 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
318 u32 ndesc_skipped =
319 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
320 u32 dma_len;
321
322 while (ndesc_skipped) {
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400323 dma_len = ndesc_skipped * desc_len;
Sujith55624202010-01-08 10:36:02 +0530324 dd->dd_desc_len += dma_len;
325
326 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
Joe Perchesee289b62010-05-17 22:47:34 -0700327 }
Sujith55624202010-01-08 10:36:02 +0530328 }
329
330 /* allocate descriptors */
331 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
332 &dd->dd_desc_paddr, GFP_KERNEL);
333 if (dd->dd_desc == NULL) {
334 error = -ENOMEM;
335 goto fail;
336 }
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400337 ds = (u8 *) dd->dd_desc;
Joe Perches226afe62010-12-02 19:12:37 -0800338 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
339 name, ds, (u32) dd->dd_desc_len,
340 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
Sujith55624202010-01-08 10:36:02 +0530341
342 /* allocate buffers */
343 bsize = sizeof(struct ath_buf) * nbuf;
344 bf = kzalloc(bsize, GFP_KERNEL);
345 if (bf == NULL) {
346 error = -ENOMEM;
347 goto fail2;
348 }
349 dd->dd_bufptr = bf;
350
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400351 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
Sujith55624202010-01-08 10:36:02 +0530352 bf->bf_desc = ds;
353 bf->bf_daddr = DS2PHYS(dd, ds);
354
355 if (!(sc->sc_ah->caps.hw_caps &
356 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
357 /*
358 * Skip descriptor addresses which can cause 4KB
359 * boundary crossing (addr + length) with a 32 dword
360 * descriptor fetch.
361 */
362 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
363 BUG_ON((caddr_t) bf->bf_desc >=
364 ((caddr_t) dd->dd_desc +
365 dd->dd_desc_len));
366
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400367 ds += (desc_len * ndesc);
Sujith55624202010-01-08 10:36:02 +0530368 bf->bf_desc = ds;
369 bf->bf_daddr = DS2PHYS(dd, ds);
370 }
371 }
372 list_add_tail(&bf->list, head);
373 }
374 return 0;
375fail2:
376 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
377 dd->dd_desc_paddr);
378fail:
379 memset(dd, 0, sizeof(*dd));
380 return error;
381#undef ATH_DESC_4KB_BOUND_CHECK
382#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
383#undef DS2PHYS
384}
385
Mohammed Shafi Shajakhandb7ec382010-12-22 12:20:12 +0530386void ath9k_init_crypto(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530387{
Sujith285f2dd2010-01-08 10:36:07 +0530388 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
389 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530390
391 /* Get the hardware key cache size. */
Sujith285f2dd2010-01-08 10:36:07 +0530392 common->keymax = sc->sc_ah->caps.keycache_size;
Sujith55624202010-01-08 10:36:02 +0530393 if (common->keymax > ATH_KEYMAX) {
Joe Perches226afe62010-12-02 19:12:37 -0800394 ath_dbg(common, ATH_DBG_ANY,
395 "Warning, using only %u entries in %u key cache\n",
396 ATH_KEYMAX, common->keymax);
Sujith55624202010-01-08 10:36:02 +0530397 common->keymax = ATH_KEYMAX;
398 }
399
400 /*
401 * Reset the key cache since some parts do not
402 * reset the contents on initial power up.
403 */
404 for (i = 0; i < common->keymax; i++)
Bruno Randolf040e5392010-09-08 16:05:04 +0900405 ath_hw_keyreset(common, (u16) i);
Sujith55624202010-01-08 10:36:02 +0530406
Felix Fietkau716f7fc2010-06-12 17:22:28 +0200407 /*
Sujith55624202010-01-08 10:36:02 +0530408 * Check whether the separate key cache entries
409 * are required to handle both tx+rx MIC keys.
410 * With split mic keys the number of stations is limited
411 * to 27 otherwise 59.
412 */
Bruno Randolf117675d2010-09-08 16:04:54 +0900413 if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
414 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
Sujith285f2dd2010-01-08 10:36:07 +0530415}
Sujith55624202010-01-08 10:36:02 +0530416
Sujith285f2dd2010-01-08 10:36:07 +0530417static int ath9k_init_btcoex(struct ath_softc *sc)
418{
Felix Fietkau066dae92010-11-07 14:59:39 +0100419 struct ath_txq *txq;
420 int r;
Sujith285f2dd2010-01-08 10:36:07 +0530421
422 switch (sc->sc_ah->btcoex_hw.scheme) {
423 case ATH_BTCOEX_CFG_NONE:
424 break;
425 case ATH_BTCOEX_CFG_2WIRE:
426 ath9k_hw_btcoex_init_2wire(sc->sc_ah);
427 break;
428 case ATH_BTCOEX_CFG_3WIRE:
429 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
430 r = ath_init_btcoex_timer(sc);
431 if (r)
432 return -1;
Felix Fietkau066dae92010-11-07 14:59:39 +0100433 txq = sc->tx.txq_map[WME_AC_BE];
434 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
Sujith285f2dd2010-01-08 10:36:07 +0530435 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
436 break;
437 default:
438 WARN_ON(1);
439 break;
Sujith55624202010-01-08 10:36:02 +0530440 }
441
Sujith285f2dd2010-01-08 10:36:07 +0530442 return 0;
443}
Sujith55624202010-01-08 10:36:02 +0530444
Sujith285f2dd2010-01-08 10:36:07 +0530445static int ath9k_init_queues(struct ath_softc *sc)
446{
Sujith285f2dd2010-01-08 10:36:07 +0530447 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530448
Sujith285f2dd2010-01-08 10:36:07 +0530449 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
Sujith285f2dd2010-01-08 10:36:07 +0530450 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
Sujith55624202010-01-08 10:36:02 +0530451
Sujith285f2dd2010-01-08 10:36:07 +0530452 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
453 ath_cabq_update(sc);
454
Ben Greear60f2d1d2011-01-09 23:11:52 -0800455 for (i = 0; i < WME_NUM_AC; i++) {
Felix Fietkau066dae92010-11-07 14:59:39 +0100456 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
Ben Greear60f2d1d2011-01-09 23:11:52 -0800457 sc->tx.txq_map[i]->mac80211_qnum = i;
458 }
Sujith285f2dd2010-01-08 10:36:07 +0530459 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530460}
461
Felix Fietkauf209f522010-10-01 01:06:53 +0200462static int ath9k_init_channels_rates(struct ath_softc *sc)
Sujith285f2dd2010-01-08 10:36:07 +0530463{
Felix Fietkauf209f522010-10-01 01:06:53 +0200464 void *channels;
465
Felix Fietkaucac42202010-10-09 02:39:30 +0200466 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
467 ARRAY_SIZE(ath9k_5ghz_chantable) !=
468 ATH9K_NUM_CHANNELS);
469
Felix Fietkaud4659912010-10-14 16:02:39 +0200470 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200471 channels = kmemdup(ath9k_2ghz_chantable,
472 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
473 if (!channels)
474 return -ENOMEM;
475
476 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530477 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
478 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
479 ARRAY_SIZE(ath9k_2ghz_chantable);
480 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
481 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
482 ARRAY_SIZE(ath9k_legacy_rates);
483 }
484
Felix Fietkaud4659912010-10-14 16:02:39 +0200485 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200486 channels = kmemdup(ath9k_5ghz_chantable,
487 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
488 if (!channels) {
489 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
490 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
491 return -ENOMEM;
492 }
493
494 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530495 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
496 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
497 ARRAY_SIZE(ath9k_5ghz_chantable);
498 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
499 ath9k_legacy_rates + 4;
500 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
501 ARRAY_SIZE(ath9k_legacy_rates) - 4;
502 }
Felix Fietkauf209f522010-10-01 01:06:53 +0200503 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530504}
Sujith55624202010-01-08 10:36:02 +0530505
Sujith285f2dd2010-01-08 10:36:07 +0530506static void ath9k_init_misc(struct ath_softc *sc)
507{
508 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
509 int i = 0;
510
Sujith285f2dd2010-01-08 10:36:07 +0530511 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
512
513 sc->config.txpowlimit = ATH_TXPOWER_MAX;
514
515 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
516 sc->sc_flags |= SC_OP_TXAGGR;
517 sc->sc_flags |= SC_OP_RXAGGR;
Sujith55624202010-01-08 10:36:02 +0530518 }
519
Sujith285f2dd2010-01-08 10:36:07 +0530520 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
521 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
522
Luis R. Rodriguez8fe65362010-04-15 17:38:14 -0400523 ath9k_hw_set_diversity(sc->sc_ah, true);
Sujith285f2dd2010-01-08 10:36:07 +0530524 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
525
Felix Fietkau364734f2010-09-14 20:22:44 +0200526 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
Sujith285f2dd2010-01-08 10:36:07 +0530527
528 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
529
Felix Fietkau7545daf2011-01-24 19:23:16 +0100530 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
Sujith285f2dd2010-01-08 10:36:07 +0530531 sc->beacon.bslot[i] = NULL;
Vasanthakumar Thiagarajan102885a2010-09-02 01:34:43 -0700532
533 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
534 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
Sujith285f2dd2010-01-08 10:36:07 +0530535}
536
537static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
538 const struct ath_bus_ops *bus_ops)
539{
540 struct ath_hw *ah = NULL;
541 struct ath_common *common;
542 int ret = 0, i;
543 int csz = 0;
544
Sujith285f2dd2010-01-08 10:36:07 +0530545 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
546 if (!ah)
547 return -ENOMEM;
548
Ben Greear233536e2011-01-09 23:11:44 -0800549 ah->hw = sc->hw;
Sujith285f2dd2010-01-08 10:36:07 +0530550 ah->hw_version.devid = devid;
551 ah->hw_version.subsysid = subsysid;
552 sc->sc_ah = ah;
553
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100554 if (!sc->dev->platform_data)
555 ah->ah_flags |= AH_USE_EEPROM;
556
Sujith285f2dd2010-01-08 10:36:07 +0530557 common = ath9k_hw_common(ah);
558 common->ops = &ath9k_common_ops;
559 common->bus_ops = bus_ops;
560 common->ah = ah;
561 common->hw = sc->hw;
562 common->priv = sc;
563 common->debug_mask = ath9k_debug;
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -0800564 common->btcoex_enabled = ath9k_btcoex_enable == 1;
Ben Greear20b257442010-10-15 15:04:09 -0700565 spin_lock_init(&common->cc_lock);
Sujith285f2dd2010-01-08 10:36:07 +0530566
Sujith285f2dd2010-01-08 10:36:07 +0530567 spin_lock_init(&sc->sc_serial_rw);
568 spin_lock_init(&sc->sc_pm_lock);
569 mutex_init(&sc->mutex);
Ben Greear7f010c92011-01-09 23:11:49 -0800570#ifdef CONFIG_ATH9K_DEBUGFS
571 spin_lock_init(&sc->nodes_lock);
572 INIT_LIST_HEAD(&sc->nodes);
573#endif
Sujith285f2dd2010-01-08 10:36:07 +0530574 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
575 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
576 (unsigned long)sc);
577
578 /*
579 * Cache line size is used to size and align various
580 * structures used to communicate with the hardware.
581 */
582 ath_read_cachesize(common, &csz);
583 common->cachelsz = csz << 2; /* convert to bytes */
584
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400585 /* Initializes the hardware for all supported chipsets */
Sujith285f2dd2010-01-08 10:36:07 +0530586 ret = ath9k_hw_init(ah);
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400587 if (ret)
Sujith285f2dd2010-01-08 10:36:07 +0530588 goto err_hw;
Sujith285f2dd2010-01-08 10:36:07 +0530589
Sujith285f2dd2010-01-08 10:36:07 +0530590 ret = ath9k_init_queues(sc);
591 if (ret)
592 goto err_queues;
593
594 ret = ath9k_init_btcoex(sc);
595 if (ret)
596 goto err_btcoex;
597
Felix Fietkauf209f522010-10-01 01:06:53 +0200598 ret = ath9k_init_channels_rates(sc);
599 if (ret)
600 goto err_btcoex;
601
Sujith285f2dd2010-01-08 10:36:07 +0530602 ath9k_init_crypto(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530603 ath9k_init_misc(sc);
604
Sujith55624202010-01-08 10:36:02 +0530605 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530606
607err_btcoex:
Sujith55624202010-01-08 10:36:02 +0530608 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
609 if (ATH_TXQ_SETUP(sc, i))
610 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
Sujith285f2dd2010-01-08 10:36:07 +0530611err_queues:
Sujith285f2dd2010-01-08 10:36:07 +0530612 ath9k_hw_deinit(ah);
613err_hw:
Sujith55624202010-01-08 10:36:02 +0530614
Sujith285f2dd2010-01-08 10:36:07 +0530615 kfree(ah);
616 sc->sc_ah = NULL;
617
618 return ret;
Sujith55624202010-01-08 10:36:02 +0530619}
620
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200621static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
622{
623 struct ieee80211_supported_band *sband;
624 struct ieee80211_channel *chan;
625 struct ath_hw *ah = sc->sc_ah;
626 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
627 int i;
628
629 sband = &sc->sbands[band];
630 for (i = 0; i < sband->n_channels; i++) {
631 chan = &sband->channels[i];
632 ah->curchan = &ah->channels[chan->hw_value];
633 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
634 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
635 chan->max_power = reg->max_power_level / 2;
636 }
637}
638
639static void ath9k_init_txpower_limits(struct ath_softc *sc)
640{
641 struct ath_hw *ah = sc->sc_ah;
642 struct ath9k_channel *curchan = ah->curchan;
643
644 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
645 ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
646 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
647 ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
648
649 ah->curchan = curchan;
650}
651
Sujith285f2dd2010-01-08 10:36:07 +0530652void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
Sujith55624202010-01-08 10:36:02 +0530653{
Sujith285f2dd2010-01-08 10:36:07 +0530654 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
655
Sujith55624202010-01-08 10:36:02 +0530656 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
657 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
658 IEEE80211_HW_SIGNAL_DBM |
Sujith55624202010-01-08 10:36:02 +0530659 IEEE80211_HW_SUPPORTS_PS |
660 IEEE80211_HW_PS_NULLFUNC_STACK |
Vivek Natarajan05df4982010-02-09 11:34:50 +0530661 IEEE80211_HW_SPECTRUM_MGMT |
Mohammed Shafi Shajakhanbd8027a2010-12-30 12:18:01 +0530662 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
Sujith55624202010-01-08 10:36:02 +0530663
Luis R. Rodriguez5ffaf8a2010-02-02 11:58:33 -0500664 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
665 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
666
John W. Linville3e6109c2011-01-05 09:39:17 -0500667 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
Sujith55624202010-01-08 10:36:02 +0530668 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
669
670 hw->wiphy->interface_modes =
Johannes Bergc426ee22010-11-26 11:38:04 +0100671 BIT(NL80211_IFTYPE_P2P_GO) |
672 BIT(NL80211_IFTYPE_P2P_CLIENT) |
Sujith55624202010-01-08 10:36:02 +0530673 BIT(NL80211_IFTYPE_AP) |
Bill Jordane51f3ef2010-10-01 11:20:39 -0400674 BIT(NL80211_IFTYPE_WDS) |
Sujith55624202010-01-08 10:36:02 +0530675 BIT(NL80211_IFTYPE_STATION) |
676 BIT(NL80211_IFTYPE_ADHOC) |
677 BIT(NL80211_IFTYPE_MESH_POINT);
678
Luis R. Rodriguez008443d2010-09-16 15:12:36 -0400679 if (AR_SREV_5416(sc->sc_ah))
680 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
Sujith55624202010-01-08 10:36:02 +0530681
682 hw->queues = 4;
683 hw->max_rates = 4;
684 hw->channel_change_time = 5000;
685 hw->max_listen_interval = 10;
Felix Fietkau65896512010-01-24 03:26:11 +0100686 hw->max_rate_tries = 10;
Sujith55624202010-01-08 10:36:02 +0530687 hw->sta_data_size = sizeof(struct ath_node);
688 hw->vif_data_size = sizeof(struct ath_vif);
689
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200690#ifdef CONFIG_ATH9K_RATE_CONTROL
Sujith55624202010-01-08 10:36:02 +0530691 hw->rate_control_algorithm = "ath9k_rate_control";
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200692#endif
Sujith55624202010-01-08 10:36:02 +0530693
Felix Fietkaud4659912010-10-14 16:02:39 +0200694 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith55624202010-01-08 10:36:02 +0530695 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
696 &sc->sbands[IEEE80211_BAND_2GHZ];
Felix Fietkaud4659912010-10-14 16:02:39 +0200697 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith55624202010-01-08 10:36:02 +0530698 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
699 &sc->sbands[IEEE80211_BAND_5GHZ];
Sujith285f2dd2010-01-08 10:36:07 +0530700
701 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
Felix Fietkaud4659912010-10-14 16:02:39 +0200702 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530703 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
Felix Fietkaud4659912010-10-14 16:02:39 +0200704 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530705 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
706 }
707
708 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
Sujith55624202010-01-08 10:36:02 +0530709}
710
Sujith285f2dd2010-01-08 10:36:07 +0530711int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
Sujith55624202010-01-08 10:36:02 +0530712 const struct ath_bus_ops *bus_ops)
713{
714 struct ieee80211_hw *hw = sc->hw;
715 struct ath_common *common;
716 struct ath_hw *ah;
Sujith285f2dd2010-01-08 10:36:07 +0530717 int error = 0;
Sujith55624202010-01-08 10:36:02 +0530718 struct ath_regulatory *reg;
719
Sujith285f2dd2010-01-08 10:36:07 +0530720 /* Bring up device */
721 error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
Sujith55624202010-01-08 10:36:02 +0530722 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530723 goto error_init;
Sujith55624202010-01-08 10:36:02 +0530724
725 ah = sc->sc_ah;
726 common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530727 ath9k_set_hw_capab(sc, hw);
Sujith55624202010-01-08 10:36:02 +0530728
Sujith285f2dd2010-01-08 10:36:07 +0530729 /* Initialize regulatory */
Sujith55624202010-01-08 10:36:02 +0530730 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
731 ath9k_reg_notifier);
732 if (error)
Sujith285f2dd2010-01-08 10:36:07 +0530733 goto error_regd;
Sujith55624202010-01-08 10:36:02 +0530734
735 reg = &common->regulatory;
736
Sujith285f2dd2010-01-08 10:36:07 +0530737 /* Setup TX DMA */
Sujith55624202010-01-08 10:36:02 +0530738 error = ath_tx_init(sc, ATH_TXBUF);
739 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530740 goto error_tx;
Sujith55624202010-01-08 10:36:02 +0530741
Sujith285f2dd2010-01-08 10:36:07 +0530742 /* Setup RX DMA */
Sujith55624202010-01-08 10:36:02 +0530743 error = ath_rx_init(sc, ATH_RXBUF);
744 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530745 goto error_rx;
746
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200747 ath9k_init_txpower_limits(sc);
748
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100749#ifdef CONFIG_MAC80211_LEDS
750 /* must be initialized before ieee80211_register_hw */
751 sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
752 IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
753 ARRAY_SIZE(ath9k_tpt_blink));
754#endif
755
Sujith285f2dd2010-01-08 10:36:07 +0530756 /* Register with mac80211 */
757 error = ieee80211_register_hw(hw);
758 if (error)
759 goto error_register;
760
Ben Greeareb272442010-11-29 14:13:22 -0800761 error = ath9k_init_debug(ah);
762 if (error) {
Joe Perches38002762010-12-02 19:12:36 -0800763 ath_err(common, "Unable to create debugfs files\n");
Ben Greeareb272442010-11-29 14:13:22 -0800764 goto error_world;
765 }
766
Sujith285f2dd2010-01-08 10:36:07 +0530767 /* Handle world regulatory */
768 if (!ath_is_world_regd(reg)) {
769 error = regulatory_hint(hw->wiphy, reg->alpha2);
770 if (error)
771 goto error_world;
772 }
Sujith55624202010-01-08 10:36:02 +0530773
Felix Fietkau347809f2010-07-02 00:09:52 +0200774 INIT_WORK(&sc->hw_check_work, ath_hw_check);
Felix Fietkau9f42c2b2010-06-12 00:34:01 -0400775 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
Felix Fietkau9ac586152011-01-24 19:23:18 +0100776 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
Sujith55624202010-01-08 10:36:02 +0530777
Sujith55624202010-01-08 10:36:02 +0530778 ath_init_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530779 ath_start_rfkill_poll(sc);
780
781 return 0;
782
Sujith285f2dd2010-01-08 10:36:07 +0530783error_world:
784 ieee80211_unregister_hw(hw);
785error_register:
786 ath_rx_cleanup(sc);
787error_rx:
788 ath_tx_cleanup(sc);
789error_tx:
790 /* Nothing */
791error_regd:
792 ath9k_deinit_softc(sc);
793error_init:
Sujith55624202010-01-08 10:36:02 +0530794 return error;
795}
796
797/*****************************/
798/* De-Initialization */
799/*****************************/
800
Sujith285f2dd2010-01-08 10:36:07 +0530801static void ath9k_deinit_softc(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530802{
Sujith285f2dd2010-01-08 10:36:07 +0530803 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530804
Felix Fietkauf209f522010-10-01 01:06:53 +0200805 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
806 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
807
808 if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
809 kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
810
Sujith285f2dd2010-01-08 10:36:07 +0530811 if ((sc->btcoex.no_stomp_timer) &&
812 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
813 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
Sujith55624202010-01-08 10:36:02 +0530814
Sujith285f2dd2010-01-08 10:36:07 +0530815 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
816 if (ATH_TXQ_SETUP(sc, i))
817 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
818
Sujith285f2dd2010-01-08 10:36:07 +0530819 ath9k_hw_deinit(sc->sc_ah);
820
Sujith736b3a22010-03-17 14:25:24 +0530821 kfree(sc->sc_ah);
822 sc->sc_ah = NULL;
Sujith55624202010-01-08 10:36:02 +0530823}
824
Sujith285f2dd2010-01-08 10:36:07 +0530825void ath9k_deinit_device(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530826{
827 struct ieee80211_hw *hw = sc->hw;
Sujith55624202010-01-08 10:36:02 +0530828
829 ath9k_ps_wakeup(sc);
830
Sujith55624202010-01-08 10:36:02 +0530831 wiphy_rfkill_stop_polling(sc->hw->wiphy);
Sujith285f2dd2010-01-08 10:36:07 +0530832 ath_deinit_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530833
Rajkumar Manoharanc7c18062011-01-27 18:39:38 +0530834 ath9k_ps_restore(sc);
835
Sujith55624202010-01-08 10:36:02 +0530836 ieee80211_unregister_hw(hw);
837 ath_rx_cleanup(sc);
838 ath_tx_cleanup(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530839 ath9k_deinit_softc(sc);
Sujith55624202010-01-08 10:36:02 +0530840}
841
842void ath_descdma_cleanup(struct ath_softc *sc,
843 struct ath_descdma *dd,
844 struct list_head *head)
845{
846 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
847 dd->dd_desc_paddr);
848
849 INIT_LIST_HEAD(head);
850 kfree(dd->dd_bufptr);
851 memset(dd, 0, sizeof(*dd));
852}
853
Sujith55624202010-01-08 10:36:02 +0530854/************************/
855/* Module Hooks */
856/************************/
857
858static int __init ath9k_init(void)
859{
860 int error;
861
862 /* Register rate control algorithm */
863 error = ath_rate_control_register();
864 if (error != 0) {
865 printk(KERN_ERR
866 "ath9k: Unable to register rate control "
867 "algorithm: %d\n",
868 error);
869 goto err_out;
870 }
871
Sujith55624202010-01-08 10:36:02 +0530872 error = ath_pci_init();
873 if (error < 0) {
874 printk(KERN_ERR
875 "ath9k: No PCI devices found, driver not installed.\n");
876 error = -ENODEV;
Ben Greeareb272442010-11-29 14:13:22 -0800877 goto err_rate_unregister;
Sujith55624202010-01-08 10:36:02 +0530878 }
879
880 error = ath_ahb_init();
881 if (error < 0) {
882 error = -ENODEV;
883 goto err_pci_exit;
884 }
885
886 return 0;
887
888 err_pci_exit:
889 ath_pci_exit();
890
Sujith55624202010-01-08 10:36:02 +0530891 err_rate_unregister:
892 ath_rate_control_unregister();
893 err_out:
894 return error;
895}
896module_init(ath9k_init);
897
898static void __exit ath9k_exit(void)
899{
Rajkumar Manoharand5847472010-12-20 14:39:51 +0530900 is_ath9k_unloaded = true;
Sujith55624202010-01-08 10:36:02 +0530901 ath_ahb_exit();
902 ath_pci_exit();
Sujith55624202010-01-08 10:36:02 +0530903 ath_rate_control_unregister();
904 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
905}
906module_exit(ath9k_exit);