blob: 0f00a1306ac0f4b9ec78e08d13e1849c1c0b4817 [file] [log] [blame]
Sujith55624202010-01-08 10:36:02 +05301/*
Sujith Manoharan5b681382011-05-17 13:36:18 +05302 * Copyright (c) 2008-2011 Atheros Communications Inc.
Sujith55624202010-01-08 10:36:02 +05303 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
Joe Perches516304b2012-03-18 17:30:52 -070017#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
Alexey Dobriyanb7f080c2011-06-16 11:01:34 +000019#include <linux/dma-mapping.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090020#include <linux/slab.h>
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +010021#include <linux/ath9k_platform.h>
Paul Gortmaker9d9779e2011-07-03 15:21:01 -040022#include <linux/module.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090023
Sujith55624202010-01-08 10:36:02 +053024#include "ath9k.h"
25
Gabor Juhosab5c4f72012-12-10 15:30:28 +010026struct ath9k_eeprom_ctx {
27 struct completion complete;
28 struct ath_hw *ah;
29};
30
Sujith55624202010-01-08 10:36:02 +053031static char *dev_info = "ath9k";
32
33MODULE_AUTHOR("Atheros Communications");
34MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
35MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
36MODULE_LICENSE("Dual BSD/GPL");
37
38static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
39module_param_named(debug, ath9k_debug, uint, 0);
40MODULE_PARM_DESC(debug, "Debugging mask");
41
John W. Linville3e6109c2011-01-05 09:39:17 -050042int ath9k_modparam_nohwcrypt;
43module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
Sujith55624202010-01-08 10:36:02 +053044MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
45
Vivek Natarajan93dbbcc2010-08-25 19:34:52 +053046int led_blink;
Vivek Natarajan9a75c2f2010-06-22 11:52:37 +053047module_param_named(blink, led_blink, int, 0444);
48MODULE_PARM_DESC(blink, "Enable LED blink on activity");
49
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -080050static int ath9k_btcoex_enable;
51module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
52MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
53
Sujith Manoharane09f2dc2012-09-16 08:06:56 +053054static int ath9k_enable_diversity;
55module_param_named(enable_diversity, ath9k_enable_diversity, int, 0444);
56MODULE_PARM_DESC(enable_diversity, "Enable Antenna diversity for AR9565");
57
Rajkumar Manoharand5847472010-12-20 14:39:51 +053058bool is_ath9k_unloaded;
Sujith55624202010-01-08 10:36:02 +053059/* We use the hw_value as an index into our private channel structure */
60
61#define CHAN2G(_freq, _idx) { \
Mohammed Shafi Shajakhanb1c1d002010-12-17 20:44:36 +053062 .band = IEEE80211_BAND_2GHZ, \
Sujith55624202010-01-08 10:36:02 +053063 .center_freq = (_freq), \
64 .hw_value = (_idx), \
65 .max_power = 20, \
66}
67
68#define CHAN5G(_freq, _idx) { \
69 .band = IEEE80211_BAND_5GHZ, \
70 .center_freq = (_freq), \
71 .hw_value = (_idx), \
72 .max_power = 20, \
73}
74
75/* Some 2 GHz radios are actually tunable on 2312-2732
76 * on 5 MHz steps, we support the channels which we know
77 * we have calibration data for all cards though to make
78 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +020079static const struct ieee80211_channel ath9k_2ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +053080 CHAN2G(2412, 0), /* Channel 1 */
81 CHAN2G(2417, 1), /* Channel 2 */
82 CHAN2G(2422, 2), /* Channel 3 */
83 CHAN2G(2427, 3), /* Channel 4 */
84 CHAN2G(2432, 4), /* Channel 5 */
85 CHAN2G(2437, 5), /* Channel 6 */
86 CHAN2G(2442, 6), /* Channel 7 */
87 CHAN2G(2447, 7), /* Channel 8 */
88 CHAN2G(2452, 8), /* Channel 9 */
89 CHAN2G(2457, 9), /* Channel 10 */
90 CHAN2G(2462, 10), /* Channel 11 */
91 CHAN2G(2467, 11), /* Channel 12 */
92 CHAN2G(2472, 12), /* Channel 13 */
93 CHAN2G(2484, 13), /* Channel 14 */
94};
95
96/* Some 5 GHz radios are actually tunable on XXXX-YYYY
97 * on 5 MHz steps, we support the channels which we know
98 * we have calibration data for all cards though to make
99 * this static */
Felix Fietkauf209f522010-10-01 01:06:53 +0200100static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
Sujith55624202010-01-08 10:36:02 +0530101 /* _We_ call this UNII 1 */
102 CHAN5G(5180, 14), /* Channel 36 */
103 CHAN5G(5200, 15), /* Channel 40 */
104 CHAN5G(5220, 16), /* Channel 44 */
105 CHAN5G(5240, 17), /* Channel 48 */
106 /* _We_ call this UNII 2 */
107 CHAN5G(5260, 18), /* Channel 52 */
108 CHAN5G(5280, 19), /* Channel 56 */
109 CHAN5G(5300, 20), /* Channel 60 */
110 CHAN5G(5320, 21), /* Channel 64 */
111 /* _We_ call this "Middle band" */
112 CHAN5G(5500, 22), /* Channel 100 */
113 CHAN5G(5520, 23), /* Channel 104 */
114 CHAN5G(5540, 24), /* Channel 108 */
115 CHAN5G(5560, 25), /* Channel 112 */
116 CHAN5G(5580, 26), /* Channel 116 */
117 CHAN5G(5600, 27), /* Channel 120 */
118 CHAN5G(5620, 28), /* Channel 124 */
119 CHAN5G(5640, 29), /* Channel 128 */
120 CHAN5G(5660, 30), /* Channel 132 */
121 CHAN5G(5680, 31), /* Channel 136 */
122 CHAN5G(5700, 32), /* Channel 140 */
123 /* _We_ call this UNII 3 */
124 CHAN5G(5745, 33), /* Channel 149 */
125 CHAN5G(5765, 34), /* Channel 153 */
126 CHAN5G(5785, 35), /* Channel 157 */
127 CHAN5G(5805, 36), /* Channel 161 */
128 CHAN5G(5825, 37), /* Channel 165 */
129};
130
131/* Atheros hardware rate code addition for short premble */
132#define SHPCHECK(__hw_rate, __flags) \
133 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
134
135#define RATE(_bitrate, _hw_rate, _flags) { \
136 .bitrate = (_bitrate), \
137 .flags = (_flags), \
138 .hw_value = (_hw_rate), \
139 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
140}
141
142static struct ieee80211_rate ath9k_legacy_rates[] = {
143 RATE(10, 0x1b, 0),
144 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
145 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
146 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
147 RATE(60, 0x0b, 0),
148 RATE(90, 0x0f, 0),
149 RATE(120, 0x0a, 0),
150 RATE(180, 0x0e, 0),
151 RATE(240, 0x09, 0),
152 RATE(360, 0x0d, 0),
153 RATE(480, 0x08, 0),
154 RATE(540, 0x0c, 0),
155};
156
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100157#ifdef CONFIG_MAC80211_LEDS
158static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
159 { .throughput = 0 * 1024, .blink_time = 334 },
160 { .throughput = 1 * 1024, .blink_time = 260 },
161 { .throughput = 5 * 1024, .blink_time = 220 },
162 { .throughput = 10 * 1024, .blink_time = 190 },
163 { .throughput = 20 * 1024, .blink_time = 170 },
164 { .throughput = 50 * 1024, .blink_time = 150 },
165 { .throughput = 70 * 1024, .blink_time = 130 },
166 { .throughput = 100 * 1024, .blink_time = 110 },
167 { .throughput = 200 * 1024, .blink_time = 80 },
168 { .throughput = 300 * 1024, .blink_time = 50 },
169};
170#endif
171
Sujith285f2dd2010-01-08 10:36:07 +0530172static void ath9k_deinit_softc(struct ath_softc *sc);
Sujith55624202010-01-08 10:36:02 +0530173
174/*
175 * Read and write, they both share the same lock. We do this to serialize
176 * reads and writes on Atheros 802.11n PCI devices only. This is required
177 * as the FIFO on these devices can only accept sanely 2 requests.
178 */
179
180static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
181{
182 struct ath_hw *ah = (struct ath_hw *) hw_priv;
183 struct ath_common *common = ath9k_hw_common(ah);
184 struct ath_softc *sc = (struct ath_softc *) common->priv;
185
Felix Fietkauf3eef642012-03-14 16:40:25 +0100186 if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
Sujith55624202010-01-08 10:36:02 +0530187 unsigned long flags;
188 spin_lock_irqsave(&sc->sc_serial_rw, flags);
189 iowrite32(val, sc->mem + reg_offset);
190 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
191 } else
192 iowrite32(val, sc->mem + reg_offset);
193}
194
195static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
196{
197 struct ath_hw *ah = (struct ath_hw *) hw_priv;
198 struct ath_common *common = ath9k_hw_common(ah);
199 struct ath_softc *sc = (struct ath_softc *) common->priv;
200 u32 val;
201
Felix Fietkauf3eef642012-03-14 16:40:25 +0100202 if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
Sujith55624202010-01-08 10:36:02 +0530203 unsigned long flags;
204 spin_lock_irqsave(&sc->sc_serial_rw, flags);
205 val = ioread32(sc->mem + reg_offset);
206 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
207 } else
208 val = ioread32(sc->mem + reg_offset);
209 return val;
210}
211
Rajkumar Manoharan5479de62011-07-17 11:43:02 +0530212static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset,
213 u32 set, u32 clr)
214{
215 u32 val;
216
217 val = ioread32(sc->mem + reg_offset);
218 val &= ~clr;
219 val |= set;
220 iowrite32(val, sc->mem + reg_offset);
221
222 return val;
223}
224
Felix Fietkau845e03c2011-03-23 20:57:25 +0100225static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
226{
227 struct ath_hw *ah = (struct ath_hw *) hw_priv;
228 struct ath_common *common = ath9k_hw_common(ah);
229 struct ath_softc *sc = (struct ath_softc *) common->priv;
230 unsigned long uninitialized_var(flags);
231 u32 val;
232
Felix Fietkauf3eef642012-03-14 16:40:25 +0100233 if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
Felix Fietkau845e03c2011-03-23 20:57:25 +0100234 spin_lock_irqsave(&sc->sc_serial_rw, flags);
Rajkumar Manoharan5479de62011-07-17 11:43:02 +0530235 val = __ath9k_reg_rmw(sc, reg_offset, set, clr);
Felix Fietkau845e03c2011-03-23 20:57:25 +0100236 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
Rajkumar Manoharan5479de62011-07-17 11:43:02 +0530237 } else
238 val = __ath9k_reg_rmw(sc, reg_offset, set, clr);
Felix Fietkau845e03c2011-03-23 20:57:25 +0100239
240 return val;
241}
242
Sujith55624202010-01-08 10:36:02 +0530243/**************************/
244/* Initialization */
245/**************************/
246
247static void setup_ht_cap(struct ath_softc *sc,
248 struct ieee80211_sta_ht_cap *ht_info)
249{
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200250 struct ath_hw *ah = sc->sc_ah;
251 struct ath_common *common = ath9k_hw_common(ah);
Sujith55624202010-01-08 10:36:02 +0530252 u8 tx_streams, rx_streams;
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200253 int i, max_streams;
Sujith55624202010-01-08 10:36:02 +0530254
255 ht_info->ht_supported = true;
256 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
257 IEEE80211_HT_CAP_SM_PS |
258 IEEE80211_HT_CAP_SGI_40 |
259 IEEE80211_HT_CAP_DSSSCCK40;
260
Luis R. Rodriguezb0a33442010-04-15 17:39:39 -0400261 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC)
262 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
263
Vasanthakumar Thiagarajan6473d242010-05-13 18:42:38 -0700264 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_SGI_20)
265 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
266
Sujith55624202010-01-08 10:36:02 +0530267 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
268 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
269
Sujith Manoharane41db612012-09-10 09:20:12 +0530270 if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah))
Vasanthakumar Thiagarajan7f1c7a62010-12-06 04:27:41 -0800271 max_streams = 1;
Mohammed Shafi Shajakhane7104192011-12-01 18:14:01 +0530272 else if (AR_SREV_9462(ah))
273 max_streams = 2;
Vasanthakumar Thiagarajan7f1c7a62010-12-06 04:27:41 -0800274 else if (AR_SREV_9300_20_OR_LATER(ah))
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200275 max_streams = 3;
276 else
277 max_streams = 2;
278
Felix Fietkau7a370812010-09-22 12:34:52 +0200279 if (AR_SREV_9280_20_OR_LATER(ah)) {
Felix Fietkau074a8c02010-04-19 19:57:36 +0200280 if (max_streams >= 2)
281 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
282 ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
283 }
284
Sujith55624202010-01-08 10:36:02 +0530285 /* set up supported mcs set */
286 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
Felix Fietkau82b2d332011-09-03 01:40:23 +0200287 tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams);
288 rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams);
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200289
Joe Perchesd2182b62011-12-15 14:55:53 -0800290 ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n",
Joe Perches226afe62010-12-02 19:12:37 -0800291 tx_streams, rx_streams);
Sujith55624202010-01-08 10:36:02 +0530292
293 if (tx_streams != rx_streams) {
Sujith55624202010-01-08 10:36:02 +0530294 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
295 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
296 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
297 }
298
Felix Fietkau3bb065a2010-04-19 19:57:34 +0200299 for (i = 0; i < rx_streams; i++)
300 ht_info->mcs.rx_mask[i] = 0xff;
Sujith55624202010-01-08 10:36:02 +0530301
302 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
303}
304
305static int ath9k_reg_notifier(struct wiphy *wiphy,
306 struct regulatory_request *request)
307{
308 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
Felix Fietkau9ac586152011-01-24 19:23:18 +0100309 struct ath_softc *sc = hw->priv;
Rajkumar Manoharan687f5452011-12-08 23:59:25 +0530310 struct ath_hw *ah = sc->sc_ah;
311 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
312 int ret;
Sujith55624202010-01-08 10:36:02 +0530313
Rajkumar Manoharan687f5452011-12-08 23:59:25 +0530314 ret = ath_reg_notifier_apply(wiphy, request, reg);
315
316 /* Set tx power */
317 if (ah->curchan) {
318 sc->config.txpowlimit = 2 * ah->curchan->chan->max_power;
319 ath9k_ps_wakeup(sc);
320 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
321 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
322 ath9k_ps_restore(sc);
323 }
324
325 return ret;
Sujith55624202010-01-08 10:36:02 +0530326}
327
328/*
329 * This function will allocate both the DMA descriptor structure, and the
330 * buffers it contains. These are used to contain the descriptors used
331 * by the system.
332*/
333int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
334 struct list_head *head, const char *name,
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400335 int nbuf, int ndesc, bool is_tx)
Sujith55624202010-01-08 10:36:02 +0530336{
Sujith55624202010-01-08 10:36:02 +0530337 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400338 u8 *ds;
Sujith55624202010-01-08 10:36:02 +0530339 struct ath_buf *bf;
Felix Fietkaub81950b12012-12-12 13:14:22 +0100340 int i, bsize, desc_len;
Sujith55624202010-01-08 10:36:02 +0530341
Joe Perchesd2182b62011-12-15 14:55:53 -0800342 ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n",
Joe Perches226afe62010-12-02 19:12:37 -0800343 name, nbuf, ndesc);
Sujith55624202010-01-08 10:36:02 +0530344
345 INIT_LIST_HEAD(head);
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400346
347 if (is_tx)
348 desc_len = sc->sc_ah->caps.tx_desc_len;
349 else
350 desc_len = sizeof(struct ath_desc);
351
Sujith55624202010-01-08 10:36:02 +0530352 /* ath_desc must be a multiple of DWORDs */
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400353 if ((desc_len % 4) != 0) {
Joe Perches38002762010-12-02 19:12:36 -0800354 ath_err(common, "ath_desc not DWORD aligned\n");
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400355 BUG_ON((desc_len % 4) != 0);
Felix Fietkaub81950b12012-12-12 13:14:22 +0100356 return -ENOMEM;
Sujith55624202010-01-08 10:36:02 +0530357 }
358
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400359 dd->dd_desc_len = desc_len * nbuf * ndesc;
Sujith55624202010-01-08 10:36:02 +0530360
361 /*
362 * Need additional DMA memory because we can't use
363 * descriptors that cross the 4K page boundary. Assume
364 * one skipped descriptor per 4K page.
365 */
366 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
367 u32 ndesc_skipped =
368 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
369 u32 dma_len;
370
371 while (ndesc_skipped) {
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400372 dma_len = ndesc_skipped * desc_len;
Sujith55624202010-01-08 10:36:02 +0530373 dd->dd_desc_len += dma_len;
374
375 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
Joe Perchesee289b62010-05-17 22:47:34 -0700376 }
Sujith55624202010-01-08 10:36:02 +0530377 }
378
379 /* allocate descriptors */
Felix Fietkaub81950b12012-12-12 13:14:22 +0100380 dd->dd_desc = dmam_alloc_coherent(sc->dev, dd->dd_desc_len,
381 &dd->dd_desc_paddr, GFP_KERNEL);
382 if (!dd->dd_desc)
383 return -ENOMEM;
384
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400385 ds = (u8 *) dd->dd_desc;
Joe Perchesd2182b62011-12-15 14:55:53 -0800386 ath_dbg(common, CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
Joe Perches226afe62010-12-02 19:12:37 -0800387 name, ds, (u32) dd->dd_desc_len,
388 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
Sujith55624202010-01-08 10:36:02 +0530389
390 /* allocate buffers */
391 bsize = sizeof(struct ath_buf) * nbuf;
Felix Fietkaub81950b12012-12-12 13:14:22 +0100392 bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
393 if (!bf)
394 return -ENOMEM;
Sujith55624202010-01-08 10:36:02 +0530395
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400396 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
Sujith55624202010-01-08 10:36:02 +0530397 bf->bf_desc = ds;
398 bf->bf_daddr = DS2PHYS(dd, ds);
399
400 if (!(sc->sc_ah->caps.hw_caps &
401 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
402 /*
403 * Skip descriptor addresses which can cause 4KB
404 * boundary crossing (addr + length) with a 32 dword
405 * descriptor fetch.
406 */
407 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
408 BUG_ON((caddr_t) bf->bf_desc >=
409 ((caddr_t) dd->dd_desc +
410 dd->dd_desc_len));
411
Vasanthakumar Thiagarajan4adfcde2010-04-15 17:39:33 -0400412 ds += (desc_len * ndesc);
Sujith55624202010-01-08 10:36:02 +0530413 bf->bf_desc = ds;
414 bf->bf_daddr = DS2PHYS(dd, ds);
415 }
416 }
417 list_add_tail(&bf->list, head);
418 }
419 return 0;
Sujith55624202010-01-08 10:36:02 +0530420}
421
Sujith285f2dd2010-01-08 10:36:07 +0530422static int ath9k_init_queues(struct ath_softc *sc)
423{
Sujith285f2dd2010-01-08 10:36:07 +0530424 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530425
Sujith285f2dd2010-01-08 10:36:07 +0530426 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
Sujith285f2dd2010-01-08 10:36:07 +0530427 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
Sujith55624202010-01-08 10:36:02 +0530428
Sujith285f2dd2010-01-08 10:36:07 +0530429 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
430 ath_cabq_update(sc);
431
Sujith Manoharanbea843c2012-11-21 18:13:10 +0530432 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
Felix Fietkau066dae92010-11-07 14:59:39 +0100433 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
Ben Greear60f2d1d2011-01-09 23:11:52 -0800434 sc->tx.txq_map[i]->mac80211_qnum = i;
Felix Fietkau7702e782012-07-15 19:53:35 +0200435 sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH;
Ben Greear60f2d1d2011-01-09 23:11:52 -0800436 }
Sujith285f2dd2010-01-08 10:36:07 +0530437 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530438}
439
Felix Fietkauf209f522010-10-01 01:06:53 +0200440static int ath9k_init_channels_rates(struct ath_softc *sc)
Sujith285f2dd2010-01-08 10:36:07 +0530441{
Felix Fietkauf209f522010-10-01 01:06:53 +0200442 void *channels;
443
Felix Fietkaucac42202010-10-09 02:39:30 +0200444 BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
445 ARRAY_SIZE(ath9k_5ghz_chantable) !=
446 ATH9K_NUM_CHANNELS);
447
Felix Fietkaud4659912010-10-14 16:02:39 +0200448 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
Felix Fietkaub81950b12012-12-12 13:14:22 +0100449 channels = devm_kzalloc(sc->dev,
Felix Fietkauf209f522010-10-01 01:06:53 +0200450 sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
451 if (!channels)
452 return -ENOMEM;
453
Felix Fietkaub81950b12012-12-12 13:14:22 +0100454 memcpy(channels, ath9k_2ghz_chantable,
455 sizeof(ath9k_2ghz_chantable));
Felix Fietkauf209f522010-10-01 01:06:53 +0200456 sc->sbands[IEEE80211_BAND_2GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530457 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
458 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
459 ARRAY_SIZE(ath9k_2ghz_chantable);
460 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
461 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
462 ARRAY_SIZE(ath9k_legacy_rates);
463 }
464
Felix Fietkaud4659912010-10-14 16:02:39 +0200465 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
Felix Fietkaub81950b12012-12-12 13:14:22 +0100466 channels = devm_kzalloc(sc->dev,
Felix Fietkauf209f522010-10-01 01:06:53 +0200467 sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
Felix Fietkaub81950b12012-12-12 13:14:22 +0100468 if (!channels)
Felix Fietkauf209f522010-10-01 01:06:53 +0200469 return -ENOMEM;
Felix Fietkauf209f522010-10-01 01:06:53 +0200470
Felix Fietkaub81950b12012-12-12 13:14:22 +0100471 memcpy(channels, ath9k_5ghz_chantable,
472 sizeof(ath9k_5ghz_chantable));
Felix Fietkauf209f522010-10-01 01:06:53 +0200473 sc->sbands[IEEE80211_BAND_5GHZ].channels = channels;
Sujith55624202010-01-08 10:36:02 +0530474 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
475 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
476 ARRAY_SIZE(ath9k_5ghz_chantable);
477 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
478 ath9k_legacy_rates + 4;
479 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
480 ARRAY_SIZE(ath9k_legacy_rates) - 4;
481 }
Felix Fietkauf209f522010-10-01 01:06:53 +0200482 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530483}
Sujith55624202010-01-08 10:36:02 +0530484
Sujith285f2dd2010-01-08 10:36:07 +0530485static void ath9k_init_misc(struct ath_softc *sc)
486{
487 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
488 int i = 0;
Sujith Manoharan3d4e20f2012-03-14 14:40:58 +0530489
Sujith285f2dd2010-01-08 10:36:07 +0530490 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
491
Sujith Manoharanaaa1ec42012-06-04 16:27:08 +0530492 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
Sujith285f2dd2010-01-08 10:36:07 +0530493 sc->config.txpowlimit = ATH_TXPOWER_MAX;
Felix Fietkau364734f2010-09-14 20:22:44 +0200494 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
Sujith285f2dd2010-01-08 10:36:07 +0530495 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
496
Felix Fietkau7545daf2011-01-24 19:23:16 +0100497 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
Sujith285f2dd2010-01-08 10:36:07 +0530498 sc->beacon.bslot[i] = NULL;
Vasanthakumar Thiagarajan102885a2010-09-02 01:34:43 -0700499
500 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
501 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
Sujith285f2dd2010-01-08 10:36:07 +0530502}
503
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100504static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob,
505 void *ctx)
506{
507 struct ath9k_eeprom_ctx *ec = ctx;
508
509 if (eeprom_blob)
510 ec->ah->eeprom_blob = eeprom_blob;
511
512 complete(&ec->complete);
513}
514
515static int ath9k_eeprom_request(struct ath_softc *sc, const char *name)
516{
517 struct ath9k_eeprom_ctx ec;
518 struct ath_hw *ah = ah = sc->sc_ah;
519 int err;
520
521 /* try to load the EEPROM content asynchronously */
522 init_completion(&ec.complete);
523 ec.ah = sc->sc_ah;
524
525 err = request_firmware_nowait(THIS_MODULE, 1, name, sc->dev, GFP_KERNEL,
526 &ec, ath9k_eeprom_request_cb);
527 if (err < 0) {
528 ath_err(ath9k_hw_common(ah),
529 "EEPROM request failed\n");
530 return err;
531 }
532
533 wait_for_completion(&ec.complete);
534
535 if (!ah->eeprom_blob) {
536 ath_err(ath9k_hw_common(ah),
537 "Unable to load EEPROM file %s\n", name);
538 return -EINVAL;
539 }
540
541 return 0;
542}
543
544static void ath9k_eeprom_release(struct ath_softc *sc)
545{
546 release_firmware(sc->sc_ah->eeprom_blob);
547}
548
Pavel Roskineb93e892011-07-23 03:55:39 -0400549static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
Sujith285f2dd2010-01-08 10:36:07 +0530550 const struct ath_bus_ops *bus_ops)
551{
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +0100552 struct ath9k_platform_data *pdata = sc->dev->platform_data;
Sujith285f2dd2010-01-08 10:36:07 +0530553 struct ath_hw *ah = NULL;
554 struct ath_common *common;
555 int ret = 0, i;
556 int csz = 0;
557
Felix Fietkaub81950b12012-12-12 13:14:22 +0100558 ah = devm_kzalloc(sc->dev, sizeof(struct ath_hw), GFP_KERNEL);
Sujith285f2dd2010-01-08 10:36:07 +0530559 if (!ah)
560 return -ENOMEM;
561
Ben Greear233536e2011-01-09 23:11:44 -0800562 ah->hw = sc->hw;
Sujith285f2dd2010-01-08 10:36:07 +0530563 ah->hw_version.devid = devid;
Felix Fietkauf9f84e92011-03-23 20:57:24 +0100564 ah->reg_ops.read = ath9k_ioread32;
565 ah->reg_ops.write = ath9k_iowrite32;
Felix Fietkau845e03c2011-03-23 20:57:25 +0100566 ah->reg_ops.rmw = ath9k_reg_rmw;
Rajkumar Manoharane8fe7332011-08-05 18:59:41 +0530567 atomic_set(&ah->intr_ref_cnt, -1);
Sujith285f2dd2010-01-08 10:36:07 +0530568 sc->sc_ah = ah;
569
Zefir Kurtisi8e92d3f2012-04-03 17:15:50 +0200570 sc->dfs_detector = dfs_pattern_detector_init(NL80211_DFS_UNSET);
571
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100572 if (!pdata) {
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100573 ah->ah_flags |= AH_USE_EEPROM;
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100574 sc->sc_ah->led_pin = -1;
575 } else {
576 sc->sc_ah->gpio_mask = pdata->gpio_mask;
577 sc->sc_ah->gpio_val = pdata->gpio_val;
578 sc->sc_ah->led_pin = pdata->led_pin;
Vasanthakumar Thiagarajanf2f5f2a2011-04-19 19:29:01 +0530579 ah->is_clk_25mhz = pdata->is_clk_25mhz;
Gabor Juhos37625612011-06-21 11:23:23 +0200580 ah->get_mac_revision = pdata->get_mac_revision;
Gabor Juhos7d95847c2011-06-21 11:23:51 +0200581 ah->external_reset = pdata->external_reset;
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100582 }
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100583
Sujith285f2dd2010-01-08 10:36:07 +0530584 common = ath9k_hw_common(ah);
Felix Fietkauf9f84e92011-03-23 20:57:24 +0100585 common->ops = &ah->reg_ops;
Sujith285f2dd2010-01-08 10:36:07 +0530586 common->bus_ops = bus_ops;
587 common->ah = ah;
588 common->hw = sc->hw;
589 common->priv = sc;
590 common->debug_mask = ath9k_debug;
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -0800591 common->btcoex_enabled = ath9k_btcoex_enable == 1;
Mohammed Shafi Shajakhan05c0be22011-05-26 10:56:15 +0530592 common->disable_ani = false;
Sujith Manoharane09f2dc2012-09-16 08:06:56 +0530593
594 /*
595 * Enable Antenna diversity only when BTCOEX is disabled
596 * and the user manually requests the feature.
597 */
598 if (!common->btcoex_enabled && ath9k_enable_diversity)
599 common->antenna_diversity = 1;
600
Ben Greear20b257442010-10-15 15:04:09 -0700601 spin_lock_init(&common->cc_lock);
Sujith285f2dd2010-01-08 10:36:07 +0530602
Sujith285f2dd2010-01-08 10:36:07 +0530603 spin_lock_init(&sc->sc_serial_rw);
604 spin_lock_init(&sc->sc_pm_lock);
605 mutex_init(&sc->mutex);
Felix Fietkau5baec742012-03-03 15:17:03 +0100606#ifdef CONFIG_ATH9K_MAC_DEBUG
607 spin_lock_init(&sc->debug.samp_lock);
608#endif
Sujith285f2dd2010-01-08 10:36:07 +0530609 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
Sujith Manoharanfb6e2522012-07-17 17:16:22 +0530610 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
Sujith285f2dd2010-01-08 10:36:07 +0530611 (unsigned long)sc);
612
Sujith Manoharanaaa1ec42012-06-04 16:27:08 +0530613 INIT_WORK(&sc->hw_reset_work, ath_reset_work);
614 INIT_WORK(&sc->hw_check_work, ath_hw_check);
615 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
616 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
617 setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc);
618
Sujith285f2dd2010-01-08 10:36:07 +0530619 /*
620 * Cache line size is used to size and align various
621 * structures used to communicate with the hardware.
622 */
623 ath_read_cachesize(common, &csz);
624 common->cachelsz = csz << 2; /* convert to bytes */
625
Gabor Juhos36b07d12012-12-11 00:06:41 +0100626 if (pdata && pdata->eeprom_name) {
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100627 ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
628 if (ret)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100629 return ret;
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100630 }
631
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400632 /* Initializes the hardware for all supported chipsets */
Sujith285f2dd2010-01-08 10:36:07 +0530633 ret = ath9k_hw_init(ah);
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400634 if (ret)
Sujith285f2dd2010-01-08 10:36:07 +0530635 goto err_hw;
Sujith285f2dd2010-01-08 10:36:07 +0530636
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +0100637 if (pdata && pdata->macaddr)
638 memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
639
Sujith285f2dd2010-01-08 10:36:07 +0530640 ret = ath9k_init_queues(sc);
641 if (ret)
642 goto err_queues;
643
644 ret = ath9k_init_btcoex(sc);
645 if (ret)
646 goto err_btcoex;
647
Felix Fietkauf209f522010-10-01 01:06:53 +0200648 ret = ath9k_init_channels_rates(sc);
649 if (ret)
650 goto err_btcoex;
651
Rajkumar Manoharanf82b4bd2011-08-13 10:28:15 +0530652 ath9k_cmn_init_crypto(sc->sc_ah);
Sujith285f2dd2010-01-08 10:36:07 +0530653 ath9k_init_misc(sc);
Rajkumar Manoharan8f176a32012-09-12 18:59:23 +0530654 ath_fill_led_pin(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530655
Sujith Manoharand09f5f42012-06-04 16:27:14 +0530656 if (common->bus_ops->aspm_init)
657 common->bus_ops->aspm_init(common);
658
Sujith55624202010-01-08 10:36:02 +0530659 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530660
661err_btcoex:
Sujith55624202010-01-08 10:36:02 +0530662 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
663 if (ATH_TXQ_SETUP(sc, i))
664 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
Sujith285f2dd2010-01-08 10:36:07 +0530665err_queues:
Sujith285f2dd2010-01-08 10:36:07 +0530666 ath9k_hw_deinit(ah);
667err_hw:
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100668 ath9k_eeprom_release(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530669 return ret;
Sujith55624202010-01-08 10:36:02 +0530670}
671
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200672static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
673{
674 struct ieee80211_supported_band *sband;
675 struct ieee80211_channel *chan;
676 struct ath_hw *ah = sc->sc_ah;
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200677 int i;
678
679 sband = &sc->sbands[band];
680 for (i = 0; i < sband->n_channels; i++) {
681 chan = &sband->channels[i];
682 ah->curchan = &ah->channels[chan->hw_value];
683 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
684 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200685 }
686}
687
688static void ath9k_init_txpower_limits(struct ath_softc *sc)
689{
690 struct ath_hw *ah = sc->sc_ah;
691 struct ath9k_channel *curchan = ah->curchan;
692
693 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
694 ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
695 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
696 ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
697
698 ah->curchan = curchan;
699}
700
Felix Fietkau43c35282011-09-03 01:40:27 +0200701void ath9k_reload_chainmask_settings(struct ath_softc *sc)
702{
703 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT))
704 return;
705
706 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
707 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
708 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
709 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
710}
711
Felix Fietkau20c8e8d2012-04-17 02:40:07 +0200712static const struct ieee80211_iface_limit if_limits[] = {
713 { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
714 BIT(NL80211_IFTYPE_P2P_CLIENT) |
715 BIT(NL80211_IFTYPE_WDS) },
716 { .max = 8, .types =
717#ifdef CONFIG_MAC80211_MESH
718 BIT(NL80211_IFTYPE_MESH_POINT) |
719#endif
720 BIT(NL80211_IFTYPE_AP) |
721 BIT(NL80211_IFTYPE_P2P_GO) },
722};
723
724static const struct ieee80211_iface_combination if_comb = {
725 .limits = if_limits,
726 .n_limits = ARRAY_SIZE(if_limits),
727 .max_interfaces = 2048,
728 .num_different_channels = 1,
Mohammed Shafi Shajakhanaebc0d42012-10-08 21:30:54 +0530729 .beacon_int_infra_match = true,
Felix Fietkau20c8e8d2012-04-17 02:40:07 +0200730};
Felix Fietkau43c35282011-09-03 01:40:27 +0200731
Sujith285f2dd2010-01-08 10:36:07 +0530732void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
Sujith55624202010-01-08 10:36:02 +0530733{
Felix Fietkau43c35282011-09-03 01:40:27 +0200734 struct ath_hw *ah = sc->sc_ah;
735 struct ath_common *common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530736
Sujith55624202010-01-08 10:36:02 +0530737 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
738 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
739 IEEE80211_HW_SIGNAL_DBM |
Sujith55624202010-01-08 10:36:02 +0530740 IEEE80211_HW_SUPPORTS_PS |
741 IEEE80211_HW_PS_NULLFUNC_STACK |
Vivek Natarajan05df4982010-02-09 11:34:50 +0530742 IEEE80211_HW_SPECTRUM_MGMT |
Mohammed Shafi Shajakhanbd8027a2010-12-30 12:18:01 +0530743 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
Sujith55624202010-01-08 10:36:02 +0530744
Luis R. Rodriguez5ffaf8a2010-02-02 11:58:33 -0500745 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
746 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
747
John W. Linville3e6109c2011-01-05 09:39:17 -0500748 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
Sujith55624202010-01-08 10:36:02 +0530749 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
750
751 hw->wiphy->interface_modes =
Johannes Bergc426ee22010-11-26 11:38:04 +0100752 BIT(NL80211_IFTYPE_P2P_GO) |
753 BIT(NL80211_IFTYPE_P2P_CLIENT) |
Sujith55624202010-01-08 10:36:02 +0530754 BIT(NL80211_IFTYPE_AP) |
Bill Jordane51f3ef2010-10-01 11:20:39 -0400755 BIT(NL80211_IFTYPE_WDS) |
Sujith55624202010-01-08 10:36:02 +0530756 BIT(NL80211_IFTYPE_STATION) |
757 BIT(NL80211_IFTYPE_ADHOC) |
758 BIT(NL80211_IFTYPE_MESH_POINT);
759
Felix Fietkau20c8e8d2012-04-17 02:40:07 +0200760 hw->wiphy->iface_combinations = &if_comb;
761 hw->wiphy->n_iface_combinations = 1;
762
Luis R. Rodriguez008443d2010-09-16 15:12:36 -0400763 if (AR_SREV_5416(sc->sc_ah))
764 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
Sujith55624202010-01-08 10:36:02 +0530765
Jouni Malinencfdc9a82011-03-23 14:52:19 +0200766 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Jouni Malinenfd656232011-10-27 17:31:50 +0300767 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
Johannes Berg81ddbb52012-03-26 18:47:18 +0200768 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Jouni Malinencfdc9a82011-03-23 14:52:19 +0200769
Mohammed Shafi Shajakhan9f11e162012-07-10 14:55:35 +0530770#ifdef CONFIG_PM_SLEEP
771
772 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
773 device_can_wakeup(sc->dev)) {
774
775 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
776 WIPHY_WOWLAN_DISCONNECT;
777 hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN;
778 hw->wiphy->wowlan.pattern_min_len = 1;
779 hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE;
780
781 }
782
783 atomic_set(&sc->wow_sleep_proc_intr, -1);
784 atomic_set(&sc->wow_got_bmiss_intr, -1);
785
786#endif
787
Sujith55624202010-01-08 10:36:02 +0530788 hw->queues = 4;
789 hw->max_rates = 4;
790 hw->channel_change_time = 5000;
Rajkumar Manoharan195ca3b2012-03-15 23:05:28 +0530791 hw->max_listen_interval = 1;
Felix Fietkau65896512010-01-24 03:26:11 +0100792 hw->max_rate_tries = 10;
Sujith55624202010-01-08 10:36:02 +0530793 hw->sta_data_size = sizeof(struct ath_node);
794 hw->vif_data_size = sizeof(struct ath_vif);
795
Felix Fietkau43c35282011-09-03 01:40:27 +0200796 hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
797 hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1;
798
799 /* single chain devices with rx diversity */
800 if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
801 hw->wiphy->available_antennas_rx = BIT(0) | BIT(1);
802
803 sc->ant_rx = hw->wiphy->available_antennas_rx;
804 sc->ant_tx = hw->wiphy->available_antennas_tx;
805
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200806#ifdef CONFIG_ATH9K_RATE_CONTROL
Sujith55624202010-01-08 10:36:02 +0530807 hw->rate_control_algorithm = "ath9k_rate_control";
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200808#endif
Sujith55624202010-01-08 10:36:02 +0530809
Felix Fietkaud4659912010-10-14 16:02:39 +0200810 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith55624202010-01-08 10:36:02 +0530811 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
812 &sc->sbands[IEEE80211_BAND_2GHZ];
Felix Fietkaud4659912010-10-14 16:02:39 +0200813 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith55624202010-01-08 10:36:02 +0530814 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
815 &sc->sbands[IEEE80211_BAND_5GHZ];
Sujith285f2dd2010-01-08 10:36:07 +0530816
Felix Fietkau43c35282011-09-03 01:40:27 +0200817 ath9k_reload_chainmask_settings(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530818
819 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
Sujith55624202010-01-08 10:36:02 +0530820}
821
Pavel Roskineb93e892011-07-23 03:55:39 -0400822int ath9k_init_device(u16 devid, struct ath_softc *sc,
Sujith55624202010-01-08 10:36:02 +0530823 const struct ath_bus_ops *bus_ops)
824{
825 struct ieee80211_hw *hw = sc->hw;
826 struct ath_common *common;
827 struct ath_hw *ah;
Sujith285f2dd2010-01-08 10:36:07 +0530828 int error = 0;
Sujith55624202010-01-08 10:36:02 +0530829 struct ath_regulatory *reg;
830
Sujith285f2dd2010-01-08 10:36:07 +0530831 /* Bring up device */
Pavel Roskineb93e892011-07-23 03:55:39 -0400832 error = ath9k_init_softc(devid, sc, bus_ops);
Felix Fietkaub81950b12012-12-12 13:14:22 +0100833 if (error)
834 return error;
Sujith55624202010-01-08 10:36:02 +0530835
836 ah = sc->sc_ah;
837 common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530838 ath9k_set_hw_capab(sc, hw);
Sujith55624202010-01-08 10:36:02 +0530839
Sujith285f2dd2010-01-08 10:36:07 +0530840 /* Initialize regulatory */
Sujith55624202010-01-08 10:36:02 +0530841 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
842 ath9k_reg_notifier);
843 if (error)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100844 goto deinit;
Sujith55624202010-01-08 10:36:02 +0530845
846 reg = &common->regulatory;
847
Sujith285f2dd2010-01-08 10:36:07 +0530848 /* Setup TX DMA */
Sujith55624202010-01-08 10:36:02 +0530849 error = ath_tx_init(sc, ATH_TXBUF);
850 if (error != 0)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100851 goto deinit;
Sujith55624202010-01-08 10:36:02 +0530852
Sujith285f2dd2010-01-08 10:36:07 +0530853 /* Setup RX DMA */
Sujith55624202010-01-08 10:36:02 +0530854 error = ath_rx_init(sc, ATH_RXBUF);
855 if (error != 0)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100856 goto deinit;
Sujith285f2dd2010-01-08 10:36:07 +0530857
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200858 ath9k_init_txpower_limits(sc);
859
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100860#ifdef CONFIG_MAC80211_LEDS
861 /* must be initialized before ieee80211_register_hw */
862 sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
863 IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
864 ARRAY_SIZE(ath9k_tpt_blink));
865#endif
866
Sujith285f2dd2010-01-08 10:36:07 +0530867 /* Register with mac80211 */
868 error = ieee80211_register_hw(hw);
869 if (error)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100870 goto rx_cleanup;
Sujith285f2dd2010-01-08 10:36:07 +0530871
Ben Greeareb272442010-11-29 14:13:22 -0800872 error = ath9k_init_debug(ah);
873 if (error) {
Joe Perches38002762010-12-02 19:12:36 -0800874 ath_err(common, "Unable to create debugfs files\n");
Felix Fietkaub81950b12012-12-12 13:14:22 +0100875 goto unregister;
Ben Greeareb272442010-11-29 14:13:22 -0800876 }
877
Sujith285f2dd2010-01-08 10:36:07 +0530878 /* Handle world regulatory */
879 if (!ath_is_world_regd(reg)) {
880 error = regulatory_hint(hw->wiphy, reg->alpha2);
881 if (error)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100882 goto unregister;
Sujith285f2dd2010-01-08 10:36:07 +0530883 }
Sujith55624202010-01-08 10:36:02 +0530884
Sujith55624202010-01-08 10:36:02 +0530885 ath_init_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530886 ath_start_rfkill_poll(sc);
887
888 return 0;
889
Felix Fietkaub81950b12012-12-12 13:14:22 +0100890unregister:
Sujith285f2dd2010-01-08 10:36:07 +0530891 ieee80211_unregister_hw(hw);
Felix Fietkaub81950b12012-12-12 13:14:22 +0100892rx_cleanup:
Sujith285f2dd2010-01-08 10:36:07 +0530893 ath_rx_cleanup(sc);
Felix Fietkaub81950b12012-12-12 13:14:22 +0100894deinit:
Sujith285f2dd2010-01-08 10:36:07 +0530895 ath9k_deinit_softc(sc);
Sujith55624202010-01-08 10:36:02 +0530896 return error;
897}
898
899/*****************************/
900/* De-Initialization */
901/*****************************/
902
Sujith285f2dd2010-01-08 10:36:07 +0530903static void ath9k_deinit_softc(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530904{
Sujith285f2dd2010-01-08 10:36:07 +0530905 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530906
Sujith Manoharan59081202012-02-22 12:40:21 +0530907 ath9k_deinit_btcoex(sc);
Mohammed Shafi Shajakhan19686dd2011-11-30 10:41:28 +0530908
Sujith285f2dd2010-01-08 10:36:07 +0530909 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
910 if (ATH_TXQ_SETUP(sc, i))
911 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
912
Sujith285f2dd2010-01-08 10:36:07 +0530913 ath9k_hw_deinit(sc->sc_ah);
Zefir Kurtisi8e92d3f2012-04-03 17:15:50 +0200914 if (sc->dfs_detector != NULL)
915 sc->dfs_detector->exit(sc->dfs_detector);
Sujith285f2dd2010-01-08 10:36:07 +0530916
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100917 ath9k_eeprom_release(sc);
Sujith55624202010-01-08 10:36:02 +0530918}
919
Sujith285f2dd2010-01-08 10:36:07 +0530920void ath9k_deinit_device(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530921{
922 struct ieee80211_hw *hw = sc->hw;
Sujith55624202010-01-08 10:36:02 +0530923
924 ath9k_ps_wakeup(sc);
925
Sujith55624202010-01-08 10:36:02 +0530926 wiphy_rfkill_stop_polling(sc->hw->wiphy);
Sujith285f2dd2010-01-08 10:36:07 +0530927 ath_deinit_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530928
Rajkumar Manoharanc7c18062011-01-27 18:39:38 +0530929 ath9k_ps_restore(sc);
930
Sujith55624202010-01-08 10:36:02 +0530931 ieee80211_unregister_hw(hw);
932 ath_rx_cleanup(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530933 ath9k_deinit_softc(sc);
Sujith55624202010-01-08 10:36:02 +0530934}
935
Sujith55624202010-01-08 10:36:02 +0530936/************************/
937/* Module Hooks */
938/************************/
939
940static int __init ath9k_init(void)
941{
942 int error;
943
944 /* Register rate control algorithm */
945 error = ath_rate_control_register();
946 if (error != 0) {
Joe Perches516304b2012-03-18 17:30:52 -0700947 pr_err("Unable to register rate control algorithm: %d\n",
948 error);
Sujith55624202010-01-08 10:36:02 +0530949 goto err_out;
950 }
951
Sujith55624202010-01-08 10:36:02 +0530952 error = ath_pci_init();
953 if (error < 0) {
Joe Perches516304b2012-03-18 17:30:52 -0700954 pr_err("No PCI devices found, driver not installed\n");
Sujith55624202010-01-08 10:36:02 +0530955 error = -ENODEV;
Ben Greeareb272442010-11-29 14:13:22 -0800956 goto err_rate_unregister;
Sujith55624202010-01-08 10:36:02 +0530957 }
958
959 error = ath_ahb_init();
960 if (error < 0) {
961 error = -ENODEV;
962 goto err_pci_exit;
963 }
964
965 return 0;
966
967 err_pci_exit:
968 ath_pci_exit();
969
Sujith55624202010-01-08 10:36:02 +0530970 err_rate_unregister:
971 ath_rate_control_unregister();
972 err_out:
973 return error;
974}
975module_init(ath9k_init);
976
977static void __exit ath9k_exit(void)
978{
Rajkumar Manoharand5847472010-12-20 14:39:51 +0530979 is_ath9k_unloaded = true;
Sujith55624202010-01-08 10:36:02 +0530980 ath_ahb_exit();
981 ath_pci_exit();
Sujith55624202010-01-08 10:36:02 +0530982 ath_rate_control_unregister();
Joe Perches516304b2012-03-18 17:30:52 -0700983 pr_info("%s: Driver unloaded\n", dev_info);
Sujith55624202010-01-08 10:36:02 +0530984}
985module_exit(ath9k_exit);