blob: c1e15921906533d077494f2f3d885f33e4dfac39 [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);
Felix Fietkau9ac586152011-01-24 19:23:18 +0100257 struct ath_softc *sc = hw->priv;
Sujith55624202010-01-08 10:36:02 +0530258 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
259
260 return ath_reg_notifier_apply(wiphy, request, reg);
261}
262
263/*
264 * This function will allocate both the DMA descriptor structure, and the
265 * buffers it contains. These are used to contain the descriptors used
266 * by the system.
267*/
268int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
269 struct list_head *head, const char *name,
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400270 int nbuf, int ndesc, bool is_tx)
Sujith55624202010-01-08 10:36:02 +0530271{
272#define DS2PHYS(_dd, _ds) \
273 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
274#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
275#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
276 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400277 u8 *ds;
Sujith55624202010-01-08 10:36:02 +0530278 struct ath_buf *bf;
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400279 int i, bsize, error, desc_len;
Sujith55624202010-01-08 10:36:02 +0530280
Joe Perches226afe62010-12-02 19:12:37 -0800281 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
282 name, nbuf, ndesc);
Sujith55624202010-01-08 10:36:02 +0530283
284 INIT_LIST_HEAD(head);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400285
286 if (is_tx)
287 desc_len = sc->sc_ah->caps.tx_desc_len;
288 else
289 desc_len = sizeof(struct ath_desc);
290
Sujith55624202010-01-08 10:36:02 +0530291 /* ath_desc must be a multiple of DWORDs */
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400292 if ((desc_len % 4) != 0) {
Joe Perches38002762010-12-02 19:12:36 -0800293 ath_err(common, "ath_desc not DWORD aligned\n");
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400294 BUG_ON((desc_len % 4) != 0);
Sujith55624202010-01-08 10:36:02 +0530295 error = -ENOMEM;
296 goto fail;
297 }
298
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400299 dd->dd_desc_len = desc_len * nbuf * ndesc;
Sujith55624202010-01-08 10:36:02 +0530300
301 /*
302 * Need additional DMA memory because we can't use
303 * descriptors that cross the 4K page boundary. Assume
304 * one skipped descriptor per 4K page.
305 */
306 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
307 u32 ndesc_skipped =
308 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
309 u32 dma_len;
310
311 while (ndesc_skipped) {
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400312 dma_len = ndesc_skipped * desc_len;
Sujith55624202010-01-08 10:36:02 +0530313 dd->dd_desc_len += dma_len;
314
315 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
Joe Perchesee289b62010-05-17 22:47:34 -0700316 }
Sujith55624202010-01-08 10:36:02 +0530317 }
318
319 /* allocate descriptors */
320 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
321 &dd->dd_desc_paddr, GFP_KERNEL);
322 if (dd->dd_desc == NULL) {
323 error = -ENOMEM;
324 goto fail;
325 }
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400326 ds = (u8 *) dd->dd_desc;
Joe Perches226afe62010-12-02 19:12:37 -0800327 ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
328 name, ds, (u32) dd->dd_desc_len,
329 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
Sujith55624202010-01-08 10:36:02 +0530330
331 /* allocate buffers */
332 bsize = sizeof(struct ath_buf) * nbuf;
333 bf = kzalloc(bsize, GFP_KERNEL);
334 if (bf == NULL) {
335 error = -ENOMEM;
336 goto fail2;
337 }
338 dd->dd_bufptr = bf;
339
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400340 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
Sujith55624202010-01-08 10:36:02 +0530341 bf->bf_desc = ds;
342 bf->bf_daddr = DS2PHYS(dd, ds);
343
344 if (!(sc->sc_ah->caps.hw_caps &
345 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
346 /*
347 * Skip descriptor addresses which can cause 4KB
348 * boundary crossing (addr + length) with a 32 dword
349 * descriptor fetch.
350 */
351 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
352 BUG_ON((caddr_t) bf->bf_desc >=
353 ((caddr_t) dd->dd_desc +
354 dd->dd_desc_len));
355
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400356 ds += (desc_len * ndesc);
Sujith55624202010-01-08 10:36:02 +0530357 bf->bf_desc = ds;
358 bf->bf_daddr = DS2PHYS(dd, ds);
359 }
360 }
361 list_add_tail(&bf->list, head);
362 }
363 return 0;
364fail2:
365 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
366 dd->dd_desc_paddr);
367fail:
368 memset(dd, 0, sizeof(*dd));
369 return error;
370#undef ATH_DESC_4KB_BOUND_CHECK
371#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
372#undef DS2PHYS
373}
374
Mohammed Shafi Shajakhandb7ec382010-12-22 12:20:12 +0530375void ath9k_init_crypto(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530376{
Sujith285f2dd2010-01-08 10:36:07 +0530377 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
378 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530379
380 /* Get the hardware key cache size. */
Sujith285f2dd2010-01-08 10:36:07 +0530381 common->keymax = sc->sc_ah->caps.keycache_size;
Sujith55624202010-01-08 10:36:02 +0530382 if (common->keymax > ATH_KEYMAX) {
Joe Perches226afe62010-12-02 19:12:37 -0800383 ath_dbg(common, ATH_DBG_ANY,
384 "Warning, using only %u entries in %u key cache\n",
385 ATH_KEYMAX, common->keymax);
Sujith55624202010-01-08 10:36:02 +0530386 common->keymax = ATH_KEYMAX;
387 }
388
389 /*
390 * Reset the key cache since some parts do not
391 * reset the contents on initial power up.
392 */
393 for (i = 0; i < common->keymax; i++)
Bruno Randolf040e5392010-09-08 16:05:04 +0900394 ath_hw_keyreset(common, (u16) i);
Sujith55624202010-01-08 10:36:02 +0530395
Felix Fietkau716f7fc2010-06-12 17:22:28 +0200396 /*
Sujith55624202010-01-08 10:36:02 +0530397 * Check whether the separate key cache entries
398 * are required to handle both tx+rx MIC keys.
399 * With split mic keys the number of stations is limited
400 * to 27 otherwise 59.
401 */
Bruno Randolf117675d2010-09-08 16:04:54 +0900402 if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
403 common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
Sujith285f2dd2010-01-08 10:36:07 +0530404}
Sujith55624202010-01-08 10:36:02 +0530405
Sujith285f2dd2010-01-08 10:36:07 +0530406static int ath9k_init_btcoex(struct ath_softc *sc)
407{
Felix Fietkau066dae92010-11-07 14:59:39 +0100408 struct ath_txq *txq;
409 int r;
Sujith285f2dd2010-01-08 10:36:07 +0530410
411 switch (sc->sc_ah->btcoex_hw.scheme) {
412 case ATH_BTCOEX_CFG_NONE:
413 break;
414 case ATH_BTCOEX_CFG_2WIRE:
415 ath9k_hw_btcoex_init_2wire(sc->sc_ah);
416 break;
417 case ATH_BTCOEX_CFG_3WIRE:
418 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
419 r = ath_init_btcoex_timer(sc);
420 if (r)
421 return -1;
Felix Fietkau066dae92010-11-07 14:59:39 +0100422 txq = sc->tx.txq_map[WME_AC_BE];
423 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
Sujith285f2dd2010-01-08 10:36:07 +0530424 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
425 break;
426 default:
427 WARN_ON(1);
428 break;
Sujith55624202010-01-08 10:36:02 +0530429 }
430
Sujith285f2dd2010-01-08 10:36:07 +0530431 return 0;
432}
Sujith55624202010-01-08 10:36:02 +0530433
Sujith285f2dd2010-01-08 10:36:07 +0530434static int ath9k_init_queues(struct ath_softc *sc)
435{
Sujith285f2dd2010-01-08 10:36:07 +0530436 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530437
Sujith285f2dd2010-01-08 10:36:07 +0530438 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
Sujith285f2dd2010-01-08 10:36:07 +0530439 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
Sujith55624202010-01-08 10:36:02 +0530440
Sujith285f2dd2010-01-08 10:36:07 +0530441 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
442 ath_cabq_update(sc);
443
Ben Greear60f2d1d2011-01-09 23:11:52 -0800444 for (i = 0; i < WME_NUM_AC; i++) {
Felix Fietkau066dae92010-11-07 14:59:39 +0100445 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
Ben Greear60f2d1d2011-01-09 23:11:52 -0800446 sc->tx.txq_map[i]->mac80211_qnum = i;
447 }
Sujith285f2dd2010-01-08 10:36:07 +0530448 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530449}
450
Felix Fietkauf209f522010-10-01 01:06:53 +0200451static int ath9k_init_channels_rates(struct ath_softc *sc)
Sujith285f2dd2010-01-08 10:36:07 +0530452{
Felix Fietkauf209f522010-10-01 01:06:53 +0200453 void *channels;
454
Felix Fietkaucac42202010-10-09 02:39:30 +0200455 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
456 ARRAY_SIZE(ath9k_5ghz_chantable) !=
457 ATH9K_NUM_CHANNELS);
458
Felix Fietkaud4659912010-10-14 16:02:39 +0200459 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200460 channels = kmemdup(ath9k_2ghz_chantable,
461 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
462 if (!channels)
463 return -ENOMEM;
464
465 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530466 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
467 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
468 ARRAY_SIZE(ath9k_2ghz_chantable);
469 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
470 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
471 ARRAY_SIZE(ath9k_legacy_rates);
472 }
473
Felix Fietkaud4659912010-10-14 16:02:39 +0200474 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
Felix Fietkauf209f522010-10-01 01:06:53 +0200475 channels = kmemdup(ath9k_5ghz_chantable,
476 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
477 if (!channels) {
478 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
479 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
480 return -ENOMEM;
481 }
482
483 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530484 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
485 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
486 ARRAY_SIZE(ath9k_5ghz_chantable);
487 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
488 ath9k_legacy_rates + 4;
489 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
490 ARRAY_SIZE(ath9k_legacy_rates) - 4;
491 }
Felix Fietkauf209f522010-10-01 01:06:53 +0200492 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530493}
Sujith55624202010-01-08 10:36:02 +0530494
Sujith285f2dd2010-01-08 10:36:07 +0530495static void ath9k_init_misc(struct ath_softc *sc)
496{
497 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
498 int i = 0;
499
Sujith285f2dd2010-01-08 10:36:07 +0530500 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
501
502 sc->config.txpowlimit = ATH_TXPOWER_MAX;
503
504 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
505 sc->sc_flags |= SC_OP_TXAGGR;
506 sc->sc_flags |= SC_OP_RXAGGR;
Sujith55624202010-01-08 10:36:02 +0530507 }
508
Sujith285f2dd2010-01-08 10:36:07 +0530509 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
510 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
511
Luis R. Rodriguez8fe65362010-04-15 17:38:14 -0400512 ath9k_hw_set_diversity(sc->sc_ah, true);
Sujith285f2dd2010-01-08 10:36:07 +0530513 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
514
Felix Fietkau364734f2010-09-14 20:22:44 +0200515 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
Sujith285f2dd2010-01-08 10:36:07 +0530516
517 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
518
Felix Fietkau7545daf2011-01-24 19:23:16 +0100519 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
Sujith285f2dd2010-01-08 10:36:07 +0530520 sc->beacon.bslot[i] = NULL;
Vasanthakumar Thiagarajan102885a2010-09-02 01:34:43 -0700521
522 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
523 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
Sujith285f2dd2010-01-08 10:36:07 +0530524}
525
526static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
527 const struct ath_bus_ops *bus_ops)
528{
529 struct ath_hw *ah = NULL;
530 struct ath_common *common;
531 int ret = 0, i;
532 int csz = 0;
533
Sujith285f2dd2010-01-08 10:36:07 +0530534 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
535 if (!ah)
536 return -ENOMEM;
537
Ben Greear233536e2011-01-09 23:11:44 -0800538 ah->hw = sc->hw;
Sujith285f2dd2010-01-08 10:36:07 +0530539 ah->hw_version.devid = devid;
540 ah->hw_version.subsysid = subsysid;
541 sc->sc_ah = ah;
542
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100543 if (!sc->dev->platform_data)
544 ah->ah_flags |= AH_USE_EEPROM;
545
Sujith285f2dd2010-01-08 10:36:07 +0530546 common = ath9k_hw_common(ah);
547 common->ops = &ath9k_common_ops;
548 common->bus_ops = bus_ops;
549 common->ah = ah;
550 common->hw = sc->hw;
551 common->priv = sc;
552 common->debug_mask = ath9k_debug;
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -0800553 common->btcoex_enabled = ath9k_btcoex_enable == 1;
Ben Greear20b257442010-10-15 15:04:09 -0700554 spin_lock_init(&common->cc_lock);
Sujith285f2dd2010-01-08 10:36:07 +0530555
Sujith285f2dd2010-01-08 10:36:07 +0530556 spin_lock_init(&sc->sc_serial_rw);
557 spin_lock_init(&sc->sc_pm_lock);
558 mutex_init(&sc->mutex);
Ben Greear7f010c92011-01-09 23:11:49 -0800559#ifdef CONFIG_ATH9K_DEBUGFS
560 spin_lock_init(&sc->nodes_lock);
561 INIT_LIST_HEAD(&sc->nodes);
562#endif
Sujith285f2dd2010-01-08 10:36:07 +0530563 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
564 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
565 (unsigned long)sc);
566
567 /*
568 * Cache line size is used to size and align various
569 * structures used to communicate with the hardware.
570 */
571 ath_read_cachesize(common, &csz);
572 common->cachelsz = csz << 2; /* convert to bytes */
573
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400574 /* Initializes the hardware for all supported chipsets */
Sujith285f2dd2010-01-08 10:36:07 +0530575 ret = ath9k_hw_init(ah);
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400576 if (ret)
Sujith285f2dd2010-01-08 10:36:07 +0530577 goto err_hw;
Sujith285f2dd2010-01-08 10:36:07 +0530578
Sujith285f2dd2010-01-08 10:36:07 +0530579 ret = ath9k_init_queues(sc);
580 if (ret)
581 goto err_queues;
582
583 ret = ath9k_init_btcoex(sc);
584 if (ret)
585 goto err_btcoex;
586
Felix Fietkauf209f522010-10-01 01:06:53 +0200587 ret = ath9k_init_channels_rates(sc);
588 if (ret)
589 goto err_btcoex;
590
Sujith285f2dd2010-01-08 10:36:07 +0530591 ath9k_init_crypto(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530592 ath9k_init_misc(sc);
593
Sujith55624202010-01-08 10:36:02 +0530594 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530595
596err_btcoex:
Sujith55624202010-01-08 10:36:02 +0530597 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
598 if (ATH_TXQ_SETUP(sc, i))
599 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
Sujith285f2dd2010-01-08 10:36:07 +0530600err_queues:
Sujith285f2dd2010-01-08 10:36:07 +0530601 ath9k_hw_deinit(ah);
602err_hw:
603 tasklet_kill(&sc->intr_tq);
604 tasklet_kill(&sc->bcon_tasklet);
Sujith55624202010-01-08 10:36:02 +0530605
Sujith285f2dd2010-01-08 10:36:07 +0530606 kfree(ah);
607 sc->sc_ah = NULL;
608
609 return ret;
Sujith55624202010-01-08 10:36:02 +0530610}
611
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200612static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
613{
614 struct ieee80211_supported_band *sband;
615 struct ieee80211_channel *chan;
616 struct ath_hw *ah = sc->sc_ah;
617 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
618 int i;
619
620 sband = &sc->sbands[band];
621 for (i = 0; i < sband->n_channels; i++) {
622 chan = &sband->channels[i];
623 ah->curchan = &ah->channels[chan->hw_value];
624 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
625 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
626 chan->max_power = reg->max_power_level / 2;
627 }
628}
629
630static void ath9k_init_txpower_limits(struct ath_softc *sc)
631{
632 struct ath_hw *ah = sc->sc_ah;
633 struct ath9k_channel *curchan = ah->curchan;
634
635 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
636 ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
637 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
638 ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
639
640 ah->curchan = curchan;
641}
642
Sujith285f2dd2010-01-08 10:36:07 +0530643void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
Sujith55624202010-01-08 10:36:02 +0530644{
Sujith285f2dd2010-01-08 10:36:07 +0530645 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
646
Sujith55624202010-01-08 10:36:02 +0530647 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
648 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
649 IEEE80211_HW_SIGNAL_DBM |
Sujith55624202010-01-08 10:36:02 +0530650 IEEE80211_HW_SUPPORTS_PS |
651 IEEE80211_HW_PS_NULLFUNC_STACK |
Vivek Natarajan05df4982010-02-09 11:34:50 +0530652 IEEE80211_HW_SPECTRUM_MGMT |
Mohammed Shafi Shajakhanbd8027a2010-12-30 12:18:01 +0530653 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
Sujith55624202010-01-08 10:36:02 +0530654
Luis R. Rodriguez5ffaf8a2010-02-02 11:58:33 -0500655 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
656 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
657
John W. Linville3e6109c2011-01-05 09:39:17 -0500658 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
Sujith55624202010-01-08 10:36:02 +0530659 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
660
661 hw->wiphy->interface_modes =
Johannes Bergc426ee22010-11-26 11:38:04 +0100662 BIT(NL80211_IFTYPE_P2P_GO) |
663 BIT(NL80211_IFTYPE_P2P_CLIENT) |
Sujith55624202010-01-08 10:36:02 +0530664 BIT(NL80211_IFTYPE_AP) |
Bill Jordane51f3ef2010-10-01 11:20:39 -0400665 BIT(NL80211_IFTYPE_WDS) |
Sujith55624202010-01-08 10:36:02 +0530666 BIT(NL80211_IFTYPE_STATION) |
667 BIT(NL80211_IFTYPE_ADHOC) |
668 BIT(NL80211_IFTYPE_MESH_POINT);
669
Luis R. Rodriguez008443d2010-09-16 15:12:36 -0400670 if (AR_SREV_5416(sc->sc_ah))
671 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
Sujith55624202010-01-08 10:36:02 +0530672
673 hw->queues = 4;
674 hw->max_rates = 4;
675 hw->channel_change_time = 5000;
676 hw->max_listen_interval = 10;
Felix Fietkau65896512010-01-24 03:26:11 +0100677 hw->max_rate_tries = 10;
Sujith55624202010-01-08 10:36:02 +0530678 hw->sta_data_size = sizeof(struct ath_node);
679 hw->vif_data_size = sizeof(struct ath_vif);
680
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200681#ifdef CONFIG_ATH9K_RATE_CONTROL
Sujith55624202010-01-08 10:36:02 +0530682 hw->rate_control_algorithm = "ath9k_rate_control";
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200683#endif
Sujith55624202010-01-08 10:36:02 +0530684
Felix Fietkaud4659912010-10-14 16:02:39 +0200685 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith55624202010-01-08 10:36:02 +0530686 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
687 &sc->sbands[IEEE80211_BAND_2GHZ];
Felix Fietkaud4659912010-10-14 16:02:39 +0200688 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith55624202010-01-08 10:36:02 +0530689 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
690 &sc->sbands[IEEE80211_BAND_5GHZ];
Sujith285f2dd2010-01-08 10:36:07 +0530691
692 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
Felix Fietkaud4659912010-10-14 16:02:39 +0200693 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530694 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
Felix Fietkaud4659912010-10-14 16:02:39 +0200695 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith285f2dd2010-01-08 10:36:07 +0530696 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
697 }
698
699 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
Sujith55624202010-01-08 10:36:02 +0530700}
701
Sujith285f2dd2010-01-08 10:36:07 +0530702int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
Sujith55624202010-01-08 10:36:02 +0530703 const struct ath_bus_ops *bus_ops)
704{
705 struct ieee80211_hw *hw = sc->hw;
706 struct ath_common *common;
707 struct ath_hw *ah;
Sujith285f2dd2010-01-08 10:36:07 +0530708 int error = 0;
Sujith55624202010-01-08 10:36:02 +0530709 struct ath_regulatory *reg;
710
Sujith285f2dd2010-01-08 10:36:07 +0530711 /* Bring up device */
712 error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
Sujith55624202010-01-08 10:36:02 +0530713 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530714 goto error_init;
Sujith55624202010-01-08 10:36:02 +0530715
716 ah = sc->sc_ah;
717 common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530718 ath9k_set_hw_capab(sc, hw);
Sujith55624202010-01-08 10:36:02 +0530719
Sujith285f2dd2010-01-08 10:36:07 +0530720 /* Initialize regulatory */
Sujith55624202010-01-08 10:36:02 +0530721 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
722 ath9k_reg_notifier);
723 if (error)
Sujith285f2dd2010-01-08 10:36:07 +0530724 goto error_regd;
Sujith55624202010-01-08 10:36:02 +0530725
726 reg = &common->regulatory;
727
Sujith285f2dd2010-01-08 10:36:07 +0530728 /* Setup TX DMA */
Sujith55624202010-01-08 10:36:02 +0530729 error = ath_tx_init(sc, ATH_TXBUF);
730 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530731 goto error_tx;
Sujith55624202010-01-08 10:36:02 +0530732
Sujith285f2dd2010-01-08 10:36:07 +0530733 /* Setup RX DMA */
Sujith55624202010-01-08 10:36:02 +0530734 error = ath_rx_init(sc, ATH_RXBUF);
735 if (error != 0)
Sujith285f2dd2010-01-08 10:36:07 +0530736 goto error_rx;
737
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200738 ath9k_init_txpower_limits(sc);
739
Sujith285f2dd2010-01-08 10:36:07 +0530740 /* Register with mac80211 */
741 error = ieee80211_register_hw(hw);
742 if (error)
743 goto error_register;
744
Ben Greeareb272442010-11-29 14:13:22 -0800745 error = ath9k_init_debug(ah);
746 if (error) {
Joe Perches38002762010-12-02 19:12:36 -0800747 ath_err(common, "Unable to create debugfs files\n");
Ben Greeareb272442010-11-29 14:13:22 -0800748 goto error_world;
749 }
750
Sujith285f2dd2010-01-08 10:36:07 +0530751 /* Handle world regulatory */
752 if (!ath_is_world_regd(reg)) {
753 error = regulatory_hint(hw->wiphy, reg->alpha2);
754 if (error)
755 goto error_world;
756 }
Sujith55624202010-01-08 10:36:02 +0530757
Felix Fietkau347809f2010-07-02 00:09:52 +0200758 INIT_WORK(&sc->hw_check_work, ath_hw_check);
Felix Fietkau9f42c2b2010-06-12 00:34:01 -0400759 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
Felix Fietkau9ac586152011-01-24 19:23:18 +0100760 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
Sujith55624202010-01-08 10:36:02 +0530761
Sujith55624202010-01-08 10:36:02 +0530762 ath_init_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530763 ath_start_rfkill_poll(sc);
764
Gabor Juhos98c316e2010-11-25 18:26:07 +0100765 pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
Vivek Natarajan10598c12010-10-30 22:05:13 +0530766 PM_QOS_DEFAULT_VALUE);
767
Sujith55624202010-01-08 10:36:02 +0530768 return 0;
769
Sujith285f2dd2010-01-08 10:36:07 +0530770error_world:
771 ieee80211_unregister_hw(hw);
772error_register:
773 ath_rx_cleanup(sc);
774error_rx:
775 ath_tx_cleanup(sc);
776error_tx:
777 /* Nothing */
778error_regd:
779 ath9k_deinit_softc(sc);
780error_init:
Sujith55624202010-01-08 10:36:02 +0530781 return error;
782}
783
784/*****************************/
785/* De-Initialization */
786/*****************************/
787
Sujith285f2dd2010-01-08 10:36:07 +0530788static void ath9k_deinit_softc(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530789{
Sujith285f2dd2010-01-08 10:36:07 +0530790 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530791
Felix Fietkauf209f522010-10-01 01:06:53 +0200792 if (sc->sbands[IEEE80211_BAND_2GHZ].channels)
793 kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels);
794
795 if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
796 kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
797
Sujith285f2dd2010-01-08 10:36:07 +0530798 if ((sc->btcoex.no_stomp_timer) &&
799 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
800 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
Sujith55624202010-01-08 10:36:02 +0530801
Sujith285f2dd2010-01-08 10:36:07 +0530802 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
803 if (ATH_TXQ_SETUP(sc, i))
804 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
805
Sujith285f2dd2010-01-08 10:36:07 +0530806 ath9k_hw_deinit(sc->sc_ah);
807
808 tasklet_kill(&sc->intr_tq);
809 tasklet_kill(&sc->bcon_tasklet);
Sujith736b3a22010-03-17 14:25:24 +0530810
811 kfree(sc->sc_ah);
812 sc->sc_ah = NULL;
Sujith55624202010-01-08 10:36:02 +0530813}
814
Sujith285f2dd2010-01-08 10:36:07 +0530815void ath9k_deinit_device(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530816{
817 struct ieee80211_hw *hw = sc->hw;
Sujith55624202010-01-08 10:36:02 +0530818
819 ath9k_ps_wakeup(sc);
820
Sujith55624202010-01-08 10:36:02 +0530821 wiphy_rfkill_stop_polling(sc->hw->wiphy);
Sujith285f2dd2010-01-08 10:36:07 +0530822 ath_deinit_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530823
Sujith55624202010-01-08 10:36:02 +0530824 ieee80211_unregister_hw(hw);
Gabor Juhos98c316e2010-11-25 18:26:07 +0100825 pm_qos_remove_request(&sc->pm_qos_req);
Sujith55624202010-01-08 10:36:02 +0530826 ath_rx_cleanup(sc);
827 ath_tx_cleanup(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530828 ath9k_deinit_softc(sc);
Sujith55624202010-01-08 10:36:02 +0530829}
830
831void ath_descdma_cleanup(struct ath_softc *sc,
832 struct ath_descdma *dd,
833 struct list_head *head)
834{
835 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
836 dd->dd_desc_paddr);
837
838 INIT_LIST_HEAD(head);
839 kfree(dd->dd_bufptr);
840 memset(dd, 0, sizeof(*dd));
841}
842
Sujith55624202010-01-08 10:36:02 +0530843/************************/
844/* Module Hooks */
845/************************/
846
847static int __init ath9k_init(void)
848{
849 int error;
850
851 /* Register rate control algorithm */
852 error = ath_rate_control_register();
853 if (error != 0) {
854 printk(KERN_ERR
855 "ath9k: Unable to register rate control "
856 "algorithm: %d\n",
857 error);
858 goto err_out;
859 }
860
Sujith55624202010-01-08 10:36:02 +0530861 error = ath_pci_init();
862 if (error < 0) {
863 printk(KERN_ERR
864 "ath9k: No PCI devices found, driver not installed.\n");
865 error = -ENODEV;
Ben Greeareb272442010-11-29 14:13:22 -0800866 goto err_rate_unregister;
Sujith55624202010-01-08 10:36:02 +0530867 }
868
869 error = ath_ahb_init();
870 if (error < 0) {
871 error = -ENODEV;
872 goto err_pci_exit;
873 }
874
875 return 0;
876
877 err_pci_exit:
878 ath_pci_exit();
879
Sujith55624202010-01-08 10:36:02 +0530880 err_rate_unregister:
881 ath_rate_control_unregister();
882 err_out:
883 return error;
884}
885module_init(ath9k_init);
886
887static void __exit ath9k_exit(void)
888{
Rajkumar Manoharand5847472010-12-20 14:39:51 +0530889 is_ath9k_unloaded = true;
Sujith55624202010-01-08 10:36:02 +0530890 ath_ahb_exit();
891 ath_pci_exit();
Sujith55624202010-01-08 10:36:02 +0530892 ath_rate_control_unregister();
893 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
894}
895module_exit(ath9k_exit);