aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMichael Wu <flamingice@sourmilk.net>2007-08-31 01:15:25 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:33 -0400
commitcc0b88cf5ecf13cdd750f08e201ce8fadcdb601f (patch)
treed49dcdc2b0e02d2e8b3886fe54a568cc009c652a /drivers/net
parentaa0daf0e020de9c20e653e437deaa1153c4d134e (diff)
[PATCH] Add adm8211 802.11b wireless driver
This patch adds a mac80211 wireless driver for ADMtek ADM8211 based wireless cards. Signed-off-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/Kconfig27
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/adm8211.c2063
-rw-r--r--drivers/net/wireless/adm8211.h659
4 files changed, 2751 insertions, 0 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index ae27af0141c0..86480afe5351 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -558,6 +558,33 @@ config RTL8187
558 558
559 Thanks to Realtek for their support! 559 Thanks to Realtek for their support!
560 560
561config ADM8211
562 tristate "ADMtek ADM8211 support"
563 depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
564 select CRC32
565 select EEPROM_93CX6
566 ---help---
567 This driver is for ADM8211A, ADM8211B, and ADM8211C based cards.
568 These are PCI/mini-PCI/Cardbus 802.11b chips found in cards such as:
569
570 Xterasys Cardbus XN-2411b
571 Blitz NetWave Point PC
572 TrendNet 221pc
573 Belkin F5D6001
574 SMC 2635W
575 Linksys WPC11 v1
576 Fiberline FL-WL-200X
577 3com Office Connect (3CRSHPW796)
578 Corega WLPCIB-11
579 SMC 2602W V2 EU
580 D-Link DWL-520 Revision C
581
582 However, some of these cards have been replaced with other chips
583 like the RTL8180L (Xterasys Cardbus XN-2411b, Belkin F5D6001) or
584 the Ralink RT2400 (SMC2635W) without a model number change.
585
586 Thanks to Infineon-ADMtek for their support of this driver.
587
561source "drivers/net/wireless/hostap/Kconfig" 588source "drivers/net/wireless/hostap/Kconfig"
562source "drivers/net/wireless/bcm43xx/Kconfig" 589source "drivers/net/wireless/bcm43xx/Kconfig"
563source "drivers/net/wireless/zd1211rw/Kconfig" 590source "drivers/net/wireless/zd1211rw/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 4eb6d9752881..e9bffdae0a04 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -47,3 +47,5 @@ obj-$(CONFIG_LIBERTAS) += libertas/
47 47
48rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o 48rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
49obj-$(CONFIG_RTL8187) += rtl8187.o 49obj-$(CONFIG_RTL8187) += rtl8187.o
50
51obj-$(CONFIG_ADM8211) += adm8211.o
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
new file mode 100644
index 000000000000..eec01fc15282
--- /dev/null
+++ b/drivers/net/wireless/adm8211.c
@@ -0,0 +1,2063 @@
1
2/*
3 * Linux device driver for ADMtek ADM8211 (IEEE 802.11b MAC/BBP)
4 *
5 * Copyright (c) 2003, Jouni Malinen <j@w1.fi>
6 * Copyright (c) 2004-2007, Michael Wu <flamingice@sourmilk.net>
7 * Some parts copyright (c) 2003 by David Young <dyoung@pobox.com>
8 * and used with permission.
9 *
10 * Much thanks to Infineon-ADMtek for their support of this driver.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation. See README and COPYING for
15 * more details.
16 */
17
18#include <linux/init.h>
19#include <linux/if.h>
20#include <linux/skbuff.h>
21#include <linux/etherdevice.h>
22#include <linux/pci.h>
23#include <linux/delay.h>
24#include <linux/crc32.h>
25#include <linux/eeprom_93cx6.h>
26#include <net/mac80211.h>
27
28#include "adm8211.h"
29
30MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
31MODULE_AUTHOR("Jouni Malinen <j@w1.fi>");
32MODULE_DESCRIPTION("Driver for IEEE 802.11b wireless cards based on ADMtek ADM8211");
33MODULE_SUPPORTED_DEVICE("ADM8211");
34MODULE_LICENSE("GPL");
35
36static unsigned int tx_ring_size __read_mostly = 16;
37static unsigned int rx_ring_size __read_mostly = 16;
38
39module_param(tx_ring_size, uint, 0);
40module_param(rx_ring_size, uint, 0);
41
42static const char version[] = KERN_INFO "adm8211: "
43"Copyright 2003, Jouni Malinen <j@w1.fi>; "
44"Copyright 2004-2007, Michael Wu <flamingice@sourmilk.net>\n";
45
46
47static struct pci_device_id adm8211_pci_id_table[] __devinitdata = {
48 /* ADMtek ADM8211 */
49 { PCI_DEVICE(0x10B7, 0x6000) }, /* 3Com 3CRSHPW796 */
50 { PCI_DEVICE(0x1200, 0x8201) }, /* ? */
51 { PCI_DEVICE(0x1317, 0x8201) }, /* ADM8211A */
52 { PCI_DEVICE(0x1317, 0x8211) }, /* ADM8211B/C */
53 { 0 }
54};
55
56static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom)
57{
58 struct adm8211_priv *priv = eeprom->data;
59 u32 reg = ADM8211_CSR_READ(SPR);
60
61 eeprom->reg_data_in = reg & ADM8211_SPR_SDI;
62 eeprom->reg_data_out = reg & ADM8211_SPR_SDO;
63 eeprom->reg_data_clock = reg & ADM8211_SPR_SCLK;
64 eeprom->reg_chip_select = reg & ADM8211_SPR_SCS;
65}
66
67static void adm8211_eeprom_register_write(struct eeprom_93cx6 *eeprom)
68{
69 struct adm8211_priv *priv = eeprom->data;
70 u32 reg = 0x4000 | ADM8211_SPR_SRS;
71
72 if (eeprom->reg_data_in)
73 reg |= ADM8211_SPR_SDI;
74 if (eeprom->reg_data_out)
75 reg |= ADM8211_SPR_SDO;
76 if (eeprom->reg_data_clock)
77 reg |= ADM8211_SPR_SCLK;
78 if (eeprom->reg_chip_select)
79 reg |= ADM8211_SPR_SCS;
80
81 ADM8211_CSR_WRITE(SPR, reg);
82 ADM8211_CSR_READ(SPR); /* eeprom_delay */
83}
84
85static int adm8211_read_eeprom(struct ieee80211_hw *dev)
86{
87 struct adm8211_priv *priv = dev->priv;
88 unsigned int words, i;
89 struct ieee80211_chan_range chan_range;
90 u16 cr49;
91 struct eeprom_93cx6 eeprom = {
92 .data = priv,
93 .register_read = adm8211_eeprom_register_read,
94 .register_write = adm8211_eeprom_register_write
95 };
96
97 if (ADM8211_CSR_READ(CSR_TEST0) & ADM8211_CSR_TEST0_EPTYP) {
98 /* 256 * 16-bit = 512 bytes */
99 eeprom.width = PCI_EEPROM_WIDTH_93C66;
100 words = 256;
101 } else {
102 /* 64 * 16-bit = 128 bytes */
103 eeprom.width = PCI_EEPROM_WIDTH_93C46;
104 words = 64;
105 }
106
107 priv->eeprom_len = words * 2;
108 priv->eeprom = kmalloc(priv->eeprom_len, GFP_KERNEL);
109 if (!priv->eeprom)
110 return -ENOMEM;
111
112 eeprom_93cx6_multiread(&eeprom, 0, (__le16 __force *)priv->eeprom, words);
113
114 cr49 = le16_to_cpu(priv->eeprom->cr49);
115 priv->rf_type = (cr49 >> 3) & 0x7;
116 switch (priv->rf_type) {
117 case ADM8211_TYPE_INTERSIL:
118 case ADM8211_TYPE_RFMD:
119 case ADM8211_TYPE_MARVEL:
120 case ADM8211_TYPE_AIROHA:
121 case ADM8211_TYPE_ADMTEK:
122 break;
123
124 default:
125 if (priv->revid < ADM8211_REV_CA)
126 priv->rf_type = ADM8211_TYPE_RFMD;
127 else
128 priv->rf_type = ADM8211_TYPE_AIROHA;
129
130 printk(KERN_WARNING "%s (adm8211): Unknown RFtype %d\n",
131 pci_name(priv->pdev), (cr49 >> 3) & 0x7);
132 }
133
134 priv->bbp_type = cr49 & 0x7;
135 switch (priv->bbp_type) {
136 case ADM8211_TYPE_INTERSIL:
137 case ADM8211_TYPE_RFMD:
138 case ADM8211_TYPE_MARVEL:
139 case ADM8211_TYPE_AIROHA:
140 case ADM8211_TYPE_ADMTEK:
141 break;
142 default:
143 if (priv->revid < ADM8211_REV_CA)
144 priv->bbp_type = ADM8211_TYPE_RFMD;
145 else
146 priv->bbp_type = ADM8211_TYPE_ADMTEK;
147
148 printk(KERN_WARNING "%s (adm8211): Unknown BBPtype: %d\n",
149 pci_name(priv->pdev), cr49 >> 3);
150 }
151
152 if (priv->eeprom->country_code >= ARRAY_SIZE(cranges)) {
153 printk(KERN_WARNING "%s (adm8211): Invalid country code (%d)\n",
154 pci_name(priv->pdev), priv->eeprom->country_code);
155
156 chan_range = cranges[2];
157 } else
158 chan_range = cranges[priv->eeprom->country_code];
159
160 printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n",
161 pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max);
162
163 priv->modes[0].num_channels = chan_range.max - chan_range.min + 1;
164 priv->modes[0].channels = priv->channels;
165
166 memcpy(priv->channels, adm8211_channels, sizeof(adm8211_channels));
167
168 for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++)
169 if (i >= chan_range.min && i <= chan_range.max)
170 priv->channels[i - 1].flag =
171 IEEE80211_CHAN_W_SCAN |
172 IEEE80211_CHAN_W_ACTIVE_SCAN |
173 IEEE80211_CHAN_W_IBSS;
174
175 switch (priv->eeprom->specific_bbptype) {
176 case ADM8211_BBP_RFMD3000:
177 case ADM8211_BBP_RFMD3002:
178 case ADM8211_BBP_ADM8011:
179 priv->specific_bbptype = priv->eeprom->specific_bbptype;
180 break;
181
182 default:
183 if (priv->revid < ADM8211_REV_CA)
184 priv->specific_bbptype = ADM8211_BBP_RFMD3000;
185 else
186 priv->specific_bbptype = ADM8211_BBP_ADM8011;
187
188 printk(KERN_WARNING "%s (adm8211): Unknown specific BBP: %d\n",
189 pci_name(priv->pdev), priv->eeprom->specific_bbptype);
190 }
191
192 switch (priv->eeprom->specific_rftype) {
193 case ADM8211_RFMD2948:
194 case ADM8211_RFMD2958:
195 case ADM8211_RFMD2958_RF3000_CONTROL_POWER:
196 case ADM8211_MAX2820:
197 case ADM8211_AL2210L:
198 priv->transceiver_type = priv->eeprom->specific_rftype;
199 break;
200
201 default:
202 if (priv->revid == ADM8211_REV_BA)
203 priv->transceiver_type = ADM8211_RFMD2958_RF3000_CONTROL_POWER;
204 else if (priv->revid == ADM8211_REV_CA)
205 priv->transceiver_type = ADM8211_AL2210L;
206 else if (priv->revid == ADM8211_REV_AB)
207 priv->transceiver_type = ADM8211_RFMD2948;
208
209 printk(KERN_WARNING "%s (adm8211): Unknown transceiver: %d\n",
210 pci_name(priv->pdev), priv->eeprom->specific_rftype);
211
212 break;
213 }
214
215 printk(KERN_DEBUG "%s (adm8211): RFtype=%d BBPtype=%d Specific BBP=%d "
216 "Transceiver=%d\n", pci_name(priv->pdev), priv->rf_type,
217 priv->bbp_type, priv->specific_bbptype, priv->transceiver_type);
218
219 return 0;
220}
221
222static inline void adm8211_write_sram(struct ieee80211_hw *dev,
223 u32 addr, u32 data)
224{
225 struct adm8211_priv *priv = dev->priv;
226
227 ADM8211_CSR_WRITE(WEPCTL, addr | ADM8211_WEPCTL_TABLE_WR |
228 (priv->revid < ADM8211_REV_BA ?
229 0 : ADM8211_WEPCTL_SEL_WEPTABLE ));
230 ADM8211_CSR_READ(WEPCTL);
231 msleep(1);
232
233 ADM8211_CSR_WRITE(WESK, data);
234 ADM8211_CSR_READ(WESK);
235 msleep(1);
236}
237
238static void adm8211_write_sram_bytes(struct ieee80211_hw *dev,
239 unsigned int addr, u8 *buf,
240 unsigned int len)
241{
242 struct adm8211_priv *priv = dev->priv;
243 u32 reg = ADM8211_CSR_READ(WEPCTL);
244 unsigned int i;
245
246 if (priv->revid < ADM8211_REV_BA) {
247 for (i = 0; i < len; i += 2) {
248 u16 val = buf[i] | (buf[i + 1] << 8);
249 adm8211_write_sram(dev, addr + i / 2, val);
250 }
251 } else {
252 for (i = 0; i < len; i += 4) {
253 u32 val = (buf[i + 0] << 0 ) | (buf[i + 1] << 8 ) |
254 (buf[i + 2] << 16) | (buf[i + 3] << 24);
255 adm8211_write_sram(dev, addr + i / 4, val);
256 }
257 }
258
259 ADM8211_CSR_WRITE(WEPCTL, reg);
260}
261
262static void adm8211_clear_sram(struct ieee80211_hw *dev)
263{
264 struct adm8211_priv *priv = dev->priv;
265 u32 reg = ADM8211_CSR_READ(WEPCTL);
266 unsigned int addr;
267
268 for (addr = 0; addr < ADM8211_SRAM_SIZE; addr++)
269 adm8211_write_sram(dev, addr, 0);
270
271 ADM8211_CSR_WRITE(WEPCTL, reg);
272}
273
274static int adm8211_get_stats(struct ieee80211_hw *dev,
275 struct ieee80211_low_level_stats *stats)
276{
277 struct adm8211_priv *priv = dev->priv;
278
279 memcpy(stats, &priv->stats, sizeof(*stats));
280
281 return 0;
282}
283
284static void adm8211_set_rx_mode(struct ieee80211_hw *dev,
285 unsigned short flags, int mc_count)
286{
287 struct adm8211_priv *priv = dev->priv;
288 unsigned int bit_nr;
289 u32 mc_filter[2];
290 struct dev_mc_list *mclist;
291 void *tmp;
292
293 if (flags & IFF_PROMISC) {
294 priv->nar |= ADM8211_NAR_PR;
295 priv->nar &= ~ADM8211_NAR_MM;
296 mc_filter[1] = mc_filter[0] = ~0;
297 } else if ((flags & IFF_ALLMULTI) || (mc_count > -1)) {
298 priv->nar &= ~ADM8211_NAR_PR;
299 priv->nar |= ADM8211_NAR_MM;
300 mc_filter[1] = mc_filter[0] = ~0;
301 } else {
302 priv->nar &= ~(ADM8211_NAR_MM | ADM8211_NAR_PR);
303 mc_filter[1] = mc_filter[0] = 0;
304 mclist = NULL;
305 while ((mclist = ieee80211_get_mc_list_item(dev, mclist, &tmp))) {
306 bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
307
308 bit_nr &= 0x3F;
309 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
310 }
311 }
312
313 ADM8211_IDLE_RX();
314
315 ADM8211_CSR_WRITE(MAR0, mc_filter[0]);
316 ADM8211_CSR_WRITE(MAR1, mc_filter[1]);
317 ADM8211_CSR_READ(NAR);
318
319 if (flags & IFF_PROMISC)
320 dev->flags |= IEEE80211_HW_RX_INCLUDES_FCS;
321 else
322 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
323
324 ADM8211_RESTORE();
325}
326
327static int adm8211_get_tx_stats(struct ieee80211_hw *dev,
328 struct ieee80211_tx_queue_stats *stats)
329{
330 struct adm8211_priv *priv = dev->priv;
331 struct ieee80211_tx_queue_stats_data *data = &stats->data[0];
332
333 data->len = priv->cur_tx - priv->dirty_tx;
334 data->limit = priv->tx_ring_size - 2;
335 data->count = priv->dirty_tx;
336
337 return 0;
338}
339
340static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
341{
342 struct adm8211_priv *priv = dev->priv;
343 unsigned int dirty_tx;
344
345 spin_lock(&priv->lock);
346
347 for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) {
348 unsigned int entry = dirty_tx % priv->tx_ring_size;
349 u32 status = le32_to_cpu(priv->tx_ring[entry].status);
350 struct adm8211_tx_ring_info *info;
351 struct sk_buff *skb;
352
353 if (status & TDES0_CONTROL_OWN ||
354 !(status & TDES0_CONTROL_DONE))
355 break;
356
357 info = &priv->tx_buffers[entry];
358 skb = info->skb;
359
360 /* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */
361
362 pci_unmap_single(priv->pdev, info->mapping,
363 info->skb->len, PCI_DMA_TODEVICE);
364
365 if (info->tx_control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) {
366 struct ieee80211_tx_status tx_status = {{0}};
367 struct ieee80211_hdr *hdr;
368 size_t hdrlen = info->hdrlen;
369
370 skb_pull(skb, sizeof(struct adm8211_tx_hdr));
371 hdr = (struct ieee80211_hdr *)skb_push(skb, hdrlen);
372 memcpy(hdr, skb->cb, hdrlen);
373 memcpy(&tx_status.control, &info->tx_control,
374 sizeof(tx_status.control));
375 if (!(status & TDES0_STATUS_ES))
376 tx_status.flags |= IEEE80211_TX_STATUS_ACK;
377 ieee80211_tx_status_irqsafe(dev, skb, &tx_status);
378 } else
379 dev_kfree_skb_irq(skb);
380 info->skb = NULL;
381 }
382
383 if (priv->cur_tx - dirty_tx < priv->tx_ring_size - 2)
384 ieee80211_wake_queue(dev, 0);
385
386 priv->dirty_tx = dirty_tx;
387 spin_unlock(&priv->lock);
388}
389
390
391static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
392{
393 struct adm8211_priv *priv = dev->priv;
394 unsigned int entry = priv->cur_rx % priv->rx_ring_size;
395 u32 status;
396 unsigned int pktlen;
397 struct sk_buff *skb, *newskb;
398 unsigned int limit = priv->rx_ring_size;
399 static const u8 rate_tbl[] = {10, 20, 55, 110, 220};
400 u8 rssi, rate;
401
402 while (!(priv->rx_ring[entry].status & cpu_to_le32(RDES0_STATUS_OWN))) {
403 if (!limit--)
404 break;
405
406 status = le32_to_cpu(priv->rx_ring[entry].status);
407 rate = (status & RDES0_STATUS_RXDR) >> 12;
408 rssi = le32_to_cpu(priv->rx_ring[entry].length) &
409 RDES1_STATUS_RSSI;
410
411 pktlen = status & RDES0_STATUS_FL;
412 if (pktlen > RX_PKT_SIZE) {
413 if (net_ratelimit())
414 printk(KERN_DEBUG "%s: frame too long (%d)\n",
415 wiphy_name(dev->wiphy), pktlen);
416 pktlen = RX_PKT_SIZE;
417 }
418
419 if (!priv->soft_rx_crc && status & RDES0_STATUS_ES) {
420 skb = NULL; /* old buffer will be reused */
421 /* TODO: update RX error stats */
422 /* TODO: check RDES0_STATUS_CRC*E */
423 } else if (pktlen < RX_COPY_BREAK) {
424 skb = dev_alloc_skb(pktlen);
425 if (skb) {
426 pci_dma_sync_single_for_cpu(
427 priv->pdev,
428 priv->rx_buffers[entry].mapping,
429 pktlen, PCI_DMA_FROMDEVICE);
430 memcpy(skb_put(skb, pktlen),
431 skb_tail_pointer(priv->rx_buffers[entry].skb),
432 pktlen);
433 pci_dma_sync_single_for_device(
434 priv->pdev,
435 priv->rx_buffers[entry].mapping,
436 RX_PKT_SIZE, PCI_DMA_FROMDEVICE);
437 }
438 } else {
439 newskb = dev_alloc_skb(RX_PKT_SIZE);
440 if (newskb) {
441 skb = priv->rx_buffers[entry].skb;
442 skb_put(skb, pktlen);
443 pci_unmap_single(
444 priv->pdev,
445 priv->rx_buffers[entry].mapping,
446 RX_PKT_SIZE, PCI_DMA_FROMDEVICE);
447 priv->rx_buffers[entry].skb = newskb;
448 priv->rx_buffers[entry].mapping =
449 pci_map_single(priv->pdev,
450 skb_tail_pointer(newskb),
451 RX_PKT_SIZE,
452 PCI_DMA_FROMDEVICE);
453 } else {
454 skb = NULL;
455 /* TODO: update rx dropped stats */
456 }
457
458 priv->rx_ring[entry].buffer1 =
459 cpu_to_le32(priv->rx_buffers[entry].mapping);
460 }
461
462 priv->rx_ring[entry].status = cpu_to_le32(RDES0_STATUS_OWN |
463 RDES0_STATUS_SQL);
464 priv->rx_ring[entry].length =
465 cpu_to_le32(RX_PKT_SIZE |
466 (entry == priv->rx_ring_size - 1 ?
467 RDES1_CONTROL_RER : 0));
468
469 if (skb) {
470 struct ieee80211_rx_status rx_status = {0};
471
472 if (priv->revid < ADM8211_REV_CA)
473 rx_status.ssi = rssi;
474 else
475 rx_status.ssi = 100 - rssi;
476
477 if (rate <= 4)
478 rx_status.rate = rate_tbl[rate];
479
480 rx_status.channel = priv->channel;
481 rx_status.freq = adm8211_channels[priv->channel - 1].freq;
482 rx_status.phymode = MODE_IEEE80211B;
483
484 ieee80211_rx_irqsafe(dev, skb, &rx_status);
485 }
486
487 entry = (++priv->cur_rx) % priv->rx_ring_size;
488 }
489
490 /* TODO: check LPC and update stats? */
491}
492
493
494static irqreturn_t adm8211_interrupt(int irq, void *dev_id)
495{
496#define ADM8211_INT(x) \
497do { \
498 if (unlikely(stsr & ADM8211_STSR_ ## x)) \
499 printk(KERN_DEBUG "%s: " #x "\n", wiphy_name(dev->wiphy)); \
500} while (0)
501
502 struct ieee80211_hw *dev = dev_id;
503 struct adm8211_priv *priv = dev->priv;
504 unsigned int count = 0;
505 u32 stsr;
506
507 do {
508 stsr = ADM8211_CSR_READ(STSR);
509 ADM8211_CSR_WRITE(STSR, stsr);
510 if (stsr == 0xffffffff)
511 return IRQ_HANDLED;
512
513 if (!(stsr & (ADM8211_STSR_NISS | ADM8211_STSR_AISS)))
514 break;
515
516 if (stsr & ADM8211_STSR_RCI)
517 adm8211_interrupt_rci(dev);
518 if (stsr & ADM8211_STSR_TCI)
519 adm8211_interrupt_tci(dev);
520
521 /*ADM8211_INT(LinkOn);*/
522 /*ADM8211_INT(LinkOff);*/
523
524 ADM8211_INT(PCF);
525 ADM8211_INT(BCNTC);
526 ADM8211_INT(GPINT);
527 ADM8211_INT(ATIMTC);
528 ADM8211_INT(TSFTF);
529 ADM8211_INT(TSCZ);
530 ADM8211_INT(SQL);
531 ADM8211_INT(WEPTD);
532 ADM8211_INT(ATIME);
533 /*ADM8211_INT(TBTT);*/
534 ADM8211_INT(TEIS);
535 ADM8211_INT(FBE);
536 ADM8211_INT(REIS);
537 ADM8211_INT(GPTT);
538 ADM8211_INT(RPS);
539 ADM8211_INT(RDU);
540 ADM8211_INT(TUF);
541 /*ADM8211_INT(TRT);*/
542 /*ADM8211_INT(TLT);*/
543 /*ADM8211_INT(TDU);*/
544 ADM8211_INT(TPS);
545
546 } while (count++ < 20);
547
548 return IRQ_RETVAL(count);
549
550#undef ADM8211_INT
551}
552
553#define WRITE_SYN(name,v_mask,v_shift,a_mask,a_shift,bits,prewrite,postwrite)\
554static void adm8211_rf_write_syn_ ## name (struct ieee80211_hw *dev, \
555 u16 addr, u32 value) { \
556 struct adm8211_priv *priv = dev->priv; \
557 unsigned int i; \
558 u32 reg, bitbuf; \
559 \
560 value &= v_mask; \
561 addr &= a_mask; \
562 bitbuf = (value << v_shift) | (addr << a_shift); \
563 \
564 ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_IF_SELECT_1); \
565 ADM8211_CSR_READ(SYNRF); \
566 ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_IF_SELECT_0); \
567 ADM8211_CSR_READ(SYNRF); \
568 \
569 if (prewrite) { \
570 ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_WRITE_SYNDATA_0); \
571 ADM8211_CSR_READ(SYNRF); \
572 } \
573 \
574 for (i = 0; i <= bits; i++) { \
575 if (bitbuf & (1 << (bits - i))) \
576 reg = ADM8211_SYNRF_WRITE_SYNDATA_1; \
577 else \
578 reg = ADM8211_SYNRF_WRITE_SYNDATA_0; \
579 \
580 ADM8211_CSR_WRITE(SYNRF, reg); \
581 ADM8211_CSR_READ(SYNRF); \
582 \
583 ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_WRITE_CLOCK_1); \
584 ADM8211_CSR_READ(SYNRF); \
585 ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_WRITE_CLOCK_0); \
586 ADM8211_CSR_READ(SYNRF); \
587 } \
588 \
589 if (postwrite == 1) { \
590 ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_IF_SELECT_0); \
591 ADM8211_CSR_READ(SYNRF); \
592 } \
593 if (postwrite == 2) { \
594 ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_IF_SELECT_1); \
595 ADM8211_CSR_READ(SYNRF); \
596 } \
597 \
598 ADM8211_CSR_WRITE(SYNRF, 0); \
599 ADM8211_CSR_READ(SYNRF); \
600}
601
602WRITE_SYN(max2820, 0x00FFF, 0, 0x0F, 12, 15, 1, 1)
603WRITE_SYN(al2210l, 0xFFFFF, 4, 0x0F, 0, 23, 1, 1)
604WRITE_SYN(rfmd2958, 0x3FFFF, 0, 0x1F, 18, 23, 0, 1)
605WRITE_SYN(rfmd2948, 0x0FFFF, 4, 0x0F, 0, 21, 0, 2)
606
607#undef WRITE_SYN
608
609static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data)
610{
611 struct adm8211_priv *priv = dev->priv;
612 unsigned int timeout;
613 u32 reg;
614
615 timeout = 10;
616 while (timeout > 0) {
617 reg = ADM8211_CSR_READ(BBPCTL);
618 if (!(reg & (ADM8211_BBPCTL_WR | ADM8211_BBPCTL_RD)))
619 break;
620 timeout--;
621 msleep(2);
622 }
623
624 if (timeout == 0) {
625 printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed"
626 " prewrite (reg=0x%08x)\n",
627 wiphy_name(dev->wiphy), addr, data, reg);
628 return -ETIMEDOUT;
629 }
630
631 switch (priv->bbp_type) {
632 case ADM8211_TYPE_INTERSIL:
633 reg = ADM8211_BBPCTL_MMISEL; /* three wire interface */
634 break;
635 case ADM8211_TYPE_RFMD:
636 reg = (0x20 << 24) | ADM8211_BBPCTL_TXCE | ADM8211_BBPCTL_CCAP |
637 (0x01 << 18);
638 break;
639 case ADM8211_TYPE_ADMTEK:
640 reg = (0x20 << 24) | ADM8211_BBPCTL_TXCE | ADM8211_BBPCTL_CCAP |
641 (0x05 << 18);
642 break;
643 }
644 reg |= ADM8211_BBPCTL_WR | (addr << 8) | data;
645
646 ADM8211_CSR_WRITE(BBPCTL, reg);
647
648 timeout = 10;
649 while (timeout > 0) {
650 reg = ADM8211_CSR_READ(BBPCTL);
651 if (!(reg & ADM8211_BBPCTL_WR))
652 break;
653 timeout--;
654 msleep(2);
655 }
656
657 if (timeout == 0) {
658 ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) &
659 ~ADM8211_BBPCTL_WR);
660 printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed"
661 " postwrite (reg=0x%08x)\n",
662 wiphy_name(dev->wiphy), addr, data, reg);
663 return -ETIMEDOUT;
664 }
665
666 return 0;
667}
668
669static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
670{
671 static const u32 adm8211_rfmd2958_reg5[] =
672 {0x22BD, 0x22D2, 0x22E8, 0x22FE, 0x2314, 0x232A, 0x2340,
673 0x2355, 0x236B, 0x2381, 0x2397, 0x23AD, 0x23C2, 0x23F7};
674 static const u32 adm8211_rfmd2958_reg6[] =
675 {0x05D17, 0x3A2E8, 0x2E8BA, 0x22E8B, 0x1745D, 0x0BA2E, 0x00000,
676 0x345D1, 0x28BA2, 0x1D174, 0x11745, 0x05D17, 0x3A2E8, 0x11745};
677
678 struct adm8211_priv *priv = dev->priv;
679 u8 ant_power = priv->ant_power > 0x3F ?
680 priv->eeprom->antenna_power[chan - 1] : priv->ant_power;
681 u8 tx_power = priv->tx_power > 0x3F ?
682 priv->eeprom->tx_power[chan - 1] : priv->tx_power;
683 u8 lpf_cutoff = priv->lpf_cutoff == 0xFF ?
684 priv->eeprom->lpf_cutoff[chan - 1] : priv->lpf_cutoff;
685 u8 lnags_thresh = priv->lnags_threshold == 0xFF ?
686 priv->eeprom->lnags_threshold[chan - 1] : priv->lnags_threshold;
687 u32 reg;
688
689 ADM8211_IDLE();
690
691 /* Program synthesizer to new channel */
692 switch (priv->transceiver_type) {
693 case ADM8211_RFMD2958:
694 case ADM8211_RFMD2958_RF3000_CONTROL_POWER:
695 adm8211_rf_write_syn_rfmd2958(dev, 0x00, 0x04007);
696 adm8211_rf_write_syn_rfmd2958(dev, 0x02, 0x00033);
697
698 adm8211_rf_write_syn_rfmd2958(dev, 0x05,
699 adm8211_rfmd2958_reg5[chan - 1]);
700 adm8211_rf_write_syn_rfmd2958(dev, 0x06,
701 adm8211_rfmd2958_reg6[chan - 1]);
702 break;
703
704 case ADM8211_RFMD2948:
705 adm8211_rf_write_syn_rfmd2948(dev, SI4126_MAIN_CONF,
706 SI4126_MAIN_XINDIV2);
707 adm8211_rf_write_syn_rfmd2948(dev, SI4126_POWERDOWN,
708 SI4126_POWERDOWN_PDIB |
709 SI4126_POWERDOWN_PDRB);
710 adm8211_rf_write_syn_rfmd2948(dev, SI4126_PHASE_DET_GAIN, 0);
711 adm8211_rf_write_syn_rfmd2948(dev, SI4126_RF2_N_DIV,
712 (chan == 14 ?
713 2110 : (2033 + (chan * 5))));
714 adm8211_rf_write_syn_rfmd2948(dev, SI4126_IF_N_DIV, 1496);
715 adm8211_rf_write_syn_rfmd2948(dev, SI4126_RF2_R_DIV, 44);
716 adm8211_rf_write_syn_rfmd2948(dev, SI4126_IF_R_DIV, 44);
717 break;
718
719 case ADM8211_MAX2820:
720 adm8211_rf_write_syn_max2820(dev, 0x3,
721 (chan == 14 ? 0x054 : (0x7 + (chan * 5))));
722 break;
723
724 case ADM8211_AL2210L:
725 adm8211_rf_write_syn_al2210l(dev, 0x0,
726 (chan == 14 ? 0x229B4 : (0x22967 + (chan * 5))));
727 break;
728
729 default:
730 printk(KERN_DEBUG "%s: unsupported transceiver type %d\n",
731 wiphy_name(dev->wiphy), priv->transceiver_type);
732 break;
733 }
734
735 /* write BBP regs */
736 if (priv->bbp_type == ADM8211_TYPE_RFMD) {
737
738 /* SMC 2635W specific? adm8211b doesn't use the 2948 though.. */
739 /* TODO: remove if SMC 2635W doesn't need this */
740 if (priv->transceiver_type == ADM8211_RFMD2948) {
741 reg = ADM8211_CSR_READ(GPIO);
742 reg &= 0xfffc0000;
743 reg |= ADM8211_CSR_GPIO_EN0;
744 if (chan != 14)
745 reg |= ADM8211_CSR_GPIO_O0;
746 ADM8211_CSR_WRITE(GPIO, reg);
747 }
748
749 if (priv->transceiver_type == ADM8211_RFMD2958) {
750 /* set PCNT2 */
751 adm8211_rf_write_syn_rfmd2958(dev, 0x0B, 0x07100);
752 /* set PCNT1 P_DESIRED/MID_BIAS */
753 reg = le16_to_cpu(priv->eeprom->cr49);
754 reg >>= 13;
755 reg <<= 15;
756 reg |= ant_power << 9;
757 adm8211_rf_write_syn_rfmd2958(dev, 0x0A, reg);
758 /* set TXRX TX_GAIN */
759 adm8211_rf_write_syn_rfmd2958(dev, 0x09, 0x00050 |
760 (priv->revid < ADM8211_REV_CA ? tx_power : 0));
761 } else {
762 reg = ADM8211_CSR_READ(PLCPHD);
763 reg &= 0xff00ffff;
764 reg |= tx_power << 18;
765 ADM8211_CSR_WRITE(PLCPHD, reg);
766 }
767
768 ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_SELRF |
769 ADM8211_SYNRF_PE1 | ADM8211_SYNRF_PHYRST);
770 ADM8211_CSR_READ(SYNRF);
771 msleep(30);
772
773 /* RF3000 BBP */
774 if (priv->transceiver_type != ADM8211_RFMD2958)
775 adm8211_write_bbp(dev, RF3000_TX_VAR_GAIN__TX_LEN_EXT,
776 tx_power<<2);
777 adm8211_write_bbp(dev, RF3000_LOW_GAIN_CALIB, lpf_cutoff);
778 adm8211_write_bbp(dev, RF3000_HIGH_GAIN_CALIB, lnags_thresh);
779 adm8211_write_bbp(dev, 0x1c, priv->revid == ADM8211_REV_BA ?
780 priv->eeprom->cr28 : 0);
781 adm8211_write_bbp(dev, 0x1d, priv->eeprom->cr29);
782
783 ADM8211_CSR_WRITE(SYNRF, 0);
784
785 /* Nothing to do for ADMtek BBP */
786 } else if (priv->bbp_type != ADM8211_TYPE_ADMTEK)
787 printk(KERN_DEBUG "%s: unsupported BBP type %d\n",
788 wiphy_name(dev->wiphy), priv->bbp_type);
789
790 ADM8211_RESTORE();
791
792 /* update current channel for adhoc (and maybe AP mode) */
793 reg = ADM8211_CSR_READ(CAP0);
794 reg &= ~0xF;
795 reg |= chan;
796 ADM8211_CSR_WRITE(CAP0, reg);
797
798 return 0;
799}
800
801static void adm8211_update_mode(struct ieee80211_hw *dev)
802{
803 struct adm8211_priv *priv = dev->priv;
804
805 ADM8211_IDLE();
806
807 priv->soft_rx_crc = 0;
808 switch (priv->mode) {
809 case IEEE80211_IF_TYPE_STA:
810 priv->nar &= ~(ADM8211_NAR_PR | ADM8211_NAR_EA);
811 priv->nar |= ADM8211_NAR_ST | ADM8211_NAR_SR;
812 break;
813 case IEEE80211_IF_TYPE_IBSS:
814 priv->nar &= ~ADM8211_NAR_PR;
815 priv->nar |= ADM8211_NAR_EA | ADM8211_NAR_ST | ADM8211_NAR_SR;
816
817 /* don't trust the error bits on rev 0x20 and up in adhoc */
818 if (priv->revid >= ADM8211_REV_BA)
819 priv->soft_rx_crc = 1;
820 break;
821 case IEEE80211_IF_TYPE_MNTR:
822 priv->nar &= ~(ADM8211_NAR_EA | ADM8211_NAR_ST);
823 priv->nar |= ADM8211_NAR_PR | ADM8211_NAR_SR;
824 break;
825 }
826
827 ADM8211_RESTORE();
828}
829
830static void adm8211_hw_init_syn(struct ieee80211_hw *dev)
831{
832 struct adm8211_priv *priv = dev->priv;
833
834 switch (priv->transceiver_type) {
835 case ADM8211_RFMD2958:
836 case ADM8211_RFMD2958_RF3000_CONTROL_POWER:
837 /* comments taken from ADMtek vendor driver */
838
839 /* Reset RF2958 after power on */
840 adm8211_rf_write_syn_rfmd2958(dev, 0x1F, 0x00000);
841 /* Initialize RF VCO Core Bias to maximum */
842 adm8211_rf_write_syn_rfmd2958(dev, 0x0C, 0x3001F);
843 /* Initialize IF PLL */
844 adm8211_rf_write_syn_rfmd2958(dev, 0x01, 0x29C03);
845 /* Initialize IF PLL Coarse Tuning */
846 adm8211_rf_write_syn_rfmd2958(dev, 0x03, 0x1FF6F);
847 /* Initialize RF PLL */
848 adm8211_rf_write_syn_rfmd2958(dev, 0x04, 0x29403);
849 /* Initialize RF PLL Coarse Tuning */
850 adm8211_rf_write_syn_rfmd2958(dev, 0x07, 0x1456F);
851 /* Initialize TX gain and filter BW (R9) */
852 adm8211_rf_write_syn_rfmd2958(dev, 0x09,
853 (priv->transceiver_type == ADM8211_RFMD2958 ?
854 0x10050 : 0x00050));
855 /* Initialize CAL register */
856 adm8211_rf_write_syn_rfmd2958(dev, 0x08, 0x3FFF8);
857 break;
858
859 case ADM8211_MAX2820:
860 adm8211_rf_write_syn_max2820(dev, 0x1, 0x01E);
861 adm8211_rf_write_syn_max2820(dev, 0x2, 0x001);
862 adm8211_rf_write_syn_max2820(dev, 0x3, 0x054);
863 adm8211_rf_write_syn_max2820(dev, 0x4, 0x310);
864 adm8211_rf_write_syn_max2820(dev, 0x5, 0x000);
865 break;
866
867 case ADM8211_AL2210L:
868 adm8211_rf_write_syn_al2210l(dev, 0x0, 0x0196C);
869 adm8211_rf_write_syn_al2210l(dev, 0x1, 0x007CB);
870 adm8211_rf_write_syn_al2210l(dev, 0x2, 0x3582F);
871 adm8211_rf_write_syn_al2210l(dev, 0x3, 0x010A9);
872 adm8211_rf_write_syn_al2210l(dev, 0x4, 0x77280);
873 adm8211_rf_write_syn_al2210l(dev, 0x5, 0x45641);
874 adm8211_rf_write_syn_al2210l(dev, 0x6, 0xEA130);
875 adm8211_rf_write_syn_al2210l(dev, 0x7, 0x80000);
876 adm8211_rf_write_syn_al2210l(dev, 0x8, 0x7850F);
877 adm8211_rf_write_syn_al2210l(dev, 0x9, 0xF900C);
878 adm8211_rf_write_syn_al2210l(dev, 0xA, 0x00000);
879 adm8211_rf_write_syn_al2210l(dev, 0xB, 0x00000);
880 break;
881
882 case ADM8211_RFMD2948:
883 default:
884 break;
885 }
886}
887
888static int adm8211_hw_init_bbp(struct ieee80211_hw *dev)
889{
890 struct adm8211_priv *priv = dev->priv;
891 u32 reg;
892
893 /* write addresses */
894 if (priv->bbp_type == ADM8211_TYPE_INTERSIL) {
895 ADM8211_CSR_WRITE(MMIWA, 0x100E0C0A);
896 ADM8211_CSR_WRITE(MMIRD0, 0x00007C7E);
897 ADM8211_CSR_WRITE(MMIRD1, 0x00100000);
898 } else if (priv->bbp_type == ADM8211_TYPE_RFMD ||
899 priv->bbp_type == ADM8211_TYPE_ADMTEK) {
900 /* check specific BBP type */
901 switch (priv->specific_bbptype) {
902 case ADM8211_BBP_RFMD3000:
903 case ADM8211_BBP_RFMD3002:
904 ADM8211_CSR_WRITE(MMIWA, 0x00009101);
905 ADM8211_CSR_WRITE(MMIRD0, 0x00000301);
906 break;
907
908 case ADM8211_BBP_ADM8011:
909 ADM8211_CSR_WRITE(MMIWA, 0x00008903);
910 ADM8211_CSR_WRITE(MMIRD0, 0x00001716);
911
912 reg = ADM8211_CSR_READ(BBPCTL);
913 reg &= ~ADM8211_BBPCTL_TYPE;
914 reg |= 0x5 << 18;
915 ADM8211_CSR_WRITE(BBPCTL, reg);
916 break;
917 }
918
919 switch (priv->revid) {
920 case ADM8211_REV_CA:
921 if (priv->transceiver_type == ADM8211_RFMD2958 ||
922 priv->transceiver_type == ADM8211_RFMD2958_RF3000_CONTROL_POWER ||
923 priv->transceiver_type == ADM8211_RFMD2948)
924 ADM8211_CSR_WRITE(SYNCTL, 0x1 << 22);
925 else if (priv->transceiver_type == ADM8211_MAX2820 ||
926 priv->transceiver_type == ADM8211_AL2210L)
927 ADM8211_CSR_WRITE(SYNCTL, 0x3 << 22);
928 break;
929
930 case ADM8211_REV_BA:
931 reg = ADM8211_CSR_READ(MMIRD1);
932 reg &= 0x0000FFFF;
933 reg |= 0x7e100000;
934 ADM8211_CSR_WRITE(MMIRD1, reg);
935 break;
936
937 case ADM8211_REV_AB:
938 case ADM8211_REV_AF:
939 default:
940 ADM8211_CSR_WRITE(MMIRD1, 0x7e100000);
941 break;
942 }
943
944 /* For RFMD */
945 ADM8211_CSR_WRITE(MACTEST, 0x800);
946 }
947
948 adm8211_hw_init_syn(dev);
949
950 /* Set RF Power control IF pin to PE1+PHYRST# */
951 ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_SELRF |
952 ADM8211_SYNRF_PE1 | ADM8211_SYNRF_PHYRST);
953 ADM8211_CSR_READ(SYNRF);
954 msleep(20);
955
956 /* write BBP regs */
957 if (priv->bbp_type == ADM8211_TYPE_RFMD) {
958 /* RF3000 BBP */
959 /* another set:
960 * 11: c8
961 * 14: 14
962 * 15: 50 (chan 1..13; chan 14: d0)
963 * 1c: 00
964 * 1d: 84
965 */
966 adm8211_write_bbp(dev, RF3000_CCA_CTRL, 0x80);
967 /* antenna selection: diversity */
968 adm8211_write_bbp(dev, RF3000_DIVERSITY__RSSI, 0x80);
969 adm8211_write_bbp(dev, RF3000_TX_VAR_GAIN__TX_LEN_EXT, 0x74);
970 adm8211_write_bbp(dev, RF3000_LOW_GAIN_CALIB, 0x38);
971 adm8211_write_bbp(dev, RF3000_HIGH_GAIN_CALIB, 0x40);
972
973 if (priv->eeprom->major_version < 2) {
974 adm8211_write_bbp(dev, 0x1c, 0x00);
975 adm8211_write_bbp(dev, 0x1d, 0x80);
976 } else {
977 if (priv->revid == ADM8211_REV_BA)
978 adm8211_write_bbp(dev, 0x1c, priv->eeprom->cr28);
979 else
980 adm8211_write_bbp(dev, 0x1c, 0x00);
981
982 adm8211_write_bbp(dev, 0x1d, priv->eeprom->cr29);
983 }
984 } else if (priv->bbp_type == ADM8211_TYPE_ADMTEK) {
985 /* reset baseband */
986 adm8211_write_bbp(dev, 0x00, 0xFF);
987 /* antenna selection: diversity */
988 adm8211_write_bbp(dev, 0x07, 0x0A);
989
990 /* TODO: find documentation for this */
991 switch (priv->transceiver_type) {
992 case ADM8211_RFMD2958:
993 case ADM8211_RFMD2958_RF3000_CONTROL_POWER:
994 adm8211_write_bbp(dev, 0x00, 0x00);
995 adm8211_write_bbp(dev, 0x01, 0x00);
996 adm8211_write_bbp(dev, 0x02, 0x00);
997 adm8211_write_bbp(dev, 0x03, 0x00);
998 adm8211_write_bbp(dev, 0x06, 0x0f);
999 adm8211_write_bbp(dev, 0x09, 0x00);
1000 adm8211_write_bbp(dev, 0x0a, 0x00);
1001 adm8211_write_bbp(dev, 0x0b, 0x00);
1002 adm8211_write_bbp(dev, 0x0c, 0x00);
1003 adm8211_write_bbp(dev, 0x0f, 0xAA);
1004 adm8211_write_bbp(dev, 0x10, 0x8c);
1005 adm8211_write_bbp(dev, 0x11, 0x43);
1006 adm8211_write_bbp(dev, 0x18, 0x40);
1007 adm8211_write_bbp(dev, 0x20, 0x23);
1008 adm8211_write_bbp(dev, 0x21, 0x02);
1009 adm8211_write_bbp(dev, 0x22, 0x28);
1010 adm8211_write_bbp(dev, 0x23, 0x30);
1011 adm8211_write_bbp(dev, 0x24, 0x2d);
1012 adm8211_write_bbp(dev, 0x28, 0x35);
1013 adm8211_write_bbp(dev, 0x2a, 0x8c);
1014 adm8211_write_bbp(dev, 0x2b, 0x81);
1015 adm8211_write_bbp(dev, 0x2c, 0x44);
1016 adm8211_write_bbp(dev, 0x2d, 0x0A);
1017 adm8211_write_bbp(dev, 0x29, 0x40);
1018 adm8211_write_bbp(dev, 0x60, 0x08);
1019 adm8211_write_bbp(dev, 0x64, 0x01);
1020 break;
1021
1022 case ADM8211_MAX2820:
1023 adm8211_write_bbp(dev, 0x00, 0x00);
1024 adm8211_write_bbp(dev, 0x01, 0x00);
1025 adm8211_write_bbp(dev, 0x02, 0x00);
1026 adm8211_write_bbp(dev, 0x03, 0x00);
1027 adm8211_write_bbp(dev, 0x06, 0x0f);
1028 adm8211_write_bbp(dev, 0x09, 0x05);
1029 adm8211_write_bbp(dev, 0x0a, 0x02);
1030 adm8211_write_bbp(dev, 0x0b, 0x00);
1031 adm8211_write_bbp(dev, 0x0c, 0x0f);
1032 adm8211_write_bbp(dev, 0x0f, 0x55);
1033 adm8211_write_bbp(dev, 0x10, 0x8d);
1034 adm8211_write_bbp(dev, 0x11, 0x43);
1035 adm8211_write_bbp(dev, 0x18, 0x4a);
1036 adm8211_write_bbp(dev, 0x20, 0x20);
1037 adm8211_write_bbp(dev, 0x21, 0x02);
1038 adm8211_write_bbp(dev, 0x22, 0x23);
1039 adm8211_write_bbp(dev, 0x23, 0x30);
1040 adm8211_write_bbp(dev, 0x24, 0x2d);
1041 adm8211_write_bbp(dev, 0x2a, 0x8c);
1042 adm8211_write_bbp(dev, 0x2b, 0x81);
1043 adm8211_write_bbp(dev, 0x2c, 0x44);
1044 adm8211_write_bbp(dev, 0x29, 0x4a);
1045 adm8211_write_bbp(dev, 0x60, 0x2b);
1046 adm8211_write_bbp(dev, 0x64, 0x01);
1047 break;
1048
1049 case ADM8211_AL2210L:
1050 adm8211_write_bbp(dev, 0x00, 0x00);
1051 adm8211_write_bbp(dev, 0x01, 0x00);
1052 adm8211_write_bbp(dev, 0x02, 0x00);
1053 adm8211_write_bbp(dev, 0x03, 0x00);
1054 adm8211_write_bbp(dev, 0x06, 0x0f);
1055 adm8211_write_bbp(dev, 0x07, 0x05);
1056 adm8211_write_bbp(dev, 0x08, 0x03);
1057 adm8211_write_bbp(dev, 0x09, 0x00);
1058 adm8211_write_bbp(dev, 0x0a, 0x00);
1059 adm8211_write_bbp(dev, 0x0b, 0x00);
1060 adm8211_write_bbp(dev, 0x0c, 0x10);
1061 adm8211_write_bbp(dev, 0x0f, 0x55);
1062 adm8211_write_bbp(dev, 0x10, 0x8d);
1063 adm8211_write_bbp(dev, 0x11, 0x43);
1064 adm8211_write_bbp(dev, 0x18, 0x4a);
1065 adm8211_write_bbp(dev, 0x20, 0x20);
1066 adm8211_write_bbp(dev, 0x21, 0x02);
1067 adm8211_write_bbp(dev, 0x22, 0x23);
1068 adm8211_write_bbp(dev, 0x23, 0x30);
1069 adm8211_write_bbp(dev, 0x24, 0x2d);
1070 adm8211_write_bbp(dev, 0x2a, 0xaa);
1071 adm8211_write_bbp(dev, 0x2b, 0x81);
1072 adm8211_write_bbp(dev, 0x2c, 0x44);
1073 adm8211_write_bbp(dev, 0x29, 0xfa);
1074 adm8211_write_bbp(dev, 0x60, 0x2d);
1075 adm8211_write_bbp(dev, 0x64, 0x01);
1076 break;
1077
1078 case ADM8211_RFMD2948:
1079 break;
1080
1081 default:
1082 printk(KERN_DEBUG "%s: unsupported transceiver %d\n",
1083 wiphy_name(dev->wiphy), priv->transceiver_type);
1084 break;
1085 }
1086 } else
1087 printk(KERN_DEBUG "%s: unsupported BBP %d\n",
1088 wiphy_name(dev->wiphy), priv->bbp_type);
1089
1090 ADM8211_CSR_WRITE(SYNRF, 0);
1091
1092 /* Set RF CAL control source to MAC control */
1093 reg = ADM8211_CSR_READ(SYNCTL);
1094 reg |= ADM8211_SYNCTL_SELCAL;
1095 ADM8211_CSR_WRITE(SYNCTL, reg);
1096
1097 return 0;
1098}
1099
1100/* configures hw beacons/probe responses */
1101static int adm8211_set_rate(struct ieee80211_hw *dev)
1102{
1103 struct adm8211_priv *priv = dev->priv;
1104 u32 reg;
1105 int i = 0;
1106 u8 rate_buf[12] = {0};
1107
1108 /* write supported rates */
1109 if (priv->revid != ADM8211_REV_BA) {
1110 rate_buf[0] = ARRAY_SIZE(adm8211_rates);
1111 for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++)
1112 rate_buf[i + 1] = (adm8211_rates[i].rate / 5) | 0x80;
1113 } else {
1114 /* workaround for rev BA specific bug */
1115 rate_buf[0] = 0x04;
1116 rate_buf[1] = 0x82;
1117 rate_buf[2] = 0x04;
1118 rate_buf[3] = 0x0b;
1119 rate_buf[4] = 0x16;
1120 }
1121
1122 adm8211_write_sram_bytes(dev, ADM8211_SRAM_SUPP_RATE, rate_buf,
1123 ARRAY_SIZE(adm8211_rates) + 1);
1124
1125 reg = ADM8211_CSR_READ(PLCPHD) & 0x00FFFFFF; /* keep bits 0-23 */
1126 reg |= 1 << 15; /* short preamble */
1127 reg |= 110 << 24;
1128 ADM8211_CSR_WRITE(PLCPHD, reg);
1129
1130 /* MTMLT = 512 TU (max TX MSDU lifetime)
1131 * BCNTSIG = plcp_signal (beacon, probe resp, and atim TX rate)
1132 * SRTYLIM = 224 (short retry limit, TX header value is default) */
1133 ADM8211_CSR_WRITE(TXLMT, (512 << 16) | (110 << 8) | (224 << 0));
1134
1135 return 0;
1136}
1137
1138static void adm8211_hw_init(struct ieee80211_hw *dev)
1139{
1140 struct adm8211_priv *priv = dev->priv;
1141 u32 reg;
1142 u8 cline;
1143
1144 reg = le32_to_cpu(ADM8211_CSR_READ(PAR));
1145 reg |= ADM8211_PAR_MRLE | ADM8211_PAR_MRME;
1146 reg &= ~(ADM8211_PAR_BAR | ADM8211_PAR_CAL);
1147
1148 if (!pci_set_mwi(priv->pdev)) {
1149 reg |= 0x1 << 24;
1150 pci_read_config_byte(priv->pdev, PCI_CACHE_LINE_SIZE, &cline);
1151
1152 switch (cline) {
1153 case 0x8: reg |= (0x1 << 14);
1154 break;
1155 case 0x16: reg |= (0x2 << 14);
1156 break;
1157 case 0x32: reg |= (0x3 << 14);
1158 break;
1159 default: reg |= (0x0 << 14);
1160 break;
1161 }
1162 }
1163
1164 ADM8211_CSR_WRITE(PAR, reg);
1165
1166 reg = ADM8211_CSR_READ(CSR_TEST1);
1167 reg &= ~(0xF << 28);
1168 reg |= (1 << 28) | (1 << 31);
1169 ADM8211_CSR_WRITE(CSR_TEST1, reg);
1170
1171 /* lose link after 4 lost beacons */
1172 reg = (0x04 << 21) | ADM8211_WCSR_TSFTWE | ADM8211_WCSR_LSOE;
1173 ADM8211_CSR_WRITE(WCSR, reg);
1174
1175 /* Disable APM, enable receive FIFO threshold, and set drain receive
1176 * threshold to store-and-forward */
1177 reg = ADM8211_CSR_READ(CMDR);
1178 reg &= ~(ADM8211_CMDR_APM | ADM8211_CMDR_DRT);
1179 reg |= ADM8211_CMDR_RTE | ADM8211_CMDR_DRT_SF;
1180 ADM8211_CSR_WRITE(CMDR, reg);
1181
1182 adm8211_set_rate(dev);
1183
1184 /* 4-bit values:
1185 * PWR1UP = 8 * 2 ms
1186 * PWR0PAPE = 8 us or 5 us
1187 * PWR1PAPE = 1 us or 3 us
1188 * PWR0TRSW = 5 us
1189 * PWR1TRSW = 12 us
1190 * PWR0PE2 = 13 us
1191 * PWR1PE2 = 1 us
1192 * PWR0TXPE = 8 or 6 */
1193 if (priv->revid < ADM8211_REV_CA)
1194 ADM8211_CSR_WRITE(TOFS2, 0x8815cd18);
1195 else
1196 ADM8211_CSR_WRITE(TOFS2, 0x8535cd16);
1197
1198 /* Enable store and forward for transmit */
1199 priv->nar = ADM8211_NAR_SF | ADM8211_NAR_PB;
1200 ADM8211_CSR_WRITE(NAR, priv->nar);
1201
1202 /* Reset RF */
1203 ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_RADIO);
1204 ADM8211_CSR_READ(SYNRF);
1205 msleep(10);
1206 ADM8211_CSR_WRITE(SYNRF, 0);
1207 ADM8211_CSR_READ(SYNRF);
1208 msleep(5);
1209
1210 /* Set CFP Max Duration to 0x10 TU */
1211 reg = ADM8211_CSR_READ(CFPP);
1212 reg &= ~(0xffff << 8);
1213 reg |= 0x0010 << 8;
1214 ADM8211_CSR_WRITE(CFPP, reg);
1215
1216 /* USCNT = 0x16 (number of system clocks, 22 MHz, in 1us
1217 * TUCNT = 0x3ff - Tu counter 1024 us */
1218 ADM8211_CSR_WRITE(TOFS0, (0x16 << 24) | 0x3ff);
1219
1220 /* SLOT=20 us, SIFS=110 cycles of 22 MHz (5 us),
1221 * DIFS=50 us, EIFS=100 us */
1222 if (priv->revid < ADM8211_REV_CA)
1223 ADM8211_CSR_WRITE(IFST, (20 << 23) | (110 << 15) |
1224 (50 << 9) | 100);
1225 else
1226 ADM8211_CSR_WRITE(IFST, (20 << 23) | (24 << 15) |
1227 (50 << 9) | 100);
1228
1229 /* PCNT = 1 (MAC idle time awake/sleep, unit S)
1230 * RMRD = 2346 * 8 + 1 us (max RX duration) */
1231 ADM8211_CSR_WRITE(RMD, (1 << 16) | 18769);
1232
1233 /* MART=65535 us, MIRT=256 us, TSFTOFST=0 us */
1234 ADM8211_CSR_WRITE(RSPT, 0xffffff00);
1235
1236 /* Initialize BBP (and SYN) */
1237 adm8211_hw_init_bbp(dev);
1238
1239 /* make sure interrupts are off */
1240 ADM8211_CSR_WRITE(IER, 0);
1241
1242 /* ACK interrupts */
1243 ADM8211_CSR_WRITE(STSR, ADM8211_CSR_READ(STSR));
1244
1245 /* Setup WEP (turns it off for now) */
1246 reg = ADM8211_CSR_READ(MACTEST);
1247 reg &= ~(7 << 20);
1248 ADM8211_CSR_WRITE(MACTEST, reg);
1249
1250 reg = ADM8211_CSR_READ(WEPCTL);
1251 reg &= ~ADM8211_WEPCTL_WEPENABLE;
1252 reg |= ADM8211_WEPCTL_WEPRXBYP;
1253 ADM8211_CSR_WRITE(WEPCTL, reg);
1254
1255 /* Clear the missed-packet counter. */
1256 ADM8211_CSR_READ(LPC);
1257
1258 if (!priv->mac_addr)
1259 return;
1260
1261 /* set mac address */
1262 ADM8211_CSR_WRITE(PAR0, *(u32 *)priv->mac_addr);
1263 ADM8211_CSR_WRITE(PAR1, *(u16 *)&priv->mac_addr[4]);
1264}
1265
1266static int adm8211_hw_reset(struct ieee80211_hw *dev)
1267{
1268 struct adm8211_priv *priv = dev->priv;
1269 u32 reg, tmp;
1270 int timeout = 100;
1271
1272 /* Power-on issue */
1273 /* TODO: check if this is necessary */
1274 ADM8211_CSR_WRITE(FRCTL, 0);
1275
1276 /* Reset the chip */
1277 tmp = ADM8211_CSR_READ(PAR);
1278 ADM8211_CSR_WRITE(PAR, ADM8211_PAR_SWR);
1279
1280 while ((ADM8211_CSR_READ(PAR) & ADM8211_PAR_SWR) && timeout--)
1281 msleep(50);
1282
1283 if (timeout <= 0)
1284 return -ETIMEDOUT;
1285
1286 ADM8211_CSR_WRITE(PAR, tmp);
1287
1288 if (priv->revid == ADM8211_REV_BA &&
1289 (priv->transceiver_type == ADM8211_RFMD2958_RF3000_CONTROL_POWER ||
1290 priv->transceiver_type == ADM8211_RFMD2958)) {
1291 reg = ADM8211_CSR_READ(CSR_TEST1);
1292 reg |= (1 << 4) | (1 << 5);
1293 ADM8211_CSR_WRITE(CSR_TEST1, reg);
1294 } else if (priv->revid == ADM8211_REV_CA) {
1295 reg = ADM8211_CSR_READ(CSR_TEST1);
1296 reg &= ~((1 << 4) | (1 << 5));
1297 ADM8211_CSR_WRITE(CSR_TEST1, reg);
1298 }
1299
1300 ADM8211_CSR_WRITE(FRCTL, 0);
1301
1302 reg = ADM8211_CSR_READ(CSR_TEST0);
1303 reg |= ADM8211_CSR_TEST0_EPRLD; /* EEPROM Recall */
1304 ADM8211_CSR_WRITE(CSR_TEST0, reg);
1305
1306 adm8211_clear_sram(dev);
1307
1308 return 0;
1309}
1310
1311static u64 adm8211_get_tsft(struct ieee80211_hw *dev)
1312{
1313 struct adm8211_priv *priv = dev->priv;
1314 u32 tsftl;
1315 u64 tsft;
1316
1317 tsftl = ADM8211_CSR_READ(TSFTL);
1318 tsft = ADM8211_CSR_READ(TSFTH);
1319 tsft <<= 32;
1320 tsft |= tsftl;
1321
1322 return tsft;
1323}
1324
1325static void adm8211_set_interval(struct ieee80211_hw *dev,
1326 unsigned short bi, unsigned short li)
1327{
1328 struct adm8211_priv *priv = dev->priv;
1329 u32 reg;
1330
1331 /* BP (beacon interval) = data->beacon_interval
1332 * LI (listen interval) = data->listen_interval (in beacon intervals) */
1333 reg = (bi << 16) | li;
1334 ADM8211_CSR_WRITE(BPLI, reg);
1335}
1336
1337static void adm8211_set_bssid(struct ieee80211_hw *dev, u8 *bssid)
1338{
1339 struct adm8211_priv *priv = dev->priv;
1340 u32 reg;
1341
1342 reg = bssid[0] | (bssid[1] << 8) | (bssid[2] << 16) | (bssid[3] << 24);
1343 ADM8211_CSR_WRITE(BSSID0, reg);
1344 reg = ADM8211_CSR_READ(ABDA1);
1345 reg &= 0x0000ffff;
1346 reg |= (bssid[4] << 16) | (bssid[5] << 24);
1347 ADM8211_CSR_WRITE(ABDA1, reg);
1348}
1349
1350static int adm8211_set_ssid(struct ieee80211_hw *dev, u8 *ssid, size_t ssid_len)
1351{
1352 struct adm8211_priv *priv = dev->priv;
1353 u8 buf[36];
1354
1355 if (ssid_len > 32)
1356 return -EINVAL;
1357
1358 memset(buf, 0, sizeof(buf));
1359 buf[0] = ssid_len;
1360 memcpy(buf + 1, ssid, ssid_len);
1361 adm8211_write_sram_bytes(dev, ADM8211_SRAM_SSID, buf, 33);
1362 /* TODO: configure beacon for adhoc? */
1363 return 0;
1364}
1365
1366static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
1367{
1368 struct adm8211_priv *priv = dev->priv;
1369
1370 if (conf->channel != priv->channel) {
1371 priv->channel = conf->channel;
1372 adm8211_rf_set_channel(dev, priv->channel);
1373 }
1374
1375 return 0;
1376}
1377
1378static int adm8211_config_interface(struct ieee80211_hw *dev, int if_id,
1379 struct ieee80211_if_conf *conf)
1380{
1381 struct adm8211_priv *priv = dev->priv;
1382
1383 if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
1384 adm8211_set_bssid(dev, conf->bssid);
1385 memcpy(priv->bssid, conf->bssid, ETH_ALEN);
1386 }
1387
1388 if (conf->ssid_len != priv->ssid_len ||
1389 memcmp(conf->ssid, priv->ssid, conf->ssid_len)) {
1390 adm8211_set_ssid(dev, conf->ssid, conf->ssid_len);
1391 priv->ssid_len = conf->ssid_len;
1392 memcpy(priv->ssid, conf->ssid, conf->ssid_len);
1393 }
1394
1395 return 0;
1396}
1397
1398static int adm8211_add_interface(struct ieee80211_hw *dev,
1399 struct ieee80211_if_init_conf *conf)
1400{
1401 struct adm8211_priv *priv = dev->priv;
1402 /* NOTE: using IEEE80211_IF_TYPE_MGMT to indicate no mode selected */
1403 if (priv->mode != IEEE80211_IF_TYPE_MGMT)
1404 return -1;
1405
1406 switch (conf->type) {
1407 case IEEE80211_IF_TYPE_STA:
1408 case IEEE80211_IF_TYPE_MNTR:
1409 priv->mode = conf->type;
1410 break;
1411 default:
1412 return -EOPNOTSUPP;
1413 }
1414
1415 priv->mac_addr = conf->mac_addr;
1416
1417 return 0;
1418}
1419
1420static void adm8211_remove_interface(struct ieee80211_hw *dev,
1421 struct ieee80211_if_init_conf *conf)
1422{
1423 struct adm8211_priv *priv = dev->priv;
1424 priv->mode = IEEE80211_IF_TYPE_MGMT;
1425}
1426
1427static int adm8211_init_rings(struct ieee80211_hw *dev)
1428{
1429 struct adm8211_priv *priv = dev->priv;
1430 struct adm8211_desc *desc = NULL;
1431 struct adm8211_rx_ring_info *rx_info;
1432 struct adm8211_tx_ring_info *tx_info;
1433 unsigned int i;
1434
1435 for (i = 0; i < priv->rx_ring_size; i++) {
1436 desc = &priv->rx_ring[i];
1437 desc->status = 0;
1438 desc->length = cpu_to_le32(RX_PKT_SIZE);
1439 priv->rx_buffers[i].skb = NULL;
1440 }
1441 /* Mark the end of RX ring; hw returns to base address after this
1442 * descriptor */
1443 desc->length |= cpu_to_le32(RDES1_CONTROL_RER);
1444
1445 for (i = 0; i < priv->rx_ring_size; i++) {
1446 desc = &priv->rx_ring[i];
1447 rx_info = &priv->rx_buffers[i];
1448
1449 rx_info->skb = dev_alloc_skb(RX_PKT_SIZE);
1450 if (rx_info->skb == NULL)
1451 break;
1452 rx_info->mapping = pci_map_single(priv->pdev,
1453 skb_tail_pointer(rx_info->skb),
1454 RX_PKT_SIZE,
1455 PCI_DMA_FROMDEVICE);
1456 desc->buffer1 = cpu_to_le32(rx_info->mapping);
1457 desc->status = cpu_to_le32(RDES0_STATUS_OWN | RDES0_STATUS_SQL);
1458 }
1459
1460 /* Setup TX ring. TX buffers descriptors will be filled in as needed */
1461 for (i = 0; i < priv->tx_ring_size; i++) {
1462 desc = &priv->tx_ring[i];
1463 tx_info = &priv->tx_buffers[i];
1464
1465 tx_info->skb = NULL;
1466 tx_info->mapping = 0;
1467 desc->status = 0;
1468 }
1469 desc->length = cpu_to_le32(TDES1_CONTROL_TER);
1470
1471 priv->cur_rx = priv->cur_tx = priv->dirty_tx = 0;
1472 ADM8211_CSR_WRITE(RDB, priv->rx_ring_dma);
1473 ADM8211_CSR_WRITE(TDBD, priv->tx_ring_dma);
1474
1475 return 0;
1476}
1477
1478static void adm8211_free_rings(struct ieee80211_hw *dev)
1479{
1480 struct adm8211_priv *priv = dev->priv;
1481 unsigned int i;
1482
1483 for (i = 0; i < priv->rx_ring_size; i++) {
1484 if (!priv->rx_buffers[i].skb)
1485 continue;
1486
1487 pci_unmap_single(
1488 priv->pdev,
1489 priv->rx_buffers[i].mapping,
1490 RX_PKT_SIZE, PCI_DMA_FROMDEVICE);
1491
1492 dev_kfree_skb(priv->rx_buffers[i].skb);
1493 }
1494
1495 for (i = 0; i < priv->tx_ring_size; i++) {
1496 if (!priv->tx_buffers[i].skb)
1497 continue;
1498
1499 pci_unmap_single(priv->pdev,
1500 priv->tx_buffers[i].mapping,
1501 priv->tx_buffers[i].skb->len,
1502 PCI_DMA_TODEVICE);
1503
1504 dev_kfree_skb(priv->tx_buffers[i].skb);
1505 }
1506}
1507
1508static int adm8211_open(struct ieee80211_hw *dev)
1509{
1510 struct adm8211_priv *priv = dev->priv;
1511 int retval;
1512
1513 /* Power up MAC and RF chips */
1514 retval = adm8211_hw_reset(dev);
1515 if (retval) {
1516 printk(KERN_ERR "%s: hardware reset failed\n",
1517 wiphy_name(dev->wiphy));
1518 goto fail;
1519 }
1520
1521 retval = adm8211_init_rings(dev);
1522 if (retval) {
1523 printk(KERN_ERR "%s: failed to initialize rings\n",
1524 wiphy_name(dev->wiphy));
1525 goto fail;
1526 }
1527
1528 /* Init hardware */
1529 adm8211_hw_init(dev);
1530 adm8211_rf_set_channel(dev, priv->channel);
1531
1532 retval = request_irq(priv->pdev->irq, &adm8211_interrupt,
1533 IRQF_SHARED, "adm8211", dev);
1534 if (retval) {
1535 printk(KERN_ERR "%s: failed to register IRQ handler\n",
1536 wiphy_name(dev->wiphy));
1537 goto fail;
1538 }
1539
1540 ADM8211_CSR_WRITE(IER, ADM8211_IER_NIE | ADM8211_IER_AIE |
1541 ADM8211_IER_RCIE | ADM8211_IER_TCIE |
1542 ADM8211_IER_TDUIE | ADM8211_IER_GPTIE);
1543 adm8211_update_mode(dev);
1544 ADM8211_CSR_WRITE(RDR, 0);
1545
1546 adm8211_set_interval(dev, 100, 10);
1547 return 0;
1548
1549fail:
1550 return retval;
1551}
1552
1553static int adm8211_stop(struct ieee80211_hw *dev)
1554{
1555 struct adm8211_priv *priv = dev->priv;
1556
1557 priv->nar = 0;
1558 ADM8211_CSR_WRITE(NAR, 0);
1559 ADM8211_CSR_WRITE(IER, 0);
1560 ADM8211_CSR_READ(NAR);
1561
1562 free_irq(priv->pdev->irq, dev);
1563
1564 adm8211_free_rings(dev);
1565 return 0;
1566}
1567
1568static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int len,
1569 int plcp_signal, int short_preamble)
1570{
1571 /* Alternative calculation from NetBSD: */
1572
1573/* IEEE 802.11b durations for DSSS PHY in microseconds */
1574#define IEEE80211_DUR_DS_LONG_PREAMBLE 144
1575#define IEEE80211_DUR_DS_SHORT_PREAMBLE 72
1576#define IEEE80211_DUR_DS_FAST_PLCPHDR 24
1577#define IEEE80211_DUR_DS_SLOW_PLCPHDR 48
1578#define IEEE80211_DUR_DS_SLOW_ACK 112
1579#define IEEE80211_DUR_DS_FAST_ACK 56
1580#define IEEE80211_DUR_DS_SLOW_CTS 112
1581#define IEEE80211_DUR_DS_FAST_CTS 56
1582#define IEEE80211_DUR_DS_SLOT 20
1583#define IEEE80211_DUR_DS_SIFS 10
1584
1585 int remainder;
1586
1587 *dur = (80 * (24 + payload_len) + plcp_signal - 1)
1588 / plcp_signal;
1589
1590 if (plcp_signal <= PLCP_SIGNAL_2M)
1591 /* 1-2Mbps WLAN: send ACK/CTS at 1Mbps */
1592 *dur += 3 * (IEEE80211_DUR_DS_SIFS +
1593 IEEE80211_DUR_DS_SHORT_PREAMBLE +
1594 IEEE80211_DUR_DS_FAST_PLCPHDR) +
1595 IEEE80211_DUR_DS_SLOW_CTS + IEEE80211_DUR_DS_SLOW_ACK;
1596 else
1597 /* 5-11Mbps WLAN: send ACK/CTS at 2Mbps */
1598 *dur += 3 * (IEEE80211_DUR_DS_SIFS +
1599 IEEE80211_DUR_DS_SHORT_PREAMBLE +
1600 IEEE80211_DUR_DS_FAST_PLCPHDR) +
1601 IEEE80211_DUR_DS_FAST_CTS + IEEE80211_DUR_DS_FAST_ACK;
1602
1603 /* lengthen duration if long preamble */
1604 if (!short_preamble)
1605 *dur += 3 * (IEEE80211_DUR_DS_LONG_PREAMBLE -
1606 IEEE80211_DUR_DS_SHORT_PREAMBLE) +
1607 3 * (IEEE80211_DUR_DS_SLOW_PLCPHDR -
1608 IEEE80211_DUR_DS_FAST_PLCPHDR);
1609
1610
1611 *plcp = (80 * len) / plcp_signal;
1612 remainder = (80 * len) % plcp_signal;
1613 if (plcp_signal == PLCP_SIGNAL_11M &&
1614 remainder <= 30 && remainder > 0)
1615 *plcp = (*plcp | 0x8000) + 1;
1616 else if (remainder)
1617 (*plcp)++;
1618}
1619
1620/* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */
1621static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
1622 u16 plcp_signal,
1623 struct ieee80211_tx_control *control,
1624 size_t hdrlen)
1625{
1626 struct adm8211_priv *priv = dev->priv;
1627 unsigned long flags;
1628 dma_addr_t mapping;
1629 unsigned int entry;
1630 u32 flag;
1631
1632 mapping = pci_map_single(priv->pdev, skb->data, skb->len,
1633 PCI_DMA_TODEVICE);
1634
1635 spin_lock_irqsave(&priv->lock, flags);
1636
1637 if (priv->cur_tx - priv->dirty_tx == priv->tx_ring_size / 2)
1638 flag = TDES1_CONTROL_IC | TDES1_CONTROL_LS | TDES1_CONTROL_FS;
1639 else
1640 flag = TDES1_CONTROL_LS | TDES1_CONTROL_FS;
1641
1642 if (priv->cur_tx - priv->dirty_tx == priv->tx_ring_size - 2)
1643 ieee80211_stop_queue(dev, 0);
1644
1645 entry = priv->cur_tx % priv->tx_ring_size;
1646
1647 priv->tx_buffers[entry].skb = skb;
1648 priv->tx_buffers[entry].mapping = mapping;
1649 memcpy(&priv->tx_buffers[entry].tx_control, control, sizeof(*control));
1650 priv->tx_buffers[entry].hdrlen = hdrlen;
1651 priv->tx_ring[entry].buffer1 = cpu_to_le32(mapping);
1652
1653 if (entry == priv->tx_ring_size - 1)
1654 flag |= TDES1_CONTROL_TER;
1655 priv->tx_ring[entry].length = cpu_to_le32(flag | skb->len);
1656
1657 /* Set TX rate (SIGNAL field in PLCP PPDU format) */
1658 flag = TDES0_CONTROL_OWN | (plcp_signal << 20) | 8 /* ? */;
1659 priv->tx_ring[entry].status = cpu_to_le32(flag);
1660
1661 priv->cur_tx++;
1662
1663 spin_unlock_irqrestore(&priv->lock, flags);
1664
1665 /* Trigger transmit poll */
1666 ADM8211_CSR_WRITE(TDR, 0);
1667}
1668
1669/* Put adm8211_tx_hdr on skb and transmit */
1670static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
1671 struct ieee80211_tx_control *control)
1672{
1673 struct adm8211_tx_hdr *txhdr;
1674 u16 fc;
1675 size_t payload_len, hdrlen;
1676 int plcp, dur, len, plcp_signal, short_preamble;
1677 struct ieee80211_hdr *hdr;
1678
1679 if (control->tx_rate < 0) {
1680 short_preamble = 1;
1681 plcp_signal = -control->tx_rate;
1682 } else {
1683 short_preamble = 0;
1684 plcp_signal = control->tx_rate;
1685 }
1686
1687 hdr = (struct ieee80211_hdr *)skb->data;
1688 fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED;
1689 hdrlen = ieee80211_get_hdrlen(fc);
1690 memcpy(skb->cb, skb->data, hdrlen);
1691 hdr = (struct ieee80211_hdr *)skb->cb;
1692 skb_pull(skb, hdrlen);
1693 payload_len = skb->len;
1694
1695 txhdr = (struct adm8211_tx_hdr *) skb_push(skb, sizeof(*txhdr));
1696 memset(txhdr, 0, sizeof(*txhdr));
1697 memcpy(txhdr->da, ieee80211_get_DA(hdr), ETH_ALEN);
1698 txhdr->signal = plcp_signal;
1699 txhdr->frame_body_size = cpu_to_le16(payload_len);
1700 txhdr->frame_control = hdr->frame_control;
1701
1702 len = hdrlen + payload_len + FCS_LEN;
1703 if (fc & IEEE80211_FCTL_PROTECTED)
1704 len += 8;
1705
1706 txhdr->frag = cpu_to_le16(0x0FFF);
1707 adm8211_calc_durations(&dur, &plcp, payload_len,
1708 len, plcp_signal, short_preamble);
1709 txhdr->plcp_frag_head_len = cpu_to_le16(plcp);
1710 txhdr->plcp_frag_tail_len = cpu_to_le16(plcp);
1711 txhdr->dur_frag_head = cpu_to_le16(dur);
1712 txhdr->dur_frag_tail = cpu_to_le16(dur);
1713
1714 txhdr->header_control = cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_EXTEND_HEADER);
1715
1716 if (short_preamble)
1717 txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE);
1718
1719 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
1720 txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS);
1721
1722 if (fc & IEEE80211_FCTL_PROTECTED)
1723 txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE);
1724
1725 txhdr->retry_limit = control->retry_limit;
1726
1727 adm8211_tx_raw(dev, skb, plcp_signal, control, hdrlen);
1728
1729 return NETDEV_TX_OK;
1730}
1731
1732static int adm8211_alloc_rings(struct ieee80211_hw *dev)
1733{
1734 struct adm8211_priv *priv = dev->priv;
1735 unsigned int ring_size;
1736
1737 priv->rx_buffers = kmalloc(sizeof(*priv->rx_buffers) * priv->rx_ring_size +
1738 sizeof(*priv->tx_buffers) * priv->tx_ring_size, GFP_KERNEL);
1739 if (!priv->rx_buffers)
1740 return -ENOMEM;
1741
1742 priv->tx_buffers = (void *)priv->rx_buffers +
1743 sizeof(*priv->rx_buffers) * priv->rx_ring_size;
1744
1745 /* Allocate TX/RX descriptors */
1746 ring_size = sizeof(struct adm8211_desc) * priv->rx_ring_size +
1747 sizeof(struct adm8211_desc) * priv->tx_ring_size;
1748 priv->rx_ring = pci_alloc_consistent(priv->pdev, ring_size,
1749 &priv->rx_ring_dma);
1750
1751 if (!priv->rx_ring) {
1752 kfree(priv->rx_buffers);
1753 priv->rx_buffers = NULL;
1754 priv->tx_buffers = NULL;
1755 return -ENOMEM;
1756 }
1757
1758 priv->tx_ring = (struct adm8211_desc *)(priv->rx_ring +
1759 priv->rx_ring_size);
1760 priv->tx_ring_dma = priv->rx_ring_dma +
1761 sizeof(struct adm8211_desc) * priv->rx_ring_size;
1762
1763 return 0;
1764}
1765
1766static const struct ieee80211_ops adm8211_ops = {
1767 .tx = adm8211_tx,
1768 .open = adm8211_open,
1769 .stop = adm8211_stop,
1770 .add_interface = adm8211_add_interface,
1771 .remove_interface = adm8211_remove_interface,
1772 .config = adm8211_config,
1773 .config_interface = adm8211_config_interface,
1774 .set_multicast_list = adm8211_set_rx_mode,
1775 .get_stats = adm8211_get_stats,
1776 .get_tx_stats = adm8211_get_tx_stats,
1777 .get_tsf = adm8211_get_tsft
1778};
1779
1780static int __devinit adm8211_probe(struct pci_dev *pdev,
1781 const struct pci_device_id *id)
1782{
1783 struct ieee80211_hw *dev;
1784 struct adm8211_priv *priv;
1785 unsigned long mem_addr, mem_len;
1786 unsigned int io_addr, io_len;
1787 int err;
1788 u32 reg;
1789 u8 perm_addr[ETH_ALEN];
1790
1791#ifndef MODULE
1792 static unsigned int cardidx;
1793 if (!cardidx++)
1794 printk(version);
1795#endif
1796
1797 err = pci_enable_device(pdev);
1798 if (err) {
1799 printk(KERN_ERR "%s (adm8211): Cannot enable new PCI device\n",
1800 pci_name(pdev));
1801 return err;
1802 }
1803
1804 io_addr = pci_resource_start(pdev, 0);
1805 io_len = pci_resource_len(pdev, 0);
1806 mem_addr = pci_resource_start(pdev, 1);
1807 mem_len = pci_resource_len(pdev, 1);
1808 if (io_len < 256 || mem_len < 1024) {
1809 printk(KERN_ERR "%s (adm8211): Too short PCI resources\n",
1810 pci_name(pdev));
1811 goto err_disable_pdev;
1812 }
1813
1814
1815 /* check signature */
1816 pci_read_config_dword(pdev, 0x80 /* CR32 */, &reg);
1817 if (reg != ADM8211_SIG1 && reg != ADM8211_SIG2) {
1818 printk(KERN_ERR "%s (adm8211): Invalid signature (0x%x)\n",
1819 pci_name(pdev), reg);
1820 goto err_disable_pdev;
1821 }
1822
1823 err = pci_request_regions(pdev, "adm8211");
1824 if (err) {
1825 printk(KERN_ERR "%s (adm8211): Cannot obtain PCI resources\n",
1826 pci_name(pdev));
1827 return err; /* someone else grabbed it? don't disable it */
1828 }
1829
1830 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
1831 pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
1832 printk(KERN_ERR "%s (adm8211): No suitable DMA available\n",
1833 pci_name(pdev));
1834 goto err_free_reg;
1835 }
1836
1837 pci_set_master(pdev);
1838
1839 dev = ieee80211_alloc_hw(sizeof(*priv), &adm8211_ops);
1840 if (!dev) {
1841 printk(KERN_ERR "%s (adm8211): ieee80211 alloc failed\n",
1842 pci_name(pdev));
1843 err = -ENOMEM;
1844 goto err_free_reg;
1845 }
1846 priv = dev->priv;
1847 priv->pdev = pdev;
1848
1849 spin_lock_init(&priv->lock);
1850
1851 SET_IEEE80211_DEV(dev, &pdev->dev);
1852
1853 pci_set_drvdata(pdev, dev);
1854
1855 priv->map = pci_iomap(pdev, 1, mem_len);
1856 if (!priv->map)
1857 priv->map = pci_iomap(pdev, 0, io_len);
1858
1859 if (!priv->map) {
1860 printk(KERN_ERR "%s (adm8211): Cannot map device memory\n",
1861 pci_name(pdev));
1862 goto err_free_dev;
1863 }
1864
1865 priv->rx_ring_size = rx_ring_size;
1866 priv->tx_ring_size = tx_ring_size;
1867
1868 if (adm8211_alloc_rings(dev)) {
1869 printk(KERN_ERR "%s (adm8211): Cannot allocate TX/RX ring\n",
1870 pci_name(pdev));
1871 goto err_iounmap;
1872 }
1873
1874 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &priv->revid);
1875
1876 *(u32 *)perm_addr = le32_to_cpu((__force __le32)ADM8211_CSR_READ(PAR0));
1877 *(u16 *)&perm_addr[4] =
1878 le16_to_cpu((__force __le16)ADM8211_CSR_READ(PAR1) & 0xFFFF);
1879
1880 if (!is_valid_ether_addr(perm_addr)) {
1881 printk(KERN_WARNING "%s (adm8211): Invalid hwaddr in EEPROM!\n",
1882 pci_name(pdev));
1883 random_ether_addr(perm_addr);
1884 }
1885 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
1886
1887 dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
1888 dev->flags = IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED;
1889 /* IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
1890
1891 dev->channel_change_time = 1000;
1892 dev->max_rssi = 100; /* FIXME: find better value */
1893
1894 priv->modes[0].mode = MODE_IEEE80211B;
1895 /* channel info filled in by adm8211_read_eeprom */
1896 memcpy(priv->rates, adm8211_rates, sizeof(adm8211_rates));
1897 priv->modes[0].num_rates = ARRAY_SIZE(adm8211_rates);
1898 priv->modes[0].rates = priv->rates;
1899
1900 dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
1901
1902 priv->retry_limit = 3;
1903 priv->ant_power = 0x40;
1904 priv->tx_power = 0x40;
1905 priv->lpf_cutoff = 0xFF;
1906 priv->lnags_threshold = 0xFF;
1907 priv->mode = IEEE80211_IF_TYPE_MGMT;
1908
1909 /* Power-on issue. EEPROM won't read correctly without */
1910 if (priv->revid >= ADM8211_REV_BA) {
1911 ADM8211_CSR_WRITE(FRCTL, 0);
1912 ADM8211_CSR_READ(FRCTL);
1913 ADM8211_CSR_WRITE(FRCTL, 1);
1914 ADM8211_CSR_READ(FRCTL);
1915 msleep(100);
1916 }
1917
1918 err = adm8211_read_eeprom(dev);
1919 if (err) {
1920 printk(KERN_ERR "%s (adm8211): Can't alloc eeprom buffer\n",
1921 pci_name(pdev));
1922 goto err_free_desc;
1923 }
1924
1925 priv->channel = priv->modes[0].channels[0].chan;
1926
1927 err = ieee80211_register_hwmode(dev, &priv->modes[0]);
1928 if (err) {
1929 printk(KERN_ERR "%s (adm8211): Can't register hwmode\n",
1930 pci_name(pdev));
1931 goto err_free_desc;
1932 }
1933
1934 err = ieee80211_register_hw(dev);
1935 if (err) {
1936 printk(KERN_ERR "%s (adm8211): Cannot register device\n",
1937 pci_name(pdev));
1938 goto err_free_desc;
1939 }
1940
1941 printk(KERN_INFO "%s: hwaddr " MAC_FMT ", Rev 0x%02x\n",
1942 wiphy_name(dev->wiphy), MAC_ARG(dev->wiphy->perm_addr),
1943 priv->revid);
1944
1945 return 0;
1946
1947 err_free_desc:
1948 pci_free_consistent(pdev,
1949 sizeof(struct adm8211_desc) * priv->rx_ring_size +
1950 sizeof(struct adm8211_desc) * priv->tx_ring_size,
1951 priv->rx_ring, priv->rx_ring_dma);
1952 kfree(priv->rx_buffers);
1953
1954 err_iounmap:
1955 pci_iounmap(pdev, priv->map);
1956
1957 err_free_dev:
1958 pci_set_drvdata(pdev, NULL);
1959 ieee80211_free_hw(dev);
1960
1961 err_free_reg:
1962 pci_release_regions(pdev);
1963
1964 err_disable_pdev:
1965 pci_disable_device(pdev);
1966 return err;
1967}
1968
1969
1970static void __devexit adm8211_remove(struct pci_dev *pdev)
1971{
1972 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1973 struct adm8211_priv *priv;
1974
1975 if (!dev)
1976 return;
1977
1978 ieee80211_unregister_hw(dev);
1979
1980 priv = dev->priv;
1981
1982 pci_free_consistent(pdev,
1983 sizeof(struct adm8211_desc) * priv->rx_ring_size +
1984 sizeof(struct adm8211_desc) * priv->tx_ring_size,
1985 priv->rx_ring, priv->rx_ring_dma);
1986
1987 kfree(priv->rx_buffers);
1988 kfree(priv->eeprom);
1989 pci_iounmap(pdev, priv->map);
1990 pci_release_regions(pdev);
1991 pci_disable_device(pdev);
1992 ieee80211_free_hw(dev);
1993}
1994
1995
1996#ifdef CONFIG_PM
1997static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state)
1998{
1999 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
2000 struct adm8211_priv *priv = dev->priv;
2001
2002 if (priv->mode != IEEE80211_IF_TYPE_MGMT) {
2003 ieee80211_stop_queues(dev);
2004 adm8211_stop(dev);
2005 }
2006
2007 pci_save_state(pdev);
2008 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2009 return 0;
2010}
2011
2012static int adm8211_resume(struct pci_dev *pdev)
2013{
2014 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
2015 struct adm8211_priv *priv = dev->priv;
2016
2017 pci_set_power_state(pdev, PCI_D0);
2018 pci_restore_state(pdev);
2019
2020 if (priv->mode != IEEE80211_IF_TYPE_MGMT) {
2021 adm8211_open(dev);
2022 ieee80211_start_queues(dev);
2023 }
2024
2025 return 0;
2026}
2027#endif /* CONFIG_PM */
2028
2029
2030MODULE_DEVICE_TABLE(pci, adm8211_pci_id_table);
2031
2032/* TODO: implement enable_wake */
2033static struct pci_driver adm8211_driver = {
2034 .name = "adm8211",
2035 .id_table = adm8211_pci_id_table,
2036 .probe = adm8211_probe,
2037 .remove = __devexit_p(adm8211_remove),
2038#ifdef CONFIG_PM
2039 .suspend = adm8211_suspend,
2040 .resume = adm8211_resume,
2041#endif /* CONFIG_PM */
2042};
2043
2044
2045
2046static int __init adm8211_init(void)
2047{
2048#ifdef MODULE
2049 printk(version);
2050#endif
2051
2052 return pci_register_driver(&adm8211_driver);
2053}
2054
2055
2056static void __exit adm8211_exit(void)
2057{
2058 pci_unregister_driver(&adm8211_driver);
2059}
2060
2061
2062module_init(adm8211_init);
2063module_exit(adm8211_exit);
diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h
new file mode 100644
index 000000000000..795d895f5c99
--- /dev/null
+++ b/drivers/net/wireless/adm8211.h
@@ -0,0 +1,659 @@
1#ifndef ADM8211_H
2#define ADM8211_H
3
4/* ADM8211 Registers */
5
6/* CR32 (SIG) signature */
7#define ADM8211_SIG1 0x82011317 /* ADM8211A */
8#define ADM8211_SIG2 0x82111317 /* ADM8211B/ADM8211C */
9
10#define ADM8211_CSR_READ(r) ioread32(&priv->map->r)
11#define ADM8211_CSR_WRITE(r, val) iowrite32((val), &priv->map->r)
12
13/* CSR (Host Control and Status Registers) */
14struct adm8211_csr {
15 __le32 PAR; /* 0x00 CSR0 */
16 __le32 FRCTL; /* 0x04 CSR0A */
17 __le32 TDR; /* 0x08 CSR1 */
18 __le32 WTDP; /* 0x0C CSR1A */
19 __le32 RDR; /* 0x10 CSR2 */
20 __le32 WRDP; /* 0x14 CSR2A */
21 __le32 RDB; /* 0x18 CSR3 */
22 __le32 TDBH; /* 0x1C CSR3A */
23 __le32 TDBD; /* 0x20 CSR4 */
24 __le32 TDBP; /* 0x24 CSR4A */
25 __le32 STSR; /* 0x28 CSR5 */
26 __le32 TDBB; /* 0x2C CSR5A */
27 __le32 NAR; /* 0x30 CSR6 */
28 __le32 CSR6A; /* reserved */
29 __le32 IER; /* 0x38 CSR7 */
30 __le32 TKIPSCEP; /* 0x3C CSR7A */
31 __le32 LPC; /* 0x40 CSR8 */
32 __le32 CSR_TEST1; /* 0x44 CSR8A */
33 __le32 SPR; /* 0x48 CSR9 */
34 __le32 CSR_TEST0; /* 0x4C CSR9A */
35 __le32 WCSR; /* 0x50 CSR10 */
36 __le32 WPDR; /* 0x54 CSR10A */
37 __le32 GPTMR; /* 0x58 CSR11 */
38 __le32 GPIO; /* 0x5C CSR11A */
39 __le32 BBPCTL; /* 0x60 CSR12 */
40 __le32 SYNCTL; /* 0x64 CSR12A */
41 __le32 PLCPHD; /* 0x68 CSR13 */
42 __le32 MMIWA; /* 0x6C CSR13A */
43 __le32 MMIRD0; /* 0x70 CSR14 */
44 __le32 MMIRD1; /* 0x74 CSR14A */
45 __le32 TXBR; /* 0x78 CSR15 */
46 __le32 SYNDATA; /* 0x7C CSR15A */
47 __le32 ALCS; /* 0x80 CSR16 */
48 __le32 TOFS2; /* 0x84 CSR17 */
49 __le32 CMDR; /* 0x88 CSR18 */
50 __le32 PCIC; /* 0x8C CSR19 */
51 __le32 PMCSR; /* 0x90 CSR20 */
52 __le32 PAR0; /* 0x94 CSR21 */
53 __le32 PAR1; /* 0x98 CSR22 */
54 __le32 MAR0; /* 0x9C CSR23 */
55 __le32 MAR1; /* 0xA0 CSR24 */
56 __le32 ATIMDA0; /* 0xA4 CSR25 */
57 __le32 ABDA1; /* 0xA8 CSR26 */
58 __le32 BSSID0; /* 0xAC CSR27 */
59 __le32 TXLMT; /* 0xB0 CSR28 */
60 __le32 MIBCNT; /* 0xB4 CSR29 */
61 __le32 BCNT; /* 0xB8 CSR30 */
62 __le32 TSFTH; /* 0xBC CSR31 */
63 __le32 TSC; /* 0xC0 CSR32 */
64 __le32 SYNRF; /* 0xC4 CSR33 */
65 __le32 BPLI; /* 0xC8 CSR34 */
66 __le32 CAP0; /* 0xCC CSR35 */
67 __le32 CAP1; /* 0xD0 CSR36 */
68 __le32 RMD; /* 0xD4 CSR37 */
69 __le32 CFPP; /* 0xD8 CSR38 */
70 __le32 TOFS0; /* 0xDC CSR39 */
71 __le32 TOFS1; /* 0xE0 CSR40 */
72 __le32 IFST; /* 0xE4 CSR41 */
73 __le32 RSPT; /* 0xE8 CSR42 */
74 __le32 TSFTL; /* 0xEC CSR43 */
75 __le32 WEPCTL; /* 0xF0 CSR44 */
76 __le32 WESK; /* 0xF4 CSR45 */
77 __le32 WEPCNT; /* 0xF8 CSR46 */
78 __le32 MACTEST; /* 0xFC CSR47 */
79 __le32 FER; /* 0x100 */
80 __le32 FEMR; /* 0x104 */
81 __le32 FPSR; /* 0x108 */
82 __le32 FFER; /* 0x10C */
83} __attribute__ ((packed));
84
85/* CSR0 - PAR (PCI Address Register) */
86#define ADM8211_PAR_MWIE (1 << 24)
87#define ADM8211_PAR_MRLE (1 << 23)
88#define ADM8211_PAR_MRME (1 << 21)
89#define ADM8211_PAR_RAP ((1 << 18) | (1 << 17))
90#define ADM8211_PAR_CAL ((1 << 15) | (1 << 14))
91#define ADM8211_PAR_PBL 0x00003f00
92#define ADM8211_PAR_BLE (1 << 7)
93#define ADM8211_PAR_DSL 0x0000007c
94#define ADM8211_PAR_BAR (1 << 1)
95#define ADM8211_PAR_SWR (1 << 0)
96
97/* CSR1 - FRCTL (Frame Control Register) */
98#define ADM8211_FRCTL_PWRMGT (1 << 31)
99#define ADM8211_FRCTL_MAXPSP (1 << 27)
100#define ADM8211_FRCTL_DRVPRSP (1 << 26)
101#define ADM8211_FRCTL_DRVBCON (1 << 25)
102#define ADM8211_FRCTL_AID 0x0000ffff
103#define ADM8211_FRCTL_AID_ON 0x0000c000
104
105/* CSR5 - STSR (Status Register) */
106#define ADM8211_STSR_PCF (1 << 31)
107#define ADM8211_STSR_BCNTC (1 << 30)
108#define ADM8211_STSR_GPINT (1 << 29)
109#define ADM8211_STSR_LinkOff (1 << 28)
110#define ADM8211_STSR_ATIMTC (1 << 27)
111#define ADM8211_STSR_TSFTF (1 << 26)
112#define ADM8211_STSR_TSCZ (1 << 25)
113#define ADM8211_STSR_LinkOn (1 << 24)
114#define ADM8211_STSR_SQL (1 << 23)
115#define ADM8211_STSR_WEPTD (1 << 22)
116#define ADM8211_STSR_ATIME (1 << 21)
117#define ADM8211_STSR_TBTT (1 << 20)
118#define ADM8211_STSR_NISS (1 << 16)
119#define ADM8211_STSR_AISS (1 << 15)
120#define ADM8211_STSR_TEIS (1 << 14)
121#define ADM8211_STSR_FBE (1 << 13)
122#define ADM8211_STSR_REIS (1 << 12)
123#define ADM8211_STSR_GPTT (1 << 11)
124#define ADM8211_STSR_RPS (1 << 8)
125#define ADM8211_STSR_RDU (1 << 7)
126#define ADM8211_STSR_RCI (1 << 6)
127#define ADM8211_STSR_TUF (1 << 5)
128#define ADM8211_STSR_TRT (1 << 4)
129#define ADM8211_STSR_TLT (1 << 3)
130#define ADM8211_STSR_TDU (1 << 2)
131#define ADM8211_STSR_TPS (1 << 1)
132#define ADM8211_STSR_TCI (1 << 0)
133
134/* CSR6 - NAR (Network Access Register) */
135#define ADM8211_NAR_TXCF (1 << 31)
136#define ADM8211_NAR_HF (1 << 30)
137#define ADM8211_NAR_UTR (1 << 29)
138#define ADM8211_NAR_SQ (1 << 28)
139#define ADM8211_NAR_CFP (1 << 27)
140#define ADM8211_NAR_SF (1 << 21)
141#define ADM8211_NAR_TR ((1 << 15) | (1 << 14))
142#define ADM8211_NAR_ST (1 << 13)
143#define ADM8211_NAR_OM ((1 << 11) | (1 << 10))
144#define ADM8211_NAR_MM (1 << 7)
145#define ADM8211_NAR_PR (1 << 6)
146#define ADM8211_NAR_EA (1 << 5)
147#define ADM8211_NAR_PB (1 << 3)
148#define ADM8211_NAR_STPDMA (1 << 2)
149#define ADM8211_NAR_SR (1 << 1)
150#define ADM8211_NAR_CTX (1 << 0)
151
152#define ADM8211_IDLE() \
153do { \
154 if (priv->nar & (ADM8211_NAR_SR | ADM8211_NAR_ST)) { \
155 ADM8211_CSR_WRITE(NAR, priv->nar & \
156 ~(ADM8211_NAR_SR | ADM8211_NAR_ST));\
157 ADM8211_CSR_READ(NAR); \
158 msleep(20); \
159 } \
160} while (0)
161
162#define ADM8211_IDLE_RX() \
163do { \
164 if (priv->nar & ADM8211_NAR_SR) { \
165 ADM8211_CSR_WRITE(NAR, priv->nar & ~ADM8211_NAR_SR); \
166 ADM8211_CSR_READ(NAR); \
167 mdelay(20); \
168 } \
169} while (0)
170
171#define ADM8211_RESTORE() \
172do { \
173 if (priv->nar & (ADM8211_NAR_SR | ADM8211_NAR_ST)) \
174 ADM8211_CSR_WRITE(NAR, priv->nar); \
175} while (0)
176
177/* CSR7 - IER (Interrupt Enable Register) */
178#define ADM8211_IER_PCFIE (1 << 31)
179#define ADM8211_IER_BCNTCIE (1 << 30)
180#define ADM8211_IER_GPIE (1 << 29)
181#define ADM8211_IER_LinkOffIE (1 << 28)
182#define ADM8211_IER_ATIMTCIE (1 << 27)
183#define ADM8211_IER_TSFTFIE (1 << 26)
184#define ADM8211_IER_TSCZE (1 << 25)
185#define ADM8211_IER_LinkOnIE (1 << 24)
186#define ADM8211_IER_SQLIE (1 << 23)
187#define ADM8211_IER_WEPIE (1 << 22)
188#define ADM8211_IER_ATIMEIE (1 << 21)
189#define ADM8211_IER_TBTTIE (1 << 20)
190#define ADM8211_IER_NIE (1 << 16)
191#define ADM8211_IER_AIE (1 << 15)
192#define ADM8211_IER_TEIE (1 << 14)
193#define ADM8211_IER_FBEIE (1 << 13)
194#define ADM8211_IER_REIE (1 << 12)
195#define ADM8211_IER_GPTIE (1 << 11)
196#define ADM8211_IER_RSIE (1 << 8)
197#define ADM8211_IER_RUIE (1 << 7)
198#define ADM8211_IER_RCIE (1 << 6)
199#define ADM8211_IER_TUIE (1 << 5)
200#define ADM8211_IER_TRTIE (1 << 4)
201#define ADM8211_IER_TLTTIE (1 << 3)
202#define ADM8211_IER_TDUIE (1 << 2)
203#define ADM8211_IER_TPSIE (1 << 1)
204#define ADM8211_IER_TCIE (1 << 0)
205
206/* CSR9 - SPR (Serial Port Register) */
207#define ADM8211_SPR_SRS (1 << 11)
208#define ADM8211_SPR_SDO (1 << 3)
209#define ADM8211_SPR_SDI (1 << 2)
210#define ADM8211_SPR_SCLK (1 << 1)
211#define ADM8211_SPR_SCS (1 << 0)
212
213/* CSR9A - CSR_TEST0 */
214#define ADM8211_CSR_TEST0_EPNE (1 << 18)
215#define ADM8211_CSR_TEST0_EPSNM (1 << 17)
216#define ADM8211_CSR_TEST0_EPTYP (1 << 16)
217#define ADM8211_CSR_TEST0_EPRLD (1 << 15)
218
219/* CSR10 - WCSR (Wake-up Control/Status Register) */
220#define ADM8211_WCSR_CRCT (1 << 30)
221#define ADM8211_WCSR_TSFTWE (1 << 20)
222#define ADM8211_WCSR_TIMWE (1 << 19)
223#define ADM8211_WCSR_ATIMWE (1 << 18)
224#define ADM8211_WCSR_KEYWE (1 << 17)
225#define ADM8211_WCSR_MPRE (1 << 9)
226#define ADM8211_WCSR_LSOE (1 << 8)
227#define ADM8211_WCSR_KEYUP (1 << 6)
228#define ADM8211_WCSR_TSFTW (1 << 5)
229#define ADM8211_WCSR_TIMW (1 << 4)
230#define ADM8211_WCSR_ATIMW (1 << 3)
231#define ADM8211_WCSR_MPR (1 << 1)
232#define ADM8211_WCSR_LSO (1 << 0)
233
234/* CSR11A - GPIO */
235#define ADM8211_CSR_GPIO_EN5 (1 << 17)
236#define ADM8211_CSR_GPIO_EN4 (1 << 16)
237#define ADM8211_CSR_GPIO_EN3 (1 << 15)
238#define ADM8211_CSR_GPIO_EN2 (1 << 14)
239#define ADM8211_CSR_GPIO_EN1 (1 << 13)
240#define ADM8211_CSR_GPIO_EN0 (1 << 12)
241#define ADM8211_CSR_GPIO_O5 (1 << 11)
242#define ADM8211_CSR_GPIO_O4 (1 << 10)
243#define ADM8211_CSR_GPIO_O3 (1 << 9)
244#define ADM8211_CSR_GPIO_O2 (1 << 8)
245#define ADM8211_CSR_GPIO_O1 (1 << 7)
246#define ADM8211_CSR_GPIO_O0 (1 << 6)
247#define ADM8211_CSR_GPIO_IN 0x0000003f
248
249/* CSR12 - BBPCTL (BBP Control port) */
250#define ADM8211_BBPCTL_MMISEL (1 << 31)
251#define ADM8211_BBPCTL_SPICADD (0x7F << 24)
252#define ADM8211_BBPCTL_RF3000 (0x20 << 24)
253#define ADM8211_BBPCTL_TXCE (1 << 23)
254#define ADM8211_BBPCTL_RXCE (1 << 22)
255#define ADM8211_BBPCTL_CCAP (1 << 21)
256#define ADM8211_BBPCTL_TYPE 0x001c0000
257#define ADM8211_BBPCTL_WR (1 << 17)
258#define ADM8211_BBPCTL_RD (1 << 16)
259#define ADM8211_BBPCTL_ADDR 0x0000ff00
260#define ADM8211_BBPCTL_DATA 0x000000ff
261
262/* CSR12A - SYNCTL (Synthesizer Control port) */
263#define ADM8211_SYNCTL_WR (1 << 31)
264#define ADM8211_SYNCTL_RD (1 << 30)
265#define ADM8211_SYNCTL_CS0 (1 << 29)
266#define ADM8211_SYNCTL_CS1 (1 << 28)
267#define ADM8211_SYNCTL_CAL (1 << 27)
268#define ADM8211_SYNCTL_SELCAL (1 << 26)
269#define ADM8211_SYNCTL_RFtype ((1 << 24) || (1 << 23) || (1 << 22))
270#define ADM8211_SYNCTL_RFMD (1 << 22)
271#define ADM8211_SYNCTL_GENERAL (0x7 << 22)
272/* SYNCTL 21:0 Data (Si4126: 18-bit data, 4-bit address) */
273
274/* CSR18 - CMDR (Command Register) */
275#define ADM8211_CMDR_PM (1 << 19)
276#define ADM8211_CMDR_APM (1 << 18)
277#define ADM8211_CMDR_RTE (1 << 4)
278#define ADM8211_CMDR_DRT ((1 << 3) | (1 << 2))
279#define ADM8211_CMDR_DRT_8DW (0x0 << 2)
280#define ADM8211_CMDR_DRT_16DW (0x1 << 2)
281#define ADM8211_CMDR_DRT_SF (0x2 << 2)
282
283/* CSR33 - SYNRF (SYNRF direct control) */
284#define ADM8211_SYNRF_SELSYN (1 << 31)
285#define ADM8211_SYNRF_SELRF (1 << 30)
286#define ADM8211_SYNRF_LERF (1 << 29)
287#define ADM8211_SYNRF_LEIF (1 << 28)
288#define ADM8211_SYNRF_SYNCLK (1 << 27)
289#define ADM8211_SYNRF_SYNDATA (1 << 26)
290#define ADM8211_SYNRF_PE1 (1 << 25)
291#define ADM8211_SYNRF_PE2 (1 << 24)
292#define ADM8211_SYNRF_PA_PE (1 << 23)
293#define ADM8211_SYNRF_TR_SW (1 << 22)
294#define ADM8211_SYNRF_TR_SWN (1 << 21)
295#define ADM8211_SYNRF_RADIO (1 << 20)
296#define ADM8211_SYNRF_CAL_EN (1 << 19)
297#define ADM8211_SYNRF_PHYRST (1 << 18)
298
299#define ADM8211_SYNRF_IF_SELECT_0 (1 << 31)
300#define ADM8211_SYNRF_IF_SELECT_1 ((1 << 31) | (1 << 28))
301#define ADM8211_SYNRF_WRITE_SYNDATA_0 (1 << 31)
302#define ADM8211_SYNRF_WRITE_SYNDATA_1 ((1 << 31) | (1 << 26))
303#define ADM8211_SYNRF_WRITE_CLOCK_0 (1 << 31)
304#define ADM8211_SYNRF_WRITE_CLOCK_1 ((1 << 31) | (1 << 27))
305
306/* CSR44 - WEPCTL (WEP Control) */
307#define ADM8211_WEPCTL_WEPENABLE (1 << 31)
308#define ADM8211_WEPCTL_WPAENABLE (1 << 30)
309#define ADM8211_WEPCTL_CURRENT_TABLE (1 << 29)
310#define ADM8211_WEPCTL_TABLE_WR (1 << 28)
311#define ADM8211_WEPCTL_TABLE_RD (1 << 27)
312#define ADM8211_WEPCTL_WEPRXBYP (1 << 25)
313#define ADM8211_WEPCTL_SEL_WEPTABLE (1 << 23)
314#define ADM8211_WEPCTL_ADDR (0x000001ff)
315
316/* CSR45 - WESK (Data Entry for Share/Individual Key) */
317#define ADM8211_WESK_DATA (0x0000ffff)
318
319/* FER (Function Event Register) */
320#define ADM8211_FER_INTR_EV_ENT (1 << 15)
321
322
323/* Si4126 RF Synthesizer - Control Registers */
324#define SI4126_MAIN_CONF 0
325#define SI4126_PHASE_DET_GAIN 1
326#define SI4126_POWERDOWN 2
327#define SI4126_RF1_N_DIV 3 /* only Si4136 */
328#define SI4126_RF2_N_DIV 4
329#define SI4126_IF_N_DIV 5
330#define SI4126_RF1_R_DIV 6 /* only Si4136 */
331#define SI4126_RF2_R_DIV 7
332#define SI4126_IF_R_DIV 8
333
334/* Main Configuration */
335#define SI4126_MAIN_XINDIV2 (1 << 6)
336#define SI4126_MAIN_IFDIV ((1 << 11) | (1 << 10))
337/* Powerdown */
338#define SI4126_POWERDOWN_PDIB (1 << 1)
339#define SI4126_POWERDOWN_PDRB (1 << 0)
340
341
342/* RF3000 BBP - Control Port Registers */
343/* 0x00 - reserved */
344#define RF3000_MODEM_CTRL__RX_STATUS 0x01
345#define RF3000_CCA_CTRL 0x02
346#define RF3000_DIVERSITY__RSSI 0x03
347#define RF3000_RX_SIGNAL_FIELD 0x04
348#define RF3000_RX_LEN_MSB 0x05
349#define RF3000_RX_LEN_LSB 0x06
350#define RF3000_RX_SERVICE_FIELD 0x07
351#define RF3000_TX_VAR_GAIN__TX_LEN_EXT 0x11
352#define RF3000_TX_LEN_MSB 0x12
353#define RF3000_TX_LEN_LSB 0x13
354#define RF3000_LOW_GAIN_CALIB 0x14
355#define RF3000_HIGH_GAIN_CALIB 0x15
356
357/* ADM8211 revisions */
358#define ADM8211_REV_AB 0x11
359#define ADM8211_REV_AF 0x15
360#define ADM8211_REV_BA 0x20
361#define ADM8211_REV_CA 0x30
362
363struct adm8211_desc {
364 __le32 status;
365 __le32 length;
366 __le32 buffer1;
367 __le32 buffer2;
368};
369
370#define RDES0_STATUS_OWN (1 << 31)
371#define RDES0_STATUS_ES (1 << 30)
372#define RDES0_STATUS_SQL (1 << 29)
373#define RDES0_STATUS_DE (1 << 28)
374#define RDES0_STATUS_FS (1 << 27)
375#define RDES0_STATUS_LS (1 << 26)
376#define RDES0_STATUS_PCF (1 << 25)
377#define RDES0_STATUS_SFDE (1 << 24)
378#define RDES0_STATUS_SIGE (1 << 23)
379#define RDES0_STATUS_CRC16E (1 << 22)
380#define RDES0_STATUS_RXTOE (1 << 21)
381#define RDES0_STATUS_CRC32E (1 << 20)
382#define RDES0_STATUS_ICVE (1 << 19)
383#define RDES0_STATUS_DA1 (1 << 17)
384#define RDES0_STATUS_DA0 (1 << 16)
385#define RDES0_STATUS_RXDR ((1 << 15) | (1 << 14) | (1 << 13) | (1 << 12))
386#define RDES0_STATUS_FL (0x00000fff)
387
388#define RDES1_CONTROL_RER (1 << 25)
389#define RDES1_CONTROL_RCH (1 << 24)
390#define RDES1_CONTROL_RBS2 (0x00fff000)
391#define RDES1_CONTROL_RBS1 (0x00000fff)
392
393#define RDES1_STATUS_RSSI (0x0000007f)
394
395
396#define TDES0_CONTROL_OWN (1 << 31)
397#define TDES0_CONTROL_DONE (1 << 30)
398#define TDES0_CONTROL_TXDR (0x0ff00000)
399
400#define TDES0_STATUS_OWN (1 << 31)
401#define TDES0_STATUS_DONE (1 << 30)
402#define TDES0_STATUS_ES (1 << 29)
403#define TDES0_STATUS_TLT (1 << 28)
404#define TDES0_STATUS_TRT (1 << 27)
405#define TDES0_STATUS_TUF (1 << 26)
406#define TDES0_STATUS_TRO (1 << 25)
407#define TDES0_STATUS_SOFBR (1 << 24)
408#define TDES0_STATUS_ACR (0x00000fff)
409
410#define TDES1_CONTROL_IC (1 << 31)
411#define TDES1_CONTROL_LS (1 << 30)
412#define TDES1_CONTROL_FS (1 << 29)
413#define TDES1_CONTROL_TER (1 << 25)
414#define TDES1_CONTROL_TCH (1 << 24)
415#define TDES1_CONTROL_RBS2 (0x00fff000)
416#define TDES1_CONTROL_RBS1 (0x00000fff)
417
418/* SRAM offsets */
419#define ADM8211_SRAM(x) (priv->revid < ADM8211_REV_BA ? \
420 ADM8211_SRAM_A_ ## x : ADM8211_SRAM_B_ ## x)
421
422#define ADM8211_SRAM_INDIV_KEY 0x0000
423#define ADM8211_SRAM_A_SHARE_KEY 0x0160
424#define ADM8211_SRAM_B_SHARE_KEY 0x00c0
425
426#define ADM8211_SRAM_A_SSID 0x0180
427#define ADM8211_SRAM_B_SSID 0x00d4
428#define ADM8211_SRAM_SSID ADM8211_SRAM(SSID)
429
430#define ADM8211_SRAM_A_SUPP_RATE 0x0191
431#define ADM8211_SRAM_B_SUPP_RATE 0x00dd
432#define ADM8211_SRAM_SUPP_RATE ADM8211_SRAM(SUPP_RATE)
433
434#define ADM8211_SRAM_A_SIZE 0x0200
435#define ADM8211_SRAM_B_SIZE 0x01c0
436#define ADM8211_SRAM_SIZE ADM8211_SRAM(SIZE)
437
438struct adm8211_rx_ring_info {
439 struct sk_buff *skb;
440 dma_addr_t mapping;
441};
442
443struct adm8211_tx_ring_info {
444 struct sk_buff *skb;
445 dma_addr_t mapping;
446 struct ieee80211_tx_control tx_control;
447 size_t hdrlen;
448};
449
450#define PLCP_SIGNAL_1M 0x0a
451#define PLCP_SIGNAL_2M 0x14
452#define PLCP_SIGNAL_5M5 0x37
453#define PLCP_SIGNAL_11M 0x6e
454
455struct adm8211_tx_hdr {
456 u8 da[6];
457 u8 signal; /* PLCP signal / TX rate in 100 Kbps */
458 u8 service;
459 __le16 frame_body_size;
460 __le16 frame_control;
461 __le16 plcp_frag_tail_len;
462 __le16 plcp_frag_head_len;
463 __le16 dur_frag_tail;
464 __le16 dur_frag_head;
465 u8 addr4[6];
466
467#define ADM8211_TXHDRCTL_SHORT_PREAMBLE (1 << 0)
468#define ADM8211_TXHDRCTL_MORE_FRAG (1 << 1)
469#define ADM8211_TXHDRCTL_MORE_DATA (1 << 2)
470#define ADM8211_TXHDRCTL_FRAG_NO (1 << 3) /* ? */
471#define ADM8211_TXHDRCTL_ENABLE_RTS (1 << 4)
472#define ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE (1 << 5)
473#define ADM8211_TXHDRCTL_ENABLE_EXTEND_HEADER (1 << 15) /* ? */
474 __le16 header_control;
475 __le16 frag;
476 u8 reserved_0;
477 u8 retry_limit;
478
479 u32 wep2key0;
480 u32 wep2key1;
481 u32 wep2key2;
482 u32 wep2key3;
483
484 u8 keyid;
485 u8 entry_control; // huh??
486 u16 reserved_1;
487 u32 reserved_2;
488} __attribute__ ((packed));
489
490
491#define RX_COPY_BREAK 128
492#define RX_PKT_SIZE 2500
493
494struct adm8211_eeprom {
495 __le16 signature; /* 0x00 */
496 u8 major_version; /* 0x02 */
497 u8 minor_version; /* 0x03 */
498 u8 reserved_1[4]; /* 0x04 */
499 u8 hwaddr[6]; /* 0x08 */
500 u8 reserved_2[8]; /* 0x1E */
501 __le16 cr49; /* 0x16 */
502 u8 cr03; /* 0x18 */
503 u8 cr28; /* 0x19 */
504 u8 cr29; /* 0x1A */
505 u8 country_code; /* 0x1B */
506
507/* specific bbp types */
508#define ADM8211_BBP_RFMD3000 0x00
509#define ADM8211_BBP_RFMD3002 0x01
510#define ADM8211_BBP_ADM8011 0x04
511 u8 specific_bbptype; /* 0x1C */
512 u8 specific_rftype; /* 0x1D */
513 u8 reserved_3[2]; /* 0x1E */
514 __le16 device_id; /* 0x20 */
515 __le16 vendor_id; /* 0x22 */
516 __le16 subsystem_id; /* 0x24 */
517 __le16 subsystem_vendor_id; /* 0x26 */
518 u8 maxlat; /* 0x28 */
519 u8 mingnt; /* 0x29 */
520 __le16 cis_pointer_low; /* 0x2A */
521 __le16 cis_pointer_high; /* 0x2C */
522 __le16 csr18; /* 0x2E */
523 u8 reserved_4[16]; /* 0x30 */
524 u8 d1_pwrdara; /* 0x40 */
525 u8 d0_pwrdara; /* 0x41 */
526 u8 d3_pwrdara; /* 0x42 */
527 u8 d2_pwrdara; /* 0x43 */
528 u8 antenna_power[14]; /* 0x44 */
529 __le16 cis_wordcnt; /* 0x52 */
530 u8 tx_power[14]; /* 0x54 */
531 u8 lpf_cutoff[14]; /* 0x62 */
532 u8 lnags_threshold[14]; /* 0x70 */
533 __le16 checksum; /* 0x7E */
534 u8 cis_data[0]; /* 0x80, 384 bytes */
535} __attribute__ ((packed));
536
537static const struct ieee80211_rate adm8211_rates[] = {
538 { .rate = 10,
539 .val = 10,
540 .val2 = -10,
541 .flags = IEEE80211_RATE_CCK_2 },
542 { .rate = 20,
543 .val = 20,
544 .val2 = -20,
545 .flags = IEEE80211_RATE_CCK_2 },
546 { .rate = 55,
547 .val = 55,
548 .val2 = -55,
549 .flags = IEEE80211_RATE_CCK_2 },
550 { .rate = 110,
551 .val = 110,
552 .val2 = -110,
553 .flags = IEEE80211_RATE_CCK_2 }
554};
555
556struct ieee80211_chan_range {
557 u8 min;
558 u8 max;
559};
560
561static const struct ieee80211_channel adm8211_channels[] = {
562 { .chan = 1,
563 .freq = 2412},
564 { .chan = 2,
565 .freq = 2417},
566 { .chan = 3,
567 .freq = 2422},
568 { .chan = 4,
569 .freq = 2427},
570 { .chan = 5,
571 .freq = 2432},
572 { .chan = 6,
573 .freq = 2437},
574 { .chan = 7,
575 .freq = 2442},
576 { .chan = 8,
577 .freq = 2447},
578 { .chan = 9,
579 .freq = 2452},
580 { .chan = 10,
581 .freq = 2457},
582 { .chan = 11,
583 .freq = 2462},
584 { .chan = 12,
585 .freq = 2467},
586 { .chan = 13,
587 .freq = 2472},
588 { .chan = 14,
589 .freq = 2484},
590};
591
592struct adm8211_priv {
593 struct pci_dev *pdev;
594 spinlock_t lock;
595 struct adm8211_csr __iomem *map;
596 struct adm8211_desc *rx_ring;
597 struct adm8211_desc *tx_ring;
598 dma_addr_t rx_ring_dma;
599 dma_addr_t tx_ring_dma;
600 struct adm8211_rx_ring_info *rx_buffers;
601 struct adm8211_tx_ring_info *tx_buffers;
602 unsigned int rx_ring_size, tx_ring_size;
603 unsigned int cur_tx, dirty_tx, cur_rx;
604
605 struct ieee80211_low_level_stats stats;
606 struct ieee80211_hw_mode modes[1];
607 struct ieee80211_channel channels[ARRAY_SIZE(adm8211_channels)];
608 struct ieee80211_rate rates[ARRAY_SIZE(adm8211_rates)];
609 int mode;
610
611 int channel;
612 u8 bssid[ETH_ALEN];
613 u8 ssid[32];
614 size_t ssid_len;
615 u8 *mac_addr;
616
617 u8 soft_rx_crc;
618 u8 retry_limit;
619
620 u8 ant_power;
621 u8 tx_power;
622 u8 lpf_cutoff;
623 u8 lnags_threshold;
624 struct adm8211_eeprom *eeprom;
625 size_t eeprom_len;
626
627 u8 revid;
628
629 u32 nar;
630
631#define ADM8211_TYPE_INTERSIL 0x00
632#define ADM8211_TYPE_RFMD 0x01
633#define ADM8211_TYPE_MARVEL 0x02
634#define ADM8211_TYPE_AIROHA 0x03
635#define ADM8211_TYPE_ADMTEK 0x05
636 unsigned int rf_type:3;
637 unsigned int bbp_type:3;
638
639 u8 specific_bbptype;
640 enum {
641 ADM8211_RFMD2948 = 0x0,
642 ADM8211_RFMD2958 = 0x1,
643 ADM8211_RFMD2958_RF3000_CONTROL_POWER = 0x2,
644 ADM8211_MAX2820 = 0x8,
645 ADM8211_AL2210L = 0xC, /* Airoha */
646 } transceiver_type;
647};
648
649static const struct ieee80211_chan_range cranges[] = {
650 {1, 11}, /* FCC */
651 {1, 11}, /* IC */
652 {1, 13}, /* ETSI */
653 {10, 11}, /* SPAIN */
654 {10, 13}, /* FRANCE */
655 {14, 14}, /* MMK */
656 {1, 14}, /* MMK2 */
657};
658
659#endif /* ADM8211_H */