Commit 5dabdf71 authored by Felix Fietkau's avatar Felix Fietkau
Browse files

mt76: mt7615: add multiple wiphy support to the dfs support code



There are two DFS detectors on the chip. When using 160 MHz channel bandwidth
(not supported in dual-wiphy mode), both are used. Otherwise, one detector is
used per wiphy.
Rework the code to start/stop them separately per phy and to indicate the
radar event on the right phy based on the detector index

Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent d23cb96c
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -248,6 +248,7 @@ mt7615_regd_notifier(struct wiphy *wiphy,
	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
	struct mt7615_dev *dev = mt7615_hw_dev(hw);
	struct mt76_phy *mphy = hw->priv;
	struct mt7615_phy *phy = mphy->priv;
	struct cfg80211_chan_def *chandef = &mphy->chandef;

	dev->mt76.region = request->dfs_region;
@@ -255,11 +256,7 @@ mt7615_regd_notifier(struct wiphy *wiphy,
	if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR))
		return;

	mt7615_dfs_stop_radar_detector(dev);
	if (request->dfs_region == NL80211_DFS_UNSET)
		mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, 0, MT_RX_SEL0, 0);
	else
		mt7615_dfs_start_radar_detector(dev);
	mt7615_dfs_init_radar_detector(phy);
}

int mt7615_register_device(struct mt7615_dev *dev)
@@ -303,7 +300,7 @@ int mt7615_register_device(struct mt7615_dev *dev)
			IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
			IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
	dev->dfs_state = -1;
	dev->phy.dfs_state = -1;

	ret = mt76_register_device(&dev->mt76, true, mt7615_rates,
				   ARRAY_SIZE(mt7615_rates));
+36 −27
Original line number Diff line number Diff line
@@ -1497,19 +1497,14 @@ void mt7615_mac_work(struct work_struct *work)
				     MT7615_WATCHDOG_TIME);
}

int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev)
static void mt7615_dfs_stop_radar_detector(struct mt7615_phy *phy)
{
	struct cfg80211_chan_def *chandef = &dev->mphy.chandef;
	int err;

	err = mt7615_mcu_rdd_cmd(dev, RDD_STOP, 0, MT_RX_SEL0, 0);
	if (err < 0)
		return err;
	struct mt7615_dev *dev = phy->dev;

	if (chandef->width == NL80211_CHAN_WIDTH_160 ||
	    chandef->width == NL80211_CHAN_WIDTH_80P80)
		err = mt7615_mcu_rdd_cmd(dev, RDD_STOP, 1, MT_RX_SEL0, 0);
	return err;
	if (phy->rdd_state & BIT(0))
		mt7615_mcu_rdd_cmd(dev, RDD_STOP, 0, MT_RX_SEL0, 0);
	if (phy->rdd_state & BIT(1))
		mt7615_mcu_rdd_cmd(dev, RDD_STOP, 1, MT_RX_SEL0, 0);
}

static int mt7615_dfs_start_rdd(struct mt7615_dev *dev, int chain)
@@ -1524,58 +1519,72 @@ static int mt7615_dfs_start_rdd(struct mt7615_dev *dev, int chain)
				  MT_RX_SEL0, 1);
}

int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev)
static int mt7615_dfs_start_radar_detector(struct mt7615_phy *phy)
{
	struct cfg80211_chan_def *chandef = &dev->mphy.chandef;
	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
	struct mt7615_dev *dev = phy->dev;
	bool ext_phy = phy != &dev->phy;
	int err;

	/* start CAC */
	err = mt7615_mcu_rdd_cmd(dev, RDD_CAC_START, 0, MT_RX_SEL0, 0);
	err = mt7615_mcu_rdd_cmd(dev, RDD_CAC_START, ext_phy, MT_RX_SEL0, 0);
	if (err < 0)
		return err;

	/* TODO: DBDC support */

	err = mt7615_dfs_start_rdd(dev, 0);
	err = mt7615_dfs_start_rdd(dev, ext_phy);
	if (err < 0)
		return err;

	phy->rdd_state |= BIT(ext_phy);

	if (chandef->width == NL80211_CHAN_WIDTH_160 ||
	    chandef->width == NL80211_CHAN_WIDTH_80P80) {
		err = mt7615_dfs_start_rdd(dev, 1);
		if (err < 0)
			return err;

		phy->rdd_state |= BIT(1);
	}

	return 0;
}

