From c925dcdb37a25a9b3bede6f99a76e916f7b6460b Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 9 Jun 2010 10:05:00 +0300 Subject: [PATCH 01/65] mx25 3ds: fix build failure Remove redundant parameters from the imx_nand_load_image() call. Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer --- board/freescale-mx25-3-stack/3stack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/freescale-mx25-3-stack/3stack.c b/board/freescale-mx25-3-stack/3stack.c index 5b802adbb..21774f235 100644 --- a/board/freescale-mx25-3-stack/3stack.c +++ b/board/freescale-mx25-3-stack/3stack.c @@ -320,7 +320,7 @@ console_initcall(imx25_console_init); #ifdef CONFIG_NAND_IMX_BOOT void __bare_init nand_boot(void) { - imx_nand_load_image((void *)TEXT_BASE, 256 * 1024, 2048, 16384); + imx_nand_load_image((void *)TEXT_BASE, 256 * 1024); } #endif From e490bd671531c7fb7c139226ef93de3db250d341 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 9 Jun 2010 10:05:01 +0300 Subject: [PATCH 02/65] mx25: fix typo in imx25-regs.h Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imx25-regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h index 556ffb0c6..80521251c 100644 --- a/arch/arm/mach-imx/include/mach/imx25-regs.h +++ b/arch/arm/mach-imx/include/mach/imx25-regs.h @@ -21,7 +21,7 @@ */ #ifndef __ASM_ARCH_MX25_REGS_H -#define __ASM_ARCH_MX35_REGS_H +#define __ASM_ARCH_MX25_REGS_H /* * sanity check From ca593071eccbac40aabe8b1fe34928837410aced Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 9 Jun 2010 10:05:02 +0300 Subject: [PATCH 03/65] mx25 3ds: cleanup lowlevel_init code * remove unused asm/cache-l2x0.h header include * remove out of place comment * remove redundant defines Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer --- board/freescale-mx25-3-stack/lowlevel_init.S | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/board/freescale-mx25-3-stack/lowlevel_init.S b/board/freescale-mx25-3-stack/lowlevel_init.S index bf03390c1..73bb14723 100644 --- a/board/freescale-mx25-3-stack/lowlevel_init.S +++ b/board/freescale-mx25-3-stack/lowlevel_init.S @@ -24,7 +24,6 @@ #include #include #include -#include #define writel(val, reg) \ ldr r0, =reg; \ @@ -56,13 +55,7 @@ CCM_BASE_ADDR_W: .word IMX_CCM_BASE board_init_lowlevel: mov r10, lr -/* - * End of ARM1136 init - */ #define MX25_CCM_MCR 0x64 -#define MX25_CCM_CGR0 0x0c -#define MX25_CCM_CGR1 0x10 -#define MX25_CCM_CGR2 0x14 ldr r0, CCM_BASE_ADDR_W /* default CLKO to 1/32 of the ARM core */ @@ -75,9 +68,9 @@ board_init_lowlevel: str r1, [r0, #MX25_CCM_MCR] /* enable all the clocks */ - writel(0x1FFFFFFF, IMX_CCM_BASE + MX25_CCM_CGR0) - writel(0xFFFFFFFF, IMX_CCM_BASE + MX25_CCM_CGR1) - writel(0x000FDFFF, IMX_CCM_BASE + MX25_CCM_CGR2) + writel(0x1FFFFFFF, IMX_CCM_BASE + CCM_CGCR0) + writel(0xFFFFFFFF, IMX_CCM_BASE + CCM_CGCR1) + writel(0x000FDFFF, IMX_CCM_BASE + CCM_CGCR2) writel(0x0000FEFF, IMX_CCM_BASE + MX25_CCM_MCR) /* Skip SDRAM initialization if we run from RAM */ From c672f6fcd7ed9fce05b6fd39d1b85dd61980063a Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 9 Jun 2010 10:05:03 +0300 Subject: [PATCH 04/65] mx25: add support for i2c Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imx25-regs.h | 1 + arch/arm/mach-imx/include/mach/iomux-mx25.h | 4 ++-- arch/arm/mach-imx/speed-imx25.c | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h index 80521251c..e91e7b69a 100644 --- a/arch/arm/mach-imx/include/mach/imx25-regs.h +++ b/arch/arm/mach-imx/include/mach/imx25-regs.h @@ -46,6 +46,7 @@ #define IMX_M3IF_BASE 0xB8003000 #define IMX_NFC_BASE 0xBB000000 #define IMX_FEC_BASE 0x50038000 +#define IMX_I2C1_BASE 0x43F80000 /* * Clock Controller Module (CCM) diff --git a/arch/arm/mach-imx/include/mach/iomux-mx25.h b/arch/arm/mach-imx/include/mach/iomux-mx25.h index 379bfcb0e..a290a338d 100644 --- a/arch/arm/mach-imx/include/mach/iomux-mx25.h +++ b/arch/arm/mach-imx/include/mach/iomux-mx25.h @@ -417,10 +417,10 @@ #define MX25_PAD_HSYNC__GPIO22 IOMUX_PAD(0x300, 0x108, 5, 0, 0, NO_PAD_CTRL) #define MX25_PAD_HSYNC__USBH2_DATA4 IOMUX_PAD(0x300, 0x108, 6, 0, 0, 0xe5) #define MX25_PAD_HSYNC__BT_UART_SRC1 IOMUX_PAD(0x300, 0x108, 7, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_I2C1_CLK__SCL IOMUX_PAD(0x348, 0x150, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_I2C1_CLK__SCL IOMUX_PAD(0x348, 0x150, 0, 0, 0, (HYS | PKE | PUE | PUS_100K_UP)) #define MX25_PAD_I2C1_CLK__GPIO12 IOMUX_PAD(0x348, 0x150, 5, 0, 0, NO_PAD_CTRL) #define MX25_PAD_I2C1_CLK__SLCDC_DATA6 IOMUX_PAD(0x348, 0x150, 6, 0, 0, NO_PAD_CTRL) -#define MX25_PAD_I2C1_DAT__SDA IOMUX_PAD(0x34c, 0x154, 0, 0, 0, NO_PAD_CTRL) +#define MX25_PAD_I2C1_DAT__SDA IOMUX_PAD(0x34c, 0x154, 0, 0, 0, (HYS | PKE | PUE | PUS_100K_UP)) #define MX25_PAD_I2C1_DAT__GPIO13 IOMUX_PAD(0x34c, 0x154, 5, 0, 0, NO_PAD_CTRL) #define MX25_PAD_I2C1_DAT__SLCDC_DATA7 IOMUX_PAD(0x34c, 0x154, 6, 0, 0, NO_PAD_CTRL) #define MX25_PAD_KPP_COL0__COL0 IOMUX_PAD(0x3b0, 0x1b8, 0, 0, 0, NO_PAD_CTRL) diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c index a615017ee..96056741e 100644 --- a/arch/arm/mach-imx/speed-imx25.c +++ b/arch/arm/mach-imx/speed-imx25.c @@ -77,6 +77,11 @@ unsigned long imx_get_lcdclk(void) return imx_get_perclk(7); } +unsigned long imx_get_i2cclk(void) +{ + return imx_get_perclk(6); +} + int imx_dump_clocks(void) { printf("mpll: %10d Hz\n", imx_get_mpllclk()); From 514387711f2d7c5e3476ca80354d989797d088f4 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 9 Jun 2010 10:05:04 +0300 Subject: [PATCH 05/65] i2c: add driver for the MC34704 PMIC Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer --- drivers/i2c/Kconfig | 3 + drivers/i2c/Makefile | 1 + drivers/i2c/mc34704.c | 140 ++++++++++++++++++++++++++++++++++++++++++ include/i2c/mc34704.h | 26 ++++++++ 4 files changed, 170 insertions(+) create mode 100644 drivers/i2c/mc34704.c create mode 100644 include/i2c/mc34704.h diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index f1b2949fa..a9ee41140 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -10,6 +10,9 @@ config DRIVER_I2C_IMX config DRIVER_I2C_MC13892 bool "MC13892 a.k.a. PMIC driver" +config DRIVER_I2C_MC34704 + bool "MC34704 PMIC driver" + config DRIVER_I2C_MC9SDZ60 bool "MC9SDZ60 driver" diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 62d030bf0..13e58040f 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -3,5 +3,6 @@ obj-$(CONFIG_I2C) += i2c.o obj-$(CONFIG_DRIVER_I2C_IMX) += i2c-imx.o obj-$(CONFIG_DRIVER_I2C_MC13892) += mc13892.o +obj-$(CONFIG_DRIVER_I2C_MC34704) += mc34704.o obj-$(CONFIG_DRIVER_I2C_MC9SDZ60) += mc9sdz60.o obj-$(CONFIG_DRIVER_I2C_LP3972) += lp3972.o diff --git a/drivers/i2c/mc34704.c b/drivers/i2c/mc34704.c new file mode 100644 index 000000000..51a873720 --- /dev/null +++ b/drivers/i2c/mc34704.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * 2009 Marc Kleine-Budde + * Copyright (C) 2010 Baruch Siach + * + * 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 +#include +#include +#include +#include + +#include +#include + +#define DRIVERNAME "mc34704" + +#define to_mc34704(a) container_of(a, struct mc34704, cdev) + +static struct mc34704 *mc34704_dev; + +struct mc34704 *mc34704_get(void) +{ + if (!mc34704_dev) + return NULL; + + return mc34704_dev; +} +EXPORT_SYMBOL(mc34704_get); + +int mc34704_reg_read(struct mc34704 *mc34704, u8 reg, u8 *val) +{ + int ret; + + ret = i2c_read_reg(mc34704->client, reg, val, 1); + + return ret == 1 ? 0 : ret; +} +EXPORT_SYMBOL(mc34704_reg_read) + +int mc34704_reg_write(struct mc34704 *mc34704, u8 reg, u8 val) +{ + int ret; + + ret = i2c_write_reg(mc34704->client, reg, &val, 1); + + return ret == 1 ? 0 : ret; +} +EXPORT_SYMBOL(mc34704_reg_write) + +static ssize_t mc34704_read(struct cdev *cdev, void *_buf, size_t count, + ulong offset, ulong flags) +{ + struct mc34704 *priv = to_mc34704(cdev); + u8 *buf = _buf; + size_t i = count; + int err; + + while (i) { + err = mc34704_reg_read(priv, offset, buf); + if (err) + return (ssize_t)err; + buf++; + i--; + offset++; + } + + return count; +} + +static ssize_t mc34704_write(struct cdev *cdev, const void *_buf, size_t count, + ulong offset, ulong flags) +{ + struct mc34704 *mc34704 = to_mc34704(cdev); + const u8 *buf = _buf; + size_t i = count; + int err; + + while (i) { + err = mc34704_reg_write(mc34704, offset, *buf); + if (err) + return (ssize_t)err; + buf++; + i--; + offset++; + } + + return count; +} + +static struct file_operations mc34704_fops = { + .lseek = dev_lseek_default, + .read = mc34704_read, + .write = mc34704_write, +}; + +static int mc34704_probe(struct device_d *dev) +{ + if (mc34704_dev) + return -EBUSY; + + mc34704_dev = xzalloc(sizeof(struct mc34704)); + mc34704_dev->cdev.name = DRIVERNAME; + mc34704_dev->client = to_i2c_client(dev); + mc34704_dev->cdev.size = 256; + mc34704_dev->cdev.dev = dev; + mc34704_dev->cdev.ops = &mc34704_fops; + + devfs_create(&mc34704_dev->cdev); + + return 0; +} + +static struct driver_d mc34704_driver = { + .name = DRIVERNAME, + .probe = mc34704_probe, +}; + +static int mc34704_init(void) +{ + register_driver(&mc34704_driver); + return 0; +} +device_initcall(mc34704_init); diff --git a/include/i2c/mc34704.h b/include/i2c/mc34704.h new file mode 100644 index 000000000..a3723d72a --- /dev/null +++ b/include/i2c/mc34704.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2009 Marc Kleine-Budde + * Copyright (C) 2010 Baruch Siach + * + * This file is released under the GPLv2 + * + * Derived from: + * - arch-mxc/pmic_external.h -- contains interface of the PMIC protocol driver + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + */ + +#ifndef __I2C_MC34704_H +#define __I2C_MC34704_H + +struct mc34704 { + struct cdev cdev; + struct i2c_client *client; +}; + +extern struct mc34704 *mc34704_get(void); + +extern int mc34704_reg_read(struct mc34704 *mc34704, u8 reg, u8 *val); +extern int mc34704_reg_write(struct mc34704 *mc34704, u8 reg, u8 val); + +#endif /* __I2C_MC34704_H */ From dcdd890e0c2e5aca9de6f254d6812941402538bf Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 9 Jun 2010 10:05:05 +0300 Subject: [PATCH 06/65] mx25 3ds: add support for i2c master and PMIC Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer --- board/freescale-mx25-3-stack/3stack.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/board/freescale-mx25-3-stack/3stack.c b/board/freescale-mx25-3-stack/3stack.c index 21774f235..5f0b50c54 100644 --- a/board/freescale-mx25-3-stack/3stack.c +++ b/board/freescale-mx25-3-stack/3stack.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include extern unsigned long _stext; @@ -183,8 +185,18 @@ static struct device_d usbh2_dev = { }; #endif +static struct i2c_board_info i2c_devices[] = { + { + I2C_BOARD_INFO("mc34704", 0x54), + }, +}; #define IOMUXC_BASE_ADDR 0x43FAC000 +static struct device_d i2c_dev = { + .name = "i2c-imx", + .map_base = IMX_I2C1_BASE, +}; + static int imx25_devices_init(void) { ulong val; @@ -256,6 +268,9 @@ static int imx25_devices_init(void) register_device(&sdram0_dev); register_device(&sram0_dev); + i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices)); + register_device(&i2c_dev); + armlinux_set_bootparams((void *)0x80000100); armlinux_set_architecture(MACH_TYPE_MX25_3DS); @@ -303,6 +318,9 @@ static struct pad_desc imx25_pads[] = { MX25_PAD_VSYNC__USBH2_DATA5, MX25_PAD_LSCLK__USBH2_DATA6, MX25_PAD_OE_ACD__USBH2_DATA7, + /* i2c */ + MX25_PAD_I2C1_CLK__SCL, + MX25_PAD_I2C1_DAT__SDA, }; static int imx25_console_init(void) From 1b1fa988bae8728c09375da799b3a6889449fd56 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 9 Jun 2010 10:05:06 +0300 Subject: [PATCH 07/65] mx25 3ds: fix fec initialization The fec network interface initialization depends on the initialization of the PMIC. Once the MC34704 driver is registered we can enable the PHY power supply, and go on with the PHY initialization. While we are at it convert the hard-coded GPIO registers access to the general GPIO API for shorter and clearer code. Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer --- board/freescale-mx25-3-stack/3stack.c | 63 ++++++++++++++------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/board/freescale-mx25-3-stack/3stack.c b/board/freescale-mx25-3-stack/3stack.c index 5f0b50c54..d030f4ed9 100644 --- a/board/freescale-mx25-3-stack/3stack.c +++ b/board/freescale-mx25-3-stack/3stack.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -190,16 +191,30 @@ static struct i2c_board_info i2c_devices[] = { I2C_BOARD_INFO("mc34704", 0x54), }, }; -#define IOMUXC_BASE_ADDR 0x43FAC000 static struct device_d i2c_dev = { .name = "i2c-imx", .map_base = IMX_I2C1_BASE, }; -static int imx25_devices_init(void) +static int imx25_3ds_pmic_init(void) { - ulong val; + struct mc34704 *pmic; + + pmic = mc34704_get(); + if (pmic == NULL) + return -EIO; + + return mc34704_reg_write(pmic, 0x2, 0x9); +} + +static int imx25_3ds_fec_init(void) +{ + int ret; + + ret = imx25_3ds_pmic_init(); + if (ret < 0) + return ret; /* * Set up the FEC_RESET_B and FEC_ENABLE GPIO pins. @@ -209,36 +224,27 @@ static int imx25_devices_init(void) * FEC_RESET_B: gpio2[3] is ALT 5 mode of pin A17 * FEC_ENABLE_B: gpio4[8] is ALT 5 mode of pin D12 */ - writel(0x8, IOMUXC_BASE_ADDR + 0x0238); /* open drain */ - writel(0x0, IOMUXC_BASE_ADDR + 0x028C); /* cmos, no pu/pd */ + writel(0x8, IMX_IOMUXC_BASE + 0x0238); /* open drain */ + writel(0x0, IMX_IOMUXC_BASE + 0x028C); /* cmos, no pu/pd */ -#define GPIO2_BASE_ADDR 0x53FD0000 -#define GPIO4_BASE_ADDR 0x53F9C000 -#define GPIO_GDIR 0x04 -#define GPIO_DR 0x00 +#define FEC_ENABLE_GPIO 35 +#define FEC_RESET_B_GPIO 104 /* make the pins output */ - val = (1 << 3) | readl(GPIO2_BASE_ADDR + GPIO_GDIR); - writel(val, GPIO2_BASE_ADDR + GPIO_GDIR); - - val = (1 << 8) | readl(GPIO4_BASE_ADDR + GPIO_GDIR); - writel(val, GPIO4_BASE_ADDR + GPIO_GDIR); - - /* drop PHY power */ - val = readl(GPIO2_BASE_ADDR + GPIO_DR) & ~(1 << 3); - writel(val, GPIO2_BASE_ADDR + GPIO_DR); - - /* assert reset */ - val = readl(GPIO4_BASE_ADDR + GPIO_DR) & ~(1 << 8); - writel(val, GPIO4_BASE_ADDR + GPIO_DR); + gpio_direction_output(FEC_ENABLE_GPIO, 0); /* drop PHY power */ + gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */ udelay(2); /* turn on power & lift reset */ - val = (1 << 3) | readl(GPIO2_BASE_ADDR + GPIO_DR); - writel(val, GPIO2_BASE_ADDR + GPIO_DR); - val = (1 << 8) | readl(GPIO4_BASE_ADDR + GPIO_DR); - writel(val, GPIO4_BASE_ADDR + GPIO_DR); + gpio_set_value(FEC_ENABLE_GPIO, 1); + gpio_set_value(FEC_RESET_B_GPIO, 1); + return 0; +} +late_initcall(imx25_3ds_fec_init); + +static int imx25_devices_init(void) +{ #ifdef CONFIG_USB /* USB does not work yet. Don't know why. Maybe * the CPLD has to be initialized. @@ -247,11 +253,6 @@ static int imx25_devices_init(void) register_device(&usbh2_dev); #endif - /* FEC does only work when the CPLD is initialized. - * Currently we do not do this in barebox, so it - * does only work when Linux has been started after - * the last powercycle. - */ register_device(&fec_dev); if (readl(IMX_CCM_BASE + CCM_RCSR) & (1 << 14)) From c9856272273698b9dfe89fbc7d1791a84f05c286 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 9 Jun 2010 11:24:56 +0300 Subject: [PATCH 08/65] mx25 3ds: fix memory initialization Signed-off-by: Baruch Siach Signed-off-by: Sascha Hauer --- board/freescale-mx25-3-stack/3stack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/board/freescale-mx25-3-stack/3stack.c b/board/freescale-mx25-3-stack/3stack.c index d030f4ed9..372fbc6d3 100644 --- a/board/freescale-mx25-3-stack/3stack.c +++ b/board/freescale-mx25-3-stack/3stack.c @@ -272,6 +272,7 @@ static int imx25_devices_init(void) i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices)); register_device(&i2c_dev); + armlinux_add_dram(&sdram0_dev); armlinux_set_bootparams((void *)0x80000100); armlinux_set_architecture(MACH_TYPE_MX25_3DS); From f2fdfe875fee5b94feab7f2e79e3de8875b3eb3f Mon Sep 17 00:00:00 2001 From: Eric Benard Date: Thu, 10 Jun 2010 09:43:02 +0200 Subject: [PATCH 09/65] Add support for Eukrea CPUIMX35 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this modules is based on Freescale's i.MX357 CPU, with 128MB of mDDR, 256 MB NAND, and ethernet PHY. Signed-off-by: Eric Bénard Signed-off-by: Sascha Hauer --- arch/arm/Makefile | 1 + arch/arm/configs/eukrea_cpuimx35_defconfig | 254 +++++++++++++++ arch/arm/mach-imx/Kconfig | 11 + board/eukrea_cpuimx35/Makefile | 25 ++ board/eukrea_cpuimx35/config.h | 23 ++ board/eukrea_cpuimx35/env/bin/_update | 36 ++ board/eukrea_cpuimx35/env/bin/boot | 52 +++ board/eukrea_cpuimx35/env/bin/hush_hack | 1 + board/eukrea_cpuimx35/env/bin/init | 41 +++ board/eukrea_cpuimx35/env/bin/update_kernel | 8 + board/eukrea_cpuimx35/env/bin/update_root | 8 + board/eukrea_cpuimx35/env/config | 27 ++ board/eukrea_cpuimx35/eukrea_cpuimx35.c | 343 ++++++++++++++++++++ board/eukrea_cpuimx35/eukrea_cpuimx35.dox | 4 + board/eukrea_cpuimx35/flash_header.c | 60 ++++ board/eukrea_cpuimx35/lowlevel.c | 218 +++++++++++++ 16 files changed, 1112 insertions(+) create mode 100644 arch/arm/configs/eukrea_cpuimx35_defconfig create mode 100644 board/eukrea_cpuimx35/Makefile create mode 100644 board/eukrea_cpuimx35/config.h create mode 100644 board/eukrea_cpuimx35/env/bin/_update create mode 100644 board/eukrea_cpuimx35/env/bin/boot create mode 100644 board/eukrea_cpuimx35/env/bin/hush_hack create mode 100644 board/eukrea_cpuimx35/env/bin/init create mode 100644 board/eukrea_cpuimx35/env/bin/update_kernel create mode 100644 board/eukrea_cpuimx35/env/bin/update_root create mode 100644 board/eukrea_cpuimx35/env/config create mode 100644 board/eukrea_cpuimx35/eukrea_cpuimx35.c create mode 100644 board/eukrea_cpuimx35/eukrea_cpuimx35.dox create mode 100644 board/eukrea_cpuimx35/flash_header.c create mode 100644 board/eukrea_cpuimx35/lowlevel.c diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 0bdce2196..85ff9c8ad 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -63,6 +63,7 @@ board-$(CONFIG_MACH_EDB9315) := edb93xx board-$(CONFIG_MACH_EDB9315A) := edb93xx board-$(CONFIG_MACH_EUKREA_CPUIMX25) := eukrea_cpuimx25 board-$(CONFIG_MACH_EUKREA_CPUIMX27) := eukrea_cpuimx27 +board-$(CONFIG_MACH_EUKREA_CPUIMX35) := eukrea_cpuimx35 board-$(CONFIG_MACH_FREESCALE_MX25_3STACK) := freescale-mx25-3-stack board-$(CONFIG_MACH_FREESCALE_MX35_3STACK) := freescale-mx35-3-stack board-$(CONFIG_MACH_IMX21ADS) := imx21ads diff --git a/arch/arm/configs/eukrea_cpuimx35_defconfig b/arch/arm/configs/eukrea_cpuimx35_defconfig new file mode 100644 index 000000000..ff6547f1d --- /dev/null +++ b/arch/arm/configs/eukrea_cpuimx35_defconfig @@ -0,0 +1,254 @@ +# +# Automatically generated make config: don't edit +# barebox version: 2010.06.0 +# Mon Jun 7 18:25:47 2010 +# +# CONFIG_BOARD_LINKER_SCRIPT is not set +CONFIG_GENERIC_LINKER_SCRIPT=y +CONFIG_ARM=y + +# +# System Type +# +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_EP93XX is not set +CONFIG_ARCH_IMX=y +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_S3C24xx is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_V6=y +CONFIG_CPU_32v6=y + +# +# processor features +# +CONFIG_ARCH_HAS_L2X0=y +CONFIG_CACHE_L2X0=y +CONFIG_ARCH_TEXT_BASE=0x87f00000 +CONFIG_BOARDINFO="Eukrea CPUIMX35" +CONFIG_ARCH_HAS_FEC_IMX=y +CONFIG_ARCH_IMX_INTERNAL_BOOT=y + +# +# Freescale i.MX System-on-Chip +# +# CONFIG_ARCH_IMX1 is not set +# CONFIG_ARCH_IMX21 is not set +# CONFIG_ARCH_IMX25 is not set +# CONFIG_ARCH_IMX27 is not set +# CONFIG_ARCH_IMX31 is not set +CONFIG_ARCH_IMX35=y +CONFIG_MACH_EUKREA_CPUIMX35=y +# CONFIG_MACH_FREESCALE_MX35_3STACK is not set +# CONFIG_MACH_PCM043 is not set + +# +# Board specific settings +# + +# +# i.MX specific settings +# +# CONFIG_IMX_CLKO is not set +# CONFIG_AEABI is not set + +# +# Arm specific settings +# +CONFIG_CMD_ARM_CPUINFO=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_GREGORIAN_CALENDER=y +CONFIG_HAS_KALLSYMS=y +CONFIG_HAS_MODULES=y +CONFIG_CMD_MEMORY=y +CONFIG_ENV_HANDLING=y +CONFIG_GENERIC_GPIO=y + +# +# General Settings +# +CONFIG_LOCALVERSION_AUTO=y + +# +# memory layout +# +CONFIG_HAVE_MMU=y +CONFIG_MMU=y +CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y +CONFIG_TEXT_BASE=0x87f00000 +CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y +CONFIG_MEMORY_LAYOUT_DEFAULT=y +# CONFIG_MEMORY_LAYOUT_FIXED is not set +CONFIG_STACK_SIZE=0x8000 +CONFIG_MALLOC_SIZE=0x800000 +# CONFIG_BROKEN is not set +# CONFIG_EXPERIMENTAL is not set +CONFIG_MACH_HAS_LOWLEVEL_INIT=y +CONFIG_MACH_DO_LOWLEVEL_INIT=y +CONFIG_PROMPT="barebox:" +CONFIG_BAUDRATE=115200 +CONFIG_LONGHELP=y +CONFIG_CBSIZE=1024 +CONFIG_MAXARGS=16 +CONFIG_SHELL_HUSH=y +# CONFIG_SHELL_SIMPLE is not set +CONFIG_GLOB=y +CONFIG_PROMPT_HUSH_PS2="> " +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_DYNAMIC_CRC_TABLE=y +CONFIG_ERRNO_MESSAGES=y +CONFIG_TIMESTAMP=y +CONFIG_CONSOLE_FULL=y +CONFIG_CONSOLE_ACTIVATE_FIRST=y +# CONFIG_OF_FLAT_TREE is not set +# CONFIG_PARTITION is not set +# CONFIG_DEFAULT_ENVIRONMENT is not set + +# +# Debugging +# +# CONFIG_DEBUG_INFO is not set +# CONFIG_ENABLE_FLASH_NOISE is not set +# CONFIG_ENABLE_PARTITION_NOISE is not set +# CONFIG_ENABLE_DEVICE_NOISE is not set + +# +# Commands +# + +# +# scripting +# +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TRUE=y +CONFIG_CMD_FALSE=y + +# +# file commands +# +CONFIG_CMD_LS=y +CONFIG_CMD_RM=y +CONFIG_CMD_CAT=y +CONFIG_CMD_MKDIR=y +CONFIG_CMD_RMDIR=y +CONFIG_CMD_CP=y +CONFIG_CMD_PWD=y +CONFIG_CMD_CD=y +CONFIG_CMD_MOUNT=y +CONFIG_CMD_UMOUNT=y + +# +# console +# +CONFIG_CMD_CLEAR=y +CONFIG_CMD_ECHO=y +CONFIG_CMD_ECHO_E=y + +# +# memory +# +CONFIG_CMD_LOADB=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_CRC=y +CONFIG_CMD_MTEST=y +# CONFIG_CMD_MTEST_ALTERNATIVE is not set + +# +# flash +# +# CONFIG_CMD_FLASH is not set + +# +# booting +# +CONFIG_CMD_BOOTM=y +# CONFIG_CMD_BOOTM_ZLIB is not set +# CONFIG_CMD_BOOTM_BZLIB is not set +# CONFIG_CMD_BOOTM_SHOW_TYPE is not set +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_BOOTU=y +# CONFIG_CMD_LINUX16 is not set +CONFIG_CMD_RESET=y +CONFIG_CMD_GO=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_TEST=y +CONFIG_CMD_VERSION=y +CONFIG_CMD_HELP=y +CONFIG_CMD_DEVINFO=y +CONFIG_CMD_BMP=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_UNLZO=y +CONFIG_NET=y +CONFIG_NET_DHCP=y +# CONFIG_NET_RARP is not set +# CONFIG_NET_NFS is not set +CONFIG_NET_PING=y +CONFIG_NET_TFTP=y + +# +# Drivers +# + +# +# serial drivers +# +# CONFIG_DRIVER_SERIAL_ARM_DCC is not set +CONFIG_DRIVER_SERIAL_IMX=y +# CONFIG_DRIVER_SERIAL_NS16550 is not set +CONFIG_MIIPHY=y + +# +# Network drivers +# +# CONFIG_DRIVER_NET_SMC911X is not set +# CONFIG_DRIVER_NET_SMC91111 is not set +CONFIG_DRIVER_NET_FEC_IMX=y + +# +# SPI drivers +# +# CONFIG_SPI is not set +# CONFIG_I2C is not set + +# +# flash drivers +# +# CONFIG_DRIVER_CFI is not set +CONFIG_NAND=y +CONFIG_NAND_IMX=y +# CONFIG_NAND_IMX_BOOT is not set +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_ATA is not set +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_IMX_IPU=y + +# +# Filesystem support +# +# CONFIG_FS_CRAMFS is not set +CONFIG_FS_RAMFS=y +CONFIG_FS_DEVFS=y +CONFIG_CRC32=y +CONFIG_CRC16=y +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +CONFIG_PROCESS_ESCAPE_SEQUENCE=y +CONFIG_LZO_DECOMPRESS=y diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 419daab8b..afd8caef5 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -4,6 +4,7 @@ config ARCH_TEXT_BASE hex default 0x83f00000 if MACH_EUKREA_CPUIMX25 default 0xa0000000 if MACH_EUKREA_CPUIMX27 + default 0x87f00000 if MACH_EUKREA_CPUIMX35 default 0x08f00000 if MACH_MX1ADS default 0xc0000000 if MACH_IMX21ADS default 0xa0000000 if MACH_IMX27ADS @@ -19,6 +20,7 @@ config ARCH_TEXT_BASE config BOARDINFO default "Eukrea CPUIMX25" if MACH_EUKREA_CPUIMX25 default "Eukrea CPUIMX27" if MACH_EUKREA_CPUIMX27 + default "Eukrea CPUIMX35" if MACH_EUKREA_CPUIMX35 default "Freescale i.MX21 ADS" if MACH_IMX21ADS default "Freescale i.MX27 ADS" if MACH_IMX27ADS default "Freescale MX35 3Stack" if MACH_FREESCALE_MX35_3STACK @@ -223,6 +225,15 @@ choice prompt "i.MX35 Board Type" +config MACH_EUKREA_CPUIMX35 + bool "EUKREA CPUIMX35" + select HAVE_MMU + select MACH_HAS_LOWLEVEL_INIT + select ARCH_HAS_L2X0 + help + Say Y here if you are using Eukrea's CPUIMX35 equipped + with a Freescale i.MX35 Processor + config MACH_FREESCALE_MX35_3STACK bool "Freescale MX35 3stack" select HAS_CFI diff --git a/board/eukrea_cpuimx35/Makefile b/board/eukrea_cpuimx35/Makefile new file mode 100644 index 000000000..32ffe42cb --- /dev/null +++ b/board/eukrea_cpuimx35/Makefile @@ -0,0 +1,25 @@ +# +# (C) Copyright 2007 Juergen Beisert +# +# 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 +# + +obj-y += lowlevel.o +obj-y += eukrea_cpuimx35.o +obj-$(CONFIG_ARCH_IMX_INTERNAL_BOOT) += flash_header.o diff --git a/board/eukrea_cpuimx35/config.h b/board/eukrea_cpuimx35/config.h new file mode 100644 index 000000000..bfd3b3964 --- /dev/null +++ b/board/eukrea_cpuimx35/config.h @@ -0,0 +1,23 @@ +/* + * 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 + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_MX35_HCLK_FREQ 24000000 + +#endif /* __CONFIG_H */ diff --git a/board/eukrea_cpuimx35/env/bin/_update b/board/eukrea_cpuimx35/env/bin/_update new file mode 100644 index 000000000..014bce351 --- /dev/null +++ b/board/eukrea_cpuimx35/env/bin/_update @@ -0,0 +1,36 @@ +#!/bin/sh + +if [ -z "$part" -o -z "$image" ]; then + echo "define \$part and \$image" + exit 1 +fi + +if [ ! -e "$part" ]; then + echo "Partition $part does not exist" + exit 1 +fi + +if [ $# = 1 ]; then + image=$1 +fi + +if [ x$ip = xdhcp ]; then + dhcp +fi + +ping $eth0.serverip +if [ $? -ne 0 ] ; then + echo "update aborted" + exit 1 +fi + +unprotect $part + +echo +echo "erasing partition $part" +erase $part + +echo +echo "flashing $image to $part" +echo +tftp $image $part diff --git a/board/eukrea_cpuimx35/env/bin/boot b/board/eukrea_cpuimx35/env/bin/boot new file mode 100644 index 000000000..fca5b8cc1 --- /dev/null +++ b/board/eukrea_cpuimx35/env/bin/boot @@ -0,0 +1,52 @@ +#!/bin/sh + +. /env/config + +if [ x$1 = xjffS2 ]; then + root=jffs2 + kernel=nand +fi + +if [ x$1 = xubifs ]; then + root=ubifs + kernel=nand +fi + +if [ x$1 = xnet ]; then + root=net + kernel=net +fi + +if [ x$ip = xdhcp ]; then + bootargs="$bootargs ip=dhcp" +else + if [ x$ip = xoff ]; then + bootargs="$bootargs ip=off" + else + bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::" + fi +fi + +if [ x$root = xjffs2 ]; then + bootargs="$bootargs root=/dev/mtdblock$rootpartnum_nand rootfstype=jffs2" +fi + +if [ x$root = xubifs ]; then + bootargs="$bootargs root=ubi0:$ubiroot ubi.mtd=$rootpartnum_nand rootfstype=ubifs" +fi + +if [ x$root = xnet ]; then + bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp" +fi + +bootargs="$bootargs mtdparts=mxc_nand:$nand_parts" + +if [ $kernel = net ]; then + if [ x$ip = xdhcp ]; then + dhcp + fi + tftp $uimage uImage || exit 1 + bootm uImage +else + bootm /dev/nand0.kernel.bb +fi diff --git a/board/eukrea_cpuimx35/env/bin/hush_hack b/board/eukrea_cpuimx35/env/bin/hush_hack new file mode 100644 index 000000000..5fffa92ec --- /dev/null +++ b/board/eukrea_cpuimx35/env/bin/hush_hack @@ -0,0 +1 @@ +nand -a /dev/nand0.* diff --git a/board/eukrea_cpuimx35/env/bin/init b/board/eukrea_cpuimx35/env/bin/init new file mode 100644 index 000000000..49e54c5fd --- /dev/null +++ b/board/eukrea_cpuimx35/env/bin/init @@ -0,0 +1,41 @@ +#!/bin/sh + +PATH=/env/bin +export PATH + +. /env/config +if [ -e /dev/nand0 ]; then + addpart /dev/nand0 $nand_parts + + # Uh, oh, hush first expands wildcards and then starts executing + # commands. What a bug! + source /env/bin/hush_hack +fi + +if [ -f /env/logo.bmp ]; then + bmp /env/logo.bmp +elif [ -f /env/logo.bmp.lzo ]; then + unlzo /env/logo.bmp.lzo /logo.bmp + bmp /logo.bmp +fi + +if [ -z $eth0.ethaddr ]; then + while [ -z $eth0.ethaddr ]; do + readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr + done + echo -a /env/config "eth0.ethaddr=$eth0.ethaddr" + saveenv +fi + +echo +echo -n "Hit any key to stop autoboot: " +timeout -a $autoboot_timeout +if [ $? != 0 ]; then + echo + echo "type update_kernel [] to update kernel into flash" + echo "type update_root [] to update rootfs into flash" + echo + exit +fi + +boot diff --git a/board/eukrea_cpuimx35/env/bin/update_kernel b/board/eukrea_cpuimx35/env/bin/update_kernel new file mode 100644 index 000000000..c2d2cc3fa --- /dev/null +++ b/board/eukrea_cpuimx35/env/bin/update_kernel @@ -0,0 +1,8 @@ +#!/bin/sh + +. /env/config + +image=$uimage +part=/dev/nand0.kernel.bb + +. /env/bin/_update $1 diff --git a/board/eukrea_cpuimx35/env/bin/update_root b/board/eukrea_cpuimx35/env/bin/update_root new file mode 100644 index 000000000..dd89a5afa --- /dev/null +++ b/board/eukrea_cpuimx35/env/bin/update_root @@ -0,0 +1,8 @@ +#!/bin/sh + +. /env/config + +image=$rootfs +part=/dev/nand0.root.bb + +. /env/bin/_update $1 diff --git a/board/eukrea_cpuimx35/env/config b/board/eukrea_cpuimx35/env/config new file mode 100644 index 000000000..df2079fa5 --- /dev/null +++ b/board/eukrea_cpuimx35/env/config @@ -0,0 +1,27 @@ +#!/bin/sh + +# can be either 'net' or 'nand'' +kernel=nand +root=ubifs + +basedir=cpuimx35 +uimage=$basedir/uImage +rootfs=$basedir/rootfs + +autoboot_timeout=1 + +nfsroot="" +bootargs="console=ttymxc0,115200" + +nand_parts="256k(barebox)ro,128k(bareboxenv),2176k(kernel),-(root)" +rootpartnum_nand=3 +ubiroot="eukrea-cpuimx35-rootfs" + +# use 'dhcp' to do dhcp in barebox and in kernel +ip=off + +# or set your networking parameters here +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d +#eth0.gateway=a.b.c.d +#eth0.serverip=a.b.c.d diff --git a/board/eukrea_cpuimx35/eukrea_cpuimx35.c b/board/eukrea_cpuimx35/eukrea_cpuimx35.c new file mode 100644 index 000000000..7f1c782f1 --- /dev/null +++ b/board/eukrea_cpuimx35/eukrea_cpuimx35.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2007 Sascha Hauer, Pengutronix + * 2009 Marc Kleine-Budde, Pengutronix + * (c) 2010 Eukrea Electromatique, Eric Bénard + * + * 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 + * + * Derived from: + * + * * mx35_3stack.c - board file for uboot-v1 + * Copyright (C) 2007, Guennadi Liakhovetski + * (C) Copyright 2008-2009 Freescale Semiconductor, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct fec_platform_data fec_info = { + .xcv_type = MII100, + .phy_addr = 0x1F, +}; + +static struct device_d fec_dev = { + .name = "fec_imx", + .map_base = IMX_FEC_BASE, + .platform_data = &fec_info, +}; + +static struct memory_platform_data sdram_pdata = { + .name = "ram0", + .flags = DEVFS_RDWR, +}; + +static struct device_d sdram_dev = { + .name = "mem", + .map_base = IMX_SDRAM_CS0, + .size = 128 * 1024 * 1024, + .platform_data = &sdram_pdata, +}; + +struct imx_nand_platform_data nand_info = { + .width = 1, + .hw_ecc = 1, + .flash_bbt = 1, +}; + +static struct device_d nand_dev = { + .name = "imx_nand", + .map_base = IMX_NFC_BASE, + .platform_data = &nand_info, +}; + +static struct fb_videomode imxfb_mode = { + .name = "CMO_QVGA", + .refresh = 60, + .xres = 320, + .yres = 240, + .pixclock = KHZ2PICOS(7000), + .left_margin = 68, + .right_margin = 20, + .upper_margin = 15, + .lower_margin = 4, + .hsync_len = 30, + .vsync_len = 3, + .sync = FB_SYNC_OE_ACT_HIGH, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, +}; + +static struct imx_ipu_fb_platform_data ipu_fb_data = { + .mode = &imxfb_mode, + .bpp = 16, +}; + +static struct device_d imxfb_dev = { + .name = "imx-ipu-fb", + .map_base = 0x53fc0000, + .size = 0x1000, + .platform_data = &ipu_fb_data, +}; + +#ifdef CONFIG_MMU +static int eukrea_cpuimx35_mmu_init(void) +{ + mmu_init(); + + arm_create_section(0x80000000, 0x80000000, 128, PMD_SECT_DEF_CACHED); + arm_create_section(0x90000000, 0x80000000, 128, PMD_SECT_DEF_UNCACHED); + + setup_dma_coherent(0x10000000); + +#if TEXT_BASE & (0x100000 - 1) +#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary +#else + arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED); +#endif + mmu_enable(); + +#ifdef CONFIG_CACHE_L2X0 + l2x0_init((void __iomem *)0x30000000, 0x00030024, 0x00000000); +#endif + return 0; +} +postcore_initcall(eukrea_cpuimx35_mmu_init); +#endif + +static int eukrea_cpuimx35_devices_init(void) +{ + register_device(&nand_dev); + + devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw"); + dev_add_bb_dev("self_raw", "self0"); + devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED, "env_raw"); + dev_add_bb_dev("env_raw", "env0"); + + register_device(&fec_dev); + + register_device(&sdram_dev); + register_device(&imxfb_dev); + + armlinux_add_dram(&sdram_dev); + armlinux_set_bootparams((void *)0x80000100); + armlinux_set_architecture(MACH_TYPE_EUKREA_CPUIMX35); + + return 0; +} + +device_initcall(eukrea_cpuimx35_devices_init); + +static int eukrea_cpuimx35_enable_display(void) +{ + gpio_direction_output(1, 1); + gpio_direction_output(0, 0); + return 0; +} + +late_initcall(eukrea_cpuimx35_enable_display); + +static struct device_d eukrea_cpuimx35_serial_device = { + .name = "imx_serial", + .map_base = IMX_UART1_BASE, + .size = 4096, +}; + +static struct pad_desc eukrea_cpuimx35_pads[] = { + MX35_PAD_FEC_TX_CLK__FEC_TX_CLK, + MX35_PAD_FEC_RX_CLK__FEC_RX_CLK, + MX35_PAD_FEC_RX_DV__FEC_RX_DV, + MX35_PAD_FEC_COL__FEC_COL, + MX35_PAD_FEC_RDATA0__FEC_RDATA_0, + MX35_PAD_FEC_TDATA0__FEC_TDATA_0, + MX35_PAD_FEC_TX_EN__FEC_TX_EN, + MX35_PAD_FEC_MDC__FEC_MDC, + MX35_PAD_FEC_MDIO__FEC_MDIO, + MX35_PAD_FEC_TX_ERR__FEC_TX_ERR, + MX35_PAD_FEC_RX_ERR__FEC_RX_ERR, + MX35_PAD_FEC_CRS__FEC_CRS, + MX35_PAD_FEC_RDATA0__FEC_RDATA_0, + MX35_PAD_FEC_TDATA0__FEC_TDATA_0, + MX35_PAD_FEC_RDATA1__FEC_RDATA_1, + MX35_PAD_FEC_TDATA1__FEC_TDATA_1, + MX35_PAD_FEC_RDATA2__FEC_RDATA_2, + MX35_PAD_FEC_TDATA2__FEC_TDATA_2, + MX35_PAD_FEC_RDATA3__FEC_RDATA_3, + MX35_PAD_FEC_TDATA3__FEC_TDATA_3, + + MX35_PAD_RXD1__UART1_RXD_MUX, + MX35_PAD_TXD1__UART1_TXD_MUX, + MX35_PAD_RTS1__UART1_RTS, + MX35_PAD_CTS1__UART1_CTS, +}; + +static int eukrea_cpuimx35_console_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads, + ARRAY_SIZE(eukrea_cpuimx35_pads)); + + register_device(&eukrea_cpuimx35_serial_device); + return 0; +} + +console_initcall(eukrea_cpuimx35_console_init); + +static int eukrea_cpuimx35_core_init(void) +{ + u32 reg; + + /* enable clock for I2C1 and FEC */ + reg = readl(IMX_CCM_BASE + CCM_CGR1); + reg |= 0x3 << CCM_CGR1_FEC_SHIFT; + reg = writel(reg, IMX_CCM_BASE + CCM_CGR1); + + /* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/ + /* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + writel(0x77777777, IMX_AIPS1_BASE); + writel(0x77777777, IMX_AIPS1_BASE + 0x4); + writel(0x77777777, IMX_AIPS2_BASE); + writel(0x77777777, IMX_AIPS2_BASE + 0x4); + + /* + * Clear the on and off peripheral modules Supervisor Protect bit + * for SDMA to access them. Did not change the AIPS control registers + * (offset 0x20) access type + */ + writel(0x0, IMX_AIPS1_BASE + 0x40); + writel(0x0, IMX_AIPS1_BASE + 0x44); + writel(0x0, IMX_AIPS1_BASE + 0x48); + writel(0x0, IMX_AIPS1_BASE + 0x4C); + reg = readl(IMX_AIPS1_BASE + 0x50); + reg &= 0x00FFFFFF; + writel(reg, IMX_AIPS1_BASE + 0x50); + + writel(0x0, IMX_AIPS2_BASE + 0x40); + writel(0x0, IMX_AIPS2_BASE + 0x44); + writel(0x0, IMX_AIPS2_BASE + 0x48); + writel(0x0, IMX_AIPS2_BASE + 0x4C); + reg = readl(IMX_AIPS2_BASE + 0x50); + reg &= 0x00FFFFFF; + writel(reg, IMX_AIPS2_BASE + 0x50); + + /* MAX (Multi-Layer AHB Crossbar Switch) setup */ + + /* MPR - priority is M4 > M2 > M3 > M5 > M0 > M1 */ +#define MAX_PARAM1 0x00302154 + writel(MAX_PARAM1, IMX_MAX_BASE + 0x000); /* for S0 */ + writel(MAX_PARAM1, IMX_MAX_BASE + 0x100); /* for S1 */ + writel(MAX_PARAM1, IMX_MAX_BASE + 0x200); /* for S2 */ + writel(MAX_PARAM1, IMX_MAX_BASE + 0x300); /* for S3 */ + writel(MAX_PARAM1, IMX_MAX_BASE + 0x400); /* for S4 */ + + /* SGPCR - always park on last master */ + writel(0x10, IMX_MAX_BASE + 0x10); /* for S0 */ + writel(0x10, IMX_MAX_BASE + 0x110); /* for S1 */ + writel(0x10, IMX_MAX_BASE + 0x210); /* for S2 */ + writel(0x10, IMX_MAX_BASE + 0x310); /* for S3 */ + writel(0x10, IMX_MAX_BASE + 0x410); /* for S4 */ + + /* MGPCR - restore default values */ + writel(0x0, IMX_MAX_BASE + 0x800); /* for M0 */ + writel(0x0, IMX_MAX_BASE + 0x900); /* for M1 */ + writel(0x0, IMX_MAX_BASE + 0xa00); /* for M2 */ + writel(0x0, IMX_MAX_BASE + 0xb00); /* for M3 */ + writel(0x0, IMX_MAX_BASE + 0xc00); /* for M4 */ + writel(0x0, IMX_MAX_BASE + 0xd00); /* for M5 */ + + /* + * M3IF Control Register (M3IFCTL) + * MRRP[0] = L2CC0 not on priority list (0 << 0) = 0x00000000 + * MRRP[1] = MAX1 not on priority list (0 << 0) = 0x00000000 + * MRRP[2] = L2CC1 not on priority list (0 << 0) = 0x00000000 + * MRRP[3] = USB not on priority list (0 << 0) = 0x00000000 + * MRRP[4] = SDMA not on priority list (0 << 0) = 0x00000000 + * MRRP[5] = GPU not on priority list (0 << 0) = 0x00000000 + * MRRP[6] = IPU1 on priority list (1 << 6) = 0x00000040 + * MRRP[7] = IPU2 not on priority list (0 << 0) = 0x00000000 + * ------------ + * 0x00000040 + */ + writel(0x40, IMX_M3IF_BASE); + + return 0; +} + +core_initcall(eukrea_cpuimx35_core_init); + +#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) +#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) + +static int do_cpufreq(struct command *cmdtp, int argc, char *argv[]) +{ + unsigned long freq; + + if (argc != 2) + return COMMAND_ERROR_USAGE; + + freq = simple_strtoul(argv[1], NULL, 0); + + switch (freq) { + case 399: + writel(MPCTL_PARAM_399, IMX_CCM_BASE + CCM_MPCTL); + break; + case 532: + writel(MPCTL_PARAM_532, IMX_CCM_BASE + CCM_MPCTL); + break; + default: + return COMMAND_ERROR_USAGE; + } + + printf("Switched CPU frequency to %dMHz\n", freq); + + return 0; +} + +static const __maybe_unused char cmd_cpufreq_help[] = +"Usage: cpufreq 399|532\n" +"\n" +"Set CPU frequency to MHz\n"; + +BAREBOX_CMD_START(cpufreq) + .cmd = do_cpufreq, + .usage = "adjust CPU frequency", + BAREBOX_CMD_HELP(cmd_cpufreq_help) +BAREBOX_CMD_END diff --git a/board/eukrea_cpuimx35/eukrea_cpuimx35.dox b/board/eukrea_cpuimx35/eukrea_cpuimx35.dox new file mode 100644 index 000000000..cbdf69db3 --- /dev/null +++ b/board/eukrea_cpuimx35/eukrea_cpuimx35.dox @@ -0,0 +1,4 @@ +/** @page eukrea_cpuimx35 Eukrea's CPUIMX35 + + +*/ diff --git a/board/eukrea_cpuimx35/flash_header.c b/board/eukrea_cpuimx35/flash_header.c new file mode 100644 index 000000000..a0ccf5c8f --- /dev/null +++ b/board/eukrea_cpuimx35/flash_header.c @@ -0,0 +1,60 @@ +#include +#include + +extern unsigned long _stext; + +void __naked __flash_header_start go(void) +{ + __asm__ __volatile__("b exception_vectors\n"); +} + +struct imx_dcd_entry __dcd_entry_0x400 dcd_entry[] = { + { .ptr_type = 4, .addr = 0xB8001010, .val = 0x00000004, }, + { .ptr_type = 4, .addr = 0xB8001010, .val = 0x0000000C, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc3f, }, + { .ptr_type = 4, .addr = 0xB8001000, .val = 0x92220000, }, + { .ptr_type = 1, .addr = 0x80000400, .val = 0x12345678, }, + { .ptr_type = 4, .addr = 0xB8001000, .val = 0xA2220000, }, + { .ptr_type = 1, .addr = 0x80000000, .val = 0x87654321, }, + { .ptr_type = 1, .addr = 0x80000000, .val = 0x87654321, }, + { .ptr_type = 4, .addr = 0xB8001000, .val = 0xB2220000, }, + { .ptr_type = 1, .addr = 0x80000033, .val = 0xda, }, + { .ptr_type = 1, .addr = 0x82000000, .val = 0xda, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001004, .val = 0x007ffc2f, }, + { .ptr_type = 4, .addr = 0xB8001000, .val = 0x82220080, }, + { .ptr_type = 4, .addr = 0xB8001000, .val = 0x82228080, }, + { .ptr_type = 4, .addr = 0xB8001020, .val = 0x80000028, }, + { .ptr_type = 4, .addr = 0xB8001024, .val = 0x80000028, }, + { .ptr_type = 4, .addr = 0xB8001028, .val = 0x80000028, }, + { .ptr_type = 4, .addr = 0xB800102c, .val = 0x80000028, }, + { .ptr_type = 4, .addr = 0xB8001030, .val = 0x80000028, }, +}; + +#define APP_DEST 0x80000000 + +struct imx_flash_header __flash_header_0x400 flash_header = { + .app_code_jump_vector = APP_DEST + 0x1000, + .app_code_barker = APP_CODE_BARKER, + .app_code_csf = 0, + .dcd_ptr_ptr = APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd), + .super_root_key = 0, + .dcd = APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd_barker), + .app_dest = APP_DEST, + .dcd_barker = DCD_BARKER, + .dcd_block_len = sizeof (dcd_entry), +}; + +unsigned long __image_len_0x400 barebox_len = 0x40000; + diff --git a/board/eukrea_cpuimx35/lowlevel.c b/board/eukrea_cpuimx35/lowlevel.c new file mode 100644 index 000000000..44f3cf072 --- /dev/null +++ b/board/eukrea_cpuimx35/lowlevel.c @@ -0,0 +1,218 @@ +/* + * + * (c) 2007 Pengutronix, Sascha Hauer + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Assuming 24MHz input clock */ +#define MPCTL_PARAM_399 (IMX_PLL_PD(0) | IMX_PLL_MFD(15) | IMX_PLL_MFI(8) | IMX_PLL_MFN(5)) +#define MPCTL_PARAM_532 ((1 << 31) | IMX_PLL_PD(0) | IMX_PLL_MFD(11) | IMX_PLL_MFI(11) | IMX_PLL_MFN(1)) +#define PPCTL_PARAM_300 (IMX_PLL_PD(0) | IMX_PLL_MFD(3) | IMX_PLL_MFI(6) | IMX_PLL_MFN(1)) + +#ifdef CONFIG_NAND_IMX_BOOT +static void __bare_init __naked insdram(void) +{ + uint32_t r; + + /* Speed up NAND controller by adjusting the NFC divider */ + r = readl(IMX_CCM_BASE + CCM_PDR4); + r &= ~(0xf << 28); + r |= 0x1 << 28; + writel(r, IMX_CCM_BASE + CCM_PDR4); + + /* setup a stack to be able to call imx_nand_load_image() */ + r = STACK_BASE + STACK_SIZE - 12; + __asm__ __volatile__("mov sp, %0" : : "r"(r)); + + imx_nand_load_image((void *)TEXT_BASE, 256 * 1024); + + board_init_lowlevel_return(); +} +#endif + +void __bare_init __naked board_init_lowlevel(void) +{ + uint32_t r, s; + unsigned long ccm_base = IMX_CCM_BASE; + unsigned long iomuxc_base = IMX_IOMUXC_BASE; +#ifdef CONFIG_NAND_IMX_BOOT + unsigned int *trg, *src; + int i; +#endif + + r = get_cr(); + r |= CR_Z; /* Flow prediction (Z) */ + r |= CR_U; /* unaligned accesses */ + r |= CR_FI; /* Low Int Latency */ + + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(s)); + s |= 0x7; + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1" : : "r"(s)); + + set_cr(r); + + r = 0; + __asm__ __volatile__("mcr p15, 0, %0, c15, c2, 4" : : "r"(r)); + + /* + * Branch predicition is now enabled. Flush the BTAC to ensure a valid + * starting point. Don't flush BTAC while it is disabled to avoid + * ARM1136 erratum 408023. + */ + __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 6" : : "r"(r)); + + /* invalidate I cache and D cache */ + __asm__ __volatile__("mcr p15, 0, %0, c7, c7, 0" : : "r"(r)); + + /* invalidate TLBs */ + __asm__ __volatile__("mcr p15, 0, %0, c8, c7, 0" : : "r"(r)); + + /* Drain the write buffer */ + __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"(r)); + + /* Also setup the Peripheral Port Remap register inside the core */ + r = 0x40000015; /* start from AIPS 2GB region */ + __asm__ __volatile__("mcr p15, 0, %0, c15, c2, 4" : : "r"(r)); + + /* + * End of ARM1136 init + */ + + writel(0x003F4208, ccm_base + CCM_CCMR); + + /* Set MPLL , arm clock and ahb clock*/ + writel(MPCTL_PARAM_532, ccm_base + CCM_MPCTL); + + writel(PPCTL_PARAM_300, ccm_base + CCM_PPCTL); + writel(0x00001000, ccm_base + CCM_PDR0); + + r = readl(ccm_base + CCM_CGR0); + r |= 0x00300000; + writel(r, ccm_base + CCM_CGR0); + + r = readl(ccm_base + CCM_CGR1); + r |= 0x00000C00; + r |= 0x00000003; + writel(r, ccm_base + CCM_CGR1); + + r = readl(IMX_L2CC_BASE + L2X0_AUX_CTRL); + r |= 0x1000; + writel(r, IMX_L2CC_BASE + L2X0_AUX_CTRL); + + /* Skip SDRAM initialization if we run from RAM */ + r = get_pc(); + if (r > 0x80000000 && r < 0x90000000) + board_init_lowlevel_return(); + + /* Set DDR Type to SDRAM, drive strength workaround * + * 0x00000000 MDDR * + * 0x00000800 3,3V SDRAM */ + + r = 0x00000800; + writel(r, iomuxc_base + 0x794); + writel(r, iomuxc_base + 0x798); + writel(r, iomuxc_base + 0x79c); + writel(r, iomuxc_base + 0x7a0); + writel(r, iomuxc_base + 0x7a4); + + /* MDDR init, enable mDDR*/ + writel(0x00000304, ESDMISC); /* was 0x00000004 */ + + /* set timing paramters */ + writel(0x00255417, ESDCFG0); + /* select Precharge-All mode */ + writel(0x92220000, ESDCTL0); + /* Precharge-All */ + writel(0x12345678, IMX_SDRAM_CS0 + 0x400); + + /* select Load-Mode-Register mode */ + writel(0xB8001000, ESDCTL0); + /* Load reg EMR2 */ + writeb(0xda, 0x84000000); + /* Load reg EMR3 */ + writeb(0xda, 0x86000000); + /* Load reg EMR1 -- enable DLL */ + writeb(0xda, 0x82000400); + /* Load reg MR -- reset DLL */ + writeb(0xda, 0x80000333); + + /* select Precharge-All mode */ + writel(0x92220000, ESDCTL0); + /* Precharge-All */ + writel(0x12345678, IMX_SDRAM_CS0 + 0x400); + + /* select Manual-Refresh mode */ + writel(0xA2220000, ESDCTL0); + /* Manual-Refresh 2 times */ + writel(0x87654321, IMX_SDRAM_CS0); + writel(0x87654321, IMX_SDRAM_CS0); + + /* select Load-Mode-Register mode */ + writel(0xB2220000, ESDCTL0); + /* Load reg MR -- CL3, BL8, end DLL reset */ + writeb(0xda, 0x80000233); + /* Load reg EMR1 -- OCD default */ + writeb(0xda, 0x82000780); + /* Load reg EMR1 -- OCD exit */ + writeb(0xda, 0x82000400); + + /* select normal-operation mode + * DSIZ32-bit, BL8, COL10-bit, ROW13-bit + * disable PWT & PRCT + * disable Auto-Refresh */ + writel(0x82220080, ESDCTL0); + + /* enable Auto-Refresh */ + writel(0x82228080, ESDCTL0); + /* enable Auto-Refresh */ + writel(0x00002000, ESDCTL1); + +#ifdef CONFIG_NAND_IMX_BOOT + /* skip NAND boot if not running from NFC space */ + r = get_pc(); + if (r < IMX_NFC_BASE || r > IMX_NFC_BASE + 0x800) + board_init_lowlevel_return(); + + src = (unsigned int *)IMX_NFC_BASE; + trg = (unsigned int *)TEXT_BASE; + + /* Move ourselves out of NFC SRAM */ + for (i = 0; i < 0x800 / sizeof(int); i++) + *trg++ = *src++; + + /* Jump to SDRAM */ + r = (unsigned int)&insdram; + __asm__ __volatile__("mov pc, %0" : : "r"(r)); +#else + board_init_lowlevel_return(); +#endif +} + From a81786a053ed1f08aab8d70d28dbf33691ab7a37 Mon Sep 17 00:00:00 2001 From: Ivo Clarysse Date: Mon, 14 Jun 2010 15:01:48 +0200 Subject: [PATCH 10/65] mx25 3ds: Fix compilation On barebox-next, I get: board/freescale-mx25-3-stack/built-in.o: In function `go': 3stack.c:(.flash_header_start+0x0): undefined reference to `_start' board/freescale-mx25-3-stack/built-in.o: In function `imx25_3ds_fec_init': 3stack.c:(.text.imx25_3ds_fec_init+0x4): undefined reference to `mc34704_get' 3stack.c:(.text.imx25_3ds_fec_init+0x1c): undefined reference to `mc34704_reg_write' Signed-off-by: Ivo Clarysse Acked-by: Baruch Siach Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index afd8caef5..18a9cbcdb 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -140,6 +140,8 @@ config MACH_FREESCALE_MX25_3STACK bool "Freescale MX25 3stack" select HAS_CFI select MACH_HAS_LOWLEVEL_INIT + select I2C + select DRIVER_I2C_MC34704 help Say Y here if you are using the Freescale MX25 3stack board equipped with a Freescale i.MX25 Processor From 994f95c073caf4df62d1271aef4112ce8aaa8add Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 27 May 2010 11:37:46 +0200 Subject: [PATCH 11/65] net: remove need for eth_halt/eth_open We used to eth_open/eth_halt the network devices during NetLoopInit which is called whenever the user enters a network command. Change this behaviour so that the current network device gets opened when making it the current one. With this change it's always possible to send packages and we are able to implement a new network stack in the next step. Signed-off-by: Sascha Hauer --- commands/net.c | 20 ++++++++++-------- include/net.h | 1 + net/eth.c | 56 ++++++++++++++++++++++++++++++++------------------ net/net.c | 21 +++++++++++-------- net/ping.c | 1 - 5 files changed, 62 insertions(+), 37 deletions(-) diff --git a/commands/net.c b/commands/net.c index 815a566a2..949963ffd 100644 --- a/commands/net.c +++ b/commands/net.c @@ -39,12 +39,16 @@ void netboot_update_env(void) { struct eth_device *eth_current = eth_get_current(); char tmp[22]; + IPaddr_t net_gateway_ip = NetOurGatewayIP; + IPaddr_t net_ip = NetOurIP; + IPaddr_t net_server_ip = NetServerIP; + IPaddr_t netmask = NetOurSubnetMask; - if (NetOurGatewayIP) - dev_set_param_ip(ð_current->dev, "gateway", NetOurGatewayIP); + if (net_gateway_ip) + dev_set_param_ip(ð_current->dev, "gateway", net_gateway_ip); - if (NetOurSubnetMask) - dev_set_param_ip(ð_current->dev, "netmask", NetOurSubnetMask); + if (netmask) + dev_set_param_ip(ð_current->dev, "netmask", netmask); if (NetOurHostName[0]) @@ -53,11 +57,11 @@ void netboot_update_env(void) if (NetOurRootPath[0]) setenv ("rootpath", NetOurRootPath); - if (NetOurIP) - dev_set_param_ip(ð_current->dev, "ipaddr", NetOurIP); + if (net_ip) + dev_set_param_ip(ð_current->dev, "ipaddr", net_ip); - if (NetServerIP) - dev_set_param_ip(ð_current->dev, "serverip", NetServerIP); + if (net_server_ip) + dev_set_param_ip(ð_current->dev, "serverip", net_server_ip); if (NetOurDNSIP) { ip_to_string (NetOurDNSIP, tmp); diff --git a/include/net.h b/include/net.h index 7353c8f50..de7829384 100644 --- a/include/net.h +++ b/include/net.h @@ -57,6 +57,7 @@ struct device_d; struct eth_device { int iobase; int state; + int active; int (*init) (struct eth_device*); diff --git a/net/eth.c b/net/eth.c index 7570198a1..fc16233be 100644 --- a/net/eth.c +++ b/net/eth.c @@ -36,7 +36,13 @@ static LIST_HEAD(netdev_list); void eth_set_current(struct eth_device *eth) { + if (eth_current && eth_current->active) { + eth_current->halt(eth_current); + eth_current->active = 0; + } + eth_current = eth; + net_update_env(); } struct eth_device * eth_get_current(void) @@ -57,37 +63,37 @@ struct eth_device *eth_get_byname(char *ethname) return NULL; } -int eth_open(void) -{ - if (!eth_current) - return -ENODEV; - - return eth_current->open(eth_current); -} - -void eth_halt(void) -{ - if (!eth_current) - return; - - eth_current->halt(eth_current); - - eth_current->state = ETH_STATE_PASSIVE; -} - int eth_send(void *packet, int length) { + int ret; + if (!eth_current) return -ENODEV; + if (!eth_current->active) { + ret = eth_current->open(eth_current); + if (ret) + return ret; + eth_current->active = 1; + } + return eth_current->send(eth_current, packet, length); } int eth_rx(void) { + int ret; + if (!eth_current) return -ENODEV; + if (!eth_current->active) { + ret = eth_current->open(eth_current); + if (ret) + return ret; + eth_current->active = 1; + } + return eth_current->recv(eth_current); } @@ -104,11 +110,15 @@ static int eth_set_ethaddr(struct device_d *dev, struct param_d *param, const ch edev->set_ethaddr(edev, ethaddr); + if (edev == eth_current) + net_update_env(); + return 0; } static int eth_set_ipaddr(struct device_d *dev, struct param_d *param, const char *val) { + struct eth_device *edev = dev->type_data; IPaddr_t ip; if (string_to_ip(val, &ip)) @@ -117,6 +127,9 @@ static int eth_set_ipaddr(struct device_d *dev, struct param_d *param, const cha free(param->value); param->value = strdup(val); + if (edev == eth_current) + net_update_env(); + return 0; } @@ -157,7 +170,7 @@ int eth_register(struct eth_device *edev) if (edev->get_ethaddr(edev, ethaddr) == 0) { ethaddr_to_string(ethaddr, ethaddr_str); - printf("got MAC address from EEPROM: %s\n",ethaddr_str); + printf("got MAC address from EEPROM: %s\n",ðaddr_str); dev_set_param(dev, "ethaddr", ethaddr_str); } @@ -180,9 +193,12 @@ void eth_unregister(struct eth_device *edev) if (edev->param_serverip.value) free(edev->param_serverip.value); - if (eth_current == edev) + if (eth_current == edev) { + eth_current->halt(eth_current); eth_current = NULL; + } list_del(&edev->list); } + diff --git a/net/net.c b/net/net.c index 4554d49e3..28943a039 100644 --- a/net/net.c +++ b/net/net.c @@ -228,9 +228,6 @@ int NetLoopInit(proto_t protocol) NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; NetArpWaitTxPacketSize = 0; - if (eth_open() < 0) - return -1; - string_to_ethaddr(dev_get_param(ð_get_current()->dev, "ethaddr"), NetOurEther); @@ -243,8 +240,6 @@ int NetLoopInit(proto_t protocol) NetServerIP = dev_get_param_ip(ð_current->dev, "serverip"); ret = net_check_prereq(protocol); - if (ret) - eth_halt(); return ret; } @@ -281,7 +276,6 @@ int NetLoop(void) * Abort if ctrl-c was pressed. */ if (ctrlc()) { - eth_halt(); puts ("\nAbort\n"); return -1; } @@ -315,11 +309,9 @@ int NetLoop(void) sprintf(buf, "0x%lx", NetBootFileXferSize); setenv("filesize", buf); } - eth_halt(); return NetBootFileXferSize; case NETLOOP_FAIL: - eth_halt(); return -1; } } @@ -959,3 +951,16 @@ void ethaddr_to_string(const unsigned char *enetaddr, char *str) enetaddr[4], enetaddr[5]); } +void net_update_env(void) +{ + struct eth_device *edev = eth_get_current(); + + NetOurIP = dev_get_param_ip(&edev->dev, "ipaddr"); + NetServerIP = dev_get_param_ip(&edev->dev, "serverip"); + NetOurGatewayIP = dev_get_param_ip(&edev->dev, "gateway"); + NetOurSubnetMask = dev_get_param_ip(&edev->dev, "netmask"); + + string_to_ethaddr(dev_get_param(&edev->dev, "ethaddr"), + NetOurEther); +} + diff --git a/net/ping.c b/net/ping.c index 1bc481af4..7e21fe4cc 100644 --- a/net/ping.c +++ b/net/ping.c @@ -62,7 +62,6 @@ static int PingSend(void) static void PingTimeout (void) { - eth_halt(); NetState = NETLOOP_FAIL; /* we did not get the reply */ } From 97070487fa67d0a8b04c4e109966bb4c1b40212e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 15:22:26 +0200 Subject: [PATCH 12/65] net: Implement a new network stack The old network stack has some bad limitations: - network commands are required to call NetLoop() which only returns when the network layer wants to. Instead we now use a net_poll() function which returns after handling one packet (or immediately if no packet is available). - There can be only one packet handler which makes it impossible to handle multiple connections - CamelCaseMakesItHardToRead The new network stack is implemented as a parallel universe. Currently all commands still use the old stack. They are converted in subsequent patches. Signed-off-by: Sascha Hauer --- include/net.h | 341 ++++++++++++++++++++++++++++++- net/net.c | 540 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 874 insertions(+), 7 deletions(-) diff --git a/include/net.h b/include/net.h index de7829384..0ee7ecb8a 100644 --- a/include/net.h +++ b/include/net.h @@ -15,6 +15,7 @@ #include #include #include +#include #include /* for nton* / ntoh* stuff */ @@ -186,8 +187,6 @@ typedef struct uchar ar_data[0]; } ARP_t; -#define ARP_HDR_SIZE (8+20) /* Size assuming ethernet */ - /* * ICMP stuff (just enough to handle (host) redirect messages) */ @@ -199,7 +198,7 @@ typedef struct #define ICMP_REDIR_NET 0 /* Redirect Net */ #define ICMP_REDIR_HOST 1 /* Redirect Host */ -typedef struct icmphdr { +typedef struct { uchar type; uchar code; ushort checksum; @@ -415,4 +414,340 @@ void eth_set_current(struct eth_device *eth); struct eth_device *eth_get_current(void); struct eth_device *eth_get_byname(char *name); +/* + * Ethernet header + */ +struct ethernet { + uint8_t et_dest[6]; /* Destination node */ + uint8_t et_src[6]; /* Source node */ + uint16_t et_protlen; /* Protocol or length */ +} __attribute__ ((packed)); + +#define ETHER_HDR_SIZE 14 /* Ethernet header size */ + +#define PROT_IP 0x0800 /* IP protocol */ +#define PROT_ARP 0x0806 /* IP ARP protocol */ +#define PROT_RARP 0x8035 /* IP ARP protocol */ +#define PROT_VLAN 0x8100 /* IEEE 802.1q protocol */ + +#define IPPROTO_ICMP 1 /* Internet Control Message Protocol */ +#define IPPROTO_UDP 17 /* User Datagram Protocol */ + +/* + * Internet Protocol (IP) header. + */ +struct iphdr { + uint8_t hl_v; + uint8_t tos; + uint16_t tot_len; + uint16_t id; + uint16_t frag_off; + uint8_t ttl; + uint8_t protocol; + uint16_t check; + uint32_t saddr; + uint32_t daddr; + /* The options start here. */ +} __attribute__ ((packed)); + +struct udphdr { + uint16_t uh_sport; /* source port */ + uint16_t uh_dport; /* destination port */ + uint16_t uh_ulen; /* udp length */ + uint16_t uh_sum; /* udp checksum */ +} __attribute__ ((packed)); + +/* + * Address Resolution Protocol (ARP) header. + */ +struct arprequest +{ + uint16_t ar_hrd; /* Format of hardware address */ +#define ARP_ETHER 1 /* Ethernet hardware address */ + uint16_t ar_pro; /* Format of protocol address */ + uint8_t ar_hln; /* Length of hardware address */ + uint8_t ar_pln; /* Length of protocol address */ + uint16_t ar_op; /* Operation */ +#define ARPOP_REQUEST 1 /* Request to resolve address */ +#define ARPOP_REPLY 2 /* Response to previous request */ + +#define RARPOP_REQUEST 3 /* Request to resolve address */ +#define RARPOP_REPLY 4 /* Response to previous request */ + + /* + * The remaining fields are variable in size, according to + * the sizes above, and are defined as appropriate for + * specific hardware/protocol combinations. + */ + uint8_t ar_data[0]; +} __attribute__ ((packed)); + +#define ARP_HDR_SIZE (8 + 20) /* Size assuming ethernet */ + +/* + * ICMP stuff (just enough to handle (host) redirect messages) + */ +#define ICMP_ECHO_REPLY 0 /* Echo reply */ +#define ICMP_REDIRECT 5 /* Redirect (change route) */ +#define ICMP_ECHO_REQUEST 8 /* Echo request */ + +/* Codes for REDIRECT. */ +#define ICMP_REDIR_NET 0 /* Redirect Net */ +#define ICMP_REDIR_HOST 1 /* Redirect Host */ + +struct icmphdr { + uint8_t type; + uint8_t code; + uint16_t checksum; + union { + struct { + uint16_t id; + uint16_t sequence; + } echo; + uint32_t gateway; + struct { + uint16_t __unused; + uint16_t mtu; + } frag; + } un; +} __attribute__ ((packed)); + + +/* + * Maximum packet size; used to allocate packet storage. + * TFTP packets can be 524 bytes + IP header + ethernet header. + * Lets be conservative, and go for 38 * 16. (Must also be + * a multiple of 32 bytes). + */ +#define PKTSIZE 1518 + +/**********************************************************************/ +/* + * Globals. + * + * Note: + * + * All variables of type IPaddr_t are stored in NETWORK byte order + * (big endian). + */ + +extern unsigned char *NetRxPackets[PKTBUFSRX];/* Receive packets */ + +void net_set_ip(IPaddr_t ip); +void net_set_serverip(IPaddr_t ip); +void net_set_netmask(IPaddr_t ip); +void net_set_gateway(IPaddr_t ip); +IPaddr_t net_get_ip(void); +IPaddr_t net_get_serverip(void); + +/* Do the work */ +void net_poll(void); + +static inline struct iphdr *net_eth_to_iphdr(char *pkt) +{ + return (struct iphdr *)(pkt + ETHER_HDR_SIZE); +} + +static inline struct udphdr *net_eth_to_udphdr(char *pkt) +{ + return (struct udphdr *)(net_eth_to_iphdr(pkt) + 1); +} + +static inline struct icmphdr *net_eth_to_icmphdr(char *pkt) +{ + return (struct icmphdr *)(net_eth_to_iphdr(pkt) + 1); +} + +static inline char *net_eth_to_icmp_payload(char *pkt) +{ + return (char *)(net_eth_to_icmphdr(pkt) + 1); +} + +static inline char *net_eth_to_udp_payload(char *pkt) +{ + return (char *)(net_eth_to_udphdr(pkt) + 1); +} + +static inline int net_eth_to_udplen(char *pkt) +{ + struct udphdr *udp = net_eth_to_udphdr(pkt); + return ntohs(udp->uh_ulen) - 8; +} + +int net_checksum_ok(unsigned char *, int); /* Return true if cksum OK */ +uint16_t net_checksum(unsigned char *, int); /* Calculate the checksum */ + +void NetReceive(unsigned char *, int); + +/* Print an IP address on the console */ +void print_IPaddr (IPaddr_t); + +/* + * The following functions are a bit ugly, but necessary to deal with + * alignment restrictions on ARM. + * + * We're using inline functions, which had the smallest memory + * footprint in our tests. + */ +/* return IP *in network byteorder* */ +static inline IPaddr_t net_read_ip(void *from) +{ + IPaddr_t ip; + memcpy((void*)&ip, from, sizeof(ip)); + return ip; +} + +/* return uint32 *in network byteorder* */ +static inline uint32_t net_read_uint32(uint32_t *from) +{ + ulong l; + memcpy((void*)&l, (void*)from, sizeof(l)); + return l; +} + +/* write IP *in network byteorder* */ +static inline void net_write_ip(void *to, IPaddr_t ip) +{ + memcpy(to, (void*)&ip, sizeof(ip)); +} + +/* copy IP */ +static inline void net_copy_ip(void *to, void *from) +{ + memcpy(to, from, sizeof(IPaddr_t)); +} + +/* copy ulong */ +static inline void net_copy_uint32(uint32_t *to, uint32_t *from) +{ + memcpy(to, from, sizeof(uint32_t)); +} + +/* Convert an IP address to a string */ +char *ip_to_string (IPaddr_t x, char *s); + +/* Convert a string to ip address */ +int string_to_ip(const char *s, IPaddr_t *ip); + +IPaddr_t getenv_ip(const char *name); +int setenv_ip(const char *name, IPaddr_t ip); + +int string_to_ethaddr(const char *str, char *enetaddr); +void ethaddr_to_string(const unsigned char *enetaddr, char *str); + +/** + * is_zero_ether_addr - Determine if give Ethernet address is all zeros. + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Return true if the address is all zeroes. + */ +static inline int is_zero_ether_addr(const u8 *addr) +{ + return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); +} + +/** + * is_multicast_ether_addr - Determine if the Ethernet address is a multicast. + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Return true if the address is a multicast address. + * By definition the broadcast address is also a multicast address. + */ +static inline int is_multicast_ether_addr(const u8 *addr) +{ + return (0x01 & addr[0]); +} + +/** + * is_local_ether_addr - Determine if the Ethernet address is locally-assigned one (IEEE 802). + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Return true if the address is a local address. + */ +static inline int is_local_ether_addr(const u8 *addr) +{ + return (0x02 & addr[0]); +} + +/** + * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Return true if the address is the broadcast address. + */ +static inline int is_broadcast_ether_addr(const u8 *addr) +{ + return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff; +} + +/** + * is_valid_ether_addr - Determine if the given Ethernet address is valid + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not + * a multicast address, and is not FF:FF:FF:FF:FF:FF. + * + * Return true if the address is valid. + */ +static inline int is_valid_ether_addr(const u8 *addr) +{ + /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to + * explicitly check for it here. */ + return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); +} + +typedef void rx_handler_f(char *packet, unsigned int len); + +void eth_set_current(struct eth_device *eth); +struct eth_device *eth_get_current(void); +struct eth_device *eth_get_byname(char *name); +void net_update_env(void); + +/** + * net_receive - Pass a received packet from an ethernet driver to the protocol stack + * @pkt: Pointer to the packet + * @len: length of the packet + * + * Return 0 if the packet is successfully handled. Can be ignored + */ +int net_receive(unsigned char *pkt, int len); + +struct net_connection { + struct ethernet *et; + struct iphdr *ip; + struct udphdr *udp; + struct icmphdr *icmp; + unsigned char *packet; + struct list_head list; + rx_handler_f *handler; + int proto; +}; + +static inline char *net_alloc_packet(void) +{ + return memalign(32, PKTSIZE); +} + +struct net_connection *net_udp_new(IPaddr_t dest, uint16_t dport, + rx_handler_f *handler); + +struct net_connection *net_icmp_new(IPaddr_t dest, rx_handler_f *handler); + +void net_unregister(struct net_connection *con); + +static inline int net_udp_bind(struct net_connection *con, int sport) +{ + con->udp->uh_sport = ntohs(sport); + return 0; +} + +static inline unsigned char *net_udp_get_payload(struct net_connection *con) +{ + return con->packet + sizeof(struct ethernet) + sizeof(struct iphdr) + + sizeof(struct udphdr); +} + +int net_udp_send(struct net_connection *con, int len); +int net_icmp_send(struct net_connection *con, int len); + #endif /* __NET_H__ */ diff --git a/net/net.c b/net/net.c index 28943a039..2b1641e8e 100644 --- a/net/net.c +++ b/net/net.c @@ -77,7 +77,9 @@ #include #include #include +#include #include +#include #include "tftp.h" #include "rarp.h" #include "nfs.h" @@ -89,7 +91,6 @@ # define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) #endif - /** BOOTP EXTENTIONS **/ IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */ @@ -407,6 +408,9 @@ NetReceive(uchar * inpkt, int len) pr_debug("packet received\n"); + if (!net_receive(inpkt, len)) + return; + NetRxPkt = inpkt; NetRxPktLen = len; et = (Ethernet_t *)inpkt; @@ -582,7 +586,8 @@ NetReceive(uchar * inpkt, int len) NetCopyIP(&NetServerIP, &arp->ar_data[ 6]); memcpy (NetServerEther, &arp->ar_data[ 0], 6); - (*packetHandler)(0,0,0,0); + if (packetHandler) + (*packetHandler)(0,0,0,0); } break; @@ -649,7 +654,8 @@ NetReceive(uchar * inpkt, int len) * IP header OK. Pass the packet to the current handler. */ /* XXX point to ip packet */ - (*packetHandler)((uchar *)ip, 0, 0, 0); + if (packetHandler) + (*packetHandler)((uchar *)ip, 0, 0, 0); return; #endif default: @@ -701,7 +707,8 @@ NetReceive(uchar * inpkt, int len) /* * IP header OK. Pass the packet to the current handler. */ - (*packetHandler)((uchar *)ip +IP_HDR_SIZE, + if (packetHandler) + (*packetHandler)((uchar *)ip +IP_HDR_SIZE, ntohs(ip->udp_dst), ntohs(ip->udp_src), ntohs(ip->udp_len) - 8); @@ -882,6 +889,30 @@ int string_to_ip(const char *s, IPaddr_t *ip) return 0; } +IPaddr_t getenv_ip(const char *name) +{ + IPaddr_t ip; + const char *var = getenv(name); + + if (!var) + return 0; + + string_to_ip(var, &ip); + + return ip; +} + +int setenv_ip(const char *name, IPaddr_t ip) +{ + char str[sizeof("xxx.xxx.xxx.xxx")]; + + ip_to_string(ip, str); + + setenv(name, str); + + return 0; +} + void VLAN_to_string(ushort x, char *s) { x = ntohs(x); @@ -951,10 +982,28 @@ void ethaddr_to_string(const unsigned char *enetaddr, char *str) enetaddr[4], enetaddr[5]); } +static IPaddr_t net_netmask; /* Our subnet mask (0=unknown) */ +static IPaddr_t net_gateway; /* Our gateways IP address */ + +static unsigned char net_ether[6]; /* Our ethernet address */ +static IPaddr_t net_ip; /* Our IP addr (0 = unknown) */ +static IPaddr_t net_serverip; /* Our IP addr (0 = unknown) */ + +unsigned char *NetRxPackets[PKTBUFSRX]; /* Receive packets */ +static unsigned int net_ip_id; + void net_update_env(void) { struct eth_device *edev = eth_get_current(); + net_ip = dev_get_param_ip(&edev->dev, "ipaddr"); + net_serverip = dev_get_param_ip(&edev->dev, "serverip"); + net_gateway = dev_get_param_ip(&edev->dev, "gateway"); + net_netmask = dev_get_param_ip(&edev->dev, "netmask"); + + string_to_ethaddr(dev_get_param(&edev->dev, "ethaddr"), + net_ether); + NetOurIP = dev_get_param_ip(&edev->dev, "ipaddr"); NetServerIP = dev_get_param_ip(&edev->dev, "serverip"); NetOurGatewayIP = dev_get_param_ip(&edev->dev, "gateway"); @@ -964,3 +1013,486 @@ void net_update_env(void) NetOurEther); } +int net_checksum_ok(unsigned char *ptr, int len) +{ + return net_checksum(ptr, len) + 1; +} + +uint16_t net_checksum(unsigned char *ptr, int len) +{ + uint32_t xsum = 0; + uint16_t *p = (uint16_t *)ptr; + + if (len & 1) + ptr[len] = 0; + + len = (len + 1) >> 1; + + while (len-- > 0) + xsum += *p++; + + xsum = (xsum & 0xffff) + (xsum >> 16); + xsum = (xsum & 0xffff) + (xsum >> 16); + return xsum & 0xffff; +} + +static unsigned char *arp_ether; +static IPaddr_t arp_wait_ip; + +static void arp_handler(struct arprequest *arp) +{ + IPaddr_t tmp; + + /* are we waiting for a reply */ + if (!arp_wait_ip) + return; + + tmp = net_read_ip(&arp->ar_data[6]); + + /* matched waiting packet's address */ + if (tmp == arp_wait_ip) { + /* save address for later use */ + memcpy(arp_ether, &arp->ar_data[0], 6); + + /* no arp request pending now */ + arp_wait_ip = 0; + } +} + +int arp_request(IPaddr_t dest, unsigned char *ether) +{ + char *pkt; + struct arprequest *arp; + uint64_t arp_start; + static char *arp_packet; + struct ethernet *et; + + if (!arp_packet) { + arp_packet = net_alloc_packet(); + if (!arp_packet) + return -ENOMEM; + } + + pkt = arp_packet; + et = (struct ethernet *)arp_packet; + + arp_wait_ip = dest; + + pr_debug("ARP broadcast\n"); + + memset(et->et_dest, 0xff, 6); + memcpy(et->et_src, net_ether, 6); + et->et_protlen = htons(PROT_ARP); + + arp = (struct arprequest *)(pkt + ETHER_HDR_SIZE); + + arp->ar_hrd = htons(ARP_ETHER); + arp->ar_pro = htons(PROT_IP); + arp->ar_hln = 6; + arp->ar_pln = 4; + arp->ar_op = htons(ARPOP_REQUEST); + + memcpy(arp->ar_data, net_ether, 6); /* source ET addr */ + net_write_ip(arp->ar_data + 6, net_ip); /* source IP addr */ + memset(arp->ar_data + 10, 0, 6); /* dest ET addr = 0 */ + + if ((dest & net_netmask) != (net_ip & net_netmask)) { + if (!net_gateway) + arp_wait_ip = dest; + else + arp_wait_ip = net_gateway; + } else { + arp_wait_ip = dest; + } + + net_write_ip(arp->ar_data + 16, arp_wait_ip); + + arp_ether = ether; + + eth_send(arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE); + arp_start = get_time_ns(); + + while (arp_wait_ip) { + if (ctrlc()) + return -EINTR; + + if (is_timeout(arp_start, 3 * SECOND)) { + printf("T "); + arp_start = get_time_ns(); + eth_send(arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE); + } + + net_poll(); + } + + pr_debug("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n", + ether[0], ether[1], + ether[2], ether[3], + ether[4], ether[5]); + return 0; +} + +void net_poll(void) +{ + eth_rx(); +} + +static uint16_t net_udp_new_localport(void) +{ + static uint16_t localport; + + localport++; + + if (localport < 1024) + localport = 1024; + + return localport; +} + +IPaddr_t net_get_serverip(void) +{ + return net_serverip; +} + +void net_set_serverip(IPaddr_t ip) +{ + struct eth_device *edev = eth_get_current(); + + net_serverip = ip; + dev_set_param_ip(&edev->dev, "serverip", net_serverip); +} + +void net_set_ip(IPaddr_t ip) +{ + struct eth_device *edev = eth_get_current(); + + net_ip = ip; + dev_set_param_ip(&edev->dev, "ipaddr", net_ip); +} + +IPaddr_t net_get_ip(void) +{ + return net_ip; +} + +void net_set_netmask(IPaddr_t nm) +{ + struct eth_device *edev = eth_get_current(); + + net_netmask = nm; + dev_set_param_ip(&edev->dev, "netmask", net_netmask); +} + +void net_set_gateway(IPaddr_t gw) +{ + struct eth_device *edev = eth_get_current(); + + net_gateway = gw; + dev_set_param_ip(&edev->dev, "gateway", net_gateway); +} + +static LIST_HEAD(connection_list); + +static struct net_connection *net_new(IPaddr_t dest, rx_handler_f *handler) +{ + struct net_connection *con; + int ret; + + if (!is_valid_ether_addr(net_ether)) + return ERR_PTR(-ENETDOWN); + + /* If we don't have an ip only broadcast is allowed */ + if (!net_ip && dest != 0xffffffff) + return ERR_PTR(-ENETDOWN); + + con = xzalloc(sizeof(*con)); + con->packet = memalign(32, PKTSIZE); + memset(con->packet, 0, PKTSIZE); + + con->et = (struct ethernet *)con->packet; + con->ip = (struct iphdr *)(con->packet + ETHER_HDR_SIZE); + con->udp = (struct udphdr *)(con->packet + ETHER_HDR_SIZE + sizeof(struct iphdr)); + con->icmp = (struct icmphdr *)(con->packet + ETHER_HDR_SIZE + sizeof(struct iphdr)); + con->handler = handler; + + if (dest == 0xffffffff) { + memset(con->et->et_dest, 0xff, 6); + } else { + ret = arp_request(dest, con->et->et_dest); + if (ret) + goto out; + } + + con->et->et_protlen = htons(PROT_IP); + memcpy(con->et->et_src, net_ether, 6); + + con->ip->hl_v = 0x45; + con->ip->tos = 0; + con->ip->frag_off = htons(0x4000); /* No fragmentation */; + con->ip->ttl = 255; + net_copy_ip(&con->ip->daddr, &dest); + net_copy_ip(&con->ip->saddr, &net_ip); + + list_add_tail(&con->list, &connection_list); + + return con; +out: + free(con->packet); + free(con); + return ERR_PTR(ret); +} + +struct net_connection *net_udp_new(IPaddr_t dest, uint16_t dport, + rx_handler_f *handler) +{ + struct net_connection *con = net_new(dest, handler); + + if (IS_ERR(con)) + return con; + + con->proto = IPPROTO_UDP; + con->udp->uh_dport = htons(dport); + con->udp->uh_sport = htons(net_udp_new_localport()); + con->ip->protocol = IPPROTO_UDP; + + return con; +} + +struct net_connection *net_icmp_new(IPaddr_t dest, rx_handler_f *handler) +{ + struct net_connection *con = net_new(dest, handler); + + if (IS_ERR(con)) + return con; + + con->proto = IPPROTO_ICMP; + con->ip->protocol = IPPROTO_ICMP; + + return con; +} + +void net_unregister(struct net_connection *con) +{ + list_del(&con->list); + free(con->packet); + free(con); +} + +int net_ip_send(struct net_connection *con, int len) +{ + con->ip->tot_len = htons(sizeof(struct iphdr) + len); + con->ip->id = htons(net_ip_id++);; + con->ip->check = 0; + con->ip->check = ~net_checksum((unsigned char *)con->ip, sizeof(struct iphdr)); + + eth_send(con->packet, ETHER_HDR_SIZE + sizeof(struct iphdr) + len); + + return 0; +} + +int net_udp_send(struct net_connection *con, int len) +{ + con->udp->uh_ulen = htons(len + 8); + con->udp->uh_sum = 0; + + return net_ip_send(con, sizeof(struct udphdr) + len); +} + +int net_icmp_send(struct net_connection *con, int len) +{ + con->icmp->checksum = ~net_checksum((unsigned char *)con->icmp, + sizeof(struct icmphdr) + len); + + return net_ip_send(con, sizeof(struct icmphdr) + len); +} + +static int net_answer_arp(unsigned char *pkt, int len) +{ + struct arprequest *arp = (struct arprequest *)(pkt + ETHER_HDR_SIZE); + struct ethernet *et = (struct ethernet *)pkt; + unsigned char *packet; + + debug("%s\n", __func__); + + memcpy (et->et_dest, et->et_src, 6); + memcpy (et->et_src, net_ether, 6); + + et->et_protlen = htons(PROT_ARP); + arp->ar_op = htons(ARPOP_REPLY); + memcpy(&arp->ar_data[10], &arp->ar_data[0], 6); + net_copy_ip(&arp->ar_data[16], &arp->ar_data[6]); + memcpy(&arp->ar_data[0], net_ether, 6); + net_copy_ip(&arp->ar_data[6], &net_ip); + + packet = net_alloc_packet(); + if (!packet) + return 0; + memcpy(packet, pkt, ETHER_HDR_SIZE + ARP_HDR_SIZE); + eth_send(packet, ETHER_HDR_SIZE + ARP_HDR_SIZE); + free(packet); + + return 0; +} + +static void net_bad_packet(unsigned char *pkt, int len) +{ +#ifdef DEBUG + /* + * We received a bad packet. for now just dump it. + * We could add more sophisticated debugging here + */ + memory_display(pkt, 0, len, 1); +#endif +} + +static int net_handle_arp(unsigned char *pkt, int len) +{ + struct arprequest *arp; + + debug("%s: got arp\n", __func__); + + /* + * We have to deal with two types of ARP packets: + * - REQUEST packets will be answered by sending our + * IP address - if we know it. + * - REPLY packets are expected only after we asked + * for the TFTP server's or the gateway's ethernet + * address; so if we receive such a packet, we set + * the server ethernet address + */ + arp = (struct arprequest *)(pkt + ETHER_HDR_SIZE); + if (len < ARP_HDR_SIZE) + goto bad; + if (ntohs(arp->ar_hrd) != ARP_ETHER) + goto bad; + if (ntohs(arp->ar_pro) != PROT_IP) + goto bad; + if (arp->ar_hln != 6) + goto bad; + if (arp->ar_pln != 4) + goto bad; + if (net_ip == 0) + return 0; + if (net_read_ip(&arp->ar_data[16]) != net_ip) + return 0; + + switch (ntohs(arp->ar_op)) { + case ARPOP_REQUEST: + return net_answer_arp(pkt, len); + case ARPOP_REPLY: + arp_handler(arp); + return 1; + default: + pr_debug("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op)); + return -EINVAL; + } + + return 0; + +bad: + net_bad_packet(pkt, len); + return -EINVAL; +} + +static int net_handle_udp(unsigned char *pkt, int len) +{ + struct iphdr *ip = (struct iphdr *)(pkt + ETHER_HDR_SIZE); + struct net_connection *con; + struct udphdr *udp; + int port; + + udp = (struct udphdr *)(ip + 1); + port = ntohs(udp->uh_dport); + list_for_each_entry(con, &connection_list, list) { + if (con->proto == IPPROTO_UDP && port == ntohs(con->udp->uh_sport)) { + con->handler(pkt, len); + return 0; + } + } + return -EINVAL; +} + +static int net_handle_icmp(unsigned char *pkt, int len) +{ + struct net_connection *con; + + debug("%s\n", __func__); + + list_for_each_entry(con, &connection_list, list) { + if (con->proto == IPPROTO_ICMP) { + con->handler(pkt, len); + return 0; + } + } + return 0; +} + +static int net_handle_ip(unsigned char *pkt, int len) +{ + struct iphdr *ip = (struct iphdr *)(pkt + ETHER_HDR_SIZE); + IPaddr_t tmp; + + debug("%s\n", __func__); + + if (len < sizeof(struct ethernet) + sizeof(struct iphdr) || + len < ETHER_HDR_SIZE + ntohs(ip->tot_len)) { + debug("%s: bad len\n", __func__); + goto bad; + } + + if ((ip->hl_v & 0xf0) != 0x40) + goto bad; + + if (ip->frag_off & htons(0x1fff)) /* Can't deal w/ fragments */ + goto bad; + if (!net_checksum_ok((unsigned char *)ip, sizeof(struct iphdr))) + goto bad; + + tmp = net_read_ip(&ip->daddr); + if (net_ip && tmp != net_ip && tmp != 0xffffffff) + return 0; + + switch (ip->protocol) { + case IPPROTO_ICMP: + return net_handle_icmp(pkt, len); + case IPPROTO_UDP: + return net_handle_udp(pkt, len); + } + + return 0; +bad: + net_bad_packet(pkt, len); + return 0; +} + +int net_receive(unsigned char *pkt, int len) +{ + struct ethernet *et = (struct ethernet *)pkt; + int et_protlen = ntohs(et->et_protlen); + + if (len < ETHER_HDR_SIZE) + return 0; + + switch (et_protlen) { + case PROT_ARP: + return net_handle_arp(pkt, len); + case PROT_IP: + return net_handle_ip(pkt, len); + default: + debug("%s: got unknown protocol type: %d\n", __func__, et_protlen); + return 1; + } +} + +static int net_init(void) +{ + int i; + + for (i = 0; i < PKTBUFSRX; i++) + NetRxPackets[i] = memalign(32, PKTSIZE); + + return 0; +} + +postcore_initcall(net_init); + From 799c00c589e620ecca144e4d04b7bab3760a306b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 15:23:04 +0200 Subject: [PATCH 13/65] remove unused sntp.h Signed-off-by: Sascha Hauer --- net/sntp.h | 61 ------------------------------------------------------ 1 file changed, 61 deletions(-) delete mode 100644 net/sntp.h diff --git a/net/sntp.h b/net/sntp.h deleted file mode 100644 index 8a097bfa3..000000000 --- a/net/sntp.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * (C) Masami Komiya 2005 - * - * 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, or (at - * your option) any later version. - */ - -#ifndef __SNTP_H__ -#define __SNTP_H__ - -#define NTP_SERVICE_PORT 123 -#define SNTP_PACKET_LEN 48 - - -/* Leap Indicator */ -#define NTP_LI_NOLEAP 0x0 -#define NTP_LI_61SECS 0x1 -#define NTP_LI_59SECS 0x2 -#define NTP_LI_ALARM 0x3 - -/* Version */ - -#define NTP_VERSION 4 - -/* Mode */ -#define NTP_MODE_RESERVED 0 -#define NTP_MODE_SYMACTIVE 1 /* Symmetric Active */ -#define NTP_MODE_SYMPASSIVE 2 /* Symmetric Passive */ -#define NTP_MODE_CLIENT 3 -#define NTP_MODE_SERVER 4 -#define NTP_MODE_BROADCAST 5 -#define NTP_MODE_NTPCTRL 6 /* Reserved for NTP control message */ -#define NTP_MODE_PRIVATE 7 /* Reserved for private use */ - -struct sntp_pkt_t { -#if __LITTLE_ENDIAN - uchar mode:3; - uchar vn:3; - uchar li:2; -#else - uchar li:2; - uchar vn:3; - uchar mode:3; -#endif - uchar stratum; - uchar poll; - uchar precision; - uint root_delay; - uint root_dispersion; - uint reference_id; - unsigned long long reference_timestamp; - unsigned long long originate_timestamp; - unsigned long long receive_timestamp; - unsigned long long transmit_timestamp; -}; - -extern void SntpStart (void); /* Begin SNTP */ - -#endif /* __SNTP_H__ */ From 870e64993b9b1b7512ab34383a0c32a980e4a2bd Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 15:50:12 +0200 Subject: [PATCH 14/65] implement dhcp using new network stack Signed-off-by: Sascha Hauer --- net/dhcp.c | 491 ++++++++++++++++++++--------------------------------- 1 file changed, 180 insertions(+), 311 deletions(-) diff --git a/net/dhcp.c b/net/dhcp.c index f27a6966d..0771964b9 100644 --- a/net/dhcp.c +++ b/net/dhcp.c @@ -14,64 +14,44 @@ #include #include #include -#include "tftp.h" -#include "nfs.h" +#include +#include #define OPT_SIZE 312 /* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */ -typedef struct -{ - uchar bp_op; /* Operation */ -# define OP_BOOTREQUEST 1 -# define OP_BOOTREPLY 2 - uchar bp_htype; /* Hardware type */ -# define HWT_ETHER 1 - uchar bp_hlen; /* Hardware address length */ -# define HWL_ETHER 6 - uchar bp_hops; /* Hop count (gateway thing) */ - ulong bp_id; /* Transaction ID */ - ushort bp_secs; /* Seconds since boot */ - ushort bp_spare1; /* Alignment */ +struct bootp { + uint8_t bp_op; /* Operation */ +#define OP_BOOTREQUEST 1 +#define OP_BOOTREPLY 2 + uint8_t bp_htype; /* Hardware type */ +#define HWT_ETHER 1 + uint8_t bp_hlen; /* Hardware address length */ +#define HWL_ETHER 6 + uint8_t bp_hops; /* Hop count (gateway thing) */ + uint32_t bp_id; /* Transaction ID */ + uint16_t bp_secs; /* Seconds since boot */ + uint16_t bp_spare1; /* Alignment */ IPaddr_t bp_ciaddr; /* Client IP address */ IPaddr_t bp_yiaddr; /* Your (client) IP address */ IPaddr_t bp_siaddr; /* Server IP address */ IPaddr_t bp_giaddr; /* Gateway IP address */ - uchar bp_chaddr[16]; /* Client hardware address */ + uint8_t bp_chaddr[16]; /* Client hardware address */ char bp_sname[64]; /* Server host name */ char bp_file[128]; /* Boot file name */ - char bp_vend[OPT_SIZE]; /* Vendor information */ -} Bootp_t; - -#define BOOTP_HDR_SIZE sizeof (Bootp_t) -#define BOOTP_SIZE (ETHER_HDR_SIZE + IP_HDR_SIZE + BOOTP_HDR_SIZE) - -/**********************************************************************/ -/* - * Global functions and variables. - */ - -/* bootp.c */ -extern ulong BootpID; /* ID of cur BOOTP request */ -extern char BootFile[128]; /* Boot file name */ -#ifdef CONFIG_BOOTP_RANDOM_DELAY -ulong seed1, seed2; /* seed for random BOOTP delay */ -#endif - - -/* Send a BOOTP request */ -extern void BootpRequest (void); - -/****************** DHCP Support *********************/ + char bp_vend[0]; /* Vendor information */ +}; /* DHCP States */ -typedef enum { INIT, - INIT_REBOOT, - REBOOTING, - SELECTING, - REQUESTING, - REBINDING, - BOUND, - RENEWING } dhcp_state_t; +typedef enum { + INIT, + INIT_REBOOT, + REBOOTING, + SELECTING, + REQUESTING, + REBINDING, + BOUND, + RENEWING, +} dhcp_state_t; #define DHCP_DISCOVER 1 #define DHCP_OFFER 2 @@ -81,44 +61,27 @@ typedef enum { INIT, #define DHCP_NAK 6 #define DHCP_RELEASE 7 -#define SELECT_TIMEOUT 3 /* Seconds to wait for offers */ - -/**********************************************************************/ - #define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */ -#define TIMEOUT 5 /* Seconds before trying BOOTP again */ -#ifndef CONFIG_NET_RETRY_COUNT -# define TIMEOUT_COUNT 5 /* # of timeouts before giving up */ -#else -# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) -#endif - #define PORT_BOOTPS 67 /* BOOTP server UDP port */ #define PORT_BOOTPC 68 /* BOOTP client UDP port */ -#ifndef CONFIG_DHCP_MIN_EXT_LEN /* minimal length of extension list */ -#define CONFIG_DHCP_MIN_EXT_LEN 64 -#endif +#define DHCP_MIN_EXT_LEN 64 /* minimal length of extension list */ -ulong BootpID; -#ifdef CONFIG_BOOTP_RANDOM_DELAY -ulong seed1, seed2; -#endif +static uint32_t Bootp_id; +static dhcp_state_t dhcp_state; +static uint32_t dhcp_leasetime; +static IPaddr_t net_dhcp_server_ip; +static uint64_t dhcp_start; -dhcp_state_t dhcp_state = INIT; -unsigned long dhcp_leasetime = 0; -IPaddr_t NetDHCPServerIP = 0; -static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len); - -static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) +static int bootp_check_packet(unsigned char *pkt, unsigned src, unsigned len) { - Bootp_t *bp = (Bootp_t *) pkt; + struct bootp *bp = (struct bootp *) pkt; int retval = 0; - if (dest != PORT_BOOTPC || src != PORT_BOOTPS) + if (src != PORT_BOOTPS) retval = -1; - else if (len < sizeof (Bootp_t) - OPT_SIZE) + else if (len < sizeof(struct bootp)) retval = -2; else if (bp->bp_op != OP_BOOTREQUEST && bp->bp_op != OP_BOOTREPLY && @@ -131,11 +94,11 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) retval = -4; else if (bp->bp_hlen != HWL_ETHER) retval = -5; - else if (NetReadLong((ulong*)&bp->bp_id) != BootpID) { + else if (net_read_uint32(&bp->bp_id) != Bootp_id) { retval = -6; } - debug ("Filtering pkt = %d\n", retval); + debug("Filtering pkt = %d\n", retval); return retval; } @@ -143,64 +106,31 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) /* * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet */ -static void BootpCopyNetParams(Bootp_t *bp) +static void bootp_copy_net_params(struct bootp *bp) { IPaddr_t tmp_ip; - NetCopyIP(&NetOurIP, &bp->bp_yiaddr); - NetCopyIP(&tmp_ip, &bp->bp_siaddr); + tmp_ip = net_read_ip(&bp->bp_yiaddr); + net_set_ip(tmp_ip); + + tmp_ip = net_read_ip(&bp->bp_siaddr); if (tmp_ip != 0) - NetCopyIP(&NetServerIP, &bp->bp_siaddr); - memcpy (NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src, 6); + net_set_serverip(tmp_ip); + if (strlen(bp->bp_file) > 0) - safe_strncpy (BootFile, bp->bp_file, sizeof(BootFile)); + setenv("bootfile", bp->bp_file); - debug ("Bootfile: %s\n", BootFile); - - /* Propagate to environment: - * don't delete exising entry when BOOTP / DHCP reply does - * not contain a new value - */ - if (*BootFile) { - setenv ("bootfile", BootFile); - } -} - -static int truncate_sz (const char *name, int maxlen, int curlen) -{ - if (curlen >= maxlen) { - printf("*** WARNING: %s is too long (%d - max: %d) - truncated\n", - name, curlen, maxlen); - curlen = maxlen - 1; - } - return (curlen); + debug("bootfile: %s\n", bp->bp_file); } /* - * Timeout on BOOTP/DHCP request. + * Initialize BOOTP extension fields in the request. */ -static void -BootpTimeout(void) -{ - NetSetTimeout (TIMEOUT * SECOND, BootpTimeout); - BootpRequest (); -} - -/* - * Initialize BOOTP extension fields in the request. - */ -static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP) +static int dhcp_extended (u8 *e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP) { u8 *start = e; u8 *cnt; -#ifdef CONFIG_BOOTP_VENDOREX - u8 *x; -#endif -#ifdef CONFIG_BOOTP_SEND_HOSTNAME - char *hostname; -#endif - *e++ = 99; /* RFC1048 Magic Cookie */ *e++ = 130; *e++ = 83; @@ -236,175 +166,118 @@ static int DhcpExtended (u8 * e, int message_type, IPaddr_t ServerID, IPaddr_t R *e++ = tmp >> 8; *e++ = tmp & 0xff; } -#ifdef CONFIG_BOOTP_SEND_HOSTNAME - if ((hostname = getenv ("hostname"))) { - int hostnamelen = strlen (hostname); - - *e++ = 12; /* Hostname */ - *e++ = hostnamelen; - memcpy (e, hostname, hostnamelen); - e += hostnamelen; - } -#endif *e++ = 55; /* Parameter Request List */ cnt = e++; /* Pointer to count of requested items */ *cnt = 0; -#ifdef CONFIG_BOOTP_SUBNETMASK *e++ = 1; /* Subnet Mask */ *cnt += 1; -#endif -#ifdef CONFIG_BOOTP_TIMEOFFSET - *e++ = 2; - *cnt += 1; -#endif -#ifdef CONFIG_BOOTP_GATEWAY *e++ = 3; /* Router Option */ *cnt += 1; -#endif -#ifdef CONFIG_BOOTP_DNS *e++ = 6; /* DNS Server(s) */ *cnt += 1; -#endif -#ifdef CONFIG_BOOTP_HOSTNAME *e++ = 12; /* Hostname */ *cnt += 1; -#endif -#ifdef CONFIG_BOOTP_BOOTFILESIZE - *e++ = 13; /* Boot File Size */ + *e++ = 15; /* domain name */ *cnt += 1; -#endif -#ifdef CONFIG_BOOTP_BOOTPATH *e++ = 17; /* Boot path */ *cnt += 1; -#endif -#ifdef CONFIG_BOOTP_NISDOMAIN - *e++ = 40; /* NIS Domain name request */ - *cnt += 1; -#endif -#ifdef CONFIG_BOOTP_NTPSERVER - *e++ = 42; - *cnt += 1; -#endif *e++ = 255; /* End of the list */ /* Pad to minimal length */ -#ifdef CONFIG_DHCP_MIN_EXT_LEN - while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN) + while ((e - start) <= DHCP_MIN_EXT_LEN) *e++ = 0; -#endif return e - start; } -void -BootpRequest (void) +static struct net_connection *dhcp_con; + +static int bootp_request(void) { - uchar *pkt, *iphdr; - Bootp_t *bp; - int ext_len, pktlen, iplen; + struct bootp *bp; + int ext_len; + int ret; + unsigned char *payload = net_udp_get_payload(dhcp_con); + const char *bfile; dhcp_state = INIT; - printf("BOOTP broadcast\n"); - pkt = NetTxPacket; - memset ((void*)pkt, 0, PKTSIZE); + debug("BOOTP broadcast\n"); - pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP); - - /* - * Next line results in incorrect packet size being transmitted, resulting - * in errors in some DHCP servers, reporting missing bytes. Size must be - * set in packet header after extension length has been determined. - * C. Hallinan, DS4.COM, Inc. - */ - /* NetSetIP(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, sizeof (Bootp_t)); */ - iphdr = pkt; /* We need this later for NetSetIP() */ - pkt += IP_HDR_SIZE; - - bp = (Bootp_t *)pkt; + bp = (struct bootp *)payload; bp->bp_op = OP_BOOTREQUEST; bp->bp_htype = HWT_ETHER; bp->bp_hlen = HWL_ETHER; bp->bp_hops = 0; bp->bp_secs = htons(get_time_ns() >> 30); - NetWriteIP(&bp->bp_ciaddr, 0); - NetWriteIP(&bp->bp_yiaddr, 0); - NetWriteIP(&bp->bp_siaddr, 0); - NetWriteIP(&bp->bp_giaddr, 0); - memcpy (bp->bp_chaddr, NetOurEther, 6); - safe_strncpy (bp->bp_file, BootFile, sizeof(bp->bp_file)); + net_write_ip(&bp->bp_ciaddr, 0); + net_write_ip(&bp->bp_yiaddr, 0); + net_write_ip(&bp->bp_siaddr, 0); + net_write_ip(&bp->bp_giaddr, 0); + memcpy(bp->bp_chaddr, dhcp_con->et->et_src, 6); + + bfile = getenv("bootfile"); + if (bfile) + safe_strncpy (bp->bp_file, bfile, sizeof(bp->bp_file)); /* Request additional information from the BOOTP/DHCP server */ - ext_len = DhcpExtended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0); + ext_len = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0); - /* - * Bootp ID is the lower 4 bytes of our ethernet address - * plus the current time in HZ. - */ - BootpID = ((ulong)NetOurEther[2] << 24) - | ((ulong)NetOurEther[3] << 16) - | ((ulong)NetOurEther[4] << 8) - | (ulong)NetOurEther[5]; - BootpID += (uint32_t)get_time_ns(); - BootpID = htonl(BootpID); - NetCopyLong(&bp->bp_id, &BootpID); - - /* - * Calculate proper packet lengths taking into account the - * variable size of the options field - */ - pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + ext_len; - iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len; - NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); - NetSetTimeout(SELECT_TIMEOUT * SECOND, BootpTimeout); + Bootp_id = (uint32_t)get_time_ns(); + net_copy_uint32(&bp->bp_id, &Bootp_id); dhcp_state = SELECTING; - NetSetHandler(DhcpHandler); - NetSendPacket(NetTxPacket, pktlen); + + ret = net_udp_send(dhcp_con, sizeof(*bp) + ext_len); + + return ret; } -static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp) +static void dhcp_options_process(unsigned char *popt, struct bootp *bp) { - uchar *end = popt + BOOTP_HDR_SIZE; - int oplen, size; + unsigned char *end = popt + sizeof(*bp) + OPT_SIZE; + int oplen; + IPaddr_t ip; + char str[256]; while (popt < end && *popt != 0xff) { oplen = *(popt + 1); switch (*popt) { case 1: - NetCopyIP (&NetOurSubnetMask, (popt + 2)); + ip = net_read_ip(popt + 2); + net_set_netmask(ip); break; case 3: - NetCopyIP (&NetOurGatewayIP, (popt + 2)); + ip = net_read_ip(popt + 2); + net_set_gateway(ip); break; case 6: - NetCopyIP (&NetOurDNSIP, (popt + 2)); -#ifdef CONFIG_BOOTP_DNS2 - if (*(popt + 1) > 4) { - NetCopyIP (&NetOurDNS2IP, (popt + 2 + 4)); - } -#endif + ip = net_read_ip(popt + 2); + setenv_ip("nameserver", ip); break; case 12: - size = truncate_sz ("Host Name", sizeof (NetOurHostName), oplen); - memcpy (&NetOurHostName, popt + 2, size); - NetOurHostName[size] = 0; + memcpy(str, popt + 2, oplen); + str[oplen] = 0; + setenv("hostname", str); break; - case 15: /* Ignore Domain Name Option */ + case 15: + memcpy(str, popt + 2, oplen); + str[oplen] = 0; + setenv("domainname", str); break; case 17: - size = truncate_sz ("Root Path", sizeof (NetOurRootPath), oplen); - memcpy (&NetOurRootPath, popt + 2, size); - NetOurRootPath[size] = 0; + memcpy(str, popt + 2, oplen); + str[oplen] = 0; + setenv("rootpath", str); break; case 51: - NetCopyLong (&dhcp_leasetime, (ulong *) (popt + 2)); + net_copy_uint32 (&dhcp_leasetime, (uint32_t *)(popt + 2)); break; case 53: /* Ignore Message Type Option */ break; case 54: - NetCopyIP (&NetDHCPServerIP, (popt + 2)); + net_copy_ip(&net_dhcp_server_ip, (popt + 2)); break; case 58: /* Ignore Renewal Time Option */ break; @@ -419,10 +292,9 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp) * pass the bootp packet pointer into here as the * second arg */ - size = truncate_sz ("Opt Boot File", - sizeof(bp->bp_file), - oplen); - if (bp->bp_file[0] == '\0' && size > 0) { + memcpy(str, popt + 2, oplen); + str[oplen] = 0; + if (bp->bp_file[0] == '\0') { /* * only use vendor boot file if we didn't * receive a boot file in the main non-vendor @@ -434,8 +306,7 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp) */ printf("*** WARNING: using vendor " "optional boot file\n"); - memcpy(bp->bp_file, popt + 2, size); - bp->bp_file[size] = '\0'; + setenv("bootfile", str); } break; default: @@ -443,16 +314,16 @@ static void DhcpOptionsProcess (uchar * popt, Bootp_t *bp) if (dhcp_vendorex_proc (popt)) break; #endif - printf ("*** Unhandled DHCP Option in OFFER/ACK: %d\n", *popt); + debug("*** Unhandled DHCP Option in OFFER/ACK: %d\n", *popt); break; } popt += oplen + 2; /* Process next option */ } } -static int DhcpMessageType(unsigned char *popt) +static int dhcp_message_type(unsigned char *popt) { - if (NetReadLong((ulong*)popt) != htonl(BOOTP_VENDOR_MAGIC)) + if (net_read_uint32((uint32_t *)popt) != htonl(BOOTP_VENDOR_MAGIC)) return -1; popt += 4; @@ -464,77 +335,66 @@ static int DhcpMessageType(unsigned char *popt) return -1; } -static void DhcpSendRequestPkt(Bootp_t *bp_offer) +static void dhcp_send_request_packet(struct bootp *bp_offer) { - uchar *pkt, *iphdr; - Bootp_t *bp; - int pktlen, iplen, extlen; + struct bootp *bp; + int extlen; IPaddr_t OfferedIP; + unsigned char *payload = net_udp_get_payload(dhcp_con); - debug ("DhcpSendRequestPkt: Sending DHCPREQUEST\n"); - pkt = NetTxPacket; - memset ((void*)pkt, 0, PKTSIZE); + debug("%s: Sending DHCPREQUEST\n", __func__); - pkt += NetSetEther(pkt, NetBcastAddr, PROT_IP); - - iphdr = pkt; /* We'll need this later to set proper pkt size */ - pkt += IP_HDR_SIZE; - - bp = (Bootp_t *)pkt; + bp = (struct bootp *)payload; bp->bp_op = OP_BOOTREQUEST; bp->bp_htype = HWT_ETHER; bp->bp_hlen = HWL_ETHER; bp->bp_hops = 0; /* FIXME what is this? */ // bp->bp_secs = htons(get_timer(0) / CFG_HZ); - NetCopyIP(&bp->bp_ciaddr, &bp_offer->bp_ciaddr); /* both in network byte order */ - NetCopyIP(&bp->bp_yiaddr, &bp_offer->bp_yiaddr); - NetCopyIP(&bp->bp_siaddr, &bp_offer->bp_siaddr); + net_copy_ip(&bp->bp_ciaddr, &bp_offer->bp_ciaddr); /* both in network byte order */ + net_copy_ip(&bp->bp_yiaddr, &bp_offer->bp_yiaddr); + net_copy_ip(&bp->bp_siaddr, &bp_offer->bp_siaddr); /* * RFC3046 requires Relay Agents to discard packets with * nonzero and offered giaddr */ - NetWriteIP(&bp->bp_giaddr, 0); + net_write_ip(&bp->bp_giaddr, 0); - memcpy (bp->bp_chaddr, NetOurEther, 6); + memcpy(bp->bp_chaddr, dhcp_con->et->et_src, 6); /* * ID is the id of the OFFER packet */ - NetCopyLong(&bp->bp_id, &bp_offer->bp_id); + net_copy_uint32(&bp->bp_id, &bp_offer->bp_id); /* * Copy options from OFFER packet if present */ - NetCopyIP(&OfferedIP, &bp->bp_yiaddr); - extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST, NetDHCPServerIP, OfferedIP); + net_copy_ip(&OfferedIP, &bp->bp_yiaddr); + extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST, net_dhcp_server_ip, OfferedIP); - pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + extlen; - iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen; - NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); - - debug ("Transmitting DHCPREQUEST packet: len = %d\n", pktlen); - NetSendPacket(NetTxPacket, pktlen); + debug("Transmitting DHCPREQUEST packet\n"); + net_udp_send(dhcp_con, sizeof(*bp) + extlen); } /* * Handle DHCP received packets. */ -static void -DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) +static void dhcp_handler(char *packet, unsigned int len) { - Bootp_t *bp = (Bootp_t *)pkt; + char *pkt = net_eth_to_udp_payload(packet); + struct udphdr *udp = net_eth_to_udphdr(packet); + struct bootp *bp = (struct bootp *)pkt; - debug ("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n", - src, dest, len, dhcp_state); + len = net_eth_to_udplen(packet); - if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */ + debug("DHCPHandler: got packet: (len=%d) state: %d\n", + len, dhcp_state); + + if (bootp_check_packet(pkt, ntohs(udp->uh_sport), len)) /* Filter out pkts we don't want */ return; - debug ("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n", - src, dest, len, dhcp_state); - switch (dhcp_state) { case SELECTING: /* @@ -543,69 +403,78 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) * If filename is in format we recognize, assume it is a valid * OFFER from a server we want. */ - debug ("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file); -#ifdef CFG_BOOTFILE_PREFIX - if (strncmp(bp->bp_file, - CFG_BOOTFILE_PREFIX, - strlen(CFG_BOOTFILE_PREFIX)) == 0 ) { -#endif /* CFG_BOOTFILE_PREFIX */ + debug ("%s: state SELECTING, bp_file: \"%s\"\n", __func__, bp->bp_file); + dhcp_state = REQUESTING; - debug ("TRANSITIONING TO REQUESTING STATE\n"); - dhcp_state = REQUESTING; + if (net_read_uint32((uint32_t *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) + dhcp_options_process((u8 *)&bp->bp_vend[4], bp); - if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp); + bootp_copy_net_params(bp); /* Store net params from reply */ - BootpCopyNetParams(bp); /* Store net params from reply */ + dhcp_start = get_time_ns(); + dhcp_send_request_packet(bp); - NetSetTimeout(TIMEOUT * SECOND, BootpTimeout); - DhcpSendRequestPkt(bp); -#ifdef CFG_BOOTFILE_PREFIX - } -#endif /* CFG_BOOTFILE_PREFIX */ - - return; break; case REQUESTING: - debug ("DHCP State: REQUESTING\n"); + debug ("%s: State REQUESTING\n", __func__); - if ( DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK ) { - if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) - DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp); - BootpCopyNetParams(bp); /* Store net params from reply */ + if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK ) { + if (net_read_uint32((uint32_t *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) + dhcp_options_process((u8 *)&bp->bp_vend[4], bp); + bootp_copy_net_params(bp); /* Store net params from reply */ dhcp_state = BOUND; puts ("DHCP client bound to address "); - print_IPaddr(NetOurIP); + print_IPaddr(net_get_ip()); putchar('\n'); - - NetState = NETLOOP_SUCCESS; return; } break; default: - puts ("DHCP: INVALID STATE\n"); + debug("%s: INVALID STATE\n", __func__); break; } - } static int do_dhcp(struct command *cmdtp, int argc, char *argv[]) { - int size; + int ret; - if (NetLoopInit(DHCP) < 0) - return 1; + dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler); + if (IS_ERR(dhcp_con)) { + ret = PTR_ERR(dhcp_con); + goto out; + } - NetOurIP = 0; - BootpRequest(); /* Basically same as BOOTP */ + ret = net_udp_bind(dhcp_con, PORT_BOOTPC); + if (ret) + goto out1; - if ((size = NetLoop()) < 0) - return 1; + net_set_ip(0); - /* NetLoop ok, update environment */ - netboot_update_env(); + ret = bootp_request(); /* Basically same as BOOTP */ + if (ret) + goto out1; - return 0; + while (dhcp_state != BOUND) { + if (ctrlc()) + break; + net_poll(); + if (is_timeout(dhcp_start, 3 * SECOND)) { + dhcp_start = get_time_ns(); + printf("T "); + ret = bootp_request(); + if (ret) + goto out1; + } + } + +out1: + net_unregister(dhcp_con); +out: + if (ret) + printf("dhcp failed: %s\n", strerror(-ret)); + + return ret ? 1 : 0; } BAREBOX_CMD_START(dhcp) From 17f1f5b3b79d05f206e21a78ad9856a6a8ef135f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 15:50:45 +0200 Subject: [PATCH 15/65] implement tftp using new network stack Signed-off-by: Sascha Hauer --- net/tftp.c | 271 +++++++++++++++++++++++++---------------------------- 1 file changed, 126 insertions(+), 145 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index e8a8a3a89..38d16bcbd 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -13,9 +13,9 @@ #include #include #include -#include "tftp.h" +#include -#define WELL_KNOWN_PORT 69 /* Well known TFTP port # */ +#define TFTP_PORT 69 /* Well known TFTP port # */ #define TIMEOUT 5 /* Seconds to timeout for a lost pkt */ # define TIMEOUT_COUNT 10 /* # of timeouts before giving up */ /* (for checking the image size) */ @@ -32,60 +32,45 @@ #define TFTP_OACK 6 -static int TftpServerPort; /* The UDP port at their end */ -static int TftpOurPort; /* The UDP port at our end */ -static ulong TftpBlock; /* packet sequence number */ -static ulong TftpLastBlock; /* last packet sequence number received */ -static ulong TftpBlockWrap; /* count of sequence number wraparounds */ -static ulong TftpBlockWrapOffset; /* memory offset due to wrapping */ -static int TftpState; +static int tftp_server_port; /* The UDP port at their end */ +static unsigned int tftp_block; /* packet sequence number */ +static unsigned int tftp_last_block; /* last packet sequence number received */ +static unsigned int tftp_block_wrap; /* count of sequence number wraparounds */ +static unsigned int tftp_block_wrap_offset; /* memory offset due to wrapping */ +static int tftp_state; +static uint64_t tftp_timer_start; +static int tftp_err; #define STATE_RRQ 1 #define STATE_DATA 2 #define STATE_OACK 3 +#define STATE_DONE 4 #define TFTP_BLOCK_SIZE 512 /* default TFTP block size */ -#define TFTP_SEQUENCE_SIZE ((ulong)(1<<16)) /* sequence number is 16 bit */ +#define TFTP_SEQUENCE_SIZE ((unsigned long)(1<<16)) /* sequence number is 16 bit */ static char *tftp_filename; - +static struct net_connection *tftp_con; static int net_store_fd; -static int store_block(unsigned block, uchar * src, unsigned len) +static int tftp_send(void) { - ulong offset = block * TFTP_BLOCK_SIZE + TftpBlockWrapOffset; - ulong newsize = offset + len; + unsigned char *pkt; + unsigned char *xp; + int len = 0; + uint16_t *s; + unsigned char *packet = net_udp_get_payload(tftp_con); int ret; - ret = write(net_store_fd, src, len); - if (ret < 0) - return ret; + pkt = packet; - if (NetBootFileXferSize < newsize) - NetBootFileXferSize = newsize; - return 0; -} - -static void TftpSend(void) -{ - uchar *pkt; - uchar *xp; - int len = 0; - ushort *s; - - /* - * We will always be sending some sort of packet, so - * cobble together the packet headers now. - */ - pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE; - - switch (TftpState) { + switch (tftp_state) { case STATE_RRQ: xp = pkt; - s = (ushort *)pkt; + s = (uint16_t *)pkt; *s++ = htons(TFTP_RRQ); - pkt = (uchar *)s; - pkt += sprintf((uchar *)pkt, "%s%coctet%ctimeout%c%d", + pkt = (unsigned char *)s; + pkt += sprintf((unsigned char *)pkt, "%s%coctet%ctimeout%c%d", tftp_filename, 0, 0, 0, TIMEOUT) + 1; len = pkt - xp; break; @@ -93,44 +78,36 @@ static void TftpSend(void) case STATE_DATA: case STATE_OACK: xp = pkt; - s = (ushort *)pkt; + s = (uint16_t *)pkt; *s++ = htons(TFTP_ACK); - *s++ = htons(TftpBlock); - pkt = (uchar *)s; + *s++ = htons(tftp_block); + pkt = (unsigned char *)s; len = pkt - xp; break; } - NetSendUDPPacket(NetServerEther, NetServerIP, TftpServerPort, - TftpOurPort, len); + ret = net_udp_send(tftp_con, len); + + return ret; } -static void TftpTimeout(void) +static void tftp_handler(char *packet, unsigned len) { - puts("T "); - NetSetTimeout(TIMEOUT * SECOND, TftpTimeout); - TftpSend(); -} - -static void TftpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) -{ - ushort proto; - ushort *s; - - if (dest != TftpOurPort) - return; - - if (TftpState != STATE_RRQ && src != TftpServerPort) - return; + uint16_t proto; + uint16_t *s; + char *pkt = net_eth_to_udp_payload(packet); + struct udphdr *udp = net_eth_to_udphdr(packet); + int ret; + len = net_eth_to_udplen(packet); if (len < 2) return; len -= 2; /* warning: don't use increment (++) in ntohs() macros!! */ - s = (ushort *)pkt; + s = (uint16_t *)pkt; proto = *s++; - pkt = (uchar *)s; + pkt = (unsigned char *)s; switch (ntohs(proto)) { case TFTP_RRQ: case TFTP_WRQ: @@ -140,16 +117,17 @@ static void TftpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) break; case TFTP_OACK: - debug("Got OACK: %s %s\n", pkt, pkt+strlen(pkt)+1); - TftpState = STATE_OACK; - TftpServerPort = src; - TftpSend(); /* Send ACK */ + debug("Got OACK: %s %s\n", pkt, pkt + strlen(pkt) + 1); + tftp_state = STATE_OACK; + tftp_server_port = ntohs(udp->uh_sport); + tftp_con->udp->uh_dport = udp->uh_sport; + tftp_send(); /* Send ACK */ break; case TFTP_DATA: if (len < 2) return; len -= 2; - TftpBlock = ntohs(*(ushort *)pkt); + tftp_block = ntohs(*(uint16_t *)pkt); /* * RFC1350 specifies that the first data packet will @@ -157,49 +135,50 @@ static void TftpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) * number of 0 this means that there was a wrap * around of the (16 bit) counter. */ - if (TftpBlock == 0) { - TftpBlockWrap++; - TftpBlockWrapOffset += TFTP_BLOCK_SIZE * TFTP_SEQUENCE_SIZE; - printf ("\n\t %lu MB received\n\t ", TftpBlockWrapOffset>>20); + if (tftp_block == 0) { + tftp_block_wrap++; + tftp_block_wrap_offset += TFTP_BLOCK_SIZE * TFTP_SEQUENCE_SIZE; } else { - if (((TftpBlock - 1) % 10) == 0) { + if (((tftp_block - 1) % 10) == 0) { putchar('#'); - } else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) { + } else if ((tftp_block % (10 * HASHES_PER_LINE)) == 0) { puts("\n\t "); } } - if (TftpState == STATE_RRQ) + if (tftp_state == STATE_RRQ) debug("Server did not acknowledge timeout option!\n"); - if (TftpState == STATE_RRQ || TftpState == STATE_OACK) { + if (tftp_state == STATE_RRQ || tftp_state == STATE_OACK) { /* first block received */ - TftpState = STATE_DATA; - TftpServerPort = src; - TftpLastBlock = 0; - TftpBlockWrap = 0; - TftpBlockWrapOffset = 0; + tftp_state = STATE_DATA; + tftp_con->udp->uh_dport = udp->uh_sport; + tftp_server_port = ntohs(udp->uh_sport); + tftp_last_block = 0; + tftp_block_wrap = 0; + tftp_block_wrap_offset = 0; - if (TftpBlock != 1) { /* Assertion */ - printf("\nTFTP error: " - "First block is not block 1 (%ld)\n" - "Starting again\n\n", - TftpBlock); - NetState = NETLOOP_FAIL; + if (tftp_block != 1) { /* Assertion */ + printf("error: First block is not block 1 (%ld)\n", + tftp_block); + tftp_err = -EINVAL; + tftp_state = STATE_DONE; break; } } - if (TftpBlock == TftpLastBlock) + if (tftp_block == tftp_last_block) /* Same block again; ignore it. */ break; - TftpLastBlock = TftpBlock; - NetSetTimeout(TIMEOUT * SECOND, TftpTimeout); + tftp_last_block = tftp_block; + tftp_timer_start = get_time_ns(); - if (store_block(TftpBlock - 1, pkt + 2, len) < 0) { + ret = write(net_store_fd, pkt + 2, len); + if (ret < 0) { perror("write"); - NetState = NETLOOP_FAIL; + tftp_err = -errno; + tftp_state = STATE_DONE; return; } @@ -207,58 +186,31 @@ static void TftpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) * Acknowledge the block just received, which will prompt * the server for the next one. */ - TftpSend(); + tftp_send(); + + if (len < TFTP_BLOCK_SIZE) + tftp_state = STATE_DONE; - if (len < TFTP_BLOCK_SIZE) { - /* - * We received the whole thing. Try to - * run it. - */ - puts("\ndone\n"); - NetState = NETLOOP_SUCCESS; - } break; case TFTP_ERROR: - printf("\nTFTP error: '%s' (%d)\n", - pkt + 2, ntohs(*(ushort *)pkt)); - NetState = NETLOOP_FAIL; + debug("\nTFTP error: '%s' (%d)\n", + pkt + 2, ntohs(*(uint16_t *)pkt)); + switch (ntohs(*(uint16_t *)pkt)) { + case 1: tftp_err = -ENOENT; break; + case 2: tftp_err = -EACCES; break; + default: tftp_err = -EINVAL; break; + } + tftp_state = STATE_DONE; break; } } -void TftpStart(char *filename) -{ - char ip1[16], ip2[16]; - - tftp_filename = filename; - - printf("TFTP from server %s; our IP address is %s\n" - "\nFilename '%s'.\nLoading: *\b", - ip_to_string(NetServerIP, ip1), - ip_to_string(NetOurIP, ip2), - tftp_filename); - - NetSetTimeout(TIMEOUT * SECOND, TftpTimeout); - NetSetHandler(TftpHandler); - - TftpServerPort = WELL_KNOWN_PORT; - TftpState = STATE_RRQ; - /* Use a pseudo-random port */ - TftpOurPort = 1024 + ((unsigned int)get_time_ns() % 3072); - TftpBlock = 0; - - /* zero out server ether in case the server ip has changed */ - memset(NetServerEther, 0, 6); - - TftpSend(); -} - static int do_tftpb(struct command *cmdtp, int argc, char *argv[]) { - int rcode = 0; - char *localfile; - char *remotefile; + char *localfile; + char *remotefile; + char ip1[16]; if (argc < 2) return COMMAND_ERROR_USAGE; @@ -276,22 +228,51 @@ static int do_tftpb(struct command *cmdtp, int argc, char *argv[]) return 1; } - if (NetLoopInit(TFTP) < 0) - goto out; - - TftpStart(remotefile); - - if (NetLoop() < 0) { - rcode = 1; - goto out; + tftp_con = net_udp_new(net_get_serverip(), TFTP_PORT, tftp_handler); + if (IS_ERR(tftp_con)) { + tftp_err = PTR_ERR(tftp_con); + goto out_close; } - /* NetLoop ok, update environment */ - netboot_update_env(); + tftp_filename = remotefile; -out: + printf("TFTP from server %s; Filename: '%s'\nLoading: ", + ip_to_string(net_get_serverip(), ip1), + tftp_filename); + + tftp_timer_start = get_time_ns(); + tftp_state = STATE_RRQ; + tftp_block = 0; + + tftp_err = tftp_send(); + if (tftp_err) + goto out_unreg; + + while (tftp_state != STATE_DONE) { + if (ctrlc()) { + tftp_err = -EINTR; + break; + } + net_poll(); + if (is_timeout(tftp_timer_start, SECOND)) { + tftp_timer_start = get_time_ns(); + printf("T "); + tftp_send(); + } + } +out_unreg: + net_unregister(tftp_con); +out_close: close(net_store_fd); - return rcode; + + if (tftp_err) { + printf("\ntftp failed: %s\n", strerror(-tftp_err)); + unlink(localfile); + } + + printf("\n"); + + return tftp_err == 0 ? 0 : 1; } static const __maybe_unused char cmd_tftp_help[] = From 98ff00b6d26497409e7aaafdecb1f5480ab20031 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 15:51:50 +0200 Subject: [PATCH 16/65] implement ping using new network stack Signed-off-by: Sascha Hauer --- net/ping.c | 145 +++++++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/net/ping.c b/net/ping.c index 7e21fe4cc..0f9868eb6 100644 --- a/net/ping.c +++ b/net/ping.c @@ -2,102 +2,103 @@ #include #include #include +#include +#include -static ushort PingSeqNo; +static uint16_t ping_sequence_number; -static IPaddr_t NetPingIP; /* the ip address to ping */ +static IPaddr_t net_ping_ip; /* the ip address to ping */ -static int PingSend(void) +#define PING_STATE_INIT 0 +#define PING_STATE_SUCCESS 1 + +static int ping_state; + +static struct net_connection *ping_con; + +static int ping_send(void) { - static uchar mac[6]; - IP_t *ip; - ushort *s; - uchar *pkt; + unsigned char *payload; + struct icmphdr *icmp; + uint64_t ts; - /* XXX always send arp request */ + icmp = ping_con->icmp; - memcpy(mac, NetEtherNullAddr, 6); + icmp->type = ICMP_ECHO_REQUEST; + icmp->code = 0; + icmp->checksum = 0; + icmp->un.echo.id = 0; + icmp->un.echo.sequence = htons(ping_sequence_number); - pr_debug("sending ARP for %08lx\n", NetPingIP); + ping_sequence_number++; - NetArpWaitPacketIP = NetPingIP; - NetArpWaitPacketMAC = mac; - - pkt = NetArpWaitTxPacket; - pkt += NetSetEther(pkt, mac, PROT_IP); - - ip = (IP_t *)pkt; - - /* - * Construct an IP and ICMP header. (need to set no fragment bit - XXX) - */ - ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ - ip->ip_tos = 0; - ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8); - ip->ip_id = htons(NetIPID++); - ip->ip_off = htons(0x4000); /* No fragmentation */ - ip->ip_ttl = 255; - ip->ip_p = 0x01; /* ICMP */ - ip->ip_sum = 0; - NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ - NetCopyIP((void*)&ip->ip_dst, &NetPingIP); /* - "" - */ - ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); - - s = &ip->udp_src; /* XXX ICMP starts here */ - s[0] = htons(0x0800); /* echo-request, code */ - s[1] = 0; /* checksum */ - s[2] = 0; /* identifier */ - s[3] = htons(PingSeqNo++); /* sequence number */ - s[1] = ~NetCksum((uchar *)s, 8/2); - - /* size of the waiting packet */ - NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE_NO_UDP + 8; - - /* and do the ARP request */ - NetArpWaitTimerStart = get_time_ns(); - ArpRequest(); - return 1; /* waiting */ + payload = (char *)(icmp + 1); + ts = get_time_ns(); + memcpy(payload, &ts, sizeof(ts)); + payload[8] = 0xab; + payload[9] = 0xcd; + return net_icmp_send(ping_con, 9); } -static void -PingTimeout (void) -{ - NetState = NETLOOP_FAIL; /* we did not get the reply */ -} - -static void -PingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len) +void ping_handler(char *pkt, unsigned len) { IPaddr_t tmp; - IP_t *ip = (IP_t *)pkt; + struct iphdr *ip = net_eth_to_iphdr(pkt); - tmp = NetReadIP((void *)&ip->ip_src); - if (tmp != NetPingIP) + tmp = net_read_ip((void *)&ip->saddr); + if (tmp != net_ping_ip) return; - NetState = NETLOOP_SUCCESS; + ping_state = PING_STATE_SUCCESS; } int do_ping(struct command *cmdtp, int argc, char *argv[]) { - if (argc < 2 || string_to_ip(argv[1], &NetPingIP)) + int ret; + uint64_t ping_start = 0; + + if (argc < 2 || string_to_ip(argv[1], &net_ping_ip)) return COMMAND_ERROR_USAGE; - if (NetLoopInit(PING) < 0) - return 1; - - NetSetTimeout (10 * SECOND, PingTimeout); - NetSetHandler (PingHandler); - PingSend(); - - if (NetLoop() < 0) { - printf("ping failed; host %s is not alive\n", argv[1]); - return 1; + ping_con = net_icmp_new(net_ping_ip, ping_handler); + if (IS_ERR(ping_con)) { + ret = PTR_ERR(ping_con); + goto out; } - printf("host %s is alive\n", argv[1]); + ping_start = get_time_ns(); + ret = ping_send(); + if (ret) + goto out_unreg; - return 0; + ping_state = PING_STATE_INIT; + ping_sequence_number = 0; + + while (ping_state == PING_STATE_INIT) { + if (ctrlc()) { + ret = -EINTR; + break; + } + + net_poll(); + + if (is_timeout(ping_start, 10 * SECOND)) { + ping_start = get_time_ns(); + ret = ping_send(); + if (ret) + goto out_unreg; + } + } + + if (!ret) + printf("host %s is alive\n", argv[1]); + +out_unreg: + net_unregister(ping_con); +out: + if (ret) + printf("ping failed: %s\n", strerror(-ret)); + return ping_state == PING_STATE_SUCCESS ? 0 : 1; } BAREBOX_CMD_START(ping) From c31ea55e928d312472940061b741cee992df389c Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 15:52:33 +0200 Subject: [PATCH 17/65] implement nfs using new network stack Signed-off-by: Sascha Hauer --- net/nfs.c | 712 ++++++++++++++++++++++++++---------------------------- 1 file changed, 344 insertions(+), 368 deletions(-) diff --git a/net/nfs.c b/net/nfs.c index 15f91abc4..51df7a367 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -32,28 +32,111 @@ #include #include #include -#include "nfs.h" +#include -/*#define NFS_DEBUG*/ +#define SUNRPC_PORT 111 + +#define PROG_PORTMAP 100000 +#define PROG_NFS 100003 +#define PROG_MOUNT 100005 + +#define MSG_CALL 0 +#define MSG_REPLY 1 + +#define PORTMAP_GETPORT 3 + +#define MOUNT_ADDENTRY 1 +#define MOUNT_UMOUNTALL 4 + +#define NFS_LOOKUP 4 +#define NFS_READLINK 5 +#define NFS_READ 6 + +#define NFS_FHSIZE 32 + +enum nfs_stat { + NFS_OK = 0, + NFSERR_PERM = 1, + NFSERR_NOENT = 2, + NFSERR_IO = 5, + NFSERR_NXIO = 6, + NFSERR_ACCES = 13, + NFSERR_EXIST = 17, + NFSERR_NODEV = 19, + NFSERR_NOTDIR = 20, + NFSERR_ISDIR = 21, + NFSERR_FBIG = 27, + NFSERR_NOSPC = 28, + NFSERR_ROFS = 30, + NFSERR_NAMETOOLONG=63, + NFSERR_NOTEMPTY = 66, + NFSERR_DQUOT = 69, + NFSERR_STALE = 70, + NFSERR_WFLUSH = 99, +}; + +/* Block size used for NFS read accesses. A RPC reply packet (including all + * headers) must fit within a single Ethernet frame to avoid fragmentation. + * Chosen to be a power of two, as most NFS servers are optimized for this. */ +#define NFS_READ_SIZE 1024 + +struct rpc_call { + uint32_t id; + uint32_t type; + uint32_t rpcvers; + uint32_t prog; + uint32_t vers; + uint32_t proc; + uint32_t data[0]; +}; + +struct rpc_reply { + uint32_t id; + uint32_t type; + uint32_t rstatus; + uint32_t verifier; + uint32_t v2; + uint32_t astatus; + uint32_t data[0]; +}; + +struct rpc_t { + union { + struct { + uint32_t id; + uint32_t type; + uint32_t rpcvers; + uint32_t prog; + uint32_t vers; + uint32_t proc; + uint32_t data[1]; + } call; + struct { + uint32_t id; + uint32_t type; + uint32_t rstatus; + uint32_t verifier; + uint32_t v2; + uint32_t astatus; + uint32_t data[19]; + } reply; + } u; +}; #define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */ #define NFS_TIMEOUT 60 -static int fs_mounted = 0; static unsigned long rpc_id = 0; static int nfs_offset = -1; -static int nfs_len; +static uint64_t nfs_timer_start; +static int nfs_err; static char dirfh[NFS_FHSIZE]; /* file handle of directory */ static char filefh[NFS_FHSIZE]; /* file handle of kernel image */ -static int NfsDownloadState; -static IPaddr_t NfsServerIP; -static int NfsSrvMountPort; -static int NfsSrvNfsPort; -static int NfsOurPort; -static int NfsTimeoutCount; -static int NfsState; +static int nfs_server_mount_port; +static int nfs_server_nfs_port; +static int nfs_state; #define STATE_PRCLOOKUP_PROG_MOUNT_REQ 1 #define STATE_PRCLOOKUP_PROG_NFS_REQ 2 #define STATE_MOUNT_REQ 3 @@ -61,40 +144,22 @@ static int NfsState; #define STATE_LOOKUP_REQ 5 #define STATE_READ_REQ 6 #define STATE_READLINK_REQ 7 +#define STATE_DONE 8 static char *nfs_filename; static char *nfs_path; static char nfs_path_buff[2048]; static int net_store_fd; - -static __inline__ int -store_block (uchar * src, unsigned offset, unsigned len) -{ - ulong newsize = offset + len; - int ret; - - ret = write(net_store_fd, src, len); - if (ret < 0) - return ret; - - if (NetBootFileXferSize < (offset+len)) - NetBootFileXferSize = newsize; - - return 0; -} +static struct net_connection *nfs_con; /************************************************************************** RPC_ADD_CREDENTIALS - Add RPC authentication/verifier entries **************************************************************************/ -static long *rpc_add_credentials (long *p) +static uint32_t *rpc_add_credentials(uint32_t *p) { int hl; - int hostnamelen; - char hostname[256]; - - strcpy (hostname, ""); - hostnamelen=strlen (hostname); + int hostnamelen = 0; /* Here's the executive summary on authentication requirements of the * various NFS server implementations: Linux accepts both AUTH_NONE @@ -112,10 +177,12 @@ static long *rpc_add_credentials (long *p) *p++ = htonl(hl+20); /* auth length */ *p++ = htonl(0); /* stamp */ *p++ = htonl(hostnamelen); /* hostname string */ - if (hostnamelen & 3) { + + if (hostnamelen & 3) *(p + hostnamelen / 4) = 0; /* add zero padding */ - } - memcpy (p, hostname, hostnamelen); + + /* memcpy(p, hostname, hostnamelen); */ /* empty hostname */ + p += hl / 4; *p++ = 0; /* uid */ *p++ = 0; /* gid */ @@ -131,46 +198,42 @@ static long *rpc_add_credentials (long *p) /************************************************************************** RPC_LOOKUP - Lookup RPC Port numbers **************************************************************************/ -static void -rpc_req (int rpc_prog, int rpc_proc, uint32_t *data, int datalen) +static int rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen) { - struct rpc_t pkt; + struct rpc_call pkt; unsigned long id; - uint32_t *p; - int pktlen; int sport; + int ret; + unsigned char *payload = net_udp_get_payload(nfs_con); id = ++rpc_id; - pkt.u.call.id = htonl(id); - pkt.u.call.type = htonl(MSG_CALL); - pkt.u.call.rpcvers = htonl(2); /* use RPC version 2 */ - pkt.u.call.prog = htonl(rpc_prog); - pkt.u.call.vers = htonl(2); /* portmapper is version 2 */ - pkt.u.call.proc = htonl(rpc_proc); - p = (uint32_t *)&(pkt.u.call.data); + pkt.id = htonl(id); + pkt.type = htonl(MSG_CALL); + pkt.rpcvers = htonl(2); /* use RPC version 2 */ + pkt.prog = htonl(rpc_prog); + pkt.vers = htonl(2); /* portmapper is version 2 */ + pkt.proc = htonl(rpc_proc); - if (datalen) - memcpy ((char *)p, (char *)data, datalen*sizeof(uint32_t)); - - pktlen = (char *)p + datalen*sizeof(uint32_t) - (char *)&pkt; - - memcpy ((char *)NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE, (char *)&pkt, pktlen); + memcpy(payload, &pkt, sizeof(pkt)); + memcpy(payload + sizeof(pkt), data, datalen * sizeof(uint32_t)); if (rpc_prog == PROG_PORTMAP) sport = SUNRPC_PORT; else if (rpc_prog == PROG_MOUNT) - sport = NfsSrvMountPort; + sport = nfs_server_mount_port; else - sport = NfsSrvNfsPort; + sport = nfs_server_nfs_port; - NetSendUDPPacket (NetServerEther, NfsServerIP, sport, NfsOurPort, pktlen); + nfs_con->udp->uh_dport = htons(sport); + ret = net_udp_send(nfs_con, sizeof(pkt) + datalen * sizeof(uint32_t)); + + return ret; } /************************************************************************** RPC_LOOKUP - Lookup RPC Port numbers **************************************************************************/ -static void -rpc_lookup_req (int prog, int ver) +static void rpc_lookup_req(int prog, int ver) { uint32_t data[16]; @@ -181,14 +244,13 @@ rpc_lookup_req (int prog, int ver) data[6] = htonl(17); /* IP_UDP */ data[7] = 0; - rpc_req (PROG_PORTMAP, PORTMAP_GETPORT, data, 8); + rpc_req(PROG_PORTMAP, PORTMAP_GETPORT, data, 8); } /************************************************************************** NFS_MOUNT - Mount an NFS Filesystem **************************************************************************/ -static void -nfs_mount_req (char *path) +static void nfs_mount_req(char *path) { uint32_t data[1024]; uint32_t *p; @@ -198,39 +260,38 @@ nfs_mount_req (char *path) pathlen = strlen (path); p = &(data[0]); - p = (uint32_t *)rpc_add_credentials((long *)p); + p = rpc_add_credentials(p); *p++ = htonl(pathlen); - if (pathlen & 3) *(p + pathlen / 4) = 0; + if (pathlen & 3) + *(p + pathlen / 4) = 0; memcpy (p, path, pathlen); p += (pathlen + 3) / 4; - len = (uint32_t *)p - (uint32_t *)&(data[0]); + len = p - &(data[0]); - rpc_req (PROG_MOUNT, MOUNT_ADDENTRY, data, len); + rpc_req(PROG_MOUNT, MOUNT_ADDENTRY, data, len); } /************************************************************************** NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server **************************************************************************/ -static void -nfs_umountall_req (void) +static void nfs_umountall_req(void) { uint32_t data[1024]; uint32_t *p; int len; - if ((NfsSrvMountPort == -1) || (!fs_mounted)) { + if (nfs_server_mount_port < 0) /* Nothing mounted, nothing to umount */ return; - } p = &(data[0]); - p = (uint32_t *)rpc_add_credentials ((long *)p); + p = rpc_add_credentials(p); - len = (uint32_t *)p - (uint32_t *)&(data[0]); + len = p - &(data[0]); - rpc_req (PROG_MOUNT, MOUNT_UMOUNTALL, data, len); + rpc_req(PROG_MOUNT, MOUNT_UMOUNTALL, data, len); } /*************************************************************************** @@ -240,29 +301,27 @@ nfs_umountall_req (void) * In case of successful readlink(), the dirname is manipulated, * so that inside the nfs() function a recursion can be done. **************************************************************************/ -static void -nfs_readlink_req (void) +static void nfs_readlink_req(void) { uint32_t data[1024]; uint32_t *p; int len; p = &(data[0]); - p = (uint32_t *)rpc_add_credentials ((long *)p); + p = rpc_add_credentials(p); memcpy (p, filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); - len = (uint32_t *)p - (uint32_t *)&(data[0]); + len = p - &(data[0]); - rpc_req (PROG_NFS, NFS_READLINK, data, len); + rpc_req(PROG_NFS, NFS_READLINK, data, len); } /************************************************************************** NFS_LOOKUP - Lookup Pathname **************************************************************************/ -static void -nfs_lookup_req (char *fname) +static void nfs_lookup_req(char *fname) { uint32_t data[1024]; uint32_t *p; @@ -272,32 +331,32 @@ nfs_lookup_req (char *fname) fnamelen = strlen (fname); p = &(data[0]); - p = (uint32_t *)rpc_add_credentials ((long *)p); + p = rpc_add_credentials(p); memcpy (p, dirfh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); *p++ = htonl(fnamelen); - if (fnamelen & 3) *(p + fnamelen / 4) = 0; + if (fnamelen & 3) + *(p + fnamelen / 4) = 0; memcpy (p, fname, fnamelen); p += (fnamelen + 3) / 4; - len = (uint32_t *)p - (uint32_t *)&(data[0]); + len = p - &(data[0]); - rpc_req (PROG_NFS, NFS_LOOKUP, data, len); + rpc_req(PROG_NFS, NFS_LOOKUP, data, len); } /************************************************************************** NFS_READ - Read File on NFS Server **************************************************************************/ -static void -nfs_read_req (int offset, int readlen) +static void nfs_read_req(int offset, int readlen) { uint32_t data[1024]; uint32_t *p; int len; p = &(data[0]); - p = (uint32_t *)rpc_add_credentials ((long *)p); + p = rpc_add_credentials(p); memcpy (p, filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); @@ -305,238 +364,194 @@ nfs_read_req (int offset, int readlen) *p++ = htonl(readlen); *p++ = 0; - len = (uint32_t *)p - (uint32_t *)&(data[0]); + len = p - &(data[0]); - rpc_req (PROG_NFS, NFS_READ, data, len); + rpc_req(PROG_NFS, NFS_READ, data, len); } /************************************************************************** RPC request dispatcher **************************************************************************/ - -static void -NfsSend (void) +static void nfs_send(void) { -#ifdef NFS_DEBUG - printf ("%s\n", __FUNCTION__); -#endif + debug("%s\n", __func__); - switch (NfsState) { + switch (nfs_state) { case STATE_PRCLOOKUP_PROG_MOUNT_REQ: - rpc_lookup_req (PROG_MOUNT, 1); + rpc_lookup_req(PROG_MOUNT, 1); break; case STATE_PRCLOOKUP_PROG_NFS_REQ: - rpc_lookup_req (PROG_NFS, 2); + rpc_lookup_req(PROG_NFS, 2); break; case STATE_MOUNT_REQ: - nfs_mount_req (nfs_path); + nfs_mount_req(nfs_path); break; case STATE_UMOUNT_REQ: - nfs_umountall_req (); + nfs_umountall_req(); break; case STATE_LOOKUP_REQ: - nfs_lookup_req (nfs_filename); + nfs_lookup_req(nfs_filename); break; case STATE_READ_REQ: - nfs_read_req (nfs_offset, nfs_len); + nfs_read_req(nfs_offset, NFS_READ_SIZE); break; case STATE_READLINK_REQ: - nfs_readlink_req (); + nfs_readlink_req(); break; } } -/************************************************************************** -Handlers for the reply from server -**************************************************************************/ - -static int -rpc_lookup_reply (int prog, uchar *pkt, unsigned len) +static int rpc_check_reply(unsigned char *pkt, int isnfs) { - struct rpc_t rpc_pkt; + uint32_t *data; + int nfserr; + struct rpc_reply rpc; - memcpy ((unsigned char *)&rpc_pkt, pkt, len); + memcpy(&rpc, pkt, sizeof(rpc)); -#ifdef NFS_DEBUG - printf ("%s\n", __FUNCTION__); -#endif + if (ntohl(rpc.id) != rpc_id) + return -EINVAL; - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) - return -1; - - if (rpc_pkt.u.reply.rstatus || - rpc_pkt.u.reply.verifier || - rpc_pkt.u.reply.astatus || - rpc_pkt.u.reply.astatus) { - return -1; + if (rpc.rstatus || + rpc.verifier || + rpc.astatus ) { + return -EINVAL; } + if (!isnfs) + return 0; + + data = (uint32_t *)(pkt + sizeof(struct rpc_reply)); + nfserr = ntohl(net_read_uint32(data)); + + debug("%s: state: %d, err %d\n", __func__, nfs_state, -nfserr); + + if (nfserr <= 30) + /* These nfs codes correspond with those in errno.h */ + return -nfserr; + if (nfserr == NFSERR_STALE) + return -ESTALE; + + return -EINVAL; +} + +static int rpc_lookup_reply(int prog, unsigned char *pkt, unsigned len) +{ + uint32_t port; + int ret; + + ret = rpc_check_reply(pkt, 0); + if (ret) + return ret; + + port = net_read_uint32((uint32_t *)(pkt + sizeof(struct rpc_reply))); switch (prog) { case PROG_MOUNT: - NfsSrvMountPort = ntohl(rpc_pkt.u.reply.data[0]); + nfs_server_mount_port = ntohl(port); break; case PROG_NFS: - NfsSrvNfsPort = ntohl(rpc_pkt.u.reply.data[0]); + nfs_server_nfs_port = ntohl(port); break; } return 0; } -static int -nfs_mount_reply (uchar *pkt, unsigned len) +static int nfs_mount_reply(unsigned char *pkt, unsigned len) { - struct rpc_t rpc_pkt; + int ret; -#ifdef NFS_DEBUG - printf ("%s\n", __FUNCTION__); -#endif + ret = rpc_check_reply(pkt, 1); + if (ret) + return ret; - memcpy ((unsigned char *)&rpc_pkt, pkt, len); - - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) - return -1; - - if (rpc_pkt.u.reply.rstatus || - rpc_pkt.u.reply.verifier || - rpc_pkt.u.reply.astatus || - rpc_pkt.u.reply.data[0]) { - return -1; - } - - fs_mounted = 1; - memcpy (dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE); + memcpy(dirfh, pkt + sizeof(struct rpc_reply) + 4, NFS_FHSIZE); return 0; } -static int -nfs_umountall_reply (uchar *pkt, unsigned len) +static int nfs_umountall_reply(unsigned char *pkt, unsigned len) { - struct rpc_t rpc_pkt; + int ret; -#ifdef NFS_DEBUG - printf ("%s\n", __FUNCTION__); -#endif + ret = rpc_check_reply(pkt, 0); + if (ret) + return ret; - memcpy ((unsigned char *)&rpc_pkt, pkt, len); - - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) - return -1; - - if (rpc_pkt.u.reply.rstatus || - rpc_pkt.u.reply.verifier || - rpc_pkt.u.reply.astatus) { - return -1; - } - - fs_mounted = 0; - memset (dirfh, 0, sizeof(dirfh)); + memset(dirfh, 0, sizeof(dirfh)); return 0; } -static int -nfs_lookup_reply (uchar *pkt, unsigned len) +static int nfs_lookup_reply(unsigned char *pkt, unsigned len) { - struct rpc_t rpc_pkt; + int ret; -#ifdef NFS_DEBUG - printf ("%s\n", __FUNCTION__); -#endif + ret = rpc_check_reply(pkt, 1); + if (ret) + return ret; - memcpy ((unsigned char *)&rpc_pkt, pkt, len); - - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) - return -1; - - if (rpc_pkt.u.reply.rstatus || - rpc_pkt.u.reply.verifier || - rpc_pkt.u.reply.astatus || - rpc_pkt.u.reply.data[0]) { - return -1; - } - - memcpy (filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE); + memcpy(filefh, pkt + sizeof(struct rpc_reply) + 4, NFS_FHSIZE); return 0; } -static int -nfs_readlink_reply (uchar *pkt, unsigned len) +static int nfs_readlink_reply(unsigned char *pkt, unsigned len) { - struct rpc_t rpc_pkt; + uint32_t *data; + char *path; int rlen; + int ret; -#ifdef NFS_DEBUG - printf ("%s\n", __FUNCTION__); -#endif + ret = rpc_check_reply(pkt, 1); + if (ret) + return ret; - memcpy ((unsigned char *)&rpc_pkt, pkt, len); + data = (uint32_t *)(pkt + sizeof(struct rpc_reply)); - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) - return -1; + data++; - if (rpc_pkt.u.reply.rstatus || - rpc_pkt.u.reply.verifier || - rpc_pkt.u.reply.astatus || - rpc_pkt.u.reply.data[0]) { - return -1; - } + rlen = ntohl(net_read_uint32(data)); /* new path length */ - rlen = ntohl (rpc_pkt.u.reply.data[1]); /* new path length */ + data++; + path = (char *)data; - if (*((char *)&(rpc_pkt.u.reply.data[2])) != '/') { - int pathlen; - strcat (nfs_path, "/"); - pathlen = strlen(nfs_path); - memcpy (nfs_path+pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen); - nfs_path[pathlen+rlen+1] = 0; + if (*path != '/') { + strcat(nfs_path, "/"); + strncat(nfs_path, path, rlen); } else { - memcpy (nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen); + memcpy(nfs_path, path, rlen); nfs_path[rlen] = 0; } return 0; } -static int -nfs_read_reply (uchar *pkt, unsigned len) +static int nfs_read_reply(unsigned char *pkt, unsigned len) { - struct rpc_t rpc_pkt; int rlen; + uint32_t *data; + int ret; -#ifdef NFS_DEBUG_nop - printf ("%s\n", __FUNCTION__); -#endif + debug("%s\n", __func__); - memcpy ((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply)); + ret = rpc_check_reply(pkt, 1); + if (ret) + return ret; - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) - return -1; + data = (uint32_t *)(pkt + sizeof(struct rpc_reply)); - if (rpc_pkt.u.reply.rstatus || - rpc_pkt.u.reply.verifier || - rpc_pkt.u.reply.astatus || - rpc_pkt.u.reply.data[0]) { - if (rpc_pkt.u.reply.rstatus) { - return -9999; - } - if (rpc_pkt.u.reply.astatus) { - return -9999; - } - return -ntohl(rpc_pkt.u.reply.data[0]);; - } - - if ((nfs_offset!=0) && !((nfs_offset) % (NFS_READ_SIZE/2*10*HASHES_PER_LINE))) { + if (nfs_offset && !((nfs_offset) % (NFS_READ_SIZE / 2 * 10 * HASHES_PER_LINE))) puts ("\n\t "); - } - if (!(nfs_offset % ((NFS_READ_SIZE/2)*10))) { + if (!(nfs_offset % ((NFS_READ_SIZE / 2) * 10))) putchar ('#'); - } - rlen = ntohl(rpc_pkt.u.reply.data[18]); - if ( store_block ((uchar *)pkt+sizeof(rpc_pkt.u.reply), nfs_offset, rlen) ) - return -9999; + rlen = ntohl(net_read_uint32(data + 18)); + + ret = write(net_store_fd, (char *)(data + 19), rlen); + if (ret < 0) { + perror("write"); + return ret; + } return rlen; } @@ -545,170 +560,116 @@ nfs_read_reply (uchar *pkt, unsigned len) Interfaces of barebox **************************************************************************/ -static void -NfsTimeout (void) +static void nfs_handler(char *packet, unsigned len) { - puts ("Timeout\n"); - NetState = NETLOOP_FAIL; - return; -} + char *pkt = net_eth_to_udp_payload(packet); + int ret; -static void -NfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len) -{ - int rlen; + debug("%s\n", __func__); -#ifdef NFS_DEBUG - printf ("%s\n", __FUNCTION__); -#endif - - if (dest != NfsOurPort) return; - - switch (NfsState) { + switch (nfs_state) { case STATE_PRCLOOKUP_PROG_MOUNT_REQ: - rpc_lookup_reply (PROG_MOUNT, pkt, len); - NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ; - NfsSend (); + ret = rpc_lookup_reply(PROG_MOUNT, pkt, len); + if (ret) + goto err_out; + nfs_state = STATE_PRCLOOKUP_PROG_NFS_REQ; break; case STATE_PRCLOOKUP_PROG_NFS_REQ: - rpc_lookup_reply (PROG_NFS, pkt, len); - NfsState = STATE_MOUNT_REQ; - NfsSend (); + ret = rpc_lookup_reply(PROG_NFS, pkt, len); + if (ret) + goto err_out; + nfs_state = STATE_MOUNT_REQ; break; case STATE_MOUNT_REQ: - if (nfs_mount_reply(pkt, len)) { - puts ("*** ERROR: Cannot mount\n"); - /* just to be sure... */ - NfsState = STATE_UMOUNT_REQ; - NfsSend (); - } else { - NfsState = STATE_LOOKUP_REQ; - NfsSend (); - } + ret = nfs_mount_reply(pkt, len); + if (ret) + goto err_out; + + nfs_state = STATE_LOOKUP_REQ; break; case STATE_UMOUNT_REQ: - if (nfs_umountall_reply(pkt, len)) { - puts ("*** ERROR: Cannot umount\n"); - NetState = NETLOOP_FAIL; - } else { - puts ("\ndone\n"); - NetState = NfsDownloadState; - } - break; + ret = nfs_umountall_reply(pkt, len); + if (ret) + nfs_err = ret; + nfs_state = STATE_DONE; + return; case STATE_LOOKUP_REQ: - if (nfs_lookup_reply(pkt, len)) { - puts ("*** ERROR: File lookup fail\n"); - NfsState = STATE_UMOUNT_REQ; - NfsSend (); - } else { - NfsState = STATE_READ_REQ; - nfs_offset = 0; - nfs_len = NFS_READ_SIZE; - NfsSend (); - } + ret = nfs_lookup_reply(pkt, len); + if (ret) + goto err_umount; + + nfs_state = STATE_READ_REQ; + nfs_offset = 0; break; case STATE_READLINK_REQ: - if (nfs_readlink_reply(pkt, len)) { - puts ("*** ERROR: Symlink fail\n"); - NfsState = STATE_UMOUNT_REQ; - NfsSend (); - } else { -#ifdef NFS_DEBUG - printf ("Symlink --> %s\n", nfs_path); -#endif - nfs_filename = basename (nfs_path); - nfs_path = dirname (nfs_path); + ret = nfs_readlink_reply(pkt, len); + if (ret) + goto err_umount; - NfsState = STATE_MOUNT_REQ; - NfsSend (); - } + debug("Symlink --> %s\n", nfs_path); + + nfs_filename = basename(nfs_path); + nfs_path = dirname(nfs_path); + + nfs_state = STATE_MOUNT_REQ; break; case STATE_READ_REQ: - rlen = nfs_read_reply (pkt, len); - NetSetTimeout (NFS_TIMEOUT * SECOND, NfsTimeout); - if (rlen > 0) { - nfs_offset += rlen; - NfsSend (); - } - else if ((rlen == -NFSERR_ISDIR)||(rlen == -NFSERR_INVAL)) { + ret = nfs_read_reply(pkt, len); + nfs_timer_start = get_time_ns(); + if (ret > 0) + nfs_offset += ret; + else if (ret == -EISDIR || ret == -EINVAL) /* symbolic link */ - NfsState = STATE_READLINK_REQ; - NfsSend (); - } else { - if ( ! rlen ) NfsDownloadState = NETLOOP_SUCCESS; - NfsState = STATE_UMOUNT_REQ; - NfsSend (); - } + nfs_state = STATE_READLINK_REQ; + else + goto err_umount; + break; } + + nfs_send(); + + return; + +err_umount: + nfs_state = STATE_UMOUNT_REQ; + nfs_err = ret; + nfs_send(); + return; + +err_out: + nfs_state = STATE_DONE; + nfs_err = ret; } - -void -NfsStart (char *p) +static void nfs_start(char *p) { -#ifdef NFS_DEBUG - printf ("%s\n", __FUNCTION__); -#endif - NfsDownloadState = NETLOOP_FAIL; + debug("%s\n", __func__); - NfsServerIP = NetServerIP; nfs_path = (char *)nfs_path_buff; - if (nfs_path == NULL) { - NetState = NETLOOP_FAIL; - puts ("*** ERROR: Fail allocate memory\n"); - return; - } - - strcpy (nfs_path, p); + strcpy(nfs_path, p); nfs_filename = basename (nfs_path); nfs_path = dirname (nfs_path); -#if defined(CONFIG_NET_MULTI) - printf ("Using %s device\n", eth_get_name()); -#endif + printf("\nFilename '%s/%s'.\nLoading: ", nfs_path, nfs_filename); - puts ("File transfer via NFS from server "); print_IPaddr (NfsServerIP); - puts ("; our IP address is "); print_IPaddr (NetOurIP); + nfs_timer_start = get_time_ns(); - /* Check if we need to send across this subnet */ - if (NetOurGatewayIP && NetOurSubnetMask) { - IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; - IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask; + nfs_state = STATE_PRCLOOKUP_PROG_MOUNT_REQ; - if (OurNet != ServerNet) { - puts ("; sending through gateway "); - print_IPaddr (NetOurGatewayIP) ; - } - } - printf ("\nFilename '%s/%s'.", nfs_path, nfs_filename); - - NetSetTimeout (NFS_TIMEOUT * SECOND, NfsTimeout); - NetSetHandler (NfsHandler); - - NfsTimeoutCount = 0; - NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ; - - /*FIX ME !!!*/ - NfsOurPort = 1000; - - /* zero out server ether in case the server ip has changed */ - memset (NetServerEther, 0, 6); - - NfsSend (); + nfs_send(); } static int do_nfs(struct command *cmdtp, int argc, char *argv[]) { - int rcode = 0; char *localfile; char *remotefile; @@ -728,23 +689,38 @@ static int do_nfs(struct command *cmdtp, int argc, char *argv[]) return 1; } - if (NetLoopInit(NFS) < 0) - goto out; + nfs_con = net_udp_new(net_get_serverip(), 0, nfs_handler); + if (IS_ERR(nfs_con)) { + nfs_err = PTR_ERR(nfs_con); + goto err_udp; + } + net_udp_bind(nfs_con, 1000); - NfsStart(remotefile); + nfs_err = 0; - rcode = NetLoop(); - if (rcode < 0) { - rcode = 1; - goto out; + nfs_start(remotefile); + + while (nfs_state != STATE_DONE) { + if (ctrlc()) { + nfs_err = -EINTR; + break; + } + net_poll(); + if (is_timeout(nfs_timer_start, NFS_TIMEOUT * SECOND)) + break; } - /* NetLoop ok, update environment */ - netboot_update_env(); - -out: + net_unregister(nfs_con); +err_udp: close(net_store_fd); - return rcode; + if (nfs_err) { + printf("NFS failed: %s\n", strerror(-nfs_err)); + unlink(localfile); + } + + printf("\n"); + + return nfs_err == 0 ? 0 : 1; } static const __maybe_unused char cmd_nfs_help[] = From 663a6269f26c3310b1c56810dbddc50f9d9280af Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 15:54:22 +0200 Subject: [PATCH 18/65] net: consider rarp support as outdated. Remove it It is disabled in all defconfigs and probably broken for longer. Remove it. Signed-off-by: Sascha Hauer --- net/Kconfig | 4 -- net/Makefile | 1 - net/rarp.c | 101 --------------------------------------------------- 3 files changed, 106 deletions(-) delete mode 100644 net/rarp.c diff --git a/net/Kconfig b/net/Kconfig index cca2b0038..a110beceb 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -7,10 +7,6 @@ config NET_DHCP bool prompt "dhcp support" -config NET_RARP - bool - prompt "rarp protocol support" - config NET_NFS bool prompt "nfs support" diff --git a/net/Makefile b/net/Makefile index 0ffc8959c..bba6f0e46 100644 --- a/net/Makefile +++ b/net/Makefile @@ -2,6 +2,5 @@ obj-$(CONFIG_NET_DHCP) += dhcp.o obj-$(CONFIG_NET) += eth.o obj-$(CONFIG_NET) += net.o obj-$(CONFIG_NET_NFS) += nfs.o -obj-$(CONFIG_NET_RARP) += rarp.o obj-$(CONFIG_NET_TFTP) += tftp.o obj-$(CONFIG_NET_PING) += ping.o diff --git a/net/rarp.c b/net/rarp.c deleted file mode 100644 index 24818f8db..000000000 --- a/net/rarp.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * (C) Copyright 2000-2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * 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 -#include -#include -#include -#include "nfs.h" -#include "rarp.h" -#include "tftp.h" - -#define TIMEOUT 5 /* Seconds before trying BOOTP again */ -#ifndef CONFIG_NET_RETRY_COUNT -# define TIMEOUT_COUNT 5 /* # of timeouts before giving up */ -#else -# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) -#endif - - -int RarpTry; - -/* - * Handle a RARP received packet. - */ -static void -RarpHandler(uchar * dummi0, unsigned dummi1, unsigned dummi2, unsigned dummi3) -{ -#ifdef DEBUG - puts ("Got good RARP\n"); -#endif - NetState = NETLOOP_SUCCESS; -} - - -/* - * Timeout on BOOTP request. - */ -static void -RarpTimeout(void) -{ - NetSetTimeout (TIMEOUT * SECOND, RarpTimeout); - RarpRequest (); -} - - -void -RarpRequest (void) -{ - int i; - uchar *pkt; - ARP_t * rarp; - - NetOurIP = 0; - RarpTry = 0; - - printf("RARP broadcast %d\n", ++RarpTry); - pkt = NetTxPacket; - - pkt += NetSetEther(pkt, NetBcastAddr, PROT_RARP); - - rarp = (ARP_t *)pkt; - - rarp->ar_hrd = htons (ARP_ETHER); - rarp->ar_pro = htons (PROT_IP); - rarp->ar_hln = 6; - rarp->ar_pln = 4; - rarp->ar_op = htons (RARPOP_REQUEST); - memcpy (&rarp->ar_data[0], NetOurEther, 6); /* source ET addr */ - memcpy (&rarp->ar_data[6], &NetOurIP, 4); /* source IP addr */ - memcpy (&rarp->ar_data[10], NetOurEther, 6); /* dest ET addr = source ET addr ??*/ - /* dest. IP addr set to broadcast */ - for (i = 0; i <= 3; i++) { - rarp->ar_data[16 + i] = 0xff; - } - - NetSendPacket(NetTxPacket, (pkt - NetTxPacket) + ARP_HDR_SIZE); - - NetSetTimeout(TIMEOUT * SECOND, RarpTimeout); - NetSetHandler(RarpHandler); -} - From c70689d72780cf0385a361bd754347c5e4a1ba97 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 15:59:16 +0200 Subject: [PATCH 19/65] network drivers: call net_receive directly instead of NetReceive Signed-off-by: Sascha Hauer --- drivers/net/at91_ether.c | 2 +- drivers/net/cs8900.c | 2 +- drivers/net/dm9000.c | 2 +- drivers/net/ep93xx.c | 4 ++-- drivers/net/fec_imx.c | 2 +- drivers/net/fec_mpc5200.c | 2 +- drivers/net/macb.c | 2 +- drivers/net/netx_eth.c | 2 +- drivers/net/smc91111.c | 2 +- drivers/net/smc911x.c | 2 +- drivers/net/tap.c | 2 +- drivers/net/usb/asix.c | 2 +- drivers/net/usb/usbnet.c | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/at91_ether.c b/drivers/net/at91_ether.c index a2d15948f..3c4f4b053 100644 --- a/drivers/net/at91_ether.c +++ b/drivers/net/at91_ether.c @@ -190,7 +190,7 @@ static int at91rm9200_eth_rx (struct eth_device *edev) return 0; size = rbfp->size & RBF_SIZE; - NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size); + net_receive((volatile uchar *) (rbfp->addr & RBF_ADDR), size); rbfp->addr &= ~RBF_OWNER; if (rbfp->addr & RBF_WRAP) diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c index 64366acb1..812087768 100644 --- a/drivers/net/cs8900.c +++ b/drivers/net/cs8900.c @@ -309,7 +309,7 @@ static int cs8900_recv(struct eth_device *dev) if (len & 1) { *addr++ = readw(priv->regs + CS8900_RTDATA0); } - NetReceive(NetRxPackets[0], len); + net_receive(NetRxPackets[0], len); return len; } diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 77c771bf3..2062c6669 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -416,7 +416,7 @@ static int dm9000_eth_rx (struct eth_device *edev) /* Pass to upper layer */ debug("passing packet to upper layer\n"); - NetReceive(NetRxPackets[0], RxLen); + net_receive(NetRxPackets[0], RxLen); return RxLen; } return 0; diff --git a/drivers/net/ep93xx.c b/drivers/net/ep93xx.c index e91a92ef4..c6c46710d 100644 --- a/drivers/net/ep93xx.c +++ b/drivers/net/ep93xx.c @@ -335,9 +335,9 @@ static int ep93xx_eth_rcv_packet(struct eth_device *edev) * protocol stack. We track the total number of * bytes in the frame (nbytes_frame) which will be * used when we pass the data off to the protocol - * layer via NetReceive(). + * layer via net_receive(). */ - NetReceive((uchar *)priv->rx_dq.current->word1, + net_receive((uchar *)priv->rx_dq.current->word1, RX_STATUS_FRAME_LEN(priv->rx_sq.current)); pr_debug("reporting %d bytes...\n", RX_STATUS_FRAME_LEN(priv->rx_sq.current)); diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 5e8e5ca19..40a754370 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -515,7 +515,7 @@ static int fec_recv(struct eth_device *dev) */ frame = phys_to_virt(readl(&rbd->data_pointer)); frame_length = readw(&rbd->data_length) - 4; - NetReceive(frame->data, frame_length); + net_receive(frame->data, frame_length); len = frame_length; } else { if (bd_status & FEC_RBD_ERR) { diff --git a/drivers/net/fec_mpc5200.c b/drivers/net/fec_mpc5200.c index d803ddf60..ce9a21d15 100644 --- a/drivers/net/fec_mpc5200.c +++ b/drivers/net/fec_mpc5200.c @@ -645,7 +645,7 @@ static int mpc5xxx_fec_recv(struct eth_device *dev) */ memcpy(buff, frame->head, 14); memcpy(buff + 14, frame->data, frame_length); - NetReceive(buff, frame_length); + net_receive(buff, frame_length); len = frame_length; } /* diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 1bb833ae6..4feeed0ba 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -190,7 +190,7 @@ static int macb_recv(struct eth_device *edev) buffer = (void *)NetRxPackets[0]; } - NetReceive(buffer, length); + net_receive(buffer, length); if (++rx_tail >= CFG_MACB_RX_RING_SIZE) rx_tail = 0; reclaim_rx_buffers(macb, rx_tail); diff --git a/drivers/net/netx_eth.c b/drivers/net/netx_eth.c index 673007aca..f2d7b4ae8 100644 --- a/drivers/net/netx_eth.c +++ b/drivers/net/netx_eth.c @@ -111,7 +111,7 @@ static int netx_eth_rx (struct eth_device *edev) /* get data */ memcpy((void*)NetRxPackets[0], (void *)(SRAM_BASE(seg) + frameno * 1560), len); /* pass to barebox */ - NetReceive(NetRxPackets[0], len); + net_receive(NetRxPackets[0], len); PFIFO_REG(PFIFO_BASE(EMPTY_PTR_FIFO(xcno))) = FIFO_PTR_SEGMENT(seg) | diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c index 9b41c6725..58ebaa9b1 100644 --- a/drivers/net/smc91111.c +++ b/drivers/net/smc91111.c @@ -1156,7 +1156,7 @@ static int smc91c111_eth_rx(struct eth_device *edev) if (!is_error) { /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[0], packet_length); + net_receive(NetRxPackets[0], packet_length); return packet_length; } diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 4a5e7b614..ca320d5a9 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -668,7 +668,7 @@ static int smc911x_eth_rx(struct eth_device *edev) ": dropped bad packet. Status: 0x%08x\n", status); else - NetReceive(NetRxPackets[0], pktlen); + net_receive(NetRxPackets[0], pktlen); } return 0; diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 8673436ca..522a9f11f 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -48,7 +48,7 @@ int tap_eth_rx (struct eth_device *edev) length = linux_read_nonblock(priv->fd, NetRxPackets[0], PKTSIZE); if (length > 0) - NetReceive(NetRxPackets[0], length); + net_receive(NetRxPackets[0], length); return 0; } diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index e44ce67b6..fc4146fdb 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -425,7 +425,7 @@ static int asix_rx_fixup(struct usbnet *dev, void *buf, int len) return 0; } - NetReceive(buf, size); + net_receive(buf, size); buf += ((size + 1) & 0xfffe); len -= ((size + 1) & 0xfffe); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 123cc3b30..b0e309096 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -137,7 +137,7 @@ static int usbnet_recv(struct eth_device *edev) if (info->rx_fixup) return info->rx_fixup(dev, rx_buf, alen); else - NetReceive(rx_buf, alen); + net_receive(rx_buf, alen); } return 0; From 57e1fc33bda4f4f215bdaa7ebb2a79cc5aac3799 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Jun 2010 16:04:52 +0200 Subject: [PATCH 20/65] net: remove old network stack All network commands now use the new stack, so remove the old one. Signed-off-by: Sascha Hauer --- commands/net.c | 42 --- include/net.h | 359 +----------------- net/net.c | 964 +++---------------------------------------------- 3 files changed, 59 insertions(+), 1306 deletions(-) diff --git a/commands/net.c b/commands/net.c index 949963ffd..938463c7c 100644 --- a/commands/net.c +++ b/commands/net.c @@ -35,48 +35,6 @@ #include #include -void netboot_update_env(void) -{ - struct eth_device *eth_current = eth_get_current(); - char tmp[22]; - IPaddr_t net_gateway_ip = NetOurGatewayIP; - IPaddr_t net_ip = NetOurIP; - IPaddr_t net_server_ip = NetServerIP; - IPaddr_t netmask = NetOurSubnetMask; - - if (net_gateway_ip) - dev_set_param_ip(ð_current->dev, "gateway", net_gateway_ip); - - if (netmask) - dev_set_param_ip(ð_current->dev, "netmask", netmask); - - - if (NetOurHostName[0]) - setenv ("hostname", NetOurHostName); - - if (NetOurRootPath[0]) - setenv ("rootpath", NetOurRootPath); - - if (net_ip) - dev_set_param_ip(ð_current->dev, "ipaddr", net_ip); - - if (net_server_ip) - dev_set_param_ip(ð_current->dev, "serverip", net_server_ip); - - if (NetOurDNSIP) { - ip_to_string (NetOurDNSIP, tmp); - setenv ("dnsip", tmp); - } -#ifdef CONFIG_BOOTP_DNS2 - if (NetOurDNS2IP) { - ip_to_string (NetOurDNS2IP, tmp); - setenv ("dnsip2", tmp); - } -#endif - if (NetOurNISDomain[0]) - setenv ("domain", NetOurNISDomain); -} - #ifdef CONFIG_NET_RARP extern void RarpRequest(void); diff --git a/include/net.h b/include/net.h index 0ee7ecb8a..a2863d082 100644 --- a/include/net.h +++ b/include/net.h @@ -19,39 +19,8 @@ #include /* for nton* / ntoh* stuff */ -/* - * The number of receive packet buffers, and the required packet buffer - * alignment in memory. - * - */ - -#ifdef CFG_RX_ETH_BUFFER -# define PKTBUFSRX CFG_RX_ETH_BUFFER -#else -# define PKTBUFSRX 4 -#endif - -#define PKTALIGN 32 - -/* - * The current receive packet handler. Called with a pointer to the - * application packet, and a protocol type (PORT_BOOTPC or PORT_TFTP). - * All other packets are dealt with without calling the handler. - */ -typedef void rxhand_f(uchar *, unsigned, unsigned, unsigned); - -/* - * A timeout handler. Called after time interval has expired. - */ -typedef void thand_f(void); - -#define NAMESIZE 16 - -enum eth_state_t { - ETH_STATE_INIT, - ETH_STATE_PASSIVE, - ETH_STATE_ACTIVE -}; +/* The number of receive packet buffers */ +#define PKTBUFSRX 4 struct device_d; @@ -92,328 +61,6 @@ int eth_rx(void); /* Check for received packets */ void eth_halt(void); /* stop SCC */ char *eth_get_name(void); /* get name of current device */ - -/**********************************************************************/ -/* - * Protocol headers. - */ - -/* - * Ethernet header - */ -typedef struct { - uchar et_dest[6]; /* Destination node */ - uchar et_src[6]; /* Source node */ - ushort et_protlen; /* Protocol or length */ - uchar et_dsap; /* 802 DSAP */ - uchar et_ssap; /* 802 SSAP */ - uchar et_ctl; /* 802 control */ - uchar et_snap1; /* SNAP */ - uchar et_snap2; - uchar et_snap3; - ushort et_prot; /* 802 protocol */ -} Ethernet_t; - -#define ETHER_HDR_SIZE 14 /* Ethernet header size */ -#define E802_HDR_SIZE 22 /* 802 ethernet header size */ - -/* - * Ethernet header - */ -typedef struct { - uchar vet_dest[6]; /* Destination node */ - uchar vet_src[6]; /* Source node */ - ushort vet_vlan_type; /* PROT_VLAN */ - ushort vet_tag; /* TAG of VLAN */ - ushort vet_type; /* protocol type */ -} VLAN_Ethernet_t; - -#define VLAN_ETHER_HDR_SIZE 18 /* VLAN Ethernet header size */ - -#define PROT_IP 0x0800 /* IP protocol */ -#define PROT_ARP 0x0806 /* IP ARP protocol */ -#define PROT_RARP 0x8035 /* IP ARP protocol */ -#define PROT_VLAN 0x8100 /* IEEE 802.1q protocol */ - -#define IPPROTO_ICMP 1 /* Internet Control Message Protocol */ -#define IPPROTO_UDP 17 /* User Datagram Protocol */ - -/* - * Internet Protocol (IP) header. - */ -typedef struct { - uchar ip_hl_v; /* header length and version */ - uchar ip_tos; /* type of service */ - ushort ip_len; /* total length */ - ushort ip_id; /* identification */ - ushort ip_off; /* fragment offset field */ - uchar ip_ttl; /* time to live */ - uchar ip_p; /* protocol */ - ushort ip_sum; /* checksum */ - IPaddr_t ip_src; /* Source IP address */ - IPaddr_t ip_dst; /* Destination IP address */ - ushort udp_src; /* UDP source port */ - ushort udp_dst; /* UDP destination port */ - ushort udp_len; /* Length of UDP packet */ - ushort udp_xsum; /* Checksum */ -} IP_t; - -#define IP_HDR_SIZE_NO_UDP (sizeof (IP_t) - 8) -#define IP_HDR_SIZE (sizeof (IP_t)) - - -/* - * Address Resolution Protocol (ARP) header. - */ -typedef struct -{ - ushort ar_hrd; /* Format of hardware address */ -# define ARP_ETHER 1 /* Ethernet hardware address */ - ushort ar_pro; /* Format of protocol address */ - uchar ar_hln; /* Length of hardware address */ - uchar ar_pln; /* Length of protocol address */ - ushort ar_op; /* Operation */ -# define ARPOP_REQUEST 1 /* Request to resolve address */ -# define ARPOP_REPLY 2 /* Response to previous request */ - -# define RARPOP_REQUEST 3 /* Request to resolve address */ -# define RARPOP_REPLY 4 /* Response to previous request */ - - /* - * The remaining fields are variable in size, according to - * the sizes above, and are defined as appropriate for - * specific hardware/protocol combinations. - */ - uchar ar_data[0]; -} ARP_t; - -/* - * ICMP stuff (just enough to handle (host) redirect messages) - */ -#define ICMP_ECHO_REPLY 0 /* Echo reply */ -#define ICMP_REDIRECT 5 /* Redirect (change route) */ -#define ICMP_ECHO_REQUEST 8 /* Echo request */ - -/* Codes for REDIRECT. */ -#define ICMP_REDIR_NET 0 /* Redirect Net */ -#define ICMP_REDIR_HOST 1 /* Redirect Host */ - -typedef struct { - uchar type; - uchar code; - ushort checksum; - union { - struct { - ushort id; - ushort sequence; - } echo; - ulong gateway; - struct { - ushort __unused; - ushort mtu; - } frag; - } un; -} ICMP_t; - - -/* - * Maximum packet size; used to allocate packet storage. - * TFTP packets can be 524 bytes + IP header + ethernet header. - * Lets be conservative, and go for 38 * 16. (Must also be - * a multiple of 32 bytes). - */ -/* - * AS.HARNOIS : Better to set PKTSIZE to maximum size because - * traffic type is not always controlled - * maximum packet size = 1518 - * maximum packet size and multiple of 32 bytes = 1536 - */ -#define PKTSIZE 1518 -#define PKTSIZE_ALIGN 1536 -/*#define PKTSIZE 608*/ - -/* - * Maximum receive ring size; that is, the number of packets - * we can buffer before overflow happens. Basically, this just - * needs to be enough to prevent a packet being discarded while - * we are processing the previous one. - */ -#define RINGSZ 4 -#define RINGSZ_LOG2 2 - -/**********************************************************************/ -/* - * Globals. - * - * Note: - * - * All variables of type IPaddr_t are stored in NETWORK byte order - * (big endian). - */ - -/* net.c */ -/** BOOTP EXTENTIONS **/ -extern IPaddr_t NetOurGatewayIP; /* Our gateway IP addresse */ -extern IPaddr_t NetOurSubnetMask; /* Our subnet mask (0 = unknown)*/ -extern IPaddr_t NetOurDNSIP; /* Our Domain Name Server (0 = unknown)*/ -extern IPaddr_t NetOurDNS2IP; /* Our 2nd Domain Name Server (0 = unknown)*/ -extern char NetOurNISDomain[32]; /* Our NIS domain */ -extern char NetOurHostName[32]; /* Our hostname */ -extern char NetOurRootPath[64]; /* Our root path */ -/** END OF BOOTP EXTENTIONS **/ -extern ulong NetBootFileXferSize; /* size of bootfile in bytes */ -extern uchar NetOurEther[6]; /* Our ethernet address */ -extern uchar NetServerEther[6]; /* Boot server enet address */ -extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ -extern IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */ -extern uchar * NetTxPacket; /* THE transmit packet */ -extern uchar * NetRxPackets[PKTBUFSRX];/* Receive packets */ -extern uchar * NetRxPkt; /* Current receive packet */ -extern int NetRxPktLen; /* Current rx packet length */ -extern unsigned NetIPID; /* IP ID (counting) */ -extern uchar NetBcastAddr[6]; /* Ethernet boardcast address */ -extern uchar NetEtherNullAddr[6]; - -#define VLAN_NONE 4095 /* untagged */ -#define VLAN_IDMASK 0x0fff /* mask of valid vlan id */ -extern ushort NetOurVLAN; /* Our VLAN */ -extern ushort NetOurNativeVLAN; /* Our Native VLAN */ - -extern int NetState; /* Network loop state */ - -/* ---------- Added by sha ------------ */ -extern IPaddr_t NetArpWaitPacketIP; -extern uchar *NetArpWaitPacketMAC; -extern uchar *NetArpWaitTxPacket; /* THE transmit packet */ -extern int NetArpWaitTxPacketSize; -extern int NetArpWaitTry; -extern uint64_t NetArpWaitTimerStart; -extern void ArpRequest (void); -/* ------------------------------------ */ - -#define NETLOOP_CONTINUE 1 -#define NETLOOP_SUCCESS 2 -#define NETLOOP_FAIL 3 - -typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP } proto_t; - -/* Initialize the network adapter */ -int NetLoopInit(proto_t); - -/* Do the work */ -int NetLoop(void); - -/* Shutdown adapters and cleanup */ -void NetStop(void); - -/* Load failed. Start again. */ -void NetStartAgain(void); - -/* Get size of the ethernet header when we send */ -int NetEthHdrSize(void); - -/* Set ethernet header; returns the size of the header */ -int NetSetEther(uchar *, uchar *, uint); - -/* Set IP header */ -void NetSetIP(uchar *, IPaddr_t, int, int, int); - -/* Checksum */ -int NetCksumOk(uchar *, int); /* Return true if cksum OK */ -uint NetCksum(uchar *, int); /* Calculate the checksum */ - -/* Set callbacks */ -void NetSetHandler(rxhand_f *); /* Set RX packet handler */ -void NetSetTimeout(uint64_t, thand_f *);/* Set timeout handler */ - -/* Transmit "NetTxPacket" */ -void NetSendPacket(uchar *, int); - -/* Transmit UDP packet, performing ARP request if needed */ -int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len); - -/* Processes a received packet */ -void NetReceive(uchar *, int); - -/* Print an IP address on the console */ -#ifdef CONFIG_NET -void print_IPaddr (IPaddr_t); -#else -#define print_IPaddr(IPaddr_t); -#endif - -void netboot_update_env(void); - -/* - * The following functions are a bit ugly, but necessary to deal with - * alignment restrictions on ARM. - * - * We're using inline functions, which had the smallest memory - * footprint in our tests. - */ -/* return IP *in network byteorder* */ -static inline IPaddr_t NetReadIP(void *from) -{ - IPaddr_t ip; - memcpy((void*)&ip, from, sizeof(ip)); - return ip; -} - -/* return ulong *in network byteorder* */ -static inline ulong NetReadLong(ulong *from) -{ - ulong l; - memcpy((void*)&l, (void*)from, sizeof(l)); - return l; -} - -/* write IP *in network byteorder* */ -static inline void NetWriteIP(void *to, IPaddr_t ip) -{ - memcpy(to, (void*)&ip, sizeof(ip)); -} - -/* copy IP */ -static inline void NetCopyIP(void *to, void *from) -{ - memcpy(to, from, sizeof(IPaddr_t)); -} - -/* copy ulong */ -static inline void NetCopyLong(ulong *to, ulong *from) -{ - memcpy((void*)to, (void*)from, sizeof(ulong)); -} - -/* Convert an IP address to a string */ -char * ip_to_string (IPaddr_t x, char *s); - -/* Convert a string to ip address */ -int string_to_ip(const char *s, IPaddr_t *ip); - -/* Convert a VLAN id to a string */ -void VLAN_to_string (ushort x, char *s); - -/* Convert a string to a vlan id */ -ushort string_to_VLAN(const char *s); - -/* read an IP address from a environment variable */ -IPaddr_t getenv_IPaddr (char *); - -/* read a VLAN id from an environment variable */ -ushort getenv_VLAN(char *); - -int string_to_ethaddr(const char *str, char *enetaddr); -void ethaddr_to_string(const unsigned char *enetaddr, char *str); - -/**********************************************************************/ -/* Network devices */ -/**********************************************************************/ - -void eth_set_current(struct eth_device *eth); -struct eth_device *eth_get_current(void); -struct eth_device *eth_get_byname(char *name); - /* * Ethernet header */ @@ -577,8 +224,6 @@ static inline int net_eth_to_udplen(char *pkt) int net_checksum_ok(unsigned char *, int); /* Return true if cksum OK */ uint16_t net_checksum(unsigned char *, int); /* Calculate the checksum */ -void NetReceive(unsigned char *, int); - /* Print an IP address on the console */ void print_IPaddr (IPaddr_t); diff --git a/net/net.c b/net/net.c index 2b1641e8e..4305c727f 100644 --- a/net/net.c +++ b/net/net.c @@ -1,73 +1,31 @@ /* - * Copied from Linux Monitor (LiMon) - Networking. + * net.c - barebox networking support * - * Copyright 1994 - 2000 Neil Russell. - * (See License) - * Copyright 2000 Roland Borde - * Copyright 2000 Paolo Scaffardi - * Copyright 2000-2002 Wolfgang Denk, wd@denx.de + * Copyright (c) 2010 Sascha Hauer , Pengutronix + * + * based on U-Boot (LiMon) code + * + * Copyright 1994 - 2000 Neil Russell. + * Copyright 2000 Roland Borde + * Copyright 2000 Paolo Scaffardi + * Copyright 2000-2002 Wolfgang Denk, wd@denx.de + * + * 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 version 2 + * as published by the Free Software Foundation. + * + * 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 */ - -/* - * General Desription: - * - * The user interface supports commands for BOOTP, RARP, and TFTP. - * Also, we support ARP internally. Depending on available data, - * these interact as follows: - * - * BOOTP: - * - * Prerequisites: - own ethernet address - * We want: - own IP address - * - TFTP server IP address - * - name of bootfile - * Next step: ARP - * - * RARP: - * - * Prerequisites: - own ethernet address - * We want: - own IP address - * - TFTP server IP address - * Next step: ARP - * - * ARP: - * - * Prerequisites: - own ethernet address - * - own IP address - * - TFTP server IP address - * We want: - TFTP server ethernet address - * Next step: TFTP - * - * DHCP: - * - * Prerequisites: - own ethernet address - * We want: - IP, Netmask, ServerIP, Gateway IP - * - bootfilename, lease time - * Next step: - TFTP - * - * TFTP: - * - * Prerequisites: - own ethernet address - * - own IP address - * - TFTP server IP address - * - TFTP server ethernet address - * - name of bootfile (if unknown, we use a default name - * derived from our own IP address) - * We want: - load the boot file - * Next step: none - * - * NFS: - * - * Prerequisites: - own ethernet address - * - own IP address - * - name of bootfile (if unknown, we use a default name - * derived from our own IP address) - * We want: - load the boot file - * Next step: none - * - */ - - #include #include #include @@ -77,778 +35,57 @@ #include #include #include +#include #include #include #include -#include "tftp.h" -#include "rarp.h" -#include "nfs.h" -#define ARP_TIMEOUT (5 * SECOND) /* Seconds before trying ARP again */ -#ifndef CONFIG_NET_RETRY_COUNT -# define ARP_TIMEOUT_COUNT 5 /* # of timeouts before giving up */ -#else -# define ARP_TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT) -#endif +static IPaddr_t net_netmask; /* Our subnet mask (0=unknown) */ +static IPaddr_t net_gateway; /* Our gateways IP address */ -/** BOOTP EXTENTIONS **/ +static unsigned char net_ether[6]; /* Our ethernet address */ +static IPaddr_t net_ip; /* Our IP addr (0 = unknown) */ +static IPaddr_t net_serverip; /* Our IP addr (0 = unknown) */ -IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */ -IPaddr_t NetOurGatewayIP=0; /* Our gateways IP address */ -IPaddr_t NetOurDNSIP=0; /* Our DNS IP address */ -#ifdef CONFIG_BOOTP_DNS2 -IPaddr_t NetOurDNS2IP=0; /* Our 2nd DNS IP address */ -#endif -char NetOurNISDomain[32]={0,}; /* Our NIS domain */ -char NetOurHostName[32]={0,}; /* Our hostname */ -char NetOurRootPath[64]={0,}; /* Our bootpath */ +unsigned char *NetRxPackets[PKTBUFSRX]; /* Receive packets */ +static unsigned int net_ip_id; -/** END OF BOOTP EXTENTIONS **/ - -ulong NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */ -uchar NetOurEther[6]; /* Our ethernet address */ -uchar NetServerEther[6] = /* Boot server enet address */ - { 0, 0, 0, 0, 0, 0 }; -IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ -IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */ -uchar *NetRxPkt; /* Current receive packet */ -int NetRxPktLen; /* Current rx packet length */ -unsigned NetIPID; /* IP packet ID */ -uchar NetBcastAddr[6] = /* Ethernet bcast address */ - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -uchar NetEtherNullAddr[6] = - { 0, 0, 0, 0, 0, 0 }; -int NetState; /* Network loop state */ - -/* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */ -ushort NetOurVLAN = 0xFFFF; /* default is without VLAN */ -ushort NetOurNativeVLAN = 0xFFFF; /* ditto */ - -char BootFile[128]; /* Boot File name */ - -uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; - -uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */ - -static rxhand_f *packetHandler; /* Current RX packet handler */ -static thand_f *timeHandler; /* Current timeout handler */ -static uint64_t timeStart; /* Time base value */ -static uint64_t timeDelta; /* Current timeout value */ -uchar *NetTxPacket = 0; /* THE transmit packet */ - -static int net_check_prereq (proto_t protocol); - -/**********************************************************************/ - -IPaddr_t NetArpWaitPacketIP; -IPaddr_t NetArpWaitReplyIP; -uchar *NetArpWaitPacketMAC; /* MAC address of waiting packet's destination */ -uchar *NetArpWaitTxPacket; /* THE transmit packet */ -int NetArpWaitTxPacketSize; -uchar NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN]; -uint64_t NetArpWaitTimerStart; - -void ArpRequest (void) -{ - int i; - uchar *pkt; - ARP_t *arp; - - pr_debug("ARP broadcast\n"); - - pkt = NetTxPacket; - - pkt += NetSetEther (pkt, NetBcastAddr, PROT_ARP); - - arp = (ARP_t *) pkt; - - arp->ar_hrd = htons (ARP_ETHER); - arp->ar_pro = htons (PROT_IP); - arp->ar_hln = 6; - arp->ar_pln = 4; - arp->ar_op = htons (ARPOP_REQUEST); - - memcpy (&arp->ar_data[0], NetOurEther, 6); /* source ET addr */ - NetWriteIP ((uchar *) & arp->ar_data[6], NetOurIP); /* source IP addr */ - for (i = 10; i < 16; ++i) { - arp->ar_data[i] = 0; /* dest ET addr = 0 */ - } - - if ((NetArpWaitPacketIP & NetOurSubnetMask) != - (NetOurIP & NetOurSubnetMask)) { - if (NetOurGatewayIP == 0) { - puts ("## Warning: gatewayip needed but not set\n"); - NetArpWaitReplyIP = NetArpWaitPacketIP; - } else { - NetArpWaitReplyIP = NetOurGatewayIP; - } - } else { - NetArpWaitReplyIP = NetArpWaitPacketIP; - } - - NetWriteIP ((uchar *) & arp->ar_data[16], NetArpWaitReplyIP); - (void) eth_send (NetTxPacket, (pkt - NetTxPacket) + ARP_HDR_SIZE); -} - -/**********************************************************************/ -/* - * Main network processing loop. - */ - -int NetLoopInit(proto_t protocol) -{ - struct eth_device *eth_current = eth_get_current(); - IPaddr_t ip; - int ret; - int i; - - if (!eth_current) { - printf("Current ethernet device not set!\n"); - return -1; - } - - ip = dev_get_param_ip(ð_current->dev, "ipaddr"); - NetCopyIP(&NetOurIP, &ip); - - /* XXX problem with bss workaround */ - NetArpWaitPacketMAC = NULL; - NetArpWaitTxPacket = NULL; - NetArpWaitPacketIP = 0; - NetArpWaitReplyIP = 0; - - /* - * Setup packet buffers, aligned correctly. - */ - NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); - NetTxPacket -= (ulong)NetTxPacket % PKTALIGN; - for (i = 0; i < PKTBUFSRX; i++) { - NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; - } - - NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1); - NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN; - NetArpWaitTxPacketSize = 0; - - string_to_ethaddr(dev_get_param(ð_get_current()->dev, "ethaddr"), - NetOurEther); - - NetState = NETLOOP_CONTINUE; - - NetOurGatewayIP = dev_get_param_ip(ð_current->dev, "gateway"); - NetOurSubnetMask = dev_get_param_ip(ð_current->dev, "netmask"); - NetOurVLAN = getenv_VLAN("vlan"); - NetOurNativeVLAN = getenv_VLAN("nvlan"); - NetServerIP = dev_get_param_ip(ð_current->dev, "serverip"); - - ret = net_check_prereq(protocol); - - return ret; -} - -int NetLoop(void) -{ - /* - * Start the ball rolling with the given start function. From - * here on, this code is a state machine driven by received - * packets and timer events. - */ - - NetBootFileXferSize = 0; - - /* - * Main packet reception loop. Loop receiving packets until - * someone sets `NetState' to a state that terminates. - */ - for (;;) { - WATCHDOG_RESET(); -#ifdef CONFIG_SHOW_ACTIVITY - { - extern void show_activity(int arg); - show_activity(1); - } -#endif - /* - * Check the ethernet for a new packet. The ethernet - * receive routine will process it. - */ - eth_rx(); - - /* - * Abort if ctrl-c was pressed. - */ - if (ctrlc()) { - puts ("\nAbort\n"); - return -1; - } - - /* check for arp timeout */ - if (NetArpWaitPacketIP && - is_timeout(NetArpWaitTimerStart, ARP_TIMEOUT)) { - NetArpWaitTimerStart = get_time_ns(); - ArpRequest(); - } - - /* - * Check for a timeout, and run the timeout handler - * if we have one. - */ - if (timeHandler && is_timeout(timeStart, timeDelta)) { - thand_f *x; - x = timeHandler; - timeHandler = (thand_f *)0; - (*x)(); - } - - - switch (NetState) { - case NETLOOP_SUCCESS: - if (NetBootFileXferSize > 0) { - char buf[10]; - printf("Bytes transferred = %ld (%lx hex)\n", - NetBootFileXferSize, - NetBootFileXferSize); - sprintf(buf, "0x%lx", NetBootFileXferSize); - setenv("filesize", buf); - } - return NetBootFileXferSize; - - case NETLOOP_FAIL: - return -1; - } - } -} - -/**********************************************************************/ -/* - * Miscelaneous bits. - */ - -void -NetSetHandler(rxhand_f * f) -{ - packetHandler = f; -} - - -void -NetSetTimeout(uint64_t iv, thand_f * f) -{ - if (iv == 0) { - timeHandler = (thand_f *)0; - } else { - timeHandler = f; - timeStart = get_time_ns(); - timeDelta = iv; - } -} - - -void -NetSendPacket(uchar * pkt, int len) -{ - (void) eth_send(pkt, len); -} - -int -NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len) -{ - uchar *pkt; - - /* convert to new style broadcast */ - if (dest == 0) - dest = 0xFFFFFFFF; - - /* if broadcast, make the ether address a broadcast and don't do ARP */ - if (dest == 0xFFFFFFFF) - ether = NetBcastAddr; - - /* if MAC address was not discovered yet, save the packet and do an ARP request */ - if (memcmp(ether, NetEtherNullAddr, 6) == 0) { - pr_debug("sending ARP for %08lx\n", dest); - - NetArpWaitPacketIP = dest; - NetArpWaitPacketMAC = ether; - - pkt = NetArpWaitTxPacket; - pkt += NetSetEther (pkt, NetArpWaitPacketMAC, PROT_IP); - - NetSetIP (pkt, dest, dport, sport, len); - memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len); - - /* size of the waiting packet */ - NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len; - - /* and do the ARP request */ - NetArpWaitTimerStart = get_time_ns(); - ArpRequest(); - return 1; /* waiting */ - } - - pr_debug("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n", - dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]); - - pkt = (uchar *)NetTxPacket; - pkt += NetSetEther (pkt, ether, PROT_IP); - NetSetIP (pkt, dest, dport, sport, len); - (void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len); - - return 0; /* transmitted */ -} - -void -NetReceive(uchar * inpkt, int len) -{ - Ethernet_t *et; - IP_t *ip; - ARP_t *arp; - IPaddr_t tmp; - int x; - uchar *pkt; - ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid; - - pr_debug("packet received\n"); - - if (!net_receive(inpkt, len)) - return; - - NetRxPkt = inpkt; - NetRxPktLen = len; - et = (Ethernet_t *)inpkt; - - /* too small packet? */ - if (len < ETHER_HDR_SIZE) - return; - - myvlanid = ntohs(NetOurVLAN); - if (myvlanid == (ushort)-1) - myvlanid = VLAN_NONE; - mynvlanid = ntohs(NetOurNativeVLAN); - if (mynvlanid == (ushort)-1) - mynvlanid = VLAN_NONE; - - x = ntohs(et->et_protlen); - - pr_debug("packet received\n"); - - if (x < 1514) { - /* - * Got a 802 packet. Check the other protocol field. - */ - x = ntohs(et->et_prot); - - ip = (IP_t *)(inpkt + E802_HDR_SIZE); - len -= E802_HDR_SIZE; - - } else if (x != PROT_VLAN) { /* normal packet */ - ip = (IP_t *)(inpkt + ETHER_HDR_SIZE); - len -= ETHER_HDR_SIZE; - - } else { /* VLAN packet */ - VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)et; - - pr_debug("VLAN packet received\n"); - - /* too small packet? */ - if (len < VLAN_ETHER_HDR_SIZE) - return; - - /* if no VLAN active */ - if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE - ) - return; - - cti = ntohs(vet->vet_tag); - vlanid = cti & VLAN_IDMASK; - x = ntohs(vet->vet_type); - - ip = (IP_t *)(inpkt + VLAN_ETHER_HDR_SIZE); - len -= VLAN_ETHER_HDR_SIZE; - } - - pr_debug("Receive from protocol 0x%x\n", x); - - if ((myvlanid & VLAN_IDMASK) != VLAN_NONE) { - if (vlanid == VLAN_NONE) - vlanid = (mynvlanid & VLAN_IDMASK); - /* not matched? */ - if (vlanid != (myvlanid & VLAN_IDMASK)) - return; - } - - switch (x) { - - case PROT_ARP: - /* - * We have to deal with two types of ARP packets: - * - REQUEST packets will be answered by sending our - * IP address - if we know it. - * - REPLY packets are expected only after we asked - * for the TFTP server's or the gateway's ethernet - * address; so if we receive such a packet, we set - * the server ethernet address - */ - pr_debug("Got ARP\n"); - - arp = (ARP_t *)ip; - if (len < ARP_HDR_SIZE) { - printf("bad length %d < %d\n", len, ARP_HDR_SIZE); - return; - } - if (ntohs(arp->ar_hrd) != ARP_ETHER) { - return; - } - if (ntohs(arp->ar_pro) != PROT_IP) { - return; - } - if (arp->ar_hln != 6) { - return; - } - if (arp->ar_pln != 4) { - return; - } - - if (NetOurIP == 0) { - return; - } - - if (NetReadIP(&arp->ar_data[16]) != NetOurIP) { - return; - } - - switch (ntohs(arp->ar_op)) { - case ARPOP_REQUEST: /* reply with our IP address */ - pr_debug("Got ARP REQUEST, return our IP\n"); - - pkt = (uchar *)et; - pkt += NetSetEther(pkt, et->et_src, PROT_ARP); - arp->ar_op = htons(ARPOP_REPLY); - memcpy (&arp->ar_data[10], &arp->ar_data[0], 6); - NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]); - memcpy (&arp->ar_data[ 0], NetOurEther, 6); - NetCopyIP(&arp->ar_data[ 6], &NetOurIP); - memcpy(NetTxPacket, et, (pkt - (uchar *)et) + ARP_HDR_SIZE); - eth_send((uchar *)NetTxPacket, (pkt - (uchar *)et) + ARP_HDR_SIZE); - return; - - case ARPOP_REPLY: /* arp reply */ - /* are we waiting for a reply */ - if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC) - break; - pr_debug("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n", - arp->ar_data[0], arp->ar_data[1], - arp->ar_data[2], arp->ar_data[3], - arp->ar_data[4], arp->ar_data[5]); - - tmp = NetReadIP(&arp->ar_data[6]); - - /* matched waiting packet's address */ - if (tmp == NetArpWaitReplyIP) { - pr_debug("Got it\n"); - - /* save address for later use */ - memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6); - - /* modify header, and transmit it */ - memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6); - (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize); - - /* no arp request pending now */ - NetArpWaitPacketIP = 0; - NetArpWaitTxPacketSize = 0; - NetArpWaitPacketMAC = NULL; - - } - return; - default: - pr_debug("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op)); - return; - } - break; - - case PROT_RARP: - pr_debug("Got RARP\n"); - - arp = (ARP_t *)ip; - if (len < ARP_HDR_SIZE) { - printf("bad length %d < %d\n", len, ARP_HDR_SIZE); - return; - } - - if ((ntohs(arp->ar_op) != RARPOP_REPLY) || - (ntohs(arp->ar_hrd) != ARP_ETHER) || - (ntohs(arp->ar_pro) != PROT_IP) || - (arp->ar_hln != 6) || (arp->ar_pln != 4)) { - - puts ("invalid RARP header\n"); - } else { - NetCopyIP(&NetOurIP, &arp->ar_data[16]); - if (NetServerIP == 0) - NetCopyIP(&NetServerIP, &arp->ar_data[ 6]); - memcpy (NetServerEther, &arp->ar_data[ 0], 6); - - if (packetHandler) - (*packetHandler)(0,0,0,0); - } - break; - - case PROT_IP: - pr_debug("Got IP\n"); - - if (len < IP_HDR_SIZE) { - debug ("len bad %d < %d\n", len, IP_HDR_SIZE); - return; - } - if (len < ntohs(ip->ip_len)) { - printf("len bad %d < %d\n", len, ntohs(ip->ip_len)); - return; - } - len = ntohs(ip->ip_len); - - pr_debug("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); - - if ((ip->ip_hl_v & 0xf0) != 0x40) { - return; - } - if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */ - return; - } - if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)) { - puts ("checksum bad\n"); - return; - } - tmp = NetReadIP(&ip->ip_dst); - if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) { - return; - } - /* - * watch for ICMP host redirects - * - * There is no real handler code (yet). We just watch - * for ICMP host redirect messages. In case anybody - * sees these messages: please contact me - * (wd@denx.de), or - even better - send me the - * necessary fixes :-) - * - * Note: in all cases where I have seen this so far - * it was a problem with the router configuration, - * for instance when a router was configured in the - * BOOTP reply, but the TFTP server was on the same - * subnet. So this is probably a warning that your - * configuration might be wrong. But I'm not really - * sure if there aren't any other situations. - */ - if (ip->ip_p == IPPROTO_ICMP) { - ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); - - switch (icmph->type) { - case ICMP_REDIRECT: - if (icmph->code != ICMP_REDIR_HOST) - return; - puts (" ICMP Host Redirect to "); - print_IPaddr(icmph->un.gateway); - putchar(' '); - return; -#ifdef CONFIG_NET_PING - case ICMP_ECHO_REPLY: - /* - * IP header OK. Pass the packet to the current handler. - */ - /* XXX point to ip packet */ - if (packetHandler) - (*packetHandler)((uchar *)ip, 0, 0, 0); - return; -#endif - default: - return; - } - } else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ - return; - } - -#ifdef CONFIG_UDP_CHECKSUM - if (ip->udp_xsum != 0) { - ulong xsum; - ushort *sumptr; - ushort sumlen; - - xsum = ip->ip_p; - xsum += (ntohs(ip->udp_len)); - xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff; - xsum += (ntohl(ip->ip_src) >> 0) & 0x0000ffff; - xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff; - xsum += (ntohl(ip->ip_dst) >> 0) & 0x0000ffff; - - sumlen = ntohs(ip->udp_len); - sumptr = (ushort *) &(ip->udp_src); - - while (sumlen > 1) { - ushort sumdata; - - sumdata = *sumptr++; - xsum += ntohs(sumdata); - sumlen -= 2; - } - if (sumlen > 0) { - ushort sumdata; - - sumdata = *(unsigned char *) sumptr; - sumdata = (sumdata << 8) & 0xff00; - xsum += sumdata; - } - while ((xsum >> 16) != 0) { - xsum = (xsum & 0x0000ffff) + ((xsum >> 16) & 0x0000ffff); - } - if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) { - printf(" UDP wrong checksum %08x %08x\n", xsum, ntohs(ip->udp_xsum)); - return; - } - } -#endif - /* - * IP header OK. Pass the packet to the current handler. - */ - if (packetHandler) - (*packetHandler)((uchar *)ip +IP_HDR_SIZE, - ntohs(ip->udp_dst), - ntohs(ip->udp_src), - ntohs(ip->udp_len) - 8); - break; - } -} - - -/**********************************************************************/ - -static int net_check_prereq (proto_t protocol) +void net_update_env(void) { struct eth_device *edev = eth_get_current(); - switch (protocol) { - /* Fall through */ -#ifdef CONFIG_NET_NFS - case NFS: -#endif - case NETCONS: - case TFTP: - if (NetServerIP == 0) { - printf("*** ERROR: `%s.serverip' not set\n", dev_id(&edev->dev)); - return -1; - } + net_ip = dev_get_param_ip(&edev->dev, "ipaddr"); + net_serverip = dev_get_param_ip(&edev->dev, "serverip"); + net_gateway = dev_get_param_ip(&edev->dev, "gateway"); + net_netmask = dev_get_param_ip(&edev->dev, "netmask"); - if (NetOurIP == 0) { - printf("*** ERROR: `%s.ipaddr' not set\n", dev_id(&edev->dev)); - return -1; - } - /* Fall through */ - - case DHCP: - case RARP: - case BOOTP: - if (memcmp (NetOurEther, "\0\0\0\0\0\0", 6) == 0) { - printf("*** ERROR: `%s.ethaddr' not set\n", dev_id(&edev->dev)); - return -1; - } - /* Fall through */ - default: - return 0; - } - - return -1; /* not reached */ -} -/**********************************************************************/ - -int -NetCksumOk(uchar * ptr, int len) -{ - return !((NetCksum(ptr, len) + 1) & 0xfffe); + string_to_ethaddr(dev_get_param(&edev->dev, "ethaddr"), + net_ether); } - -unsigned -NetCksum(uchar * ptr, int len) +int net_checksum_ok(unsigned char *ptr, int len) { - ulong xsum; - ushort *p = (ushort *)ptr; + return net_checksum(ptr, len) + 1; +} + +uint16_t net_checksum(unsigned char *ptr, int len) +{ + uint32_t xsum = 0; + uint16_t *p = (uint16_t *)ptr; + + if (len & 1) + ptr[len] = 0; + + len = (len + 1) >> 1; - xsum = 0; while (len-- > 0) xsum += *p++; + xsum = (xsum & 0xffff) + (xsum >> 16); xsum = (xsum & 0xffff) + (xsum >> 16); return xsum & 0xffff; } -int -NetEthHdrSize(void) -{ - ushort myvlanid; - - myvlanid = ntohs(NetOurVLAN); - if (myvlanid == (ushort)-1) - myvlanid = VLAN_NONE; - - return ((myvlanid & VLAN_IDMASK) == VLAN_NONE) ? ETHER_HDR_SIZE : VLAN_ETHER_HDR_SIZE; -} - -int -NetSetEther(uchar * xet, uchar * addr, uint prot) -{ - Ethernet_t *et = (Ethernet_t *)xet; - ushort myvlanid; - - myvlanid = ntohs(NetOurVLAN); - if (myvlanid == (ushort)-1) - myvlanid = VLAN_NONE; - - memcpy (et->et_dest, addr, 6); - memcpy (et->et_src, NetOurEther, 6); - if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) { - et->et_protlen = htons(prot); - return ETHER_HDR_SIZE; - } else { - VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)xet; - - vet->vet_vlan_type = htons(PROT_VLAN); - vet->vet_tag = htons((0 << 5) | (myvlanid & VLAN_IDMASK)); - vet->vet_type = htons(prot); - return VLAN_ETHER_HDR_SIZE; - } -} - -void -NetSetIP(uchar * xip, IPaddr_t dest, int dport, int sport, int len) -{ - IP_t *ip = (IP_t *)xip; - - /* - * If the data is an odd number of bytes, zero the - * byte after the last byte so that the checksum - * will work. - */ - if (len & 1) - xip[IP_HDR_SIZE + len] = 0; - - /* - * Construct an IP and UDP header. - * (need to set no fragment bit - XXX) - */ - ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ - ip->ip_tos = 0; - ip->ip_len = htons(IP_HDR_SIZE + len); - ip->ip_id = htons(NetIPID++); - ip->ip_off = htons(0x4000); /* No fragmentation */ - ip->ip_ttl = 255; - ip->ip_p = 17; /* UDP */ - ip->ip_sum = 0; - NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ - NetCopyIP((void*)&ip->ip_dst, &dest); /* - "" - */ - ip->udp_src = htons(sport); - ip->udp_dst = htons(dport); - ip->udp_len = htons(8 + len); - ip->udp_xsum = 0; - ip->ip_sum = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2); -} - char *ip_to_string (IPaddr_t x, char *s) { x = ntohl (x); @@ -870,7 +107,7 @@ int string_to_ip(const char *s, IPaddr_t *ip) return -EINVAL; for (i = 0; i < 4; i++) { - ulong val; + unsigned long val; if (!isdigit(*s)) return -EINVAL; @@ -913,34 +150,6 @@ int setenv_ip(const char *name, IPaddr_t ip) return 0; } -void VLAN_to_string(ushort x, char *s) -{ - x = ntohs(x); - - if (x == (ushort)-1) - x = VLAN_NONE; - - if (x == VLAN_NONE) - strcpy(s, "none"); - else - sprintf(s, "%d", x & VLAN_IDMASK); -} - -ushort string_to_VLAN(const char *s) -{ - ushort id; - - if (s == NULL) - return htons(VLAN_NONE); - - if (*s < '0' || *s > '9') - id = VLAN_NONE; - else - id = (ushort)simple_strtoul(s, NULL, 10); - - return htons(id); -} - void print_IPaddr (IPaddr_t x) { char tmp[16]; @@ -950,14 +159,9 @@ void print_IPaddr (IPaddr_t x) puts (tmp); } -ushort getenv_VLAN(char *var) -{ - return string_to_VLAN(getenv(var)); -} - int string_to_ethaddr(const char *str, char *enetaddr) { - ulong reg; + int reg; char *e; if (!str || strlen(str) != 17) @@ -977,65 +181,11 @@ int string_to_ethaddr(const char *str, char *enetaddr) void ethaddr_to_string(const unsigned char *enetaddr, char *str) { - sprintf (str, "%02X:%02X:%02X:%02X:%02X:%02X", + sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", enetaddr[0], enetaddr[1], enetaddr[2], enetaddr[3], enetaddr[4], enetaddr[5]); } -static IPaddr_t net_netmask; /* Our subnet mask (0=unknown) */ -static IPaddr_t net_gateway; /* Our gateways IP address */ - -static unsigned char net_ether[6]; /* Our ethernet address */ -static IPaddr_t net_ip; /* Our IP addr (0 = unknown) */ -static IPaddr_t net_serverip; /* Our IP addr (0 = unknown) */ - -unsigned char *NetRxPackets[PKTBUFSRX]; /* Receive packets */ -static unsigned int net_ip_id; - -void net_update_env(void) -{ - struct eth_device *edev = eth_get_current(); - - net_ip = dev_get_param_ip(&edev->dev, "ipaddr"); - net_serverip = dev_get_param_ip(&edev->dev, "serverip"); - net_gateway = dev_get_param_ip(&edev->dev, "gateway"); - net_netmask = dev_get_param_ip(&edev->dev, "netmask"); - - string_to_ethaddr(dev_get_param(&edev->dev, "ethaddr"), - net_ether); - - NetOurIP = dev_get_param_ip(&edev->dev, "ipaddr"); - NetServerIP = dev_get_param_ip(&edev->dev, "serverip"); - NetOurGatewayIP = dev_get_param_ip(&edev->dev, "gateway"); - NetOurSubnetMask = dev_get_param_ip(&edev->dev, "netmask"); - - string_to_ethaddr(dev_get_param(&edev->dev, "ethaddr"), - NetOurEther); -} - -int net_checksum_ok(unsigned char *ptr, int len) -{ - return net_checksum(ptr, len) + 1; -} - -uint16_t net_checksum(unsigned char *ptr, int len) -{ - uint32_t xsum = 0; - uint16_t *p = (uint16_t *)ptr; - - if (len & 1) - ptr[len] = 0; - - len = (len + 1) >> 1; - - while (len-- > 0) - xsum += *p++; - - xsum = (xsum & 0xffff) + (xsum >> 16); - xsum = (xsum & 0xffff) + (xsum >> 16); - return xsum & 0xffff; -} - static unsigned char *arp_ether; static IPaddr_t arp_wait_ip; From c3789cd49b43ec1c414ba1b0e9f48e8ccc19f8e1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 3 Jun 2010 10:13:29 +0200 Subject: [PATCH 21/65] rework device parameters Change device parameters so that the memory management is in generic code. This also removes the need of storing statically initialized parameters as they are stored in a struct list_head for each device. Signed-off-by: Sascha Hauer --- common/console.c | 40 ++++----- drivers/nand/nand.c | 7 +- drivers/video/fb.c | 21 +++-- drivers/video/imx.c | 17 ++-- include/console.h | 6 -- include/driver.h | 2 +- include/fb.h | 2 - include/net.h | 6 -- include/param.h | 15 +++- lib/driver.c | 12 +-- lib/parameter.c | 197 ++++++++++++++++++++++++++++---------------- net/eth.c | 48 ++++------- 12 files changed, 203 insertions(+), 170 deletions(-) diff --git a/common/console.c b/common/console.c index d3d31f789..7199d9afb 100644 --- a/common/console.c +++ b/common/console.c @@ -57,26 +57,32 @@ static int console_std_set(struct device_d *dev, struct param_d *param, const char *val) { struct console_device *cdev = dev->type_data; + char active[4]; unsigned int flag = 0, i = 0; + if (!val) + dev_param_set_generic(dev, param, NULL); + if (strchr(val, 'i') && cdev->f_caps & CONSOLE_STDIN) { - cdev->active[i++] = 'i'; + active[i++] = 'i'; flag |= CONSOLE_STDIN; } if (strchr(val, 'o') && cdev->f_caps & CONSOLE_STDOUT) { - cdev->active[i++] = 'o'; + active[i++] = 'o'; flag |= CONSOLE_STDOUT; } if (strchr(val, 'e') && cdev->f_caps & CONSOLE_STDERR) { - cdev->active[i++] = 'e'; + active[i++] = 'e'; flag |= CONSOLE_STDERR; } - cdev->active[i] = 0; + active[i] = 0; cdev->f_active = flag; + dev_param_set_generic(dev, param, active); + return 0; } @@ -85,8 +91,12 @@ static int console_baudrate_set(struct device_d *dev, struct param_d *param, { struct console_device *cdev = dev->type_data; int baudrate; + char baudstr[16]; unsigned char c; + if (!val) + dev_param_set_generic(dev, param, NULL); + baudrate = simple_strtoul(val, NULL, 10); if (cdev->f_active) { @@ -101,7 +111,8 @@ static int console_baudrate_set(struct device_d *dev, struct param_d *param, } else cdev->setbrg(cdev, baudrate); - sprintf(cdev->baudrate_string, "%d", baudrate); + sprintf(baudstr, "%d", baudrate); + dev_param_set_generic(dev, param, baudstr); return 0; } @@ -129,29 +140,20 @@ int console_register(struct console_device *newcdev) register_device(dev); if (newcdev->setbrg) { - newcdev->baudrate_param.set = console_baudrate_set; - newcdev->baudrate_param.name = "baudrate"; - sprintf(newcdev->baudrate_string, "%d", - CONFIG_BAUDRATE); - console_baudrate_set(dev, &newcdev->baudrate_param, - newcdev->baudrate_string); - newcdev->baudrate_param.value = newcdev->baudrate_string; - dev_add_param(dev, &newcdev->baudrate_param); + dev_add_param(dev, "baudrate", console_baudrate_set, NULL, 0); + dev_set_param(dev, "baudrate", "115200"); } - newcdev->active_param.set = console_std_set; - newcdev->active_param.name = "active"; - newcdev->active_param.value = newcdev->active; - dev_add_param(dev, &newcdev->active_param); + dev_add_param(dev, "active", console_std_set, NULL, 0); initialized = CONSOLE_INIT_FULL; #ifdef CONFIG_CONSOLE_ACTIVATE_ALL - console_std_set(dev, &newcdev->active_param, "ioe"); + dev_set_param(dev, "active", "ioe"); #endif #ifdef CONFIG_CONSOLE_ACTIVATE_FIRST if (list_empty(&console_list)) { first = 1; - console_std_set(dev, &newcdev->active_param, "ioe"); + dev_set_param(dev, "active", "ioe"); } #endif diff --git a/drivers/nand/nand.c b/drivers/nand/nand.c index bcf52bd94..4927231c1 100644 --- a/drivers/nand/nand.c +++ b/drivers/nand/nand.c @@ -210,6 +210,7 @@ static struct file_operations nand_ops_oob = { int add_mtd_device(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; + char str[16]; strcpy(mtd->class_dev.name, "nand"); register_device(&mtd->class_dev); @@ -220,10 +221,8 @@ int add_mtd_device(struct mtd_info *mtd) mtd->cdev.priv = mtd; mtd->cdev.dev = &mtd->class_dev; - mtd->param_size.flags = PARAM_FLAG_RO; - mtd->param_size.name = "size"; - mtd->param_size.value = asprintf("%u", mtd->size); - dev_add_param(&mtd->class_dev, &mtd->param_size); + sprintf(str, "%u", mtd->size); + dev_add_param_fixed(&mtd->class_dev, "size", str); devfs_create(&mtd->cdev); diff --git a/drivers/video/fb.c b/drivers/video/fb.c index 00a0f6a17..841c3afe9 100644 --- a/drivers/video/fb.c +++ b/drivers/video/fb.c @@ -32,15 +32,22 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param, { struct fb_info *info = dev->priv; int enable; + char *new; + + if (!val) + return dev_param_set_generic(dev, param, NULL); enable = simple_strtoul(val, NULL, 0); - if (enable) + if (enable) { info->fbops->fb_enable(info); - else + new = "1"; + } else { info->fbops->fb_disable(info); + new = "0"; + } - sprintf(info->enable_string, "%d", !!enable); + dev_param_set_generic(dev, param, new); return 0; } @@ -71,13 +78,9 @@ int register_framebuffer(struct fb_info *info) sprintf(dev->name, "fb"); - info->param_enable.set = fb_enable_set; - info->param_enable.name = "enable"; - sprintf(info->enable_string, "%d", 0); - info->param_enable.value = info->enable_string; - dev_add_param(dev, &info->param_enable); - register_device(&info->dev); + dev_add_param(dev, "enable", fb_enable_set, NULL, 0); + dev_set_param(dev, "enable", "0"); devfs_create(&info->cdev); diff --git a/drivers/video/imx.c b/drivers/video/imx.c index 67cae349e..d9ba643ac 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -154,8 +154,6 @@ struct imxfb_info { struct fb_info overlay; - struct param_d param_alpha; - char alpha_string[4]; }; #define IMX_NAME "IMX" @@ -427,8 +425,12 @@ static int imxfb_alpha_set(struct device_d *dev, struct param_d *param, struct fb_info *overlay = dev->priv; struct imxfb_info *fbi = overlay->priv; int alpha; + char alphastr[16]; unsigned int tmp; + if (!val) + return dev_param_set_generic(dev, param, NULL); + alpha = simple_strtoul(val, NULL, 0); alpha &= 0xff; @@ -437,7 +439,9 @@ static int imxfb_alpha_set(struct device_d *dev, struct param_d *param, tmp |= LGWCR_GWAV(alpha); writel(tmp , fbi->regs + LCDC_LGWCR); - sprintf(fbi->alpha_string, "%d", alpha); + sprintf(alphastr, "%d", alpha); + + dev_param_set_generic(dev, param, alphastr); return 0; } @@ -502,11 +506,8 @@ static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb) return ret; } - fbi->param_alpha.set = imxfb_alpha_set; - fbi->param_alpha.name = "alpha"; - sprintf(fbi->alpha_string, "%d", 0); - fbi->param_alpha.value = fbi->alpha_string; - dev_add_param(&overlay->dev, &fbi->param_alpha); + dev_add_param(&overlay->dev, "alpha", imxfb_alpha_set, NULL, 0); + dev_set_param(&overlay->dev, "alpha", "0"); return 0; } diff --git a/include/console.h b/include/console.h index 3568c562a..3bcc5dbbc 100644 --- a/include/console.h +++ b/include/console.h @@ -46,12 +46,6 @@ struct console_device { unsigned char f_caps; unsigned char f_active; - - struct param_d baudrate_param; - char baudrate_string[8]; - - struct param_d active_param; - char active[4]; }; int console_register(struct console_device *cdev); diff --git a/include/driver.h b/include/driver.h index 1dde38e02..6950c0204 100644 --- a/include/driver.h +++ b/include/driver.h @@ -98,7 +98,7 @@ struct device_d { /*! The parameters for this device. This is used to carry information * of board specific data from the board code to the device driver. */ - struct param_d *param; + struct list_head parameters; struct list_head cdevs; }; diff --git a/include/fb.h b/include/fb.h index f213c420d..218500b98 100644 --- a/include/fb.h +++ b/include/fb.h @@ -80,8 +80,6 @@ struct fb_info { struct fb_ops *fbops; struct device_d dev; /* This is this fb device */ - struct param_d param_enable; - char enable_string[1]; void *screen_base; diff --git a/include/net.h b/include/net.h index a2863d082..15106a782 100644 --- a/include/net.h +++ b/include/net.h @@ -41,12 +41,6 @@ struct eth_device { struct eth_device *next; void *priv; - struct param_d param_ip; - struct param_d param_netmask; - struct param_d param_gateway; - struct param_d param_serverip; - struct param_d param_ethaddr; - struct device_d dev; struct list_head list; diff --git a/include/param.h b/include/param.h index fe4468ed2..207ad5016 100644 --- a/include/param.h +++ b/include/param.h @@ -2,6 +2,7 @@ #define PARAM_H #include +#include #define PARAM_FLAG_RO (1 << 0) @@ -15,12 +16,24 @@ struct param_d { char *name; struct param_d *next; char *value; + struct list_head list; }; const char *dev_get_param(struct device_d *dev, const char *name); int dev_set_param(struct device_d *dev, const char *name, const char *val); struct param_d *get_param_by_name(struct device_d *dev, const char *name); -int dev_add_param(struct device_d *dev, struct param_d *par); + +int dev_add_param(struct device_d *dev, char *name, + int (*set)(struct device_d *dev, struct param_d *p, const char *val), + char *(*get)(struct device_d *, struct param_d *p), + unsigned long flags); + +int dev_add_param_fixed(struct device_d *dev, char *name, char *value); + +void dev_remove_parameters(struct device_d *dev); + +int dev_param_set_generic(struct device_d *dev, struct param_d *p, + const char *val); /* Convenience functions to handle a parameter as an ip address */ int dev_set_param_ip(struct device_d *dev, char *name, IPaddr_t ip); diff --git a/lib/driver.c b/lib/driver.c index f433c3e9b..b60074511 100644 --- a/lib/driver.c +++ b/lib/driver.c @@ -107,6 +107,7 @@ int register_device(struct device_d *new_device) list_add_tail(&new_device->list, &device_list); INIT_LIST_HEAD(&new_device->children); INIT_LIST_HEAD(&new_device->cdevs); + INIT_LIST_HEAD(&new_device->parameters); for_each_driver(drv) { if (!match(drv, new_device)) @@ -313,16 +314,11 @@ static int do_devinfo(struct command *cmdtp, int argc, char *argv[]) if (dev->driver) dev->driver->info(dev); - param = dev->param; + printf("%s\n", list_empty(&dev->parameters) ? + "no parameters available" : "Parameters:"); - printf("%s\n", param ? - "Parameters:" : "no parameters available"); - - while (param) { + list_for_each_entry(param, &dev->parameters, list) printf("%16s = %s\n", param->name, param->value); - param = param->next; - } - } return 0; diff --git a/lib/parameter.c b/lib/parameter.c index 6b32207cd..0aa419343 100644 --- a/lib/parameter.c +++ b/lib/parameter.c @@ -33,17 +33,22 @@ struct param_d *get_param_by_name(struct device_d *dev, const char *name) { - struct param_d *param = dev->param; + struct param_d *p; - while (param) { - if (!strcmp(param->name, name)) - return param; - param = param->next; + list_for_each_entry(p, &dev->parameters, list) { + if (!strcmp(p->name, name)) + return p; } return NULL; } +/** + * dev_get_param - get the value of a parameter + * @param dev The device + * @param name The name of the parameter + * @return The value + */ const char *dev_get_param(struct device_d *dev, const char *name) { struct param_d *param = get_param_by_name(dev, name); @@ -53,10 +58,7 @@ const char *dev_get_param(struct device_d *dev, const char *name) return NULL; } - if (param->get) - return param->get(dev, param); - - return param->value; + return param->get(dev, param); } #ifdef CONFIG_NET @@ -80,6 +82,12 @@ int dev_set_param_ip(struct device_d *dev, char *name, IPaddr_t ip) } #endif +/** + * dev_set_param - set a parameter of a device to a new value + * @param dev The device + * @param name The name of the parameter + * @param value The new value of the parameter + */ int dev_set_param(struct device_d *dev, const char *name, const char *val) { struct param_d *param; @@ -101,35 +109,124 @@ int dev_set_param(struct device_d *dev, const char *name, const char *val) return -EACCES; } - if (param->set) { - errno = param->set(dev, param, val); - return errno; + errno = param->set(dev, param, val); + return errno; +} + +/** + * dev_param_set_generic - generic setter function for a parameter + * @param dev The device + * @param p the parameter + * @param val The new value + * + * If used the value of a parameter is a string allocated with + * malloc and freed with free. If val is NULL the value is freed. This is + * used during deregistration of the parameter to free the alloctated + * memory. + */ +int dev_param_set_generic(struct device_d *dev, struct param_d *p, + const char *val) +{ + if (p->value) + free(p->value); + if (!val) { + p->value = NULL; + return 0; } - - if (param->value) - free(param->value); - - param->value = strdup(val); + p->value = strdup(val); return 0; } -int dev_add_param(struct device_d *dev, struct param_d *newparam) +static char *param_get_generic(struct device_d *dev, struct param_d *p) { - struct param_d *param = dev->param; + return p->value; +} - newparam->next = NULL; +static struct param_d *__dev_add_param(struct device_d *dev, char *name, + int (*set)(struct device_d *dev, struct param_d *p, const char *val), + char *(*get)(struct device_d *dev, struct param_d *p), + unsigned long flags) +{ + struct param_d *param; - if (param) { - while (param->next) - param = param->next; - param->next = newparam; - } else { - dev->param = newparam; - } + param = xzalloc(sizeof(*param)); + + if (set) + param->set = set; + else + param->set = dev_param_set_generic; + if (get) + param->get = get; + else + param->get = param_get_generic; + + param->name = strdup(name); + param->flags = flags; + list_add_tail(¶m->list, &dev->parameters); + + return param; +} + +/** + * dev_add_param - add a parameter to a device + * @param dev The device + * @param name The name of the parameter + * @param set setter function for the parameter + * @param get getter function for the parameter + * @param flags + * + * This function adds a new parameter to a device. The get/set functions can + * be zero in which case the generic functions are used. The generic functions + * expect the parameter value to be a string which can be freed with free(). Do + * not use static arrays when using the generic functions. + */ +int dev_add_param(struct device_d *dev, char *name, + int (*set)(struct device_d *dev, struct param_d *p, const char *val), + char *(*get)(struct device_d *dev, struct param_d *param), + unsigned long flags) +{ + struct param_d *param; + + param = __dev_add_param(dev, name, set, get, flags); + + return param ? 0 : -EINVAL; +} + +/** + * dev_add_param_fixed - add a readonly parameter to a device + * @param dev The device + * @param name The name of the parameter + * @param value The value of the parameter + */ +int dev_add_param_fixed(struct device_d *dev, char *name, char *value) +{ + struct param_d *param; + + param = __dev_add_param(dev, name, NULL, NULL, PARAM_FLAG_RO); + if (!param) + return -EINVAL; + + param->value = strdup(value); return 0; } +/** + * dev_remove_parameters - remove all parameters from a device and free their + * memory + * @param dev The device + */ +void dev_remove_parameters(struct device_d *dev) +{ + struct param_d *p, *n; + + list_for_each_entry_safe(p, n, &dev->parameters, list) { + p->set(dev, p, NULL); + list_del(&p->list); + free(p); + } +} + /** @page dev_params Device parameters @section params_devices Devices can have several parameters. @@ -145,50 +242,6 @@ IP address of the first ethernet device is a matter of typing devices currently present. If called with a device id as parameter it shows the parameters available for a device. -@section params_programming Device parameters programming API - -@code -struct param_d { - char* (*get)(struct device_d *, struct param_d *param); - int (*set)(struct device_d *, struct param_d *param, const char *val); - ulong flags; - char *name; - struct param_d *next; - char *value; -}; -@endcode - -@code -int dev_add_param(struct device_d *dev, struct param_d *newparam); -@endcode - -This function adds a new parameter to a device. At least the name field in -the new parameter struct has to be initialized. The 'get' and 'set' fields -can be set to NULL in which case the framework handles them. It is also -allowed to implement only one of the get/set functions. Care must be taken -with the initial value of the parameter. If the framework handles the set -function it will try to free the value of the parameter. If this is a -static array bad things will happen. A parameter can have the flag -PARAM_FLAG_RO which means that the parameter is readonly. It is perfectly ok -then to point the value to a static array. - -@code -const char *dev_get_param(struct device_d *dev, const char *name); -@endcode - -This function returns a pointer to the value of the parameter specified -with dev and name. -If the framework handles the get/set functions the parameter value strings -are alloceted with malloc and freed with free when another value is set for -this parameter. Drivers implementing set/get themselves are allowed to -return values in static arrays. This means that the pointers returned from -dev_get_param() are only valid until the next call to dev_get_param. If this -is not long enough strdup() or similar must be used. - -@code -int dev_set_param(struct device_d *dev, const char *name, const char *val); -@endcode - -Set the value of a parameter. +See the individual functions for parameter programming. */ diff --git a/net/eth.c b/net/eth.c index fc16233be..4d5819121 100644 --- a/net/eth.c +++ b/net/eth.c @@ -102,11 +102,13 @@ static int eth_set_ethaddr(struct device_d *dev, struct param_d *param, const ch struct eth_device *edev = dev->type_data; char ethaddr[sizeof("xx:xx:xx:xx:xx:xx")]; + if (!val) + return dev_param_set_generic(dev, param, NULL); + if (string_to_ethaddr(val, ethaddr) < 0) return -EINVAL; - free(param->value); - param->value = strdup(val); + dev_param_set_generic(dev, param, val); edev->set_ethaddr(edev, ethaddr); @@ -121,11 +123,13 @@ static int eth_set_ipaddr(struct device_d *dev, struct param_d *param, const cha struct eth_device *edev = dev->type_data; IPaddr_t ip; + if (!val) + return dev_param_set_generic(dev, param, NULL); + if (string_to_ip(val, &ip)) return -EINVAL; - free(param->value); - param->value = strdup(val); + dev_param_set_generic(dev, param, val); if (edev == eth_current) net_update_env(); @@ -148,21 +152,11 @@ int eth_register(struct eth_device *edev) register_device(&edev->dev); dev->type_data = edev; - edev->param_ip.name = "ipaddr"; - edev->param_ip.set = ð_set_ipaddr; - edev->param_ethaddr.name = "ethaddr"; - edev->param_ethaddr.set = ð_set_ethaddr; - edev->param_gateway.name = "gateway"; - edev->param_gateway.set = ð_set_ipaddr; - edev->param_netmask.name = "netmask"; - edev->param_netmask.set = ð_set_ipaddr; - edev->param_serverip.name = "serverip"; - edev->param_serverip.set = ð_set_ipaddr; - dev_add_param(dev, &edev->param_ip); - dev_add_param(dev, &edev->param_ethaddr); - dev_add_param(dev, &edev->param_gateway); - dev_add_param(dev, &edev->param_netmask); - dev_add_param(dev, &edev->param_serverip); + dev_add_param(dev, "ipaddr", eth_set_ipaddr, NULL, 0); + dev_add_param(dev, "ethaddr", eth_set_ethaddr, NULL, 0); + dev_add_param(dev, "gateway", eth_set_ipaddr, NULL, 0); + dev_add_param(dev, "netmask", eth_set_ipaddr, NULL, 0); + dev_add_param(dev, "serverip", eth_set_ipaddr, NULL, 0); edev->init(edev); @@ -182,21 +176,7 @@ int eth_register(struct eth_device *edev) void eth_unregister(struct eth_device *edev) { - if (edev->param_ip.value) - free(edev->param_ip.value); - if (edev->param_ethaddr.value) - free(edev->param_ethaddr.value); - if (edev->param_gateway.value) - free(edev->param_gateway.value); - if (edev->param_netmask.value) - free(edev->param_netmask.value); - if (edev->param_serverip.value) - free(edev->param_serverip.value); - - if (eth_current == edev) { - eth_current->halt(eth_current); - eth_current = NULL; - } + dev_remove_parameters(&edev->dev); list_del(&edev->list); } From 56d0e7f2747937ce5d5e1c7ca83add159d8d9534 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 26 May 2010 10:34:05 +0200 Subject: [PATCH 22/65] errno: add strings for network related error messages Signed-off-by: Sascha Hauer --- common/misc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/common/misc.c b/common/misc.c index b3292d312..7edf536ba 100644 --- a/common/misc.c +++ b/common/misc.c @@ -56,6 +56,10 @@ const char *strerror(int errnum) case ENAMETOOLONG : str = "File name too long"; break; case ENOSYS : str = "Function not implemented"; break; case ENOTEMPTY : str = "Directory not empty"; break; + case EHOSTUNREACH : str = "No route to host"; break; + case EINTR : str = "Interrupted system call"; break; + case ENETUNREACH : str = "Network is unreachable"; break; + case ENETDOWN : str = "Network is down"; break; #if 0 /* These are probably not needed */ case ENOTBLK : str = "Block device required"; break; case EFBIG : str = "File too large"; break; @@ -79,8 +83,6 @@ const char *strerror(int errnum) case EAFNOSUPPORT : str = "Address family not supported by protocol"; break; case EADDRINUSE : str = "Address already in use"; break; case EADDRNOTAVAIL : str = "Cannot assign requested address"; break; - case ENETDOWN : str = "Network is down"; break; - case ENETUNREACH : str = "Network is unreachable"; break; case ENETRESET : str = "Network dropped connection because of reset"; break; case ECONNABORTED : str = "Software caused connection abort"; break; case ECONNRESET : str = "Connection reset by peer"; break; @@ -88,7 +90,6 @@ const char *strerror(int errnum) case ETIMEDOUT : str = "Connection timed out"; break; case ECONNREFUSED : str = "Connection refused"; break; case EHOSTDOWN : str = "Host is down"; break; - case EHOSTUNREACH : str = "No route to host"; break; case EALREADY : str = "Operation already in progress"; break; case EINPROGRESS : str = "Operation now in progress"; break; case ESTALE : str = "Stale NFS file handle"; break; From 232b46996c039e3a01bb8774fb9148616d94d8e9 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 3 Jun 2010 13:01:31 +0200 Subject: [PATCH 23/65] add netconsole support Signed-off-by: Sascha Hauer --- Documentation/users_manual.dox | 1 + Doxyfile | 3 +- net/Kconfig | 7 + net/Makefile | 1 + net/netconsole.c | 228 +++++++++++++++++++++++++++++++++ 5 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 net/netconsole.c diff --git a/Documentation/users_manual.dox b/Documentation/users_manual.dox index 5467bee47..cd2b99cd4 100644 --- a/Documentation/users_manual.dox +++ b/Documentation/users_manual.dox @@ -11,5 +11,6 @@ work easier. @li @subpage command_reference @li @subpage partitions @li @subpage x86_bootloader +@li @subpage net_netconsole */ diff --git a/Doxyfile b/Doxyfile index 94dd6ae0d..40bcb2f97 100644 --- a/Doxyfile +++ b/Doxyfile @@ -485,7 +485,8 @@ INPUT = Documentation \ common \ board \ lib \ - scripts/setupmbr + scripts/setupmbr \ + net # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default diff --git a/net/Kconfig b/net/Kconfig index a110beceb..faf2c286c 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -18,4 +18,11 @@ config NET_PING config NET_TFTP bool prompt "tftp support" + +config NET_NETCONSOLE + bool + prompt "network console support" + help + This option adds support for a simple udp based network console. + endif diff --git a/net/Makefile b/net/Makefile index bba6f0e46..e42a484f2 100644 --- a/net/Makefile +++ b/net/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_NET) += net.o obj-$(CONFIG_NET_NFS) += nfs.o obj-$(CONFIG_NET_TFTP) += tftp.o obj-$(CONFIG_NET_PING) += ping.o +obj-$(CONFIG_NET_NETCONSOLE) += netconsole.o diff --git a/net/netconsole.c b/net/netconsole.c new file mode 100644 index 000000000..07e6a6cf2 --- /dev/null +++ b/net/netconsole.c @@ -0,0 +1,228 @@ +/* + * netconsole.c - network console support + * + * Copyright (c) 2010 Sascha Hauer , Pengutronix + * + * 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 version 2 + * as published by the Free Software Foundation. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @file + * @brief Network console support + */ + +struct nc_priv { + struct console_device cdev; + struct kfifo *fifo; + int busy; + struct net_connection *con; + + uint16_t port; + IPaddr_t ip; +}; + +static struct nc_priv *g_priv; + +static void nc_handler(char *pkt, unsigned len) +{ + struct nc_priv *priv = g_priv; + unsigned char *packet = net_eth_to_udp_payload(pkt); + + kfifo_put(priv->fifo, packet, net_eth_to_udplen(pkt)); +} + +static int nc_init(void) +{ + struct nc_priv *priv = g_priv; + + if (priv->con) + net_unregister(priv->con); + + priv->con = net_udp_new(priv->ip, priv->port, nc_handler); + if (IS_ERR(priv->con)) { + int ret = PTR_ERR(priv->con); + priv->con = NULL; + return ret; + } + + net_udp_bind(priv->con, priv->port); + priv->cdev.f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR; + return 0; +} + +static int nc_getc(struct console_device *cdev) +{ + struct nc_priv *priv = container_of(cdev, + struct nc_priv, cdev); + unsigned char c; + + while (!kfifo_len(priv->fifo)) + net_poll(); + + kfifo_getc(priv->fifo, &c); + + return c; +} + +static int nc_tstc(struct console_device *cdev) +{ + struct nc_priv *priv = container_of(cdev, + struct nc_priv, cdev); + + if (priv->busy) + return kfifo_len(priv->fifo) ? 1 : 0; + + net_poll(); + + return kfifo_len(priv->fifo) ? 1 : 0; +} + +static void nc_putc(struct console_device *cdev, char c) +{ + struct nc_priv *priv = container_of(cdev, + struct nc_priv, cdev); + unsigned char *packet; + + if (!priv->con) + return; + + if (priv->busy) + return; + + packet = net_udp_get_payload(priv->con); + *packet = c; + + priv->busy = 1; + net_udp_send(priv->con, 1); + priv->busy = 0; +} + +static int nc_setbaudrate(struct console_device *cdev, int baudrate) +{ + return 0; +} + +static int nc_port_set(struct device_d *dev, struct param_d *param, + const char *val) +{ + struct nc_priv *priv = g_priv; + char portstr[16]; + int port; + + if (!val) + dev_param_set_generic(dev, param, NULL); + + port = simple_strtoul(val, NULL, 10); + if (port > 65535) + return -EINVAL; + + priv->port = port; + nc_init(); + + sprintf(portstr, "%d", port); + dev_param_set_generic(dev, param, portstr); + + return 0; +} + +static int nc_remoteip_set(struct device_d *dev, struct param_d *param, + const char *val) +{ + struct nc_priv *priv = g_priv; + IPaddr_t ip; + int ret; + + if (!val) + dev_param_set_generic(dev, param, NULL); + + if (string_to_ip(val, &ip)) + return -EINVAL; + + priv->ip = ip; + ret = nc_init(); + if (ret) + return ret; + + dev_param_set_generic(dev, param, val); + + return 0; +} + +static int netconsole_init(void) +{ + struct nc_priv *priv; + struct console_device *cdev; + + priv = xzalloc(sizeof(*priv)); + cdev = &priv->cdev; + cdev->tstc = nc_tstc; + cdev->putc = nc_putc; + cdev->getc = nc_getc; + cdev->setbrg = nc_setbaudrate; + + g_priv = priv; + + priv->fifo = kfifo_alloc(1024); + + console_register(cdev); + + dev_add_param(&cdev->class_dev, "ip", nc_remoteip_set, NULL, 0); + dev_add_param(&cdev->class_dev, "port", nc_port_set, NULL, 0); + dev_set_param(&cdev->class_dev, "port", "6666"); + + printf("registered netconsole as %s%d\n", cdev->class_dev.name, cdev->class_dev.id); + + return 0; +} + +device_initcall(netconsole_init); + +/** @page net_netconsole Network console + +@section net_netconsole Using an UDP based network console + +If enabled barebox supports a console via udp networking. There is only +one network console supported registered during init time. It is deactivated +by default because it opens great security holes, so use with care. + +To use the network console you have to configure the remote ip and the local +and remote ports. Assuming the network console is registered as cs1, it can be +configured with: + +@code +cs1.ip= +cs1.port= +cs1.active=ioe +@endcode + +On the remote host call scripts/netconsole with bareboxes ip and port as +parameters. port is initialized to 6666 by default. + +*/ From cd81aa6e3b9181ffdbd8d91770407fa5f9e47aee Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 8 Jun 2010 13:11:40 +0200 Subject: [PATCH 24/65] net: add dns support Signed-off-by: Sascha Hauer --- include/net.h | 11 +++ net/Kconfig | 4 + net/Makefile | 1 + net/dns.c | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 280 insertions(+) create mode 100644 net/dns.c diff --git a/include/net.h b/include/net.h index 15106a782..8db83d830 100644 --- a/include/net.h +++ b/include/net.h @@ -274,6 +274,17 @@ int setenv_ip(const char *name, IPaddr_t ip); int string_to_ethaddr(const char *str, char *enetaddr); void ethaddr_to_string(const unsigned char *enetaddr, char *str); +#ifdef CONFIG_NET_RESOLV +IPaddr_t resolv(char *host); +#else +static inline IPaddr_t resolv(char *host) +{ + IPaddr_t ip = 0; + string_to_ip(host, &ip); + return ip; +} +#endif + /** * is_zero_ether_addr - Determine if give Ethernet address is all zeros. * @addr: Pointer to a six-byte array containing the Ethernet address diff --git a/net/Kconfig b/net/Kconfig index faf2c286c..ff6e45523 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -25,4 +25,8 @@ config NET_NETCONSOLE help This option adds support for a simple udp based network console. +config NET_RESOLV + bool + prompt "dns support" + endif diff --git a/net/Makefile b/net/Makefile index e42a484f2..66dc564da 100644 --- a/net/Makefile +++ b/net/Makefile @@ -4,4 +4,5 @@ obj-$(CONFIG_NET) += net.o obj-$(CONFIG_NET_NFS) += nfs.o obj-$(CONFIG_NET_TFTP) += tftp.o obj-$(CONFIG_NET_PING) += ping.o +obj-$(CONFIG_NET_RESOLV)+= dns.o obj-$(CONFIG_NET_NETCONSOLE) += netconsole.o diff --git a/net/dns.c b/net/dns.c new file mode 100644 index 000000000..1ee270b67 --- /dev/null +++ b/net/dns.c @@ -0,0 +1,264 @@ +/* + * DNS support driver + * + * Copyright (c) 2008 Pieter Voorthuijsen + * Copyright (c) 2009 Robin Getz + * + * This is a simple DNS implementation for U-Boot. It will use the first IP + * in the DNS response as NetServerIP. This can then be used for any other + * network related activities. + * + * The packet handling is partly based on TADNS, original copyrights + * follow below. + * + */ + +/* + * Copyright (c) 2004-2005 Sergey Lyubka + * + * "THE BEER-WARE LICENSE" (Revision 42): + * Sergey Lyubka wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. + */ +//#define DEBUG +#include +#include +#include +#include +#include +#include + +#define DNS_PORT 53 + +/* http://en.wikipedia.org/wiki/List_of_DNS_record_types */ +enum dns_query_type { + DNS_A_RECORD = 0x01, + DNS_CNAME_RECORD = 0x05, + DNS_MX_RECORD = 0x0f, +}; + +/* + * DNS network packet + */ +struct header { + uint16_t tid; /* Transaction ID */ + uint16_t flags; /* Flags */ + uint16_t nqueries; /* Questions */ + uint16_t nanswers; /* Answers */ + uint16_t nauth; /* Authority PRs */ + uint16_t nother; /* Other PRs */ + unsigned char data[1]; /* Data, variable length */ +}; + +#define STATE_INIT 0 +#define STATE_DONE 1 + +static struct net_connection *dns_con; +static uint64_t dns_timer_start; +static int dns_state; +static IPaddr_t dns_ip; + +static int dns_send(char *name) +{ + int ret; + struct header *header; + enum dns_query_type qtype = DNS_A_RECORD; + unsigned char *packet = net_udp_get_payload(dns_con); + unsigned char *p, *s, *fullname, *dotptr; + const unsigned char *domain; + + /* Prepare DNS packet header */ + header = (struct header *)packet; + header->tid = 1; + header->flags = htons(0x100); /* standard query */ + header->nqueries = htons(1); /* Just one query */ + header->nanswers = 0; + header->nauth = 0; + header->nother = 0; + + domain = getenv("domainname"); + + if (!strchr(name, '.') && domain && *domain) + fullname = asprintf(".%s.%s.", name, domain); + else + fullname = asprintf(".%s.", name); + + /* replace dots in fullname with chunk len */ + dotptr = fullname; + do { + int len; + + s = strchr(dotptr + 1, '.'); + + len = s - dotptr - 1; + + *dotptr = len; + dotptr = s; + } while (*(dotptr + 1)); + *dotptr = 0; +//memory_display(fullname, 0, strlen(fullname), 1); + strcpy(header->data, fullname); + + p = header->data + strlen(fullname); + + *p++ = 0; /* Mark end of host name */ + *p++ = 0; /* Some servers require double null */ + *p++ = (unsigned char)qtype; /* Query Type */ + + *p++ = 0; + *p++ = 1; /* Class: inet, 0x0001 */ + + ret = net_udp_send(dns_con, p - packet); + + free(fullname); + + return ret; +} + +static void dns_handler(char *packet, unsigned len) +{ + struct header *header; + unsigned char *p, *e, *s; + u16 type; + int found, stop, dlen; + short tmp; + + debug("%s\n", __func__); + + /* We sent 1 query. We want to see more that 1 answer. */ + header = (struct header *)net_eth_to_udp_payload(packet);; + if (ntohs(header->nqueries) != 1) + return; + + /* Received 0 answers */ + if (header->nanswers == 0) { + dns_state = STATE_DONE; + debug("DNS server returned no answers\n"); + return; + } + + /* Skip host name */ + s = &header->data[0]; + e = packet + len; + for (p = s; p < e && *p != '\0'; p++) + continue; + + /* We sent query class 1, query type 1 */ + tmp = p[1] | (p[2] << 8); + if (&p[5] > e || ntohs(tmp) != DNS_A_RECORD) { + debug("DNS response was not A record\n"); + return; + } + + /* Go to the first answer section */ + p += 5; + + /* Loop through the answers, we want A type answer */ + for (found = stop = 0; !stop && &p[12] < e; ) { + + /* Skip possible name in CNAME answer */ + if (*p != 0xc0) { + while (*p && &p[12] < e) + p++; + p--; + } + debug("Name (Offset in header): %d\n", p[1]); + + tmp = p[2] | (p[3] << 8); + type = ntohs(tmp); + debug("type = %d\n", type); + if (type == DNS_CNAME_RECORD) { + /* CNAME answer. shift to the next section */ + debug("Found canonical name\n"); + tmp = p[10] | (p[11] << 8); + dlen = ntohs(tmp); + debug("dlen = %d\n", dlen); + p += 12 + dlen; + } else if (type == DNS_A_RECORD) { + debug("Found A-record\n"); + found = stop = 1; + } else { + debug("Unknown type\n"); + stop = 1; + } + } + + if (found && &p[12] < e) { + + tmp = p[10] | (p[11] << 8); + dlen = ntohs(tmp); + p += 12; + dns_ip = net_read_ip(p); + dns_state = STATE_DONE; + } +} + +IPaddr_t resolv(char *host) +{ + IPaddr_t ip; + + if (!string_to_ip(host, &ip)) + return ip; + + dns_ip = 0; + + dns_state = STATE_INIT; + + ip = getenv_ip("nameserver"); + if (!ip) + return 0; + + debug("resolving host %s via nameserver %s\n", host, getenv("nameserver")); + + dns_con = net_udp_new(ip, DNS_PORT, dns_handler); + if (IS_ERR(dns_con)) + return PTR_ERR(dns_con); + dns_timer_start = get_time_ns(); + dns_send(host); + + while (dns_state != STATE_DONE) { + if (ctrlc()) { + break; + } + net_poll(); + if (is_timeout(dns_timer_start, SECOND)) { + dns_timer_start = get_time_ns(); + printf("T "); + dns_send(host); + } + } + + net_unregister(dns_con); + + return dns_ip; +} + +static int do_host(struct command *cmdtp, int argc, char *argv[]) +{ + IPaddr_t ip; + + if (argc != 2) + return COMMAND_ERROR_USAGE; + + ip = resolv(argv[1]); + if (!ip) + printf("unknown host %s\n", argv[1]); + else { + printf("%s is at ", argv[1]); + print_IPaddr(ip); + printf("\n"); + } + + return 0; +} + +static const __maybe_unused char cmd_host_help[] = +"Usage: host \n"; + +BAREBOX_CMD_START(host) + .cmd = do_host, + .usage = "resolve a hostname", + BAREBOX_CMD_HELP(cmd_host_help) +BAREBOX_CMD_END + From c5de3fdcce291a9049a03f86f0553032f5068916 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 8 Jun 2010 13:12:01 +0200 Subject: [PATCH 25/65] ping: resolv hostnames Signed-off-by: Sascha Hauer --- net/ping.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/ping.c b/net/ping.c index 0f9868eb6..440e229ba 100644 --- a/net/ping.c +++ b/net/ping.c @@ -57,9 +57,15 @@ int do_ping(struct command *cmdtp, int argc, char *argv[]) int ret; uint64_t ping_start = 0; - if (argc < 2 || string_to_ip(argv[1], &net_ping_ip)) + if (argc < 2) return COMMAND_ERROR_USAGE; + net_ping_ip = resolv(argv[1]); + if (!net_ping_ip) { + printf("unknown host %s\n", argv[1]); + return 1; + } + ping_con = net_icmp_new(net_ping_ip, ping_handler); if (IS_ERR(ping_con)) { ret = PTR_ERR(ping_con); From 9c827f121ac9073d58ab12c1901f5cd24406794d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Jun 2010 14:22:56 +0200 Subject: [PATCH 26/65] pcm037: Add MMU support Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 2 ++ board/pcm037/pcm037.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 18a9cbcdb..0cf6334f0 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -210,7 +210,9 @@ choice config MACH_PCM037 bool "phyCORE-i.MX31" select MACH_HAS_LOWLEVEL_INIT + select HAVE_MMU select USB_ISP1504 if USB + select ARCH_HAS_L2X0 help Say Y here if you are using Phytec's phyCORE-i.MX31 (pcm037) equipped with a Freescale i.MX31 Processor diff --git a/board/pcm037/pcm037.c b/board/pcm037/pcm037.c index aee40c6c2..2e6968b84 100644 --- a/board/pcm037/pcm037.c +++ b/board/pcm037/pcm037.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +118,7 @@ static struct device_d sdram1_dev = { struct imx_nand_platform_data nand_info = { .width = 1, .hw_ecc = 1, + .flash_bbt = 1, }; static struct device_d nand_dev = { @@ -226,8 +228,37 @@ static void pcm037_usb_init(void) } #endif +#ifdef CONFIG_MMU +static void pcm037_mmu_init(void) +{ + mmu_init(); + + arm_create_section(0x80000000, 0x80000000, 128, PMD_SECT_DEF_CACHED); + arm_create_section(0x90000000, 0x80000000, 128, PMD_SECT_DEF_UNCACHED); + + setup_dma_coherent(0x10000000); + +#if TEXT_BASE & (0x100000 - 1) +#warning cannot create vector section. Adjust TEXT_BASE to a 1M boundary +#else + arm_create_section(0x0, TEXT_BASE, 1, PMD_SECT_DEF_UNCACHED); +#endif + mmu_enable(); + +#ifdef CONFIG_CACHE_L2X0 + l2x0_init((void __iomem *)0x30000000, 0x00030024, 0x00000000); +#endif +} +#else +static void pcm037_mmu_init(void) +{ +} +#endif + static int imx31_devices_init(void) { + pcm037_mmu_init(); + __REG(CSCR_U(0)) = 0x0000cf03; /* CS0: Nor Flash */ __REG(CSCR_L(0)) = 0x10000d03; __REG(CSCR_A(0)) = 0x00720900; From 72861584e33759ca4b531a47702d04ddbf730548 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 11 Jun 2010 09:54:15 +0200 Subject: [PATCH 27/65] bootu: Allow passing in devices as parameter Signed-off-by: Sascha Hauer --- arch/arm/lib/armlinux.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c index 75c65195b..a38c6bf65 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -332,15 +332,21 @@ BAREBOX_CMD_END #ifdef CONFIG_CMD_BOOTU static int do_bootu(struct command *cmdtp, int argc, char *argv[]) { - void (*theKernel)(int zero, int arch, void *params); + void (*theKernel)(int zero, int arch, void *params) = NULL; const char *commandline = getenv("bootargs"); + int fd; if (argc != 2) { barebox_cmd_usage(cmdtp); return 1; } - theKernel = (void *)simple_strtoul(argv[1], NULL, 0); + fd = open(argv[1], O_RDONLY); + if (fd > 0) + theKernel = (void *)memmap(fd, PROT_READ); + + if (!theKernel) + theKernel = (void *)simple_strtoul(argv[1], NULL, 0); setup_start_tag(); setup_memory_tags(); From 600c0e987e3a03c383dfb0c3ffe57c12d366cb1b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 11 Jun 2010 14:09:51 +0200 Subject: [PATCH 28/65] Allow to merge default environment from more than one directory Signed-off-by: Sascha Hauer --- Makefile | 15 --------------- common/Kconfig | 4 ++-- common/Makefile | 5 +++-- scripts/genenv | 17 +++++++++++++++++ 4 files changed, 22 insertions(+), 19 deletions(-) create mode 100755 scripts/genenv diff --git a/Makefile b/Makefile index d17ca47ff..e24ae45a6 100644 --- a/Makefile +++ b/Makefile @@ -1299,18 +1299,3 @@ Makefile: ; # information in a variable se we can use it in if_changed and friends. .PHONY: $(PHONY) -# -# sanity checks for check default environemnt -# -ifdef CONFIG_DEFAULT_ENVIRONMENT - -ifeq ($(CONFIG_DEFAULT_ENVIRONMENT_PATH),"") -$(error default environment path empty)) -endif - -saved-env_path := $(CONFIG_DEFAULT_ENVIRONMENT_PATH) -CONFIG_DEFAULT_ENVIRONMENT_PATH := $(shell cd $(if $(filter /%,$(CONFIG_DEFAULT_ENVIRONMENT_PATH)),,$(srctree)/)$(CONFIG_DEFAULT_ENVIRONMENT_PATH) && /bin/pwd) -$(if $(CONFIG_DEFAULT_ENVIRONMENT_PATH),, \ - $(error default environment path $(saved-env_path) does not exist)) - -endif # ifdef CONFIG_DEFAULT_ENVIRONMENT diff --git a/common/Kconfig b/common/Kconfig index f5147597f..a58f242ff 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -339,8 +339,8 @@ config DEFAULT_ENVIRONMENT_PATH depends on DEFAULT_ENVIRONMENT prompt "Default environment path" help - The path the default environment will be taken from. Relative - pathes will be relative to the barebox Toplevel dir, but absolute + Space separated list of pathes the default environment will be taken from. + Relative pathes will be relative to the barebox Toplevel dir, but absolute pathes are fine aswell. endmenu diff --git a/common/Makefile b/common/Makefile index 0c075a960..8b8686db1 100644 --- a/common/Makefile +++ b/common/Makefile @@ -22,9 +22,10 @@ ifdef CONFIG_DEFAULT_ENVIRONMENT $(obj)/startup.o: include/barebox_default_env.h $(obj)/env.o: include/barebox_default_env.h -ENV_FILES := $(shell find $(srctree)/$(CONFIG_DEFAULT_ENVIRONMENT_PATH)) +ENV_FILES := $(shell cd $(srctree); for i in $(CONFIG_DEFAULT_ENVIRONMENT_PATH); do find $${i} -type f -exec readlink -f {} \;; done) + endif # ifdef CONFIG_DEFAULT_ENVIRONMENT include/barebox_default_env.h: $(ENV_FILES) - $(Q)scripts/bareboxenv -s $(srctree)/$(CONFIG_DEFAULT_ENVIRONMENT_PATH) barebox_default_env + $(Q)scripts/genenv $(srctree) $(CONFIG_DEFAULT_ENVIRONMENT_PATH) $(Q)cat barebox_default_env | scripts/bin2c default_environment > $@ diff --git a/scripts/genenv b/scripts/genenv new file mode 100755 index 000000000..6a833b161 --- /dev/null +++ b/scripts/genenv @@ -0,0 +1,17 @@ +#!/bin/bash + +# Generate the default environment file from a list of directories +# usage: genenv ... +# where is the base directory for relative pathes in +cd $1 || exit 1 +shift + +tempdir=$(mktemp -d) + +for i in $*; do + cp -r $i/* $tempdir +done +scripts/bareboxenv -s $tempdir barebox_default_env + +rm -r $tempdir + From 738d70e430b0f4cb9ac71d2811b3f6a4c74abbf6 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 11 Jun 2010 14:10:36 +0200 Subject: [PATCH 29/65] include support for a simple pseudo number generator Signed-off-by: Sascha Hauer --- include/net.h | 1 + include/stdlib.h | 16 ++++++++++++++++ lib/Makefile | 1 + lib/random.c | 26 ++++++++++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 include/stdlib.h create mode 100644 lib/random.c diff --git a/include/net.h b/include/net.h index 8db83d830..709e76c89 100644 --- a/include/net.h +++ b/include/net.h @@ -16,6 +16,7 @@ #include #include #include +#include #include /* for nton* / ntoh* stuff */ diff --git a/include/stdlib.h b/include/stdlib.h new file mode 100644 index 000000000..dc720132e --- /dev/null +++ b/include/stdlib.h @@ -0,0 +1,16 @@ +#ifndef __STDLIB_H +#define __STDLIB_H + +#define RAND_MAX 32767 + +/* return a pseudo-random integer in the range [0, RAND_MAX] */ +unsigned int rand(void); + +/* set the seed for rand () */ +void srand(unsigned int seed); + +/* fill a buffer with pseudo-random data */ +void get_random_bytes(char *buf, int len); + + +#endif /* __STDLIB_H */ diff --git a/lib/Makefile b/lib/Makefile index b072fb6be..4a33aaa3c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o obj-y += glob.o obj-y += notifier.o obj-y += copy_file.o +obj-y += random.o obj-y += lzo/ obj-$(CONFIG_LZO_DECOMPRESS) += decompress_unlzo.o obj-$(CONFIG_PROCESS_ESCAPE_SEQUENCE) += process_escape_sequence.o diff --git a/lib/random.c b/lib/random.c new file mode 100644 index 000000000..352d6bf3f --- /dev/null +++ b/lib/random.c @@ -0,0 +1,26 @@ +#include +#include + +static unsigned int random_seed; + +#if RAND_MAX > 32767 +#error this rand implementation is for RAND_MAX < 32678 only. +#endif + +unsigned int rand(void) +{ + random_seed = random_seed * 1103515245 + 12345; + return (random_seed / 65536) % (RAND_MAX + 1); +} + +void srand(unsigned int seed) +{ + random_seed = seed; +} + +void get_random_bytes(char *buf, int len) +{ + while (len--) + *buf++ = rand() % 256; +} + From 7867ceb8dc5c4d2c64d337aa130c57a05d9b556a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 11 Jun 2010 14:11:12 +0200 Subject: [PATCH 30/65] net: implement random_ether_addr Signed-off-by: Sascha Hauer --- include/net.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/net.h b/include/net.h index 709e76c89..c695e5f72 100644 --- a/include/net.h +++ b/include/net.h @@ -17,6 +17,7 @@ #include #include #include +#include #include /* for nton* / ntoh* stuff */ @@ -331,6 +332,21 @@ static inline int is_broadcast_ether_addr(const u8 *addr) return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff; } +/** + * random_ether_addr - Generate software assigned random Ethernet address + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Generate a random Ethernet address (MAC) that is not multicast + * and has the local assigned bit set. + */ +static inline void random_ether_addr(u8 *addr) +{ + srand(get_time_ns()); + get_random_bytes(addr, 6); + addr [0] &= 0xfe; /* clear multicast bit */ + addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ +} + /** * is_valid_ether_addr - Determine if the given Ethernet address is valid * @addr: Pointer to a six-byte array containing the Ethernet address From e7048e1862a16866766a3584fe946012a206c110 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 11 Jun 2010 14:12:12 +0200 Subject: [PATCH 31/65] net: use a random mac address if the current device does not have a valid address Signed-off-by: Sascha Hauer --- net/net.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/net/net.c b/net/net.c index 4305c727f..8d9959520 100644 --- a/net/net.c +++ b/net/net.c @@ -345,12 +345,21 @@ static LIST_HEAD(connection_list); static struct net_connection *net_new(IPaddr_t dest, rx_handler_f *handler) { + struct eth_device *edev = eth_get_current(); struct net_connection *con; int ret; - if (!is_valid_ether_addr(net_ether)) + if (!edev) return ERR_PTR(-ENETDOWN); + if (!is_valid_ether_addr(net_ether)) { + char str[sizeof("xx:xx:xx:xx:xx:xx")]; + random_ether_addr(net_ether); + ethaddr_to_string(net_ether, str); + printf("warning: No MAC address set. Using random address %s\n", str); + dev_set_param(&edev->dev, "ethaddr", str); + } + /* If we don't have an ip only broadcast is allowed */ if (!net_ip && dest != 0xffffffff) return ERR_PTR(-ENETDOWN); From c56830349b6af5a45e25f73dd24457131f42928e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 11 Jun 2010 14:14:30 +0200 Subject: [PATCH 32/65] add a generic default environment We have several nearly identical default environments in the tree. Lets merge them to a single environment and use it on many boards. This defaultenv is arm centric at the moment due to the use of arm specific boot commands. This can be improved over time. changes since last version: - fix potentially empty variable tests - be a bit more verbose in boot script - run a board specific init script (/env/bin/init_board) if it exists Signed-off-by: Sascha Hauer --- defaultenv/bin/_update | 39 +++++++++++++ defaultenv/bin/boot | 109 +++++++++++++++++++++++++++++++++++ defaultenv/bin/hush_hack | 1 + defaultenv/bin/init | 34 +++++++++++ defaultenv/bin/update_kernel | 15 +++++ defaultenv/bin/update_rootfs | 16 +++++ 6 files changed, 214 insertions(+) create mode 100644 defaultenv/bin/_update create mode 100644 defaultenv/bin/boot create mode 100644 defaultenv/bin/hush_hack create mode 100644 defaultenv/bin/init create mode 100644 defaultenv/bin/update_kernel create mode 100644 defaultenv/bin/update_rootfs diff --git a/defaultenv/bin/_update b/defaultenv/bin/_update new file mode 100644 index 000000000..ddd6b84f7 --- /dev/null +++ b/defaultenv/bin/_update @@ -0,0 +1,39 @@ +#!/bin/sh + +if [ -z "$part" -o -z "$image" ]; then + echo "define \$part and \$image" + exit 1 +fi + +if [ ! -e "$part" ]; then + echo "Partition $part does not exist" + exit 1 +fi + +if [ $# = 1 ]; then + image=$1 +fi + +if [ x$ip = xdhcp ]; then + dhcp +fi + +ping $eth0.serverip +if [ $? -ne 0 ] ; then + echo "Server did not reply! Update aborted." + exit 1 +fi + +unprotect $part + +echo +echo "erasing partition $part" +echo +erase $part + +echo +echo "flashing $image to $part" +echo +tftp $image $part + +protect $part diff --git a/defaultenv/bin/boot b/defaultenv/bin/boot new file mode 100644 index 000000000..6a508fbda --- /dev/null +++ b/defaultenv/bin/boot @@ -0,0 +1,109 @@ +#!/bin/sh + +. /env/config + +if [ x$1 = xnand ]; then + rootfs_loc=nand + kernel_loc=nand +elif [ x$1 = xnor ]; then + rootfs_loc=nor + kernel_loc=nor +elif [ x$1 = xnet ]; then + rootfs_loc=net + kernel_loc=net +fi + +if [ x$ip = xdhcp ]; then + bootargs="$bootargs ip=dhcp" +elif [ x$ip = xnone ]; then + bootargs="ip=none" +else + bootargs="$bootargs ip=$eth0.ipaddr::$eth0.gateway:$eth0.netmask:::" +fi + + +if [ x$rootfs_loc = xnet ]; then + bootargs="$bootargs root=/dev/nfs nfsroot=$nfsroot,v3,tcp noinitrd" +elif [ x$rootfs_loc = xinitrd ]; then + bootargs="$bootargs root=/dev/ram0 rdinit=/sbin/init" +else + if [ x$rootfs_loc = xnand ]; then + rootfs_mtdblock=$rootfs_mtdblock_nand + else + rootfs_mtdblock=$rootfs_mtdblock_nor + fi + + if [ x$rootfs_type = xubifs ]; then + bootargs="$bootargs root=ubi0:root ubi.mtd=$rootfs_mtdblock" + else + bootargs="$bootargs root=/dev/mtdblock$rootfs_mtdblock" + fi + + bootargs="$bootargs rootfstype=$rootfs_type noinitrd" +fi + +if [ -n $nor_parts ]; then + mtdparts="${mtdparts}physmap-flash.o:${nor_parts};" +fi + +if [ -n $nand_parts ]; then + mtdparts="${mtdparts}$nand_device:${nor_parts};" +fi + +if [ -n $mtdparts ]; then + bootargs="${bootargs} mtdparts=\"${mtdparts}\"" +fi + +if [ ! -e /dev/ram0.kernelraw ]; then + # arm raw kernel images are usually located at sdram start + 0x8000 + addpart dev/ram0 8M@0x8000(kernelraw) +fi + +if [ ! -e /dev/ram0.kernel ]; then + # Here we can safely put the kernel without risking of overwriting it + # while extracting + addpart dev/ram0 8M(kernel) +fi + +if [ x$kernel_loc = xnet ]; then + if [ x$ip = xdhcp ]; then + dhcp + fi + if [ $kernelimage_type = uimage ]; then + netload="/dev/ram0.kernel" + elif [ $kernelimage_type = zimage ]; then + netload="/dev/ram0.kernel" + elif [ $kernelimage_type = raw ]; then + netload="/dev/ram0.kernelraw" + elif [ $kernelimage_type = raw_lzo ]; then + netload="/dev/ram0.kernel" + else + echo "error: set kernelimage_type to one of 'uimage', 'zimage', 'raw' or 'raw_lzo'" + exit 1 + fi + tftp $kernelimage $netload || exit 1 + kdev="$netload" +elif [ x$kernel_loc = xnor ]; then + kdev="/dev/nor0.kernel" +elif [ x$kernel_loc = xnand ]; then + kdev="/dev/nand0.kernel.bb" +else + echo "error: set kernel_loc to one of 'net', 'nand' or 'nor'" + exit 1 +fi + +echo "booting kernel of type $kernelimage_type from $kdev" + +if [ x$kernelimage_type = xuimage ]; then + bootm $kdev +elif [ x$kernelimage_type = xzimage ]; then + bootz $kdev +elif [ x$kernelimage_type = xraw ]; then + if [ $kernel_loc != net ]; then + cp $kdev /dev/ram0.kernelraw + fi + bootu /dev/ram0.kernelraw +elif [ x$kernelimage_type = xraw_lzo ]; then + unlzo $kdev /dev/ram0.kernelraw + bootu /dev/ram0.kernelraw +fi diff --git a/defaultenv/bin/hush_hack b/defaultenv/bin/hush_hack new file mode 100644 index 000000000..5fffa92ec --- /dev/null +++ b/defaultenv/bin/hush_hack @@ -0,0 +1 @@ +nand -a /dev/nand0.* diff --git a/defaultenv/bin/init b/defaultenv/bin/init new file mode 100644 index 000000000..a55e8e60a --- /dev/null +++ b/defaultenv/bin/init @@ -0,0 +1,34 @@ +#!/bin/sh + +PATH=/env/bin +export PATH + +. /env/config +if [ -e /dev/nor0 ]; then + addpart /dev/nor0 $nor_parts +fi + +if [ -e /dev/nand0 ]; then + addpart /dev/nand0 $nand_parts + + # Uh, oh, hush first expands wildcards and then starts executing + # commands. What a bug! + source /env/bin/hush_hack +fi + +if [ -f /env/bin/init_board ]; then + /env/bin/init_board +fi + +echo +echo -n "Hit any key to stop autoboot: " +timeout -a $autoboot_timeout +if [ $? != 0 ]; then + echo + echo "type update_kernel nand|nor [] to update kernel into flash" + echo "type update_rootfs nand|nor [] to update rootfs into flash" + echo + exit +fi + +boot diff --git a/defaultenv/bin/update_kernel b/defaultenv/bin/update_kernel new file mode 100644 index 000000000..1d35ed972 --- /dev/null +++ b/defaultenv/bin/update_kernel @@ -0,0 +1,15 @@ +#!/bin/sh + +. /env/config +image=$kernelimage + +if [ x$1 = xnand ]; then + part=/dev/nand0.kernel.bb +elif [ x$1 = xnor ]; then + part=/dev/nor0.kernel +else + echo "usage: $0 nor|nand [imagename]" + exit 1 +fi + +. /env/bin/_update $2 diff --git a/defaultenv/bin/update_rootfs b/defaultenv/bin/update_rootfs new file mode 100644 index 000000000..63663150c --- /dev/null +++ b/defaultenv/bin/update_rootfs @@ -0,0 +1,16 @@ +#!/bin/sh + +. /env/config + +image=$rootfsimage + +if [ x$1 = xnand ]; then + part=/dev/nand0.root.bb +elif [ x$1 = xnor ]; then + part=/dev/nor0.root +else + echo "usage: $0 nor|nand [imagename]" + exit 1 +fi + +. /env/bin/_update $2 From 3dc4dedb71dae9abca7376d38144098e05ec202f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 11 Jun 2010 14:17:29 +0200 Subject: [PATCH 33/65] pcm038: use generic default env Signed-off-by: Sascha Hauer --- arch/arm/configs/pcm038_defconfig | 2 +- board/pcm038/env/bin/_update | 36 ----------------- board/pcm038/env/bin/boot | 47 ---------------------- board/pcm038/env/bin/hush_hack | 1 - board/pcm038/env/bin/init | 37 ------------------ board/pcm038/env/bin/update_kernel | 15 -------- board/pcm038/env/bin/update_root | 16 -------- board/pcm038/env/config | 62 ++++++++++++++++++++++-------- 8 files changed, 46 insertions(+), 170 deletions(-) delete mode 100644 board/pcm038/env/bin/_update delete mode 100644 board/pcm038/env/bin/boot delete mode 100644 board/pcm038/env/bin/hush_hack delete mode 100644 board/pcm038/env/bin/init delete mode 100644 board/pcm038/env/bin/update_kernel delete mode 100644 board/pcm038/env/bin/update_root diff --git a/arch/arm/configs/pcm038_defconfig b/arch/arm/configs/pcm038_defconfig index 0c9ac5fef..a80089cd4 100644 --- a/arch/arm/configs/pcm038_defconfig +++ b/arch/arm/configs/pcm038_defconfig @@ -110,7 +110,7 @@ CONFIG_CONSOLE_ACTIVATE_FIRST=y # CONFIG_OF_FLAT_TREE is not set CONFIG_PARTITION=y CONFIG_DEFAULT_ENVIRONMENT=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="board/pcm038/env" +CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv board/pcm038/env" # # Debugging diff --git a/board/pcm038/env/bin/_update b/board/pcm038/env/bin/_update deleted file mode 100644 index 014bce351..000000000 --- a/board/pcm038/env/bin/_update +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -if [ -z "$part" -o -z "$image" ]; then - echo "define \$part and \$image" - exit 1 -fi - -if [ ! -e "$part" ]; then - echo "Partition $part does not exist" - exit 1 -fi - -if [ $# = 1 ]; then - image=$1 -fi - -if [ x$ip = xdhcp ]; then - dhcp -fi - -ping $eth0.serverip -if [ $? -ne 0 ] ; then - echo "update aborted" - exit 1 -fi - -unprotect $part - -echo -echo "erasing partition $part" -erase $part - -echo -echo "flashing $image to $part" -echo -tftp $image $part diff --git a/board/pcm038/env/bin/boot b/board/pcm038/env/bin/boot deleted file mode 100644 index dfb59aa69..000000000 --- a/board/pcm038/env/bin/boot +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh - -. /env/config - -if [ x$1 = xnand ]; then - root=nand - kernel=nand -fi - -if [ x$1 = xnet ]; then - root=net - kernel=net -fi - -if [ x$1 = xnor ]; then - root=nor - kernel=nor -fi - -if [ x$ip = xdhcp ]; then - bootargs="$bootargs ip=dhcp" -else - bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::" -fi - -if [ x$root = xnand ]; then - bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2" -elif [ x$root = xnor ]; then - bootargs="$bootargs root=$rootpart_nor rootfstype=jffs2" -else - bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp" -fi - -bootargs="$bootargs mtdparts=physmap-flash.0:$nor_parts;imx_nand:$nand_parts" - -if [ $kernel = net ]; then - if [ x$ip = xdhcp ]; then - dhcp - fi - tftp $uimage uImage || exit 1 - bootm uImage -elif [ $kernel = nor ]; then - bootm /dev/nor0.kernel -else - bootm /dev/nand0.kernel.bb -fi - diff --git a/board/pcm038/env/bin/hush_hack b/board/pcm038/env/bin/hush_hack deleted file mode 100644 index 5fffa92ec..000000000 --- a/board/pcm038/env/bin/hush_hack +++ /dev/null @@ -1 +0,0 @@ -nand -a /dev/nand0.* diff --git a/board/pcm038/env/bin/init b/board/pcm038/env/bin/init deleted file mode 100644 index 3bfd19491..000000000 --- a/board/pcm038/env/bin/init +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -PATH=/env/bin -export PATH - -. /env/config -if [ -e /dev/nor0 ]; then - addpart /dev/nor0 $nor_parts -fi - -if [ -e /dev/nand0 ]; then - addpart /dev/nand0 $nand_parts - - # Uh, oh, hush first expands wildcards and then starts executing - # commands. What a bug! - source /env/bin/hush_hack -fi - -if [ -z $eth0.ethaddr ]; then - while [ -z $eth0.ethaddr ]; do - readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr - done - echo -a /env/config "eth0.ethaddr=$eth0.ethaddr" -fi - -echo -echo -n "Hit any key to stop autoboot: " -timeout -a $autoboot_timeout -if [ $? != 0 ]; then - echo - echo "type update_kernel nand|nor [] to update kernel into flash" - echo "type update_root nand|nor [] to update rootfs into flash" - echo - exit -fi - -boot diff --git a/board/pcm038/env/bin/update_kernel b/board/pcm038/env/bin/update_kernel deleted file mode 100644 index 05c822d86..000000000 --- a/board/pcm038/env/bin/update_kernel +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -if [ x$1 = xnand ]; then - part=/dev/nand0.kernel.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.kernel -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 diff --git a/board/pcm038/env/bin/update_root b/board/pcm038/env/bin/update_root deleted file mode 100644 index eaf36ebce..000000000 --- a/board/pcm038/env/bin/update_root +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -if [ x$1 = xnand ]; then - part=/dev/nand0.root.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.root -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 - diff --git a/board/pcm038/env/config b/board/pcm038/env/config index 9fcb3dc7b..a8be5c924 100644 --- a/board/pcm038/env/config +++ b/board/pcm038/env/config @@ -1,24 +1,11 @@ #!/bin/sh -# can be either 'net', 'nor' or 'nand'' -kernel=net -root=net - -uimage=uImage-pcm038 -jffs2=root-pcm038.jffs2 - -autoboot_timeout=3 - -nfsroot="/ptx/work/octopus/rsc/svn/oselas/bsp/phytec/phyCORE-i.MX27/OSELAS.BSP-Phytec-phyCORE-i.MX27-trunk/root" -bootargs="console=ttymxc0,115200" - -nor_parts="256k(barebox)ro,128k(bareboxenv),1536k(kernel),-(root)" -rootpart_nor="/dev/mtdblock3" - -nand_parts="256k(barebox)ro,128k(bareboxenv),1536k(kernel),-(root)" -rootpart_nand="/dev/mtdblock7" +machine=pcm038 +eth0.serverip= +user= # use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration ip=dhcp # or set your networking parameters here @@ -26,3 +13,44 @@ ip=dhcp #eth0.netmask=a.b.c.d #eth0.gateway=a.b.c.d #eth0.serverip=a.b.c.d + +# can be either 'net', 'nor' or 'nand' +kernel_loc=net +# can be either 'net', 'nor', 'nand' or 'initrd' +rootfs_loc=net + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root-$machine.$rootfs_type + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +kernelimage_type=zimage +kernelimage=zImage-$machine +#kernelimage_type=uimage +#kernelimage=uImage-$machine +#kernelimage_type=raw +#kernelimage=Image-$machine +#kernelimage_type=raw_lzo +#kernelimage=Image-$machine.lzo + +if [ -n $user ]; then + kernelimage="$user"-"$kernelimage" + nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine" + rootfsimage="$user"-"$rootfsimage" +else + nfsroot="$eth0.serverip:/path/to/nfs/root" +fi + +autoboot_timeout=3 + +bootargs="console=ttymxc0,115200" + +nor_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nor=3 + +nand_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nand=7 + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " + From 4666c09f1cd3b485e67d09f802fe93a8f36bf4aa Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 11 Jun 2010 14:18:54 +0200 Subject: [PATCH 34/65] pcm043: use generic default env Signed-off-by: Sascha Hauer --- arch/arm/configs/pcm043_defconfig | 2 +- board/pcm043/env/bin/_update | 36 ---------------- board/pcm043/env/bin/boot | 47 -------------------- board/pcm043/env/bin/hush_hack | 1 - board/pcm043/env/bin/init | 37 ---------------- board/pcm043/env/bin/update_kernel | 15 ------- board/pcm043/env/bin/update_root | 16 ------- board/pcm043/env/config | 69 +++++++++++++++++++++--------- 8 files changed, 50 insertions(+), 173 deletions(-) delete mode 100644 board/pcm043/env/bin/_update delete mode 100644 board/pcm043/env/bin/boot delete mode 100644 board/pcm043/env/bin/hush_hack delete mode 100644 board/pcm043/env/bin/init delete mode 100644 board/pcm043/env/bin/update_kernel delete mode 100644 board/pcm043/env/bin/update_root diff --git a/arch/arm/configs/pcm043_defconfig b/arch/arm/configs/pcm043_defconfig index 556335607..72a8a4291 100644 --- a/arch/arm/configs/pcm043_defconfig +++ b/arch/arm/configs/pcm043_defconfig @@ -109,7 +109,7 @@ CONFIG_CONSOLE_ACTIVATE_FIRST=y # CONFIG_OF_FLAT_TREE is not set CONFIG_PARTITION=y CONFIG_DEFAULT_ENVIRONMENT=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="board/pcm043/env/" +CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv board/pcm043/env" # # Debugging diff --git a/board/pcm043/env/bin/_update b/board/pcm043/env/bin/_update deleted file mode 100644 index 014bce351..000000000 --- a/board/pcm043/env/bin/_update +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -if [ -z "$part" -o -z "$image" ]; then - echo "define \$part and \$image" - exit 1 -fi - -if [ ! -e "$part" ]; then - echo "Partition $part does not exist" - exit 1 -fi - -if [ $# = 1 ]; then - image=$1 -fi - -if [ x$ip = xdhcp ]; then - dhcp -fi - -ping $eth0.serverip -if [ $? -ne 0 ] ; then - echo "update aborted" - exit 1 -fi - -unprotect $part - -echo -echo "erasing partition $part" -erase $part - -echo -echo "flashing $image to $part" -echo -tftp $image $part diff --git a/board/pcm043/env/bin/boot b/board/pcm043/env/bin/boot deleted file mode 100644 index 7bbff2d1f..000000000 --- a/board/pcm043/env/bin/boot +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh - -. /env/config - -if [ x$1 = xnand ]; then - root=nand - kernel=nand -fi - -if [ x$1 = xnet ]; then - root=net - kernel=net -fi - -if [ x$1 = xnor ]; then - root=nor - kernel=nor -fi - -if [ x$ip = xdhcp ]; then - bootargs="$bootargs ip=dhcp" -else - bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::" -fi - -if [ x$root = xnand ]; then - bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2" -elif [ x$root = xnor ]; then - bootargs="$bootargs root=$rootpart_nor rootfstype=jffs2" -else - bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp" -fi - -bootargs="$bootargs mtdparts=physmap-flash.0:$nor_parts;mxc_nand:$nand_parts" - -if [ $kernel = net ]; then - if [ x$ip = xdhcp ]; then - dhcp - fi - tftp $uimage uImage || exit 1 - bootm uImage -elif [ $kernel = nor ]; then - bootm /dev/nor0.kernel -else - bootm /dev/nand0.kernel.bb -fi - diff --git a/board/pcm043/env/bin/hush_hack b/board/pcm043/env/bin/hush_hack deleted file mode 100644 index 5fffa92ec..000000000 --- a/board/pcm043/env/bin/hush_hack +++ /dev/null @@ -1 +0,0 @@ -nand -a /dev/nand0.* diff --git a/board/pcm043/env/bin/init b/board/pcm043/env/bin/init deleted file mode 100644 index 3bfd19491..000000000 --- a/board/pcm043/env/bin/init +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -PATH=/env/bin -export PATH - -. /env/config -if [ -e /dev/nor0 ]; then - addpart /dev/nor0 $nor_parts -fi - -if [ -e /dev/nand0 ]; then - addpart /dev/nand0 $nand_parts - - # Uh, oh, hush first expands wildcards and then starts executing - # commands. What a bug! - source /env/bin/hush_hack -fi - -if [ -z $eth0.ethaddr ]; then - while [ -z $eth0.ethaddr ]; do - readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr - done - echo -a /env/config "eth0.ethaddr=$eth0.ethaddr" -fi - -echo -echo -n "Hit any key to stop autoboot: " -timeout -a $autoboot_timeout -if [ $? != 0 ]; then - echo - echo "type update_kernel nand|nor [] to update kernel into flash" - echo "type update_root nand|nor [] to update rootfs into flash" - echo - exit -fi - -boot diff --git a/board/pcm043/env/bin/update_kernel b/board/pcm043/env/bin/update_kernel deleted file mode 100644 index 05c822d86..000000000 --- a/board/pcm043/env/bin/update_kernel +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -if [ x$1 = xnand ]; then - part=/dev/nand0.kernel.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.kernel -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 diff --git a/board/pcm043/env/bin/update_root b/board/pcm043/env/bin/update_root deleted file mode 100644 index eaf36ebce..000000000 --- a/board/pcm043/env/bin/update_root +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -if [ x$1 = xnand ]; then - part=/dev/nand0.root.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.root -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 - diff --git a/board/pcm043/env/config b/board/pcm043/env/config index c1ab234e6..212b6a9cd 100644 --- a/board/pcm043/env/config +++ b/board/pcm043/env/config @@ -1,29 +1,58 @@ #!/bin/sh -# can be either 'net', 'nor' or 'nand'' -kernel=nor -root=nor - -uimage=uImage-pcm043 -jffs2=root-pcm043.jffs2 - -autoboot_timeout=3 - -nfsroot="/path/to/nfs_root" -bootargs="console=ttymxc0,115200" - -nor_parts="256k(barebox)ro,128k(bareboxenv),2048k(kernel),-(root)" -rootpart_nor="/dev/mtdblock3" -nand_parts="256k(barebox)ro,128k(bareboxenv),2048k(kernel),-(root)" -rootpart_nand="/dev/mtdblock3" +machine=pcm043 +eth0.serverip= +user= # use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration ip=dhcp # or set your networking parameters here -eth0.ipaddr=192.168.3.11 -eth0.netmask=255.255.255.0 +#eth0.ipaddr=a.b.c.d +#eth0.netmask=a.b.c.d #eth0.gateway=a.b.c.d -#eth0.serverip=192.168.3.10 -#eth0.ethaddr=aa.bb.cc.dd.ee.ff +#eth0.serverip=a.b.c.d + +# can be either 'net', 'nor' or 'nand' +kernel_loc=net +# can be either 'net', 'nor', 'nand' or 'initrd' +rootfs_loc=net + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root-$machine.$rootfs_type + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +kernelimage_type=zimage +kernelimage=zImage-$machine +#kernelimage_type=uimage +#kernelimage=uImage-$machine +#kernelimage_type=raw +#kernelimage=Image-$machine +#kernelimage_type=raw_lzo +#kernelimage=Image-$machine.lzo + +if [ -n $user ]; then + kernelimage="$user"-"$kernelimage" + nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine" + rootfsimage="$user"-"$rootfsimage" +else + nfsroot="$eth0.serverip:/path/to/nfs/root" +fi + +autoboot_timeout=3 + +bootargs="console=ttymxc0,115200" + +bootargs="$bootargs video=mx3fb:CTP-CLAA070LC0ACW" + +nor_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nor=3 + +nand_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nand=7 + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " From dc4d0da985c839fd9ba38fec03dc7fbc7556968a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Jun 2010 11:19:15 +0200 Subject: [PATCH 35/65] pcm037: use generic default env Signed-off-by: Sascha Hauer --- arch/arm/configs/pcm037_defconfig | 2 +- board/pcm037/env/bin/_update | 36 ----------------- board/pcm037/env/bin/boot | 47 ---------------------- board/pcm037/env/bin/hush_hack | 1 - board/pcm037/env/bin/init | 37 ------------------ board/pcm037/env/bin/update_kernel | 15 -------- board/pcm037/env/bin/update_root | 16 -------- board/pcm037/env/config | 62 ++++++++++++++++++++++-------- 8 files changed, 46 insertions(+), 170 deletions(-) delete mode 100644 board/pcm037/env/bin/_update delete mode 100644 board/pcm037/env/bin/boot delete mode 100644 board/pcm037/env/bin/hush_hack delete mode 100644 board/pcm037/env/bin/init delete mode 100644 board/pcm037/env/bin/update_kernel delete mode 100644 board/pcm037/env/bin/update_root diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig index e82733f4e..9353d0e54 100644 --- a/arch/arm/configs/pcm037_defconfig +++ b/arch/arm/configs/pcm037_defconfig @@ -106,7 +106,7 @@ CONFIG_CONSOLE_ACTIVATE_FIRST=y # CONFIG_OF_FLAT_TREE is not set CONFIG_PARTITION=y CONFIG_DEFAULT_ENVIRONMENT=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="board/pcm037/env" +CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv board/pcm037/env" # # Debugging diff --git a/board/pcm037/env/bin/_update b/board/pcm037/env/bin/_update deleted file mode 100644 index 014bce351..000000000 --- a/board/pcm037/env/bin/_update +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -if [ -z "$part" -o -z "$image" ]; then - echo "define \$part and \$image" - exit 1 -fi - -if [ ! -e "$part" ]; then - echo "Partition $part does not exist" - exit 1 -fi - -if [ $# = 1 ]; then - image=$1 -fi - -if [ x$ip = xdhcp ]; then - dhcp -fi - -ping $eth0.serverip -if [ $? -ne 0 ] ; then - echo "update aborted" - exit 1 -fi - -unprotect $part - -echo -echo "erasing partition $part" -erase $part - -echo -echo "flashing $image to $part" -echo -tftp $image $part diff --git a/board/pcm037/env/bin/boot b/board/pcm037/env/bin/boot deleted file mode 100644 index dfb59aa69..000000000 --- a/board/pcm037/env/bin/boot +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh - -. /env/config - -if [ x$1 = xnand ]; then - root=nand - kernel=nand -fi - -if [ x$1 = xnet ]; then - root=net - kernel=net -fi - -if [ x$1 = xnor ]; then - root=nor - kernel=nor -fi - -if [ x$ip = xdhcp ]; then - bootargs="$bootargs ip=dhcp" -else - bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::" -fi - -if [ x$root = xnand ]; then - bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2" -elif [ x$root = xnor ]; then - bootargs="$bootargs root=$rootpart_nor rootfstype=jffs2" -else - bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp" -fi - -bootargs="$bootargs mtdparts=physmap-flash.0:$nor_parts;imx_nand:$nand_parts" - -if [ $kernel = net ]; then - if [ x$ip = xdhcp ]; then - dhcp - fi - tftp $uimage uImage || exit 1 - bootm uImage -elif [ $kernel = nor ]; then - bootm /dev/nor0.kernel -else - bootm /dev/nand0.kernel.bb -fi - diff --git a/board/pcm037/env/bin/hush_hack b/board/pcm037/env/bin/hush_hack deleted file mode 100644 index 5fffa92ec..000000000 --- a/board/pcm037/env/bin/hush_hack +++ /dev/null @@ -1 +0,0 @@ -nand -a /dev/nand0.* diff --git a/board/pcm037/env/bin/init b/board/pcm037/env/bin/init deleted file mode 100644 index 3bfd19491..000000000 --- a/board/pcm037/env/bin/init +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -PATH=/env/bin -export PATH - -. /env/config -if [ -e /dev/nor0 ]; then - addpart /dev/nor0 $nor_parts -fi - -if [ -e /dev/nand0 ]; then - addpart /dev/nand0 $nand_parts - - # Uh, oh, hush first expands wildcards and then starts executing - # commands. What a bug! - source /env/bin/hush_hack -fi - -if [ -z $eth0.ethaddr ]; then - while [ -z $eth0.ethaddr ]; do - readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr - done - echo -a /env/config "eth0.ethaddr=$eth0.ethaddr" -fi - -echo -echo -n "Hit any key to stop autoboot: " -timeout -a $autoboot_timeout -if [ $? != 0 ]; then - echo - echo "type update_kernel nand|nor [] to update kernel into flash" - echo "type update_root nand|nor [] to update rootfs into flash" - echo - exit -fi - -boot diff --git a/board/pcm037/env/bin/update_kernel b/board/pcm037/env/bin/update_kernel deleted file mode 100644 index 05c822d86..000000000 --- a/board/pcm037/env/bin/update_kernel +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -if [ x$1 = xnand ]; then - part=/dev/nand0.kernel.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.kernel -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 diff --git a/board/pcm037/env/bin/update_root b/board/pcm037/env/bin/update_root deleted file mode 100644 index eaf36ebce..000000000 --- a/board/pcm037/env/bin/update_root +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -if [ x$1 = xnand ]; then - part=/dev/nand0.root.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.root -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 - diff --git a/board/pcm037/env/config b/board/pcm037/env/config index fb1f5afdd..bf1562005 100644 --- a/board/pcm037/env/config +++ b/board/pcm037/env/config @@ -1,24 +1,11 @@ #!/bin/sh -# can be either 'net', 'nor' or 'nand'' -kernel=net -root=net - -uimage=uImage-pcm037 -jffs2=root-pcm037.jffs2 - -autoboot_timeout=3 - -nfsroot="/ptx/work/octopus/rsc/svn/oselas/bsp/phytec/phyCORE-i.MX27/OSELAS.BSP-Phytec-phyCORE-i.MX27-trunk/root" -bootargs="console=ttymxc0,115200" - -nor_parts="256k(barebox)ro,128k(bareboxenv),1536k(kernel),-(root)" -rootpart_nor="/dev/mtdblock3" - -nand_parts="256k(barebox)ro,128k(bareboxenv),1536k(kernel),-(root)" -rootpart_nand="/dev/mtdblock7" +machine=pcm037 +eth0.serverip= +user= # use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration ip=dhcp # or set your networking parameters here @@ -26,3 +13,44 @@ ip=dhcp #eth0.netmask=a.b.c.d #eth0.gateway=a.b.c.d #eth0.serverip=a.b.c.d + +# can be either 'net', 'nor' or 'nand' +kernel_loc=net +# can be either 'net', 'nor', 'nand' or 'initrd' +rootfs_loc=net + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root-$machine.$rootfs_type + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +kernelimage_type=zimage +kernelimage=zImage-$machine +#kernelimage_type=uimage +#kernelimage=uImage-$machine +#kernelimage_type=raw +#kernelimage=Image-$machine +#kernelimage_type=raw_lzo +#kernelimage=Image-$machine.lzo + +if [ -n $user ]; then + kernelimage="$user"-"$kernelimage" + nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine" + rootfsimage="$user"-"$rootfsimage" +else + nfsroot="$eth0.serverip:/path/to/nfs/root" +fi + +autoboot_timeout=3 + +bootargs="console=ttymxc0,115200" + +nor_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nor=3 + +nand_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nand=7 + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " + From 334fe1dc8a1b866d1f0f4ccf82ff7b06589ec022 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Jun 2010 11:20:04 +0200 Subject: [PATCH 36/65] pca100: use generic default env Signed-off-by: Sascha Hauer --- arch/arm/configs/pca100_defconfig | 2 +- board/phycard-i.MX27/env/bin/_update | 36 -------------- board/phycard-i.MX27/env/bin/boot | 40 --------------- board/phycard-i.MX27/env/bin/hush_hack | 1 - board/phycard-i.MX27/env/bin/init | 37 -------------- board/phycard-i.MX27/env/bin/update_kernel | 15 ------ board/phycard-i.MX27/env/bin/update_root | 16 ------ board/phycard-i.MX27/env/config | 57 ++++++++++++++++------ 8 files changed, 44 insertions(+), 160 deletions(-) delete mode 100644 board/phycard-i.MX27/env/bin/_update delete mode 100644 board/phycard-i.MX27/env/bin/boot delete mode 100644 board/phycard-i.MX27/env/bin/hush_hack delete mode 100644 board/phycard-i.MX27/env/bin/init delete mode 100644 board/phycard-i.MX27/env/bin/update_kernel delete mode 100644 board/phycard-i.MX27/env/bin/update_root diff --git a/arch/arm/configs/pca100_defconfig b/arch/arm/configs/pca100_defconfig index f0a951244..52a5d93bb 100644 --- a/arch/arm/configs/pca100_defconfig +++ b/arch/arm/configs/pca100_defconfig @@ -110,7 +110,7 @@ CONFIG_CONSOLE_ACTIVATE_FIRST=y # CONFIG_OF_FLAT_TREE is not set CONFIG_PARTITION=y CONFIG_DEFAULT_ENVIRONMENT=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="board/phycard-i.MX27/env/" +CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv board/phycard-i.MX27/env" # # Debugging diff --git a/board/phycard-i.MX27/env/bin/_update b/board/phycard-i.MX27/env/bin/_update deleted file mode 100644 index 014bce351..000000000 --- a/board/phycard-i.MX27/env/bin/_update +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -if [ -z "$part" -o -z "$image" ]; then - echo "define \$part and \$image" - exit 1 -fi - -if [ ! -e "$part" ]; then - echo "Partition $part does not exist" - exit 1 -fi - -if [ $# = 1 ]; then - image=$1 -fi - -if [ x$ip = xdhcp ]; then - dhcp -fi - -ping $eth0.serverip -if [ $? -ne 0 ] ; then - echo "update aborted" - exit 1 -fi - -unprotect $part - -echo -echo "erasing partition $part" -erase $part - -echo -echo "flashing $image to $part" -echo -tftp $image $part diff --git a/board/phycard-i.MX27/env/bin/boot b/board/phycard-i.MX27/env/bin/boot deleted file mode 100644 index 56a03775a..000000000 --- a/board/phycard-i.MX27/env/bin/boot +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -. /env/config - -if [ x$1 = xnand ]; then - root=nand - kernel=nand -fi - -if [ x$1 = xnet ]; then - root=net - kernel=net -fi - -if [ x$ip = xdhcp ]; then - bootargs="$bootargs ip=dhcp" -else - bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask:::" -fi - -if [ x$root = xnand ]; then - bootargs="$bootargs root=$rootpart_nand rootfstype=jffs2" -else - bootargs="$bootargs root=/dev/nfs nfsroot=$eth0.serverip:$nfsroot,v3,tcp" -fi - -bootargs="$bootargs mtdparts=mxc_nand:$nand_parts" - -if [ $kernel = net ]; then - if [ x$ip = xdhcp ]; then - dhcp - fi - tftp $uimage uImage || exit 1 - bootm uImage -elif [ $kernel = nor ]; then - bootm /dev/nor0.kernel -else - bootm /dev/nand0.kernel.bb -fi - diff --git a/board/phycard-i.MX27/env/bin/hush_hack b/board/phycard-i.MX27/env/bin/hush_hack deleted file mode 100644 index 5fffa92ec..000000000 --- a/board/phycard-i.MX27/env/bin/hush_hack +++ /dev/null @@ -1 +0,0 @@ -nand -a /dev/nand0.* diff --git a/board/phycard-i.MX27/env/bin/init b/board/phycard-i.MX27/env/bin/init deleted file mode 100644 index 3bfd19491..000000000 --- a/board/phycard-i.MX27/env/bin/init +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -PATH=/env/bin -export PATH - -. /env/config -if [ -e /dev/nor0 ]; then - addpart /dev/nor0 $nor_parts -fi - -if [ -e /dev/nand0 ]; then - addpart /dev/nand0 $nand_parts - - # Uh, oh, hush first expands wildcards and then starts executing - # commands. What a bug! - source /env/bin/hush_hack -fi - -if [ -z $eth0.ethaddr ]; then - while [ -z $eth0.ethaddr ]; do - readline "no MAC address set for eth0. please enter the one found on your board: " eth0.ethaddr - done - echo -a /env/config "eth0.ethaddr=$eth0.ethaddr" -fi - -echo -echo -n "Hit any key to stop autoboot: " -timeout -a $autoboot_timeout -if [ $? != 0 ]; then - echo - echo "type update_kernel nand|nor [] to update kernel into flash" - echo "type update_root nand|nor [] to update rootfs into flash" - echo - exit -fi - -boot diff --git a/board/phycard-i.MX27/env/bin/update_kernel b/board/phycard-i.MX27/env/bin/update_kernel deleted file mode 100644 index 05c822d86..000000000 --- a/board/phycard-i.MX27/env/bin/update_kernel +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -if [ x$1 = xnand ]; then - part=/dev/nand0.kernel.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.kernel -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 diff --git a/board/phycard-i.MX27/env/bin/update_root b/board/phycard-i.MX27/env/bin/update_root deleted file mode 100644 index eaf36ebce..000000000 --- a/board/phycard-i.MX27/env/bin/update_root +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -. /env/config - -image=$uimage -if [ x$1 = xnand ]; then - part=/dev/nand0.root.bb -elif [ x$1 = xnor ]; then - part=/dev/nor0.root -else - echo "usage: $0 nor|nand [imagename]" - exit 1 -fi - -. /env/bin/_update $2 - diff --git a/board/phycard-i.MX27/env/config b/board/phycard-i.MX27/env/config index 6a93580da..d0670dec2 100644 --- a/board/phycard-i.MX27/env/config +++ b/board/phycard-i.MX27/env/config @@ -1,21 +1,11 @@ #!/bin/sh -# can be either 'net', 'nor' or 'nand'' -kernel=net -root=net - -uimage=uImage-pca100 -jffs2=root-pca100.jffs2 - -autoboot_timeout=3 - -nfsroot="/tmp/root" -bootargs="console=ttymxc0,115200" - -nand_parts="256k(barebox)ro,128k(bareboxenv),1536k(kernel),-(root)" -rootpart_nand="/dev/mtdblock3" +machine=pca100 +eth0.serverip= +user= # use 'dhcp' to do dhcp in barebox and in kernel +# use 'none' if you want to skip kernel ip autoconfiguration ip=dhcp # or set your networking parameters here @@ -23,3 +13,42 @@ ip=dhcp #eth0.netmask=a.b.c.d #eth0.gateway=a.b.c.d #eth0.serverip=a.b.c.d + +# can be either 'net', 'nor' or 'nand' +kernel_loc=net +# can be either 'net', 'nor', 'nand' or 'initrd' +rootfs_loc=net + +# can be either 'jffs2' or 'ubifs' +rootfs_type=ubifs +rootfsimage=root-$machine.$rootfs_type + +# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo +kernelimage_type=zimage +kernelimage=zImage-$machine +#kernelimage_type=uimage +#kernelimage=uImage-$machine +#kernelimage_type=raw +#kernelimage=Image-$machine +#kernelimage_type=raw_lzo +#kernelimage=Image-$machine.lzo + +if [ -n $user ]; then + kernelimage="$user"-"$kernelimage" + nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine" + rootfsimage="$user"-"$rootfsimage" +else + nfsroot="$eth0.serverip:/path/to/nfs/root" +fi + +autoboot_timeout=3 + +bootargs="console=ttymxc0,115200" + +nand_parts="256k(barebox)ro,128k(bareboxenv),2M(kernel),-(root)" +rootfs_mtdblock_nand=7 + +# set a fancy prompt (if support is compiled in) +PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " + + From 6c5f1c0fdfa52fc76dfb392aa13d6059c75f1843 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 16 Jun 2010 14:30:07 +0200 Subject: [PATCH 37/65] i.MX27: merge iomux pim definitions from kernel The Kernel pin definitions are more complete and up to date. Being here we also use seperate files for the iomuxer like the other i.MX SoCs already do. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imx21-regs.h | 33 --- arch/arm/mach-imx/include/mach/imx27-regs.h | 93 -------- arch/arm/mach-imx/include/mach/iomux-mx21.h | 121 ++++++++++ arch/arm/mach-imx/include/mach/iomux-mx27.h | 204 +++++++++++++++++ arch/arm/mach-imx/include/mach/iomux-mx2x.h | 230 ++++++++++++++++++++ board/eukrea_cpuimx27/eukrea_cpuimx27.c | 3 +- board/imx21ads/imx21ads.c | 1 + board/imx27ads/imx27ads.c | 3 +- board/pcm038/pcm038.c | 3 +- board/phycard-i.MX27/pca100.c | 3 +- 10 files changed, 564 insertions(+), 130 deletions(-) create mode 100644 arch/arm/mach-imx/include/mach/iomux-mx21.h create mode 100644 arch/arm/mach-imx/include/mach/iomux-mx27.h create mode 100644 arch/arm/mach-imx/include/mach/iomux-mx2x.h diff --git a/arch/arm/mach-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h index 3d2174995..6d64b811e 100644 --- a/arch/arm/mach-imx/include/mach/imx21-regs.h +++ b/arch/arm/mach-imx/include/mach/imx21-regs.h @@ -115,39 +115,6 @@ #define CCSR_32K_SR (1 << 15) -#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5) -#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6) -#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7) -#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8) -#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9) -#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10) -#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11) -#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12) -#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13) -#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14) -#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15) -#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16) -#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17) -#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18) -#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19) -#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20) -#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21) -#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22) -#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23) -#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24) -#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25) -#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26) -#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27) -#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28) -#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29) -#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30) -#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31) - -#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 12) -#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 13) -#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 14) -#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 15) - /* * Definitions for the clocksource driver */ diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h index 4e2261261..d804a9d7f 100644 --- a/arch/arm/mach-imx/include/mach/imx27-regs.h +++ b/arch/arm/mach-imx/include/mach/imx27-regs.h @@ -232,99 +232,6 @@ #define ESDMISC_MA10_SHARE (1 << 6) #define ESDMISC_SDRAM_RDY (1 << 6) -#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0) -#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1) -#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2) -#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3) -#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4) -#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5) -#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6) -#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7) -#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8) -#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9) -#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10) -#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11) -#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12) -#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13) -#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14) -#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15) -#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16) -#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17) -#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18) -#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19) -#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20) -#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21) -#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22) -#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23) -#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24) -#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25) -#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26) -#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27) -#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28) -#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29) -#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30) -#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31) -#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 0) -#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 1) -#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 2) -#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 3) -#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 4) -#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 5) -#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 6) -#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 7) -#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_IN | GPIO_AF | 8) -#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 9) -#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 10) -#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 11) -#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 12) -#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 13) -#define PD14_AOUT_FEC_CLR (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 14) -#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 15) -#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 16) -#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17) -#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18) -#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19) -#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20) -#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21) -#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22) -#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23) -#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24) -#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25) -#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26) -#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26) -#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27) -#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28) -#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29) -#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_IN | GPIO_PF | 30) -#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_OUT | GPIO_PF | 31) -#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_OUT | GPIO_AIN | 23) -#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 3) -#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 4) -#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 6) -#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 7) -#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 8) -#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 9) -#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 10) -#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 11) -#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 12) -#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 13) -#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 14) -#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 15) -#define PC5_PF_I2C2_DATA (GPIO_PORTC | GPIO_OUT | GPIO_PF | 5) -#define PC6_PF_I2C2_CLK (GPIO_PORTC | GPIO_OUT | GPIO_PF | 6) -#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7) -#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8) -#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9) -#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10) -#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11) -#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12) -#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13) -#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0) -#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1) -#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2) -#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24) -#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25) - /* * Definitions for the clocksource driver */ diff --git a/arch/arm/mach-imx/include/mach/iomux-mx21.h b/arch/arm/mach-imx/include/mach/iomux-mx21.h new file mode 100644 index 000000000..c7218bce7 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/iomux-mx21.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2009 by Holger Schurig + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#ifndef __MACH_IOMUX_MX21_H__ +#define __MACH_IOMUX_MX21_H__ + +#include + +/* Primary GPIO pin functions */ + +#define PB22_PF_USBH1_BYP (GPIO_PORTB | GPIO_PF | 22) +#define PB25_PF_USBH1_ON (GPIO_PORTB | GPIO_PF | 25) +#define PC5_PF_USBOTG_SDA (GPIO_PORTC | GPIO_PF | 5) +#define PC6_PF_USBOTG_SCL (GPIO_PORTC | GPIO_PF | 6) +#define PC7_PF_USBOTG_ON (GPIO_PORTC | GPIO_PF | 7) +#define PC8_PF_USBOTG_FS (GPIO_PORTC | GPIO_PF | 8) +#define PC9_PF_USBOTG_OE (GPIO_PORTC | GPIO_PF | 9) +#define PC10_PF_USBOTG_TXDM (GPIO_PORTC | GPIO_PF | 10) +#define PC11_PF_USBOTG_TXDP (GPIO_PORTC | GPIO_PF | 11) +#define PC12_PF_USBOTG_RXDM (GPIO_PORTC | GPIO_PF | 12) +#define PC13_PF_USBOTG_RXDP (GPIO_PORTC | GPIO_PF | 13) +#define PC16_PF_SAP_FS (GPIO_PORTC | GPIO_PF | 16) +#define PC17_PF_SAP_RXD (GPIO_PORTC | GPIO_PF | 17) +#define PC18_PF_SAP_TXD (GPIO_PORTC | GPIO_PF | 18) +#define PC19_PF_SAP_CLK (GPIO_PORTC | GPIO_PF | 19) +#define PE0_PF_TEST_WB2 (GPIO_PORTE | GPIO_PF | 0) +#define PE1_PF_TEST_WB1 (GPIO_PORTE | GPIO_PF | 1) +#define PE2_PF_TEST_WB0 (GPIO_PORTE | GPIO_PF | 2) +#define PF1_PF_NFCE (GPIO_PORTF | GPIO_PF | 1) +#define PF3_PF_NFCLE (GPIO_PORTF | GPIO_PF | 3) +#define PF7_PF_NFIO0 (GPIO_PORTF | GPIO_PF | 7) +#define PF8_PF_NFIO1 (GPIO_PORTF | GPIO_PF | 8) +#define PF9_PF_NFIO2 (GPIO_PORTF | GPIO_PF | 9) +#define PF10_PF_NFIO3 (GPIO_PORTF | GPIO_PF | 10) +#define PF11_PF_NFIO4 (GPIO_PORTF | GPIO_PF | 11) +#define PF12_PF_NFIO5 (GPIO_PORTF | GPIO_PF | 12) +#define PF13_PF_NFIO6 (GPIO_PORTF | GPIO_PF | 13) +#define PF14_PF_NFIO7 (GPIO_PORTF | GPIO_PF | 14) +#define PF16_PF_RES (GPIO_PORTF | GPIO_PF | 16) + +/* Alternate GPIO pin functions */ + +#define PA5_AF_BMI_CLK_CS (GPIO_PORTA | GPIO_AF | 5) +#define PA6_AF_BMI_D0 (GPIO_PORTA | GPIO_AF | 6) +#define PA7_AF_BMI_D1 (GPIO_PORTA | GPIO_AF | 7) +#define PA8_AF_BMI_D2 (GPIO_PORTA | GPIO_AF | 8) +#define PA9_AF_BMI_D3 (GPIO_PORTA | GPIO_AF | 9) +#define PA10_AF_BMI_D4 (GPIO_PORTA | GPIO_AF | 10) +#define PA11_AF_BMI_D5 (GPIO_PORTA | GPIO_AF | 11) +#define PA12_AF_BMI_D6 (GPIO_PORTA | GPIO_AF | 12) +#define PA13_AF_BMI_D7 (GPIO_PORTA | GPIO_AF | 13) +#define PA14_AF_BMI_D8 (GPIO_PORTA | GPIO_AF | 14) +#define PA15_AF_BMI_D9 (GPIO_PORTA | GPIO_AF | 15) +#define PA16_AF_BMI_D10 (GPIO_PORTA | GPIO_AF | 16) +#define PA17_AF_BMI_D11 (GPIO_PORTA | GPIO_AF | 17) +#define PA18_AF_BMI_D12 (GPIO_PORTA | GPIO_AF | 18) +#define PA19_AF_BMI_D13 (GPIO_PORTA | GPIO_AF | 19) +#define PA20_AF_BMI_D14 (GPIO_PORTA | GPIO_AF | 20) +#define PA21_AF_BMI_D15 (GPIO_PORTA | GPIO_AF | 21) +#define PA22_AF_BMI_READ_REQ (GPIO_PORTA | GPIO_AF | 22) +#define PA23_AF_BMI_WRITE (GPIO_PORTA | GPIO_AF | 23) +#define PA29_AF_BMI_RX_FULL (GPIO_PORTA | GPIO_AF | 29) +#define PA30_AF_BMI_READ (GPIO_PORTA | GPIO_AF | 30) + +/* AIN GPIO pin functions */ + +#define PC14_AIN_SYS_CLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14) +#define PD21_AIN_USBH2_FS (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 21) +#define PD22_AIN_USBH2_OE (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 22) +#define PD23_AIN_USBH2_TXDM (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 23) +#define PD24_AIN_USBH2_TXDP (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 24) +#define PE8_AIN_IR_TXD (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 8) +#define PF0_AIN_PC_RST (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 0) +#define PF1_AIN_PC_CE1 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 1) +#define PF2_AIN_PC_CE2 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 2) +#define PF3_AIN_PC_POE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 3) +#define PF4_AIN_PC_OE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 4) +#define PF5_AIN_PC_RW (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 5) + +/* BIN GPIO pin functions */ + +#define PC14_BIN_SYS_CLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14) +#define PD27_BIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_BIN | GPIO_OUT | 27) + +/* CIN GPIO pin functions */ + +#define PB26_CIN_USBH1_RXDAT (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 26) + +/* AOUT GPIO pin functions */ + +#define PA29_AOUT_BMI_WAIT (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 29) +#define PD19_AOUT_USBH2_RXDM (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 19) +#define PD20_AOUT_USBH2_RXDP (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 20) +#define PD25_AOUT_EXT_DMAREQ (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 25) +#define PD26_AOUT_USBOTG_RXDAT (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 26) +#define PE9_AOUT_IR_RXD (GPIO_PORTE | GPIO_AOUT | GPIO_IN | 9) +#define PF6_AOUT_PC_BVD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 6) +#define PF7_AOUT_PC_BVD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 7) +#define PF8_AOUT_PC_VS2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 8) +#define PF9_AOUT_PC_VS1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 9) +#define PF10_AOUT_PC_WP (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 10) +#define PF11_AOUT_PC_READY (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 11) +#define PF12_AOUT_PC_WAIT (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 12) +#define PF13_AOUT_PC_CD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 13) +#define PF14_AOUT_PC_CD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 14) + +#endif /* ifndef __MACH_IOMUX_MX21_H__ */ diff --git a/arch/arm/mach-imx/include/mach/iomux-mx27.h b/arch/arm/mach-imx/include/mach/iomux-mx27.h new file mode 100644 index 000000000..993b14104 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/iomux-mx27.h @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2008 by Sascha Hauer + * Copyright (C) 2009 by Holger Schurig + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#ifndef __MACH_IOMUX_MX27_H__ +#define __MACH_IOMUX_MX27_H__ + +#include + +/* Primary GPIO pin functions */ + +#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0) +#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1) +#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2) +#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3) +#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4) +#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22) +#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25) +#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_PF | GPIO_IN | 5) +#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_PF | GPIO_IN | 6) +#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7) +#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8) +#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9) +#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10) +#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11) +#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12) +#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13) +#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 16) +#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 17) +#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 18) +#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 19) +#define PD0_PF_SD3_CMD (GPIO_PORTD | GPIO_PF | 0) +#define PD1_PF_SD3_CLK (GPIO_PORTD | GPIO_PF | 1) +#define PD2_PF_ATA_DATA0 (GPIO_PORTD | GPIO_PF | 2) +#define PD3_PF_ATA_DATA1 (GPIO_PORTD | GPIO_PF | 3) +#define PD4_PF_ATA_DATA2 (GPIO_PORTD | GPIO_PF | 4) +#define PD5_PF_ATA_DATA3 (GPIO_PORTD | GPIO_PF | 5) +#define PD6_PF_ATA_DATA4 (GPIO_PORTD | GPIO_PF | 6) +#define PD7_PF_ATA_DATA5 (GPIO_PORTD | GPIO_PF | 7) +#define PD8_PF_ATA_DATA6 (GPIO_PORTD | GPIO_PF | 8) +#define PD9_PF_ATA_DATA7 (GPIO_PORTD | GPIO_PF | 9) +#define PD10_PF_ATA_DATA8 (GPIO_PORTD | GPIO_PF | 10) +#define PD11_PF_ATA_DATA9 (GPIO_PORTD | GPIO_PF | 11) +#define PD12_PF_ATA_DATA10 (GPIO_PORTD | GPIO_PF | 12) +#define PD13_PF_ATA_DATA11 (GPIO_PORTD | GPIO_PF | 13) +#define PD14_PF_ATA_DATA12 (GPIO_PORTD | GPIO_PF | 14) +#define PD15_PF_ATA_DATA13 (GPIO_PORTD | GPIO_PF | 15) +#define PD16_PF_ATA_DATA14 (GPIO_PORTD | GPIO_PF | 16) +#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0) +#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1) +#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2) +#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24) +#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25) +#define PF1_PF_NFCLE (GPIO_PORTF | GPIO_PF | 1) +#define PF3_PF_NFCE (GPIO_PORTF | GPIO_PF | 3) +#define PF7_PF_PC_POE (GPIO_PORTF | GPIO_PF | 7) +#define PF8_PF_PC_RW (GPIO_PORTF | GPIO_PF | 8) +#define PF9_PF_PC_IOIS16 (GPIO_PORTF | GPIO_PF | 9) +#define PF10_PF_PC_RST (GPIO_PORTF | GPIO_PF | 10) +#define PF11_PF_PC_BVD2 (GPIO_PORTF | GPIO_PF | 11) +#define PF12_PF_PC_BVD1 (GPIO_PORTF | GPIO_PF | 12) +#define PF13_PF_PC_VS2 (GPIO_PORTF | GPIO_PF | 13) +#define PF14_PF_PC_VS1 (GPIO_PORTF | GPIO_PF | 14) +#define PF16_PF_PC_PWRON (GPIO_PORTF | GPIO_PF | 16) +#define PF17_PF_PC_READY (GPIO_PORTF | GPIO_PF | 17) +#define PF18_PF_PC_WAIT (GPIO_PORTF | GPIO_PF | 18) +#define PF19_PF_PC_CD2 (GPIO_PORTF | GPIO_PF | 19) +#define PF20_PF_PC_CD1 (GPIO_PORTF | GPIO_PF | 20) +#define PF23_PF_ATA_DATA15 (GPIO_PORTF | GPIO_PF | 23) + +/* Alternate GPIO pin functions */ + +#define PB4_AF_MSHC_DATA0 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 4) +#define PB5_AF_MSHC_DATA1 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 5) +#define PB6_AF_MSHC_DATA2 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 6) +#define PB7_AF_MSHC_DATA4 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 7) +#define PB8_AF_MSHC_BS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 8) +#define PB9_AF_MSHC_SCLK (GPIO_PORTB | GPIO_AF | GPIO_OUT | 9) +#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 10) +#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 11) +#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 12) +#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 13) +#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 18) +#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 19) +#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 20) +#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 21) +#define PC8_AF_FEC_MDIO (GPIO_PORTC | GPIO_AF | GPIO_IN | 8) +#define PC24_AF_GPT5_TOUT (GPIO_PORTC | GPIO_AF | 24) +#define PC25_AF_GPT5_TIN (GPIO_PORTC | GPIO_AF | 25) +#define PC26_AF_GPT4_TOUT (GPIO_PORTC | GPIO_AF | 26) +#define PC27_AF_GPT4_TIN (GPIO_PORTC | GPIO_AF | 27) +#define PD1_AF_ETMTRACE_PKT15 (GPIO_PORTD | GPIO_AF | 1) +#define PD6_AF_ETMTRACE_PKT14 (GPIO_PORTD | GPIO_AF | 6) +#define PD7_AF_ETMTRACE_PKT13 (GPIO_PORTD | GPIO_AF | 7) +#define PD9_AF_ETMTRACE_PKT12 (GPIO_PORTD | GPIO_AF | 9) +#define PD2_AF_SD3_D0 (GPIO_PORTD | GPIO_AF | 2) +#define PD3_AF_SD3_D1 (GPIO_PORTD | GPIO_AF | 3) +#define PD4_AF_SD3_D2 (GPIO_PORTD | GPIO_AF | 4) +#define PD5_AF_SD3_D3 (GPIO_PORTD | GPIO_AF | 5) +#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_AF | GPIO_IN | 8) +#define PD10_AF_ETMTRACE_PKT11 (GPIO_PORTD | GPIO_AF | 10) +#define PD11_AF_ETMTRACE_PKT10 (GPIO_PORTD | GPIO_AF | 11) +#define PD12_AF_ETMTRACE_PKT9 (GPIO_PORTD | GPIO_AF | 12) +#define PD13_AF_ETMTRACE_PKT8 (GPIO_PORTD | GPIO_AF | 13) +#define PD14_AF_ETMTRACE_PKT7 (GPIO_PORTD | GPIO_AF | 14) +#define PD15_AF_ETMTRACE_PKT6 (GPIO_PORTD | GPIO_AF | 15) +#define PD16_AF_ETMTRACE_PKT5 (GPIO_PORTD | GPIO_AF | 16) +#define PF1_AF_ETMTRACE_PKT0 (GPIO_PORTF | GPIO_AF | 1) +#define PF3_AF_ETMTRACE_PKT2 (GPIO_PORTF | GPIO_AF | 3) +#define PF5_AF_ETMPIPESTAT11 (GPIO_PORTF | GPIO_AF | 5) +#define PF7_AF_ATA_BUFFER_EN (GPIO_PORTF | GPIO_AF | 7) +#define PF8_AF_ATA_IORDY (GPIO_PORTF | GPIO_AF | 8) +#define PF9_AF_ATA_INTRQ (GPIO_PORTF | GPIO_AF | 9) +#define PF10_AF_ATA_RESET (GPIO_PORTF | GPIO_AF | 10) +#define PF11_AF_ATA_DMACK (GPIO_PORTF | GPIO_AF | 11) +#define PF12_AF_ATA_DMAREQ (GPIO_PORTF | GPIO_AF | 12) +#define PF13_AF_ATA_DA0 (GPIO_PORTF | GPIO_AF | 13) +#define PF14_AF_ATA_DA1 (GPIO_PORTF | GPIO_AF | 14) +#define PF15_AF_ETMTRACE_SYNC (GPIO_PORTF | GPIO_AF | 15) +#define PF16_AF_ATA_DA2 (GPIO_PORTF | GPIO_AF | 16) +#define PF17_AF_ATA_CS0 (GPIO_PORTF | GPIO_AF | 17) +#define PF18_AF_ATA_CS1 (GPIO_PORTF | GPIO_AF | 18) +#define PF19_AF_ATA_DIOW (GPIO_PORTF | GPIO_AF | 19) +#define PF20_AF_ATA_DIOR (GPIO_PORTF | GPIO_AF | 20) +#define PF22_AF_ETMTRACE_CLK (GPIO_PORTF | GPIO_AF | 22) +#define PF23_AF_ETMTRACE_PKT4 (GPIO_PORTF | GPIO_AF | 23) + +/* AIN GPIO pin functions */ + +#define PC14_AIN_SSI1_MCLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14) +#define PC15_AIN_GPT6_TOUT (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 15) +#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 0) +#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 1) +#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 2) +#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 3) +#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 9) +#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 16) +#define PD27_AIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 27) +#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 23) + +/* BIN GPIO pin functions */ + +#define PC14_BIN_SSI2_MCLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14) + +/* CIN GPIO pin functions */ + +#define PD2_CIN_SLCDC1_DAT0 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 2) +#define PD3_CIN_SLCDC1_DAT1 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 3) +#define PD4_CIN_SLCDC1_DAT2 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 4) +#define PD5_CIN_SLCDC1_DAT3 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 5) +#define PD6_CIN_SLCDC1_DAT4 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 6) +#define PD7_CIN_SLCDC1_DAT5 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 7) +#define PD8_CIN_SLCDC1_DAT6 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 8) +#define PD9_CIN_SLCDC1_DAT7 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 9) +#define PD10_CIN_SLCDC1_DAT8 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 10) +#define PD11_CIN_SLCDC1_DAT9 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 11) +#define PD12_CIN_SLCDC1_DAT10 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 12) +#define PD13_CIN_SLCDC1_DAT11 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 13) +#define PD14_CIN_SLCDC1_DAT12 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 14) +#define PD15_CIN_SLCDC1_DAT13 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 15) +#define PD16_CIN_SLCDC1_DAT14 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 16) +#define PD23_CIN_SLCDC1_DAT15 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 23) +#define PF27_CIN_EXT_DMA_GRANT (GPIO_PORTF | GPIO_CIN | GPIO_OUT | 27) +/* LCDC_TESTx on PBxx omitted, because it's not clear what they do */ + +/* AOUT GPIO pin functions */ + +#define PC14_AOUT_GPT6_TIN (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 14) +#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 4) +#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 5) +#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 6) +#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 7) +#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 10) +#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 11) +#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 12) +#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 13) +#define PD14_AOUT_FEC_RX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 14) +#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 15) + +/* BOUT GPIO pin functions */ + +#define PC17_BOUT_PC_IOIS16 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 17) +#define PC18_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 18) +#define PC19_BOUT_PC_BVD1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 19) +#define PC28_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 28) +#define PC29_BOUT_PC_VS1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 29) +#define PC30_BOUT_PC_READY (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 30) +#define PC31_BOUT_PC_WAIT (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 31) + +#endif /* __MACH_IOMUX_MX27_H__ */ diff --git a/arch/arm/mach-imx/include/mach/iomux-mx2x.h b/arch/arm/mach-imx/include/mach/iomux-mx2x.h new file mode 100644 index 000000000..c4f116d21 --- /dev/null +++ b/arch/arm/mach-imx/include/mach/iomux-mx2x.h @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2008 by Sascha Hauer + * Copyright (C) 2009 by Holger Schurig + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#ifndef __MACH_IOMUX_MX2x_H__ +#define __MACH_IOMUX_MX2x_H__ + +/* Primary GPIO pin functions */ + +#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5) +#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6) +#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7) +#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8) +#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9) +#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10) +#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11) +#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12) +#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13) +#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14) +#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15) +#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16) +#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17) +#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18) +#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19) +#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20) +#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21) +#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22) +#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23) +#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24) +#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25) +#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26) +#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27) +#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28) +#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29) +#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30) +#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31) +#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4) +#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5) +#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6) +#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7) +#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8) +#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9) +#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 10) +#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 11) +#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 12) +#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 13) +#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 14) +#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 15) +#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 16) +#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 17) +#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 18) +#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 19) +#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 20) +#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 21) +#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23) +#define PB24_PF_USB_OC (GPIO_PORTB | GPIO_PF | 24) +#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26) +#define PB27_PF_USBH1_OE (GPIO_PORTB | GPIO_PF | 27) +#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28) +#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29) +#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30) +#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31) +#define PC14_PF_TOUT (GPIO_PORTC | GPIO_PF | 14) +#define PC15_PF_TIN (GPIO_PORTC | GPIO_PF | 15) +#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 20) +#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 21) +#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 22) +#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 23) +#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 24) +#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 25) +#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 26) +#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 27) +#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 28) +#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 29) +#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 30) +#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31) +#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17) +#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18) +#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | 19) +#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | 20) +#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | 21) +#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | 22) +#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | 23) +#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | 24) +#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25) +#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26) +#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27) +#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28) +#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29) +#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 30) +#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 31) +#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 3) +#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 4) +#define PE5_PF_PWMO (GPIO_PORTE | GPIO_PF | 5) +#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 6) +#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 7) +#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 8) +#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 9) +#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 10) +#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 11) +#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 12) +#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 13) +#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 14) +#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 15) +#define PE16_PF_RTCK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 16) +#define PE17_PF_RESET_OUT (GPIO_PORTE | GPIO_PF | 17) +#define PE18_PF_SD1_D0 (GPIO_PORTE | GPIO_PF | 18) +#define PE19_PF_SD1_D1 (GPIO_PORTE | GPIO_PF | 19) +#define PE20_PF_SD1_D2 (GPIO_PORTE | GPIO_PF | 20) +#define PE21_PF_SD1_D3 (GPIO_PORTE | GPIO_PF | 21) +#define PE22_PF_SD1_CMD (GPIO_PORTE | GPIO_PF | 22) +#define PE23_PF_SD1_CLK (GPIO_PORTE | GPIO_PF | 23) +#define PF0_PF_NRFB (GPIO_PORTF | GPIO_PF | 0) +#define PF2_PF_NFWP (GPIO_PORTF | GPIO_PF | 2) +#define PF4_PF_NFALE (GPIO_PORTF | GPIO_PF | 4) +#define PF5_PF_NFRE (GPIO_PORTF | GPIO_PF | 5) +#define PF6_PF_NFWE (GPIO_PORTF | GPIO_PF | 6) +#define PF15_PF_CLKO (GPIO_PORTF | GPIO_PF | 15) +#define PF21_PF_CS4 (GPIO_PORTF | GPIO_PF | 21) +#define PF22_PF_CS5 (GPIO_PORTF | GPIO_PF | 22) + +/* Alternate GPIO pin functions */ + +#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 26) +#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 28) +#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 29) +#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 31) +#define PC28_AF_SLCDC2_D0 (GPIO_PORTC | GPIO_AF | 28) +#define PC29_AF_SLCDC2_RS (GPIO_PORTC | GPIO_AF | 29) +#define PC30_AF_SLCDC2_CS (GPIO_PORTC | GPIO_AF | 30) +#define PC31_AF_SLCDC2_CLK (GPIO_PORTC | GPIO_AF | 31) +#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19) +#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20) +#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21) +#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22) +#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23) +#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24) +#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26) +#define PE0_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 0) +#define PE1_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 1) +#define PE2_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 2) +#define PE3_AF_KP_COL7 (GPIO_PORTE | GPIO_AF | 3) +#define PE4_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 4) +#define PE6_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 6) +#define PE7_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 7) +#define PE16_AF_OWIRE (GPIO_PORTE | GPIO_AF | 16) +#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_AF | GPIO_IN | 18) +#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_AF | GPIO_OUT | 21) +#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_AF | GPIO_OUT | 22) +#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_AF | GPIO_OUT | 23) + +/* AIN GPIO pin functions */ + +#define PA6_AIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 6) +#define PA7_AIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 7) +#define PA8_AIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 8) +#define PA0_AIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0) +#define PA11_AIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 11) +#define PA13_AIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 13) +#define PA15_AIN_SLCDC1_DAT9 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 15) +#define PA17_AIN_SLCDC1_DAT11 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17) +#define PA19_AIN_SLCDC1_DAT13 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 19) +#define PA21_AIN_SLCDC1_DAT15 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 21) +#define PA22_AIN_EXT_DMAGRANT (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 22) +#define PA24_AIN_SLCDC1_D0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 24) +#define PA25_AIN_SLCDC1_RS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 25) +#define PA26_AIN_SLCDC1_CS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 26) +#define PA27_AIN_SLCDC1_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 27) +#define PB6_AIN_SLCDC1_D0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 6) +#define PB7_AIN_SLCDC1_RS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 7) +#define PB8_AIN_SLCDC1_CS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 8) +#define PB9_AIN_SLCDC1_CLK (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 9) +#define PB25_AIN_SLCDC1_DAT0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 25) +#define PB26_AIN_SLCDC1_DAT1 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 26) +#define PB27_AIN_SLCDC1_DAT2 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 27) +#define PB28_AIN_SLCDC1_DAT3 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 28) +#define PB29_AIN_SLCDC1_DAT4 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 29) +#define PB30_AIN_SLCDC1_DAT5 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 30) +#define PB31_AIN_SLCDC1_DAT6 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 31) +#define PC5_AIN_SLCDC1_DAT7 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 5) +#define PC6_AIN_SLCDC1_DAT8 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 6) +#define PC7_AIN_SLCDC1_DAT9 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 7) +#define PC8_AIN_SLCDC1_DAT10 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 8) +#define PC9_AIN_SLCDC1_DAT11 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 9) +#define PC10_AIN_SLCDC1_DAT12 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 10) +#define PC11_AIN_SLCDC1_DAT13 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 11) +#define PC12_AIN_SLCDC1_DAT14 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 12) +#define PC13_AIN_SLCDC1_DAT15 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 13) +#define PE5_AIN_PC_SPKOUT (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 5) + +/* BIN GPIO pin functions */ + +#define PE5_BIN_TOUT2 (GPIO_PORTE | GPIO_BIN | GPIO_OUT | 5) + +/* CIN GPIO pin functions */ + +#define PA14_CIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 14) +#define PA15_CIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 15) +#define PA16_CIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 16) +#define PA17_CIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 17) +#define PA18_CIN_SLCDC1_DAT4 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 18) +#define PA19_CIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 19) +#define PA20_CIN_SLCDC1_DAT6 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 20) +#define PA21_CIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 21) +#define PB30_CIN_UART4_CTS (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 30) +#define PE5_CIN_TOUT3 (GPIO_PORTE | GPIO_CIN | GPIO_OUT | 5) + +/* AOUT GPIO pin functions */ + +#define PB29_AOUT_UART4_RXD (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 29) +#define PB31_AOUT_UART4_RTS (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 31) +#define PC8_AOUT_USBOTG_TXR_INT (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 8) +#define PC15_AOUT_WKGD (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15) +#define PF21_AOUT_DTACK (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21) + +#endif /* ifndef __MACH_IOMUX_MX2x_H__ */ diff --git a/board/eukrea_cpuimx27/eukrea_cpuimx27.c b/board/eukrea_cpuimx27/eukrea_cpuimx27.c index e40c26032..1937d21c8 100644 --- a/board/eukrea_cpuimx27/eukrea_cpuimx27.c +++ b/board/eukrea_cpuimx27/eukrea_cpuimx27.c @@ -45,6 +45,7 @@ #include #include #include +#include static struct device_d cfi_dev = { .name = "cfi_flash", @@ -230,7 +231,7 @@ static int eukrea_cpuimx27_devices_init(void) PD11_AOUT_FEC_TX_CLK, PD12_AOUT_FEC_RXD0, PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_CLR, + PD14_AOUT_FEC_RX_CLK, PD15_AOUT_FEC_COL, PD16_AIN_FEC_TX_ER, PF23_AIN_FEC_TX_EN, diff --git a/board/imx21ads/imx21ads.c b/board/imx21ads/imx21ads.c index 9eba19afb..5e88af4fd 100644 --- a/board/imx21ads/imx21ads.c +++ b/board/imx21ads/imx21ads.c @@ -35,6 +35,7 @@ #include #include #include +#include #define MX21ADS_IO_REG 0xCC800000 #define MX21ADS_IO_LCDON (1 << 9) diff --git a/board/imx27ads/imx27ads.c b/board/imx27ads/imx27ads.c index 3512ed368..6f31520ff 100644 --- a/board/imx27ads/imx27ads.c +++ b/board/imx27ads/imx27ads.c @@ -31,6 +31,7 @@ #include #include #include +#include static struct device_d cfi_dev = { .name = "cfi_flash", @@ -114,7 +115,7 @@ static int mx27ads_devices_init(void) PD11_AOUT_FEC_TX_CLK, PD12_AOUT_FEC_RXD0, PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_CLR, + PD14_AOUT_FEC_RX_CLK, PD15_AOUT_FEC_COL, PD16_AIN_FEC_TX_ER, PF23_AIN_FEC_TX_EN, diff --git a/board/pcm038/pcm038.c b/board/pcm038/pcm038.c index fbd53a543..03794fc13 100644 --- a/board/pcm038/pcm038.c +++ b/board/pcm038/pcm038.c @@ -42,6 +42,7 @@ #include #include #include +#include static struct device_d cfi_dev = { .name = "cfi_flash", @@ -229,7 +230,7 @@ static int pcm038_devices_init(void) PD11_AOUT_FEC_TX_CLK, PD12_AOUT_FEC_RXD0, PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_CLR, + PD14_AOUT_FEC_RX_CLK, PD15_AOUT_FEC_COL, PD16_AIN_FEC_TX_ER, PF23_AIN_FEC_TX_EN, diff --git a/board/phycard-i.MX27/pca100.c b/board/phycard-i.MX27/pca100.c index 2fb1e35ac..ce59960e2 100644 --- a/board/phycard-i.MX27/pca100.c +++ b/board/phycard-i.MX27/pca100.c @@ -38,6 +38,7 @@ #include #include #include +#include static struct memory_platform_data ram_pdata = { .name = "ram0", @@ -147,7 +148,7 @@ static int pca100_devices_init(void) PD11_AOUT_FEC_TX_CLK, PD12_AOUT_FEC_RXD0, PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_CLR, + PD14_AOUT_FEC_RX_CLK, PD15_AOUT_FEC_COL, PD16_AIN_FEC_TX_ER, PF23_AIN_FEC_TX_EN, From 695a4247aa32367f112042cbd67e10500d74b1d9 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 16 Jun 2010 14:49:33 +0200 Subject: [PATCH 38/65] imxfb: Add board specific hook to enable display Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imxfb.h | 2 ++ drivers/video/imx.c | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h index e31b66815..16b43ea4c 100644 --- a/arch/arm/mach-imx/include/mach/imxfb.h +++ b/arch/arm/mach-imx/include/mach/imxfb.h @@ -74,6 +74,8 @@ struct imx_fb_platform_data { void *framebuffer; /** force a memory area to be used, else NULL for dynamic allocation */ void *framebuffer_ovl; + /** hook to enable backlight and stuff */ + void (*enable)(int enable); }; void set_imx_fb_info(struct imx_fb_platform_data *); diff --git a/drivers/video/imx.c b/drivers/video/imx.c index d9ba643ac..3a4f938f4 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -152,6 +152,7 @@ struct imxfb_info { struct fb_info info; struct device_d *dev; + void (*enable)(int enable); struct fb_info overlay; }; @@ -262,12 +263,17 @@ static void imxfb_enable_controller(struct fb_info *info) writel(readl(IMX_CCM_BASE + CCM_CGCR1) | (1 << 29), IMX_CCM_BASE + CCM_CGCR1); #endif + if (fbi->enable) + fbi->enable(1); } static void imxfb_disable_controller(struct fb_info *info) { struct imxfb_info *fbi = info->priv; + if (fbi->enable) + fbi->enable(0); + writel(0, fbi->regs + LCDC_RMCR); #ifdef CONFIG_ARCH_IMX21 PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN); @@ -546,6 +552,7 @@ static int imxfb_probe(struct device_d *dev) fbi->pwmr = pdata->pwmr; fbi->lscr1 = pdata->lscr1; fbi->dmacr = pdata->dmacr; + fbi->enable = pdata->enable; fbi->dev = dev; info->priv = fbi; info->mode = &pdata->mode->mode; From cd4bc69126f6f97ea3647c8538514e4a2c4d65eb Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 16 Jun 2010 14:51:19 +0200 Subject: [PATCH 39/65] imxfb: do not enable framebuffer on startup The board code or startup script should enable it when it actually wants to. Signed-off-by: Sascha Hauer --- drivers/video/imx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/video/imx.c b/drivers/video/imx.c index 3a4f938f4..ac518588c 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -579,8 +579,6 @@ static int imxfb_probe(struct device_d *dev) #ifdef CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY imxfb_register_overlay(fbi, pdata->framebuffer_ovl); #endif - imxfb_enable_controller(info); - return 0; } From 3e94938068169d29b55355f22b2671262df69305 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 3 May 2010 12:53:52 +0200 Subject: [PATCH 40/65] memcpy cmd: Do not expect to read/write the whole chunk at once read() does not necessarily return the number of bytes we want to read, so deal with less bytes. Signed-off-by: Sascha Hauer --- commands/mem.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/commands/mem.c b/commands/mem.c index 619246652..bd1d3493c 100644 --- a/commands/mem.c +++ b/commands/mem.c @@ -455,27 +455,35 @@ static int do_mem_cp(struct command *cmdtp, int argc, char *argv[]) } while (count > 0) { - int now, r, w; + int now, r, w, tmp; now = min(RW_BUF_SIZE, count); - if ((r = read(sourcefd, rw_buf, now)) < 0) { + r = read(sourcefd, rw_buf, now); + if (r < 0) { perror("read"); goto out; } - if ((w = write(destfd, rw_buf, r)) < 0) { - perror("write"); - goto out; + if (!r) + break; + + tmp = 0; + now = r; + while (now) { + w = write(destfd, rw_buf + tmp, now); + if (w < 0) { + perror("write"); + goto out; + } + if (!w) + break; + + now -= w; + tmp += w; } - if (r < now) - break; - - if (w < r) - break; - - count -= now; + count -= r; } if (count) { From 8f1691d58c6281c87ce04833ca0ceeaa1cf86876 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 17 May 2010 10:50:58 +0200 Subject: [PATCH 41/65] armlinux: reorder tag setup We call the individual setup_*_tag functions from three different boot commands. Waste less space by calling a single setup_tags function instead. Signed-off-by: Sascha Hauer --- arch/arm/lib/armlinux.c | 51 ++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c index a38c6bf65..89d989a73 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -142,6 +142,25 @@ static void setup_end_tag (void) params->hdr.size = 0; } +static void setup_tags(void) +{ + const char *commandline = getenv("bootargs"); + + setup_start_tag(); + setup_memory_tags(); + setup_commandline_tag(commandline); +#if 0 + if (initrd_start && initrd_end) + setup_initrd_tag (initrd_start, initrd_end); +#endif + setup_revision_tag(); + setup_end_tag(); + + printf("commandline: %s\n" + "arch_number: %d\n", commandline, armlinux_architecture); + +} + void armlinux_set_bootparams(void *params) { armlinux_bootparams = params; @@ -172,7 +191,6 @@ int do_bootm_linux(struct image_data *data) { void (*theKernel)(int zero, int arch, void *params); image_header_t *os_header = &data->os->header; - const char *commandline = getenv("bootargs"); if (os_header->ih_type == IH_TYPE_MULTI) { printf("Multifile images not handled at the moment\n"); @@ -189,23 +207,12 @@ int do_bootm_linux(struct image_data *data) return -1; } - printf("commandline: %s\n" - "arch_number: %d\n", commandline, armlinux_architecture); - theKernel = (void *)ntohl(os_header->ih_ep); debug("## Transferring control to Linux (at address 0x%p) ...\n", theKernel); - setup_start_tag(); - setup_memory_tags(); - setup_commandline_tag(commandline); -#if 0 - if (initrd_start && initrd_end) - setup_initrd_tag (initrd_start, initrd_end); -#endif - setup_revision_tag(); - setup_end_tag(); + setup_tags(); if (relocate_image(data->os, (void *)ntohl(os_header->ih_load))) return -1; @@ -259,7 +266,6 @@ struct zimage_header { static int do_bootz(struct command *cmdtp, int argc, char *argv[]) { void (*theKernel)(int zero, int arch, void *params); - const char *commandline = getenv("bootargs"); int fd, ret; struct zimage_header header; void *zimage; @@ -295,15 +301,7 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[]) printf("loaded zImage from %s with size %d\n", argv[1], header.end); - setup_start_tag(); - setup_memory_tags(); - setup_commandline_tag(commandline); -#if 0 - if (initrd_start && initrd_end) - setup_initrd_tag (initrd_start, initrd_end); -#endif - setup_revision_tag(); - setup_end_tag(); + setup_tags(); shutdown_barebox(); theKernel(0, armlinux_architecture, armlinux_bootparams); @@ -333,7 +331,6 @@ BAREBOX_CMD_END static int do_bootu(struct command *cmdtp, int argc, char *argv[]) { void (*theKernel)(int zero, int arch, void *params) = NULL; - const char *commandline = getenv("bootargs"); int fd; if (argc != 2) { @@ -348,11 +345,7 @@ static int do_bootu(struct command *cmdtp, int argc, char *argv[]) if (!theKernel) theKernel = (void *)simple_strtoul(argv[1], NULL, 0); - setup_start_tag(); - setup_memory_tags(); - setup_commandline_tag(commandline); - setup_revision_tag(); - setup_end_tag(); + setup_tags(); shutdown_barebox(); theKernel(0, armlinux_architecture, armlinux_bootparams); From 90fc3a611737d45246222de6903770ddb63fb7c5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 22 Oct 2009 11:09:10 +0200 Subject: [PATCH 42/65] remove eco920 board support It has been broken for long time and nobody cared, so remove it. Signed-off-by: Sascha Hauer --- arch/arm/Makefile | 1 - arch/arm/mach-at91rm9200/Kconfig | 8 -- board/eco920/Makefile | 2 - board/eco920/config.h | 134 -------------------- board/eco920/config.mk | 1 - board/eco920/eco920.c | 211 ------------------------------- 6 files changed, 357 deletions(-) delete mode 100644 board/eco920/Makefile delete mode 100644 board/eco920/config.h delete mode 100644 board/eco920/config.mk delete mode 100644 board/eco920/eco920.c diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 85ff9c8ad..1c9f24e7d 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -52,7 +52,6 @@ board-$(CONFIG_MACH_A9M2410) := a9m2410 board-$(CONFIG_MACH_A9M2440) := a9m2440 board-$(CONFIG_MACH_AT91SAM9260EK) := at91sam9260ek board-$(CONFIG_MACH_AT91SAM9263EK) := at91sam9263ek -board-$(CONFIG_MACH_ECO920) := eco920 board-$(CONFIG_MACH_EDB9301) := edb93xx board-$(CONFIG_MACH_EDB9302) := edb93xx board-$(CONFIG_MACH_EDB9302A) := edb93xx diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91rm9200/Kconfig index 7e9017999..c062097d0 100644 --- a/arch/arm/mach-at91rm9200/Kconfig +++ b/arch/arm/mach-at91rm9200/Kconfig @@ -2,7 +2,6 @@ if ARCH_AT91RM9200 config ARCH_TEXT_BASE hex - default 0x21e00000 if MACH_ECO920 config BOARDINFO @@ -12,13 +11,6 @@ choice prompt "AT91RM9200 Board Type" -config MACH_ECO920 - bool "eco920" - select HAS_AT91_ETHER - select HAS_CFI - help - Say Y here if you are using the Motorola MX1ADS board - endchoice endif diff --git a/board/eco920/Makefile b/board/eco920/Makefile deleted file mode 100644 index 2cc70ca05..000000000 --- a/board/eco920/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-y += eco920.o - diff --git a/board/eco920/config.h b/board/eco920/config.h deleted file mode 100644 index 3fb8beb8c..000000000 --- a/board/eco920/config.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * (C) Copyright 2007 Pengutronix - * Sascha Hauer, - * - * 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 - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -/* ARM asynchronous clock */ -#define AT91C_MAIN_CLOCK 179712000 /* from 18.432 MHz crystal (18432000 / 4 * 39) */ -#define AT91C_MASTER_CLOCK 59904000 /* peripheral clock (AT91C_MASTER_CLOCK / 3) */ -/* #define AT91C_MASTER_CLOCK 44928000 */ /* peripheral clock (AT91C_MASTER_CLOCK / 4) */ - -#define AT91_SLOW_CLOCK 32768 /* slow clock */ - -#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ -#define USE_920T_MMU 1 - -#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ -#define CONFIG_SETUP_MEMORY_TAGS 1 -#define CONFIG_INITRD_TAG 1 - -#define CFG_USE_MAIN_OSCILLATOR 1 -/* flash */ -#define MC_PUIA_VAL 0x00000000 -#define MC_PUP_VAL 0x00000000 -#define MC_PUER_VAL 0x00000000 -#define MC_ASR_VAL 0x00000000 -#define MC_AASR_VAL 0x00000000 -#define EBI_CFGR_VAL 0x00000000 -#define SMC2_CSR_VAL 0x00003287 - -/* clocks */ -#define PLLAR_VAL 0x2026be04 -#define PLLBR_VAL 0x10483e0e -#define MCKR_VAL 0x00000202 - -/* sdram */ -#define PIOC_ASR_VAL 0xffff0000 -#define PIOC_BSR_VAL 0x00000000 -#define PIOC_PDR_VAL 0xffff0000 -#define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */ -#define SDRC_CR_VAL 0x2188c155 /* set up the SDRAM */ -#define SDRAM 0x20000000 /* address of the SDRAM */ -#define SDRAM1 0x20000080 /* address of the SDRAM */ -#define SDRAM_VAL 0x00000000 /* value written to SDRAM */ -#define SDRC_MR_VAL 0x00000002 /* Precharge All */ -#define SDRC_MR_VAL1 0x00000004 /* refresh */ -#define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ -#define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ -#define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ - -#define CONFIG_BAUDRATE 115200 - -/* - * Hardware drivers - */ - -/* define one of CONFIG_DBGU, CONFIG_USART0 or CONFIG_USART1 to choose console */ -#define CONFIG_DBGU - -#define CONFIG_BOOTDELAY 3 - -#define CONFIG_CMDLINE_EDITING 1 - -#define CONFIG_EXTRA_ENV_SETTINGS \ - "mtdids=nor0=physmap-flash.0\0" \ - "mtdparts=mtdparts=physmap-flash.0:128k(barebox)ro,128k(env),1536k(kernel),-(jffs2)\0" \ - "bootargs_base=setenv bootargs console=ttyAT0,115200\0" \ - "bootargs_nfs=setenv bootargs $(bootargs) root=/dev/nfs ip=dhcp nfsroot=$(serverip):$(nfsrootfs),v3,tcp\0" \ - "bootargs_mtd=setenv bootargs $(bootargs) $(mtdparts)\0" \ - "bootargs_flash=setenv bootargs $(bootargs) root=/dev/mtdblock3 rootfstype=jffs2\0" \ - "bootcmd_flash=run bootargs_base bootargs_mtd bootargs_flash; bootm 0x11040000\0" \ - "bootcmd_net=run bootargs_base bootargs_mtd bootargs_nfs; tftpboot 0x20000000 $(uimage); bootm\0" \ - "autoload=n\0" \ - "uimage=uImage-eco920\0" \ - "jffs2=root-eco920.jffs2\0" - -/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ -#include - -#define CONFIG_NR_DRAM_BANKS 1 -#define PHYS_SDRAM 0x20000000 -#define PHYS_SDRAM_SIZE 0x2000000 - -#define CFG_MEMTEST_START PHYS_SDRAM -#define CFG_MEMTEST_END CFG_MEMTEST_START + PHYS_SDRAM_SIZE - 262144 - -#define CONFIG_DRIVER_ETHER -#define CONFIG_NET_RETRY_COUNT 20 -#define CONFIG_AT91C_USE_RMII - -#define CFG_LOAD_ADDR 0x21000000 /* default load address */ - -#define CFG_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 } - -#define CFG_LONGHELP /* undef to save memory */ -#define CFG_PROMPT "barebox> " /* Monitor Command Prompt */ -#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ -#define CFG_MAXARGS 32 /* max number of command args */ -#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ - -#define CLOCK_TICK_RATE AT91C_MASTER_CLOCK/2 /* AT91C_TC0_CMR is implicitly set to */ - /* AT91C_TC_TIMER_DIV1_CLOCK */ - -#define CONFIG_MISC_INIT_R 1 /* call misc_init_r() on init */ -#define CFG_SPLASH 1 -#define CFG_S1D13706FB 1 - -#define CFG_USB_OHCI_MAX_ROOT_PORTS 15 -#define CFG_USB_OHCI_SLOT_NAME "at91rm9200" -#define LITTLEENDIAN -#define CONFIG_AT91C_PQFP_UHPBUG - -#endif - diff --git a/board/eco920/config.mk b/board/eco920/config.mk deleted file mode 100644 index 9ce161e55..000000000 --- a/board/eco920/config.mk +++ /dev/null @@ -1 +0,0 @@ -TEXT_BASE = 0x21f00000 diff --git a/board/eco920/eco920.c b/board/eco920/eco920.c deleted file mode 100644 index 8d00877ce..000000000 --- a/board/eco920/eco920.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * (C) Copyright 2007 Pengutronix - * Sascha Hauer, - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Miscelaneous platform dependent initialisations - */ - -static struct cfi_platform_data cfi_info = { -}; - -struct device_d cfi_dev = { - .name = "cfi_flash", - .map_base = 0x11000000, - .size = 16 * 1024 * 1024, - - .platform_data = &cfi_info, -}; - -static struct memory_platform_data ram_pdata = { - .name = "ram0", - .flags = DEVFS_RDWR, -}; - -struct device_d sdram_dev = { - .name = "mem", - .map_base = 0x20000000, - .size = 32 * 1024 * 1024, - .platform_data = &ram_pdata, -}; - -static struct device_d at91_ath_dev = { - .name = "at91_eth", -}; - -static int devices_init (void) -{ - register_device(&cfi_dev); - register_device(&sdram_dev); - register_device(&at91_ath_dev); - - armlinux_set_bootparams((void *)(PHYS_SDRAM + 0x100)); - armlinux_set_architecture(MACH_TYPE_ECO920); - - return 0; -} - -device_initcall(devices_init); - -static unsigned int phy_is_connected (AT91PS_EMAC p_mac) -{ - return 1; -} - -static unsigned char phy_init_bogus (AT91PS_EMAC p_mac) -{ - unsigned short val; - int timeout, adr, speed, fullduplex; - - at91rm9200_EmacEnableMDIO (p_mac); - - /* Scan through phy addresses to find a phy */ - for (adr = 0; adr < 16; adr++) { - at91rm9200_EmacReadPhy(p_mac, PHY_PHYIDR1 | (adr << 5), &val); - if (val != 0xffff) - break; - } - - adr <<= 5; - - val = PHY_BMCR_RESET; - at91rm9200_EmacWritePhy(p_mac, PHY_BMCR | adr, &val); - - udelay(1000); - - val = 0x01e1; /* ADVERTISE_100FULL | ADVERTISE_100HALF | - * ADVERTISE_10FULL | ADVERTISE_10HALF | - * ADVERTISE_CSMA */ - at91rm9200_EmacWritePhy(p_mac, PHY_ANAR | adr, &val); - - at91rm9200_EmacReadPhy(p_mac, PHY_BMCR | adr, &val); - val |= PHY_BMCR_AUTON | PHY_BMCR_RST_NEG; - at91rm9200_EmacWritePhy(p_mac, PHY_BMCR | adr, &val); - - timeout = 500; - do { - /* at91rm9200_EmacReadPhy() has a udelay(10000) - * in it, so this should be about 5 deconds - */ - if ((timeout--) == 0) { - printf("Autonegotiation timeout\n"); - goto out; - } - - at91rm9200_EmacReadPhy(p_mac, PHY_BMSR | adr, &val); - } while (!(val & PHY_BMSR_LS)); - - at91rm9200_EmacReadPhy(p_mac, PHY_ANLPAR | adr, &val); - - if (val & PHY_ANLPAR_100) { - speed = 100; - p_mac->EMAC_CFG |= AT91C_EMAC_SPD; - } else { - speed = 10; - p_mac->EMAC_CFG &= ~AT91C_EMAC_SPD; - } - - if (val & (PHY_ANLPAR_TXFD | PHY_ANLPAR_10FD)) { - fullduplex = 1; - p_mac->EMAC_CFG |= AT91C_EMAC_FD; - } else { - fullduplex = 0; - p_mac->EMAC_CFG &= ~AT91C_EMAC_FD; - } - - printf("running at %d-%sDuplex\n",speed, fullduplex ? "FUll" : "Half"); - -out: - at91rm9200_EmacDisableMDIO (p_mac); - - return 1; -} - -void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops) -{ - p_phyops->Init = phy_init_bogus; - p_phyops->IsPhyConnected = phy_is_connected; - /* This is not used anywhere */ - p_phyops->GetLinkSpeed = NULL; - /* ditto */ - p_phyops->AutoNegotiate = NULL; -} - -#ifdef CONFIG_DRIVER_VIDEO_S1D13706 -static int efb_init(struct efb_info *efb) -{ - writeb(GPIO_CONTROL0_GPO, efb->regs + EFB_GPIO_CONTROL1); - writeb(PCLK_SOURCE_CLKI2, efb->regs + EFB_PCLK_CONF); - writeb(0x1, efb->regs + 0x26); /* FIXME: display specific, should be set to zero - * according to datasheet - */ - return 0; -} - -/* Nanya STN Display */ -static struct efb_info efb = { - .fbd = { - .xres = 320, - .yres = 240, - .bpp = 8, - .fb = (void*)0x40020000, - }, - - .init = efb_init, - .regs = (void*)0x40000000, - .pixclock = 100000, - .hsync_len = 1, - .left_margin = 22, - .right_margin = 1, - .vsync_len = 1, - .upper_margin = 0, - .lower_margin = 1, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .panel_type = PANEL_TYPE_STN | PANEL_TYPE_WIDTH_8 | - PANEL_TYPE_COLOR | PANEL_TYPE_FORMAT_2, -}; -#endif -#define SMC_CSR3 0xFFFFFF7C - -int misc_init_r(void) -{ - /* Initialization of the Static Memory Controller for Chip Select 3 */ - *(volatile unsigned long*)SMC_CSR3 = 0x00002185; -#ifdef CONFIG_DRIVER_VIDEO_S1D13706 - s1d13706fb_init(&efb); -#endif -#ifdef CONFIG_CMD_SPLASH - splash_set_fb_data(&efb.fbd); -#endif - return 0; -} From 322bace5fb422fb4f8f22a119856877a3ad6c78e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 21 Jun 2010 12:11:23 +0200 Subject: [PATCH 43/65] usbnet: remove unused dev member in struct usbnet Signed-off-by: Sascha Hauer --- drivers/net/usb/asix.c | 12 ++++++------ drivers/net/usb/usbnet.c | 9 +++++---- include/usb/usbnet.h | 2 -- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index fc4146fdb..ca71b34e1 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -415,13 +415,13 @@ static int asix_rx_fixup(struct usbnet *dev, void *buf, int len) while (len > 0) { if ((short)(header & 0x0000ffff) != ~((short)((header & 0xffff0000) >> 16))) - dev_err(&dev->dev, "asix_rx_fixup() Bad Header Length"); - + dev_err(&dev->edev.dev, "asix_rx_fixup() Bad Header Length"); + /* get the packet length */ size = (unsigned short) (header & 0x0000ffff); if (size > 1514) { - dev_err(&dev->dev, "asix_rx_fixup() Bad RX Length %d", size); + dev_err(&dev->edev.dev, "asix_rx_fixup() Bad RX Length %d", size); return 0; } @@ -440,7 +440,7 @@ static int asix_rx_fixup(struct usbnet *dev, void *buf, int len) } if (len < 0) { - dev_err(&dev->dev,"asix_rx_fixup() Bad SKB Length %d", len); + dev_err(&dev->edev.dev,"asix_rx_fixup() Bad SKB Length %d", len); return -1; } return 0; @@ -503,13 +503,13 @@ static int ax88172_bind(struct usbnet *dev) unsigned long gpio_bits = dev->driver_info->data; struct asix_data *data = (struct asix_data *)&dev->data; - dev_dbg(&dev->dev, "%s\n", __func__); + dev_dbg(&dev->edev.dev, "%s\n", __func__); data->eeprom_len = AX88172_EEPROM_LEN; ret = usbnet_get_endpoints(dev); if (ret) { - dev_err(&dev->dev, "can not get EPs\n"); + dev_err(&dev->edev.dev, "can not get EPs\n"); return ret; } diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index b0e309096..cc170f661 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -74,7 +74,7 @@ int usbnet_get_endpoints(struct usbnet *dev) in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); dev->out = usb_sndbulkpipe (dev->udev, out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - dev_dbg(&dev->dev, "found endpoints: IN=%d OUT=%d\n", + dev_dbg(&dev->edev.dev, "found endpoints: IN=%d OUT=%d\n", in->bEndpointAddress, out->bEndpointAddress); return 0; @@ -89,14 +89,14 @@ static int usbnet_send(struct eth_device *edev, void *eth_data, int data_length) struct driver_info *info = dev->driver_info; int len, alen, ret; - dev_dbg(&dev->dev, "%s\n",__func__); + dev_dbg(&edev->dev, "%s\n",__func__); /* some devices want funky USB-level framing, for * win32 driver (usually) and/or hardware quirks */ if(info->tx_fixup) { if(info->tx_fixup(dev, eth_data, data_length, tx_buffer, &len)) { - dev_dbg(&dev->dev, "can't tx_fixup packet"); + dev_dbg(&edev->dev, "can't tx_fixup packet"); return 0; } } else { @@ -191,7 +191,7 @@ int usbnet_probe(struct usb_device *usbdev, const struct usb_device_id *prod) struct driver_info *info; int status; - dev_dbg(&edev->dev, "%s\n", __func__); + dev_dbg(&usbdev->dev, "%s\n", __func__); undev = xzalloc(sizeof (*undev)); @@ -206,6 +206,7 @@ int usbnet_probe(struct usb_device *usbdev, const struct usb_device_id *prod) edev->recv = usbnet_recv, edev->halt = usbnet_halt, edev->priv = undev; + edev->dev = usbdev->dev; /* will be overwritten by eth_register */ info = (struct driver_info *)prod->driver_info; undev->driver_info = info; diff --git a/include/usb/usbnet.h b/include/usb/usbnet.h index 77f19603c..e3ea373d9 100644 --- a/include/usb/usbnet.h +++ b/include/usb/usbnet.h @@ -54,8 +54,6 @@ struct usbnet { # define EVENT_RX_MEMORY 2 # define EVENT_STS_SPLIT 3 # define EVENT_LINK_RESET 4 - /* FIXME: Our eth_device should have this, not us! */ - struct device_d dev; }; #if 0 From 1996f64c4dd5684873d220ad923d26b4bd814960 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 21 Jun 2010 15:19:09 +0200 Subject: [PATCH 44/65] i.MX serial: Use readl/writel instead of pointer deref Signed-off-by: Sascha Hauer --- drivers/serial/serial_imx.c | 135 +++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 65 deletions(-) diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c index 91d3b188c..801004e18 100644 --- a/drivers/serial/serial_imx.c +++ b/drivers/serial/serial_imx.c @@ -24,34 +24,35 @@ #include #include #include +#include -#define URXD0(base) __REG( 0x0 +(base)) /* Receiver Register */ -#define URTX0(base) __REG( 0x40 +(base)) /* Transmitter Register */ -#define UCR1(base) __REG( 0x80 +(base)) /* Control Register 1 */ -#define UCR2(base) __REG( 0x84 +(base)) /* Control Register 2 */ -#define UCR3(base) __REG( 0x88 +(base)) /* Control Register 3 */ -#define UCR4(base) __REG( 0x8c +(base)) /* Control Register 4 */ -#define UFCR(base) __REG( 0x90 +(base)) /* FIFO Control Register */ -#define USR1(base) __REG( 0x94 +(base)) /* Status Register 1 */ -#define USR2(base) __REG( 0x98 +(base)) /* Status Register 2 */ -#define UESC(base) __REG( 0x9c +(base)) /* Escape Character Register */ -#define UTIM(base) __REG( 0xa0 +(base)) /* Escape Timer Register */ -#define UBIR(base) __REG( 0xa4 +(base)) /* BRM Incremental Register */ -#define UBMR(base) __REG( 0xa8 +(base)) /* BRM Modulator Register */ -#define UBRC(base) __REG( 0xac +(base)) /* Baud Rate Count Register */ +#define URXD0 0x0 /* Receiver Register */ +#define URTX0 0x40 /* Transmitter Register */ +#define UCR1 0x80 /* Control Register 1 */ +#define UCR2 0x84 /* Control Register 2 */ +#define UCR3 0x88 /* Control Register 3 */ +#define UCR4 0x8c /* Control Register 4 */ +#define UFCR 0x90 /* FIFO Control Register */ +#define USR1 0x94 /* Status Register 1 */ +#define USR2 0x98 /* Status Register 2 */ +#define UESC 0x9c /* Escape Character Register */ +#define UTIM 0xa0 /* Escape Timer Register */ +#define UBIR 0xa4 /* BRM Incremental Register */ +#define UBMR 0xa8 /* BRM Modulator Register */ +#define UBRC 0xac /* Baud Rate Count Register */ #ifdef CONFIG_ARCH_IMX1 -#define BIPR1(base) __REG( 0xb0 +(base)) /* Incremental Preset Register 1 */ -#define BIPR2(base) __REG( 0xb4 +(base)) /* Incremental Preset Register 2 */ -#define BIPR3(base) __REG( 0xb8 +(base)) /* Incremental Preset Register 3 */ -#define BIPR4(base) __REG( 0xbc +(base)) /* Incremental Preset Register 4 */ -#define BMPR1(base) __REG( 0xc0 +(base)) /* BRM Modulator Register 1 */ -#define BMPR2(base) __REG( 0xc4 +(base)) /* BRM Modulator Register 2 */ -#define BMPR3(base) __REG( 0xc8 +(base)) /* BRM Modulator Register 3 */ -#define BMPR4(base) __REG( 0xcc +(base)) /* BRM Modulator Register 4 */ -#define UTS(base) __REG( 0xd0 +(base)) /* UART Test Register */ +#define BIPR1 0xb0 /* Incremental Preset Register 1 */ +#define BIPR2 0xb4 /* Incremental Preset Register 2 */ +#define BIPR3 0xb8 /* Incremental Preset Register 3 */ +#define BIPR4 0xbc /* Incremental Preset Register 4 */ +#define BMPR1 0xc0 /* BRM Modulator Register 1 */ +#define BMPR2 0xc4 /* BRM Modulator Register 2 */ +#define BMPR3 0xc8 /* BRM Modulator Register 3 */ +#define BMPR4 0xcc /* BRM Modulator Register 4 */ +#define UTS 0xd0 /* UART Test Register */ #else -#define ONEMS(base) __REG( 0xb0 +(base)) /* One Millisecond register */ -#define UTS(base) __REG( 0xb4 +(base)) /* UART Test Register */ +#define ONEMS 0xb0 /* One Millisecond register */ +#define UTS 0xb4 /* UART Test Register */ #endif /* UART Control Register Bit Fields.*/ @@ -175,7 +176,7 @@ static int imx_serial_reffreq(ulong base) { ulong rfdiv; - rfdiv = (UFCR(base) >> 7) & 7; + rfdiv = (readl(base + UFCR) >> 7) & 7; rfdiv = rfdiv < 6 ? 6 - rfdiv : 7; return imx_get_uartclk() / rfdiv; @@ -190,45 +191,42 @@ static int imx_serial_init_port(struct console_device *cdev) { struct device_d *dev = cdev->dev; ulong base = dev->map_base; + uint32_t val; + + writel(UCR1_VAL, base + UCR1); + writel(UCR2_WS | UCR2_IRTS, base + UCR2); + writel(UCR3_VAL, base + UCR3); + writel(UCR4_VAL, base + UCR4); + writel(0x0000002B, base + UESC); + writel(0, base + UTIM); + writel(0, base + UBIR); + writel(0, base + UBMR); + writel(0, base + UTS); - UCR1(base) = UCR1_VAL; - UCR2(base) = UCR2_WS | UCR2_IRTS; - UCR3(base) = UCR3_VAL; - UCR4(base) = UCR4_VAL; - UESC(base) = 0x0000002B; - UTIM(base) = 0; - UBIR(base) = 0; - UBMR(base) = 0; - UTS(base) = 0; /* Configure FIFOs */ - UFCR(base) = 0xa81; + writel(0xa81, base + UFCR); #ifdef ONEMS - ONEMS(base) = imx_serial_reffreq(base) / 1000; + writel(imx_serial_reffreq(base) / 1000, base + ONEMS); #endif /* Enable FIFOs */ - UCR2(base) |= UCR2_SRST | UCR2_RXEN | UCR2_TXEN; + val = readl(base + UCR2); + val |= UCR2_SRST | UCR2_RXEN | UCR2_TXEN; + writel(val, base + UCR2); /* Clear status flags */ - USR2(base) |= USR2_ADET | - USR2_DTRF | - USR2_IDLE | - USR2_IRINT | - USR2_WAKE | - USR2_RTSF | - USR2_BRCD | - USR2_ORE | - USR2_RDR; + val = readl(base + USR2); + val |= USR2_ADET | USR2_DTRF | USR2_IDLE | USR2_IRINT | USR2_WAKE | + USR2_RTSF | USR2_BRCD | USR2_ORE | USR2_RDR; + writel(val, base + USR2); /* Clear status flags */ - USR1(base) |= USR1_PARITYERR | - USR1_RTSD | - USR1_ESCF | - USR1_FRAMERR | - USR1_AIRINT | - USR1_AWAKE; + val = readl(base + USR2); + val |= USR1_PARITYERR | USR1_RTSD | USR1_ESCF | USR1_FRAMERR | USR1_AIRINT | + USR1_AWAKE; + writel(val, base + USR2); return 0; } @@ -238,9 +236,9 @@ static void imx_serial_putc(struct console_device *cdev, char c) struct device_d *dev = cdev->dev; /* Wait for Tx FIFO not full */ - while (UTS(dev->map_base) & UTS_TXFULL); + while (readl(dev->map_base + UTS) & UTS_TXFULL); - URTX0(dev->map_base) = c; + writel(c, dev->map_base + URTX0); } static int imx_serial_tstc(struct console_device *cdev) @@ -248,7 +246,7 @@ static int imx_serial_tstc(struct console_device *cdev) struct device_d *dev = cdev->dev; /* If receive fifo is empty, return false */ - if (UTS(dev->map_base) & UTS_RXEMPTY) + if (readl(dev->map_base + UTS) & UTS_RXEMPTY) return 0; return 1; } @@ -258,9 +256,9 @@ static int imx_serial_getc(struct console_device *cdev) struct device_d *dev = cdev->dev; unsigned char ch; - while (UTS(dev->map_base) & UTS_RXEMPTY); + while (readl(dev->map_base + UTS) & UTS_RXEMPTY); - ch = URXD0(dev->map_base); + ch = readl(dev->map_base + URXD0); return ch; } @@ -269,7 +267,7 @@ static void imx_serial_flush(struct console_device *cdev) { struct device_d *dev = cdev->dev; - while (!(USR2(dev->map_base) & USR2_TXDC)); + while (!(readl(dev->map_base + USR2) & USR2_TXDC)); } static int imx_serial_setbaudrate(struct console_device *cdev, int baudrate) @@ -277,18 +275,22 @@ static int imx_serial_setbaudrate(struct console_device *cdev, int baudrate) struct device_d *dev = cdev->dev; struct imx_serial_priv *priv = container_of(cdev, struct imx_serial_priv, cdev); + uint32_t val; + ulong base = dev->map_base; - ulong ucr1 = UCR1(base); + ulong ucr1 = readl(base + UCR1); /* disable UART */ - UCR1(base) &= ~UCR1_UARTEN; + val = readl(base + UCR1); + val &= ~UCR1_UARTEN; + writel(val, base + UCR1); /* Set the numerator value minus one of the BRM ratio */ - UBIR(base) = (baudrate / 100) - 1; + writel((baudrate / 100) - 1, base + UBIR); /* Set the denominator value minus one of the BRM ratio */ - UBMR(base) = ((imx_serial_reffreq(base) / 1600) - 1); + writel((imx_serial_reffreq(base) / 1600) - 1, base + UBMR); - UCR1(base) = ucr1; + writel(ucr1, base + UCR1); priv->baudrate = baudrate; @@ -310,6 +312,7 @@ static int imx_serial_probe(struct device_d *dev) { struct console_device *cdev; struct imx_serial_priv *priv; + uint32_t val; priv = malloc(sizeof(*priv)); cdev = &priv->cdev; @@ -327,7 +330,9 @@ static int imx_serial_probe(struct device_d *dev) imx_serial_setbaudrate(cdev, 115200); /* Enable UART */ - UCR1(cdev->dev->map_base) |= UCR1_UARTEN; + val = readl(cdev->dev->map_base + UCR1); + val |= UCR1_UARTEN; + writel(val, cdev->dev->map_base + UCR1); console_register(cdev); priv->notify.notifier_call = imx_clocksource_clock_change; From c38883953df6cc8f233ebf07d8a96f04fdbee443 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 21 Jun 2010 15:19:26 +0200 Subject: [PATCH 45/65] i.MX clocksource: Use readl/writel instead of pointer deref Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clocksource.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c index 4b400a0ca..a16603854 100644 --- a/arch/arm/mach-imx/clocksource.c +++ b/arch/arm/mach-imx/clocksource.c @@ -35,12 +35,14 @@ #include #include #include +#include #define GPT(x) __REG(IMX_TIM1_BASE + (x)) +#define timer_base (IMX_TIM1_BASE) uint64_t imx_clocksource_read(void) { - return GPT(GPT_TCN); + return readl(timer_base + GPT_TCN); } static struct clocksource cs = { @@ -62,8 +64,10 @@ static struct notifier_block imx_clock_notifier = { static int clocksource_init (void) { int i; + uint32_t val; + /* setup GP Timer 1 */ - GPT(GPT_TCTL) = TCTL_SWR; + writel(TCTL_SWR, timer_base + GPT_TCTL); #ifdef CONFIG_ARCH_IMX21 PCCR1 |= PCCR1_GPT1_EN; @@ -74,12 +78,12 @@ static int clocksource_init (void) #endif for (i = 0; i < 100; i++) - GPT(GPT_TCTL) = 0; /* We have no udelay by now */ + writel(0, timer_base + GPT_TCTL); /* We have no udelay by now */ - GPT(GPT_TPRER) = 0; - GPT(GPT_TCTL) |= TCTL_FRR | (1< Date: Tue, 22 Jun 2010 16:42:52 +0200 Subject: [PATCH 46/65] i.MX27: Add some missing device base addresses Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imx27-regs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h index d804a9d7f..8d0bcda72 100644 --- a/arch/arm/mach-imx/include/mach/imx27-regs.h +++ b/arch/arm/mach-imx/include/mach/imx27-regs.h @@ -16,6 +16,7 @@ #define IMX_UART2_BASE (0x0b000 + IMX_IO_BASE) #define IMX_UART3_BASE (0x0c000 + IMX_IO_BASE) #define IMX_UART4_BASE (0x0d000 + IMX_IO_BASE) +#define IMX_SPI1_BASE (0x0e000 + IMX_IO_BASE) #define IMX_I2C1_BASE (0x12000 + IMX_IO_BASE) #define IMX_GPIO_BASE (0x15000 + IMX_IO_BASE) #define IMX_TIM4_BASE (0x19000 + IMX_IO_BASE) @@ -25,9 +26,11 @@ #define IMX_I2C2_BASE (0x1d000 + IMX_IO_BASE) #define IMX_TIM6_BASE (0x1f000 + IMX_IO_BASE) #define IMX_AIPI2_BASE (0x20000 + IMX_IO_BASE) +#define IMX_FB_BASE (0x21000 + IMX_IO_BASE) #define IMX_PLL_BASE (0x27000 + IMX_IO_BASE) #define IMX_SYSTEM_CTL_BASE (0x27800 + IMX_IO_BASE) #define IMX_OTG_BASE (0x24000 + IMX_IO_BASE) +#define IMX_FEC_BASE (0x2b000 + IMX_IO_BASE) #define IMX_NFC_BASE (0xd8000000) #define IMX_ESD_BASE (0xd8001000) From 112d65d3d2bde37529e61d6ad3011c39a1f65589 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 22 Jun 2010 16:26:35 +0200 Subject: [PATCH 47/65] fb: add a usage counter to prevent double enable/disable Signed-off-by: Sascha Hauer --- drivers/video/fb.c | 5 +++++ include/fb.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/video/fb.c b/drivers/video/fb.c index 841c3afe9..f9a425efa 100644 --- a/drivers/video/fb.c +++ b/drivers/video/fb.c @@ -39,6 +39,9 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param, enable = simple_strtoul(val, NULL, 0); + if (info->enabled == !!enable) + return 0; + if (enable) { info->fbops->fb_enable(info); new = "1"; @@ -49,6 +52,8 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param, dev_param_set_generic(dev, param, new); + info->enabled = !!enable; + return 0; } diff --git a/include/fb.h b/include/fb.h index 218500b98..379f931e9 100644 --- a/include/fb.h +++ b/include/fb.h @@ -96,7 +96,9 @@ struct fb_info { struct fb_bitfield red; /* bitfield in fb mem if true color, */ struct fb_bitfield green; /* else only length is significant */ struct fb_bitfield blue; - struct fb_bitfield transp; /* transparency */ + struct fb_bitfield transp; /* transparency */ + + int enabled; }; int register_framebuffer(struct fb_info *info); From 57b56a989fb0071382832c9e7263e48057314e6c Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 23 Jun 2010 15:29:44 +0200 Subject: [PATCH 48/65] ehci: Make has_tt configurable via platform data Signed-off-by: Sascha Hauer --- drivers/usb/usb_ehci_core.c | 18 ++++++++++++------ include/usb/ehci.h | 10 ++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 include/usb/ehci.h diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c index d7efaadb8..f3611cda2 100644 --- a/drivers/usb/usb_ehci_core.c +++ b/drivers/usb/usb_ehci_core.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "usb_ehci.h" @@ -43,6 +44,7 @@ struct ehci_priv { struct QH *qh_list; void *qhp; int portreset; + unsigned long flags; }; #define to_ehci(ptr) container_of(ptr, struct ehci_priv, host) @@ -112,13 +114,8 @@ static struct descriptor { 255 /* bInterval */ }, }; -#define CONFIG_EHCI_IS_TDI // FIXME -#if defined(CONFIG_EHCI_IS_TDI) -#define ehci_is_TDI() (1) -#else -#define ehci_is_TDI() (0) -#endif +#define ehci_is_TDI() (ehci->flags & EHCI_HAS_TT) #ifdef CONFIG_MMU /* @@ -861,10 +858,19 @@ static int ehci_probe(struct device_d *dev) struct usb_host *host; struct ehci_priv *ehci; uint32_t reg; + struct ehci_platform_data *pdata = dev->platform_data; ehci = xmalloc(sizeof(struct ehci_priv)); host = &ehci->host; + if (pdata) + ehci->flags = pdata->flags; + else + /* default to EHCI_HAS_TT to not change behaviour of boards + * with platform_data + */ + ehci->flags = EHCI_HAS_TT; + host->init = ehci_init; host->submit_int_msg = submit_int_msg; host->submit_control_msg = submit_control_msg; diff --git a/include/usb/ehci.h b/include/usb/ehci.h new file mode 100644 index 000000000..3304b6027 --- /dev/null +++ b/include/usb/ehci.h @@ -0,0 +1,10 @@ +#ifndef __USB_EHCI_H +#define __USB_EHCI_H + +#define EHCI_HAS_TT (1 << 0) + +struct ehci_platform_data { + unsigned long flags; +}; + +#endif /* __USB_EHCI_H */ From c8363b8f603db301575cf444108554e5485e24a5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 24 Jun 2010 10:13:31 +0200 Subject: [PATCH 49/65] ehci: Handle hub port reset properly This has been copied from the U-Boot ehci driver. Signed-off-by: Sascha Hauer --- drivers/usb/usb_ehci_core.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c index f3611cda2..c5d4da3f6 100644 --- a/drivers/usb/usb_ehci_core.c +++ b/drivers/usb/usb_ehci_core.c @@ -676,6 +676,8 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, ehci_writel(status_reg, reg); break; } else { + int ret; + reg |= EHCI_PS_PR; reg &= ~EHCI_PS_PE; ehci_writel(status_reg, reg); @@ -686,6 +688,22 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, */ wait_ms(50); ehci->portreset |= 1 << le16_to_cpu(req->index); + /* terminate the reset */ + ehci_writel(status_reg, reg & ~EHCI_PS_PR); + /* + * A host controller must terminate the reset + * and stabilize the state of the port within + * 2 milliseconds + */ + ret = handshake(status_reg, EHCI_PS_PR, 0, + 2 * 1000); + if (!ret) + ehci->portreset |= + 1 << le16_to_cpu(req->index); + else + printf("port(%d) reset error\n", + le16_to_cpu(req->index) - 1); + } break; default: From d99aa6b7613fe670eff2930ebc6f79d667947530 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 24 Jun 2010 10:16:26 +0200 Subject: [PATCH 50/65] usb: Check return value of host controller init And do not scan the bus if initialization failed. Signed-off-by: Sascha Hauer --- drivers/usb/usb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index 1ad4babb8..76e033eb7 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -453,6 +453,7 @@ static int __usb_init(void) { struct usb_device *dev, *tmp; struct usb_host *host; + int ret; list_for_each_entry_safe(dev, tmp, &usb_device_list, list) { list_del(&dev->list); @@ -466,7 +467,9 @@ static int __usb_init(void) dev_index = 0; list_for_each_entry(host, &host_list, list) { - host->init(host); + ret = host->init(host); + if (ret) + continue; dev = usb_alloc_new_device(); dev->host = host; From 0b863c83d0908a1524eed1e55f0efc3397badd2e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 24 Jun 2010 10:22:40 +0200 Subject: [PATCH 51/65] ehci: use is_timeout for timeout instead of udelay counter Signed-off-by: Sascha Hauer --- drivers/usb/usb_ehci_core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c index c5d4da3f6..e70e8718a 100644 --- a/drivers/usb/usb_ehci_core.c +++ b/drivers/usb/usb_ehci_core.c @@ -213,18 +213,20 @@ static inline void ehci_invalidate_dcache(struct QH *qh) static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec) { uint32_t result; + uint64_t start; - do { + start = get_time_ns(); + + while (1) { result = ehci_readl(ptr); if (result == ~(uint32_t)0) return -1; result &= mask; if (result == done) return 0; - udelay(1); - usec--; - } while (usec > 0); - return -1; + if (is_timeout(start, usec * USECOND)) + return -ETIMEDOUT; + } } static int ehci_reset(struct ehci_priv *ehci) From 2f64aa66abc67be70b0e963bdfd70a2b72f4a942 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 24 Jun 2010 10:34:27 +0200 Subject: [PATCH 52/65] ehci: Force a ehci_halt before trying to reset As observed on OMAP some controllers do not like being resetted when running. Signed-off-by: Sascha Hauer --- drivers/usb/usb_ehci_core.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c index e70e8718a..fe988c3b8 100644 --- a/drivers/usb/usb_ehci_core.c +++ b/drivers/usb/usb_ehci_core.c @@ -770,12 +770,33 @@ unknown: return -1; } +/* force HC to halt state from unknown (EHCI spec section 2.3) */ +static int ehci_halt(struct ehci_priv *ehci) +{ + u32 temp = ehci_readl(&ehci->hcor->or_usbsts); + + /* disable any irqs left enabled by previous code */ + ehci_writel(&ehci->hcor->or_usbintr, 0); + + if (temp & STS_HALT) + return 0; + + temp = ehci_readl(&ehci->hcor->or_usbcmd); + temp &= ~CMD_RUN; + ehci_writel(&ehci->hcor->or_usbcmd, temp); + + return handshake(&ehci->hcor->or_usbsts, + STS_HALT, STS_HALT, 16 * 125); +} + static int ehci_init(struct usb_host *host) { struct ehci_priv *ehci = to_ehci(host); uint32_t reg; uint32_t cmd; + ehci_halt(ehci); + /* EHCI spec section 4.1 */ if (ehci_reset(ehci) != 0) return -1; From 17ef55f6d649440100180906e65cf244c967b765 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 24 Jun 2010 10:43:48 +0200 Subject: [PATCH 53/65] ehci: remove unused code Signed-off-by: Sascha Hauer --- drivers/usb/usb_ehci.h | 4 ---- drivers/usb/usb_ehci_core.c | 5 ----- 2 files changed, 9 deletions(-) diff --git a/drivers/usb/usb_ehci.h b/drivers/usb/usb_ehci.h index b3c1d5d72..af4924955 100644 --- a/drivers/usb/usb_ehci.h +++ b/drivers/usb/usb_ehci.h @@ -187,8 +187,4 @@ struct QH { uint8_t fill[16]; }; -/* Low level init functions */ -int ehci_hcd_init(void); -int ehci_hcd_stop(void); - #endif /* USB_EHCI_H */ diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c index fe988c3b8..af066de4b 100644 --- a/drivers/usb/usb_ehci_core.c +++ b/drivers/usb/usb_ehci_core.c @@ -801,11 +801,6 @@ static int ehci_init(struct usb_host *host) if (ehci_reset(ehci) != 0) return -1; -#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET) - if (ehci_hcd_init() != 0) - return -1; -#endif - /* Set head of reclaim list */ ehci->qhp = xzalloc(sizeof(struct QH) + 32); ehci->qh_list = (struct QH *)(((unsigned long)ehci->qhp + 32) & ~31); From 7a1f70e70a8ef9cece22207f9f540624b4d982da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Thu, 24 Jun 2010 11:49:55 +0200 Subject: [PATCH 54/65] fix command loadb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit which was broken after commit c3789cd49b43ec1c414ba1b0e9f48e8ccc19f8e1 Signed-off-by: Eric Bénard Signed-off-by: Sascha Hauer --- commands/loadb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/loadb.c b/commands/loadb.c index 6740ef4a4..437b60f8c 100644 --- a/commands/loadb.c +++ b/commands/loadb.c @@ -724,7 +724,7 @@ static int do_load_serial_bin(struct command *cmdtp, int argc, char *argv[]) printf("%s:No console device with STDIN and STDOUT\n", argv[0]); return -ENODEV; } - current_baudrate = simple_strtoul(cdev->baudrate_string, NULL, 10); + current_baudrate = (int)simple_strtoul(dev_get_param(cdev->dev, "baudrate"), NULL, 10); /* Load Defaults */ if (load_baudrate == 0) From 485890986b6cff0ff2a1f23ef46cc50451c3110f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 24 Jun 2010 17:37:00 +0200 Subject: [PATCH 55/65] add netconsole host script Signed-off-by: Sascha Hauer --- scripts/netconsole | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100755 scripts/netconsole diff --git a/scripts/netconsole b/scripts/netconsole new file mode 100755 index 000000000..c8109bb09 --- /dev/null +++ b/scripts/netconsole @@ -0,0 +1,59 @@ +#!/bin/sh + +usage() { + ( + echo "Usage: $0 [board port]" + echo "" + echo "If port is not specified, '6666' will be used" + [ -z "$*" ] && exit 0 + echo "" + echo "ERROR: $*" + exit 1 + ) 1>&2 + exit $? +} + +while [ -n "$1" ] ; do + case $1 in + -h|--help) usage;; + --) break;; + -*) usage "Invalid option $1";; + *) break;; + esac + shift +done + +ip=$1 +port=${2:-6666} + +if [ -z "${ip}" ] || [ -n "$3" ] ; then + usage "Invalid number of arguments" +fi + +for nc in netcat nc ; do + type ${nc} >/dev/null 2>&1 && break +done + +trap "stty icanon echo intr ^C" 0 2 3 5 10 13 15 +echo "NOTE: the interrupt signal (normally ^C) has been remapped to ^T" + +stty -icanon -echo intr ^T +( +if type ncb 2>/dev/null ; then + # see if ncb is in $PATH + exec ncb ${port} + +elif [ -x ${0%/*}/ncb ] ; then + # maybe it's in the same dir as the netconsole script + exec ${0%/*}/ncb ${port} + +else + # blah, just use regular netcat + while ${nc} -u -l -p ${port} < /dev/null ; do + : + done +fi +) & +pid=$! +${nc} -u ${ip} ${port} +kill ${pid} 2>/dev/null From 3039467bbd3eb1fa8c9ea2c3b63451f0082143e9 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Jun 2010 14:56:50 +0200 Subject: [PATCH 56/65] tftp: remove unused variables Signed-off-by: Sascha Hauer --- net/tftp.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index 38d16bcbd..338359b11 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -35,8 +35,6 @@ static int tftp_server_port; /* The UDP port at their end */ static unsigned int tftp_block; /* packet sequence number */ static unsigned int tftp_last_block; /* last packet sequence number received */ -static unsigned int tftp_block_wrap; /* count of sequence number wraparounds */ -static unsigned int tftp_block_wrap_offset; /* memory offset due to wrapping */ static int tftp_state; static uint64_t tftp_timer_start; static int tftp_err; @@ -135,10 +133,7 @@ static void tftp_handler(char *packet, unsigned len) * number of 0 this means that there was a wrap * around of the (16 bit) counter. */ - if (tftp_block == 0) { - tftp_block_wrap++; - tftp_block_wrap_offset += TFTP_BLOCK_SIZE * TFTP_SEQUENCE_SIZE; - } else { + if (tftp_block) { if (((tftp_block - 1) % 10) == 0) { putchar('#'); } else if ((tftp_block % (10 * HASHES_PER_LINE)) == 0) { @@ -155,8 +150,6 @@ static void tftp_handler(char *packet, unsigned len) tftp_con->udp->uh_dport = udp->uh_sport; tftp_server_port = ntohs(udp->uh_sport); tftp_last_block = 0; - tftp_block_wrap = 0; - tftp_block_wrap_offset = 0; if (tftp_block != 1) { /* Assertion */ printf("error: First block is not block 1 (%ld)\n", From 257da5cac07854c89861de5925475b339e8ff71b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Jun 2010 22:31:04 +0200 Subject: [PATCH 57/65] add progression bar function Signed-off-by: Sascha Hauer --- include/progress.h | 15 +++++++++++ lib/Makefile | 1 + lib/show_progress.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 include/progress.h create mode 100644 lib/show_progress.c diff --git a/include/progress.h b/include/progress.h new file mode 100644 index 000000000..5c4dd1e77 --- /dev/null +++ b/include/progress.h @@ -0,0 +1,15 @@ +#ifndef __PROGRSS_H +#define __PROGRSS_H + +/* Initialize a progress bar. If max > 0 a one line progress + * bar is printed where 'max' corresponds to 100%. If max == 0 + * a multi line progress bar is printed. + */ +void init_progression_bar(int max); + +/* update a progress bar to a new value. If now < 0 then a + * spinner is printed. + */ +void show_progress(int now); + +#endif /* __PROGRSS_H */ diff --git a/lib/Makefile b/lib/Makefile index 4a33aaa3c..5afbf132a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -30,5 +30,6 @@ obj-y += notifier.o obj-y += copy_file.o obj-y += random.o obj-y += lzo/ +obj-y += show_progress.o obj-$(CONFIG_LZO_DECOMPRESS) += decompress_unlzo.o obj-$(CONFIG_PROCESS_ESCAPE_SEQUENCE) += process_escape_sequence.o diff --git a/lib/show_progress.c b/lib/show_progress.c new file mode 100644 index 000000000..333f49868 --- /dev/null +++ b/lib/show_progress.c @@ -0,0 +1,62 @@ +/* + * show_progress.c - simple progress bar functions + * + * Copyright (c) 2010 Sascha Hauer , Pengutronix + * + * 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 version 2 + * as published by the Free Software Foundation. + * + * 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 +#include + +#define HASHES_PER_LINE 65 + +static int printed; +static int progress_max; +static int spin; + +void show_progress(int now) +{ + char spinchr[] = "\\|/-"; + + if (now < 0) { + printf("%c\b", spinchr[spin++ % (sizeof(spinchr) - 1)]); + return; + } + + if (progress_max) + now = now * HASHES_PER_LINE / progress_max; + + while (printed < now) { + if (!(printed % HASHES_PER_LINE) && printed) + printf("\n\t"); + printf("#"); + printed++; + } +} + +void init_progression_bar(int max) +{ + printed = 0; + progress_max = max; + spin = 0; + if (progress_max) + printf("\t[%65s]\r\t[", ""); + else + printf("\t"); +} + From b99e2c4ac6296b28b7ab0a62dd82d358855c4126 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Jun 2010 22:31:46 +0200 Subject: [PATCH 58/65] cfi flash driver: Use generic progression bar function Signed-off-by: Sascha Hauer --- drivers/nor/cfi_flash.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c index dbfb004d0..b21739bd2 100644 --- a/drivers/nor/cfi_flash.c +++ b/drivers/nor/cfi_flash.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "cfi_flash.h" /* @@ -499,11 +500,13 @@ static int cfi_erase(struct cdev *cdev, size_t count, unsigned long offset) start = find_sector(finfo, cdev->dev->map_base + offset); end = find_sector(finfo, cdev->dev->map_base + offset + count - 1); + init_progression_bar(end - start); + for (i = start; i <= end; i++) { ret = finfo->cfi_cmd_set->flash_erase_one(finfo, i); if (ret) goto out; - printf("."); + show_progress(i - start); } out: putchar('\n'); From c59d7ae527c76fc5c1b524aee8af29343ac71dc7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Jun 2010 22:42:11 +0200 Subject: [PATCH 59/65] tftp: use generic progression bar Signed-off-by: Sascha Hauer --- net/tftp.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index 338359b11..4b60cc8dd 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -13,13 +13,11 @@ #include #include #include +#include #include #define TFTP_PORT 69 /* Well known TFTP port # */ #define TIMEOUT 5 /* Seconds to timeout for a lost pkt */ -# define TIMEOUT_COUNT 10 /* # of timeouts before giving up */ - /* (for checking the image size) */ -#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */ /* * TFTP operations. @@ -50,6 +48,7 @@ static int tftp_err; static char *tftp_filename; static struct net_connection *tftp_con; static int net_store_fd; +static int tftp_size; static int tftp_send(void) { @@ -84,6 +83,8 @@ static int tftp_send(void) break; } + tftp_timer_start = get_time_ns(); + show_progress(tftp_size); ret = net_udp_send(tftp_con, len); return ret; @@ -127,20 +128,6 @@ static void tftp_handler(char *packet, unsigned len) len -= 2; tftp_block = ntohs(*(uint16_t *)pkt); - /* - * RFC1350 specifies that the first data packet will - * have sequence number 1. If we receive a sequence - * number of 0 this means that there was a wrap - * around of the (16 bit) counter. - */ - if (tftp_block) { - if (((tftp_block - 1) % 10) == 0) { - putchar('#'); - } else if ((tftp_block % (10 * HASHES_PER_LINE)) == 0) { - puts("\n\t "); - } - } - if (tftp_state == STATE_RRQ) debug("Server did not acknowledge timeout option!\n"); @@ -165,7 +152,9 @@ static void tftp_handler(char *packet, unsigned len) break; tftp_last_block = tftp_block; - tftp_timer_start = get_time_ns(); + + if (!(tftp_block % 10)) + tftp_size++; ret = write(net_store_fd, pkt + 2, len); if (ret < 0) { @@ -205,6 +194,8 @@ static int do_tftpb(struct command *cmdtp, int argc, char *argv[]) char *remotefile; char ip1[16]; + tftp_size = 0; + if (argc < 2) return COMMAND_ERROR_USAGE; @@ -229,10 +220,12 @@ static int do_tftpb(struct command *cmdtp, int argc, char *argv[]) tftp_filename = remotefile; - printf("TFTP from server %s; Filename: '%s'\nLoading: ", + printf("TFTP from server %s; Filename: '%s'\n", ip_to_string(net_get_serverip(), ip1), tftp_filename); + init_progression_bar(0); + tftp_timer_start = get_time_ns(); tftp_state = STATE_RRQ; tftp_block = 0; @@ -248,8 +241,7 @@ static int do_tftpb(struct command *cmdtp, int argc, char *argv[]) } net_poll(); if (is_timeout(tftp_timer_start, SECOND)) { - tftp_timer_start = get_time_ns(); - printf("T "); + show_progress(-1); tftp_send(); } } From d0548ba506d127cba8bce93e90c5bc04583f0238 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 15 Jun 2010 09:32:51 +0200 Subject: [PATCH 60/65] tftp: Add push support Signed-off-by: Sascha Hauer Tested-by: Baruch Siach --- net/Kconfig | 4 ++ net/tftp.c | 188 +++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 155 insertions(+), 37 deletions(-) diff --git a/net/Kconfig b/net/Kconfig index ff6e45523..3169d2083 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -19,6 +19,10 @@ config NET_TFTP bool prompt "tftp support" +config NET_TFTP_PUSH + bool + prompt "tftp push support" + config NET_NETCONSOLE bool prompt "network console support" diff --git a/net/tftp.c b/net/tftp.c index 4b60cc8dd..e6a202738 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -14,6 +14,9 @@ #include #include #include +#include +#include +#include #include #define TFTP_PORT 69 /* Well known TFTP port # */ @@ -38,41 +41,89 @@ static uint64_t tftp_timer_start; static int tftp_err; #define STATE_RRQ 1 -#define STATE_DATA 2 -#define STATE_OACK 3 -#define STATE_DONE 4 +#define STATE_WRQ 2 +#define STATE_RDATA 3 +#define STATE_WDATA 4 +#define STATE_OACK 5 +#define STATE_LAST 6 +#define STATE_DONE 7 #define TFTP_BLOCK_SIZE 512 /* default TFTP block size */ -#define TFTP_SEQUENCE_SIZE ((unsigned long)(1<<16)) /* sequence number is 16 bit */ static char *tftp_filename; static struct net_connection *tftp_con; -static int net_store_fd; +static int tftp_fd; static int tftp_size; +#ifdef CONFIG_NET_TFTP_PUSH +static int tftp_push; + +static inline void do_tftp_push(int push) +{ + tftp_push = push; +} + +#else + +#define tftp_push 0 + +static inline void do_tftp_push(int push) +{ +} +#endif + static int tftp_send(void) { - unsigned char *pkt; unsigned char *xp; int len = 0; uint16_t *s; - unsigned char *packet = net_udp_get_payload(tftp_con); + unsigned char *pkt = net_udp_get_payload(tftp_con); int ret; - - pkt = packet; + static int last_len; switch (tftp_state) { case STATE_RRQ: + case STATE_WRQ: xp = pkt; s = (uint16_t *)pkt; - *s++ = htons(TFTP_RRQ); + if (tftp_state == STATE_RRQ) + *s++ = htons(TFTP_RRQ); + else + *s++ = htons(TFTP_WRQ); pkt = (unsigned char *)s; pkt += sprintf((unsigned char *)pkt, "%s%coctet%ctimeout%c%d", tftp_filename, 0, 0, 0, TIMEOUT) + 1; len = pkt - xp; break; - case STATE_DATA: + case STATE_WDATA: + if (!tftp_push) + break; + + if (tftp_last_block == tftp_block) { + len = last_len; + break; + } + + tftp_last_block = tftp_block; + s = (uint16_t *)pkt; + *s++ = htons(TFTP_DATA); + *s++ = htons(tftp_block); + len = read(tftp_fd, s, 512); + if (len < 0) { + perror("read"); + tftp_err = -errno; + tftp_state = STATE_DONE; + return tftp_err; + } + tftp_size += len; + if (len < 512) + tftp_state = STATE_LAST; + len += 4; + last_len = len; + break; + + case STATE_RDATA: case STATE_OACK: xp = pkt; s = (uint16_t *)pkt; @@ -103,24 +154,52 @@ static void tftp_handler(char *packet, unsigned len) return; len -= 2; - /* warning: don't use increment (++) in ntohs() macros!! */ + s = (uint16_t *)pkt; proto = *s++; pkt = (unsigned char *)s; + switch (ntohs(proto)) { case TFTP_RRQ: case TFTP_WRQ: - case TFTP_ACK: - break; default: break; + case TFTP_ACK: + if (!tftp_push) + break; + + tftp_block = ntohs(*(uint16_t *)pkt); + if (tftp_block != tftp_last_block) { + debug("ack %d != %d\n", tftp_block, tftp_last_block); + break; + } + tftp_block++; + if (tftp_state == STATE_LAST) { + tftp_state = STATE_DONE; + break; + } + tftp_con->udp->uh_dport = udp->uh_sport; + tftp_state = STATE_WDATA; + tftp_send(); + break; case TFTP_OACK: debug("Got OACK: %s %s\n", pkt, pkt + strlen(pkt) + 1); - tftp_state = STATE_OACK; tftp_server_port = ntohs(udp->uh_sport); tftp_con->udp->uh_dport = udp->uh_sport; - tftp_send(); /* Send ACK */ + + if (tftp_push) { + /* send first block */ + tftp_state = STATE_WDATA; + tftp_block = 1; + } else { + /* send ACK */ + tftp_state = STATE_OACK; + tftp_block = 0; + } + + tftp_send(); + break; case TFTP_DATA: if (len < 2) @@ -133,7 +212,7 @@ static void tftp_handler(char *packet, unsigned len) if (tftp_state == STATE_RRQ || tftp_state == STATE_OACK) { /* first block received */ - tftp_state = STATE_DATA; + tftp_state = STATE_RDATA; tftp_con->udp->uh_dport = udp->uh_sport; tftp_server_port = ntohs(udp->uh_sport); tftp_last_block = 0; @@ -156,7 +235,7 @@ static void tftp_handler(char *packet, unsigned len) if (!(tftp_block % 10)) tftp_size++; - ret = write(net_store_fd, pkt + 2, len); + ret = write(tftp_fd, pkt + 2, len); if (ret < 0) { perror("write"); tftp_err = -errno; @@ -190,24 +269,47 @@ static void tftp_handler(char *packet, unsigned len) static int do_tftpb(struct command *cmdtp, int argc, char *argv[]) { - char *localfile; - char *remotefile; + char *localfile, *remotefile, *file1, *file2; char ip1[16]; + int opt; + struct stat s; + unsigned long flags; + do_tftp_push(0); + tftp_last_block = 0; tftp_size = 0; - if (argc < 2) + while((opt = getopt(argc, argv, "p")) > 0) { + switch(opt) { + case 'p': + do_tftp_push(1); + break; + } + } + + if (argc <= optind) return COMMAND_ERROR_USAGE; - remotefile = argv[1]; + file1 = argv[optind++]; - if (argc == 2) - localfile = basename(remotefile); + if (argc == optind) + file2 = basename(file1); else - localfile = argv[2]; + file2 = argv[optind]; - net_store_fd = open(localfile, O_WRONLY | O_CREAT); - if (net_store_fd < 0) { + if (tftp_push) { + localfile = file1; + remotefile = file2; + stat(localfile, &s); + flags = O_RDONLY; + } else { + localfile = file2; + remotefile = file1; + flags = O_WRONLY | O_CREAT; + } + + tftp_fd = open(localfile, flags); + if (tftp_fd < 0) { perror("open"); return 1; } @@ -220,15 +322,16 @@ static int do_tftpb(struct command *cmdtp, int argc, char *argv[]) tftp_filename = remotefile; - printf("TFTP from server %s; Filename: '%s'\n", + printf("TFTP %s server %s ('%s' -> '%s')\n", + tftp_push ? "to" : "from", ip_to_string(net_get_serverip(), ip1), - tftp_filename); + file1, file2); - init_progression_bar(0); + init_progression_bar(tftp_push ? s.st_size : 0); tftp_timer_start = get_time_ns(); - tftp_state = STATE_RRQ; - tftp_block = 0; + tftp_state = tftp_push ? STATE_WRQ : STATE_RRQ; + tftp_block = 1; tftp_err = tftp_send(); if (tftp_err) @@ -248,11 +351,12 @@ static int do_tftpb(struct command *cmdtp, int argc, char *argv[]) out_unreg: net_unregister(tftp_con); out_close: - close(net_store_fd); + close(tftp_fd); if (tftp_err) { printf("\ntftp failed: %s\n", strerror(-tftp_err)); - unlink(localfile); + if (!tftp_push) + unlink(localfile); } printf("\n"); @@ -261,12 +365,22 @@ out_close: } static const __maybe_unused char cmd_tftp_help[] = -"Usage: tftp [localfile]\n" -"Load a file via network using BootP/TFTP protocol.\n"; +"Usage: tftp [localfile]\n" +"Load a file from a TFTP server.\n" +#ifdef CONFIG_NET_TFTP_PUSH +"or\n" +" tftp -p [remotefile]\n" +"Upload a file to a TFTP server\n" +#endif +; BAREBOX_CMD_START(tftp) .cmd = do_tftpb, - .usage = "Load file using tftp protocol", + .usage = +#ifdef CONFIG_NET_TFTP_PUSH + "(up-)" +#endif + "Load file using tftp protocol", BAREBOX_CMD_HELP(cmd_tftp_help) BAREBOX_CMD_END From 80c071dd56bdd021b41b0d303f1f190bd79f590c Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 15 Jun 2010 10:41:47 +0200 Subject: [PATCH 61/65] nfs: Use generic progression bar Signed-off-by: Sascha Hauer --- net/nfs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/nfs.c b/net/nfs.c index 51df7a367..bdf05bd40 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #define SUNRPC_PORT 111 @@ -123,7 +124,6 @@ struct rpc_t { } u; }; -#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */ #define NFS_TIMEOUT 60 static unsigned long rpc_id = 0; @@ -540,10 +540,10 @@ static int nfs_read_reply(unsigned char *pkt, unsigned len) data = (uint32_t *)(pkt + sizeof(struct rpc_reply)); - if (nfs_offset && !((nfs_offset) % (NFS_READ_SIZE / 2 * 10 * HASHES_PER_LINE))) - puts ("\n\t "); - if (!(nfs_offset % ((NFS_READ_SIZE / 2) * 10))) - putchar ('#'); + if (!nfs_offset) { + uint32_t filesize = ntohl(net_read_uint32(data + 6)); + init_progression_bar(filesize); + } rlen = ntohl(net_read_uint32(data + 18)); @@ -629,7 +629,7 @@ static void nfs_handler(char *packet, unsigned len) nfs_state = STATE_READLINK_REQ; else goto err_umount; - + show_progress(nfs_offset); break; } @@ -659,7 +659,7 @@ static void nfs_start(char *p) nfs_filename = basename (nfs_path); nfs_path = dirname (nfs_path); - printf("\nFilename '%s/%s'.\nLoading: ", nfs_path, nfs_filename); + printf("\nFilename '%s/%s'.\n", nfs_path, nfs_filename); nfs_timer_start = get_time_ns(); From b3c91fbf5fcfb6d9b022bce8727abadb93266c1f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 15 Jun 2010 10:44:43 +0200 Subject: [PATCH 62/65] nfs: resend requests after timeout Signed-off-by: Sascha Hauer --- net/nfs.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/net/nfs.c b/net/nfs.c index bdf05bd40..4ca1d6e52 100644 --- a/net/nfs.c +++ b/net/nfs.c @@ -124,7 +124,7 @@ struct rpc_t { } u; }; -#define NFS_TIMEOUT 60 +#define NFS_TIMEOUT 1 static unsigned long rpc_id = 0; static int nfs_offset = -1; @@ -399,6 +399,8 @@ static void nfs_send(void) nfs_readlink_req(); break; } + + nfs_timer_start = get_time_ns(); } static int rpc_check_reply(unsigned char *pkt, int isnfs) @@ -661,8 +663,6 @@ static void nfs_start(char *p) printf("\nFilename '%s/%s'.\n", nfs_path, nfs_filename); - nfs_timer_start = get_time_ns(); - nfs_state = STATE_PRCLOOKUP_PROG_MOUNT_REQ; nfs_send(); @@ -706,8 +706,10 @@ static int do_nfs(struct command *cmdtp, int argc, char *argv[]) break; } net_poll(); - if (is_timeout(nfs_timer_start, NFS_TIMEOUT * SECOND)) - break; + if (is_timeout(nfs_timer_start, NFS_TIMEOUT * SECOND)) { + show_progress(-1); + nfs_send(); + } } net_unregister(nfs_con); From 38d862f68731ef204aaad906cecb049882db7c05 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 15 Jun 2010 11:49:19 +0200 Subject: [PATCH 63/65] tftp: update doxygen information Signed-off-by: Sascha Hauer --- net/tftp.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index e6a202738..6345a7220 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -387,16 +387,21 @@ BAREBOX_CMD_END /** * @page tftp_command tftp * - * Usage is: tftp \ [\] + * Usage: + * tftp \ [\] * - * Load a file via network using BootP/TFTP protocol. The loaded file you - * can find after download in you current ramdisk. Refer \b ls command. + * or * - * \ can be the local filename only, or also a device name. In the - * case of a device name, the will gets stored there. This works also for - * partitions of flash memory. Refer \b erase, \b unprotect for flash - * preparation. + * tftp -p \ [\] * - * Note: This command is available only, if enabled in the menuconfig. + * Load a file from a tftp server or upload a file to a tftp server if + * the -p option is given. The second file argument can be skipped in + * which case the first filename is used (without the directory part). + * + * \ can be the local filename or a device file under /dev. + * This also works for flash memory. Refer to \b erase, \b unprotect for + * flash preparation. + * + * Note: This command is available only if enabled in menuconfig. */ From c26f09b2c1a7f1ed2d712dc7994f244d2a8be799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Thu, 24 Jun 2010 17:03:04 +0200 Subject: [PATCH 64/65] imx-ipu-fb: Add board specific hook to enable display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eric Bénard Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imx-ipu-fb.h | 2 ++ drivers/video/imx-ipu-fb.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/arch/arm/mach-imx/include/mach/imx-ipu-fb.h b/arch/arm/mach-imx/include/mach/imx-ipu-fb.h index 53c6d2652..dd65b04c5 100644 --- a/arch/arm/mach-imx/include/mach/imx-ipu-fb.h +++ b/arch/arm/mach-imx/include/mach/imx-ipu-fb.h @@ -28,6 +28,8 @@ struct imx_ipu_fb_platform_data { const struct fb_videomode *mode; unsigned char bpp; void __iomem *framebuffer; + /** hook to enable backlight and stuff */ + void (*enable)(int enable); }; #endif /* __MACH_IMX_IPU_FB_H__ */ diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c index 0bd86b286..bfdc3a59d 100644 --- a/drivers/video/imx-ipu-fb.c +++ b/drivers/video/imx-ipu-fb.c @@ -36,6 +36,8 @@ struct ipu_fb_info { void __iomem *regs; + void (*enable)(int enable); + struct fb_info info; struct device_d *dev; }; @@ -828,6 +830,8 @@ static void ipu_fb_enable(struct fb_info *info) * Linux driver calls sdc_set_brightness() here again, * once is enough for us */ + if (fbi->enable) + fbi->enable(1); } static void ipu_fb_disable(struct fb_info *info) @@ -837,6 +841,9 @@ static void ipu_fb_disable(struct fb_info *info) printf("%s\n", __func__); + if (fbi->enable) + fbi->enable(0); + reg = reg_read(fbi, SDC_COM_CONF); reg &= ~SDC_COM_BG_EN; reg_write(fbi, reg, SDC_COM_CONF); @@ -868,6 +875,7 @@ static int imxfb_probe(struct device_d *dev) info->yres = pdata->mode->yres; info->bits_per_pixel = pdata->bpp; info->fbops = &imxfb_ops; + fbi->enable = pdata->enable; dev_info(dev, "i.MX Framebuffer driver\n"); From 7f5644fad10f8f7a86742dd30d2812261cd0a623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Thu, 24 Jun 2010 17:03:05 +0200 Subject: [PATCH 65/65] imx-ipu-fb: do not enable framebuffer on startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The board code or startup script should enable it when it actually wants to. Signed-off-by: Eric Bénard Signed-off-by: Sascha Hauer --- drivers/video/imx-ipu-fb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c index bfdc3a59d..7e2c74bcc 100644 --- a/drivers/video/imx-ipu-fb.c +++ b/drivers/video/imx-ipu-fb.c @@ -899,8 +899,6 @@ static int imxfb_probe(struct device_d *dev) return ret; } - ipu_fb_enable(info); - return 0; }