Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
boot.c
Go to the documentation of this file.
1 /*
2  * This file is part of wl1271
3  *
4  * Copyright (C) 2008-2010 Nokia Corporation
5  *
6  * Contact: Luciano Coelho <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23 
24 #include <linux/slab.h>
25 #include <linux/wl12xx.h>
26 #include <linux/export.h>
27 
28 #include "debug.h"
29 #include "acx.h"
30 #include "boot.h"
31 #include "io.h"
32 #include "event.h"
33 #include "rx.h"
34 #include "hw_ops.h"
35 
36 static int wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
37 {
38  u32 cpu_ctrl;
39  int ret;
40 
41  /* 10.5.0 run the firmware (I) */
42  ret = wlcore_read_reg(wl, REG_ECPU_CONTROL, &cpu_ctrl);
43  if (ret < 0)
44  goto out;
45 
46  /* 10.5.1 run the firmware (II) */
47  cpu_ctrl |= flag;
48  ret = wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl);
49 
50 out:
51  return ret;
52 }
53 
54 static int wlcore_boot_parse_fw_ver(struct wl1271 *wl,
55  struct wl1271_static_data *static_data)
56 {
57  int ret;
58 
59  strncpy(wl->chip.fw_ver_str, static_data->fw_version,
60  sizeof(wl->chip.fw_ver_str));
61 
62  /* make sure the string is NULL-terminated */
63  wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
64 
65  ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
66  &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
67  &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
68  &wl->chip.fw_ver[4]);
69 
70  if (ret != 5) {
71  wl1271_warning("fw version incorrect value");
72  memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
73  ret = -EINVAL;
74  goto out;
75  }
76 
77  ret = wlcore_identify_fw(wl);
78  if (ret < 0)
79  goto out;
80 out:
81  return ret;
82 }
83 
84 static int wlcore_validate_fw_ver(struct wl1271 *wl)
85 {
86  unsigned int *fw_ver = wl->chip.fw_ver;
87  unsigned int *min_ver = wl->min_fw_ver;
88 
89  /* the chip must be exactly equal */
90  if (min_ver[FW_VER_CHIP] != fw_ver[FW_VER_CHIP])
91  goto fail;
92 
93  /* always check the next digit if all previous ones are equal */
94 
95  if (min_ver[FW_VER_IF_TYPE] < fw_ver[FW_VER_IF_TYPE])
96  goto out;
97  else if (min_ver[FW_VER_IF_TYPE] > fw_ver[FW_VER_IF_TYPE])
98  goto fail;
99 
100  if (min_ver[FW_VER_MAJOR] < fw_ver[FW_VER_MAJOR])
101  goto out;
102  else if (min_ver[FW_VER_MAJOR] > fw_ver[FW_VER_MAJOR])
103  goto fail;
104 
105  if (min_ver[FW_VER_SUBTYPE] < fw_ver[FW_VER_SUBTYPE])
106  goto out;
107  else if (min_ver[FW_VER_SUBTYPE] > fw_ver[FW_VER_SUBTYPE])
108  goto fail;
109 
110  if (min_ver[FW_VER_MINOR] < fw_ver[FW_VER_MINOR])
111  goto out;
112  else if (min_ver[FW_VER_MINOR] > fw_ver[FW_VER_MINOR])
113  goto fail;
114 
115 out:
116  return 0;
117 
118 fail:
119  wl1271_error("Your WiFi FW version (%u.%u.%u.%u.%u) is outdated.\n"
120  "Please use at least FW %u.%u.%u.%u.%u.\n"
121  "You can get more information at:\n"
122  "http://wireless.kernel.org/en/users/Drivers/wl12xx",
123  fw_ver[FW_VER_CHIP], fw_ver[FW_VER_IF_TYPE],
124  fw_ver[FW_VER_MAJOR], fw_ver[FW_VER_SUBTYPE],
125  fw_ver[FW_VER_MINOR], min_ver[FW_VER_CHIP],
126  min_ver[FW_VER_IF_TYPE], min_ver[FW_VER_MAJOR],
127  min_ver[FW_VER_SUBTYPE], min_ver[FW_VER_MINOR]);
128  return -EINVAL;
129 }
130 
131 static int wlcore_boot_static_data(struct wl1271 *wl)
132 {
133  struct wl1271_static_data *static_data;
134  size_t len = sizeof(*static_data) + wl->static_data_priv_len;
135  int ret;
136 
137  static_data = kmalloc(len, GFP_KERNEL);
138  if (!static_data) {
139  ret = -ENOMEM;
140  goto out;
141  }
142 
143  ret = wlcore_read(wl, wl->cmd_box_addr, static_data, len, false);
144  if (ret < 0)
145  goto out_free;
146 
147  ret = wlcore_boot_parse_fw_ver(wl, static_data);
148  if (ret < 0)
149  goto out_free;
150 
151  ret = wlcore_validate_fw_ver(wl);
152  if (ret < 0)
153  goto out_free;
154 
155  ret = wlcore_handle_static_data(wl, static_data);
156  if (ret < 0)
157  goto out_free;
158 
159 out_free:
160  kfree(static_data);
161 out:
162  return ret;
163 }
164 
165 static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
166  size_t fw_data_len, u32 dest)
167 {
169  int addr, chunk_num, partition_limit;
170  u8 *p, *chunk;
171  int ret;
172 
173  /* whal_FwCtrl_LoadFwImageSm() */
174 
175  wl1271_debug(DEBUG_BOOT, "starting firmware upload");
176 
177  wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
178  fw_data_len, CHUNK_SIZE);
179 
180  if ((fw_data_len % 4) != 0) {
181  wl1271_error("firmware length not multiple of four");
182  return -EIO;
183  }
184 
185  chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL);
186  if (!chunk) {
187  wl1271_error("allocation for firmware upload chunk failed");
188  return -ENOMEM;
189  }
190 
191  memcpy(&partition, &wl->ptable[PART_DOWN], sizeof(partition));
192  partition.mem.start = dest;
193  ret = wlcore_set_partition(wl, &partition);
194  if (ret < 0)
195  goto out;
196 
197  /* 10.1 set partition limit and chunk num */
198  chunk_num = 0;
199  partition_limit = wl->ptable[PART_DOWN].mem.size;
200 
201  while (chunk_num < fw_data_len / CHUNK_SIZE) {
202  /* 10.2 update partition, if needed */
203  addr = dest + (chunk_num + 2) * CHUNK_SIZE;
204  if (addr > partition_limit) {
205  addr = dest + chunk_num * CHUNK_SIZE;
206  partition_limit = chunk_num * CHUNK_SIZE +
207  wl->ptable[PART_DOWN].mem.size;
208  partition.mem.start = addr;
209  ret = wlcore_set_partition(wl, &partition);
210  if (ret < 0)
211  goto out;
212  }
213 
214  /* 10.3 upload the chunk */
215  addr = dest + chunk_num * CHUNK_SIZE;
216  p = buf + chunk_num * CHUNK_SIZE;
217  memcpy(chunk, p, CHUNK_SIZE);
218  wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
219  p, addr);
220  ret = wlcore_write(wl, addr, chunk, CHUNK_SIZE, false);
221  if (ret < 0)
222  goto out;
223 
224  chunk_num++;
225  }
226 
227  /* 10.4 upload the last chunk */
228  addr = dest + chunk_num * CHUNK_SIZE;
229  p = buf + chunk_num * CHUNK_SIZE;
230  memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
231  wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
232  fw_data_len % CHUNK_SIZE, p, addr);
233  ret = wlcore_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
234 
235 out:
236  kfree(chunk);
237  return ret;
238 }
239 
241 {
242  u32 chunks, addr, len;
243  int ret = 0;
244  u8 *fw;
245 
246  fw = wl->fw;
247  chunks = be32_to_cpup((__be32 *) fw);
248  fw += sizeof(u32);
249 
250  wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
251 
252  while (chunks--) {
253  addr = be32_to_cpup((__be32 *) fw);
254  fw += sizeof(u32);
255  len = be32_to_cpup((__be32 *) fw);
256  fw += sizeof(u32);
257 
258  if (len > 300000) {
259  wl1271_info("firmware chunk too long: %u", len);
260  return -EINVAL;
261  }
262  wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
263  chunks, addr, len);
264  ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
265  if (ret != 0)
266  break;
267  fw += len;
268  }
269 
270  return ret;
271 }
273 
275 {
276  size_t nvs_len, burst_len;
277  int i;
278  u32 dest_addr, val;
279  u8 *nvs_ptr, *nvs_aligned;
280  int ret;
281 
282  if (wl->nvs == NULL) {
283  wl1271_error("NVS file is needed during boot");
284  return -ENODEV;
285  }
286 
287  if (wl->quirks & WLCORE_QUIRK_LEGACY_NVS) {
288  struct wl1271_nvs_file *nvs =
289  (struct wl1271_nvs_file *)wl->nvs;
290  /*
291  * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
292  * band configurations) can be removed when those NVS files stop
293  * floating around.
294  */
295  if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
297  if (nvs->general_params.dual_mode_select)
298  wl->enable_11a = true;
299  }
300 
301  if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
303  wl->enable_11a)) {
304  wl1271_error("nvs size is not as expected: %zu != %zu",
305  wl->nvs_len, sizeof(struct wl1271_nvs_file));
306  kfree(wl->nvs);
307  wl->nvs = NULL;
308  wl->nvs_len = 0;
309  return -EILSEQ;
310  }
311 
312  /* only the first part of the NVS needs to be uploaded */
313  nvs_len = sizeof(nvs->nvs);
314  nvs_ptr = (u8 *) nvs->nvs;
315  } else {
316  struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
317 
318  if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
319  if (nvs->general_params.dual_mode_select)
320  wl->enable_11a = true;
321  } else {
322  wl1271_error("nvs size is not as expected: %zu != %zu",
323  wl->nvs_len,
324  sizeof(struct wl128x_nvs_file));
325  kfree(wl->nvs);
326  wl->nvs = NULL;
327  wl->nvs_len = 0;
328  return -EILSEQ;
329  }
330 
331  /* only the first part of the NVS needs to be uploaded */
332  nvs_len = sizeof(nvs->nvs);
333  nvs_ptr = (u8 *)nvs->nvs;
334  }
335 
336  /* update current MAC address to NVS */
337  nvs_ptr[11] = wl->addresses[0].addr[0];
338  nvs_ptr[10] = wl->addresses[0].addr[1];
339  nvs_ptr[6] = wl->addresses[0].addr[2];
340  nvs_ptr[5] = wl->addresses[0].addr[3];
341  nvs_ptr[4] = wl->addresses[0].addr[4];
342  nvs_ptr[3] = wl->addresses[0].addr[5];
343 
344  /*
345  * Layout before the actual NVS tables:
346  * 1 byte : burst length.
347  * 2 bytes: destination address.
348  * n bytes: data to burst copy.
349  *
350  * This is ended by a 0 length, then the NVS tables.
351  */
352 
353  /* FIXME: Do we need to check here whether the LSB is 1? */
354  while (nvs_ptr[0]) {
355  burst_len = nvs_ptr[0];
356  dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
357 
358  /*
359  * Due to our new wl1271_translate_reg_addr function,
360  * we need to add the register partition start address
361  * to the destination
362  */
363  dest_addr += wl->curr_part.reg.start;
364 
365  /* We move our pointer to the data */
366  nvs_ptr += 3;
367 
368  for (i = 0; i < burst_len; i++) {
369  if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len)
370  goto out_badnvs;
371 
372  val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
373  | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
374 
376  "nvs burst write 0x%x: 0x%x",
377  dest_addr, val);
378  ret = wlcore_write32(wl, dest_addr, val);
379  if (ret < 0)
380  return ret;
381 
382  nvs_ptr += 4;
383  dest_addr += 4;
384  }
385 
386  if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
387  goto out_badnvs;
388  }
389 
390  /*
391  * We've reached the first zero length, the first NVS table
392  * is located at an aligned offset which is at least 7 bytes further.
393  * NOTE: The wl->nvs->nvs element must be first, in order to
394  * simplify the casting, we assume it is at the beginning of
395  * the wl->nvs structure.
396  */
397  nvs_ptr = (u8 *)wl->nvs +
398  ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
399 
400  if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
401  goto out_badnvs;
402 
403  nvs_len -= nvs_ptr - (u8 *)wl->nvs;
404 
405  /* Now we must set the partition correctly */
406  ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
407  if (ret < 0)
408  return ret;
409 
410  /* Copy the NVS tables to a new block to ensure alignment */
411  nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
412  if (!nvs_aligned)
413  return -ENOMEM;
414 
415  /* And finally we upload the NVS tables */
416  ret = wlcore_write_data(wl, REG_CMD_MBOX_ADDRESS, nvs_aligned, nvs_len,
417  false);
418 
419  kfree(nvs_aligned);
420  return ret;
421 
422 out_badnvs:
423  wl1271_error("nvs data is malformed");
424  return -EILSEQ;
425 }
427 
429 {
430  int loop, ret;
431  u32 chip_id, intr;
432 
433  /* Make sure we have the boot partition */
434  ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
435  if (ret < 0)
436  return ret;
437 
438  ret = wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
439  if (ret < 0)
440  return ret;
441 
442  ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &chip_id);
443  if (ret < 0)
444  return ret;
445 
446  wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
447 
448  if (chip_id != wl->chip.id) {
449  wl1271_error("chip id doesn't match after firmware boot");
450  return -EIO;
451  }
452 
453  /* wait for init to complete */
454  loop = 0;
455  while (loop++ < INIT_LOOP) {
457  ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr);
458  if (ret < 0)
459  return ret;
460 
461  if (intr == 0xffffffff) {
462  wl1271_error("error reading hardware complete "
463  "init indication");
464  return -EIO;
465  }
466  /* check that ACX_INTR_INIT_COMPLETE is enabled */
467  else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
468  ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK,
469  WL1271_ACX_INTR_INIT_COMPLETE);
470  if (ret < 0)
471  return ret;
472  break;
473  }
474  }
475 
476  if (loop > INIT_LOOP) {
477  wl1271_error("timeout waiting for the hardware to "
478  "complete initialization");
479  return -EIO;
480  }
481 
482  /* get hardware config command mail box */
483  ret = wlcore_read_reg(wl, REG_COMMAND_MAILBOX_PTR, &wl->cmd_box_addr);
484  if (ret < 0)
485  return ret;
486 
487  wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x", wl->cmd_box_addr);
488 
489  /* get hardware config event mail box */
490  ret = wlcore_read_reg(wl, REG_EVENT_MAILBOX_PTR, &wl->mbox_ptr[0]);
491  if (ret < 0)
492  return ret;
493 
494  wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
495 
496  wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x",
497  wl->mbox_ptr[0], wl->mbox_ptr[1]);
498 
499  ret = wlcore_boot_static_data(wl);
500  if (ret < 0) {
501  wl1271_error("error getting static data");
502  return ret;
503  }
504 
505  /*
506  * in case of full asynchronous mode the firmware event must be
507  * ready to receive event from the command mailbox
508  */
509 
510  /* unmask required mbox events */
527 
528  ret = wl1271_event_unmask(wl);
529  if (ret < 0) {
530  wl1271_error("EVENT mask setting failed");
531  return ret;
532  }
533 
534  /* set the working partition to its "running" mode offset */
535  ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
536 
537  /* firmware startup completed */
538  return ret;
539 }