Export the expected throughput towards a peer
Subsystems (2)
v4 cover Export the expected throughput towards a peer
Changes since v3:
- squash patch 1 and 2
- in 3/3 change mac_addr from u8 * to const u8 * (both in the new cfg80211_get_station and in the already existing rdev_get_station)
- add type and unit for NL80211_STA_EXPECTED_THROUGHPUT
Changes since v2:
- fix throughput computation in minstrel
- squash minstrel patches
Changes since v1:
- add expected throughput nl80211 attribute to the GET_STATION reply message
- the unit of the exported value has been changed to kbps
- the way the exported value was computed in minstrel and minstrel_ht has been changed after having really understood what minstrel is doing (thanks Johannes!)
- the number of arguments of the RC api have been reduced
- allow the API result to be 0 if the underlying layer does not know what to report
- squash ex patch 2/3/4
- use wiphy_to_rdev() where needed
Antonio Quartulli (3):
cfg80211: export expected throughput through get_station()
mac80211: export the expected throughput
cfg80211: implement cfg80211_get_station cfg80211 API
include/net/cfg80211.h | 75 ++++++++++++++++++++++++-------------- include/net/mac80211.h | 7 ++++ include/uapi/linux/nl80211.h | 3 ++ net/mac80211/cfg.c | 19 ++++++++++ net/mac80211/driver-ops.h | 13 +++++++ net/mac80211/rc80211_minstrel.c | 12 ++++++ net/mac80211/rc80211_minstrel_ht.c | 17 +++++++++ net/mac80211/trace.h | 32 ++++++++++++++++ net/wireless/nl80211.c | 4 ++ net/wireless/rdev-ops.h | 2 +- net/wireless/util.c | 18 +++++++++ 11 files changed, 173 insertions(+), 29 deletions(-)
Signature · 1 line
1.8.5.5
PATCH v4 1/3 cfg80211: export expected throughput through get_station()
From: Antonio Quartulli <[email protected]>
Users may need information about the expected throughput towards a given peer.
This value is supposed to consider the size overhead generated by the 802.11 header.
This value is exported in kbps through the get_station() API by including it into the station_info object. Moreover, it is sent to user space when replying to the nl80211 GET_STATION command.
This information will be useful to the batman-adv module which will use it for its new metric computation.
--- include/net/cfg80211.h | 62 ++++++++++++++++++++++++-------------------- include/uapi/linux/nl80211.h | 3 +++ net/wireless/nl80211.c | 4 +++ 3 files changed, 41 insertions(+), 28 deletions(-)
include/net/cfg80211.h +34 -28
@@ -873,36 +873,38 @@ int cfg80211_check_station_change(struct wiphy *wiphy,* @STATION_INFO_NONPEER_PM: @nonpeer_pm filled * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled +* @STATION_INFO_EXPECTED_THROUGHPUT: @expected_throughput filled */ enum station_info_flags { -STATION_INFO_INACTIVE_TIME =1 <<0 , -STATION_INFO_RX_BYTES =1 <<1 , -STATION_INFO_TX_BYTES =1 <<2 , -STATION_INFO_LLID =1 <<3 , -STATION_INFO_PLID =1 <<4 , -STATION_INFO_PLINK_STATE =1 <<5 , -STATION_INFO_SIGNAL =1 <<6 , -STATION_INFO_TX_BITRATE =1 <<7 , -STATION_INFO_RX_PACKETS =1 <<8 , -STATION_INFO_TX_PACKETS =1 <<9 , -STATION_INFO_TX_RETRIES =1 <<10 , -STATION_INFO_TX_FAILED =1 <<11 , -STATION_INFO_RX_DROP_MISC =1 <<12 , -STATION_INFO_SIGNAL_AVG =1 <<13 , -STATION_INFO_RX_BITRATE =1 <<14 , -STATION_INFO_BSS_PARAM =1 <<15 , -STATION_INFO_CONNECTED_TIME =1 <<16 , -STATION_INFO_ASSOC_REQ_IES =1 <<17 , -STATION_INFO_STA_FLAGS =1 <<18 , -STATION_INFO_BEACON_LOSS_COUNT =1 <<19 , -STATION_INFO_T_OFFSET =1 <<20 , -STATION_INFO_LOCAL_PM =1 <<21 , -STATION_INFO_PEER_PM =1 <<22 , -STATION_INFO_NONPEER_PM =1 <<23 , -STATION_INFO_RX_BYTES64 =1 <<24 , -STATION_INFO_TX_BYTES64 =1 <<25 , -STATION_INFO_CHAIN_SIGNAL =1 <<26 , -STATION_INFO_CHAIN_SIGNAL_AVG =1 <<27 , +STATION_INFO_INACTIVE_TIME =BIT (0 ), +STATION_INFO_RX_BYTES =BIT (1 ), +STATION_INFO_TX_BYTES =BIT (2 ), +STATION_INFO_LLID =BIT (3 ), +STATION_INFO_PLID =BIT (4 ), +STATION_INFO_PLINK_STATE =BIT (5 ), +STATION_INFO_SIGNAL =BIT (6 ), +STATION_INFO_TX_BITRATE =BIT (7 ), +STATION_INFO_RX_PACKETS =BIT (8 ), +STATION_INFO_TX_PACKETS =BIT (9 ), +STATION_INFO_TX_RETRIES =BIT (10 ), +STATION_INFO_TX_FAILED =BIT (11 ), +STATION_INFO_RX_DROP_MISC =BIT (12 ), +STATION_INFO_SIGNAL_AVG =BIT (13 ), +STATION_INFO_RX_BITRATE =BIT (14 ), +STATION_INFO_BSS_PARAM =BIT (15 ), +STATION_INFO_CONNECTED_TIME =BIT (16 ), +STATION_INFO_ASSOC_REQ_IES =BIT (17 ), +STATION_INFO_STA_FLAGS =BIT (18 ), +STATION_INFO_BEACON_LOSS_COUNT =BIT (19 ), +STATION_INFO_T_OFFSET =BIT (20 ), +STATION_INFO_LOCAL_PM =BIT (21 ), +STATION_INFO_PEER_PM =BIT (22 ), +STATION_INFO_NONPEER_PM =BIT (23 ), +STATION_INFO_RX_BYTES64 =BIT (24 ), +STATION_INFO_TX_BYTES64 =BIT (25 ), +STATION_INFO_CHAIN_SIGNAL =BIT (26 ), +STATION_INFO_CHAIN_SIGNAL_AVG =BIT (27 ), +STATION_INFO_EXPECTED_THROUGHPUT =BIT (28 ), };/**
@@ -1024,6 +1026,8 @@ struct sta_bss_parameters {* @local_pm: local mesh STA power save mode * @peer_pm: peer mesh STA power save mode * @nonpeer_pm: non-peer mesh STA power save mode +* @expected_throughput: expected throughput in kbps (including 802.11 headers) +* towards this station. */ struct station_info {u32 filled;
@@ -1062,6 +1066,8 @@ struct station_info {enum nl80211_mesh_power_mode peer_pm;enum nl80211_mesh_power_mode nonpeer_pm; +u32 expected_throughput; +/* * Note: Add a new enum station_info_flags value for each new field and * use it to check which fields are initialized.
include/uapi/linux/nl80211.h +3 -0
@@ -2199,6 +2199,8 @@ enum nl80211_sta_bss_param {* Contains a nested array of signal strength attributes (u8, dBm) * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average * Same format as NL80211_STA_INFO_CHAIN_SIGNAL. +* @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the +* 802.11 header (u32, kbps) * @__NL80211_STA_INFO_AFTER_LAST: internal * @NL80211_STA_INFO_MAX: highest possible station info attribute */
@@ -2230,6 +2232,7 @@ enum nl80211_sta_info {NL80211_STA_INFO_TX_BYTES64 ,NL80211_STA_INFO_CHAIN_SIGNAL ,NL80211_STA_INFO_CHAIN_SIGNAL_AVG , +NL80211_STA_INFO_EXPECTED_THROUGHPUT ,/* keep last */ __NL80211_STA_INFO_AFTER_LAST,
net/wireless/nl80211.c +4 -0
@@ -3650,6 +3650,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, sinfo->tx_failed)) goto nla_put_failure; +if ((sinfo->filled &STATION_INFO_EXPECTED_THROUGHPUT ) && +nla_put_u32 (msg,NL80211_STA_INFO_EXPECTED_THROUGHPUT , + sinfo->expected_throughput)) + goto nla_put_failure;if ((sinfo->filled &STATION_INFO_BEACON_LOSS_COUNT ) &&nla_put_u32 (msg,NL80211_STA_INFO_BEACON_LOSS , sinfo->beacon_loss_count))
Signature · 1 line
1.8.5.5
PATCH v4 2/3 mac80211: export the expected throughput
In reply to Antonio QuartulliFrom: Antonio Quartulli <[email protected]>
Add get_expected_throughput() API to mac80211 so that each driver can implement its own version based on the RC algorithm they are using (might be using an HW RC algo). The API returns a value expressed in Kbps.
Also, add the new get_expected_throughput() member to the rate_control_ops structure in order to be able to query the RC algorithm (this patch provides an implementation of this API for both minstrel and minstrel_ht).
The related member in the station_info object is now filled accordingly when dumping a station.
--- include/net/mac80211.h | 7 +++++++ net/mac80211/cfg.c | 19 +++++++++++++++++++ net/mac80211/driver-ops.h | 13 +++++++++++++ net/mac80211/rc80211_minstrel.c | 12 ++++++++++++ net/mac80211/rc80211_minstrel_ht.c | 17 +++++++++++++++++ net/mac80211/trace.h | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 100 insertions(+)
include/net/mac80211.h +7 -0
@@ -2769,6 +2769,10 @@ enum ieee80211_roc_type {* information in bss_conf is set up and the beacon can be retrieved. A * channel context is bound before this is called. * @leave_ibss: Leave the IBSS again. +* +* @get_expected_throughput: extract the expected throughput towards the +* specified station. The returned value is expressed in Kbps. It returns 0 +* if the RC algorithm does not have proper data to provide. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw,
@@ -2962,6 +2966,7 @@ struct ieee80211_ops {int (*join_ibss)(struct ieee80211_hw *hw,struct ieee80211_vif *vif);void (*leave_ibss)(struct ieee80211_hw *hw,struct ieee80211_vif *vif); +u32 (*get_expected_throughput)(struct ieee80211_sta *sta); };/**
@@ -4535,6 +4540,8 @@ struct rate_control_ops {void (*add_sta_debugfs)(void *priv,void *priv_sta,struct dentry *dir);void (*remove_sta_debugfs)(void *priv,void *priv_sta); + +u32 (*get_expected_throughput)(void *priv_sta); }; static inline int rate_supported(struct ieee80211_sta *sta,
net/mac80211/cfg.c +19 -0
@@ -472,8 +472,12 @@ 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 ieee80211_supported_band *sband; +enum ieee80211_band band;struct timespec uptime;u64 packets =0 ; +u32 thr =0 ;int i, ac; sinfo->generation = sdata->local->sta_generation;
@@ -587,6 +591,21 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 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) { + band =ieee80211_get_sdata_band (sta->sdata); + sband = sta->local->hw.wiphy->bands[band]; + + 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 ] = {
net/mac80211/driver-ops.h +13 -0
@@ -1156,4 +1156,17 @@ static inline void drv_leave_ibss(struct ieee80211_local *local, trace_drv_return_void(local); } +static inline u32 drv_get_expected_throughput (struct ieee80211_local *local, +struct ieee80211_sta *sta) +{ +u32 ret =0 ; + +trace_drv_get_expected_throughput (sta); +if (local->ops->get_expected_throughput) + ret = local->ops->get_expected_throughput (sta); +trace_drv_return_u32 (local, ret); + +return ret; +} +#endif /* __MAC80211_DRIVER_OPS */
net/mac80211/rc80211_minstrel.c +12 -0
@@ -657,6 +657,17 @@ minstrel_free(void *priv)kfree (priv); } +static u32 minstrel_get_expected_throughput (void *priv_sta) +{ +struct minstrel_sta_info *mi = priv_sta; +int idx = mi->max_tp_rate[0 ]; + +/* convert pkt per sec in kbps (1200 is the average pkt size used for +* computing cur_tp +*/ +return MINSTREL_TRUNC (mi->r[idx].cur_tp) *1200 *8 /1024 ; +} +const struct rate_control_ops mac80211_minstrel = { .name ="minstrel" , .tx_status = minstrel_tx_status,
@@ -670,6 +681,7 @@ const struct rate_control_ops mac80211_minstrel = { .add_sta_debugfs = minstrel_add_sta_debugfs, .remove_sta_debugfs = minstrel_remove_sta_debugfs, #endif + .get_expected_throughput = minstrel_get_expected_throughput, };int __init
net/mac80211/rc80211_minstrel_ht.c +17 -0
@@ -1032,6 +1032,22 @@ minstrel_ht_free(void *priv) mac80211_minstrel.free (priv); } +static u32 minstrel_ht_get_expected_throughput (void *priv_sta) +{ +struct minstrel_ht_sta_priv *msp = priv_sta; +struct minstrel_ht_sta *mi = &msp->ht; +int i, j; + +if (!msp->is_ht) +return mac80211_minstrel.get_expected_throughput (priv_sta); + + i = mi->max_tp_rate /MCS_GROUP_RATES ; + j = mi->max_tp_rate %MCS_GROUP_RATES ; + +/* convert cur_tp from pkt per second in kbps */ +return mi->groups[i].rates[j].cur_tp *AVG_PKT_SIZE *8 /1024 ; +} +static const struct rate_control_ops mac80211_minstrel_ht = { .name ="minstrel_ht" , .tx_status = minstrel_ht_tx_status,
@@ -1046,6 +1062,7 @@ static const struct rate_control_ops mac80211_minstrel_ht = { .add_sta_debugfs = minstrel_ht_add_sta_debugfs, .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs, #endif + .get_expected_throughput = minstrel_ht_get_expected_throughput, };
net/mac80211/trace.h +32 -0
@@ -184,6 +184,20 @@ TRACE_EVENT(drv_return_bool, "true" : "false") ); +TRACE_EVENT (drv_return_u32, + TP_PROTO(struct ieee80211_local *local, u32 ret), +TP_ARGS (local, ret), +TP_STRUCT__entry ( + LOCAL_ENTRY +__field (u32, ret) + ), +TP_fast_assign ( + LOCAL_ASSIGN; + __entry->ret = ret; + ), +TP_printk (LOCAL_PR_FMT " - %u" ,LOCAL_PR_ARG , __entry->ret) +); + TRACE_EVENT(drv_return_u64, TP_PROTO(struct ieee80211_local *local, u64 ret), TP_ARGS(local, ret),
@@ -1499,6 +1513,24 @@ DEFINE_EVENT(local_sdata_evt, drv_leave_ibss,TP_ARGS (local, sdata) ); +TRACE_EVENT (drv_get_expected_throughput, + TP_PROTO(struct ieee80211_sta *sta), + +TP_ARGS (sta), + +TP_STRUCT__entry ( +STA_ENTRY + ), + +TP_fast_assign ( + STA_ASSIGN; + ), + +TP_printk ( +STA_PR_FMT ,STA_PR_ARG + ) +); +/* * Tracing for API calls that drivers call. */
Signature · 1 line
1.8.5.5
A message that is not in the archive (sent off-list or not yet received): CAEbDFcSH7p+P6i=utpNT35+JoQ+ADwnbuX8TBgE+1fLYvG9Lqw@mail.gmail.com
Re: [B.A.T.M.A.N.] [PATCHv4 2/3] mac80211: export the expected throughput
Quoted 3 lines · Krishnathiepan Rasanayagam
Dear all,
Sorry if I'm disturbing you. please let me know how to ask a question and getting answer about batman-adv
By writing a *new* email to the batman-adv mailing list *only* for example? :)
In case you want to know more, I think that you can just visit this link:
http://www.open-mesh.org/projects/open-mesh/wiki
Cheers,
Signature · 1 line
Antonio Quartulli
PATCH v4 3/3 cfg80211: implement cfg80211_get_station cfg80211 API
In reply to Antonio QuartulliFrom: Antonio Quartulli <[email protected]>
Implement and export the new cfg80211_get_station() API. This utility can be used by other kernel modules to obtain detailed information about a given wireless station.
It will be in particular useful to batman-adv which will implement a wireless rate based metric.
--- include/net/cfg80211.h | 13 +++++++++++++ net/wireless/rdev-ops.h | 2 +- net/wireless/util.c | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-)
include/net/cfg80211.h +13 -0
@@ -1075,6 +1075,19 @@ struct station_info { };/** +* cfg80211_get_station - retrieve information about a given station +* @dev: the device where the station is supposed to be connected to +* @mac_addr: the mac address of the station of interest +* @sinfo: pointer to the structure to fill with the information +* +* Returns 0 on success and sinfo is filled with the available information +* otherwise returns a negative error code and the content of sinfo has to be +* considered undefined. +*/ +int cfg80211_get_station (struct net_device *dev,const u8 *mac_addr, +struct station_info *sinfo); + +/** * enum monitor_flags - monitor flags * * Monitor interface configuration flags. Note that these must be the bits
net/wireless/rdev-ops.h +1 -1
@@ -199,7 +199,7 @@ static inline int rdev_change_station(struct cfg80211_registered_device *rdev, }static inline int rdev_get_station (struct cfg80211_registered_device *rdev, -struct net_device *dev,u8 *mac, +struct net_device *dev,const u8 *mac,struct station_info *sinfo) {int ret;
net/wireless/util.c +18 -0
@@ -1546,6 +1546,24 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy) }EXPORT_SYMBOL (ieee80211_get_num_supported_channels); +int cfg80211_get_station (struct net_device *dev,const u8 *mac_addr, +struct station_info *sinfo) +{ +struct cfg80211_registered_device *rdev; +struct wireless_dev *wdev; + + wdev = dev->ieee80211_ptr; +if (!wdev) +return -EOPNOTSUPP ; + + rdev =wiphy_to_rdev (wdev->wiphy); +if (!rdev->ops->get_station) +return -EOPNOTSUPP ; + +return rdev_get_station (rdev, dev, mac_addr, sinfo); +} +EXPORT_SYMBOL (cfg80211_get_station); +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ const unsigned char rfc1042_header[] __aligned(2) =
Signature · 1 line
1.8.5.5
Applied all, thanks.
johannes