2020-04-29 14:58:29

by John Crispin

[permalink] [raw]
Subject: [PATCH V3 1/3] nl80211: add support for setting fixed HE rate/gi/ltf

From: Miles Hu <[email protected]>

This patch adds the nl80211 structs, definitions, policies and parsing
code required to pass fixed HE rate, gi and ltf settings.

Signed-off-by: Miles Hu <[email protected]>
Signed-off-by: John Crispin <[email protected]>
---
Changes in V3
* minor cleanup based on Johannes's feedback
* properly make use the iftype_data array

Changes in V2
* add more policies
* reoder enums
* remove incorrect he_cap from ieee80211_supported_band
* remove _WARN from policy

include/net/cfg80211.h | 25 ++++++++
include/uapi/linux/nl80211.h | 28 +++++++++
net/wireless/nl80211.c | 119 ++++++++++++++++++++++++++++++++++-
3 files changed, 170 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index c78bd4ff9e33..deaa3668d47a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -495,6 +495,28 @@ ieee80211_get_he_iftype_cap(const struct ieee80211_supported_band *sband,
return NULL;
}

+/**
+ * ieee80211_get_he_cap - return the first he_cap that we find for a sband
+ * @sband: the sband that we want to check for HE support
+ *
+ * Return: return a valid he_cap or NULL
+ */
+static inline const struct ieee80211_sta_he_cap *
+ieee80211_get_he_cap(const struct ieee80211_supported_band *sband)
+{
+ int i;
+
+ for (i = 0; i < sband->n_iftype_data; i++) {
+ const struct ieee80211_sband_iftype_data *data =
+ &sband->iftype_data[i];
+
+ if (data->he_cap.has_he)
+ return &data->he_cap;
+ }
+
+ return NULL;
+}
+
/**
* ieee80211_get_he_sta_cap - return HE capabilities for an sband's STA
* @sband: the sband to search for the STA on
@@ -1006,7 +1028,10 @@ struct cfg80211_bitrate_mask {
u32 legacy;
u8 ht_mcs[IEEE80211_HT_MCS_MASK_LEN];
u16 vht_mcs[NL80211_VHT_NSS_MAX];
+ u16 he_mcs[NL80211_HE_NSS_MAX];
enum nl80211_txrate_gi gi;
+ enum nl80211_he_gi he_gi;
+ enum nl80211_he_ltf he_ltf;
} control[NUM_NL80211_BANDS];
};

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 2b691161830f..966887bd654c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3134,6 +3134,18 @@ enum nl80211_he_gi {
NL80211_RATE_INFO_HE_GI_3_2,
};

+/**
+ * enum nl80211_he_ltf - HE long training field
+ * @NL80211_RATE_INFO_HE_1xLTF: 3.2 usec
+ * @NL80211_RATE_INFO_HE_2xLTF: 6.4 usec
+ * @NL80211_RATE_INFO_HE_4xLTF: 12.8 usec
+ */
+enum nl80211_he_ltf {
+ NL80211_RATE_INFO_HE_1XLTF,
+ NL80211_RATE_INFO_HE_2XLTF,
+ NL80211_RATE_INFO_HE_4XLTF,
+};
+
/**
* enum nl80211_he_ru_alloc - HE RU allocation values
* @NL80211_RATE_INFO_HE_RU_ALLOC_26: 26-tone RU allocation
@@ -4653,6 +4665,10 @@ enum nl80211_key_attributes {
* @NL80211_TXRATE_VHT: VHT rates allowed for TX rate selection,
* see &struct nl80211_txrate_vht
* @NL80211_TXRATE_GI: configure GI, see &enum nl80211_txrate_gi
+ * @NL80211_TXRATE_HE: HE rates allowed for TX rate selection,
+ * see &struct nl80211_txrate_he
+ * @NL80211_TXRATE_HE_GI: configure HE GI, 0.8us, 1.6us and 3.2us.
+ * @NL80211_TXRATE_HE_LTF: configure HE LTF, 1XLTF, 2XLTF and 4XLTF.
* @__NL80211_TXRATE_AFTER_LAST: internal
* @NL80211_TXRATE_MAX: highest TX rate attribute
*/
@@ -4662,6 +4678,9 @@ enum nl80211_tx_rate_attributes {
NL80211_TXRATE_HT,
NL80211_TXRATE_VHT,
NL80211_TXRATE_GI,
+ NL80211_TXRATE_HE,
+ NL80211_TXRATE_HE_GI,
+ NL80211_TXRATE_HE_LTF,

/* keep last */
__NL80211_TXRATE_AFTER_LAST,
@@ -4679,6 +4698,15 @@ struct nl80211_txrate_vht {
__u16 mcs[NL80211_VHT_NSS_MAX];
};

+#define NL80211_HE_NSS_MAX 8
+/**
+ * struct nl80211_txrate_he - HE MCS/NSS txrate bitmap
+ * @mcs: MCS bitmap table for each NSS (array index 0 for 1 stream, etc.)
+ */
+struct nl80211_txrate_he {
+ __u16 mcs[NL80211_HE_NSS_MAX];
+};
+
enum nl80211_txrate_gi {
NL80211_TXRATE_DEFAULT_GI,
NL80211_TXRATE_FORCE_SGI,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5fa402144cda..4bc652b904c1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4403,6 +4403,83 @@ static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
return true;
}

+static u16 he_mcs_map_to_mcs_mask(u8 he_mcs_map)
+{
+ switch (he_mcs_map) {
+ case IEEE80211_HE_MCS_NOT_SUPPORTED:
+ return 0;
+ case IEEE80211_HE_MCS_SUPPORT_0_7:
+ return 0x00FF;
+ case IEEE80211_HE_MCS_SUPPORT_0_9:
+ return 0x03FF;
+ case IEEE80211_HE_MCS_SUPPORT_0_11:
+ return 0xFFF;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void he_build_mcs_mask(u16 he_mcs_map,
+ u16 he_mcs_mask[NL80211_HE_NSS_MAX])
+{
+ u8 nss;
+
+ for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
+ he_mcs_mask[nss] = he_mcs_map_to_mcs_mask(he_mcs_map & 0x03);
+ he_mcs_map >>= 2;
+ }
+}
+
+static u16 he_get_txmcsmap(struct genl_info *info,
+ const struct ieee80211_sta_he_cap *he_cap)
+{
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+ switch (wdev->chandef.width) {
+ case NL80211_CHAN_WIDTH_80P80:
+ return he_cap->he_mcs_nss_supp.tx_mcs_80p80;
+ case NL80211_CHAN_WIDTH_160:
+ return he_cap->he_mcs_nss_supp.tx_mcs_160;
+ default:
+ break;
+ }
+ return le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);
+}
+
+static bool he_set_mcs_mask(struct genl_info *info,
+ struct ieee80211_supported_band *sband,
+ struct nl80211_txrate_he *txrate,
+ u16 mcs[NL80211_HE_NSS_MAX])
+{
+ const struct ieee80211_sta_he_cap *he_cap;
+ u16 tx_mcs_mask[NL80211_HE_NSS_MAX] = {};
+ u16 tx_mcs_map = 0;
+ u8 i;
+
+ he_cap = ieee80211_get_he_cap(sband);
+
+ if (!he_cap)
+ return false;
+
+ memset(mcs, 0, sizeof(u16) * NL80211_HE_NSS_MAX);
+
+ tx_mcs_map = he_get_txmcsmap(info, he_cap);
+
+ /* Build he_mcs_mask from HE capabilities */
+ he_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
+
+ for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
+ if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
+ mcs[i] = txrate->mcs[i];
+ else
+ return false;
+ }
+
+ return true;
+}
+
static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
[NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
.len = NL80211_MAX_SUPP_RATES },
@@ -4413,6 +4490,16 @@ static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
.len = sizeof(struct nl80211_txrate_vht),
},
[NL80211_TXRATE_GI] = { .type = NLA_U8 },
+ [NL80211_TXRATE_HE] = {
+ .type = NLA_EXACT_LEN,
+ .len = sizeof(struct nl80211_txrate_he),
+ },
+ [NL80211_TXRATE_HE_GI] = NLA_POLICY_RANGE(NLA_U8,
+ NL80211_RATE_INFO_HE_GI_0_8,
+ NL80211_RATE_INFO_HE_GI_3_2),
+ [NL80211_TXRATE_HE_LTF] = NLA_POLICY_RANGE(NLA_U8,
+ NL80211_RATE_INFO_HE_1XLTF,
+ NL80211_RATE_INFO_HE_4XLTF),
};

