aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wimax/i2400m/fw.c63
-rw-r--r--include/linux/wimax/i2400m.h2
2 files changed, 52 insertions, 13 deletions
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c
index 55fe011a9633..eef236d85af3 100644
--- a/drivers/net/wimax/i2400m/fw.c
+++ b/drivers/net/wimax/i2400m/fw.c
@@ -812,7 +812,7 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
812 * 812 *
813 * @i2400m: device descriptor 813 * @i2400m: device descriptor
814 * @flags: 814 * @flags:
815 * I2400M_BRI_SOFT: a reboot notification has been seen 815 * I2400M_BRI_SOFT: a reboot barker has been seen
816 * already, so don't wait for it. 816 * already, so don't wait for it.
817 * 817 *
818 * I2400M_BRI_NO_REBOOT: Don't send a reboot command, but wait 818 * I2400M_BRI_NO_REBOOT: Don't send a reboot command, but wait
@@ -829,8 +829,9 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
829 * main phases to this: 829 * main phases to this:
830 * 830 *
831 * a. (1) send a reboot command and (2) get a reboot barker 831 * a. (1) send a reboot command and (2) get a reboot barker
832 * b. (1) ack the reboot sending a reboot barker and (2) getting an 832 *
833 * ack barker in return 833 * b. (1) echo/ack the reboot sending the reboot barker back and (2)
834 * getting an ack barker in return
834 * 835 *
835 * We want to skip (a) in some cases [soft]. The state machine is 836 * We want to skip (a) in some cases [soft]. The state machine is
836 * horrible, but it is basically: on each phase, send what has to be 837 * horrible, but it is basically: on each phase, send what has to be
@@ -838,6 +839,16 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
838 * have to backtrack and retry, so we keep a max tries counter for 839 * have to backtrack and retry, so we keep a max tries counter for
839 * that. 840 * that.
840 * 841 *
842 * It sucks because we don't know ahead of time which is going to be
843 * the reboot barker (the device might send different ones depending
844 * on its EEPROM config) and once the device reboots and waits for the
845 * echo/ack reboot barker being sent back, it doesn't understand
846 * anything else. So we can be left at the point where we don't know
847 * what to send to it -- cold reset and bus reset seem to have little
848 * effect. So the function iterates (in this case) through all the
849 * known barkers and tries them all until an ACK is
850 * received. Otherwise, it gives up.
851 *
841 * If we get a timeout after sending a warm reset, we do it again. 852 * If we get a timeout after sending a warm reset, we do it again.
842 */ 853 */
843int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) 854int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
@@ -848,6 +859,7 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
848 struct i2400m_bootrom_header ack; 859 struct i2400m_bootrom_header ack;
849 int count = i2400m->bus_bm_retries; 860 int count = i2400m->bus_bm_retries;
850 int ack_timeout_cnt = 1; 861 int ack_timeout_cnt = 1;
862 unsigned i;
851 863
852 BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_barker_db[0].data)); 864 BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_barker_db[0].data));
853 BUILD_BUG_ON(sizeof(ack) != sizeof(i2400m_ACK_BARKER)); 865 BUILD_BUG_ON(sizeof(ack) != sizeof(i2400m_ACK_BARKER));
@@ -858,6 +870,7 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
858 if (flags & I2400M_BRI_SOFT) 870 if (flags & I2400M_BRI_SOFT)
859 goto do_reboot_ack; 871 goto do_reboot_ack;
860do_reboot: 872do_reboot:
873 ack_timeout_cnt = 1;
861 if (--count < 0) 874 if (--count < 0)
862 goto error_timeout; 875 goto error_timeout;
863 d_printf(4, dev, "device reboot: reboot command [%d # left]\n", 876 d_printf(4, dev, "device reboot: reboot command [%d # left]\n",
@@ -869,22 +882,47 @@ do_reboot:
869 flags &= ~I2400M_BRI_NO_REBOOT; 882 flags &= ~I2400M_BRI_NO_REBOOT;
870 switch (result) { 883 switch (result) {
871 case -ERESTARTSYS: 884 case -ERESTARTSYS:
885 /*
886 * at this point, i2400m_bm_cmd(), through
887 * __i2400m_bm_ack_process(), has updated
888 * i2400m->barker and we are good to go.
889 */
872 d_printf(4, dev, "device reboot: got reboot barker\n"); 890 d_printf(4, dev, "device reboot: got reboot barker\n");
873 break; 891 break;
874 case -EISCONN: /* we don't know how it got here...but we follow it */ 892 case -EISCONN: /* we don't know how it got here...but we follow it */
875 d_printf(4, dev, "device reboot: got ack barker - whatever\n"); 893 d_printf(4, dev, "device reboot: got ack barker - whatever\n");
876 goto do_reboot; 894 goto do_reboot;
877 case -ETIMEDOUT: /* device has timed out, we might be in boot 895 case -ETIMEDOUT:
878 * mode already and expecting an ack, let's try 896 /*
879 * that */ 897 * Device has timed out, we might be in boot mode
880 if (i2400m->barker == NULL) { 898 * already and expecting an ack; if we don't know what
881 dev_info(dev, "warm reset timed out, unknown barker " 899 * the barker is, we just send them all. Cold reset
882 "type, rebooting\n"); 900 * and bus reset don't work. Beats me.
883 goto do_reboot; 901 */
884 } else { 902 if (i2400m->barker != NULL) {
885 dev_info(dev, "warm reset timed out, trying an ack\n"); 903 dev_err(dev, "device boot: reboot barker timed out, "
904 "trying (set) %08x echo/ack\n",
905 le32_to_cpu(i2400m->barker->data[0]));
886 goto do_reboot_ack; 906 goto do_reboot_ack;
887 } 907 }
908 for (i = 0; i < i2400m_barker_db_used; i++) {
909 struct i2400m_barker_db *barker = &i2400m_barker_db[i];
910 memcpy(cmd, barker->data, sizeof(barker->data));
911 result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
912 &ack, sizeof(ack),
913 I2400M_BM_CMD_RAW);
914 if (result == -EISCONN) {
915 dev_warn(dev, "device boot: got ack barker "
916 "after sending echo/ack barker "
917 "#%d/%08x; rebooting j.i.c.\n",
918 i, le32_to_cpu(barker->data[0]));
919 flags &= ~I2400M_BRI_NO_REBOOT;
920 goto do_reboot;
921 }
922 }
923 dev_err(dev, "device boot: tried all the echo/acks, could "
924 "not get device to respond; giving up");
925 result = -ESHUTDOWN;
888 case -EPROTO: 926 case -EPROTO:
889 case -ESHUTDOWN: /* dev is gone */ 927 case -ESHUTDOWN: /* dev is gone */
890 case -EINTR: /* user cancelled */ 928 case -EINTR: /* user cancelled */
@@ -892,6 +930,7 @@ do_reboot:
892 default: 930 default:
893 dev_err(dev, "device reboot: error %d while waiting " 931 dev_err(dev, "device reboot: error %d while waiting "
894 "for reboot barker - rebooting\n", result); 932 "for reboot barker - rebooting\n", result);
933 d_dump(1, dev, &ack, result);
895 goto do_reboot; 934 goto do_reboot;
896 } 935 }
897 /* At this point we ack back with 4 REBOOT barkers and expect 936 /* At this point we ack back with 4 REBOOT barkers and expect
diff --git a/include/linux/wimax/i2400m.h b/include/linux/wimax/i2400m.h
index d6e2a3595682..fd5af05083cb 100644
--- a/include/linux/wimax/i2400m.h
+++ b/include/linux/wimax/i2400m.h
@@ -138,7 +138,7 @@ struct i2400m_bcf_hdr {
138 __le32 module_id; 138 __le32 module_id;
139 __le32 module_vendor; 139 __le32 module_vendor;
140 __le32 date; /* BCD YYYMMDD */ 140 __le32 date; /* BCD YYYMMDD */
141 __le32 size; 141 __le32 size; /* in dwords */
142 __le32 key_size; /* in dwords */ 142 __le32 key_size; /* in dwords */
143 __le32 modulus_size; /* in dwords */ 143 __le32 modulus_size; /* in dwords */
144 __le32 exponent_size; /* in dwords */ 144 __le32 exponent_size; /* in dwords */