diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-hcmd.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-hcmd.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 258d059ef41f..76f996623140 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -51,9 +51,7 @@ const char *get_cmd_string(u8 cmd) | |||
51 | IWL_CMD(REPLY_REMOVE_ALL_STA); | 51 | IWL_CMD(REPLY_REMOVE_ALL_STA); |
52 | IWL_CMD(REPLY_TXFIFO_FLUSH); | 52 | IWL_CMD(REPLY_TXFIFO_FLUSH); |
53 | IWL_CMD(REPLY_WEPKEY); | 53 | IWL_CMD(REPLY_WEPKEY); |
54 | IWL_CMD(REPLY_3945_RX); | ||
55 | IWL_CMD(REPLY_TX); | 54 | IWL_CMD(REPLY_TX); |
56 | IWL_CMD(REPLY_RATE_SCALE); | ||
57 | IWL_CMD(REPLY_LEDS_CMD); | 55 | IWL_CMD(REPLY_LEDS_CMD); |
58 | IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); | 56 | IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); |
59 | IWL_CMD(COEX_PRIORITY_TABLE_CMD); | 57 | IWL_CMD(COEX_PRIORITY_TABLE_CMD); |
@@ -97,12 +95,23 @@ const char *get_cmd_string(u8 cmd) | |||
97 | IWL_CMD(REPLY_TX_POWER_DBM_CMD); | 95 | IWL_CMD(REPLY_TX_POWER_DBM_CMD); |
98 | IWL_CMD(TEMPERATURE_NOTIFICATION); | 96 | IWL_CMD(TEMPERATURE_NOTIFICATION); |
99 | IWL_CMD(TX_ANT_CONFIGURATION_CMD); | 97 | IWL_CMD(TX_ANT_CONFIGURATION_CMD); |
98 | IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF); | ||
99 | IWL_CMD(REPLY_BT_COEX_PRIO_TABLE); | ||
100 | IWL_CMD(REPLY_BT_COEX_PROT_ENV); | ||
101 | IWL_CMD(REPLY_WIPAN_PARAMS); | ||
102 | IWL_CMD(REPLY_WIPAN_RXON); | ||
103 | IWL_CMD(REPLY_WIPAN_RXON_TIMING); | ||
104 | IWL_CMD(REPLY_WIPAN_RXON_ASSOC); | ||
105 | IWL_CMD(REPLY_WIPAN_QOS_PARAM); | ||
106 | IWL_CMD(REPLY_WIPAN_WEPKEY); | ||
107 | IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); | ||
108 | IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); | ||
109 | IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE); | ||
100 | default: | 110 | default: |
101 | return "UNKNOWN"; | 111 | return "UNKNOWN"; |
102 | 112 | ||
103 | } | 113 | } |
104 | } | 114 | } |
105 | EXPORT_SYMBOL(get_cmd_string); | ||
106 | 115 | ||
107 | #define HOST_COMPLETE_TIMEOUT (HZ / 2) | 116 | #define HOST_COMPLETE_TIMEOUT (HZ / 2) |
108 | 117 | ||
@@ -134,10 +143,12 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
134 | { | 143 | { |
135 | int ret; | 144 | int ret; |
136 | 145 | ||
137 | BUG_ON(!(cmd->flags & CMD_ASYNC)); | 146 | if (WARN_ON(!(cmd->flags & CMD_ASYNC))) |
147 | return -EINVAL; | ||
138 | 148 | ||
139 | /* An asynchronous command can not expect an SKB to be set. */ | 149 | /* An asynchronous command can not expect an SKB to be set. */ |
140 | BUG_ON(cmd->flags & CMD_WANT_SKB); | 150 | if (WARN_ON(cmd->flags & CMD_WANT_SKB)) |
151 | return -EINVAL; | ||
141 | 152 | ||
142 | /* Assign a generic callback if one is not provided */ | 153 | /* Assign a generic callback if one is not provided */ |
143 | if (!cmd->callback) | 154 | if (!cmd->callback) |
@@ -160,14 +171,15 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
160 | int cmd_idx; | 171 | int cmd_idx; |
161 | int ret; | 172 | int ret; |
162 | 173 | ||
163 | BUG_ON(cmd->flags & CMD_ASYNC); | 174 | if (WARN_ON(cmd->flags & CMD_ASYNC)) |
175 | return -EINVAL; | ||
164 | 176 | ||
165 | /* A synchronous command can not have a callback set. */ | 177 | /* A synchronous command can not have a callback set. */ |
166 | BUG_ON(cmd->callback); | 178 | if (WARN_ON(cmd->callback)) |
179 | return -EINVAL; | ||
167 | 180 | ||
168 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", | 181 | IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", |
169 | get_cmd_string(cmd->id)); | 182 | get_cmd_string(cmd->id)); |
170 | mutex_lock(&priv->sync_cmd_mutex); | ||
171 | 183 | ||
172 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); | 184 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); |
173 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", | 185 | IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", |
@@ -176,9 +188,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
176 | cmd_idx = iwl_enqueue_hcmd(priv, cmd); | 188 | cmd_idx = iwl_enqueue_hcmd(priv, cmd); |
177 | if (cmd_idx < 0) { | 189 | if (cmd_idx < 0) { |
178 | ret = cmd_idx; | 190 | ret = cmd_idx; |
191 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||
179 | IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", | 192 | IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", |
180 | get_cmd_string(cmd->id), ret); | 193 | get_cmd_string(cmd->id), ret); |
181 | goto out; | 194 | return ret; |
182 | } | 195 | } |
183 | 196 | ||
184 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 197 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, |
@@ -218,8 +231,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
218 | goto cancel; | 231 | goto cancel; |
219 | } | 232 | } |
220 | 233 | ||
221 | ret = 0; | 234 | return 0; |
222 | goto out; | ||
223 | 235 | ||
224 | cancel: | 236 | cancel: |
225 | if (cmd->flags & CMD_WANT_SKB) { | 237 | if (cmd->flags & CMD_WANT_SKB) { |
@@ -229,7 +241,7 @@ cancel: | |||
229 | * in later, it will possibly set an invalid | 241 | * in later, it will possibly set an invalid |
230 | * address (cmd->meta.source). | 242 | * address (cmd->meta.source). |
231 | */ | 243 | */ |
232 | priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_idx].flags &= | 244 | priv->txq[priv->cmd_queue].meta[cmd_idx].flags &= |
233 | ~CMD_WANT_SKB; | 245 | ~CMD_WANT_SKB; |
234 | } | 246 | } |
235 | fail: | 247 | fail: |
@@ -237,11 +249,9 @@ fail: | |||
237 | iwl_free_pages(priv, cmd->reply_page); | 249 | iwl_free_pages(priv, cmd->reply_page); |
238 | cmd->reply_page = 0; | 250 | cmd->reply_page = 0; |
239 | } | 251 | } |
240 | out: | 252 | |
241 | mutex_unlock(&priv->sync_cmd_mutex); | ||
242 | return ret; | 253 | return ret; |
243 | } | 254 | } |
244 | EXPORT_SYMBOL(iwl_send_cmd_sync); | ||
245 | 255 | ||
246 | int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | 256 | int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) |
247 | { | 257 | { |
@@ -250,19 +260,17 @@ int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
250 | 260 | ||
251 | return iwl_send_cmd_sync(priv, cmd); | 261 | return iwl_send_cmd_sync(priv, cmd); |
252 | } | 262 | } |
253 | EXPORT_SYMBOL(iwl_send_cmd); | ||
254 | 263 | ||
255 | int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) | 264 | int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) |
256 | { | 265 | { |
257 | struct iwl_host_cmd cmd = { | 266 | struct iwl_host_cmd cmd = { |
258 | .id = id, | 267 | .id = id, |
259 | .len = len, | 268 | .len = { len, }, |
260 | .data = data, | 269 | .data = { data, }, |
261 | }; | 270 | }; |
262 | 271 | ||
263 | return iwl_send_cmd_sync(priv, &cmd); | 272 | return iwl_send_cmd_sync(priv, &cmd); |
264 | } | 273 | } |
265 | EXPORT_SYMBOL(iwl_send_cmd_pdu); | ||
266 | 274 | ||
267 | int iwl_send_cmd_pdu_async(struct iwl_priv *priv, | 275 | int iwl_send_cmd_pdu_async(struct iwl_priv *priv, |
268 | u8 id, u16 len, const void *data, | 276 | u8 id, u16 len, const void *data, |
@@ -272,8 +280,8 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, | |||
272 | { | 280 | { |
273 | struct iwl_host_cmd cmd = { | 281 | struct iwl_host_cmd cmd = { |
274 | .id = id, | 282 | .id = id, |
275 | .len = len, | 283 | .len = { len, }, |
276 | .data = data, | 284 | .data = { data, }, |
277 | }; | 285 | }; |
278 | 286 | ||
279 | cmd.flags |= CMD_ASYNC; | 287 | cmd.flags |= CMD_ASYNC; |
@@ -281,4 +289,3 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, | |||
281 | 289 | ||
282 | return iwl_send_cmd_async(priv, &cmd); | 290 | return iwl_send_cmd_async(priv, &cmd); |
283 | } | 291 | } |
284 | EXPORT_SYMBOL(iwl_send_cmd_pdu_async); | ||