static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
@@ -4423,11 +4510,13 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
int rem, i;
struct nlattr *tx_rates;
struct ieee80211_supported_band *sband;
- u16 vht_tx_mcs_map;
+ u16 vht_tx_mcs_map, he_tx_mcs_map;

memset(mask, 0, sizeof(*mask));
/* Default to all rates enabled */
for (i = 0; i < NUM_NL80211_BANDS; i++) {
+ const struct ieee80211_sta_he_cap *he_cap;
+
sband = rdev->wiphy.bands[i];

if (!sband)
@@ -4443,6 +4532,16 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,

vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
+
+ he_cap = ieee80211_get_he_cap(sband);
+ if (!he_cap)
+ continue;
+
+ he_tx_mcs_map = he_get_txmcsmap(info, he_cap);
+ he_build_mcs_mask(he_tx_mcs_map, mask->control[i].he_mcs);
+
+ mask->control[i].he_gi = 0xFF;
+ mask->control[i].he_ltf = 0xFF;
}

/* if no rates are given set it back to the defaults */
@@ -4498,13 +4597,25 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
return -EINVAL;
}
+ if (tb[NL80211_TXRATE_HE] &&
+ !he_set_mcs_mask(info, sband,
+ nla_data(tb[NL80211_TXRATE_HE]),
+ mask->control[band].he_mcs))
+ return -EINVAL;
+ if (tb[NL80211_TXRATE_HE_GI])
+ mask->control[band].he_gi =
+ nla_get_u8(tb[NL80211_TXRATE_HE_GI]);
+ if (tb[NL80211_TXRATE_HE_LTF])
+ mask->control[band].he_ltf =
+ nla_get_u8(tb[NL80211_TXRATE_HE_LTF]);

if (mask->control[band].legacy == 0) {
/* don't allow empty legacy rates if HT or VHT
* are not even supported.
*/
if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
- rdev->wiphy.bands[band]->vht_cap.vht_supported))
+ rdev->wiphy.bands[band]->vht_cap.vht_supported ||
+ ieee80211_get_he_cap(rdev->wiphy.bands[band])))
return -EINVAL;

for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
@@ -4515,6 +4626,10 @@ static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
if (mask->control[band].vht_mcs[i])
goto out;

+ for (i = 0; i < NL80211_HE_NSS_MAX; i++)
+ if (mask->control[band].he_mcs[i])
+ goto out;
+
/* legacy and mcs rates may not be both empty */
return -EINVAL;
}
--
2.20.1


2020-04-29 14:59:23

by John Crispin

[permalink] [raw]
Subject: [PATCH V3 3/3] ath11k: add support for setting fixed HE rate/gi/ltf

From: Miles Hu <[email protected]>

This patch adds ath11k support for setting fixed HE rate/gi/ltf values that
we are now able to send to the kernel using nl80211. The added code is
reusing parts of the existing code path already used for HT/VHT. The new
helpers are symmetric to how we do it for HT/VHT.

Signed-off-by: Miles Hu <[email protected]>
Signed-off-by: John Crispin <[email protected]>
---
drivers/net/wireless/ath/ath11k/mac.c | 350 +++++++++++++++++++++++---
drivers/net/wireless/ath/ath11k/wmi.h | 1 +
2 files changed, 323 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index e28f5a348be6..aef012912003 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -268,6 +268,18 @@ ath11k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
return 1;
}

+static u32
+ath11k_mac_max_he_nss(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
+{
+ int nss;
+
+ for (nss = NL80211_HE_NSS_MAX - 1; nss >= 0; nss--)
+ if (he_mcs_mask[nss])
+ return nss + 1;
+
+ return 1;
+}
+
static u8 ath11k_parse_mpdudensity(u8 mpdudensity)
{
/* 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
@@ -1151,17 +1163,98 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar,
/* TODO: rxnss_override */
}

+static int ath11k_mac_get_max_he_mcs_map(u16 mcs_map, int nss)
+{
+ switch ((mcs_map >> (2 * nss)) & 0x3) {
+ case IEEE80211_HE_MCS_SUPPORT_0_7: return BIT(8) - 1;
+ case IEEE80211_HE_MCS_SUPPORT_0_9: return BIT(10) - 1;
+ case IEEE80211_HE_MCS_SUPPORT_0_11: return BIT(12) - 1;
+ }
+ return 0;
+}
+
+static u16 ath11k_peer_assoc_h_he_limit(u16 tx_mcs_set,
+ const u16 he_mcs_limit[NL80211_HE_NSS_MAX])
+{
+ int idx_limit;
+ int nss;
+ u16 mcs_map;
+ u16 mcs;
+
+ for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
+ mcs_map = ath11k_mac_get_max_he_mcs_map(tx_mcs_set, nss) &
+ he_mcs_limit[nss];
+
+ if (mcs_map)
+ idx_limit = fls(mcs_map) - 1;
+ else
+ idx_limit = -1;
+
+ switch (idx_limit) {
+ case 0 ... 7:
+ mcs = IEEE80211_HE_MCS_SUPPORT_0_7;
+ break;
+ case 8:
+ case 9:
+ mcs = IEEE80211_HE_MCS_SUPPORT_0_9;
+ break;
+ case 10:
+ case 11:
+ mcs = IEEE80211_HE_MCS_SUPPORT_0_11;
+ break;
+ default:
+ WARN_ON(1);
+ /* fall through */
+ case -1:
+ mcs = IEEE80211_HE_MCS_NOT_SUPPORTED;
+ break;
+ }
+
+ tx_mcs_set &= ~(0x3 << (nss * 2));
+ tx_mcs_set |= mcs << (nss * 2);
+ }
+
+ return tx_mcs_set;
+}
+
+static bool
+ath11k_peer_assoc_h_he_masked(const u16 he_mcs_mask[NL80211_HE_NSS_MAX])
+{
+ int nss;
+
+ for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++)
+ if (he_mcs_mask[nss])
+ return false;
+
+ return true;
+}
+
static void ath11k_peer_assoc_h_he(struct ath11k *ar,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct peer_assoc_params *arg)
{
+ struct ath11k_vif *arvif = (void *)vif->drv_priv;
+ struct cfg80211_chan_def def;
const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
- u16 v;
+ enum nl80211_band band;
+ const u16 *he_mcs_mask;
+ u8 max_nss, he_mcs;
+ __le16 he_tx_mcs = 0, v = 0;
+ int i;
+
+ if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))
+ return;

