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