aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Wu <flamingice@sourmilk.net>2007-10-14 14:43:16 -0400
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:35 -0500
commitf653211197f3841f383fa9757ef8ce182c6cf627 (patch)
treeba56e1fa09924d1ffab4f825044175291786b58e /drivers
parentfa1c114fdaa605496045e56c42d0c8aa4c139e57 (diff)
Add rtl8180 wireless driver
This patch adds a mac80211 based wireless driver for the rtl8180 and rtl8185 PCI wireless cards. Also included are some rtl8187 changes required due to the relationship between that driver and this one. Michael Wu is primarily responsible for the initial driver and rtl8185 support. Andreas Merello provided the additional rtl8180 support. Thanks to Jukka Ruohonen for the donating a rtl8185 card! It was very helpful for the rtl8225z2 code. The Signed-off-by information below is collected from the individual patches submitted to wireless-2.6 before merging this driver upstream. Signed-off-by: Andrea Merello <andreamrl@tiscali.it> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Pavel Roskin <proski@gnu.org> Signed-off-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/Kconfig56
-rw-r--r--drivers/net/wireless/Makefile3
-rw-r--r--drivers/net/wireless/rtl8180.h151
-rw-r--r--drivers/net/wireless/rtl8180_dev.c1048
-rw-r--r--drivers/net/wireless/rtl8180_grf5101.c179
-rw-r--r--drivers/net/wireless/rtl8180_grf5101.h28
-rw-r--r--drivers/net/wireless/rtl8180_max2820.c150
-rw-r--r--drivers/net/wireless/rtl8180_max2820.h28
-rw-r--r--drivers/net/wireless/rtl8180_rtl8225.c779
-rw-r--r--drivers/net/wireless/rtl8180_rtl8225.h23
-rw-r--r--drivers/net/wireless/rtl8180_sa2400.c201
-rw-r--r--drivers/net/wireless/rtl8180_sa2400.h36
-rw-r--r--drivers/net/wireless/rtl8187.h2
-rw-r--r--drivers/net/wireless/rtl8187_dev.c60
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.c52
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.h9
-rw-r--r--drivers/net/wireless/rtl818x.h29
17 files changed, 2774 insertions, 60 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 50a8b6c2fa00..f372960904b2 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -545,6 +545,62 @@ config USB_ZD1201
545 To compile this driver as a module, choose M here: the 545 To compile this driver as a module, choose M here: the
546 module will be called zd1201. 546 module will be called zd1201.
547 547
548config RTL8180
549 tristate "Realtek 8180/8185 PCI support"
550 depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
551 select EEPROM_93CX6
552 ---help---
553 This is a driver for RTL8180 and RTL8185 based cards.
554 These are PCI based chips found in cards such as:
555
556 (RTL8185 802.11g)
557 A-Link WL54PC
558
559 (RTL8180 802.11b)
560 Belkin F5D6020 v3
561 Belkin F5D6020 v3
562 Dlink DWL-610
563 Dlink DWL-510
564 Netgear MA521
565 Level-One WPC-0101
566 Acer Aspire 1357 LMi
567 VCTnet PC-11B1
568 Ovislink AirLive WL-1120PCM
569 Mentor WL-PCI
570 Linksys WPC11 v4
571 TrendNET TEW-288PI
572 D-Link DWL-520 Rev D
573 Repotec RP-WP7126
574 TP-Link TL-WN250/251
575 Zonet ZEW1000
576 Longshine LCS-8031-R
577 HomeLine HLW-PCC200
578 GigaFast WF721-AEX
579 Planet WL-3553
580 Encore ENLWI-PCI1-NT
581 TrendNET TEW-266PC
582 Gigabyte GN-WLMR101
583 Siemens-fujitsu Amilo D1840W
584 Edimax EW-7126
585 PheeNet WL-11PCIR
586 Tonze PC-2100T
587 Planet WL-8303
588 Dlink DWL-650 v M1
589 Edimax EW-7106
590 Q-Tec 770WC
591 Topcom Skyr@cer 4011b
592 Roper FreeLan 802.11b (edition 2004)
593 Wistron Neweb Corp CB-200B
594 Pentagram HorNET
595 QTec 775WC
596 TwinMOS Booming B Series
597 Micronet SP906BB
598 Sweex LC700010
599 Surecom EP-9428
600 Safecom SWLCR-1100
601
602 Thanks to Realtek for their support!
603
548config RTL8187 604config RTL8187
549 tristate "Realtek 8187 USB support" 605 tristate "Realtek 8187 USB support"
550 depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL 606 depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 7e1535ece17a..6af7b158624e 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -47,7 +47,10 @@ obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
47obj-$(CONFIG_USB_ZD1201) += zd1201.o 47obj-$(CONFIG_USB_ZD1201) += zd1201.o
48obj-$(CONFIG_LIBERTAS) += libertas/ 48obj-$(CONFIG_LIBERTAS) += libertas/
49 49
50rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
50rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o 51rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
52
53obj-$(CONFIG_RTL8180) += rtl8180.o
51obj-$(CONFIG_RTL8187) += rtl8187.o 54obj-$(CONFIG_RTL8187) += rtl8187.o
52 55
53obj-$(CONFIG_ADM8211) += adm8211.o 56obj-$(CONFIG_ADM8211) += adm8211.o
diff --git a/drivers/net/wireless/rtl8180.h b/drivers/net/wireless/rtl8180.h
new file mode 100644
index 000000000000..0b333cacbd85
--- /dev/null
+++ b/drivers/net/wireless/rtl8180.h
@@ -0,0 +1,151 @@
1#ifndef RTL8180_H
2#define RTL8180_H
3
4#include "rtl818x.h"
5
6#define MAX_RX_SIZE IEEE80211_MAX_RTS_THRESHOLD
7
8#define RF_PARAM_ANALOGPHY (1 << 0)
9#define RF_PARAM_ANTBDEFAULT (1 << 1)
10#define RF_PARAM_CARRIERSENSE1 (1 << 2)
11#define RF_PARAM_CARRIERSENSE2 (1 << 3)
12
13#define BB_ANTATTEN_CHAN14 0x0C
14#define BB_ANTENNA_B 0x40
15
16#define BB_HOST_BANG (1 << 30)
17#define BB_HOST_BANG_EN (1 << 2)
18#define BB_HOST_BANG_CLK (1 << 1)
19#define BB_HOST_BANG_DATA 1
20
21#define ANAPARAM_TXDACOFF_SHIFT 27
22#define ANAPARAM_PWR0_SHIFT 28
23#define ANAPARAM_PWR0_MASK (0x07 << ANAPARAM_PWR0_SHIFT)
24#define ANAPARAM_PWR1_SHIFT 20
25#define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT)
26
27enum rtl8180_tx_desc_flags {
28 RTL8180_TX_DESC_FLAG_NO_ENC = (1 << 15),
29 RTL8180_TX_DESC_FLAG_TX_OK = (1 << 15),
30 RTL8180_TX_DESC_FLAG_SPLCP = (1 << 16),
31 RTL8180_TX_DESC_FLAG_RX_UNDER = (1 << 16),
32 RTL8180_TX_DESC_FLAG_MOREFRAG = (1 << 17),
33 RTL8180_TX_DESC_FLAG_CTS = (1 << 18),
34 RTL8180_TX_DESC_FLAG_RTS = (1 << 23),
35 RTL8180_TX_DESC_FLAG_LS = (1 << 28),
36 RTL8180_TX_DESC_FLAG_FS = (1 << 29),
37 RTL8180_TX_DESC_FLAG_DMA = (1 << 30),
38 RTL8180_TX_DESC_FLAG_OWN = (1 << 31)
39};
40
41struct rtl8180_tx_desc {
42 __le32 flags;
43 __le16 rts_duration;
44 __le16 plcp_len;
45 __le32 tx_buf;
46 __le32 frame_len;
47 __le32 next_tx_desc;
48 u8 cw;
49 u8 retry_limit;
50 u8 agc;
51 u8 flags2;
52 u32 reserved[2];
53} __attribute__ ((packed));
54
55enum rtl8180_rx_desc_flags {
56 RTL8180_RX_DESC_FLAG_ICV_ERR = (1 << 12),
57 RTL8180_RX_DESC_FLAG_CRC32_ERR = (1 << 13),
58 RTL8180_RX_DESC_FLAG_PM = (1 << 14),
59 RTL8180_RX_DESC_FLAG_RX_ERR = (1 << 15),
60 RTL8180_RX_DESC_FLAG_BCAST = (1 << 16),
61 RTL8180_RX_DESC_FLAG_PAM = (1 << 17),
62 RTL8180_RX_DESC_FLAG_MCAST = (1 << 18),
63 RTL8180_RX_DESC_FLAG_SPLCP = (1 << 25),
64 RTL8180_RX_DESC_FLAG_FOF = (1 << 26),
65 RTL8180_RX_DESC_FLAG_DMA_FAIL = (1 << 27),
66 RTL8180_RX_DESC_FLAG_LS = (1 << 28),
67 RTL8180_RX_DESC_FLAG_FS = (1 << 29),
68 RTL8180_RX_DESC_FLAG_EOR = (1 << 30),
69 RTL8180_RX_DESC_FLAG_OWN = (1 << 31)
70};
71
72struct rtl8180_rx_desc {
73 __le32 flags;
74 __le32 flags2;
75 union {
76 __le32 rx_buf;
77 __le64 tsft;
78 };
79} __attribute__ ((packed));
80
81struct rtl8180_tx_ring {
82 struct rtl8180_tx_desc *desc;
83 dma_addr_t dma;
84 unsigned int idx;
85 unsigned int entries;
86 struct sk_buff_head queue;
87};
88
89struct rtl8180_priv {
90 /* common between rtl818x drivers */
91 struct rtl818x_csr __iomem *map;
92 const struct rtl818x_rf_ops *rf;
93 int mode;
94 int if_id;
95
96 /* rtl8180 driver specific */
97 spinlock_t lock;
98 struct rtl8180_rx_desc *rx_ring;
99 dma_addr_t rx_ring_dma;
100 unsigned int rx_idx;
101 struct sk_buff *rx_buf[32];
102 struct rtl8180_tx_ring tx_ring[4];
103 struct ieee80211_channel channels[14];
104 struct ieee80211_rate rates[12];
105 struct ieee80211_hw_mode modes[2];
106 struct pci_dev *pdev;
107 u32 rx_conf;
108
109 int r8185;
110 u32 anaparam;
111 u16 rfparam;
112 u8 csthreshold;
113};
114
115void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
116void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam);
117
118static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr)
119{
120 return ioread8(addr);
121}
122
123static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, __le16 __iomem *addr)
124{
125 return ioread16(addr);
126}
127
128static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, __le32 __iomem *addr)
129{
130 return ioread32(addr);
131}
132
133static inline void rtl818x_iowrite8(struct rtl8180_priv *priv,
134 u8 __iomem *addr, u8 val)
135{
136 iowrite8(val, addr);
137}
138
139static inline void rtl818x_iowrite16(struct rtl8180_priv *priv,
140 __le16 __iomem *addr, u16 val)
141{
142 iowrite16(val, addr);
143}
144
145static inline void rtl818x_iowrite32(struct rtl8180_priv *priv,
146 __le32 __iomem *addr, u32 val)
147{
148 iowrite32(val, addr);
149}
150
151#endif /* RTL8180_H */
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
new file mode 100644
index 000000000000..4b7b032c194a
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -0,0 +1,1048 @@
1
2/*
3 * Linux device driver for RTL8180 / RTL8185
4 *
5 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
6 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
7 *
8 * Based on the r8180 driver, which is:
9 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
10 *
11 * Thanks to Realtek for their support!
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/pci.h>
20#include <linux/delay.h>
21#include <linux/etherdevice.h>
22#include <linux/eeprom_93cx6.h>
23#include <net/mac80211.h>
24
25#include "rtl8180.h"
26#include "rtl8180_rtl8225.h"
27#include "rtl8180_sa2400.h"
28#include "rtl8180_max2820.h"
29#include "rtl8180_grf5101.h"
30
31MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
32MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
33MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver");
34MODULE_LICENSE("GPL");
35
36static struct pci_device_id rtl8180_table[] __devinitdata = {
37 /* rtl8185 */
38 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
39 { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) },
40
41 /* rtl8180 */
42 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) },
43 { PCI_DEVICE(0x1799, 0x6001) },
44 { PCI_DEVICE(0x1799, 0x6020) },
45 { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) },
46 { }
47};
48
49MODULE_DEVICE_TABLE(pci, rtl8180_table);
50
51void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
52{
53 struct rtl8180_priv *priv = dev->priv;
54 int i = 10;
55 u32 buf;
56
57 buf = (data << 8) | addr;
58
59 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf | 0x80);
60 while (i--) {
61 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf);
62 if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF))
63 return;
64 }
65}
66
67static void rtl8180_handle_rx(struct ieee80211_hw *dev)
68{
69 struct rtl8180_priv *priv = dev->priv;
70 unsigned int count = 32;
71
72 while (count--) {
73 struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
74 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
75 u32 flags = le32_to_cpu(entry->flags);
76
77 if (flags & RTL8180_RX_DESC_FLAG_OWN)
78 return;
79
80 if (unlikely(flags & (RTL8180_RX_DESC_FLAG_DMA_FAIL |
81 RTL8180_RX_DESC_FLAG_FOF |
82 RTL8180_RX_DESC_FLAG_RX_ERR)))
83 goto done;
84 else {
85 u32 flags2 = le32_to_cpu(entry->flags2);
86 struct ieee80211_rx_status rx_status = {0};
87 struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE);
88
89 if (unlikely(!new_skb))
90 goto done;
91
92 pci_unmap_single(priv->pdev,
93 *((dma_addr_t *)skb->cb),
94 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
95 skb_put(skb, flags & 0xFFF);
96
97 rx_status.antenna = (flags2 >> 15) & 1;
98 /* TODO: improve signal/rssi reporting */
99 rx_status.signal = flags2 & 0xFF;
100 rx_status.ssi = (flags2 >> 8) & 0x7F;
101 rx_status.rate = (flags >> 20) & 0xF;
102 rx_status.freq = dev->conf.freq;
103 rx_status.channel = dev->conf.channel;
104 rx_status.phymode = dev->conf.phymode;
105 rx_status.mactime = le64_to_cpu(entry->tsft);
106 rx_status.flag |= RX_FLAG_TSFT;
107 if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR)
108 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
109
110 ieee80211_rx_irqsafe(dev, skb, &rx_status);
111
112 skb = new_skb;
113 priv->rx_buf[priv->rx_idx] = skb;
114 *((dma_addr_t *) skb->cb) =
115 pci_map_single(priv->pdev, skb_tail_pointer(skb),
116 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
117 }
118
119 done:
120 entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb));
121 entry->flags = cpu_to_le32(RTL8180_RX_DESC_FLAG_OWN |
122 MAX_RX_SIZE);
123 if (priv->rx_idx == 31)
124 entry->flags |= cpu_to_le32(RTL8180_RX_DESC_FLAG_EOR);
125 priv->rx_idx = (priv->rx_idx + 1) % 32;
126 }
127}
128
129static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
130{
131 struct rtl8180_priv *priv = dev->priv;
132 struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
133
134 while (skb_queue_len(&ring->queue)) {
135 struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
136 struct sk_buff *skb;
137 struct ieee80211_tx_status status = { {0} };
138 struct ieee80211_tx_control *control;
139 u32 flags = le32_to_cpu(entry->flags);
140
141 if (flags & RTL8180_TX_DESC_FLAG_OWN)
142 return;
143
144 ring->idx = (ring->idx + 1) % ring->entries;
145 skb = __skb_dequeue(&ring->queue);
146 pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
147 skb->len, PCI_DMA_TODEVICE);
148
149 control = *((struct ieee80211_tx_control **)skb->cb);
150 if (control)
151 memcpy(&status.control, control, sizeof(*control));
152 kfree(control);
153
154 if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
155 if (flags & RTL8180_TX_DESC_FLAG_TX_OK)
156 status.flags = IEEE80211_TX_STATUS_ACK;
157 else
158 status.excessive_retries = 1;
159 }
160 status.retry_count = flags & 0xFF;
161
162 ieee80211_tx_status_irqsafe(dev, skb, &status);
163 if (ring->entries - skb_queue_len(&ring->queue) == 2)
164 ieee80211_wake_queue(dev, prio);
165 }
166}
167
168static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
169{
170 struct ieee80211_hw *dev = dev_id;
171 struct rtl8180_priv *priv = dev->priv;
172 u16 reg;
173
174 spin_lock(&priv->lock);
175 reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
176 if (unlikely(reg == 0xFFFF)) {
177 spin_unlock(&priv->lock);
178 return IRQ_HANDLED;
179 }
180
181 rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
182
183 if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
184 rtl8180_handle_tx(dev, 3);
185
186 if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR))
187 rtl8180_handle_tx(dev, 2);
188
189 if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
190 rtl8180_handle_tx(dev, 1);
191
192 if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
193 rtl8180_handle_tx(dev, 0);
194
195 if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
196 rtl8180_handle_rx(dev);
197
198 spin_unlock(&priv->lock);
199
200 return IRQ_HANDLED;
201}
202
203static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
204 struct ieee80211_tx_control *control)
205{
206 struct rtl8180_priv *priv = dev->priv;
207 struct rtl8180_tx_ring *ring;
208 struct rtl8180_tx_desc *entry;
209 unsigned long flags;
210 unsigned int idx, prio;
211 dma_addr_t mapping;
212 u32 tx_flags;
213 u16 plcp_len = 0;
214 __le16 rts_duration = 0;
215
216 prio = control->queue;
217 ring = &priv->tx_ring[prio];
218
219 mapping = pci_map_single(priv->pdev, skb->data,
220 skb->len, PCI_DMA_TODEVICE);
221
222 tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS |
223 RTL8180_TX_DESC_FLAG_LS | (control->tx_rate << 24) |
224 (control->rts_cts_rate << 19) | skb->len;
225
226 if (priv->r8185)
227 tx_flags |= RTL8180_TX_DESC_FLAG_DMA |
228 RTL8180_TX_DESC_FLAG_NO_ENC;
229
230 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
231 tx_flags |= RTL8180_TX_DESC_FLAG_RTS;
232 else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
233 tx_flags |= RTL8180_TX_DESC_FLAG_CTS;
234
235 *((struct ieee80211_tx_control **) skb->cb) =
236 kmemdup(control, sizeof(*control), GFP_ATOMIC);
237
238 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
239 rts_duration = ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
240
241 if (!priv->r8185) {
242 unsigned int remainder;
243
244 plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
245 (control->rate->rate * 2) / 10);
246 remainder = (16 * (skb->len + 4)) %
247 ((control->rate->rate * 2) / 10);
248 if (remainder > 0 && remainder <= 6)
249 plcp_len |= 1 << 15;
250 }
251
252 spin_lock_irqsave(&priv->lock, flags);
253 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
254 entry = &ring->desc[idx];
255
256 entry->rts_duration = rts_duration;
257 entry->plcp_len = cpu_to_le16(plcp_len);
258 entry->tx_buf = cpu_to_le32(mapping);
259 entry->frame_len = cpu_to_le32(skb->len);
260 entry->flags2 = control->alt_retry_rate != -1 ?
261 control->alt_retry_rate << 4 : 0;
262 entry->retry_limit = control->retry_limit;
263 entry->flags = cpu_to_le32(tx_flags);
264 __skb_queue_tail(&ring->queue, skb);
265 if (ring->entries - skb_queue_len(&ring->queue) < 2)
266 ieee80211_stop_queue(dev, control->queue);
267 spin_unlock_irqrestore(&priv->lock, flags);
268
269 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
270
271 return 0;
272}
273
274void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam)
275{
276 u8 reg;
277
278 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
279 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
280 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
281 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
282 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
283 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
284 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
285 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
286}
287
288static int rtl8180_init_hw(struct ieee80211_hw *dev)
289{
290 struct rtl8180_priv *priv = dev->priv;
291 u16 reg;
292
293 rtl818x_iowrite8(priv, &priv->map->CMD, 0);
294 rtl818x_ioread8(priv, &priv->map->CMD);
295 msleep(10);
296
297 /* reset */
298 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
299 rtl818x_ioread8(priv, &priv->map->CMD);
300
301 reg = rtl818x_ioread8(priv, &priv->map->CMD);
302 reg &= (1 << 1);
303 reg |= RTL818X_CMD_RESET;
304 rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET);
305 rtl818x_ioread8(priv, &priv->map->CMD);
306 msleep(200);
307
308 /* check success of reset */
309 if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
310 printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy));
311 return -ETIMEDOUT;
312 }
313
314 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
315 rtl818x_ioread8(priv, &priv->map->CMD);
316 msleep(200);
317
318 if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) {
319 /* For cardbus */
320 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
321 reg |= 1 << 1;
322 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
323 reg = rtl818x_ioread16(priv, &priv->map->FEMR);
324 reg |= (1 << 15) | (1 << 14) | (1 << 4);
325 rtl818x_iowrite16(priv, &priv->map->FEMR, reg);
326 }
327
328 rtl818x_iowrite8(priv, &priv->map->MSR, 0);
329
330 if (!priv->r8185)
331 rtl8180_set_anaparam(priv, priv->anaparam);
332
333 rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
334 rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma);
335 rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma);
336 rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma);
337 rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma);
338
339 /* TODO: necessary? specs indicate not */
340 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
341 reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
342 rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3));
343 if (priv->r8185) {
344 reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
345 rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4));
346 }
347 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
348
349 /* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */
350
351 /* TODO: turn off hw wep on rtl8180 */
352
353 rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
354
355 if (priv->r8185) {
356 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
357 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
358 rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
359
360 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
361
362 /* TODO: set ClkRun enable? necessary? */
363 reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE);
364 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6));
365 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
366 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
367 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2));
368 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
369 } else {
370 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1);
371 rtl818x_iowrite8(priv, &priv->map->SECURITY, 0);
372
373 rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6);
374 rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C);
375 }
376
377 priv->rf->init(dev);
378 if (priv->r8185)
379 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
380 return 0;
381}
382
383static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
384{
385 struct rtl8180_priv *priv = dev->priv;
386 struct rtl8180_rx_desc *entry;
387 int i;
388
389 priv->rx_ring = pci_alloc_consistent(priv->pdev,
390 sizeof(*priv->rx_ring) * 32,
391 &priv->rx_ring_dma);
392
393 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
394 printk(KERN_ERR "%s: Cannot allocate RX ring\n",
395 wiphy_name(dev->wiphy));
396 return -ENOMEM;
397 }
398
399 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32);
400 priv->rx_idx = 0;
401
402 for (i = 0; i < 32; i++) {
403 struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE);
404 dma_addr_t *mapping;
405 entry = &priv->rx_ring[i];
406 if (!skb)
407 return 0;
408
409 priv->rx_buf[i] = skb;
410 mapping = (dma_addr_t *)skb->cb;
411 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
412 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
413 entry->rx_buf = cpu_to_le32(*mapping);
414 entry->flags = cpu_to_le32(RTL8180_RX_DESC_FLAG_OWN |
415 MAX_RX_SIZE);
416 }
417 entry->flags |= cpu_to_le32(RTL8180_RX_DESC_FLAG_EOR);
418 return 0;
419}
420
421static void rtl8180_free_rx_ring(struct ieee80211_hw *dev)
422{
423 struct rtl8180_priv *priv = dev->priv;
424 int i;
425
426 for (i = 0; i < 32; i++) {
427 struct sk_buff *skb = priv->rx_buf[i];
428 if (!skb)
429 continue;
430
431 pci_unmap_single(priv->pdev,
432 *((dma_addr_t *)skb->cb),
433 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
434 kfree_skb(skb);
435 }
436
437 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32,
438 priv->rx_ring, priv->rx_ring_dma);
439 priv->rx_ring = NULL;
440}
441
442static int rtl8180_init_tx_ring(struct ieee80211_hw *dev,
443 unsigned int prio, unsigned int entries)
444{
445 struct rtl8180_priv *priv = dev->priv;
446 struct rtl8180_tx_desc *ring;
447 dma_addr_t dma;
448 int i;
449
450 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
451 if (!ring || (unsigned long)ring & 0xFF) {
452 printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n",
453 wiphy_name(dev->wiphy), prio);
454 return -ENOMEM;
455 }
456
457 memset(ring, 0, sizeof(*ring)*entries);
458 priv->tx_ring[prio].desc = ring;
459 priv->tx_ring[prio].dma = dma;
460 priv->tx_ring[prio].idx = 0;
461 priv->tx_ring[prio].entries = entries;
462 skb_queue_head_init(&priv->tx_ring[prio].queue);
463
464 for (i = 0; i < entries; i++)
465 ring[i].next_tx_desc =
466 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
467
468 return 0;
469}
470
471static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio)
472{
473 struct rtl8180_priv *priv = dev->priv;
474 struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
475
476 while (skb_queue_len(&ring->queue)) {
477 struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
478 struct sk_buff *skb = __skb_dequeue(&ring->queue);
479
480 pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
481 skb->len, PCI_DMA_TODEVICE);
482 kfree(*((struct ieee80211_tx_control **) skb->cb));
483 kfree_skb(skb);
484 ring->idx = (ring->idx + 1) % ring->entries;
485 }
486
487 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
488 ring->desc, ring->dma);
489 ring->desc = NULL;
490}
491
492static int rtl8180_start(struct ieee80211_hw *dev)
493{
494 struct rtl8180_priv *priv = dev->priv;
495 int ret, i;
496 u32 reg;
497
498 ret = rtl8180_init_rx_ring(dev);
499 if (ret)
500 return ret;
501
502 for (i = 0; i < 4; i++)
503 if ((ret = rtl8180_init_tx_ring(dev, i, 16)))
504 goto err_free_rings;
505
506 ret = rtl8180_init_hw(dev);
507 if (ret)
508 goto err_free_rings;
509
510 rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
511 rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma);
512 rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma);
513 rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma);
514 rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma);
515
516 ret = request_irq(priv->pdev->irq, &rtl8180_interrupt,
517 IRQF_SHARED, KBUILD_MODNAME, dev);
518 if (ret) {
519 printk(KERN_ERR "%s: failed to register IRQ handler\n",
520 wiphy_name(dev->wiphy));
521 goto err_free_rings;
522 }
523
524 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
525
526 rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
527 rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
528
529 reg = RTL818X_RX_CONF_ONLYERLPKT |
530 RTL818X_RX_CONF_RX_AUTORESETPHY |
531 RTL818X_RX_CONF_MGMT |
532 RTL818X_RX_CONF_DATA |
533 (7 << 8 /* MAX RX DMA */) |
534 RTL818X_RX_CONF_BROADCAST |
535 RTL818X_RX_CONF_NICMAC;
536
537 if (priv->r8185)
538 reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2;
539 else {
540 reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1)
541 ? RTL818X_RX_CONF_CSDM1 : 0;
542 reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2)
543 ? RTL818X_RX_CONF_CSDM2 : 0;
544 }
545
546 priv->rx_conf = reg;
547 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
548
549 if (priv->r8185) {
550 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
551 reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT;
552 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
553 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
554
555 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
556 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
557 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
558 reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
559 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
560
561 /* disable early TX */
562 rtl818x_iowrite8(priv, (u8 __iomem *)priv->map + 0xec, 0x3f);
563 }
564
565 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
566 reg |= (6 << 21 /* MAX TX DMA */) |
567 RTL818X_TX_CONF_NO_ICV;
568
569 if (priv->r8185)
570 reg &= ~RTL818X_TX_CONF_PROBE_DTS;
571 else
572 reg &= ~RTL818X_TX_CONF_HW_SEQNUM;
573
574 /* different meaning, same value on both rtl8185 and rtl8180 */
575 reg &= ~RTL818X_TX_CONF_SAT_HWPLCP;
576
577 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
578
579 reg = rtl818x_ioread8(priv, &priv->map->CMD);
580 reg |= RTL818X_CMD_RX_ENABLE;
581 reg |= RTL818X_CMD_TX_ENABLE;
582 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
583
584 priv->mode = IEEE80211_IF_TYPE_MNTR;
585 return 0;
586
587 err_free_rings:
588 rtl8180_free_rx_ring(dev);
589 for (i = 0; i < 4; i++)
590 if (priv->tx_ring[i].desc)
591 rtl8180_free_tx_ring(dev, i);
592
593 return ret;
594}
595
596static void rtl8180_stop(struct ieee80211_hw *dev)
597{
598 struct rtl8180_priv *priv = dev->priv;
599 u8 reg;
600 int i;
601
602 priv->mode = IEEE80211_IF_TYPE_INVALID;
603
604 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
605
606 reg = rtl818x_ioread8(priv, &priv->map->CMD);
607 reg &= ~RTL818X_CMD_TX_ENABLE;
608 reg &= ~RTL818X_CMD_RX_ENABLE;
609 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
610
611 priv->rf->stop(dev);
612
613 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
614 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
615 rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
616 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
617
618 free_irq(priv->pdev->irq, dev);
619
620 rtl8180_free_rx_ring(dev);
621 for (i = 0; i < 4; i++)
622 rtl8180_free_tx_ring(dev, i);
623}
624
625static int rtl8180_add_interface(struct ieee80211_hw *dev,
626 struct ieee80211_if_init_conf *conf)
627{
628 struct rtl8180_priv *priv = dev->priv;
629
630 if (priv->mode != IEEE80211_IF_TYPE_MNTR)
631 return -EOPNOTSUPP;
632
633 switch (conf->type) {
634 case IEEE80211_IF_TYPE_STA:
635 priv->mode = conf->type;
636 break;
637 default:
638 return -EOPNOTSUPP;
639 }
640
641 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
642 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
643 cpu_to_le32(*(u32 *)conf->mac_addr));
644 rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4],
645 cpu_to_le16(*(u16 *)(conf->mac_addr + 4)));
646 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
647
648 return 0;
649}
650
651static void rtl8180_remove_interface(struct ieee80211_hw *dev,
652 struct ieee80211_if_init_conf *conf)
653{
654 struct rtl8180_priv *priv = dev->priv;
655 priv->mode = IEEE80211_IF_TYPE_MNTR;
656}
657
658static int rtl8180_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
659{
660 struct rtl8180_priv *priv = dev->priv;
661
662 priv->rf->set_chan(dev, conf);
663
664 return 0;
665}
666
667static int rtl8180_config_interface(struct ieee80211_hw *dev, int if_id,
668 struct ieee80211_if_conf *conf)
669{
670 struct rtl8180_priv *priv = dev->priv;
671 int i;
672
673 priv->if_id = if_id;
674
675 for (i = 0; i < ETH_ALEN; i++)
676 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
677
678 if (is_valid_ether_addr(conf->bssid))
679 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
680 else
681 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
682
683 return 0;
684}
685
686static void rtl8180_configure_filter(struct ieee80211_hw *dev,
687 unsigned int changed_flags,
688 unsigned int *total_flags,
689 int mc_count, struct dev_addr_list *mclist)
690{
691 struct rtl8180_priv *priv = dev->priv;
692
693 if (changed_flags & FIF_FCSFAIL)
694 priv->rx_conf ^= RTL818X_RX_CONF_FCS;
695 if (changed_flags & FIF_CONTROL)
696 priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
697 if (changed_flags & FIF_OTHER_BSS)
698 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
699 if (*total_flags & FIF_ALLMULTI || mc_count > 0)
700 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
701 else
702 priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
703
704 *total_flags = 0;
705
706 if (priv->rx_conf & RTL818X_RX_CONF_FCS)
707 *total_flags |= FIF_FCSFAIL;
708 if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
709 *total_flags |= FIF_CONTROL;
710 if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
711 *total_flags |= FIF_OTHER_BSS;
712 if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
713 *total_flags |= FIF_ALLMULTI;
714
715 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
716}
717
718static const struct ieee80211_ops rtl8180_ops = {
719 .tx = rtl8180_tx,
720 .start = rtl8180_start,
721 .stop = rtl8180_stop,
722 .add_interface = rtl8180_add_interface,
723 .remove_interface = rtl8180_remove_interface,
724 .config = rtl8180_config,
725 .config_interface = rtl8180_config_interface,
726 .configure_filter = rtl8180_configure_filter,
727};
728
729static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
730{
731 struct ieee80211_hw *dev = eeprom->data;
732 struct rtl8180_priv *priv = dev->priv;
733 u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
734
735 eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
736 eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
737 eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
738 eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
739}
740
741static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom)
742{
743 struct ieee80211_hw *dev = eeprom->data;
744 struct rtl8180_priv *priv = dev->priv;
745 u8 reg = 2 << 6;
746
747 if (eeprom->reg_data_in)
748 reg |= RTL818X_EEPROM_CMD_WRITE;
749 if (eeprom->reg_data_out)
750 reg |= RTL818X_EEPROM_CMD_READ;
751 if (eeprom->reg_data_clock)
752 reg |= RTL818X_EEPROM_CMD_CK;
753 if (eeprom->reg_chip_select)
754 reg |= RTL818X_EEPROM_CMD_CS;
755
756 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
757 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
758 udelay(10);
759}
760
761static int __devinit rtl8180_probe(struct pci_dev *pdev,
762 const struct pci_device_id *id)
763{
764 struct ieee80211_hw *dev;
765 struct rtl8180_priv *priv;
766 unsigned long mem_addr, mem_len;
767 unsigned int io_addr, io_len;
768 int err, i;
769 struct eeprom_93cx6 eeprom;
770 const char *chip_name, *rf_name = NULL;
771 u32 reg;
772 u16 eeprom_val;
773 DECLARE_MAC_BUF(mac);
774
775 err = pci_enable_device(pdev);
776 if (err) {
777 printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n",
778 pci_name(pdev));
779 return err;
780 }
781
782 err = pci_request_regions(pdev, KBUILD_MODNAME);
783 if (err) {
784 printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n",
785 pci_name(pdev));
786 return err;
787 }
788
789 io_addr = pci_resource_start(pdev, 0);
790 io_len = pci_resource_len(pdev, 0);
791 mem_addr = pci_resource_start(pdev, 1);
792 mem_len = pci_resource_len(pdev, 1);
793
794 if (mem_len < sizeof(struct rtl818x_csr) ||
795 io_len < sizeof(struct rtl818x_csr)) {
796 printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n",
797 pci_name(pdev));
798 err = -ENOMEM;
799 goto err_free_reg;
800 }
801
802 if ((err = pci_set_dma_mask(pdev, 0xFFFFFF00ULL)) ||
803 (err = pci_set_consistent_dma_mask(pdev, 0xFFFFFF00ULL))) {
804 printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n",
805 pci_name(pdev));
806 goto err_free_reg;
807 }
808
809 pci_set_master(pdev);
810
811 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops);
812 if (!dev) {
813 printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n",
814 pci_name(pdev));
815 err = -ENOMEM;
816 goto err_free_reg;
817 }
818
819 priv = dev->priv;
820 priv->pdev = pdev;
821
822 SET_IEEE80211_DEV(dev, &pdev->dev);
823 pci_set_drvdata(pdev, dev);
824
825 priv->map = pci_iomap(pdev, 1, mem_len);
826 if (!priv->map)
827 priv->map = pci_iomap(pdev, 0, io_len);
828
829 if (!priv->map) {
830 printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n",
831 pci_name(pdev));
832 goto err_free_dev;
833 }
834
835 memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
836 memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
837 priv->modes[0].mode = MODE_IEEE80211G;
838 priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates);
839 priv->modes[0].rates = priv->rates;
840 priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels);
841 priv->modes[0].channels = priv->channels;
842 priv->modes[1].mode = MODE_IEEE80211B;
843 priv->modes[1].num_rates = 4;
844 priv->modes[1].rates = priv->rates;
845 priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels);
846 priv->modes[1].channels = priv->channels;
847 priv->mode = IEEE80211_IF_TYPE_INVALID;
848 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
849 IEEE80211_HW_RX_INCLUDES_FCS;
850 dev->queues = 1;
851 dev->max_rssi = 65;
852
853 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
854 reg &= RTL818X_TX_CONF_HWVER_MASK;
855 switch (reg) {
856 case RTL818X_TX_CONF_R8180_ABCD:
857 chip_name = "RTL8180";
858 break;
859 case RTL818X_TX_CONF_R8180_F:
860 chip_name = "RTL8180vF";
861 break;
862 case RTL818X_TX_CONF_R8185_ABC:
863 chip_name = "RTL8185";
864 break;
865 case RTL818X_TX_CONF_R8185_D:
866 chip_name = "RTL8185vD";
867 break;
868 default:
869 printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n",
870 pci_name(pdev), reg >> 25);
871 goto err_iounmap;
872 }
873
874 priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC;
875 if (priv->r8185) {
876 if ((err = ieee80211_register_hwmode(dev, &priv->modes[0])))
877 goto err_iounmap;
878
879 pci_try_set_mwi(pdev);
880 }
881
882 if ((err = ieee80211_register_hwmode(dev, &priv->modes[1])))
883 goto err_iounmap;
884
885 eeprom.data = dev;
886 eeprom.register_read = rtl8180_eeprom_register_read;
887 eeprom.register_write = rtl8180_eeprom_register_write;
888 if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
889 eeprom.width = PCI_EEPROM_WIDTH_93C66;
890 else
891 eeprom.width = PCI_EEPROM_WIDTH_93C46;
892
893 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM);
894 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
895 udelay(10);
896
897 eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val);
898 eeprom_val &= 0xFF;
899 switch (eeprom_val) {
900 case 1: rf_name = "Intersil";
901 break;
902 case 2: rf_name = "RFMD";
903 break;
904 case 3: priv->rf = &sa2400_rf_ops;
905 break;
906 case 4: priv->rf = &max2820_rf_ops;
907 break;
908 case 5: priv->rf = &grf5101_rf_ops;
909 break;
910 case 9: priv->rf = rtl8180_detect_rf(dev);
911 break;
912 case 10:
913 rf_name = "RTL8255";
914 break;
915 default:
916 printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n",
917 pci_name(pdev), eeprom_val);
918 goto err_iounmap;
919 }
920
921 if (!priv->rf) {
922 printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n",
923 pci_name(pdev), rf_name);
924 goto err_iounmap;
925 }
926
927 eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val);
928 priv->csthreshold = eeprom_val >> 8;
929 if (!priv->r8185) {
930 __le32 anaparam;
931 eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2);
932 priv->anaparam = le32_to_cpu(anaparam);
933 eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam);
934 }
935
936 eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3);
937 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
938 printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using"
939 " randomly generated MAC addr\n", pci_name(pdev));
940 random_ether_addr(dev->wiphy->perm_addr);
941 }
942
943 /* CCK TX power */
944 for (i = 0; i < 14; i += 2) {
945 u16 txpwr;
946 eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr);
947 priv->channels[i].val = txpwr & 0xFF;
948 priv->channels[i + 1].val = txpwr >> 8;
949 }
950
951 /* OFDM TX power */
952 if (priv->r8185) {
953 for (i = 0; i < 14; i += 2) {
954 u16 txpwr;
955 eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr);
956 priv->channels[i].val |= (txpwr & 0xFF) << 8;
957 priv->channels[i + 1].val |= txpwr & 0xFF00;
958 }
959 }
960
961 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
962
963 spin_lock_init(&priv->lock);
964
965 err = ieee80211_register_hw(dev);
966 if (err) {
967 printk(KERN_ERR "%s (rtl8180): Cannot register device\n",
968 pci_name(pdev));
969 goto err_iounmap;
970 }
971
972 printk(KERN_INFO "%s: hwaddr %s, %s + %s\n",
973 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
974 chip_name, priv->rf->name);
975
976 return 0;
977
978 err_iounmap:
979 iounmap(priv->map);
980
981 err_free_dev:
982 pci_set_drvdata(pdev, NULL);
983 ieee80211_free_hw(dev);
984
985 err_free_reg:
986 pci_release_regions(pdev);
987 pci_disable_device(pdev);
988 return err;
989}
990
991static void __devexit rtl8180_remove(struct pci_dev *pdev)
992{
993 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
994 struct rtl8180_priv *priv;
995
996 if (!dev)
997 return;
998
999 ieee80211_unregister_hw(dev);
1000
1001 priv = dev->priv;
1002
1003 pci_iounmap(pdev, priv->map);
1004 pci_release_regions(pdev);
1005 pci_disable_device(pdev);
1006 ieee80211_free_hw(dev);
1007}
1008
1009#ifdef CONFIG_PM
1010static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
1011{
1012 pci_save_state(pdev);
1013 pci_set_power_state(pdev, pci_choose_state(pdev, state));
1014 return 0;
1015}
1016
1017static int rtl8180_resume(struct pci_dev *pdev)
1018{
1019 pci_set_power_state(pdev, PCI_D0);
1020 pci_restore_state(pdev);
1021 return 0;
1022}
1023
1024#endif /* CONFIG_PM */
1025
1026static struct pci_driver rtl8180_driver = {
1027 .name = KBUILD_MODNAME,
1028 .id_table = rtl8180_table,
1029 .probe = rtl8180_probe,
1030 .remove = __devexit_p(rtl8180_remove),
1031#ifdef CONFIG_PM
1032 .suspend = rtl8180_suspend,
1033 .resume = rtl8180_resume,
1034#endif /* CONFIG_PM */
1035};
1036
1037static int __init rtl8180_init(void)
1038{
1039 return pci_register_driver(&rtl8180_driver);
1040}
1041
1042static void __exit rtl8180_exit(void)
1043{
1044 pci_unregister_driver(&rtl8180_driver);
1045}
1046
1047module_init(rtl8180_init);
1048module_exit(rtl8180_exit);
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c
new file mode 100644
index 000000000000..8293e19c4c59
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_grf5101.c
@@ -0,0 +1,179 @@
1
2/*
3 * Radio tuning for GCT GRF5101 on RTL8180
4 *
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Code from the BSD driver and the rtl8181 project have been
8 * very useful to understand certain things
9 *
10 * I want to thanks the Authors of such projects and the Ndiswrapper
11 * project Authors.
12 *
13 * A special Big Thanks also is for all people who donated me cards,
14 * making possible the creation of the original rtl8180 driver
15 * from which this code is derived!
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 */
21
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <net/mac80211.h>
26
27#include "rtl8180.h"
28#include "rtl8180_grf5101.h"
29
30static const int grf5101_encode[] = {
31 0x0, 0x8, 0x4, 0xC,
32 0x2, 0xA, 0x6, 0xE,
33 0x1, 0x9, 0x5, 0xD,
34 0x3, 0xB, 0x7, 0xF
35};
36
37static void write_grf5101(struct ieee80211_hw *dev, u8 addr, u32 data)
38{
39 struct rtl8180_priv *priv = dev->priv;
40 u32 phy_config;
41
42 phy_config = grf5101_encode[(data >> 8) & 0xF];
43 phy_config |= grf5101_encode[(data >> 4) & 0xF] << 4;
44 phy_config |= grf5101_encode[data & 0xF] << 8;
45 phy_config |= grf5101_encode[(addr >> 1) & 0xF] << 12;
46 phy_config |= (addr & 1) << 16;
47 phy_config |= grf5101_encode[(data & 0xf000) >> 12] << 24;
48
49 /* MAC will bang bits to the chip */
50 phy_config |= 0x90000000;
51
52 rtl818x_iowrite32(priv,
53 (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
54
55 msleep(3);
56}
57
58static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan)
59{
60 struct rtl8180_priv *priv = dev->priv;
61 u8 ant = GRF5101_ANTENNA;
62
63 if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
64 ant |= BB_ANTENNA_B;
65
66 if (chan == 14)
67 ant |= BB_ANTATTEN_CHAN14;
68
69 rtl8180_write_phy(dev, 0x10, ant);
70}
71
72static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
73 struct ieee80211_conf *conf)
74{
75 struct rtl8180_priv *priv = dev->priv;
76 u32 txpw = priv->channels[conf->channel - 1].val & 0xFF;
77 u32 chan = conf->channel - 1;
78
79 /* set TX power */
80 write_grf5101(dev, 0x15, 0x0);
81 write_grf5101(dev, 0x06, txpw);
82 write_grf5101(dev, 0x15, 0x10);
83 write_grf5101(dev, 0x15, 0x0);
84
85 /* set frequency */
86 write_grf5101(dev, 0x07, 0x0);
87 write_grf5101(dev, 0x0B, chan);
88 write_grf5101(dev, 0x07, 0x1000);
89
90 grf5101_write_phy_antenna(dev, chan);
91}
92
93static void grf5101_rf_stop(struct ieee80211_hw *dev)
94{
95 struct rtl8180_priv *priv = dev->priv;
96 u32 anaparam;
97
98 anaparam = priv->anaparam;
99 anaparam &= 0x000fffff;
100 anaparam |= 0x3f900000;
101 rtl8180_set_anaparam(priv, anaparam);
102
103 write_grf5101(dev, 0x07, 0x0);
104 write_grf5101(dev, 0x1f, 0x45);
105 write_grf5101(dev, 0x1f, 0x5);
106 write_grf5101(dev, 0x00, 0x8e4);
107}
108
109static void grf5101_rf_init(struct ieee80211_hw *dev)
110{
111 struct rtl8180_priv *priv = dev->priv;
112
113 rtl8180_set_anaparam(priv, priv->anaparam);
114
115 write_grf5101(dev, 0x1f, 0x0);
116 write_grf5101(dev, 0x1f, 0x0);
117 write_grf5101(dev, 0x1f, 0x40);
118 write_grf5101(dev, 0x1f, 0x60);
119 write_grf5101(dev, 0x1f, 0x61);
120 write_grf5101(dev, 0x1f, 0x61);
121 write_grf5101(dev, 0x00, 0xae4);
122 write_grf5101(dev, 0x1f, 0x1);
123 write_grf5101(dev, 0x1f, 0x41);
124 write_grf5101(dev, 0x1f, 0x61);
125
126 write_grf5101(dev, 0x01, 0x1a23);
127 write_grf5101(dev, 0x02, 0x4971);
128 write_grf5101(dev, 0x03, 0x41de);
129 write_grf5101(dev, 0x04, 0x2d80);
130 write_grf5101(dev, 0x05, 0x68ff); /* 0x61ff original value */
131 write_grf5101(dev, 0x06, 0x0);
132 write_grf5101(dev, 0x07, 0x0);
133 write_grf5101(dev, 0x08, 0x7533);
134 write_grf5101(dev, 0x09, 0xc401);
135 write_grf5101(dev, 0x0a, 0x0);
136 write_grf5101(dev, 0x0c, 0x1c7);
137 write_grf5101(dev, 0x0d, 0x29d3);
138 write_grf5101(dev, 0x0e, 0x2e8);
139 write_grf5101(dev, 0x10, 0x192);
140 write_grf5101(dev, 0x11, 0x248);
141 write_grf5101(dev, 0x12, 0x0);
142 write_grf5101(dev, 0x13, 0x20c4);
143 write_grf5101(dev, 0x14, 0xf4fc);
144 write_grf5101(dev, 0x15, 0x0);
145 write_grf5101(dev, 0x16, 0x1500);
146
147 write_grf5101(dev, 0x07, 0x1000);
148
149 /* baseband configuration */
150 rtl8180_write_phy(dev, 0, 0xa8);
151 rtl8180_write_phy(dev, 3, 0x0);
152 rtl8180_write_phy(dev, 4, 0xc0);
153 rtl8180_write_phy(dev, 5, 0x90);
154 rtl8180_write_phy(dev, 6, 0x1e);
155 rtl8180_write_phy(dev, 7, 0x64);
156
157 grf5101_write_phy_antenna(dev, 1);
158
159 rtl8180_write_phy(dev, 0x11, 0x88);
160
161 if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
162 RTL818X_CONFIG2_ANTENNA_DIV)
163 rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */
164 else
165 rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */
166
167 rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
168
169 rtl8180_write_phy(dev, 0x19, 0x0);
170 rtl8180_write_phy(dev, 0x1a, 0xa0);
171 rtl8180_write_phy(dev, 0x1b, 0x44);
172}
173
174const struct rtl818x_rf_ops grf5101_rf_ops = {
175 .name = "GCT",
176 .init = grf5101_rf_init,
177 .stop = grf5101_rf_stop,
178 .set_chan = grf5101_rf_set_channel
179};
diff --git a/drivers/net/wireless/rtl8180_grf5101.h b/drivers/net/wireless/rtl8180_grf5101.h
new file mode 100644
index 000000000000..76647111bcff
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_grf5101.h
@@ -0,0 +1,28 @@
1#ifndef RTL8180_GRF5101_H
2#define RTL8180_GRF5101_H
3
4/*
5 * Radio tuning for GCT GRF5101 on RTL8180
6 *
7 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
8 *
9 * Code from the BSD driver and the rtl8181 project have been
10 * very useful to understand certain things
11 *
12 * I want to thanks the Authors of such projects and the Ndiswrapper
13 * project Authors.
14 *
15 * A special Big Thanks also is for all people who donated me cards,
16 * making possible the creation of the original rtl8180 driver
17 * from which this code is derived!
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 2 as
21 * published by the Free Software Foundation.
22 */
23
24#define GRF5101_ANTENNA 0xA3
25
26extern const struct rtl818x_rf_ops grf5101_rf_ops;
27
28#endif /* RTL8180_GRF5101_H */
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c
new file mode 100644
index 000000000000..98fe9fd64968
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_max2820.c
@@ -0,0 +1,150 @@
1/*
2 * Radio tuning for Maxim max2820 on RTL8180
3 *
4 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
5 *
6 * Code from the BSD driver and the rtl8181 project have been
7 * very useful to understand certain things
8 *
9 * I want to thanks the Authors of such projects and the Ndiswrapper
10 * project Authors.
11 *
12 * A special Big Thanks also is for all people who donated me cards,
13 * making possible the creation of the original rtl8180 driver
14 * from which this code is derived!
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 */
20
21#include <linux/init.h>
22#include <linux/pci.h>
23#include <linux/delay.h>
24#include <net/mac80211.h>
25
26#include "rtl8180.h"
27#include "rtl8180_max2820.h"
28
29static const u32 max2820_chan[] = {
30 12, /* CH 1 */
31 17,
32 22,
33 27,
34 32,
35 37,
36 42,
37 47,
38 52,
39 57,
40 62,
41 67,
42 72,
43 84, /* CH 14 */
44};
45
46static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data)
47{
48 struct rtl8180_priv *priv = dev->priv;
49 u32 phy_config;
50
51 phy_config = 0x90 + (data & 0xf);
52 phy_config <<= 16;
53 phy_config += addr;
54 phy_config <<= 8;
55 phy_config += (data >> 4) & 0xff;
56
57 rtl818x_iowrite32(priv,
58 (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
59
60 msleep(1);
61}
62
63static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
64{
65 struct rtl8180_priv *priv = dev->priv;
66 u8 ant;
67
68 ant = MAXIM_ANTENNA;
69 if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
70 ant |= BB_ANTENNA_B;
71 if (chan == 14)
72 ant |= BB_ANTATTEN_CHAN14;
73
74 rtl8180_write_phy(dev, 0x10, ant);
75}
76
77static void max2820_rf_set_channel(struct ieee80211_hw *dev,
78 struct ieee80211_conf *conf)
79{
80 struct rtl8180_priv *priv = dev->priv;
81 unsigned int chan_idx = conf ? conf->channel - 1 : 0;
82 u32 txpw = priv->channels[chan_idx].val & 0xFF;
83 u32 chan = max2820_chan[chan_idx];
84
85 /* While philips SA2400 drive the PA bias from
86 * sa2400, for MAXIM we do this directly from BB */
87 rtl8180_write_phy(dev, 3, txpw);
88
89 max2820_write_phy_antenna(dev, chan);
90 write_max2820(dev, 3, chan);
91}
92
93static void max2820_rf_stop(struct ieee80211_hw *dev)
94{
95 rtl8180_write_phy(dev, 3, 0x8);
96 write_max2820(dev, 1, 0);
97}
98
99
100static void max2820_rf_init(struct ieee80211_hw *dev)
101{
102 struct rtl8180_priv *priv = dev->priv;
103
104 /* MAXIM from netbsd driver */
105 write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */
106 write_max2820(dev, 1, 0x01e); /* enable register */
107 write_max2820(dev, 2, 0x001); /* synt register */
108
109 max2820_rf_set_channel(dev, NULL);
110
111 write_max2820(dev, 4, 0x313); /* rx register */
112
113 /* PA is driven directly by the BB, we keep the MAXIM bias
114 * at the highest value in case that setting it to lower
115 * values may introduce some further attenuation somewhere..
116 */
117 write_max2820(dev, 5, 0x00f);
118
119 /* baseband configuration */
120 rtl8180_write_phy(dev, 0, 0x88); /* sys1 */
121 rtl8180_write_phy(dev, 3, 0x08); /* txagc */
122 rtl8180_write_phy(dev, 4, 0xf8); /* lnadet */
123 rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit */
124 rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */
125 rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet */
126
127 max2820_write_phy_antenna(dev, 1);
128
129 rtl8180_write_phy(dev, 0x11, 0x88); /* trl */
130
131 if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
132 RTL818X_CONFIG2_ANTENNA_DIV)
133 rtl8180_write_phy(dev, 0x12, 0xc7);
134 else
135 rtl8180_write_phy(dev, 0x12, 0x47);
136
137 rtl8180_write_phy(dev, 0x13, 0x9b);
138
139 rtl8180_write_phy(dev, 0x19, 0x0); /* CHESTLIM */
140 rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM */
141
142 max2820_rf_set_channel(dev, NULL);
143}
144
145const struct rtl818x_rf_ops max2820_rf_ops = {
146 .name = "Maxim",
147 .init = max2820_rf_init,
148 .stop = max2820_rf_stop,
149 .set_chan = max2820_rf_set_channel
150};
diff --git a/drivers/net/wireless/rtl8180_max2820.h b/drivers/net/wireless/rtl8180_max2820.h
new file mode 100644
index 000000000000..61cf6d1e7d57
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_max2820.h
@@ -0,0 +1,28 @@
1#ifndef RTL8180_MAX2820_H
2#define RTL8180_MAX2820_H
3
4/*
5 * Radio tuning for Maxim max2820 on RTL8180
6 *
7 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
8 *
9 * Code from the BSD driver and the rtl8181 project have been
10 * very useful to understand certain things
11 *
12 * I want to thanks the Authors of such projects and the Ndiswrapper
13 * project Authors.
14 *
15 * A special Big Thanks also is for all people who donated me cards,
16 * making possible the creation of the original rtl8180 driver
17 * from which this code is derived!
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 2 as
21 * published by the Free Software Foundation.
22 */
23
24#define MAXIM_ANTENNA 0xb3
25
26extern const struct rtl818x_rf_ops max2820_rf_ops;
27
28#endif /* RTL8180_MAX2820_H */
diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c
new file mode 100644
index 000000000000..ef3832bee85c
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_rtl8225.c
@@ -0,0 +1,779 @@
1
2/*
3 * Radio tuning for RTL8225 on RTL8180
4 *
5 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
6 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
7 *
8 * Based on the r8180 driver, which is:
9 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
10 *
11 * Thanks to Realtek for their support!
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/pci.h>
20#include <linux/delay.h>
21#include <net/mac80211.h>
22
23#include "rtl8180.h"
24#include "rtl8180_rtl8225.h"
25
26static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
27{
28 struct rtl8180_priv *priv = dev->priv;
29 u16 reg80, reg84, reg82;
30 u32 bangdata;
31 int i;
32
33 bangdata = (data << 4) | (addr & 0xf);
34
35 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
36 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
37
38 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
39
40 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
41 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400);
42 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
43 udelay(10);
44
45 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
46 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
47 udelay(2);
48 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
49 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
50 udelay(10);
51
52 for (i = 15; i >= 0; i--) {
53 u16 reg = reg80 | !!(bangdata & (1 << i));
54
55 if (i & 1)
56 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
57
58 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
59 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
60
61 if (!(i & 1))
62 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
63 }
64
65 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
66 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
67 udelay(10);
68
69 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
70 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400);
71 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
72}
73
74static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
75{
76 struct rtl8180_priv *priv = dev->priv;
77 u16 reg80, reg82, reg84, out;
78 int i;
79
80 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
81 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
82 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400;
83
84 reg80 &= ~0xF;
85
86 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
87 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
88
89 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
90 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
91 udelay(4);
92 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
93 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
94 udelay(5);
95
96 for (i = 4; i >= 0; i--) {
97 u16 reg = reg80 | ((addr >> i) & 1);
98
99 if (!(i & 1)) {
100 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
101 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
102 udelay(1);
103 }
104
105 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
106 reg | (1 << 1));
107 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
108 udelay(2);
109 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
110 reg | (1 << 1));
111 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
112 udelay(2);
113
114 if (i & 1) {
115 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
116 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
117 udelay(1);
118 }
119 }
120
121 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E);
122 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E);
123 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
124 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
125 reg80 | (1 << 3) | (1 << 1));
126 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
127 udelay(2);
128 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
129 reg80 | (1 << 3));
130 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
131 udelay(2);
132 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
133 reg80 | (1 << 3));
134 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
135 udelay(2);
136
137 out = 0;
138 for (i = 11; i >= 0; i--) {
139 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
140 reg80 | (1 << 3));
141 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
142 udelay(1);
143 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
144 reg80 | (1 << 3) | (1 << 1));
145 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
146 udelay(2);
147 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
148 reg80 | (1 << 3) | (1 << 1));
149 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
150 udelay(2);
151 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
152 reg80 | (1 << 3) | (1 << 1));
153 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
154 udelay(2);
155
156 if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
157 out |= 1 << i;
158
159 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
160 reg80 | (1 << 3));
161 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
162 udelay(2);
163 }
164
165 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
166 reg80 | (1 << 3) | (1 << 2));
167 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
168 udelay(2);
169
170 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
171 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
172 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
173
174 return out;
175}
176
177static const u16 rtl8225bcd_rxgain[] = {
178 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
179 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
180 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
181 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
182 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
183 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
184 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
185 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
186 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
187 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
188 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
189 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
190};
191
192static const u8 rtl8225_agc[] = {
193 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
194 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
195 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
196 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
197 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
198 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
199 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
200 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
201 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
202 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
203 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
204 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
205 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
206 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
207 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
208 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
209};
210
211static const u8 rtl8225_gain[] = {
212 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
213 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
214 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
215 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
216 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
217 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
218 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
219};
220
221static const u8 rtl8225_threshold[] = {
222 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
223};
224
225static const u8 rtl8225_tx_gain_cck_ofdm[] = {
226 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
227};
228
229static const u8 rtl8225_tx_power_cck[] = {
230 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
231 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
232 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
233 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
234 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
235 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
236};
237
238static const u8 rtl8225_tx_power_cck_ch14[] = {
239 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
240 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
241 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
242 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
243 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
244 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
245};
246
247static const u8 rtl8225_tx_power_ofdm[] = {
248 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
249};
250
251static const u32 rtl8225_chan[] = {
252 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
253 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
254};
255
256static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
257{
258 struct rtl8180_priv *priv = dev->priv;
259 u8 cck_power, ofdm_power;
260 const u8 *tmp;
261 u32 reg;
262 int i;
263
264 cck_power = priv->channels[channel - 1].val & 0xFF;
265 ofdm_power = priv->channels[channel - 1].val >> 8;
266
267 cck_power = min(cck_power, (u8)35);
268 ofdm_power = min(ofdm_power, (u8)35);
269
270 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
271 rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
272
273 if (channel == 14)
274 tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
275 else
276 tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
277
278 for (i = 0; i < 8; i++)
279 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
280
281 msleep(1); /* FIXME: optional? */
282
283 /* anaparam2 on */
284 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
285 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
286 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
287 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
288 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
289 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
290
291 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
292 rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1);
293
294 tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
295
296 rtl8225_write_phy_ofdm(dev, 5, *tmp);
297 rtl8225_write_phy_ofdm(dev, 7, *tmp);
298
299 msleep(1);
300}
301
302static void rtl8225_rf_init(struct ieee80211_hw *dev)
303{
304 struct rtl8180_priv *priv = dev->priv;
305 int i;
306
307 rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
308
309 /* host_pci_init */
310 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
311 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
312 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
313 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
314 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
315 msleep(200); /* FIXME: ehh?? */
316 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
317
318 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
319
320 /* TODO: check if we need really to change BRSR to do RF config */
321 rtl818x_ioread16(priv, &priv->map->BRSR);
322 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
323 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
324 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
325 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
326 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
327
328 rtl8225_write(dev, 0x0, 0x067);
329 rtl8225_write(dev, 0x1, 0xFE0);
330 rtl8225_write(dev, 0x2, 0x44D);
331 rtl8225_write(dev, 0x3, 0x441);
332 rtl8225_write(dev, 0x4, 0x8BE);
333 rtl8225_write(dev, 0x5, 0xBF0); /* TODO: minipci */
334 rtl8225_write(dev, 0x6, 0xAE6);
335 rtl8225_write(dev, 0x7, rtl8225_chan[0]);
336 rtl8225_write(dev, 0x8, 0x01F);
337 rtl8225_write(dev, 0x9, 0x334);
338 rtl8225_write(dev, 0xA, 0xFD4);
339 rtl8225_write(dev, 0xB, 0x391);
340 rtl8225_write(dev, 0xC, 0x050);
341 rtl8225_write(dev, 0xD, 0x6DB);
342 rtl8225_write(dev, 0xE, 0x029);
343 rtl8225_write(dev, 0xF, 0x914); msleep(1);
344
345 rtl8225_write(dev, 0x2, 0xC4D); msleep(100);
346
347 rtl8225_write(dev, 0x0, 0x127);
348
349 for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
350 rtl8225_write(dev, 0x1, i + 1);
351 rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
352 }
353
354 rtl8225_write(dev, 0x0, 0x027);
355 rtl8225_write(dev, 0x0, 0x22F);
356 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
357
358 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
359 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
360 msleep(1);
361 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
362 msleep(1);
363 }
364
365 msleep(1);
366
367 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
368 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
369 rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
370 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
371 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
372 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
373 rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1);
374 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
375 rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1);
376 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
377 rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
378 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
379 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
380 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
381 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
382 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
383 rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1);
384 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
385 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
386 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
387 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
388 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
389 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
390 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
391 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
392 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
393 rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
394 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
395 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
396 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
397 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
398 rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
399 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
400 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
401 rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
402 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
403 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
404
405 rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
406 rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
407 rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
408 rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
409 rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
410 rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
411 rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
412 rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
413 rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
414 rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
415 rtl8225_write_phy_cck(dev, 0x13, 0xd0);
416 rtl8225_write_phy_cck(dev, 0x19, 0x00);
417 rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
418 rtl8225_write_phy_cck(dev, 0x1b, 0x08);
419 rtl8225_write_phy_cck(dev, 0x40, 0x86);
420 rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
421 rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
422 rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
423 rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
424 rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
425 rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
426 rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
427 rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
428 rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
429 rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
430 rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
431 rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
432
433 rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1);
434
435 rtl8225_rf_set_tx_power(dev, 1);
436
437 /* RX antenna default to A */
438 rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */
439 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */
440
441 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
442 msleep(1);
443 rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
444 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
445
446 rtl8225_write(dev, 0x0c, 0x50);
447 /* set OFDM initial gain */
448 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]);
449 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]);
450 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]);
451 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]);
452 /* set CCK threshold */
453 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]);
454}
455
456static const u8 rtl8225z2_tx_power_cck_ch14[] = {
457 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
458};
459
460static const u8 rtl8225z2_tx_power_cck_B[] = {
461 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04
462};
463
464static const u8 rtl8225z2_tx_power_cck_A[] = {
465 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04
466};
467
468static const u8 rtl8225z2_tx_power_cck[] = {
469 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
470};
471
472static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
473{
474 struct rtl8180_priv *priv = dev->priv;
475 u8 cck_power, ofdm_power;
476 const u8 *tmp;
477 int i;
478
479 cck_power = priv->channels[channel - 1].val & 0xFF;
480 ofdm_power = priv->channels[channel - 1].val >> 8;
481
482 if (channel == 14)
483 tmp = rtl8225z2_tx_power_cck_ch14;
484 else if (cck_power == 12)
485 tmp = rtl8225z2_tx_power_cck_B;
486 else if (cck_power == 13)
487 tmp = rtl8225z2_tx_power_cck_A;
488 else
489 tmp = rtl8225z2_tx_power_cck;
490
491 for (i = 0; i < 8; i++)
492 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
493
494 cck_power = min(cck_power, (u8)35);
495 if (cck_power == 13 || cck_power == 14)
496 cck_power = 12;
497 if (cck_power >= 15)
498 cck_power -= 2;
499
500 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power);
501 rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK);
502 msleep(1);
503
504 ofdm_power = min(ofdm_power, (u8)35);
505 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power);
506
507 rtl8225_write_phy_ofdm(dev, 2, 0x62);
508 rtl8225_write_phy_ofdm(dev, 5, 0x00);
509 rtl8225_write_phy_ofdm(dev, 6, 0x40);
510 rtl8225_write_phy_ofdm(dev, 7, 0x00);
511 rtl8225_write_phy_ofdm(dev, 8, 0x40);
512
513 msleep(1);
514}
515
516static const u16 rtl8225z2_rxgain[] = {
517 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
518 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
519 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
520 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
521 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
522 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
523 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
524 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
525 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
526 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
527 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
528 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
529};
530
531static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
532{
533 struct rtl8180_priv *priv = dev->priv;
534 int i;
535
536 rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
537
538 /* host_pci_init */
539 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
540 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
541 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
542 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
543 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
544 msleep(200); /* FIXME: ehh?? */
545 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
546
547 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008);
548
549 /* TODO: check if we need really to change BRSR to do RF config */
550 rtl818x_ioread16(priv, &priv->map->BRSR);
551 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
552 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
553 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
554 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
555 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
556
557 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
558
559 rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
560 rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
561 rtl8225_write(dev, 0x2, 0x44D); msleep(1);
562 rtl8225_write(dev, 0x3, 0x441); msleep(1);
563 rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
564 rtl8225_write(dev, 0x5, 0xC72); msleep(1);
565 rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
566 rtl8225_write(dev, 0x7, 0x82A); msleep(1);
567 rtl8225_write(dev, 0x8, 0x03F); msleep(1);
568 rtl8225_write(dev, 0x9, 0x335); msleep(1);
569 rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
570 rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
571 rtl8225_write(dev, 0xc, 0x850); msleep(1);
572 rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
573 rtl8225_write(dev, 0xe, 0x02B); msleep(1);
574 rtl8225_write(dev, 0xf, 0x114); msleep(100);
575
576 if (!(rtl8225_read(dev, 6) & (1 << 7))) {
577 rtl8225_write(dev, 0x02, 0x0C4D);
578 msleep(200);
579 rtl8225_write(dev, 0x02, 0x044D);
580 msleep(100);
581 /* TODO: readd calibration failure message when the calibration
582 check works */
583 }
584
585 rtl8225_write(dev, 0x0, 0x1B7);
586 rtl8225_write(dev, 0x3, 0x002);
587 rtl8225_write(dev, 0x5, 0x004);
588
589 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
590 rtl8225_write(dev, 0x1, i + 1);
591 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
592 }
593
594 rtl8225_write(dev, 0x0, 0x0B7); msleep(100);
595 rtl8225_write(dev, 0x2, 0xC4D);
596
597 msleep(200);
598 rtl8225_write(dev, 0x2, 0x44D);
599 msleep(100);
600
601 rtl8225_write(dev, 0x00, 0x2BF);
602 rtl8225_write(dev, 0xFF, 0xFFFF);
603
604 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
605
606 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
607 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
608 msleep(1);
609 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
610 msleep(1);
611 }
612
613 msleep(1);
614
615 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
616 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
617 rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
618 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
619 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
620 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
621 rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
622 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
623 rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
624 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
625 rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
626 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
627 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
628 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
629 rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
630 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
631 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
632 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
633 rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
634 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
635 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
636 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
637 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
638 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
639 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
640 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
641 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
642 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
643 rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1);
644 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
645 rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
646 rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1);
647 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
648 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
649 rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
650 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
651 rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */
652 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
653 rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
654 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
655 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
656
657 rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
658 rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
659 rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
660 rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
661 rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
662 rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
663 rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
664 rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
665 rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
666 rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
667 rtl8225_write_phy_cck(dev, 0x13, 0xd0);
668 rtl8225_write_phy_cck(dev, 0x19, 0x00);
669 rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
670 rtl8225_write_phy_cck(dev, 0x1b, 0x08);
671 rtl8225_write_phy_cck(dev, 0x40, 0x86);
672 rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1);
673 rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
674 rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
675 rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
676 rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
677 rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
678 rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
679 rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
680 rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
681 rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
682 rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
683 rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
684
685 rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1);
686
687 rtl8225z2_rf_set_tx_power(dev, 1);
688
689 /* RX antenna default to A */
690 rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */
691 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */
692
693 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
694 msleep(1);
695 rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
696 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
697}
698
699static void rtl8225_rf_stop(struct ieee80211_hw *dev)
700{
701 struct rtl8180_priv *priv = dev->priv;
702 u8 reg;
703
704 rtl8225_write(dev, 0x4, 0x1f); msleep(1);
705
706 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
707 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
708 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
709 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
710 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
711 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
712 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
713}
714
715static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
716 struct ieee80211_conf *conf)
717{
718 struct rtl8180_priv *priv = dev->priv;
719
720 if (priv->rf->init == rtl8225_rf_init)
721 rtl8225_rf_set_tx_power(dev, conf->channel);
722 else
723 rtl8225z2_rf_set_tx_power(dev, conf->channel);
724
725 rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]);
726 msleep(10);
727
728 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
729 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
730 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
731 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
732 rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
733 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
734 } else {
735 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
736 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44);
737 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
738 rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
739 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
740 }
741}
742
743static const struct rtl818x_rf_ops rtl8225_ops = {
744 .name = "rtl8225",
745 .init = rtl8225_rf_init,
746 .stop = rtl8225_rf_stop,
747 .set_chan = rtl8225_rf_set_channel
748};
749
750static const struct rtl818x_rf_ops rtl8225z2_ops = {
751 .name = "rtl8225z2",
752 .init = rtl8225z2_rf_init,
753 .stop = rtl8225_rf_stop,
754 .set_chan = rtl8225_rf_set_channel
755};
756
757const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
758{
759 struct rtl8180_priv *priv = dev->priv;
760 u16 reg8, reg9;
761
762 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
763 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
764 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
765 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
766 msleep(100);
767
768 rtl8225_write(dev, 0, 0x1B7);
769
770 reg8 = rtl8225_read(dev, 8);
771 reg9 = rtl8225_read(dev, 9);
772
773 rtl8225_write(dev, 0, 0x0B7);
774
775 if (reg8 != 0x588 || reg9 != 0x700)
776 return &rtl8225_ops;
777
778 return &rtl8225z2_ops;
779}
diff --git a/drivers/net/wireless/rtl8180_rtl8225.h b/drivers/net/wireless/rtl8180_rtl8225.h
new file mode 100644
index 000000000000..310013a2d726
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_rtl8225.h
@@ -0,0 +1,23 @@
1#ifndef RTL8180_RTL8225_H
2#define RTL8180_RTL8225_H
3
4#define RTL8225_ANAPARAM_ON 0xa0000b59
5#define RTL8225_ANAPARAM2_ON 0x860dec11
6#define RTL8225_ANAPARAM_OFF 0xa00beb59
7#define RTL8225_ANAPARAM2_OFF 0x840dec11
8
9const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *);
10
11static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
12 u8 addr, u8 data)
13{
14 rtl8180_write_phy(dev, addr, data);
15}
16
17static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev,
18 u8 addr, u8 data)
19{
20 rtl8180_write_phy(dev, addr, data | 0x10000);
21}
22
23#endif /* RTL8180_RTL8225_H */
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c
new file mode 100644
index 000000000000..e08ace7b1cb7
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_sa2400.c
@@ -0,0 +1,201 @@
1
2/*
3 * Radio tuning for Philips SA2400 on RTL8180
4 *
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Code from the BSD driver and the rtl8181 project have been
8 * very useful to understand certain things
9 *
10 * I want to thanks the Authors of such projects and the Ndiswrapper
11 * project Authors.
12 *
13 * A special Big Thanks also is for all people who donated me cards,
14 * making possible the creation of the original rtl8180 driver
15 * from which this code is derived!
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 */
21
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <net/mac80211.h>
26
27#include "rtl8180.h"
28#include "rtl8180_sa2400.h"
29
30static const u32 sa2400_chan[] = {
31 0x00096c, /* ch1 */
32 0x080970,
33 0x100974,
34 0x180978,
35 0x000980,
36 0x080984,
37 0x100988,
38 0x18098c,
39 0x000994,
40 0x080998,
41 0x10099c,
42 0x1809a0,
43 0x0009a8,
44 0x0009b4, /* ch 14 */
45};
46
47static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data)
48{
49 struct rtl8180_priv *priv = dev->priv;
50 u32 phy_config;
51
52 /* MAC will bang bits to the sa2400. sw 3-wire is NOT used */
53 phy_config = 0xb0000000;
54
55 phy_config |= ((u32)(addr & 0xf)) << 24;
56 phy_config |= data & 0xffffff;
57
58 rtl818x_iowrite32(priv,
59 (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
60
61 msleep(3);
62}
63
64static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
65{
66 struct rtl8180_priv *priv = dev->priv;
67 u8 ant = SA2400_ANTENNA;
68
69 if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
70 ant |= BB_ANTENNA_B;
71
72 if (chan == 14)
73 ant |= BB_ANTATTEN_CHAN14;
74
75 rtl8180_write_phy(dev, 0x10, ant);
76
77}
78
79static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
80 struct ieee80211_conf *conf)
81{
82 struct rtl8180_priv *priv = dev->priv;
83 u32 txpw = priv->channels[conf->channel - 1].val & 0xFF;
84 u32 chan = sa2400_chan[conf->channel - 1];
85
86 write_sa2400(dev, 7, txpw);
87
88 sa2400_write_phy_antenna(dev, chan);
89
90 write_sa2400(dev, 0, chan);
91 write_sa2400(dev, 1, 0xbb50);
92 write_sa2400(dev, 2, 0x80);
93 write_sa2400(dev, 3, 0);
94}
95
96static void sa2400_rf_stop(struct ieee80211_hw *dev)
97{
98 write_sa2400(dev, 4, 0);
99}
100
101static void sa2400_rf_init(struct ieee80211_hw *dev)
102{
103 struct rtl8180_priv *priv = dev->priv;
104 u32 anaparam, txconf;
105 u8 firdac;
106 int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY;
107
108 anaparam = priv->anaparam;
109 anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT);
110 anaparam &= ~ANAPARAM_PWR1_MASK;
111 anaparam &= ~ANAPARAM_PWR0_MASK;
112
113 if (analogphy) {
114 anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT;
115 firdac = 0;
116 } else {
117 anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT);
118 anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT);
119 firdac = 1 << SA2400_REG4_FIRDAC_SHIFT;
120 }
121
122 rtl8180_set_anaparam(priv, anaparam);
123
124 write_sa2400(dev, 0, sa2400_chan[0]);
125 write_sa2400(dev, 1, 0xbb50);
126 write_sa2400(dev, 2, 0x80);
127 write_sa2400(dev, 3, 0);
128 write_sa2400(dev, 4, 0x19340 | firdac);
129 write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15);
130 write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */
131
132 if (!analogphy)
133 write_sa2400(dev, 4, 0x1938c); /*???*/
134
135 write_sa2400(dev, 4, 0x19340 | firdac);
136
137 write_sa2400(dev, 0, sa2400_chan[0]);
138 write_sa2400(dev, 1, 0xbb50);
139 write_sa2400(dev, 2, 0x80);
140 write_sa2400(dev, 3, 0);
141 write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */
142
143 /* new from rtl8180 embedded driver (rtl8181 project) */
144 write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */
145 write_sa2400(dev, 8, 0); /* VCO */
146
147 if (analogphy) {
148 rtl8180_set_anaparam(priv, anaparam |
149 (1 << ANAPARAM_TXDACOFF_SHIFT));
150
151 txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF);
152 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
153 txconf | RTL818X_TX_CONF_LOOPBACK_CONT);
154
155 write_sa2400(dev, 4, 0x19341); /* calibrates DC */
156
157 /* a 5us sleep is required here,
158 * we rely on the 3ms delay introduced in write_sa2400 */
159 write_sa2400(dev, 4, 0x19345);
160
161 /* a 20us sleep is required here,
162 * we rely on the 3ms delay introduced in write_sa2400 */
163
164 rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf);
165
166 rtl8180_set_anaparam(priv, anaparam);
167 }
168 /* end new code */
169
170 write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */
171
172 /* baseband configuration */
173 rtl8180_write_phy(dev, 0, 0x98);
174 rtl8180_write_phy(dev, 3, 0x38);
175 rtl8180_write_phy(dev, 4, 0xe0);
176 rtl8180_write_phy(dev, 5, 0x90);
177 rtl8180_write_phy(dev, 6, 0x1a);
178 rtl8180_write_phy(dev, 7, 0x64);
179
180 sa2400_write_phy_antenna(dev, 1);
181
182 rtl8180_write_phy(dev, 0x11, 0x80);
183
184 if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
185 RTL818X_CONFIG2_ANTENNA_DIV)
186 rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */
187 else
188 rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */
189
190 rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
191
192 rtl8180_write_phy(dev, 0x19, 0x0);
193 rtl8180_write_phy(dev, 0x1a, 0xa0);
194}
195
196const struct rtl818x_rf_ops sa2400_rf_ops = {
197 .name = "Philips",
198 .init = sa2400_rf_init,
199 .stop = sa2400_rf_stop,
200 .set_chan = sa2400_rf_set_channel
201};
diff --git a/drivers/net/wireless/rtl8180_sa2400.h b/drivers/net/wireless/rtl8180_sa2400.h
new file mode 100644
index 000000000000..a4aaa0d413f1
--- /dev/null
+++ b/drivers/net/wireless/rtl8180_sa2400.h
@@ -0,0 +1,36 @@
1#ifndef RTL8180_SA2400_H
2#define RTL8180_SA2400_H
3
4/*
5 * Radio tuning for Philips SA2400 on RTL8180
6 *
7 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
8 *
9 * Code from the BSD driver and the rtl8181 project have been
10 * very useful to understand certain things
11 *
12 * I want to thanks the Authors of such projects and the Ndiswrapper
13 * project Authors.
14 *
15 * A special Big Thanks also is for all people who donated me cards,
16 * making possible the creation of the original rtl8180 driver
17 * from which this code is derived!
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 2 as
21 * published by the Free Software Foundation.
22 */
23
24#define SA2400_ANTENNA 0x91
25#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8
26#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28
27#define SA2400_ANAPARAM_PWR0_ON 0x3
28
29/* RX sensitivity in dbm */
30#define SA2400_MAX_SENS 85
31
32#define SA2400_REG4_FIRDAC_SHIFT 7
33
34extern const struct rtl818x_rf_ops sa2400_rf_ops;
35
36#endif /* RTL8180_SA2400_H */
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
index 6ad322ef0da1..26a4f1097b4a 100644
--- a/drivers/net/wireless/rtl8187.h
+++ b/drivers/net/wireless/rtl8187.h
@@ -64,7 +64,7 @@ struct rtl8187_tx_hdr {
64struct rtl8187_priv { 64struct rtl8187_priv {
65 /* common between rtl818x drivers */ 65 /* common between rtl818x drivers */
66 struct rtl818x_csr *map; 66 struct rtl818x_csr *map;
67 void (*rf_init)(struct ieee80211_hw *); 67 const struct rtl818x_rf_ops *rf;
68 int mode; 68 int mode;
69 int if_id; 69 int if_id;
70 70
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 09e48d3bef36..8dab25a65990 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -393,37 +393,19 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
393 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7); 393 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
394 msleep(100); 394 msleep(100);
395 395
396 priv->rf_init(dev); 396 priv->rf->init(dev);
397 397
398 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); 398 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
399 reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & 0xfffe; 399 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
400 rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 0x1); 400 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
401 rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10); 401 rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10);
402 rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80); 402 rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80);
403 rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60); 403 rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60);
404 rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg); 404 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
405 405
406 return 0; 406 return 0;
407} 407}
408 408
409static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel)
410{
411 u32 reg;
412 struct rtl8187_priv *priv = dev->priv;
413
414 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
415 /* Enable TX loopback on MAC level to avoid TX during channel
416 * changes, as this has be seen to causes problems and the
417 * card will stop work until next reset
418 */
419 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
420 reg | RTL818X_TX_CONF_LOOPBACK_MAC);
421 msleep(10);
422 rtl8225_rf_set_channel(dev, channel);
423 msleep(10);
424 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
425}
426
427static int rtl8187_start(struct ieee80211_hw *dev) 409static int rtl8187_start(struct ieee80211_hw *dev)
428{ 410{
429 struct rtl8187_priv *priv = dev->priv; 411 struct rtl8187_priv *priv = dev->priv;
@@ -492,7 +474,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
492 reg &= ~RTL818X_CMD_RX_ENABLE; 474 reg &= ~RTL818X_CMD_RX_ENABLE;
493 rtl818x_iowrite8(priv, &priv->map->CMD, reg); 475 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
494 476
495 rtl8225_rf_stop(dev); 477 priv->rf->stop(dev);
496 478
497 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 479 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
498 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); 480 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
@@ -543,7 +525,19 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
543static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 525static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
544{ 526{
545 struct rtl8187_priv *priv = dev->priv; 527 struct rtl8187_priv *priv = dev->priv;
546 rtl8187_set_channel(dev, conf->channel); 528 u32 reg;
529
530 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
531 /* Enable TX loopback on MAC level to avoid TX during channel
532 * changes, as this has be seen to causes problems and the
533 * card will stop work until next reset
534 */
535 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
536 reg | RTL818X_TX_CONF_LOOPBACK_MAC);
537 msleep(10);
538 priv->rf->set_chan(dev, conf);
539 msleep(10);
540 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
547 541
548 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); 542 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
549 543
@@ -753,23 +747,16 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
753 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, 747 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
754 &priv->txpwr_base); 748 &priv->txpwr_base);
755 749
756 reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & ~1; 750 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
757 rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 1); 751 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
758 /* 0 means asic B-cut, we should use SW 3 wire 752 /* 0 means asic B-cut, we should use SW 3 wire
759 * bit-by-bit banging for radio. 1 means we can use 753 * bit-by-bit banging for radio. 1 means we can use
760 * USB specific request to write radio registers */ 754 * USB specific request to write radio registers */
761 priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3; 755 priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3;
762 rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg); 756 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
763 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 757 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
764 758
765 rtl8225_write(dev, 0, 0x1B7); 759 priv->rf = rtl8187_detect_rf(dev);
766
767 if (rtl8225_read(dev, 8) != 0x588 || rtl8225_read(dev, 9) != 0x700)
768 priv->rf_init = rtl8225_rf_init;
769 else
770 priv->rf_init = rtl8225z2_rf_init;
771
772 rtl8225_write(dev, 0, 0x0B7);
773 760
774 err = ieee80211_register_hw(dev); 761 err = ieee80211_register_hw(dev);
775 if (err) { 762 if (err) {
@@ -779,8 +766,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
779 766
780 printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n", 767 printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
781 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), 768 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
782 priv->asic_rev, priv->rf_init == rtl8225_rf_init ? 769 priv->asic_rev, priv->rf->name);
783 "rtl8225" : "rtl8225z2");
784 770
785 return 0; 771 return 0;
786 772
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index efc41207780e..b713de17ba0a 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -101,7 +101,7 @@ static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
101 msleep(2); 101 msleep(2);
102} 102}
103 103
104void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) 104static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
105{ 105{
106 struct rtl8187_priv *priv = dev->priv; 106 struct rtl8187_priv *priv = dev->priv;
107 107
@@ -111,7 +111,7 @@ void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
111 rtl8225_write_bitbang(dev, addr, data); 111 rtl8225_write_bitbang(dev, addr, data);
112} 112}
113 113
114u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) 114static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
115{ 115{
116 struct rtl8187_priv *priv = dev->priv; 116 struct rtl8187_priv *priv = dev->priv;
117 u16 reg80, reg82, reg84, out; 117 u16 reg80, reg82, reg84, out;
@@ -325,7 +325,7 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
325 msleep(1); 325 msleep(1);
326} 326}
327 327
328void rtl8225_rf_init(struct ieee80211_hw *dev) 328static void rtl8225_rf_init(struct ieee80211_hw *dev)
329{ 329{
330 struct rtl8187_priv *priv = dev->priv; 330 struct rtl8187_priv *priv = dev->priv;
331 int i; 331 int i;
@@ -567,7 +567,7 @@ static const u8 rtl8225z2_gain_bg[] = {
567 0x63, 0x15, 0xc5 /* -66dBm */ 567 0x63, 0x15, 0xc5 /* -66dBm */
568}; 568};
569 569
570void rtl8225z2_rf_init(struct ieee80211_hw *dev) 570static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
571{ 571{
572 struct rtl8187_priv *priv = dev->priv; 572 struct rtl8187_priv *priv = dev->priv;
573 int i; 573 int i;
@@ -715,7 +715,7 @@ void rtl8225z2_rf_init(struct ieee80211_hw *dev)
715 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); 715 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
716} 716}
717 717
718void rtl8225_rf_stop(struct ieee80211_hw *dev) 718static void rtl8225_rf_stop(struct ieee80211_hw *dev)
719{ 719{
720 u8 reg; 720 u8 reg;
721 struct rtl8187_priv *priv = dev->priv; 721 struct rtl8187_priv *priv = dev->priv;
@@ -731,15 +731,47 @@ void rtl8225_rf_stop(struct ieee80211_hw *dev)
731 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 731 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
732} 732}
733 733
734void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel) 734static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
735 struct ieee80211_conf *conf)
735{ 736{
736 struct rtl8187_priv *priv = dev->priv; 737 struct rtl8187_priv *priv = dev->priv;
737 738
738 if (priv->rf_init == rtl8225_rf_init) 739 if (priv->rf->init == rtl8225_rf_init)
739 rtl8225_rf_set_tx_power(dev, channel); 740 rtl8225_rf_set_tx_power(dev, conf->channel);
740 else 741 else
741 rtl8225z2_rf_set_tx_power(dev, channel); 742 rtl8225z2_rf_set_tx_power(dev, conf->channel);
742 743
743 rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]); 744 rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]);
744 msleep(10); 745 msleep(10);
745} 746}
747
748static const struct rtl818x_rf_ops rtl8225_ops = {
749 .name = "rtl8225",
750 .init = rtl8225_rf_init,
751 .stop = rtl8225_rf_stop,
752 .set_chan = rtl8225_rf_set_channel
753};
754
755static const struct rtl818x_rf_ops rtl8225z2_ops = {
756 .name = "rtl8225z2",
757 .init = rtl8225z2_rf_init,
758 .stop = rtl8225_rf_stop,
759 .set_chan = rtl8225_rf_set_channel
760};
761
762const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
763{
764 u16 reg8, reg9;
765
766 rtl8225_write(dev, 0, 0x1B7);
767
768 reg8 = rtl8225_read(dev, 8);
769 reg9 = rtl8225_read(dev, 9);
770
771 rtl8225_write(dev, 0, 0x0B7);
772
773 if (reg8 != 0x588 || reg9 != 0x700)
774 return &rtl8225_ops;
775
776 return &rtl8225z2_ops;
777}
diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl8187_rtl8225.h
index 798ba4a97376..d39ed0295b6e 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.h
+++ b/drivers/net/wireless/rtl8187_rtl8225.h
@@ -20,14 +20,7 @@
20#define RTL8225_ANAPARAM_OFF 0xa00beb59 20#define RTL8225_ANAPARAM_OFF 0xa00beb59
21#define RTL8225_ANAPARAM2_OFF 0x840dec11 21#define RTL8225_ANAPARAM2_OFF 0x840dec11
22 22
23void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data); 23const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *);
24u16 rtl8225_read(struct ieee80211_hw *, u8 addr);
25
26void rtl8225_rf_init(struct ieee80211_hw *);
27void rtl8225z2_rf_init(struct ieee80211_hw *);
28void rtl8225_rf_stop(struct ieee80211_hw *);
29void rtl8225_rf_set_channel(struct ieee80211_hw *, int);
30
31 24
32static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, 25static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
33 u8 addr, u32 data) 26 u8 addr, u32 data)
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h
index 880d4becae31..1e7d6f8278d7 100644
--- a/drivers/net/wireless/rtl818x.h
+++ b/drivers/net/wireless/rtl818x.h
@@ -58,13 +58,17 @@ struct rtl818x_csr {
58#define RTL818X_INT_TX_FO (1 << 15) 58#define RTL818X_INT_TX_FO (1 << 15)
59 __le32 TX_CONF; 59 __le32 TX_CONF;
60#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17) 60#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17)
61#define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17)
61#define RTL818X_TX_CONF_NO_ICV (1 << 19) 62#define RTL818X_TX_CONF_NO_ICV (1 << 19)
62#define RTL818X_TX_CONF_DISCW (1 << 20) 63#define RTL818X_TX_CONF_DISCW (1 << 20)
64#define RTL818X_TX_CONF_SAT_HWPLCP (1 << 24)
63#define RTL818X_TX_CONF_R8180_ABCD (2 << 25) 65#define RTL818X_TX_CONF_R8180_ABCD (2 << 25)
64#define RTL818X_TX_CONF_R8180_F (3 << 25) 66#define RTL818X_TX_CONF_R8180_F (3 << 25)
65#define RTL818X_TX_CONF_R8185_ABC (4 << 25) 67#define RTL818X_TX_CONF_R8185_ABC (4 << 25)
66#define RTL818X_TX_CONF_R8185_D (5 << 25) 68#define RTL818X_TX_CONF_R8185_D (5 << 25)
67#define RTL818X_TX_CONF_HWVER_MASK (7 << 25) 69#define RTL818X_TX_CONF_HWVER_MASK (7 << 25)
70#define RTL818X_TX_CONF_PROBE_DTS (1 << 29)
71#define RTL818X_TX_CONF_HW_SEQNUM (1 << 30)
68#define RTL818X_TX_CONF_CW_MIN (1 << 31) 72#define RTL818X_TX_CONF_CW_MIN (1 << 31)
69 __le32 RX_CONF; 73 __le32 RX_CONF;
70#define RTL818X_RX_CONF_MONITOR (1 << 0) 74#define RTL818X_RX_CONF_MONITOR (1 << 0)
@@ -75,8 +79,12 @@ struct rtl818x_csr {
75#define RTL818X_RX_CONF_DATA (1 << 18) 79#define RTL818X_RX_CONF_DATA (1 << 18)
76#define RTL818X_RX_CONF_CTRL (1 << 19) 80#define RTL818X_RX_CONF_CTRL (1 << 19)
77#define RTL818X_RX_CONF_MGMT (1 << 20) 81#define RTL818X_RX_CONF_MGMT (1 << 20)
82#define RTL818X_RX_CONF_ADDR3 (1 << 21)
83#define RTL818X_RX_CONF_PM (1 << 22)
78#define RTL818X_RX_CONF_BSSID (1 << 23) 84#define RTL818X_RX_CONF_BSSID (1 << 23)
79#define RTL818X_RX_CONF_RX_AUTORESETPHY (1 << 28) 85#define RTL818X_RX_CONF_RX_AUTORESETPHY (1 << 28)
86#define RTL818X_RX_CONF_CSDM1 (1 << 29)
87#define RTL818X_RX_CONF_CSDM2 (1 << 30)
80#define RTL818X_RX_CONF_ONLYERLPKT (1 << 31) 88#define RTL818X_RX_CONF_ONLYERLPKT (1 << 31)
81 __le32 INT_TIMEOUT; 89 __le32 INT_TIMEOUT;
82 __le32 TBDA; 90 __le32 TBDA;
@@ -92,6 +100,7 @@ struct rtl818x_csr {
92 u8 CONFIG0; 100 u8 CONFIG0;
93 u8 CONFIG1; 101 u8 CONFIG1;
94 u8 CONFIG2; 102 u8 CONFIG2;
103#define RTL818X_CONFIG2_ANTENNA_DIV (1 << 6)
95 __le32 ANAPARAM; 104 __le32 ANAPARAM;
96 u8 MSR; 105 u8 MSR;
97#define RTL818X_MSR_NO_LINK (0 << 2) 106#define RTL818X_MSR_NO_LINK (0 << 2)
@@ -104,14 +113,17 @@ struct rtl818x_csr {
104#define RTL818X_CONFIG4_VCOOFF (1 << 7) 113#define RTL818X_CONFIG4_VCOOFF (1 << 7)
105 u8 TESTR; 114 u8 TESTR;
106 u8 reserved_9[2]; 115 u8 reserved_9[2];
107 __le16 PGSELECT; 116 u8 PGSELECT;
117 u8 SECURITY;
108 __le32 ANAPARAM2; 118 __le32 ANAPARAM2;
109 u8 reserved_10[12]; 119 u8 reserved_10[12];
110 __le16 BEACON_INTERVAL; 120 __le16 BEACON_INTERVAL;
111 __le16 ATIM_WND; 121 __le16 ATIM_WND;
112 __le16 BEACON_INTERVAL_TIME; 122 __le16 BEACON_INTERVAL_TIME;
113 __le16 ATIMTR_INTERVAL; 123 __le16 ATIMTR_INTERVAL;
114 u8 reserved_11[4]; 124 u8 PHY_DELAY;
125 u8 CARRIER_SENSE_COUNTER;
126 u8 reserved_11[2];
115 u8 PHY[4]; 127 u8 PHY[4];
116 __le16 RFPinsOutput; 128 __le16 RFPinsOutput;
117 __le16 RFPinsEnable; 129 __le16 RFPinsEnable;
@@ -149,11 +161,20 @@ struct rtl818x_csr {
149 u8 RETRY_CTR; 161 u8 RETRY_CTR;
150 u8 reserved_18[5]; 162 u8 reserved_18[5];
151 __le32 RDSAR; 163 __le32 RDSAR;
152 u8 reserved_19[18]; 164 u8 reserved_19[12];
153 u16 TALLY_CNT; 165 __le16 FEMR;
166 u8 reserved_20[4];
167 __le16 TALLY_CNT;
154 u8 TALLY_SEL; 168 u8 TALLY_SEL;
155} __attribute__((packed)); 169} __attribute__((packed));
156 170
171struct rtl818x_rf_ops {
172 char *name;
173 void (*init)(struct ieee80211_hw *);
174 void (*stop)(struct ieee80211_hw *);
175 void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
176};
177
157static const struct ieee80211_rate rtl818x_rates[] = { 178static const struct ieee80211_rate rtl818x_rates[] = {
158 { .rate = 10, 179 { .rate = 10,
159 .val = 0, 180 .val = 0,