aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl8187_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtl8187_dev.c')
-rw-r--r--drivers/net/wireless/rtl8187_dev.c110
1 files changed, 79 insertions, 31 deletions
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index d3067b1216ca..57376fb993ed 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -31,6 +31,8 @@ MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32 32
33static struct usb_device_id rtl8187_table[] __devinitdata = { 33static struct usb_device_id rtl8187_table[] __devinitdata = {
34 /* Asus */
35 {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
34 /* Realtek */ 36 /* Realtek */
35 {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187}, 37 {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
36 {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, 38 {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
@@ -169,6 +171,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
169{ 171{
170 struct rtl8187_priv *priv = dev->priv; 172 struct rtl8187_priv *priv = dev->priv;
171 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 173 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
174 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
172 unsigned int ep; 175 unsigned int ep;
173 void *buf; 176 void *buf;
174 struct urb *urb; 177 struct urb *urb;
@@ -234,6 +237,20 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
234 ep = epmap[skb_get_queue_mapping(skb)]; 237 ep = epmap[skb_get_queue_mapping(skb)];
235 } 238 }
236 239
240 /* FIXME: The sequence that follows is needed for this driver to
241 * work with mac80211 since "mac80211: fix TX sequence numbers".
242 * As with the temporary code in rt2x00, changes will be needed
243 * to get proper sequence numbers on beacons. In addition, this
244 * patch places the sequence number in the hardware state, which
245 * limits us to a single virtual state.
246 */
247 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
248 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
249 priv->seqno += 0x10;
250 ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
251 ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
252 }
253
237 info->driver_data[0] = dev; 254 info->driver_data[0] = dev;
238 info->driver_data[1] = urb; 255 info->driver_data[1] = urb;
239 256
@@ -257,6 +274,7 @@ static void rtl8187_rx_cb(struct urb *urb)
257 struct ieee80211_rx_status rx_status = { 0 }; 274 struct ieee80211_rx_status rx_status = { 0 };
258 int rate, signal; 275 int rate, signal;
259 u32 flags; 276 u32 flags;
277 u32 quality;
260 278
261 spin_lock(&priv->rx_queue.lock); 279 spin_lock(&priv->rx_queue.lock);
262 if (skb->next) 280 if (skb->next)
@@ -280,44 +298,57 @@ static void rtl8187_rx_cb(struct urb *urb)
280 flags = le32_to_cpu(hdr->flags); 298 flags = le32_to_cpu(hdr->flags);
281 signal = hdr->signal & 0x7f; 299 signal = hdr->signal & 0x7f;
282 rx_status.antenna = (hdr->signal >> 7) & 1; 300 rx_status.antenna = (hdr->signal >> 7) & 1;
283 rx_status.signal = signal;
284 rx_status.noise = hdr->noise; 301 rx_status.noise = hdr->noise;
285 rx_status.mactime = le64_to_cpu(hdr->mac_time); 302 rx_status.mactime = le64_to_cpu(hdr->mac_time);
286 priv->signal = signal;
287 priv->quality = signal; 303 priv->quality = signal;
304 rx_status.qual = priv->quality;
288 priv->noise = hdr->noise; 305 priv->noise = hdr->noise;
306 rate = (flags >> 20) & 0xF;
307 if (rate > 3) { /* OFDM rate */
308 if (signal > 90)
309 signal = 90;
310 else if (signal < 25)
311 signal = 25;
312 signal = 90 - signal;
313 } else { /* CCK rate */
314 if (signal > 95)
315 signal = 95;
316 else if (signal < 30)
317 signal = 30;
318 signal = 95 - signal;
319 }
320 rx_status.signal = signal;
321 priv->signal = signal;
289 } else { 322 } else {
290 struct rtl8187b_rx_hdr *hdr = 323 struct rtl8187b_rx_hdr *hdr =
291 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); 324 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
325 /* The Realtek datasheet for the RTL8187B shows that the RX
326 * header contains the following quantities: signal quality,
327 * RSSI, AGC, the received power in dB, and the measured SNR.
328 * In testing, none of these quantities show qualitative
329 * agreement with AP signal strength, except for the AGC,
330 * which is inversely proportional to the strength of the
331 * signal. In the following, the quality and signal strength
332 * are derived from the AGC. The arbitrary scaling constants
333 * are chosen to make the results close to the values obtained
334 * for a BCM4312 using b43 as the driver. The noise is ignored
335 * for now.
336 */
292 flags = le32_to_cpu(hdr->flags); 337 flags = le32_to_cpu(hdr->flags);
293 signal = hdr->agc >> 1; 338 quality = 170 - hdr->agc;
294 rx_status.antenna = (hdr->signal >> 7) & 1; 339 if (quality > 100)
295 rx_status.signal = 64 - min(hdr->noise, (u8)64); 340 quality = 100;
296 rx_status.noise = hdr->noise; 341 signal = 14 - hdr->agc / 2;
342 rx_status.qual = quality;
343 priv->quality = quality;
344 rx_status.signal = signal;
345 priv->signal = signal;
346 rx_status.antenna = (hdr->rssi >> 7) & 1;
297 rx_status.mactime = le64_to_cpu(hdr->mac_time); 347 rx_status.mactime = le64_to_cpu(hdr->mac_time);
298 priv->signal = hdr->signal; 348 rate = (flags >> 20) & 0xF;
299 priv->quality = hdr->agc >> 1;
300 priv->noise = hdr->noise;
301 } 349 }
302 350
303 skb_trim(skb, flags & 0x0FFF); 351 skb_trim(skb, flags & 0x0FFF);
304 rate = (flags >> 20) & 0xF;
305 if (rate > 3) { /* OFDM rate */
306 if (signal > 90)
307 signal = 90;
308 else if (signal < 25)
309 signal = 25;
310 signal = 90 - signal;
311 } else { /* CCK rate */
312 if (signal > 95)
313 signal = 95;
314 else if (signal < 30)
315 signal = 30;
316 signal = 95 - signal;
317 }
318
319 rx_status.qual = priv->quality;
320 rx_status.signal = signal;
321 rx_status.rate_idx = rate; 352 rx_status.rate_idx = rate;
322 rx_status.freq = dev->conf.channel->center_freq; 353 rx_status.freq = dev->conf.channel->center_freq;
323 rx_status.band = dev->conf.channel->band; 354 rx_status.band = dev->conf.channel->band;
@@ -697,6 +728,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
697 if (ret) 728 if (ret)
698 return ret; 729 return ret;
699 730
731 mutex_lock(&priv->conf_mutex);
700 if (priv->is_rtl8187b) { 732 if (priv->is_rtl8187b) {
701 reg = RTL818X_RX_CONF_MGMT | 733 reg = RTL818X_RX_CONF_MGMT |
702 RTL818X_RX_CONF_DATA | 734 RTL818X_RX_CONF_DATA |
@@ -718,6 +750,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
718 (7 << 0 /* long retry limit */) | 750 (7 << 0 /* long retry limit */) |
719 (7 << 21 /* MAX TX DMA */)); 751 (7 << 21 /* MAX TX DMA */));
720 rtl8187_init_urbs(dev); 752 rtl8187_init_urbs(dev);
753 mutex_unlock(&priv->conf_mutex);
721 return 0; 754 return 0;
722 } 755 }
723 756
@@ -761,6 +794,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
761 reg |= RTL818X_CMD_TX_ENABLE; 794 reg |= RTL818X_CMD_TX_ENABLE;
762 reg |= RTL818X_CMD_RX_ENABLE; 795 reg |= RTL818X_CMD_RX_ENABLE;
763 rtl818x_iowrite8(priv, &priv->map->CMD, reg); 796 rtl818x_iowrite8(priv, &priv->map->CMD, reg);
797 mutex_unlock(&priv->conf_mutex);
764 798
765 return 0; 799 return 0;
766} 800}
@@ -772,6 +806,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
772 struct sk_buff *skb; 806 struct sk_buff *skb;
773 u32 reg; 807 u32 reg;
774 808
809 mutex_lock(&priv->conf_mutex);
775 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); 810 rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
776 811
777 reg = rtl818x_ioread8(priv, &priv->map->CMD); 812 reg = rtl818x_ioread8(priv, &priv->map->CMD);
@@ -791,7 +826,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
791 usb_kill_urb(info->urb); 826 usb_kill_urb(info->urb);
792 kfree_skb(skb); 827 kfree_skb(skb);
793 } 828 }
794 return; 829 mutex_unlock(&priv->conf_mutex);
795} 830}
796 831
797static int rtl8187_add_interface(struct ieee80211_hw *dev, 832static int rtl8187_add_interface(struct ieee80211_hw *dev,
@@ -811,6 +846,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
811 return -EOPNOTSUPP; 846 return -EOPNOTSUPP;
812 } 847 }
813 848
849 mutex_lock(&priv->conf_mutex);
814 priv->vif = conf->vif; 850 priv->vif = conf->vif;
815 851
816 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 852 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
@@ -819,6 +855,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
819 ((u8 *)conf->mac_addr)[i]); 855 ((u8 *)conf->mac_addr)[i]);
820 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 856 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
821 857
858 mutex_unlock(&priv->conf_mutex);
822 return 0; 859 return 0;
823} 860}
824 861
@@ -826,8 +863,10 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
826 struct ieee80211_if_init_conf *conf) 863 struct ieee80211_if_init_conf *conf)
827{ 864{
828 struct rtl8187_priv *priv = dev->priv; 865 struct rtl8187_priv *priv = dev->priv;
866 mutex_lock(&priv->conf_mutex);
829 priv->mode = IEEE80211_IF_TYPE_MNTR; 867 priv->mode = IEEE80211_IF_TYPE_MNTR;
830 priv->vif = NULL; 868 priv->vif = NULL;
869 mutex_unlock(&priv->conf_mutex);
831} 870}
832 871
833static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 872static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
@@ -835,6 +874,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
835 struct rtl8187_priv *priv = dev->priv; 874 struct rtl8187_priv *priv = dev->priv;
836 u32 reg; 875 u32 reg;
837 876
877 mutex_lock(&priv->conf_mutex);
838 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); 878 reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
839 /* Enable TX loopback on MAC level to avoid TX during channel 879 /* Enable TX loopback on MAC level to avoid TX during channel
840 * changes, as this has be seen to causes problems and the 880 * changes, as this has be seen to causes problems and the
@@ -867,6 +907,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
867 rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100); 907 rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
868 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); 908 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
869 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100); 909 rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
910 mutex_unlock(&priv->conf_mutex);
870 return 0; 911 return 0;
871} 912}
872 913
@@ -878,6 +919,7 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
878 int i; 919 int i;
879 u8 reg; 920 u8 reg;
880 921
922 mutex_lock(&priv->conf_mutex);
881 for (i = 0; i < ETH_ALEN; i++) 923 for (i = 0; i < ETH_ALEN; i++)
882 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); 924 rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
883 925
@@ -891,6 +933,7 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
891 rtl818x_iowrite8(priv, &priv->map->MSR, reg); 933 rtl818x_iowrite8(priv, &priv->map->MSR, reg);
892 } 934 }
893 935
936 mutex_unlock(&priv->conf_mutex);
894 return 0; 937 return 0;
895} 938}
896 939
@@ -1015,9 +1058,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1015 1058
1016 priv->mode = IEEE80211_IF_TYPE_MNTR; 1059 priv->mode = IEEE80211_IF_TYPE_MNTR;
1017 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1060 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1018 IEEE80211_HW_RX_INCLUDES_FCS | 1061 IEEE80211_HW_RX_INCLUDES_FCS;
1019 IEEE80211_HW_SIGNAL_UNSPEC;
1020 dev->max_signal = 65;
1021 1062
1022 eeprom.data = dev; 1063 eeprom.data = dev;
1023 eeprom.register_read = rtl8187_eeprom_register_read; 1064 eeprom.register_read = rtl8187_eeprom_register_read;
@@ -1132,10 +1173,16 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1132 (*channel++).hw_value = txpwr >> 8; 1173 (*channel++).hw_value = txpwr >> 8;
1133 } 1174 }
1134 1175
1135 if (priv->is_rtl8187b) 1176 if (priv->is_rtl8187b) {
1136 printk(KERN_WARNING "rtl8187: 8187B chip detected. Support " 1177 printk(KERN_WARNING "rtl8187: 8187B chip detected. Support "
1137 "is EXPERIMENTAL, and could damage your\n" 1178 "is EXPERIMENTAL, and could damage your\n"
1138 " hardware, use at your own risk\n"); 1179 " hardware, use at your own risk\n");
1180 dev->flags |= IEEE80211_HW_SIGNAL_DBM;
1181 } else {
1182 dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC;
1183 dev->max_signal = 65;
1184 }
1185
1139 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) 1186 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
1140 printk(KERN_INFO "rtl8187: inconsistency between id with OEM" 1187 printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
1141 " info!\n"); 1188 " info!\n");
@@ -1154,6 +1201,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1154 printk(KERN_ERR "rtl8187: Cannot register device\n"); 1201 printk(KERN_ERR "rtl8187: Cannot register device\n");
1155 goto err_free_dev; 1202 goto err_free_dev;
1156 } 1203 }
1204 mutex_init(&priv->conf_mutex);
1157 1205
1158 printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n", 1206 printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
1159 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), 1207 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),