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/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -2718,7 +2718,8 @@ static int ath11k_mac_config_obss_pd(str
 {
 	u32 bitmap[2], param_id, param_val, pdev_id;
 	int ret;
-	s8 non_srg_th = 0, srg_th = 0;
+	s8 non_srg_th = ATH11K_OBSS_PD_THRESHOLD_DISABLED;
+	s8 srg_th = 0;
 
 	pdev_id = ar->pdev->pdev_id;
 
@@ -2747,8 +2748,6 @@ static int ath11k_mac_config_obss_pd(str
 		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;
 	}
@@ -2763,7 +2762,8 @@ static int ath11k_mac_config_obss_pd(str
 		param_val |= ATH11K_OBSS_PD_THRESHOLD_IN_DBM;
 		param_val |= FIELD_PREP(GENMASK(15, 8), srg_th);
 	} else {
-		non_srg_th -= ATH11K_DEFAULT_NOISE_FLOOR;
+		if ((non_srg_th & 0xff) != ATH11K_OBSS_PD_THRESHOLD_DISABLED)
+			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);
--- a/drivers/net/wireless/ath/ath11k/mac.h
+++ b/drivers/net/wireless/ath/ath11k/mac.h
@@ -120,7 +120,7 @@ struct ath11k_generic_iter {
 #define ATH11K_PEER_RX_NSS_80_80MHZ            GENMASK(5, 3)
 
 #define ATH11K_OBSS_PD_MAX_THRESHOLD			-82
-#define ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD		-62
+#define ATH11K_OBSS_PD_THRESHOLD_DISABLED		128
 #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)
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5531,7 +5531,8 @@ static int nl80211_start_ap(struct sk_bu
 		err = nl80211_parse_he_obss_pd(
 					info->attrs[NL80211_ATTR_HE_OBSS_PD],
 					&params.he_obss_pd);
-		goto out;
+		if (err)
+			goto out;
 	}
 
 	if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
