|
@@ -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;
|
|
|
}
|