if (!he_cap->has_he)
return;

+ band = def.chan->band;
+ he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
+
+ if (ath11k_peer_assoc_h_he_masked(he_mcs_mask))
+ return;
+
arg->he_flag = true;

memcpy(&arg->peer_he_cap_macinfo, he_cap->he_cap_elem.mac_cap_info,
@@ -1218,17 +1311,22 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;

v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80);
+ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;

arg->peer_he_mcs_count++;
+ he_tx_mcs = v;
}
v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;

v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160);
+ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;

arg->peer_he_mcs_count++;
+ if (!he_tx_mcs)
+ he_tx_mcs = v;
/* fall through */

default:
@@ -1236,11 +1334,29 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;

v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);
+ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;

arg->peer_he_mcs_count++;
+ if (!he_tx_mcs)
+ he_tx_mcs = v;
break;
}
+ /* Calculate peer NSS capability from HE capabilities if STA
+ * supports HE.
+ */
+ for (i = 0, max_nss = 0, he_mcs = 0; i < NL80211_HE_NSS_MAX; i++) {
+ he_mcs = __le16_to_cpu(he_tx_mcs) >> (2 * i) & 3;
+
+ if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED &&
+ he_mcs_mask[i])
+ max_nss = i + 1;
+ }
+ arg->peer_nss = min(sta->rx_nss, max_nss);
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
+ "mac he peer %pM nss %d mcs cnt %d\n",
+ sta->addr, arg->peer_nss, arg->peer_he_mcs_count);
}

static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta,
@@ -1443,6 +1559,7 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
enum nl80211_band band;
const u8 *ht_mcs_mask;
const u16 *vht_mcs_mask;
+ const u16 *he_mcs_mask;
enum wmi_phy_mode phymode = MODE_UNKNOWN;

if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))
@@ -1451,10 +1568,12 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
band = def.chan->band;
ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
+ he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;

