From 0db4cd25e4993eda476cb64348b506b91e24c50c Mon Sep 17 00:00:00 2001 From: Pradeep Gurumath Date: Thu, 10 Aug 2023 13:24:53 -0500 Subject: [PATCH 172/296] brcmfmac: Send CSA to supplicant on channel change Fixes: SWLINUX-3649 When the AP changes channels, the underlying Driver/FW will negotiate correctly and stay connected, however, the Driver never informs netlink of the channel change. When the channel is queried, the channel is correct, however, wpa_supplicant is waiting on the NL80211_CMD_CH_SWITCH_NOTIFY event, which is triggered by cfg80211_ch_switch_notify which should be called by the FMAC driver. This patch adds support to send CSA event to wpa_supplicant. Signed-off-by: Pradeep Gurumath --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 54 +++++++++++++++++++ .../broadcom/brcm80211/brcmfmac/fweh.h | 1 + 2 files changed, 55 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index d1de0346425c..313c97c979d1 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -6598,6 +6598,58 @@ static int brcmf_cfg80211_get_channel(struct wiphy *wiphy, return 0; } +static s32 +brcmf_notify_csa_completion_ind(struct brcmf_if *ifp, + const struct brcmf_event_msg *e, void *data) +{ + struct brcmf_cfg80211_info *cfg; + struct net_device *ndev; + struct wiphy *wiphy; + struct cfg80211_chan_def chandef; + struct wireless_dev *wdev; + + int error = 0; + + brcmf_dbg(TRACE, "Enter\n"); + + if (unlikely(e->status)) { + brcmf_err("status:0x%x\n", e->status); + return -EINVAL; + } + + if (!ifp) + return -EINVAL; + else if (!ifp->drvr) + return -EINVAL; + + cfg = ifp->drvr->config; + ndev = cfg_to_ndev(cfg); + wiphy = cfg_to_wiphy(cfg); + + if (!cfg || !ndev || !wiphy) + return -EINVAL; + + wdev = ndev->ieee80211_ptr; + if (!wdev) + return -EINVAL; + + memset(&chandef, 0, sizeof(chandef)); + /* Reuse cfg80211 call to get chandef */ + error = brcmf_cfg80211_get_channel(wiphy, wdev, 0, &chandef); + if (unlikely(error)) { + brcmf_err("Get chandef error: %d \n", error); + return -EINVAL; + } + + /* Send channel switch notification only for STA mode */ + if (wdev->iftype == NL80211_IFTYPE_STATION) { + cfg80211_ch_switch_notify(ndev, &chandef, 0, 0); + brcmf_dbg(TRACE, "CSA sent upstream\n"); + } + + return 0; +} + static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy, struct wireless_dev *wdev, enum nl80211_crit_proto_id proto, @@ -8078,6 +8130,8 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) brcmf_notify_connect_status); brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, brcmf_notify_sched_scan_results); + brcmf_fweh_register(cfg->pub, BRCMF_E_SA_COMPLETE_IND, + brcmf_notify_csa_completion_ind); brcmf_fweh_register(cfg->pub, BRCMF_E_IF, brcmf_notify_vif_event); brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h index e32379dcadc9..3b9f2dd78dc7 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h @@ -89,6 +89,7 @@ struct brcmf_cfg80211_info; BRCMF_ENUM_DEF(DCS_REQUEST, 73) \ BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ + BRCMF_ENUM_DEF(SA_COMPLETE_IND, 80) \ BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \ BRCMF_ENUM_DEF(PHY_TEMP, 111) \ BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \ -- 2.25.1