From 7daf9621ada28638831beca3073ee3e2b8e6609e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 22 Aug 2018 12:26:12 +0200 Subject: [PATCH] mt7603: add survey support Since channel active time is not available from MIB registers, emulate it using the kernel boot time (in us) Signed-off-by: Felix Fietkau --- mt7603.h | 4 ++++ mt7603_init.c | 1 + mt7603_mac.c | 24 ++++++++++++++++++++++++ mt7603_main.c | 11 +++++++++++ mt7603_regs.h | 16 ++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/mt7603.h b/mt7603.h index 9ec7c1f8..0f96bf9c 100644 --- a/mt7603.h +++ b/mt7603.h @@ -18,6 +18,7 @@ #define __MT7603_H #include +#include #include "mt76.h" #include "mt7603_regs.h" @@ -141,6 +142,7 @@ struct mt7603_dev { u8 slottime; s16 coverage_class; + ktime_t survey_time; int beacon_int; struct mt7603_mcu mcu; @@ -265,4 +267,6 @@ void mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps); void mt7603_tbtt(struct mt7603_dev *dev); void mt7603_pre_tbtt_tasklet(unsigned long arg); +void mt7603_update_channel(struct mt76_dev *mdev); + #endif diff --git a/mt7603_init.c b/mt7603_init.c index d43dbfc6..55da4a3e 100644 --- a/mt7603_init.c +++ b/mt7603_init.c @@ -28,6 +28,7 @@ struct mt7603_dev *mt7603_alloc_device(struct device *pdev) .rx_skb = mt7603_queue_rx_skb, .rx_poll_complete = mt7603_rx_poll_complete, .sta_ps = mt7603_sta_ps, + .update_survey = mt7603_update_channel, }; struct mt7603_dev *dev; struct mt76_dev *mdev; diff --git a/mt7603_mac.c b/mt7603_mac.c index 7c5de273..0c0dc1ae 100644 --- a/mt7603_mac.c +++ b/mt7603_mac.c @@ -15,6 +15,7 @@ */ #include +#include #include "mt7603.h" #include "mt7603_mac.h" @@ -1371,6 +1372,27 @@ mt7603_watchdog_check(struct mt7603_dev *dev, u8 *counter, return true; } +void mt7603_update_channel(struct mt76_dev *mdev) +{ + struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); + struct mt76_channel_state *state; + ktime_t cur_time; + u32 busy; + + if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state)) + return; + + state = mt76_channel_state(&dev->mt76, dev->mt76.chandef.chan); + busy = mt76_rr(dev, MT_MIB_STAT_PSCCA); + + spin_lock_bh(&dev->mt76.cc_lock); + cur_time = ktime_get_boottime(); + state->cc_busy += busy; + state->cc_active += ktime_to_us(ktime_sub(cur_time, dev->survey_time)); + dev->survey_time = cur_time; + spin_unlock_bh(&dev->mt76.cc_lock); +} + void mt7603_mac_work(struct work_struct *work) { struct mt7603_dev *dev = container_of(work, struct mt7603_dev, mac_work.work); @@ -1391,6 +1413,8 @@ void mt7603_mac_work(struct work_struct *work) mutex_lock(&dev->mutex); + mt7603_update_channel(&dev->mt76); + if (mt7603_watchdog_check(dev, &dev->tx_dma_check, RESET_CAUSE_TX_BUSY, mt7603_tx_dma_busy) || diff --git a/mt7603_main.c b/mt7603_main.c index 06ce2cf6..8b9d4cbb 100644 --- a/mt7603_main.c +++ b/mt7603_main.c @@ -29,6 +29,7 @@ mt7603_start(struct ieee80211_hw *hw) ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work, MT7603_WATCHDOG_TIME); mt7603_mac_start(dev); + dev->survey_time = ktime_get_boottime(); set_bit(MT76_STATE_RUNNING, &dev->mt76.state); return 0; @@ -134,6 +135,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def) mutex_lock(&dev->mutex); set_bit(MT76_RESET, &dev->mt76.state); + mt76_set_channel(&dev->mt76); mt7603_mac_stop(dev); if (def->width == NL80211_CHAN_WIDTH_40) @@ -167,6 +169,14 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def) ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work, MT7603_WATCHDOG_TIME); + /* reset channel stats */ + mt76_clear(dev, MT_MIB_CTL, MT_MIB_CTL_READ_CLR_DIS); + mt76_set(dev, MT_MIB_CTL, + MT_MIB_CTL_CCA_NAV_TX | MT_MIB_CTL_PSCCA_TIME); + mt76_rr(dev, MT_MIB_STAT_PSCCA); + + dev->survey_time = ktime_get_boottime(); + mutex_unlock(&dev->mutex); return 0; @@ -593,6 +603,7 @@ const struct ieee80211_ops mt7603_ops = { .release_buffered_frames = mt76_release_buffered_frames, .set_coverage_class = mt7603_set_coverage_class, .set_tim = mt7603_set_tim, + .get_survey = mt76_get_survey, }; MODULE_LICENSE("Dual BSD/GPL"); diff --git a/mt7603_regs.h b/mt7603_regs.h index 13e20c6e..57979419 100644 --- a/mt7603_regs.h +++ b/mt7603_regs.h @@ -482,6 +482,22 @@ enum { #define MT_WTBL_RIUCR3_RATE6 GENMASK(19, 8) #define MT_WTBL_RIUCR3_RATE7 GENMASK(31, 20) +#define MT_MIB_BASE 0x2c000 +#define MT_MIB(_n) (MT_MIB_BASE + (_n)) + +#define MT_MIB_CTL MT_MIB(0x00) +#define MT_MIB_CTL_CCA_NAV_TX GENMASK(16, 14) +#define MT_MIB_CTL_PSCCA_TIME GENMASK(13, 11) +#define MT_MIB_CTL_READ_CLR_DIS BIT(31) + +#define MT_MIB_STAT(_n) MT_MIB(0x08 + (_n) * 4) + +#define MT_MIB_STAT_CCA MT_MIB_STAT(9) +#define MT_MIB_STAT_CCA_MASK GENMASK(23, 0) + +#define MT_MIB_STAT_PSCCA MT_MIB_STAT(16) +#define MT_MIB_STAT_PSCCA_MASK GENMASK(23, 0) + #define MT_PCIE_REMAP_BASE_1 0x40000 #define MT_PCIE_REMAP_BASE_2 0x80000