diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h index 92bb8be9f319db308003b579682225ab468ebd97..034a0727303822400959623949fb9d47acb21713 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h @@ -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 diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c index 6afd21542c7d3b1ac62dfd1ec051299651beae29..8fcbc8dc94c174f5cdd56dc321cbb1f1ea01de3c 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c @@ -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); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00link.c b/drivers/net/wireless/ralink/rt2x00/rt2x00link.c index 73cbf23b17ef6ee4d9abe3eec1de834f52c73803..2010a7715f2115a913182358d825b0d2492818cc 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00link.c @@ -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. */ diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c index d4b50fb948eef861cec1a9dd1d99f69ec9c3be98..3cc1384ed2fcc24b3c95b052465a4cdb69b2d972 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c @@ -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);