Skip to contentSkip to conversation

mt7615: add Smart Carrier Sense support

PATCH New Lorenzo Bianconi 1 participant 3 messages Jul 28, 2019

Subsystems (2)
lore
Share & tools
lore

Lorenzo Bianconi

author maintainer
#0 lore raw

cover mt7615: add Smart Carrier Sense support

Add Smart Carrier Sense (SCS) algorithm in order to tune device sensitivity to track long-range clients and cut-off possible interferences using RTS error rate and False CCA reported by the radio

Lorenzo Bianconi (2):
mt76: mt7615: rework locking scheme for mt7615_set_channel
mt76: mt7615: add Smart Carrier Sense support

 drivers/net/wireless/mediatek/mt76/mt76.h     |   9 +-
 .../wireless/mediatek/mt76/mt7615/debugfs.c   |  39 ++++
 .../net/wireless/mediatek/mt76/mt7615/init.c  |   1 +
 .../net/wireless/mediatek/mt76/mt7615/mac.c   | 176 ++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7615/main.c  |  15 +-
 .../wireless/mediatek/mt76/mt7615/mt7615.h    |  14 ++
 .../net/wireless/mediatek/mt76/mt7615/regs.h  |  36 ++++
 7 files changed, 281 insertions(+), 9 deletions(-)
Signature · 1 line
2.21.0
author maintainer
#1 lore raw

PATCH 1/2 mt76: mt7615: rework locking scheme for mt7615_set_channel

As already done for mt7603 driver, move mt76.mutex lock inside mt7615_set_channel since we need to grab mt76.mutex in mt7615_mac_work. This is a preliminary patch to add Smart Carrier Sense (SCS) support

---
 drivers/net/wireless/mediatek/mt76/mt7615/main.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/main.c +8 -6
index 900253e85db9..9138153f4686 100644
@@ -135,6 +135,8 @@ static int mt7615_set_channel(struct mt7615_dev *dev)
 	int ret;
 
 	cancel_delayed_work_sync(&dev->mt76.mac_work);
+
+	mutex_lock(&dev->mt76.mutex);
 	set_bit(MT76_RESET, &dev->mt76.state);
 
 	mt7615_dfs_check_channel(dev);
@@ -143,18 +145,18 @@ static int mt7615_set_channel(struct mt7615_dev *dev)
 
 	ret = mt7615_mcu_set_channel(dev);
 	if (ret)
-		return ret;
+		goto out;
 
 	ret = mt7615_dfs_init_radar_detector(dev);
-	if (ret < 0)
-		return ret;
 
+out:
 	clear_bit(MT76_RESET, &dev->mt76.state);
+	mutex_unlock(&dev->mt76.mutex);
 
 	mt76_txq_schedule_all(&dev->mt76);
 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
 				     MT7615_WATCHDOG_TIME);
-	return 0;
+	return ret;
 }
 
 static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -213,14 +215,14 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
 	struct mt7615_dev *dev = hw->priv;
 	int ret = 0;
 
-	mutex_lock(&dev->mt76.mutex);
-
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 		ieee80211_stop_queues(hw);
 		ret = mt7615_set_channel(dev);
 		ieee80211_wake_queues(hw);
 	}
 
+	mutex_lock(&dev->mt76.mutex);
+
 	if (changed & IEEE80211_CONF_CHANGE_POWER)
 		ret = mt7615_mcu_set_tx_power(dev);
 
Signature · 1 line
2.21.0
author maintainer
#2 lore raw

PATCH 2/2 mt76: mt7615: add Smart Carrier Sense support

In reply to Lorenzo Bianconi

Introduce Smart Carrier Sense support in order to tune device sensitivity according to RTS error rate and False CCA reported by the radio

---
This patch relies on 'mt76: mt7615: fix MT7615_WATCHDOG_TIME definition'
https://patchwork.kernel.org/patch/11049597/

---
 drivers/net/wireless/mediatek/mt76/mt76.h     |   9 +-
 .../wireless/mediatek/mt76/mt7615/debugfs.c   |  39 ++++
 .../net/wireless/mediatek/mt76/mt7615/init.c  |   1 +
 .../net/wireless/mediatek/mt76/mt7615/mac.c   | 176 ++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7615/main.c  |   1 +
 .../wireless/mediatek/mt76/mt7615/mt7615.h    |  14 ++
 .../net/wireless/mediatek/mt76/mt7615/regs.h  |  36 ++++
 7 files changed, 273 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +6 -3
