aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl818x/rtl8187
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-12-20 15:16:53 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-22 13:45:32 -0500
commit3cfeb0c33f5cbcc6dde371392877ef3101b8f805 (patch)
tree017c47fa83ee62682e20d7ff90de1e4c17331194 /drivers/net/wireless/rtl818x/rtl8187
parent3d986b25b5faa50ba6afd94f60f270b6c3061e5e (diff)
rtl818x: move rtl8180 and rtl8187 to separate subdirectories
These drivers share one header file, but nothing else. Worse, both drivers use the rtl8225 part with different register settings. The results has been some ugly naming -- let's simplify that. Signed-off-by: John W. Linville <linville@tuxdriver.com> Acked-by: Hin-Tak Leung <htl10@users.sourceforge.net> Acked-by: Larry Finger <Larry.Finger@lwfinger.net> Acked-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
Diffstat (limited to 'drivers/net/wireless/rtl818x/rtl8187')
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/Makefile5
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c1591
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/leds.c245
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/leds.h59
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rfkill.c64
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rfkill.h8
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8187.h271
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8225.c961
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8225.h44
9 files changed, 3248 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8187/Makefile b/drivers/net/wireless/rtl818x/rtl8187/Makefile
new file mode 100644
index 000000000000..7b6299268ecf
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/Makefile
@@ -0,0 +1,5 @@
1rtl8187-objs := dev.o rtl8225.o leds.o rfkill.o
2
3obj-$(CONFIG_RTL8187) += rtl8187.o
4
5ccflags-y += -Idrivers/net/wireless/rtl818x
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
new file mode 100644
index 000000000000..6b82cac37ee3
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -0,0 +1,1591 @@
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 * The driver was extended to the RTL8187B in 2008 by:
11 * Herton Ronaldo Krzesinski <herton@mandriva.com.br>
12 * Hin-Tak Leung <htl10@users.sourceforge.net>
13 * Larry Finger <Larry.Finger@lwfinger.net>
14 *
15 * Magic delays and register offsets below are taken from the original
16 * r8187 driver sources. Thanks to Realtek for their support!
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/init.h>
24#include <linux/usb.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/etherdevice.h>
28#include <linux/eeprom_93cx6.h>
29#include <net/mac80211.h>
30
31#include "rtl8187.h"
32#include "rtl8225.h"
33#ifdef CONFIG_RTL8187_LEDS
34#include "leds.h"
35#endif
36#include "rfkill.h"
37
38MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
39MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
40MODULE_AUTHOR("Herton Ronaldo Krzesinski <herton@mandriva.com.br>");
41MODULE_AUTHOR("Hin-Tak Leung <htl10@users.sourceforge.net>");
42MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
43MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
44MODULE_LICENSE("GPL");
45
46static struct usb_device_id rtl8187_table[] __devinitdata = {
47 /* Asus */
48 {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
49 /* Belkin */
50 {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B},
51 /* Realtek */
52 {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
53 {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
54 {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
55 {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
56 /* Surecom */
57 {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187},
58 /* Logitech */
59 {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187},
60 /* Netgear */
61 {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
62 {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
63 {USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B},
64 /* HP */
65 {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
66 /* Sitecom */
67 {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
68 {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
69 {USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B},
70 /* Sphairon Access Systems GmbH */
71 {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187},
72 /* Dick Smith Electronics */
73 {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187},
74 /* Abocom */
75 {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187},
76 /* Qcom */
77 {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187},
78 /* AirLive */
79 {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187},
80 /* Linksys */
81 {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B},
82 {}
83};
84
85MODULE_DEVICE_TABLE(usb, rtl8187_table);
86
87static const struct ieee80211_rate rtl818x_rates[] = {
88 { .bitrate = 10, .hw_value = 0, },
89 { .bitrate = 20, .hw_value = 1, },
90 { .bitrate = 55, .hw_value = 2, },
91 { .bitrate = 110, .hw_value = 3, },
92 { .bitrate = 60, .hw_value = 4, },
93 { .bitrate = 90, .hw_value = 5, },
94 { .bitrate = 120, .hw_value = 6, },
95 { .bitrate = 180, .hw_value = 7, },
96 { .bitrate = 240, .hw_value = 8, },
97 { .bitrate = 360, .hw_value = 9, },
98 { .bitrate = 480, .hw_value = 10, },
99 { .bitrate = 540, .hw_value = 11, },
100};
101
102static const struct ieee80211_channel rtl818x_channels[] = {
103 { .center_freq = 2412 },
104 { .center_freq = 2417 },
105 { .center_freq = 2422 },
106 { .center_freq = 2427 },
107 { .center_freq = 2432 },
108 { .center_freq = 2437 },
109 { .center_freq = 2442 },
110 { .center_freq = 2447 },
111 { .center_freq = 2452 },
112 { .center_freq = 2457 },
113 { .center_freq = 2462 },
114 { .center_freq = 2467 },
115 { .center_freq = 2472 },
116 { .center_freq = 2484 },
117};
118
119static void rtl8187_iowrite_async_cb(struct urb *urb)
120{
121 kfree(urb->context);
122}
123
124static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr,
125 void *data, u16 len)
126{
127 struct usb_ctrlrequest *dr;
128 struct urb *urb;
129 struct rtl8187_async_write_data {
130 u8 data[4];
131 struct usb_ctrlrequest dr;
132 } *buf;
133 int rc;
134
135 buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
136 if (!buf)
137 return;
138
139 urb = usb_alloc_urb(0, GFP_ATOMIC);
140 if (!urb) {
141 kfree(buf);
142 return;
143 }
144
145 dr = &buf->dr;
146
147 dr->bRequestType = RTL8187_REQT_WRITE;
148 dr->bRequest = RTL8187_REQ_SET_REG;
149 dr->wValue = addr;
150 dr->wIndex = 0;
151 dr->wLength = cpu_to_le16(len);
152
153 memcpy(buf, data, len);
154
155 usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0),
156 (unsigned char *)dr, buf, len,
157 rtl8187_iowrite_async_cb, buf);
158 usb_anchor_urb(urb, &priv->anchored);
159 rc = usb_submit_urb(urb, GFP_ATOMIC);
160 if (rc < 0) {
161 kfree(buf);
162 usb_unanchor_urb(urb);
163 }
164 usb_free_urb(urb);
165}
166
167static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv,
168 __le32 *addr, u32 val)
169{
170 __le32 buf = cpu_to_le32(val);
171
172 rtl8187_iowrite_async(priv, cpu_to_le16((unsigned long)addr),
173 &buf, sizeof(buf));
174}
175
176void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
177{
178 struct rtl8187_priv *priv = dev->priv;
179
180 data <<= 8;
181 data |= addr | 0x80;
182
183 rtl818x_iowrite8(priv, &priv->map->PHY[3], (data >> 24) & 0xFF);
184 rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF);
185 rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF);
186 rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF);
187}
188
189static void rtl8187_tx_cb(struct urb *urb)
190{
191 struct sk_buff *skb = (struct sk_buff *)urb->context;
192 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
193 struct ieee80211_hw *hw = info->rate_driver_data[0];
194 struct rtl8187_priv *priv = hw->priv;
195
196 skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
197 sizeof(struct rtl8187_tx_hdr));
198 ieee80211_tx_info_clear_status(info);
199
200 if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
201 if (priv->is_rtl8187b) {
202 skb_queue_tail(&priv->b_tx_status.queue, skb);
203
204 /* queue is "full", discard last items */
205 while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
206 struct sk_buff *old_skb;
207
208 dev_dbg(&priv->udev->dev,
209 "transmit status queue full\n");
210
211 old_skb = skb_dequeue(&priv->b_tx_status.queue);
212 ieee80211_tx_status_irqsafe(hw, old_skb);
213 }
214 return;
215 } else {
216 info->flags |= IEEE80211_TX_STAT_ACK;
217 }
218 }
219 if (priv->is_rtl8187b)
220 ieee80211_tx_status_irqsafe(hw, skb);
221 else {
222 /* Retry information for the RTI8187 is only available by
223 * reading a register in the device. We are in interrupt mode
224 * here, thus queue the skb and finish on a work queue. */
225 skb_queue_tail(&priv->b_tx_status.queue, skb);
226 ieee80211_queue_delayed_work(hw, &priv->work, 0);
227 }
228}
229
230static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
231{
232 struct rtl8187_priv *priv = dev->priv;
233 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
234 unsigned int ep;
235 void *buf;
236 struct urb *urb;
237 __le16 rts_dur = 0;
238 u32 flags;
239 int rc;
240
241 urb = usb_alloc_urb(0, GFP_ATOMIC);
242 if (!urb) {
243 kfree_skb(skb);
244 return NETDEV_TX_OK;
245 }
246
247 flags = skb->len;
248 flags |= RTL818X_TX_DESC_FLAG_NO_ENC;
249
250 flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;
251 if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control))
252 flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
253 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
254 flags |= RTL818X_TX_DESC_FLAG_RTS;
255 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
256 rts_dur = ieee80211_rts_duration(dev, priv->vif,
257 skb->len, info);
258 } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
259 flags |= RTL818X_TX_DESC_FLAG_CTS;
260 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
261 }
262
263 if (!priv->is_rtl8187b) {
264 struct rtl8187_tx_hdr *hdr =
265 (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
266 hdr->flags = cpu_to_le32(flags);
267 hdr->len = 0;
268 hdr->rts_duration = rts_dur;
269 hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8);
270 buf = hdr;
271
272 ep = 2;
273 } else {
274 /* fc needs to be calculated before skb_push() */
275 unsigned int epmap[4] = { 6, 7, 5, 4 };
276 struct ieee80211_hdr *tx_hdr =
277 (struct ieee80211_hdr *)(skb->data);
278 u16 fc = le16_to_cpu(tx_hdr->frame_control);
279
280 struct rtl8187b_tx_hdr *hdr =
281 (struct rtl8187b_tx_hdr *)skb_push(skb, sizeof(*hdr));
282 struct ieee80211_rate *txrate =
283 ieee80211_get_tx_rate(dev, info);
284 memset(hdr, 0, sizeof(*hdr));
285 hdr->flags = cpu_to_le32(flags);
286 hdr->rts_duration = rts_dur;
287 hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8);
288 hdr->tx_duration =
289 ieee80211_generic_frame_duration(dev, priv->vif,
290 skb->len, txrate);
291 buf = hdr;
292
293 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
294 ep = 12;
295 else
296 ep = epmap[skb_get_queue_mapping(skb)];
297 }
298
299 info->rate_driver_data[0] = dev;
300 info->rate_driver_data[1] = urb;
301
302 usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
303 buf, skb->len, rtl8187_tx_cb, skb);
304 urb->transfer_flags |= URB_ZERO_PACKET;
305 usb_anchor_urb(urb, &priv->anchored);
306 rc = usb_submit_urb(urb, GFP_ATOMIC);
307 if (rc < 0) {
308 usb_unanchor_urb(urb);
309 kfree_skb(skb);
310 }
311 usb_free_urb(urb);
312
313 return NETDEV_TX_OK;
314}
315
316static void rtl8187_rx_cb(struct urb *urb)
317{
318 struct sk_buff *skb = (struct sk_buff *)urb->context;
319 struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb;
320 struct ieee80211_hw *dev = info->dev;
321 struct rtl8187_priv *priv = dev->priv;
322 struct ieee80211_rx_status rx_status = { 0 };
323 int rate, signal;
324 u32 flags;
325 unsigned long f;
326
327 spin_lock_irqsave(&priv->rx_queue.lock, f);
328 __skb_unlink(skb, &priv->rx_queue);
329 spin_unlock_irqrestore(&priv->rx_queue.lock, f);
330 skb_put(skb, urb->actual_length);
331
332 if (unlikely(urb->status)) {
333 dev_kfree_skb_irq(skb);
334 return;
335 }
336
337 if (!priv->is_rtl8187b) {
338 struct rtl8187_rx_hdr *hdr =
339 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
340 flags = le32_to_cpu(hdr->flags);
341 /* As with the RTL8187B below, the AGC is used to calculate
342 * signal strength. In this case, the scaling
343 * constants are derived from the output of p54usb.
344 */
345 signal = -4 - ((27 * hdr->agc) >> 6);
346 rx_status.antenna = (hdr->signal >> 7) & 1;
347 rx_status.mactime = le64_to_cpu(hdr->mac_time);
348 } else {
349 struct rtl8187b_rx_hdr *hdr =
350 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
351 /* The Realtek datasheet for the RTL8187B shows that the RX
352 * header contains the following quantities: signal quality,
353 * RSSI, AGC, the received power in dB, and the measured SNR.
354 * In testing, none of these quantities show qualitative
355 * agreement with AP signal strength, except for the AGC,
356 * which is inversely proportional to the strength of the
357 * signal. In the following, the signal strength
358 * is derived from the AGC. The arbitrary scaling constants
359 * are chosen to make the results close to the values obtained
360 * for a BCM4312 using b43 as the driver. The noise is ignored
361 * for now.
362 */
363 flags = le32_to_cpu(hdr->flags);
364 signal = 14 - hdr->agc / 2;
365 rx_status.antenna = (hdr->rssi >> 7) & 1;
366 rx_status.mactime = le64_to_cpu(hdr->mac_time);
367 }
368
369 rx_status.signal = signal;
370 priv->signal = signal;
371 rate = (flags >> 20) & 0xF;
372 skb_trim(skb, flags & 0x0FFF);
373 rx_status.rate_idx = rate;
374 rx_status.freq = dev->conf.channel->center_freq;
375 rx_status.band = dev->conf.channel->band;
376 rx_status.flag |= RX_FLAG_TSFT;
377 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
378 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
379 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
380 ieee80211_rx_irqsafe(dev, skb);
381
382 skb = dev_alloc_skb(RTL8187_MAX_RX);
383 if (unlikely(!skb)) {
384 /* TODO check rx queue length and refill *somewhere* */
385 return;
386 }
387
388 info = (struct rtl8187_rx_info *)skb->cb;
389 info->urb = urb;
390 info->dev = dev;
391 urb->transfer_buffer = skb_tail_pointer(skb);
392 urb->context = skb;
393 skb_queue_tail(&priv->rx_queue, skb);
394
395 usb_anchor_urb(urb, &priv->anchored);
396 if (usb_submit_urb(urb, GFP_ATOMIC)) {
397 usb_unanchor_urb(urb);
398 skb_unlink(skb, &priv->rx_queue);
399 dev_kfree_skb_irq(skb);
400 }
401}
402
403static int rtl8187_init_urbs(struct ieee80211_hw *dev)
404{
405 struct rtl8187_priv *priv = dev->priv;
406 struct urb *entry = NULL;
407 struct sk_buff *skb;
408 struct rtl8187_rx_info *info;
409 int ret = 0;
410
411 while (skb_queue_len(&priv->rx_queue) < 16) {
412 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
413 if (!skb) {
414 ret = -ENOMEM;
415 goto err;
416 }
417 entry = usb_alloc_urb(0, GFP_KERNEL);
418 if (!entry) {
419 ret = -ENOMEM;
420 goto err;
421 }
422 usb_fill_bulk_urb(entry, priv->udev,
423 usb_rcvbulkpipe(priv->udev,
424 priv->is_rtl8187b ? 3 : 1),
425 skb_tail_pointer(skb),
426 RTL8187_MAX_RX, rtl8187_rx_cb, skb);
427 info = (struct rtl8187_rx_info *)skb->cb;
428 info->urb = entry;
429 info->dev = dev;
430 skb_queue_tail(&priv->rx_queue, skb);
431 usb_anchor_urb(entry, &priv->anchored);
432 ret = usb_submit_urb(entry, GFP_KERNEL);
433 if (ret) {
434 skb_unlink(skb, &priv->rx_queue);
435 usb_unanchor_urb(entry);
436 goto err;
437 }
438 usb_free_urb(entry);
439 }
440 return ret;
441
442err:
443 usb_free_urb(entry);
444 kfree_skb(skb);
445 usb_kill_anchored_urbs(&priv->anchored);
446 return ret;
447}
448
449static void rtl8187b_status_cb(struct urb *urb)
450{
451 struct ieee80211_hw *hw = (struct ieee80211_hw *)urb->context;
452 struct rtl8187_priv *priv = hw->priv;
453 u64 val;
454 unsigned int cmd_type;
455
456 if (unlikely(urb->status))
457 return;
458
459 /*
460 * Read from status buffer:
461 *
462 * bits [30:31] = cmd type:
463 * - 0 indicates tx beacon interrupt
464 * - 1 indicates tx close descriptor
465 *
466 * In the case of tx beacon interrupt:
467 * [0:9] = Last Beacon CW
468 * [10:29] = reserved
469 * [30:31] = 00b
470 * [32:63] = Last Beacon TSF
471 *
472 * If it's tx close descriptor:
473 * [0:7] = Packet Retry Count
474 * [8:14] = RTS Retry Count
475 * [15] = TOK
476 * [16:27] = Sequence No
477 * [28] = LS
478 * [29] = FS
479 * [30:31] = 01b
480 * [32:47] = unused (reserved?)
481 * [48:63] = MAC Used Time
482 */
483 val = le64_to_cpu(priv->b_tx_status.buf);
484
485 cmd_type = (val >> 30) & 0x3;
486 if (cmd_type == 1) {
487 unsigned int pkt_rc, seq_no;
488 bool tok;
489 struct sk_buff *skb;
490 struct ieee80211_hdr *ieee80211hdr;
491 unsigned long flags;
492
493 pkt_rc = val & 0xFF;
494 tok = val & (1 << 15);
495 seq_no = (val >> 16) & 0xFFF;
496
497 spin_lock_irqsave(&priv->b_tx_status.queue.lock, flags);
498 skb_queue_reverse_walk(&priv->b_tx_status.queue, skb) {
499 ieee80211hdr = (struct ieee80211_hdr *)skb->data;
500
501 /*
502 * While testing, it was discovered that the seq_no
503 * doesn't actually contains the sequence number.
504 * Instead of returning just the 12 bits of sequence
505 * number, hardware is returning entire sequence control
506 * (fragment number plus sequence number) in a 12 bit
507 * only field overflowing after some time. As a
508 * workaround, just consider the lower bits, and expect
509 * it's unlikely we wrongly ack some sent data
510 */
511 if ((le16_to_cpu(ieee80211hdr->seq_ctrl)
512 & 0xFFF) == seq_no)
513 break;
514 }
515 if (skb != (struct sk_buff *) &priv->b_tx_status.queue) {
516 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
517
518 __skb_unlink(skb, &priv->b_tx_status.queue);
519 if (tok)
520 info->flags |= IEEE80211_TX_STAT_ACK;
521 info->status.rates[0].count = pkt_rc + 1;
522
523 ieee80211_tx_status_irqsafe(hw, skb);
524 }
525 spin_unlock_irqrestore(&priv->b_tx_status.queue.lock, flags);
526 }
527
528 usb_anchor_urb(urb, &priv->anchored);
529 if (usb_submit_urb(urb, GFP_ATOMIC))
530 usb_unanchor_urb(urb);
531}
532
533static int rtl8187b_init_status_urb(struct ieee80211_hw *dev)
534{
535 struct rtl8187_priv *priv = dev->priv;
536 struct urb *entry;
537 int ret = 0;
538
539 entry = usb_alloc_urb(0, GFP_KERNEL);
540 if (!entry)
541 return -ENOMEM;
542
543 usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 9),
544 &priv->b_tx_status.buf, sizeof(priv->b_tx_status.buf),
545 rtl8187b_status_cb, dev);
546
547 usb_anchor_urb(entry, &priv->anchored);
548 ret = usb_submit_urb(entry, GFP_KERNEL);
549 if (ret)
550 usb_unanchor_urb(entry);
551 usb_free_urb(entry);
552
553 return ret;
554}
555
556static void rtl8187_set_anaparam(struct rtl8187_priv *priv, bool rfon)
557{
558 u32 anaparam, anaparam2;
559 u8 anaparam3, reg;
560
561 if (!priv->is_rtl8187b) {
562 if (rfon) {
563 anaparam = RTL8187_RTL8225_ANAPARAM_ON;
564 anaparam2 = RTL8187_RTL8225_ANAPARAM2_ON;
565 } else {
566 anaparam = RTL8187_RTL8225_ANAPARAM_OFF;
567 anaparam2 = RTL8187_RTL8225_ANAPARAM2_OFF;
568 }
569 } else {
570 if (rfon) {
571 anaparam = RTL8187B_RTL8225_ANAPARAM_ON;
572 anaparam2 = RTL8187B_RTL8225_ANAPARAM2_ON;
573 anaparam3 = RTL8187B_RTL8225_ANAPARAM3_ON;
574 } else {
575 anaparam = RTL8187B_RTL8225_ANAPARAM_OFF;
576 anaparam2 = RTL8187B_RTL8225_ANAPARAM2_OFF;
577 anaparam3 = RTL8187B_RTL8225_ANAPARAM3_OFF;
578 }
579 }
580
581 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
582 RTL818X_EEPROM_CMD_CONFIG);
583 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
584 reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
585 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
586 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
587 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2);
588 if (priv->is_rtl8187b)
589 rtl818x_iowrite8(priv, &priv->map->ANAPARAM3, anaparam3);
590 reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
591 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
592 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
593 RTL818X_EEPROM_CMD_NORMAL);
594}
595
596static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
597{
598 struct rtl8187_priv *priv = dev->priv;
599 u8 reg;
600 int i;
601
602 reg = rtl818x_ioread8(priv, &priv->map->CMD);
603 reg &= (1 << 1);
604 reg |= RTL818X_CMD_RESET;
605 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
606
607 i = 10;
608 do {
609 msleep(2);
610 if (!(rtl818x_ioread8(priv, &priv->map->CMD) &
611 RTL818X_CMD_RESET))
612 break;
613 } while (--i);
614
615 if (!i) {
616 wiphy_err(dev->wiphy, "Reset timeout!\n");
617 return -ETIMEDOUT;
618 }
619
620 /* reload registers from eeprom */
621 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
622
623 i = 10;
624 do {
625 msleep(4);
626 if (!(rtl818x_ioread8(priv, &priv->map->EEPROM_CMD) &
627 RTL818X_EEPROM_CMD_CONFIG))
628 break;
629 } while (--i);
630
631 if (!i) {
632 wiphy_err(dev->wiphy, "eeprom reset timeout!\n");
633 return -ETIMEDOUT;
634 }
635
636 return 0;
637}
638
639static int rtl8187_init_hw(struct ieee80211_hw *dev)
640{
641 struct rtl8187_priv *priv = dev->priv;
642 u8 reg;
643 int res;
644
645 /* reset */
646 rtl8187_set_anaparam(priv, true);
647
648 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
649
650 msleep(200);
651 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
652 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
653 rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
654 msleep(200);
655
656 res = rtl8187_cmd_reset(dev);
657 if (res)
658 return res;
659
660 rtl8187_set_anaparam(priv, true);
661
662 /* setup card */
663 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
664 rtl818x_iowrite8(priv, &priv->map->GPIO0, 0);
665
666 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
667 rtl818x_iowrite8(priv, &priv->map->GPIO0, 1);
668 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
669
670 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
671
672 rtl818x_iowrite16(priv, (__le16 *)0xFFF4, 0xFFFF);
673 reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
674 reg &= 0x3F;
675 reg |= 0x80;
676 rtl818x_iowrite8(priv, &priv->map->CONFIG1, reg);
677
678 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
679
680 rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
681 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
682 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);
683
684 // TODO: set RESP_RATE and BRSR properly
685 rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
686 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
687
688 /* host_usb_init */
689 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
690 rtl818x_iowrite8(priv, &priv->map->GPIO0, 0);
691 reg = rtl818x_ioread8(priv, (u8 *)0xFE53);
692 rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7));
693 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
694 rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x20);
695 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
696 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80);
697 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80);
698 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x80);
699 msleep(100);
700
701 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
702 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
703 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
704 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
705 RTL818X_EEPROM_CMD_CONFIG);
706 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
707 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
708 RTL818X_EEPROM_CMD_NORMAL);
709 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
710 msleep(100);
711
712 priv->rf->init(dev);
713
714 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
715 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
716 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
717 rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10);
718 rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80);
719 rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60);
720 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
721
722 return 0;
723}
724
725static const u8 rtl8187b_reg_table[][3] = {
726 {0xF0, 0x32, 0}, {0xF1, 0x32, 0}, {0xF2, 0x00, 0}, {0xF3, 0x00, 0},
727 {0xF4, 0x32, 0}, {0xF5, 0x43, 0}, {0xF6, 0x00, 0}, {0xF7, 0x00, 0},
728 {0xF8, 0x46, 0}, {0xF9, 0xA4, 0}, {0xFA, 0x00, 0}, {0xFB, 0x00, 0},
729 {0xFC, 0x96, 0}, {0xFD, 0xA4, 0}, {0xFE, 0x00, 0}, {0xFF, 0x00, 0},
730
731 {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1},
732 {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1},
733 {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1},
734 {0xF2, 0x02, 1}, {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1},
735 {0xF6, 0x06, 1}, {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
736
737 {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2},
738 {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2},
739 {0x27, 0x8D, 2}, {0x4D, 0x08, 2}, {0x50, 0x05, 2}, {0x51, 0xF5, 2},
740 {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2},
741 {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2},
742 {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2},
743 {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2},
744
745 {0x5B, 0x40, 0}, {0x84, 0x88, 0}, {0x85, 0x24, 0}, {0x88, 0x54, 0},
746 {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0},
747 {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0},
748 {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, {0xBE, 0x80, 0}, {0xDB, 0x00, 0},
749 {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
750
751 {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0},
752 {0x8F, 0x00, 0}
753};
754
755static int rtl8187b_init_hw(struct ieee80211_hw *dev)
756{
757 struct rtl8187_priv *priv = dev->priv;
758 int res, i;
759 u8 reg;
760
761 rtl8187_set_anaparam(priv, true);
762
763 /* Reset PLL sequence on 8187B. Realtek note: reduces power
764 * consumption about 30 mA */
765 rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
766 reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
767 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5));
768 rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5));
769
770 res = rtl8187_cmd_reset(dev);
771 if (res)
772 return res;
773
774 rtl8187_set_anaparam(priv, true);
775
776 /* BRSR (Basic Rate Set Register) on 8187B looks to be the same as
777 * RESP_RATE on 8187L in Realtek sources: each bit should be each
778 * one of the 12 rates, all are enabled */
779 rtl818x_iowrite16(priv, (__le16 *)0xFF34, 0x0FFF);
780
781 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
782 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
783 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
784
785 /* Auto Rate Fallback Register (ARFR): 1M-54M setting */
786 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
787 rtl818x_iowrite8_idx(priv, (u8 *)0xFFE2, 0x00, 1);
788
789 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1);
790
791 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
792 RTL818X_EEPROM_CMD_CONFIG);
793 reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
794 rtl818x_iowrite8(priv, &priv->map->CONFIG1, (reg & 0x3F) | 0x80);
795 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
796 RTL818X_EEPROM_CMD_NORMAL);
797
798 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
799 for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) {
800 rtl818x_iowrite8_idx(priv,
801 (u8 *)(uintptr_t)
802 (rtl8187b_reg_table[i][0] | 0xFF00),
803 rtl8187b_reg_table[i][1],
804 rtl8187b_reg_table[i][2]);
805 }
806
807 rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50);
808 rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0);
809
810 rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF0, 0, 1);
811 rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF4, 0, 1);
812 rtl818x_iowrite8_idx(priv, (u8 *)0xFFF8, 0, 1);
813
814 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
815
816 /* RFSW_CTRL register */
817 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
818
819 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
820 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
821 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
822 msleep(100);
823
824 priv->rf->init(dev);
825
826 reg = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE;
827 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
828 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
829
830 rtl818x_iowrite8(priv, (u8 *)0xFE41, 0xF4);
831 rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x00);
832 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
833 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
834 rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x0F);
835 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
836 rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
837
838 reg = rtl818x_ioread8(priv, (u8 *)0xFFDB);
839 rtl818x_iowrite8(priv, (u8 *)0xFFDB, reg | (1 << 2));
840 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x59FA, 3);
841 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF74, 0x59D2, 3);
842 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF76, 0x59D2, 3);
843 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF78, 0x19FA, 3);
844 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7A, 0x19FA, 3);
845 rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7C, 0x00D0, 3);
846 rtl818x_iowrite8(priv, (u8 *)0xFF61, 0);
847 rtl818x_iowrite8_idx(priv, (u8 *)0xFF80, 0x0F, 1);
848 rtl818x_iowrite8_idx(priv, (u8 *)0xFF83, 0x03, 1);
849 rtl818x_iowrite8(priv, (u8 *)0xFFDA, 0x10);
850 rtl818x_iowrite8_idx(priv, (u8 *)0xFF4D, 0x08, 2);
851
852 rtl818x_iowrite32(priv, &priv->map->HSSI_PARA, 0x0600321B);
853
854 rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1);
855
856 priv->slot_time = 0x9;
857 priv->aifsn[0] = 2; /* AIFSN[AC_VO] */
858 priv->aifsn[1] = 2; /* AIFSN[AC_VI] */
859 priv->aifsn[2] = 7; /* AIFSN[AC_BK] */
860 priv->aifsn[3] = 3; /* AIFSN[AC_BE] */
861 rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
862
863 /* ENEDCA flag must always be set, transmit issues? */
864 rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA);
865
866 return 0;
867}
868
869static void rtl8187_work(struct work_struct *work)
870{
871 /* The RTL8187 returns the retry count through register 0xFFFA. In
872 * addition, it appears to be a cumulative retry count, not the
873 * value for the current TX packet. When multiple TX entries are
874 * queued, the retry count will be valid for the last one in the queue.
875 * The "error" should not matter for purposes of rate setting. */
876 struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
877 work.work);
878 struct ieee80211_tx_info *info;
879 struct ieee80211_hw *dev = priv->dev;
880 static u16 retry;
881 u16 tmp;
882
883 mutex_lock(&priv->conf_mutex);
884 tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA);
885 while (skb_queue_len(&priv->b_tx_status.queue) > 0) {
886 struct sk_buff *old_skb;
887
888 old_skb = skb_dequeue(&priv->b_tx_status.queue);
889 info = IEEE80211_SKB_CB(old_skb);
890 info->status.rates[0].count = tmp - retry + 1;
891 ieee80211_tx_status_irqsafe(dev, old_skb);
892 }
893 retry = tmp;
894 mutex_unlock(&priv->conf_mutex);
895}
896
897static int rtl8187_start(struct ieee80211_hw *dev)
898{
899 struct rtl8187_priv *priv = dev->priv;
900 u32 reg;
901 int ret;
902
903 mutex_lock(&priv->conf_mutex);
904
905 ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) :
906 rtl8187b_init_hw(dev);
907 if (ret)
908 goto rtl8187_start_exit;
909
910 init_usb_anchor(&priv->anchored);
911 priv->dev = dev;
912
913 if (priv->is_rtl8187b) {
914 reg = RTL818X_RX_CONF_MGMT |
915 RTL818X_RX_CONF_DATA |
916 RTL818X_RX_CONF_BROADCAST |
917 RTL818X_RX_CONF_NICMAC |
918 RTL818X_RX_CONF_BSSID |
919 (7 << 13 /* RX FIFO threshold NONE */) |
920 (7 << 10 /* MAX RX DMA */) |
921 RTL818X_RX_CONF_RX_AUTORESETPHY |
922 RTL818X_RX_CONF_ONLYERLPKT |
923 RTL818X_RX_CONF_MULTICAST;
924 priv->rx_conf = reg;
925 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
926
927 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
928 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
929 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
930 reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
931 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
932
933 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
934 RTL818X_TX_CONF_HW_SEQNUM |
935 RTL818X_TX_CONF_DISREQQSIZE |
936 (7 << 8 /* short retry limit */) |
937 (7 << 0 /* long retry limit */) |
938 (7 << 21 /* MAX TX DMA */));
939 rtl8187_init_urbs(dev);
940 rtl8187b_init_status_urb(dev);
941 goto rtl8187_start_exit;
942 }
943
944 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
945
946 rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
947 rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
948
949 rtl8187_init_urbs(dev);
950
951 reg = RTL818X_RX_CONF_ONLYERLPKT |
952 RTL818X_RX_CONF_RX_AUTORESETPHY |
953 RTL818X_RX_CONF_BSSID |
954 RTL818X_RX_CONF_MGMT |
955 RTL818X_RX_CONF_DATA |
956 (7 << 13 /* RX FIFO threshold NONE */) |
957 (7 << 10 /* MAX RX DMA */) |
958 RTL818X_RX_CONF_BROADCAST |
959 RTL818X_RX_CONF_NICMAC;
960
961 priv->rx_conf = reg;
962 rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
963
964 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
965 reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT;
966 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
967 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
968
969 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
970 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
971 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
972 reg &= ~RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
973 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
974
975 reg = RTL818X_TX_CONF_CW_MIN |
976 (7 << 21 /* MAX TX DMA */) |
977 RTL818X_TX_CONF_NO_ICV;
978 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
979
980 reg = rtl818x_ioread8(priv, &priv->map->CMD);
981 reg |= RTL818X_CMD_TX_ENABLE;
982 reg |= RTL818X_CMD_RX_ENABLE;
983 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
984 INIT_DELAYED_WORK(&priv->work, rtl8187_work);
985
986rtl8187_start_exit:
987 mutex_unlock(&priv->conf_mutex);
988 return ret;
989}
990
991static void rtl8187_stop(struct ieee80211_hw *dev)
992{
993 struct rtl8187_priv *priv = dev->priv;
994 struct sk_buff *skb;
995 u32 reg;
996
997 mutex_lock(&priv->conf_mutex);
998 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
999
1000 reg = rtl818x_ioread8(priv, &priv->map->CMD);
1001 reg &= ~RTL818X_CMD_TX_ENABLE;
1002 reg &= ~RTL818X_CMD_RX_ENABLE;
1003 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
1004
1005 priv->rf->stop(dev);
1006 rtl8187_set_anaparam(priv, false);
1007
1008 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1009 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
1010 rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
1011 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1012
1013 while ((skb = skb_dequeue(&priv->b_tx_status.queue)))
1014 dev_kfree_skb_any(skb);
1015
1016 usb_kill_anchored_urbs(&priv->anchored);
1017 mutex_unlock(&priv->conf_mutex);
1018
1019 if (!priv->is_rtl8187b)
1020 cancel_delayed_work_sync(&priv->work);
1021}
1022
1023static int rtl8187_add_interface(struct ieee80211_hw *dev,
1024 struct ieee80211_vif *vif)
1025{
1026 struct rtl8187_priv *priv = dev->priv;
1027 int i;
1028 int ret = -EOPNOTSUPP;
1029
1030 mutex_lock(&priv->conf_mutex);
1031 if (priv->vif)
1032 goto exit;
1033
1034 switch (vif->type) {
1035 case NL80211_IFTYPE_STATION:
1036 break;
1037 default:
1038 goto exit;
1039 }
1040
1041 ret = 0;
1042 priv->vif = vif;
1043
1044 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1045 for (i = 0; i < ETH_ALEN; i++)
1046 rtl818x_iowrite8(priv, &priv->map->MAC[i],
1047 ((u8 *)vif->addr)[i]);
1048 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1049
1050exit:
1051 mutex_unlock(&priv->conf_mutex);
1052 return ret;
1053}
1054
1055static void rtl8187_remove_interface(struct ieee80211_hw *dev,
1056 struct ieee80211_vif *vif)
1057{
1058 struct rtl8187_priv *priv = dev->priv;
1059 mutex_lock(&priv->conf_mutex);
1060 priv->vif = NULL;
1061 mutex_unlock(&priv->conf_mutex);
1062}
1063
1064static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
1065{
1066 struct rtl8187_priv *priv = dev->priv;
1067 struct ieee80211_conf *conf = &dev->conf;
1068 u32 reg;
1069
1070 mutex_lock(&priv->conf_mutex);
1071 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
1072 /* Enable TX loopback on MAC level to avoid TX during channel
1073 * changes, as this has be seen to causes problems and the
1074 * card will stop work until next reset
1075 */
1076 rtl818x_iowrite32(priv, &priv->map->TX_CONF,
1077 reg | RTL818X_TX_CONF_LOOPBACK_MAC);
1078 priv->rf->set_chan(dev, conf);
1079 msleep(10);
1080 rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
1081
1082 rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
1083 rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
1084 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
1085 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
1086 mutex_unlock(&priv->conf_mutex);
1087 return 0;
1088}
1089
1090/*
1091 * With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for
1092 * example. Thus we have to use raw values for AC_*_PARAM register addresses.
1093 */
1094static __le32 *rtl8187b_ac_addr[4] = {
1095 (__le32 *) 0xFFF0, /* AC_VO */
1096 (__le32 *) 0xFFF4, /* AC_VI */
1097 (__le32 *) 0xFFFC, /* AC_BK */
1098 (__le32 *) 0xFFF8, /* AC_BE */
1099};
1100
1101#define SIFS_TIME 0xa
1102
1103static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot,
1104 bool use_short_preamble)
1105{
1106 if (priv->is_rtl8187b) {
1107 u8 difs, eifs;
1108 u16 ack_timeout;
1109 int queue;
1110
1111 if (use_short_slot) {
1112 priv->slot_time = 0x9;
1113 difs = 0x1c;
1114 eifs = 0x53;
1115 } else {
1116 priv->slot_time = 0x14;
1117 difs = 0x32;
1118 eifs = 0x5b;
1119 }
1120 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
1121 rtl818x_iowrite8(priv, &priv->map->SLOT, priv->slot_time);
1122 rtl818x_iowrite8(priv, &priv->map->DIFS, difs);
1123
1124 /*
1125 * BRSR+1 on 8187B is in fact EIFS register
1126 * Value in units of 4 us
1127 */
1128 rtl818x_iowrite8(priv, (u8 *)&priv->map->BRSR + 1, eifs);
1129
1130 /*
1131 * For 8187B, CARRIER_SENSE_COUNTER is in fact ack timeout
1132 * register. In units of 4 us like eifs register
1133 * ack_timeout = ack duration + plcp + difs + preamble
1134 */
1135 ack_timeout = 112 + 48 + difs;
1136 if (use_short_preamble)
1137 ack_timeout += 72;
1138 else
1139 ack_timeout += 144;
1140 rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER,
1141 DIV_ROUND_UP(ack_timeout, 4));
1142
1143 for (queue = 0; queue < 4; queue++)
1144 rtl818x_iowrite8(priv, (u8 *) rtl8187b_ac_addr[queue],
1145 priv->aifsn[queue] * priv->slot_time +
1146 SIFS_TIME);
1147 } else {
1148 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
1149 if (use_short_slot) {
1150 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
1151 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
1152 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
1153 } else {
1154 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
1155 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
1156 rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
1157 }
1158 }
1159}
1160
1161static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
1162 struct ieee80211_vif *vif,
1163 struct ieee80211_bss_conf *info,
1164 u32 changed)
1165{
1166 struct rtl8187_priv *priv = dev->priv;
1167 int i;
1168 u8 reg;
1169
1170 if (changed & BSS_CHANGED_BSSID) {
1171 mutex_lock(&priv->conf_mutex);
1172 for (i = 0; i < ETH_ALEN; i++)
1173 rtl818x_iowrite8(priv, &priv->map->BSSID[i],
1174 info->bssid[i]);
1175
1176 if (priv->is_rtl8187b)
1177 reg = RTL818X_MSR_ENEDCA;
1178 else
1179 reg = 0;
1180
1181 if (is_valid_ether_addr(info->bssid))
1182 reg |= RTL818X_MSR_INFRA;
1183 else
1184 reg |= RTL818X_MSR_NO_LINK;
1185
1186 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
1187
1188 mutex_unlock(&priv->conf_mutex);
1189 }
1190
1191 if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
1192 rtl8187_conf_erp(priv, info->use_short_slot,
1193 info->use_short_preamble);
1194}
1195
1196static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev,
1197 struct netdev_hw_addr_list *mc_list)
1198{
1199 return netdev_hw_addr_list_count(mc_list);
1200}
1201
1202static void rtl8187_configure_filter(struct ieee80211_hw *dev,
1203 unsigned int changed_flags,
1204 unsigned int *total_flags,
1205 u64 multicast)
1206{
1207 struct rtl8187_priv *priv = dev->priv;
1208
1209 if (changed_flags & FIF_FCSFAIL)
1210 priv->rx_conf ^= RTL818X_RX_CONF_FCS;
1211 if (changed_flags & FIF_CONTROL)
1212 priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
1213 if (changed_flags & FIF_OTHER_BSS)
1214 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
1215 if (*total_flags & FIF_ALLMULTI || multicast > 0)
1216 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
1217 else
1218 priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
1219
1220 *total_flags = 0;
1221
1222 if (priv->rx_conf & RTL818X_RX_CONF_FCS)
1223 *total_flags |= FIF_FCSFAIL;
1224 if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
1225 *total_flags |= FIF_CONTROL;
1226 if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
1227 *total_flags |= FIF_OTHER_BSS;
1228 if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
1229 *total_flags |= FIF_ALLMULTI;
1230
1231 rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
1232}
1233
1234static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue,
1235 const struct ieee80211_tx_queue_params *params)
1236{
1237 struct rtl8187_priv *priv = dev->priv;
1238 u8 cw_min, cw_max;
1239
1240 if (queue > 3)
1241 return -EINVAL;
1242
1243 cw_min = fls(params->cw_min);
1244 cw_max = fls(params->cw_max);
1245
1246 if (priv->is_rtl8187b) {
1247 priv->aifsn[queue] = params->aifs;
1248
1249 /*
1250 * This is the structure of AC_*_PARAM registers in 8187B:
1251 * - TXOP limit field, bit offset = 16
1252 * - ECWmax, bit offset = 12
1253 * - ECWmin, bit offset = 8
1254 * - AIFS, bit offset = 0
1255 */
1256 rtl818x_iowrite32(priv, rtl8187b_ac_addr[queue],
1257 (params->txop << 16) | (cw_max << 12) |
1258 (cw_min << 8) | (params->aifs *
1259 priv->slot_time + SIFS_TIME));
1260 } else {
1261 if (queue != 0)
1262 return -EINVAL;
1263
1264 rtl818x_iowrite8(priv, &priv->map->CW_VAL,
1265 cw_min | (cw_max << 4));
1266 }
1267 return 0;
1268}
1269
1270static u64 rtl8187_get_tsf(struct ieee80211_hw *dev)
1271{
1272 struct rtl8187_priv *priv = dev->priv;
1273
1274 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
1275 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
1276}
1277
1278static const struct ieee80211_ops rtl8187_ops = {
1279 .tx = rtl8187_tx,
1280 .start = rtl8187_start,
1281 .stop = rtl8187_stop,
1282 .add_interface = rtl8187_add_interface,
1283 .remove_interface = rtl8187_remove_interface,
1284 .config = rtl8187_config,
1285 .bss_info_changed = rtl8187_bss_info_changed,
1286 .prepare_multicast = rtl8187_prepare_multicast,
1287 .configure_filter = rtl8187_configure_filter,
1288 .conf_tx = rtl8187_conf_tx,
1289 .rfkill_poll = rtl8187_rfkill_poll,
1290 .get_tsf = rtl8187_get_tsf,
1291};
1292
1293static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
1294{
1295 struct ieee80211_hw *dev = eeprom->data;
1296 struct rtl8187_priv *priv = dev->priv;
1297 u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
1298
1299 eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
1300 eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
1301 eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
1302 eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
1303}
1304
1305static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom)
1306{
1307 struct ieee80211_hw *dev = eeprom->data;
1308 struct rtl8187_priv *priv = dev->priv;
1309 u8 reg = RTL818X_EEPROM_CMD_PROGRAM;
1310
1311 if (eeprom->reg_data_in)
1312 reg |= RTL818X_EEPROM_CMD_WRITE;
1313 if (eeprom->reg_data_out)
1314 reg |= RTL818X_EEPROM_CMD_READ;
1315 if (eeprom->reg_data_clock)
1316 reg |= RTL818X_EEPROM_CMD_CK;
1317 if (eeprom->reg_chip_select)
1318 reg |= RTL818X_EEPROM_CMD_CS;
1319
1320 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
1321 udelay(10);
1322}
1323
1324static int __devinit rtl8187_probe(struct usb_interface *intf,
1325 const struct usb_device_id *id)
1326{
1327 struct usb_device *udev = interface_to_usbdev(intf);
1328 struct ieee80211_hw *dev;
1329 struct rtl8187_priv *priv;
1330 struct eeprom_93cx6 eeprom;
1331 struct ieee80211_channel *channel;
1332 const char *chip_name;
1333 u16 txpwr, reg;
1334 u16 product_id = le16_to_cpu(udev->descriptor.idProduct);
1335 int err, i;
1336 u8 mac_addr[ETH_ALEN];
1337
1338 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
1339 if (!dev) {
1340 printk(KERN_ERR "rtl8187: ieee80211 alloc failed\n");
1341 return -ENOMEM;
1342 }
1343
1344 priv = dev->priv;
1345 priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B);
1346
1347 /* allocate "DMA aware" buffer for register accesses */
1348 priv->io_dmabuf = kmalloc(sizeof(*priv->io_dmabuf), GFP_KERNEL);
1349 if (!priv->io_dmabuf) {
1350 err = -ENOMEM;
1351 goto err_free_dev;
1352 }
1353 mutex_init(&priv->io_mutex);
1354
1355 SET_IEEE80211_DEV(dev, &intf->dev);
1356 usb_set_intfdata(intf, dev);
1357 priv->udev = udev;
1358
1359 usb_get_dev(udev);
1360
1361 skb_queue_head_init(&priv->rx_queue);
1362
1363 BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels));
1364 BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates));
1365
1366 memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
1367 memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
1368 priv->map = (struct rtl818x_csr *)0xFF00;
1369
1370 priv->band.band = IEEE80211_BAND_2GHZ;
1371 priv->band.channels = priv->channels;
1372 priv->band.n_channels = ARRAY_SIZE(rtl818x_channels);
1373 priv->band.bitrates = priv->rates;
1374 priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates);
1375 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
1376
1377
1378 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1379 IEEE80211_HW_SIGNAL_DBM |
1380 IEEE80211_HW_RX_INCLUDES_FCS;
1381
1382 eeprom.data = dev;
1383 eeprom.register_read = rtl8187_eeprom_register_read;
1384 eeprom.register_write = rtl8187_eeprom_register_write;
1385 if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
1386 eeprom.width = PCI_EEPROM_WIDTH_93C66;
1387 else
1388 eeprom.width = PCI_EEPROM_WIDTH_93C46;
1389
1390 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1391 udelay(10);
1392
1393 eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR,
1394 (__le16 __force *)mac_addr, 3);
1395 if (!is_valid_ether_addr(mac_addr)) {
1396 printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly "
1397 "generated MAC address\n");
1398 random_ether_addr(mac_addr);
1399 }
1400 SET_IEEE80211_PERM_ADDR(dev, mac_addr);
1401
1402 channel = priv->channels;
1403 for (i = 0; i < 3; i++) {
1404 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i,
1405 &txpwr);
1406 (*channel++).hw_value = txpwr & 0xFF;
1407 (*channel++).hw_value = txpwr >> 8;
1408 }
1409 for (i = 0; i < 2; i++) {
1410 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i,
1411 &txpwr);
1412 (*channel++).hw_value = txpwr & 0xFF;
1413 (*channel++).hw_value = txpwr >> 8;
1414 }
1415
1416 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
1417 &priv->txpwr_base);
1418
1419 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
1420 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
1421 /* 0 means asic B-cut, we should use SW 3 wire
1422 * bit-by-bit banging for radio. 1 means we can use
1423 * USB specific request to write radio registers */
1424 priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3;
1425 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
1426 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1427
1428 if (!priv->is_rtl8187b) {
1429 u32 reg32;
1430 reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF);
1431 reg32 &= RTL818X_TX_CONF_HWVER_MASK;
1432 switch (reg32) {
1433 case RTL818X_TX_CONF_R8187vD_B:
1434 /* Some RTL8187B devices have a USB ID of 0x8187
1435 * detect them here */
1436 chip_name = "RTL8187BvB(early)";
1437 priv->is_rtl8187b = 1;
1438 priv->hw_rev = RTL8187BvB;
1439 break;
1440 case RTL818X_TX_CONF_R8187vD:
1441 chip_name = "RTL8187vD";
1442 break;
1443 default:
1444 chip_name = "RTL8187vB (default)";
1445 }
1446 } else {
1447 /*
1448 * Force USB request to write radio registers for 8187B, Realtek
1449 * only uses it in their sources
1450 */
1451 /*if (priv->asic_rev == 0) {
1452 printk(KERN_WARNING "rtl8187: Forcing use of USB "
1453 "requests to write to radio registers\n");
1454 priv->asic_rev = 1;
1455 }*/
1456 switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) {
1457 case RTL818X_R8187B_B:
1458 chip_name = "RTL8187BvB";
1459 priv->hw_rev = RTL8187BvB;
1460 break;
1461 case RTL818X_R8187B_D:
1462 chip_name = "RTL8187BvD";
1463 priv->hw_rev = RTL8187BvD;
1464 break;
1465 case RTL818X_R8187B_E:
1466 chip_name = "RTL8187BvE";
1467 priv->hw_rev = RTL8187BvE;
1468 break;
1469 default:
1470 chip_name = "RTL8187BvB (default)";
1471 priv->hw_rev = RTL8187BvB;
1472 }
1473 }
1474
1475 if (!priv->is_rtl8187b) {
1476 for (i = 0; i < 2; i++) {
1477 eeprom_93cx6_read(&eeprom,
1478 RTL8187_EEPROM_TXPWR_CHAN_6 + i,
1479 &txpwr);
1480 (*channel++).hw_value = txpwr & 0xFF;
1481 (*channel++).hw_value = txpwr >> 8;
1482 }
1483 } else {
1484 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6,
1485 &txpwr);
1486 (*channel++).hw_value = txpwr & 0xFF;
1487
1488 eeprom_93cx6_read(&eeprom, 0x0A, &txpwr);
1489 (*channel++).hw_value = txpwr & 0xFF;
1490
1491 eeprom_93cx6_read(&eeprom, 0x1C, &txpwr);
1492 (*channel++).hw_value = txpwr & 0xFF;
1493 (*channel++).hw_value = txpwr >> 8;
1494 }
1495 /* Handle the differing rfkill GPIO bit in different models */
1496 priv->rfkill_mask = RFKILL_MASK_8187_89_97;
1497 if (product_id == 0x8197 || product_id == 0x8198) {
1498 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, &reg);
1499 if (reg & 0xFF00)
1500 priv->rfkill_mask = RFKILL_MASK_8198;
1501 }
1502
1503 /*
1504 * XXX: Once this driver supports anything that requires
1505 * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
1506 */
1507 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1508
1509 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
1510 printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
1511 " info!\n");
1512
1513 priv->rf = rtl8187_detect_rf(dev);
1514 dev->extra_tx_headroom = (!priv->is_rtl8187b) ?
1515 sizeof(struct rtl8187_tx_hdr) :
1516 sizeof(struct rtl8187b_tx_hdr);
1517 if (!priv->is_rtl8187b)
1518 dev->queues = 1;
1519 else
1520 dev->queues = 4;
1521
1522 err = ieee80211_register_hw(dev);
1523 if (err) {
1524 printk(KERN_ERR "rtl8187: Cannot register device\n");
1525 goto err_free_dmabuf;
1526 }
1527 mutex_init(&priv->conf_mutex);
1528 skb_queue_head_init(&priv->b_tx_status.queue);
1529
1530 wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
1531 mac_addr, chip_name, priv->asic_rev, priv->rf->name,
1532 priv->rfkill_mask);
1533
1534#ifdef CONFIG_RTL8187_LEDS
1535 eeprom_93cx6_read(&eeprom, 0x3F, &reg);
1536 reg &= 0xFF;
1537 rtl8187_leds_init(dev, reg);
1538#endif
1539 rtl8187_rfkill_init(dev);
1540
1541 return 0;
1542
1543 err_free_dmabuf:
1544 kfree(priv->io_dmabuf);
1545 err_free_dev:
1546 ieee80211_free_hw(dev);
1547 usb_set_intfdata(intf, NULL);
1548 usb_put_dev(udev);
1549 return err;
1550}
1551
1552static void __devexit rtl8187_disconnect(struct usb_interface *intf)
1553{
1554 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1555 struct rtl8187_priv *priv;
1556
1557 if (!dev)
1558 return;
1559
1560#ifdef CONFIG_RTL8187_LEDS
1561 rtl8187_leds_exit(dev);
1562#endif
1563 rtl8187_rfkill_exit(dev);
1564 ieee80211_unregister_hw(dev);
1565
1566 priv = dev->priv;
1567 usb_reset_device(priv->udev);
1568 usb_put_dev(interface_to_usbdev(intf));
1569 kfree(priv->io_dmabuf);
1570 ieee80211_free_hw(dev);
1571}
1572
1573static struct usb_driver rtl8187_driver = {
1574 .name = KBUILD_MODNAME,
1575 .id_table = rtl8187_table,
1576 .probe = rtl8187_probe,
1577 .disconnect = __devexit_p(rtl8187_disconnect),
1578};
1579
1580static int __init rtl8187_init(void)
1581{
1582 return usb_register(&rtl8187_driver);
1583}
1584
1585static void __exit rtl8187_exit(void)
1586{
1587 usb_deregister(&rtl8187_driver);
1588}
1589
1590module_init(rtl8187_init);
1591module_exit(rtl8187_exit);
diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.c b/drivers/net/wireless/rtl818x/rtl8187/leds.c
new file mode 100644
index 000000000000..2e0de2f5f0f9
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/leds.c
@@ -0,0 +1,245 @@
1/*
2 * Linux LED driver for RTL8187
3 *
4 * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
5 *
6 * Based on the LED handling in the r8187 driver, which is:
7 * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
8 *
9 * Thanks to Realtek for their support!
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifdef CONFIG_RTL8187_LEDS
17
18#include <net/mac80211.h>
19#include <linux/usb.h>
20#include <linux/eeprom_93cx6.h>
21
22#include "rtl8187.h"
23#include "leds.h"
24
25static void led_turn_on(struct work_struct *work)
26{
27 /* As this routine does read/write operations on the hardware, it must
28 * be run from a work queue.
29 */
30 u8 reg;
31 struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
32 led_on.work);
33 struct rtl8187_led *led = &priv->led_tx;
34
35 /* Don't change the LED, when the device is down. */
36 if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED)
37 return ;
38
39 /* Skip if the LED is not registered. */
40 if (!led->dev)
41 return;
42 mutex_lock(&priv->conf_mutex);
43 switch (led->ledpin) {
44 case LED_PIN_GPIO0:
45 rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01);
46 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00);
47 break;
48 case LED_PIN_LED0:
49 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 4);
50 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
51 break;
52 case LED_PIN_LED1:
53 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 5);
54 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
55 break;
56 case LED_PIN_HW:
57 default:
58 break;
59 }
60 mutex_unlock(&priv->conf_mutex);
61}
62
63static void led_turn_off(struct work_struct *work)
64{
65 /* As this routine does read/write operations on the hardware, it must
66 * be run from a work queue.
67 */
68 u8 reg;
69 struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
70 led_off.work);
71 struct rtl8187_led *led = &priv->led_tx;
72
73 /* Don't change the LED, when the device is down. */
74 if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED)
75 return ;
76
77 /* Skip if the LED is not registered. */
78 if (!led->dev)
79 return;
80 mutex_lock(&priv->conf_mutex);
81 switch (led->ledpin) {
82 case LED_PIN_GPIO0:
83 rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01);
84 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01);
85 break;
86 case LED_PIN_LED0:
87 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 4);
88 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
89 break;
90 case LED_PIN_LED1:
91 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 5);
92 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
93 break;
94 case LED_PIN_HW:
95 default:
96 break;
97 }
98 mutex_unlock(&priv->conf_mutex);
99}
100
101/* Callback from the LED subsystem. */
102static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
103 enum led_brightness brightness)
104{
105 struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led,
106 led_dev);
107 struct ieee80211_hw *hw = led->dev;
108 struct rtl8187_priv *priv;
109 static bool radio_on;
110
111 if (!hw)
112 return;
113 priv = hw->priv;
114 if (led->is_radio) {
115 if (brightness == LED_FULL) {
116 ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
117 radio_on = true;
118 } else if (radio_on) {
119 radio_on = false;
120 cancel_delayed_work_sync(&priv->led_on);
121 ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
122 }
123 } else if (radio_on) {
124 if (brightness == LED_OFF) {
125 ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
126 /* The LED is off for 1/20 sec - it just blinks. */
127 ieee80211_queue_delayed_work(hw, &priv->led_on,
128 HZ / 20);
129 } else
130 ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
131 }
132}
133
134static int rtl8187_register_led(struct ieee80211_hw *dev,
135 struct rtl8187_led *led, const char *name,
136 const char *default_trigger, u8 ledpin,
137 bool is_radio)
138{
139 int err;
140 struct rtl8187_priv *priv = dev->priv;
141
142 if (led->dev)
143 return -EEXIST;
144 if (!default_trigger)
145 return -EINVAL;
146 led->dev = dev;
147 led->ledpin = ledpin;
148 led->is_radio = is_radio;
149 strncpy(led->name, name, sizeof(led->name));
150
151 led->led_dev.name = led->name;
152 led->led_dev.default_trigger = default_trigger;
153 led->led_dev.brightness_set = rtl8187_led_brightness_set;
154
155 err = led_classdev_register(&priv->udev->dev, &led->led_dev);
156 if (err) {
157 printk(KERN_INFO "LEDs: Failed to register %s\n", name);
158 led->dev = NULL;
159 return err;
160 }
161 return 0;
162}
163
164static void rtl8187_unregister_led(struct rtl8187_led *led)
165{
166 struct ieee80211_hw *hw = led->dev;
167 struct rtl8187_priv *priv = hw->priv;
168
169 led_classdev_unregister(&led->led_dev);
170 flush_delayed_work(&priv->led_off);
171 led->dev = NULL;
172}
173
174void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
175{
176 struct rtl8187_priv *priv = dev->priv;
177 char name[RTL8187_LED_MAX_NAME_LEN + 1];
178 u8 ledpin;
179 int err;
180
181 /* According to the vendor driver, the LED operation depends on the
182 * customer ID encoded in the EEPROM
183 */
184 printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid);
185 switch (custid) {
186 case EEPROM_CID_RSVD0:
187 case EEPROM_CID_RSVD1:
188 case EEPROM_CID_SERCOMM_PS:
189 case EEPROM_CID_QMI:
190 case EEPROM_CID_DELL:
191 case EEPROM_CID_TOSHIBA:
192 ledpin = LED_PIN_GPIO0;
193 break;
194 case EEPROM_CID_ALPHA0:
195 ledpin = LED_PIN_LED0;
196 break;
197 case EEPROM_CID_HW:
198 ledpin = LED_PIN_HW;
199 break;
200 default:
201 ledpin = LED_PIN_GPIO0;
202 }
203
204 INIT_DELAYED_WORK(&priv->led_on, led_turn_on);
205 INIT_DELAYED_WORK(&priv->led_off, led_turn_off);
206
207 snprintf(name, sizeof(name),
208 "rtl8187-%s::radio", wiphy_name(dev->wiphy));
209 err = rtl8187_register_led(dev, &priv->led_radio, name,
210 ieee80211_get_radio_led_name(dev), ledpin, true);
211 if (err)
212 return;
213
214 snprintf(name, sizeof(name),
215 "rtl8187-%s::tx", wiphy_name(dev->wiphy));
216 err = rtl8187_register_led(dev, &priv->led_tx, name,
217 ieee80211_get_tx_led_name(dev), ledpin, false);
218 if (err)
219 goto err_tx;
220
221 snprintf(name, sizeof(name),
222 "rtl8187-%s::rx", wiphy_name(dev->wiphy));
223 err = rtl8187_register_led(dev, &priv->led_rx, name,
224 ieee80211_get_rx_led_name(dev), ledpin, false);
225 if (!err)
226 return;
227
228 /* registration of RX LED failed - unregister */
229 rtl8187_unregister_led(&priv->led_tx);
230err_tx:
231 rtl8187_unregister_led(&priv->led_radio);
232}
233
234void rtl8187_leds_exit(struct ieee80211_hw *dev)
235{
236 struct rtl8187_priv *priv = dev->priv;
237
238 rtl8187_unregister_led(&priv->led_radio);
239 rtl8187_unregister_led(&priv->led_rx);
240 rtl8187_unregister_led(&priv->led_tx);
241 cancel_delayed_work_sync(&priv->led_off);
242 cancel_delayed_work_sync(&priv->led_on);
243}
244#endif /* def CONFIG_RTL8187_LEDS */
245
diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.h b/drivers/net/wireless/rtl818x/rtl8187/leds.h
new file mode 100644
index 000000000000..d743c96d4a20
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/leds.h
@@ -0,0 +1,59 @@
1/*
2 * Definitions for RTL8187 leds
3 *
4 * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
5 *
6 * Based on the LED handling in the r8187 driver, which is:
7 * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef RTL8187_LED_H
15#define RTL8187_LED_H
16
17#ifdef CONFIG_RTL8187_LEDS
18
19#define RTL8187_LED_MAX_NAME_LEN 21
20
21#include <linux/leds.h>
22#include <linux/types.h>
23
24enum {
25 LED_PIN_LED0,
26 LED_PIN_LED1,
27 LED_PIN_GPIO0,
28 LED_PIN_HW
29};
30
31enum {
32 EEPROM_CID_RSVD0 = 0x00,
33 EEPROM_CID_RSVD1 = 0xFF,
34 EEPROM_CID_ALPHA0 = 0x01,
35 EEPROM_CID_SERCOMM_PS = 0x02,
36 EEPROM_CID_HW = 0x03,
37 EEPROM_CID_TOSHIBA = 0x04,
38 EEPROM_CID_QMI = 0x07,
39 EEPROM_CID_DELL = 0x08
40};
41
42struct rtl8187_led {
43 struct ieee80211_hw *dev;
44 /* The LED class device */
45 struct led_classdev led_dev;
46 /* The pin/method used to control the led */
47 u8 ledpin;
48 /* The unique name string for this LED device. */
49 char name[RTL8187_LED_MAX_NAME_LEN + 1];
50 /* If the LED is radio or tx/rx */
51 bool is_radio;
52};
53
54void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);
55void rtl8187_leds_exit(struct ieee80211_hw *dev);
56
57#endif /* def CONFIG_RTL8187_LEDS */
58
59#endif /* RTL8187_LED_H */
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rfkill.c b/drivers/net/wireless/rtl818x/rtl8187/rfkill.c
new file mode 100644
index 000000000000..34116719974a
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/rfkill.c
@@ -0,0 +1,64 @@
1/*
2 * Linux RFKILL support for RTL8187
3 *
4 * Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br>
5 *
6 * Based on the RFKILL handling in the r8187 driver, which is:
7 * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
8 *
9 * Thanks to Realtek for their support!
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/types.h>
17#include <linux/usb.h>
18#include <net/mac80211.h>
19
20#include "rtl8187.h"
21#include "rfkill.h"
22
23static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
24{
25 u8 gpio;
26
27 gpio = rtl818x_ioread8(priv, &priv->map->GPIO0);
28 rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask);
29 gpio = rtl818x_ioread8(priv, &priv->map->GPIO1);
30
31 return gpio & priv->rfkill_mask;
32}
33
34void rtl8187_rfkill_init(struct ieee80211_hw *hw)
35{
36 struct rtl8187_priv *priv = hw->priv;
37
38 priv->rfkill_off = rtl8187_is_radio_enabled(priv);
39 printk(KERN_INFO "rtl8187: wireless switch is %s\n",
40 priv->rfkill_off ? "on" : "off");
41 wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off);
42 wiphy_rfkill_start_polling(hw->wiphy);
43}
44
45void rtl8187_rfkill_poll(struct ieee80211_hw *hw)
46{
47 bool enabled;
48 struct rtl8187_priv *priv = hw->priv;
49
50 mutex_lock(&priv->conf_mutex);
51 enabled = rtl8187_is_radio_enabled(priv);
52 if (unlikely(enabled != priv->rfkill_off)) {
53 priv->rfkill_off = enabled;
54 printk(KERN_INFO "rtl8187: wireless radio switch turned %s\n",
55 enabled ? "on" : "off");
56 wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
57 }
58 mutex_unlock(&priv->conf_mutex);
59}
60
61void rtl8187_rfkill_exit(struct ieee80211_hw *hw)
62{
63 wiphy_rfkill_stop_polling(hw->wiphy);
64}
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rfkill.h b/drivers/net/wireless/rtl818x/rtl8187/rfkill.h
new file mode 100644
index 000000000000..e12575e96d11
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/rfkill.h
@@ -0,0 +1,8 @@
1#ifndef RTL8187_RFKILL_H
2#define RTL8187_RFKILL_H
3
4void rtl8187_rfkill_init(struct ieee80211_hw *hw);
5void rtl8187_rfkill_poll(struct ieee80211_hw *hw);
6void rtl8187_rfkill_exit(struct ieee80211_hw *hw);
7
8#endif /* RTL8187_RFKILL_H */
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
new file mode 100644
index 000000000000..0d7b1423f77b
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
@@ -0,0 +1,271 @@
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#include "leds.h"
20
21#define RTL8187_EEPROM_TXPWR_BASE 0x05
22#define RTL8187_EEPROM_MAC_ADDR 0x07
23#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */
24#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */
25#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */
26#define RTL8187_EEPROM_SELECT_GPIO 0x3B
27
28#define RTL8187_REQT_READ 0xC0
29#define RTL8187_REQT_WRITE 0x40
30#define RTL8187_REQ_GET_REG 0x05
31#define RTL8187_REQ_SET_REG 0x05
32
33#define RTL8187_MAX_RX 0x9C4
34
35#define RFKILL_MASK_8187_89_97 0x2
36#define RFKILL_MASK_8198 0x4
37
38struct rtl8187_rx_info {
39 struct urb *urb;
40 struct ieee80211_hw *dev;
41};
42
43struct rtl8187_rx_hdr {
44 __le32 flags;
45 u8 noise;
46 u8 signal;
47 u8 agc;
48 u8 reserved;
49 __le64 mac_time;
50} __packed;
51
52struct rtl8187b_rx_hdr {
53 __le32 flags;
54 __le64 mac_time;
55 u8 sq;
56 u8 rssi;
57 u8 agc;
58 u8 flags2;
59 __le16 snr_long2end;
60 s8 pwdb_g12;
61 u8 fot;
62} __packed;
63
64/* {rtl8187,rtl8187b}_tx_info is in skb */
65
66struct rtl8187_tx_hdr {
67 __le32 flags;
68 __le16 rts_duration;
69 __le16 len;
70 __le32 retry;
71} __packed;
72
73struct rtl8187b_tx_hdr {
74 __le32 flags;
75 __le16 rts_duration;
76 __le16 len;
77 __le32 unused_1;
78 __le16 unused_2;
79 __le16 tx_duration;
80 __le32 unused_3;
81 __le32 retry;
82 __le32 unused_4[2];
83} __packed;
84
85enum {
86 DEVICE_RTL8187,
87 DEVICE_RTL8187B
88};
89
90struct rtl8187_priv {
91 /* common between rtl818x drivers */
92 struct rtl818x_csr *map;
93 const struct rtl818x_rf_ops *rf;
94 struct ieee80211_vif *vif;
95
96 /* The mutex protects the TX loopback state.
97 * Any attempt to set channels concurrently locks the device.
98 */
99 struct mutex conf_mutex;
100
101 /* rtl8187 specific */
102 struct ieee80211_channel channels[14];
103 struct ieee80211_rate rates[12];
104 struct ieee80211_supported_band band;
105 struct usb_device *udev;
106 u32 rx_conf;
107 struct usb_anchor anchored;
108 struct delayed_work work;
109 struct ieee80211_hw *dev;
110#ifdef CONFIG_RTL8187_LEDS
111 struct rtl8187_led led_radio;
112 struct rtl8187_led led_tx;
113 struct rtl8187_led led_rx;
114 struct delayed_work led_on;
115 struct delayed_work led_off;
116#endif
117 u16 txpwr_base;
118 u8 asic_rev;
119 u8 is_rtl8187b;
120 enum {
121 RTL8187BvB,
122 RTL8187BvD,
123 RTL8187BvE
124 } hw_rev;
125 struct sk_buff_head rx_queue;
126 u8 signal;
127 u8 noise;
128 u8 slot_time;
129 u8 aifsn[4];
130 u8 rfkill_mask;
131 struct {
132 __le64 buf;
133 struct sk_buff_head queue;
134 } b_tx_status; /* This queue is used by both -b and non-b devices */
135 struct mutex io_mutex;
136 union {
137 u8 bits8;
138 __le16 bits16;
139 __le32 bits32;
140 } *io_dmabuf;
141 bool rfkill_off;
142};
143
144void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
145
146static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv,
147 u8 *addr, u8 idx)
148{
149 u8 val;
150
151 mutex_lock(&priv->io_mutex);
152 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
153 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
154 (unsigned long)addr, idx & 0x03,
155 &priv->io_dmabuf->bits8, sizeof(val), HZ / 2);
156
157 val = priv->io_dmabuf->bits8;
158 mutex_unlock(&priv->io_mutex);
159
160 return val;
161}
162
163static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
164{
165 return rtl818x_ioread8_idx(priv, addr, 0);
166}
167
168static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv,
169 __le16 *addr, u8 idx)
170{
171 __le16 val;
172
173 mutex_lock(&priv->io_mutex);
174 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
175 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
176 (unsigned long)addr, idx & 0x03,
177 &priv->io_dmabuf->bits16, sizeof(val), HZ / 2);
178
179 val = priv->io_dmabuf->bits16;
180 mutex_unlock(&priv->io_mutex);
181
182 return le16_to_cpu(val);
183}
184
185static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
186{
187 return rtl818x_ioread16_idx(priv, addr, 0);
188}
189
190static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv,
191 __le32 *addr, u8 idx)
192{
193 __le32 val;
194
195 mutex_lock(&priv->io_mutex);
196 usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
197 RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
198 (unsigned long)addr, idx & 0x03,
199 &priv->io_dmabuf->bits32, sizeof(val), HZ / 2);
200
201 val = priv->io_dmabuf->bits32;
202 mutex_unlock(&priv->io_mutex);
203
204 return le32_to_cpu(val);
205}
206
207static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
208{
209 return rtl818x_ioread32_idx(priv, addr, 0);
210}
211
212static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv,
213 u8 *addr, u8 val, u8 idx)
214{
215 mutex_lock(&priv->io_mutex);
216
217 priv->io_dmabuf->bits8 = val;
218 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
219 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
220 (unsigned long)addr, idx & 0x03,
221 &priv->io_dmabuf->bits8, sizeof(val), HZ / 2);
222
223 mutex_unlock(&priv->io_mutex);
224}
225
226static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val)
227{
228 rtl818x_iowrite8_idx(priv, addr, val, 0);
229}
230
231static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv,
232 __le16 *addr, u16 val, u8 idx)
233{
234 mutex_lock(&priv->io_mutex);
235
236 priv->io_dmabuf->bits16 = cpu_to_le16(val);
237 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
238 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
239 (unsigned long)addr, idx & 0x03,
240 &priv->io_dmabuf->bits16, sizeof(val), HZ / 2);
241
242 mutex_unlock(&priv->io_mutex);
243}
244
245static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr,
246 u16 val)
247{
248 rtl818x_iowrite16_idx(priv, addr, val, 0);
249}
250
251static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv,
252 __le32 *addr, u32 val, u8 idx)
253{
254 mutex_lock(&priv->io_mutex);
255
256 priv->io_dmabuf->bits32 = cpu_to_le32(val);
257 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
258 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
259 (unsigned long)addr, idx & 0x03,
260 &priv->io_dmabuf->bits32, sizeof(val), HZ / 2);
261
262 mutex_unlock(&priv->io_mutex);
263}
264
265static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr,
266 u32 val)
267{
268 rtl818x_iowrite32_idx(priv, addr, val, 0);
269}
270
271#endif /* RTL8187_H */
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
new file mode 100644
index 000000000000..908903f721f5
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8225.c
@@ -0,0 +1,961 @@
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 "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 mutex_lock(&priv->io_mutex);
92
93 priv->io_dmabuf->bits16 = data;
94 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
95 RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
96 addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data),
97 HZ / 2);
98
99 mutex_unlock(&priv->io_mutex);
100
101 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
102 udelay(10);
103
104 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
105 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
106}
107
108static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
109{
110 struct rtl8187_priv *priv = dev->priv;
111
112 if (priv->asic_rev)
113 rtl8225_write_8051(dev, addr, cpu_to_le16(data));
114 else
115 rtl8225_write_bitbang(dev, addr, data);
116}
117
118static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
119{
120 struct rtl8187_priv *priv = dev->priv;
121 u16 reg80, reg82, reg84, out;
122 int i;
123
124 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
125 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
126 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
127
128 reg80 &= ~0xF;
129
130 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
131 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
132
133 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
134 udelay(4);
135 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
136 udelay(5);
137
138 for (i = 4; i >= 0; i--) {
139 u16 reg = reg80 | ((addr >> i) & 1);
140
141 if (!(i & 1)) {
142 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
143 udelay(1);
144 }
145
146 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
147 reg | (1 << 1));
148 udelay(2);
149 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
150 reg | (1 << 1));
151 udelay(2);
152
153 if (i & 1) {
154 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
155 udelay(1);
156 }
157 }
158
159 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
160 reg80 | (1 << 3) | (1 << 1));
161 udelay(2);
162 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
163 reg80 | (1 << 3));
164 udelay(2);
165 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
166 reg80 | (1 << 3));
167 udelay(2);
168
169 out = 0;
170 for (i = 11; i >= 0; i--) {
171 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
172 reg80 | (1 << 3));
173 udelay(1);
174 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
175 reg80 | (1 << 3) | (1 << 1));
176 udelay(2);
177 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
178 reg80 | (1 << 3) | (1 << 1));
179 udelay(2);
180 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
181 reg80 | (1 << 3) | (1 << 1));
182 udelay(2);
183
184 if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
185 out |= 1 << i;
186
187 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
188 reg80 | (1 << 3));
189 udelay(2);
190 }
191
192 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
193 reg80 | (1 << 3) | (1 << 2));
194 udelay(2);
195
196 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
197 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
198 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
199
200 return out;
201}
202
203static const u16 rtl8225bcd_rxgain[] = {
204 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
205 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
206 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
207 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
208 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
209 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
210 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
211 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
212 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
213 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
214 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
215 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
216};
217
218static const u8 rtl8225_agc[] = {
219 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
220 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
221 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
222 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
223 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
224 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
225 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
226 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
227 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
228 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
229 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
230 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
231 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
232 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
233 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
234 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
235};
236
237static const u8 rtl8225_gain[] = {
238 0x23, 0x88, 0x7c, 0xa5, /* -82dBm */
239 0x23, 0x88, 0x7c, 0xb5, /* -82dBm */
240 0x23, 0x88, 0x7c, 0xc5, /* -82dBm */
241 0x33, 0x80, 0x79, 0xc5, /* -78dBm */
242 0x43, 0x78, 0x76, 0xc5, /* -74dBm */
243 0x53, 0x60, 0x73, 0xc5, /* -70dBm */
244 0x63, 0x58, 0x70, 0xc5, /* -66dBm */
245};
246
247static const u8 rtl8225_threshold[] = {
248 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
249};
250
251static const u8 rtl8225_tx_gain_cck_ofdm[] = {
252 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
253};
254
255static const u8 rtl8225_tx_power_cck[] = {
256 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
257 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
258 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
259 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
260 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
261 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
262};
263
264static const u8 rtl8225_tx_power_cck_ch14[] = {
265 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
266 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
267 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
268 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
269 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
270 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
271};
272
273static const u8 rtl8225_tx_power_ofdm[] = {
274 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
275};
276
277static const u32 rtl8225_chan[] = {
278 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
279 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
280};
281
282static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
283{
284 struct rtl8187_priv *priv = dev->priv;
285 u8 cck_power, ofdm_power;
286 const u8 *tmp;
287 u32 reg;
288 int i;
289
290 cck_power = priv->channels[channel - 1].hw_value & 0xF;
291 ofdm_power = priv->channels[channel - 1].hw_value >> 4;
292
293 cck_power = min(cck_power, (u8)11);
294 if (ofdm_power > (u8)15)
295 ofdm_power = 25;
296 else
297 ofdm_power += 10;
298
299 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
300 rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
301
302 if (channel == 14)
303 tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
304 else
305 tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
306
307 for (i = 0; i < 8; i++)
308 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
309
310 msleep(1); // FIXME: optional?
311
312 /* anaparam2 on */
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->ANAPARAM2,
318 RTL8187_RTL8225_ANAPARAM2_ON);
319 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
320 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
321 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
322
323 rtl8225_write_phy_ofdm(dev, 2, 0x42);
324 rtl8225_write_phy_ofdm(dev, 6, 0x00);
325 rtl8225_write_phy_ofdm(dev, 8, 0x00);
326
327 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
328 rtl8225_tx_gain_cck_ofdm[ofdm_power / 6] >> 1);
329
330 tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
331
332 rtl8225_write_phy_ofdm(dev, 5, *tmp);
333 rtl8225_write_phy_ofdm(dev, 7, *tmp);
334
335 msleep(1);
336}
337
338static void rtl8225_rf_init(struct ieee80211_hw *dev)
339{
340 struct rtl8187_priv *priv = dev->priv;
341 int i;
342
343 rtl8225_write(dev, 0x0, 0x067);
344 rtl8225_write(dev, 0x1, 0xFE0);
345 rtl8225_write(dev, 0x2, 0x44D);
346 rtl8225_write(dev, 0x3, 0x441);
347 rtl8225_write(dev, 0x4, 0x486);
348 rtl8225_write(dev, 0x5, 0xBC0);
349 rtl8225_write(dev, 0x6, 0xAE6);
350 rtl8225_write(dev, 0x7, 0x82A);
351 rtl8225_write(dev, 0x8, 0x01F);
352 rtl8225_write(dev, 0x9, 0x334);
353 rtl8225_write(dev, 0xA, 0xFD4);
354 rtl8225_write(dev, 0xB, 0x391);
355 rtl8225_write(dev, 0xC, 0x050);
356 rtl8225_write(dev, 0xD, 0x6DB);
357 rtl8225_write(dev, 0xE, 0x029);
358 rtl8225_write(dev, 0xF, 0x914); msleep(100);
359
360 rtl8225_write(dev, 0x2, 0xC4D); msleep(200);
361 rtl8225_write(dev, 0x2, 0x44D); msleep(200);
362
363 if (!(rtl8225_read(dev, 6) & (1 << 7))) {
364 rtl8225_write(dev, 0x02, 0x0c4d);
365 msleep(200);
366 rtl8225_write(dev, 0x02, 0x044d);
367 msleep(100);
368 if (!(rtl8225_read(dev, 6) & (1 << 7)))
369 wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n",
370 rtl8225_read(dev, 6));
371 }
372
373 rtl8225_write(dev, 0x0, 0x127);
374
375 for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
376 rtl8225_write(dev, 0x1, i + 1);
377 rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
378 }
379
380 rtl8225_write(dev, 0x0, 0x027);
381 rtl8225_write(dev, 0x0, 0x22F);
382
383 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
384 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
385 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
386 }
387
388 msleep(1);
389
390 rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
391 rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
392 rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
393 rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
394 rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
395 rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
396 rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
397 rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
398 rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
399 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
400 rtl8225_write_phy_ofdm(dev, 0x0a, 0x09);
401 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
402 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
403 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
404 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
405 rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
406 rtl8225_write_phy_ofdm(dev, 0x11, 0x06);
407 rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
408 rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
409 rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
410 rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
411 rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
412 rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
413 rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
414 rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
415 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
416 rtl8225_write_phy_ofdm(dev, 0x1b, 0x76);
417 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
418 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
419 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
420 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
421 rtl8225_write_phy_ofdm(dev, 0x21, 0x27);
422 rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
423 rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
424 rtl8225_write_phy_ofdm(dev, 0x25, 0x20);
425 rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
426 rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
427
428 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
429 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
430 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
431 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
432
433 rtl8225_write_phy_cck(dev, 0x00, 0x98);
434 rtl8225_write_phy_cck(dev, 0x03, 0x20);
435 rtl8225_write_phy_cck(dev, 0x04, 0x7e);
436 rtl8225_write_phy_cck(dev, 0x05, 0x12);
437 rtl8225_write_phy_cck(dev, 0x06, 0xfc);
438 rtl8225_write_phy_cck(dev, 0x07, 0x78);
439 rtl8225_write_phy_cck(dev, 0x08, 0x2e);
440 rtl8225_write_phy_cck(dev, 0x10, 0x9b);
441 rtl8225_write_phy_cck(dev, 0x11, 0x88);
442 rtl8225_write_phy_cck(dev, 0x12, 0x47);
443 rtl8225_write_phy_cck(dev, 0x13, 0xd0);
444 rtl8225_write_phy_cck(dev, 0x19, 0x00);
445 rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
446 rtl8225_write_phy_cck(dev, 0x1b, 0x08);
447 rtl8225_write_phy_cck(dev, 0x40, 0x86);
448 rtl8225_write_phy_cck(dev, 0x41, 0x8d);
449 rtl8225_write_phy_cck(dev, 0x42, 0x15);
450 rtl8225_write_phy_cck(dev, 0x43, 0x18);
451 rtl8225_write_phy_cck(dev, 0x44, 0x1f);
452 rtl8225_write_phy_cck(dev, 0x45, 0x1e);
453 rtl8225_write_phy_cck(dev, 0x46, 0x1a);
454 rtl8225_write_phy_cck(dev, 0x47, 0x15);
455 rtl8225_write_phy_cck(dev, 0x48, 0x10);
456 rtl8225_write_phy_cck(dev, 0x49, 0x0a);
457 rtl8225_write_phy_cck(dev, 0x4a, 0x05);
458 rtl8225_write_phy_cck(dev, 0x4b, 0x02);
459 rtl8225_write_phy_cck(dev, 0x4c, 0x05);
460
461 rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D);
462
463 rtl8225_rf_set_tx_power(dev, 1);
464
465 /* RX antenna default to A */
466 rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */
467 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */
468
469 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
470 msleep(1);
471 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
472
473 /* set sensitivity */
474 rtl8225_write(dev, 0x0c, 0x50);
475 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
476 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
477 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
478 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
479 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
480}
481
482static const u8 rtl8225z2_agc[] = {
483 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f,
484 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
485 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f,
486 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
487 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
488 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
489 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28,
490 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
491 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30,
492 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
493 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
494};
495static const u8 rtl8225z2_ofdm[] = {
496 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
497 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
498 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
499 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
500 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
501 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
502 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
503 0x6d, 0x3c, 0xfb, 0x07
504};
505
506static const u8 rtl8225z2_tx_power_cck_ch14[] = {
507 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
508 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
509 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
510 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
511};
512
513static const u8 rtl8225z2_tx_power_cck[] = {
514 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
515 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
516 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
517 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
518};
519
520static const u8 rtl8225z2_tx_power_ofdm[] = {
521 0x42, 0x00, 0x40, 0x00, 0x40
522};
523
524static const u8 rtl8225z2_tx_gain_cck_ofdm[] = {
525 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
526 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
527 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
528 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
529 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
530 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
531};
532
533static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
534{
535 struct rtl8187_priv *priv = dev->priv;
536 u8 cck_power, ofdm_power;
537 const u8 *tmp;
538 u32 reg;
539 int i;
540
541 cck_power = priv->channels[channel - 1].hw_value & 0xF;
542 ofdm_power = priv->channels[channel - 1].hw_value >> 4;
543
544 cck_power = min(cck_power, (u8)15);
545 cck_power += priv->txpwr_base & 0xF;
546 cck_power = min(cck_power, (u8)35);
547
548 if (ofdm_power > (u8)15)
549 ofdm_power = 25;
550 else
551 ofdm_power += 10;
552 ofdm_power += priv->txpwr_base >> 4;
553 ofdm_power = min(ofdm_power, (u8)35);
554
555 if (channel == 14)
556 tmp = rtl8225z2_tx_power_cck_ch14;
557 else
558 tmp = rtl8225z2_tx_power_cck;
559
560 for (i = 0; i < 8; i++)
561 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
562
563 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
564 rtl8225z2_tx_gain_cck_ofdm[cck_power]);
565 msleep(1);
566
567 /* anaparam2 on */
568 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
569 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
570 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
571 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
572 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
573 RTL8187_RTL8225_ANAPARAM2_ON);
574 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
575 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
576 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
577
578 rtl8225_write_phy_ofdm(dev, 2, 0x42);
579 rtl8225_write_phy_ofdm(dev, 5, 0x00);
580 rtl8225_write_phy_ofdm(dev, 6, 0x40);
581 rtl8225_write_phy_ofdm(dev, 7, 0x00);
582 rtl8225_write_phy_ofdm(dev, 8, 0x40);
583
584 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
585 rtl8225z2_tx_gain_cck_ofdm[ofdm_power]);
586 msleep(1);
587}
588
589static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
590{
591 struct rtl8187_priv *priv = dev->priv;
592 u8 cck_power, ofdm_power;
593 const u8 *tmp;
594 int i;
595
596 cck_power = priv->channels[channel - 1].hw_value & 0xF;
597 ofdm_power = priv->channels[channel - 1].hw_value >> 4;
598
599 if (cck_power > 15)
600 cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22;
601 else
602 cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
603 cck_power += priv->txpwr_base & 0xF;
604 cck_power = min(cck_power, (u8)35);
605
606 if (ofdm_power > 15)
607 ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25;
608 else
609 ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10;
610 ofdm_power += (priv->txpwr_base >> 4) & 0xF;
611 ofdm_power = min(ofdm_power, (u8)35);
612
613 if (channel == 14)
614 tmp = rtl8225z2_tx_power_cck_ch14;
615 else
616 tmp = rtl8225z2_tx_power_cck;
617
618 if (priv->hw_rev == RTL8187BvB) {
619 if (cck_power <= 6)
620 ; /* do nothing */
621 else if (cck_power <= 11)
622 tmp += 8;
623 else
624 tmp += 16;
625 } else {
626 if (cck_power <= 5)
627 ; /* do nothing */
628 else if (cck_power <= 11)
629 tmp += 8;
630 else if (cck_power <= 17)
631 tmp += 16;
632 else
633 tmp += 24;
634 }
635
636 for (i = 0; i < 8; i++)
637 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
638
639 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
640 rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1);
641 msleep(1);
642
643 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
644 rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1);
645 if (priv->hw_rev == RTL8187BvB) {
646 if (ofdm_power <= 11) {
647 rtl8225_write_phy_ofdm(dev, 0x87, 0x60);
648 rtl8225_write_phy_ofdm(dev, 0x89, 0x60);
649 } else {
650 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
651 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
652 }
653 } else {
654 if (ofdm_power <= 11) {
655 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
656 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
657 } else if (ofdm_power <= 17) {
658 rtl8225_write_phy_ofdm(dev, 0x87, 0x54);
659 rtl8225_write_phy_ofdm(dev, 0x89, 0x54);
660 } else {
661 rtl8225_write_phy_ofdm(dev, 0x87, 0x50);
662 rtl8225_write_phy_ofdm(dev, 0x89, 0x50);
663 }
664 }
665 msleep(1);
666}
667
668static const u16 rtl8225z2_rxgain[] = {
669 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
670 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
671 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
672 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
673 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
674 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
675 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
676 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
677 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
678 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
679 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
680 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
681};
682
683static const u8 rtl8225z2_gain_bg[] = {
684 0x23, 0x15, 0xa5, /* -82-1dBm */
685 0x23, 0x15, 0xb5, /* -82-2dBm */
686 0x23, 0x15, 0xc5, /* -82-3dBm */
687 0x33, 0x15, 0xc5, /* -78dBm */
688 0x43, 0x15, 0xc5, /* -74dBm */
689 0x53, 0x15, 0xc5, /* -70dBm */
690 0x63, 0x15, 0xc5 /* -66dBm */
691};
692
693static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
694{
695 struct rtl8187_priv *priv = dev->priv;
696 int i;
697
698 rtl8225_write(dev, 0x0, 0x2BF);
699 rtl8225_write(dev, 0x1, 0xEE0);
700 rtl8225_write(dev, 0x2, 0x44D);
701 rtl8225_write(dev, 0x3, 0x441);
702 rtl8225_write(dev, 0x4, 0x8C3);
703 rtl8225_write(dev, 0x5, 0xC72);
704 rtl8225_write(dev, 0x6, 0x0E6);
705 rtl8225_write(dev, 0x7, 0x82A);
706 rtl8225_write(dev, 0x8, 0x03F);
707 rtl8225_write(dev, 0x9, 0x335);
708 rtl8225_write(dev, 0xa, 0x9D4);
709 rtl8225_write(dev, 0xb, 0x7BB);
710 rtl8225_write(dev, 0xc, 0x850);
711 rtl8225_write(dev, 0xd, 0xCDF);
712 rtl8225_write(dev, 0xe, 0x02B);
713 rtl8225_write(dev, 0xf, 0x114);
714 msleep(100);
715
716 rtl8225_write(dev, 0x0, 0x1B7);
717
718 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
719 rtl8225_write(dev, 0x1, i + 1);
720 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
721 }
722
723 rtl8225_write(dev, 0x3, 0x080);
724 rtl8225_write(dev, 0x5, 0x004);
725 rtl8225_write(dev, 0x0, 0x0B7);
726 rtl8225_write(dev, 0x2, 0xc4D);
727
728 msleep(200);
729 rtl8225_write(dev, 0x2, 0x44D);
730 msleep(100);
731
732 if (!(rtl8225_read(dev, 6) & (1 << 7))) {
733 rtl8225_write(dev, 0x02, 0x0C4D);
734 msleep(200);
735 rtl8225_write(dev, 0x02, 0x044D);
736 msleep(100);
737 if (!(rtl8225_read(dev, 6) & (1 << 7)))
738 wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n",
739 rtl8225_read(dev, 6));
740 }
741
742 msleep(200);
743
744 rtl8225_write(dev, 0x0, 0x2BF);
745
746 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
747 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
748 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
749 }
750
751 msleep(1);
752
753 rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
754 rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
755 rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
756 rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
757 rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
758 rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
759 rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
760 rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
761 rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
762 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
763 rtl8225_write_phy_ofdm(dev, 0x0a, 0x08);
764 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
765 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
766 rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
767 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
768 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
769 rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
770 rtl8225_write_phy_ofdm(dev, 0x11, 0x07);
771 rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
772 rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
773 rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
774 rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
775 rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
776 rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
777 rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
778 rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
779 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
780 rtl8225_write_phy_ofdm(dev, 0x1b, 0x15);
781 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
782 rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5);
783 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
784 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
785 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
786 rtl8225_write_phy_ofdm(dev, 0x21, 0x17);
787 rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
788 rtl8225_write_phy_ofdm(dev, 0x23, 0x80);
789 rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
790 rtl8225_write_phy_ofdm(dev, 0x25, 0x00);
791 rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
792 rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
793
794 rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
795 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
796 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
797 rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
798
799 rtl8225_write_phy_cck(dev, 0x00, 0x98);
800 rtl8225_write_phy_cck(dev, 0x03, 0x20);
801 rtl8225_write_phy_cck(dev, 0x04, 0x7e);
802 rtl8225_write_phy_cck(dev, 0x05, 0x12);
803 rtl8225_write_phy_cck(dev, 0x06, 0xfc);
804 rtl8225_write_phy_cck(dev, 0x07, 0x78);
805 rtl8225_write_phy_cck(dev, 0x08, 0x2e);
806 rtl8225_write_phy_cck(dev, 0x10, 0x9b);
807 rtl8225_write_phy_cck(dev, 0x11, 0x88);
808 rtl8225_write_phy_cck(dev, 0x12, 0x47);
809 rtl8225_write_phy_cck(dev, 0x13, 0xd0);
810 rtl8225_write_phy_cck(dev, 0x19, 0x00);
811 rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
812 rtl8225_write_phy_cck(dev, 0x1b, 0x08);
813 rtl8225_write_phy_cck(dev, 0x40, 0x86);
814 rtl8225_write_phy_cck(dev, 0x41, 0x8d);
815 rtl8225_write_phy_cck(dev, 0x42, 0x15);
816 rtl8225_write_phy_cck(dev, 0x43, 0x18);
817 rtl8225_write_phy_cck(dev, 0x44, 0x36);
818 rtl8225_write_phy_cck(dev, 0x45, 0x35);
819 rtl8225_write_phy_cck(dev, 0x46, 0x2e);
820 rtl8225_write_phy_cck(dev, 0x47, 0x25);
821 rtl8225_write_phy_cck(dev, 0x48, 0x1c);
822 rtl8225_write_phy_cck(dev, 0x49, 0x12);
823 rtl8225_write_phy_cck(dev, 0x4a, 0x09);
824 rtl8225_write_phy_cck(dev, 0x4b, 0x04);
825 rtl8225_write_phy_cck(dev, 0x4c, 0x05);
826
827 rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
828
829 rtl8225z2_rf_set_tx_power(dev, 1);
830
831 /* RX antenna default to A */
832 rtl8225_write_phy_cck(dev, 0x10, 0x9b); /* B: 0xDB */
833 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); /* B: 0x10 */
834
835 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */
836 msleep(1);
837 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
838}
839
840static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
841{
842 struct rtl8187_priv *priv = dev->priv;
843 int i;
844
845 rtl8225_write(dev, 0x0, 0x0B7);
846 rtl8225_write(dev, 0x1, 0xEE0);
847 rtl8225_write(dev, 0x2, 0x44D);
848 rtl8225_write(dev, 0x3, 0x441);
849 rtl8225_write(dev, 0x4, 0x8C3);
850 rtl8225_write(dev, 0x5, 0xC72);
851 rtl8225_write(dev, 0x6, 0x0E6);
852 rtl8225_write(dev, 0x7, 0x82A);
853 rtl8225_write(dev, 0x8, 0x03F);
854 rtl8225_write(dev, 0x9, 0x335);
855 rtl8225_write(dev, 0xa, 0x9D4);
856 rtl8225_write(dev, 0xb, 0x7BB);
857 rtl8225_write(dev, 0xc, 0x850);
858 rtl8225_write(dev, 0xd, 0xCDF);
859 rtl8225_write(dev, 0xe, 0x02B);
860 rtl8225_write(dev, 0xf, 0x114);
861
862 rtl8225_write(dev, 0x0, 0x1B7);
863
864 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
865 rtl8225_write(dev, 0x1, i + 1);
866 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
867 }
868
869 rtl8225_write(dev, 0x3, 0x080);
870 rtl8225_write(dev, 0x5, 0x004);
871 rtl8225_write(dev, 0x0, 0x0B7);
872
873 rtl8225_write(dev, 0x2, 0xC4D);
874
875 rtl8225_write(dev, 0x2, 0x44D);
876 rtl8225_write(dev, 0x0, 0x2BF);
877
878 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
879 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
880 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
881
882 rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
883 for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
884 rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]);
885 rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i);
886 rtl8225_write_phy_ofdm(dev, 0xE, 0);
887 }
888 rtl8225_write_phy_ofdm(dev, 0x80, 0x10);
889
890 for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
891 rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
892
893 rtl8225_write_phy_ofdm(dev, 0x97, 0x46);
894 rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6);
895 rtl8225_write_phy_ofdm(dev, 0x85, 0xfc);
896 rtl8225_write_phy_cck(dev, 0xc1, 0x88);
897}
898
899static void rtl8225_rf_stop(struct ieee80211_hw *dev)
900{
901 rtl8225_write(dev, 0x4, 0x1f);
902}
903
904static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
905 struct ieee80211_conf *conf)
906{
907 struct rtl8187_priv *priv = dev->priv;
908 int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
909
910 if (priv->rf->init == rtl8225_rf_init)
911 rtl8225_rf_set_tx_power(dev, chan);
912 else if (priv->rf->init == rtl8225z2_rf_init)
913 rtl8225z2_rf_set_tx_power(dev, chan);
914 else
915 rtl8225z2_b_rf_set_tx_power(dev, chan);
916
917 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
918 msleep(10);
919}
920
921static const struct rtl818x_rf_ops rtl8225_ops = {
922 .name = "rtl8225",
923 .init = rtl8225_rf_init,
924 .stop = rtl8225_rf_stop,
925 .set_chan = rtl8225_rf_set_channel
926};
927
928static const struct rtl818x_rf_ops rtl8225z2_ops = {
929 .name = "rtl8225z2",
930 .init = rtl8225z2_rf_init,
931 .stop = rtl8225_rf_stop,
932 .set_chan = rtl8225_rf_set_channel
933};
934
935static const struct rtl818x_rf_ops rtl8225z2_b_ops = {
936 .name = "rtl8225z2",
937 .init = rtl8225z2_b_rf_init,
938 .stop = rtl8225_rf_stop,
939 .set_chan = rtl8225_rf_set_channel
940};
941
942const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
943{
944 u16 reg8, reg9;
945 struct rtl8187_priv *priv = dev->priv;
946
947 if (!priv->is_rtl8187b) {
948 rtl8225_write(dev, 0, 0x1B7);
949
950 reg8 = rtl8225_read(dev, 8);
951 reg9 = rtl8225_read(dev, 9);
952
953 rtl8225_write(dev, 0, 0x0B7);
954
955 if (reg8 != 0x588 || reg9 != 0x700)
956 return &rtl8225_ops;
957
958 return &rtl8225z2_ops;
959 } else
960 return &rtl8225z2_b_ops;
961}
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 */