switch (band) {
case NL80211_BAND_2GHZ:
- if (sta->he_cap.has_he) {
+ if (sta->he_cap.has_he &&
+ !ath11k_peer_assoc_h_he_masked(he_mcs_mask)) {
if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
phymode = MODE_11AX_HE80_2G;
else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
@@ -1481,7 +1600,8 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
break;
case NL80211_BAND_5GHZ:
/* Check HE first */
- if (sta->he_cap.has_he) {
+ if (sta->he_cap.has_he &&
+ !ath11k_peer_assoc_h_he_masked(he_mcs_mask)) {
phymode = ath11k_mac_get_phymode_he(ar, sta);
} else if (sta->vht_cap.vht_supported &&
!ath11k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
@@ -2412,6 +2532,20 @@ ath11k_mac_bitrate_mask_num_vht_rates(struct ath11k *ar,
return num_rates;
}

+static int
+ath11k_mac_bitrate_mask_num_he_rates(struct ath11k *ar,
+ enum nl80211_band band,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ int num_rates = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++)
+ num_rates += hweight16(mask->control[band].he_mcs[i]);
+
+ return num_rates;
+}
+
static int
ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif,
struct ieee80211_sta *sta,
@@ -2458,6 +2592,52 @@ ath11k_mac_set_peer_vht_fixed_rate(struct ath11k_vif *arvif,
return ret;
}

+static int
+ath11k_mac_set_peer_he_fixed_rate(struct ath11k_vif *arvif,
+ struct ieee80211_sta *sta,
+ const struct cfg80211_bitrate_mask *mask,
+ enum nl80211_band band)
+{
+ struct ath11k *ar = arvif->ar;
+ u8 he_rate, nss;
+ u32 rate_code;
+ int ret, i;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ nss = 0;
+
+ for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
+ if (hweight16(mask->control[band].he_mcs[i]) == 1) {
+ nss = i + 1;
+ he_rate = ffs(mask->control[band].he_mcs[i]) - 1;
+ }
+ }
+
+ if (!nss) {
+ ath11k_warn(ar->ab, "No single HE Fixed rate found to set for %pM",
+ sta->addr);
+ return -EINVAL;
+ }
+
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
+ "Setting Fixed HE Rate for peer %pM. Device will not switch to any other selected rates",
+ sta->addr);
+
+ rate_code = ATH11K_HW_RATE_CODE(he_rate, nss - 1,
+ WMI_RATE_PREAMBLE_HE);
+ ret = ath11k_wmi_set_peer_param(ar, sta->addr,
+ arvif->vdev_id,
+ WMI_PEER_PARAM_FIXED_RATE,
+ rate_code);
+ if (ret)
+ ath11k_warn(ar->ab,
+ "failed to update STA %pM Fixed Rate %d: %d\n",
+ sta->addr, rate_code, ret);
+
+ return ret;
+}
+
static int ath11k_station_assoc(struct ath11k *ar,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -2576,8 +2756,9 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
enum nl80211_band band;
const u8 *ht_mcs_mask;
const u16 *vht_mcs_mask;
+ const u16 *he_mcs_mask;
u32 changed, bw, nss, smps;
- int err, num_vht_rates;
+ int err, num_vht_rates, num_he_rates;
const struct cfg80211_bitrate_mask *mask;
struct peer_assoc_params peer_arg;

@@ -2592,6 +2773,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
band = def.chan->band;
ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
+ he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;

spin_lock_bh(&ar->data_lock);

@@ -2607,8 +2789,9 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
mutex_lock(&ar->conf_mutex);

nss = max_t(u32, 1, nss);
- nss = min(nss, max(ath11k_mac_max_ht_nss(ht_mcs_mask),
- ath11k_mac_max_vht_nss(vht_mcs_mask)));
+ nss = min(nss, max(max(ath11k_mac_max_ht_nss(ht_mcs_mask),
+ ath11k_mac_max_vht_nss(vht_mcs_mask)),
+ ath11k_mac_max_he_nss(he_mcs_mask)));

if (changed & IEEE80211_RC_BW_CHANGED) {
err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
@@ -2644,6 +2827,8 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
mask = &arvif->bitrate_mask;
num_vht_rates = ath11k_mac_bitrate_mask_num_vht_rates(ar, band,
mask);
+ num_he_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band,
+ mask);

/* Peer_assoc_prepare will reject vht rates in
* bitrate_mask if its not available in range format and
@@ -2659,6 +2844,9 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
if (sta->vht_cap.vht_supported && num_vht_rates == 1) {
ath11k_mac_set_peer_vht_fixed_rate(arvif, sta, mask,
band);
+ } else if (sta->he_cap.has_he && num_he_rates == 1) {
+ ath11k_mac_set_peer_he_fixed_rate(arvif, sta, mask,
+ band);
} else {
/* If the peer is non-VHT or no fixed VHT rate
* is provided in the new bitrate mask we set the
@@ -4097,6 +4285,8 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
sizeof(arvif->bitrate_mask.control[i].ht_mcs));
memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
sizeof(arvif->bitrate_mask.control[i].vht_mcs));
+ memset(arvif->bitrate_mask.control[i].he_mcs, 0xff,
+ sizeof(arvif->bitrate_mask.control[i].he_mcs));
}

bit = __ffs64(ab->free_vdev_map);
@@ -5022,9 +5212,25 @@ ath11k_mac_has_single_legacy_rate(struct ath11k *ar,
if (ath11k_mac_bitrate_mask_num_vht_rates(ar, band, mask))
return false;

+ if (ath11k_mac_bitrate_mask_num_he_rates(ar, band, mask))
+ return false;
+
return num_rates == 1;
}

+u16 ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
+{
+ if (he_cap->he_cap_elem.phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
+ return he_cap->he_mcs_nss_supp.tx_mcs_80p80;
+
+ if (he_cap->he_cap_elem.phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ return he_cap->he_mcs_nss_supp.tx_mcs_160;
+
+ return he_cap->he_mcs_nss_supp.tx_mcs_80;
+}
+
static bool
ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
enum nl80211_band band,
@@ -5033,8 +5239,10 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
{
struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
+ u16 he_mcs_map = 0;
u8 ht_nss_mask = 0;
u8 vht_nss_mask = 0;
+ u8 he_nss_mask = 0;
int i;

/* No need to consider legacy here. Basic rates are always present
@@ -5061,7 +5269,19 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
return false;
}

- if (ht_nss_mask != vht_nss_mask)
+ he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(&sband->iftype_data->he_cap));
+
+ for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
+ if (mask->control[band].he_mcs[i] == 0)
+ continue;
+ else if (mask->control[band].he_mcs[i] ==
+ ath11k_mac_get_max_he_mcs_map(he_mcs_map, i))
+ he_nss_mask |= BIT(i);
+ else
+ return false;
+ }
+
+ if (ht_nss_mask != vht_nss_mask || ht_nss_mask != he_nss_mask)
return false;

if (ht_nss_mask == 0)
@@ -5109,7 +5329,8 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar,
}

static int ath11k_mac_set_fixed_rate_params(struct ath11k_vif *arvif,
- u32 rate, u8 nss, u8 sgi, u8 ldpc)
+ u32 rate, u8 nss, u8 sgi, u8 ldpc,
+ u8 he_gi, u8 he_ltf)
{
struct ath11k *ar = arvif->ar;
u32 vdev_param;
@@ -5120,15 +5341,16 @@ static int ath11k_mac_set_fixed_rate_params(struct ath11k_vif *arvif,
ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
arvif->vdev_id, rate, nss, sgi);

- vdev_param = WMI_VDEV_PARAM_FIXED_RATE;
- ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
- vdev_param, rate);
- if (ret) {
- ath11k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n",
- rate, ret);
- return ret;
+ if (!arvif->vif->bss_conf.he_support) {
+ vdev_param = WMI_VDEV_PARAM_FIXED_RATE;
+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+ vdev_param, rate);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to set fixed rate param 0x%02x: %d\n",
+ rate, ret);
+ return ret;
+ }
}
-
vdev_param = WMI_VDEV_PARAM_NSS;
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
vdev_param, nss);
@@ -5138,15 +5360,6 @@ static int ath11k_mac_set_fixed_rate_params(struct ath11k_vif *arvif,
return ret;
}

- vdev_param = WMI_VDEV_PARAM_SGI;
- ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
- vdev_param, sgi);
- if (ret) {
- ath11k_warn(ar->ab, "failed to set sgi param %d: %d\n",
- sgi, ret);
- return ret;
- }
-
vdev_param = WMI_VDEV_PARAM_LDPC;
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
vdev_param, ldpc);
@@ -5156,6 +5369,43 @@ static int ath11k_mac_set_fixed_rate_params(struct ath11k_vif *arvif,
return ret;
}

+ if (arvif->vif->bss_conf.he_support) {
+ if (he_gi != 0xFF) {
+ vdev_param = WMI_VDEV_PARAM_SGI;
+ /* 0.8 = 0, 1.6 = 2 and 3.2 = 3. */
+ if (he_gi)
+ he_gi += 1;
+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+ vdev_param, he_gi);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to set hegi param %d: %d\n",
+ sgi, ret);
+ return ret;
+ }
+ }
+ if (he_ltf != 0xFF) {
+ vdev_param = WMI_VDEV_PARAM_HE_LTF;
+ /* start from 1 */
+ he_ltf += 1;
+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+ vdev_param, he_ltf);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to set heltf param %d: %d\n",
+ he_ltf, ret);
+ return ret;
+ }
+ }
+ } else {
+ vdev_param = WMI_VDEV_PARAM_SGI;
+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
+ vdev_param, sgi);
+ if (ret) {
+ ath11k_warn(ar->ab, "failed to set sgi param %d: %d\n",
+ sgi, ret);
+ return ret;
+ }
+ }
+
return 0;
}

@@ -5184,6 +5434,31 @@ ath11k_mac_vht_mcs_range_present(struct ath11k *ar,
return true;
}

