]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/wireless/iwlwifi/iwl-drv.c
iwlwifi: split out firmware store
[mirror_ubuntu-artful-kernel.git] / drivers / net / wireless / iwlwifi / iwl-drv.c
CommitLineData
5c58edc6
EG
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include <linux/completion.h>
15854ef9
JB
64#include <linux/dma-mapping.h>
65#include <linux/firmware.h>
66#include <linux/module.h>
5c58edc6
EG
67
68#include "iwl-drv.h"
69#include "iwl-trans.h"
70#include "iwl-wifi.h"
15854ef9 71#include "iwl-shared.h"
d0f76d68 72#include "iwl-op-mode.h"
5c58edc6 73
0692fe41
JB
74/* private includes */
75#include "iwl-ucode.h"
76
15854ef9
JB
77static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc)
78{
79 if (desc->v_addr)
80 dma_free_coherent(trans(nic)->dev, desc->len,
81 desc->v_addr, desc->p_addr);
82 desc->v_addr = NULL;
83 desc->len = 0;
84}
85
86static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img)
87{
88 iwl_free_fw_desc(nic, &img->code);
89 iwl_free_fw_desc(nic, &img->data);
90}
91
92static void iwl_dealloc_ucode(struct iwl_nic *nic)
93{
94 iwl_free_fw_img(nic, &nic->fw.ucode_rt);
95 iwl_free_fw_img(nic, &nic->fw.ucode_init);
96 iwl_free_fw_img(nic, &nic->fw.ucode_wowlan);
97}
98
99static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc,
100 const void *data, size_t len)
101{
102 if (!len) {
103 desc->v_addr = NULL;
104 return -EINVAL;
105 }
106
107 desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len,
108 &desc->p_addr, GFP_KERNEL);
109 if (!desc->v_addr)
110 return -ENOMEM;
111
112 desc->len = len;
113 memcpy(desc->v_addr, data, len);
114 return 0;
115}
116
117static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
118
119#define UCODE_EXPERIMENTAL_INDEX 100
120#define UCODE_EXPERIMENTAL_TAG "exp"
121
122static int iwl_request_firmware(struct iwl_nic *nic, bool first)
123{
124 const struct iwl_cfg *cfg = cfg(nic);
125 const char *name_pre = cfg->fw_name_pre;
126 char tag[8];
127
128 if (first) {
129#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
130 nic->fw_index = UCODE_EXPERIMENTAL_INDEX;
131 strcpy(tag, UCODE_EXPERIMENTAL_TAG);
132 } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) {
133#endif
134 nic->fw_index = cfg->ucode_api_max;
135 sprintf(tag, "%d", nic->fw_index);
136 } else {
137 nic->fw_index--;
138 sprintf(tag, "%d", nic->fw_index);
139 }
140
141 if (nic->fw_index < cfg->ucode_api_min) {
142 IWL_ERR(nic, "no suitable firmware found!\n");
143 return -ENOENT;
144 }
145
146 sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
147
148 IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n",
149 (nic->fw_index == UCODE_EXPERIMENTAL_INDEX)
150 ? "EXPERIMENTAL " : "",
151 nic->firmware_name);
152
153 return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name,
154 trans(nic)->dev,
155 GFP_KERNEL, nic, iwl_ucode_callback);
156}
157
158struct iwlagn_firmware_pieces {
159 const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
160 size_t inst_size, data_size, init_size, init_data_size,
161 wowlan_inst_size, wowlan_data_size;
162
163 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
164 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
165};
166
167static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic,
168 const struct firmware *ucode_raw,
169 struct iwlagn_firmware_pieces *pieces)
170{
171 struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
172 u32 api_ver, hdr_size, build;
173 char buildstr[25];
174 const u8 *src;
175
176 nic->fw.ucode_ver = le32_to_cpu(ucode->ver);
177 api_ver = IWL_UCODE_API(nic->fw.ucode_ver);
178
179 switch (api_ver) {
180 default:
181 hdr_size = 28;
182 if (ucode_raw->size < hdr_size) {
183 IWL_ERR(nic, "File size too small!\n");
184 return -EINVAL;
185 }
186 build = le32_to_cpu(ucode->u.v2.build);
187 pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
188 pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
189 pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
190 pieces->init_data_size =
191 le32_to_cpu(ucode->u.v2.init_data_size);
192 src = ucode->u.v2.data;
193 break;
194 case 0:
195 case 1:
196 case 2:
197 hdr_size = 24;
198 if (ucode_raw->size < hdr_size) {
199 IWL_ERR(nic, "File size too small!\n");
200 return -EINVAL;
201 }
202 build = 0;
203 pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
204 pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
205 pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
206 pieces->init_data_size =
207 le32_to_cpu(ucode->u.v1.init_data_size);
208 src = ucode->u.v1.data;
209 break;
210 }
211
212 if (build)
213 sprintf(buildstr, " build %u%s", build,
214 (nic->fw_index == UCODE_EXPERIMENTAL_INDEX)
215 ? " (EXP)" : "");
216 else
217 buildstr[0] = '\0';
218
219 snprintf(nic->fw.fw_version,
220 sizeof(nic->fw.fw_version),
221 "%u.%u.%u.%u%s",
222 IWL_UCODE_MAJOR(nic->fw.ucode_ver),
223 IWL_UCODE_MINOR(nic->fw.ucode_ver),
224 IWL_UCODE_API(nic->fw.ucode_ver),
225 IWL_UCODE_SERIAL(nic->fw.ucode_ver),
226 buildstr);
227
228 /* Verify size of file vs. image size info in file's header */
229 if (ucode_raw->size != hdr_size + pieces->inst_size +
230 pieces->data_size + pieces->init_size +
231 pieces->init_data_size) {
232
233 IWL_ERR(nic,
234 "uCode file size %d does not match expected size\n",
235 (int)ucode_raw->size);
236 return -EINVAL;
237 }
238
239 pieces->inst = src;
240 src += pieces->inst_size;
241 pieces->data = src;
242 src += pieces->data_size;
243 pieces->init = src;
244 src += pieces->init_size;
245 pieces->init_data = src;
246 src += pieces->init_data_size;
247
248 return 0;
249}
250
251static int iwl_parse_tlv_firmware(struct iwl_nic *nic,
252 const struct firmware *ucode_raw,
253 struct iwlagn_firmware_pieces *pieces,
254 struct iwl_ucode_capabilities *capa)
255{
256 struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
257 struct iwl_ucode_tlv *tlv;
258 size_t len = ucode_raw->size;
259 const u8 *data;
260 int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
261 int tmp;
262 u64 alternatives;
263 u32 tlv_len;
264 enum iwl_ucode_tlv_type tlv_type;
265 const u8 *tlv_data;
266 char buildstr[25];
267 u32 build;
268
269 if (len < sizeof(*ucode)) {
270 IWL_ERR(nic, "uCode has invalid length: %zd\n", len);
271 return -EINVAL;
272 }
273
274 if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
275 IWL_ERR(nic, "invalid uCode magic: 0X%x\n",
276 le32_to_cpu(ucode->magic));
277 return -EINVAL;
278 }
279
280 /*
281 * Check which alternatives are present, and "downgrade"
282 * when the chosen alternative is not present, warning
283 * the user when that happens. Some files may not have
284 * any alternatives, so don't warn in that case.
285 */
286 alternatives = le64_to_cpu(ucode->alternatives);
287 tmp = wanted_alternative;
288 if (wanted_alternative > 63)
289 wanted_alternative = 63;
290 while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
291 wanted_alternative--;
292 if (wanted_alternative && wanted_alternative != tmp)
293 IWL_WARN(nic,
294 "uCode alternative %d not available, choosing %d\n",
295 tmp, wanted_alternative);
296
297 nic->fw.ucode_ver = le32_to_cpu(ucode->ver);
298 build = le32_to_cpu(ucode->build);
299
300 if (build)
301 sprintf(buildstr, " build %u%s", build,
302 (nic->fw_index == UCODE_EXPERIMENTAL_INDEX)
303 ? " (EXP)" : "");
304 else
305 buildstr[0] = '\0';
306
307 snprintf(nic->fw.fw_version,
308 sizeof(nic->fw.fw_version),
309 "%u.%u.%u.%u%s",
310 IWL_UCODE_MAJOR(nic->fw.ucode_ver),
311 IWL_UCODE_MINOR(nic->fw.ucode_ver),
312 IWL_UCODE_API(nic->fw.ucode_ver),
313 IWL_UCODE_SERIAL(nic->fw.ucode_ver),
314 buildstr);
315
316 data = ucode->data;
317
318 len -= sizeof(*ucode);
319
320 while (len >= sizeof(*tlv)) {
321 u16 tlv_alt;
322
323 len -= sizeof(*tlv);
324 tlv = (void *)data;
325
326 tlv_len = le32_to_cpu(tlv->length);
327 tlv_type = le16_to_cpu(tlv->type);
328 tlv_alt = le16_to_cpu(tlv->alternative);
329 tlv_data = tlv->data;
330
331 if (len < tlv_len) {
332 IWL_ERR(nic, "invalid TLV len: %zd/%u\n",
333 len, tlv_len);
334 return -EINVAL;
335 }
336 len -= ALIGN(tlv_len, 4);
337 data += sizeof(*tlv) + ALIGN(tlv_len, 4);
338
339 /*
340 * Alternative 0 is always valid.
341 *
342 * Skip alternative TLVs that are not selected.
343 */
344 if (tlv_alt != 0 && tlv_alt != wanted_alternative)
345 continue;
346
347 switch (tlv_type) {
348 case IWL_UCODE_TLV_INST:
349 pieces->inst = tlv_data;
350 pieces->inst_size = tlv_len;
351 break;
352 case IWL_UCODE_TLV_DATA:
353 pieces->data = tlv_data;
354 pieces->data_size = tlv_len;
355 break;
356 case IWL_UCODE_TLV_INIT:
357 pieces->init = tlv_data;
358 pieces->init_size = tlv_len;
359 break;
360 case IWL_UCODE_TLV_INIT_DATA:
361 pieces->init_data = tlv_data;
362 pieces->init_data_size = tlv_len;
363 break;
364 case IWL_UCODE_TLV_BOOT:
365 IWL_ERR(nic, "Found unexpected BOOT ucode\n");
366 break;
367 case IWL_UCODE_TLV_PROBE_MAX_LEN:
368 if (tlv_len != sizeof(u32))
369 goto invalid_tlv_len;
370 capa->max_probe_length =
371 le32_to_cpup((__le32 *)tlv_data);
372 break;
373 case IWL_UCODE_TLV_PAN:
374 if (tlv_len)
375 goto invalid_tlv_len;
376 capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
377 break;
378 case IWL_UCODE_TLV_FLAGS:
379 /* must be at least one u32 */
380 if (tlv_len < sizeof(u32))
381 goto invalid_tlv_len;
382 /* and a proper number of u32s */
383 if (tlv_len % sizeof(u32))
384 goto invalid_tlv_len;
385 /*
386 * This driver only reads the first u32 as
387 * right now no more features are defined,
388 * if that changes then either the driver
389 * will not work with the new firmware, or
390 * it'll not take advantage of new features.
391 */
392 capa->flags = le32_to_cpup((__le32 *)tlv_data);
393 break;
394 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
395 if (tlv_len != sizeof(u32))
396 goto invalid_tlv_len;
397 pieces->init_evtlog_ptr =
398 le32_to_cpup((__le32 *)tlv_data);
399 break;
400 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
401 if (tlv_len != sizeof(u32))
402 goto invalid_tlv_len;
403 pieces->init_evtlog_size =
404 le32_to_cpup((__le32 *)tlv_data);
405 break;
406 case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
407 if (tlv_len != sizeof(u32))
408 goto invalid_tlv_len;
409 pieces->init_errlog_ptr =
410 le32_to_cpup((__le32 *)tlv_data);
411 break;
412 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
413 if (tlv_len != sizeof(u32))
414 goto invalid_tlv_len;
415 pieces->inst_evtlog_ptr =
416 le32_to_cpup((__le32 *)tlv_data);
417 break;
418 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
419 if (tlv_len != sizeof(u32))
420 goto invalid_tlv_len;
421 pieces->inst_evtlog_size =
422 le32_to_cpup((__le32 *)tlv_data);
423 break;
424 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
425 if (tlv_len != sizeof(u32))
426 goto invalid_tlv_len;
427 pieces->inst_errlog_ptr =
428 le32_to_cpup((__le32 *)tlv_data);
429 break;
430 case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
431 if (tlv_len)
432 goto invalid_tlv_len;
433 nic->fw.enhance_sensitivity_table = true;
434 break;
435 case IWL_UCODE_TLV_WOWLAN_INST:
436 pieces->wowlan_inst = tlv_data;
437 pieces->wowlan_inst_size = tlv_len;
438 break;
439 case IWL_UCODE_TLV_WOWLAN_DATA:
440 pieces->wowlan_data = tlv_data;
441 pieces->wowlan_data_size = tlv_len;
442 break;
443 case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
444 if (tlv_len != sizeof(u32))
445 goto invalid_tlv_len;
446 capa->standard_phy_calibration_size =
447 le32_to_cpup((__le32 *)tlv_data);
448 break;
449 default:
450 IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type);
451 break;
452 }
453 }
454
455 if (len) {
456 IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len);
457 iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len);
458 return -EINVAL;
459 }
460
461 return 0;
462
463 invalid_tlv_len:
464 IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
465 iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len);
466
467 return -EINVAL;
468}
469
470/**
471 * iwl_ucode_callback - callback when firmware was loaded
472 *
473 * If loaded successfully, copies the firmware into buffers
474 * for the card to fetch (via DMA).
475 */
476static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
477{
478 struct iwl_nic *nic = context;
479 const struct iwl_cfg *cfg = cfg(nic);
480 struct iwl_fw *fw = &nic->fw;
481 struct iwl_ucode_header *ucode;
482 int err;
483 struct iwlagn_firmware_pieces pieces;
484 const unsigned int api_max = cfg->ucode_api_max;
485 unsigned int api_ok = cfg->ucode_api_ok;
486 const unsigned int api_min = cfg->ucode_api_min;
487 u32 api_ver;
488
489 fw->ucode_capa.max_probe_length = 200;
490 fw->ucode_capa.standard_phy_calibration_size =
491 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
492
493 if (!api_ok)
494 api_ok = api_max;
495
496 memset(&pieces, 0, sizeof(pieces));
497
498 if (!ucode_raw) {
499 if (nic->fw_index <= api_ok)
500 IWL_ERR(nic,
501 "request for firmware file '%s' failed.\n",
502 nic->firmware_name);
503 goto try_again;
504 }
505
506 IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n",
507 nic->firmware_name, ucode_raw->size);
508
509 /* Make sure that we got at least the API version number */
510 if (ucode_raw->size < 4) {
511 IWL_ERR(nic, "File size way too small!\n");
512 goto try_again;
513 }
514
515 /* Data from ucode file: header followed by uCode images */
516 ucode = (struct iwl_ucode_header *)ucode_raw->data;
517
518 if (ucode->ver)
519 err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces);
520 else
521 err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces,
522 &fw->ucode_capa);
523
524 if (err)
525 goto try_again;
526
527 api_ver = IWL_UCODE_API(nic->fw.ucode_ver);
528
529 /*
530 * api_ver should match the api version forming part of the
531 * firmware filename ... but we don't check for that and only rely
532 * on the API version read from firmware header from here on forward
533 */
534 /* no api version check required for experimental uCode */
535 if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) {
536 if (api_ver < api_min || api_ver > api_max) {
537 IWL_ERR(nic,
538 "Driver unable to support your firmware API. "
539 "Driver supports v%u, firmware is v%u.\n",
540 api_max, api_ver);
541 goto try_again;
542 }
543
544 if (api_ver < api_ok) {
545 if (api_ok != api_max)
546 IWL_ERR(nic, "Firmware has old API version, "
547 "expected v%u through v%u, got v%u.\n",
548 api_ok, api_max, api_ver);
549 else
550 IWL_ERR(nic, "Firmware has old API version, "
551 "expected v%u, got v%u.\n",
552 api_max, api_ver);
553 IWL_ERR(nic, "New firmware can be obtained from "
554 "http://www.intellinuxwireless.org/.\n");
555 }
556 }
557
558 IWL_INFO(nic, "loaded firmware version %s", nic->fw.fw_version);
559
560 /*
561 * For any of the failures below (before allocating pci memory)
562 * we will try to load a version with a smaller API -- maybe the
563 * user just got a corrupted version of the latest API.
564 */
565
566 IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n",
567 nic->fw.ucode_ver);
568 IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n",
569 pieces.inst_size);
570 IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n",
571 pieces.data_size);
572 IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n",
573 pieces.init_size);
574 IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n",
575 pieces.init_data_size);
576
577 /* Verify that uCode images will fit in card's SRAM */
578 if (pieces.inst_size > cfg->max_inst_size) {
579 IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n",
580 pieces.inst_size);
581 goto try_again;
582 }
583
584 if (pieces.data_size > cfg->max_data_size) {
585 IWL_ERR(nic, "uCode data len %Zd too large to fit in\n",
586 pieces.data_size);
587 goto try_again;
588 }
589
590 if (pieces.init_size > cfg->max_inst_size) {
591 IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n",
592 pieces.init_size);
593 goto try_again;
594 }
595
596 if (pieces.init_data_size > cfg->max_data_size) {
597 IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n",
598 pieces.init_data_size);
599 goto try_again;
600 }
601
602 /* Allocate ucode buffers for card's bus-master loading ... */
603
604 /* Runtime instructions and 2 copies of data:
605 * 1) unmodified from disk
606 * 2) backup cache for save/restore during power-downs */
607 if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code,
608 pieces.inst, pieces.inst_size))
609 goto err_pci_alloc;
610 if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data,
611 pieces.data, pieces.data_size))
612 goto err_pci_alloc;
613
614 /* Initialization instructions and data */
615 if (pieces.init_size && pieces.init_data_size) {
616 if (iwl_alloc_fw_desc(nic,
617 &nic->fw.ucode_init.code,
618 pieces.init, pieces.init_size))
619 goto err_pci_alloc;
620 if (iwl_alloc_fw_desc(nic,
621 &nic->fw.ucode_init.data,
622 pieces.init_data, pieces.init_data_size))
623 goto err_pci_alloc;
624 }
625
626 /* WoWLAN instructions and data */
627 if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
628 if (iwl_alloc_fw_desc(nic,
629 &nic->fw.ucode_wowlan.code,
630 pieces.wowlan_inst,
631 pieces.wowlan_inst_size))
632 goto err_pci_alloc;
633 if (iwl_alloc_fw_desc(nic,
634 &nic->fw.ucode_wowlan.data,
635 pieces.wowlan_data,
636 pieces.wowlan_data_size))
637 goto err_pci_alloc;
638 }
639
640 /* Now that we can no longer fail, copy information */
641
642 /*
643 * The (size - 16) / 12 formula is based on the information recorded
644 * for each event, which is of mode 1 (including timestamp) for all
645 * new microcodes that include this information.
646 */
0692fe41 647 fw->init_evtlog_ptr = pieces.init_evtlog_ptr;
15854ef9 648 if (pieces.init_evtlog_size)
0692fe41 649 fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
15854ef9 650 else
0692fe41 651 fw->init_evtlog_size =
15854ef9 652 cfg->base_params->max_event_log_size;
0692fe41
JB
653 fw->init_errlog_ptr = pieces.init_errlog_ptr;
654 fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
15854ef9 655 if (pieces.inst_evtlog_size)
0692fe41 656 fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
15854ef9 657 else
0692fe41 658 fw->inst_evtlog_size =
15854ef9 659 cfg->base_params->max_event_log_size;
0692fe41 660 fw->inst_errlog_ptr = pieces.inst_errlog_ptr;
15854ef9
JB
661
662 /*
663 * figure out the offset of chain noise reset and gain commands
664 * base on the size of standard phy calibration commands table size
665 */
666 if (fw->ucode_capa.standard_phy_calibration_size >
667 IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
668 fw->ucode_capa.standard_phy_calibration_size =
669 IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
670
671 /* We have our copies now, allow OS release its copies */
672 release_firmware(ucode_raw);
673 complete(&nic->request_firmware_complete);
674
0692fe41 675 nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans, &nic->fw);
15854ef9
JB
676
677 if (!nic->op_mode)
678 goto out_unbind;
679
680 return;
681
682 try_again:
683 /* try next, if any */
684 release_firmware(ucode_raw);
685 if (iwl_request_firmware(nic, false))
686 goto out_unbind;
687 return;
688
689 err_pci_alloc:
690 IWL_ERR(nic, "failed to allocate pci memory\n");
691 iwl_dealloc_ucode(nic);
692 release_firmware(ucode_raw);
693 out_unbind:
694 complete(&nic->request_firmware_complete);
695 device_release_driver(trans(nic)->dev);
696}
697
5c58edc6 698int iwl_drv_start(struct iwl_shared *shrd,
706c4ff6 699 struct iwl_trans *trans, const struct iwl_cfg *cfg)
5c58edc6 700{
0692fe41 701 struct iwl_nic *nic;
5c58edc6
EG
702 int ret;
703
704 shrd->cfg = cfg;
705
0692fe41
JB
706 nic = kzalloc(sizeof(*nic), GFP_KERNEL);
707 if (!nic) {
5c58edc6
EG
708 dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_nic");
709 return -ENOMEM;
710 }
0692fe41
JB
711 nic->shrd = shrd;
712 shrd->nic = nic;
5c58edc6 713
0692fe41 714 init_completion(&nic->request_firmware_complete);
5c58edc6 715
0692fe41 716 ret = iwl_request_firmware(nic, true);
5c58edc6
EG
717
718 if (ret) {
719 dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw");
0692fe41
JB
720 kfree(nic);
721 shrd->nic = NULL;
5c58edc6
EG
722 }
723
724 return ret;
725}
726
07590f08
EG
727void iwl_drv_stop(struct iwl_shared *shrd)
728{
0692fe41
JB
729 struct iwl_nic *nic = shrd->nic;
730
731 wait_for_completion(&nic->request_firmware_complete);
2e7eb117 732
d0f76d68 733 /* op_mode can be NULL if its start failed */
0692fe41
JB
734 if (nic->op_mode)
735 iwl_op_mode_stop(nic->op_mode);
07590f08 736
0692fe41 737 iwl_dealloc_ucode(nic);
7db5b989 738
0692fe41
JB
739 kfree(nic);
740 shrd->nic = NULL;
07590f08 741}