aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-11-17 05:35:23 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-01-08 09:28:06 -0500
commit2b9a7e1bac24df8ddb0713ad1e5807a7243bcab0 (patch)
treef118d24b4a347e52c0a0a9173178efbe850531af /net/mac80211/sta_info.c
parent6f7a8d26e2668e00de524d3da0122a4411047dd2 (diff)
mac80211: allow drivers to provide most station statistics
In many cases, drivers can filter things like beacons that will skew statistics reported by mac80211. To get correct statistics in these cases, call drivers to obtain statistics and let them override all values, filling values from mac80211 if the driver didn't provide them. Not all of them make sense for the driver to fill, so some are still always done by mac80211. Note that this doesn't currently allow a driver to say "I know this value is wrong, don't report it at all", or to sum it up with a mac80211 value (as could be useful for "dropped misc"), that can be added if it turns out to be needed. This also gets rid of the get_rssi() method as is can now be implemented using sta_statistics(). Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c97
1 files changed, 65 insertions, 32 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 388ff0b2ad2b..967b42eae5c2 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1746,7 +1746,6 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
1746 struct ieee80211_local *local = sdata->local; 1746 struct ieee80211_local *local = sdata->local;
1747 struct rate_control_ref *ref = NULL; 1747 struct rate_control_ref *ref = NULL;
1748 struct timespec uptime; 1748 struct timespec uptime;
1749 u64 packets = 0;
1750 u32 thr = 0; 1749 u32 thr = 0;
1751 int i, ac; 1750 int i, ac;
1752 1751
@@ -1755,47 +1754,74 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
1755 1754
1756 sinfo->generation = sdata->local->sta_generation; 1755 sinfo->generation = sdata->local->sta_generation;
1757 1756
1758 sinfo->filled = STATION_INFO_INACTIVE_TIME | 1757 drv_sta_statistics(local, sdata, &sta->sta, sinfo);
1759 STATION_INFO_RX_BYTES64 | 1758
1760 STATION_INFO_TX_BYTES64 | 1759 sinfo->filled |= STATION_INFO_INACTIVE_TIME |
1761 STATION_INFO_RX_PACKETS | 1760 STATION_INFO_STA_FLAGS |
1762 STATION_INFO_TX_PACKETS | 1761 STATION_INFO_BSS_PARAM |
1763 STATION_INFO_TX_RETRIES | 1762 STATION_INFO_CONNECTED_TIME |
1764 STATION_INFO_TX_FAILED | 1763 STATION_INFO_RX_DROP_MISC |
1765 STATION_INFO_TX_BITRATE | 1764 STATION_INFO_BEACON_LOSS_COUNT;
1766 STATION_INFO_RX_BITRATE |
1767 STATION_INFO_RX_DROP_MISC |
1768 STATION_INFO_BSS_PARAM |
1769 STATION_INFO_CONNECTED_TIME |
1770 STATION_INFO_STA_FLAGS |
1771 STATION_INFO_BEACON_LOSS_COUNT;
1772 1765
1773 ktime_get_ts(&uptime); 1766 ktime_get_ts(&uptime);
1774 sinfo->connected_time = uptime.tv_sec - sta->last_connected; 1767 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
1775
1776 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 1768 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
1777 sinfo->tx_bytes = 0; 1769
1778 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 1770 if (!(sinfo->filled & (STATION_INFO_TX_BYTES64 |
1779 sinfo->tx_bytes += sta->tx_bytes[ac]; 1771 STATION_INFO_TX_BYTES))) {
1780 packets += sta->tx_packets[ac]; 1772 sinfo->tx_bytes = 0;
1773 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
1774 sinfo->tx_bytes += sta->tx_bytes[ac];
1775 sinfo->filled |= STATION_INFO_TX_BYTES64;
1776 }
1777
1778 if (!(sinfo->filled & STATION_INFO_TX_PACKETS)) {
1779 sinfo->tx_packets = 0;
1780 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
1781 sinfo->tx_packets += sta->tx_packets[ac];
1782 sinfo->filled |= STATION_INFO_TX_PACKETS;
1783 }
1784
1785 if (!(sinfo->filled & (STATION_INFO_RX_BYTES64 |
1786 STATION_INFO_RX_BYTES))) {
1787 sinfo->rx_bytes = sta->rx_bytes;
1788 sinfo->filled |= STATION_INFO_RX_BYTES64;
1789 }
1790
1791 if (!(sinfo->filled & STATION_INFO_RX_PACKETS)) {
1792 sinfo->rx_packets = sta->rx_packets;
1793 sinfo->filled |= STATION_INFO_RX_PACKETS;
1794 }
1795
1796 if (!(sinfo->filled & STATION_INFO_TX_RETRIES)) {
1797 sinfo->tx_retries = sta->tx_retry_count;
1798 sinfo->filled |= STATION_INFO_TX_RETRIES;
1799 }
1800
1801 if (!(sinfo->filled & STATION_INFO_TX_FAILED)) {
1802 sinfo->tx_failed = sta->tx_retry_failed;
1803 sinfo->filled |= STATION_INFO_TX_FAILED;
1781 } 1804 }
1782 sinfo->tx_packets = packets; 1805
1783 sinfo->rx_bytes = sta->rx_bytes;
1784 sinfo->rx_packets = sta->rx_packets;
1785 sinfo->tx_retries = sta->tx_retry_count;
1786 sinfo->tx_failed = sta->tx_retry_failed;
1787 sinfo->rx_dropped_misc = sta->rx_dropped; 1806 sinfo->rx_dropped_misc = sta->rx_dropped;
1788 sinfo->beacon_loss_count = sta->beacon_loss_count; 1807 sinfo->beacon_loss_count = sta->beacon_loss_count;
1789 1808
1790 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 1809 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
1791 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 1810 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
1792 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; 1811 if (!(sinfo->filled & STATION_INFO_SIGNAL)) {
1793 if (!local->ops->get_rssi ||
1794 drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
1795 sinfo->signal = (s8)sta->last_signal; 1812 sinfo->signal = (s8)sta->last_signal;
1796 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); 1813 sinfo->filled |= STATION_INFO_SIGNAL;
1814 }
1815
1816 if (!(sinfo->filled & STATION_INFO_SIGNAL_AVG)) {
1817 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
1818 sinfo->filled |= STATION_INFO_SIGNAL_AVG;
1819 }
1797 } 1820 }
1798 if (sta->chains) { 1821
1822 if (sta->chains &&
1823 !(sinfo->filled & (STATION_INFO_CHAIN_SIGNAL |
1824 STATION_INFO_CHAIN_SIGNAL_AVG))) {
1799 sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | 1825 sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
1800 STATION_INFO_CHAIN_SIGNAL_AVG; 1826 STATION_INFO_CHAIN_SIGNAL_AVG;
1801 1827
@@ -1807,8 +1833,15 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
1807 } 1833 }
1808 } 1834 }
1809 1835
1810 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); 1836 if (!(sinfo->filled & STATION_INFO_TX_BITRATE)) {
1811 sta_set_rate_info_rx(sta, &sinfo->rxrate); 1837 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
1838 sinfo->filled |= STATION_INFO_TX_BITRATE;
1839 }
1840
1841 if (!(sinfo->filled & STATION_INFO_RX_BITRATE)) {
1842 sta_set_rate_info_rx(sta, &sinfo->rxrate);
1843 sinfo->filled |= STATION_INFO_RX_BITRATE;
1844 }
1812 1845
1813 if (ieee80211_vif_is_mesh(&sdata->vif)) { 1846 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1814#ifdef CONFIG_MAC80211_MESH 1847#ifdef CONFIG_MAC80211_MESH