]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/iwlwifi/iwl-ucode.c
iwlwifi: add wrappers for command sending
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / iwl-ucode.c
1 /******************************************************************************
2  *
3  * GPL LICENSE SUMMARY
4  *
5  * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
6  *
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
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19  * USA
20  *
21  * The full GNU General Public License is included in this distribution
22  * in the file called LICENSE.GPL.
23  *
24  * Contact Information:
25  *  Intel Linux Wireless <ilw@linux.intel.com>
26  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27  *
28  *****************************************************************************/
29
30 #include <linux/kernel.h>
31 #include <linux/init.h>
32 #include <linux/sched.h>
33
34 #include "iwl-dev.h"
35 #include "iwl-core.h"
36 #include "iwl-io.h"
37 #include "iwl-agn-hw.h"
38 #include "iwl-agn.h"
39 #include "iwl-agn-calib.h"
40 #include "iwl-trans.h"
41 #include "iwl-fh.h"
42 #include "iwl-op-mode.h"
43
44 static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
45         {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
46          0, COEX_UNASSOC_IDLE_FLAGS},
47         {COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
48          0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
49         {COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
50          0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
51         {COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
52          0, COEX_CALIBRATION_FLAGS},
53         {COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
54          0, COEX_PERIODIC_CALIBRATION_FLAGS},
55         {COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
56          0, COEX_CONNECTION_ESTAB_FLAGS},
57         {COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
58          0, COEX_ASSOCIATED_IDLE_FLAGS},
59         {COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
60          0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
61         {COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
62          0, COEX_ASSOC_AUTO_SCAN_FLAGS},
63         {COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
64          0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
65         {COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
66         {COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
67         {COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
68          0, COEX_STAND_ALONE_DEBUG_FLAGS},
69         {COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
70          0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
71         {COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
72         {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
73 };
74
75 /******************************************************************************
76  *
77  * uCode download functions
78  *
79  ******************************************************************************/
80
81 static inline const struct fw_img *
82 iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type)
83 {
84         switch (ucode_type) {
85         case IWL_UCODE_INIT:
86                 return &priv->fw->ucode_init;
87         case IWL_UCODE_WOWLAN:
88                 return &priv->fw->ucode_wowlan;
89         case IWL_UCODE_REGULAR:
90                 return &priv->fw->ucode_rt;
91         case IWL_UCODE_NONE:
92                 break;
93         }
94         return NULL;
95 }
96
97 /*
98  *  Calibration
99  */
100 static int iwl_set_Xtal_calib(struct iwl_priv *priv)
101 {
102         struct iwl_calib_xtal_freq_cmd cmd;
103         __le16 *xtal_calib =
104                 (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL);
105
106         iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD);
107         cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
108         cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
109         return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
110 }
111
112 static int iwl_set_temperature_offset_calib(struct iwl_priv *priv)
113 {
114         struct iwl_calib_temperature_offset_cmd cmd;
115         __le16 *offset_calib =
116                 (__le16 *)iwl_eeprom_query_addr(priv->shrd,
117                                                 EEPROM_RAW_TEMPERATURE);
118
119         memset(&cmd, 0, sizeof(cmd));
120         iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
121         memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(*offset_calib));
122         if (!(cmd.radio_sensor_offset))
123                 cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
124
125         IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
126                         le16_to_cpu(cmd.radio_sensor_offset));
127         return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
128 }
129
130 static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv)
131 {
132         struct iwl_calib_temperature_offset_v2_cmd cmd;
133         __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd,
134                                      EEPROM_KELVIN_TEMPERATURE);
135         __le16 *offset_calib_low =
136                 (__le16 *)iwl_eeprom_query_addr(priv->shrd,
137                                                 EEPROM_RAW_TEMPERATURE);
138         struct iwl_eeprom_calib_hdr *hdr;
139
140         memset(&cmd, 0, sizeof(cmd));
141         iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
142         hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd,
143                                                         EEPROM_CALIB_ALL);
144         memcpy(&cmd.radio_sensor_offset_high, offset_calib_high,
145                 sizeof(*offset_calib_high));
146         memcpy(&cmd.radio_sensor_offset_low, offset_calib_low,
147                 sizeof(*offset_calib_low));
148         if (!(cmd.radio_sensor_offset_low)) {
149                 IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n");
150                 cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET;
151                 cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET;
152         }
153         memcpy(&cmd.burntVoltageRef, &hdr->voltage,
154                 sizeof(hdr->voltage));
155
156         IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n",
157                         le16_to_cpu(cmd.radio_sensor_offset_high));
158         IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n",
159                         le16_to_cpu(cmd.radio_sensor_offset_low));
160         IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n",
161                         le16_to_cpu(cmd.burntVoltageRef));
162
163         return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
164 }
165
166 static int iwl_send_calib_cfg(struct iwl_priv *priv)
167 {
168         struct iwl_calib_cfg_cmd calib_cfg_cmd;
169         struct iwl_host_cmd cmd = {
170                 .id = CALIBRATION_CFG_CMD,
171                 .len = { sizeof(struct iwl_calib_cfg_cmd), },
172                 .data = { &calib_cfg_cmd, },
173         };
174
175         memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
176         calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
177         calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL;
178         calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL;
179         calib_cfg_cmd.ucd_calib_cfg.flags =
180                 IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK;
181
182         return iwl_dvm_send_cmd(priv, &cmd);
183 }
184
185 int iwlagn_rx_calib_result(struct iwl_priv *priv,
186                             struct iwl_rx_cmd_buffer *rxb,
187                             struct iwl_device_cmd *cmd)
188 {
189         struct iwl_rx_packet *pkt = rxb_addr(rxb);
190         struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
191         int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
192
193         /* reduce the size of the length field itself */
194         len -= 4;
195
196         if (iwl_calib_set(priv, hdr, len))
197                 IWL_ERR(priv, "Failed to record calibration data %d\n",
198                         hdr->op_code);
199
200         return 0;
201 }
202
203 int iwl_init_alive_start(struct iwl_priv *priv)
204 {
205         int ret;
206
207         if (cfg(priv)->bt_params &&
208             cfg(priv)->bt_params->advanced_bt_coexist) {
209                 /*
210                  * Tell uCode we are ready to perform calibration
211                  * need to perform this before any calibration
212                  * no need to close the envlope since we are going
213                  * to load the runtime uCode later.
214                  */
215                 ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
216                         BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
217                 if (ret)
218                         return ret;
219
220         }
221
222         ret = iwl_send_calib_cfg(priv);
223         if (ret)
224                 return ret;
225
226         /**
227          * temperature offset calibration is only needed for runtime ucode,
228          * so prepare the value now.
229          */
230         if (cfg(priv)->need_temp_offset_calib) {
231                 if (cfg(priv)->temp_offset_v2)
232                         return iwl_set_temperature_offset_calib_v2(priv);
233                 else
234                         return iwl_set_temperature_offset_calib(priv);
235         }
236
237         return 0;
238 }
239
240 static int iwl_send_wimax_coex(struct iwl_priv *priv)
241 {
242         struct iwl_wimax_coex_cmd coex_cmd;
243
244         if (cfg(priv)->base_params->support_wimax_coexist) {
245                 /* UnMask wake up src at associated sleep */
246                 coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
247
248                 /* UnMask wake up src at unassociated sleep */
249                 coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
250                 memcpy(coex_cmd.sta_prio, cu_priorities,
251                         sizeof(struct iwl_wimax_coex_event_entry) *
252                          COEX_NUM_OF_EVENTS);
253
254                 /* enabling the coexistence feature */
255                 coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
256
257                 /* enabling the priorities tables */
258                 coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
259         } else {
260                 /* coexistence is disabled */
261                 memset(&coex_cmd, 0, sizeof(coex_cmd));
262         }
263         return iwl_dvm_send_cmd_pdu(priv,
264                                 COEX_PRIORITY_TABLE_CMD, CMD_SYNC,
265                                 sizeof(coex_cmd), &coex_cmd);
266 }
267
268 static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
269         ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
270                 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
271         ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
272                 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
273         ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
274                 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
275         ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
276                 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
277         ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
278                 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
279         ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
280                 (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
281         ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
282                 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
283         ((BT_COEX_PRIO_TBL_PRIO_COEX_OFF << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
284                 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
285         ((BT_COEX_PRIO_TBL_PRIO_COEX_ON << IWL_BT_COEX_PRIO_TBL_PRIO_POS) |
286                 (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)),
287         0, 0, 0, 0, 0, 0, 0
288 };
289
290 void iwl_send_prio_tbl(struct iwl_priv *priv)
291 {
292         struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd;
293
294         memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl,
295                 sizeof(iwl_bt_prio_tbl));
296         if (iwl_dvm_send_cmd_pdu(priv,
297                                 REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC,
298                                 sizeof(prio_tbl_cmd), &prio_tbl_cmd))
299                 IWL_ERR(priv, "failed to send BT prio tbl command\n");
300 }
301
302 int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
303 {
304         struct iwl_bt_coex_prot_env_cmd env_cmd;
305         int ret;
306
307         env_cmd.action = action;
308         env_cmd.type = type;
309         ret = iwl_dvm_send_cmd_pdu(priv,
310                                REPLY_BT_COEX_PROT_ENV, CMD_SYNC,
311                                sizeof(env_cmd), &env_cmd);
312         if (ret)
313                 IWL_ERR(priv, "failed to send BT env command\n");
314         return ret;
315 }
316
317
318 static int iwl_alive_notify(struct iwl_priv *priv)
319 {
320         struct iwl_rxon_context *ctx;
321         int ret;
322
323         if (!priv->tx_cmd_pool)
324                 priv->tx_cmd_pool =
325                         kmem_cache_create("iwl_dev_cmd",
326                                           sizeof(struct iwl_device_cmd),
327                                           sizeof(void *), 0, NULL);
328
329         if (!priv->tx_cmd_pool)
330                 return -ENOMEM;
331
332         iwl_trans_fw_alive(trans(priv));
333         for_each_context(priv, ctx)
334                 ctx->last_tx_rejected = false;
335
336         ret = iwl_send_wimax_coex(priv);
337         if (ret)
338                 return ret;
339
340         if (!cfg(priv)->no_xtal_calib) {
341                 ret = iwl_set_Xtal_calib(priv);
342                 if (ret)
343                         return ret;
344         }
345
346         return iwl_send_calib_results(priv);
347 }
348
349
350 /**
351  * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
352  *   using sample data 100 bytes apart.  If these sample points are good,
353  *   it's a pretty good bet that everything between them is good, too.
354  */
355 static int iwl_verify_inst_sparse(struct iwl_priv *priv,
356                                   const struct fw_desc *fw_desc)
357 {
358         __le32 *image = (__le32 *)fw_desc->v_addr;
359         u32 len = fw_desc->len;
360         u32 val;
361         u32 i;
362
363         IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
364
365         for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
366                 /* read data comes through single port, auto-incr addr */
367                 /* NOTE: Use the debugless read so we don't flood kernel log
368                  * if IWL_DL_IO is set */
369                 iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR,
370                         i + IWLAGN_RTC_INST_LOWER_BOUND);
371                 val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
372                 if (val != le32_to_cpu(*image))
373                         return -EIO;
374         }
375
376         return 0;
377 }
378
379 static void iwl_print_mismatch_inst(struct iwl_priv *priv,
380                                     const struct fw_desc *fw_desc)
381 {
382         __le32 *image = (__le32 *)fw_desc->v_addr;
383         u32 len = fw_desc->len;
384         u32 val;
385         u32 offs;
386         int errors = 0;
387
388         IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
389
390         iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR,
391                            IWLAGN_RTC_INST_LOWER_BOUND);
392
393         for (offs = 0;
394              offs < len && errors < 20;
395              offs += sizeof(u32), image++) {
396                 /* read data comes through single port, auto-incr addr */
397                 val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
398                 if (val != le32_to_cpu(*image)) {
399                         IWL_ERR(priv, "uCode INST section at "
400                                 "offset 0x%x, is 0x%x, s/b 0x%x\n",
401                                 offs, val, le32_to_cpu(*image));
402                         errors++;
403                 }
404         }
405 }
406
407 /**
408  * iwl_verify_ucode - determine which instruction image is in SRAM,
409  *    and verify its contents
410  */
411 static int iwl_verify_ucode(struct iwl_priv *priv,
412                             enum iwl_ucode_type ucode_type)
413 {
414         const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type);
415
416         if (!img) {
417                 IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type);
418                 return -EINVAL;
419         }
420
421         if (!iwl_verify_inst_sparse(priv, &img->code)) {
422                 IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n");
423                 return 0;
424         }
425
426         IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
427
428         iwl_print_mismatch_inst(priv, &img->code);
429         return -EIO;
430 }
431
432 struct iwl_alive_data {
433         bool valid;
434         u8 subtype;
435 };
436
437 static void iwl_alive_fn(struct iwl_priv *priv,
438                             struct iwl_rx_packet *pkt,
439                             void *data)
440 {
441         struct iwl_alive_data *alive_data = data;
442         struct iwl_alive_resp *palive;
443
444         palive = &pkt->u.alive_frame;
445
446         IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision "
447                        "0x%01X 0x%01X\n",
448                        palive->is_valid, palive->ver_type,
449                        palive->ver_subtype);
450
451         priv->shrd->device_pointers.error_event_table =
452                 le32_to_cpu(palive->error_event_table_ptr);
453         priv->shrd->device_pointers.log_event_table =
454                 le32_to_cpu(palive->log_event_table_ptr);
455
456         alive_data->subtype = palive->ver_subtype;
457         alive_data->valid = palive->is_valid == UCODE_VALID_OK;
458 }
459
460 /* notification wait support */
461 void iwl_init_notification_wait(struct iwl_shared *shrd,
462                                 struct iwl_notification_wait *wait_entry,
463                                 u8 cmd,
464                                 void (*fn)(struct iwl_priv *priv,
465                                            struct iwl_rx_packet *pkt,
466                                            void *data),
467                                 void *fn_data)
468 {
469         wait_entry->fn = fn;
470         wait_entry->fn_data = fn_data;
471         wait_entry->cmd = cmd;
472         wait_entry->triggered = false;
473         wait_entry->aborted = false;
474
475         spin_lock_bh(&shrd->notif_wait_lock);
476         list_add(&wait_entry->list, &shrd->notif_waits);
477         spin_unlock_bh(&shrd->notif_wait_lock);
478 }
479
480 int iwl_wait_notification(struct iwl_shared *shrd,
481                              struct iwl_notification_wait *wait_entry,
482                              unsigned long timeout)
483 {
484         int ret;
485
486         ret = wait_event_timeout(shrd->notif_waitq,
487                                  wait_entry->triggered || wait_entry->aborted,
488                                  timeout);
489
490         spin_lock_bh(&shrd->notif_wait_lock);
491         list_del(&wait_entry->list);
492         spin_unlock_bh(&shrd->notif_wait_lock);
493
494         if (wait_entry->aborted)
495                 return -EIO;
496
497         /* return value is always >= 0 */
498         if (ret <= 0)
499                 return -ETIMEDOUT;
500         return 0;
501 }
502
503 void iwl_remove_notification(struct iwl_shared *shrd,
504                                 struct iwl_notification_wait *wait_entry)
505 {
506         spin_lock_bh(&shrd->notif_wait_lock);
507         list_del(&wait_entry->list);
508         spin_unlock_bh(&shrd->notif_wait_lock);
509 }
510
511 void iwl_abort_notification_waits(struct iwl_shared *shrd)
512 {
513         unsigned long flags;
514         struct iwl_notification_wait *wait_entry;
515
516         spin_lock_irqsave(&shrd->notif_wait_lock, flags);
517         list_for_each_entry(wait_entry, &shrd->notif_waits, list)
518                 wait_entry->aborted = true;
519         spin_unlock_irqrestore(&shrd->notif_wait_lock, flags);
520
521         wake_up_all(&shrd->notif_waitq);
522 }
523
524 #define UCODE_ALIVE_TIMEOUT     HZ
525 #define UCODE_CALIB_TIMEOUT     (2*HZ)
526
527 int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
528                                  enum iwl_ucode_type ucode_type)
529 {
530         struct iwl_notification_wait alive_wait;
531         struct iwl_alive_data alive_data;
532         const struct fw_img *fw;
533         int ret;
534         enum iwl_ucode_type old_type;
535
536         iwl_init_notification_wait(priv->shrd, &alive_wait, REPLY_ALIVE,
537                                       iwl_alive_fn, &alive_data);
538
539         old_type = priv->shrd->ucode_type;
540         priv->shrd->ucode_type = ucode_type;
541         fw = iwl_get_ucode_image(priv, ucode_type);
542
543         if (!fw)
544                 return -EINVAL;
545
546         ret = iwl_trans_start_fw(trans(priv), fw);
547         if (ret) {
548                 priv->shrd->ucode_type = old_type;
549                 iwl_remove_notification(priv->shrd, &alive_wait);
550                 return ret;
551         }
552
553         /*
554          * Some things may run in the background now, but we
555          * just wait for the ALIVE notification here.
556          */
557         ret = iwl_wait_notification(priv->shrd, &alive_wait,
558                                         UCODE_ALIVE_TIMEOUT);
559         if (ret) {
560                 priv->shrd->ucode_type = old_type;
561                 return ret;
562         }
563
564         if (!alive_data.valid) {
565                 IWL_ERR(priv, "Loaded ucode is not valid!\n");
566                 priv->shrd->ucode_type = old_type;
567                 return -EIO;
568         }
569
570         /*
571          * This step takes a long time (60-80ms!!) and
572          * WoWLAN image should be loaded quickly, so
573          * skip it for WoWLAN.
574          */
575         if (ucode_type != IWL_UCODE_WOWLAN) {
576                 ret = iwl_verify_ucode(priv, ucode_type);
577                 if (ret) {
578                         priv->shrd->ucode_type = old_type;
579                         return ret;
580                 }
581
582                 /* delay a bit to give rfkill time to run */
583                 msleep(5);
584         }
585
586         ret = iwl_alive_notify(priv);
587         if (ret) {
588                 IWL_WARN(priv,
589                         "Could not complete ALIVE transition: %d\n", ret);
590                 priv->shrd->ucode_type = old_type;
591                 return ret;
592         }
593
594         return 0;
595 }
596
597 int iwl_run_init_ucode(struct iwl_priv *priv)
598 {
599         struct iwl_notification_wait calib_wait;
600         int ret;
601
602         lockdep_assert_held(&priv->shrd->mutex);
603
604         /* No init ucode required? Curious, but maybe ok */
605         if (!priv->fw->ucode_init.code.len)
606                 return 0;
607
608         if (priv->shrd->ucode_type != IWL_UCODE_NONE)
609                 return 0;
610
611         iwl_init_notification_wait(priv->shrd, &calib_wait,
612                                       CALIBRATION_COMPLETE_NOTIFICATION,
613                                       NULL, NULL);
614
615         /* Will also start the device */
616         ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);
617         if (ret)
618                 goto error;
619
620         ret = iwl_init_alive_start(priv);
621         if (ret)
622                 goto error;
623
624         /*
625          * Some things may run in the background now, but we
626          * just wait for the calibration complete notification.
627          */
628         ret = iwl_wait_notification(priv->shrd, &calib_wait,
629                                         UCODE_CALIB_TIMEOUT);
630
631         goto out;
632
633  error:
634         iwl_remove_notification(priv->shrd, &calib_wait);
635  out:
636         /* Whatever happened, stop the device */
637         iwl_trans_stop_device(trans(priv));
638         return ret;
639 }