mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-19 18:31:33 +00:00
656 lines
22 KiB
Diff
656 lines
22 KiB
Diff
From 81694575884dc69535252a6f44128323fd6a2504 Mon Sep 17 00:00:00 2001
|
|
From: Rajkumar Manoharan <rmanohar@codeaurora.org>
|
|
Date: Sat, 26 Sep 2020 23:17:03 -0700
|
|
Subject: [PATCH 1/3] nl80211: fix OBSS PD min and max offset validation
|
|
|
|
The SRG minimum and maximum offset doesn't present when the SR control field
|
|
of Spatial Reuse Parameter Set element set SRG Information Present to 0.
|
|
Both attributes are 1-byte values so use appropriate nla_get function.
|
|
|
|
Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org>
|
|
---
|
|
net/wireless/nl80211.c | 21 ++++++++++-----------
|
|
1 file changed, 10 insertions(+), 11 deletions(-)
|
|
|
|
--- a/net/wireless/nl80211.c
|
|
+++ b/net/wireless/nl80211.c
|
|
@@ -322,6 +322,13 @@ he_obss_pd_policy[NL80211_HE_OBSS_PD_ATT
|
|
NLA_POLICY_RANGE(NLA_U8, 1, 20),
|
|
[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET] =
|
|
NLA_POLICY_RANGE(NLA_U8, 1, 20),
|
|
+ [NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET] =
|
|
+ NLA_POLICY_RANGE(NLA_U8, 1, 20),
|
|
+ [NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP] =
|
|
+ NLA_POLICY_EXACT_LEN(8),
|
|
+ [NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP] =
|
|
+ NLA_POLICY_EXACT_LEN(8),
|
|
+ [NL80211_HE_OBSS_PD_ATTR_SR_CTRL] = { .type = NLA_U8 },
|
|
};
|
|
|
|
static const struct nla_policy
|
|
@@ -4844,18 +4851,36 @@ static int nl80211_parse_he_obss_pd(stru
|
|
if (err)
|
|
return err;
|
|
|
|
- if (!tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET] ||
|
|
- !tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET])
|
|
+ if (!tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL])
|
|
return -EINVAL;
|
|
|
|
- he_obss_pd->min_offset =
|
|
- nla_get_u32(tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET]);
|
|
- he_obss_pd->max_offset =
|
|
- nla_get_u32(tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET]);
|
|
+ he_obss_pd->sr_ctrl = nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL]);
|
|
+
|
|
+ if (tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET])
|
|
+ he_obss_pd->min_offset =
|
|
+ nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET]);
|
|
+ if (tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET])
|
|
+ he_obss_pd->max_offset =
|
|
+ nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET]);
|
|
+ if (tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET])
|
|
+ he_obss_pd->non_srg_max_offset =
|
|
+ nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET]);
|
|
|
|
- if (he_obss_pd->min_offset >= he_obss_pd->max_offset)
|
|
+ if (he_obss_pd->min_offset > he_obss_pd->max_offset)
|
|
return -EINVAL;
|
|
|
|
+ if (tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP]) {
|
|
+ memcpy(he_obss_pd->bss_color_bitmap,
|
|
+ nla_data(tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP]),
|
|
+ sizeof(he_obss_pd->bss_color_bitmap));
|
|
+ }
|
|
+
|
|
+ if (tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP]) {
|
|
+ memcpy(he_obss_pd->partial_bssid_bitmap,
|
|
+ nla_data(tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP]),
|
|
+ sizeof(he_obss_pd->partial_bssid_bitmap));
|
|
+ }
|
|
+
|
|
he_obss_pd->enable = true;
|
|
|
|
return 0;
|
|
@@ -5239,7 +5264,8 @@ static int nl80211_start_ap(struct sk_bu
|
|
err = nl80211_parse_he_obss_pd(
|
|
info->attrs[NL80211_ATTR_HE_OBSS_PD],
|
|
¶ms.he_obss_pd);
|
|
- goto out;
|
|
+ if (err)
|
|
+ goto out;
|
|
}
|
|
|
|
if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
|
|
--- a/include/linux/ieee80211.h
|
|
+++ b/include/linux/ieee80211.h
|
|
@@ -2294,8 +2294,11 @@ ieee80211_he_6ghz_oper(const struct ieee
|
|
}
|
|
|
|
/* HE Spatial Reuse defines */
|
|
-#define IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT 0x4
|
|
-#define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT 0x8
|
|
+#define IEEE80211_HE_SPR_PSR_DISALLOWED BIT(0)
|
|
+#define IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED BIT(1)
|
|
+#define IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT BIT(2)
|
|
+#define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT BIT(3)
|
|
+#define IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED BIT(4)
|
|
|
|
/*
|
|
* ieee80211_he_spr_size - calculate 802.11ax HE Spatial Reuse IE size
|
|
--- a/include/net/cfg80211.h
|
|
+++ b/include/net/cfg80211.h
|
|
@@ -255,13 +255,23 @@ struct ieee80211_rate {
|
|
* struct ieee80211_he_obss_pd - AP settings for spatial reuse
|
|
*
|
|
* @enable: is the feature enabled.
|
|
+ * @sr_ctrl: The SR Control field of SRP element.
|
|
+ * @non_srg_max_offset: non-SRG maximum tx power offset
|
|
* @min_offset: minimal tx power offset an associated station shall use
|
|
* @max_offset: maximum tx power offset an associated station shall use
|
|
+ * @bss_color_bitmap: bitmap that indicates the BSS color values used by
|
|
+ * members of the SRG
|
|
+ * @partial_bssid_bitmap: bitmap that indicates the partial BSSID values
|
|
+ * used by members of the SRG
|
|
*/
|
|
struct ieee80211_he_obss_pd {
|
|
bool enable;
|
|
+ u8 sr_ctrl;
|
|
+ u8 non_srg_max_offset;
|
|
u8 min_offset;
|
|
u8 max_offset;
|
|
+ u8 bss_color_bitmap[8];
|
|
+ u8 partial_bssid_bitmap[8];
|
|
};
|
|
|
|
/**
|
|
--- a/include/uapi/linux/nl80211.h
|
|
+++ b/include/uapi/linux/nl80211.h
|
|
@@ -6992,6 +6992,13 @@ enum nl80211_peer_measurement_ftm_resp {
|
|
*
|
|
* @NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET: the OBSS PD minimum tx power offset.
|
|
* @NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET: the OBSS PD maximum tx power offset.
|
|
+ * @NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET: the non-SRG OBSS PD maximum
|
|
+ * tx power offset.
|
|
+ * @NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP: bitmap that indicates the BSS color
|
|
+ * values used by members of the SRG.
|
|
+ * @NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP: bitmap that indicates the partial
|
|
+ * BSSID values used by members of the SRG.
|
|
+ * @NL80211_HE_OBSS_PD_ATTR_SR_CTRL: The SR Control field of SRP element.
|
|
*
|
|
* @__NL80211_HE_OBSS_PD_ATTR_LAST: Internal
|
|
* @NL80211_HE_OBSS_PD_ATTR_MAX: highest OBSS PD attribute.
|
|
@@ -7001,6 +7008,10 @@ enum nl80211_obss_pd_attributes {
|
|
|
|
NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET,
|
|
NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET,
|
|
+ NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET,
|
|
+ NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP,
|
|
+ NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP,
|
|
+ NL80211_HE_OBSS_PD_ATTR_SR_CTRL,
|
|
|
|
/* keep last */
|
|
__NL80211_HE_OBSS_PD_ATTR_LAST,
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -2768,6 +2768,137 @@ static void ath11k_mac_op_nss_bss_info_c
|
|
mutex_unlock(&ar->conf_mutex);
|
|
}
|
|
|
|
+static void ath11k_mac_config_obss_pd(struct ath11k *ar,
|
|
+ struct ieee80211_he_obss_pd *he_obss_pd)
|
|
+{
|
|
+ u32 bitmap[2], param_id, param_val, pdev_id;
|
|
+ int ret;
|
|
+ s8 non_srg_th = 0, srg_th = 0;
|
|
+
|
|
+ pdev_id = ar->pdev->pdev_id;
|
|
+
|
|
+ /* Set and enable SRG/non-SRG OBSS PD Threshold */
|
|
+ param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD;
|
|
+ if (ar->monitor_started) {
|
|
+ ret = ath11k_wmi_pdev_set_param(ar, param_id, 0, pdev_id);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set obss_pd_threshold for pdev: %u\n",
|
|
+ pdev_id);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
|
+ "OBSS PD Params: sr_ctrl %x non_srg_thres %u srg_max %u\n",
|
|
+ he_obss_pd->sr_ctrl, he_obss_pd->non_srg_max_offset,
|
|
+ he_obss_pd->max_offset);
|
|
+
|
|
+ param_val = 0;
|
|
+ if (he_obss_pd->sr_ctrl &
|
|
+ IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED) {
|
|
+ non_srg_th = ATH11K_OBSS_PD_MAX_THRESHOLD;
|
|
+ } else {
|
|
+ if (he_obss_pd->sr_ctrl &
|
|
+ IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
|
|
+ non_srg_th = (ATH11K_OBSS_PD_MAX_THRESHOLD +
|
|
+ he_obss_pd->non_srg_max_offset);
|
|
+ else
|
|
+ non_srg_th = ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD;
|
|
+ param_val |= ATH11K_OBSS_PD_NON_SRG_EN;
|
|
+ }
|
|
+
|
|
+ if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) {
|
|
+ srg_th = ATH11K_OBSS_PD_MAX_THRESHOLD + he_obss_pd->max_offset;
|
|
+ param_val |= ATH11K_OBSS_PD_SRG_EN;
|
|
+ }
|
|
+
|
|
+ if (test_bit(WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT,
|
|
+ ar->ab->wmi_ab.svc_map)) {
|
|
+ param_val |= ATH11K_OBSS_PD_THRESHOLD_IN_DBM;
|
|
+ param_val |= ((u16)(srg_th << 7) & 0xff00);
|
|
+ } else {
|
|
+ non_srg_th -= ATH11K_DEFAULT_NOISE_FLOOR;
|
|
+ /* SRG not supported and threshold in dB */
|
|
+ param_val &= ~(ATH11K_OBSS_PD_SRG_EN |
|
|
+ ATH11K_OBSS_PD_THRESHOLD_IN_DBM);
|
|
+ }
|
|
+
|
|
+ param_val |= (non_srg_th & 0xff);
|
|
+ ret = ath11k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set obss_pd_threshold for pdev: %u\n",
|
|
+ pdev_id);
|
|
+
|
|
+ /* Enable OBSS PD for all access category */
|
|
+ param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC;
|
|
+ param_val = 0xf;
|
|
+ ret = ath11k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set obss_pd_per_ac for pdev: %u\n",
|
|
+ pdev_id);
|
|
+
|
|
+ /* Set SR Prohibit */
|
|
+ param_id = WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT;
|
|
+ param_val = !!(he_obss_pd->sr_ctrl &
|
|
+ IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED);
|
|
+ ret = ath11k_wmi_pdev_set_param(ar, param_id, param_val, pdev_id);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab, "Failed to set sr_prohibit for pdev: %u\n",
|
|
+ pdev_id);
|
|
+
|
|
+ if (!test_bit(WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT,
|
|
+ ar->ab->wmi_ab.svc_map))
|
|
+ return;
|
|
+
|
|
+ /* Set SRG BSS Color Bitmap */
|
|
+ memcpy(bitmap, he_obss_pd->bss_color_bitmap, sizeof(bitmap));
|
|
+ ret = ath11k_wmi_pdev_set_srg_bss_color_bitmap(ar, bitmap);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set bss_color_bitmap for pdev: %u\n",
|
|
+ pdev_id);
|
|
+
|
|
+ /* Set SRG Partial BSSID Bitmap */
|
|
+ memcpy(bitmap, he_obss_pd->partial_bssid_bitmap, sizeof(bitmap));
|
|
+ ret = ath11k_wmi_pdev_set_srg_patial_bssid_bitmap(ar, bitmap);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set partial_bssid_bitmap for pdev: %u\n",
|
|
+ pdev_id);
|
|
+
|
|
+ memset(bitmap, 0xff, sizeof(bitmap));
|
|
+
|
|
+ /* Enable all BSS Colors for SRG */
|
|
+ ret = ath11k_wmi_pdev_srg_obss_color_enable_bitmap(ar, bitmap);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set srg_color_en_bitmap pdev: %u\n",
|
|
+ pdev_id);
|
|
+
|
|
+ /* Enable all patial BSSID mask for SRG */
|
|
+ ret = ath11k_wmi_pdev_srg_obss_bssid_enable_bitmap(ar, bitmap);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set srg_bssid_en_bitmap pdev: %u\n",
|
|
+ pdev_id);
|
|
+
|
|
+ /* Enable all BSS Colors for non-SRG */
|
|
+ ret = ath11k_wmi_pdev_non_srg_obss_color_enable_bitmap(ar, bitmap);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set non_srg_color_en_bitmap pdev: %u\n",
|
|
+ pdev_id);
|
|
+
|
|
+ /* Enable all patial BSSID mask for non-SRG */
|
|
+ ret = ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(ar, bitmap);
|
|
+ if (ret)
|
|
+ ath11k_warn(ar->ab,
|
|
+ "Failed to set non_srg_bssid_en_bitmap pdev: %u\n",
|
|
+ pdev_id);
|
|
+}
|
|
+
|
|
static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
struct ieee80211_bss_conf *info,
|
|
@@ -3006,8 +3137,7 @@ static void ath11k_mac_op_bss_info_chang
|
|
}
|
|
|
|
if (changed & BSS_CHANGED_HE_OBSS_PD)
|
|
- ath11k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id,
|
|
- &info->he_obss_pd);
|
|
+ ath11k_mac_config_obss_pd(ar, &info->he_obss_pd);
|
|
|
|
if (changed & BSS_CHANGED_HE_BSS_COLOR) {
|
|
if (vif->type == NL80211_IFTYPE_AP) {
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.h
|
|
@@ -127,6 +127,12 @@ struct ath11k_generic_iter {
|
|
#define IEEE80211_HE_DL_MU_SUPPORT_ENABLE 2
|
|
#define IEEE80211_HE_DL_MU_SUPPORT_INVALID 3
|
|
|
|
+#define ATH11K_OBSS_PD_MAX_THRESHOLD -82
|
|
+#define ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62
|
|
+#define ATH11K_OBSS_PD_THRESHOLD_IN_DBM BIT(29)
|
|
+#define ATH11K_OBSS_PD_SRG_EN BIT(30)
|
|
+#define ATH11K_OBSS_PD_NON_SRG_EN BIT(31)
|
|
+
|
|
extern const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default;
|
|
|
|
int ath11k_mac_ap_ps_recalc(struct ath11k *ar);
|
|
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
|
@@ -3476,6 +3476,233 @@ ath11k_wmi_send_obss_spr_cmd(struct ath1
|
|
}
|
|
|
|
int
|
|
+ath11k_wmi_pdev_set_srg_bss_color_bitmap(struct ath11k *ar, u32 *bitmap)
|
|
+{
|
|
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct ath11k_base *ab = wmi->wmi_ab->ab;
|
|
+ struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ int ret, len;
|
|
+
|
|
+ len = sizeof(*cmd);
|
|
+
|
|
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
|
|
+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
|
|
+ WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+ memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
|
+ "obss pd pdev_id %d bss color bitmap %08x %08x\n",
|
|
+ cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
|
|
+
|
|
+ ret = ath11k_wmi_cmd_send(wmi, skb,
|
|
+ WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ab,
|
|
+ "Failed to send WMI_PDEV_SET_SRG_BSS_COLOR_BITMAP_CMDID");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int
|
|
+ath11k_wmi_pdev_set_srg_patial_bssid_bitmap(struct ath11k *ar, u32 *bitmap)
|
|
+{
|
|
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct ath11k_base *ab = wmi->wmi_ab->ab;
|
|
+ struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ int ret, len;
|
|
+
|
|
+ len = sizeof(*cmd);
|
|
+
|
|
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
|
|
+ cmd->tlv_header =
|
|
+ FIELD_PREP(WMI_TLV_TAG,
|
|
+ WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+ memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
|
+ "obss pd pdev_id %d partial bssid bitmap %08x %08x\n",
|
|
+ cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
|
|
+
|
|
+ ret = ath11k_wmi_cmd_send(wmi, skb,
|
|
+ WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ab,
|
|
+ "Failed to send WMI_PDEV_SET_SRG_PARTIAL_BSSID_BITMAP_CMDID");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int
|
|
+ath11k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath11k *ar, u32 *bitmap)
|
|
+{
|
|
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct ath11k_base *ab = wmi->wmi_ab->ab;
|
|
+ struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ int ret, len;
|
|
+
|
|
+ len = sizeof(*cmd);
|
|
+
|
|
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
|
|
+ cmd->tlv_header =
|
|
+ FIELD_PREP(WMI_TLV_TAG,
|
|
+ WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+ memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
|
+ "obss pd srg pdev_id %d bss color enable bitmap %08x %08x\n",
|
|
+ cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
|
|
+
|
|
+ ret = ath11k_wmi_cmd_send(wmi, skb,
|
|
+ WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ab,
|
|
+ "Failed to send WMI_PDEV_SET_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int
|
|
+ath11k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath11k *ar, u32 *bitmap)
|
|
+{
|
|
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct ath11k_base *ab = wmi->wmi_ab->ab;
|
|
+ struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ int ret, len;
|
|
+
|
|
+ len = sizeof(*cmd);
|
|
+
|
|
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
|
|
+ cmd->tlv_header =
|
|
+ FIELD_PREP(WMI_TLV_TAG,
|
|
+ WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+ memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
|
+ "obss pd srg pdev_id %d bssid enable bitmap %08x %08x\n",
|
|
+ cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
|
|
+
|
|
+ ret = ath11k_wmi_cmd_send(wmi, skb,
|
|
+ WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ab,
|
|
+ "Failed to send WMI_PDEV_SET_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int
|
|
+ath11k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath11k *ar, u32 *bitmap)
|
|
+{
|
|
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct ath11k_base *ab = wmi->wmi_ab->ab;
|
|
+ struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ int ret, len;
|
|
+
|
|
+ len = sizeof(*cmd);
|
|
+
|
|
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
|
|
+ cmd->tlv_header =
|
|
+ FIELD_PREP(WMI_TLV_TAG,
|
|
+ WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+ memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
|
+ "obss pd non_srg pdev_id %d bss color enable bitmap %08x %08x\n",
|
|
+ cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
|
|
+
|
|
+ ret = ath11k_wmi_cmd_send(wmi, skb,
|
|
+ WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ab,
|
|
+ "Failed to send WMI_PDEV_SET_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMDID");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int
|
|
+ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar, u32 *bitmap)
|
|
+{
|
|
+ struct ath11k_pdev_wmi *wmi = ar->wmi;
|
|
+ struct ath11k_base *ab = wmi->wmi_ab->ab;
|
|
+ struct wmi_pdev_obss_pd_bitmap_cmd *cmd;
|
|
+ struct sk_buff *skb;
|
|
+ int ret, len;
|
|
+
|
|
+ len = sizeof(*cmd);
|
|
+
|
|
+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
|
+ if (!skb)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ cmd = (struct wmi_pdev_obss_pd_bitmap_cmd *)skb->data;
|
|
+ cmd->tlv_header =
|
|
+ FIELD_PREP(WMI_TLV_TAG,
|
|
+ WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD) |
|
|
+ FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
|
+ cmd->pdev_id = ar->pdev->pdev_id;
|
|
+ memcpy(cmd->bitmap, bitmap, sizeof(cmd->bitmap));
|
|
+
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
|
+ "obss pd non_srg pdev_id %d bssid enable bitmap %08x %08x\n",
|
|
+ cmd->pdev_id, cmd->bitmap[0], cmd->bitmap[1]);
|
|
+
|
|
+ ret = ath11k_wmi_cmd_send(wmi, skb,
|
|
+ WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID);
|
|
+ if (ret) {
|
|
+ ath11k_warn(ab,
|
|
+ "Failed to send WMI_PDEV_SET_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMDID");
|
|
+ dev_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int
|
|
ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id,
|
|
u8 bss_color, u32 period,
|
|
bool enable)
|
|
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
|
@@ -960,6 +960,9 @@ enum wmi_tlv_pdev_param {
|
|
WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE,
|
|
WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE,
|
|
WMI_PDEV_PARAM_MESH_MCAST_ENABLE,
|
|
+ WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 0xbc,
|
|
+ WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC = 0xbe,
|
|
+ WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT = 0xc6,
|
|
};
|
|
|
|
enum wmi_tlv_vdev_param {
|
|
@@ -1862,6 +1865,13 @@ enum wmi_tlv_tag {
|
|
WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO,
|
|
WMI_TAG_MUEDCA_PARAMS_CONFIG_EVENT = 0x32a,
|
|
WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344,
|
|
+ WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b,
|
|
+ WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD,
|
|
+ WMI_TAG_PDEV_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD =
|
|
+ WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD + 5,
|
|
+ WMI_TAG_PDEV_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
|
|
+ WMI_TAG_PDEV_NON_SRG_OBSS_COLOR_ENABLE_BITMAP_CMD,
|
|
+ WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD,
|
|
WMI_TAG_TPC_STATS_GET_CMD = 0x38B,
|
|
WMI_TAG_TPC_STATS_EVENT_FIXED_PARAM,
|
|
WMI_TAG_TPC_STATS_CONFIG_EVENT,
|
|
@@ -5221,6 +5231,12 @@ struct wmi_obss_spatial_reuse_params_cmd
|
|
u32 vdev_id;
|
|
} __packed;
|
|
|
|
+struct wmi_pdev_obss_pd_bitmap_cmd {
|
|
+ u32 tlv_header;
|
|
+ u32 pdev_id;
|
|
+ u32 bitmap[2];
|
|
+} __packed;
|
|
+
|
|
#define ATH11K_BSS_COLOR_COLLISION_SCAN_PERIOD_MS 200
|
|
#define ATH11K_OBSS_COLOR_COLLISION_DETECTION_DISABLE 0
|
|
#define ATH11K_OBSS_COLOR_COLLISION_DETECTION 1
|
|
@@ -5782,6 +5798,16 @@ int ath11k_wmi_send_twt_resume_dialog_cm
|
|
struct wmi_twt_resume_dialog_params *params);
|
|
int ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id,
|
|
struct ieee80211_he_obss_pd *he_obss_pd);
|
|
+int ath11k_wmi_pdev_set_srg_bss_color_bitmap(struct ath11k *ar, u32 *bitmap);
|
|
+int ath11k_wmi_pdev_set_srg_patial_bssid_bitmap(struct ath11k *ar, u32 *bitmap);
|
|
+int ath11k_wmi_pdev_srg_obss_color_enable_bitmap(struct ath11k *ar,
|
|
+ u32 *bitmap);
|
|
+int ath11k_wmi_pdev_srg_obss_bssid_enable_bitmap(struct ath11k *ar,
|
|
+ u32 *bitmap);
|
|
+int ath11k_wmi_pdev_non_srg_obss_color_enable_bitmap(struct ath11k *ar,
|
|
+ u32 *bitmap);
|
|
+int ath11k_wmi_pdev_non_srg_obss_bssid_enable_bitmap(struct ath11k *ar,
|
|
+ u32 *bitmap);
|
|
int ath11k_send_coex_config_cmd(struct ath11k *ar,
|
|
struct coex_config_arg *coex_config);
|
|
int ath11k_wmi_pdev_ap_ps_cmd_send(struct ath11k *ar, u8 pdev_id, u32 value);
|
|
--- a/drivers/net/wireless/ath/ath11k/debug_htt_stats.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/debug_htt_stats.c
|
|
@@ -3678,6 +3678,18 @@ htt_print_pdev_obss_pd_stats_tlv_v(const
|
|
htt_stats_buf->num_obss_tx_ppdu_success);
|
|
len += HTT_DBG_OUT(buf + len, buf_len - len, "OBSS Tx failures PPDU = %u\n",
|
|
htt_stats_buf->num_obss_tx_ppdu_failure);
|
|
+ len += HTT_DBG_OUT(buf + len, buf_len - len, "Non-SRG Opportunities = %u\n",
|
|
+ htt_stats_buf->num_non_srg_opportunities);
|
|
+ len += HTT_DBG_OUT(buf + len, buf_len - len, "Non-SRG tried PPDU = %u\n",
|
|
+ htt_stats_buf->num_non_srg_ppdu_tried);
|
|
+ len += HTT_DBG_OUT(buf + len, buf_len - len, "Non-SRG success PPDU = %u\n",
|
|
+ htt_stats_buf->num_non_srg_ppdu_success);
|
|
+ len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG Opportunies = %u\n",
|
|
+ htt_stats_buf->num_srg_opportunities);
|
|
+ len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG tried PPDU = %u\n",
|
|
+ htt_stats_buf->num_srg_ppdu_tried);
|
|
+ len += HTT_DBG_OUT(buf + len, buf_len - len, "SRG success PPDU = %u\n",
|
|
+ htt_stats_buf->num_srg_ppdu_success);
|
|
|
|
if (len >= buf_len)
|
|
buf[buf_len - 1] = 0;
|
|
--- a/drivers/net/wireless/ath/ath11k/debug_htt_stats.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/debug_htt_stats.h
|
|
@@ -1715,8 +1715,19 @@ struct htt_tx_sounding_stats_tlv {
|
|
};
|
|
|
|
struct htt_pdev_obss_pd_stats_tlv {
|
|
- u32 num_obss_tx_ppdu_success;
|
|
- u32 num_obss_tx_ppdu_failure;
|
|
+ u32 num_obss_tx_ppdu_success;
|
|
+ u32 num_obss_tx_ppdu_failure;
|
|
+ u32 num_sr_tx_transmissions;
|
|
+ u32 num_spatial_reuse_opportunities;
|
|
+ u32 num_non_srg_opportunities;
|
|
+ u32 num_non_srg_ppdu_tried;
|
|
+ u32 num_non_srg_ppdu_success;
|
|
+ u32 num_srg_opportunities;
|
|
+ u32 num_srg_ppdu_tried;
|
|
+ u32 num_srg_ppdu_success;
|
|
+ u32 num_psr_opportunities;
|
|
+ u32 num_psr_ppdu_tried;
|
|
+ u32 num_psr_ppdu_success;
|
|
};
|
|
|
|
void ath11k_debug_htt_stats_init(struct ath11k *ar);
|