diff options
-rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 20 | ||||
-rw-r--r-- | include/net/mac80211.h | 17 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 30 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 97 | ||||
-rw-r--r-- | net/mac80211/trace.h | 33 |
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 | ||
5379 | static int wlcore_op_get_rssi(struct ieee80211_hw *hw, | 5379 | static 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 | |||
5403 | out_sleep: | 5407 | out_sleep: |
5404 | wl1271_ps_elp_sleep(wl); | 5408 | wl1271_ps_elp_sleep(wl); |
5405 | 5409 | ||
5406 | out: | 5410 | out: |
5407 | mutex_unlock(&wl->mutex); | 5411 | mutex_unlock(&wl->mutex); |
5408 | |||
5409 | return ret; | ||
5410 | } | 5412 | } |
5411 | 5413 | ||
5412 | static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) | 5414 | static 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 | ||
642 | static 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 | |||
642 | static inline int drv_conf_tx(struct ieee80211_local *local, | 657 | static 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 | ||
969 | static 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 | |||
984 | static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, | 984 | static 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 | ||
828 | DEFINE_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 | |||
828 | DEFINE_EVENT(sta_event, drv_sta_add, | 835 | DEFINE_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 | ||
1332 | TRACE_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 | |||
1358 | DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, | 1339 | DEFINE_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), |