rt2x00: add mutex to synchronize config and link tuner
authorStanislaw Gruszka <sgruszka@redhat.com>
Mon, 19 Dec 2016 10:52:57 +0000 (11:52 +0100)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 30 Dec 2016 12:03:41 +0000 (14:03 +0200)
Do not perform mac80211 config and link_tuner at the same time,
this can possibly result in wrong RF or BBP configuration.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ralink/rt2x00/rt2x00.h
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
drivers/net/wireless/ralink/rt2x00/rt2x00link.c
drivers/net/wireless/ralink/rt2x00/rt2x00mac.c

index 92bb8be9f319db308003b579682225ab468ebd97..034a0727303822400959623949fb9d47acb21713 100644 (file)
@@ -833,6 +833,10 @@ struct rt2x00_dev {
         */
        struct mutex csr_mutex;
 
+       /*
+        * Mutex to synchronize config and link tuner.
+        */
+       struct mutex conf_mutex;
        /*
         * Current packet filter configuration for the device.
         * This contains all currently active FIF_* flags send
index 6afd21542c7d3b1ac62dfd1ec051299651beae29..8fcbc8dc94c174f5cdd56dc321cbb1f1ea01de3c 100644 (file)
@@ -1313,6 +1313,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 
        spin_lock_init(&rt2x00dev->irqmask_lock);
        mutex_init(&rt2x00dev->csr_mutex);
+       mutex_init(&rt2x00dev->conf_mutex);
        INIT_LIST_HEAD(&rt2x00dev->bar_list);
        spin_lock_init(&rt2x00dev->bar_list_lock);
 
index 73cbf23b17ef6ee4d9abe3eec1de834f52c73803..2010a7715f2115a913182358d825b0d2492818cc 100644 (file)
@@ -363,6 +363,9 @@ static void rt2x00link_tuner(struct work_struct *work)
            test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
                return;
 
+       /* Do not race with rt2x00mac_config(). */
+       mutex_lock(&rt2x00dev->conf_mutex);
+
        if (rt2x00dev->intf_sta_count)
                rt2x00link_tuner_sta(rt2x00dev, link);
 
@@ -375,6 +378,8 @@ static void rt2x00link_tuner(struct work_struct *work)
            (link->count % (VCO_SECONDS / LINK_TUNE_SECONDS)) == 0)
                rt2x00dev->ops->lib->vco_calibration(rt2x00dev);
 
+       mutex_unlock(&rt2x00dev->conf_mutex);
+
        /*
         * Increase tuner counter, and reschedule the next link tuner run.
         */
index d4b50fb948eef861cec1a9dd1d99f69ec9c3be98..3cc1384ed2fcc24b3c95b052465a4cdb69b2d972 100644 (file)
@@ -320,6 +320,9 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
         */
        rt2x00queue_stop_queue(rt2x00dev->rx);
 
+       /* Do not race with with link tuner. */
+       mutex_lock(&rt2x00dev->conf_mutex);
+
        /*
         * When we've just turned on the radio, we want to reprogram
         * everything to ensure a consistent state
@@ -335,6 +338,8 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
         */
        rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
 
+       mutex_unlock(&rt2x00dev->conf_mutex);
+
        /* Turn RX back on */
        rt2x00queue_start_queue(rt2x00dev->rx);