^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * mac80211 ethtool hooks for cfg80211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copied from cfg.c - originally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2014 Intel Corporation (Author: Johannes Berg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2018 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <net/cfg80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "ieee80211_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "sta_info.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "driver-ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static int ieee80211_set_ringparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct ethtool_ringparam *rp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return drv_set_ringparam(local, rp->tx_pending, rp->rx_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static void ieee80211_get_ringparam(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct ethtool_ringparam *rp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) memset(rp, 0, sizeof(*rp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) drv_get_ringparam(local, &rp->tx_pending, &rp->tx_max_pending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) &rp->rx_pending, &rp->rx_max_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) "rx_packets", "rx_bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) "rx_duplicates", "rx_fragments", "rx_dropped",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "tx_packets", "tx_bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) "tx_filtered", "tx_retry_failed", "tx_retries",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) "sta_state", "txrate", "rxrate", "signal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) "channel", "noise", "ch_time", "ch_time_busy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) "ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define STA_STATS_LEN ARRAY_SIZE(ieee80211_gstrings_sta_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int ieee80211_get_sset_count(struct net_device *dev, int sset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int rv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (sset == ETH_SS_STATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) rv += STA_STATS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) rv += drv_get_et_sset_count(sdata, sset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (rv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static void ieee80211_get_stats(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct ethtool_stats *stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u64 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct ieee80211_chanctx_conf *chanctx_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct ieee80211_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct sta_info *sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct ieee80211_local *local = sdata->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct station_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct survey_info survey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int i, q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define STA_STATS_SURVEY_LEN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) memset(data, 0, sizeof(u64) * STA_STATS_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define ADD_STA_STATS(sta) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) data[i++] += sta->rx_stats.packets; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) data[i++] += sta->rx_stats.bytes; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) data[i++] += sta->rx_stats.num_duplicates; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) data[i++] += sta->rx_stats.fragments; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) data[i++] += sta->rx_stats.dropped; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) data[i++] += sinfo.tx_packets; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) data[i++] += sinfo.tx_bytes; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) data[i++] += sta->status_stats.filtered; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) data[i++] += sta->status_stats.retry_failed; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) data[i++] += sta->status_stats.retry_count; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* For Managed stations, find the single station based on BSSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * and use that. For interface types, iterate through all available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * stations and add stats for any station that is assigned to this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * network device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) mutex_lock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (sdata->vif.type == NL80211_IFTYPE_STATION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) goto do_survey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) memset(&sinfo, 0, sizeof(sinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) sta_set_sinfo(sta, &sinfo, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ADD_STA_STATS(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) data[i++] = sta->sta_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) data[i] = 100000ULL *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cfg80211_calculate_bitrate(&sinfo.txrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) data[i] = 100000ULL *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) cfg80211_calculate_bitrate(&sinfo.rxrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) data[i] = (u8)sinfo.signal_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) list_for_each_entry(sta, &local->sta_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Make sure this station belongs to the proper dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (sta->sdata->dev != dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) memset(&sinfo, 0, sizeof(sinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) sta_set_sinfo(sta, &sinfo, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ADD_STA_STATS(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) do_survey:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Get survey stats for current channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) survey.filled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (chanctx_conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) channel = chanctx_conf->def.chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) channel = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) q = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) survey.filled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (drv_get_survey(local, q, &survey) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) survey.filled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) q++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) } while (channel != survey.channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (survey.filled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) data[i++] = survey.channel->center_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) data[i++] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (survey.filled & SURVEY_INFO_NOISE_DBM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) data[i++] = (u8)survey.noise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) data[i++] = -1LL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (survey.filled & SURVEY_INFO_TIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) data[i++] = survey.time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) data[i++] = -1LL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (survey.filled & SURVEY_INFO_TIME_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) data[i++] = survey.time_busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) data[i++] = -1LL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (survey.filled & SURVEY_INFO_TIME_EXT_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) data[i++] = survey.time_ext_busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) data[i++] = -1LL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (survey.filled & SURVEY_INFO_TIME_RX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) data[i++] = survey.time_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) data[i++] = -1LL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (survey.filled & SURVEY_INFO_TIME_TX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) data[i++] = survey.time_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) data[i++] = -1LL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) mutex_unlock(&local->sta_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (WARN_ON(i != STA_STATS_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int sz_sta_stats = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (sset == ETH_SS_STATS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int ieee80211_get_regs_len(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void ieee80211_get_regs(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct ethtool_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) regs->version = wdev->wiphy->hw_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) regs->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) const struct ethtool_ops ieee80211_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .get_drvinfo = cfg80211_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .get_regs_len = ieee80211_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .get_regs = ieee80211_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .get_link = ethtool_op_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .get_ringparam = ieee80211_get_ringparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .set_ringparam = ieee80211_set_ringparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .get_strings = ieee80211_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .get_ethtool_stats = ieee80211_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .get_sset_count = ieee80211_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };