add setmac/showmac commands to setmac or showmac

setmac <eth0> <eth1> <wlan0> [nobackup]
setmac first do a backup of the calibration sector. It copys the
sector to the sector before itself. This behavious can be overwritten by
adding `nobackup`.

showmac - show mac addreses.
This commit is contained in:
Alexander Couzens 2015-03-11 20:07:05 +01:00
parent 401b4f165b
commit 72e548d4c5
3 changed files with 262 additions and 1 deletions

View File

@ -60,7 +60,7 @@ COBJS = main.o circbuf.o \
cmd_nand.o cmd_net.o cmd_nvedit.o \
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \
cmd_vfd.o cmd_ethreg.o cmd_recovery.o cmd_bootcycle.o \
cmd_vfd.o cmd_ethreg.o cmd_recovery.o cmd_bootcycle.o cmd_setmac.o \
command.o console.o devices.o dlmalloc.o \
environment.o env_common.o \
env_nand.o env_dataflash.o env_flash.o env_eeprom.o \

259
u-boot/common/cmd_setmac.c Normal file
View File

@ -0,0 +1,259 @@
/*
* (C) Copyright 2015
* Alexander Couzens, lynxis@fe80.eu
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#ifdef CFG_CMD_SETMAC
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
extern flash_info_t flash_info[]; /* info for FLASH chips */
static int mac_location[] = {
0x0, /* eth0 */
0x6, /* eth1 */
0x1002, /* wlan0 */
};
typedef unsigned char bool;
#define true 1
#define false 0
/* from xyzmodem.c */
// Validate a hex character
__inline__ static bool
_is_hex(char c)
{
return (((c >= '0') && (c <= '9')) ||
((c >= 'A') && (c <= 'F')) ||
((c >= 'a') && (c <= 'f')));
}
/* from xyzmodem.c */
// Convert a single hex nibble
__inline__ static u8
_from_hex(char c)
{
u8 ret = 0;
if ((c >= '0') && (c <= '9')) {
ret = (c - '0');
} else if ((c >= 'a') && (c <= 'f')) {
ret = (c - 'a' + 0x0a);
} else if ((c >= 'A') && (c <= 'F')) {
ret = (c - 'A' + 0x0A);
}
return ret;
}
static int is_valid_mac_str(char *mac)
{
/* mac must look like "00:11:22:33:44:55" */
int i;
if (strlen(mac) < 17)
return 0;
for (i=0; i <=15 ; i+=3) {
if (!_is_hex(mac[i]) || !_is_hex(mac[i+1]))
return 0;
/* check for colons - last group doesn't end with a colon*/
if (i != 15 && mac[i+2] != ':')
return 0;
}
return 1;
}
static int parse_mac(u8 *dst, char *mac_str) {
int i;
int j;
if (!is_valid_mac_str(mac_str))
return 1;
/* j = dst offset
* i = mac_str offset
*/
for (i=0, j=0; i<= 15; i+=3, j++) {
dst[j] = _from_hex(mac_str[i]) << 4 | _from_hex(mac_str[i + 1]);
}
return 0;
}
/* copy calibration sector to the sector before calibration */
static int backup_calibration(u8 *buffer)
{
int rc = -1;
/* read */
memcpy(buffer, (void *)BOARDCAL, CFG_FLASH_SECTOR_SIZE);
/* erase */
rc = flash_erase(flash_info, CAL_SECTOR-1, CAL_SECTOR-1);
if (rc) {
printf("Backup failed because flash erase failed! rc %d\n", rc);
return 1;
}
/* cp */
rc = write_buff(flash_info, buffer, BOARDCAL-CFG_FLASH_SECTOR_SIZE, CFG_FLASH_SECTOR_SIZE);
if (rc) {
printf("Backup failed because write to flash failed! rc %d\n", rc);
return 1;
}
/* compare */
if (memcmp(buffer, (void *)BOARDCAL-CFG_FLASH_SECTOR_SIZE, CFG_FLASH_SECTOR_SIZE)) {
printf("Backup failed. Read back different value!\n");
return 1;
}
return 0;
}
int write_mac(u8 *buffer, u8 macs[ARRAY_SIZE(mac_location)][ETH_ALEN])
{
int i;
int rc;
/* read */
memcpy(buffer, (void *)BOARDCAL, CFG_FLASH_SECTOR_SIZE);
/* set macs */
for(i=0; i<ARRAY_SIZE(mac_location); i++) {
memcpy(buffer + mac_location[i], macs[i], ETH_ALEN);
}
/* erase */
rc = flash_erase(flash_info, CAL_SECTOR, CAL_SECTOR);
if (rc) {
printf("Write mac failed because flash_erase failed! rc %d\n", rc);
return 1;
}
/* write */
rc = write_buff(flash_info, buffer, BOARDCAL, CFG_FLASH_SECTOR_SIZE);
if (rc) {
printf("Write mac failed because write_buff failed! rc %d\n", rc);
return 1;
}
return 0;
}
int do_setmac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
u8 buffer[CFG_FLASH_SECTOR_SIZE];
u8 macs[ARRAY_SIZE(mac_location)][ETH_ALEN];
int i;
bool do_backup = true;
/* valid arguments are:
* set_mac <mac0> <mac1> [..] or set_mac <mac0> <mac1> [..] nobackup
* check if enough arguments given
*/
if (argc != (ARRAY_SIZE(mac_location)+1) &&
argc != (ARRAY_SIZE(mac_location)+2))
return CMD_RET_FAILURE;
/* check if nobackup was given */
if (argc == (ARRAY_SIZE(mac_location)+2)) {
if(!strncmp("nobackup", argv[argc-1], 8)) {
do_backup = false;
} else {
printf("Unknown argument %s!\n", argv[argc-1]);
return CMD_RET_FAILURE;
}
}
/* all other arguments are mac address */
for (i=0; i < ARRAY_SIZE(mac_location); i++) {
if (!is_valid_mac_str(argv[i+1])) {
printf("Invalid MAC address %s!\n", argv[i+1]);
return CMD_RET_FAILURE;
}
}
/* parse macs and copy into macs */
for (i=0; i < ARRAY_SIZE(mac_location); i++) {
if (parse_mac(macs[i], argv[i+1])) {
printf("Can not parse mac %s!\n", argv[i+1]);
return CMD_RET_FAILURE;
}
}
if (do_backup) {
if (backup_calibration(buffer)) {
printf("Backup failed to the sector before calibration. Not updating calibration sector!");
return CMD_RET_FAILURE;
}
}
if (!write_mac(buffer, macs)) {
return CMD_RET_FAILURE;
}
return CMD_RET_SUCCESS;
}
int do_showmac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int i = 0;
u8 buffer[CFG_FLASH_SECTOR_SIZE];
u8 *mac;
memcpy(buffer, (void *)BOARDCAL, CFG_FLASH_SECTOR_SIZE);
for (i=0; i < ARRAY_SIZE(mac_location); i++) {
mac = buffer + mac_location[i];
printf("mac %d = %02x:%02x:%02x:%02x:%02x:%02x\n", i,
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
setmac, ARRAY_SIZE(mac_location)+2, 0, do_setmac,
"setmac - Set ethernet MAC addresses\n",
"setmac [<eth0> <eth1> <wlan0> [nobackup]]\n"
" without arguments it shows actual configuration\n"
" <eth0> mac address\n"
" <eth1> mac address\n"
" <wlan0> mac address\n"
" mac address 00:aa:bb:cc:dd:ee\n"
" nobackup - don't do a backup in the sector before calibration"
);
U_BOOT_CMD(
showmac, 1, 0, do_showmac,
"showmac - Show ethernet MAC addresses\n",
);
#endif /* CFG_CMD_SETMAC */

View File

@ -6,6 +6,8 @@
*/
#define CFG_FLASH_BASE 0x9f000000
#define CFG_CMD_SETMAC
#ifdef COMPRESSED_UBOOT
#define BOOTSTRAP_TEXT_BASE CFG_FLASH_BASE
#define BOOTSTRAP_CFG_MONITOR_BASE BOOTSTRAP_TEXT_BASE