int mt7615_dfs_init_radar_detector(struct mt7615_dev *dev)
int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy)
{
	struct cfg80211_chan_def *chandef = &dev->mphy.chandef;
	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
	struct mt7615_dev *dev = phy->dev;
	bool ext_phy = phy != &dev->phy;
	int err;

	if (dev->mt76.region == NL80211_DFS_UNSET)
	if (dev->mt76.region == NL80211_DFS_UNSET) {
		phy->dfs_state = -1;
		if (phy->rdd_state)
			goto stop;

		return 0;
	}

	if (test_bit(MT76_SCANNING, &dev->mphy.state))
	if (test_bit(MT76_SCANNING, &phy->mt76->state))
		return 0;

	if (dev->dfs_state == chandef->chan->dfs_state)
	if (phy->dfs_state == chandef->chan->dfs_state)
		return 0;

	dev->dfs_state = chandef->chan->dfs_state;
	phy->dfs_state = chandef->chan->dfs_state;

	if (chandef->chan->flags & IEEE80211_CHAN_RADAR) {
		if (chandef->chan->dfs_state != NL80211_DFS_AVAILABLE)
			return mt7615_dfs_start_radar_detector(dev);
			return mt7615_dfs_start_radar_detector(phy);

		return mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, 0, MT_RX_SEL0, 0);
		return mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, ext_phy,
					  MT_RX_SEL0, 0);
	}

	err = mt7615_mcu_rdd_cmd(dev, RDD_NORMAL_START, 0, MT_RX_SEL0, 0);
stop:
	err = mt7615_mcu_rdd_cmd(dev, RDD_NORMAL_START, ext_phy, MT_RX_SEL0, 0);
	if (err < 0)
		return err;

	return mt7615_dfs_stop_radar_detector(dev);
	mt7615_dfs_stop_radar_detector(phy);
	return 0;
}
+2 −3
Original line number Diff line number Diff line
@@ -185,15 +185,14 @@ static int mt7615_set_channel(struct mt7615_phy *phy)
	mutex_lock(&dev->mt76.mutex);
	set_bit(MT76_RESET, &phy->mt76->state);

	mt7615_dfs_check_channel(dev);

	phy->dfs_state = -1;
	mt76_set_channel(phy->mt76);

	ret = mt7615_mcu_set_channel(phy);
	if (ret)
		goto out;

	ret = mt7615_dfs_init_radar_detector(dev);
	ret = mt7615_dfs_init_radar_detector(phy);
	mt7615_mac_cca_stats_reset(phy);

	mt7615_mac_reset_counters(dev);
+16 −2
Original line number Diff line number Diff line
@@ -185,6 +185,21 @@ mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
		ieee80211_csa_finish(vif);
}

static void
mt7615_mcu_rx_radar_detected(struct mt7615_dev *dev, struct sk_buff *skb)
{
	struct mt76_phy *mphy = &dev->mt76.phy;
	struct mt7615_mcu_rdd_report *r;

	r = (struct mt7615_mcu_rdd_report *)skb->data;

	if (r->idx && dev->mt76.phy2)
		mphy = dev->mt76.phy2;

	ieee80211_radar_detected(mphy->hw);
	dev->hw_pattern++;
}

static void
mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)
{
@@ -192,8 +207,7 @@ mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)

	switch (rxd->ext_eid) {
	case MCU_EXT_EVENT_RDD_REPORT:
		ieee80211_radar_detected(dev->mt76.hw);
		dev->hw_pattern++;
		mt7615_mcu_rx_radar_detected(dev, skb);
		break;
	case MCU_EXT_EVENT_CSA_NOTIFY:
		ieee80211_iterate_active_interfaces_atomic(dev->mt76.hw,
+46 −0
Original line number Diff line number Diff line
@@ -60,6 +60,52 @@ struct mt7615_mcu_rxd {
	u8 s2d_index;
};

struct mt7615_mcu_rdd_report {
	struct mt7615_mcu_rxd rxd;

	u8 idx;
	u8 long_detected;
	u8 constant_prf_detected;
	u8 staggered_prf_detected;
	u8 radar_type_idx;
	u8 periodic_pulse_num;
	u8 long_pulse_num;
	u8 hw_pulse_num;

	u8 out_lpn;
	u8 out_spn;
	u8 out_crpn;
	u8 out_crpw;
	u8 out_crbn;
	u8 out_stgpn;
	u8 out_stgpw;

	u8 _rsv[2];

	__le32 out_pri_const;
	__le32 out_pri_stg[3];

	struct {
		__le32 start;
		__le16 pulse_width;
		__le16 pulse_power;
	} long_pulse[32];

	struct {
		__le32 start;
		__le16 pulse_width;
		__le16 pulse_power;
	} periodic_pulse[32];

	struct {
		__le32 start;
		__le16 pulse_width;
		__le16 pulse_power;
		u8 sc_pass;
		u8 sw_reset;
	} hw_pulse[32];
};

#define MCU_PQ_ID(p, q)		(((p) << 15) | ((q) << 10))
#define MCU_PKT_ID		0xa0

Loading