blob: 5c01f43c32b05a722f1e2e01dd603c627b1f7e68 [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
Felix Fietkauc1b976d2012-12-12 13:14:23 +0100562 ah->dev = sc->dev;
Ben Greear233536e2011-01-09 23:11:44 -0800563 ah->hw = sc->hw;
Sujith285f2dd2010-01-08 10:36:07 +0530564 ah->hw_version.devid = devid;
Felix Fietkauf9f84e92011-03-23 20:57:24 +0100565 ah->reg_ops.read = ath9k_ioread32;
566 ah->reg_ops.write = ath9k_iowrite32;
Felix Fietkau845e03c2011-03-23 20:57:25 +0100567 ah->reg_ops.rmw = ath9k_reg_rmw;
Rajkumar Manoharane8fe7332011-08-05 18:59:41 +0530568 atomic_set(&ah->intr_ref_cnt, -1);
Sujith285f2dd2010-01-08 10:36:07 +0530569 sc->sc_ah = ah;
570
Zefir Kurtisi8e92d3f2012-04-03 17:15:50 +0200571 sc->dfs_detector = dfs_pattern_detector_init(NL80211_DFS_UNSET);
572
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100573 if (!pdata) {
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100574 ah->ah_flags |= AH_USE_EEPROM;
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100575 sc->sc_ah->led_pin = -1;
576 } else {
577 sc->sc_ah->gpio_mask = pdata->gpio_mask;
578 sc->sc_ah->gpio_val = pdata->gpio_val;
579 sc->sc_ah->led_pin = pdata->led_pin;
Vasanthakumar Thiagarajanf2f5f2a2011-04-19 19:29:01 +0530580 ah->is_clk_25mhz = pdata->is_clk_25mhz;
Gabor Juhos37625612011-06-21 11:23:23 +0200581 ah->get_mac_revision = pdata->get_mac_revision;
Gabor Juhos7d95847c2011-06-21 11:23:51 +0200582 ah->external_reset = pdata->external_reset;
Felix Fietkau6de66dd2011-03-19 13:55:40 +0100583 }
Felix Fietkaua05b5d452010-11-17 04:25:33 +0100584
Sujith285f2dd2010-01-08 10:36:07 +0530585 common = ath9k_hw_common(ah);
Felix Fietkauf9f84e92011-03-23 20:57:24 +0100586 common->ops = &ah->reg_ops;
Sujith285f2dd2010-01-08 10:36:07 +0530587 common->bus_ops = bus_ops;
588 common->ah = ah;
589 common->hw = sc->hw;
590 common->priv = sc;
591 common->debug_mask = ath9k_debug;
Vasanthakumar Thiagarajan8f5dcb12010-11-26 06:10:06 -0800592 common->btcoex_enabled = ath9k_btcoex_enable == 1;
Mohammed Shafi Shajakhan05c0be22011-05-26 10:56:15 +0530593 common->disable_ani = false;
Sujith Manoharane09f2dc2012-09-16 08:06:56 +0530594
595 /*
596 * Enable Antenna diversity only when BTCOEX is disabled
597 * and the user manually requests the feature.
598 */
599 if (!common->btcoex_enabled && ath9k_enable_diversity)
600 common->antenna_diversity = 1;
601
Ben Greear20b257442010-10-15 15:04:09 -0700602 spin_lock_init(&common->cc_lock);
Sujith285f2dd2010-01-08 10:36:07 +0530603
Sujith285f2dd2010-01-08 10:36:07 +0530604 spin_lock_init(&sc->sc_serial_rw);
605 spin_lock_init(&sc->sc_pm_lock);
606 mutex_init(&sc->mutex);
Felix Fietkau5baec742012-03-03 15:17:03 +0100607#ifdef CONFIG_ATH9K_MAC_DEBUG
608 spin_lock_init(&sc->debug.samp_lock);
609#endif
Sujith285f2dd2010-01-08 10:36:07 +0530610 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
Sujith Manoharanfb6e2522012-07-17 17:16:22 +0530611 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
Sujith285f2dd2010-01-08 10:36:07 +0530612 (unsigned long)sc);
613
Sujith Manoharanaaa1ec42012-06-04 16:27:08 +0530614 INIT_WORK(&sc->hw_reset_work, ath_reset_work);
615 INIT_WORK(&sc->hw_check_work, ath_hw_check);
616 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
617 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
618 setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc);
619
Sujith285f2dd2010-01-08 10:36:07 +0530620 /*
621 * Cache line size is used to size and align various
622 * structures used to communicate with the hardware.
623 */
624 ath_read_cachesize(common, &csz);
625 common->cachelsz = csz << 2; /* convert to bytes */
626
Gabor Juhos36b07d12012-12-11 00:06:41 +0100627 if (pdata && pdata->eeprom_name) {
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100628 ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
629 if (ret)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100630 return ret;
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100631 }
632
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400633 /* Initializes the hardware for all supported chipsets */
Sujith285f2dd2010-01-08 10:36:07 +0530634 ret = ath9k_hw_init(ah);
Luis R. Rodriguezd70357d2010-04-15 17:38:06 -0400635 if (ret)
Sujith285f2dd2010-01-08 10:36:07 +0530636 goto err_hw;
Sujith285f2dd2010-01-08 10:36:07 +0530637
Felix Fietkau6fb1b1e2011-03-19 13:55:39 +0100638 if (pdata && pdata->macaddr)
639 memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
640
Sujith285f2dd2010-01-08 10:36:07 +0530641 ret = ath9k_init_queues(sc);
642 if (ret)
643 goto err_queues;
644
645 ret = ath9k_init_btcoex(sc);
646 if (ret)
647 goto err_btcoex;
648
Felix Fietkauf209f522010-10-01 01:06:53 +0200649 ret = ath9k_init_channels_rates(sc);
650 if (ret)
651 goto err_btcoex;
652
Rajkumar Manoharanf82b4bd2011-08-13 10:28:15 +0530653 ath9k_cmn_init_crypto(sc->sc_ah);
Sujith285f2dd2010-01-08 10:36:07 +0530654 ath9k_init_misc(sc);
Rajkumar Manoharan8f176a32012-09-12 18:59:23 +0530655 ath_fill_led_pin(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530656
Sujith Manoharand09f5f42012-06-04 16:27:14 +0530657 if (common->bus_ops->aspm_init)
658 common->bus_ops->aspm_init(common);
659
Sujith55624202010-01-08 10:36:02 +0530660 return 0;
Sujith285f2dd2010-01-08 10:36:07 +0530661
662err_btcoex:
Sujith55624202010-01-08 10:36:02 +0530663 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
664 if (ATH_TXQ_SETUP(sc, i))
665 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
Sujith285f2dd2010-01-08 10:36:07 +0530666err_queues:
Sujith285f2dd2010-01-08 10:36:07 +0530667 ath9k_hw_deinit(ah);
668err_hw:
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100669 ath9k_eeprom_release(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530670 return ret;
Sujith55624202010-01-08 10:36:02 +0530671}
672
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200673static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
674{
675 struct ieee80211_supported_band *sband;
676 struct ieee80211_channel *chan;
677 struct ath_hw *ah = sc->sc_ah;
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200678 int i;
679
680 sband = &sc->sbands[band];
681 for (i = 0; i < sband->n_channels; i++) {
682 chan = &sband->channels[i];
683 ah->curchan = &ah->channels[chan->hw_value];
684 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
685 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200686 }
687}
688
689static void ath9k_init_txpower_limits(struct ath_softc *sc)
690{
691 struct ath_hw *ah = sc->sc_ah;
692 struct ath9k_channel *curchan = ah->curchan;
693
694 if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
695 ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
696 if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
697 ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
698
699 ah->curchan = curchan;
700}
701
Felix Fietkau43c35282011-09-03 01:40:27 +0200702void ath9k_reload_chainmask_settings(struct ath_softc *sc)
703{
704 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT))
705 return;
706
707 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
708 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
709 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
710 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
711}
712
Felix Fietkau20c8e8d2012-04-17 02:40:07 +0200713static const struct ieee80211_iface_limit if_limits[] = {
714 { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
715 BIT(NL80211_IFTYPE_P2P_CLIENT) |
716 BIT(NL80211_IFTYPE_WDS) },
717 { .max = 8, .types =
718#ifdef CONFIG_MAC80211_MESH
719 BIT(NL80211_IFTYPE_MESH_POINT) |
720#endif
721 BIT(NL80211_IFTYPE_AP) |
722 BIT(NL80211_IFTYPE_P2P_GO) },
723};
724
725static const struct ieee80211_iface_combination if_comb = {
726 .limits = if_limits,
727 .n_limits = ARRAY_SIZE(if_limits),
728 .max_interfaces = 2048,
729 .num_different_channels = 1,
Mohammed Shafi Shajakhanaebc0d42012-10-08 21:30:54 +0530730 .beacon_int_infra_match = true,
Felix Fietkau20c8e8d2012-04-17 02:40:07 +0200731};
Felix Fietkau43c35282011-09-03 01:40:27 +0200732
Sujith285f2dd2010-01-08 10:36:07 +0530733void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
Sujith55624202010-01-08 10:36:02 +0530734{
Felix Fietkau43c35282011-09-03 01:40:27 +0200735 struct ath_hw *ah = sc->sc_ah;
736 struct ath_common *common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530737
Sujith55624202010-01-08 10:36:02 +0530738 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
739 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
740 IEEE80211_HW_SIGNAL_DBM |
Sujith55624202010-01-08 10:36:02 +0530741 IEEE80211_HW_SUPPORTS_PS |
742 IEEE80211_HW_PS_NULLFUNC_STACK |
Vivek Natarajan05df4982010-02-09 11:34:50 +0530743 IEEE80211_HW_SPECTRUM_MGMT |
Mohammed Shafi Shajakhanbd8027a2010-12-30 12:18:01 +0530744 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
Sujith55624202010-01-08 10:36:02 +0530745
Luis R. Rodriguez5ffaf8a2010-02-02 11:58:33 -0500746 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
747 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
748
John W. Linville3e6109c2011-01-05 09:39:17 -0500749 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
Sujith55624202010-01-08 10:36:02 +0530750 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
751
752 hw->wiphy->interface_modes =
Johannes Bergc426ee22010-11-26 11:38:04 +0100753 BIT(NL80211_IFTYPE_P2P_GO) |
754 BIT(NL80211_IFTYPE_P2P_CLIENT) |
Sujith55624202010-01-08 10:36:02 +0530755 BIT(NL80211_IFTYPE_AP) |
Bill Jordane51f3ef2010-10-01 11:20:39 -0400756 BIT(NL80211_IFTYPE_WDS) |
Sujith55624202010-01-08 10:36:02 +0530757 BIT(NL80211_IFTYPE_STATION) |
758 BIT(NL80211_IFTYPE_ADHOC) |
759 BIT(NL80211_IFTYPE_MESH_POINT);
760
Felix Fietkau20c8e8d2012-04-17 02:40:07 +0200761 hw->wiphy->iface_combinations = &if_comb;
762 hw->wiphy->n_iface_combinations = 1;
763
Luis R. Rodriguez008443d2010-09-16 15:12:36 -0400764 if (AR_SREV_5416(sc->sc_ah))
765 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
Sujith55624202010-01-08 10:36:02 +0530766
Jouni Malinencfdc9a82011-03-23 14:52:19 +0200767 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Jouni Malinenfd656232011-10-27 17:31:50 +0300768 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
Johannes Berg81ddbb52012-03-26 18:47:18 +0200769 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Jouni Malinencfdc9a82011-03-23 14:52:19 +0200770
Mohammed Shafi Shajakhan9f11e162012-07-10 14:55:35 +0530771#ifdef CONFIG_PM_SLEEP
772
773 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
774 device_can_wakeup(sc->dev)) {
775
776 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
777 WIPHY_WOWLAN_DISCONNECT;
778 hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN;
779 hw->wiphy->wowlan.pattern_min_len = 1;
780 hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE;
781
782 }
783
784 atomic_set(&sc->wow_sleep_proc_intr, -1);
785 atomic_set(&sc->wow_got_bmiss_intr, -1);
786
787#endif
788
Sujith55624202010-01-08 10:36:02 +0530789 hw->queues = 4;
790 hw->max_rates = 4;
791 hw->channel_change_time = 5000;
Rajkumar Manoharan195ca3b2012-03-15 23:05:28 +0530792 hw->max_listen_interval = 1;
Felix Fietkau65896512010-01-24 03:26:11 +0100793 hw->max_rate_tries = 10;
Sujith55624202010-01-08 10:36:02 +0530794 hw->sta_data_size = sizeof(struct ath_node);
795 hw->vif_data_size = sizeof(struct ath_vif);
796
Felix Fietkau43c35282011-09-03 01:40:27 +0200797 hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
798 hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1;
799
800 /* single chain devices with rx diversity */
801 if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
802 hw->wiphy->available_antennas_rx = BIT(0) | BIT(1);
803
804 sc->ant_rx = hw->wiphy->available_antennas_rx;
805 sc->ant_tx = hw->wiphy->available_antennas_tx;
806
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200807#ifdef CONFIG_ATH9K_RATE_CONTROL
Sujith55624202010-01-08 10:36:02 +0530808 hw->rate_control_algorithm = "ath9k_rate_control";
Felix Fietkau6e5c2b42010-09-20 13:45:40 +0200809#endif
Sujith55624202010-01-08 10:36:02 +0530810
Felix Fietkaud4659912010-10-14 16:02:39 +0200811 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
Sujith55624202010-01-08 10:36:02 +0530812 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
813 &sc->sbands[IEEE80211_BAND_2GHZ];
Felix Fietkaud4659912010-10-14 16:02:39 +0200814 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
Sujith55624202010-01-08 10:36:02 +0530815 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
816 &sc->sbands[IEEE80211_BAND_5GHZ];
Sujith285f2dd2010-01-08 10:36:07 +0530817
Felix Fietkau43c35282011-09-03 01:40:27 +0200818 ath9k_reload_chainmask_settings(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530819
820 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
Sujith55624202010-01-08 10:36:02 +0530821}
822
Pavel Roskineb93e892011-07-23 03:55:39 -0400823int ath9k_init_device(u16 devid, struct ath_softc *sc,
Sujith55624202010-01-08 10:36:02 +0530824 const struct ath_bus_ops *bus_ops)
825{
826 struct ieee80211_hw *hw = sc->hw;
827 struct ath_common *common;
828 struct ath_hw *ah;
Sujith285f2dd2010-01-08 10:36:07 +0530829 int error = 0;
Sujith55624202010-01-08 10:36:02 +0530830 struct ath_regulatory *reg;
831
Sujith285f2dd2010-01-08 10:36:07 +0530832 /* Bring up device */
Pavel Roskineb93e892011-07-23 03:55:39 -0400833 error = ath9k_init_softc(devid, sc, bus_ops);
Felix Fietkaub81950b12012-12-12 13:14:22 +0100834 if (error)
835 return error;
Sujith55624202010-01-08 10:36:02 +0530836
837 ah = sc->sc_ah;
838 common = ath9k_hw_common(ah);
Sujith285f2dd2010-01-08 10:36:07 +0530839 ath9k_set_hw_capab(sc, hw);
Sujith55624202010-01-08 10:36:02 +0530840
Sujith285f2dd2010-01-08 10:36:07 +0530841 /* Initialize regulatory */
Sujith55624202010-01-08 10:36:02 +0530842 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
843 ath9k_reg_notifier);
844 if (error)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100845 goto deinit;
Sujith55624202010-01-08 10:36:02 +0530846
847 reg = &common->regulatory;
848
Sujith285f2dd2010-01-08 10:36:07 +0530849 /* Setup TX DMA */
Sujith55624202010-01-08 10:36:02 +0530850 error = ath_tx_init(sc, ATH_TXBUF);
851 if (error != 0)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100852 goto deinit;
Sujith55624202010-01-08 10:36:02 +0530853
Sujith285f2dd2010-01-08 10:36:07 +0530854 /* Setup RX DMA */
Sujith55624202010-01-08 10:36:02 +0530855 error = ath_rx_init(sc, ATH_RXBUF);
856 if (error != 0)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100857 goto deinit;
Sujith285f2dd2010-01-08 10:36:07 +0530858
Felix Fietkaubabcbc22010-10-20 02:09:46 +0200859 ath9k_init_txpower_limits(sc);
860
Felix Fietkau0cf55c22011-02-27 22:26:40 +0100861#ifdef CONFIG_MAC80211_LEDS
862 /* must be initialized before ieee80211_register_hw */
863 sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
864 IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
865 ARRAY_SIZE(ath9k_tpt_blink));
866#endif
867
Sujith285f2dd2010-01-08 10:36:07 +0530868 /* Register with mac80211 */
869 error = ieee80211_register_hw(hw);
870 if (error)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100871 goto rx_cleanup;
Sujith285f2dd2010-01-08 10:36:07 +0530872
Ben Greeareb272442010-11-29 14:13:22 -0800873 error = ath9k_init_debug(ah);
874 if (error) {
Joe Perches38002762010-12-02 19:12:36 -0800875 ath_err(common, "Unable to create debugfs files\n");
Felix Fietkaub81950b12012-12-12 13:14:22 +0100876 goto unregister;
Ben Greeareb272442010-11-29 14:13:22 -0800877 }
878
Sujith285f2dd2010-01-08 10:36:07 +0530879 /* Handle world regulatory */
880 if (!ath_is_world_regd(reg)) {
881 error = regulatory_hint(hw->wiphy, reg->alpha2);
882 if (error)
Felix Fietkaub81950b12012-12-12 13:14:22 +0100883 goto unregister;
Sujith285f2dd2010-01-08 10:36:07 +0530884 }
Sujith55624202010-01-08 10:36:02 +0530885
Sujith55624202010-01-08 10:36:02 +0530886 ath_init_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530887 ath_start_rfkill_poll(sc);
888
889 return 0;
890
Felix Fietkaub81950b12012-12-12 13:14:22 +0100891unregister:
Sujith285f2dd2010-01-08 10:36:07 +0530892 ieee80211_unregister_hw(hw);
Felix Fietkaub81950b12012-12-12 13:14:22 +0100893rx_cleanup:
Sujith285f2dd2010-01-08 10:36:07 +0530894 ath_rx_cleanup(sc);
Felix Fietkaub81950b12012-12-12 13:14:22 +0100895deinit:
Sujith285f2dd2010-01-08 10:36:07 +0530896 ath9k_deinit_softc(sc);
Sujith55624202010-01-08 10:36:02 +0530897 return error;
898}
899
900/*****************************/
901/* De-Initialization */
902/*****************************/
903
Sujith285f2dd2010-01-08 10:36:07 +0530904static void ath9k_deinit_softc(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530905{
Sujith285f2dd2010-01-08 10:36:07 +0530906 int i = 0;
Sujith55624202010-01-08 10:36:02 +0530907
Sujith Manoharan59081202012-02-22 12:40:21 +0530908 ath9k_deinit_btcoex(sc);
Mohammed Shafi Shajakhan19686dd2011-11-30 10:41:28 +0530909
Sujith285f2dd2010-01-08 10:36:07 +0530910 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
911 if (ATH_TXQ_SETUP(sc, i))
912 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
913
Sujith285f2dd2010-01-08 10:36:07 +0530914 ath9k_hw_deinit(sc->sc_ah);
Zefir Kurtisi8e92d3f2012-04-03 17:15:50 +0200915 if (sc->dfs_detector != NULL)
916 sc->dfs_detector->exit(sc->dfs_detector);
Sujith285f2dd2010-01-08 10:36:07 +0530917
Gabor Juhosab5c4f72012-12-10 15:30:28 +0100918 ath9k_eeprom_release(sc);
Sujith55624202010-01-08 10:36:02 +0530919}
920
Sujith285f2dd2010-01-08 10:36:07 +0530921void ath9k_deinit_device(struct ath_softc *sc)
Sujith55624202010-01-08 10:36:02 +0530922{
923 struct ieee80211_hw *hw = sc->hw;
Sujith55624202010-01-08 10:36:02 +0530924
925 ath9k_ps_wakeup(sc);
926
Sujith55624202010-01-08 10:36:02 +0530927 wiphy_rfkill_stop_polling(sc->hw->wiphy);
Sujith285f2dd2010-01-08 10:36:07 +0530928 ath_deinit_leds(sc);
Sujith55624202010-01-08 10:36:02 +0530929
Rajkumar Manoharanc7c18062011-01-27 18:39:38 +0530930 ath9k_ps_restore(sc);
931
Sujith55624202010-01-08 10:36:02 +0530932 ieee80211_unregister_hw(hw);
933 ath_rx_cleanup(sc);
Sujith285f2dd2010-01-08 10:36:07 +0530934 ath9k_deinit_softc(sc);
Sujith55624202010-01-08 10:36:02 +0530935}
936
Sujith55624202010-01-08 10:36:02 +0530937/************************/
938/* Module Hooks */
939/************************/
940
941static int __init ath9k_init(void)
942{
943 int error;
944
945 /* Register rate control algorithm */
946 error = ath_rate_control_register();
947 if (error != 0) {
Joe Perches516304b2012-03-18 17:30:52 -0700948 pr_err("Unable to register rate control algorithm: %d\n",
949 error);
Sujith55624202010-01-08 10:36:02 +0530950 goto err_out;
951 }
952
Sujith55624202010-01-08 10:36:02 +0530953 error = ath_pci_init();
954 if (error < 0) {
Joe Perches516304b2012-03-18 17:30:52 -0700955 pr_err("No PCI devices found, driver not installed\n");
Sujith55624202010-01-08 10:36:02 +0530956 error = -ENODEV;
Ben Greeareb272442010-11-29 14:13:22 -0800957 goto err_rate_unregister;
Sujith55624202010-01-08 10:36:02 +0530958 }
959
960 error = ath_ahb_init();
961 if (error < 0) {
962 error = -ENODEV;
963 goto err_pci_exit;
964 }
965
966 return 0;
967
968 err_pci_exit:
969 ath_pci_exit();
970
Sujith55624202010-01-08 10:36:02 +0530971 err_rate_unregister:
972 ath_rate_control_unregister();
973 err_out:
974 return error;
975}
976module_init(ath9k_init);
977
978static void __exit ath9k_exit(void)
979{
Rajkumar Manoharand5847472010-12-20 14:39:51 +0530980 is_ath9k_unloaded = true;
Sujith55624202010-01-08 10:36:02 +0530981 ath_ahb_exit();
982 ath_pci_exit();
Sujith55624202010-01-08 10:36:02 +0530983 ath_rate_control_unregister();
Joe Perches516304b2012-03-18 17:30:52 -0700984 pr_info("%s: Driver unloaded\n", dev_info);
Sujith55624202010-01-08 10:36:02 +0530985}
986module_exit(ath9k_exit);