diff options
author | Stanislaw Gruszka | 2019-03-19 11:37:39 +0100 |
---|---|---|
committer | Felix Fietkau | 2019-05-01 13:03:56 +0200 |
commit | c6ad1feb1f0bab6eeb387b9e5980ce0f1fbb727a (patch) | |
tree | 5db1f8b48b09f8c9c596eba116133971fba10449 /drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | |
parent | mt76x02: introduce beacon_ops (diff) | |
download | kernel-qcow2-linux-c6ad1feb1f0bab6eeb387b9e5980ce0f1fbb727a.tar.gz kernel-qcow2-linux-c6ad1feb1f0bab6eeb387b9e5980ce0f1fbb727a.tar.xz kernel-qcow2-linux-c6ad1feb1f0bab6eeb387b9e5980ce0f1fbb727a.zip |
mt76x02u: implement beacon_ops
Add implementation of beacon_ops for USB and exit function to
stop the timer if running when device is removed. Still no
actual work on pre tbtt event.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c index eec6f856f88a..82b78cc5b362 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c @@ -151,6 +151,15 @@ static void mt76x02u_restart_pre_tbtt_timer(struct mt76x02_dev *dev) hrtimer_start(&dev->pre_tbtt_timer, time, HRTIMER_MODE_REL); } +static void mt76x02u_stop_pre_tbtt_timer(struct mt76x02_dev *dev) +{ + do { + hrtimer_cancel(&dev->pre_tbtt_timer); + cancel_work_sync(&dev->pre_tbtt_work); + /* Timer can be rearmed by work. */ + } while (hrtimer_active(&dev->pre_tbtt_timer)); +} + static void mt76x02u_pre_tbtt_work(struct work_struct *work) { struct mt76x02_dev *dev = @@ -173,10 +182,21 @@ static enum hrtimer_restart mt76x02u_pre_tbtt_interrupt(struct hrtimer *timer) static void mt76x02u_pre_tbtt_enable(struct mt76x02_dev *dev, bool en) { + if (en && dev->beacon_mask && !hrtimer_active(&dev->pre_tbtt_timer)) + mt76x02u_start_pre_tbtt_timer(dev); + if (!en) + mt76x02u_stop_pre_tbtt_timer(dev); } static void mt76x02u_beacon_enable(struct mt76x02_dev *dev, bool en) { + if (WARN_ON_ONCE(!dev->beacon_int)) + return; + + if (en) + mt76x02u_start_pre_tbtt_timer(dev); + + /* Nothing to do on disable as timer is already stopped */ } void mt76x02u_init_beacon_config(struct mt76x02_dev *dev) @@ -194,3 +214,16 @@ void mt76x02u_init_beacon_config(struct mt76x02_dev *dev) mt76x02_init_beacon_config(dev); } EXPORT_SYMBOL_GPL(mt76x02u_init_beacon_config); + +void mt76x02u_exit_beacon_config(struct mt76x02_dev *dev) +{ + if (!test_bit(MT76_REMOVED, &dev->mt76.state)) + mt76_clear(dev, MT_BEACON_TIME_CFG, + MT_BEACON_TIME_CFG_TIMER_EN | + MT_BEACON_TIME_CFG_SYNC_MODE | + MT_BEACON_TIME_CFG_TBTT_EN | + MT_BEACON_TIME_CFG_BEACON_TX); + + mt76x02u_stop_pre_tbtt_timer(dev); +} +EXPORT_SYMBOL_GPL(mt76x02u_exit_beacon_config); |