From 2631ea7ebbf591822b0900715225f40126a40cbc Mon Sep 17 00:00:00 2001 From: Gokul Sivakumar Date: Fri, 19 May 2023 00:28:48 -0500 Subject: [PATCH 168/296] brcmfmac: TWT: create a debugfs file to expose the TWT stats to userspace Create a debugfs file "twt_stats" with support for file read operation to let the userspace access the TWT session info along with the respective TWT session parameters like Target Wake Time, Wake Duration, Wake Interval, etc. Skip the attempt to print the TWT session info either if the Firmware does not support TWT or if the TWT session list is empty in an interface. $ cat /sys/kernel/debug/ieee80211/phy0/twt_stats ifname: wlan0, ifidx: 0, bsscfgidx: 0 iTWT Session, Flow ID: 0 Session state : Setup complete TWT peer : 00:00:00:00:00:00 Target Wake Time : 2399607488 uS Wake Duration : 20480 uS Wake Interval : 307200 uS Dialog_token : 1 Session type : Implicit, Trigger based, Announced iTWT Session, Flow ID: 1 Session state : Setup complete TWT peer : 00:00:00:00:00:00 Target Wake Time : 2433133585 uS Wake Duration : 20480 uS Wake Interval : 64000 uS Dialog_token : 2 Session type : Implicit, Non-Trigger based, Un-Announced Signed-off-by: Gokul Sivakumar --- .../broadcom/brcm80211/brcmfmac/core.c | 1 + .../broadcom/brcm80211/brcmfmac/twt.c | 85 +++++++++++++++++++ .../broadcom/brcm80211/brcmfmac/twt.h | 7 ++ 3 files changed, 93 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 230f36d0a10e..5d82153211b9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -1611,6 +1611,7 @@ static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) brcmf_feat_debugfs_create(drvr); brcmf_proto_debugfs_create(drvr); brcmf_bus_debugfs_create(bus_if); + brcmf_twt_debugfs_create(drvr); return 0; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/twt.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/twt.c index 546bbfe7f61c..46080c6a0a3b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/twt.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/twt.c @@ -143,6 +143,91 @@ brcmf_twt_float_to_u32(u8 exponent, u16 mantissa) return (u32)mantissa << exponent; } +/** + * brcmf_twt_stats_read() - Read the contents of the debugfs file "twt_stats". + * + * @seq: sequence for debugfs entry. + * @data: raw data pointer. + * + * return: 0. + */ +static int +brcmf_twt_stats_read(struct seq_file *seq, void *data) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); + struct brcmf_pub *drvr = bus_if->drvr; + int i; + + /* Return if the if TWT is not supported by Firmware */ + if (!(drvr->feat_flags & BIT(BRCMF_FEAT_TWT))) + return 0; + + /* Iterate the interface list in struct brcmf_pub */ + for (i = 0; i < BRCMF_MAX_IFS; i++) { + struct brcmf_if *ifp = drvr->iflist[i]; + struct brcmf_twt_session *twt_sess; + + /* Skip interface if TWT session list in struct brcmf_if is empty */ + if (!ifp || list_empty(&ifp->twt_sess_list)) + continue; + + seq_printf(seq, "ifname: %s, ifidx: %u, bsscfgidx: %d\n", + ifp->ndev ? ifp->ndev->name : "" , + ifp->ifidx, ifp->bsscfgidx); + + /* Iterate the TWT session list in struct brcmf_if */ + list_for_each_entry(twt_sess, &ifp->twt_sess_list, list) { + struct brcmf_twt_params *twt_params; + u32 wake_dur, wake_int; + + twt_params = &twt_sess->twt_params; + + wake_dur = brcmf_twt_min_twt_to_wake_dur(twt_params->min_twt, + twt_params->min_twt_unit); + wake_int = brcmf_twt_float_to_u32(twt_params->exponent, + twt_params->mantissa); + + if (twt_params->negotiation_type == IFX_TWT_PARAM_NEGO_TYPE_ITWT) + seq_printf(seq, "\tiTWT Session, Flow ID: %u\n", + twt_params->flow_id); + else if (twt_params->negotiation_type == IFX_TWT_PARAM_NEGO_TYPE_BTWT) + seq_printf(seq, "\tbTWT Session, Bcast TWT ID: %u\n", + twt_params->bcast_twt_id); + else + continue; + + seq_printf(seq, "\t\tSession state : %s\n", + brcmf_twt_session_state_str[twt_sess->state]); + seq_printf(seq, "\t\tTWT peer : %pM\n", + twt_sess->peer_addr.octet); + seq_printf(seq, "\t\tTarget Wake Time : %llu uS\n", + twt_params->twt); + seq_printf(seq, "\t\tWake Duration : %u uS\n", + wake_dur); + seq_printf(seq, "\t\tWake Interval : %u uS\n", + wake_int); + seq_printf(seq, "\t\tDialog_token : %u\n", + twt_params->dialog_token); + seq_printf(seq, "\t\tSession type : %s, %s, %s\n\n", + twt_params->implicit ? "Implicit" : "Explicit", + twt_params->trigger ? "Trigger based" : "Non-Trigger based", + twt_params->flow_type ? "Un-Announced" : "Announced"); + } + } + return 0; +} + +/** + * brcmf_twt_debugfs_create() - create debugfs entries. + * + * @drvr: driver instance. + */ +void +brcmf_twt_debugfs_create(struct brcmf_pub *drvr) +{ + brcmf_debugfs_add_entry(drvr, "twt_stats", brcmf_twt_stats_read); +} + /** * brcmf_twt_cleanup_sessions - Cleanup the TWT sessions from the driver list. * diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/twt.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/twt.h index 3dc81d414ef0..0208aed50584 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/twt.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/twt.h @@ -304,6 +304,13 @@ struct brcmf_twt_teardown_oper { struct brcmf_twt_teardesc teardesc; }; +/** + * brcmf_twt_debugfs_create() - create debugfs entries. + * + * @drvr: driver instance. + */ +void brcmf_twt_debugfs_create(struct brcmf_pub *drvr); + /** * brcmf_twt_cleanup_sessions - Cleanup the TWT sessions from the driver list. * -- 2.25.1