index 80664e8234bd..20f83e5b9337 100644
@@ -27,9 +27,12 @@
 #include <net/mac80211.h>
 #include "util.h"
 
-#define MT_TX_RING_SIZE     256
-#define MT_MCU_RING_SIZE    32
-#define MT_RX_BUF_SIZE      2048
+#define MT_TX_RING_SIZE		256
+#define MT_MCU_RING_SIZE	32
+#define MT_RX_BUF_SIZE		2048
+
+#define MT_FRAC_SCALE		12
+#define MT_FRAC(val, div)	(((val) << MT_FRAC_SCALE) / (div))
 
 struct mt76_dev;
 struct mt76_wcid;
drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c +39 -0
index ed605fcc99f9..4dbaf5047b37 100644
@@ -13,6 +13,42 @@ mt7615_radar_pattern_set(void *data, u64 val)
 DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
 			 mt7615_radar_pattern_set, "%lld\n");
 
+static int
+mt7615_scs_set(void *data, u64 val)
+{
+	struct mt7615_dev *dev = data;
+
+	mt7615_mac_set_scs(dev, val);
+
+	return 0;
+}
+
+static int
+mt7615_scs_get(void *data, u64 *val)
+{
+	struct mt7615_dev *dev = data;
+
+	*val = dev->scs_en;
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_scs, mt7615_scs_get,
+			 mt7615_scs_set, "%lld\n");
+
+static int
+mt7615_radio_read(struct seq_file *s, void *data)
+{
+	struct mt7615_dev *dev = dev_get_drvdata(s->private);
+
+	seq_printf(s, "Sensitivity: ofdm=%d cck=%d\n",
+		   dev->ofdm_sensitivity, dev->cck_sensitivity);
+	seq_printf(s, "False CCA: ofdm=%d cck=%d\n",
+		   dev->false_cca_ofdm, dev->false_cca_cck);
+
+	return 0;
+}
+
 int mt7615_init_debugfs(struct mt7615_dev *dev)
 {
 	struct dentry *dir;
@@ -21,6 +57,9 @@ int mt7615_init_debugfs(struct mt7615_dev *dev)
 	if (!dir)
 		return -ENOMEM;
 
+	debugfs_create_file("scs", 0600, dir, dev, &fops_scs);
+	debugfs_create_devm_seqfile(dev->mt76.dev, "radio", dir,
+				    mt7615_radio_read);
 	debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
 	/* test pattern knobs */
 	debugfs_create_u8("pattern_len", 0600, dir,
drivers/net/wireless/mediatek/mt76/mt7615/init.c +1 -0
index be144e13fe4c..1104e4c8aaa6 100644
@@ -50,6 +50,7 @@ static void mt7615_mac_init(struct mt7615_dev *dev)
 		 MT_TMAC_CTCR0_INS_DDLMT_EN);
 
 	mt7615_mcu_set_rts_thresh(dev, 0x92b);
+	mt7615_mac_set_scs(dev, false);
 
 	mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS,
 		 MT_AGG_SCR_NLNAV_MID_PTEC_DIS);
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +176 -0

188 lines not on this page · raw message

drivers/net/wireless/mediatek/mt76/mt7615/main.c +1 -0
index 9138153f4686..6b881e862595 100644
@@ -148,6 +148,7 @@ static int mt7615_set_channel(struct mt7615_dev *dev)
 		goto out;
 
 	ret = mt7615_dfs_init_radar_detector(dev);
+	mt7615_mac_cca_stats_reset(dev);
 
 out:
 	clear_bit(MT76_RESET, &dev->mt76.state);
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +14 -0
index a014f7b17825..c83d1d212ac9 100644
@@ -86,6 +86,13 @@ struct mt7615_dev {
 	u32 hw_pattern;
 	int dfs_state;
 
+	int false_cca_ofdm, false_cca_cck;
+	unsigned long last_cca_adj;
+	u8 mac_work_count;
+	s8 ofdm_sensitivity;
+	s8 cck_sensitivity;
+	bool scs_en;
+
 	spinlock_t token_lock;
 	struct idr token;
 };
@@ -191,6 +198,11 @@ int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev);
 int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev);
 int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev);
 
