The attached patch fixes iwlwifi to set the rfkill state to RFKILL_STATE_HARD_BLOCKED when the device is disabled by the hardware rfkill. --------------- This patch fixes the rfkill states to set RFKILL_STATE_HARD_BLOCKED when the radio is disabled by a hardware killswitch. It does not allow setting the sw state while the device is blocked by a hardware rfkill switch. Signed-off-by: Adel Gadllah <adel.gadllah@xxxxxxxxx> diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 2838093..ad479f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -349,10 +349,19 @@ static inline int iwl_is_init(struct iwl_priv *priv) return test_bit(STATUS_INIT, &priv->status); } +static inline int iwl_is_rfkill_sw(struct iwl_priv *priv) +{ + return test_bit(STATUS_RF_KILL_SW, &priv->status); +} + +static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) +{ + return test_bit(STATUS_RF_KILL_HW, &priv->status); +} + static inline int iwl_is_rfkill(struct iwl_priv *priv) { - return test_bit(STATUS_RF_KILL_HW, &priv->status) || - test_bit(STATUS_RF_KILL_SW, &priv->status); + return iwl_is_rfkill_sw(priv) || iwl_is_rfkill_hw(priv); } static inline int iwl_is_ready_rf(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index ffefbb4..b75813e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c @@ -53,22 +53,23 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state); mutex_lock(&priv->mutex); + if (iwl_is_rfkill_hw(priv)) { + err = -EBUSY; + goto out; + } + switch (state) { case RFKILL_STATE_UNBLOCKED: iwl_radio_kill_sw_enable_radio(priv); - /* if HW rf-kill is set dont allow ON state */ - if (iwl_is_rfkill(priv)) - err = -EBUSY; break; case RFKILL_STATE_SOFT_BLOCKED: iwl_radio_kill_sw_disable_radio(priv); - if (!iwl_is_rfkill(priv)) - err = -EBUSY; break; default: IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); break; } +out: mutex_unlock(&priv->mutex); return err; @@ -177,9 +178,14 @@ void iwl_rfkill_set_hw_state(struct iwl_priv *priv) if (!priv->rfkill_mngr.rfkill) return; - if (!iwl_is_rfkill(priv)) - priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; + if (iwl_is_rfkill_hw(priv)) { + priv->rfkill_mngr.rfkill->state = RFKILL_STATE_HARD_BLOCKED; + return; + } + + if (!iwl_is_rfkill_sw(priv)) + priv->rfkill_mngr.rfkill->state = RFKILL_STATE_UNBLOCKED; else - priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; + priv->rfkill_mngr.rfkill->state = RFKILL_STATE_BLOCKED; } EXPORT_SYMBOL(iwl_rfkill_set_hw_state); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html