Search Linux Wireless

[PATCH 2/2] mt76x0: pci: add DFS support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Introduce dfs support in mt76x0e driver and unlock radar channels

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@xxxxxxxxxx>
---
 .../net/wireless/mediatek/mt76/mt76x0/main.c  | 11 +++++--
 .../net/wireless/mediatek/mt76/mt76x0/phy.c   |  4 +++
 .../net/wireless/mediatek/mt76/mt76x02_dfs.c  | 31 +++++++++++++++++--
 .../net/wireless/mediatek/mt76/mt76x02_dfs.h  |  1 +
 .../net/wireless/mediatek/mt76/mt76x02_util.c |  5 +++
 .../wireless/mediatek/mt76/mt76x2/pci_init.c  |  7 -----
 .../net/wireless/mediatek/mt76/mt76x2/phy.c   | 23 +-------------
 7 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
index cd1a1225ad8b..a803a9b6a4c5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
@@ -22,7 +22,10 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
 	int ret;
 
 	cancel_delayed_work_sync(&dev->cal_work);
-	tasklet_disable(&dev->pre_tbtt_tasklet);
+	if (mt76_is_mmio(dev)) {
+		tasklet_disable(&dev->pre_tbtt_tasklet);
+		tasklet_disable(&dev->dfs_pd.dfs_tasklet);
+	}
 
 	mt76_set_channel(&dev->mt76);
 	ret = mt76x0_phy_set_channel(dev, chandef);
@@ -31,7 +34,11 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
 	mt76_rr(dev, MT_CH_IDLE);
 	mt76_rr(dev, MT_CH_BUSY);
 
-	tasklet_enable(&dev->pre_tbtt_tasklet);
+	if (mt76_is_mmio(dev)) {
+		mt76x02_dfs_init_params(dev);
+		tasklet_enable(&dev->pre_tbtt_tasklet);
+		tasklet_enable(&dev->dfs_pd.dfs_tasklet);
+	}
 	mt76_txq_schedule_all(&dev->mt76);
 
 	return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
index b33074b783dc..c734987a344c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
@@ -719,6 +719,10 @@ static void mt76x0_phy_set_gain_val(struct mt76x02_dev *dev)
 
 	mt76_wr(dev, MT_BBP(AGC, 8),
 		val | FIELD_PREP(MT_BBP_AGC_GAIN, gain));
+
+	if ((dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR) &&
+	    !is_mt7630(dev))
+		mt76x02_phy_dfs_adjust_agc(dev);
 }
 
 static void
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
index 21e7b8c9f824..527e530d480a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
@@ -802,6 +802,35 @@ static void mt76x02_dfs_set_bbp_params(struct mt76x02_dev *dev)
 	mt76_wr(dev, 0x212c, 0x0c350001);
 }
 
+void mt76x02_phy_dfs_adjust_agc(struct mt76x02_dev *dev)
+{
+	u32 agc_r8, agc_r4, val_r8, val_r4, dfs_r31;
+
+	agc_r8 = mt76_rr(dev, MT_BBP(AGC, 8));
+	agc_r4 = mt76_rr(dev, MT_BBP(AGC, 4));
+
+	val_r8 = (agc_r8 & 0x00007e00) >> 9;
+	val_r4 = agc_r4 & ~0x1f000000;
+	val_r4 += (((val_r8 + 1) >> 1) << 24);
+	mt76_wr(dev, MT_BBP(AGC, 4), val_r4);
+
+	dfs_r31 = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, val_r4);
+	dfs_r31 += val_r8;
+	dfs_r31 -= (agc_r8 & 0x00000038) >> 3;
+	dfs_r31 = (dfs_r31 << 16) | 0x00000307;
+	mt76_wr(dev, MT_BBP(DFS, 31), dfs_r31);
+
+	if (is_mt76x2(dev)) {
+		mt76_wr(dev, MT_BBP(DFS, 32), 0x00040071);
+	} else {
+		/* disable hw detector */
+		mt76_wr(dev, MT_BBP(DFS, 0), 0);
+		/* enable hw detector */
+		mt76_wr(dev, MT_BBP(DFS, 0), MT_DFS_CH_EN << 16);
+	}
+}
+EXPORT_SYMBOL_GPL(mt76x02_phy_dfs_adjust_agc);
+
 void mt76x02_dfs_init_params(struct mt76x02_dev *dev)
 {
 	struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
@@ -841,7 +870,6 @@ void mt76x02_dfs_init_detector(struct mt76x02_dev *dev)
 	tasklet_init(&dfs_pd->dfs_tasklet, mt76x02_dfs_tasklet,
 		     (unsigned long)dev);
 }
