diff options
author | Loic Poulain <loic.poulain@linaro.org> | 2021-11-22 16:47:26 +0100 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2021-11-29 12:24:59 +0200 |
commit | 7a6cfe28ae3ef6a78774fd1e21e3b76c90937112 (patch) | |
tree | 0b2be7ce02cba2375c683122ab0cd90ddbf44013 /drivers/net/wireless/broadcom/brcm80211 | |
parent | wilc1000: remove '-Wunused-but-set-variable' warning in chip_wakeup() (diff) | |
download | linux-dev-7a6cfe28ae3ef6a78774fd1e21e3b76c90937112.tar.xz linux-dev-7a6cfe28ae3ef6a78774fd1e21e3b76c90937112.zip |
brcmfmac: Configure keep-alive packet on suspend
When entering suspend as a client station with wowlan enabled,
the Wi-Fi link is supposed to be maintained. In that state, no
more data is generated from client side, and the link stays idle
as long the station is suspended and as long the AP as no data to
transmit.
However, most of the APs kick-off such 'inactive' stations after
few minutes, causing unexpected disconnect (reconnect, etc...).
The usual way to prevent this is to submit a Null function frame
periodically as a keep-alive. This is something that can be host
/software generated (e.g. wpa_supplicant), but that needs to be
offloaded to the Wi-Fi controller in case of suspended host.
This change enables firmware generated keep-alive frames when
entering wowlan suspend, using the 'mkeep_alive' IOVAR.
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1637596046-21651-1-git-send-email-loic.poulain@linaro.org
Diffstat (limited to 'drivers/net/wireless/broadcom/brcm80211')
-rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h | 19 |
2 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index fb727778312c..1679361f187b 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -3901,6 +3901,24 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg, cfg->wowl.active = true; } +static int brcmf_keepalive_start(struct brcmf_if *ifp, unsigned int interval) +{ + struct brcmf_mkeep_alive_pkt_le kalive = {0}; + int ret = 0; + + /* Configure Null function/data keepalive */ + kalive.version = cpu_to_le16(1); + kalive.period_msec = cpu_to_le16(interval * MSEC_PER_SEC); + kalive.len_bytes = cpu_to_le16(0); + kalive.keep_alive_id = cpu_to_le16(0); + + ret = brcmf_fil_iovar_data_set(ifp, "mkeep_alive", &kalive, sizeof(kalive)); + if (ret) + brcmf_err("keep-alive packet config failed, ret=%d\n", ret); + + return ret; +} + static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wowl) { @@ -3947,6 +3965,9 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, } else { /* Configure WOWL paramaters */ brcmf_configure_wowl(cfg, ifp, wowl); + + /* Prevent disassociation due to inactivity with keep-alive */ + brcmf_keepalive_start(ifp, 30); } exit: diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h index ff2ef557f0ea..e69d1e56996f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -1052,4 +1052,23 @@ struct brcmf_gscan_config { struct brcmf_gscan_bucket_config bucket[1]; }; +/** + * struct brcmf_mkeep_alive_pkt_le - configuration data for keep-alive frame. + * + * @version: version for mkeep_alive + * @length: length of fixed parameters in the structure. + * @period_msec: keep-alive period in milliseconds. + * @len_bytes: size of the data. + * @keep_alive_id: ID (0 - 3). + * @data: keep-alive frame data. + */ +struct brcmf_mkeep_alive_pkt_le { + __le16 version; + __le16 length; + __le32 period_msec; + __le16 len_bytes; + u8 keep_alive_id; + u8 data[0]; +} __packed; + #endif /* FWIL_TYPES_H_ */ |