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

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
......@@ -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,
......
......@@ -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);
......
......@@ -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,
};
......@@ -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;
......
......@@ -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;
......
......@@ -269,6 +269,10 @@ struct mt7915_dev {
struct tasklet_struct irq_tasklet;
struct mt7915_phy phy;
/* monitor rx chain configured channel */
struct cfg80211_chan_def rdd2_chandef;
struct mt7915_phy *rdd2_phy;
u16 chainmask;
u32 hif_idx;
......@@ -328,6 +332,7 @@ enum {
enum {
MT_RX_SEL0,
MT_RX_SEL1,
MT_RX_SEL2, /* monitor chain */
};
enum mt7915_rdd_cmd {
......@@ -461,6 +466,8 @@ int mt7915_mcu_get_temperature(struct mt7915_phy *phy);
int mt7915_mcu_set_thermal_throttling(struct mt7915_phy *phy, u8 state);
int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct rate_info *rate);
int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
struct cfg80211_chan_def *chandef);
int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment