diff --git a/target/linux/ar71xx/config-2.6.26 b/target/linux/ar71xx/config-2.6.26 index a7144684d..0d7918fdd 100644 --- a/target/linux/ar71xx/config-2.6.26 +++ b/target/linux/ar71xx/config-2.6.26 @@ -164,6 +164,7 @@ CONFIG_MTD_REDBOOT_PARTS_READONLY=y CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_SLRAM is not set +CONFIG_MYLOADER=y # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_NET_VENDOR_3COM is not set @@ -235,7 +236,6 @@ CONFIG_TRAD_SIGNALS=y CONFIG_USB=m CONFIG_USB_EHCI_AR71XX=y CONFIG_USB_EHCI_HCD=m -# CONFIG_USB_ISIGHTFW is not set CONFIG_USB_OHCI_AR71XX=y # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig index 274c3ede1..8640b2cc5 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig @@ -12,6 +12,7 @@ config AR71XX_MACH_GENERIC config AR71XX_MACH_WP543 bool "Compex WP543 board support" + select MYLOADER default y config AR71XX_MACH_RB_4XX diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c b/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c index db804fbb9..9e62114b1 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c @@ -414,7 +414,12 @@ err_free_buttons: kfree(p); } -void __init ar71xx_set_mac_base(char *mac_str) +void __init ar71xx_set_mac_base(unsigned char *mac) +{ + memcpy(ar71xx_mac_base, mac, ETH_ALEN); +} + +void __init ar71xx_parse_mac_addr(char *mac_str) { u8 tmp[ETH_ALEN]; int t; @@ -423,7 +428,7 @@ void __init ar71xx_set_mac_base(char *mac_str) &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); if (t == ETH_ALEN) - memcpy(ar71xx_mac_base, tmp, ETH_ALEN); + ar71xx_set_mac_base(tmp); else printk(KERN_DEBUG "AR71XX: failed to parse mac address " "\"%s\"\n", mac_str); diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/prom.c b/target/linux/ar71xx/files/arch/mips/ar71xx/prom.c index 69425d50c..d22c593e1 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/prom.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/prom.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -42,34 +43,31 @@ static struct board_rec boards[] __initdata = { } }; -static __init void routerboot_printargs(void) +static __init char *ar71xx_prom_getargv(const char *name) { + int len = strlen(name); int i; - for (i = 0; i < ar71xx_prom_argc; i++) - printk(KERN_DEBUG "prom: routerboot envp[%d]: %s\n", - i, ar71xx_prom_argv[i]); -} - -static __init char *routerboot_getenv(const char *envname) -{ - int len = strlen(envname); - int i; + if (!ar71xx_prom_argv) + return NULL; for (i = 0; i < ar71xx_prom_argc; i++) { - char *env = ar71xx_prom_argv[i]; - if (strncmp(envname, env, len) == 0 && (env)[len] == '=') - return env + len + 1; + char *argv = ar71xx_prom_argv[i]; + if (strncmp(name, argv, len) == 0 && (argv)[len] == '=') + return argv + len + 1; } return NULL; } -static __init char *redboot_getenv(const char *envname) +static __init char *ar71xx_prom_getenv(const char *envname) { int len = strlen(envname); char **env; + if (!ar71xx_prom_envp) + return NULL; + for (env = ar71xx_prom_envp; *env != NULL; env++) if (strncmp(envname, *env, len) == 0 && (*env)[len] == '=') return *env + len + 1; @@ -88,40 +86,61 @@ static __init unsigned long find_board_byname(char *name) return MACH_AR71XX_GENERIC; } +static int ar71xx_prom_init_myloader(void) +{ + struct myloader_info *mylo; + + mylo = myloader_get_info(); + if (!mylo) + return 0; + + switch (mylo->did) { + case DEVID_COMPEX_WP543: + mips_machtype = MACH_AR71XX_WP543; + break; + default: + printk(KERN_WARNING "prom: unknown device id: %x\n", + mylo->did); + } + ar71xx_set_mac_base(mylo->macs[0]); + + return 1; +} + +static void ar71xx_prom_init_generic(void) +{ + char *p; + + ar71xx_prom_argc = fw_arg0; + ar71xx_prom_argv = (char **)fw_arg1; + ar71xx_prom_envp = (char **)fw_arg2; + + p = ar71xx_prom_getenv("board"); + if (!p) + p = ar71xx_prom_getargv("board"); + if (p) + mips_machtype = find_board_byname(p); + + p = ar71xx_prom_getenv("ethaddr"); + if (!p) + p = ar71xx_prom_getargv("kmac"); + if (p) + ar71xx_parse_mac_addr(p); +} + void __init prom_init(void) { - char *board = NULL; - char *mac = NULL; - printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, " "fw_arg2=%08x, fw_arg3=%08x\n", (unsigned int)fw_arg0, (unsigned int)fw_arg1, (unsigned int)fw_arg2, (unsigned int)fw_arg3); - if ((fw_arg0 == 7) && (fw_arg2 == 0) && (fw_arg3 == 0)) { - /* assume RouterBOOT */ - ar71xx_prom_argc = fw_arg0; - ar71xx_prom_argv = (char **)fw_arg1; - routerboot_printargs(); - board = routerboot_getenv("board"); - mac = routerboot_getenv("kmac"); - } else { - /* assume Redboot */ - ar71xx_prom_argc = fw_arg0; - ar71xx_prom_argv = (char **)fw_arg1; - ar71xx_prom_envp = (char **)fw_arg2; - mac = redboot_getenv("ethaddr"); - } + mips_machtype = MACH_AR71XX_GENERIC; - if (board) - mips_machtype = find_board_byname(board); - else - mips_machtype = MACH_AR71XX_GENERIC; + if (ar71xx_prom_init_myloader()) + return; - if (mac) - ar71xx_set_mac_base(mac); - - ar71xx_print_cmdline(); + ar71xx_prom_init_generic(); } void __init prom_free_prom_memory(void) diff --git a/target/linux/ar71xx/files/arch/mips/fw/myloader/Makefile b/target/linux/ar71xx/files/arch/mips/fw/myloader/Makefile new file mode 100644 index 000000000..34acfd01c --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/fw/myloader/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the Compex's MyLoader support on MIPS architecture +# + +lib-y += myloader.o diff --git a/target/linux/ar71xx/files/arch/mips/fw/myloader/myloader.c b/target/linux/ar71xx/files/arch/mips/fw/myloader/myloader.c new file mode 100644 index 000000000..a26f9ad3f --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/fw/myloader/myloader.c @@ -0,0 +1,63 @@ +/* + * Compex's MyLoader specific prom routines + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include +#include +#include +#include + +#include +#include + +#define SYS_PARAMS_ADDR KSEG1ADDR(0x80000800) +#define BOARD_PARAMS_ADDR KSEG1ADDR(0x80000A00) +#define PART_TABLE_ADDR KSEG1ADDR(0x80000C00) +#define BOOT_PARAMS_ADDR KSEG1ADDR(0x80000E00) + +static struct myloader_info myloader_info __initdata; +static int myloader_found __initdata; + +struct myloader_info * __init myloader_get_info(void) +{ + struct mylo_system_params *sysp; + struct mylo_board_params *boardp; + struct mylo_partition_table *parts; + + if (myloader_found) + return &myloader_info; + + sysp = (struct mylo_system_params *)(SYS_PARAMS_ADDR); + boardp = (struct mylo_board_params *)(BOARD_PARAMS_ADDR); + parts = (struct mylo_partition_table *)(PART_TABLE_ADDR); + + printk(KERN_DEBUG "MyLoader: sysp=%08x, boardp=%08x, parts=%08x\n", + sysp->magic, boardp->magic, parts->magic); + + /* Check for some magic numbers */ + if (sysp->magic != MYLO_MAGIC_SYS_PARAMS || + boardp->magic != MYLO_MAGIC_BOARD_PARAMS || + le32_to_cpu(parts->magic) != MYLO_MAGIC_PARTITIONS) + return NULL; + + printk(KERN_DEBUG "MyLoader: id=%04x:%04x, sub_id=%04x:%04x\n", + sysp->vid, sysp->did, sysp->svid, sysp->sdid); + + myloader_info.vid = sysp->vid; + myloader_info.did = sysp->did; + myloader_info.svid = sysp->svid; + myloader_info.sdid = sysp->sdid; + + memcpy(myloader_info.macs, boardp->addr, sizeof(myloader_info.macs)); + + myloader_found = 1; + + return &myloader_info; +} diff --git a/target/linux/ar71xx/files/include/asm-mips/fw/myloader/myloader.h b/target/linux/ar71xx/files/include/asm-mips/fw/myloader/myloader.h new file mode 100644 index 000000000..8a99d566d --- /dev/null +++ b/target/linux/ar71xx/files/include/asm-mips/fw/myloader/myloader.h @@ -0,0 +1,34 @@ +/* + * Compex's MyLoader specific definitions + * + * Copyright (C) 2006-2008 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#ifndef _ASM_MIPS_FW_MYLOADER_H +#define _ASM_MIPS_FW_MYLOADER_H + +#include + +struct myloader_info { + uint32_t vid; + uint32_t did; + uint32_t svid; + uint32_t sdid; + uint8_t macs[MYLO_ETHADDR_COUNT][6]; +}; + +#ifdef CONFIG_MYLOADER +extern struct myloader_info *myloader_get_info(void) __init; +#else +static inline struct myloader_info *myloader_get_info(void) +{ + return NULL; +} +#endif /* CONFIG_MYLOADER */ + +#endif /* _ASM_MIPS_FW_MYLOADER_H */ diff --git a/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h b/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h index 32ca2965e..5b00e00be 100644 --- a/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h +++ b/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h @@ -45,7 +45,8 @@ extern void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata, struct spi_board_info const *info, unsigned n) __init; -extern void ar71xx_set_mac_base(char *mac_str) __init; +extern void ar71xx_set_mac_base(unsigned char *mac) __init; +extern void ar71xx_parse_mac_addr(char *mac_str) __init; extern void ar71xx_add_device_eth(unsigned int id, phy_interface_t phy_if_mode, u32 phy_mask) __init; diff --git a/target/linux/ar71xx/files/include/linux/myloader.h b/target/linux/ar71xx/files/include/linux/myloader.h new file mode 100644 index 000000000..c16c41341 --- /dev/null +++ b/target/linux/ar71xx/files/include/linux/myloader.h @@ -0,0 +1,116 @@ +/* + * Compex's MyLoader specific definitions + * + * Copyright (C) 2006-2008 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#ifndef _MYLOADER_H_ +#define _MYLOADER_H_ + +/* Myloader specific magic numbers */ +#define MYLO_MAGIC_SYS_PARAMS 0x20021107 +#define MYLO_MAGIC_PARTITIONS 0x20021103 +#define MYLO_MAGIC_BOARD_PARAMS 0x20021103 + +/* Vendor ID's (seems to be same as the PCI vendor ID's) */ +#define VENID_COMPEX 0x11F6 + +/* Devices based on the ADM5120 */ +#define DEVID_COMPEX_NP27G 0x0078 +#define DEVID_COMPEX_NP28G 0x044C +#define DEVID_COMPEX_NP28GHS 0x044E +#define DEVID_COMPEX_WP54Gv1C 0x0514 +#define DEVID_COMPEX_WP54G 0x0515 +#define DEVID_COMPEX_WP54AG 0x0546 +#define DEVID_COMPEX_WPP54AG 0x0550 +#define DEVID_COMPEX_WPP54G 0x0555 + +/* Devices based on the Atheros AR71xx */ +#define DEVID_COMPEX_WP543 0x0640 + +/* Devices based on the IXP422 */ +#define DEVID_COMPEX_WP18 0x047E +#define DEVID_COMPEX_NP18A 0x0489 + +/* Other devices */ +#define DEVID_COMPEX_NP26G8M 0x03E8 +#define DEVID_COMPEX_NP26G16M 0x03E9 + +struct mylo_partition { + uint16_t flags; /* partition flags */ + uint16_t type; /* type of the partition */ + uint32_t addr; /* relative address of the partition from the + flash start */ + uint32_t size; /* size of the partition in bytes */ + uint32_t param; /* if this is the active partition, the + MyLoader load code to this address */ +}; + +#define PARTITION_FLAG_ACTIVE 0x8000 /* this is the active partition, + * MyLoader loads firmware from here */ +#define PARTITION_FLAG_ISRAM 0x2000 /* FIXME: this is a RAM partition? */ +#define PARTIIION_FLAG_RAMLOAD 0x1000 /* FIXME: load this partition into the RAM? */ +#define PARTITION_FLAG_PRELOAD 0x0800 /* the partition data preloaded to RAM + * before decompression */ +#define PARTITION_FLAG_LZMA 0x0100 /* partition data compressed by LZMA */ +#define PARTITION_FLAG_HAVEHDR 0x0002 /* the partition data have a header */ + +#define PARTITION_TYPE_FREE 0 +#define PARTITION_TYPE_USED 1 + +#define MYLO_MAX_PARTITIONS 8 /* maximum number of partitions in the + partition table */ + +struct mylo_partition_table { + uint32_t magic; /* must be MYLO_MAGIC_PARTITIONS */ + uint32_t res0; /* unknown/unused */ + uint32_t res1; /* unknown/unused */ + uint32_t res2; /* unknown/unused */ + struct mylo_partition partitions[MYLO_MAX_PARTITIONS]; +}; + +struct mylo_partition_header { + uint32_t len; /* length of the partition data */ + uint32_t crc; /* CRC value of the partition data */ +}; + +struct mylo_system_params { + uint32_t magic; /* must be MYLO_MAGIC_SYS_PARAMS */ + uint32_t res0; + uint32_t res1; + uint32_t mylo_ver; + uint16_t vid; /* Vendor ID */ + uint16_t did; /* Device ID */ + uint16_t svid; /* Sub Vendor ID */ + uint16_t sdid; /* Sub Device ID */ + uint32_t rev; /* device revision */ + uint32_t fwhi; + uint32_t fwlo; + uint32_t tftp_addr; + uint32_t prog_start; + uint32_t flash_size; /* size of boot FLASH in bytes */ + uint32_t dram_size; /* size of onboard RAM in bytes */ +}; + +struct mylo_eth_addr { + uint8_t mac[6]; + uint8_t csum[2]; +}; + +#define MYLO_ETHADDR_COUNT 8 /* maximum number of ethernet address + in the board parameters */ + +struct mylo_board_params { + uint32_t magic; /* must be MYLO_MAGIC_BOARD_PARAMS */ + uint32_t res0; + uint32_t res1; + uint32_t res2; + struct mylo_eth_addr addr[MYLO_ETHADDR_COUNT]; +}; + +#endif /* _MYLOADER_H_*/ diff --git a/target/linux/ar71xx/patches-2.6.26/300-mips_fw_myloader.patch b/target/linux/ar71xx/patches-2.6.26/300-mips_fw_myloader.patch new file mode 100644 index 000000000..4ab8b7521 --- /dev/null +++ b/target/linux/ar71xx/patches-2.6.26/300-mips_fw_myloader.patch @@ -0,0 +1,22 @@ +--- a/arch/mips/Makefile ++++ b/arch/mips/Makefile +@@ -158,6 +158,7 @@ + # + libs-$(CONFIG_ARC) += arch/mips/fw/arc/ + libs-$(CONFIG_CFE) += arch/mips/fw/cfe/ ++libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/ + libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/ + libs-y += arch/mips/fw/lib/ + libs-$(CONFIG_SIBYTE_CFE) += arch/mips/sibyte/cfe/ +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -873,6 +873,9 @@ + config MIPS_DISABLE_OBSOLETE_IDE + bool + ++config MYLOADER ++ bool ++ + config SYNC_R4K + bool +