Skip to content

Commit cca674d

Browse files
ordexjmberg-intel
authored andcommitted
mac80211: export the expected throughput
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. Cc: Felix Fietkau <[email protected]> Signed-off-by: Antonio Quartulli <[email protected]> Signed-off-by: Johannes Berg <[email protected]>
1 parent 867d849 commit cca674d

File tree

6 files changed

+94
-0
lines changed

6 files changed

+94
-0
lines changed

include/net/mac80211.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,10 @@ enum ieee80211_roc_type {
27692769
* information in bss_conf is set up and the beacon can be retrieved. A
27702770
* channel context is bound before this is called.
27712771
* @leave_ibss: Leave the IBSS again.
2772+
*
2773+
* @get_expected_throughput: extract the expected throughput towards the
2774+
* specified station. The returned value is expressed in Kbps. It returns 0
2775+
* if the RC algorithm does not have proper data to provide.
27722776
*/
27732777
struct ieee80211_ops {
27742778
void (*tx)(struct ieee80211_hw *hw,
@@ -2962,6 +2966,7 @@ struct ieee80211_ops {
29622966

29632967
int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
29642968
void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
2969+
u32 (*get_expected_throughput)(struct ieee80211_sta *sta);
29652970
};
29662971

29672972
/**
@@ -4535,6 +4540,8 @@ struct rate_control_ops {
45354540
void (*add_sta_debugfs)(void *priv, void *priv_sta,
45364541
struct dentry *dir);
45374542
void (*remove_sta_debugfs)(void *priv, void *priv_sta);
4543+
4544+
u32 (*get_expected_throughput)(void *priv_sta);
45384545
};
45394546

45404547
static inline int rate_supported(struct ieee80211_sta *sta,

net/mac80211/cfg.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,10 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
472472
{
473473
struct ieee80211_sub_if_data *sdata = sta->sdata;
474474
struct ieee80211_local *local = sdata->local;
475+
struct rate_control_ref *ref = local->rate_ctrl;
475476
struct timespec uptime;
476477
u64 packets = 0;
478+
u32 thr = 0;
477479
int i, ac;
478480

479481
sinfo->generation = sdata->local->sta_generation;
@@ -587,6 +589,17 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
587589
sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
588590
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
589591
sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
592+
593+
/* check if the driver has a SW RC implementation */
594+
if (ref && ref->ops->get_expected_throughput)
595+
thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv);
596+
else
597+
thr = drv_get_expected_throughput(local, &sta->sta);
598+
599+
if (thr != 0) {
600+
sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT;
601+
sinfo->expected_throughput = thr;
602+
}
590603
}
591604

592605
static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {

net/mac80211/driver-ops.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,4 +1156,17 @@ static inline void drv_leave_ibss(struct ieee80211_local *local,
11561156
trace_drv_return_void(local);
11571157
}
11581158

1159+
static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
1160+
struct ieee80211_sta *sta)
1161+
{
1162+
u32 ret = 0;
1163+
1164+
trace_drv_get_expected_throughput(sta);
1165+
if (local->ops->get_expected_throughput)
1166+
ret = local->ops->get_expected_throughput(sta);
1167+
trace_drv_return_u32(local, ret);
1168+
1169+
return ret;
1170+
}
1171+
11591172
#endif /* __MAC80211_DRIVER_OPS */

net/mac80211/rc80211_minstrel.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,17 @@ minstrel_free(void *priv)
657657
kfree(priv);
658658
}
659659

660+
static u32 minstrel_get_expected_throughput(void *priv_sta)
661+
{
662+
struct minstrel_sta_info *mi = priv_sta;
663+
int idx = mi->max_tp_rate[0];
664+
665+
/* convert pkt per sec in kbps (1200 is the average pkt size used for
666+
* computing cur_tp
667+
*/
668+
return MINSTREL_TRUNC(mi->r[idx].cur_tp) * 1200 * 8 / 1024;
669+
}
670+
660671
const struct rate_control_ops mac80211_minstrel = {
661672
.name = "minstrel",
662673
.tx_status = minstrel_tx_status,
@@ -670,6 +681,7 @@ const struct rate_control_ops mac80211_minstrel = {
670681
.add_sta_debugfs = minstrel_add_sta_debugfs,
671682
.remove_sta_debugfs = minstrel_remove_sta_debugfs,
672683
#endif
684+
.get_expected_throughput = minstrel_get_expected_throughput,
673685
};
674686

675687
int __init

net/mac80211/rc80211_minstrel_ht.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,22 @@ minstrel_ht_free(void *priv)
10321032
mac80211_minstrel.free(priv);
10331033
}
10341034

1035+
static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
1036+
{
1037+
struct minstrel_ht_sta_priv *msp = priv_sta;
1038+
struct minstrel_ht_sta *mi = &msp->ht;
1039+
int i, j;
1040+
1041+
if (!msp->is_ht)
1042+
return mac80211_minstrel.get_expected_throughput(priv_sta);
1043+
1044+
i = mi->max_tp_rate / MCS_GROUP_RATES;
1045+
j = mi->max_tp_rate % MCS_GROUP_RATES;
1046+
1047+
/* convert cur_tp from pkt per second in kbps */
1048+
return mi->groups[i].rates[j].cur_tp * AVG_PKT_SIZE * 8 / 1024;
1049+
}
1050+
10351051
static const struct rate_control_ops mac80211_minstrel_ht = {
10361052
.name = "minstrel_ht",
10371053
.tx_status = minstrel_ht_tx_status,
@@ -1046,6 +1062,7 @@ static const struct rate_control_ops mac80211_minstrel_ht = {
10461062
.add_sta_debugfs = minstrel_ht_add_sta_debugfs,
10471063
.remove_sta_debugfs = minstrel_ht_remove_sta_debugfs,
10481064
#endif
1065+
.get_expected_throughput = minstrel_ht_get_expected_throughput,
10491066
};
10501067

10511068

net/mac80211/trace.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,20 @@ TRACE_EVENT(drv_return_bool,
184184
"true" : "false")
185185
);
186186

187+
TRACE_EVENT(drv_return_u32,
188+
TP_PROTO(struct ieee80211_local *local, u32 ret),
189+
TP_ARGS(local, ret),
190+
TP_STRUCT__entry(
191+
LOCAL_ENTRY
192+
__field(u32, ret)
193+
),
194+
TP_fast_assign(
195+
LOCAL_ASSIGN;
196+
__entry->ret = ret;
197+
),
198+
TP_printk(LOCAL_PR_FMT " - %u", LOCAL_PR_ARG, __entry->ret)
199+
);
200+
187201
TRACE_EVENT(drv_return_u64,
188202
TP_PROTO(struct ieee80211_local *local, u64 ret),
189203
TP_ARGS(local, ret),
@@ -1499,6 +1513,24 @@ DEFINE_EVENT(local_sdata_evt, drv_leave_ibss,
14991513
TP_ARGS(local, sdata)
15001514
);
15011515

1516+
TRACE_EVENT(drv_get_expected_throughput,
1517+
TP_PROTO(struct ieee80211_sta *sta),
1518+
1519+
TP_ARGS(sta),
1520+
1521+
TP_STRUCT__entry(
1522+
STA_ENTRY
1523+
),
1524+
1525+
TP_fast_assign(
1526+
STA_ASSIGN;
1527+
),
1528+
1529+
TP_printk(
1530+
STA_PR_FMT, STA_PR_ARG
1531+
)
1532+
);
1533+
15021534
/*
15031535
* Tracing for API calls that drivers call.
15041536
*/

0 commit comments

Comments
 (0)