All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/2] rtw88: update regulatory settings
@ 2020-03-24  7:52 yhchuang
  2020-03-24  7:52 ` [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset yhchuang
  2020-03-24  7:52 ` [PATCH v6 2/2] rtw88: add adaptivity support for EU/JP regulatory yhchuang
  0 siblings, 2 replies; 7+ messages in thread
From: yhchuang @ 2020-03-24  7:52 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, briannorris, tehuang

From: Yan-Hsuan Chuang <yhchuang@realtek.com>

This patchset applies regulatory rules for Realtek's chip set.

Some of the modules are programmed country-specific code in the efuse.
And for this kind of modules, driver doesn't want the regulatory to be
changed, so the driver tends to not listen to the regulatory hint that
is notified by the stack. Otherwise if the modules are not programmed
to a country-specific code, then the world-wide (WW) settings will be
adopted. If the regulatory is WW, the driver will apply the settings
notified by the stack.

If anyone wants to allow regulatory being set from user-space tools
(ex: iw reg set), a compile option flag RTW88_REGD_USER_REG_HINTS
should be set to allow regulatory hist from user.

Also add "Adaptivity" support for some special country codes, because
they have to stop TX immediately if there's any energy detected.


v2 -> v3
  * split patch set for further discussion

v3 -> v4
  * squash patch set, since nobody has different idea for it
  * "rtw88: add regulatory process strategy for different chipset" and
    "rtw88: support dynamic user regulatory setting" are squashed
  * modify the commit log to better describe it
  * add a new patch for adaptivity support "rtw88: add adaptivity
    support for EU/JP regulatory"

v4 -> v5
  * check return value of kstrtobool()

v5 -> v6
  * remove custom world-wide, use stack world-wide
  * surface err codes by printing logs
  * fix incorrect debugfs set parameter for edcca enable


Tzu-En Huang (2):
  rtw88: add regulatory process strategy for different chipset
  rtw88: add adaptivity support for EU/JP regulatory

 drivers/net/wireless/realtek/rtw88/Kconfig    | 10 +++
 drivers/net/wireless/realtek/rtw88/debug.c    | 40 ++++++++++
 drivers/net/wireless/realtek/rtw88/main.c     |  6 +-
 drivers/net/wireless/realtek/rtw88/main.h     | 32 ++++++++
 drivers/net/wireless/realtek/rtw88/phy.c      | 60 +++++++++++++++
 drivers/net/wireless/realtek/rtw88/phy.h      |  2 +
 drivers/net/wireless/realtek/rtw88/reg.h      |  2 +
 drivers/net/wireless/realtek/rtw88/regd.c     | 75 ++++++++++++++++---
 drivers/net/wireless/realtek/rtw88/regd.h     |  2 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 41 ++++++++++
 drivers/net/wireless/realtek/rtw88/rtw8822b.h |  6 ++
 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 45 +++++++++++
 drivers/net/wireless/realtek/rtw88/rtw8822c.h |  2 +
 13 files changed, 311 insertions(+), 12 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset
  2020-03-24  7:52 [PATCH v6 0/2] rtw88: update regulatory settings yhchuang
