aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl818x/rtl8187_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtl818x/rtl8187_dev.c')
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c53
1 files changed, 31 insertions, 22 deletions
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);