+static bool
+ath11k_mac_he_mcs_range_present(struct ath11k *ar,
+ enum nl80211_band band,
+ const struct cfg80211_bitrate_mask *mask)
+{
+ int i;
+ u16 he_mcs;
+
+ for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
+ he_mcs = mask->control[band].he_mcs[i];
+
+ switch (he_mcs) {
+ case 0:
+ case BIT(8) - 1:
+ case BIT(10) - 1:
+ case BIT(12) - 1:
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+}
+
static void ath11k_mac_set_bitrate_mask_iter(void *data,
struct ieee80211_sta *sta)
{
@@ -5226,6 +5501,9 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
enum nl80211_band band;
const u8 *ht_mcs_mask;
const u16 *vht_mcs_mask;
+ const u16 *he_mcs_mask;
+ u8 he_ltf = 0;
+ u8 he_gi = 0;
u32 rate;
u8 nss;
u8 sgi;
@@ -5240,12 +5518,16 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
band = def.chan->band;
ht_mcs_mask = mask->control[band].ht_mcs;
vht_mcs_mask = mask->control[band].vht_mcs;
+ he_mcs_mask = mask->control[band].he_mcs;
ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);

sgi = mask->control[band].gi;
if (sgi == NL80211_TXRATE_FORCE_LGI)
return -EINVAL;

+ he_gi = mask->control[band].he_gi;
+ he_ltf = mask->control[band].he_ltf;
+
/* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it
* requires passing atleast one of used basic rates along with them.
* Fixed rate setting across different preambles(legacy, HT, VHT) is
@@ -5272,8 +5554,9 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
} else {
rate = WMI_FIXED_RATE_NONE;
nss = min_t(u32, ar->num_tx_chains,
- max(ath11k_mac_max_ht_nss(ht_mcs_mask),
- ath11k_mac_max_vht_nss(vht_mcs_mask)));
+ max(max(ath11k_mac_max_ht_nss(ht_mcs_mask),
+ ath11k_mac_max_vht_nss(vht_mcs_mask)),
+ ath11k_mac_max_he_nss(he_mcs_mask)));

/* If multiple rates across different preambles are given
* we can reconfigure this info with all peers using PEER_ASSOC
@@ -5308,6 +5591,16 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
return -EINVAL;
}

+ num_rates = ath11k_mac_bitrate_mask_num_he_rates(ar, band,
+ mask);
+
+ if (!ath11k_mac_he_mcs_range_present(ar, band, mask) &&
+ num_rates > 1) {
+ ath11k_warn(ar->ab,
+ "Setting more than one HE MCS Value in bitrate mask not supported\n");
+ return -EINVAL;
+ }
+
ieee80211_iterate_stations_atomic(ar->hw,
ath11k_mac_disable_peer_fixed_rate,
arvif);
@@ -5324,7 +5617,8 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,

mutex_lock(&ar->conf_mutex);

- ret = ath11k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
+ ret = ath11k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc,
+ he_gi, he_ltf);
if (ret) {
ath11k_warn(ar->ab, "failed to set fixed rate params on vdev %i: %d\n",
arvif->vdev_id, ret);
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
index 742fcd6e37a3..82929415e119 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -1008,6 +1008,7 @@ enum wmi_tlv_vdev_param {
WMI_VDEV_PARAM_HE_RANGE_EXT,
WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
+ WMI_VDEV_PARAM_HE_LTF = 0x74,
WMI_VDEV_PARAM_BA_MODE = 0x7e,
WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
WMI_VDEV_PARAM_PROTOTYPE = 0x8000,
--
2.20.1

2020-04-30 08:51:00

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH V3 3/3] ath11k: add support for setting fixed HE rate/gi/ltf

John Crispin <[email protected]> writes:

> From: Miles Hu <[email protected]>
>
> This patch adds ath11k support for setting fixed HE rate/gi/ltf values that
> we are now able to send to the kernel using nl80211. The added code is
> reusing parts of the existing code path already used for HT/VHT. The new
> helpers are symmetric to how we do it for HT/VHT.
>
> Signed-off-by: Miles Hu <[email protected]>
> Signed-off-by: John Crispin <[email protected]>

[...]

> + if (he_ltf != 0xFF) {
> + vdev_param = WMI_VDEV_PARAM_HE_LTF;
> + /* start from 1 */
> + he_ltf += 1;

Indentation looks weird here, but I can fix that during commit.

--
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2020-04-30 22:39:25

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH V3 1/3] nl80211: add support for setting fixed HE rate/gi/ltf

Hi John,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on mac80211/master]
[also build test WARNING on ath6kl/ath-next v5.7-rc3 next-20200430]
[cannot apply to mac80211-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/John-Crispin/nl80211-add-support-for-setting-fixed-HE-rate-gi-ltf/20200430-040802
base: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git master
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-191-gc51a0382-dirty
make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <[email protected]>


sparse warnings: (new ones prefixed by >>)

>> net/wireless/nl80211.c:4440:47: sparse: sparse: incorrect type in return expression (different base types) @@ expected unsigned short @@ got restricted __le16 conunsigned short @@
>> net/wireless/nl80211.c:4440:47: sparse: expected unsigned short
>> net/wireless/nl80211.c:4440:47: sparse: got restricted __le16 const [usertype] tx_mcs_80p80
net/wireless/nl80211.c:4442:47: sparse: sparse: incorrect type in return expression (different base types) @@ expected unsigned short @@ got restricted __le16 conunsigned short @@
net/wireless/nl80211.c:4442:47: sparse: expected unsigned short
>> net/wireless/nl80211.c:4442:47: sparse: got restricted __le16 const [usertype] tx_mcs_160

vim +4440 net/wireless/nl80211.c

4431
4432 static u16 he_get_txmcsmap(struct genl_info *info,
4433 const struct ieee80211_sta_he_cap *he_cap)
4434 {
4435 struct net_device *dev = info->user_ptr[1];
4436 struct wireless_dev *wdev = dev->ieee80211_ptr;
4437
4438 switch (wdev->chandef.width) {
4439 case NL80211_CHAN_WIDTH_80P80:
> 4440 return he_cap->he_mcs_nss_supp.tx_mcs_80p80;
4441 case NL80211_CHAN_WIDTH_160:
> 4442 return he_cap->he_mcs_nss_supp.tx_mcs_160;
4443 default:
4444 break;
4445 }
4446 return le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);
4447 }
4448

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]

2020-05-01 02:15:26

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH V3 3/3] ath11k: add support for setting fixed HE rate/gi/ltf

Hi John,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on mac80211/master]
[also build test WARNING on ath6kl/ath-next v5.7-rc3]
[cannot apply to mac80211-next/master next-20200430]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/John-Crispin/nl80211-add-support-for-setting-fixed-HE-rate-gi-ltf/20200430-040802
base: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git master
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-191-gc51a0382-dirty
make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <[email protected]>


sparse warnings: (new ones prefixed by >>)

