|
@@ -468,326 +468,6 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
|
|
|
rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
|
|
|
}
|
|
|
|
|
|
-static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
|
|
|
-{
|
|
|
- struct ieee80211_sub_if_data *sdata = sta->sdata;
|
|
|
- struct ieee80211_local *local = sdata->local;
|
|
|
- struct rate_control_ref *ref = local->rate_ctrl;
|
|
|
- struct timespec uptime;
|
|
|
- u64 packets = 0;
|
|
|
- u32 thr = 0;
|
|
|
- int i, ac;
|
|
|
-
|
|
|
- sinfo->generation = sdata->local->sta_generation;
|
|
|
-
|
|
|
- sinfo->filled = STATION_INFO_INACTIVE_TIME |
|
|
|
- STATION_INFO_RX_BYTES64 |
|
|
|
- STATION_INFO_TX_BYTES64 |
|
|
|
- STATION_INFO_RX_PACKETS |
|
|
|
- STATION_INFO_TX_PACKETS |
|
|
|
- STATION_INFO_TX_RETRIES |
|
|
|
- STATION_INFO_TX_FAILED |
|
|
|
- STATION_INFO_TX_BITRATE |
|
|
|
- STATION_INFO_RX_BITRATE |
|
|
|
- STATION_INFO_RX_DROP_MISC |
|
|
|
- STATION_INFO_BSS_PARAM |
|
|
|
- STATION_INFO_CONNECTED_TIME |
|
|
|
- STATION_INFO_STA_FLAGS |
|
|
|
- STATION_INFO_BEACON_LOSS_COUNT;
|
|
|
-
|
|
|
- do_posix_clock_monotonic_gettime(&uptime);
|
|
|
- sinfo->connected_time = uptime.tv_sec - sta->last_connected;
|
|
|
-
|
|
|
- sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
|
|
|
- sinfo->tx_bytes = 0;
|
|
|
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
|
|
- sinfo->tx_bytes += sta->tx_bytes[ac];
|
|
|
- packets += sta->tx_packets[ac];
|
|
|
- }
|
|
|
- sinfo->tx_packets = packets;
|
|
|
- sinfo->rx_bytes = sta->rx_bytes;
|
|
|
- sinfo->rx_packets = sta->rx_packets;
|
|
|
- sinfo->tx_retries = sta->tx_retry_count;
|
|
|
- sinfo->tx_failed = sta->tx_retry_failed;
|
|
|
- sinfo->rx_dropped_misc = sta->rx_dropped;
|
|
|
- sinfo->beacon_loss_count = sta->beacon_loss_count;
|
|
|
-
|
|
|
- if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
|
|
|
- (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
|
|
|
- sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
|
|
|
- if (!local->ops->get_rssi ||
|
|
|
- drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
|
|
|
- sinfo->signal = (s8)sta->last_signal;
|
|
|
- sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
|
|
|
- }
|
|
|
- if (sta->chains) {
|
|
|
- sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
|
|
|
- STATION_INFO_CHAIN_SIGNAL_AVG;
|
|
|
-
|
|
|
- sinfo->chains = sta->chains;
|
|
|
- for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
|
|
|
- sinfo->chain_signal[i] = sta->chain_signal_last[i];
|
|
|
- sinfo->chain_signal_avg[i] =
|
|
|
- (s8) -ewma_read(&sta->chain_signal_avg[i]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
|
|
|
- sta_set_rate_info_rx(sta, &sinfo->rxrate);
|
|
|
-
|
|
|
- if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
|
|
-#ifdef CONFIG_MAC80211_MESH
|
|
|
- sinfo->filled |= STATION_INFO_LLID |
|
|
|
- STATION_INFO_PLID |
|
|
|
- STATION_INFO_PLINK_STATE |
|
|
|
- STATION_INFO_LOCAL_PM |
|
|
|
- STATION_INFO_PEER_PM |
|
|
|
- STATION_INFO_NONPEER_PM;
|
|
|
-
|
|
|
- sinfo->llid = sta->llid;
|
|
|
- sinfo->plid = sta->plid;
|
|
|
- sinfo->plink_state = sta->plink_state;
|
|
|
- if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
|
|
|
- sinfo->filled |= STATION_INFO_T_OFFSET;
|
|
|
- sinfo->t_offset = sta->t_offset;
|
|
|
- }
|
|
|
- sinfo->local_pm = sta->local_pm;
|
|
|
- sinfo->peer_pm = sta->peer_pm;
|
|
|
- sinfo->nonpeer_pm = sta->nonpeer_pm;
|
|
|
-#endif
|
|
|
- }
|
|
|
-
|
|
|
- sinfo->bss_param.flags = 0;
|
|
|
- if (sdata->vif.bss_conf.use_cts_prot)
|
|
|
- sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
|
|
|
- if (sdata->vif.bss_conf.use_short_preamble)
|
|
|
- sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
|
|
|
- if (sdata->vif.bss_conf.use_short_slot)
|
|
|
- sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
|
|
|
- sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
|
|
|
- sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
|
|
|
-
|
|
|
- sinfo->sta_flags.set = 0;
|
|
|
- sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
|
|
|
- BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
|
|
|
- BIT(NL80211_STA_FLAG_WME) |
|
|
|
- BIT(NL80211_STA_FLAG_MFP) |
|
|
|
- BIT(NL80211_STA_FLAG_AUTHENTICATED) |
|
|
|
- BIT(NL80211_STA_FLAG_ASSOCIATED) |
|
|
|
- BIT(NL80211_STA_FLAG_TDLS_PEER);
|
|
|
- if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
|
|
|
- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
|
|
|
- if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
|
|
|
- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
|
|
|
- if (test_sta_flag(sta, WLAN_STA_WME))
|
|
|
- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
|
|
|
- if (test_sta_flag(sta, WLAN_STA_MFP))
|
|
|
- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
|
|
|
- if (test_sta_flag(sta, WLAN_STA_AUTH))
|
|
|
- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
|
|
|
- if (test_sta_flag(sta, WLAN_STA_ASSOC))
|
|
|
- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
|
|
|
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
|
|
|
- sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
|
|
|
-
|
|
|
- /* check if the driver has a SW RC implementation */
|
|
|
- if (ref && ref->ops->get_expected_throughput)
|
|
|
- thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv);
|
|
|
- else
|
|
|
- thr = drv_get_expected_throughput(local, &sta->sta);
|
|
|
-
|
|
|
- if (thr != 0) {
|
|
|
- sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT;
|
|
|
- sinfo->expected_throughput = thr;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
|
|
|
- "rx_packets", "rx_bytes",
|
|
|
- "rx_duplicates", "rx_fragments", "rx_dropped",
|
|
|
- "tx_packets", "tx_bytes", "tx_fragments",
|
|
|
- "tx_filtered", "tx_retry_failed", "tx_retries",
|
|
|
- "beacon_loss", "sta_state", "txrate", "rxrate", "signal",
|
|
|
- "channel", "noise", "ch_time", "ch_time_busy",
|
|
|
- "ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
|
|
|
-};
|
|
|
-#define STA_STATS_LEN ARRAY_SIZE(ieee80211_gstrings_sta_stats)
|
|
|
-
|
|
|
-static int ieee80211_get_et_sset_count(struct wiphy *wiphy,
|
|
|
- struct net_device *dev,
|
|
|
- int sset)
|
|
|
-{
|
|
|
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
|
- int rv = 0;
|
|
|
-
|
|
|
- if (sset == ETH_SS_STATS)
|
|
|
- rv += STA_STATS_LEN;
|
|
|
-
|
|
|
- rv += drv_get_et_sset_count(sdata, sset);
|
|
|
-
|
|
|
- if (rv == 0)
|
|
|
- return -EOPNOTSUPP;
|
|
|
- return rv;
|
|
|
-}
|
|
|
-
|
|
|
-static void ieee80211_get_et_stats(struct wiphy *wiphy,
|
|
|
- struct net_device *dev,
|
|
|
- struct ethtool_stats *stats,
|
|
|
- u64 *data)
|
|
|
-{
|
|
|
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
|
- struct ieee80211_chanctx_conf *chanctx_conf;
|
|
|
- struct ieee80211_channel *channel;
|
|
|
- struct sta_info *sta;
|
|
|
- struct ieee80211_local *local = sdata->local;
|
|
|
- struct station_info sinfo;
|
|
|
- struct survey_info survey;
|
|
|
- int i, q;
|
|
|
-#define STA_STATS_SURVEY_LEN 7
|
|
|
-
|
|
|
- memset(data, 0, sizeof(u64) * STA_STATS_LEN);
|
|
|
-
|
|
|
-#define ADD_STA_STATS(sta) \
|
|
|
- do { \
|
|
|
- data[i++] += sta->rx_packets; \
|
|
|
- data[i++] += sta->rx_bytes; \
|
|
|
- data[i++] += sta->num_duplicates; \
|
|
|
- data[i++] += sta->rx_fragments; \
|
|
|
- data[i++] += sta->rx_dropped; \
|
|
|
- \
|
|
|
- data[i++] += sinfo.tx_packets; \
|
|
|
- data[i++] += sinfo.tx_bytes; \
|
|
|
- data[i++] += sta->tx_fragments; \
|
|
|
- data[i++] += sta->tx_filtered_count; \
|
|
|
- data[i++] += sta->tx_retry_failed; \
|
|
|
- data[i++] += sta->tx_retry_count; \
|
|
|
- data[i++] += sta->beacon_loss_count; \
|
|
|
- } while (0)
|
|
|
-
|
|
|
- /* For Managed stations, find the single station based on BSSID
|
|
|
- * and use that. For interface types, iterate through all available
|
|
|
- * stations and add stats for any station that is assigned to this
|
|
|
- * network device.
|
|
|
- */
|
|
|
-
|
|
|
- mutex_lock(&local->sta_mtx);
|
|
|
-
|
|
|
- if (sdata->vif.type == NL80211_IFTYPE_STATION) {
|
|
|
- sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
|
|
|
-
|
|
|
- if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
|
|
|
- goto do_survey;
|
|
|
-
|
|
|
- sinfo.filled = 0;
|
|
|
- sta_set_sinfo(sta, &sinfo);
|
|
|
-
|
|
|
- i = 0;
|
|
|
- ADD_STA_STATS(sta);
|
|
|
-
|
|
|
- data[i++] = sta->sta_state;
|
|
|
-
|
|
|
-
|
|
|
- if (sinfo.filled & STATION_INFO_TX_BITRATE)
|
|
|
- data[i] = 100000 *
|
|
|
- cfg80211_calculate_bitrate(&sinfo.txrate);
|
|
|
- i++;
|
|
|
- if (sinfo.filled & STATION_INFO_RX_BITRATE)
|
|
|
- data[i] = 100000 *
|
|
|
- cfg80211_calculate_bitrate(&sinfo.rxrate);
|
|
|
- i++;
|
|
|
-
|
|
|
- if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
|
|
|
- data[i] = (u8)sinfo.signal_avg;
|
|
|
- i++;
|
|
|
- } else {
|
|
|
- list_for_each_entry(sta, &local->sta_list, list) {
|
|
|
- /* Make sure this station belongs to the proper dev */
|
|
|
- if (sta->sdata->dev != dev)
|
|
|
- continue;
|
|
|
-
|
|
|
- sinfo.filled = 0;
|
|
|
- sta_set_sinfo(sta, &sinfo);
|
|
|
- i = 0;
|
|
|
- ADD_STA_STATS(sta);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-do_survey:
|
|
|
- i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
|
|
|
- /* Get survey stats for current channel */
|
|
|
- survey.filled = 0;
|
|
|
-
|
|
|
- rcu_read_lock();
|
|
|
- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
|
|
- if (chanctx_conf)
|
|
|
- channel = chanctx_conf->def.chan;
|
|
|
- else
|
|
|
- channel = NULL;
|
|
|
- rcu_read_unlock();
|
|
|
-
|
|
|
- if (channel) {
|
|
|
- q = 0;
|
|
|
- do {
|
|
|
- survey.filled = 0;
|
|
|
- if (drv_get_survey(local, q, &survey) != 0) {
|
|
|
- survey.filled = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
- q++;
|
|
|
- } while (channel != survey.channel);
|
|
|
- }
|
|
|
-
|
|
|
- if (survey.filled)
|
|
|
- data[i++] = survey.channel->center_freq;
|
|
|
- else
|
|
|
- data[i++] = 0;
|
|
|
- if (survey.filled & SURVEY_INFO_NOISE_DBM)
|
|
|
- data[i++] = (u8)survey.noise;
|
|
|
- else
|
|
|
- data[i++] = -1LL;
|
|
|
- if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
|
|
|
- data[i++] = survey.channel_time;
|
|
|
- else
|
|
|
- data[i++] = -1LL;
|
|
|
- if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
|
|
|
- data[i++] = survey.channel_time_busy;
|
|
|
- else
|
|
|
- data[i++] = -1LL;
|
|
|
- if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
|
|
|
- data[i++] = survey.channel_time_ext_busy;
|
|
|
- else
|
|
|
- data[i++] = -1LL;
|
|
|
- if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
|
|
|
- data[i++] = survey.channel_time_rx;
|
|
|
- else
|
|
|
- data[i++] = -1LL;
|
|
|
- if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
|
|
|
- data[i++] = survey.channel_time_tx;
|
|
|
- else
|
|
|
- data[i++] = -1LL;
|
|
|
-
|
|
|
- mutex_unlock(&local->sta_mtx);
|
|
|
-
|
|
|
- if (WARN_ON(i != STA_STATS_LEN))
|
|
|
- return;
|
|
|
-
|
|
|
- drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
|
|
|
-}
|
|
|
-
|
|
|
-static void ieee80211_get_et_strings(struct wiphy *wiphy,
|
|
|
- struct net_device *dev,
|
|
|
- u32 sset, u8 *data)
|
|
|
-{
|
|
|
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
|
- int sz_sta_stats = 0;
|
|
|
-
|
|
|
- if (sset == ETH_SS_STATS) {
|
|
|
- sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
|
|
|
- memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
|
|
|
- }
|
|
|
- drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
|
|
|
-}
|
|
|
-
|
|
|
static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
|
|
|
int idx, u8 *mac, struct station_info *sinfo)
|
|
|
{
|
|
@@ -3597,21 +3277,6 @@ static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
|
|
|
return drv_get_antenna(local, tx_ant, rx_ant);
|
|
|
}
|
|
|
|
|
|
-static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx)
|
|
|
-{
|
|
|
- struct ieee80211_local *local = wiphy_priv(wiphy);
|
|
|
-
|
|
|
- return drv_set_ringparam(local, tx, rx);
|
|
|
-}
|
|
|
-
|
|
|
-static void ieee80211_get_ringparam(struct wiphy *wiphy,
|
|
|
- u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
|
|
|
-{
|
|
|
- struct ieee80211_local *local = wiphy_priv(wiphy);
|
|
|
-
|
|
|
- drv_get_ringparam(local, tx, tx_max, rx, rx_max);
|
|
|
-}
|
|
|
-
|
|
|
static int ieee80211_set_rekey_data(struct wiphy *wiphy,
|
|
|
struct net_device *dev,
|
|
|
struct cfg80211_gtk_rekey_data *data)
|
|
@@ -3843,8 +3508,6 @@ const struct cfg80211_ops mac80211_config_ops = {
|
|
|
.mgmt_frame_register = ieee80211_mgmt_frame_register,
|
|
|
.set_antenna = ieee80211_set_antenna,
|
|
|
.get_antenna = ieee80211_get_antenna,
|
|
|
- .set_ringparam = ieee80211_set_ringparam,
|
|
|
- .get_ringparam = ieee80211_get_ringparam,
|
|
|
.set_rekey_data = ieee80211_set_rekey_data,
|
|
|
.tdls_oper = ieee80211_tdls_oper,
|
|
|
.tdls_mgmt = ieee80211_tdls_mgmt,
|
|
@@ -3853,9 +3516,6 @@ const struct cfg80211_ops mac80211_config_ops = {
|
|
|
#ifdef CONFIG_PM
|
|
|
.set_wakeup = ieee80211_set_wakeup,
|
|
|
#endif
|
|
|
- .get_et_sset_count = ieee80211_get_et_sset_count,
|
|
|
- .get_et_stats = ieee80211_get_et_stats,
|
|
|
- .get_et_strings = ieee80211_get_et_strings,
|
|
|
.get_channel = ieee80211_cfg_get_channel,
|
|
|
.start_radar_detection = ieee80211_start_radar_detection,
|
|
|
.channel_switch = ieee80211_channel_switch,
|