aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c20
-rw-r--r--include/net/mac80211.h17
-rw-r--r--net/mac80211/driver-ops.h30
-rw-r--r--net/mac80211/sta_info.c97
-rw-r--r--net/mac80211/trace.h33
5 files changed, 110 insertions, 87 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 2a99456b6b8f..8d11b0ca412c 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5376,14 +5376,15 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
5376 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed); 5376 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed);
5377} 5377}
5378 5378
5379static int wlcore_op_get_rssi(struct ieee80211_hw *hw, 5379static void wlcore_op_sta_statistics(struct ieee80211_hw *hw,
5380 struct ieee80211_vif *vif, 5380 struct ieee80211_vif *vif,
5381 struct ieee80211_sta *sta, 5381 struct ieee80211_sta *sta,
5382 s8 *rssi_dbm) 5382 struct station_info *sinfo)
5383{ 5383{
5384 struct wl1271 *wl = hw->priv; 5384 struct wl1271 *wl = hw->priv;
5385 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 5385 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5386 int ret = 0; 5386 s8 rssi_dbm;
5387 int ret;
5387 5388
5388 wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi"); 5389 wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi");
5389 5390
@@ -5396,17 +5397,18 @@ static int wlcore_op_get_rssi(struct ieee80211_hw *hw,
5396 if (ret < 0) 5397 if (ret < 0)
5397 goto out_sleep; 5398 goto out_sleep;
5398 5399
5399 ret = wlcore_acx_average_rssi(wl, wlvif, rssi_dbm); 5400 ret = wlcore_acx_average_rssi(wl, wlvif, &rssi_dbm);
5400 if (ret < 0) 5401 if (ret < 0)
5401 goto out_sleep; 5402 goto out_sleep;
5402 5403
5404 sinfo->filled |= STATION_INFO_SIGNAL;
5405 sinfo->signal = rssi_dbm;
5406
5403out_sleep: 5407out_sleep:
5404 wl1271_ps_elp_sleep(wl); 5408 wl1271_ps_elp_sleep(wl);
5405 5409
5406out: 5410out:
5407 mutex_unlock(&wl->mutex); 5411 mutex_unlock(&wl->mutex);
5408
5409 return ret;
5410} 5412}
5411 5413
5412static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) 5414static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
@@ -5606,7 +5608,7 @@ static const struct ieee80211_ops wl1271_ops = {
5606 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx, 5608 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
5607 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx, 5609 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
5608 .sta_rc_update = wlcore_op_sta_rc_update, 5610 .sta_rc_update = wlcore_op_sta_rc_update,
5609 .get_rssi = wlcore_op_get_rssi, 5611 .sta_statistics = wlcore_op_sta_statistics,
5610 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 5612 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
5611}; 5613};
5612 5614
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 555a845ad51e..123f2308958a 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2708,6 +2708,14 @@ enum ieee80211_reconfig_type {
2708 * is only used if the configured rate control algorithm actually uses 2708 * is only used if the configured rate control algorithm actually uses
2709 * the new rate table API, and is therefore optional. Must be atomic. 2709 * the new rate table API, and is therefore optional. Must be atomic.
2710 * 2710 *
2711 * @sta_statistics: Get statistics for this station. For example with beacon
2712 * filtering, the statistics kept by mac80211 might not be accurate, so
2713 * let the driver pre-fill the statistics. The driver can fill most of
2714 * the values (indicating which by setting the filled bitmap), but not
2715 * all of them make sense - see the source for which ones are possible.
2716 * Statistics that the driver doesn't fill will be filled by mac80211.
2717 * The callback can sleep.
2718 *
2711 * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), 2719 * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
2712 * bursting) for a hardware TX queue. 2720 * bursting) for a hardware TX queue.
2713 * Returns a negative error code on failure. 2721 * Returns a negative error code on failure.
@@ -2868,9 +2876,6 @@ enum ieee80211_reconfig_type {
2868 * @get_et_strings: Ethtool API to get a set of strings to describe stats 2876 * @get_et_strings: Ethtool API to get a set of strings to describe stats
2869 * and perhaps other supported types of ethtool data-sets. 2877 * and perhaps other supported types of ethtool data-sets.
2870 * 2878 *
2871 * @get_rssi: Get current signal strength in dBm, the function is optional
2872 * and can sleep.
2873 *
2874 * @mgd_prepare_tx: Prepare for transmitting a management frame for association 2879 * @mgd_prepare_tx: Prepare for transmitting a management frame for association
2875 * before associated. In multi-channel scenarios, a virtual interface is 2880 * before associated. In multi-channel scenarios, a virtual interface is
2876 * bound to a channel before it is associated, but as it isn't associated 2881 * bound to a channel before it is associated, but as it isn't associated
@@ -3071,6 +3076,10 @@ struct ieee80211_ops {
3071 void (*sta_rate_tbl_update)(struct ieee80211_hw *hw, 3076 void (*sta_rate_tbl_update)(struct ieee80211_hw *hw,
3072 struct ieee80211_vif *vif, 3077 struct ieee80211_vif *vif,
3073 struct ieee80211_sta *sta); 3078 struct ieee80211_sta *sta);
3079 void (*sta_statistics)(struct ieee80211_hw *hw,
3080 struct ieee80211_vif *vif,
3081 struct ieee80211_sta *sta,
3082 struct station_info *sinfo);
3074 int (*conf_tx)(struct ieee80211_hw *hw, 3083 int (*conf_tx)(struct ieee80211_hw *hw,
3075 struct ieee80211_vif *vif, u16 ac, 3084 struct ieee80211_vif *vif, u16 ac,
3076 const struct ieee80211_tx_queue_params *params); 3085 const struct ieee80211_tx_queue_params *params);
@@ -3138,8 +3147,6 @@ struct ieee80211_ops {
3138 void (*get_et_strings)(struct ieee80211_hw *hw, 3147 void (*get_et_strings)(struct ieee80211_hw *hw,
3139 struct ieee80211_vif *vif, 3148 struct ieee80211_vif *vif,
3140 u32 sset, u8 *data); 3149 u32 sset, u8 *data);
3141 int (*get_rssi)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3142 struct ieee80211_sta *sta, s8 *rssi_dbm);
3143 3150
3144 void (*mgd_prepare_tx)(struct ieee80211_hw *hw, 3151 void (*mgd_prepare_tx)(struct ieee80211_hw *hw,
3145 struct ieee80211_vif *vif); 3152 struct ieee80211_vif *vif);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 2ebc9ead9695..fdeda17b8dd2 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -639,6 +639,21 @@ static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
639 trace_drv_return_void(local); 639 trace_drv_return_void(local);
640} 640}
641 641
642static inline void drv_sta_statistics(struct ieee80211_local *local,
643 struct ieee80211_sub_if_data *sdata,
644 struct ieee80211_sta *sta,
645 struct station_info *sinfo)
646{
647 sdata = get_bss_sdata(sdata);
648 if (!check_sdata_in_driver(sdata))
649 return;
650
651 trace_drv_sta_statistics(local, sdata, sta);
652 if (local->ops->sta_statistics)
653 local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo);
654 trace_drv_return_void(local);
655}
656
642static inline int drv_conf_tx(struct ieee80211_local *local, 657static inline int drv_conf_tx(struct ieee80211_local *local,
643 struct ieee80211_sub_if_data *sdata, u16 ac, 658 struct ieee80211_sub_if_data *sdata, u16 ac,
644 const struct ieee80211_tx_queue_params *params) 659 const struct ieee80211_tx_queue_params *params)
@@ -966,21 +981,6 @@ drv_allow_buffered_frames(struct ieee80211_local *local,
966 trace_drv_return_void(local); 981 trace_drv_return_void(local);
967} 982}
968 983
969static inline int drv_get_rssi(struct ieee80211_local *local,
970 struct ieee80211_sub_if_data *sdata,
971 struct ieee80211_sta *sta,
972 s8 *rssi_dbm)
973{
974 int ret;
975
976 might_sleep();
977
978 ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm);
979 trace_drv_get_rssi(local, sta, *rssi_dbm, ret);
980
981 return ret;
982}
983
984static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, 984static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
985 struct ieee80211_sub_if_data *sdata) 985 struct ieee80211_sub_if_data *sdata)
986{ 986{
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
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 8e461a02c6a8..263a9561eb26 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -825,6 +825,13 @@ DECLARE_EVENT_CLASS(sta_event,
825 ) 825 )
826); 826);
827 827
828DEFINE_EVENT(sta_event, drv_sta_statistics,
829 TP_PROTO(struct ieee80211_local *local,
830 struct ieee80211_sub_if_data *sdata,
831 struct ieee80211_sta *sta),
832 TP_ARGS(local, sdata, sta)
833);
834
828DEFINE_EVENT(sta_event, drv_sta_add, 835DEFINE_EVENT(sta_event, drv_sta_add,
829 TP_PROTO(struct ieee80211_local *local, 836 TP_PROTO(struct ieee80211_local *local,
830 struct ieee80211_sub_if_data *sdata, 837 struct ieee80211_sub_if_data *sdata,
@@ -1329,32 +1336,6 @@ DEFINE_EVENT(release_evt, drv_allow_buffered_frames,
1329 TP_ARGS(local, sta, tids, num_frames, reason, more_data) 1336 TP_ARGS(local, sta, tids, num_frames, reason, more_data)
1330); 1337);
1331 1338
1332TRACE_EVENT(drv_get_rssi,
1333 TP_PROTO(struct ieee80211_local *local, struct ieee80211_sta *sta,
1334 s8 rssi, int ret),
1335
1336 TP_ARGS(local, sta, rssi, ret),
1337
1338 TP_STRUCT__entry(
1339 LOCAL_ENTRY
1340 STA_ENTRY
1341 __field(s8, rssi)
1342 __field(int, ret)
1343 ),
1344
1345 TP_fast_assign(
1346 LOCAL_ASSIGN;
1347 STA_ASSIGN;
1348 __entry->rssi = rssi;
1349 __entry->ret = ret;
1350 ),
1351
1352 TP_printk(
1353 LOCAL_PR_FMT STA_PR_FMT " rssi:%d ret:%d",
1354 LOCAL_PR_ARG, STA_PR_ARG, __entry->rssi, __entry->ret
1355 )
1356);
1357
1358DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, 1339DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx,
1359 TP_PROTO(struct ieee80211_local *local, 1340 TP_PROTO(struct ieee80211_local *local,
1360 struct ieee80211_sub_if_data *sdata), 1341 struct ieee80211_sub_if_data *sdata),