aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl818x
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2008-10-31 20:19:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-21 11:06:04 -0500
commit1c740ed2210a0d124674a477ea538468aba47810 (patch)
treee65f654e382456c85bb3d8b162176357efcf0226 /drivers/net/wireless/rtl818x
parent55b3961953494c340b3625486f484af8ded31dd7 (diff)
Move all rtl818x files to a common directory.
This change improves the maintainability of these drivers. No functionality is changed. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtl818x')
-rw-r--r--drivers/net/wireless/rtl818x/Makefile7
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180.h120
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c1081
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_grf5101.c180
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_grf5101.h28
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_max2820.c152
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_max2820.h28
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_rtl8225.c780
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_rtl8225.h23
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_sa2400.c202
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_sa2400.h36
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h220
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c1298
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.c977
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.h44
-rw-r--r--drivers/net/wireless/rtl818x/rtl818x.h231
16 files changed, 5407 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile
new file mode 100644
index 000000000000..c113b3e69046
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/Makefile
@@ -0,0 +1,7 @@
1rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
2rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
3
4obj-$(CONFIG_RTL8180) += rtl8180.o
5obj-$(CONFIG_RTL8187) += rtl8187.o
6
7
diff --git a/drivers/net/wireless/rtl818x/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180.h
new file mode 100644
index 000000000000..8721282a8185
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8180.h
@@ -0,0 +1,120 @@
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
27struct rtl8180_tx_desc {
28 __le32 flags;
29 __le16 rts_duration;
30 __le16 plcp_len;
31 __le32 tx_buf;
32 __le32 frame_len;
33 __le32 next_tx_desc;
34 u8 cw;
35 u8 retry_limit;
36 u8 agc;
37 u8 flags2;
38 u32 reserved[2];
39} __attribute__ ((packed));
40
41struct rtl8180_rx_desc {
42 __le32 flags;
43 __le32 flags2;
44 union {
45 __le32 rx_buf;
46 __le64 tsft;
47 };
48} __attribute__ ((packed));
49
50struct rtl8180_tx_ring {
51 struct rtl8180_tx_desc *desc;
52 dma_addr_t dma;
53 unsigned int idx;
54 unsigned int entries;
55 struct sk_buff_head queue;
56};
57
58struct rtl8180_priv {
59 /* common between rtl818x drivers */
60 struct rtl818x_csr __iomem *map;
61 const struct rtl818x_rf_ops *rf;
62 struct ieee80211_vif *vif;
63 int mode;
64
65 /* rtl8180 driver specific */
66 spinlock_t lock;
67 struct rtl8180_rx_desc *rx_ring;
68 dma_addr_t rx_ring_dma;
69 unsigned int rx_idx;
70 struct sk_buff *rx_buf[32];
71 struct rtl8180_tx_ring tx_ring[4];
72 struct ieee80211_channel channels[14];
73 struct ieee80211_rate rates[12];
74 struct ieee80211_supported_band band;
75 struct pci_dev *pdev;
76 u32 rx_conf;
77
78 int r8185;
79 u32 anaparam;
80 u16 rfparam;
81 u8 csthreshold;
82};
83
84void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
85void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam);
86
87static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr)
88{
89 return ioread8(addr);
90}
91
92static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, __le16 __iomem *addr)
93{
94 return ioread16(addr);
95}
96
97static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, __le32 __iomem *addr)
98{
99 return ioread32(addr);
100}
101
102static inline void rtl818x_iowrite8(struct rtl8180_priv *priv,
103 u8 __iomem *addr, u8 val)
104{
105 iowrite8(val, addr);
106}
107
108static inline void rtl818x_iowrite16(struct rtl8180_priv *priv,
109 __le16 __iomem *addr, u16 val)
110{
111 iowrite16(val, addr);
112}
113
114static inline void rtl818x_iowrite32(struct rtl8180_priv *priv,
115 __le32 __iomem *addr, u32 val)
116{
117 iowrite32(val, addr);
118}
119
120#endif /* RTL8180_H */
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
new file mode 100644
index 000000000000..6c226c024dd9
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -0,0 +1,1081 @@
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, 0x700f) },
40 { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) },
41
42 /* rtl8180 */
43 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) },
44 { PCI_DEVICE(0x1799, 0x6001) },
45 { PCI_DEVICE(0x1799, 0x6020) },
46 { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) },
47 { }
48};
49
50MODULE_DEVICE_TABLE(pci, rtl8180_table);
51
52static const struct ieee80211_rate rtl818x_rates[] = {
53 { .bitrate = 10, .hw_value = 0, },
54 { .bitrate = 20, .hw_value = 1, },
55 { .bitrate = 55, .hw_value = 2, },
56 { .bitrate = 110, .hw_value = 3, },
57 { .bitrate = 60, .hw_value = 4, },
58 { .bitrate = 90, .hw_value = 5, },
59 { .bitrate = 120, .hw_value = 6, },
60 { .bitrate = 180, .hw_value = 7, },
61 { .bitrate = 240, .hw_value = 8, },
62 { .bitrate = 360, .hw_value = 9, },
63 { .bitrate = 480, .hw_value = 10, },
64 { .bitrate = 540, .hw_value = 11, },
65};
66
67static const struct ieee80211_channel rtl818x_channels[] = {
68 { .center_freq = 2412 },
69 { .center_freq = 2417 },
70 { .center_freq = 2422 },
71 { .center_freq = 2427 },
72 { .center_freq = 2432 },
73 { .center_freq = 2437 },
74 { .center_freq = 2442 },
75 { .center_freq = 2447 },
76 { .center_freq = 2452 },
77 { .center_freq = 2457 },
78 { .center_freq = 2462 },
79 { .center_freq = 2467 },
80 { .center_freq = 2472 },
81 { .center_freq = 2484 },
82};
83
84
85
86
87void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
88{
89 struct rtl8180_priv *priv = dev->priv;
90 int i = 10;
91 u32 buf;
92
93 buf = (data << 8) | addr;
94
95 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf | 0x80);
96 while (i--) {
97 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf);
98 if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF))
99 return;
100 }
101}
102
103static void rtl8180_handle_rx(struct ieee80211_hw *dev)
104{
105 struct rtl8180_priv *priv = dev->priv;
106 unsigned int count = 32;
107
108 while (count--) {
109 struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
110 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
111 u32 flags = le32_to_cpu(entry->flags);
112
113 if (flags & RTL818X_RX_DESC_FLAG_OWN)
114 return;
115
116 if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
117 RTL818X_RX_DESC_FLAG_FOF |
118 RTL818X_RX_DESC_FLAG_RX_ERR)))
119 goto done;
120 else {
121 u32 flags2 = le32_to_cpu(entry->flags2);
122 struct ieee80211_rx_status rx_status = {0};
123 struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE);
124
125 if (unlikely(!new_skb))
126 goto done;
127
128 pci_unmap_single(priv->pdev,
129 *((dma_addr_t *)skb->cb),
130 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
131 skb_put(skb, flags & 0xFFF);
132
133 rx_status.antenna = (flags2 >> 15) & 1;
134 /* TODO: improve signal/rssi reporting */
135 rx_status.qual = flags2 & 0xFF;
136 rx_status.signal = (flags2 >> 8) & 0x7F;
137 /* XXX: is this correct? */
138 rx_status.rate_idx = (flags >> 20) & 0xF;
139 rx_status.freq = dev->conf.channel->center_freq;
140 rx_status.band = dev->conf.channel->band;
141 rx_status.mactime = le64_to_cpu(entry->tsft);
142 rx_status.flag |= RX_FLAG_TSFT;
143 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
144 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
145
146 ieee80211_rx_irqsafe(dev, skb, &rx_status);
147
148 skb = new_skb;
149 priv->rx_buf[priv->rx_idx] = skb;
150 *((dma_addr_t *) skb->cb) =
151 pci_map_single(priv->pdev, skb_tail_pointer(skb),
152 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
153 }
154
155 done:
156 entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb));
157 entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
158 MAX_RX_SIZE);
159 if (priv->rx_idx == 31)
160 entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
161 priv->rx_idx = (priv->rx_idx + 1) % 32;
162 }
163}
164
165static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
166{
167 struct rtl8180_priv *priv = dev->priv;
168 struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
169
170 while (skb_queue_len(&ring->queue)) {
171 struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
172 struct sk_buff *skb;
173 struct ieee80211_tx_info *info;
174 u32 flags = le32_to_cpu(entry->flags);
175
176 if (flags & RTL818X_TX_DESC_FLAG_OWN)
177 return;
178
179 ring->idx = (ring->idx + 1) % ring->entries;
180 skb = __skb_dequeue(&ring->queue);
181 pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
182 skb->len, PCI_DMA_TODEVICE);
183
184 info = IEEE80211_SKB_CB(skb);
185 ieee80211_tx_info_clear_status(info);
186
187 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
188 (flags & RTL818X_TX_DESC_FLAG_TX_OK))
189 info->flags |= IEEE80211_TX_STAT_ACK;
190
191 info->status.rates[0].count = (flags & 0xFF) + 1;
192
193 ieee80211_tx_status_irqsafe(dev, skb);
194 if (ring->entries - skb_queue_len(&ring->queue) == 2)
195 ieee80211_wake_queue(dev, prio);
196 }
197}
198
199static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
200{
201 struct ieee80211_hw *dev = dev_id;
202 struct rtl8180_priv *priv = dev->priv;
203 u16 reg;
204
205 spin_lock(&priv->lock);
206 reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
207 if (unlikely(reg == 0xFFFF)) {
208 spin_unlock(&priv->lock);
209 return IRQ_HANDLED;
210 }
211
212 rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
213
214 if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
215 rtl8180_handle_tx(dev, 3);
216
217 if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR))
218 rtl8180_handle_tx(dev, 2);
219
220 if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
221 rtl8180_handle_tx(dev, 1);
222
223 if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
224 rtl8180_handle_tx(dev, 0);
225
226 if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
227 rtl8180_handle_rx(dev);
228
229 spin_unlock(&priv->lock);
230
231 return IRQ_HANDLED;
232}
233
234static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
235{
236 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
237 struct rtl8180_priv *priv = dev->priv;
238 struct rtl8180_tx_ring *ring;
239 struct rtl8180_tx_desc *entry;
240 unsigned long flags;
241 unsigned int idx, prio;
242 dma_addr_t mapping;
243 u32 tx_flags;
244 u8 rc_flags;
245 u16 plcp_len = 0;
246 __le16 rts_duration = 0;
247
248 prio = skb_get_queue_mapping(skb);
249 ring = &priv->tx_ring[prio];
250
251 mapping = pci_map_single(priv->pdev, skb->data,
252 skb->len, PCI_DMA_TODEVICE);
253
254 tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS |
255 RTL818X_TX_DESC_FLAG_LS |
256 (ieee80211_get_tx_rate(dev, info)->hw_value << 24) |
257 skb->len;
258
259 if (priv->r8185)
260 tx_flags |= RTL818X_TX_DESC_FLAG_DMA |
261 RTL818X_TX_DESC_FLAG_NO_ENC;
262
263 rc_flags = info->control.rates[0].flags;
264 if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
265 tx_flags |= RTL818X_TX_DESC_FLAG_RTS;
266 tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
267 } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
268 tx_flags |= RTL818X_TX_DESC_FLAG_CTS;
269 tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
270 }
271
272 if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS)
273 rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len,
274 info);
275
276 if (!priv->r8185) {
277 unsigned int remainder;
278
279 plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
280 (ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
281 remainder = (16 * (skb->len + 4)) %
282 ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
283 if (remainder > 0 && remainder <= 6)
284 plcp_len |= 1 << 15;
285 }
286
287 spin_lock_irqsave(&priv->lock, flags);
288 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
289 entry = &ring->desc[idx];
290
291 entry->rts_duration = rts_duration;
292 entry->plcp_len = cpu_to_le16(plcp_len);
293 entry->tx_buf = cpu_to_le32(mapping);
294 entry->frame_len = cpu_to_le32(skb->len);
295 entry->flags2 = info->control.rates[1].idx >= 0 ?
296 ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
297 entry->retry_limit = info->control.rates[0].count;
298 entry->flags = cpu_to_le32(tx_flags);
299 __skb_queue_tail(&ring->queue, skb);
300 if (ring->entries - skb_queue_len(&ring->queue) < 2)
301 ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
302 spin_unlock_irqrestore(&priv->lock, flags);
303
304 rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
305
306 return 0;
307}
308
309void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam)
310{
311 u8 reg;
312
313 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
314 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
315 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
316 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
317 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
318 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
319 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
320 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
321}
322
323static int rtl8180_init_hw(struct ieee80211_hw *dev)
324{
325 struct rtl8180_priv *priv = dev->priv;
326 u16 reg;
327
328 rtl818x_iowrite8(priv, &priv->map->CMD, 0);
329 rtl818x_ioread8(priv, &priv->map->CMD);
330 msleep(10);
331
332 /* reset */
333 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
334 rtl818x_ioread8(priv, &priv->map->CMD);
335
336 reg = rtl818x_ioread8(priv, &priv->map->CMD);
337 reg &= (1 << 1);
338 reg |= RTL818X_CMD_RESET;
339 rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET);
340 rtl818x_ioread8(priv, &priv->map->CMD);
341 msleep(200);
342
343 /* check success of reset */
344 if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
345 printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy));
346 return -ETIMEDOUT;
347 }
348
349 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
350 rtl818x_ioread8(priv, &priv->map->CMD);
351 msleep(200);
352
353 if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) {
354 /* For cardbus */
355 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
356 reg |= 1 << 1;
357 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
358 reg = rtl818x_ioread16(priv, &priv->map->FEMR);
359 reg |= (1 << 15) | (1 << 14) | (1 << 4);
360 rtl818x_iowrite16(priv, &priv->map->FEMR, reg);
361 }
362
363 rtl818x_iowrite8(priv, &priv->map->MSR, 0);
364
365 if (!priv->r8185)
366 rtl8180_set_anaparam(priv, priv->anaparam);
367
368 rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
369 rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma);
370 rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma);
371 rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma);
372 rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma);
373
374 /* TODO: necessary? specs indicate not */
375 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
376 reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
377 rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3));
378 if (priv->r8185) {
379 reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
380 rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4));
381 }
382 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
383
384 /* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */
385
386 /* TODO: turn off hw wep on rtl8180 */
387
388 rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
389
390 if (priv->r8185) {
391 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
392 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
393 rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
394
395 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
396
397 /* TODO: set ClkRun enable? necessary? */
398 reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE);
399 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6));
400 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
401 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
402 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2));
403 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
404 } else {
405 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1);
406 rtl818x_iowrite8(priv, &priv->map->SECURITY, 0);
407
408 rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6);
409 rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C);
410 }
411
412 priv->rf->init(dev);
413 if (priv->r8185)
414 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
415 return 0;
416}
417
418static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
419{
420 struct rtl8180_priv *priv = dev->priv;
421 struct rtl8180_rx_desc *entry;
422 int i;
423
424 priv->rx_ring = pci_alloc_consistent(priv->pdev,
425 sizeof(*priv->rx_ring) * 32,
426 &priv->rx_ring_dma);
427
428 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
429 printk(KERN_ERR "%s: Cannot allocate RX ring\n",
430 wiphy_name(dev->wiphy));
431 return -ENOMEM;
432 }
433
434 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32);
435 priv->rx_idx = 0;
436
437 for (i = 0; i < 32; i++) {
438 struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE);
439 dma_addr_t *mapping;
440 entry = &priv->rx_ring[i];
441 if (!skb)
442 return 0;
443
444 priv->rx_buf[i] = skb;
445 mapping = (dma_addr_t *)skb->cb;
446 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
447 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
448 entry->rx_buf = cpu_to_le32(*mapping);
449 entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
450 MAX_RX_SIZE);
451 }
452 entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
453 return 0;
454}
455
456static void rtl8180_free_rx_ring(struct ieee80211_hw *dev)
457{
458 struct rtl8180_priv *priv = dev->priv;
459 int i;
460
461 for (i = 0; i < 32; i++) {
462 struct sk_buff *skb = priv->rx_buf[i];
463 if (!skb)
464 continue;
465
466 pci_unmap_single(priv->pdev,
467 *((dma_addr_t *)skb->cb),
468 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
469 kfree_skb(skb);
470 }
471
472 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32,
473 priv->rx_ring, priv->rx_ring_dma);
474 priv->rx_ring = NULL;
475}
476
477static int rtl8180_init_tx_ring(struct ieee80211_hw *dev,
478 unsigned int prio, unsigned int entries)
479{
480 struct rtl8180_priv *priv = dev->priv;
481 struct rtl8180_tx_desc *ring;
482 dma_addr_t dma;
483 int i;
484
485 ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
486 if (!ring || (unsigned long)ring & 0xFF) {
487 printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n",
488 wiphy_name(dev->wiphy), prio);
489 return -ENOMEM;
490 }
491
492 memset(ring, 0, sizeof(*ring)*entries);
493 priv->tx_ring[prio].desc = ring;
494 priv->tx_ring[prio].dma = dma;
495 priv->tx_ring[prio].idx = 0;
496 priv->tx_ring[prio].entries = entries;
497 skb_queue_head_init(&priv->tx_ring[prio].queue);
498
499 for (i = 0; i < entries; i++)
500 ring[i].next_tx_desc =
501 cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
502
503 return 0;
504}
505
506static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio)
507{
508 struct rtl8180_priv *priv = dev->priv;
509 struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
510
511 while (skb_queue_len(&ring->queue)) {
512 struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
513 struct sk_buff *skb = __skb_dequeue(&ring->queue);
514
515 pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
516 skb->len, PCI_DMA_TODEVICE);
517 kfree_skb(skb);
518 ring->idx = (ring->idx + 1) % ring->entries;
519 }
520
521 pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
522 ring->desc, ring->dma);
523 ring->desc = NULL;
524}
525
526static int rtl8180_start(struct ieee80211_hw *dev)
527{
528 struct rtl8180_priv *priv = dev->priv;
529 int ret, i;
530 u32 reg;
531
532 ret = rtl8180_init_rx_ring(dev);
533 if (ret)
534 return ret;
535
536 for (i = 0; i < 4; i++)
537 if ((ret = rtl8180_init_tx_ring(dev, i, 16)))
538 goto err_free_rings;
539
540 ret = rtl8180_init_hw(dev);
541 if (ret)
542 goto err_free_rings;
543
544 rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
545 rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma);
546 rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma);
547 rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma);
548 rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma);
549
550 ret = request_irq(priv->pdev->irq, &rtl8180_interrupt,
551 IRQF_SHARED, KBUILD_MODNAME, dev);
552 if (ret) {
553 printk(KERN_ERR "%s: failed to register IRQ handler\n",
554 wiphy_name(dev->wiphy));
555 goto err_free_rings;
556 }
557
558 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
559
560 rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
561 rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
562
563 reg = RTL818X_RX_CONF_ONLYERLPKT |
564 RTL818X_RX_CONF_RX_AUTORESETPHY |
565 RTL818X_RX_CONF_MGMT |
566 RTL818X_RX_CONF_DATA |
567 (7 << 8 /* MAX RX DMA */) |
568 RTL818X_RX_CONF_BROADCAST |
569 RTL818X_RX_CONF_NICMAC;
570
571 if (priv->r8185)
572 reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2;
573 else {
574 reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1)
575 ? RTL818X_RX_CONF_CSDM1 : 0;
576 reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2)
577 ? RTL818X_RX_CONF_CSDM2 : 0;
578 }
579
580 priv->rx_conf = reg;
581 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
582
583 if (priv->r8185) {
584 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
585 reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT;
586 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
587 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
588
589 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
590 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
591 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
592 reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
593 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
594
595 /* disable early TX */
596 rtl818x_iowrite8(priv, (u8 __iomem *)priv->map + 0xec, 0x3f);
597 }
598
599 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
600 reg |= (6 << 21 /* MAX TX DMA */) |
601 RTL818X_TX_CONF_NO_ICV;
602
603 if (priv->r8185)
604 reg &= ~RTL818X_TX_CONF_PROBE_DTS;
605 else
606 reg &= ~RTL818X_TX_CONF_HW_SEQNUM;
607
608 /* different meaning, same value on both rtl8185 and rtl8180 */
609 reg &= ~RTL818X_TX_CONF_SAT_HWPLCP;
610
611 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
612
613 reg = rtl818x_ioread8(priv, &priv->map->CMD);
614 reg |= RTL818X_CMD_RX_ENABLE;
615 reg |= RTL818X_CMD_TX_ENABLE;
616 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
617
618 priv->mode = NL80211_IFTYPE_MONITOR;
619 return 0;
620
621 err_free_rings:
622 rtl8180_free_rx_ring(dev);
623 for (i = 0; i < 4; i++)
624 if (priv->tx_ring[i].desc)
625 rtl8180_free_tx_ring(dev, i);
626
627 return ret;
628}
629
630static void rtl8180_stop(struct ieee80211_hw *dev)
631{
632 struct rtl8180_priv *priv = dev->priv;
633 u8 reg;
634 int i;
635
636 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
637
638 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
639
640 reg = rtl818x_ioread8(priv, &priv->map->CMD);
641 reg &= ~RTL818X_CMD_TX_ENABLE;
642 reg &= ~RTL818X_CMD_RX_ENABLE;
643 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
644
645 priv->rf->stop(dev);
646
647 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
648 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
649 rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
650 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
651
652 free_irq(priv->pdev->irq, dev);
653
654 rtl8180_free_rx_ring(dev);
655 for (i = 0; i < 4; i++)
656 rtl8180_free_tx_ring(dev, i);
657}
658
659static int rtl8180_add_interface(struct ieee80211_hw *dev,
660 struct ieee80211_if_init_conf *conf)
661{
662 struct rtl8180_priv *priv = dev->priv;
663
664 if (priv->mode != NL80211_IFTYPE_MONITOR)
665 return -EOPNOTSUPP;
666
667 switch (conf->type) {
668 case NL80211_IFTYPE_STATION:
669 priv->mode = conf->type;
670 break;
671 default:
672 return -EOPNOTSUPP;
673 }
674
675 priv->vif = conf->vif;
676
677 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
678 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
679 le32_to_cpu(*(__le32 *)conf->mac_addr));
680 rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4],
681 le16_to_cpu(*(__le16 *)(conf->mac_addr + 4)));
682 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
683
684 return 0;
685}
686
687static void rtl8180_remove_interface(struct ieee80211_hw *dev,
688 struct ieee80211_if_init_conf *conf)
689{
690 struct rtl8180_priv *priv = dev->priv;
691 priv->mode = NL80211_IFTYPE_MONITOR;
692 priv->vif = NULL;
693}
694
695static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
696{
697 struct rtl8180_priv *priv = dev->priv;
698 struct ieee80211_conf *conf = &dev->conf;
699
700 priv->rf->set_chan(dev, conf);
701
702 return 0;
703}
704
705static int rtl8180_config_interface(struct ieee80211_hw *dev,
706 struct ieee80211_vif *vif,
707 struct ieee80211_if_conf *conf)
708{
709 struct rtl8180_priv *priv = dev->priv;
710 int i;
711
712 for (i = 0; i < ETH_ALEN; i++)
713 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
714
715 if (is_valid_ether_addr(conf->bssid))
716 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
717 else
718 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
719
720 return 0;
721}
722
723static void rtl8180_configure_filter(struct ieee80211_hw *dev,
724 unsigned int changed_flags,
725 unsigned int *total_flags,
726 int mc_count, struct dev_addr_list *mclist)
727{
728 struct rtl8180_priv *priv = dev->priv;
729
730 if (changed_flags & FIF_FCSFAIL)
731 priv->rx_conf ^= RTL818X_RX_CONF_FCS;
732 if (changed_flags & FIF_CONTROL)
733 priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
734 if (changed_flags & FIF_OTHER_BSS)
735 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
736 if (*total_flags & FIF_ALLMULTI || mc_count > 0)
737 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
738 else
739 priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
740
741 *total_flags = 0;
742
743 if (priv->rx_conf & RTL818X_RX_CONF_FCS)
744 *total_flags |= FIF_FCSFAIL;
745 if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
746 *total_flags |= FIF_CONTROL;
747 if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
748 *total_flags |= FIF_OTHER_BSS;
749 if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
750 *total_flags |= FIF_ALLMULTI;
751
752 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
753}
754
755static const struct ieee80211_ops rtl8180_ops = {
756 .tx = rtl8180_tx,
757 .start = rtl8180_start,
758 .stop = rtl8180_stop,
759 .add_interface = rtl8180_add_interface,
760 .remove_interface = rtl8180_remove_interface,
761 .config = rtl8180_config,
762 .config_interface = rtl8180_config_interface,
763 .configure_filter = rtl8180_configure_filter,
764};
765
766static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
767{
768 struct ieee80211_hw *dev = eeprom->data;
769 struct rtl8180_priv *priv = dev->priv;
770 u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
771
772 eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
773 eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
774 eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
775 eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
776}
777
778static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom)
779{
780 struct ieee80211_hw *dev = eeprom->data;
781 struct rtl8180_priv *priv = dev->priv;
782 u8 reg = 2 << 6;
783
784 if (eeprom->reg_data_in)
785 reg |= RTL818X_EEPROM_CMD_WRITE;
786 if (eeprom->reg_data_out)
787 reg |= RTL818X_EEPROM_CMD_READ;
788 if (eeprom->reg_data_clock)
789 reg |= RTL818X_EEPROM_CMD_CK;
790 if (eeprom->reg_chip_select)
791 reg |= RTL818X_EEPROM_CMD_CS;
792
793 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
794 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
795 udelay(10);
796}
797
798static int __devinit rtl8180_probe(struct pci_dev *pdev,
799 const struct pci_device_id *id)
800{
801 struct ieee80211_hw *dev;
802 struct rtl8180_priv *priv;
803 unsigned long mem_addr, mem_len;
804 unsigned int io_addr, io_len;
805 int err, i;
806 struct eeprom_93cx6 eeprom;
807 const char *chip_name, *rf_name = NULL;
808 u32 reg;
809 u16 eeprom_val;
810
811 err = pci_enable_device(pdev);
812 if (err) {
813 printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n",
814 pci_name(pdev));
815 return err;
816 }
817
818 err = pci_request_regions(pdev, KBUILD_MODNAME);
819 if (err) {
820 printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n",
821 pci_name(pdev));
822 return err;
823 }
824
825 io_addr = pci_resource_start(pdev, 0);
826 io_len = pci_resource_len(pdev, 0);
827 mem_addr = pci_resource_start(pdev, 1);
828 mem_len = pci_resource_len(pdev, 1);
829
830 if (mem_len < sizeof(struct rtl818x_csr) ||
831 io_len < sizeof(struct rtl818x_csr)) {
832 printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n",
833 pci_name(pdev));
834 err = -ENOMEM;
835 goto err_free_reg;
836 }
837
838 if ((err = pci_set_dma_mask(pdev, 0xFFFFFF00ULL)) ||
839 (err = pci_set_consistent_dma_mask(pdev, 0xFFFFFF00ULL))) {
840 printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n",
841 pci_name(pdev));
842 goto err_free_reg;
843 }
844
845 pci_set_master(pdev);
846
847 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops);
848 if (!dev) {
849 printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n",
850 pci_name(pdev));
851 err = -ENOMEM;
852 goto err_free_reg;
853 }
854
855 priv = dev->priv;
856 priv->pdev = pdev;
857
858 dev->max_rates = 2;
859 SET_IEEE80211_DEV(dev, &pdev->dev);
860 pci_set_drvdata(pdev, dev);
861
862 priv->map = pci_iomap(pdev, 1, mem_len);
863 if (!priv->map)
864 priv->map = pci_iomap(pdev, 0, io_len);
865
866 if (!priv->map) {
867 printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n",
868 pci_name(pdev));
869 goto err_free_dev;
870 }
871
872 BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels));
873 BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates));
874
875 memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
876 memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
877
878 priv->band.band = IEEE80211_BAND_2GHZ;
879 priv->band.channels = priv->channels;
880 priv->band.n_channels = ARRAY_SIZE(rtl818x_channels);
881 priv->band.bitrates = priv->rates;
882 priv->band.n_bitrates = 4;
883 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
884
885 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
886 IEEE80211_HW_RX_INCLUDES_FCS |
887 IEEE80211_HW_SIGNAL_UNSPEC;
888 dev->queues = 1;
889 dev->max_signal = 65;
890
891 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
892 reg &= RTL818X_TX_CONF_HWVER_MASK;
893 switch (reg) {
894 case RTL818X_TX_CONF_R8180_ABCD:
895 chip_name = "RTL8180";
896 break;
897 case RTL818X_TX_CONF_R8180_F:
898 chip_name = "RTL8180vF";
899 break;
900 case RTL818X_TX_CONF_R8185_ABC:
901 chip_name = "RTL8185";
902 break;
903 case RTL818X_TX_CONF_R8185_D:
904 chip_name = "RTL8185vD";
905 break;
906 default:
907 printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n",
908 pci_name(pdev), reg >> 25);
909 goto err_iounmap;
910 }
911
912 priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC;
913 if (priv->r8185) {
914 priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates);
915 pci_try_set_mwi(pdev);
916 }
917
918 eeprom.data = dev;
919 eeprom.register_read = rtl8180_eeprom_register_read;
920 eeprom.register_write = rtl8180_eeprom_register_write;
921 if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
922 eeprom.width = PCI_EEPROM_WIDTH_93C66;
923 else
924 eeprom.width = PCI_EEPROM_WIDTH_93C46;
925
926 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM);
927 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
928 udelay(10);
929
930 eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val);
931 eeprom_val &= 0xFF;
932 switch (eeprom_val) {
933 case 1: rf_name = "Intersil";
934 break;
935 case 2: rf_name = "RFMD";
936 break;
937 case 3: priv->rf = &sa2400_rf_ops;
938 break;
939 case 4: priv->rf = &max2820_rf_ops;
940 break;
941 case 5: priv->rf = &grf5101_rf_ops;
942 break;
943 case 9: priv->rf = rtl8180_detect_rf(dev);
944 break;
945 case 10:
946 rf_name = "RTL8255";
947 break;
948 default:
949 printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n",
950 pci_name(pdev), eeprom_val);
951 goto err_iounmap;
952 }
953
954 if (!priv->rf) {
955 printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n",
956 pci_name(pdev), rf_name);
957 goto err_iounmap;
958 }
959
960 eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val);
961 priv->csthreshold = eeprom_val >> 8;
962 if (!priv->r8185) {
963 __le32 anaparam;
964 eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2);
965 priv->anaparam = le32_to_cpu(anaparam);
966 eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam);
967 }
968
969 eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3);
970 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
971 printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using"
972 " randomly generated MAC addr\n", pci_name(pdev));
973 random_ether_addr(dev->wiphy->perm_addr);
974 }
975
976 /* CCK TX power */
977 for (i = 0; i < 14; i += 2) {
978 u16 txpwr;
979 eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr);
980 priv->channels[i].hw_value = txpwr & 0xFF;
981 priv->channels[i + 1].hw_value = txpwr >> 8;
982 }
983
984 /* OFDM TX power */
985 if (priv->r8185) {
986 for (i = 0; i < 14; i += 2) {
987 u16 txpwr;
988 eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr);
989 priv->channels[i].hw_value |= (txpwr & 0xFF) << 8;
990 priv->channels[i + 1].hw_value |= txpwr & 0xFF00;
991 }
992 }
993
994 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
995
996 spin_lock_init(&priv->lock);
997
998 err = ieee80211_register_hw(dev);
999 if (err) {
1000 printk(KERN_ERR "%s (rtl8180): Cannot register device\n",
1001 pci_name(pdev));
1002 goto err_iounmap;
1003 }
1004
1005 printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n",
1006 wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
1007 chip_name, priv->rf->name);
1008
1009 return 0;
1010
1011 err_iounmap:
1012 iounmap(priv->map);
1013
1014 err_free_dev:
1015 pci_set_drvdata(pdev, NULL);
1016 ieee80211_free_hw(dev);
1017
1018 err_free_reg:
1019 pci_release_regions(pdev);
1020 pci_disable_device(pdev);
1021 return err;
1022}
1023
1024static void __devexit rtl8180_remove(struct pci_dev *pdev)
1025{
1026 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1027 struct rtl8180_priv *priv;
1028
1029 if (!dev)
1030 return;
1031
1032 ieee80211_unregister_hw(dev);
1033
1034 priv = dev->priv;
1035
1036 pci_iounmap(pdev, priv->map);
1037 pci_release_regions(pdev);
1038 pci_disable_device(pdev);
1039 ieee80211_free_hw(dev);
1040}
1041
1042#ifdef CONFIG_PM
1043static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
1044{
1045 pci_save_state(pdev);
1046 pci_set_power_state(pdev, pci_choose_state(pdev, state));
1047 return 0;
1048}
1049
1050static int rtl8180_resume(struct pci_dev *pdev)
1051{
1052 pci_set_power_state(pdev, PCI_D0);
1053 pci_restore_state(pdev);
1054 return 0;
1055}
1056
1057#endif /* CONFIG_PM */
1058
1059static struct pci_driver rtl8180_driver = {
1060 .name = KBUILD_MODNAME,
1061 .id_table = rtl8180_table,
1062 .probe = rtl8180_probe,
1063 .remove = __devexit_p(rtl8180_remove),
1064#ifdef CONFIG_PM
1065 .suspend = rtl8180_suspend,
1066 .resume = rtl8180_resume,
1067#endif /* CONFIG_PM */
1068};
1069
1070static int __init rtl8180_init(void)
1071{
1072 return pci_register_driver(&rtl8180_driver);
1073}
1074
1075static void __exit rtl8180_exit(void)
1076{
1077 pci_unregister_driver(&rtl8180_driver);
1078}
1079
1080module_init(rtl8180_init);
1081module_exit(rtl8180_exit);
diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.c b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c
new file mode 100644
index 000000000000..947ee55f18b2
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c
@@ -0,0 +1,180 @@
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 int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
77 u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
78 u32 chan = channel - 1;
79
80 /* set TX power */
81 write_grf5101(dev, 0x15, 0x0);
82 write_grf5101(dev, 0x06, txpw);
83 write_grf5101(dev, 0x15, 0x10);
84 write_grf5101(dev, 0x15, 0x0);
85
86 /* set frequency */
87 write_grf5101(dev, 0x07, 0x0);
88 write_grf5101(dev, 0x0B, chan);
89 write_grf5101(dev, 0x07, 0x1000);
90
91 grf5101_write_phy_antenna(dev, channel);
92}
93
94static void grf5101_rf_stop(struct ieee80211_hw *dev)
95{
96 struct rtl8180_priv *priv = dev->priv;
97 u32 anaparam;
98
99 anaparam = priv->anaparam;
100 anaparam &= 0x000fffff;
101 anaparam |= 0x3f900000;
102 rtl8180_set_anaparam(priv, anaparam);
103
104 write_grf5101(dev, 0x07, 0x0);
105 write_grf5101(dev, 0x1f, 0x45);
106 write_grf5101(dev, 0x1f, 0x5);
107 write_grf5101(dev, 0x00, 0x8e4);
108}
109
110static void grf5101_rf_init(struct ieee80211_hw *dev)
111{
112 struct rtl8180_priv *priv = dev->priv;
113
114 rtl8180_set_anaparam(priv, priv->anaparam);
115
116 write_grf5101(dev, 0x1f, 0x0);
117 write_grf5101(dev, 0x1f, 0x0);
118 write_grf5101(dev, 0x1f, 0x40);
119 write_grf5101(dev, 0x1f, 0x60);
120 write_grf5101(dev, 0x1f, 0x61);
121 write_grf5101(dev, 0x1f, 0x61);
122 write_grf5101(dev, 0x00, 0xae4);
123 write_grf5101(dev, 0x1f, 0x1);
124 write_grf5101(dev, 0x1f, 0x41);
125 write_grf5101(dev, 0x1f, 0x61);
126
127 write_grf5101(dev, 0x01, 0x1a23);
128 write_grf5101(dev, 0x02, 0x4971);
129 write_grf5101(dev, 0x03, 0x41de);
130 write_grf5101(dev, 0x04, 0x2d80);
131 write_grf5101(dev, 0x05, 0x68ff); /* 0x61ff original value */
132 write_grf5101(dev, 0x06, 0x0);
133 write_grf5101(dev, 0x07, 0x0);
134 write_grf5101(dev, 0x08, 0x7533);
135 write_grf5101(dev, 0x09, 0xc401);
136 write_grf5101(dev, 0x0a, 0x0);
137 write_grf5101(dev, 0x0c, 0x1c7);
138 write_grf5101(dev, 0x0d, 0x29d3);
139 write_grf5101(dev, 0x0e, 0x2e8);
140 write_grf5101(dev, 0x10, 0x192);
141 write_grf5101(dev, 0x11, 0x248);
142 write_grf5101(dev, 0x12, 0x0);
143 write_grf5101(dev, 0x13, 0x20c4);
144 write_grf5101(dev, 0x14, 0xf4fc);
145 write_grf5101(dev, 0x15, 0x0);
146 write_grf5101(dev, 0x16, 0x1500);
147
148 write_grf5101(dev, 0x07, 0x1000);
149
150 /* baseband configuration */
151 rtl8180_write_phy(dev, 0, 0xa8);
152 rtl8180_write_phy(dev, 3, 0x0);
153 rtl8180_write_phy(dev, 4, 0xc0);
154 rtl8180_write_phy(dev, 5, 0x90);
155 rtl8180_write_phy(dev, 6, 0x1e);
156 rtl8180_write_phy(dev, 7, 0x64);
157
158 grf5101_write_phy_antenna(dev, 1);
159
160 rtl8180_write_phy(dev, 0x11, 0x88);
161
162 if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
163 RTL818X_CONFIG2_ANTENNA_DIV)
164 rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */
165 else
166 rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */
167
168 rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
169
170 rtl8180_write_phy(dev, 0x19, 0x0);
171 rtl8180_write_phy(dev, 0x1a, 0xa0);
172 rtl8180_write_phy(dev, 0x1b, 0x44);
173}
174
175const struct rtl818x_rf_ops grf5101_rf_ops = {
176 .name = "GCT",
177 .init = grf5101_rf_init,
178 .stop = grf5101_rf_stop,
179 .set_chan = grf5101_rf_set_channel
180};
diff --git a/drivers/net/wireless/rtl818x/rtl8180_grf5101.h b/drivers/net/wireless/rtl818x/rtl8180_grf5101.h
new file mode 100644
index 000000000000..76647111bcff
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/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/rtl818x/rtl8180_max2820.c b/drivers/net/wireless/rtl818x/rtl8180_max2820.c
new file mode 100644
index 000000000000..6c825fd7f3b6
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8180_max2820.c
@@ -0,0 +1,152 @@
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 int channel = conf ?
82 ieee80211_frequency_to_channel(conf->channel->center_freq) : 1;
83 unsigned int chan_idx = channel - 1;
84 u32 txpw = priv->channels[chan_idx].hw_value & 0xFF;
85 u32 chan = max2820_chan[chan_idx];
86
87 /* While philips SA2400 drive the PA bias from
88 * sa2400, for MAXIM we do this directly from BB */
89 rtl8180_write_phy(dev, 3, txpw);
90
91 max2820_write_phy_antenna(dev, channel);
92 write_max2820(dev, 3, chan);
93}
94
95static void max2820_rf_stop(struct ieee80211_hw *dev)
96{
97 rtl8180_write_phy(dev, 3, 0x8);
98 write_max2820(dev, 1, 0);
99}
100
101
102static void max2820_rf_init(struct ieee80211_hw *dev)
103{
104 struct rtl8180_priv *priv = dev->priv;
105
106 /* MAXIM from netbsd driver */
107 write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */
108 write_max2820(dev, 1, 0x01e); /* enable register */
109 write_max2820(dev, 2, 0x001); /* synt register */
110
111 max2820_rf_set_channel(dev, NULL);
112
113 write_max2820(dev, 4, 0x313); /* rx register */
114
115 /* PA is driven directly by the BB, we keep the MAXIM bias
116 * at the highest value in case that setting it to lower
117 * values may introduce some further attenuation somewhere..
118 */
119 write_max2820(dev, 5, 0x00f);
120
121 /* baseband configuration */
122 rtl8180_write_phy(dev, 0, 0x88); /* sys1 */
123 rtl8180_write_phy(dev, 3, 0x08); /* txagc */
124 rtl8180_write_phy(dev, 4, 0xf8); /* lnadet */
125 rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit */
126 rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */
127 rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet */
128
129 max2820_write_phy_antenna(dev, 1);
130
131 rtl8180_write_phy(dev, 0x11, 0x88); /* trl */
132
133 if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
134 RTL818X_CONFIG2_ANTENNA_DIV)
135 rtl8180_write_phy(dev, 0x12, 0xc7);
136 else
137 rtl8180_write_phy(dev, 0x12, 0x47);
138
139 rtl8180_write_phy(dev, 0x13, 0x9b);
140
141 rtl8180_write_phy(dev, 0x19, 0x0); /* CHESTLIM */
142 rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM */
143
144 max2820_rf_set_channel(dev, NULL);
145}
146
147const struct rtl818x_rf_ops max2820_rf_ops = {
148 .name = "Maxim",
149 .init = max2820_rf_init,
150 .stop = max2820_rf_stop,
151 .set_chan = max2820_rf_set_channel
152};
diff --git a/drivers/net/wireless/rtl818x/rtl8180_max2820.h b/drivers/net/wireless/rtl818x/rtl8180_max2820.h
new file mode 100644
index 000000000000..61cf6d1e7d57
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/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/rtl818x/rtl8180_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
new file mode 100644
index 000000000000..cd22781728a9
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
@@ -0,0 +1,780 @@
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].hw_value & 0xFF;
265 ofdm_power = priv->channels[channel - 1].hw_value >> 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].hw_value & 0xFF;
480 ofdm_power = priv->channels[channel - 1].hw_value >> 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 int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
720
721 if (priv->rf->init == rtl8225_rf_init)
722 rtl8225_rf_set_tx_power(dev, chan);
723 else
724 rtl8225z2_rf_set_tx_power(dev, chan);
725
726 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
727 msleep(10);
728
729 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
730 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
731 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
732 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
733 rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
734 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
735 } else {
736 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
737 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44);
738 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
739 rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
740 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
741 }
742}
743
744static const struct rtl818x_rf_ops rtl8225_ops = {
745 .name = "rtl8225",
746 .init = rtl8225_rf_init,
747 .stop = rtl8225_rf_stop,
748 .set_chan = rtl8225_rf_set_channel
749};
750
751static const struct rtl818x_rf_ops rtl8225z2_ops = {
752 .name = "rtl8225z2",
753 .init = rtl8225z2_rf_init,
754 .stop = rtl8225_rf_stop,
755 .set_chan = rtl8225_rf_set_channel
756};
757
758const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
759{
760 struct rtl8180_priv *priv = dev->priv;
761 u16 reg8, reg9;
762
763 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
764 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
765 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
766 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
767 msleep(100);
768
769 rtl8225_write(dev, 0, 0x1B7);
770
771 reg8 = rtl8225_read(dev, 8);
772 reg9 = rtl8225_read(dev, 9);
773
774 rtl8225_write(dev, 0, 0x0B7);
775
776 if (reg8 != 0x588 || reg9 != 0x700)
777 return &rtl8225_ops;
778
779 return &rtl8225z2_ops;
780}
diff --git a/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h
new file mode 100644
index 000000000000..310013a2d726
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/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/rtl818x/rtl8180_sa2400.c b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c
new file mode 100644
index 000000000000..cea4e0ccb92d
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c
@@ -0,0 +1,202 @@
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 int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
84 u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
85 u32 chan = sa2400_chan[channel - 1];
86
87 write_sa2400(dev, 7, txpw);
88
89 sa2400_write_phy_antenna(dev, channel);
90
91 write_sa2400(dev, 0, chan);
92 write_sa2400(dev, 1, 0xbb50);
93 write_sa2400(dev, 2, 0x80);
94 write_sa2400(dev, 3, 0);
95}
96
97static void sa2400_rf_stop(struct ieee80211_hw *dev)
98{
99 write_sa2400(dev, 4, 0);
100}
101
102static void sa2400_rf_init(struct ieee80211_hw *dev)
103{
104 struct rtl8180_priv *priv = dev->priv;
105 u32 anaparam, txconf;
106 u8 firdac;
107 int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY;
108
109 anaparam = priv->anaparam;
110 anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT);
111 anaparam &= ~ANAPARAM_PWR1_MASK;
112 anaparam &= ~ANAPARAM_PWR0_MASK;
113
114 if (analogphy) {
115 anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT;
116 firdac = 0;
117 } else {
118 anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT);
119 anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT);
120 firdac = 1 << SA2400_REG4_FIRDAC_SHIFT;
121 }
122
123 rtl8180_set_anaparam(priv, anaparam);
124
125 write_sa2400(dev, 0, sa2400_chan[0]);
126 write_sa2400(dev, 1, 0xbb50);
127 write_sa2400(dev, 2, 0x80);
128 write_sa2400(dev, 3, 0);
129 write_sa2400(dev, 4, 0x19340 | firdac);
130 write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15);
131 write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */
132
133 if (!analogphy)
134 write_sa2400(dev, 4, 0x1938c); /*???*/
135
136 write_sa2400(dev, 4, 0x19340 | firdac);
137
138 write_sa2400(dev, 0, sa2400_chan[0]);
139 write_sa2400(dev, 1, 0xbb50);
140 write_sa2400(dev, 2, 0x80);
141 write_sa2400(dev, 3, 0);
142 write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */
143
144 /* new from rtl8180 embedded driver (rtl8181 project) */
145 write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */
146 write_sa2400(dev, 8, 0); /* VCO */
147
148 if (analogphy) {
149 rtl8180_set_anaparam(priv, anaparam |
150 (1 << ANAPARAM_TXDACOFF_SHIFT));
151
152 txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF);
153 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
154 txconf | RTL818X_TX_CONF_LOOPBACK_CONT);
155
156 write_sa2400(dev, 4, 0x19341); /* calibrates DC */
157
158 /* a 5us sleep is required here,
159 * we rely on the 3ms delay introduced in write_sa2400 */
160 write_sa2400(dev, 4, 0x19345);
161
162 /* a 20us sleep is required here,
163 * we rely on the 3ms delay introduced in write_sa2400 */
164
165 rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf);
166
167 rtl8180_set_anaparam(priv, anaparam);
168 }
169 /* end new code */
170
171 write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */
172
173 /* baseband configuration */
174 rtl8180_write_phy(dev, 0, 0x98);
175 rtl8180_write_phy(dev, 3, 0x38);
176 rtl8180_write_phy(dev, 4, 0xe0);
177 rtl8180_write_phy(dev, 5, 0x90);
178 rtl8180_write_phy(dev, 6, 0x1a);
179 rtl8180_write_phy(dev, 7, 0x64);
180
181 sa2400_write_phy_antenna(dev, 1);
182
183 rtl8180_write_phy(dev, 0x11, 0x80);
184
185 if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
186 RTL818X_CONFIG2_ANTENNA_DIV)
187 rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */
188 else
189 rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */
190
191 rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
192
193 rtl8180_write_phy(dev, 0x19, 0x0);
194 rtl8180_write_phy(dev, 0x1a, 0xa0);
195}
196
197const struct rtl818x_rf_ops sa2400_rf_ops = {
198 .name = "Philips",
199 .init = sa2400_rf_init,
200 .stop = sa2400_rf_stop,
201 .set_chan = sa2400_rf_set_channel
202};
diff --git a/drivers/net/wireless/rtl818x/rtl8180_sa2400.h b/drivers/net/wireless/rtl818x/rtl8180_sa2400.h
new file mode 100644
index 000000000000..a4aaa0d413f1
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/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/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
new file mode 100644
index 000000000000..33725d0978b3
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -0,0 +1,220 @@
1/*
2 * Definitions for RTL8187 hardware
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef RTL8187_H
16#define RTL8187_H
17
18#include "rtl818x.h"
19
20#define RTL8187_EEPROM_TXPWR_BASE 0x05
21#define RTL8187_EEPROM_MAC_ADDR 0x07
22#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */
23#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */
24#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */
25
26#define RTL8187_REQT_READ 0xC0
27#define RTL8187_REQT_WRITE 0x40
28#define RTL8187_REQ_GET_REG 0x05
29#define RTL8187_REQ_SET_REG 0x05
30
31#define RTL8187_MAX_RX 0x9C4
32
33struct rtl8187_rx_info {
34 struct urb *urb;
35 struct ieee80211_hw *dev;
36};
37
38struct rtl8187_rx_hdr {
39 __le32 flags;
40 u8 noise;
41 u8 signal;
42 u8 agc;
43 u8 reserved;
44 __le64 mac_time;
45} __attribute__((packed));
46
47struct rtl8187b_rx_hdr {
48 __le32 flags;
49 __le64 mac_time;
50 u8 sq;
51 u8 rssi;
52 u8 agc;
53 u8 flags2;
54 __le16 snr_long2end;
55 s8 pwdb_g12;
56 u8 fot;
57} __attribute__((packed));
58
59/* {rtl8187,rtl8187b}_tx_info is in skb */
60
61struct rtl8187_tx_hdr {
62 __le32 flags;
63 __le16 rts_duration;
64 __le16 len;
65 __le32 retry;
66} __attribute__((packed));
67
68struct rtl8187b_tx_hdr {
69 __le32 flags;
70 __le16 rts_duration;
71 __le16 len;
72 __le32 unused_1;
73 __le16 unused_2;
74 __le16 tx_duration;
75 __le32 unused_3;
76 __le32 retry;
77 __le32 unused_4[2];
78} __attribute__((packed));
79
80enum {
81 DEVICE_RTL8187,
82 DEVICE_RTL8187B
83};
84
85struct rtl8187_priv {
86 /* common between rtl818x drivers */
87 struct rtl818x_csr *map;
88 const struct rtl818x_rf_ops *rf;
89 struct ieee80211_vif *vif;
90 int mode;
91 /* The mutex protects the TX loopback state.
92 * Any attempt to set channels concurrently locks the device.
93 */
94 struct mutex conf_mutex;
95
96 /* rtl8187 specific */
97 struct ieee80211_channel channels[14];
98 struct ieee80211_rate rates[12];
99 struct ieee80211_supported_band band;
100 struct usb_device *udev;
101 u32 rx_conf;
102 u16 txpwr_base;
103 u8 asic_rev;
104 u8 is_rtl8187b;
105 enum {
106 RTL8187BvB,
107 RTL8187BvD,
108 RTL8187BvE
109 } hw_rev;
110 struct sk_buff_head rx_queue;
111 u8 signal;
112 u8 quality;
113 u8 noise;
114};
115
116void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
117
118static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv,
119 u8 *addr, u8 idx)
120{
121 u8 val;
122
123 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
124 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
125 (unsigned long)addr, idx & 0x03, &val,
126 sizeof(val), HZ / 2);
127
128 return val;
129}
130
131static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
132{
133 return rtl818x_ioread8_idx(priv, addr, 0);
134}
135
136static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv,
137 __le16 *addr, u8 idx)
138{
139 __le16 val;
140
141 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
142 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
143 (unsigned long)addr, idx & 0x03, &val,
144 sizeof(val), HZ / 2);
145
146 return le16_to_cpu(val);
147}
148
149static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
150{
151 return rtl818x_ioread16_idx(priv, addr, 0);
152}
153
154static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv,
155 __le32 *addr, u8 idx)
156{
157 __le32 val;
158
159 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
160 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
161 (unsigned long)addr, idx & 0x03, &val,
162 sizeof(val), HZ / 2);
163
164 return le32_to_cpu(val);
165}
166
167static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
168{
169 return rtl818x_ioread32_idx(priv, addr, 0);
170}
171
172static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv,
173 u8 *addr, u8 val, u8 idx)
174{
175 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
176 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
177 (unsigned long)addr, idx & 0x03, &val,
178 sizeof(val), HZ / 2);
179}
180
181static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val)
182{
183 rtl818x_iowrite8_idx(priv, addr, val, 0);
184}
185
186static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv,
187 __le16 *addr, u16 val, u8 idx)
188{
189 __le16 buf = cpu_to_le16(val);
190
191 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
192 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
193 (unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
194 HZ / 2);
195}
196
197static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr,
198 u16 val)
199{
200 rtl818x_iowrite16_idx(priv, addr, val, 0);
201}
202
203static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv,
204 __le32 *addr, u32 val, u8 idx)
205{
206 __le32 buf = cpu_to_le32(val);
207
208 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
209 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
210 (unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
211 HZ / 2);
212}
213
214static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr,
215 u32 val)
216{
217 rtl818x_iowrite32_idx(priv, addr, val, 0);
218}
219
220#endif /* RTL8187_H */
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
new file mode 100644
index 000000000000..e1399d0b55d3
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -0,0 +1,1298 @@
1/*
2 * Linux device driver for RTL8187
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * Magic delays and register offsets below are taken from the original
11 * r8187 driver sources. 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/usb.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 "rtl8187.h"
26#include "rtl8187_rtl8225.h"
27
28MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
29MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
30MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
31MODULE_LICENSE("GPL");
32
33static struct usb_device_id rtl8187_table[] __devinitdata = {
34 /* Asus */
35 {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
36 /* Belkin */
37 {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B},
38 /* Realtek */
39 {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
40 {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
41 {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
42 {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
43 /* Netgear */
44 {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
45 {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
46 {USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B},
47 /* HP */
48 {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
49 /* Sitecom */
50 {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
51 {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
52 /* Abocom */
53 {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187},
54 {}
55};
56
57MODULE_DEVICE_TABLE(usb, rtl8187_table);
58
59static const struct ieee80211_rate rtl818x_rates[] = {
60 { .bitrate = 10, .hw_value = 0, },
61 { .bitrate = 20, .hw_value = 1, },
62 { .bitrate = 55, .hw_value = 2, },
63 { .bitrate = 110, .hw_value = 3, },
64 { .bitrate = 60, .hw_value = 4, },
65 { .bitrate = 90, .hw_value = 5, },
66 { .bitrate = 120, .hw_value = 6, },
67 { .bitrate = 180, .hw_value = 7, },
68 { .bitrate = 240, .hw_value = 8, },
69 { .bitrate = 360, .hw_value = 9, },
70 { .bitrate = 480, .hw_value = 10, },
71 { .bitrate = 540, .hw_value = 11, },
72};
73
74static const struct ieee80211_channel rtl818x_channels[] = {
75 { .center_freq = 2412 },
76 { .center_freq = 2417 },
77 { .center_freq = 2422 },
78 { .center_freq = 2427 },
79 { .center_freq = 2432 },
80 { .center_freq = 2437 },
81 { .center_freq = 2442 },
82 { .center_freq = 2447 },
83 { .center_freq = 2452 },
84 { .center_freq = 2457 },
85 { .center_freq = 2462 },
86 { .center_freq = 2467 },
87 { .center_freq = 2472 },
88 { .center_freq = 2484 },
89};
90
91static void rtl8187_iowrite_async_cb(struct urb *urb)
92{
93 kfree(urb->context);
94 usb_free_urb(urb);
95}
96
97static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr,
98 void *data, u16 len)
99{
100 struct usb_ctrlrequest *dr;
101 struct urb *urb;
102 struct rtl8187_async_write_data {
103 u8 data[4];
104 struct usb_ctrlrequest dr;
105 } *buf;
106 int rc;
107
108 buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
109 if (!buf)
110 return;
111
112 urb = usb_alloc_urb(0, GFP_ATOMIC);
113 if (!urb) {
114 kfree(buf);
115 return;
116 }
117
118 dr = &buf->dr;
119
120 dr->bRequestType = RTL8187_REQT_WRITE;
121 dr->bRequest = RTL8187_REQ_SET_REG;
122 dr->wValue = addr;
123 dr->wIndex = 0;
124 dr->wLength = cpu_to_le16(len);
125
126 memcpy(buf, data, len);
127
128 usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0),
129 (unsigned char *)dr, buf, len,
130 rtl8187_iowrite_async_cb, buf);
131 rc = usb_submit_urb(urb, GFP_ATOMIC);
132 if (rc < 0) {
133 kfree(buf);
134 usb_free_urb(urb);
135 }
136}
137
138static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv,
139 __le32 *addr, u32 val)
140{
141 __le32 buf = cpu_to_le32(val);
142
143 rtl8187_iowrite_async(priv, cpu_to_le16((unsigned long)addr),
144 &buf, sizeof(buf));
145}
146
147void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
148{
149 struct rtl8187_priv *priv = dev->priv;
150
151 data <<= 8;
152 data |= addr | 0x80;
153
154 rtl818x_iowrite8(priv, &priv->map->PHY[3], (data >> 24) & 0xFF);
155 rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF);
156 rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF);
157 rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF);
158}
159
160static void rtl8187_tx_cb(struct urb *urb)
161{
162 struct sk_buff *skb = (struct sk_buff *)urb->context;
163 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
164 struct ieee80211_hw *hw = info->rate_driver_data[0];
165 struct rtl8187_priv *priv = hw->priv;
166
167 usb_free_urb(info->rate_driver_data[1]);
168 skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
169 sizeof(struct rtl8187_tx_hdr));
170 ieee80211_tx_info_clear_status(info);
171 info->flags |= IEEE80211_TX_STAT_ACK;
172 ieee80211_tx_status_irqsafe(hw, skb);
173}
174
175static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
176{
177 struct rtl8187_priv *priv = dev->priv;
178 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
179 unsigned int ep;
180 void *buf;
181 struct urb *urb;
182 __le16 rts_dur = 0;
183 u32 flags;
184 int rc;
185
186 urb = usb_alloc_urb(0, GFP_ATOMIC);
187 if (!urb) {
188 kfree_skb(skb);
189 return 0;
190 }
191
192 flags = skb->len;
193 flags |= RTL818X_TX_DESC_FLAG_NO_ENC;
194
195 flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;
196 if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control))
197 flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
198 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
199 flags |= RTL818X_TX_DESC_FLAG_RTS;
200 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
201 rts_dur = ieee80211_rts_duration(dev, priv->vif,
202 skb->len, info);
203 } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
204 flags |= RTL818X_TX_DESC_FLAG_CTS;
205 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
206 }
207
208 if (!priv->is_rtl8187b) {
209 struct rtl8187_tx_hdr *hdr =
210 (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
211 hdr->flags = cpu_to_le32(flags);
212 hdr->len = 0;
213 hdr->rts_duration = rts_dur;
214 hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8);
215 buf = hdr;
216
217 ep = 2;
218 } else {
219 /* fc needs to be calculated before skb_push() */
220 unsigned int epmap[4] = { 6, 7, 5, 4 };
221 struct ieee80211_hdr *tx_hdr =
222 (struct ieee80211_hdr *)(skb->data);
223 u16 fc = le16_to_cpu(tx_hdr->frame_control);
224
225 struct rtl8187b_tx_hdr *hdr =
226 (struct rtl8187b_tx_hdr *)skb_push(skb, sizeof(*hdr));
227 struct ieee80211_rate *txrate =
228 ieee80211_get_tx_rate(dev, info);
229 memset(hdr, 0, sizeof(*hdr));
230 hdr->flags = cpu_to_le32(flags);
231 hdr->rts_duration = rts_dur;
232 hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8);
233 hdr->tx_duration =
234 ieee80211_generic_frame_duration(dev, priv->vif,
235 skb->len, txrate);
236 buf = hdr;
237
238 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
239 ep = 12;
240 else
241 ep = epmap[skb_get_queue_mapping(skb)];
242 }
243
244 info->rate_driver_data[0] = dev;
245 info->rate_driver_data[1] = urb;
246
247 usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
248 buf, skb->len, rtl8187_tx_cb, skb);
249 rc = usb_submit_urb(urb, GFP_ATOMIC);
250 if (rc < 0) {
251 usb_free_urb(urb);
252 kfree_skb(skb);
253 }
254
255 return 0;
256}
257
258static void rtl8187_rx_cb(struct urb *urb)
259{
260 struct sk_buff *skb = (struct sk_buff *)urb->context;
261 struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb;
262 struct ieee80211_hw *dev = info->dev;
263 struct rtl8187_priv *priv = dev->priv;
264 struct ieee80211_rx_status rx_status = { 0 };
265 int rate, signal;
266 u32 flags;
267 u32 quality;
268
269 spin_lock(&priv->rx_queue.lock);
270 if (skb->next)
271 __skb_unlink(skb, &priv->rx_queue);
272 else {
273 spin_unlock(&priv->rx_queue.lock);
274 return;
275 }
276 spin_unlock(&priv->rx_queue.lock);
277
278 if (unlikely(urb->status)) {
279 usb_free_urb(urb);
280 dev_kfree_skb_irq(skb);
281 return;
282 }
283
284 skb_put(skb, urb->actual_length);
285 if (!priv->is_rtl8187b) {
286 struct rtl8187_rx_hdr *hdr =
287 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
288 flags = le32_to_cpu(hdr->flags);
289 signal = hdr->signal & 0x7f;
290 rx_status.antenna = (hdr->signal >> 7) & 1;
291 rx_status.noise = hdr->noise;
292 rx_status.mactime = le64_to_cpu(hdr->mac_time);
293 priv->quality = signal;
294 rx_status.qual = priv->quality;
295 priv->noise = hdr->noise;
296 rate = (flags >> 20) & 0xF;
297 if (rate > 3) { /* OFDM rate */
298 if (signal > 90)
299 signal = 90;
300 else if (signal < 25)
301 signal = 25;
302 signal = 90 - signal;
303 } else { /* CCK rate */
304 if (signal > 95)
305 signal = 95;
306 else if (signal < 30)
307 signal = 30;
308 signal = 95 - signal;
309 }
310 rx_status.signal = signal;
311 priv->signal = signal;
312 } else {
313 struct rtl8187b_rx_hdr *hdr =
314 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
315 /* The Realtek datasheet for the RTL8187B shows that the RX
316 * header contains the following quantities: signal quality,
317 * RSSI, AGC, the received power in dB, and the measured SNR.
318 * In testing, none of these quantities show qualitative
319 * agreement with AP signal strength, except for the AGC,
320 * which is inversely proportional to the strength of the
321 * signal. In the following, the quality and signal strength
322 * are derived from the AGC. The arbitrary scaling constants
323 * are chosen to make the results close to the values obtained
324 * for a BCM4312 using b43 as the driver. The noise is ignored
325 * for now.
326 */
327 flags = le32_to_cpu(hdr->flags);
328 quality = 170 - hdr->agc;
329 if (quality > 100)
330 quality = 100;
331 signal = 14 - hdr->agc / 2;
332 rx_status.qual = quality;
333 priv->quality = quality;
334 rx_status.signal = signal;
335 priv->signal = signal;
336 rx_status.antenna = (hdr->rssi >> 7) & 1;
337 rx_status.mactime = le64_to_cpu(hdr->mac_time);
338 rate = (flags >> 20) & 0xF;
339 }
340
341 skb_trim(skb, flags & 0x0FFF);
342 rx_status.rate_idx = rate;
343 rx_status.freq = dev->conf.channel->center_freq;
344 rx_status.band = dev->conf.channel->band;
345 rx_status.flag |= RX_FLAG_TSFT;
346 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
347 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
348 ieee80211_rx_irqsafe(dev, skb, &rx_status);
349
350 skb = dev_alloc_skb(RTL8187_MAX_RX);
351 if (unlikely(!skb)) {
352 usb_free_urb(urb);
353 /* TODO check rx queue length and refill *somewhere* */
354 return;
355 }
356
357 info = (struct rtl8187_rx_info *)skb->cb;
358 info->urb = urb;
359 info->dev = dev;
360 urb->transfer_buffer = skb_tail_pointer(skb);
361 urb->context = skb;
362 skb_queue_tail(&priv->rx_queue, skb);
363
364 usb_submit_urb(urb, GFP_ATOMIC);
365}
366
367static int rtl8187_init_urbs(struct ieee80211_hw *dev)
368{
369 struct rtl8187_priv *priv = dev->priv;
370 struct urb *entry;
371 struct sk_buff *skb;
372 struct rtl8187_rx_info *info;
373
374 while (skb_queue_len(&priv->rx_queue) < 8) {
375 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
376 if (!skb)
377 break;
378 entry = usb_alloc_urb(0, GFP_KERNEL);
379 if (!entry) {
380 kfree_skb(skb);
381 break;
382 }
383 usb_fill_bulk_urb(entry, priv->udev,
384 usb_rcvbulkpipe(priv->udev,
385 priv->is_rtl8187b ? 3 : 1),
386 skb_tail_pointer(skb),
387 RTL8187_MAX_RX, rtl8187_rx_cb, skb);
388 info = (struct rtl8187_rx_info *)skb->cb;
389 info->urb = entry;
390 info->dev = dev;
391 skb_queue_tail(&priv->rx_queue, skb);
392 usb_submit_urb(entry, GFP_KERNEL);
393 }
394
395 return 0;
396}
397
398static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
399{
400 struct rtl8187_priv *priv = dev->priv;
401 u8 reg;
402 int i;
403
404 reg = rtl818x_ioread8(priv, &priv->map->CMD);
405 reg &= (1 << 1);
406 reg |= RTL818X_CMD_RESET;
407 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
408
409 i = 10;
410 do {
411 msleep(2);
412 if (!(rtl818x_ioread8(priv, &priv->map->CMD) &
413 RTL818X_CMD_RESET))
414 break;
415 } while (--i);
416
417 if (!i) {
418 printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy));
419 return -ETIMEDOUT;
420 }
421
422 /* reload registers from eeprom */
423 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
424
425 i = 10;
426 do {
427 msleep(4);
428 if (!(rtl818x_ioread8(priv, &priv->map->EEPROM_CMD) &
429 RTL818X_EEPROM_CMD_CONFIG))
430 break;
431 } while (--i);
432
433 if (!i) {
434 printk(KERN_ERR "%s: eeprom reset timeout!\n",
435 wiphy_name(dev->wiphy));
436 return -ETIMEDOUT;
437 }
438
439 return 0;
440}
441
442static int rtl8187_init_hw(struct ieee80211_hw *dev)
443{
444 struct rtl8187_priv *priv = dev->priv;
445 u8 reg;
446 int res;
447
448 /* reset */
449 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
450 RTL818X_EEPROM_CMD_CONFIG);
451 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
452 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg |
453 RTL818X_CONFIG3_ANAPARAM_WRITE);
454 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
455 RTL8187_RTL8225_ANAPARAM_ON);
456 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
457 RTL8187_RTL8225_ANAPARAM2_ON);
458 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg &
459 ~RTL818X_CONFIG3_ANAPARAM_WRITE);
460 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
461 RTL818X_EEPROM_CMD_NORMAL);
462
463 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
464
465 msleep(200);
466 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
467 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
468 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
469 msleep(200);
470
471 res = rtl8187_cmd_reset(dev);
472 if (res)
473 return res;
474
475 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
476 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
477 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
478 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
479 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
480 RTL8187_RTL8225_ANAPARAM_ON);
481 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
482 RTL8187_RTL8225_ANAPARAM2_ON);
483 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
484 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
485 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
486
487 /* setup card */
488 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
489 rtl818x_iowrite8(priv, &priv->map->GPIO, 0);
490
491 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
492 rtl818x_iowrite8(priv, &priv->map->GPIO, 1);
493 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
494
495 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
496
497 rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF);
498 reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
499 reg &= 0x3F;
500 reg |= 0x80;
501 rtl818x_iowrite8(priv, &priv->map->CONFIG1, reg);
502
503 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
504
505 rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
506 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
507 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
508
509 // TODO: set RESP_RATE and BRSR properly
510 rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
511 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
512
513 /* host_usb_init */
514 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
515 rtl818x_iowrite8(priv, &priv->map->GPIO, 0);
516 reg = rtl818x_ioread8(priv, (u8 *)0xFE53);
517 rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7));
518 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
519 rtl818x_iowrite8(priv, &priv->map->GPIO, 0x20);
520 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
521 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80);
522 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80);
523 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x80);
524 msleep(100);
525
526 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
527 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
528 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
529 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
530 RTL818X_EEPROM_CMD_CONFIG);
531 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
532 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
533 RTL818X_EEPROM_CMD_NORMAL);
534 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
535 msleep(100);
536
537 priv->rf->init(dev);
538
539 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
540 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
541 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
542 rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10);
543 rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80);
544 rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60);
545 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
546
547 return 0;
548}
549
550static const u8 rtl8187b_reg_table[][3] = {
551 {0xF0, 0x32, 0}, {0xF1, 0x32, 0}, {0xF2, 0x00, 0}, {0xF3, 0x00, 0},
552 {0xF4, 0x32, 0}, {0xF5, 0x43, 0}, {0xF6, 0x00, 0}, {0xF7, 0x00, 0},
553 {0xF8, 0x46, 0}, {0xF9, 0xA4, 0}, {0xFA, 0x00, 0}, {0xFB, 0x00, 0},
554 {0xFC, 0x96, 0}, {0xFD, 0xA4, 0}, {0xFE, 0x00, 0}, {0xFF, 0x00, 0},
555
556 {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1},
557 {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1},
558 {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xE0, 0xFF, 1}, {0xE1, 0x0F, 1},
559 {0xE2, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, {0xF2, 0x02, 1},
560 {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, {0xF6, 0x06, 1},
561 {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
562
563 {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2},
564 {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2},
565 {0x27, 0x8D, 2}, {0x4D, 0x08, 2}, {0x50, 0x05, 2}, {0x51, 0xF5, 2},
566 {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2},
567 {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2},
568 {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2},
569 {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2},
570 {0x73, 0x9A, 2},
571
572 {0x34, 0xF0, 0}, {0x35, 0x0F, 0}, {0x5B, 0x40, 0}, {0x84, 0x88, 0},
573 {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
574 {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
575 {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
576 {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x91, 0x03, 0},
577
578 {0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0},
579 {0x8E, 0x08, 0}, {0x8F, 0x00, 0}
580};
581
582static int rtl8187b_init_hw(struct ieee80211_hw *dev)
583{
584 struct rtl8187_priv *priv = dev->priv;
585 int res, i;
586 u8 reg;
587
588 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
589 RTL818X_EEPROM_CMD_CONFIG);
590
591 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
592 reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT;
593 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
594 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
595 RTL8187B_RTL8225_ANAPARAM2_ON);
596 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
597 RTL8187B_RTL8225_ANAPARAM_ON);
598 rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
599 RTL8187B_RTL8225_ANAPARAM3_ON);
600
601 rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
602 reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
603 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5));
604 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5));
605
606 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
607 reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
608 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
609
610 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
611 RTL818X_EEPROM_CMD_NORMAL);
612
613 res = rtl8187_cmd_reset(dev);
614 if (res)
615 return res;
616
617 rtl818x_iowrite16(priv, (__le16 *)0xFF2D, 0x0FFF);
618 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
619 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
620 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
621 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
622 reg |= RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT |
623 RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
624 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
625
626 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
627 reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
628 reg |= RTL818X_RATE_FALLBACK_ENABLE;
629 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);
630
631 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
632 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
633 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1);
634
635 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
636 RTL818X_EEPROM_CMD_CONFIG);
637 reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
638 rtl818x_iowrite8(priv, &priv->map->CONFIG1, (reg & 0x3F) | 0x80);
639 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
640 RTL818X_EEPROM_CMD_NORMAL);
641
642 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
643 for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) {
644 rtl818x_iowrite8_idx(priv,
645 (u8 *)(uintptr_t)
646 (rtl8187b_reg_table[i][0] | 0xFF00),
647 rtl8187b_reg_table[i][1],
648 rtl8187b_reg_table[i][2]);
649 }
650
651 rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50);
652 rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0);
653
654 rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF0, 0, 1);
655 rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF4, 0, 1);
656 rtl818x_iowrite8_idx(priv, (u8 *)0xFFF8, 0, 1);
657
658 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
659
660 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
661
662 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
663 RTL818X_EEPROM_CMD_CONFIG);
664 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
665 reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
666 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
667 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
668 RTL818X_EEPROM_CMD_NORMAL);
669
670 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
671 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
672 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
673 msleep(100);
674
675 priv->rf->init(dev);
676
677 reg = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE;
678 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
679 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
680
681 rtl818x_iowrite8(priv, (u8 *)0xFE41, 0xF4);
682 rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x00);
683 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
684 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
685 rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x0F);
686 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
687 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
688
689 reg = rtl818x_ioread8(priv, (u8 *)0xFFDB);
690 rtl818x_iowrite8(priv, (u8 *)0xFFDB, reg | (1 << 2));
691 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x59FA, 3);
692 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF74, 0x59D2, 3);
693 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF76, 0x59D2, 3);
694 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF78, 0x19FA, 3);
695 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7A, 0x19FA, 3);
696 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7C, 0x00D0, 3);
697 rtl818x_iowrite8(priv, (u8 *)0xFF61, 0);
698 rtl818x_iowrite8_idx(priv, (u8 *)0xFF80, 0x0F, 1);
699 rtl818x_iowrite8_idx(priv, (u8 *)0xFF83, 0x03, 1);
700 rtl818x_iowrite8(priv, (u8 *)0xFFDA, 0x10);
701 rtl818x_iowrite8_idx(priv, (u8 *)0xFF4D, 0x08, 2);
702
703 rtl818x_iowrite32(priv, &priv->map->HSSI_PARA, 0x0600321B);
704
705 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1);
706
707 return 0;
708}
709
710static int rtl8187_start(struct ieee80211_hw *dev)
711{
712 struct rtl8187_priv *priv = dev->priv;
713 u32 reg;
714 int ret;
715
716 ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) :
717 rtl8187b_init_hw(dev);
718 if (ret)
719 return ret;
720
721 mutex_lock(&priv->conf_mutex);
722 if (priv->is_rtl8187b) {
723 reg = RTL818X_RX_CONF_MGMT |
724 RTL818X_RX_CONF_DATA |
725 RTL818X_RX_CONF_BROADCAST |
726 RTL818X_RX_CONF_NICMAC |
727 RTL818X_RX_CONF_BSSID |
728 (7 << 13 /* RX FIFO threshold NONE */) |
729 (7 << 10 /* MAX RX DMA */) |
730 RTL818X_RX_CONF_RX_AUTORESETPHY |
731 RTL818X_RX_CONF_ONLYERLPKT |
732 RTL818X_RX_CONF_MULTICAST;
733 priv->rx_conf = reg;
734 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
735
736 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
737 RTL818X_TX_CONF_HW_SEQNUM |
738 RTL818X_TX_CONF_DISREQQSIZE |
739 (7 << 8 /* short retry limit */) |
740 (7 << 0 /* long retry limit */) |
741 (7 << 21 /* MAX TX DMA */));
742 rtl8187_init_urbs(dev);
743 mutex_unlock(&priv->conf_mutex);
744 return 0;
745 }
746
747 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
748
749 rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
750 rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
751
752 rtl8187_init_urbs(dev);
753
754 reg = RTL818X_RX_CONF_ONLYERLPKT |
755 RTL818X_RX_CONF_RX_AUTORESETPHY |
756 RTL818X_RX_CONF_BSSID |
757 RTL818X_RX_CONF_MGMT |
758 RTL818X_RX_CONF_DATA |
759 (7 << 13 /* RX FIFO threshold NONE */) |
760 (7 << 10 /* MAX RX DMA */) |
761 RTL818X_RX_CONF_BROADCAST |
762 RTL818X_RX_CONF_NICMAC;
763
764 priv->rx_conf = reg;
765 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
766
767 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
768 reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT;
769 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
770 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
771
772 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
773 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
774 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
775 reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
776 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
777
778 reg = RTL818X_TX_CONF_CW_MIN |
779 (7 << 21 /* MAX TX DMA */) |
780 RTL818X_TX_CONF_NO_ICV;
781 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
782
783 reg = rtl818x_ioread8(priv, &priv->map->CMD);
784 reg |= RTL818X_CMD_TX_ENABLE;
785 reg |= RTL818X_CMD_RX_ENABLE;
786 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
787 mutex_unlock(&priv->conf_mutex);
788
789 return 0;
790}
791
792static void rtl8187_stop(struct ieee80211_hw *dev)
793{
794 struct rtl8187_priv *priv = dev->priv;
795 struct rtl8187_rx_info *info;
796 struct sk_buff *skb;
797 u32 reg;
798
799 mutex_lock(&priv->conf_mutex);
800 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
801
802 reg = rtl818x_ioread8(priv, &priv->map->CMD);
803 reg &= ~RTL818X_CMD_TX_ENABLE;
804 reg &= ~RTL818X_CMD_RX_ENABLE;
805 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
806
807 priv->rf->stop(dev);
808
809 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
810 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
811 rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
812 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
813
814 while ((skb = skb_dequeue(&priv->rx_queue))) {
815 info = (struct rtl8187_rx_info *)skb->cb;
816 usb_kill_urb(info->urb);
817 kfree_skb(skb);
818 }
819 mutex_unlock(&priv->conf_mutex);
820}
821
822static int rtl8187_add_interface(struct ieee80211_hw *dev,
823 struct ieee80211_if_init_conf *conf)
824{
825 struct rtl8187_priv *priv = dev->priv;
826 int i;
827
828 if (priv->mode != NL80211_IFTYPE_MONITOR)
829 return -EOPNOTSUPP;
830
831 switch (conf->type) {
832 case NL80211_IFTYPE_STATION:
833 priv->mode = conf->type;
834 break;
835 default:
836 return -EOPNOTSUPP;
837 }
838
839 mutex_lock(&priv->conf_mutex);
840 priv->vif = conf->vif;
841
842 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
843 for (i = 0; i < ETH_ALEN; i++)
844 rtl818x_iowrite8(priv, &priv->map->MAC[i],
845 ((u8 *)conf->mac_addr)[i]);
846 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
847
848 mutex_unlock(&priv->conf_mutex);
849 return 0;
850}
851
852static void rtl8187_remove_interface(struct ieee80211_hw *dev,
853 struct ieee80211_if_init_conf *conf)
854{
855 struct rtl8187_priv *priv = dev->priv;
856 mutex_lock(&priv->conf_mutex);
857 priv->mode = NL80211_IFTYPE_MONITOR;
858 priv->vif = NULL;
859 mutex_unlock(&priv->conf_mutex);
860}
861
862static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
863{
864 struct rtl8187_priv *priv = dev->priv;
865 struct ieee80211_conf *conf = &dev->conf;
866 u32 reg;
867
868 mutex_lock(&priv->conf_mutex);
869 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
870 /* Enable TX loopback on MAC level to avoid TX during channel
871 * changes, as this has be seen to causes problems and the
872 * card will stop work until next reset
873 */
874 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
875 reg | RTL818X_TX_CONF_LOOPBACK_MAC);
876 priv->rf->set_chan(dev, conf);
877 msleep(10);
878 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
879
880 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
881 rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
882 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
883 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
884 mutex_unlock(&priv->conf_mutex);
885 return 0;
886}
887
888static int rtl8187_config_interface(struct ieee80211_hw *dev,
889 struct ieee80211_vif *vif,
890 struct ieee80211_if_conf *conf)
891{
892 struct rtl8187_priv *priv = dev->priv;
893 int i;
894 u8 reg;
895
896 mutex_lock(&priv->conf_mutex);
897 for (i = 0; i < ETH_ALEN; i++)
898 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
899
900 if (is_valid_ether_addr(conf->bssid)) {
901 reg = RTL818X_MSR_INFRA;
902 if (priv->is_rtl8187b)
903 reg |= RTL818X_MSR_ENEDCA;
904 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
905 } else {
906 reg = RTL818X_MSR_NO_LINK;
907 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
908 }
909
910 mutex_unlock(&priv->conf_mutex);
911 return 0;
912}
913
914static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot,
915 bool use_short_preamble)
916{
917 if (priv->is_rtl8187b) {
918 u8 difs, eifs, slot_time;
919 u16 ack_timeout;
920
921 if (use_short_slot) {
922 slot_time = 0x9;
923 difs = 0x1c;
924 eifs = 0x53;
925 } else {
926 slot_time = 0x14;
927 difs = 0x32;
928 eifs = 0x5b;
929 }
930 rtl818x_iowrite8(priv, &priv->map->SIFS, 0xa);
931 rtl818x_iowrite8(priv, &priv->map->SLOT, slot_time);
932 rtl818x_iowrite8(priv, &priv->map->DIFS, difs);
933
934 /*
935 * BRSR+1 on 8187B is in fact EIFS register
936 * Value in units of 4 us
937 */
938 rtl818x_iowrite8(priv, (u8 *)&priv->map->BRSR + 1, eifs);
939
940 /*
941 * For 8187B, CARRIER_SENSE_COUNTER is in fact ack timeout
942 * register. In units of 4 us like eifs register
943 * ack_timeout = ack duration + plcp + difs + preamble
944 */
945 ack_timeout = 112 + 48 + difs;
946 if (use_short_preamble)
947 ack_timeout += 72;
948 else
949 ack_timeout += 144;
950 rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER,
951 DIV_ROUND_UP(ack_timeout, 4));
952 } else {
953 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
954 if (use_short_slot) {
955 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
956 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
957 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
958 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
959 } else {
960 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
961 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
962 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
963 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
964 }
965 }
966}
967
968static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
969 struct ieee80211_vif *vif,
970 struct ieee80211_bss_conf *info,
971 u32 changed)
972{
973 struct rtl8187_priv *priv = dev->priv;
974
975 if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
976 rtl8187_conf_erp(priv, info->use_short_slot,
977 info->use_short_preamble);
978}
979
980static void rtl8187_configure_filter(struct ieee80211_hw *dev,
981 unsigned int changed_flags,
982 unsigned int *total_flags,
983 int mc_count, struct dev_addr_list *mclist)
984{
985 struct rtl8187_priv *priv = dev->priv;
986
987 if (changed_flags & FIF_FCSFAIL)
988 priv->rx_conf ^= RTL818X_RX_CONF_FCS;
989 if (changed_flags & FIF_CONTROL)
990 priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
991 if (changed_flags & FIF_OTHER_BSS)
992 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
993 if (*total_flags & FIF_ALLMULTI || mc_count > 0)
994 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
995 else
996 priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
997
998 *total_flags = 0;
999
1000 if (priv->rx_conf & RTL818X_RX_CONF_FCS)
1001 *total_flags |= FIF_FCSFAIL;
1002 if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
1003 *total_flags |= FIF_CONTROL;
1004 if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
1005 *total_flags |= FIF_OTHER_BSS;
1006 if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
1007 *total_flags |= FIF_ALLMULTI;
1008
1009 rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
1010}
1011
1012static const struct ieee80211_ops rtl8187_ops = {
1013 .tx = rtl8187_tx,
1014 .start = rtl8187_start,
1015 .stop = rtl8187_stop,
1016 .add_interface = rtl8187_add_interface,
1017 .remove_interface = rtl8187_remove_interface,
1018 .config = rtl8187_config,
1019 .config_interface = rtl8187_config_interface,
1020 .bss_info_changed = rtl8187_bss_info_changed,
1021 .configure_filter = rtl8187_configure_filter,
1022};
1023
1024static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
1025{
1026 struct ieee80211_hw *dev = eeprom->data;
1027 struct rtl8187_priv *priv = dev->priv;
1028 u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
1029
1030 eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
1031 eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
1032 eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
1033 eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
1034}
1035
1036static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom)
1037{
1038 struct ieee80211_hw *dev = eeprom->data;
1039 struct rtl8187_priv *priv = dev->priv;
1040 u8 reg = RTL818X_EEPROM_CMD_PROGRAM;
1041
1042 if (eeprom->reg_data_in)
1043 reg |= RTL818X_EEPROM_CMD_WRITE;
1044 if (eeprom->reg_data_out)
1045 reg |= RTL818X_EEPROM_CMD_READ;
1046 if (eeprom->reg_data_clock)
1047 reg |= RTL818X_EEPROM_CMD_CK;
1048 if (eeprom->reg_chip_select)
1049 reg |= RTL818X_EEPROM_CMD_CS;
1050
1051 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
1052 udelay(10);
1053}
1054
1055static int __devinit rtl8187_probe(struct usb_interface *intf,
1056 const struct usb_device_id *id)
1057{
1058 struct usb_device *udev = interface_to_usbdev(intf);
1059 struct ieee80211_hw *dev;
1060 struct rtl8187_priv *priv;
1061 struct eeprom_93cx6 eeprom;
1062 struct ieee80211_channel *channel;
1063 const char *chip_name;
1064 u16 txpwr, reg;
1065 int err, i;
1066
1067 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
1068 if (!dev) {
1069 printk(KERN_ERR "rtl8187: ieee80211 alloc failed\n");
1070 return -ENOMEM;
1071 }
1072
1073 priv = dev->priv;
1074 priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B);
1075
1076 SET_IEEE80211_DEV(dev, &intf->dev);
1077 usb_set_intfdata(intf, dev);
1078 priv->udev = udev;
1079
1080 usb_get_dev(udev);
1081
1082 skb_queue_head_init(&priv->rx_queue);
1083
1084 BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels));
1085 BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates));
1086
1087 memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
1088 memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
1089 priv->map = (struct rtl818x_csr *)0xFF00;
1090
1091 priv->band.band = IEEE80211_BAND_2GHZ;
1092 priv->band.channels = priv->channels;
1093 priv->band.n_channels = ARRAY_SIZE(rtl818x_channels);
1094 priv->band.bitrates = priv->rates;
1095 priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates);
1096 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
1097
1098
1099 priv->mode = NL80211_IFTYPE_MONITOR;
1100 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1101 IEEE80211_HW_RX_INCLUDES_FCS;
1102
1103 eeprom.data = dev;
1104 eeprom.register_read = rtl8187_eeprom_register_read;
1105 eeprom.register_write = rtl8187_eeprom_register_write;
1106 if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
1107 eeprom.width = PCI_EEPROM_WIDTH_93C66;
1108 else
1109 eeprom.width = PCI_EEPROM_WIDTH_93C46;
1110
1111 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1112 udelay(10);
1113
1114 eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR,
1115 (__le16 __force *)dev->wiphy->perm_addr, 3);
1116 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
1117 printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly "
1118 "generated MAC address\n");
1119 random_ether_addr(dev->wiphy->perm_addr);
1120 }
1121
1122 channel = priv->channels;
1123 for (i = 0; i < 3; i++) {
1124 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i,
1125 &txpwr);
1126 (*channel++).hw_value = txpwr & 0xFF;
1127 (*channel++).hw_value = txpwr >> 8;
1128 }
1129 for (i = 0; i < 2; i++) {
1130 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i,
1131 &txpwr);
1132 (*channel++).hw_value = txpwr & 0xFF;
1133 (*channel++).hw_value = txpwr >> 8;
1134 }
1135
1136 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
1137 &priv->txpwr_base);
1138
1139 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
1140 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
1141 /* 0 means asic B-cut, we should use SW 3 wire
1142 * bit-by-bit banging for radio. 1 means we can use
1143 * USB specific request to write radio registers */
1144 priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3;
1145 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
1146 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1147
1148 if (!priv->is_rtl8187b) {
1149 u32 reg32;
1150 reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF);
1151 reg32 &= RTL818X_TX_CONF_HWVER_MASK;
1152 switch (reg32) {
1153 case RTL818X_TX_CONF_R8187vD_B:
1154 /* Some RTL8187B devices have a USB ID of 0x8187
1155 * detect them here */
1156 chip_name = "RTL8187BvB(early)";
1157 priv->is_rtl8187b = 1;
1158 priv->hw_rev = RTL8187BvB;
1159 break;
1160 case RTL818X_TX_CONF_R8187vD:
1161 chip_name = "RTL8187vD";
1162 break;
1163 default:
1164 chip_name = "RTL8187vB (default)";
1165 }
1166 } else {
1167 /*
1168 * Force USB request to write radio registers for 8187B, Realtek
1169 * only uses it in their sources
1170 */
1171 /*if (priv->asic_rev == 0) {
1172 printk(KERN_WARNING "rtl8187: Forcing use of USB "
1173 "requests to write to radio registers\n");
1174 priv->asic_rev = 1;
1175 }*/
1176 switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) {
1177 case RTL818X_R8187B_B:
1178 chip_name = "RTL8187BvB";
1179 priv->hw_rev = RTL8187BvB;
1180 break;
1181 case RTL818X_R8187B_D:
1182 chip_name = "RTL8187BvD";
1183 priv->hw_rev = RTL8187BvD;
1184 break;
1185 case RTL818X_R8187B_E:
1186 chip_name = "RTL8187BvE";
1187 priv->hw_rev = RTL8187BvE;
1188 break;
1189 default:
1190 chip_name = "RTL8187BvB (default)";
1191 priv->hw_rev = RTL8187BvB;
1192 }
1193 }
1194
1195 if (!priv->is_rtl8187b) {
1196 for (i = 0; i < 2; i++) {
1197 eeprom_93cx6_read(&eeprom,
1198 RTL8187_EEPROM_TXPWR_CHAN_6 + i,
1199 &txpwr);
1200 (*channel++).hw_value = txpwr & 0xFF;
1201 (*channel++).hw_value = txpwr >> 8;
1202 }
1203 } else {
1204 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6,
1205 &txpwr);
1206 (*channel++).hw_value = txpwr & 0xFF;
1207
1208 eeprom_93cx6_read(&eeprom, 0x0A, &txpwr);
1209 (*channel++).hw_value = txpwr & 0xFF;
1210
1211 eeprom_93cx6_read(&eeprom, 0x1C, &txpwr);
1212 (*channel++).hw_value = txpwr & 0xFF;
1213 (*channel++).hw_value = txpwr >> 8;
1214 }
1215
1216 if (priv->is_rtl8187b) {
1217 printk(KERN_WARNING "rtl8187: 8187B chip detected. Support "
1218 "is EXPERIMENTAL, and could damage your\n"
1219 " hardware, use at your own risk\n");
1220 dev->flags |= IEEE80211_HW_SIGNAL_DBM;
1221 } else {
1222 dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC;
1223 dev->max_signal = 65;
1224 }
1225
1226 /*
1227 * XXX: Once this driver supports anything that requires
1228 * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
1229 */
1230 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1231
1232 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
1233 printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
1234 " info!\n");
1235
1236 priv->rf = rtl8187_detect_rf(dev);
1237 dev->extra_tx_headroom = (!priv->is_rtl8187b) ?
1238 sizeof(struct rtl8187_tx_hdr) :
1239 sizeof(struct rtl8187b_tx_hdr);
1240 if (!priv->is_rtl8187b)
1241 dev->queues = 1;
1242 else
1243 dev->queues = 4;
1244
1245 err = ieee80211_register_hw(dev);
1246 if (err) {
1247 printk(KERN_ERR "rtl8187: Cannot register device\n");
1248 goto err_free_dev;
1249 }
1250 mutex_init(&priv->conf_mutex);
1251
1252 printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s\n",
1253 wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
1254 chip_name, priv->asic_rev, priv->rf->name);
1255
1256 return 0;
1257
1258 err_free_dev:
1259 ieee80211_free_hw(dev);
1260 usb_set_intfdata(intf, NULL);
1261 usb_put_dev(udev);
1262 return err;
1263}
1264
1265static void __devexit rtl8187_disconnect(struct usb_interface *intf)
1266{
1267 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1268 struct rtl8187_priv *priv;
1269
1270 if (!dev)
1271 return;
1272
1273 ieee80211_unregister_hw(dev);
1274
1275 priv = dev->priv;
1276 usb_put_dev(interface_to_usbdev(intf));
1277 ieee80211_free_hw(dev);
1278}
1279
1280static struct usb_driver rtl8187_driver = {
1281 .name = KBUILD_MODNAME,
1282 .id_table = rtl8187_table,
1283 .probe = rtl8187_probe,
1284 .disconnect = __devexit_p(rtl8187_disconnect),
1285};
1286
1287static int __init rtl8187_init(void)
1288{
1289 return usb_register(&rtl8187_driver);
1290}
1291
1292static void __exit rtl8187_exit(void)
1293{
1294 usb_deregister(&rtl8187_driver);
1295}
1296
1297module_init(rtl8187_init);
1298module_exit(rtl8187_exit);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
new file mode 100644
index 000000000000..69030be62b36
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
@@ -0,0 +1,977 @@
1/*
2 * Radio tuning for RTL8225 on RTL8187
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * Magic delays, register offsets, and phy value tables below are
11 * taken from the original r8187 driver sources. Thanks to Realtek
12 * for their support!
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/init.h>
20#include <linux/usb.h>
21#include <net/mac80211.h>
22
23#include "rtl8187.h"
24#include "rtl8187_rtl8225.h"
25
26static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
27{
28 struct rtl8187_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);
42 udelay(10);
43
44 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
45 udelay(2);
46 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
47 udelay(10);
48
49 for (i = 15; i >= 0; i--) {
50 u16 reg = reg80 | (bangdata & (1 << i)) >> i;
51
52 if (i & 1)
53 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
54
55 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
56 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
57
58 if (!(i & 1))
59 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
60 }
61
62 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
63 udelay(10);
64
65 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
66 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
67}
68
69static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
70{
71 struct rtl8187_priv *priv = dev->priv;
72 u16 reg80, reg82, reg84;
73
74 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
75 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
76 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
77
78 reg80 &= ~(0x3 << 2);
79 reg84 &= ~0xF;
80
81 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x0007);
82 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x0007);
83 udelay(10);
84
85 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
86 udelay(2);
87
88 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
89 udelay(10);
90
91 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
92 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
93 addr, 0x8225, &data, sizeof(data), HZ / 2);
94
95 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
96 udelay(10);
97
98 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
99 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
100}
101
102static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
103{
104 struct rtl8187_priv *priv = dev->priv;
105
106 if (priv->asic_rev)
107 rtl8225_write_8051(dev, addr, cpu_to_le16(data));
108 else
109 rtl8225_write_bitbang(dev, addr, data);
110}
111
112static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
113{
114 struct rtl8187_priv *priv = dev->priv;
115 u16 reg80, reg82, reg84, out;
116 int i;
117
118 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
119 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
120 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
121
122 reg80 &= ~0xF;
123
124 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
125 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
126
127 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
128 udelay(4);
129 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
130 udelay(5);
131
132 for (i = 4; i >= 0; i--) {
133 u16 reg = reg80 | ((addr >> i) & 1);
134
135 if (!(i & 1)) {
136 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
137 udelay(1);
138 }
139
140 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
141 reg | (1 << 1));
142 udelay(2);
143 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
144 reg | (1 << 1));
145 udelay(2);
146
147 if (i & 1) {
148 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
149 udelay(1);
150 }
151 }
152
153 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
154 reg80 | (1 << 3) | (1 << 1));
155 udelay(2);
156 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
157 reg80 | (1 << 3));
158 udelay(2);
159 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
160 reg80 | (1 << 3));
161 udelay(2);
162
163 out = 0;
164 for (i = 11; i >= 0; i--) {
165 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
166 reg80 | (1 << 3));
167 udelay(1);
168 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
169 reg80 | (1 << 3) | (1 << 1));
170 udelay(2);
171 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
172 reg80 | (1 << 3) | (1 << 1));
173 udelay(2);
174 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
175 reg80 | (1 << 3) | (1 << 1));
176 udelay(2);
177
178 if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
179 out |= 1 << i;
180
181 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
182 reg80 | (1 << 3));
183 udelay(2);
184 }
185
186 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
187 reg80 | (1 << 3) | (1 << 2));
188 udelay(2);
189
190 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
191 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
192 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
193
194 return out;
195}
196
197static const u16 rtl8225bcd_rxgain[] = {
198 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
199 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
200 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
201 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
202 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
203 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
204 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
205 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
206 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
207 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
208 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
209 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
210};
211
212static const u8 rtl8225_agc[] = {
213 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
214 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
215 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
216 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
217 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
218 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
219 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
220 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
221 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
222 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
223 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
224 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
225 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
226 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
227 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
228 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
229};
230
231static const u8 rtl8225_gain[] = {
232 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
233 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
234 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
235 0x33, 0x80, 0x79, 0xc5, /* -78dBm */
236 0x43, 0x78, 0x76, 0xc5, /* -74dBm */
237 0x53, 0x60, 0x73, 0xc5, /* -70dBm */
238 0x63, 0x58, 0x70, 0xc5, /* -66dBm */
239};
240
241static const u8 rtl8225_threshold[] = {
242 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
243};
244
245static const u8 rtl8225_tx_gain_cck_ofdm[] = {
246 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
247};
248
249static const u8 rtl8225_tx_power_cck[] = {
250 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
251 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
252 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
253 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
254 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
255 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
256};
257
258static const u8 rtl8225_tx_power_cck_ch14[] = {
259 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
260 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
261 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
262 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
263 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
264 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
265};
266
267static const u8 rtl8225_tx_power_ofdm[] = {
268 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
269};
270
271static const u32 rtl8225_chan[] = {
272 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
273 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
274};
275
276static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
277{
278 struct rtl8187_priv *priv = dev->priv;
279 u8 cck_power, ofdm_power;
280 const u8 *tmp;
281 u32 reg;
282 int i;
283
284 cck_power = priv->channels[channel - 1].hw_value & 0xF;
285 ofdm_power = priv->channels[channel - 1].hw_value >> 4;
286
287 cck_power = min(cck_power, (u8)11);
288 ofdm_power = min(ofdm_power, (u8)35);
289
290 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
291 rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
292
293 if (channel == 14)
294 tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
295 else
296 tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
297
298 for (i = 0; i < 8; i++)
299 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
300
301 msleep(1); // FIXME: optional?
302
303 /* anaparam2 on */
304 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
305 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
306 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
307 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
308 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
309 RTL8187_RTL8225_ANAPARAM2_ON);
310 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
311 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
312 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
313
314 rtl8225_write_phy_ofdm(dev, 2, 0x42);
315 rtl8225_write_phy_ofdm(dev, 6, 0x00);
316 rtl8225_write_phy_ofdm(dev, 8, 0x00);
317
318 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
319 rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1);
320
321 tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
322
323 rtl8225_write_phy_ofdm(dev, 5, *tmp);
324 rtl8225_write_phy_ofdm(dev, 7, *tmp);
325
326 msleep(1);
327}
328
329static void rtl8225_rf_init(struct ieee80211_hw *dev)
330{
331 struct rtl8187_priv *priv = dev->priv;
332 int i;
333
334 rtl8225_write(dev, 0x0, 0x067);
335 rtl8225_write(dev, 0x1, 0xFE0);
336 rtl8225_write(dev, 0x2, 0x44D);
337 rtl8225_write(dev, 0x3, 0x441);
338 rtl8225_write(dev, 0x4, 0x486);
339 rtl8225_write(dev, 0x5, 0xBC0);
340 rtl8225_write(dev, 0x6, 0xAE6);
341 rtl8225_write(dev, 0x7, 0x82A);
342 rtl8225_write(dev, 0x8, 0x01F);
343 rtl8225_write(dev, 0x9, 0x334);
344 rtl8225_write(dev, 0xA, 0xFD4);
345 rtl8225_write(dev, 0xB, 0x391);
346 rtl8225_write(dev, 0xC, 0x050);
347 rtl8225_write(dev, 0xD, 0x6DB);
348 rtl8225_write(dev, 0xE, 0x029);
349 rtl8225_write(dev, 0xF, 0x914); msleep(100);
350
351 rtl8225_write(dev, 0x2, 0xC4D); msleep(200);
352 rtl8225_write(dev, 0x2, 0x44D); msleep(200);
353
354 if (!(rtl8225_read(dev, 6) & (1 << 7))) {
355 rtl8225_write(dev, 0x02, 0x0c4d);
356 msleep(200);
357 rtl8225_write(dev, 0x02, 0x044d);
358 msleep(100);
359 if (!(rtl8225_read(dev, 6) & (1 << 7)))
360 printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
361 wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
362 }
363
364 rtl8225_write(dev, 0x0, 0x127);
365
366 for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
367 rtl8225_write(dev, 0x1, i + 1);
368 rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
369 }
370
371 rtl8225_write(dev, 0x0, 0x027);
372 rtl8225_write(dev, 0x0, 0x22F);
373
374 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
375 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
376 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
377 }
378
379 msleep(1);
380
381 rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
382 rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
383 rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
384 rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
385 rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
386 rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
387 rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
388 rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
389 rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
390 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
391 rtl8225_write_phy_ofdm(dev, 0x0a, 0x09);
392 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
393 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
394 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
395 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
396 rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
397 rtl8225_write_phy_ofdm(dev, 0x11, 0x06);
398 rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
399 rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
400 rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
401 rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
402 rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
403 rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
404 rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
405 rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
406 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
407 rtl8225_write_phy_ofdm(dev, 0x1b, 0x76);
408 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
409 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
410 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
411 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
412 rtl8225_write_phy_ofdm(dev, 0x21, 0x27);
413 rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
414 rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
415 rtl8225_write_phy_ofdm(dev, 0x25, 0x20);
416 rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
417 rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
418
419 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
420 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
421 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
422 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
423
424 rtl8225_write_phy_cck(dev, 0x00, 0x98);
425 rtl8225_write_phy_cck(dev, 0x03, 0x20);
426 rtl8225_write_phy_cck(dev, 0x04, 0x7e);
427 rtl8225_write_phy_cck(dev, 0x05, 0x12);
428 rtl8225_write_phy_cck(dev, 0x06, 0xfc);
429 rtl8225_write_phy_cck(dev, 0x07, 0x78);
430 rtl8225_write_phy_cck(dev, 0x08, 0x2e);
431 rtl8225_write_phy_cck(dev, 0x10, 0x9b);
432 rtl8225_write_phy_cck(dev, 0x11, 0x88);
433 rtl8225_write_phy_cck(dev, 0x12, 0x47);
434 rtl8225_write_phy_cck(dev, 0x13, 0xd0);
435 rtl8225_write_phy_cck(dev, 0x19, 0x00);
436 rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
437 rtl8225_write_phy_cck(dev, 0x1b, 0x08);
438 rtl8225_write_phy_cck(dev, 0x40, 0x86);
439 rtl8225_write_phy_cck(dev, 0x41, 0x8d);
440 rtl8225_write_phy_cck(dev, 0x42, 0x15);
441 rtl8225_write_phy_cck(dev, 0x43, 0x18);
442 rtl8225_write_phy_cck(dev, 0x44, 0x1f);
443 rtl8225_write_phy_cck(dev, 0x45, 0x1e);
444 rtl8225_write_phy_cck(dev, 0x46, 0x1a);
445 rtl8225_write_phy_cck(dev, 0x47, 0x15);
446 rtl8225_write_phy_cck(dev, 0x48, 0x10);
447 rtl8225_write_phy_cck(dev, 0x49, 0x0a);
448 rtl8225_write_phy_cck(dev, 0x4a, 0x05);
449 rtl8225_write_phy_cck(dev, 0x4b, 0x02);
450 rtl8225_write_phy_cck(dev, 0x4c, 0x05);
451
452 rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D);
453
454 rtl8225_rf_set_tx_power(dev, 1);
455
456 /* RX antenna default to A */
457 rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */
458 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */
459
460 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
461 msleep(1);
462 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
463
464 /* set sensitivity */
465 rtl8225_write(dev, 0x0c, 0x50);
466 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
467 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
468 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
469 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
470 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
471}
472
473static const u8 rtl8225z2_agc[] = {
474 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f,
475 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
476 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f,
477 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
478 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
479 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
480 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28,
481 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
482 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30,
483 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
484 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
485};
486static const u8 rtl8225z2_ofdm[] = {
487 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
488 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
489 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
490 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
491 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
492 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
493 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
494 0x6d, 0x3c, 0xfb, 0x07
495};
496
497static const u8 rtl8225z2_tx_power_cck_ch14[] = {
498 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
499 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
500 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
501 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
502};
503
504static const u8 rtl8225z2_tx_power_cck[] = {
505 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
506 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
507 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
508 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
509};
510
511static const u8 rtl8225z2_tx_power_ofdm[] = {
512 0x42, 0x00, 0x40, 0x00, 0x40
513};
514
515static const u8 rtl8225z2_tx_gain_cck_ofdm[] = {
516 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
517 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
518 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
519 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
520 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
521 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
522};
523
524static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
525{
526 struct rtl8187_priv *priv = dev->priv;
527 u8 cck_power, ofdm_power;
528 const u8 *tmp;
529 u32 reg;
530 int i;
531
532 cck_power = priv->channels[channel - 1].hw_value & 0xF;
533 ofdm_power = priv->channels[channel - 1].hw_value >> 4;
534
535 cck_power = min(cck_power, (u8)15);
536 cck_power += priv->txpwr_base & 0xF;
537 cck_power = min(cck_power, (u8)35);
538
539 ofdm_power = min(ofdm_power, (u8)15);
540 ofdm_power += priv->txpwr_base >> 4;
541 ofdm_power = min(ofdm_power, (u8)35);
542
543 if (channel == 14)
544 tmp = rtl8225z2_tx_power_cck_ch14;
545 else
546 tmp = rtl8225z2_tx_power_cck;
547
548 for (i = 0; i < 8; i++)
549 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
550
551 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
552 rtl8225z2_tx_gain_cck_ofdm[cck_power]);
553 msleep(1);
554
555 /* anaparam2 on */
556 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
557 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
558 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
559 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
560 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
561 RTL8187_RTL8225_ANAPARAM2_ON);
562 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
563 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
564 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
565
566 rtl8225_write_phy_ofdm(dev, 2, 0x42);
567 rtl8225_write_phy_ofdm(dev, 5, 0x00);
568 rtl8225_write_phy_ofdm(dev, 6, 0x40);
569 rtl8225_write_phy_ofdm(dev, 7, 0x00);
570 rtl8225_write_phy_ofdm(dev, 8, 0x40);
571
572 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
573 rtl8225z2_tx_gain_cck_ofdm[ofdm_power]);
574 msleep(1);
575}
576
577static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
578{
579 struct rtl8187_priv *priv = dev->priv;
580 u8 cck_power, ofdm_power;
581 const u8 *tmp;
582 int i;
583
584 cck_power = priv->channels[channel - 1].hw_value & 0xF;
585 ofdm_power = priv->channels[channel - 1].hw_value >> 4;
586
587 if (cck_power > 15)
588 cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22;
589 else
590 cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
591 cck_power += priv->txpwr_base & 0xF;
592 cck_power = min(cck_power, (u8)35);
593
594 if (ofdm_power > 15)
595 ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25;
596 else
597 ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10;
598 ofdm_power += (priv->txpwr_base >> 4) & 0xF;
599 ofdm_power = min(ofdm_power, (u8)35);
600
601 if (channel == 14)
602 tmp = rtl8225z2_tx_power_cck_ch14;
603 else
604 tmp = rtl8225z2_tx_power_cck;
605
606 if (priv->hw_rev == RTL8187BvB) {
607 if (cck_power <= 6)
608 ; /* do nothing */
609 else if (cck_power <= 11)
610 tmp += 8;
611 else
612 tmp += 16;
613 } else {
614 if (cck_power <= 5)
615 ; /* do nothing */
616 else if (cck_power <= 11)
617 tmp += 8;
618 else if (cck_power <= 17)
619 tmp += 16;
620 else
621 tmp += 24;
622 }
623
624 for (i = 0; i < 8; i++)
625 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
626
627 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
628 rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1);
629 msleep(1);
630
631 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
632 rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1);
633 if (priv->hw_rev == RTL8187BvB) {
634 if (ofdm_power <= 11) {
635 rtl8225_write_phy_ofdm(dev, 0x87, 0x60);
636 rtl8225_write_phy_ofdm(dev, 0x89, 0x60);
637 } else {
638 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
639 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
640 }
641 } else {
642 if (ofdm_power <= 11) {
643 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
644 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
645 } else if (ofdm_power <= 17) {
646 rtl8225_write_phy_ofdm(dev, 0x87, 0x54);
647 rtl8225_write_phy_ofdm(dev, 0x89, 0x54);
648 } else {
649 rtl8225_write_phy_ofdm(dev, 0x87, 0x50);
650 rtl8225_write_phy_ofdm(dev, 0x89, 0x50);
651 }
652 }
653 msleep(1);
654}
655
656static const u16 rtl8225z2_rxgain[] = {
657 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
658 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
659 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
660 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
661 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
662 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
663 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
664 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
665 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
666 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
667 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
668 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
669};
670
671static const u8 rtl8225z2_gain_bg[] = {
672 0x23, 0x15, 0xa5, /* -82-1dBm */
673 0x23, 0x15, 0xb5, /* -82-2dBm */
674 0x23, 0x15, 0xc5, /* -82-3dBm */
675 0x33, 0x15, 0xc5, /* -78dBm */
676 0x43, 0x15, 0xc5, /* -74dBm */
677 0x53, 0x15, 0xc5, /* -70dBm */
678 0x63, 0x15, 0xc5 /* -66dBm */
679};
680
681static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
682{
683 struct rtl8187_priv *priv = dev->priv;
684 int i;
685
686 rtl8225_write(dev, 0x0, 0x2BF);
687 rtl8225_write(dev, 0x1, 0xEE0);
688 rtl8225_write(dev, 0x2, 0x44D);
689 rtl8225_write(dev, 0x3, 0x441);
690 rtl8225_write(dev, 0x4, 0x8C3);
691 rtl8225_write(dev, 0x5, 0xC72);
692 rtl8225_write(dev, 0x6, 0x0E6);
693 rtl8225_write(dev, 0x7, 0x82A);
694 rtl8225_write(dev, 0x8, 0x03F);
695 rtl8225_write(dev, 0x9, 0x335);
696 rtl8225_write(dev, 0xa, 0x9D4);
697 rtl8225_write(dev, 0xb, 0x7BB);
698 rtl8225_write(dev, 0xc, 0x850);
699 rtl8225_write(dev, 0xd, 0xCDF);
700 rtl8225_write(dev, 0xe, 0x02B);
701 rtl8225_write(dev, 0xf, 0x114);
702 msleep(100);
703
704 rtl8225_write(dev, 0x0, 0x1B7);
705
706 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
707 rtl8225_write(dev, 0x1, i + 1);
708 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
709 }
710
711 rtl8225_write(dev, 0x3, 0x080);
712 rtl8225_write(dev, 0x5, 0x004);
713 rtl8225_write(dev, 0x0, 0x0B7);
714 rtl8225_write(dev, 0x2, 0xc4D);
715
716 msleep(200);
717 rtl8225_write(dev, 0x2, 0x44D);
718 msleep(100);
719
720 if (!(rtl8225_read(dev, 6) & (1 << 7))) {
721 rtl8225_write(dev, 0x02, 0x0C4D);
722 msleep(200);
723 rtl8225_write(dev, 0x02, 0x044D);
724 msleep(100);
725 if (!(rtl8225_read(dev, 6) & (1 << 7)))
726 printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
727 wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
728 }
729
730 msleep(200);
731
732 rtl8225_write(dev, 0x0, 0x2BF);
733
734 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
735 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
736 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
737 }
738
739 msleep(1);
740
741 rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
742 rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
743 rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
744 rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
745 rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
746 rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
747 rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
748 rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
749 rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
750 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
751 rtl8225_write_phy_ofdm(dev, 0x0a, 0x08);
752 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
753 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
754 rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
755 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
756 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
757 rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
758 rtl8225_write_phy_ofdm(dev, 0x11, 0x07);
759 rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
760 rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
761 rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
762 rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
763 rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
764 rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
765 rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
766 rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
767 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
768 rtl8225_write_phy_ofdm(dev, 0x1b, 0x15);
769 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
770 rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5);
771 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
772 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
773 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
774 rtl8225_write_phy_ofdm(dev, 0x21, 0x17);
775 rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
776 rtl8225_write_phy_ofdm(dev, 0x23, 0x80);
777 rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
778 rtl8225_write_phy_ofdm(dev, 0x25, 0x00);
779 rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
780 rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
781
782 rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
783 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
784 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
785 rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
786
787 rtl8225_write_phy_cck(dev, 0x00, 0x98);
788 rtl8225_write_phy_cck(dev, 0x03, 0x20);
789 rtl8225_write_phy_cck(dev, 0x04, 0x7e);
790 rtl8225_write_phy_cck(dev, 0x05, 0x12);
791 rtl8225_write_phy_cck(dev, 0x06, 0xfc);
792 rtl8225_write_phy_cck(dev, 0x07, 0x78);
793 rtl8225_write_phy_cck(dev, 0x08, 0x2e);
794 rtl8225_write_phy_cck(dev, 0x10, 0x9b);
795 rtl8225_write_phy_cck(dev, 0x11, 0x88);
796 rtl8225_write_phy_cck(dev, 0x12, 0x47);
797 rtl8225_write_phy_cck(dev, 0x13, 0xd0);
798 rtl8225_write_phy_cck(dev, 0x19, 0x00);
799 rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
800 rtl8225_write_phy_cck(dev, 0x1b, 0x08);
801 rtl8225_write_phy_cck(dev, 0x40, 0x86);
802 rtl8225_write_phy_cck(dev, 0x41, 0x8d);
803 rtl8225_write_phy_cck(dev, 0x42, 0x15);
804 rtl8225_write_phy_cck(dev, 0x43, 0x18);
805 rtl8225_write_phy_cck(dev, 0x44, 0x36);
806 rtl8225_write_phy_cck(dev, 0x45, 0x35);
807 rtl8225_write_phy_cck(dev, 0x46, 0x2e);
808 rtl8225_write_phy_cck(dev, 0x47, 0x25);
809 rtl8225_write_phy_cck(dev, 0x48, 0x1c);
810 rtl8225_write_phy_cck(dev, 0x49, 0x12);
811 rtl8225_write_phy_cck(dev, 0x4a, 0x09);
812 rtl8225_write_phy_cck(dev, 0x4b, 0x04);
813 rtl8225_write_phy_cck(dev, 0x4c, 0x05);
814
815 rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
816
817 rtl8225z2_rf_set_tx_power(dev, 1);
818
819 /* RX antenna default to A */
820 rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */
821 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */
822
823 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
824 msleep(1);
825 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
826}
827
828static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
829{
830 struct rtl8187_priv *priv = dev->priv;
831 int i;
832
833 rtl8225_write(dev, 0x0, 0x0B7);
834 rtl8225_write(dev, 0x1, 0xEE0);
835 rtl8225_write(dev, 0x2, 0x44D);
836 rtl8225_write(dev, 0x3, 0x441);
837 rtl8225_write(dev, 0x4, 0x8C3);
838 rtl8225_write(dev, 0x5, 0xC72);
839 rtl8225_write(dev, 0x6, 0x0E6);
840 rtl8225_write(dev, 0x7, 0x82A);
841 rtl8225_write(dev, 0x8, 0x03F);
842 rtl8225_write(dev, 0x9, 0x335);
843 rtl8225_write(dev, 0xa, 0x9D4);
844 rtl8225_write(dev, 0xb, 0x7BB);
845 rtl8225_write(dev, 0xc, 0x850);
846 rtl8225_write(dev, 0xd, 0xCDF);
847 rtl8225_write(dev, 0xe, 0x02B);
848 rtl8225_write(dev, 0xf, 0x114);
849
850 rtl8225_write(dev, 0x0, 0x1B7);
851
852 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
853 rtl8225_write(dev, 0x1, i + 1);
854 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
855 }
856
857 rtl8225_write(dev, 0x3, 0x080);
858 rtl8225_write(dev, 0x5, 0x004);
859 rtl8225_write(dev, 0x0, 0x0B7);
860
861 rtl8225_write(dev, 0x2, 0xC4D);
862
863 rtl8225_write(dev, 0x2, 0x44D);
864 rtl8225_write(dev, 0x0, 0x2BF);
865
866 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
867 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
868 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
869
870 rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
871 for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
872 rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]);
873 rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i);
874 rtl8225_write_phy_ofdm(dev, 0xE, 0);
875 }
876 rtl8225_write_phy_ofdm(dev, 0x80, 0x10);
877
878 for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
879 rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
880
881 rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
882 rtl818x_iowrite32(priv, (__le32 *)0xFFF4, (7 << 12) | (3 << 8) | 28);
883 rtl818x_iowrite32(priv, (__le32 *)0xFFF8, (7 << 12) | (3 << 8) | 28);
884 rtl818x_iowrite32(priv, (__le32 *)0xFFFC, (7 << 12) | (3 << 8) | 28);
885 rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
886
887 rtl8225_write_phy_ofdm(dev, 0x97, 0x46);
888 rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6);
889 rtl8225_write_phy_ofdm(dev, 0x85, 0xfc);
890 rtl8225_write_phy_cck(dev, 0xc1, 0x88);
891}
892
893static void rtl8225_rf_stop(struct ieee80211_hw *dev)
894{
895 u8 reg;
896 struct rtl8187_priv *priv = dev->priv;
897
898 rtl8225_write(dev, 0x4, 0x1f);
899
900 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
901 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
902 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
903 if (!priv->is_rtl8187b) {
904 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
905 RTL8187_RTL8225_ANAPARAM2_OFF);
906 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
907 RTL8187_RTL8225_ANAPARAM_OFF);
908 } else {
909 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
910 RTL8187B_RTL8225_ANAPARAM2_OFF);
911 rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
912 RTL8187B_RTL8225_ANAPARAM_OFF);
913 rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
914 RTL8187B_RTL8225_ANAPARAM3_OFF);
915 }
916 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
917 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
918}
919
920static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
921 struct ieee80211_conf *conf)
922{
923 struct rtl8187_priv *priv = dev->priv;
924 int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
925
926 if (priv->rf->init == rtl8225_rf_init)
927 rtl8225_rf_set_tx_power(dev, chan);
928 else if (priv->rf->init == rtl8225z2_rf_init)
929 rtl8225z2_rf_set_tx_power(dev, chan);
930 else
931 rtl8225z2_b_rf_set_tx_power(dev, chan);
932
933 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
934 msleep(10);
935}
936
937static const struct rtl818x_rf_ops rtl8225_ops = {
938 .name = "rtl8225",
939 .init = rtl8225_rf_init,
940 .stop = rtl8225_rf_stop,
941 .set_chan = rtl8225_rf_set_channel
942};
943
944static const struct rtl818x_rf_ops rtl8225z2_ops = {
945 .name = "rtl8225z2",
946 .init = rtl8225z2_rf_init,
947 .stop = rtl8225_rf_stop,
948 .set_chan = rtl8225_rf_set_channel
949};
950
951static const struct rtl818x_rf_ops rtl8225z2_b_ops = {
952 .name = "rtl8225z2",
953 .init = rtl8225z2_b_rf_init,
954 .stop = rtl8225_rf_stop,
955 .set_chan = rtl8225_rf_set_channel
956};
957
958const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
959{
960 u16 reg8, reg9;
961 struct rtl8187_priv *priv = dev->priv;
962
963 if (!priv->is_rtl8187b) {
964 rtl8225_write(dev, 0, 0x1B7);
965
966 reg8 = rtl8225_read(dev, 8);
967 reg9 = rtl8225_read(dev, 9);
968
969 rtl8225_write(dev, 0, 0x0B7);
970
971 if (reg8 != 0x588 || reg9 != 0x700)
972 return &rtl8225_ops;
973
974 return &rtl8225z2_ops;
975 } else
976 return &rtl8225z2_b_ops;
977}
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h
new file mode 100644
index 000000000000..20c5b6ead0f6
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h
@@ -0,0 +1,44 @@
1/*
2 * Radio tuning definitions for RTL8225 on RTL8187
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef RTL8187_RTL8225_H
16#define RTL8187_RTL8225_H
17
18#define RTL8187_RTL8225_ANAPARAM_ON 0xa0000a59
19#define RTL8187_RTL8225_ANAPARAM2_ON 0x860c7312
20#define RTL8187_RTL8225_ANAPARAM_OFF 0xa00beb59
21#define RTL8187_RTL8225_ANAPARAM2_OFF 0x840dec11
22
23#define RTL8187B_RTL8225_ANAPARAM_ON 0x45090658
24#define RTL8187B_RTL8225_ANAPARAM2_ON 0x727f3f52
25#define RTL8187B_RTL8225_ANAPARAM3_ON 0x00
26#define RTL8187B_RTL8225_ANAPARAM_OFF 0x55480658
27#define RTL8187B_RTL8225_ANAPARAM2_OFF 0x72003f50
28#define RTL8187B_RTL8225_ANAPARAM3_OFF 0x00
29
30const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *);
31
32static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
33 u8 addr, u32 data)
34{
35 rtl8187_write_phy(dev, addr, data);
36}
37
38static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev,
39 u8 addr, u32 data)
40{
41 rtl8187_write_phy(dev, addr, data | 0x10000);
42}
43
44#endif /* RTL8187_RTL8225_H */
diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h
new file mode 100644
index 000000000000..3538b15211b1
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl818x.h
@@ -0,0 +1,231 @@
1/*
2 * Definitions for RTL818x hardware
3 *
4 * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef RTL818X_H
16#define RTL818X_H
17
18struct rtl818x_csr {
19 u8 MAC[6];
20 u8 reserved_0[2];
21 __le32 MAR[2];
22 u8 RX_FIFO_COUNT;
23 u8 reserved_1;
24 u8 TX_FIFO_COUNT;
25 u8 BQREQ;
26 u8 reserved_2[4];
27 __le32 TSFT[2];
28 __le32 TLPDA;
29 __le32 TNPDA;
30 __le32 THPDA;
31 __le16 BRSR;
32 u8 BSSID[6];
33 u8 RESP_RATE;
34 u8 EIFS;
35 u8 reserved_3[1];
36 u8 CMD;
37#define RTL818X_CMD_TX_ENABLE (1 << 2)
38#define RTL818X_CMD_RX_ENABLE (1 << 3)
39#define RTL818X_CMD_RESET (1 << 4)
40 u8 reserved_4[4];
41 __le16 INT_MASK;
42 __le16 INT_STATUS;
43#define RTL818X_INT_RX_OK (1 << 0)
44#define RTL818X_INT_RX_ERR (1 << 1)
45#define RTL818X_INT_TXL_OK (1 << 2)
46#define RTL818X_INT_TXL_ERR (1 << 3)
47#define RTL818X_INT_RX_DU (1 << 4)
48#define RTL818X_INT_RX_FO (1 << 5)
49#define RTL818X_INT_TXN_OK (1 << 6)
50#define RTL818X_INT_TXN_ERR (1 << 7)
51#define RTL818X_INT_TXH_OK (1 << 8)
52#define RTL818X_INT_TXH_ERR (1 << 9)
53#define RTL818X_INT_TXB_OK (1 << 10)
54#define RTL818X_INT_TXB_ERR (1 << 11)
55#define RTL818X_INT_ATIM (1 << 12)
56#define RTL818X_INT_BEACON (1 << 13)
57#define RTL818X_INT_TIME_OUT (1 << 14)
58#define RTL818X_INT_TX_FO (1 << 15)
59 __le32 TX_CONF;
60#define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17)
61#define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17)
62#define RTL818X_TX_CONF_NO_ICV (1 << 19)
63#define RTL818X_TX_CONF_DISCW (1 << 20)
64#define RTL818X_TX_CONF_SAT_HWPLCP (1 << 24)
65#define RTL818X_TX_CONF_R8180_ABCD (2 << 25)
66#define RTL818X_TX_CONF_R8180_F (3 << 25)
67#define RTL818X_TX_CONF_R8185_ABC (4 << 25)
68#define RTL818X_TX_CONF_R8185_D (5 << 25)
69#define RTL818X_TX_CONF_R8187vD (5 << 25)
70#define RTL818X_TX_CONF_R8187vD_B (6 << 25)
71#define RTL818X_TX_CONF_HWVER_MASK (7 << 25)
72#define RTL818X_TX_CONF_DISREQQSIZE (1 << 28)
73#define RTL818X_TX_CONF_PROBE_DTS (1 << 29)
74#define RTL818X_TX_CONF_HW_SEQNUM (1 << 30)
75#define RTL818X_TX_CONF_CW_MIN (1 << 31)
76 __le32 RX_CONF;
77#define RTL818X_RX_CONF_MONITOR (1 << 0)
78#define RTL818X_RX_CONF_NICMAC (1 << 1)
79#define RTL818X_RX_CONF_MULTICAST (1 << 2)
80#define RTL818X_RX_CONF_BROADCAST (1 << 3)
81#define RTL818X_RX_CONF_FCS (1 << 5)
82#define RTL818X_RX_CONF_DATA (1 << 18)
83#define RTL818X_RX_CONF_CTRL (1 << 19)
84#define RTL818X_RX_CONF_MGMT (1 << 20)
85#define RTL818X_RX_CONF_ADDR3 (1 << 21)
86#define RTL818X_RX_CONF_PM (1 << 22)
87#define RTL818X_RX_CONF_BSSID (1 << 23)
88#define RTL818X_RX_CONF_RX_AUTORESETPHY (1 << 28)
89#define RTL818X_RX_CONF_CSDM1 (1 << 29)
90#define RTL818X_RX_CONF_CSDM2 (1 << 30)
91#define RTL818X_RX_CONF_ONLYERLPKT (1 << 31)
92 __le32 INT_TIMEOUT;
93 __le32 TBDA;
94 u8 EEPROM_CMD;
95#define RTL818X_EEPROM_CMD_READ (1 << 0)
96#define RTL818X_EEPROM_CMD_WRITE (1 << 1)
97#define RTL818X_EEPROM_CMD_CK (1 << 2)
98#define RTL818X_EEPROM_CMD_CS (1 << 3)
99#define RTL818X_EEPROM_CMD_NORMAL (0 << 6)
100#define RTL818X_EEPROM_CMD_LOAD (1 << 6)
101#define RTL818X_EEPROM_CMD_PROGRAM (2 << 6)
102#define RTL818X_EEPROM_CMD_CONFIG (3 << 6)
103 u8 CONFIG0;
104 u8 CONFIG1;
105 u8 CONFIG2;
106#define RTL818X_CONFIG2_ANTENNA_DIV (1 << 6)
107 __le32 ANAPARAM;
108 u8 MSR;
109#define RTL818X_MSR_NO_LINK (0 << 2)
110#define RTL818X_MSR_ADHOC (1 << 2)
111#define RTL818X_MSR_INFRA (2 << 2)
112#define RTL818X_MSR_MASTER (3 << 2)
113#define RTL818X_MSR_ENEDCA (4 << 2)
114 u8 CONFIG3;
115#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6)
116#define RTL818X_CONFIG3_GNT_SELECT (1 << 7)
117 u8 CONFIG4;
118#define RTL818X_CONFIG4_POWEROFF (1 << 6)
119#define RTL818X_CONFIG4_VCOOFF (1 << 7)
120 u8 TESTR;
121 u8 reserved_9[2];
122 u8 PGSELECT;
123 u8 SECURITY;
124 __le32 ANAPARAM2;
125 u8 reserved_10[12];
126 __le16 BEACON_INTERVAL;
127 __le16 ATIM_WND;
128 __le16 BEACON_INTERVAL_TIME;
129 __le16 ATIMTR_INTERVAL;
130 u8 PHY_DELAY;
131 u8 CARRIER_SENSE_COUNTER;
132 u8 reserved_11[2];
133 u8 PHY[4];
134 __le16 RFPinsOutput;
135 __le16 RFPinsEnable;
136 __le16 RFPinsSelect;
137 __le16 RFPinsInput;
138 __le32 RF_PARA;
139 __le32 RF_TIMING;
140 u8 GP_ENABLE;
141 u8 GPIO;
142 u8 reserved_12[2];
143 __le32 HSSI_PARA;
144 u8 reserved_13[4];
145 u8 TX_AGC_CTL;
146#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT (1 << 0)
147#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT (1 << 1)
148#define RTL818X_TX_AGC_CTL_FEEDBACK_ANT (1 << 2)
149 u8 TX_GAIN_CCK;
150 u8 TX_GAIN_OFDM;
151 u8 TX_ANTENNA;
152 u8 reserved_14[16];
153 u8 WPA_CONF;
154 u8 reserved_15[3];
155 u8 SIFS;
156 u8 DIFS;
157 u8 SLOT;
158 u8 reserved_16[5];
159 u8 CW_CONF;
160#define RTL818X_CW_CONF_PERPACKET_CW_SHIFT (1 << 0)
161#define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT (1 << 1)
162 u8 CW_VAL;
163 u8 RATE_FALLBACK;
164#define RTL818X_RATE_FALLBACK_ENABLE (1 << 7)
165 u8 ACM_CONTROL;
166 u8 reserved_17[24];
167 u8 CONFIG5;
168 u8 TX_DMA_POLLING;
169 u8 reserved_18[2];
170 __le16 CWR;
171 u8 RETRY_CTR;
172 u8 reserved_19[3];
173 __le16 INT_MIG;
174/* RTL818X_R8187B_*: magic numbers from ioregisters */
175#define RTL818X_R8187B_B 0
176#define RTL818X_R8187B_D 1
177#define RTL818X_R8187B_E 2
178 __le32 RDSAR;
179 __le16 TID_AC_MAP;
180 u8 reserved_20[4];
181 u8 ANAPARAM3;
182 u8 reserved_21[5];
183 __le16 FEMR;
184 u8 reserved_22[4];
185 __le16 TALLY_CNT;
186 u8 TALLY_SEL;
187} __attribute__((packed));
188
189struct rtl818x_rf_ops {
190 char *name;
191 void (*init)(struct ieee80211_hw *);
192 void (*stop)(struct ieee80211_hw *);
193 void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
194};
195
196/* Tx/Rx flags are common between RTL818X chips */
197
198enum rtl818x_tx_desc_flags {
199 RTL818X_TX_DESC_FLAG_NO_ENC = (1 << 15),
200 RTL818X_TX_DESC_FLAG_TX_OK = (1 << 15),
201 RTL818X_TX_DESC_FLAG_SPLCP = (1 << 16),
202 RTL818X_TX_DESC_FLAG_RX_UNDER = (1 << 16),
203 RTL818X_TX_DESC_FLAG_MOREFRAG = (1 << 17),
204 RTL818X_TX_DESC_FLAG_CTS = (1 << 18),
205 RTL818X_TX_DESC_FLAG_RTS = (1 << 23),
206 RTL818X_TX_DESC_FLAG_LS = (1 << 28),
207 RTL818X_TX_DESC_FLAG_FS = (1 << 29),
208 RTL818X_TX_DESC_FLAG_DMA = (1 << 30),
209 RTL818X_TX_DESC_FLAG_OWN = (1 << 31)
210};
211
212enum rtl818x_rx_desc_flags {
213 RTL818X_RX_DESC_FLAG_ICV_ERR = (1 << 12),
214 RTL818X_RX_DESC_FLAG_CRC32_ERR = (1 << 13),
215 RTL818X_RX_DESC_FLAG_PM = (1 << 14),
216 RTL818X_RX_DESC_FLAG_RX_ERR = (1 << 15),
217 RTL818X_RX_DESC_FLAG_BCAST = (1 << 16),
218 RTL818X_RX_DESC_FLAG_PAM = (1 << 17),
219 RTL818X_RX_DESC_FLAG_MCAST = (1 << 18),
220 RTL818X_RX_DESC_FLAG_QOS = (1 << 19), /* RTL8187(B) only */
221 RTL818X_RX_DESC_FLAG_TRSW = (1 << 24), /* RTL8187(B) only */
222 RTL818X_RX_DESC_FLAG_SPLCP = (1 << 25),
223 RTL818X_RX_DESC_FLAG_FOF = (1 << 26),
224 RTL818X_RX_DESC_FLAG_DMA_FAIL = (1 << 27),
225 RTL818X_RX_DESC_FLAG_LS = (1 << 28),
226 RTL818X_RX_DESC_FLAG_FS = (1 << 29),
227 RTL818X_RX_DESC_FLAG_EOR = (1 << 30),
228 RTL818X_RX_DESC_FLAG_OWN = (1 << 31)
229};
230
231#endif /* RTL818X_H */