>> drivers/net/wireless/ath/ath11k/mac.c:1310:27: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got tricted __le16 [usertype] v @@
>> drivers/net/wireless/ath/ath11k/mac.c:1310:27: sparse: expected restricted __le16 [usertype] v
>> drivers/net/wireless/ath/ath11k/mac.c:1310:27: sparse: got unsigned short [usertype]
>> drivers/net/wireless/ath/ath11k/mac.c:1311:83: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int @@ got restricted __le16unsigned int @@
>> drivers/net/wireless/ath/ath11k/mac.c:1311:83: sparse: expected unsigned int
>> drivers/net/wireless/ath/ath11k/mac.c:1311:83: sparse: got restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1313:27: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got tricted __le16 [usertype] v @@
drivers/net/wireless/ath/ath11k/mac.c:1313:27: sparse: expected restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1313:27: sparse: got unsigned short [usertype]
>> drivers/net/wireless/ath/ath11k/mac.c:1314:58: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned short [assigned] [usertype] tx_mcs_set @@ got short [assigned] [usertype] tx_mcs_set @@
>> drivers/net/wireless/ath/ath11k/mac.c:1314:58: sparse: expected unsigned short [assigned] [usertype] tx_mcs_set
drivers/net/wireless/ath/ath11k/mac.c:1314:58: sparse: got restricted __le16 [usertype] v
>> drivers/net/wireless/ath/ath11k/mac.c:1314:27: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got 16 [usertype] v @@
drivers/net/wireless/ath/ath11k/mac.c:1314:27: sparse: expected restricted __le16 [usertype] v
>> drivers/net/wireless/ath/ath11k/mac.c:1314:27: sparse: got unsigned short
drivers/net/wireless/ath/ath11k/mac.c:1315:83: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int @@ got restricted __le16unsigned int @@
drivers/net/wireless/ath/ath11k/mac.c:1315:83: sparse: expected unsigned int
drivers/net/wireless/ath/ath11k/mac.c:1315:83: sparse: got restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1320:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got tricted __le16 [usertype] v @@
drivers/net/wireless/ath/ath11k/mac.c:1320:19: sparse: expected restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1320:19: sparse: got unsigned short [usertype]
drivers/net/wireless/ath/ath11k/mac.c:1321:73: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int @@ got restricted __le16unsigned int @@
drivers/net/wireless/ath/ath11k/mac.c:1321:73: sparse: expected unsigned int
drivers/net/wireless/ath/ath11k/mac.c:1321:73: sparse: got restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1323:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got tricted __le16 [usertype] v @@
drivers/net/wireless/ath/ath11k/mac.c:1323:19: sparse: expected restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1323:19: sparse: got unsigned short [usertype]
drivers/net/wireless/ath/ath11k/mac.c:1324:50: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned short [assigned] [usertype] tx_mcs_set @@ got short [assigned] [usertype] tx_mcs_set @@
drivers/net/wireless/ath/ath11k/mac.c:1324:50: sparse: expected unsigned short [assigned] [usertype] tx_mcs_set
drivers/net/wireless/ath/ath11k/mac.c:1324:50: sparse: got restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1324:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got 16 [usertype] v @@
drivers/net/wireless/ath/ath11k/mac.c:1324:19: sparse: expected restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1324:19: sparse: got unsigned short
drivers/net/wireless/ath/ath11k/mac.c:1325:73: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int @@ got restricted __le16unsigned int @@
drivers/net/wireless/ath/ath11k/mac.c:1325:73: sparse: expected unsigned int
drivers/net/wireless/ath/ath11k/mac.c:1325:73: sparse: got restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1333:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got tricted __le16 [usertype] v @@
drivers/net/wireless/ath/ath11k/mac.c:1333:19: sparse: expected restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1333:19: sparse: got unsigned short [usertype]
drivers/net/wireless/ath/ath11k/mac.c:1334:72: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int @@ got restricted __le16unsigned int @@
drivers/net/wireless/ath/ath11k/mac.c:1334:72: sparse: expected unsigned int
drivers/net/wireless/ath/ath11k/mac.c:1334:72: sparse: got restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1336:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got tricted __le16 [usertype] v @@
drivers/net/wireless/ath/ath11k/mac.c:1336:19: sparse: expected restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1336:19: sparse: got unsigned short [usertype]
drivers/net/wireless/ath/ath11k/mac.c:1337:50: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned short [assigned] [usertype] tx_mcs_set @@ got short [assigned] [usertype] tx_mcs_set @@
drivers/net/wireless/ath/ath11k/mac.c:1337:50: sparse: expected unsigned short [assigned] [usertype] tx_mcs_set
drivers/net/wireless/ath/ath11k/mac.c:1337:50: sparse: got restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1337:19: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] v @@ got 16 [usertype] v @@
drivers/net/wireless/ath/ath11k/mac.c:1337:19: sparse: expected restricted __le16 [usertype] v
drivers/net/wireless/ath/ath11k/mac.c:1337:19: sparse: got unsigned short
drivers/net/wireless/ath/ath11k/mac.c:1338:72: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int @@ got restricted __le16unsigned int @@
drivers/net/wireless/ath/ath11k/mac.c:1338:72: sparse: expected unsigned int
drivers/net/wireless/ath/ath11k/mac.c:1338:72: sparse: got restricted __le16 [usertype] v
>> drivers/net/wireless/ath/ath11k/mac.c:5292:47: sparse: sparse: incorrect type in return expression (different base types) @@ expected unsigned short @@ got restricted __le16 conunsigned short @@
>> drivers/net/wireless/ath/ath11k/mac.c:5292:47: sparse: expected unsigned short
>> drivers/net/wireless/ath/ath11k/mac.c:5292:47: sparse: got restricted __le16 const [usertype] tx_mcs_80p80
drivers/net/wireless/ath/ath11k/mac.c:5296:47: sparse: sparse: incorrect type in return expression (different base types) @@ expected unsigned short @@ got restricted __le16 conunsigned short @@
drivers/net/wireless/ath/ath11k/mac.c:5296:47: sparse: expected unsigned short
>> drivers/net/wireless/ath/ath11k/mac.c:5296:47: sparse: got restricted __le16 const [usertype] tx_mcs_160
drivers/net/wireless/ath/ath11k/mac.c:5298:39: sparse: sparse: incorrect type in return expression (different base types) @@ expected unsigned short @@ got restricted __le16 conunsigned short @@
drivers/net/wireless/ath/ath11k/mac.c:5298:39: sparse: expected unsigned short
>> drivers/net/wireless/ath/ath11k/mac.c:5298:39: sparse: got restricted __le16 const [usertype] tx_mcs_80
>> drivers/net/wireless/ath/ath11k/mac.c:5288:5: sparse: sparse: symbol 'ath11k_mac_get_tx_mcs_map' was not declared. Should it be static?
>> drivers/net/wireless/ath/ath11k/mac.c:5339:22: sparse: sparse: cast to restricted __le16

