157 #include <linux/sched.h>
158 #include <linux/slab.h>
160 #include <linux/export.h>
164 #define D_SUBMODULE fw
168 static const __le32 i2400m_ACK_BARKER[4] = {
190 if (i2400m_brh_get_use_checksum(cmd)) {
193 const u32 *checksum_ptr = (
void *) cmd->
payload;
211 static struct i2400m_barker_db {
214 static size_t i2400m_barker_db_used, i2400m_barker_db_size;
218 int i2400m_zrealloc_2x(
void **
ptr,
size_t *_count,
size_t el_size,
221 size_t old_count = *_count,
222 new_count = old_count ? 2 * old_count : 2,
224 new_size = el_size * new_count;
225 void *nptr =
krealloc(*ptr, new_size, gfp_flags);
230 memset(nptr, 0, new_size);
248 int i2400m_barker_db_add(
u32 barker_id)
252 struct i2400m_barker_db *
barker;
253 if (i2400m_barker_db_used >= i2400m_barker_db_size) {
254 result = i2400m_zrealloc_2x(
255 (
void **) &i2400m_barker_db, &i2400m_barker_db_size,
260 barker = i2400m_barker_db + i2400m_barker_db_used++;
271 kfree(i2400m_barker_db);
272 i2400m_barker_db =
NULL;
273 i2400m_barker_db_size = 0;
274 i2400m_barker_db_used = 0;
283 int i2400m_barker_db_known_barkers(
void)
317 i2400m_barker_db =
NULL;
318 i2400m_barker_db_size = 0;
319 i2400m_barker_db_used = 0;
321 result = i2400m_barker_db_known_barkers();
325 if (_options !=
NULL) {
329 if (options_orig ==
NULL) {
333 options = options_orig;
335 while ((token =
strsep(&options,
",")) !=
NULL) {
338 if (
sscanf(token,
"%x", &barker) != 1
339 || barker > 0xffffffff) {
341 "i2400m.barkers value '%s' as "
352 result = i2400m_barker_db_add(barker);
362 kfree(i2400m_barker_db);
389 struct i2400m_barker_db *
barker;
393 if (buf_size !=
sizeof(i2400m_barker_db[i].
data))
400 unsigned index = (i2400m->
barker - i2400m_barker_db)
401 /
sizeof(*i2400m->
barker);
402 d_printf(2, dev,
"boot barker cache-confirmed #%u/%08x\n",
407 for (i = 0; i < i2400m_barker_db_used; i++) {
408 barker = &i2400m_barker_db[
i];
410 if (
memcmp(buf, barker->data,
sizeof(barker->data)))
415 d_printf(1, dev,
"boot barker set to #%u/%08x\n",
421 }
else if (i2400m->
barker != barker) {
422 dev_err(dev,
"HW inconsistency: device "
423 "reports a different boot barker "
424 "than set (from %08x to %08x)\n",
429 d_printf(2, dev,
"boot barker confirmed #%u/%08x\n",
455 size_t ack_size,
int flags)
460 d_fnstart(8, dev,
"(i2400m %p opcode %d ack %p size %zu)\n",
461 i2400m, opcode, ack, ack_size);
462 if (ack_size <
sizeof(*ack)) {
464 dev_err(dev,
"boot-mode cmd %d: HW BUG? notification didn't "
465 "return enough data (%zu bytes vs %zu expected)\n",
466 opcode, ack_size,
sizeof(*ack));
467 goto error_ack_short;
472 d_printf(6, dev,
"boot-mode cmd %d: HW boot barker\n", opcode);
475 if (ack_size ==
sizeof(i2400m_ACK_BARKER)
476 &&
memcmp(ack, i2400m_ACK_BARKER,
sizeof(*ack)) == 0) {
478 d_printf(3, dev,
"boot-mode cmd %d: HW reboot ack barker\n",
480 goto error_reboot_ack;
488 d_printf(5, dev,
"boot-mode cmd %d: notification for opcode %u "
489 "response %u csum %u rr %u da %u\n",
490 opcode, i2400m_brh_get_opcode(ack),
491 i2400m_brh_get_response(ack),
492 i2400m_brh_get_use_checksum(ack),
493 i2400m_brh_get_response_required(ack),
494 i2400m_brh_get_direct_access(ack));
496 if (i2400m_brh_get_signature(ack) != 0xcbbc) {
497 dev_err(dev,
"boot-mode cmd %d: HW BUG? wrong signature "
498 "0x%04x\n", opcode, i2400m_brh_get_signature(ack));
499 goto error_ack_signature;
501 if (opcode != -1 && opcode != i2400m_brh_get_opcode(ack)) {
502 dev_err(dev,
"boot-mode cmd %d: HW BUG? "
503 "received response for opcode %u, expected %u\n",
504 opcode, i2400m_brh_get_opcode(ack), opcode);
505 goto error_ack_opcode;
507 if (i2400m_brh_get_response(ack) != 0) {
508 dev_err(dev,
"boot-mode cmd %d: error; hw response %u\n",
509 opcode, i2400m_brh_get_response(ack));
510 goto error_ack_failed;
512 if (ack_size < ack->
data_size +
sizeof(*ack)) {
513 dev_err(dev,
"boot-mode cmd %d: SW BUG "
514 "driver provided only %zu bytes for %zu bytes "
515 "of data\n", opcode, ack_size,
517 goto error_ack_short_buffer;
523 error_ack_short_buffer:
531 d_fnend(8, dev,
"(i2400m %p opcode %d ack %p size %zu) = %d\n",
532 i2400m, opcode, ack, ack_size, (
int) result);
583 ssize_t i2400m_bm_cmd(
struct i2400m *i2400m,
589 struct device *dev = i2400m_dev(i2400m);
590 int opcode = cmd ==
NULL ? -1 : i2400m_brh_get_opcode(cmd);
592 d_fnstart(6, dev,
"(i2400m %p cmd %p size %zu ack %p size %zu)\n",
593 i2400m, cmd, cmd_size, ack, ack_size);
594 BUG_ON(ack_size <
sizeof(*ack));
601 if ((flags & I2400M_BM_CMD_RAW) == 0)
603 "boot-mode cmd %d csum %u rr %u da %u: "
604 "addr 0x%04x size %u block csum 0x%04x\n",
605 opcode, i2400m_brh_get_use_checksum(cmd),
606 i2400m_brh_get_response_required(cmd),
607 i2400m_brh_get_direct_access(cmd),
613 dev_err(dev,
"boot-mode cmd %d: error waiting for an ack: %d\n",
614 opcode, (
int) result);
615 goto error_wait_for_ack;
620 result = __i2400m_bm_ack_verify(i2400m, opcode, ack, ack_size, flags);
630 d_fnend(6, dev,
"(i2400m %p cmd %p size %zu ack %p size %zu) = %d\n",
631 i2400m, cmd, cmd_size, ack, ack_size, (
int) result);
646 static int i2400m_download_chunk(
struct i2400m *i2400m,
const void *
chunk,
647 size_t __chunk_len,
unsigned long addr,
652 struct device *dev = i2400m_dev(i2400m);
655 u8 cmd_payload[chunk_len];
659 d_fnstart(5, dev,
"(i2400m %p chunk %p __chunk_len %zu addr 0x%08lx "
660 "direct %u do_csum %u)\n", i2400m, chunk, __chunk_len,
661 addr, direct, do_csum);
663 memcpy(buf->cmd_payload, chunk, __chunk_len);
664 memset(buf->cmd_payload + __chunk_len, 0
xad, chunk_len - __chunk_len);
667 __chunk_len & 0x3 ? 0 : do_csum,
668 __chunk_len & 0xf ? 0 : direct);
671 ret = i2400m_bm_cmd(i2400m, &buf->cmd,
sizeof(buf->cmd) + chunk_len,
672 &ack,
sizeof(ack), 0);
675 d_fnend(5, dev,
"(i2400m %p chunk %p __chunk_len %zu addr 0x%08lx "
676 "direct %u do_csum %u) = %d\n", i2400m, chunk, __chunk_len,
677 addr, direct, do_csum, ret);
701 ssize_t i2400m_dnload_bcf(
struct i2400m *i2400m,
705 struct device *dev = i2400m_dev(i2400m);
713 d_fnstart(3, dev,
"(i2400m %p bcf %p bcf_len %zu)\n",
714 i2400m, bcf, bcf_len);
719 bh = (
void *) bcf + offset;
721 section_size =
ALIGN(
sizeof(*bh) + data_size, 4);
723 "downloading section #%zu (@%zu %zu B) to 0x%08x\n",
724 section, offset,
sizeof(*bh) + data_size,
734 d_printf(5, dev,
"jump found @%zu\n", offset);
737 if (offset + section_size > bcf_len) {
738 dev_err(dev,
"fw %s: bad section #%zu, "
739 "end (@%zu) beyond EOF (@%zu)\n",
741 offset + section_size, bcf_len);
743 goto error_section_beyond_eof;
746 ret = i2400m_bm_cmd(i2400m, bh, section_size,
747 &ack,
sizeof(ack), I2400M_BM_CMD_RAW);
749 dev_err(dev,
"fw %s: section #%zu (@%zu %zu B) "
750 "failed %d\n", i2400m->
fw_name, section,
751 offset,
sizeof(*bh) + data_size, (
int) ret);
754 offset += section_size;
758 error_section_beyond_eof:
760 d_fnend(3, dev,
"(i2400m %p bcf %p bcf_len %zu) = %d\n",
761 i2400m, bcf, bcf_len, (
int) ret);
771 unsigned i2400m_boot_is_signed(
struct i2400m *i2400m)
789 int i2400m_dnload_finalize(
struct i2400m *i2400m,
794 struct device *dev = i2400m_dev(i2400m);
800 size_t signature_block_offset, signature_block_size;
802 d_fnstart(3, dev,
"offset %zu\n", offset);
803 cmd = (
void *) bcf + offset;
804 if (i2400m_boot_is_signed(i2400m) == 0) {
806 d_printf(1, dev,
"unsecure boot, jumping to 0x%08x\n",
809 memcpy(&cmd_buf->cmd, cmd,
sizeof(*cmd));
814 ret = i2400m_bm_cmd(i2400m, cmd,
sizeof(*cmd),
815 &jump_ack,
sizeof(jump_ack), 0);
817 d_printf(1, dev,
"secure boot, jumping to 0x%08x\n",
820 memcpy(&cmd_buf->cmd, cmd,
sizeof(*cmd));
821 signature_block_offset =
825 signature_block_size =
828 (
void *) bcf_hdr + signature_block_offset,
829 signature_block_size);
830 ret = i2400m_bm_cmd(i2400m, &cmd_buf->cmd,
831 sizeof(cmd_buf->cmd) + signature_block_size,
832 &ack,
sizeof(ack), I2400M_BM_CMD_RAW);
834 d_fnend(3, dev,
"returning %d\n", ret);
886 struct device *dev = i2400m_dev(i2400m);
890 int ack_timeout_cnt = 1;
896 d_fnstart(4, dev,
"(i2400m %p flags 0x%08x)\n", i2400m, flags);
905 d_printf(4, dev,
"device reboot: reboot command [%d # left]\n",
909 result = i2400m_bm_cmd(i2400m,
NULL, 0, &ack,
sizeof(ack),
911 flags &= ~I2400M_BRI_NO_REBOOT;
919 d_printf(4, dev,
"device reboot: got reboot barker\n");
922 d_printf(4, dev,
"device reboot: got ack barker - whatever\n");
932 dev_err(dev,
"device boot: reboot barker timed out, "
933 "trying (set) %08x echo/ack\n",
937 for (i = 0; i < i2400m_barker_db_used; i++) {
938 struct i2400m_barker_db *barker = &i2400m_barker_db[
i];
939 memcpy(cmd, barker->data,
sizeof(barker->data));
940 result = i2400m_bm_cmd(i2400m, cmd,
sizeof(*cmd),
944 dev_warn(dev,
"device boot: got ack barker "
945 "after sending echo/ack barker "
946 "#%d/%08x; rebooting j.i.c.\n",
948 flags &= ~I2400M_BRI_NO_REBOOT;
952 dev_err(dev,
"device boot: tried all the echo/acks, could "
953 "not get device to respond; giving up");
960 dev_err(dev,
"device reboot: error %d while waiting "
961 "for reboot barker - rebooting\n", result);
962 d_dump(1, dev, &ack, result);
970 d_printf(4, dev,
"device reboot ack: sending ack [%d # left]\n", count);
972 result = i2400m_bm_cmd(i2400m, cmd,
sizeof(*cmd),
973 &ack,
sizeof(ack), I2400M_BM_CMD_RAW);
976 d_printf(4, dev,
"reboot ack: got reboot barker - retrying\n");
981 d_printf(4, dev,
"reboot ack: got ack barker - good\n");
984 if (ack_timeout_cnt-- < 0) {
985 d_printf(4, dev,
"reboot ack timedout: retrying\n");
988 dev_err(dev,
"reboot ack timedout too long: "
997 dev_err(dev,
"device reboot ack: error %d while waiting for "
998 "reboot ack barker - rebooting\n", result);
1001 d_printf(2, dev,
"device reboot ack: got ack barker - boot done\n");
1005 d_fnend(4, dev,
"(i2400m %p flags 0x%08x) = %d\n",
1006 i2400m, flags, result);
1010 dev_err(dev,
"Timed out waiting for reboot ack\n");
1028 struct device *dev = i2400m_dev(i2400m);
1036 d_fnstart(5, dev,
"(i2400m %p)\n", i2400m);
1041 result = i2400m_bm_cmd(i2400m, cmd,
sizeof(*cmd),
1042 &ack_buf.ack,
sizeof(ack_buf), 0);
1044 dev_err(dev,
"BM: read mac addr failed: %d\n", result);
1045 goto error_read_mac;
1047 d_printf(2, dev,
"mac addr is %pM\n", ack_buf.ack_pl);
1049 ack_buf.ack_pl[0] = 0x00;
1050 ack_buf.ack_pl[1] = 0x16;
1051 ack_buf.ack_pl[2] = 0xd3;
1053 dev_err(dev,
"BM is MAC addr impaired, faking MAC addr to "
1054 "mac addr is %pM\n", ack_buf.ack_pl);
1061 d_fnend(5, dev,
"(i2400m %p) = %d\n", i2400m, result);
1074 int i2400m_dnload_init_nonsigned(
struct i2400m *i2400m)
1078 struct device *dev = i2400m_dev(i2400m);
1079 d_fnstart(5, dev,
"(i2400m %p)\n", i2400m);
1082 ret = i2400m_download_chunk(
1092 d_fnend(5, dev,
"(i2400m %p) = %d\n", i2400m, ret);
1112 int i2400m_dnload_init_signed(
struct i2400m *i2400m,
1116 struct device *dev = i2400m_dev(i2400m);
1123 d_fnstart(5, dev,
"(i2400m %p bcf_hdr %p)\n", i2400m, bcf_hdr);
1125 cmd_buf->cmd.command =
1127 cmd_buf->cmd.target_addr = 0;
1128 cmd_buf->cmd.data_size =
cpu_to_le32(
sizeof(cmd_buf->cmd_pl));
1129 memcpy(&cmd_buf->cmd_pl, bcf_hdr,
sizeof(*bcf_hdr));
1130 ret = i2400m_bm_cmd(i2400m, &cmd_buf->cmd,
sizeof(*cmd_buf),
1131 &ack,
sizeof(ack), 0);
1134 d_fnend(5, dev,
"(i2400m %p bcf_hdr %p) = %d\n", i2400m, bcf_hdr, ret);
1146 int i2400m_dnload_init(
struct i2400m *i2400m,
1150 struct device *dev = i2400m_dev(i2400m);
1152 if (i2400m_boot_is_signed(i2400m)) {
1154 result = i2400m_dnload_init_signed(i2400m, bcf_hdr);
1158 dev_err(dev,
"firmware %s: signed boot download "
1159 "initialization failed: %d\n",
1163 d_printf(1, dev,
"non-signed boot\n");
1164 result = i2400m_dnload_init_nonsigned(i2400m);
1168 dev_err(dev,
"firmware %s: non-signed download "
1169 "initialization failed: %d\n",
1188 int i2400m_fw_hdr_check(
struct i2400m *i2400m,
1190 size_t index,
size_t offset)
1192 struct device *dev = i2400m_dev(i2400m);
1207 d_printf(1, dev,
"firmware %s #%zd@%08zx: BCF header "
1208 "type:vendor:id 0x%x:%x:%x v%u.%u (%u/%u B) built %08x\n",
1209 i2400m->
fw_name, index, offset,
1210 module_type, module_vendor, module_id,
1211 major_version, minor_version, header_len, size, date);
1214 if (major_version != 1) {
1215 dev_err(dev,
"firmware %s #%zd@%08zx: major header version "
1216 "v%u.%u not supported\n",
1217 i2400m->
fw_name, index, offset,
1218 major_version, minor_version);
1222 if (module_type != 6) {
1223 dev_err(dev,
"firmware %s #%zd@%08zx: unexpected module "
1224 "type 0x%x; aborting\n",
1225 i2400m->
fw_name, index, offset,
1230 if (module_vendor != 0x8086) {
1231 dev_err(dev,
"firmware %s #%zd@%08zx: unexpected module "
1232 "vendor 0x%x; aborting\n",
1233 i2400m->
fw_name, index, offset, module_vendor);
1237 if (date < 0x20080300)
1238 dev_warn(dev,
"firmware %s #%zd@%08zx: build date %08x "
1239 "too old; unsupported\n",
1240 i2400m->
fw_name, index, offset, date);
1257 int i2400m_fw_check(
struct i2400m *i2400m,
const void *bcf,
size_t bcf_size)
1260 struct device *dev = i2400m_dev(i2400m);
1264 size_t slots = 0, used_slots = 0;
1266 for (itr = bcf, top = itr + bcf_size;
1268 headers++, itr =
next) {
1271 leftover = top - itr;
1273 if (leftover <=
sizeof(*bcf_hdr)) {
1274 dev_err(dev,
"firmware %s: %zu B left at @%zx, "
1275 "not enough for BCF header\n",
1276 i2400m->
fw_name, leftover, offset);
1289 result = i2400m_fw_hdr_check(i2400m, bcf_hdr, headers, offset);
1292 if (used_slots + 1 >= slots) {
1296 result = i2400m_zrealloc_2x(
1297 (
void **) &i2400m->
fw_hdrs, &slots,
1301 goto error_zrealloc;
1303 i2400m->
fw_hdrs[used_slots] = bcf_hdr;
1307 dev_err(dev,
"firmware %s: no usable headers found\n",
1324 unsigned i2400m_bcf_hdr_match(
struct i2400m *i2400m,
1335 if (module_id == barker)
1341 const struct i2400m_bcf_hdr *i2400m_bcf_hdr_find(
struct i2400m *i2400m)
1343 struct device *dev = i2400m_dev(i2400m);
1348 d_printf(2, dev,
"finding BCF header for barker %08x\n", barker);
1351 d_printf(1, dev,
"using BCF header #%u/%08x for non-signed "
1355 for (bcf_itr = i2400m->
fw_hdrs; *bcf_itr !=
NULL; bcf_itr++, i++) {
1357 if (i2400m_bcf_hdr_match(i2400m, bcf_hdr)) {
1358 d_printf(1, dev,
"hit on BCF hdr #%u/%08x\n",
1362 d_printf(1, dev,
"miss on BCF hdr #%u/%08x\n",
1365 dev_err(dev,
"cannot find a matching BCF header for barker %08x\n",
1386 int i2400m_fw_dnload(
struct i2400m *i2400m,
const struct i2400m_bcf_hdr *bcf,
1390 struct device *dev = i2400m_dev(i2400m);
1395 d_fnstart(5, dev,
"(i2400m %p bcf %p fw size %zu)\n",
1396 i2400m, bcf, fw_size);
1402 dev_err(dev,
"device rebooted too many times, aborting\n");
1403 goto error_too_many_reboots;
1408 dev_err(dev,
"bootrom init failed: %d\n", ret);
1409 goto error_bootrom_init;
1424 bcf_hdr = i2400m_bcf_hdr_find(i2400m);
1425 if (bcf_hdr ==
NULL)
1426 goto error_bcf_hdr_find;
1428 ret = i2400m_dnload_init(i2400m, bcf_hdr);
1430 goto error_dev_rebooted;
1432 goto error_dnload_init;
1440 ret = i2400m_dnload_bcf(i2400m, bcf, bcf_size);
1442 goto error_dev_rebooted;
1444 dev_err(dev,
"fw %s: download failed: %d\n",
1446 goto error_dnload_bcf;
1449 ret = i2400m_dnload_finalize(i2400m, bcf_hdr, bcf, ret);
1451 goto error_dev_rebooted;
1454 "download finalization failed: %d\n",
1456 goto error_dnload_finalize;
1459 d_printf(2, dev,
"fw %s successfully uploaded\n",
1463 error_dnload_finalize:
1468 error_too_many_reboots:
1469 d_fnend(5, dev,
"(i2400m %p bcf %p size %zu) = %d\n",
1470 i2400m, bcf, fw_size, ret);
1474 dev_err(dev,
"device rebooted, %d tries left\n", count);
1481 int i2400m_fw_bootstrap(
struct i2400m *i2400m,
const struct firmware *
fw,
1485 struct device *dev = i2400m_dev(i2400m);
1488 d_fnstart(5, dev,
"(i2400m %p)\n", i2400m);
1489 bcf = (
void *) fw->
data;
1490 ret = i2400m_fw_check(i2400m, bcf, fw->
size);
1492 ret = i2400m_fw_dnload(i2400m, bcf, fw->
size, flags);
1494 dev_err(dev,
"%s: cannot use: %d, skipping\n",
1498 d_fnend(5, dev,
"(i2400m %p) = %d\n", i2400m, ret);
1511 void i2400m_fw_destroy(
struct kref *
kref)
1523 if (i2400m_fw !=
NULL && i2400m_fw != (
void *) ~0)
1524 kref_get(&i2400m_fw->
kref);
1530 void i2400m_fw_put(
struct i2400m_fw *i2400m_fw)
1532 kref_put(&i2400m_fw->
kref, i2400m_fw_destroy);
1554 struct device *dev = i2400m_dev(i2400m);
1555 struct i2400m_fw *i2400m_fw;
1560 d_fnstart(5, dev,
"(i2400m %p)\n", i2400m);
1564 i2400m_fw = i2400m_fw_get(i2400m->
fw_cached);
1565 spin_unlock(&i2400m->
rx_lock);
1566 if (i2400m_fw == (
void *) ~0) {
1567 dev_err(dev,
"can't load firmware now!");
1569 }
else if (i2400m_fw !=
NULL) {
1570 dev_info(dev,
"firmware %s: loading from cache\n",
1572 ret = i2400m_fw_bootstrap(i2400m, i2400m_fw->
fw, flags);
1573 i2400m_fw_put(i2400m_fw);
1578 for (itr = 0, bcf =
NULL, ret = -
ENOENT; ; itr++) {
1580 if (fw_name ==
NULL) {
1581 dev_err(dev,
"Could not find a usable firmware image\n");
1584 d_printf(1, dev,
"trying firmware %s (%d)\n", fw_name, itr);
1587 dev_err(dev,
"fw %s: cannot load file: %d\n",
1592 ret = i2400m_fw_bootstrap(i2400m, fw, flags);
1599 d_fnend(5, dev,
"(i2400m %p) = %d\n", i2400m, ret);
1608 struct i2400m_fw *i2400m_fw;
1609 struct device *dev = i2400m_dev(i2400m);
1614 spin_unlock(&i2400m->
rx_lock);
1615 if (i2400m_fw !=
NULL && i2400m_fw != (
void *) ~0) {
1616 i2400m_fw_put(i2400m_fw);
1617 WARN(1,
"%s:%u: still cached fw still present?\n",
1618 __func__, __LINE__);
1622 dev_err(dev,
"firmware n/a: can't cache\n");
1623 i2400m_fw = (
void *) ~0;
1627 i2400m_fw = kzalloc(
sizeof(*i2400m_fw),
GFP_ATOMIC);
1628 if (i2400m_fw ==
NULL)
1630 kref_init(&i2400m_fw->
kref);
1633 dev_err(dev,
"firmware %s: failed to cache: %d\n",
1636 i2400m_fw = (
void *) ~0;
1642 spin_unlock(&i2400m->
rx_lock);
1648 struct i2400m_fw *i2400m_fw;
1653 spin_unlock(&i2400m->
rx_lock);
1655 if (i2400m_fw !=
NULL && i2400m_fw != (
void *) ~0)
1656 i2400m_fw_put(i2400m_fw);