Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 171209
b: refs/heads/master
c: 923d708
h: refs/heads/master
i:
  171207: f3e4c5e
v: v3
  • Loading branch information
Inaky Perez-Gonzalez committed Oct 19, 2009
1 parent 3e785b2 commit f28b44c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ebc5f62b76ad540ff7b3e438506638009e7812a6
refs/heads/master: 923d708fed9d47c7b4d67694500d766337663e29
63 changes: 51 additions & 12 deletions trunk/drivers/net/wimax/i2400m/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
*
* @i2400m: device descriptor
* @flags:
* I2400M_BRI_SOFT: a reboot notification has been seen
* I2400M_BRI_SOFT: a reboot barker has been seen
* already, so don't wait for it.
*
* I2400M_BRI_NO_REBOOT: Don't send a reboot command, but wait
Expand All @@ -829,15 +829,26 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
* main phases to this:
*
* a. (1) send a reboot command and (2) get a reboot barker
* b. (1) ack the reboot sending a reboot barker and (2) getting an
* ack barker in return
*
* b. (1) echo/ack the reboot sending the reboot barker back and (2)
* getting an ack barker in return
*
* We want to skip (a) in some cases [soft]. The state machine is
* horrible, but it is basically: on each phase, send what has to be
* sent (if any), wait for the answer and act on the answer. We might
* have to backtrack and retry, so we keep a max tries counter for
* that.
*
* It sucks because we don't know ahead of time which is going to be
* the reboot barker (the device might send different ones depending
* on its EEPROM config) and once the device reboots and waits for the
* echo/ack reboot barker being sent back, it doesn't understand
* anything else. So we can be left at the point where we don't know
* what to send to it -- cold reset and bus reset seem to have little
* effect. So the function iterates (in this case) through all the
* known barkers and tries them all until an ACK is
* received. Otherwise, it gives up.
*
* If we get a timeout after sending a warm reset, we do it again.
*/
int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
Expand All @@ -848,6 +859,7 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
struct i2400m_bootrom_header ack;
int count = i2400m->bus_bm_retries;
int ack_timeout_cnt = 1;
unsigned i;

BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_barker_db[0].data));
BUILD_BUG_ON(sizeof(ack) != sizeof(i2400m_ACK_BARKER));
Expand All @@ -858,6 +870,7 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
if (flags & I2400M_BRI_SOFT)
goto do_reboot_ack;
do_reboot:
ack_timeout_cnt = 1;
if (--count < 0)
goto error_timeout;
d_printf(4, dev, "device reboot: reboot command [%d # left]\n",
Expand All @@ -869,29 +882,55 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
flags &= ~I2400M_BRI_NO_REBOOT;
switch (result) {
case -ERESTARTSYS:
/*
* at this point, i2400m_bm_cmd(), through
* __i2400m_bm_ack_process(), has updated
* i2400m->barker and we are good to go.
*/
d_printf(4, dev, "device reboot: got reboot barker\n");
break;
case -EISCONN: /* we don't know how it got here...but we follow it */
d_printf(4, dev, "device reboot: got ack barker - whatever\n");
goto do_reboot;
case -ETIMEDOUT: /* device has timed out, we might be in boot
* mode already and expecting an ack, let's try
* that */
if (i2400m->barker == NULL) {
dev_info(dev, "warm reset timed out, unknown barker "
"type, rebooting\n");
goto do_reboot;
} else {
dev_info(dev, "warm reset timed out, trying an ack\n");
case -ETIMEDOUT:
/*
* Device has timed out, we might be in boot mode
* already and expecting an ack; if we don't know what
* the barker is, we just send them all. Cold reset
* and bus reset don't work. Beats me.
*/
if (i2400m->barker != NULL) {
dev_err(dev, "device boot: reboot barker timed out, "
"trying (set) %08x echo/ack\n",
le32_to_cpu(i2400m->barker->data[0]));
goto do_reboot_ack;
}
for (i = 0; i < i2400m_barker_db_used; i++) {
struct i2400m_barker_db *barker = &i2400m_barker_db[i];
memcpy(cmd, barker->data, sizeof(barker->data));
result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
&ack, sizeof(ack),
I2400M_BM_CMD_RAW);
if (result == -EISCONN) {
dev_warn(dev, "device boot: got ack barker "
"after sending echo/ack barker "
"#%d/%08x; rebooting j.i.c.\n",
i, le32_to_cpu(barker->data[0]));
flags &= ~I2400M_BRI_NO_REBOOT;
goto do_reboot;
}
}
dev_err(dev, "device boot: tried all the echo/acks, could "
"not get device to respond; giving up");
result = -ESHUTDOWN;
case -EPROTO:
case -ESHUTDOWN: /* dev is gone */
case -EINTR: /* user cancelled */
goto error_dev_gone;
default:
dev_err(dev, "device reboot: error %d while waiting "
"for reboot barker - rebooting\n", result);
d_dump(1, dev, &ack, result);
goto do_reboot;
}
/* At this point we ack back with 4 REBOOT barkers and expect
Expand Down
2 changes: 1 addition & 1 deletion trunk/include/linux/wimax/i2400m.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ struct i2400m_bcf_hdr {
__le32 module_id;
__le32 module_vendor;
__le32 date; /* BCD YYYMMDD */
__le32 size;
__le32 size; /* in dwords */
__le32 key_size; /* in dwords */
__le32 modulus_size; /* in dwords */
__le32 exponent_size; /* in dwords */
Expand Down

0 comments on commit f28b44c

Please sign in to comment.