From 5bcb2d0026b7ccabb2d1184cee073b8287146014 Mon Sep 17 00:00:00 2001 From: Ashwin Adiga Date: Tue, 27 Sep 2022 07:50:27 -0500 Subject: [PATCH 113/296] brcmfmac: Implementing set_bitrate_mask cfg80211 ops for iw Implement .set_bitrate_mask on cfg80211 ops & function brcmf_cfg80211_set_bitrate to parse the rate parameters coming from the above layer. Signed-off-by: Ashwin Adiga --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 51 +++++++++++++++++++ .../broadcom/brcm80211/brcmfmac/cfg80211.h | 8 +++ 2 files changed, 59 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 99ee4e18871e..214666af034a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -6636,6 +6636,56 @@ brcmf_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev, return ret; } +static int +brcmf_cfg80211_set_bitrate(struct wiphy *wiphy, struct net_device *ndev, + unsigned int link_id, const u8 *addr, + const struct cfg80211_bitrate_mask *mask) +{ + struct brcmf_if *ifp; + u32 he[2] = {0, 0}; + u32 rspec = 0; + uint hegi; + int ret = TIME_OK, i = 0; + + ifp = netdev_priv(ndev); + ret = brcmf_fil_iovar_data_get(ifp, "he", he, sizeof(he)); + if (unlikely(ret)) { + brcmf_dbg(INFO, "error reading he (%d)\n", ret); + return -EOPNOTSUPP; + } + for (i = 0; i < NUM_NL80211_BANDS; i++) { + if (i != NL80211_BAND_2GHZ && i != NL80211_BAND_5GHZ && + i != NL80211_BAND_6GHZ) { + continue; + } + if (he[0]) { + rspec = WL_RSPEC_ENCODE_HE; /* 11ax HE */ + rspec |= (WL_RSPEC_HE_NSS_UNSPECIFIED << WL_RSPEC_HE_NSS_SHIFT) | + mask->control[i].he_mcs[0]; + /* set the other rspec fields */ + hegi = mask->control[i].he_gi; + rspec |= ((hegi != 0xFF) ? HE_GI_TO_RSPEC(hegi) : 0); + + if (i == NL80211_BAND_2GHZ) + ret = brcmf_fil_iovar_data_set(ifp, "2g_rate", (char *)&rspec, 4); + + if (i == NL80211_BAND_5GHZ) + ret = brcmf_fil_iovar_data_set(ifp, "5g_rate", (char *)&rspec, 4); + + if (i == NL80211_BAND_6GHZ) + ret = brcmf_fil_iovar_data_set(ifp, "6g_rate", (char *)&rspec, 4); + + if (unlikely(ret)) + brcmf_dbg(INFO, "%s: set rate failed, retcode = %d\n", + __func__, ret); + } else { + brcmf_dbg(INFO, "Only HE supported\n"); + return -EOPNOTSUPP; + } + } + return ret; +} + static int brcmf_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, s32 rssi_thold, u32 rssi_hyst) @@ -6697,6 +6747,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = { .start_ap = brcmf_cfg80211_start_ap, .stop_ap = brcmf_cfg80211_stop_ap, .change_beacon = brcmf_cfg80211_change_beacon, + .set_bitrate_mask = brcmf_cfg80211_set_bitrate, .del_station = brcmf_cfg80211_del_station, .change_station = brcmf_cfg80211_change_station, .sched_scan_start = brcmf_cfg80211_sched_scan_start, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index e67c5dba098f..3a88f0f262a0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -101,6 +101,14 @@ #define WL_WOWLAN_PKT_FILTER_ID_FIRST 201 #define WL_WOWLAN_PKT_FILTER_ID_LAST (WL_WOWLAN_PKT_FILTER_ID_FIRST + \ WL_WOWLAN_MAX_PATTERNS - 1) + +#define WL_RSPEC_ENCODE_HE 0x03000000 /* HE MCS and Nss is stored in RSPEC_RATE_MASK */ +#define WL_RSPEC_HE_NSS_UNSPECIFIED 0xF +#define WL_RSPEC_HE_NSS_SHIFT 4 /* HE Nss value shift */ +#define WL_RSPEC_HE_GI_MASK 0x00000C00 /* HE GI indices */ +#define WL_RSPEC_HE_GI_SHIFT 10 +#define HE_GI_TO_RSPEC(gi) (((gi) << WL_RSPEC_HE_GI_SHIFT) & WL_RSPEC_HE_GI_MASK) + /** * enum brcmf_scan_status - scan engine status * -- 2.25.1