Commit 39cdf080 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

mt76: mt7915: introduce mt7915_set_radar_background routine



Introduce mt7915_mcu_rdd_background_enable and
mt7915_mcu_background_chain_ctrl routines to configure rx dfs dedicated chain.
This is a preliminary patch to add zero-wait dfs support performing CAC
detection on rdd2.

Tested-by: default avatarOwen Peng <owen.peng@mediatek.com>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent d3bc1113
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -977,6 +977,7 @@ enum {
	MCU_EXT_CMD_SCS_CTRL = 0x82,
	MCU_EXT_CMD_TWT_AGRT_UPDATE = 0x94,
	MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
	MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
	MCU_EXT_CMD_SET_RDD_TH = 0x9d,
	MCU_EXT_CMD_MURU_CTRL = 0x9f,
	MCU_EXT_CMD_SET_SPR = 0xa8,
+3 −0
Original line number Diff line number Diff line
@@ -293,6 +293,9 @@ mt7915_regd_notifier(struct wiphy *wiphy,
	memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));
	dev->mt76.region = request->dfs_region;

	if (dev->mt76.region == NL80211_DFS_UNSET)
		mt7915_mcu_rdd_background_enable(phy, NULL);

	mt7915_init_txpower(dev, &mphy->sband_2g.sband);
	mt7915_init_txpower(dev, &mphy->sband_5g.sband);

+50 −0
Original line number Diff line number Diff line
@@ -1356,6 +1356,55 @@ mt7915_twt_teardown_request(struct ieee80211_hw *hw,
	mutex_unlock(&dev->mt76.mutex);
}

static int
mt7915_set_radar_background(struct ieee80211_hw *hw,
			    struct cfg80211_chan_def *chandef)
{
	struct mt7915_phy *phy = mt7915_hw_phy(hw);
	struct mt7915_dev *dev = phy->dev;
	int ret = -EINVAL;
	bool running;

	mutex_lock(&dev->mt76.mutex);

	if (dev->mt76.region == NL80211_DFS_UNSET)
		goto out;

	if (dev->rdd2_phy && dev->rdd2_phy != phy) {
		/* rdd2 is already locked */
		ret = -EBUSY;
		goto out;
	}

	/* rdd2 already configured on a radar channel */
	running = dev->rdd2_phy &&
		  cfg80211_chandef_valid(&dev->rdd2_chandef) &&
		  !!(dev->rdd2_chandef.chan->flags & IEEE80211_CHAN_RADAR);

	if (!chandef || running ||
	    !(chandef->chan->flags & IEEE80211_CHAN_RADAR)) {
		ret = mt7915_mcu_rdd_background_enable(phy, NULL);
		if (ret)
			goto out;

		if (!running)
			goto update_phy;
	}

	ret = mt7915_mcu_rdd_background_enable(phy, chandef);
	if (ret)
		goto out;

update_phy:
	dev->rdd2_phy = chandef ? phy : NULL;
	if (chandef)
		dev->rdd2_chandef = *chandef;
out:
	mutex_unlock(&dev->mt76.mutex);

	return ret;
}

const struct ieee80211_ops mt7915_ops = {
	.tx = mt7915_tx,
	.start = mt7915_start,
@@ -1402,4 +1451,5 @@ const struct ieee80211_ops mt7915_ops = {
#ifdef CONFIG_MAC80211_DEBUGFS
	.sta_add_debugfs = mt7915_sta_add_debugfs,
#endif
	.set_radar_background = mt7915_set_radar_background,
};
+93 −0
Original line number Diff line number Diff line
@@ -2629,6 +2629,99 @@ int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
				 sizeof(req), true);
}