Please review and possibly fold the followup patch.

vim +1310 drivers/net/wireless/ath/ath11k/mac.c

f4740f8f367c7c Miles Hu 2020-04-29 1231
d5c65159f28953 Kalle Valo 2019-11-23 1232 static void ath11k_peer_assoc_h_he(struct ath11k *ar,
d5c65159f28953 Kalle Valo 2019-11-23 1233 struct ieee80211_vif *vif,
d5c65159f28953 Kalle Valo 2019-11-23 1234 struct ieee80211_sta *sta,
d5c65159f28953 Kalle Valo 2019-11-23 1235 struct peer_assoc_params *arg)
d5c65159f28953 Kalle Valo 2019-11-23 1236 {
f4740f8f367c7c Miles Hu 2020-04-29 1237 struct ath11k_vif *arvif = (void *)vif->drv_priv;
f4740f8f367c7c Miles Hu 2020-04-29 1238 struct cfg80211_chan_def def;
9f056ed8ee01ad John Crispin 2019-11-25 1239 const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
f4740f8f367c7c Miles Hu 2020-04-29 1240 enum nl80211_band band;
f4740f8f367c7c Miles Hu 2020-04-29 1241 const u16 *he_mcs_mask;
f4740f8f367c7c Miles Hu 2020-04-29 1242 u8 max_nss, he_mcs;
f4740f8f367c7c Miles Hu 2020-04-29 1243 __le16 he_tx_mcs = 0, v = 0;
f4740f8f367c7c Miles Hu 2020-04-29 1244 int i;
f4740f8f367c7c Miles Hu 2020-04-29 1245
f4740f8f367c7c Miles Hu 2020-04-29 1246 if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))
f4740f8f367c7c Miles Hu 2020-04-29 1247 return;
9f056ed8ee01ad John Crispin 2019-11-25 1248
9f056ed8ee01ad John Crispin 2019-11-25 1249 if (!he_cap->has_he)
9f056ed8ee01ad John Crispin 2019-11-25 1250 return;
9f056ed8ee01ad John Crispin 2019-11-25 1251
f4740f8f367c7c Miles Hu 2020-04-29 1252 band = def.chan->band;
f4740f8f367c7c Miles Hu 2020-04-29 1253 he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
f4740f8f367c7c Miles Hu 2020-04-29 1254
f4740f8f367c7c Miles Hu 2020-04-29 1255 if (ath11k_peer_assoc_h_he_masked(he_mcs_mask))
f4740f8f367c7c Miles Hu 2020-04-29 1256 return;
f4740f8f367c7c Miles Hu 2020-04-29 1257
9f056ed8ee01ad John Crispin 2019-11-25 1258 arg->he_flag = true;
9f056ed8ee01ad John Crispin 2019-11-25 1259
9f056ed8ee01ad John Crispin 2019-11-25 1260 memcpy(&arg->peer_he_cap_macinfo, he_cap->he_cap_elem.mac_cap_info,
9f056ed8ee01ad John Crispin 2019-11-25 1261 sizeof(arg->peer_he_cap_macinfo));
9f056ed8ee01ad John Crispin 2019-11-25 1262 memcpy(&arg->peer_he_cap_phyinfo, he_cap->he_cap_elem.phy_cap_info,
9f056ed8ee01ad John Crispin 2019-11-25 1263 sizeof(arg->peer_he_cap_phyinfo));
9f056ed8ee01ad John Crispin 2019-11-25 1264 memcpy(&arg->peer_he_ops, &vif->bss_conf.he_operation,
9f056ed8ee01ad John Crispin 2019-11-25 1265 sizeof(arg->peer_he_ops));
9f056ed8ee01ad John Crispin 2019-11-25 1266
9f056ed8ee01ad John Crispin 2019-11-25 1267 /* the top most byte is used to indicate BSS color info */
9f056ed8ee01ad John Crispin 2019-11-25 1268 arg->peer_he_ops &= 0xffffff;
9f056ed8ee01ad John Crispin 2019-11-25 1269
9f056ed8ee01ad John Crispin 2019-11-25 1270 if (he_cap->he_cap_elem.phy_cap_info[6] &
9f056ed8ee01ad John Crispin 2019-11-25 1271 IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
9f056ed8ee01ad John Crispin 2019-11-25 1272 int bit = 7;
9f056ed8ee01ad John Crispin 2019-11-25 1273 int nss, ru;
9f056ed8ee01ad John Crispin 2019-11-25 1274
9f056ed8ee01ad John Crispin 2019-11-25 1275 arg->peer_ppet.numss_m1 = he_cap->ppe_thres[0] &
9f056ed8ee01ad John Crispin 2019-11-25 1276 IEEE80211_PPE_THRES_NSS_MASK;
9f056ed8ee01ad John Crispin 2019-11-25 1277 arg->peer_ppet.ru_bit_mask =
9f056ed8ee01ad John Crispin 2019-11-25 1278 (he_cap->ppe_thres[0] &
9f056ed8ee01ad John Crispin 2019-11-25 1279 IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK) >>
9f056ed8ee01ad John Crispin 2019-11-25 1280 IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS;
9f056ed8ee01ad John Crispin 2019-11-25 1281
9f056ed8ee01ad John Crispin 2019-11-25 1282 for (nss = 0; nss <= arg->peer_ppet.numss_m1; nss++) {
9f056ed8ee01ad John Crispin 2019-11-25 1283 for (ru = 0; ru < 4; ru++) {
9f056ed8ee01ad John Crispin 2019-11-25 1284 u32 val = 0;
9f056ed8ee01ad John Crispin 2019-11-25 1285 int i;
9f056ed8ee01ad John Crispin 2019-11-25 1286
9f056ed8ee01ad John Crispin 2019-11-25 1287 if ((arg->peer_ppet.ru_bit_mask & BIT(ru)) == 0)
9f056ed8ee01ad John Crispin 2019-11-25 1288 continue;
9f056ed8ee01ad John Crispin 2019-11-25 1289 for (i = 0; i < 6; i++) {
9f056ed8ee01ad John Crispin 2019-11-25 1290 val >>= 1;
9f056ed8ee01ad John Crispin 2019-11-25 1291 val |= ((he_cap->ppe_thres[bit / 8] >>
9f056ed8ee01ad John Crispin 2019-11-25 1292 (bit % 8)) & 0x1) << 5;
9f056ed8ee01ad John Crispin 2019-11-25 1293 bit++;
9f056ed8ee01ad John Crispin 2019-11-25 1294 }
9f056ed8ee01ad John Crispin 2019-11-25 1295 arg->peer_ppet.ppet16_ppet8_ru3_ru0[nss] |=
9f056ed8ee01ad John Crispin 2019-11-25 1296 val << (ru * 6);
9f056ed8ee01ad John Crispin 2019-11-25 1297 }
9f056ed8ee01ad John Crispin 2019-11-25 1298 }
9f056ed8ee01ad John Crispin 2019-11-25 1299 }
9f056ed8ee01ad John Crispin 2019-11-25 1300
6d293d447670da John Crispin 2019-11-25 1301 if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_RES)
6d293d447670da John Crispin 2019-11-25 1302 arg->twt_responder = true;
6d293d447670da John Crispin 2019-11-25 1303 if (he_cap->he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_TWT_REQ)
6d293d447670da John Crispin 2019-11-25 1304 arg->twt_requester = true;
6d293d447670da John Crispin 2019-11-25 1305
9f056ed8ee01ad John Crispin 2019-11-25 1306 switch (sta->bandwidth) {
9f056ed8ee01ad John Crispin 2019-11-25 1307 case IEEE80211_STA_RX_BW_160:
9f056ed8ee01ad John Crispin 2019-11-25 1308 if (he_cap->he_cap_elem.phy_cap_info[0] &
9f056ed8ee01ad John Crispin 2019-11-25 1309 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {
9f056ed8ee01ad John Crispin 2019-11-25 @1310 v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80p80);
9f056ed8ee01ad John Crispin 2019-11-25 @1311 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;
9f056ed8ee01ad John Crispin 2019-11-25 1312
9f056ed8ee01ad John Crispin 2019-11-25 1313 v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80p80);
f4740f8f367c7c Miles Hu 2020-04-29 @1314 v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
9f056ed8ee01ad John Crispin 2019-11-25 1315 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80_80] = v;
9f056ed8ee01ad John Crispin 2019-11-25 1316
9f056ed8ee01ad John Crispin 2019-11-25 1317 arg->peer_he_mcs_count++;
f4740f8f367c7c Miles Hu 2020-04-29 1318 he_tx_mcs = v;
9f056ed8ee01ad John Crispin 2019-11-25 1319 }
9f056ed8ee01ad John Crispin 2019-11-25 1320 v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
9f056ed8ee01ad John Crispin 2019-11-25 1321 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
9f056ed8ee01ad John Crispin 2019-11-25 1322
9f056ed8ee01ad John Crispin 2019-11-25 1323 v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160);
f4740f8f367c7c Miles Hu 2020-04-29 1324 v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
9f056ed8ee01ad John Crispin 2019-11-25 1325 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v;
9f056ed8ee01ad John Crispin 2019-11-25 1326
9f056ed8ee01ad John Crispin 2019-11-25 1327 arg->peer_he_mcs_count++;
f4740f8f367c7c Miles Hu 2020-04-29 1328 if (!he_tx_mcs)
f4740f8f367c7c Miles Hu 2020-04-29 1329 he_tx_mcs = v;
9f056ed8ee01ad John Crispin 2019-11-25 1330 /* fall through */
9f056ed8ee01ad John Crispin 2019-11-25 1331
9f056ed8ee01ad John Crispin 2019-11-25 1332 default:
9f056ed8ee01ad John Crispin 2019-11-25 1333 v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);
9f056ed8ee01ad John Crispin 2019-11-25 1334 arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;
9f056ed8ee01ad John Crispin 2019-11-25 1335
9f056ed8ee01ad John Crispin 2019-11-25 1336 v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);
f4740f8f367c7c Miles Hu 2020-04-29 @1337 v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask);
9f056ed8ee01ad John Crispin 2019-11-25 @1338 arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v;
9f056ed8ee01ad John Crispin 2019-11-25 1339
9f056ed8ee01ad John Crispin 2019-11-25 1340 arg->peer_he_mcs_count++;
f4740f8f367c7c Miles Hu 2020-04-29 1341 if (!he_tx_mcs)
f4740f8f367c7c Miles Hu 2020-04-29 1342 he_tx_mcs = v;
9f056ed8ee01ad John Crispin 2019-11-25 1343 break;
9f056ed8ee01ad John Crispin 2019-11-25 1344 }
f4740f8f367c7c Miles Hu 2020-04-29 1345 /* Calculate peer NSS capability from HE capabilities if STA
f4740f8f367c7c Miles Hu 2020-04-29 1346 * supports HE.
f4740f8f367c7c Miles Hu 2020-04-29 1347 */
f4740f8f367c7c Miles Hu 2020-04-29 1348 for (i = 0, max_nss = 0, he_mcs = 0; i < NL80211_HE_NSS_MAX; i++) {
f4740f8f367c7c Miles Hu 2020-04-29 1349 he_mcs = __le16_to_cpu(he_tx_mcs) >> (2 * i) & 3;
f4740f8f367c7c Miles Hu 2020-04-29 1350
f4740f8f367c7c Miles Hu 2020-04-29 1351 if (he_mcs != IEEE80211_HE_MCS_NOT_SUPPORTED &&
f4740f8f367c7c Miles Hu 2020-04-29 1352 he_mcs_mask[i])
f4740f8f367c7c Miles Hu 2020-04-29 1353 max_nss = i + 1;
f4740f8f367c7c Miles Hu 2020-04-29 1354 }
f4740f8f367c7c Miles Hu 2020-04-29 1355 arg->peer_nss = min(sta->rx_nss, max_nss);
f4740f8f367c7c Miles Hu 2020-04-29 1356
f4740f8f367c7c Miles Hu 2020-04-29 1357 ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
f4740f8f367c7c Miles Hu 2020-04-29 1358 "mac he peer %pM nss %d mcs cnt %d\n",
f4740f8f367c7c Miles Hu 2020-04-29 1359 sta->addr, arg->peer_nss, arg->peer_he_mcs_count);
d5c65159f28953 Kalle Valo 2019-11-23 1360 }
d5c65159f28953 Kalle Valo 2019-11-23 1361

:::::: The code at line 1310 was first introduced by commit
:::::: 9f056ed8ee01ad6898db49707cdc70ce923be3d0 ath11k: add HE support

:::::: TO: John Crispin <[email protected]>
:::::: CC: Kalle Valo <[email protected]>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]

2020-05-01 02:17:55

by kernel test robot

[permalink] [raw]
Subject: [RFC PATCH] ath11k: ath11k_mac_get_tx_mcs_map() can be static


Signed-off-by: kbuild test robot <[email protected]>
---
mac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index ad05409783c05..c8acdc1e33353 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -5285,7 +5285,7 @@ ath11k_mac_has_single_legacy_rate(struct ath11k *ar,
return num_rates == 1;
}

-u16 ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
+static u16 ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
{
if (he_cap->he_cap_elem.phy_cap_info[0] &
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)