aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorUlrich Kunitz <kune@deine-taler.de>2006-08-29 18:50:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-09-11 16:11:08 -0400
commitdb888aed7e83559d61cff04bf002d0fb80ecbfa7 (patch)
tree4c8795f5924ce440ddc79cf0e2d7ae25d633d5ad /drivers
parent38f5745c5a90641079fd5b48600ae63f7ab6edcd (diff)
[PATCH] zd1211rw: Fix of signal strength and quality measurement
Caused by a documentation issue I mixed up fields of the zd_status structure. This patch fixes it and improves also the average computation, which is now using only measurements of packets sent by the access point. Signed-off-by: Ulrich Kunitz <kune@deine-taler.de> Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c61
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c43
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h11
3 files changed, 88 insertions, 27 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index da9d06bdb818..aa792821854e 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1430,9 +1430,43 @@ static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
1430 break; 1430 break;
1431 } 1431 }
1432 1432
1433 switch (rate) {
1434 case ZD_OFDM_RATE_6M:
1435 case ZD_OFDM_RATE_9M:
1436 i += 3;
1437 break;
1438 case ZD_OFDM_RATE_12M:
1439 case ZD_OFDM_RATE_18M:
1440 i += 5;
1441 break;
1442 case ZD_OFDM_RATE_24M:
1443 case ZD_OFDM_RATE_36M:
1444 i += 9;
1445 break;
1446 case ZD_OFDM_RATE_48M:
1447 case ZD_OFDM_RATE_54M:
1448 i += 15;
1449 break;
1450 default:
1451 return -EINVAL;
1452 }
1453
1433 return i; 1454 return i;
1434} 1455}
1435 1456
1457static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size)
1458{
1459 int r;
1460
1461 r = ofdm_qual_db(status_quality, rate, size);
1462 ZD_ASSERT(r >= 0);
1463 if (r < 0)
1464 r = 0;
1465
1466 r = (r * 100)/29;
1467 return r <= 100 ? r : 100;
1468}
1469
1436static unsigned int log10times100(unsigned int x) 1470static unsigned int log10times100(unsigned int x)
1437{ 1471{
1438 static const u8 log10[] = { 1472 static const u8 log10[] = {
@@ -1476,31 +1510,28 @@ static int cck_snr_db(u8 status_quality)
1476 return r; 1510 return r;
1477} 1511}
1478 1512
1479static int rx_qual_db(const void *rx_frame, unsigned int size, 1513static int cck_qual_percent(u8 status_quality)
1480 const struct rx_status *status)
1481{ 1514{
1482 return (status->frame_status&ZD_RX_OFDM) ? 1515 int r;
1483 ofdm_qual_db(status->signal_quality_ofdm, 1516
1484 zd_ofdm_plcp_header_rate(rx_frame), 1517 r = cck_snr_db(status_quality);
1485 size) : 1518 r = (100*r)/17;
1486 cck_snr_db(status->signal_quality_cck); 1519 return r <= 100 ? r : 100;
1487} 1520}
1488 1521
1489u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, 1522u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
1490 const struct rx_status *status) 1523 const struct rx_status *status)
1491{ 1524{
1492 int r = rx_qual_db(rx_frame, size, status); 1525 return (status->frame_status&ZD_RX_OFDM) ?
1493 if (r < 0) 1526 ofdm_qual_percent(status->signal_quality_ofdm,
1494 r = 0; 1527 zd_ofdm_plcp_header_rate(rx_frame),
1495 r = (r * 100) / 14; 1528 size) :
1496 if (r > 100) 1529 cck_qual_percent(status->signal_quality_cck);
1497 r = 100;
1498 return r;
1499} 1530}
1500 1531
1501u8 zd_rx_strength_percent(u8 rssi) 1532u8 zd_rx_strength_percent(u8 rssi)
1502{ 1533{
1503 int r = (rssi*100) / 30; 1534 int r = (rssi*100) / 41;
1504 if (r > 100) 1535 if (r > 100)
1505 r = 100; 1536 r = 100;
1506 return (u8) r; 1537 return (u8) r;
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index d6f3e02a0b54..a9bd80a08613 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -816,13 +816,25 @@ static int filter_rx(struct ieee80211_device *ieee,
816 return -EINVAL; 816 return -EINVAL;
817} 817}
818 818
819static void update_qual_rssi(struct zd_mac *mac, u8 qual_percent, u8 rssi) 819static void update_qual_rssi(struct zd_mac *mac,
820 const u8 *buffer, unsigned int length,
821 u8 qual_percent, u8 rssi_percent)
820{ 822{
821 unsigned long flags; 823 unsigned long flags;
824 struct ieee80211_hdr_3addr *hdr;
825 int i;
826
827 hdr = (struct ieee80211_hdr_3addr *)buffer;
828 if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
829 return;
830 if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0)
831 return;
822 832
823 spin_lock_irqsave(&mac->lock, flags); 833 spin_lock_irqsave(&mac->lock, flags);
824 mac->qual_average = (7 * mac->qual_average + qual_percent) / 8; 834 i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE;
825 mac->rssi_average = (7 * mac->rssi_average + rssi) / 8; 835 mac->qual_buffer[i] = qual_percent;
836 mac->rssi_buffer[i] = rssi_percent;
837 mac->stats_count++;
826 spin_unlock_irqrestore(&mac->lock, flags); 838 spin_unlock_irqrestore(&mac->lock, flags);
827} 839}
828 840
@@ -853,7 +865,6 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats,
853 if (stats->rate) 865 if (stats->rate)
854 stats->mask |= IEEE80211_STATMASK_RATE; 866 stats->mask |= IEEE80211_STATMASK_RATE;
855 867
856 update_qual_rssi(mac, stats->signal, stats->rssi);
857 return 0; 868 return 0;
858} 869}
859 870
@@ -877,6 +888,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length)
877 sizeof(struct rx_status); 888 sizeof(struct rx_status);
878 buffer += ZD_PLCP_HEADER_SIZE; 889 buffer += ZD_PLCP_HEADER_SIZE;
879 890
891 update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi);
892
880 r = filter_rx(ieee, buffer, length, &stats); 893 r = filter_rx(ieee, buffer, length, &stats);
881 if (r <= 0) 894 if (r <= 0)
882 return r; 895 return r;
@@ -981,17 +994,31 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
981{ 994{
982 struct zd_mac *mac = zd_netdev_mac(ndev); 995 struct zd_mac *mac = zd_netdev_mac(ndev);
983 struct iw_statistics *iw_stats = &mac->iw_stats; 996 struct iw_statistics *iw_stats = &mac->iw_stats;
997 unsigned int i, count, qual_total, rssi_total;
984 998
985 memset(iw_stats, 0, sizeof(struct iw_statistics)); 999 memset(iw_stats, 0, sizeof(struct iw_statistics));
986 /* We are not setting the status, because ieee->state is not updated 1000 /* We are not setting the status, because ieee->state is not updated
987 * at all and this driver doesn't track authentication state. 1001 * at all and this driver doesn't track authentication state.
988 */ 1002 */
989 spin_lock_irq(&mac->lock); 1003 spin_lock_irq(&mac->lock);
990 iw_stats->qual.qual = mac->qual_average; 1004 count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ?
991 iw_stats->qual.level = mac->rssi_average; 1005 mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE;
992 iw_stats->qual.updated = IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED| 1006 qual_total = rssi_total = 0;
993 IW_QUAL_NOISE_INVALID; 1007 for (i = 0; i < count; i++) {
1008 qual_total += mac->qual_buffer[i];
1009 rssi_total += mac->rssi_buffer[i];
1010 }
994 spin_unlock_irq(&mac->lock); 1011 spin_unlock_irq(&mac->lock);
1012 iw_stats->qual.updated = IW_QUAL_NOISE_INVALID;
1013 if (count > 0) {
1014 iw_stats->qual.qual = qual_total / count;
1015 iw_stats->qual.level = rssi_total / count;
1016 iw_stats->qual.updated |=
1017 IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED;
1018 } else {
1019 iw_stats->qual.updated |=
1020 IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID;
1021 }
995 /* TODO: update counter */ 1022 /* TODO: update counter */
996 return iw_stats; 1023 return iw_stats;
997} 1024}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 71e382c589ee..b3ba49b84634 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -1,4 +1,4 @@
1/* zd_mac.c 1/* zd_mac.h
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by 4 * it under the terms of the GNU General Public License as published by
@@ -87,9 +87,9 @@ struct rx_length_info {
87#define RX_LENGTH_INFO_TAG 0x697e 87#define RX_LENGTH_INFO_TAG 0x697e
88 88
89struct rx_status { 89struct rx_status {
90 u8 signal_quality_cck;
90 /* rssi */ 91 /* rssi */
91 u8 signal_strength; 92 u8 signal_strength;
92 u8 signal_quality_cck;
93 u8 signal_quality_ofdm; 93 u8 signal_quality_ofdm;
94 u8 decryption_type; 94 u8 decryption_type;
95 u8 frame_status; 95 u8 frame_status;
@@ -120,14 +120,17 @@ enum mac_flags {
120 MAC_FIXED_CHANNEL = 0x01, 120 MAC_FIXED_CHANNEL = 0x01,
121}; 121};
122 122
123#define ZD_MAC_STATS_BUFFER_SIZE 16
124
123struct zd_mac { 125struct zd_mac {
124 struct net_device *netdev; 126 struct net_device *netdev;
125 struct zd_chip chip; 127 struct zd_chip chip;
126 spinlock_t lock; 128 spinlock_t lock;
127 /* Unlocked reading possible */ 129 /* Unlocked reading possible */
128 struct iw_statistics iw_stats; 130 struct iw_statistics iw_stats;
129 u8 qual_average; 131 unsigned int stats_count;
130 u8 rssi_average; 132 u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
133 u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
131 u8 regdomain; 134 u8 regdomain;
132 u8 default_regdomain; 135 u8 default_regdomain;
133 u8 requested_channel; 136 u8 requested_channel;