static int
mt7915_mcu_background_chain_ctrl(struct mt7915_phy *phy,
				 struct cfg80211_chan_def *chandef,
				 int cmd)
{
	struct mt7915_dev *dev = phy->dev;
	struct mt76_phy *mphy = phy->mt76;
	struct ieee80211_channel *chan = mphy->chandef.chan;
	int freq = mphy->chandef.center_freq1;
	struct mt7915_mcu_background_chain_ctrl req = {
		.monitor_scan_type = 2, /* simple rx */
	};

	if (!chandef && cmd != CH_SWITCH_BACKGROUND_SCAN_STOP)
		return -EINVAL;

	if (!cfg80211_chandef_valid(&mphy->chandef))
		return -EINVAL;

	switch (cmd) {
	case CH_SWITCH_BACKGROUND_SCAN_START: {
		req.chan = chan->hw_value;
		req.central_chan = ieee80211_frequency_to_channel(freq);
		req.bw = mt76_connac_chan_bw(&mphy->chandef);
		req.monitor_chan = chandef->chan->hw_value;
		req.monitor_central_chan =
			ieee80211_frequency_to_channel(chandef->center_freq1);
		req.monitor_bw = mt76_connac_chan_bw(chandef);
		req.band_idx = phy != &dev->phy;
		req.scan_mode = 1;
		break;
	}
	case CH_SWITCH_BACKGROUND_SCAN_RUNNING:
		req.monitor_chan = chandef->chan->hw_value;
		req.monitor_central_chan =
			ieee80211_frequency_to_channel(chandef->center_freq1);
		req.band_idx = phy != &dev->phy;
		req.scan_mode = 2;
		break;
	case CH_SWITCH_BACKGROUND_SCAN_STOP:
		req.chan = chan->hw_value;
		req.central_chan = ieee80211_frequency_to_channel(freq);
		req.bw = mt76_connac_chan_bw(&mphy->chandef);
		req.tx_stream = hweight8(mphy->antenna_mask);
		req.rx_stream = mphy->antenna_mask;
		break;
	default:
		return -EINVAL;
	}
	req.band = chandef ? chandef->chan->band == NL80211_BAND_5GHZ : 1;

	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(OFFCH_SCAN_CTRL),
				 &req, sizeof(req), false);
}

int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
				     struct cfg80211_chan_def *chandef)
{
	struct mt7915_dev *dev = phy->dev;
	int err, region;

	if (!chandef) { /* disable offchain */
		err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_STOP, MT_RX_SEL2,
					      0, 0);
		if (err)
			return err;

		return mt7915_mcu_background_chain_ctrl(phy, NULL,
				CH_SWITCH_BACKGROUND_SCAN_STOP);
	}

	err = mt7915_mcu_background_chain_ctrl(phy, chandef,
					       CH_SWITCH_BACKGROUND_SCAN_START);
	if (err)
		return err;

	switch (dev->mt76.region) {
	case NL80211_DFS_ETSI:
		region = 0;
		break;
	case NL80211_DFS_JP:
		region = 2;
		break;
	case NL80211_DFS_FCC:
	default:
		region = 1;
		break;
	}

	return mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_START, MT_RX_SEL2,
				       0, region);
}

int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
{
	struct mt7915_dev *dev = phy->dev;
+23 −0
Original line number Diff line number Diff line
@@ -131,6 +131,29 @@ struct mt7915_mcu_rdd_report {
	} hw_pulse[32];
} __packed;

struct mt7915_mcu_background_chain_ctrl {
	u8 chan;		/* primary channel */
	u8 central_chan;	/* central channel */
	u8 bw;
	u8 tx_stream;
	u8 rx_stream;

	u8 monitor_chan;	/* monitor channel */
	u8 monitor_central_chan;/* monitor central channel */
	u8 monitor_bw;
	u8 monitor_tx_stream;
	u8 monitor_rx_stream;

	u8 scan_mode;		/* 0: ScanStop
				 * 1: ScanStart
				 * 2: ScanRunning
				 */
	u8 band_idx;		/* DBDC */
	u8 monitor_scan_type;
	u8 band;		/* 0: 2.4GHz, 1: 5GHz */
	u8 rsv[2];
} __packed;

struct mt7915_mcu_eeprom {
	u8 buffer_mode;
	u8 format;
Loading