@ 2020-03-24  7:52 ` yhchuang
  2020-03-24 16:51   ` Brian Norris
  2020-03-24  7:52 ` [PATCH v6 2/2] rtw88: add adaptivity support for EU/JP regulatory yhchuang
  1 sibling, 1 reply; 7+ messages in thread
From: yhchuang @ 2020-03-24  7:52 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, briannorris, tehuang

From: Tzu-En Huang <tehuang@realtek.com>

If the country code in efuse is not set to a specific regulatory,
then the efuse setting is WW (world-wide).

For the country codes that are set to a specific country, the driver
is not going to apply any new setting notified from the stack.

For the country codes that are not set, which is treated as WW, the
driver hints stack with "00" country code. But when there's any other
regulatory found in IE, notified by NL80211_REGDOM_SET_BY_COUNTRY_IE,
the driver will apply the setting found in the IE for 802.11d.

We want all of the regulatory rules being set strictly, not to loose
the restrictions of the country setting, so apply REGULATORY_STRICT_REG
to all of the regulatory settings.

For user notification (NL80211_REGDOM_SET_BY_USER), we'd like to
default disable it because as FCC publication 594280 states:
"In particular, users must not be relied on to set a country code or
location code to ensure compliance". If any distributions or OSes want
to set regulatory through user space tool (ex, iw reg set), then they
should honor the compile flag option RTW88_REGD_USER_REG_HINTS.

Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
---

v3 -> v4
  * squashed with "rtw88: support dynamic user regulatory setting"
  * modify the commit log

v4 -> v5
  * no change

v5 -> v6
  * remove custom world-wide, use stack world-wide
  * surface error codes

 drivers/net/wireless/realtek/rtw88/Kconfig | 10 ++++
 drivers/net/wireless/realtek/rtw88/main.c  |  5 +-
 drivers/net/wireless/realtek/rtw88/regd.c  | 54 ++++++++++++++++++----
 3 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/Kconfig b/drivers/net/wireless/realtek/rtw88/Kconfig
index 33bd7ed797ff..04b84ec1dfc1 100644
--- a/drivers/net/wireless/realtek/rtw88/Kconfig
+++ b/drivers/net/wireless/realtek/rtw88/Kconfig
@@ -52,4 +52,14 @@ config RTW88_DEBUGFS
 
 	  If unsure, say Y to simplify debug problems
 
+config RTW88_REGD_USER_REG_HINTS
+	bool "Realtek rtw88 user regulatory hints"
+	depends on RTW88_CORE
+	default n
+	help
+	  Enable regulatoy user hints
+
+	  If unsure, say N. This should only be allowed on distributions
+	  that need this to correct the regulatory.
+
 endif
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 7640e97706f5..5d43bef91a3c 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1501,8 +1501,9 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
 		return ret;
 	}
 
-	if (regulatory_hint(hw->wiphy, rtwdev->regd.alpha2))
-		rtw_err(rtwdev, "regulatory_hint fail\n");
+	ret = regulatory_hint(hw->wiphy, rtwdev->efuse.country_code);
+	if (ret)
+		rtw_warn(rtwdev, "failed to hint regulatory: %d\n", ret);
 
 	rtw_debugfs_init(rtwdev);
 
diff --git a/drivers/net/wireless/realtek/rtw88/regd.c b/drivers/net/wireless/realtek/rtw88/regd.c
index 69744dd65968..4cc1234bfb9a 100644
--- a/drivers/net/wireless/realtek/rtw88/regd.c
+++ b/drivers/net/wireless/realtek/rtw88/regd.c
@@ -339,12 +339,34 @@ static struct rtw_regulatory rtw_regd_find_reg_by_name(char *alpha2)
 	return rtw_defined_chplan;
 }
 
+static bool rtw_regd_is_ww(struct rtw_regulatory *reg)
+{
+	if (reg->txpwr_regd == RTW_REGD_WW)
+		return true;
+
+	return false;
+}
+
 static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev,
 				   struct wiphy *wiphy,
 				   struct regulatory_request *request)
 {
-	if (request->initiator == NL80211_REGDOM_SET_BY_USER)
+	if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
+		return -ENOTSUPP;
+
+	if (request->initiator == NL80211_REGDOM_SET_BY_USER &&
+	    !IS_ENABLED(CONFIG_RTW88_REGD_USER_REG_HINTS))
+		return -EPERM;
+
+	if (request->initiator == NL80211_REGDOM_SET_BY_CORE) {
+		char *country_code;
+
+		/* return to the efuse setting */
+		country_code = rtwdev->efuse.country_code;
+		rtwdev->regd = rtw_regd_find_reg_by_name(country_code);
 		return 0;
+	}
+
 	rtwdev->regd = rtw_regd_find_reg_by_name(request->alpha2);
 	rtw_regd_apply_world_flags(wiphy, request->initiator);
 
@@ -352,16 +374,20 @@ static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev,
 }
 
 static int
-rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy,
+rtw_regd_init_wiphy(struct rtw_dev *rtwdev, struct wiphy *wiphy,
 		    void (*reg_notifier)(struct wiphy *wiphy,
 					 struct regulatory_request *request))
 {
-	wiphy->reg_notifier = reg_notifier;
+	struct rtw_regulatory *reg = &rtwdev->regd;
 
-	wiphy->regulatory_flags &= ~REGULATORY_CUSTOM_REG;
-	wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
-	wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
+	if (rtw_regd_is_ww(reg)) {
+		/* "00" implies worldwide in stack */
+		rtwdev->efuse.country_code[0] = '0';
+		rtwdev->efuse.country_code[1] = '0';
+	}
 
+	wiphy->reg_notifier = reg_notifier;
+	wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
 	rtw_regd_apply_hw_cap_flags(wiphy);
 
 	return 0;
@@ -377,7 +403,7 @@ int rtw_regd_init(struct rtw_dev *rtwdev,
 		return -EINVAL;
 
 	rtwdev->regd = rtw_regd_find_reg_by_name(rtwdev->efuse.country_code);
-	rtw_regd_init_wiphy(&rtwdev->regd, wiphy, reg_notifier);
+	rtw_regd_init_wiphy(rtwdev, wiphy, reg_notifier);
 
 	return 0;
 }
@@ -387,12 +413,20 @@ void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct rtw_dev *rtwdev = hw->priv;
 	struct rtw_hal *hal = &rtwdev->hal;
+	int ret;
+
+	ret = rtw_regd_notifier_apply(rtwdev, wiphy, request);
+	if (ret) {
+		rtw_warn(rtwdev, "failed to apply regulatory from initiator %d: %d\n",
+			 request->initiator, ret);
+		return;
+	}
 
-	rtw_regd_notifier_apply(rtwdev, wiphy, request);
 	rtw_dbg(rtwdev, RTW_DBG_REGD,
 		"get alpha2 %c%c from initiator %d, mapping to chplan 0x%x, txregd %d\n",
-		request->alpha2[0], request->alpha2[1], request->initiator,
-		rtwdev->regd.chplan, rtwdev->regd.txpwr_regd);
+		request->alpha2[0], request->alpha2[1],
+		request->initiator, rtwdev->regd.chplan,
+		rtwdev->regd.txpwr_regd);
 
 	rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v6 2/2] rtw88: add adaptivity support for EU/JP regulatory
  2020-03-24  7:52 [PATCH v6 0/2] rtw88: update regulatory settings yhchuang
  2020-03-24  7:52 ` [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset yhchuang
@ 2020-03-24  7:52 ` yhchuang
  1 sibling, 0 replies; 7+ messages in thread
From: yhchuang @ 2020-03-24  7:52 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, briannorris, tehuang

From: Tzu-En Huang <tehuang@realtek.com>

From MIC Ordinance Regulating Radio Equipment article 49.20,
ETSI EN-300-328 and EN-301-893, the device should be able to
dynamically pause TX activity when energy detected on the air.

To achieve this, add Energy Detected CCA (EDCCA) support to
detect the energy in the channel. Driver will set corresponding
thresholds to the device, if the energy detected exceeds the
threshold, the TX activity will be halted immediately.

As this could lead to performance downgrade when the environment
is noisy, add a debugfs to disable this for debugging usage.

Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
---

v4
  * first added

v4 -> v5
  * check return value of kstrtobool()

v5 -> v6
  * fix incorrect edcca set parameter

 drivers/net/wireless/realtek/rtw88/debug.c    | 40 +++++++++++++
 drivers/net/wireless/realtek/rtw88/main.c     |  1 +
 drivers/net/wireless/realtek/rtw88/main.h     | 32 ++++++++++
 drivers/net/wireless/realtek/rtw88/phy.c      | 60 +++++++++++++++++++
 drivers/net/wireless/realtek/rtw88/phy.h      |  2 +
 drivers/net/wireless/realtek/rtw88/reg.h      |  2 +
 drivers/net/wireless/realtek/rtw88/regd.c     | 21 +++++++
 drivers/net/wireless/realtek/rtw88/regd.h     |  2 +
 drivers/net/wireless/realtek/rtw88/rtw8822b.c | 41 +++++++++++++
 drivers/net/wireless/realtek/rtw88/rtw8822b.h |  6 ++
 drivers/net/wireless/realtek/rtw88/rtw8822c.c | 45 ++++++++++++++
 drivers/net/wireless/realtek/rtw88/rtw8822c.h |  2 +
 12 files changed, 254 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/debug.c b/drivers/net/wireless/realtek/rtw88/debug.c
index 5a181e01ebef..6652c3fc3159 100644
--- a/drivers/net/wireless/realtek/rtw88/debug.c
+++ b/drivers/net/wireless/realtek/rtw88/debug.c
@@ -694,6 +694,40 @@ static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v)
 	return 0;
 }
 
+static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp,
+					    const char __user *buffer,
+					    size_t count, loff_t *loff)
+{
+	struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
+	struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
+	struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+	char tmp[32 + 1];
+	int ret;
+
+	rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1);
+
+	ret = kstrtobool(tmp, &rtw_edcca_enabled);
+	if (ret) {
+		rtw_warn(rtwdev, "invalid arguments\n");
+		return ret;
+	}
+
+	rtw_phy_adaptivity_set_mode(rtwdev);
+
+	return count;
+}
+
+static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v)
+{
+	struct rtw_debugfs_priv *debugfs_priv = m->private;
+	struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
+	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+	seq_printf(m, "EDCCA mode %d\n", dm_info->edcca_mode);
+
+	return 0;
+}
+
 #define rtw_debug_impl_mac(page, addr)				\
 static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = {	\
 	.cb_read = rtw_debug_get_mac_page,			\
@@ -784,6 +818,11 @@ static struct rtw_debugfs_priv rtw_debug_priv_phy_info = {
 	.cb_read = rtw_debugfs_get_phy_info,
 };
 
+static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = {
+	.cb_write = rtw_debugfs_set_edcca_enable,
+	.cb_read = rtw_debugfs_get_edcca_enable,
+};
+
 #define rtw_debugfs_add_core(name, mode, fopname, parent)		\
 	do {								\
 		rtw_debug_priv_ ##name.rtwdev = rtwdev;			\
@@ -854,6 +893,7 @@ void rtw_debugfs_init(struct rtw_dev *rtwdev)
 	}
 	rtw_debugfs_add_r(rf_dump);
 	rtw_debugfs_add_r(tx_pwr_tbl);
+	rtw_debugfs_add_rw(edcca_enable);
 }
 
 #endif /* CONFIG_RTW88_DEBUGFS */
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index 5d43bef91a3c..ffe3612e63a6 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -21,6 +21,7 @@ EXPORT_SYMBOL(rtw_fw_lps_deep_mode);
 bool rtw_bf_support = true;
 unsigned int rtw_debug_mask;
 EXPORT_SYMBOL(rtw_debug_mask);
+bool rtw_edcca_enabled = true;
 
 module_param_named(lps_deep_mode, rtw_fw_lps_deep_mode, uint, 0644);
 module_param_named(support_bf, rtw_bf_support, bool, 0644);
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index 279410a87141..9d3c0cded77e 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -38,6 +38,7 @@
 extern bool rtw_bf_support;
 extern unsigned int rtw_fw_lps_deep_mode;
 extern unsigned int rtw_debug_mask;
+extern bool rtw_edcca_enabled;
 extern const struct ieee80211_ops rtw_ops;
 extern struct rtw_chip_info rtw8822b_hw_spec;
 extern struct rtw_chip_info rtw8822c_hw_spec;
@@ -327,6 +328,8 @@ enum rtw_trx_desc_rate {
 	DESC_RATE_MAX,
 };
 
+#define RTW_REGION_INVALID 0xff
+
 enum rtw_regulatory_domains {
 	RTW_REGD_FCC		= 0,
 	RTW_REGD_MKK		= 1,
@@ -515,6 +518,11 @@ struct rtw_hw_reg {
 	u32 mask;
 };
 
+struct rtw_hw_reg_offset {
+	struct rtw_hw_reg hw_reg;
+	u8 offset;
+};
+
 struct rtw_backup_info {
 	u8 len;
 	u32 reg;
@@ -765,6 +773,7 @@ struct rtw_regulatory {
 	char alpha2[2];
 	u8 chplan;
 	u8 txpwr_regd;
+	enum nl80211_dfs_regions region;
 };
 
 struct rtw_chip_ops {
@@ -798,6 +807,8 @@ struct rtw_chip_ops {
 			      struct ieee80211_bss_conf *conf);
 	void (*cfg_csi_rate)(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate,
 			     u8 fixrate_en, u8 *new_rate);
+	void (*adaptivity_init)(struct rtw_dev *rtwdev);
+	void (*adaptivity)(struct rtw_dev *rtwdev);
 
 	/* for coex */
 	void (*coex_set_init)(struct rtw_dev *rtwdev);
@@ -1086,6 +1097,10 @@ struct rtw_chip_info {
 	u8 bfer_su_max_num;
 	u8 bfer_mu_max_num;
 
+	struct rtw_hw_reg_offset *edcca_th;
+	s8 l2h_th_ini_cs;
+	s8 l2h_th_ini_ad;
+
 	const char *wow_fw_name;
 	const struct wiphy_wowlan_support *wowlan_stub;
 	const u8 max_sched_scan_ssids;
@@ -1355,6 +1370,20 @@ struct rtw_pkt_count {
 DECLARE_EWMA(evm, 10, 4);
 DECLARE_EWMA(snr, 10, 4);
 
+#define EDCCA_TH_L2H_IDX 0
+#define EDCCA_TH_H2L_IDX 1
+#define EDCCA_TH_L2H_LB 48
+#define EDCCA_ADC_BACKOFF 12
+#define EDCCA_IGI_BASE 50
+#define EDCCA_IGI_L2H_DIFF 8
+#define EDCCA_L2H_H2L_DIFF 7
+#define EDCCA_L2H_H2L_DIFF_NORMAL 8
+
+enum rtw_edcca_mode {
+	RTW_EDCCA_NORMAL	= 0,
+	RTW_EDCCA_ADAPTIVITY	= 1,
+};
+
 struct rtw_dm_info {
 	u32 cck_fa_cnt;
 	u32 ofdm_fa_cnt;
@@ -1414,6 +1443,9 @@ struct rtw_dm_info {
 	struct rtw_pkt_count last_pkt_count;
 	struct ewma_evm ewma_evm[RTW_EVM_NUM];
 	struct ewma_snr ewma_snr[RTW_SNR_NUM];
+
+	s8 l2h_th_ini;
+	enum rtw_edcca_mode edcca_mode;
 };
 
 struct rtw_efuse {
diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
index 8793dd22188f..9e398c18f631 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.c
+++ b/drivers/net/wireless/realtek/rtw88/phy.c
@@ -9,6 +9,7 @@
 #include "fw.h"
 #include "phy.h"
 #include "debug.h"
+#include "regd.h"
 
 struct phy_cfg_pair {
 	u32 addr;
@@ -115,6 +116,57 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
 	dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
 }
 
+void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l)
+{
+	struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
+
+	rtw_write32_mask(rtwdev,
+			 edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,
+			 edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask,
+			 l2h + edcca_th[EDCCA_TH_L2H_IDX].offset);
+	rtw_write32_mask(rtwdev,
+			 edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr,
+			 edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask,
+			 h2l + edcca_th[EDCCA_TH_H2L_IDX].offset);
+}
+
+void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev)
+{
+	struct rtw_chip_info *chip = rtwdev->chip;
+	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+
+	/* turn off in debugfs for debug usage */
+	if (!rtw_edcca_enabled) {
+		dm_info->edcca_mode = RTW_EDCCA_NORMAL;
+		rtw_dbg(rtwdev, RTW_DBG_PHY, "EDCCA disabled, cannot be set\n");
+		return;
+	}
+
+	switch (rtwdev->regd.region) {
+	case NL80211_DFS_ETSI:
+		dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY;
+		dm_info->l2h_th_ini = chip->l2h_th_ini_ad;
+		break;
+	case NL80211_DFS_JP:
+		dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY;
+		dm_info->l2h_th_ini = chip->l2h_th_ini_cs;
+		break;
+	default:
+		dm_info->edcca_mode = RTW_EDCCA_NORMAL;
+		break;
+	}
+}
+
+static void rtw_phy_adaptivity_init(struct rtw_dev *rtwdev)
+{
+	struct rtw_chip_info *chip = rtwdev->chip;
+
+	rtw_regd_init_dfs_region(rtwdev, rtwdev->regd.region);
+	rtw_phy_adaptivity_set_mode(rtwdev);
+	if (chip->ops->adaptivity_init)
+		chip->ops->adaptivity_init(rtwdev);
+}
+
 void rtw_phy_init(struct rtw_dev *rtwdev)
 {
 	struct rtw_chip_info *chip = rtwdev->chip;
@@ -134,6 +186,7 @@ void rtw_phy_init(struct rtw_dev *rtwdev)
 	mask = chip->dig[0].mask;
 	dm_info->igi_history[0] = rtw_read32_mask(rtwdev, addr, mask);
 	rtw_phy_cck_pd_init(rtwdev);
+	rtw_phy_adaptivity_init(rtwdev);
 }
 
 void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi)
@@ -543,6 +596,12 @@ static void rtw_phy_pwr_track(struct rtw_dev *rtwdev)
 	rtwdev->chip->ops->pwr_track(rtwdev);
 }
 
+static void rtw_phy_adaptivity(struct rtw_dev *rtwdev)
+{
+	if (rtwdev->chip->ops->adaptivity)
+		rtwdev->chip->ops->adaptivity(rtwdev);
+}
+
 void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
 {
 	/* for further calculation */
@@ -552,6 +611,7 @@ void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
 	rtw_phy_ra_info_update(rtwdev);
 	rtw_phy_dpk_track(rtwdev);
 	rtw_phy_pwr_track(rtwdev);
+	rtw_phy_adaptivity(rtwdev);
 }
 
 #define FRAC_BITS 3
diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h
index af916d8784cd..ca7af828b5a7 100644
--- a/drivers/net/wireless/realtek/rtw88/phy.h
+++ b/drivers/net/wireless/realtek/rtw88/phy.h
@@ -56,6 +56,8 @@ s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev,
 bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev);
 void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
 				struct rtw_swing_table *swing_table);
+void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l);
+void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev);
 
 struct rtw_txpwr_lmt_cfg_pair {
 	u8 regd;
diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index 9d94534c9674..b8c6601e5123 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -265,9 +265,11 @@
 #define BIT_SHIFT_SIFS_OFDM_TRX	24
 #define REG_SLOT		0x051B
 #define REG_TX_PTCL_CTRL	0x0520
+#define BIT_DIS_EDCCA		BIT(15)
 #define BIT_SIFS_BK_EN		BIT(12)
 #define REG_TXPAUSE		0x0522
 #define REG_RD_CTRL		0x0524
+#define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11)
 #define BIT_DIS_TXOP_CFE	BIT(10)
 #define BIT_DIS_LSIG_CFE	BIT(9)
 #define BIT_DIS_STBC_CFE	BIT(8)
diff --git a/drivers/net/wireless/realtek/rtw88/regd.c b/drivers/net/wireless/realtek/rtw88/regd.c
index 4cc1234bfb9a..cec3e10b2a4e 100644
--- a/drivers/net/wireless/realtek/rtw88/regd.c
+++ b/drivers/net/wireless/realtek/rtw88/regd.c
@@ -347,6 +347,22 @@ static bool rtw_regd_is_ww(struct rtw_regulatory *reg)
 	return false;
 }
 
+void rtw_regd_init_dfs_region(struct rtw_dev *rtwdev,
+			      enum nl80211_dfs_regions curr_region)
+{
+	struct ieee80211_hw *hw = rtwdev->hw;
+	const struct ieee80211_regdomain *wiphy_regd = NULL;
+
+	if (curr_region != RTW_REGION_INVALID)
+		return;
+
+	rcu_read_lock();
+	wiphy_regd = rcu_dereference(hw->wiphy->regd);
+	if (wiphy_regd)
+		rtwdev->regd.region = wiphy_regd->dfs_region;
+	rcu_read_unlock();
+}
+
 static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev,
 				   struct wiphy *wiphy,
 				   struct regulatory_request *request)
@@ -364,11 +380,13 @@ static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev,
 		/* return to the efuse setting */
 		country_code = rtwdev->efuse.country_code;
 		rtwdev->regd = rtw_regd_find_reg_by_name(country_code);
+		rtw_regd_init_dfs_region(rtwdev, RTW_REGION_INVALID);
 		return 0;
 	}
 
 	rtwdev->regd = rtw_regd_find_reg_by_name(request->alpha2);
 	rtw_regd_apply_world_flags(wiphy, request->initiator);
+	rtwdev->regd.region = request->dfs_region;
 
 	return 0;
 }
@@ -404,6 +422,7 @@ int rtw_regd_init(struct rtw_dev *rtwdev,
 
 	rtwdev->regd = rtw_regd_find_reg_by_name(rtwdev->efuse.country_code);
 	rtw_regd_init_wiphy(rtwdev, wiphy, reg_notifier);
+	rtwdev->regd.region = RTW_REGION_INVALID;
 
 	return 0;
 }
@@ -428,5 +447,7 @@ void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 		request->initiator, rtwdev->regd.chplan,
 		rtwdev->regd.txpwr_regd);
 
+	rtw_phy_adaptivity_set_mode(rtwdev);
+
 	rtw_phy_set_tx_power_level(rtwdev, hal->current_channel);
 }
diff --git a/drivers/net/wireless/realtek/rtw88/regd.h b/drivers/net/wireless/realtek/rtw88/regd.h
index 5d4578331788..b50d5fb9545a 100644
--- a/drivers/net/wireless/realtek/rtw88/regd.h
+++ b/drivers/net/wireless/realtek/rtw88/regd.h
@@ -68,4 +68,6 @@ int rtw_regd_init(struct rtw_dev *rtwdev,
 		  void (*reg_notifier)(struct wiphy *wiphy,
 				       struct regulatory_request *request));
 void rtw_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+void rtw_regd_init_dfs_region(struct rtw_dev *rtwdev,
+			      enum nl80211_dfs_regions curr_region);
 #endif
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
index 96aa332fb28d..8b73b7e0a9f6 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c
@@ -1543,6 +1543,37 @@ static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif,
 		rtw_warn(rtwdev, "wrong bfee role\n");
 }
 
+static void rtw8822b_adaptivity_init(struct rtw_dev *rtwdev)
+{
+	rtw_phy_set_edcca_th(rtwdev, 0x7f, 0x7f);
+	/* mac edcca state setting */
+	rtw_write32_mask(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA, 0);
+	rtw_write32_mask(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN, 1);
+
+	rtw_write32_mask(rtwdev, REG_EDCCA_SOURCE, BIT_SOURCE_OPTION, 1);
+	rtw_write32_mask(rtwdev, REG_EDCCA_POW_MA, BIT_MA_LEVEL, 0);
+	/* edcca decistion opt */
+	rtw_write32_mask(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION, 1);
+}
+
+static void rtw8822b_adaptivity(struct rtw_dev *rtwdev)
+{
+	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+	s8 l2h, h2l;
+	u8 igi;
+
+	igi = dm_info->igi_history[0];
+	if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) {
+		l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB);
+		h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
+	} else {
+		l2h = min_t(s8, igi, dm_info->l2h_th_ini);
+		h2l = l2h - EDCCA_L2H_H2L_DIFF;
+	}
+
+	rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
+}
+
 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
 	{0x0086,
 	 RTW_PWR_CUT_ALL_MSK,
@@ -2094,6 +2125,8 @@ static struct rtw_chip_ops rtw8822b_ops = {
 	.config_bfee		= rtw8822b_bf_config_bfee,
 	.set_gid_table		= rtw_bf_set_gid_table,
 	.cfg_csi_rate		= rtw_bf_cfg_csi_rate,
+	.adaptivity_init	= rtw8822b_adaptivity_init,
+	.adaptivity		= rtw8822b_adaptivity,
 
 	.coex_set_init		= rtw8822b_coex_cfg_init,
 	.coex_set_ant_switch	= rtw8822b_coex_cfg_ant_switch,
@@ -2371,6 +2404,11 @@ static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = {
 	.pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p,
 };
 
+static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
+	[EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
+	[EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
+};
+
 struct rtw_chip_info rtw8822b_hw_spec = {
 	.ops = &rtw8822b_ops,
 	.id = RTW_CHIP_TYPE_8822B,
@@ -2413,6 +2451,9 @@ struct rtw_chip_info rtw8822b_hw_spec = {
 	.iqk_threshold = 8,
 	.bfer_su_max_num = 2,
 	.bfer_mu_max_num = 1,
+	.edcca_th = rtw8822b_edcca_th,
+	.l2h_th_ini_cs = 10 + EDCCA_IGI_BASE,
+	.l2h_th_ini_ad = -14 + EDCCA_IGI_BASE,
 
 	.coex_para_ver = 0x19062706,
 	.bt_desired_ver = 0x6,
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.h b/drivers/net/wireless/realtek/rtw88/rtw8822b.h
index 6211f4b547b9..f2518356a464 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h
@@ -152,11 +152,17 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
 #define REG_L1PKWT	0x840
 #define REG_MRC		0x850
 #define REG_CLKTRK	0x860
+#define REG_EDCCA_POW_MA	0x8a0
+#define BIT_MA_LEVEL	GENMASK(1, 0)
 #define REG_ADCCLK	0x8ac
 #define REG_ADC160	0x8c4
 #define REG_ADC40	0x8c8
+#define REG_EDCCA_DECISION	0x8dc
+#define BIT_EDCCA_OPTION	BIT(5)
 #define REG_CDDTXP	0x93c
 #define REG_TXPSEL1	0x940
+#define REG_EDCCA_SOURCE	0x944
+#define BIT_SOURCE_OPTION	GENMASK(29, 28)
 #define REG_ACBB0	0x948
 #define REG_ACBBRXFIR	0x94c
 #define REG_ACGG2TBL	0x958
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index d2469f91976b..fe4033b2ec6b 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -3414,6 +3414,37 @@ static void rtw8822c_pwr_track(struct rtw_dev *rtwdev)
 	dm_info->pwr_trk_triggered = false;
 }
 
+static void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev)
+{
+	rtw_phy_set_edcca_th(rtwdev, 0x7f, 0x7f);
+	/* mac edcca state setting */
+	rtw_write32_mask(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA, 0);
+	rtw_write32_mask(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN, 1);
+	/* edcca decistion opt */
+	rtw_write32_mask(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION, 0);
+}
+
+static void rtw8822c_adaptivity(struct rtw_dev *rtwdev)
+{
+	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
+	s8 l2h, h2l;
+	u8 igi;
+
+	igi = dm_info->igi_history[0];
+	if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) {
+		l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB);
+		h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL;
+	} else {
+		if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF)
+			l2h = igi + EDCCA_ADC_BACKOFF;
+		else
+			l2h = dm_info->l2h_th_ini;
+		h2l = l2h - EDCCA_L2H_H2L_DIFF;
+	}
+
+	rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
+}
+
 static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = {
 	{0x0086,
 	 RTW_PWR_CUT_ALL_MSK,
@@ -3803,6 +3834,8 @@ static struct rtw_chip_ops rtw8822c_ops = {
 	.config_bfee		= rtw8822c_bf_config_bfee,
 	.set_gid_table		= rtw_bf_set_gid_table,
 	.cfg_csi_rate		= rtw_bf_cfg_csi_rate,
+	.adaptivity_init	= rtw8822c_adaptivity_init,
+	.adaptivity		= rtw8822c_adaptivity,
 
 	.coex_set_init		= rtw8822c_coex_cfg_init,
 	.coex_set_ant_switch	= NULL,
@@ -4080,6 +4113,15 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
 	.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
 };
 
+static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
+	[EDCCA_TH_L2H_IDX] = {
+		{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
+	},
+	[EDCCA_TH_H2L_IDX] = {
+		{.addr = 0x84c, .mask = MASKBYTE3}, .offset = 0x80
+	},
+};
+
 #ifdef CONFIG_PM
 static const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = {
 	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_GTK_REKEY_FAILURE |
@@ -4137,6 +4179,9 @@ struct rtw_chip_info rtw8822c_hw_spec = {
 	.iqk_threshold = 8,
 	.bfer_su_max_num = 2,
 	.bfer_mu_max_num = 1,
+	.edcca_th = rtw8822c_edcca_th,
+	.l2h_th_ini_cs = 60,
+	.l2h_th_ini_ad = 45,
 
 #ifdef CONFIG_PM
 	.wow_fw_name = "rtw88/rtw8822c_wow_fw.bin",
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h
index dfd8662a0c0e..953fb19fad7e 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h
@@ -171,6 +171,8 @@ const struct rtw_table name ## _tbl = {			\
 #define REG_DFIRBW	0x810
 #define REG_ANTMAP0	0x820
 #define REG_ANTMAP	0x824
+#define REG_EDCCA_DECISION	0x844
+#define BIT_EDCCA_OPTION	GENMASK(30, 29)
 #define REG_DYMPRITH	0x86c
 #define REG_DYMENTH0	0x870
 #define REG_DYMENTH	0x874
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset
  2020-03-24  7:52 ` [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset yhchuang
@ 2020-03-24 16:51   ` Brian Norris
  2020-03-25  3:11     ` Andy Huang
  0 siblings, 1 reply; 7+ messages in thread
From: Brian Norris @ 2020-03-24 16:51 UTC (permalink / raw)
  To: yhchuang; +Cc: kvalo, linux-wireless, tehuang

Hi,

On Tue, Mar 24, 2020 at 03:52:15PM +0800, yhchuang@realtek.com wrote:
> --- a/drivers/net/wireless/realtek/rtw88/Kconfig
> +++ b/drivers/net/wireless/realtek/rtw88/Kconfig
> @@ -52,4 +52,14 @@ config RTW88_DEBUGFS
>  
>  	  If unsure, say Y to simplify debug problems
>  
> +config RTW88_REGD_USER_REG_HINTS
> +	bool "Realtek rtw88 user regulatory hints"
> +	depends on RTW88_CORE
> +	default n
> +	help
> +	  Enable regulatoy user hints
> +
> +	  If unsure, say N. This should only be allowed on distributions
> +	  that need this to correct the regulatory.
> +

I'm still not sure why rtw88 needs this, and nobody else does. I read
your commit message, but that doesn't sound like something that belongs
in a single driver still.

>  endif
> diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
> index 7640e97706f5..5d43bef91a3c 100644
> --- a/drivers/net/wireless/realtek/rtw88/main.c
> +++ b/drivers/net/wireless/realtek/rtw88/main.c
> @@ -1501,8 +1501,9 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
>  		return ret;
>  	}
>  
> -	if (regulatory_hint(hw->wiphy, rtwdev->regd.alpha2))
> -		rtw_err(rtwdev, "regulatory_hint fail\n");
> +	ret = regulatory_hint(hw->wiphy, rtwdev->efuse.country_code);
> +	if (ret)
> +		rtw_warn(rtwdev, "failed to hint regulatory: %d\n", ret);

I don't think this is what you want; you had it right in previous
revisions:

	if (!rtwdev->efuse.country_worldwide) {
		if (regulatory_hint(hw->wiphy, rtwdev->efuse.country_code))
			rtw_err( ... );
	}

Without the 'country_worlwide' check, you start "hinting" (even on
worldwide chips) that you really wanted "country" 00 only, and so we
*never* adapt to more strict country settings. That's not how world-wide
settings are supposed to work.

>  
>  	rtw_debugfs_init(rtwdev);
>  
> diff --git a/drivers/net/wireless/realtek/rtw88/regd.c b/drivers/net/wireless/realtek/rtw88/regd.c
> index 69744dd65968..4cc1234bfb9a 100644
> --- a/drivers/net/wireless/realtek/rtw88/regd.c
> +++ b/drivers/net/wireless/realtek/rtw88/regd.c
>  static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev,
>  				   struct wiphy *wiphy,
>  				   struct regulatory_request *request)
>  {
> -	if (request->initiator == NL80211_REGDOM_SET_BY_USER)
> +	if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)

