break;
}
} while (ret == CE_PR_MORE);
+ free(buffer);
if (ret != CE_PR_EOF)
return CMD_RET_FAILURE;
- free(buffer);
if (getenv_yesno("autostart") != 1) {
/*
* just use bootce to load the image to SDRAM;
} else {
int rc = ce_send_write_ack(net);
- printf("Dropping out of sequence packet with ID %d (expected %d)\n",
- blknum, nxt);
+ if (net->verbose)
+ printf("Dropping out of sequence packet with ID %d (expected %d)\n",
+ blknum, nxt);
if (rc != 0)
return rc;
net->state = BOOTME_DEBUG;
}
-debug("%s@%d\n", __func__, __LINE__);
switch (header.cmd) {
case EDBG_CMD_JUMPIMG:
-debug("%s@%d\n", __func__, __LINE__);
net->gotJumpingRequest = 1;
if (net->verbose) {
printf("Received JUMPING command\n");
}
/* Just pass through and copy CONFIG structure */
+ ret = BOOTME_DONE;
case EDBG_CMD_OS_CONFIG:
-debug("%s@%d\n", __func__, __LINE__);
/* Copy config structure */
- memcpy(&bin->edbgConfig, header.data,
+ memcpy(&bin->edbgConfig, &net->data[sizeof(header)],
sizeof(edbg_os_config_data));
if (net->verbose) {
printf("Received CONFIG command\n");
printf("--> Force clean boot\n");
}
}
- ret = BOOTME_DEBUG;
break;
default:
/* Respond with ack */
header.flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
+ memcpy(net->data, &header, sizeof(header));
net->dataLen = EDBG_DATA_OFFSET;
-debug("%s@%d: sending packet %p len %u\n", __func__, __LINE__,
- net->data, net->dataLen);
- bootme_send_frame(net->data, net->dataLen);
- return ret;
+
+ int retries = 10;
+ int rc;
+ do {
+ rc = bootme_send_frame(net->data, net->dataLen);
+ if (rc != 0) {
+ printf("Failed to send ACK: %d\n", rc);
+ }
+ } while (rc && retries-- > 0);
+ return rc ?: ret;
}
static enum bootme_state ce_edbg_handler(const void *buf, size_t len)
i++;
if (argc > i) {
timeout = simple_strtoul(argv[i],
- NULL, 10);
+ NULL, 0);
if (timeout >= UINT_MAX / CONFIG_SYS_HZ) {
printf("Timeout value %lu out of range (max.: %lu)\n",
timeout, UINT_MAX / CONFIG_SYS_HZ - 1);
server_ip = string_to_ip(argv[i]);
printf("Using server %pI4\n", &server_ip);
} else {
- printf("Option requires an argument - t\n");
+ printf("Option requires an argument - h\n");
return CMD_RET_USAGE;
}
}
DECLARE_GLOBAL_DATA_PTR;
-#define WINCE_VRAM_BASE 0x80000000
-#define CE_FIX_ADDRESS(a) ((void *)((a) - WINCE_VRAM_BASE + CONFIG_SYS_SDRAM_BASE))
-
-#ifndef INT_MAX
-#define INT_MAX ((int)(~0 >> 1))
-#endif
-
-/* Bin image parse states */
-#define CE_PS_RTI_ADDR 0
-#define CE_PS_RTI_LEN 1
-#define CE_PS_E_ADDR 2
-#define CE_PS_E_LEN 3
-#define CE_PS_E_CHKSUM 4
-#define CE_PS_E_DATA 5
-
-#define CE_MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define CE_MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-#define _STRMAC(s) #s
-#define STRMAC(s) _STRMAC(s)
-
static enum bootme_state bootme_state;
static int bootme_src_port = 0xdeadface;
static int bootme_dst_port = 0xdeadbeef;
static uchar bootme_ether[ETH_ALEN];
static IPaddr_t bootme_ip;
static int bootme_timed_out;
-//static size_t input_len, input_size;
-//static void *input_packet;
static const char *output_packet; /* used by first send udp */
static int output_packet_len;
static unsigned long bootme_timeout;
static void bootme_timeout_handler(void)
{
+ printf("%s\n", __func__);
net_set_state(NETLOOP_SUCCESS);
bootme_timed_out++;
}
uchar *eth_pkt = pkt;
unsigned eth_len = len;
static char cursor = '|';
- enum bootme_state last_state = BOOTME_INIT;
-#if 1
+ enum bootme_state last_state = bootme_state;
+
debug("received packet of len %d from %pI4:%d to port %d\n",
len, &src_ip, src_port, dest_port);
ce_dump_block(pkt, len);
-#endif
+
if (!bootme_packet_handler) {
printf("No packet handler set for BOOTME protocol; dropping packet\n");
return;
printf("%c\x08", cursor);
cursor = next_cursor(cursor);
- if (is_broadcast(bootme_ip)) {
- bootme_ip = src_ip;
- } else if (src_ip != bootme_ip) {
+ if (!is_broadcast(bootme_ip) && src_ip != bootme_ip) {
debug("src_ip %pI4 does not match destination IP %pI4\n",
&src_ip, &bootme_ip);
return; /* not from our server */
}
-
- last_state = bootme_state;
- bootme_dst_port = src_port;
- debug("bootme_dst_port set to %d\n", bootme_dst_port);
+ if (bootme_state == BOOTME_INIT || bootme_state == BOOTME_DEBUG_INIT) {
+ struct ethernet_hdr *eth = (struct ethernet_hdr *)(pkt -
+ NetEthHdrSize() - IP_UDP_HDR_SIZE);
+ memcpy(bootme_ether, eth->et_src, sizeof(bootme_ether));
+ printf("Target MAC address set to %pM\n", bootme_ether);
+
+ if (is_broadcast(bootme_ip)) {
+ NetCopyIP(&bootme_ip, &src_ip);
+ }
+ }
if (bootme_state == BOOTME_INIT) {
bootme_src_port = EDBG_SVC_PORT;
debug("%s: bootme_src_port set to %d\n", __func__, bootme_src_port);
}
+
+ debug("bootme_dst_port %d -> %d\n", bootme_dst_port, src_port);
+ bootme_dst_port = src_port;
+
bootme_state = bootme_packet_handler(eth_pkt, eth_len);
debug("bootme_packet_handler() returned %d\n", bootme_state);
if (bootme_state != last_state)
- debug("bootme_state: %d -> %d\n", last_state, bootme_state);
+ debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+ last_state, bootme_state);
switch (bootme_state) {
case BOOTME_INIT:
+ case BOOTME_DEBUG_INIT:
break;
case BOOTME_DOWNLOAD:
NetBootFileXferSize += len - 4;
/* fallthru */
case BOOTME_DEBUG:
- if (last_state == BOOTME_INIT) {
+ if (last_state == BOOTME_INIT ||
+ last_state == BOOTME_DEBUG_INIT)
bootme_timeout = 3 * 1000;
- }
NetSetTimeout(bootme_timeout, bootme_timeout_handler);
break;
assert(NetTxPacket != NULL);
pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
memcpy(pkt, output_packet, output_packet_len);
+ debug("%s@%d: Sending ARP request:\n", __func__, __LINE__);
+ ce_dump_block(pkt, output_packet_len);
NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
bootme_src_port, output_packet_len);
+ output_packet_len = 0;
}
}
{
int ret;
struct eth_device *eth;
- int inited = 0;
uchar *pkt;
eth = eth_get_dev();
if (eth == NULL)
return -EINVAL;
- if (bootme_state == BOOTME_INIT)
+ if (bootme_state == BOOTME_INIT || bootme_state == BOOTME_DEBUG_INIT)
check_net_config();
debug("%s: buf: %p len: %u from %pI4:%d to %pI4:%d\n",
- __func__, buf, len, &NetOurIP, bootme_src_port, &bootme_ip, bootme_dst_port);
+ __func__, buf, len, &NetOurIP, bootme_src_port, &bootme_ip,
+ bootme_dst_port);
if (memcmp(bootme_ether, NetEtherNullAddr, ETH_ALEN) == 0) {
- if (eth->state == ETH_STATE_ACTIVE)
- return 0; /* inside net loop */
-
output_packet = buf;
output_packet_len = len;
/* wait for arp reply and send packet */
return 0;
}
- if (eth->state != ETH_STATE_ACTIVE) {
- if (eth_is_on_demand_init()) {
- ret = eth_init(gd->bd);
- if (ret < 0)
- return ret;
- eth_set_last_protocol(BOOTME);
- } else {
- eth_init_state_only(gd->bd);
- }
- inited = 1;
- }
-
assert(NetTxPacket != NULL);
pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
memcpy(pkt, buf, len);
ret = NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
bootme_src_port, len);
- if (inited) {
- debug("Stopping network\n");
- if (eth_is_on_demand_init())
- eth_halt();
- else
- eth_halt_state_only();
- }
+ if (ret)
+ printf("Failed to send packet: %d\n", ret);
+
return ret;
}
static void bootme_init(IPaddr_t server_ip)
{
+ debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+ bootme_state, BOOTME_INIT);
bootme_state = BOOTME_INIT;
bootme_ip = server_ip;
/* force reconfiguration in check_net_config() */
bootme_packet_handler = handler;
bootme_init(bootme_ip);
- bootme_state = BOOTME_DEBUG;
+ debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+ bootme_state, BOOTME_DEBUG_INIT);
+ bootme_state = BOOTME_DEBUG_INIT;
+
bootme_timeout = 3 * 1000;
NetSetTimeout(bootme_timeout, bootme_timeout_handler);