Skip to content

Commit

Permalink
mt76: mt7615: add multiple wiphy support to the dfs support code
Browse files Browse the repository at this point in the history
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: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
Felix Fietkau committed Feb 14, 2020
1 parent d23cb96 commit 5dabdf7
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 53 deletions.
9 changes: 3 additions & 6 deletions drivers/net/wireless/mediatek/mt76/mt7615/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,18 +248,15 @@ 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;

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)
Expand Down Expand Up @@ -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));
Expand Down
63 changes: 36 additions & 27 deletions drivers/net/wireless/mediatek/mt76/mt7615/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
5 changes: 2 additions & 3 deletions drivers/net/wireless/mediatek/mt76/mt7615/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 16 additions & 2 deletions drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,29 @@ 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)
{
struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;

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,
Expand Down
46 changes: 46 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
19 changes: 4 additions & 15 deletions drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ struct mt7615_phy {
int false_cca_ofdm, false_cca_cck;
s8 ofdm_sensitivity;
s8 cck_sensitivity;

u8 rdd_state;
int dfs_state;
};

struct mt7615_dev {
Expand All @@ -115,7 +118,6 @@ struct mt7615_dev {
s16 power;
} radar_pattern;
u32 hw_pattern;
int dfs_state;

u8 mac_work_count;
bool scs_en;
Expand Down Expand Up @@ -243,26 +245,13 @@ void mt7615_mcu_rx_event(struct mt7615_dev *dev, struct sk_buff *skb);
int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
enum mt7615_rdd_cmd cmd, u8 index,
u8 rx_sel, u8 val);
int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev);
int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev);
int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev);

static inline bool is_mt7622(struct mt76_dev *dev)
{
return mt76_chip(dev) == 0x7622;
}

static inline void mt7615_dfs_check_channel(struct mt7615_dev *dev)
{
enum nl80211_chan_width width = dev->mphy.chandef.width;
u32 freq = dev->mphy.chandef.chan->center_freq;
struct ieee80211_hw *hw = mt76_hw(dev);

if (hw->conf.chandef.chan->center_freq != freq ||
hw->conf.chandef.width != width)
dev->dfs_state = -1;
}

static inline void mt7615_irq_enable(struct mt7615_dev *dev, u32 mask)
{
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, 0, mask);
Expand Down Expand Up @@ -319,7 +308,7 @@ void mt7615_mac_work(struct work_struct *work);
void mt7615_txp_skb_unmap(struct mt76_dev *dev,
struct mt76_txwi_cache *txwi);
int mt76_dfs_start_rdd(struct mt7615_dev *dev, bool force);
int mt7615_dfs_init_radar_detector(struct mt7615_dev *dev);
int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy);

int mt7615_init_debugfs(struct mt7615_dev *dev);

Expand Down

0 comments on commit 5dabdf7

Please sign in to comment.