-EXPORT_SYMBOL_GPL(mt76x02_dfs_init_detector);
 
 static void
 mt76x02_dfs_set_domain(struct mt76x02_dev *dev,
@@ -865,4 +893,3 @@ void mt76x02_regd_notifier(struct wiphy *wiphy,
 
 	mt76x02_dfs_set_domain(dev, request->dfs_region);
 }
-EXPORT_SYMBOL_GPL(mt76x02_regd_notifier);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h
index 59e1524ff98b..70b394e17340 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h
@@ -141,4 +141,5 @@ void mt76x02_dfs_init_params(struct mt76x02_dev *dev);
 void mt76x02_dfs_init_detector(struct mt76x02_dev *dev);
 void mt76x02_regd_notifier(struct wiphy *wiphy,
 			   struct regulatory_request *request);
+void mt76x02_phy_dfs_adjust_agc(struct mt76x02_dev *dev);
 #endif /* __MT76x02_DFS_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 4c3b8392b2b7..9f083008dbd4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -93,6 +93,9 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
 					 MT_DMA_HDR_LEN;
 		wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 	} else {
+		mt76x02_dfs_init_detector(dev);
+
+		wiphy->reg_notifier = mt76x02_regd_notifier;
 		wiphy->iface_combinations = mt76x02_if_comb;
 		wiphy->n_iface_combinations = ARRAY_SIZE(mt76x02_if_comb);
 		wiphy->interface_modes =
@@ -635,6 +638,8 @@ void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
 	/* Fire a pre-TBTT interrupt 8 ms before TBTT */
 	mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT,
 		       8 << 4);
+	mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER,
+		       MT_DFS_GP_INTERVAL);
 	mt76_wr(dev, MT_INT_TIMER_EN, 0);
 
 	mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index b6144e03047f..f6e8af6432c1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -122,9 +122,6 @@ static int mt76x2_mac_reset(struct mt76x02_dev *dev, bool hard)
 	mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(macaddr));
 	mt76_wr(dev, MT_MAC_ADDR_DW1, get_unaligned_le16(macaddr + 4));
 
-	mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER,
-		       MT_DFS_GP_INTERVAL);
-
 	mt76x02_init_beacon_config(dev);
 	if (!hard)
 		return 0;
@@ -414,12 +411,8 @@ int mt76x2_register_device(struct mt76x02_dev *dev)
 	wiphy->addresses = dev->macaddr_list;
 	wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);
 
-	wiphy->reg_notifier = mt76x02_regd_notifier;
-
 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
 
-	mt76x02_dfs_init_detector(dev);
-
 	/* init led callbacks */
 	dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness;
 	dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c
index 0f9f54569147..bbeff9c19997 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c
@@ -251,27 +251,6 @@ void mt76x2_phy_tssi_compensate(struct mt76x02_dev *dev, bool wait)
 }
 EXPORT_SYMBOL_GPL(mt76x2_phy_tssi_compensate);
 
-static void mt76x2_phy_dfs_adjust_agc(struct mt76x02_dev *dev)
-{
-	u32 agc_r8, agc_r4, val_r8, val_r4, dfs_r31;
-
-	agc_r8 = mt76_rr(dev, MT_BBP(AGC, 8));
-	agc_r4 = mt76_rr(dev, MT_BBP(AGC, 4));
-
-	val_r8 = (agc_r8 & 0x00007e00) >> 9;
-	val_r4 = agc_r4 & ~0x1f000000;
-	val_r4 += (((val_r8 + 1) >> 1) << 24);
-	mt76_wr(dev, MT_BBP(AGC, 4), val_r4);
-
-	dfs_r31 = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, val_r4);
-	dfs_r31 += val_r8;
-	dfs_r31 -= (agc_r8 & 0x00000038) >> 3;
-	dfs_r31 = (dfs_r31 << 16) | 0x00000307;
-	mt76_wr(dev, MT_BBP(DFS, 31), dfs_r31);
-
-	mt76_wr(dev, MT_BBP(DFS, 32), 0x00040071);
-}
-
 static void
 mt76x2_phy_set_gain_val(struct mt76x02_dev *dev)
 {
@@ -294,7 +273,7 @@ mt76x2_phy_set_gain_val(struct mt76x02_dev *dev)
 		val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[1]));
 
 	if (dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR)
-		mt76x2_phy_dfs_adjust_agc(dev);
+		mt76x02_phy_dfs_adjust_agc(dev);
 }
 
 void mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev)
-- 
2.19.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux