From bf41a8c8cac74ef2c24a016e358211ad80f967b0 Mon Sep 17 00:00:00 2001 From: Ian Lin Date: Tue, 2 Jul 2024 21:29:20 -0500 Subject: [PATCH 263/296] brcmfmac: add new iovar format for action frame A new parameter format of iovar "actframe" was applied for 6G P2P feature which was introduced to H2. The corresponding driver changes are: - get interface version while chip initialization - if the version matches particular one, apply new parameter format of actframe Signed-off-by: Ian Lin --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- .../broadcom/brcm80211/brcmfmac/cfg80211.h | 2 ++ .../broadcom/brcm80211/brcmfmac/common.c | 16 +++++++++ .../broadcom/brcm80211/brcmfmac/core.h | 8 +++++ .../broadcom/brcm80211/brcmfmac/fwil_types.h | 14 ++++++++ .../broadcom/brcm80211/brcmfmac/p2p.c | 34 +++++++++++++------ 6 files changed, 64 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index a391353c456b..4cde3aefe659 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -552,7 +552,7 @@ wl_cfgoce_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len, return false; } -static u8 nl80211_band_to_fwil(enum nl80211_band band) +u8 nl80211_band_to_fwil(enum nl80211_band band) { switch (band) { case NL80211_BAND_2GHZ: diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index c886530c1991..a6e4e196510f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -493,6 +493,8 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) return &cfg->conn_info; } +u8 nl80211_band_to_fwil(enum nl80211_band band); + struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, struct cfg80211_ops *ops, bool p2pdev_forced); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 9d0663eaca50..8ef5837d3da0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -450,6 +450,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) struct brcmf_bus *bus; struct brcmf_rev_info_le revinfo; struct brcmf_rev_info *ri; + struct brcmf_wlc_version_le wlc_ver; char *clmver; char *ptr; s32 err; @@ -564,6 +565,21 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) } strscpy(ifp->drvr->fwver, ptr + 1, sizeof(ifp->drvr->fwver)); + /* Get wlc interface version, set to 0 for legacy chip + * that is not supporting wlc_ver iovar + */ + err = brcmf_fil_iovar_data_get(ifp, "wlc_ver", &wlc_ver, sizeof(wlc_ver)); + if (err < 0) { + ifp->drvr->wlc_ver.wlc_ver_major = 0; + ifp->drvr->wlc_ver.wlc_ver_minor = 0; + } else { + ifp->drvr->wlc_ver.wlc_ver_major = le16_to_cpu(wlc_ver.wlc_ver_major); + ifp->drvr->wlc_ver.wlc_ver_minor = le16_to_cpu(wlc_ver.wlc_ver_minor); + } + brcmf_dbg(TRACE, "wlc interface version, major=%d, minor=%d\n", + ifp->drvr->wlc_ver.wlc_ver_major, + ifp->drvr->wlc_ver.wlc_ver_minor); + /* Query for 'clmver' to get CLM version info from firmware */ memset(buf, 0, sizeof(buf)); err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf)); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index fda8af9722d0..c78bd67412f8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -98,6 +98,13 @@ struct brcmf_rev_info { u32 nvramrev; }; +/** wlc interface version */ +struct brcmf_wlc_version { + /* wlc interface version numbers */ + u16 wlc_ver_major; /**< wlc interface major version number */ + u16 wlc_ver_minor; /**< wlc interface minor version number */ +}; + /* Common structure for module and instance linkage */ struct brcmf_pub { /* Linkage ponters */ @@ -133,6 +140,7 @@ struct brcmf_pub { int req_mpc; struct brcmf_rev_info revinfo; + struct brcmf_wlc_version wlc_ver; #ifdef DEBUG struct dentry *dbgfs_dir; #endif diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h index fb83a8187ac6..6fa149f4adaa 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -12,6 +12,9 @@ #define BRCMF_FIL_ACTION_FRAME_SIZE 1800 +#define BRCMF_AF_PARAM_V2_FW_MAJOR 13 +#define BRCMF_AF_PARAM_V2_FW_MINOR 2 + /* ARP Offload feature flags for arp_ol iovar */ #define BRCMF_ARP_OL_AGENT 0x00000001 #define BRCMF_ARP_OL_SNOOP 0x00000002 @@ -308,6 +311,17 @@ struct brcmf_fil_af_params_le { struct brcmf_fil_action_frame_le action_frame; }; +struct brcmf_fil_af_params_v2_le { + __le16 version; + __le16 length; + __le32 channel; + __le32 dwell_time; + u8 bssid[ETH_ALEN]; + u8 band; + u8 pad[1]; + struct brcmf_fil_action_frame_le action_frame; +}; + struct brcmf_fil_bss_enable_le { __le32 bsscfgidx; __le32 enable; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 4a61e0cc8c61..d98a50c5dbd0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -1572,8 +1572,9 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp, * brcmf_p2p_tx_action_frame() - send action frame over fil. * * @p2p: p2p info struct for vif. + * @vif: vif to send. * @af_params: action frame data/info. - * @vif: vif to send + * @band: nl80211 band info. * * Send an action frame immediately without doing channel synchronization. * @@ -1582,17 +1583,13 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp, * frame is transmitted. */ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, + struct brcmf_cfg80211_vif *vif, struct brcmf_fil_af_params_le *af_params, - struct brcmf_cfg80211_vif *vif - ) + u8 band) { struct brcmf_pub *drvr = p2p->cfg->pub; s32 err = 0; - struct brcmf_fil_action_frame_le *action_frame; - u16 action_frame_len; - - action_frame = &af_params->action_frame; - action_frame_len = le16_to_cpu(action_frame->len); + struct brcmf_fil_af_params_v2_le af_params_v2; brcmf_dbg(TRACE, "Enter\n"); @@ -1600,8 +1597,23 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status); clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status); - err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params, - sizeof(*af_params)); + if (drvr->wlc_ver.wlc_ver_major == BRCMF_AF_PARAM_V2_FW_MAJOR && + drvr->wlc_ver.wlc_ver_minor >= BRCMF_AF_PARAM_V2_FW_MINOR) { + /* set actframe iovar with af_params_v2 */ + af_params_v2.band = nl80211_band_to_fwil(band); + af_params_v2.channel = af_params->channel; + af_params_v2.dwell_time = af_params->dwell_time; + memcpy(af_params_v2.bssid, af_params->bssid, ETH_ALEN); + af_params_v2.action_frame = af_params->action_frame; + + err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", &af_params_v2, + sizeof(af_params_v2)); + } else { + /* set actframe iovar with af_params */ + err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params, + sizeof(*af_params)); + } + if (err) { bphy_err(drvr, " sending action frame has failed\n"); goto exit; @@ -1908,7 +1920,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, if (af_params->channel) msleep(P2P_AF_RETRY_DELAY_TIME); - ack = !brcmf_p2p_tx_action_frame(p2p, af_params, vif); + ack = !brcmf_p2p_tx_action_frame(p2p, vif, af_params, peer_listen_chan->band); tx_retry++; dwell_overflow = brcmf_p2p_check_dwell_overflow(requested_dwell, dwell_jiffies); -- 2.25.1