126 lines
3.0 KiB
C
126 lines
3.0 KiB
C
/*
|
|
* Copyright (C) 2012, 2013 sysmocom s.f.m.c. GmbH
|
|
* Author: Holger Hans Peter Freyther
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <common.h>
|
|
#include <command.h>
|
|
#include <status_led.h>
|
|
#include <asm-generic/gpio.h>
|
|
|
|
#define BLINK_LED
|
|
|
|
static int enable_netconsole(void)
|
|
{
|
|
printf("Enabling the network console.\n");
|
|
|
|
/* reset in 60s if it is not interrupted */
|
|
return run_command("setenv stdout nc; setenv stdin nc", 0);
|
|
}
|
|
|
|
static int env_failed(void)
|
|
{
|
|
printf("Environment clearing failed.\n");
|
|
|
|
BLINK_LED(7);
|
|
return -1;
|
|
}
|
|
|
|
static int dhcp_failed(void)
|
|
{
|
|
printf("DHCP failed. Giving up on recovery.\n");
|
|
|
|
BLINK_LED(10);
|
|
return -1;
|
|
}
|
|
|
|
static int tftp_failed(void)
|
|
{
|
|
printf("TFTP failed.\n");
|
|
BLINK_LED(13);
|
|
enable_netconsole();
|
|
return -1;
|
|
}
|
|
|
|
static int flash_failed(void)
|
|
{
|
|
printf("Flash failed.\n");
|
|
BLINK_LED(15);
|
|
enable_netconsole();
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* This will run the recovery process.
|
|
* 1.) Enable the LED to give instant feedback.
|
|
* 2.) Clear the environment in case of bad configuration.
|
|
* 3.) Get a DHCP lease.
|
|
* 4.) Try to tftpboot
|
|
* 5.) Try to tftpboot with a different server
|
|
* 6.) Flash
|
|
* 7.) Reset or enter netconsole
|
|
*/
|
|
static int do_run_recovery(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|
{
|
|
int rc;
|
|
|
|
//status_led_set(0, STATUS_LED_ON);
|
|
printf("Starting the recovery process.\n");
|
|
|
|
/* Wait a bit and check if the reset button is still pressed */
|
|
if (argc == 2 && strcmp(argv[1], "force") == 0) {
|
|
printf("Forcing the recovery process.\n");
|
|
}
|
|
|
|
BLINK_LED(5);
|
|
//status_led_set(0, STATUS_LED_ON);
|
|
|
|
/* erase u-boot enviroment */
|
|
rc = run_command("erase 0x9f040000 +0x10000", 0);
|
|
if (rc < 0)
|
|
return env_failed();
|
|
|
|
rc = run_command("setenv autoload no; setenv netretry no; dhcp", 0);
|
|
if (rc < 0)
|
|
return dhcp_failed();
|
|
|
|
rc = run_command("setenv filesize 0; "
|
|
"tftp 0x81000000 " RECOVERY_FILENAME_STRING, 0);
|
|
if (rc < 0) {
|
|
rc = run_command("setenv filesize 0; "
|
|
"setenv serverip 255.255.255.255; "
|
|
"tftp 0x81000000 " RECOVERY_FILENAME_STRING, 0);
|
|
}
|
|
|
|
if (rc < 0)
|
|
return tftp_failed();
|
|
|
|
rc = run_command("erase 0x9f050000 +0x7a0000; "
|
|
"cp.b 0x81000000 0x9f050000 0x7a0000", 0);
|
|
if (rc < 0)
|
|
return flash_failed();
|
|
|
|
return run_command("resetcycle; reset", 0);
|
|
}
|
|
|
|
U_BOOT_CMD(
|
|
run_recovery, 2, 0, do_run_recovery,
|
|
"run_recovery - Run the sysmocom sysmoBTS recovery process",
|
|
"[force]"
|
|
);
|