aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl818x
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtl818x')
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180.h1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c41
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h9
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c53
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.c74
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.h4
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rfkill.c4
7 files changed, 116 insertions, 70 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180.h
index 8721282a8185..de3844fe06d8 100644
--- a/drivers/net/wireless/rtl818x/rtl8180.h
+++ b/drivers/net/wireless/rtl818x/rtl8180.h
@@ -60,7 +60,6 @@ struct rtl8180_priv {
60 struct rtl818x_csr __iomem *map; 60 struct rtl818x_csr __iomem *map;
61 const struct rtl818x_rf_ops *rf; 61 const struct rtl818x_rf_ops *rf;
62 struct ieee80211_vif *vif; 62 struct ieee80211_vif *vif;
63 int mode;
64 63
65 /* rtl8180 driver specific */ 64 /* rtl8180 driver specific */
66 spinlock_t lock; 65 spinlock_t lock;
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 16429c49139c..2131a442831a 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/slab.h>
20#include <linux/delay.h> 21#include <linux/delay.h>
21#include <linux/etherdevice.h> 22#include <linux/etherdevice.h>
22#include <linux/eeprom_93cx6.h> 23#include <linux/eeprom_93cx6.h>
@@ -33,7 +34,7 @@ MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
33MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver"); 34MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver");
34MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
35 36
36static struct pci_device_id rtl8180_table[] __devinitdata = { 37static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = {
37 /* rtl8185 */ 38 /* rtl8185 */
38 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) }, 39 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
39 { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) }, 40 { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) },
@@ -82,8 +83,6 @@ static const struct ieee80211_channel rtl818x_channels[] = {
82}; 83};
83 84
84 85
85
86
87void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) 86void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
88{ 87{
89 struct rtl8180_priv *priv = dev->priv; 88 struct rtl8180_priv *priv = dev->priv;
@@ -132,7 +131,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
132 131
133 rx_status.antenna = (flags2 >> 15) & 1; 132 rx_status.antenna = (flags2 >> 15) & 1;
134 /* TODO: improve signal/rssi reporting */ 133 /* TODO: improve signal/rssi reporting */
135 rx_status.qual = flags2 & 0xFF;
136 rx_status.signal = (flags2 >> 8) & 0x7F; 134 rx_status.signal = (flags2 >> 8) & 0x7F;
137 /* XXX: is this correct? */ 135 /* XXX: is this correct? */
138 rx_status.rate_idx = (flags >> 20) & 0xF; 136 rx_status.rate_idx = (flags >> 20) & 0xF;
@@ -548,7 +546,7 @@ static int rtl8180_start(struct ieee80211_hw *dev)
548 rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); 546 rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma);
549 rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); 547 rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma);
550 548
551 ret = request_irq(priv->pdev->irq, &rtl8180_interrupt, 549 ret = request_irq(priv->pdev->irq, rtl8180_interrupt,
552 IRQF_SHARED, KBUILD_MODNAME, dev); 550 IRQF_SHARED, KBUILD_MODNAME, dev);
553 if (ret) { 551 if (ret) {
554 printk(KERN_ERR "%s: failed to register IRQ handler\n", 552 printk(KERN_ERR "%s: failed to register IRQ handler\n",
@@ -616,7 +614,6 @@ static int rtl8180_start(struct ieee80211_hw *dev)
616 reg |= RTL818X_CMD_TX_ENABLE; 614 reg |= RTL818X_CMD_TX_ENABLE;
617 rtl818x_iowrite8(priv, &priv->map->CMD, reg); 615 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
618 616
619 priv->mode = NL80211_IFTYPE_MONITOR;
620 return 0; 617 return 0;
621 618
622 err_free_rings: 619 err_free_rings:
@@ -634,8 +631,6 @@ static void rtl8180_stop(struct ieee80211_hw *dev)
634 u8 reg; 631 u8 reg;
635 int i; 632 int i;
636 633
637 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
638
639 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); 634 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
640 635
641 reg = rtl818x_ioread8(priv, &priv->map->CMD); 636 reg = rtl818x_ioread8(priv, &priv->map->CMD);
@@ -658,38 +653,39 @@ static void rtl8180_stop(struct ieee80211_hw *dev)
658} 653}
659 654
660static int rtl8180_add_interface(struct ieee80211_hw *dev, 655static int rtl8180_add_interface(struct ieee80211_hw *dev,
661 struct ieee80211_if_init_conf *conf) 656 struct ieee80211_vif *vif)
662{ 657{
663 struct rtl8180_priv *priv = dev->priv; 658 struct rtl8180_priv *priv = dev->priv;
664 659
665 if (priv->mode != NL80211_IFTYPE_MONITOR) 660 /*
666 return -EOPNOTSUPP; 661 * We only support one active interface at a time.
662 */
663 if (priv->vif)
664 return -EBUSY;
667 665
668 switch (conf->type) { 666 switch (vif->type) {
669 case NL80211_IFTYPE_STATION: 667 case NL80211_IFTYPE_STATION:
670 priv->mode = conf->type;
671 break; 668 break;
672 default: 669 default:
673 return -EOPNOTSUPP; 670 return -EOPNOTSUPP;
674 } 671 }
675 672
676 priv->vif = conf->vif; 673 priv->vif = vif;
677 674
678 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 675 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
679 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0], 676 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
680 le32_to_cpu(*(__le32 *)conf->mac_addr)); 677 le32_to_cpu(*(__le32 *)vif->addr));
681 rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4], 678 rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4],
682 le16_to_cpu(*(__le16 *)(conf->mac_addr + 4))); 679 le16_to_cpu(*(__le16 *)(vif->addr + 4)));
683 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 680 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
684 681
685 return 0; 682 return 0;
686} 683}
687 684
688static void rtl8180_remove_interface(struct ieee80211_hw *dev, 685static void rtl8180_remove_interface(struct ieee80211_hw *dev,
689 struct ieee80211_if_init_conf *conf) 686 struct ieee80211_vif *vif)
690{ 687{
691 struct rtl8180_priv *priv = dev->priv; 688 struct rtl8180_priv *priv = dev->priv;
692 priv->mode = NL80211_IFTYPE_MONITOR;
693 priv->vif = NULL; 689 priv->vif = NULL;
694} 690}
695 691
@@ -766,6 +762,14 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
766 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); 762 rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
767} 763}
768 764
765static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
766{
767 struct rtl8180_priv *priv = dev->priv;
768
769 return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
770 (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
771}
772
769static const struct ieee80211_ops rtl8180_ops = { 773static const struct ieee80211_ops rtl8180_ops = {
770 .tx = rtl8180_tx, 774 .tx = rtl8180_tx,
771 .start = rtl8180_start, 775 .start = rtl8180_start,
@@ -776,6 +780,7 @@ static const struct ieee80211_ops rtl8180_ops = {
776 .bss_info_changed = rtl8180_bss_info_changed, 780 .bss_info_changed = rtl8180_bss_info_changed,
777 .prepare_multicast = rtl8180_prepare_multicast, 781 .prepare_multicast = rtl8180_prepare_multicast,
778 .configure_filter = rtl8180_configure_filter, 782 .configure_filter = rtl8180_configure_filter,
783 .get_tsf = rtl8180_get_tsf,
779}; 784};
780 785
781static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) 786static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index bf9175a8c1f4..6bb32112e65c 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -23,6 +23,7 @@
23#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */ 23#define RTL8187_EEPROM_TXPWR_CHAN_1 0x16 /* 3 channels */
24#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */ 24#define RTL8187_EEPROM_TXPWR_CHAN_6 0x1B /* 2 channels */
25#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */ 25#define RTL8187_EEPROM_TXPWR_CHAN_4 0x3D /* 2 channels */
26#define RTL8187_EEPROM_SELECT_GPIO 0x3B
26 27
27#define RTL8187_REQT_READ 0xC0 28#define RTL8187_REQT_READ 0xC0
28#define RTL8187_REQT_WRITE 0x40 29#define RTL8187_REQT_WRITE 0x40
@@ -31,6 +32,9 @@
31 32
32#define RTL8187_MAX_RX 0x9C4 33#define RTL8187_MAX_RX 0x9C4
33 34
35#define RFKILL_MASK_8187_89_97 0x2
36#define RFKILL_MASK_8198 0x4
37
34struct rtl8187_rx_info { 38struct rtl8187_rx_info {
35 struct urb *urb; 39 struct urb *urb;
36 struct ieee80211_hw *dev; 40 struct ieee80211_hw *dev;
@@ -88,7 +92,7 @@ struct rtl8187_priv {
88 struct rtl818x_csr *map; 92 struct rtl818x_csr *map;
89 const struct rtl818x_rf_ops *rf; 93 const struct rtl818x_rf_ops *rf;
90 struct ieee80211_vif *vif; 94 struct ieee80211_vif *vif;
91 int mode; 95
92 /* The mutex protects the TX loopback state. 96 /* The mutex protects the TX loopback state.
93 * Any attempt to set channels concurrently locks the device. 97 * Any attempt to set channels concurrently locks the device.
94 */ 98 */
@@ -104,6 +108,7 @@ struct rtl8187_priv {
104 struct delayed_work work; 108 struct delayed_work work;
105 struct ieee80211_hw *dev; 109 struct ieee80211_hw *dev;
106#ifdef CONFIG_RTL8187_LEDS 110#ifdef CONFIG_RTL8187_LEDS
111 struct rtl8187_led led_radio;
107 struct rtl8187_led led_tx; 112 struct rtl8187_led led_tx;
108 struct rtl8187_led led_rx; 113 struct rtl8187_led led_rx;
109 struct delayed_work led_on; 114 struct delayed_work led_on;
@@ -119,10 +124,10 @@ struct rtl8187_priv {
119 } hw_rev; 124 } hw_rev;
120 struct sk_buff_head rx_queue; 125 struct sk_buff_head rx_queue;
121 u8 signal; 126 u8 signal;
122 u8 quality;
123 u8 noise; 127 u8 noise;
124 u8 slot_time; 128 u8 slot_time;
125 u8 aifsn[4]; 129 u8 aifsn[4];
130 u8 rfkill_mask;
126 struct { 131 struct {
127 __le64 buf; 132 __le64 buf;
128 struct sk_buff_head queue; 133 struct sk_buff_head queue;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 2017ccc00145..1d30792973f5 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -22,6 +22,7 @@
22 22
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/usb.h> 24#include <linux/usb.h>
25#include <linux/slab.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
26#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
27#include <linux/eeprom_93cx6.h> 28#include <linux/eeprom_93cx6.h>
@@ -65,6 +66,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
65 /* Sitecom */ 66 /* Sitecom */
66 {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, 67 {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
67 {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, 68 {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
69 {USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B},
68 /* Sphairon Access Systems GmbH */ 70 /* Sphairon Access Systems GmbH */
69 {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, 71 {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187},
70 /* Dick Smith Electronics */ 72 /* Dick Smith Electronics */
@@ -320,7 +322,6 @@ static void rtl8187_rx_cb(struct urb *urb)
320 struct ieee80211_rx_status rx_status = { 0 }; 322 struct ieee80211_rx_status rx_status = { 0 };
321 int rate, signal; 323 int rate, signal;
322 u32 flags; 324 u32 flags;
323 u32 quality;
324 unsigned long f; 325 unsigned long f;
325 326
326 spin_lock_irqsave(&priv->rx_queue.lock, f); 327 spin_lock_irqsave(&priv->rx_queue.lock, f);
@@ -338,10 +339,9 @@ static void rtl8187_rx_cb(struct urb *urb)
338 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); 339 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
339 flags = le32_to_cpu(hdr->flags); 340 flags = le32_to_cpu(hdr->flags);
340 /* As with the RTL8187B below, the AGC is used to calculate 341 /* As with the RTL8187B below, the AGC is used to calculate
341 * signal strength and quality. In this case, the scaling 342 * signal strength. In this case, the scaling
342 * constants are derived from the output of p54usb. 343 * constants are derived from the output of p54usb.
343 */ 344 */
344 quality = 130 - ((41 * hdr->agc) >> 6);
345 signal = -4 - ((27 * hdr->agc) >> 6); 345 signal = -4 - ((27 * hdr->agc) >> 6);
346 rx_status.antenna = (hdr->signal >> 7) & 1; 346 rx_status.antenna = (hdr->signal >> 7) & 1;
347 rx_status.mactime = le64_to_cpu(hdr->mac_time); 347 rx_status.mactime = le64_to_cpu(hdr->mac_time);
@@ -354,23 +354,18 @@ static void rtl8187_rx_cb(struct urb *urb)
354 * In testing, none of these quantities show qualitative 354 * In testing, none of these quantities show qualitative
355 * agreement with AP signal strength, except for the AGC, 355 * agreement with AP signal strength, except for the AGC,
356 * which is inversely proportional to the strength of the 356 * which is inversely proportional to the strength of the
357 * signal. In the following, the quality and signal strength 357 * signal. In the following, the signal strength
358 * are derived from the AGC. The arbitrary scaling constants 358 * is derived from the AGC. The arbitrary scaling constants
359 * are chosen to make the results close to the values obtained 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 360 * for a BCM4312 using b43 as the driver. The noise is ignored
361 * for now. 361 * for now.
362 */ 362 */
363 flags = le32_to_cpu(hdr->flags); 363 flags = le32_to_cpu(hdr->flags);
364 quality = 170 - hdr->agc;
365 signal = 14 - hdr->agc / 2; 364 signal = 14 - hdr->agc / 2;
366 rx_status.antenna = (hdr->rssi >> 7) & 1; 365 rx_status.antenna = (hdr->rssi >> 7) & 1;
367 rx_status.mactime = le64_to_cpu(hdr->mac_time); 366 rx_status.mactime = le64_to_cpu(hdr->mac_time);
368 } 367 }
369 368
370 if (quality > 100)
371 quality = 100;
372 rx_status.qual = quality;
373 priv->quality = quality;
374 rx_status.signal = signal; 369 rx_status.signal = signal;
375 priv->signal = signal; 370 priv->signal = signal;
376 rate = (flags >> 20) & 0xF; 371 rate = (flags >> 20) & 0xF;
@@ -1025,31 +1020,30 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
1025} 1020}
1026 1021
1027static int rtl8187_add_interface(struct ieee80211_hw *dev, 1022static int rtl8187_add_interface(struct ieee80211_hw *dev,
1028 struct ieee80211_if_init_conf *conf) 1023 struct ieee80211_vif *vif)
1029{ 1024{
1030 struct rtl8187_priv *priv = dev->priv; 1025 struct rtl8187_priv *priv = dev->priv;
1031 int i; 1026 int i;
1032 int ret = -EOPNOTSUPP; 1027 int ret = -EOPNOTSUPP;
1033 1028
1034 mutex_lock(&priv->conf_mutex); 1029 mutex_lock(&priv->conf_mutex);
1035 if (priv->mode != NL80211_IFTYPE_MONITOR) 1030 if (priv->vif)
1036 goto exit; 1031 goto exit;
1037 1032
1038 switch (conf->type) { 1033 switch (vif->type) {
1039 case NL80211_IFTYPE_STATION: 1034 case NL80211_IFTYPE_STATION:
1040 priv->mode = conf->type;
1041 break; 1035 break;
1042 default: 1036 default:
1043 goto exit; 1037 goto exit;
1044 } 1038 }
1045 1039
1046 ret = 0; 1040 ret = 0;
1047 priv->vif = conf->vif; 1041 priv->vif = vif;
1048 1042
1049 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 1043 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1050 for (i = 0; i < ETH_ALEN; i++) 1044 for (i = 0; i < ETH_ALEN; i++)
1051 rtl818x_iowrite8(priv, &priv->map->MAC[i], 1045 rtl818x_iowrite8(priv, &priv->map->MAC[i],
1052 ((u8 *)conf->mac_addr)[i]); 1046 ((u8 *)vif->addr)[i]);
1053 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 1047 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1054 1048
1055exit: 1049exit:
@@ -1058,11 +1052,10 @@ exit:
1058} 1052}
1059 1053
1060static void rtl8187_remove_interface(struct ieee80211_hw *dev, 1054static void rtl8187_remove_interface(struct ieee80211_hw *dev,
1061 struct ieee80211_if_init_conf *conf) 1055 struct ieee80211_vif *vif)
1062{ 1056{
1063 struct rtl8187_priv *priv = dev->priv; 1057 struct rtl8187_priv *priv = dev->priv;
1064 mutex_lock(&priv->conf_mutex); 1058 mutex_lock(&priv->conf_mutex);
1065 priv->mode = NL80211_IFTYPE_MONITOR;
1066 priv->vif = NULL; 1059 priv->vif = NULL;
1067 mutex_unlock(&priv->conf_mutex); 1060 mutex_unlock(&priv->conf_mutex);
1068} 1061}
@@ -1274,6 +1267,14 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue,
1274 return 0; 1267 return 0;
1275} 1268}
1276 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
1277static const struct ieee80211_ops rtl8187_ops = { 1278static const struct ieee80211_ops rtl8187_ops = {
1278 .tx = rtl8187_tx, 1279 .tx = rtl8187_tx,
1279 .start = rtl8187_start, 1280 .start = rtl8187_start,
@@ -1285,7 +1286,8 @@ static const struct ieee80211_ops rtl8187_ops = {
1285 .prepare_multicast = rtl8187_prepare_multicast, 1286 .prepare_multicast = rtl8187_prepare_multicast,
1286 .configure_filter = rtl8187_configure_filter, 1287 .configure_filter = rtl8187_configure_filter,
1287 .conf_tx = rtl8187_conf_tx, 1288 .conf_tx = rtl8187_conf_tx,
1288 .rfkill_poll = rtl8187_rfkill_poll 1289 .rfkill_poll = rtl8187_rfkill_poll,
1290 .get_tsf = rtl8187_get_tsf,
1289}; 1291};
1290 1292
1291static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) 1293static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -1329,6 +1331,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1329 struct ieee80211_channel *channel; 1331 struct ieee80211_channel *channel;
1330 const char *chip_name; 1332 const char *chip_name;
1331 u16 txpwr, reg; 1333 u16 txpwr, reg;
1334 u16 product_id = le16_to_cpu(udev->descriptor.idProduct);
1332 int err, i; 1335 int err, i;
1333 1336
1334 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); 1337 dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
@@ -1371,7 +1374,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1371 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; 1374 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
1372 1375
1373 1376
1374 priv->mode = NL80211_IFTYPE_MONITOR;
1375 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1377 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1376 IEEE80211_HW_SIGNAL_DBM | 1378 IEEE80211_HW_SIGNAL_DBM |
1377 IEEE80211_HW_RX_INCLUDES_FCS; 1379 IEEE80211_HW_RX_INCLUDES_FCS;
@@ -1488,6 +1490,13 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1488 (*channel++).hw_value = txpwr & 0xFF; 1490 (*channel++).hw_value = txpwr & 0xFF;
1489 (*channel++).hw_value = txpwr >> 8; 1491 (*channel++).hw_value = txpwr >> 8;
1490 } 1492 }
1493 /* Handle the differing rfkill GPIO bit in different models */
1494 priv->rfkill_mask = RFKILL_MASK_8187_89_97;
1495 if (product_id == 0x8197 || product_id == 0x8198) {
1496 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_SELECT_GPIO, &reg);
1497 if (reg & 0xFF00)
1498 priv->rfkill_mask = RFKILL_MASK_8198;
1499 }
1491 1500
1492 /* 1501 /*
1493 * XXX: Once this driver supports anything that requires 1502 * XXX: Once this driver supports anything that requires
@@ -1516,9 +1525,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1516 mutex_init(&priv->conf_mutex); 1525 mutex_init(&priv->conf_mutex);
1517 skb_queue_head_init(&priv->b_tx_status.queue); 1526 skb_queue_head_init(&priv->b_tx_status.queue);
1518 1527
1519 printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s\n", 1528 printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
1520 wiphy_name(dev->wiphy), dev->wiphy->perm_addr, 1529 wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
1521 chip_name, priv->asic_rev, priv->rf->name); 1530 chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask);
1522 1531
1523#ifdef CONFIG_RTL8187_LEDS 1532#ifdef CONFIG_RTL8187_LEDS
1524 eeprom_93cx6_read(&eeprom, 0x3F, &reg); 1533 eeprom_93cx6_read(&eeprom, 0x3F, &reg);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
index cf8a4a40fdf6..4637337d5ce6 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -33,7 +33,7 @@ static void led_turn_on(struct work_struct *work)
33 struct rtl8187_led *led = &priv->led_tx; 33 struct rtl8187_led *led = &priv->led_tx;
34 34
35 /* Don't change the LED, when the device is down. */ 35 /* Don't change the LED, when the device is down. */
36 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) 36 if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED)
37 return ; 37 return ;
38 38
39 /* Skip if the LED is not registered. */ 39 /* Skip if the LED is not registered. */
@@ -71,7 +71,7 @@ static void led_turn_off(struct work_struct *work)
71 struct rtl8187_led *led = &priv->led_tx; 71 struct rtl8187_led *led = &priv->led_tx;
72 72
73 /* Don't change the LED, when the device is down. */ 73 /* Don't change the LED, when the device is down. */
74 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) 74 if (!priv->vif || priv->vif->type == NL80211_IFTYPE_UNSPECIFIED)
75 return ; 75 return ;
76 76
77 /* Skip if the LED is not registered. */ 77 /* Skip if the LED is not registered. */
@@ -105,19 +105,36 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
105 struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, 105 struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led,
106 led_dev); 106 led_dev);
107 struct ieee80211_hw *hw = led->dev; 107 struct ieee80211_hw *hw = led->dev;
108 struct rtl8187_priv *priv = hw->priv; 108 struct rtl8187_priv *priv;
109 static bool radio_on;
109 110
110 if (brightness == LED_OFF) { 111 if (!hw)
111 ieee80211_queue_delayed_work(hw, &priv->led_off, 0); 112 return;
112 /* The LED is off for 1/20 sec so that it just blinks. */ 113 priv = hw->priv;
113 ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20); 114 if (led->is_radio) {
114 } else 115 if (brightness == LED_FULL) {
115 ieee80211_queue_delayed_work(hw, &priv->led_on, 0); 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 }
116} 132}
117 133
118static int rtl8187_register_led(struct ieee80211_hw *dev, 134static int rtl8187_register_led(struct ieee80211_hw *dev,
119 struct rtl8187_led *led, const char *name, 135 struct rtl8187_led *led, const char *name,
120 const char *default_trigger, u8 ledpin) 136 const char *default_trigger, u8 ledpin,
137 bool is_radio)
121{ 138{
122 int err; 139 int err;
123 struct rtl8187_priv *priv = dev->priv; 140 struct rtl8187_priv *priv = dev->priv;
@@ -128,6 +145,7 @@ static int rtl8187_register_led(struct ieee80211_hw *dev,
128 return -EINVAL; 145 return -EINVAL;
129 led->dev = dev; 146 led->dev = dev;
130 led->ledpin = ledpin; 147 led->ledpin = ledpin;
148 led->is_radio = is_radio;
131 strncpy(led->name, name, sizeof(led->name)); 149 strncpy(led->name, name, sizeof(led->name));
132 150
133 led->led_dev.name = led->name; 151 led->led_dev.name = led->name;
@@ -145,7 +163,11 @@ static int rtl8187_register_led(struct ieee80211_hw *dev,
145 163
146static void rtl8187_unregister_led(struct rtl8187_led *led) 164static void rtl8187_unregister_led(struct rtl8187_led *led)
147{ 165{
166 struct ieee80211_hw *hw = led->dev;
167 struct rtl8187_priv *priv = hw->priv;
168
148 led_classdev_unregister(&led->led_dev); 169 led_classdev_unregister(&led->led_dev);
170 flush_delayed_work(&priv->led_off);
149 led->dev = NULL; 171 led->dev = NULL;
150} 172}
151 173
@@ -183,37 +205,41 @@ void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
183 INIT_DELAYED_WORK(&priv->led_off, led_turn_off); 205 INIT_DELAYED_WORK(&priv->led_off, led_turn_off);
184 206
185 snprintf(name, sizeof(name), 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),
186 "rtl8187-%s::tx", wiphy_name(dev->wiphy)); 215 "rtl8187-%s::tx", wiphy_name(dev->wiphy));
187 err = rtl8187_register_led(dev, &priv->led_tx, name, 216 err = rtl8187_register_led(dev, &priv->led_tx, name,
188 ieee80211_get_tx_led_name(dev), ledpin); 217 ieee80211_get_tx_led_name(dev), ledpin, false);
189 if (err) 218 if (err)
190 goto error; 219 goto err_tx;
220
191 snprintf(name, sizeof(name), 221 snprintf(name, sizeof(name),
192 "rtl8187-%s::rx", wiphy_name(dev->wiphy)); 222 "rtl8187-%s::rx", wiphy_name(dev->wiphy));
193 err = rtl8187_register_led(dev, &priv->led_rx, name, 223 err = rtl8187_register_led(dev, &priv->led_rx, name,
194 ieee80211_get_rx_led_name(dev), ledpin); 224 ieee80211_get_rx_led_name(dev), ledpin, false);
195 if (!err) { 225 if (!err)
196 ieee80211_queue_delayed_work(dev, &priv->led_on, 0);
197 return; 226 return;
198 } 227
199 /* registration of RX LED failed - unregister TX */ 228 /* registration of RX LED failed - unregister */
200 rtl8187_unregister_led(&priv->led_tx); 229 rtl8187_unregister_led(&priv->led_tx);
201error: 230err_tx:
202 /* If registration of either failed, cancel delayed work */ 231 rtl8187_unregister_led(&priv->led_radio);
203 cancel_delayed_work_sync(&priv->led_off);
204 cancel_delayed_work_sync(&priv->led_on);
205} 232}
206 233
207void rtl8187_leds_exit(struct ieee80211_hw *dev) 234void rtl8187_leds_exit(struct ieee80211_hw *dev)
208{ 235{
209 struct rtl8187_priv *priv = dev->priv; 236 struct rtl8187_priv *priv = dev->priv;
210 237
211 /* turn the LED off before exiting */ 238 rtl8187_unregister_led(&priv->led_radio);
212 ieee80211_queue_delayed_work(dev, &priv->led_off, 0);
213 rtl8187_unregister_led(&priv->led_rx); 239 rtl8187_unregister_led(&priv->led_rx);
214 rtl8187_unregister_led(&priv->led_tx); 240 rtl8187_unregister_led(&priv->led_tx);
215 cancel_delayed_work_sync(&priv->led_off); 241 cancel_delayed_work_sync(&priv->led_off);
216 cancel_delayed_work_sync(&priv->led_on); 242 cancel_delayed_work_sync(&priv->led_on);
217} 243}
218#endif /* def CONFIG_RTL8187_LED */ 244#endif /* def CONFIG_RTL8187_LEDS */
219 245
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h
index a0332027aead..d743c96d4a20 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.h
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.h
@@ -47,11 +47,13 @@ struct rtl8187_led {
47 u8 ledpin; 47 u8 ledpin;
48 /* The unique name string for this LED device. */ 48 /* The unique name string for this LED device. */
49 char name[RTL8187_LED_MAX_NAME_LEN + 1]; 49 char name[RTL8187_LED_MAX_NAME_LEN + 1];
50 /* If the LED is radio or tx/rx */
51 bool is_radio;
50}; 52};
51 53
52void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); 54void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);
53void rtl8187_leds_exit(struct ieee80211_hw *dev); 55void rtl8187_leds_exit(struct ieee80211_hw *dev);
54 56
55#endif /* def CONFIG_RTL8187_LED */ 57#endif /* def CONFIG_RTL8187_LEDS */
56 58
57#endif /* RTL8187_LED_H */ 59#endif /* RTL8187_LED_H */
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
index cad8037ab2af..03555e1e0cab 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
@@ -25,10 +25,10 @@ static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
25 u8 gpio; 25 u8 gpio;
26 26
27 gpio = rtl818x_ioread8(priv, &priv->map->GPIO0); 27 gpio = rtl818x_ioread8(priv, &priv->map->GPIO0);
28 rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~0x02); 28 rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~priv->rfkill_mask);
29 gpio = rtl818x_ioread8(priv, &priv->map->GPIO1); 29 gpio = rtl818x_ioread8(priv, &priv->map->GPIO1);
30 30
31 return gpio & 0x02; 31 return gpio & priv->rfkill_mask;
32} 32}
33 33
34void rtl8187_rfkill_init(struct ieee80211_hw *hw) 34void rtl8187_rfkill_init(struct ieee80211_hw *hw)