提交 db888aed 编写于 作者: U Ulrich Kunitz 提交者: John W. Linville

[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: NUlrich Kunitz <kune@deine-taler.de>
Signed-off-by: NDaniel Drake <dsd@gentoo.org>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 38f5745c
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -1430,9 +1430,43 @@ static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
break;
}
switch (rate) {
case ZD_OFDM_RATE_6M:
case ZD_OFDM_RATE_9M:
i += 3;
break;
case ZD_OFDM_RATE_12M:
case ZD_OFDM_RATE_18M:
i += 5;
break;
case ZD_OFDM_RATE_24M:
case ZD_OFDM_RATE_36M:
i += 9;
break;
case ZD_OFDM_RATE_48M:
case ZD_OFDM_RATE_54M:
i += 15;
break;
default:
return -EINVAL;
}
return i;
}
static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size)
{
int r;
r = ofdm_qual_db(status_quality, rate, size);
ZD_ASSERT(r >= 0);
if (r < 0)
r = 0;
r = (r * 100)/29;
return r <= 100 ? r : 100;
}
static unsigned int log10times100(unsigned int x)
{
static const u8 log10[] = {
......@@ -1476,31 +1510,28 @@ static int cck_snr_db(u8 status_quality)
return r;
}
static int rx_qual_db(const void *rx_frame, unsigned int size,
const struct rx_status *status)
static int cck_qual_percent(u8 status_quality)
{
return (status->frame_status&ZD_RX_OFDM) ?
ofdm_qual_db(status->signal_quality_ofdm,
zd_ofdm_plcp_header_rate(rx_frame),
size) :
cck_snr_db(status->signal_quality_cck);
int r;
r = cck_snr_db(status_quality);
r = (100*r)/17;
return r <= 100 ? r : 100;
}
u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
const struct rx_status *status)
{
int r = rx_qual_db(rx_frame, size, status);
if (r < 0)
r = 0;
r = (r * 100) / 14;
if (r > 100)
r = 100;
return r;
return (status->frame_status&ZD_RX_OFDM) ?
ofdm_qual_percent(status->signal_quality_ofdm,
zd_ofdm_plcp_header_rate(rx_frame),
size) :
cck_qual_percent(status->signal_quality_cck);
}
u8 zd_rx_strength_percent(u8 rssi)
{
int r = (rssi*100) / 30;
int r = (rssi*100) / 41;
if (r > 100)
r = 100;
return (u8) r;
......
......@@ -816,13 +816,25 @@ static int filter_rx(struct ieee80211_device *ieee,
return -EINVAL;
}
static void update_qual_rssi(struct zd_mac *mac, u8 qual_percent, u8 rssi)
static void update_qual_rssi(struct zd_mac *mac,
const u8 *buffer, unsigned int length,
u8 qual_percent, u8 rssi_percent)
{
unsigned long flags;
struct ieee80211_hdr_3addr *hdr;
int i;
hdr = (struct ieee80211_hdr_3addr *)buffer;
if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
return;
if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0)
return;
spin_lock_irqsave(&mac->lock, flags);
mac->qual_average = (7 * mac->qual_average + qual_percent) / 8;
mac->rssi_average = (7 * mac->rssi_average + rssi) / 8;
i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE;
mac->qual_buffer[i] = qual_percent;
mac->rssi_buffer[i] = rssi_percent;
mac->stats_count++;
spin_unlock_irqrestore(&mac->lock, flags);
}
......@@ -853,7 +865,6 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats,
if (stats->rate)
stats->mask |= IEEE80211_STATMASK_RATE;
update_qual_rssi(mac, stats->signal, stats->rssi);
return 0;
}
......@@ -877,6 +888,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length)
sizeof(struct rx_status);
buffer += ZD_PLCP_HEADER_SIZE;
update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi);
r = filter_rx(ieee, buffer, length, &stats);
if (r <= 0)
return r;
......@@ -981,17 +994,31 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
{
struct zd_mac *mac = zd_netdev_mac(ndev);
struct iw_statistics *iw_stats = &mac->iw_stats;
unsigned int i, count, qual_total, rssi_total;
memset(iw_stats, 0, sizeof(struct iw_statistics));
/* We are not setting the status, because ieee->state is not updated
* at all and this driver doesn't track authentication state.
*/
spin_lock_irq(&mac->lock);
iw_stats->qual.qual = mac->qual_average;
iw_stats->qual.level = mac->rssi_average;
iw_stats->qual.updated = IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED|
IW_QUAL_NOISE_INVALID;
count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ?
mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE;
qual_total = rssi_total = 0;
for (i = 0; i < count; i++) {
qual_total += mac->qual_buffer[i];
rssi_total += mac->rssi_buffer[i];
}
spin_unlock_irq(&mac->lock);
iw_stats->qual.updated = IW_QUAL_NOISE_INVALID;
if (count > 0) {
iw_stats->qual.qual = qual_total / count;
iw_stats->qual.level = rssi_total / count;
iw_stats->qual.updated |=
IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED;
} else {
iw_stats->qual.updated |=
IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID;
}
/* TODO: update counter */
return iw_stats;
}
......
/* zd_mac.c
/* zd_mac.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -87,9 +87,9 @@ struct rx_length_info {
#define RX_LENGTH_INFO_TAG 0x697e
struct rx_status {
u8 signal_quality_cck;
/* rssi */
u8 signal_strength;
u8 signal_quality_cck;
u8 signal_quality_ofdm;
u8 decryption_type;
u8 frame_status;
......@@ -120,14 +120,17 @@ enum mac_flags {
MAC_FIXED_CHANNEL = 0x01,
};
#define ZD_MAC_STATS_BUFFER_SIZE 16
struct zd_mac {
struct net_device *netdev;
struct zd_chip chip;
spinlock_t lock;
/* Unlocked reading possible */
struct iw_statistics iw_stats;
u8 qual_average;
u8 rssi_average;
unsigned int stats_count;
u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 regdomain;
u8 default_regdomain;
u8 requested_channel;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部