@@ -53,22 +53,31 @@ static int iwl_rfkill_soft_rf_kill(void
switch (state) {
case RFKILL_STATE_UNBLOCKED:
if (iwl_is_rfkill_hw(priv)) {
+ /* pass error to rfkill core, make it state HARD
+ * BLOCKED (rfkill->mutex taken) and disable
+ * software kill switch */
err = -EBUSY;
- goto out_unlock;
+ priv->rfkill->state = RFKILL_STATE_HARD_BLOCKED;
}
iwl_radio_kill_sw_enable_radio(priv);
break;
case RFKILL_STATE_SOFT_BLOCKED:
iwl_radio_kill_sw_disable_radio(priv);
+ /* rfkill->mutex is taken */
+ if (priv->rfkill->state == RFKILL_STATE_HARD_BLOCKED) {
+ /* force rfkill core state to be SOFT BLOCKED,
+ * otherwise core will be unable to disable software
+ * kill switch */
+ priv->rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
+ }
break;
default:
IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
state);
break;
}
-out_unlock:
- mutex_unlock(&priv->mutex);
+ mutex_unlock(&priv->mutex);
return err;
}
@@ -132,14 +141,11 @@ void iwl_rfkill_set_hw_state(struct iwl_
if (!priv->rfkill)
return;
- if (iwl_is_rfkill_hw(priv)) {
+ if (iwl_is_rfkill_sw(priv))
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
+ else if (iwl_is_rfkill_hw(priv))
rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
- return;
- }
-
- if (!iwl_is_rfkill_sw(priv))
- rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
else
- rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
}
EXPORT_SYMBOL(iwl_rfkill_set_hw_state);