diff options
Diffstat (limited to 'drivers/net/wimax/i2400m/fw.c')
-rw-r--r-- | drivers/net/wimax/i2400m/fw.c | 58 |
1 files changed, 20 insertions, 38 deletions
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 675c6ce810c0..e81750e54452 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c | |||
@@ -397,7 +397,7 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk, | |||
397 | unsigned int direct, unsigned int do_csum) | 397 | unsigned int direct, unsigned int do_csum) |
398 | { | 398 | { |
399 | int ret; | 399 | int ret; |
400 | size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_PAD); | 400 | size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_ALIGN); |
401 | struct device *dev = i2400m_dev(i2400m); | 401 | struct device *dev = i2400m_dev(i2400m); |
402 | struct { | 402 | struct { |
403 | struct i2400m_bootrom_header cmd; | 403 | struct i2400m_bootrom_header cmd; |
@@ -532,14 +532,14 @@ int i2400m_dnload_finalize(struct i2400m *i2400m, | |||
532 | cmd = (void *) bcf + offset; | 532 | cmd = (void *) bcf + offset; |
533 | if (i2400m->sboot == 0) { | 533 | if (i2400m->sboot == 0) { |
534 | struct i2400m_bootrom_header jump_ack; | 534 | struct i2400m_bootrom_header jump_ack; |
535 | d_printf(3, dev, "unsecure boot, jumping to 0x%08x\n", | 535 | d_printf(1, dev, "unsecure boot, jumping to 0x%08x\n", |
536 | le32_to_cpu(cmd->target_addr)); | 536 | le32_to_cpu(cmd->target_addr)); |
537 | i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP); | 537 | i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP); |
538 | cmd->data_size = 0; | 538 | cmd->data_size = 0; |
539 | ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), | 539 | ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), |
540 | &jump_ack, sizeof(jump_ack), 0); | 540 | &jump_ack, sizeof(jump_ack), 0); |
541 | } else { | 541 | } else { |
542 | d_printf(3, dev, "secure boot, jumping to 0x%08x\n", | 542 | d_printf(1, dev, "secure boot, jumping to 0x%08x\n", |
543 | le32_to_cpu(cmd->target_addr)); | 543 | le32_to_cpu(cmd->target_addr)); |
544 | cmd_buf = i2400m->bm_cmd_buf; | 544 | cmd_buf = i2400m->bm_cmd_buf; |
545 | memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd)); | 545 | memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd)); |
@@ -696,8 +696,7 @@ error_dev_gone: | |||
696 | return result; | 696 | return result; |
697 | 697 | ||
698 | error_timeout: | 698 | error_timeout: |
699 | dev_err(dev, "Timed out waiting for reboot ack, resetting\n"); | 699 | dev_err(dev, "Timed out waiting for reboot ack\n"); |
700 | i2400m->bus_reset(i2400m, I2400M_RT_BUS); | ||
701 | result = -ETIMEDOUT; | 700 | result = -ETIMEDOUT; |
702 | goto exit_timeout; | 701 | goto exit_timeout; |
703 | } | 702 | } |
@@ -770,40 +769,21 @@ error_read_mac: | |||
770 | static | 769 | static |
771 | int i2400m_dnload_init_nonsigned(struct i2400m *i2400m) | 770 | int i2400m_dnload_init_nonsigned(struct i2400m *i2400m) |
772 | { | 771 | { |
773 | #define POKE(a, d) { \ | 772 | unsigned i = 0; |
774 | .address = cpu_to_le32(a), \ | 773 | int ret = 0; |
775 | .data = cpu_to_le32(d) \ | ||
776 | } | ||
777 | static const struct { | ||
778 | __le32 address; | ||
779 | __le32 data; | ||
780 | } i2400m_pokes[] = { | ||
781 | POKE(0x081A58, 0xA7810230), | ||
782 | POKE(0x080040, 0x00000000), | ||
783 | POKE(0x080048, 0x00000082), | ||
784 | POKE(0x08004C, 0x0000081F), | ||
785 | POKE(0x080054, 0x00000085), | ||
786 | POKE(0x080058, 0x00000180), | ||
787 | POKE(0x08005C, 0x00000018), | ||
788 | POKE(0x080060, 0x00000010), | ||
789 | POKE(0x080574, 0x00000001), | ||
790 | POKE(0x080550, 0x00000005), | ||
791 | POKE(0xAE0000, 0x00000000), | ||
792 | }; | ||
793 | #undef POKE | ||
794 | unsigned i; | ||
795 | int ret; | ||
796 | struct device *dev = i2400m_dev(i2400m); | 774 | struct device *dev = i2400m_dev(i2400m); |
797 | |||
798 | dev_warn(dev, "WARNING!!! non-signed boot UNTESTED PATH!\n"); | ||
799 | |||
800 | d_fnstart(5, dev, "(i2400m %p)\n", i2400m); | 775 | d_fnstart(5, dev, "(i2400m %p)\n", i2400m); |
801 | for (i = 0; i < ARRAY_SIZE(i2400m_pokes); i++) { | 776 | if (i2400m->bus_bm_pokes_table) { |
802 | ret = i2400m_download_chunk(i2400m, &i2400m_pokes[i].data, | 777 | while (i2400m->bus_bm_pokes_table[i].address) { |
803 | sizeof(i2400m_pokes[i].data), | 778 | ret = i2400m_download_chunk( |
804 | i2400m_pokes[i].address, 1, 1); | 779 | i2400m, |
805 | if (ret < 0) | 780 | &i2400m->bus_bm_pokes_table[i].data, |
806 | break; | 781 | sizeof(i2400m->bus_bm_pokes_table[i].data), |
782 | i2400m->bus_bm_pokes_table[i].address, 1, 1); | ||
783 | if (ret < 0) | ||
784 | break; | ||
785 | i++; | ||
786 | } | ||
807 | } | 787 | } |
808 | d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret); | 788 | d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret); |
809 | return ret; | 789 | return ret; |
@@ -980,11 +960,12 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, | |||
980 | { | 960 | { |
981 | int ret = 0; | 961 | int ret = 0; |
982 | struct device *dev = i2400m_dev(i2400m); | 962 | struct device *dev = i2400m_dev(i2400m); |
983 | int count = I2400M_BOOT_RETRIES; | 963 | int count = i2400m->bus_bm_retries; |
984 | 964 | ||
985 | d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n", | 965 | d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n", |
986 | i2400m, bcf, bcf_size); | 966 | i2400m, bcf, bcf_size); |
987 | i2400m->boot_mode = 1; | 967 | i2400m->boot_mode = 1; |
968 | wmb(); /* Make sure other readers see it */ | ||
988 | hw_reboot: | 969 | hw_reboot: |
989 | if (count-- == 0) { | 970 | if (count-- == 0) { |
990 | ret = -ERESTARTSYS; | 971 | ret = -ERESTARTSYS; |
@@ -1033,6 +1014,7 @@ hw_reboot: | |||
1033 | d_printf(2, dev, "fw %s successfully uploaded\n", | 1014 | d_printf(2, dev, "fw %s successfully uploaded\n", |
1034 | i2400m->fw_name); | 1015 | i2400m->fw_name); |
1035 | i2400m->boot_mode = 0; | 1016 | i2400m->boot_mode = 0; |
1017 | wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */ | ||
1036 | error_dnload_finalize: | 1018 | error_dnload_finalize: |
1037 | error_dnload_bcf: | 1019 | error_dnload_bcf: |
1038 | error_dnload_init: | 1020 | error_dnload_init: |