From 9e33a3553821418b2c4f53d09311476c55176b13 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 28 Mar 2011 13:33:40 +0200 Subject: rt2x00: Implement tx power temperature compensation rt2800 devices should adjust their tx power in accordance with the eeproms temperature calibration values. Add a new driver callback gain_calibration that is called every 4 seconds. The rt2800 gain calibration routine simply runs the tx power configuration that takes care of calculating the temperature compensation delta. We don't need to synchronize the calls to rt2800_config_txpower as they should all happen from mac80211's single threaded workqueue. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00link.c | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers/net/wireless/rt2x00/rt2x00link.c') diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index fc8cee91b54..128b3615c08 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -446,8 +446,46 @@ static void rt2x00link_watchdog(struct work_struct *work) WATCHDOG_INTERVAL); } +void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev) +{ + struct link *link = &rt2x00dev->link; + + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + rt2x00dev->ops->lib->gain_calibration) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->agc_work, + AGC_INTERVAL); +} + +void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev) +{ + cancel_delayed_work_sync(&rt2x00dev->link.agc_work); +} + +static void rt2x00link_agc(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, link.agc_work.work); + struct link *link = &rt2x00dev->link; + + /* + * When the radio is shutting down we should + * immediately cease the watchdog monitoring. + */ + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return; + + rt2x00dev->ops->lib->gain_calibration(rt2x00dev); + + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->agc_work, + AGC_INTERVAL); +} + void rt2x00link_register(struct rt2x00_dev *rt2x00dev) { + INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc); INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog); INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); } -- cgit v1.2.3