During mac80211 software scan, carl9170_set_channel() can return -EIO if the firmware is busy (TX queue draining, AGC calibration timeout). This error propagates back to mac80211 via carl9170_op_config(), which then aborts the entire scan rather than advancing to the next channel. Add sw_scan_start/sw_scan_complete callbacks to track the scanning state in a new 'bool scanning' field in struct ar9170. When a channel change fails during an active scan, log the failure at wiphy_dbg level and return 0 so mac80211 advances to the next scan channel instead of aborting. Channel-change failures outside of a scan continue to propagate the error normally. Signed-off-by: Masi Osmani --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 + drivers/net/wireless/ath/carl9170/main.c | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -335,6 +335,7 @@ /* PHY */ struct ieee80211_channel *channel; unsigned int num_channels; + bool scanning; int noise[4]; unsigned int chan_fail; unsigned int total_chan_fail; --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -989,8 +989,16 @@ err = carl9170_set_channel(ar, hw->conf.chandef.chan, channel_type); - if (err) + if (err) { + if (ar->scanning) { + wiphy_dbg(ar->hw->wiphy, + "scan: skip channel %d MHz, change failed (%d)\n", + hw->conf.chandef.chan->center_freq, + err); + err = 0; + } goto out; + } err = carl9170_update_survey(ar, false, true); if (err) @@ -1016,6 +1024,27 @@ return err; } +static void carl9170_op_sw_scan_start(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *mac_addr) +{ + struct ar9170 *ar = hw->priv; + + mutex_lock(&ar->mutex); + ar->scanning = true; + mutex_unlock(&ar->mutex); +} + +static void carl9170_op_sw_scan_complete(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ar9170 *ar = hw->priv; + + mutex_lock(&ar->mutex); + ar->scanning = false; + mutex_unlock(&ar->mutex); +} + static u64 carl9170_op_prepare_multicast(struct ieee80211_hw *hw, struct netdev_hw_addr_list *mc_list) { @@ -1836,6 +1865,8 @@ .add_interface = carl9170_op_add_interface, .remove_interface = carl9170_op_remove_interface, .config = carl9170_op_config, + .sw_scan_start = carl9170_op_sw_scan_start, + .sw_scan_complete = carl9170_op_sw_scan_complete, .prepare_multicast = carl9170_op_prepare_multicast, .configure_filter = carl9170_op_configure_filter, .conf_tx = carl9170_op_conf_tx, -- Regards, Masi Osmani