Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 801ccc8a authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

mt76x0: pci: add DFS support



Introduce dfs support in mt76x0e driver and unlock radar channels

Signed-off-by: default avatarLorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent e6cb3291
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -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);
	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);

	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;
+4 −0
Original line number Diff line number Diff line
@@ -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
+29 −2
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+5 −0
Original line number Diff line number Diff line
@@ -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);
Loading