From c8705adaed86efa0bee203d354ca4ee5906391f5 Mon Sep 17 00:00:00 2001 From: Ashwin Adiga Date: Sun, 5 May 2024 08:46:44 -0500 Subject: [PATCH 257/296] non-upstream: mkeep_alive and tko string vendor cmds IW vendor commands for mkeep_alive & tko are being added here which uses string parsing infrastructure. Example for mkeep_alive: wl -> iw 1. wl mkeep_alive 0 1000 2. echo 'mkeep_alive 0 1000 ' | iw dev wlan0 vendor send 0x000319 0x1C - Example for tko: wl -> iw 1. wl tko enable 1 2. echo 'tko enable 1 ' | iw dev wlan0 vendor send 0x000319 0x1C - Signed-off-by: Ashwin Adiga --- .../broadcom/brcm80211/brcmfmac/vendor_ifx.c | 85 +++++++++++++++++++ .../broadcom/brcm80211/brcmfmac/vendor_ifx.h | 32 +++++++ 2 files changed, 117 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c index cbd58f0082d1..82cf1eafbeea 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.c @@ -47,6 +47,8 @@ static const struct ifx_vendor_cmdstr ifx_vndr_cmdstr[] = { { "offload_config", ifx_vndr_cmdstr_offload_config}, + { "mkeep_alive", ifx_vndr_cmdstr_mkeep_alive}, + { "tko", ifx_vndr_cmdstr_tko}, { NULL, NULL } }; @@ -884,6 +886,89 @@ int ifx_vndr_cmdstr_offload_config(struct wiphy *wiphy, struct wireless_dev *wde return ret; } +int ifx_vndr_cmdstr_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev, + char cmd_str[VNDR_CMD_STR_NUM][VNDR_CMD_STR_MAX_LEN], + long *cmd_val) +{ + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; + int ret = 0; + struct ifx_mkeep_alive mkeep_alive = {0}; + bool immed_flag = 0; + + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); + ifp = vif->ifp; + + /* echo 'mkeep_alive 0 1000 ' | iw dev wlan0 vendor + * send 0x000319 0x1C - + */ + + if (cmd_val[0] < 0 || cmd_val[0] > 4 || cmd_val[1] < 0) { + brcmf_err("Invalid command format\n"); + return -EINVAL; + } + if (cmd_str[1] && (strlen(cmd_str[1]) == 9) && + (memcmp(cmd_str[1], "immediate", 9)) == 0) { + immed_flag = 1; + } + mkeep_alive.period_msec = cmd_val[1]; + if (mkeep_alive.period_msec & WL_MKEEP_ALIVE_IMMEDIATE) { + brcmf_err("Period %d too large\n", mkeep_alive.period_msec); + return -EINVAL; + } + if (immed_flag && mkeep_alive.period_msec) + mkeep_alive.period_msec |= WL_MKEEP_ALIVE_IMMEDIATE; + + mkeep_alive.version = WL_MKEEP_ALIVE_VERSION; + mkeep_alive.length = offsetof(struct ifx_mkeep_alive, data); + mkeep_alive.keep_alive_id = cmd_val[0]; + mkeep_alive.len_bytes = 0; + + ret = brcmf_fil_bsscfg_data_set(ifp, "mkeep_alive", (void *)&mkeep_alive, + mkeep_alive.length); + if (ret) + brcmf_err("Failed to set mkeeplive params: %d\n", ret); + + return ret; +} + +int ifx_vndr_cmdstr_tko(struct wiphy *wiphy, struct wireless_dev *wdev, + char cmd_str[VNDR_CMD_STR_NUM][VNDR_CMD_STR_MAX_LEN], + long *cmd_val) +{ + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; + int ret = 0; + struct ifx_tko tko = {0}; + struct ifx_tko_enable *tko_enable; + int length; + + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); + ifp = vif->ifp; + + /* echo 'tko enable 1 ' | iw dev wlan0 vendor + * send 0x000319 0x1C - + */ + if (cmd_str[1] && (strlen(cmd_str[1]) == 6) && + (memcmp(cmd_str[1], "enable", 6) == 0) && + (cmd_val[0] == 0 || cmd_val[0] == 1)) { + tko_enable = (struct ifx_tko_enable *)tko.data; + tko.subcmd_id = WL_TKO_SUBCMD_ENABLE; + tko.len = sizeof(*tko_enable); + tko_enable->enable = cmd_val[0]; + + length = offsetof(struct ifx_tko, data) + tko.len; + ret = brcmf_fil_bsscfg_data_set(ifp, "tko", (void *)&tko, length); + if (ret) + brcmf_err("Failed to enable/disable tko: %d\n", ret); + } else { + brcmf_err("Invalid tko command format\n"); + return -EINVAL; + } + + return ret; +} + int ifx_cfg80211_vndr_cmds_str(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h index 2ece83f5e0f2..22a3548237a5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor_ifx.h @@ -700,6 +700,32 @@ struct ifx_maxidle_wnm { int protect; }; +#define WL_MKEEP_ALIVE_VERSION 1 +#define WL_MKEEP_ALIVE_IMMEDIATE 0x80000000 + +struct ifx_mkeep_alive { + u16 version; /* Version for mkeep_alive */ + u16 length; /* length of fixed parameters in the structure */ + u32 period_msec; /* high bit on means immediate send */ + u16 len_bytes; + u8 keep_alive_id; /* 0 - 3 for N = 4 */ + u8 data[1]; +}; + +struct ifx_tko { + u16 subcmd_id; /* subcommand id */ + u16 len; /* total length of data[] */ + u8 data[1]; /* subcommand data */ +}; + +/* subcommand ids */ +#define WL_TKO_SUBCMD_ENABLE 3 /* enable/disable */ + +struct ifx_tko_enable { + u8 enable; /* 1 - enable, 0 - disable */ + u8 pad[3]; /* 4-byte struct alignment */ +}; + /* String based vendor commands infra */ #define VNDR_CMD_STR_NUM 15 @@ -760,6 +786,12 @@ int ifx_cfg80211_vndr_cmds_wnm_wl_cap(struct wiphy *wiphy, int ifx_vndr_cmdstr_offload_config(struct wiphy *wiphy, struct wireless_dev *wdev, char cmd_str[VNDR_CMD_STR_NUM][VNDR_CMD_STR_MAX_LEN], long cmd_val[VNDR_CMD_VAL_NUM]); +int ifx_vndr_cmdstr_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev, + char cmd_str[VNDR_CMD_STR_NUM][VNDR_CMD_STR_MAX_LEN], + long *cmd_val); +int ifx_vndr_cmdstr_tko(struct wiphy *wiphy, struct wireless_dev *wdev, + char cmd_str[VNDR_CMD_STR_NUM][VNDR_CMD_STR_MAX_LEN], + long *cmd_val); int ifx_cfg80211_vndr_cmds_str(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len); -- 2.25.1