Why are you ignoring SET_BY_DRIVER? That's what happens when (a few
lines up) you call regulatory_hint(). At a minimum, that doesn't deserve
a loud error print when we "fail" this function -- you should handle it
properly.

Brian

> +		return -ENOTSUPP;
> +
> +	if (request->initiator == NL80211_REGDOM_SET_BY_USER &&
> +	    !IS_ENABLED(CONFIG_RTW88_REGD_USER_REG_HINTS))
> +		return -EPERM;
> +
> +	if (request->initiator == NL80211_REGDOM_SET_BY_CORE) {
> +		char *country_code;
> +
> +		/* return to the efuse setting */
> +		country_code = rtwdev->efuse.country_code;
> +		rtwdev->regd = rtw_regd_find_reg_by_name(country_code);
>  		return 0;
> +	}
> +
>  	rtwdev->regd = rtw_regd_find_reg_by_name(request->alpha2);
>  	rtw_regd_apply_world_flags(wiphy, request->initiator);
>  

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset
  2020-03-24 16:51   ` Brian Norris
@ 2020-03-25  3:11     ` Andy Huang
  2020-03-26  1:45       ` Brian Norris
  0 siblings, 1 reply; 7+ messages in thread
From: Andy Huang @ 2020-03-25  3:11 UTC (permalink / raw)
  To: Brian Norris, Tony Chuang; +Cc: kvalo, linux-wireless

> 
> Hi,
> 
> On Tue, Mar 24, 2020 at 03:52:15PM +0800, yhchuang@realtek.com wrote:
> > --- a/drivers/net/wireless/realtek/rtw88/Kconfig
> > +++ b/drivers/net/wireless/realtek/rtw88/Kconfig
> > @@ -52,4 +52,14 @@ config RTW88_DEBUGFS
> >
> >  	  If unsure, say Y to simplify debug problems
> >
> > +config RTW88_REGD_USER_REG_HINTS
> > +	bool "Realtek rtw88 user regulatory hints"
> > +	depends on RTW88_CORE
> > +	default n
> > +	help
> > +	  Enable regulatoy user hints
> > +
> > +	  If unsure, say N. This should only be allowed on distributions
> > +	  that need this to correct the regulatory.
> > +
> 
> I'm still not sure why rtw88 needs this, and nobody else does. I read 

I think in Atheros driver, ATH_REG_DYNAMIC_USER_REG_HINTS config serves
the same purpose.

> your commit message, but that doesn't sound like something that belongs
> in a single driver still.
> 

As our previous commit message claims, it is due to FCC publication 594280
statement, "In particular, users must not be relied on to set a country code or
location code to ensure compliance".

> >  endif
> > diff --git a/drivers/net/wireless/realtek/rtw88/main.c
> b/drivers/net/wireless/realtek/rtw88/main.c
> > index 7640e97706f5..5d43bef91a3c 100644
> > --- a/drivers/net/wireless/realtek/rtw88/main.c
> > +++ b/drivers/net/wireless/realtek/rtw88/main.c
> > @@ -1501,8 +1501,9 @@ int rtw_register_hw(struct rtw_dev *rtwdev,
> struct ieee80211_hw *hw)
> >  		return ret;
> >  	}
> >
> > -	if (regulatory_hint(hw->wiphy, rtwdev->regd.alpha2))
> > -		rtw_err(rtwdev, "regulatory_hint fail\n");
> > +	ret = regulatory_hint(hw->wiphy, rtwdev->efuse.country_code);
> > +	if (ret)
> > +		rtw_warn(rtwdev, "failed to hint regulatory: %d\n", ret);
> 
> I don't think this is what you want; you had it right in previous
> revisions:
> 
> 	if (!rtwdev->efuse.country_worldwide) {
> 		if (regulatory_hint(hw->wiphy, rtwdev->efuse.country_code))
> 			rtw_err( ... );
> 	}
> 
> Without the 'country_worlwide' check, you start "hinting" (even on
> worldwide chips) that you really wanted "country" 00 only, and so we
> *never* adapt to more strict country settings. That's not how world-wide
> settings are supposed to work.
> 

It doesn't mean that we want country 00 only, we will get country notifies
from stack, and we will apply it if we accept it. We don't want stack to change
the channel plan for us.
And this is also related to RTW88_REGD_USER_REG_HINTS config, since we
do not want stack to change the channel plan set from user space without
this config.

> >
> >  	rtw_debugfs_init(rtwdev);
> >
> > diff --git a/drivers/net/wireless/realtek/rtw88/regd.c
> b/drivers/net/wireless/realtek/rtw88/regd.c
> > index 69744dd65968..4cc1234bfb9a 100644
> > --- a/drivers/net/wireless/realtek/rtw88/regd.c
> > +++ b/drivers/net/wireless/realtek/rtw88/regd.c
> >  static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev,
> >  				   struct wiphy *wiphy,
> >  				   struct regulatory_request *request)
> >  {
> > -	if (request->initiator == NL80211_REGDOM_SET_BY_USER)
> > +	if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
> 
> Why are you ignoring SET_BY_DRIVER? That's what happens when (a few
> lines up) you call regulatory_hint(). At a minimum, that doesn't deserve
> a loud error print when we "fail" this function -- you should handle it
> properly.
> 
> Brian

Since the notification with NL80211_REGDOM_SET_BY_DRIVER flag might
comes from an another chipset's regulatory_hint().

Tzu-En

> 
> > +		return -ENOTSUPP;
> > +
> > +	if (request->initiator == NL80211_REGDOM_SET_BY_USER &&
> > +	    !IS_ENABLED(CONFIG_RTW88_REGD_USER_REG_HINTS))
> > +		return -EPERM;
> > +
> > +	if (request->initiator == NL80211_REGDOM_SET_BY_CORE) {
> > +		char *country_code;
> > +
> > +		/* return to the efuse setting */
> > +		country_code = rtwdev->efuse.country_code;
> > +		rtwdev->regd = rtw_regd_find_reg_by_name(country_code);
> >  		return 0;
> > +	}
> > +
> >  	rtwdev->regd = rtw_regd_find_reg_by_name(request->alpha2);
> >  	rtw_regd_apply_world_flags(wiphy, request->initiator);
> >
> 
> ------Please consider the environment before printing this e-mail.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset
  2020-03-25  3:11     ` Andy Huang
