xref: /openbmc/linux/drivers/net/wireless/ti/wlcore/boot.c (revision d0b73b48)
1 /*
2  * This file is part of wl1271
3  *
4  * Copyright (C) 2008-2010 Nokia Corporation
5  *
6  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
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 {
168 	struct wlcore_partition_set partition;
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 
240 int wlcore_boot_upload_firmware(struct wl1271 *wl)
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 }
272 EXPORT_SYMBOL_GPL(wlcore_boot_upload_firmware);
273 
274 int wlcore_boot_upload_nvs(struct wl1271 *wl)
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) ||
296 		    wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
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) &&
302 		    (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
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 
375 			wl1271_debug(DEBUG_BOOT,
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 }
426 EXPORT_SYMBOL_GPL(wlcore_boot_upload_nvs);
427 
428 int wlcore_boot_run_firmware(struct wl1271 *wl)
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) {
456 		udelay(INIT_LOOP_DELAY);
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  */
511 	wl->event_mask = BSS_LOSE_EVENT_ID |
512 		REGAINED_BSS_EVENT_ID |
513 		SCAN_COMPLETE_EVENT_ID |
514 		ROLE_STOP_COMPLETE_EVENT_ID |
515 		RSSI_SNR_TRIGGER_0_EVENT_ID |
516 		PSPOLL_DELIVERY_FAILURE_EVENT_ID |
517 		SOFT_GEMINI_SENSE_EVENT_ID |
518 		PERIODIC_SCAN_REPORT_EVENT_ID |
519 		PERIODIC_SCAN_COMPLETE_EVENT_ID |
520 		DUMMY_PACKET_EVENT_ID |
521 		PEER_REMOVE_COMPLETE_EVENT_ID |
522 		BA_SESSION_RX_CONSTRAINT_EVENT_ID |
523 		REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
524 		INACTIVE_STA_EVENT_ID |
525 		MAX_TX_RETRY_EVENT_ID |
526 		CHANNEL_SWITCH_COMPLETE_EVENT_ID;
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 }
540 EXPORT_SYMBOL_GPL(wlcore_boot_run_firmware);
541