Trigger the WMI call en/disabling OBSS PD when the bss config changes or we assoc to an AP that broadcasts the IE. Signed-off-by: Shashidhar Lakkavalli <slakkavalli@xxxxxxxxx> Signed-off-by: John Crispin <john@xxxxxxxxxxx> --- drivers/net/wireless/ath/ath11k/mac.c | 10 ++++++++ drivers/net/wireless/ath/ath11k/wmi.c | 35 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/wmi.h | 16 ++++++++++++ 3 files changed, 61 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 904b16d020d4..f87a9f906202 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -1715,6 +1715,12 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw, 1); if (ret) ath11k_warn(ar->ab, "Unable to authorize BSS peer: %d\n", ret); + + ret = ath11k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, + &bss_conf->he_obss_pd); + if (ret) + ath11k_warn(ar->ab, "failed to set vdev %i OBSS PD parameters: %d\n", + arvif->vdev_id, ret); } static void ath11k_bss_disassoc(struct ieee80211_hw *hw, @@ -1906,6 +1912,10 @@ static void ath11k_bss_info_changed(struct ieee80211_hw *hw, ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev_idx); } + if (changed & BSS_CHANGED_HE_OBSS_PD) + ath11k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id, + &info->he_obss_pd); + mutex_unlock(&ar->conf_mutex); } diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 7a46239b5d14..941c05cd529e 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -2586,6 +2586,41 @@ ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id) return ret; } +int +ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id, + struct ieee80211_he_obss_pd *he_obss_pd) +{ + struct ath11k_pdev_wmi *wmi = ar->wmi; + struct ath11k_base *ab = wmi->wmi_sc->sc; + struct wmi_obss_spatial_reuse_params_cmd *cmd; + struct sk_buff *skb; + int ret, len; + + len = sizeof(*cmd); + + skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len); + if (!skb) + return -ENOMEM; + + cmd = (void *)skb->data; + cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, + WMI_TAG_OBSS_SPATIAL_REUSE_SET_CMD) | + FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE); + cmd->vdev_id = vdev_id; + cmd->enable = he_obss_pd->enable; + cmd->obss_min = he_obss_pd->min_offset; + cmd->obss_max = he_obss_pd->max_offset; + + ret = ath11k_wmi_cmd_send(wmi, skb, + WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID); + if (ret) { + ath11k_warn(ab, + "Failed to send WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID"); + dev_kfree_skb(skb); + } + return ret; +} + static inline void ath11k_fill_band_to_mac_param(struct ath11k_base *soc, struct wmi_host_pdev_band_to_mac *band_to_mac) { diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index c74aa98439ca..10f2a83db327 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -172,6 +172,8 @@ enum wmi_cmd_group { WMI_GRP_WLM, /* 0x3c */ WMI_GRP_11K_OFFLOAD, /* 0x3d */ WMI_GRP_TWT, /* 0x3e */ + WMI_GRP_MOTION_DET, /* 0x3f */ + WMI_GRP_SPATIAL_REUSE, /* 0x40 */ }; @@ -541,6 +543,9 @@ enum wmi_tlv_cmd_id { WMI_TWT_DEL_DIALOG_CMDID, WMI_TWT_PAUSE_DIALOG_CMDID, WMI_TWT_RESUME_DIALOG_CMDID, + WMI_PDEV_OBSS_PD_SPATIAL_REUSE_CMDID = + WMI_TLV_CMD(WMI_GRP_SPATIAL_REUSE), + WMI_PDEV_OBSS_PD_SPATIAL_REUSE_SET_DEF_OBSS_THRESH_CMDID, }; enum wmi_tlv_event_id { @@ -5114,6 +5119,15 @@ struct wmi_twt_disable_params_cmd { u32 pdev_id; }; +struct wmi_obss_spatial_reuse_params_cmd { + u32 tlv_header; + u32 pdev_id; + u32 enable; + s32 obss_min; + s32 obss_max; + u32 vdev_id; +}; + struct target_resource_config { u32 num_vdevs; u32 num_peers; @@ -5305,4 +5319,6 @@ void ath11k_wmi_fw_stats_fill(struct ath11k *ar, int ath11k_wmi_simulate_radar(struct ath11k *ar); int ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id); int ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id); +int ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id, + struct ieee80211_he_obss_pd *he_obss_pd); #endif -- 2.20.1