@ 2020-03-26  1:45       ` Brian Norris
  2020-03-26  7:11         ` Andy Huang
  0 siblings, 1 reply; 7+ messages in thread
From: Brian Norris @ 2020-03-26  1:45 UTC (permalink / raw)
  To: Andy Huang; +Cc: Tony Chuang, kvalo, linux-wireless

[ I'll preface this by saying that the more I look at the regulatory
core, the more I realize I'm confused or wrong at times. So forgive me
if I've made errors along the way, and please do correct me. ]

On Tue, Mar 24, 2020 at 8:11 PM Andy Huang <tehuang@realtek.com> wrote:
> > On Tue, Mar 24, 2020 at 03:52:15PM +0800, yhchuang@realtek.com wrote:
> > > --- a/drivers/net/wireless/realtek/rtw88/Kconfig
> > > +++ b/drivers/net/wireless/realtek/rtw88/Kconfig

> > I'm still not sure why rtw88 needs this, and nobody else does. I read
>
> I think in Atheros driver, ATH_REG_DYNAMIC_USER_REG_HINTS config serves
> the same purpose.

Ah, I forgot about that one, sorry.

> > your commit message, but that doesn't sound like something that belongs
> > in a single driver still.
> >
>
> As our previous commit message claims, it is due to FCC [...]

Yes, I saw that: my point was that effectively all drivers are subject
to this FCC rule, and so this could be a common CONFIG_*. But if we
already have the ATH_* one (I missed that, above), I guess we can have
an rtw88 one too. It might be less confusing (and more
straightforwardly-implemented) if we moved this stuff to the core
someday, though.

> > > +   ret = regulatory_hint(hw->wiphy, rtwdev->efuse.country_code);
> > > +   if (ret)
> > > +           rtw_warn(rtwdev, "failed to hint regulatory: %d\n", ret);
> >
> > I don't think this is what you want; you had it right in previous
> > revisions:
> >
> >       if (!rtwdev->efuse.country_worldwide) {
> >               if (regulatory_hint(hw->wiphy, rtwdev->efuse.country_code))
> >                       rtw_err( ... );
> >       }
> >
> > Without the 'country_worlwide' check, you start "hinting" (even on
> > worldwide chips) that you really wanted "country" 00 only, and so we
> > *never* adapt to more strict country settings. That's not how world-wide
> > settings are supposed to work.
>
> It doesn't mean that we want country 00 only, we will get country notifies
> from stack, and we will apply it if we accept it. We don't want stack to change
> the channel plan for us.

I noted this to you privately, but I don't believe it's expected to
call regulatory_hint() with "00". See the kerneldoc:

 * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
 *      should be in. If @rd is set this should be NULL. Note that if you
 *      set this to NULL you should still set rd->alpha2 to some accepted
 *      alpha2.

Note that "00" is *not* actually an ISO 3166 alpha2 code.

The key problem I'm seeing: once you do this, you establish a
wiphy-specific regd, and this regd never updates its country code or
DFS region according to IE updates. So attributes like
NL80211_ATTR_DFS_REGION and NL80211_ATTR_REG_ALPHA2 remain unset.

Your previous revision -- which for WW settings used
wiphy_apply_custom_regulatory() and *not* regulatory_hint() -- did not
have that problem.

> > Why are you ignoring SET_BY_DRIVER?
>
> Since the notification with NL80211_REGDOM_SET_BY_DRIVER flag might
> comes from an another chipset's regulatory_hint().

Ack.

Brian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset
  2020-03-26  1:45       ` Brian Norris
@ 2020-03-26  7:11         ` Andy Huang
  0 siblings, 0 replies; 7+ messages in thread
From: Andy Huang @ 2020-03-26  7:11 UTC (permalink / raw)
  To: Brian Norris; +Cc: Tony Chuang, kvalo, linux-wireless



> [ I'll preface this by saying that the more I look at the regulatory
> core, the more I realize I'm confused or wrong at times. So forgive me
> if I've made errors along the way, and please do correct me. ]
> 
> On Tue, Mar 24, 2020 at 8:11 PM Andy Huang <tehuang@realtek.com> wrote:
> > > On Tue, Mar 24, 2020 at 03:52:15PM +0800, yhchuang@realtek.com
> wrote:
> > > > --- a/drivers/net/wireless/realtek/rtw88/Kconfig
> > > > +++ b/drivers/net/wireless/realtek/rtw88/Kconfig
> 
> > > I'm still not sure why rtw88 needs this, and nobody else does. I read
> >
> > I think in Atheros driver, ATH_REG_DYNAMIC_USER_REG_HINTS config
> serves
> > the same purpose.
> 
> Ah, I forgot about that one, sorry.
> 
> > > your commit message, but that doesn't sound like something that belongs
> > > in a single driver still.
> > >
> >
> > As our previous commit message claims, it is due to FCC [...]
> 
> Yes, I saw that: my point was that effectively all drivers are subject
> to this FCC rule, and so this could be a common CONFIG_*. But if we
> already have the ATH_* one (I missed that, above), I guess we can have
> an rtw88 one too. It might be less confusing (and more
> straightforwardly-implemented) if we moved this stuff to the core
> someday, though.
> 
> > > > +   ret = regulatory_hint(hw->wiphy, rtwdev->efuse.country_code);
> > > > +   if (ret)
> > > > +           rtw_warn(rtwdev, "failed to hint regulatory: %d\n", ret);
> > >
> > > I don't think this is what you want; you had it right in previous
> > > revisions:
> > >
> > >       if (!rtwdev->efuse.country_worldwide) {
> > >               if (regulatory_hint(hw->wiphy,
> rtwdev->efuse.country_code))
> > >                       rtw_err( ... );
> > >       }
> > >
> > > Without the 'country_worlwide' check, you start "hinting" (even on
> > > worldwide chips) that you really wanted "country" 00 only, and so we
> > > *never* adapt to more strict country settings. That's not how world-wide
> > > settings are supposed to work.
> >
> > It doesn't mean that we want country 00 only, we will get country notifies
> > from stack, and we will apply it if we accept it. We don't want stack to
> change
> > the channel plan for us.
> 
> I noted this to you privately, but I don't believe it's expected to
> call regulatory_hint() with "00". See the kerneldoc:
> 
>  * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
>  *      should be in. If @rd is set this should be NULL. Note that if you
>  *      set this to NULL you should still set rd->alpha2 to some accepted
>  *      alpha2.
> 
> Note that "00" is *not* actually an ISO 3166 alpha2 code.
> 
Yes, I think you make sense, we will provide v7, which will be similar to v5 with
more detailed explain in commit log.

Tzu-En

> The key problem I'm seeing: once you do this, you establish a
> wiphy-specific regd, and this regd never updates its country code or
> DFS region according to IE updates. So attributes like
> NL80211_ATTR_DFS_REGION and NL80211_ATTR_REG_ALPHA2 remain unset.
> 
> Your previous revision -- which for WW settings used
> wiphy_apply_custom_regulatory() and *not* regulatory_hint() -- did not
> have that problem.
> 
> > > Why are you ignoring SET_BY_DRIVER?
> >
> > Since the notification with NL80211_REGDOM_SET_BY_DRIVER flag might
> > comes from an another chipset's regulatory_hint().
> 
> Ack.
> 
> Brian
> 
> ------Please consider the environment before printing this e-mail.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-03-26  7:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-24  7:52 [PATCH v6 0/2] rtw88: update regulatory settings yhchuang
2020-03-24  7:52 ` [PATCH v6 1/2] rtw88: add regulatory process strategy for different chipset yhchuang
2020-03-24 16:51   ` Brian Norris
2020-03-25  3:11     ` Andy Huang
2020-03-26  1:45       ` Brian Norris
2020-03-26  7:11         ` Andy Huang
2020-03-24  7:52 ` [PATCH v6 2/2] rtw88: add adaptivity support for EU/JP regulatory yhchuang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.