diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/rtl8187.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/rtl8187_dev.c | 78 |
2 files changed, 54 insertions, 34 deletions
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h index 8961901b5c04..1b0d750f6623 100644 --- a/drivers/net/wireless/rtl8187.h +++ b/drivers/net/wireless/rtl8187.h | |||
@@ -47,11 +47,13 @@ struct rtl8187_rx_hdr { | |||
47 | struct rtl8187b_rx_hdr { | 47 | struct rtl8187b_rx_hdr { |
48 | __le32 flags; | 48 | __le32 flags; |
49 | __le64 mac_time; | 49 | __le64 mac_time; |
50 | u8 noise; | 50 | u8 sq; |
51 | u8 signal; | 51 | u8 rssi; |
52 | u8 agc; | 52 | u8 agc; |
53 | u8 reserved; | 53 | u8 flags2; |
54 | __le32 unused; | 54 | __le16 snr_long2end; |
55 | s8 pwdb_g12; | ||
56 | u8 fot; | ||
55 | } __attribute__((packed)); | 57 | } __attribute__((packed)); |
56 | 58 | ||
57 | /* {rtl8187,rtl8187b}_tx_info is in skb */ | 59 | /* {rtl8187,rtl8187b}_tx_info is in skb */ |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 7ff03aca2518..177988efd660 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -272,6 +272,7 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
272 | struct ieee80211_rx_status rx_status = { 0 }; | 272 | struct ieee80211_rx_status rx_status = { 0 }; |
273 | int rate, signal; | 273 | int rate, signal; |
274 | u32 flags; | 274 | u32 flags; |
275 | u32 quality; | ||
275 | 276 | ||
276 | spin_lock(&priv->rx_queue.lock); | 277 | spin_lock(&priv->rx_queue.lock); |
277 | if (skb->next) | 278 | if (skb->next) |
@@ -295,44 +296,57 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
295 | flags = le32_to_cpu(hdr->flags); | 296 | flags = le32_to_cpu(hdr->flags); |
296 | signal = hdr->signal & 0x7f; | 297 | signal = hdr->signal & 0x7f; |
297 | rx_status.antenna = (hdr->signal >> 7) & 1; | 298 | rx_status.antenna = (hdr->signal >> 7) & 1; |
298 | rx_status.signal = signal; | ||
299 | rx_status.noise = hdr->noise; | 299 | rx_status.noise = hdr->noise; |
300 | rx_status.mactime = le64_to_cpu(hdr->mac_time); | 300 | rx_status.mactime = le64_to_cpu(hdr->mac_time); |
301 | priv->signal = signal; | ||
302 | priv->quality = signal; | 301 | priv->quality = signal; |
302 | rx_status.qual = priv->quality; | ||
303 | priv->noise = hdr->noise; | 303 | priv->noise = hdr->noise; |
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 | rx_status.signal = signal; | ||
319 | priv->signal = signal; | ||
304 | } else { | 320 | } else { |
305 | struct rtl8187b_rx_hdr *hdr = | 321 | struct rtl8187b_rx_hdr *hdr = |
306 | (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); | 322 | (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); |
323 | /* The Realtek datasheet for the RTL8187B shows that the RX | ||
324 | * header contains the following quantities: signal quality, | ||
325 | * RSSI, AGC, the received power in dB, and the measured SNR. | ||
326 | * In testing, none of these quantities show qualitative | ||
327 | * agreement with AP signal strength, except for the AGC, | ||
328 | * which is inversely proportional to the strength of the | ||
329 | * signal. In the following, the quality and signal strength | ||
330 | * are derived from the AGC. The arbitrary scaling constants | ||
331 | * are chosen to make the results close to the values obtained | ||
332 | * for a BCM4312 using b43 as the driver. The noise is ignored | ||
333 | * for now. | ||
334 | */ | ||
307 | flags = le32_to_cpu(hdr->flags); | 335 | flags = le32_to_cpu(hdr->flags); |
308 | signal = hdr->agc >> 1; | 336 | quality = 170 - hdr->agc; |
309 | rx_status.antenna = (hdr->signal >> 7) & 1; | 337 | if (quality > 100) |
310 | rx_status.signal = 64 - min(hdr->noise, (u8)64); | 338 | quality = 100; |
311 | rx_status.noise = hdr->noise; | 339 | signal = 14 - hdr->agc / 2; |
340 | rx_status.qual = quality; | ||
341 | priv->quality = quality; | ||
342 | rx_status.signal = signal; | ||
343 | priv->signal = signal; | ||
344 | rx_status.antenna = (hdr->rssi >> 7) & 1; | ||
312 | rx_status.mactime = le64_to_cpu(hdr->mac_time); | 345 | rx_status.mactime = le64_to_cpu(hdr->mac_time); |
313 | priv->signal = hdr->signal; | 346 | rate = (flags >> 20) & 0xF; |
314 | priv->quality = hdr->agc >> 1; | ||
315 | priv->noise = hdr->noise; | ||
316 | } | 347 | } |
317 | 348 | ||
318 | skb_trim(skb, flags & 0x0FFF); | 349 | skb_trim(skb, flags & 0x0FFF); |
319 | rate = (flags >> 20) & 0xF; | ||
320 | if (rate > 3) { /* OFDM rate */ | ||
321 | if (signal > 90) | ||
322 | signal = 90; | ||
323 | else if (signal < 25) | ||
324 | signal = 25; | ||
325 | signal = 90 - signal; | ||
326 | } else { /* CCK rate */ | ||
327 | if (signal > 95) | ||
328 | signal = 95; | ||
329 | else if (signal < 30) | ||
330 | signal = 30; | ||
331 | signal = 95 - signal; | ||
332 | } | ||
333 | |||
334 | rx_status.qual = priv->quality; | ||
335 | rx_status.signal = signal; | ||
336 | rx_status.rate_idx = rate; | 350 | rx_status.rate_idx = rate; |
337 | rx_status.freq = dev->conf.channel->center_freq; | 351 | rx_status.freq = dev->conf.channel->center_freq; |
338 | rx_status.band = dev->conf.channel->band; | 352 | rx_status.band = dev->conf.channel->band; |
@@ -1030,9 +1044,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1030 | 1044 | ||
1031 | priv->mode = IEEE80211_IF_TYPE_MNTR; | 1045 | priv->mode = IEEE80211_IF_TYPE_MNTR; |
1032 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1046 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1033 | IEEE80211_HW_RX_INCLUDES_FCS | | 1047 | IEEE80211_HW_RX_INCLUDES_FCS; |
1034 | IEEE80211_HW_SIGNAL_UNSPEC; | ||
1035 | dev->max_signal = 65; | ||
1036 | 1048 | ||
1037 | eeprom.data = dev; | 1049 | eeprom.data = dev; |
1038 | eeprom.register_read = rtl8187_eeprom_register_read; | 1050 | eeprom.register_read = rtl8187_eeprom_register_read; |
@@ -1147,10 +1159,16 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1147 | (*channel++).hw_value = txpwr >> 8; | 1159 | (*channel++).hw_value = txpwr >> 8; |
1148 | } | 1160 | } |
1149 | 1161 | ||
1150 | if (priv->is_rtl8187b) | 1162 | if (priv->is_rtl8187b) { |
1151 | printk(KERN_WARNING "rtl8187: 8187B chip detected. Support " | 1163 | printk(KERN_WARNING "rtl8187: 8187B chip detected. Support " |
1152 | "is EXPERIMENTAL, and could damage your\n" | 1164 | "is EXPERIMENTAL, and could damage your\n" |
1153 | " hardware, use at your own risk\n"); | 1165 | " hardware, use at your own risk\n"); |
1166 | dev->flags |= IEEE80211_HW_SIGNAL_DBM; | ||
1167 | } else { | ||
1168 | dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC; | ||
1169 | dev->max_signal = 65; | ||
1170 | } | ||
1171 | |||
1154 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) | 1172 | if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) |
1155 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" | 1173 | printk(KERN_INFO "rtl8187: inconsistency between id with OEM" |
1156 | " info!\n"); | 1174 | " info!\n"); |