blob: 5279653c90c7f28bf28cb8f8af374609ecc751a7 [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
Mohammed Shafi Shajakhan4dc35302010-12-14 13:18:28 +053044int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
45module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
46MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
47
Rajkumar Manoharand5847472010-12-20 14:39:51 +053048bool is_ath9k_unloaded;
Sujith55624202010-01-08 10:36:02 +053049/* We use the hw_value as an index into our private channel structure */
50
51#define CHAN2G(_freq, _idx) { \
Mohammed Shafi Shajakhanb1c1d002010-12-17 20:44:36 +053052 .band = IEEE80211_BAND_2GHZ, \
Sujith55624202010-01-08 10:36:02 +053053 .center_freq = (_freq), \
54 .hw_value = (_idx), \
55 .max_power = 20, \
56}
57
58#define CHAN5G(_freq, _idx) { \
59 .band = IEEE80211_BAND_5GHZ, \
60 .center_freq = (_freq), \
61 .hw_value = (_idx), \
62 .max_power = 20, \
63}
64
65/* Some 2 GHz radios are actually tunable on 2312-2732
66 * on 5 MHz steps, we support the channels which we know
67 * we have calibration data for all cards though to make
68 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020069static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053070 CHAN2G(2412, 0), /* Channel 1 */
71 CHAN2G(2417, 1), /* Channel 2 */
72 CHAN2G(2422, 2), /* Channel 3 */
73 CHAN2G(2427, 3), /* Channel 4 */
74 CHAN2G(2432, 4), /* Channel 5 */
75 CHAN2G(2437, 5), /* Channel 6 */
76 CHAN2G(2442, 6), /* Channel 7 */
77 CHAN2G(2447, 7), /* Channel 8 */
78 CHAN2G(2452, 8), /* Channel 9 */
79 CHAN2G(2457, 9), /* Channel 10 */
80 CHAN2G(2462, 10), /* Channel 11 */
81 CHAN2G(2467, 11), /* Channel 12 */
82 CHAN2G(2472, 12), /* Channel 13 */
83 CHAN2G(2484, 13), /* Channel 14 */
84};
85
86/* Some 5 GHz radios are actually tunable on XXXX-YYYY
87 * on 5 MHz steps, we support the channels which we know
88 * we have calibration data for all cards though to make
89 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020090static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053091 /* _We_ call this UNII 1 */
92 CHAN5G(5180, 14), /* Channel 36 */
93 CHAN5G(5200, 15), /* Channel 40 */
94 CHAN5G(5220, 16), /* Channel 44 */
95 CHAN5G(5240, 17), /* Channel 48 */
96 /* _We_ call this UNII 2 */
97 CHAN5G(5260, 18), /* Channel 52 */
98 CHAN5G(5280, 19), /* Channel 56 */
99 CHAN5G(5300, 20), /* Channel 60 */
100 CHAN5G(5320, 21), /* Channel 64 */
101 /* _We_ call this "Middle band" */
102 CHAN5G(5500, 22), /* Channel 100 */
103 CHAN5G(5520, 23), /* Channel 104 */
104 CHAN5G(5540, 24), /* Channel 108 */
105 CHAN5G(5560, 25), /* Channel 112 */
106 CHAN5G(5580, 26), /* Channel 116 */
107 CHAN5G(5600, 27), /* Channel 120 */
108 CHAN5G(5620, 28), /* Channel 124 */
109 CHAN5G(5640, 29), /* Channel 128 */
110 CHAN5G(5660, 30), /* Channel 132 */
111 CHAN5G(5680, 31), /* Channel 136 */
112 CHAN5G(5700, 32), /* Channel 140 */
113 /* _We_ call this UNII 3 */
114 CHAN5G(5745, 33), /* Channel 149 */
115 CHAN5G(5765, 34), /* Channel 153 */
116 CHAN5G(5785, 35), /* Channel 157 */
117 CHAN5G(5805, 36), /* Channel 161 */
118 CHAN5G(5825, 37), /* Channel 165 */
119};
120
121/* Atheros hardware rate code addition for short premble */
122#define SHPCHECK(__hw_rate, __flags) \
123 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
124
125#define RATE(_bitrate, _hw_rate, _flags) { \
126 .bitrate = (_bitrate), \
127 .flags = (_flags), \
128 .hw_value = (_hw_rate), \
129 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
130}
131
132static struct ieee80211_rate ath9k_legacy_rates[] = {
133 RATE(10, 0x1b, 0),
134 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
135 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
136 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
137 RATE(60, 0x0b, 0),
138 RATE(90, 0x0f, 0),
139 RATE(120, 0x0a, 0),
140 RATE(180, 0x0e, 0),
141 RATE(240, 0x09, 0),
142 RATE(360, 0x0d, 0),
143 RATE(480, 0x08, 0),
144 RATE(540, 0x0c, 0),
145};
146
Sujith285f2dd2010-01-08 10:36:07 +0530147static void ath9k_deinit_softc(struct ath_softc *sc);
Sujith55624202010-01-08 10:36:02 +0530148
149/*
150 * Read and write, they both share the same lock. We do this to serialize
151 * reads and writes on Atheros 802.11n PCI devices only. This is required
152 * as the FIFO on these devices can only accept sanely 2 requests.
153 */
154
155static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
156{
157 struct ath_hw *ah = (struct ath_hw *) hw_priv;
158 struct ath_common *common = ath9k_hw_common(ah);
159 struct ath_softc *sc = (struct ath_softc *) common->priv;
160
161 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
162 unsigned long flags;
163 spin_lock_irqsave(&sc->sc_serial_rw, flags);
164 iowrite32(val, sc->mem + reg_offset);
165 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
166 } else
167 iowrite32(val, sc->mem + reg_offset);
168}
169
170static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
171{
172 struct ath_hw *ah = (struct ath_hw *) hw_priv;
173 struct ath_common *common = ath9k_hw_common(ah);
174 struct ath_softc *sc = (struct ath_softc *) common->priv;
175 u32 val;
176
177 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
178 unsigned long flags;
179 spin_lock_irqsave(&sc->sc_serial_rw, flags);
180 val = ioread32(sc->mem + reg_offset);
181 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
182 } else
183 val = ioread32(sc->mem + reg_offset);
184 return val;
185}
186
187static const struct ath_ops ath9k_common_ops = {
188 .read = ath9k_ioread32,
189 .write = ath9k_iowrite32,
190};
191
192/**************************/
193/* Initialization */
194/**************************/
195
196static void setup_ht_cap(struct ath_softc *sc,
197 struct ieee80211_sta_ht_cap *ht_info)
198{
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200199 struct ath_hw *ah = sc->sc_ah;
200 struct ath_common *common = ath9k_hw_common(ah);
Sujith55624202010-01-08 10:36:02 +0530201 u8 tx_streams, rx_streams;
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200202 int i, max_streams;
Sujith55624202010-01-08 10:36:02 +0530203
204 ht_info->ht_supported = true;
205 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
206 IEEE80211_HT_CAP_SM_PS |
207 IEEE80211_HT_CAP_SGI_40 |
208 IEEE80211_HT_CAP_DSSSCCK40;
209
Luis R. Rodriguezb0a33442010-04-15 17:39:39 -0400210 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
211 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
212
Vasanthakumar Thiagarajan6473d242010-05-13 18:42:38 -0700213 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
214 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
215
Sujith55624202010-01-08 10:36:02 +0530216 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
217 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
218
Vasanthakumar Thiagarajan7f1c7a62010-12-06 04:27:41 -0800219 if (AR_SREV_9485(ah))
220 max_streams = 1;
221 else if (AR_SREV_9300_20_OR_LATER(ah))
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200222 max_streams = 3;
223 else
224 max_streams = 2;
225
Felix Fietkau7a370812010-09-22 12:34:52 +0200226 if (AR_SREV_9280_20_OR_LATER(ah)) {
Felix Fietkau074a8c02010-04-19 19:57:36 +0200227 if (max_streams >= 2)
228 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
229 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
230 }
231
Sujith55624202010-01-08 10:36:02 +0530232 /* set up supported mcs set */
233 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
Sujith61389f32010-06-02 15:53:37 +0530234 tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
235 rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200236
Joe Perches226afe62010-12-02 19:12:37 -0800237 ath_dbg(common, ATH_DBG_CONFIG,
238 "TX streams %d, RX streams: %d\n",
239 tx_streams, rx_streams);
Sujith55624202010-01-08 10:36:02 +0530240
241 if (tx_streams != rx_streams) {
Sujith55624202010-01-08 10:36:02 +0530242 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
243 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
244 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
245 }
246
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200247 for (i = 0; i < rx_streams; i++)
248 ht_info->mcs.rx_mask[i] = 0xff;
Sujith55624202010-01-08 10:36:02 +0530249
250 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
251}
252
253static int ath9k_reg_notifier(struct wiphy *wiphy,
254 struct regulatory_request *request)
255{
256 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
257 struct ath_wiphy *aphy = hw->priv;
258 struct ath_softc *sc = aphy->sc;
259 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
260
261 return ath_reg_notifier_apply(wiphy, request, reg);
262}
263
264/*
265 * This function will allocate both the DMA descriptor structure, and the
266 * buffers it contains. These are used to contain the descriptors used
267 * by the system.
268*/
269int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
270 struct list_head *head, const char *name,
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400271 int nbuf, int ndesc, bool is_tx)
Sujith55624202010-01-08 10:36:02 +0530272{
273#define DS2PHYS(_dd, _ds) \
274 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
275#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
276#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
277 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400278 u8 *ds;
Sujith55624202010-01-08 10:36:02 +0530279 struct ath_buf *bf;
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400280 int i, bsize, error, desc_len;
Sujith55624202010-01-08 10:36:02 +0530281
Joe Perches226afe62010-12-02 19:12:37 -0800282 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
283 name, nbuf, ndesc);
Sujith55624202010-01-08 10:36:02 +0530284
285 INIT_LIST_HEAD(head);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400286
287 if (is_tx)
288 desc_len = sc->sc_ah->caps.tx_desc_len;
289 else
290 desc_len = sizeof(struct ath_desc);
291
Sujith55624202010-01-08 10:36:02 +0530292 /* ath_desc must be a multiple of DWORDs */
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400293 if ((desc_len % 4) != 0) {
Joe Perches38002762010-12-02 19:12:36 -0800294 ath_err(common, "ath_desc not DWORD aligned\n");
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400295 BUG_ON((desc_len % 4) != 0);
Sujith55624202010-01-08 10:36:02 +0530296 error = -ENOMEM;
297 goto fail;
298 }
299
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400300 dd->dd_desc_len = desc_len * nbuf * ndesc;
Sujith55624202010-01-08 10:36:02 +0530301
302 /*
303 * Need additional DMA memory because we can't use
304 * descriptors that cross the 4K page boundary. Assume
305 * one skipped descriptor per 4K page.
306 */
307 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
308 u32 ndesc_skipped =
309 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
310 u32 dma_len;
311
312 while (ndesc_skipped) {
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400313 dma_len = ndesc_skipped * desc_len;
Sujith55624202010-01-08 10:36:02 +0530314 dd->dd_desc_len += dma_len;
315
316 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
Joe Perchesee289b62010-05-17 22:47:34 -0700317 }
Sujith55624202010-01-08 10:36:02 +0530318 }
319
320 /* allocate descriptors */
321 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
322 &dd->dd_desc_paddr, GFP_KERNEL);
323 if (dd->dd_desc == NULL) {
324 error = -ENOMEM;
325 goto fail;
326 }
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400327 ds = (u8 *) dd->dd_desc;
Joe Perches226afe62010-12-02 19:12:37 -0800328 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
329 name, ds, (u32) dd->dd_desc_len,
330 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
Sujith55624202010-01-08 10:36:02 +0530331
332 /* allocate buffers */
333 bsize = sizeof(struct ath_buf) * nbuf;
334 bf = kzalloc(bsize, GFP_KERNEL);
335 if (bf == NULL) {
336 error = -ENOMEM;
337 goto fail2;
338 }
339 dd->dd_bufptr = bf;
340
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400341 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
Sujith55624202010-01-08 10:36:02 +0530342 bf->bf_desc = ds;
343 bf->bf_daddr = DS2PHYS(dd, ds);
344
345 if (!(sc->sc_ah->caps.hw_caps &
346 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
347 /*
348 * Skip descriptor addresses which can cause 4KB
349 * boundary crossing (addr + length) with a 32 dword
350 * descriptor fetch.
351 */
352 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
353 BUG_ON((caddr_t) bf->bf_desc >=
354 ((caddr_t) dd->dd_desc +
355 dd->dd_desc_len));
356
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400357 ds += (desc_len * ndesc);
Sujith55624202010-01-08 10:36:02 +0530358 bf->bf_desc = ds;
359 bf->bf_daddr = DS2PHYS(dd, ds);
360 }
361 }
362 list_add_tail(&bf->list, head);
363 }
364 return 0;
365fail2:
366 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
367 dd->dd_desc_paddr);
368fail:
369 memset(dd, 0, sizeof(*dd));
370 return error;
371#undef ATH_DESC_4KB_BOUND_CHECK
372#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
373#undef DS2PHYS
374}
375
Mohammed Shafi Shajakhandb7ec382010-12-22 12:20:12 +0530376void ath9k_init_crypto(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530377{
Sujith285f2dd2010-01-08 10:36:07 +0530378 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
379 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530380
381 /* Get the hardware key cache size. */
Sujith285f2dd2010-01-08 10:36:07 +0530382 common->keymax = sc->sc_ah->caps.keycache_size;
Sujith55624202010-01-08 10:36:02 +0530383 if (common->keymax > ATH_KEYMAX) {
Joe Perches226afe62010-12-02 19:12:37 -0800384 ath_dbg(common, ATH_DBG_ANY,
385 "Warning, using only %u entries in %u key cache\n",
386 ATH_KEYMAX, common->keymax);
Sujith55624202010-01-08 10:36:02 +0530387 common->keymax = ATH_KEYMAX;
388 }
389
390 /*
391 * Reset the key cache since some parts do not
392 * reset the contents on initial power up.
393 */
394 for (i = 0; i < common->keymax; i++)
Bruno Randolf040e5392010-09-08 16:05:04 +0900395 ath_hw_keyreset(common, (u16) i);
Sujith55624202010-01-08 10:36:02 +0530396
Felix Fietkau716f7fc2010-06-12 17:22:28 +0200397 /*
Sujith55624202010-01-08 10:36:02 +0530398 * Check whether the separate key cache entries
399 * are required to handle both tx+rx MIC keys.
400 * With split mic keys the number of stations is limited
401 * to 27 otherwise 59.
402 */
Bruno Randolf117675d2010-09-08 16:04:54 +0900403 if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
404 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
Sujith285f2dd2010-01-08 10:36:07 +0530405}
Sujith55624202010-01-08 10:36:02 +0530406
Sujith285f2dd2010-01-08 10:36:07 +0530407static int ath9k_init_btcoex(struct ath_softc *sc)
408{
Felix Fietkau066dae92010-11-07 14:59:39 +0100409 struct ath_txq *txq;
410 int r;
Sujith285f2dd2010-01-08 10:36:07 +0530411
412 switch (sc->sc_ah->btcoex_hw.scheme) {
413 case ATH_BTCOEX_CFG_NONE:
414 break;
415 case ATH_BTCOEX_CFG_2WIRE:
416 ath9k_hw_btcoex_init_2wire(sc->sc_ah);
417 break;
418 case ATH_BTCOEX_CFG_3WIRE:
419 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
420 r = ath_init_btcoex_timer(sc);
421 if (r)
422 return -1;
Felix Fietkau066dae92010-11-07 14:59:39 +0100423 txq = sc->tx.txq_map[WME_AC_BE];
424 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
Sujith285f2dd2010-01-08 10:36:07 +0530425 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
426 break;
427 default:
428 WARN_ON(1);
429 break;
Sujith55624202010-01-08 10:36:02 +0530430 }
431
Sujith285f2dd2010-01-08 10:36:07 +0530432 return 0;
433}
Sujith55624202010-01-08 10:36:02 +0530434
Sujith285f2dd2010-01-08 10:36:07 +0530435static int ath9k_init_queues(struct ath_softc *sc)
436{
Sujith285f2dd2010-01-08 10:36:07 +0530437 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530438
Sujith285f2dd2010-01-08 10:36:07 +0530439 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
Sujith285f2dd2010-01-08 10:36:07 +0530440 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
Sujith55624202010-01-08 10:36:02 +0530441
Sujith285f2dd2010-01-08 10:36:07 +0530442 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
443 ath_cabq_update(sc);
444
Ben Greear60f2d1d2011-01-09 23:11:52 -0800445 for (i = 0; i < WME_NUM_AC; i++) {
Felix Fietkau066dae92010-11-07 14:59:39 +0100446 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
Ben Greear60f2d1d2011-01-09 23:11:52 -0800447 sc->tx.txq_map[i]->mac80211_qnum = i;
448 }
Sujith285f2dd2010-01-08 10:36:07 +0530449 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530450}
451
Felix Fietkauf209f522010-10-01 01:06:53 +0200452static int ath9k_init_channels_rates(struct ath_softc *sc)
Sujith285f2dd2010-01-08 10:36:07 +0530453{
Felix Fietkauf209f522010-10-01 01:06:53 +0200454 void *channels;
455
Felix Fietkaucac42202010-10-09 02:39:30 +0200456 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
457 ARRAY_SIZE(ath9k_5ghz_chantable) !=
458 ATH9K_NUM_CHANNELS);
459
Felix Fietkaud4659912010-10-14 16:02:39 +0200460 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200461 channels = kmemdup(ath9k_2ghz_chantable,
462 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
463 if (!channels)
464 return -ENOMEM;
465
466 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530467 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
468 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
469 ARRAY_SIZE(ath9k_2ghz_chantable);
470 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
471 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
472 ARRAY_SIZE(ath9k_legacy_rates);
473 }
474
Felix Fietkaud4659912010-10-14 16:02:39 +0200475 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200476 channels = kmemdup(ath9k_5ghz_chantable,
477 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
478 if (!channels) {
479 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
480 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
481 return -ENOMEM;
482 }
483
484 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530485 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
486 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
487 ARRAY_SIZE(ath9k_5ghz_chantable);
488 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
489 ath9k_legacy_rates + 4;
490 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
491 ARRAY_SIZE(ath9k_legacy_rates) - 4;
492 }
Felix Fietkauf209f522010-10-01 01:06:53 +0200493 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530494}
Sujith55624202010-01-08 10:36:02 +0530495
Sujith285f2dd2010-01-08 10:36:07 +0530496static void ath9k_init_misc(struct ath_softc *sc)
497{
498 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
499 int i = 0;
500
Sujith285f2dd2010-01-08 10:36:07 +0530501 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
502
503 sc->config.txpowlimit = ATH_TXPOWER_MAX;
504
505 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
506 sc->sc_flags |= SC_OP_TXAGGR;
507 sc->sc_flags |= SC_OP_RXAGGR;
Sujith55624202010-01-08 10:36:02 +0530508 }
509
Sujith285f2dd2010-01-08 10:36:07 +0530510 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
511 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
512
Luis R. Rodriguez8fe65362010-04-15 17:38:14 -0400513 ath9k_hw_set_diversity(sc->sc_ah, true);
Sujith285f2dd2010-01-08 10:36:07 +0530514 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
515
Felix Fietkau364734f2010-09-14 20:22:44 +0200516 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
Sujith285f2dd2010-01-08 10:36:07 +0530517
518 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
519
520 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
521 sc->beacon.bslot[i] = NULL;
522 sc->beacon.bslot_aphy[i] = NULL;
523 }
Vasanthakumar Thiagarajan102885a2010-09-02 01:34:43 -0700524
525 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
526 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
Sujith285f2dd2010-01-08 10:36:07 +0530527}
528
529static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
530 const struct ath_bus_ops *bus_ops)
531{
532 struct ath_hw *ah = NULL;
533 struct ath_common *common;
534 int ret = 0, i;
535 int csz = 0;
536
Sujith285f2dd2010-01-08 10:36:07 +0530537 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
538 if (!ah)
539 return -ENOMEM;
540
Ben Greear233536e2011-01-09 23:11:44 -0800541 ah->hw = sc->hw;
Sujith285f2dd2010-01-08 10:36:07 +0530542 ah->hw_version.devid = devid;
543 ah->hw_version.subsysid = subsysid;
544 sc->sc_ah = ah;
545
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100546 if (!sc->dev->platform_data)
547 ah->ah_flags |= AH_USE_EEPROM;
548
Sujith285f2dd2010-01-08 10:36:07 +0530549 common = ath9k_hw_common(ah);
550 common->ops = &ath9k_common_ops;
551 common->bus_ops = bus_ops;
552 common->ah = ah;
553 common->hw = sc->hw;
554 common->priv = sc;
555 common->debug_mask = ath9k_debug;
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -0800556 common->btcoex_enabled = ath9k_btcoex_enable == 1;
Ben Greear20b257442010-10-15 15:04:09 -0700557 spin_lock_init(&common->cc_lock);
Sujith285f2dd2010-01-08 10:36:07 +0530558
559 spin_lock_init(&sc->wiphy_lock);
Sujith285f2dd2010-01-08 10:36:07 +0530560 spin_lock_init(&sc->sc_serial_rw);
561 spin_lock_init(&sc->sc_pm_lock);
562 mutex_init(&sc->mutex);
Ben Greear7f010c92011-01-09 23:11:49 -0800563#ifdef CONFIG_ATH9K_DEBUGFS
564 spin_lock_init(&sc->nodes_lock);
565 INIT_LIST_HEAD(&sc->nodes);
566#endif
Sujith285f2dd2010-01-08 10:36:07 +0530567 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
568 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
569 (unsigned long)sc);
570
571 /*
572 * Cache line size is used to size and align various
573 * structures used to communicate with the hardware.
574 */
575 ath_read_cachesize(common, &csz);
576 common->cachelsz = csz << 2; /* convert to bytes */
577
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400578 /* Initializes the hardware for all supported chipsets */
Sujith285f2dd2010-01-08 10:36:07 +0530579 ret = ath9k_hw_init(ah);
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400580 if (ret)
Sujith285f2dd2010-01-08 10:36:07 +0530581 goto err_hw;
Sujith285f2dd2010-01-08 10:36:07 +0530582
Sujith285f2dd2010-01-08 10:36:07 +0530583 ret = ath9k_init_queues(sc);
584 if (ret)
585 goto err_queues;
586
587 ret = ath9k_init_btcoex(sc);
588 if (ret)
589 goto err_btcoex;
590
Felix Fietkauf209f522010-10-01 01:06:53 +0200591 ret = ath9k_init_channels_rates(sc);
592 if (ret)
593 goto err_btcoex;
594
Sujith285f2dd2010-01-08 10:36:07 +0530595 ath9k_init_crypto(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530596 ath9k_init_misc(sc);
597
Sujith55624202010-01-08 10:36:02 +0530598 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530599
600err_btcoex:
Sujith55624202010-01-08 10:36:02 +0530601 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
602 if (ATH_TXQ_SETUP(sc, i))
603 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
Sujith285f2dd2010-01-08 10:36:07 +0530604err_queues:
Sujith285f2dd2010-01-08 10:36:07 +0530605 ath9k_hw_deinit(ah);
606err_hw:
607 tasklet_kill(&sc->intr_tq);
608 tasklet_kill(&sc->bcon_tasklet);
Sujith55624202010-01-08 10:36:02 +0530609
Sujith285f2dd2010-01-08 10:36:07 +0530610 kfree(ah);
611 sc->sc_ah = NULL;
612
613 return ret;
Sujith55624202010-01-08 10:36:02 +0530614}
615
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200616static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
617{
618 struct ieee80211_supported_band *sband;
619 struct ieee80211_channel *chan;
620 struct ath_hw *ah = sc->sc_ah;
621 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
622 int i;
623
624 sband = &sc->sbands[band];
625 for (i = 0; i < sband->n_channels; i++) {
626 chan = &sband->channels[i];
627 ah->curchan = &ah->channels[chan->hw_value];
628 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
629 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
630 chan->max_power = reg->max_power_level / 2;
631 }
632}
633
634static void ath9k_init_txpower_limits(struct ath_softc *sc)
635{
636 struct ath_hw *ah = sc->sc_ah;
637 struct ath9k_channel *curchan = ah->curchan;
638
639 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
640 ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
641 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
642 ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
643
644 ah->curchan = curchan;
645}
646
Sujith285f2dd2010-01-08 10:36:07 +0530647void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
Sujith55624202010-01-08 10:36:02 +0530648{
Sujith285f2dd2010-01-08 10:36:07 +0530649 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
650
Sujith55624202010-01-08 10:36:02 +0530651 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
652 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
653 IEEE80211_HW_SIGNAL_DBM |
Sujith55624202010-01-08 10:36:02 +0530654 IEEE80211_HW_SUPPORTS_PS |
655 IEEE80211_HW_PS_NULLFUNC_STACK |
Vivek Natarajan05df4982010-02-09 11:34:50 +0530656 IEEE80211_HW_SPECTRUM_MGMT |
Mohammed Shafi Shajakhanbd8027a2010-12-30 12:18:01 +0530657 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
Sujith55624202010-01-08 10:36:02 +0530658
Luis R. Rodriguez5ffaf8a2010-02-02 11:58:33 -0500659 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
660 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
661
John W. Linville3e6109c2011-01-05 09:39:17 -0500662 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
Sujith55624202010-01-08 10:36:02 +0530663 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
664
665 hw->wiphy->interface_modes =
Johannes Bergc426ee22010-11-26 11:38:04 +0100666 BIT(NL80211_IFTYPE_P2P_GO) |
667 BIT(NL80211_IFTYPE_P2P_CLIENT) |
Sujith55624202010-01-08 10:36:02 +0530668 BIT(NL80211_IFTYPE_AP) |
Bill Jordane51f3ef2010-10-01 11:20:39 -0400669 BIT(NL80211_IFTYPE_WDS) |
Sujith55624202010-01-08 10:36:02 +0530670 BIT(NL80211_IFTYPE_STATION) |
671 BIT(NL80211_IFTYPE_ADHOC) |
672 BIT(NL80211_IFTYPE_MESH_POINT);
673
Luis R. Rodriguez008443d2010-09-16 15:12:36 -0400674 if (AR_SREV_5416(sc->sc_ah))
675 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
Sujith55624202010-01-08 10:36:02 +0530676
677 hw->queues = 4;
678 hw->max_rates = 4;
679 hw->channel_change_time = 5000;
680 hw->max_listen_interval = 10;
Felix Fietkau65896512010-01-24 03:26:11 +0100681 hw->max_rate_tries = 10;
Sujith55624202010-01-08 10:36:02 +0530682 hw->sta_data_size = sizeof(struct ath_node);
683 hw->vif_data_size = sizeof(struct ath_vif);
684
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200685#ifdef CONFIG_ATH9K_RATE_CONTROL
Sujith55624202010-01-08 10:36:02 +0530686 hw->rate_control_algorithm = "ath9k_rate_control";
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200687#endif
Sujith55624202010-01-08 10:36:02 +0530688
Felix Fietkaud4659912010-10-14 16:02:39 +0200689 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith55624202010-01-08 10:36:02 +0530690 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
691 &sc->sbands[IEEE80211_BAND_2GHZ];
Felix Fietkaud4659912010-10-14 16:02:39 +0200692 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith55624202010-01-08 10:36:02 +0530693 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
694 &sc->sbands[IEEE80211_BAND_5GHZ];
Sujith285f2dd2010-01-08 10:36:07 +0530695
696 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
Felix Fietkaud4659912010-10-14 16:02:39 +0200697 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530698 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
Felix Fietkaud4659912010-10-14 16:02:39 +0200699 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530700 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
701 }
702
703 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
Sujith55624202010-01-08 10:36:02 +0530704}
705
Sujith285f2dd2010-01-08 10:36:07 +0530706int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
Sujith55624202010-01-08 10:36:02 +0530707 const struct ath_bus_ops *bus_ops)
708{
709 struct ieee80211_hw *hw = sc->hw;
Felix Fietkau9fa23e12010-10-15 20:03:31 +0200710 struct ath_wiphy *aphy = hw->priv;
Sujith55624202010-01-08 10:36:02 +0530711 struct ath_common *common;
712 struct ath_hw *ah;
Sujith285f2dd2010-01-08 10:36:07 +0530713 int error = 0;
Sujith55624202010-01-08 10:36:02 +0530714 struct ath_regulatory *reg;
715
Sujith285f2dd2010-01-08 10:36:07 +0530716 /* Bring up device */
717 error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
Sujith55624202010-01-08 10:36:02 +0530718 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530719 goto error_init;
Sujith55624202010-01-08 10:36:02 +0530720
721 ah = sc->sc_ah;
722 common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530723 ath9k_set_hw_capab(sc, hw);
Sujith55624202010-01-08 10:36:02 +0530724
Sujith285f2dd2010-01-08 10:36:07 +0530725 /* Initialize regulatory */
Sujith55624202010-01-08 10:36:02 +0530726 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
727 ath9k_reg_notifier);
728 if (error)
Sujith285f2dd2010-01-08 10:36:07 +0530729 goto error_regd;
Sujith55624202010-01-08 10:36:02 +0530730
731 reg = &common->regulatory;
732
Sujith285f2dd2010-01-08 10:36:07 +0530733 /* Setup TX DMA */
Sujith55624202010-01-08 10:36:02 +0530734 error = ath_tx_init(sc, ATH_TXBUF);
735 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530736 goto error_tx;
Sujith55624202010-01-08 10:36:02 +0530737
Sujith285f2dd2010-01-08 10:36:07 +0530738 /* Setup RX DMA */
Sujith55624202010-01-08 10:36:02 +0530739 error = ath_rx_init(sc, ATH_RXBUF);
740 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530741 goto error_rx;
742
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200743 ath9k_init_txpower_limits(sc);
744
Sujith285f2dd2010-01-08 10:36:07 +0530745 /* Register with mac80211 */
746 error = ieee80211_register_hw(hw);
747 if (error)
748 goto error_register;
749
Ben Greeareb272442010-11-29 14:13:22 -0800750 error = ath9k_init_debug(ah);
751 if (error) {
Joe Perches38002762010-12-02 19:12:36 -0800752 ath_err(common, "Unable to create debugfs files\n");
Ben Greeareb272442010-11-29 14:13:22 -0800753 goto error_world;
754 }
755
Sujith285f2dd2010-01-08 10:36:07 +0530756 /* Handle world regulatory */
757 if (!ath_is_world_regd(reg)) {
758 error = regulatory_hint(hw->wiphy, reg->alpha2);
759 if (error)
760 goto error_world;
761 }
Sujith55624202010-01-08 10:36:02 +0530762
Felix Fietkau347809f2010-07-02 00:09:52 +0200763 INIT_WORK(&sc->hw_check_work, ath_hw_check);
Felix Fietkau9f42c2b2010-06-12 00:34:01 -0400764 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
Sujith55624202010-01-08 10:36:02 +0530765 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
766 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
767 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
Felix Fietkau9fa23e12010-10-15 20:03:31 +0200768 aphy->last_rssi = ATH_RSSI_DUMMY_MARKER;
Sujith55624202010-01-08 10:36:02 +0530769
Sujith55624202010-01-08 10:36:02 +0530770 ath_init_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530771 ath_start_rfkill_poll(sc);
772
Gabor Juhos98c316e2010-11-25 18:26:07 +0100773 pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
Vivek Natarajan10598c12010-10-30 22:05:13 +0530774 PM_QOS_DEFAULT_VALUE);
775
Sujith55624202010-01-08 10:36:02 +0530776 return 0;
777
Sujith285f2dd2010-01-08 10:36:07 +0530778error_world:
779 ieee80211_unregister_hw(hw);
780error_register:
781 ath_rx_cleanup(sc);
782error_rx:
783 ath_tx_cleanup(sc);
784error_tx:
785 /* Nothing */
786error_regd:
787 ath9k_deinit_softc(sc);
788error_init:
Sujith55624202010-01-08 10:36:02 +0530789 return error;
790}
791
792/*****************************/
793/* De-Initialization */
794/*****************************/
795
Sujith285f2dd2010-01-08 10:36:07 +0530796static void ath9k_deinit_softc(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530797{
Sujith285f2dd2010-01-08 10:36:07 +0530798 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530799
Felix Fietkauf209f522010-10-01 01:06:53 +0200800 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
801 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
802
803 if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
804 kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
805
Sujith285f2dd2010-01-08 10:36:07 +0530806 if ((sc->btcoex.no_stomp_timer) &&
807 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
808 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
Sujith55624202010-01-08 10:36:02 +0530809
Sujith285f2dd2010-01-08 10:36:07 +0530810 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
811 if (ATH_TXQ_SETUP(sc, i))
812 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
813
Sujith285f2dd2010-01-08 10:36:07 +0530814 ath9k_hw_deinit(sc->sc_ah);
815
816 tasklet_kill(&sc->intr_tq);
817 tasklet_kill(&sc->bcon_tasklet);
Sujith736b3a22010-03-17 14:25:24 +0530818
819 kfree(sc->sc_ah);
820 sc->sc_ah = NULL;
Sujith55624202010-01-08 10:36:02 +0530821}
822
Sujith285f2dd2010-01-08 10:36:07 +0530823void ath9k_deinit_device(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530824{
825 struct ieee80211_hw *hw = sc->hw;
Sujith55624202010-01-08 10:36:02 +0530826 int i = 0;
827
828 ath9k_ps_wakeup(sc);
829
Sujith55624202010-01-08 10:36:02 +0530830 wiphy_rfkill_stop_polling(sc->hw->wiphy);
Sujith285f2dd2010-01-08 10:36:07 +0530831 ath_deinit_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530832
833 for (i = 0; i < sc->num_sec_wiphy; i++) {
834 struct ath_wiphy *aphy = sc->sec_wiphy[i];
835 if (aphy == NULL)
836 continue;
837 sc->sec_wiphy[i] = NULL;
838 ieee80211_unregister_hw(aphy->hw);
839 ieee80211_free_hw(aphy->hw);
840 }
Sujith285f2dd2010-01-08 10:36:07 +0530841
Sujith55624202010-01-08 10:36:02 +0530842 ieee80211_unregister_hw(hw);
Gabor Juhos98c316e2010-11-25 18:26:07 +0100843 pm_qos_remove_request(&sc->pm_qos_req);
Sujith55624202010-01-08 10:36:02 +0530844 ath_rx_cleanup(sc);
845 ath_tx_cleanup(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530846 ath9k_deinit_softc(sc);
Rajkumar Manoharan447a42c2010-07-08 12:12:29 +0530847 kfree(sc->sec_wiphy);
Sujith55624202010-01-08 10:36:02 +0530848}
849
850void ath_descdma_cleanup(struct ath_softc *sc,
851 struct ath_descdma *dd,
852 struct list_head *head)
853{
854 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
855 dd->dd_desc_paddr);
856
857 INIT_LIST_HEAD(head);
858 kfree(dd->dd_bufptr);
859 memset(dd, 0, sizeof(*dd));
860}
861
Sujith55624202010-01-08 10:36:02 +0530862/************************/
863/* Module Hooks */
864/************************/
865
866static int __init ath9k_init(void)
867{
868 int error;
869
870 /* Register rate control algorithm */
871 error = ath_rate_control_register();
872 if (error != 0) {
873 printk(KERN_ERR
874 "ath9k: Unable to register rate control "
875 "algorithm: %d\n",
876 error);
877 goto err_out;
878 }
879
Sujith55624202010-01-08 10:36:02 +0530880 error = ath_pci_init();
881 if (error < 0) {
882 printk(KERN_ERR
883 "ath9k: No PCI devices found, driver not installed.\n");
884 error = -ENODEV;
Ben Greeareb272442010-11-29 14:13:22 -0800885 goto err_rate_unregister;
Sujith55624202010-01-08 10:36:02 +0530886 }
887
888 error = ath_ahb_init();
889 if (error < 0) {
890 error = -ENODEV;
891 goto err_pci_exit;
892 }
893
894 return 0;
895
896 err_pci_exit:
897 ath_pci_exit();
898
Sujith55624202010-01-08 10:36:02 +0530899 err_rate_unregister:
900 ath_rate_control_unregister();
901 err_out:
902 return error;
903}
904module_init(ath9k_init);
905
906static void __exit ath9k_exit(void)
907{
Rajkumar Manoharand5847472010-12-20 14:39:51 +0530908 is_ath9k_unloaded = true;
Sujith55624202010-01-08 10:36:02 +0530909 ath_ahb_exit();
910 ath_pci_exit();
Sujith55624202010-01-08 10:36:02 +0530911 ath_rate_control_unregister();
912 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
913}
914module_exit(ath9k_exit);