diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-rfkill.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rfkill.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index eebaf43f66b2..e5e5846e9f25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c | |||
@@ -44,7 +44,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | |||
44 | struct iwl_priv *priv = data; | 44 | struct iwl_priv *priv = data; |
45 | int err = 0; | 45 | int err = 0; |
46 | 46 | ||
47 | if (!priv->rfkill_mngr.rfkill) | 47 | if (!priv->rfkill) |
48 | return 0; | 48 | return 0; |
49 | 49 | ||
50 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 50 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
@@ -55,20 +55,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | |||
55 | 55 | ||
56 | switch (state) { | 56 | switch (state) { |
57 | case RFKILL_STATE_UNBLOCKED: | 57 | case RFKILL_STATE_UNBLOCKED: |
58 | iwl_radio_kill_sw_enable_radio(priv); | 58 | if (iwl_is_rfkill_hw(priv)) { |
59 | /* if HW rf-kill is set dont allow ON state */ | ||
60 | if (iwl_is_rfkill(priv)) | ||
61 | err = -EBUSY; | 59 | err = -EBUSY; |
60 | goto out_unlock; | ||
61 | } | ||
62 | iwl_radio_kill_sw_enable_radio(priv); | ||
62 | break; | 63 | break; |
63 | case RFKILL_STATE_SOFT_BLOCKED: | 64 | case RFKILL_STATE_SOFT_BLOCKED: |
64 | iwl_radio_kill_sw_disable_radio(priv); | 65 | iwl_radio_kill_sw_disable_radio(priv); |
65 | if (!iwl_is_rfkill(priv)) | ||
66 | err = -EBUSY; | ||
67 | break; | 66 | break; |
68 | default: | 67 | default: |
69 | IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); | 68 | IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); |
70 | break; | 69 | break; |
71 | } | 70 | } |
71 | out_unlock: | ||
72 | mutex_unlock(&priv->mutex); | 72 | mutex_unlock(&priv->mutex); |
73 | 73 | ||
74 | return err; | 74 | return err; |
@@ -82,23 +82,23 @@ int iwl_rfkill_init(struct iwl_priv *priv) | |||
82 | BUG_ON(device == NULL); | 82 | BUG_ON(device == NULL); |
83 | 83 | ||
84 | IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); | 84 | IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); |
85 | priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | 85 | priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); |
86 | if (!priv->rfkill_mngr.rfkill) { | 86 | if (!priv->rfkill) { |
87 | IWL_ERROR("Unable to allocate rfkill device.\n"); | 87 | IWL_ERROR("Unable to allocate rfkill device.\n"); |
88 | ret = -ENOMEM; | 88 | ret = -ENOMEM; |
89 | goto error; | 89 | goto error; |
90 | } | 90 | } |
91 | 91 | ||
92 | priv->rfkill_mngr.rfkill->name = priv->cfg->name; | 92 | priv->rfkill->name = priv->cfg->name; |
93 | priv->rfkill_mngr.rfkill->data = priv; | 93 | priv->rfkill->data = priv; |
94 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; | 94 | priv->rfkill->state = RFKILL_STATE_UNBLOCKED; |
95 | priv->rfkill_mngr.rfkill->toggle_radio = iwl_rfkill_soft_rf_kill; | 95 | priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill; |
96 | priv->rfkill_mngr.rfkill->user_claim_unsupported = 1; | 96 | priv->rfkill->user_claim_unsupported = 1; |
97 | 97 | ||
98 | priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; | 98 | priv->rfkill->dev.class->suspend = NULL; |
99 | priv->rfkill_mngr.rfkill->dev.class->resume = NULL; | 99 | priv->rfkill->dev.class->resume = NULL; |
100 | 100 | ||
101 | ret = rfkill_register(priv->rfkill_mngr.rfkill); | 101 | ret = rfkill_register(priv->rfkill); |
102 | if (ret) { | 102 | if (ret) { |
103 | IWL_ERROR("Unable to register rfkill: %d\n", ret); | 103 | IWL_ERROR("Unable to register rfkill: %d\n", ret); |
104 | goto free_rfkill; | 104 | goto free_rfkill; |
@@ -108,9 +108,9 @@ int iwl_rfkill_init(struct iwl_priv *priv) | |||
108 | return ret; | 108 | return ret; |
109 | 109 | ||
110 | free_rfkill: | 110 | free_rfkill: |
111 | if (priv->rfkill_mngr.rfkill != NULL) | 111 | if (priv->rfkill != NULL) |
112 | rfkill_free(priv->rfkill_mngr.rfkill); | 112 | rfkill_free(priv->rfkill); |
113 | priv->rfkill_mngr.rfkill = NULL; | 113 | priv->rfkill = NULL; |
114 | 114 | ||
115 | error: | 115 | error: |
116 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | 116 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); |
@@ -121,22 +121,27 @@ EXPORT_SYMBOL(iwl_rfkill_init); | |||
121 | void iwl_rfkill_unregister(struct iwl_priv *priv) | 121 | void iwl_rfkill_unregister(struct iwl_priv *priv) |
122 | { | 122 | { |
123 | 123 | ||
124 | if (priv->rfkill_mngr.rfkill) | 124 | if (priv->rfkill) |
125 | rfkill_unregister(priv->rfkill_mngr.rfkill); | 125 | rfkill_unregister(priv->rfkill); |
126 | 126 | ||
127 | priv->rfkill_mngr.rfkill = NULL; | 127 | priv->rfkill = NULL; |
128 | } | 128 | } |
129 | EXPORT_SYMBOL(iwl_rfkill_unregister); | 129 | EXPORT_SYMBOL(iwl_rfkill_unregister); |
130 | 130 | ||
131 | /* set rf-kill to the right state. */ | 131 | /* set rf-kill to the right state. */ |
132 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv) | 132 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv) |
133 | { | 133 | { |
134 | if (!priv->rfkill_mngr.rfkill) | 134 | if (!priv->rfkill) |
135 | return; | 135 | return; |
136 | 136 | ||
137 | if (!iwl_is_rfkill(priv)) | 137 | if (iwl_is_rfkill_hw(priv)) { |
138 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON; | 138 | rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED); |
139 | return; | ||
140 | } | ||
141 | |||
142 | if (!iwl_is_rfkill_sw(priv)) | ||
143 | rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED); | ||
139 | else | 144 | else |
140 | priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF; | 145 | rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED); |
141 | } | 146 | } |
142 | EXPORT_SYMBOL(iwl_rfkill_set_hw_state); | 147 | EXPORT_SYMBOL(iwl_rfkill_set_hw_state); |