mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
wifi: mt76: mt7996: fix the behavior of radar detection
RDD_DET_MODE is a firmware command intended for testing and does not
pause TX after radar detection, so remove it from the normal flow;
instead, use the MAC_ENABLE_CTRL firmware command to resume TX after
the radar-triggered channel switch completes.
Fixes: 1529e335f93d ("wifi: mt76: mt7996: rework radar HWRDD idx")
Co-developed-by: Shayne Chen <[email protected]>
Signed-off-by: Shayne Chen <[email protected]>
Signed-off-by: StanleyYP Wang <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
committed by
Felix Fietkau
parent
12c099c526
commit
85c39fb244
+2
-6
@@ -2973,7 +2973,7 @@ static void mt7996_dfs_stop_radar_detector(struct mt7996_phy *phy)
|
|||||||
|
|
||||||
static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int rdd_idx)
|
static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int rdd_idx)
|
||||||
{
|
{
|
||||||
int err, region;
|
int region;
|
||||||
|
|
||||||
switch (dev->mt76.region) {
|
switch (dev->mt76.region) {
|
||||||
case NL80211_DFS_ETSI:
|
case NL80211_DFS_ETSI:
|
||||||
@@ -2988,11 +2988,7 @@ static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int rdd_idx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mt7996_mcu_rdd_cmd(dev, RDD_START, rdd_idx, region);
|
return mt7996_mcu_rdd_cmd(dev, RDD_START, rdd_idx, region);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
return mt7996_mcu_rdd_cmd(dev, RDD_DET_MODE, rdd_idx, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mt7996_dfs_start_radar_detector(struct mt7996_phy *phy)
|
static int mt7996_dfs_start_radar_detector(struct mt7996_phy *phy)
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ static void mt7996_stop_phy(struct mt7996_phy *phy)
|
|||||||
|
|
||||||
mutex_lock(&dev->mt76.mutex);
|
mutex_lock(&dev->mt76.mutex);
|
||||||
|
|
||||||
|
mt7996_mcu_rdd_resume_tx(phy);
|
||||||
mt7996_mcu_set_radio_en(phy, false);
|
mt7996_mcu_set_radio_en(phy, false);
|
||||||
|
|
||||||
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
|
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
|
||||||
@@ -953,6 +954,24 @@ mt7996_channel_switch_beacon(struct ieee80211_hw *hw,
|
|||||||
mutex_unlock(&dev->mt76.mutex);
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mt7996_post_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||||
|
struct ieee80211_bss_conf *link_conf)
|
||||||
|
{
|
||||||
|
struct cfg80211_chan_def *chandef = &link_conf->chanreq.oper;
|
||||||
|
struct mt7996_dev *dev = mt7996_hw_dev(hw);
|
||||||
|
struct mt7996_phy *phy = mt7996_band_phy(dev, chandef->chan->band);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&dev->mt76.mutex);
|
||||||
|
|
||||||
|
ret = mt7996_mcu_rdd_resume_tx(phy);
|
||||||
|
|
||||||
|
mutex_unlock(&dev->mt76.mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mt7996_mac_sta_init_link(struct mt7996_dev *dev,
|
mt7996_mac_sta_init_link(struct mt7996_dev *dev,
|
||||||
struct ieee80211_bss_conf *link_conf,
|
struct ieee80211_bss_conf *link_conf,
|
||||||
@@ -2326,6 +2345,7 @@ const struct ieee80211_ops mt7996_ops = {
|
|||||||
.release_buffered_frames = mt76_release_buffered_frames,
|
.release_buffered_frames = mt76_release_buffered_frames,
|
||||||
.get_txpower = mt7996_get_txpower,
|
.get_txpower = mt7996_get_txpower,
|
||||||
.channel_switch_beacon = mt7996_channel_switch_beacon,
|
.channel_switch_beacon = mt7996_channel_switch_beacon,
|
||||||
|
.post_channel_switch = mt7996_post_channel_switch,
|
||||||
.get_stats = mt7996_get_stats,
|
.get_stats = mt7996_get_stats,
|
||||||
.get_et_sset_count = mt7996_get_et_sset_count,
|
.get_et_sset_count = mt7996_get_et_sset_count,
|
||||||
.get_et_stats = mt7996_get_et_stats,
|
.get_et_stats = mt7996_get_et_stats,
|
||||||
|
|||||||
+43
-6
@@ -520,24 +520,32 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
|
|||||||
break;
|
break;
|
||||||
case MT_RDD_IDX_BACKGROUND:
|
case MT_RDD_IDX_BACKGROUND:
|
||||||
if (!dev->rdd2_phy)
|
if (!dev->rdd2_phy)
|
||||||
return;
|
goto err;
|
||||||
mphy = dev->rdd2_phy->mt76;
|
mphy = dev->rdd2_phy->mt76;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(dev->mt76.dev, "Unknown RDD idx %d\n", r->rdd_idx);
|
goto err;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mphy)
|
if (!mphy)
|
||||||
return;
|
goto err;
|
||||||
|
|
||||||
if (r->rdd_idx == MT_RDD_IDX_BACKGROUND)
|
if (r->rdd_idx == MT_RDD_IDX_BACKGROUND) {
|
||||||
cfg80211_background_radar_event(mphy->hw->wiphy,
|
cfg80211_background_radar_event(mphy->hw->wiphy,
|
||||||
&dev->rdd2_chandef,
|
&dev->rdd2_chandef,
|
||||||
GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
else
|
} else {
|
||||||
|
struct mt7996_phy *phy = mphy->priv;
|
||||||
|
|
||||||
|
phy->rdd_tx_paused = true;
|
||||||
ieee80211_radar_detected(mphy->hw, NULL);
|
ieee80211_radar_detected(mphy->hw, NULL);
|
||||||
|
}
|
||||||
dev->hw_pattern++;
|
dev->hw_pattern++;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
err:
|
||||||
|
dev_err(dev->mt76.dev, "Invalid RDD idx %d\n", r->rdd_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4610,6 +4618,35 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable)
|
|||||||
&req, sizeof(req), true);
|
&req, sizeof(req), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mt7996_mcu_rdd_resume_tx(struct mt7996_phy *phy)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
u8 band_idx;
|
||||||
|
u8 _rsv[3];
|
||||||
|
|
||||||
|
__le16 tag;
|
||||||
|
__le16 len;
|
||||||
|
u8 mac_enable;
|
||||||
|
u8 _rsv2[3];
|
||||||
|
} __packed req = {
|
||||||
|
.band_idx = phy->mt76->band_idx,
|
||||||
|
.tag = cpu_to_le16(UNI_BAND_CONFIG_MAC_ENABLE_CTRL),
|
||||||
|
.len = cpu_to_le16(sizeof(req) - 4),
|
||||||
|
.mac_enable = 2,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!phy->rdd_tx_paused)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
|
||||||
|
&req, sizeof(req), true);
|
||||||
|
if (!ret)
|
||||||
|
phy->rdd_tx_paused = false;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val)
|
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -835,6 +835,7 @@ enum {
|
|||||||
enum {
|
enum {
|
||||||
UNI_BAND_CONFIG_RADIO_ENABLE,
|
UNI_BAND_CONFIG_RADIO_ENABLE,
|
||||||
UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
|
UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
|
||||||
|
UNI_BAND_CONFIG_MAC_ENABLE_CTRL = 0x0c,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
@@ -377,6 +377,7 @@ struct mt7996_phy {
|
|||||||
|
|
||||||
bool has_aux_rx;
|
bool has_aux_rx;
|
||||||
bool counter_reset;
|
bool counter_reset;
|
||||||
|
bool rdd_tx_paused;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mt7996_dev {
|
struct mt7996_dev {
|
||||||
@@ -726,6 +727,7 @@ int mt7996_mcu_get_temperature(struct mt7996_phy *phy);
|
|||||||
int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state);
|
int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state);
|
||||||
int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable);
|
int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable);
|
||||||
int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
|
int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
|
||||||
|
int mt7996_mcu_rdd_resume_tx(struct mt7996_phy *phy);
|
||||||
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val);
|
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val);
|
||||||
int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
|
int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
|
||||||
struct cfg80211_chan_def *chandef);
|
struct cfg80211_chan_def *chandef);
|
||||||
|
|||||||
Reference in New Issue
Block a user