+static inline bool is_mt7622(struct mt76_dev *dev)
+{
+	return mt76_chip(dev) == 0x7622;
+}
+
 static inline void mt7615_dfs_check_channel(struct mt7615_dev *dev)
 {
 	enum nl80211_chan_width width = dev->mt76.chandef.width;
@@ -212,6 +224,8 @@ static inline void mt7615_irq_disable(struct mt7615_dev *dev, u32 mask)
 	mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
 }
 
+void mt7615_mac_cca_stats_reset(struct mt7615_dev *dev);
+void mt7615_mac_set_scs(struct mt7615_dev *dev, bool enable);
 int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
 			  struct sk_buff *skb, struct mt76_wcid *wcid,
 			  struct ieee80211_sta *sta, int pid,
drivers/net/wireless/mediatek/mt76/mt7615/regs.h +36 -0
index 1dcd202746ef..12fc12edf78c 100644
@@ -71,6 +71,34 @@
 #define MT_WF_PHY_WF2_RFCTRL0		MT_WF_PHY(0x1900)
 #define MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN	BIT(9)
 
+#define MT_WF_PHY_R0_B0_PHYMUX_5	MT_WF_PHY(0x0614)
+
+#define MT_WF_PHY_R0_B0_PHYCTRL_STS0	MT_WF_PHY(0x020c)
+#define MT_WF_PHYCTRL_STAT_PD_OFDM	GENMASK(31, 16)
+#define MT_WF_PHYCTRL_STAT_PD_CCK	GENMASK(15, 0)
+
+#define MT_WF_PHY_R0_B0_PHYCTRL_STS5	MT_WF_PHY(0x0220)
+#define MT_WF_PHYCTRL_STAT_MDRDY_OFDM	GENMASK(31, 16)
+#define MT_WF_PHYCTRL_STAT_MDRDY_CCK	GENMASK(15, 0)
+
+#define MT_WF_PHY_B0_MIN_PRI_PWR	MT_WF_PHY(0x229c)
+#define MT_WF_PHY_B0_PD_OFDM_MASK	GENMASK(28, 20)
+#define MT_WF_PHY_B0_PD_OFDM(v)		((v) << 20)
+#define MT_WF_PHY_B0_PD_BLK		BIT(19)
+
+#define MT_WF_PHY_B1_MIN_PRI_PWR	MT_WF_PHY(0x084)
+#define MT_WF_PHY_B1_PD_OFDM_MASK	GENMASK(24, 16)
+#define MT_WF_PHY_B1_PD_OFDM(v)		((v) << 16)
+#define MT_WF_PHY_B1_PD_BLK		BIT(25)
+
+#define MT_WF_PHY_B0_RXTD_CCK_PD	MT_WF_PHY(0x2310)
+#define MT_WF_PHY_B0_PD_CCK_MASK	GENMASK(8, 1)
+#define MT_WF_PHY_B0_PD_CCK(v)		((v) << 1)
+
+#define MT_WF_PHY_B1_RXTD_CCK_PD	MT_WF_PHY(0x2314)
+#define MT_WF_PHY_B1_PD_CCK_MASK	GENMASK(31, 24)
+#define MT_WF_PHY_B1_PD_CCK(v)		((v) << 24)
+
 #define MT_WF_CFG_BASE			0x20200
 #define MT_WF_CFG(ofs)			(MT_WF_CFG_BASE + (ofs))
 
@@ -219,6 +247,14 @@
 #define MT_LPON_UTTR0			MT_LPON(0x018)
 #define MT_LPON_UTTR1			MT_LPON(0x01c)
 
+#define MT_WF_MIB_BASE			0x24800
+#define MT_WF_MIB(ofs)			(MT_WF_MIB_BASE + (ofs))
+
+#define MT_MIB_M0_MISC_CR		MT_WF_MIB(0x00c)
+#define MT_MIB_MB_SDR0(n)		MT_WF_MIB(0x100 + ((n) << 4))
+#define MT_MIB_RTS_RETRIES_COUNT_MASK	GENMASK(31, 16)
+#define MT_MIB_RTS_COUNT_MASK		GENMASK(15, 0)
+
 #define MT_EFUSE_BASE			0x81070000
 #define MT_EFUSE_BASE_CTRL		0x000
 #define MT_EFUSE_BASE_CTRL_EMPTY	BIT(30)
Signature · 1 line
2.21.0