diff options
Diffstat (limited to 'target/linux/ixp4xx')
13 files changed, 1091 insertions, 193 deletions
diff --git a/target/linux/ixp4xx/Makefile b/target/linux/ixp4xx/Makefile index 23cec4b8b..e0797749c 100644 --- a/target/linux/ixp4xx/Makefile +++ b/target/linux/ixp4xx/Makefile @@ -12,7 +12,7 @@ BOARDNAME:=Intel IXP4xx FEATURES:=squashfs SUBTARGETS=generic harddisk -LINUX_VERSION:=2.6.24.5 +LINUX_VERSION:=2.6.25 include $(INCLUDE_DIR)/target.mk diff --git a/target/linux/ixp4xx/patches-2.6.25/151-lanready_ap1000_mac_plat_info.patch b/target/linux/ixp4xx/patches-2.6.25/151-lanready_ap1000_mac_plat_info.patch index 4259ff971..2ab59ff06 100644 --- a/target/linux/ixp4xx/patches-2.6.25/151-lanready_ap1000_mac_plat_info.patch +++ b/target/linux/ixp4xx/patches-2.6.25/151-lanready_ap1000_mac_plat_info.patch @@ -1,14 +1,15 @@ diff -Nur linux-2.6.23.1/arch/arm/mach-ixp4xx/ap1000-setup.c linux-2.6.23.1-owrt/arch/arm/mach-ixp4xx/ap1000-setup.c --- linux-2.6.23.1/arch/arm/mach-ixp4xx/ap1000-setup.c 2007-11-14 14:11:10.000000000 +0100 +++ linux-2.6.23.1-owrt/arch/arm/mach-ixp4xx/ap1000-setup.c 2007-11-14 14:09:30.000000000 +0100 -@@ -90,9 +90,36 @@ +@@ -90,9 +90,37 @@ .resource = ap1000_uart_resources }; +/* Built-in 10/100 Ethernet MAC interfaces */ +static struct eth_plat_info ap1000_plat_eth[] = { + { -+ .phy = 4, ++ .phy = IXP4XX_ETH_PHY_MAX_ADDR, ++ .phy_mask = 0x1e, + .rxq = 3, + .txreadyq = 20, + }, { diff --git a/target/linux/ixp4xx/patches-2.6.25/190-cambria_support.patch b/target/linux/ixp4xx/patches-2.6.25/190-cambria_support.patch new file mode 100644 index 000000000..4fbc1de8a --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.25/190-cambria_support.patch @@ -0,0 +1,390 @@ +diff -Nur linux-2.6.24.5/arch/arm/mach-ixp4xx/Kconfig linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/Kconfig +--- linux-2.6.24.5/arch/arm/mach-ixp4xx/Kconfig 2008-04-28 20:22:27.000000000 +0200 ++++ linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/Kconfig 2008-04-28 20:26:44.000000000 +0200 +@@ -25,6 +25,14 @@ + Avila Network Platform. For more information on this platform, + see <file:Documentation/arm/IXP4xx>. + ++config MACH_CAMBRIA ++ bool "Cambria" ++ select PCI ++ help ++ Say 'Y' here if you want your kernel to support the Gateworks ++ Cambria series. For more information on this platform, ++ see <file:Documentation/arm/IXP4xx>. ++ + config MACH_LOFT + bool "Loft" + depends on MACH_AVILA +@@ -200,7 +208,7 @@ + + config CPU_IXP43X + bool +- depends on MACH_KIXRP435 ++ depends on MACH_KIXRP435 || MACH_CAMBRIA + default y + + config MACH_GTWX5715 +diff -Nur linux-2.6.24.5/arch/arm/mach-ixp4xx/Makefile linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/Makefile +--- linux-2.6.24.5/arch/arm/mach-ixp4xx/Makefile 2008-04-28 20:22:27.000000000 +0200 ++++ linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/Makefile 2008-04-28 20:26:44.000000000 +0200 +@@ -7,6 +7,7 @@ + + obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o + obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o ++obj-pci-$(CONFIG_MACH_CAMBRIA) += cambria-pci.o + obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o + obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o + obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o +@@ -28,6 +29,7 @@ + + obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o + obj-$(CONFIG_MACH_AVILA) += avila-setup.o ++obj-$(CONFIG_MACH_CAMBRIA) += cambria-setup.o + obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o + obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o + obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o +diff -Nur linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-pci.c linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/cambria-pci.c +--- linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/cambria-pci.c 2008-04-28 20:30:35.000000000 +0200 +@@ -0,0 +1,74 @@ ++/* ++ * arch/arch/mach-ixp4xx/cambria-pci.c ++ * ++ * PCI setup routines for Gateworks Cambria series ++ * ++ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> ++ * ++ * based on coyote-pci.c: ++ * Copyright (C) 2002 Jungo Software Technologies. ++ * Copyright (C) 2003 MontaVista Softwrae, Inc. ++ * ++ * Maintainer: Imre Kaloz <kaloz@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++#include <linux/irq.h> ++ ++#include <asm/mach-types.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++ ++#include <asm/mach/pci.h> ++ ++extern void ixp4xx_pci_preinit(void); ++extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); ++extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); ++ ++void __init cambria_pci_preinit(void) ++{ ++ set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW); ++ set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW); ++ set_irq_type(IRQ_IXP4XX_GPIO9, IRQT_LOW); ++ set_irq_type(IRQ_IXP4XX_GPIO8, IRQT_LOW); ++ ++ ixp4xx_pci_preinit(); ++} ++ ++static int __init cambria_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ if (slot == 1) ++ return IRQ_IXP4XX_GPIO11; ++ else if (slot == 2) ++ return IRQ_IXP4XX_GPIO10; ++ else if (slot == 3) ++ return IRQ_IXP4XX_GPIO9; ++ else if (slot == 4) ++ return IRQ_IXP4XX_GPIO8; ++ else return -1; ++} ++ ++struct hw_pci cambria_pci __initdata = { ++ .nr_controllers = 1, ++ .preinit = cambria_pci_preinit, ++ .swizzle = pci_std_swizzle, ++ .setup = ixp4xx_setup, ++ .scan = ixp4xx_scan_bus, ++ .map_irq = cambria_map_irq, ++}; ++ ++int __init cambria_pci_init(void) ++{ ++ if (machine_is_cambria()) ++ pci_common_init(&cambria_pci); ++ return 0; ++} ++ ++subsys_initcall(cambria_pci_init); +diff -Nur linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-setup.c linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/cambria-setup.c +--- linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/cambria-setup.c 2008-04-28 21:07:16.000000000 +0200 +@@ -0,0 +1,250 @@ ++/* ++ * arch/arm/mach-ixp4xx/cambria-setup.c ++ * ++ * Board setup for the Gateworks Cambria series ++ * ++ * Copyright (C) 2008 Imre Kaloz <Kaloz@openwrt.org> ++ * ++ * based on coyote-setup.c: ++ * Copyright (C) 2003-2005 MontaVista Software, Inc. ++ * ++ * Author: Imre Kaloz <Kaloz@openwrt.org> ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/if_ether.h> ++#include <linux/socket.h> ++#include <linux/netdevice.h> ++#include <linux/serial.h> ++#include <linux/tty.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++#ifdef CONFIG_SENSORS_EEPROM ++# include <linux/i2c.h> ++# include <linux/eeprom.h> ++#endif ++ ++#include <linux/i2c-gpio.h> ++#include <asm/types.h> ++#include <asm/setup.h> ++#include <asm/memory.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++ ++static struct flash_platform_data cambria_flash_data = { ++ .map_name = "cfi_probe", ++ .width = 2, ++}; ++ ++static struct resource cambria_flash_resource = { ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct platform_device cambria_flash = { ++ .name = "IXP4XX-Flash", ++ .id = 0, ++ .dev = { ++ .platform_data = &cambria_flash_data, ++ }, ++ .num_resources = 1, ++ .resource = &cambria_flash_resource, ++}; ++ ++static struct i2c_gpio_platform_data cambria_i2c_gpio_data = { ++ .sda_pin = 7, ++ .scl_pin = 6, ++}; ++ ++static struct platform_device cambria_i2c_gpio = { ++ .name = "i2c-gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &cambria_i2c_gpio_data, ++ }, ++}; ++ ++static struct resource cambria_uart_resource = { ++ .start = IXP4XX_UART1_BASE_PHYS, ++ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct plat_serial8250_port cambria_uart_data[] = { ++ { ++ .mapbase = IXP4XX_UART1_BASE_PHYS, ++ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, ++ .irq = IRQ_IXP4XX_UART1, ++ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++ .iotype = UPIO_MEM, ++ .regshift = 2, ++ .uartclk = IXP4XX_UART_XTAL, ++ }, ++ { }, ++}; ++ ++static struct platform_device cambria_uart = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .dev = { ++ .platform_data = cambria_uart_data, ++ }, ++ .num_resources = 1, ++ .resource = &cambria_uart_resource, ++}; ++ ++static struct resource cambria_pata_resources[] = { ++ { ++ .flags = IORESOURCE_MEM ++ }, ++ { ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .name = "intrq", ++ .start = IRQ_IXP4XX_GPIO12, ++ .end = IRQ_IXP4XX_GPIO12, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct ixp4xx_pata_data cambria_pata_data = { ++ .cs0_bits = 0xbfff3c03, ++ .cs1_bits = 0xbfff3c03, ++}; ++ ++static struct platform_device cambria_pata = { ++ .name = "pata_ixp4xx_cf", ++ .id = 0, ++ .dev.platform_data = &cambria_pata_data, ++ .num_resources = ARRAY_SIZE(cambria_pata_resources), ++ .resource = cambria_pata_resources, ++}; ++ ++static struct eth_plat_info cambria_plat_eth[] = { ++ { ++ .phy = 2, ++ .rxq = 4, ++ .txreadyq = 21, ++ }, { ++ .phy = 1, ++ .rxq = 2, ++ .txreadyq = 19, ++ } ++}; ++ ++static struct platform_device cambria_eth[] = { ++ { ++ .name = "ixp4xx_eth", ++ .id = IXP4XX_ETH_NPEC, ++ .dev.platform_data = cambria_plat_eth, ++ }, { ++ .name = "ixp4xx_eth", ++ .id = IXP4XX_ETH_NPEA, ++ .dev.platform_data = cambria_plat_eth + 1, ++ } ++}; ++ ++#ifdef CONFIG_LEDS_IXP4XX ++static struct platform_device cambria_leds_pld = { ++ .name = "IXP4XX-PLD-LED", ++ .id = -1, ++ .num_resources = 0, ++}; ++ ++static struct platform_device cambria_leds_mem = { ++ .name = "IXP4XX-MEM-LED", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ ++static struct platform_device *cambria_devices[] __initdata = { ++ &cambria_i2c_gpio, ++ &cambria_flash, ++ &cambria_uart, ++#ifdef CONFIG_LEDS_IXP4XX ++ &cambria_leds_pld, ++ &cambria_leds_mem, ++#endif ++ &cambria_eth[0], ++ &cambria_eth[1], ++}; ++ ++#ifdef CONFIG_SENSORS_EEPROM ++static int cambria_eeprom_do(struct notifier_block *self, unsigned long event, void *t) ++{ ++ struct eeprom_data *data = t; ++ struct sockaddr address; ++ struct net_device * netdev; ++ ++ char macs[12]; ++ ++ /* The MACs are the first 12 bytes in the eeprom at address 0x51 */ ++ if (event == EEPROM_REGISTER && data->client.addr == 0x51) { ++ data->attr->read(&data->client.dev.kobj, data->attr, macs, 0, 12); ++ /* eth0 */ ++ memcpy(address.sa_data, macs, ETH_ALEN); ++ memcpy(&cambria_plat_eth[0].hwaddr, macs, ETH_ALEN); ++ if ( (netdev = dev_get_by_name(&init_net, "eth0")) ) ++ netdev->set_mac_address(netdev, &address); ++ ++ /* eth1 */ ++ memcpy(address.sa_data, macs + ETH_ALEN, ETH_ALEN); ++ memcpy(&cambria_plat_eth[1].hwaddr, macs + ETH_ALEN, ETH_ALEN); ++ if ( (netdev = dev_get_by_name(&init_net, "eth1")) ) ++ netdev->set_mac_address(netdev, &address); ++ } ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block cambria_eeprom_notifier = { ++ .notifier_call = cambria_eeprom_do ++}; ++#endif ++ ++static void __init cambria_init(void) ++{ ++ ixp4xx_sys_init(); ++ ++#ifdef CONFIG_SENSORS_EEPROM ++ register_eeprom_notifier(&cambria_eeprom_notifier); ++#endif ++ ++ cambria_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++ cambria_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1; ++ ++ *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE; ++ *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; ++ ++ platform_add_devices(cambria_devices, ARRAY_SIZE(cambria_devices)); ++ ++ cambria_pata_resources[0].start = 0x53e00000; ++ cambria_pata_resources[0].end = 0x53e3ffff; ++ ++ cambria_pata_resources[1].start = 0x53e40000; ++ cambria_pata_resources[1].end = 0x53e7ffff; ++ ++ cambria_pata_data.cs0_cfg = IXP4XX_EXP_CS3; ++ cambria_pata_data.cs1_cfg = IXP4XX_EXP_CS3; ++ ++ platform_device_register(&cambria_pata); ++} ++ ++#ifdef CONFIG_MACH_CAMBRIA ++MACHINE_START(CAMBRIA, "Gateworks Cambria series") ++ /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */ ++ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, ++ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, ++ .map_io = ixp4xx_map_io, ++ .init_irq = ixp4xx_init_irq, ++ .timer = &ixp4xx_timer, ++ .boot_params = 0x0100, ++ .init_machine = cambria_init, ++MACHINE_END ++#endif +diff -Nur linux-2.6.24.5/include/asm-arm/arch-ixp4xx/hardware.h linux-2.6.24.5-owrt/include/asm-arm/arch-ixp4xx/hardware.h +--- linux-2.6.24.5/include/asm-arm/arch-ixp4xx/hardware.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.24.5-owrt/include/asm-arm/arch-ixp4xx/hardware.h 2008-04-28 21:07:16.000000000 +0200 +@@ -18,7 +18,7 @@ + #define __ASM_ARCH_HARDWARE_H__ + + #define PCIBIOS_MIN_IO 0x00001000 +-#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x40000000 : 0x48000000) ++#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x48000000 : 0x48000000) + + /* + * We override the standard dma-mask routines for bouncing. diff --git a/target/linux/ixp4xx/patches-2.6.25/202-npe_driver_switch_support.patch b/target/linux/ixp4xx/patches-2.6.25/202-npe_driver_switch_support.patch new file mode 100644 index 000000000..4e6c959d9 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.25/202-npe_driver_switch_support.patch @@ -0,0 +1,252 @@ +Index: linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c +=================================================================== +--- linux-2.6.24.2.orig/drivers/net/arm/ixp4xx_eth.c ++++ linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c +@@ -165,14 +165,15 @@ struct port { + struct net_device *netdev; + struct napi_struct napi; + struct net_device_stats stat; +- struct mii_if_info mii; ++ struct mii_if_info mii[IXP4XX_ETH_PHY_MAX_ADDR]; + struct delayed_work mdio_thread; + struct eth_plat_info *plat; + buffer_t *rx_buff_tab[RX_DESCS], *tx_buff_tab[TX_DESCS]; + struct desc *desc_tab; /* coherent */ + u32 desc_tab_phys; + int id; /* logical port ID */ +- u16 mii_bmcr; ++ u16 mii_bmcr[IXP4XX_ETH_PHY_MAX_ADDR]; ++ int phy_count; + }; + + /* NPE message structure */ +@@ -316,13 +317,14 @@ static void mdio_write(struct net_device + spin_unlock_irqrestore(&mdio_lock, flags); + } + +-static void phy_reset(struct net_device *dev, int phy_id) ++static void phy_reset(struct net_device *dev, int idx) + { + struct port *port = netdev_priv(dev); ++ int phy_id = port->mii[idx].phy_id; + int cycles = 0; + +- mdio_write(dev, phy_id, MII_BMCR, port->mii_bmcr | BMCR_RESET); +- ++ mdio_write(dev, phy_id, MII_BMCR, port->mii_bmcr[idx] | BMCR_RESET); ++ + while (cycles < MAX_MII_RESET_RETRIES) { + if (!(mdio_read(dev, phy_id, MII_BMCR) & BMCR_RESET)) { + #if DEBUG_MDIO +@@ -335,12 +337,12 @@ static void phy_reset(struct net_device + cycles++; + } + +- printk(KERN_ERR "%s: MII reset failed\n", dev->name); ++ printk(KERN_ERR "%s: MII reset failed on PHY%2d\n", dev->name, phy_id); + } + +-static void eth_set_duplex(struct port *port) ++static void eth_set_duplex(struct port *port, int full_duplex) + { +- if (port->mii.full_duplex) ++ if (full_duplex) + __raw_writel(DEFAULT_TX_CNTRL0 & ~TX_CNTRL0_HALFDUPLEX, + &port->regs->tx_control[0]); + else +@@ -348,7 +350,7 @@ static void eth_set_duplex(struct port * + &port->regs->tx_control[0]); + } + +- ++#if 0 + static void phy_check_media(struct port *port, int init) + { + if (mii_check_media(&port->mii, 1, init)) +@@ -367,7 +369,63 @@ static void phy_check_media(struct port + } + } + } ++#else ++static void phy_update_link(struct net_device *dev, int link) ++{ ++ int prev_link = netif_carrier_ok(dev); ++ ++ if (!prev_link && link) { ++ printk(KERN_INFO "%s: link up\n", dev->name); ++ netif_carrier_on(dev); ++ } else if (prev_link && !link) { ++ printk(KERN_INFO "%s: link down\n", dev->name); ++ netif_carrier_off(dev); ++ } ++} ++ ++static void phy_check_media(struct port *port, int init) ++{ ++ struct net_device *dev = port->netdev; ++ ++ if (port->phy_count == 1) { ++ struct mii_if_info *mii = &port->mii[0]; ++ ++ if (mii_check_media(mii, 1, init)) ++ eth_set_duplex(port, mii->full_duplex); ++ ++ if (mii->force_media) /* mii_check_media() doesn't work */ ++ phy_update_link(dev, mii_link_ok(mii)); ++ } else { ++ int cur_link = 0; ++ int i; ++ ++ if (init) ++ eth_set_duplex(port, 1); ++ ++ for (i = 0; i < port->phy_count; i++) ++ cur_link |= mii_link_ok(&port->mii[i]); ++ ++ phy_update_link(dev, cur_link); ++ } ++} ++#endif + ++static void phy_power_down(struct net_device *dev, int idx) ++{ ++ struct port *port = netdev_priv(dev); ++ int phy_id = port->mii[idx].phy_id; ++ ++ port->mii_bmcr[idx] = mdio_read(dev, phy_id, MII_BMCR) & ++ ~(BMCR_RESET | BMCR_PDOWN); ++ mdio_write(dev, phy_id, MII_BMCR, port->mii_bmcr[idx] | BMCR_PDOWN); ++} ++ ++static void phy_power_up(struct net_device *dev, int idx) ++{ ++ struct port *port = netdev_priv(dev); ++ ++ mdio_write(dev, port->mii[idx].phy_id, MII_BMCR, port->mii_bmcr[idx]); ++} + + static void mdio_thread(struct work_struct *work) + { +@@ -790,9 +848,12 @@ static int eth_ioctl(struct net_device * + + if (!netif_running(dev)) + return -EINVAL; +- err = generic_mii_ioctl(&port->mii, if_mii(req), cmd, &duplex_chg); ++ if (port->phy_count != 1) ++ return -EOPNOTSUPP; ++ ++ err = generic_mii_ioctl(&port->mii[0], if_mii(req), cmd, &duplex_chg); + if (duplex_chg) +- eth_set_duplex(port); ++ eth_set_duplex(port, port->mii[0].full_duplex); + return err; + } + +@@ -944,7 +1005,8 @@ static int eth_open(struct net_device *d + } + } + +- mdio_write(dev, port->plat->phy, MII_BMCR, port->mii_bmcr); ++ for (i = 0; i < port->phy_count; i++) ++ phy_power_up(dev, i); + + memset(&msg, 0, sizeof(msg)); + msg.cmd = NPE_VLAN_SETRXQOSENTRY; +@@ -1103,10 +1165,8 @@ static int eth_close(struct net_device * + printk(KERN_CRIT "%s: unable to disable loopback\n", + dev->name); + +- port->mii_bmcr = mdio_read(dev, port->plat->phy, MII_BMCR) & +- ~(BMCR_RESET | BMCR_PDOWN); /* may have been altered */ +- mdio_write(dev, port->plat->phy, MII_BMCR, +- port->mii_bmcr | BMCR_PDOWN); ++ for (i = 0; i < port->phy_count; i++) ++ phy_power_down(dev, i); + + if (!ports_open) + qmgr_disable_irq(TXDONE_QUEUE); +@@ -1117,6 +1177,42 @@ static int eth_close(struct net_device * + return 0; + } + ++static void eth_add_phy(struct net_device *dev, int phy_id) ++{ ++ struct port *port = netdev_priv(dev); ++ int i; ++ ++ i = port->phy_count++; ++ ++ port->mii[i].dev = dev; ++ port->mii[i].mdio_read = mdio_read; ++ port->mii[i].mdio_write = mdio_write; ++ port->mii[i].phy_id = phy_id; ++ port->mii[i].phy_id_mask = 0x1F; ++ port->mii[i].reg_num_mask = 0x1F; ++ ++ printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, phy_id, ++ npe_name(port->npe)); ++ ++ phy_reset(dev, i); ++ phy_power_down(dev, i); ++} ++ ++static void eth_init_mii(struct net_device *dev) ++{ ++ struct port *port = netdev_priv(dev); ++ ++ if (port->plat->phy < IXP4XX_ETH_PHY_MAX_ADDR) { ++ eth_add_phy(dev, port->plat->phy); ++ } else { ++ int i; ++ for (i = 0; i < IXP4XX_ETH_PHY_MAX_ADDR; i++) ++ if (port->plat->phy_mask & (1U << i)) ++ eth_add_phy(dev, i); ++ } ++ ++} ++ + static int __devinit eth_init_one(struct platform_device *pdev) + { + struct port *port; +@@ -1189,20 +1285,7 @@ static int __devinit eth_init_one(struct + __raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control); + udelay(50); + +- port->mii.dev = dev; +- port->mii.mdio_read = mdio_read; +- port->mii.mdio_write = mdio_write; +- port->mii.phy_id = plat->phy; +- port->mii.phy_id_mask = 0x1F; +- port->mii.reg_num_mask = 0x1F; +- +- printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, +- npe_name(port->npe)); +- +- phy_reset(dev, plat->phy); +- port->mii_bmcr = mdio_read(dev, plat->phy, MII_BMCR) & +- ~(BMCR_RESET | BMCR_PDOWN); +- mdio_write(dev, plat->phy, MII_BMCR, port->mii_bmcr | BMCR_PDOWN); ++ eth_init_mii(dev); + + INIT_DELAYED_WORK(&port->mdio_thread, mdio_thread); + return 0; +Index: linux-2.6.24.2/include/asm-arm/arch-ixp4xx/platform.h +=================================================================== +--- linux-2.6.24.2.orig/include/asm-arm/arch-ixp4xx/platform.h ++++ linux-2.6.24.2/include/asm-arm/arch-ixp4xx/platform.h +@@ -106,12 +106,15 @@ struct sys_timer; + #define IXP4XX_ETH_NPEB 0x10 + #define IXP4XX_ETH_NPEC 0x20 + ++#define IXP4XX_ETH_PHY_MAX_ADDR 32 ++ + /* Information about built-in Ethernet MAC interfaces */ + struct eth_plat_info { + u8 phy; /* MII PHY ID, 0 - 31 */ + u8 rxq; /* configurable, currently 0 - 31 only */ + u8 txreadyq; + u8 hwaddr[6]; ++ u32 phy_mask; + }; + + /* Information about built-in HSS (synchronous serial) interfaces */ diff --git a/target/linux/ixp4xx/patches-2.6.25/203-npe_driver_phy_reset_autoneg.patch b/target/linux/ixp4xx/patches-2.6.25/203-npe_driver_phy_reset_autoneg.patch new file mode 100644 index 000000000..6e1056e55 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.25/203-npe_driver_phy_reset_autoneg.patch @@ -0,0 +1,44 @@ +Index: linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c +=================================================================== +--- linux-2.6.24.2.orig/drivers/net/arm/ixp4xx_eth.c ++++ linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c +@@ -322,8 +322,12 @@ static void phy_reset(struct net_device + struct port *port = netdev_priv(dev); + int phy_id = port->mii[idx].phy_id; + int cycles = 0; ++ u16 bmcr; + +- mdio_write(dev, phy_id, MII_BMCR, port->mii_bmcr[idx] | BMCR_RESET); ++ /* reset the PHY */ ++ bmcr = mdio_read(dev, phy_id, MII_BMCR); ++ bmcr |= BMCR_ANENABLE; ++ mdio_write(dev, phy_id, MII_BMCR, bmcr | BMCR_RESET); + + while (cycles < MAX_MII_RESET_RETRIES) { + if (!(mdio_read(dev, phy_id, MII_BMCR) & BMCR_RESET)) { +@@ -331,13 +335,23 @@ static void phy_reset(struct net_device + printk(KERN_DEBUG "%s: phy_reset() took %i cycles\n", + dev->name, cycles); + #endif +- return; ++ break; + } + udelay(1); + cycles++; + } + +- printk(KERN_ERR "%s: MII reset failed on PHY%2d\n", dev->name, phy_id); ++ if (cycles == MAX_MII_RESET_RETRIES) { ++ printk(KERN_ERR "%s: MII reset failed on PHY%2d\n", dev->name, ++ phy_id); ++ return; ++ } ++ ++ /* restart auto negotiation */ ++ bmcr = mdio_read(dev, phy_id, MII_BMCR); ++ bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); ++ mdio_write(dev, phy_id, MII_BMCR, bmcr); ++ + } + + static void eth_set_duplex(struct port *port, int full_duplex) diff --git a/target/linux/ixp4xx/patches-2.6.25/204-npe_driver_ixp43x_support.patch b/target/linux/ixp4xx/patches-2.6.25/204-npe_driver_ixp43x_support.patch new file mode 100644 index 000000000..c0b55aa11 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.25/204-npe_driver_ixp43x_support.patch @@ -0,0 +1,86 @@ +diff -Nur linux-2.6.24.2/arch/arm/mach-ixp4xx/ixp4xx_npe.c linux-2.6.24.2-owrt/arch/arm/mach-ixp4xx/ixp4xx_npe.c +--- linux-2.6.24.2/arch/arm/mach-ixp4xx/ixp4xx_npe.c 2008-04-22 12:24:29.000000000 +0200 ++++ linux-2.6.24.2-owrt/arch/arm/mach-ixp4xx/ixp4xx_npe.c 2008-04-24 13:26:56.000000000 +0200 +@@ -571,8 +571,8 @@ + for (i = 0; i < image->size; i++) + image->data[i] = swab32(image->data[i]); + +- if (!cpu_is_ixp46x() && ((image->id >> 28) & 0xF /* device ID */)) { +- print_npe(KERN_INFO, npe, "IXP46x firmware ignored on " ++ if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) { ++ print_npe(KERN_INFO, npe, "IXP46x/IXP43x firmware ignored on " + "IXP42x\n"); + goto err; + } +@@ -594,7 +594,7 @@ + "revision 0x%X:%X\n", (image->id >> 16) & 0xFF, + (image->id >> 8) & 0xFF, image->id & 0xFF); + +- if (!cpu_is_ixp46x()) { ++ if (cpu_is_ixp42x()) { + if (!npe->id) + instr_size = NPE_A_42X_INSTR_SIZE; + else +diff -Nur linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c linux-2.6.24.2-owrt/drivers/net/arm/ixp4xx_eth.c +--- linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c 2008-04-22 12:24:29.000000000 +0200 ++++ linux-2.6.24.2-owrt/drivers/net/arm/ixp4xx_eth.c 2008-04-24 18:23:24.000000000 +0200 +@@ -32,6 +32,7 @@ + #include <linux/kernel.h> + #include <linux/mii.h> + #include <linux/platform_device.h> ++#include <asm/arch/cpu.h> + #include <asm/arch/npe.h> + #include <asm/arch/qmgr.h> + +@@ -1238,12 +1239,16 @@ + + static int __init eth_init_module(void) + { +- if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) +- return -ENOSYS; + +- /* All MII PHY accesses use NPE-B Ethernet registers */ + spin_lock_init(&mdio_lock); +- mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; ++ if (!cpu_is_ixp43x()) ++ /* All MII PHY accesses use NPE-B Ethernet registers */ ++ mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; ++ ++ else ++ /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ ++ mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; ++ + __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control); + + return platform_driver_register(&drv); +diff -Nur linux-2.6.24.2/include/asm-arm/arch-ixp4xx/cpu.h linux-2.6.24.2-owrt/include/asm-arm/arch-ixp4xx/cpu.h +--- linux-2.6.24.2/include/asm-arm/arch-ixp4xx/cpu.h 2008-04-22 12:24:29.000000000 +0200 ++++ linux-2.6.24.2-owrt/include/asm-arm/arch-ixp4xx/cpu.h 2008-04-24 18:15:29.000000000 +0200 +@@ -34,6 +34,8 @@ + val &= ~IXP4XX_FEATURE_RESERVED; + if (!cpu_is_ixp46x()) + val &= ~IXP4XX_FEATURE_IXP46X_ONLY; ++ if (cpu_is_ixp42x()) ++ val &= ~IXP4XX_FEATURE_IXP43X_46X; + + return val; + } +diff -Nur linux-2.6.24.2/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h linux-2.6.24.2-owrt/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h +--- linux-2.6.24.2/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h 2008-04-22 12:24:29.000000000 +0200 ++++ linux-2.6.24.2-owrt/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h 2008-04-24 18:15:13.000000000 +0200 +@@ -628,11 +628,12 @@ + #define IXP4XX_FEATURE_XSCALE_MAX_FREQ (3 << 22) + #define IXP4XX_FEATURE_RESERVED (0xFF << 24) + +-#define IXP4XX_FEATURE_IXP46X_ONLY (IXP4XX_FEATURE_ECC_TIMESYNC | \ ++#define IXP4XX_FEATURE_IXP43X_46X (IXP4XX_FEATURE_ECC_TIMESYNC | \ + IXP4XX_FEATURE_USB_HOST | \ + IXP4XX_FEATURE_NPEA_ETH | \ +- IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \ +- IXP4XX_FEATURE_RSA | \ + IXP4XX_FEATURE_XSCALE_MAX_FREQ) + ++#define IXP4XX_FEATURE_IXP46X_ONLY (IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \ ++ IXP4XX_FEATURE_RSA) ++ + #endif diff --git a/target/linux/ixp4xx/patches-2.6.25/202-npe_hss.patch b/target/linux/ixp4xx/patches-2.6.25/210-npe_hss.patch index 3950456bd..3950456bd 100644 --- a/target/linux/ixp4xx/patches-2.6.25/202-npe_hss.patch +++ b/target/linux/ixp4xx/patches-2.6.25/210-npe_hss.patch diff --git a/target/linux/ixp4xx/patches-2.6.25/296-avila_mac_plat_info.patch b/target/linux/ixp4xx/patches-2.6.25/296-avila_mac_plat_info.patch index 8c142df13..0c18956e3 100644 --- a/target/linux/ixp4xx/patches-2.6.25/296-avila_mac_plat_info.patch +++ b/target/linux/ixp4xx/patches-2.6.25/296-avila_mac_plat_info.patch @@ -2,54 +2,44 @@ Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c =================================================================== --- linux-2.6.24.2.orig/arch/arm/mach-ixp4xx/avila-setup.c +++ linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c -@@ -132,12 +132,42 @@ static struct platform_device avila_pata +@@ -132,6 +132,31 @@ static struct platform_device avila_pata .resource = avila_pata_resources, }; +/* Built-in 10/100 Ethernet MAC interfaces */ -+static struct eth_plat_info avila_plat_eth[] = { -+ { -+ .phy = 0, -+ .rxq = 3, -+ .txreadyq = 20, -+ }, { -+ .phy = 1, -+ .rxq = 4, -+ .txreadyq = 21, -+ } ++static struct eth_plat_info avila_npeb_data = { ++ .phy = 0, ++ .rxq = 3, ++ .txreadyq = 20, +}; + -+static struct platform_device avila_eth[] = { -+ { -+ .name = "ixp4xx_eth", -+ .id = IXP4XX_ETH_NPEB, -+ .dev.platform_data = avila_plat_eth, -+ }, { -+ .name = "ixp4xx_eth", -+ .id = IXP4XX_ETH_NPEC, -+ .dev.platform_data = avila_plat_eth + 1, -+ } ++static struct eth_plat_info avila_npec_data = { ++ .phy = 1, ++ .rxq = 4, ++ .txreadyq = 21, ++}; ++ ++static struct platform_device avila_npeb_device = { ++ .name = "ixp4xx_eth", ++ .id = IXP4XX_ETH_NPEB, ++ .dev.platform_data = &avila_npeb_data, ++}; ++ ++static struct platform_device avila_npec_device = { ++ .name = "ixp4xx_eth", ++ .id = IXP4XX_ETH_NPEC, ++ .dev.platform_data = &avila_npec_data, +}; + static struct platform_device *avila_devices[] __initdata = { &avila_i2c_gpio, &avila_flash, - &avila_uart - }; - -+static struct platform_device *avila_eth_devices[] = { -+ &avila_eth[0], -+ &avila_eth[1] -+}; -+ - static void __init avila_init(void) - { - ixp4xx_sys_init(); -@@ -159,6 +189,7 @@ static void __init avila_init(void) +@@ -159,6 +184,8 @@ static void __init avila_init(void) platform_device_register(&avila_pata); -+ platform_add_devices(avila_eth_devices, ARRAY_SIZE(avila_eth_devices)); ++ platform_device_register(avila_npeb_device); ++ platform_device_register(avila_npec_device); } MACHINE_START(AVILA, "Gateworks Avila Network Platform") diff --git a/target/linux/ixp4xx/patches-2.6.25/298-avila_rtc_fixup.patch b/target/linux/ixp4xx/patches-2.6.25/298-avila_rtc_fixup.patch deleted file mode 100644 index f706c100a..000000000 --- a/target/linux/ixp4xx/patches-2.6.25/298-avila_rtc_fixup.patch +++ /dev/null @@ -1,55 +0,0 @@ -diff -uprN linux-2.6.23.orig/arch/arm/mach-ixp4xx/avila-setup.c linux-2.6.23/arch/arm/mach-ixp4xx/avila-setup.c ---- linux-2.6.23.orig/arch/arm/mach-ixp4xx/avila-setup.c 2007-10-09 15:31:38.000000000 -0500 -+++ linux-2.6.23/arch/arm/mach-ixp4xx/avila-setup.c 2007-10-11 01:08:21.000000000 -0500 -@@ -138,6 +138,35 @@ static struct platform_device *avila_dev - &avila_uart - }; - -+static char avila_rtc_probe[] __initdata = "rtc-ds1672.probe=0,0x68 "; -+ -+static void __init avila_fixup(struct machine_desc *desc, -+ struct tag *tags, char **cmdline, struct meminfo *mi) -+{ -+ struct tag *t = tags; -+ char *p = *cmdline; -+ -+ /* Find the end of the tags table, taking note of any cmdline tag. */ -+ for (; t->hdr.size; t = tag_next(t)) { -+ if (t->hdr.tag == ATAG_CMDLINE) { -+ p = t->u.cmdline.cmdline; -+ } -+ } -+ -+ /* Overwrite the end of the table with a new cmdline tag. */ -+ t->hdr.tag = ATAG_CMDLINE; -+ t->hdr.size = (sizeof (struct tag_header) + -+ strlen(avila_rtc_probe) + strlen(p) + 1 + 4) >> 2; -+ strlcpy(t->u.cmdline.cmdline, avila_rtc_probe, COMMAND_LINE_SIZE); -+ strlcpy(t->u.cmdline.cmdline + strlen(avila_rtc_probe), p, -+ COMMAND_LINE_SIZE - strlen(avila_rtc_probe)); -+ -+ /* Terminate the table. */ -+ t = tag_next(t); -+ t->hdr.tag = ATAG_NONE; -+ t->hdr.size = 0; -+} -+ - static void __init avila_init(void) - { - ixp4xx_sys_init(); -@@ -165,6 +194,7 @@ MACHINE_START(AVILA, "Gateworks Avila Ne - /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */ - .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, - .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, -+ .fixup = avila_fixup, - .map_io = ixp4xx_map_io, - .init_irq = ixp4xx_init_irq, - .timer = &ixp4xx_timer, -@@ -182,6 +212,7 @@ MACHINE_START(LOFT, "Giant Shoulder Inc - /* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */ - .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, - .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, -+ .fixup = avila_fixup, - .map_io = ixp4xx_map_io, - .init_irq = ixp4xx_init_irq, - .timer = &ixp4xx_timer, diff --git a/target/linux/ixp4xx/patches-2.6.25/300-avila_fetch_mac.patch b/target/linux/ixp4xx/patches-2.6.25/300-avila_fetch_mac.patch index cedeb8469..e35ddbe33 100644 --- a/target/linux/ixp4xx/patches-2.6.25/300-avila_fetch_mac.patch +++ b/target/linux/ixp4xx/patches-2.6.25/300-avila_fetch_mac.patch @@ -21,55 +21,104 @@ Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c #include <linux/i2c-gpio.h> #include <asm/types.h> -@@ -177,6 +185,118 @@ static struct platform_device *avila_eth - &avila_eth[1] - }; +@@ -29,6 +37,13 @@ + #include <asm/mach/arch.h> + #include <asm/mach/flash.h> -+#ifdef CONFIG_SENSORS_EEPROM +struct avila_board_info { -+ unsigned char *model; -+ int npes_used; -+ int npeb_phy; -+ int npec_phy; ++ unsigned char *model; ++ void (* setup)(void); +}; + -+static struct avila_board_info avila_boards[] = { ++static struct avila_board_info *avila_info __initdata; ++ + static struct flash_platform_data avila_flash_data = { + .map_name = "cfi_probe", + .width = 2, +@@ -192,10 +207,160 @@ static void __init avila_fixup(struct ma + t->hdr.size = 0; + } + ++static void __init avila_gw23xx_setup(void) ++{ ++ platform_device_register(&avila_npeb_device); ++ platform_device_register(&avila_npec_device); ++} ++ ++#ifdef CONFIG_SENSORS_EEPROM ++static void __init avila_gw2342_setup(void) ++{ ++ platform_device_register(&avila_npeb_device); ++ platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2345_setup(void) ++{ ++ avila_npeb_data.phy = IXP4XX_ETH_PHY_MAX_ADDR; ++ avila_npeb_data.phy_mask = 0x1e; /* ports 1-4 of the KS8995 switch */ ++ platform_device_register(&avila_npeb_device); ++ ++ avila_npec_data.phy = 5; /* port 5 of the KS8995 switch */ ++ platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2347_setup(void) ++{ ++ platform_device_register(&avila_npeb_device); ++} ++ ++static void __init avila_gw2348_setup(void) ++{ ++ platform_device_register(&avila_npeb_device); ++ platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2353_setup(void) ++{ ++ platform_device_register(&avila_npeb_device); ++} ++ ++static void __init avila_gw2355_setup(void) ++{ ++ avila_npeb_data.phy = IXP4XX_ETH_PHY_MAX_ADDR; ++ avila_npeb_data.phy_mask = 0x1e; /* ports 1-4 of the KS8995 switch */ ++ platform_device_register(&avila_npeb_device); ++ ++ avila_npec_data.phy = 16; ++ platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2357_setup(void) ++{ ++ platform_device_register(&avila_npeb_device); ++} ++ ++static struct avila_board_info avila_boards[] __initdata = { + { + .model = "GW2342", -+ .npes_used = 2, -+ .npeb_phy = 0, -+ .npec_phy = 1, ++ .setup = avila_gw2342_setup, + }, { -+ .model = "GW2347", -+ .npes_used = 1, -+ .npeb_phy = 1, ++ .model = "GW2345", ++ .setup = avila_gw2345_setup, + }, { -+ .model = "GW2348-2", -+ .npes_used = 2, -+ .npeb_phy = 0, -+ .npec_phy = 1, ++ .model = "GW2347", ++ .setup = avila_gw2347_setup, + }, { -+ .model = "GW2348-4", -+ .npes_used = 2, -+ .npeb_phy = 0, -+ .npec_phy = 1, ++ .model = "GW2348", ++ .setup = avila_gw2348_setup, + }, { + .model = "GW2353", -+ .npes_used = 1, -+ .npeb_phy = 1, ++ .setup = avila_gw2353_setup, + }, { + .model = "GW2355", -+ .npes_used = 2, -+ .npeb_phy = -1, -+ .npec_phy = 1, ++ .setup = avila_gw2355_setup, + }, { + .model = "GW2357", -+ .npes_used = 1, -+ .npeb_phy = 1, ++ .setup = avila_gw2357_setup, + } +}; + -+static struct avila_board_info *avila_find_board_info(char *model) ++static struct avila_board_info * __init avila_find_board_info(char *model) +{ + int i; + @@ -91,64 +140,90 @@ Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c + unsigned char model[16]; +}; + -+static int avila_eeprom_notify(struct notifier_block *self, ++static int __init avila_eeprom_notify(struct notifier_block *self, + unsigned long event, void *t) +{ + struct eeprom_data *ee = t; -+ struct avila_board_info *info = NULL; + struct avila_eeprom_header hdr; + ++ if (avila_info) ++ return NOTIFY_DONE; ++ + /* The eeprom is at address 0x51 */ + if (event != EEPROM_REGISTER || ee->client.addr != 0x51) + return NOTIFY_DONE; + + ee->attr->read(&ee->client.dev.kobj, ee->attr, (char *)&hdr, -+ 0, sizeof(hdr)); ++ 0, sizeof(hdr)); + + if (hdr.magic[0] != 'G' || hdr.magic[1] != 'W') + return NOTIFY_DONE; + -+ memcpy(&avila_plat_eth[0].hwaddr, hdr.mac0, ETH_ALEN); -+ memcpy(&avila_plat_eth[1].hwaddr, hdr.mac1, ETH_ALEN); -+ -+ info = avila_find_board_info(hdr.model); -+ -+ if (info) { -+ printk(KERN_DEBUG "Running on Gateworks Avila %s\n", -+ info->model); -+ avila_plat_eth[0].phy = info->npeb_phy; -+ avila_plat_eth[1].phy = info->npec_phy; -+ platform_add_devices(avila_eth_devices, -+ info->npes_used); -+ } else { -+ printk(KERN_INFO "Unknown/missing Avila model number" -+ " -- defaults will be used\n"); -+ platform_add_devices(avila_eth_devices, -+ ARRAY_SIZE(avila_eth_devices)); -+ } ++ memcpy(&avila_npeb_data.hwaddr, hdr.mac0, ETH_ALEN); ++ memcpy(&avila_npec_data.hwaddr, hdr.mac1, ETH_ALEN); + -+ unregister_eeprom_notifier(self); ++ avila_info = avila_find_board_info(hdr.model); + + return NOTIFY_OK; +} + -+static struct notifier_block avila_eeprom_notifier = { ++static struct notifier_block avila_eeprom_notifier __initdata = { + .notifier_call = avila_eeprom_notify +}; -+#endif ++ ++static void __init avila_register_eeprom_notifier(void) ++{ ++ register_eeprom_notifier(&avila_eeprom_notifier); ++} ++ ++static void __init avila_unregister_eeprom_notifier(void) ++{ ++ unregister_eeprom_notifier(&avila_eeprom_notifier); ++} ++#else /* CONFIG_SENSORS_EEPROM */ ++static inline void avila_register_eeprom_notifier(void) {}; ++static inline void avila_unregister_eeprom_notifier(void) {}; ++#endif /* CONFIG_SENSORS_EEPROM */ + static void __init avila_init(void) { ixp4xx_sys_init(); -@@ -201,7 +321,11 @@ static void __init avila_init(void) + ++ /* ++ * These devices are present on all Avila models and don't need any ++ * model specific setup. ++ */ + avila_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + avila_flash_resource.end = + IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; +@@ -213,9 +378,28 @@ static void __init avila_init(void) platform_device_register(&avila_pata); -+#ifdef CONFIG_SENSORS_EEPROM -+ register_eeprom_notifier(&avila_eeprom_notifier); -+#else - platform_add_devices(avila_eth_devices, ARRAY_SIZE(avila_eth_devices)); -+#endif +- platform_device_register(avila_npeb_device); +- platform_device_register(avila_npec_device); ++ avila_register_eeprom_notifier(); ++} ++ ++static int __init avila_model_setup(void) ++{ ++ if (!machine_is_avila()) ++ return 0; ++ ++ if (avila_info) { ++ printk(KERN_DEBUG "Running on Gateworks Avila %s\n", ++ avila_info->model); ++ avila_info->setup(); ++ } else { ++ printk(KERN_INFO "Unknown/missing Avila model number" ++ " -- defaults will be used\n"); ++ avila_gw23xx_setup(); ++ } ++ ++ avila_unregister_eeprom_notifier(); ++ return 0; } ++late_initcall(avila_model_setup); MACHINE_START(AVILA, "Gateworks Avila Network Platform") + /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */ diff --git a/target/linux/ixp4xx/patches-2.6.25/301-avila_led.patch b/target/linux/ixp4xx/patches-2.6.25/301-avila_led.patch index 181d6baad..825773900 100644 --- a/target/linux/ixp4xx/patches-2.6.25/301-avila_led.patch +++ b/target/linux/ixp4xx/patches-2.6.25/301-avila_led.patch @@ -2,47 +2,115 @@ Index: linux-2.6.24.2/include/asm-arm/arch-ixp4xx/avila.h =================================================================== --- linux-2.6.24.2.orig/include/asm-arm/arch-ixp4xx/avila.h +++ linux-2.6.24.2/include/asm-arm/arch-ixp4xx/avila.h -@@ -36,4 +36,5 @@ +@@ -36,4 +36,6 @@ #define AVILA_PCI_INTC_PIN 9 #define AVILA_PCI_INTD_PIN 8 - -+/* User LED */ -+#define AVILA_LED_USER_GPIO 3 ++/* User LEDs */ ++#define AVILA_GW23XX_LED_USER_GPIO 3 ++#define AVILA_GW23X7_LED_USER_GPIO 4 Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c =================================================================== --- linux-2.6.24.2.orig/arch/arm/mach-ixp4xx/avila-setup.c +++ linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c -@@ -174,10 +174,31 @@ static struct platform_device avila_eth[ - } +@@ -26,6 +26,7 @@ + # include <linux/eeprom.h> + #endif + ++#include <linux/leds.h> + #include <linux/i2c-gpio.h> + + #include <asm/types.h> +@@ -172,6 +173,25 @@ static struct platform_device avila_npec + .dev.platform_data = &avila_npec_data, }; -+#ifdef CONFIG_LEDS_IXP4XX -+static struct resource avila_led_resources[] = { ++static struct gpio_led avila_leds[] = { + { -+ .name = "user", -+ .start = AVILA_LED_USER_GPIO, -+ .end = AVILA_LED_USER_GPIO, -+ .flags = IXP4XX_GPIO_LOW, -+ }, ++ .name = "user", /* green led */ ++ .gpio = AVILA_GW23XX_LED_USER_GPIO, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_led_platform_data avila_leds_data = { ++ .num_leds = 1, ++ .leds = avila_leds, +}; + -+static struct platform_device avila_leds = { -+ .name = "IXP4XX-GPIO-LED", ++static struct platform_device avila_leds_device = { ++ .name = "leds-gpio", + .id = -1, -+ .num_resources = ARRAY_SIZE(avila_led_resources), -+ .resource = avila_led_resources, ++ .dev.platform_data = &avila_leds_data, +}; -+#endif + static struct platform_device *avila_devices[] __initdata = { &avila_i2c_gpio, &avila_flash, -- &avila_uart -+ &avila_uart, -+#ifdef CONFIG_LEDS_IXP4XX -+ &avila_leds, -+#endif - }; +@@ -211,6 +231,8 @@ static void __init avila_gw23xx_setup(vo + { + platform_device_register(&avila_npeb_device); + platform_device_register(&avila_npec_device); ++ ++ platform_device_register(&avila_leds_device); + } + + #ifdef CONFIG_SENSORS_EEPROM +@@ -218,6 +240,8 @@ static void __init avila_gw2342_setup(vo + { + platform_device_register(&avila_npeb_device); + platform_device_register(&avila_npec_device); ++ ++ platform_device_register(&avila_leds_device); + } + + static void __init avila_gw2345_setup(void) +@@ -228,22 +252,30 @@ static void __init avila_gw2345_setup(vo + + avila_npec_data.phy = 5; /* port 5 of the KS8995 switch */ + platform_device_register(&avila_npec_device); ++ ++ platform_device_register(&avila_leds_device); + } + + static void __init avila_gw2347_setup(void) + { + platform_device_register(&avila_npeb_device); ++ ++ avila_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; ++ platform_device_register(&avila_leds_device); + } + + static void __init avila_gw2348_setup(void) + { + platform_device_register(&avila_npeb_device); + platform_device_register(&avila_npec_device); ++ ++ platform_device_register(&avila_leds_device); + } + + static void __init avila_gw2353_setup(void) + { + platform_device_register(&avila_npeb_device); ++ platform_device_register(&avila_leds_device); + } + + static void __init avila_gw2355_setup(void) +@@ -254,11 +286,16 @@ static void __init avila_gw2355_setup(vo + + avila_npec_data.phy = 5; + platform_device_register(&avila_npec_device); ++ ++ platform_device_register(&avila_leds_device); + } + + static void __init avila_gw2357_setup(void) + { + platform_device_register(&avila_npeb_device); ++ ++ avila_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; ++ platform_device_register(&avila_leds_device); + } - static struct platform_device *avila_eth_devices[] = { + static struct avila_board_info avila_boards[] __initdata = { diff --git a/target/linux/ixp4xx/patches-2.6.25/302-avila_gpio_device.patch b/target/linux/ixp4xx/patches-2.6.25/302-avila_gpio_device.patch index faa08beea..aee0eeeec 100644 --- a/target/linux/ixp4xx/patches-2.6.25/302-avila_gpio_device.patch +++ b/target/linux/ixp4xx/patches-2.6.25/302-avila_gpio_device.patch @@ -2,14 +2,14 @@ Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c =================================================================== --- linux-2.6.24.2.orig/arch/arm/mach-ixp4xx/avila-setup.c +++ linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c -@@ -192,6 +192,24 @@ static struct platform_device avila_leds +@@ -192,10 +192,28 @@ static struct platform_device avila_leds + .dev.platform_data = &avila_leds_data, }; - #endif -+#ifdef CONFIG_GPIO_DEVICE +static struct resource avila_gpio_resources[] = { + { + .name = "gpio", ++ /* FIXME: gpio mask should be model specific */ + .start = AVILA_GPIO_MASK, + .end = AVILA_GPIO_MASK, + .flags = 0, @@ -22,29 +22,24 @@ Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c + .num_resources = ARRAY_SIZE(avila_gpio_resources), + .resource = avila_gpio_resources, +}; -+#endif + static struct platform_device *avila_devices[] __initdata = { &avila_i2c_gpio, &avila_flash, -@@ -199,6 +217,9 @@ static struct platform_device *avila_dev - #ifdef CONFIG_LEDS_IXP4XX - &avila_leds, - #endif -+#ifdef CONFIG_GPIO_DEVICE +- &avila_uart ++ &avila_uart, + &avila_gpio, -+#endif }; - static struct platform_device *avila_eth_devices[] = { + static char avila_rtc_probe[] __initdata = "rtc-ds1672.probe=0,0x68 "; Index: linux-2.6.24.2/include/asm-arm/arch-ixp4xx/avila.h =================================================================== --- linux-2.6.24.2.orig/include/asm-arm/arch-ixp4xx/avila.h +++ linux-2.6.24.2/include/asm-arm/arch-ixp4xx/avila.h -@@ -38,3 +38,6 @@ - - /* User LED */ - #define AVILA_LED_USER_GPIO 3 +@@ -39,3 +39,6 @@ + /* User LEDs */ + #define AVILA_GW23XX_LED_USER_GPIO 3 + #define AVILA_GW23X7_LED_USER_GPIO 4 + +/* gpio mask used by platform device */ -+#define AVILA_GPIO_MASK (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) ++#define AVILA_GPIO_MASK (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) diff --git a/target/linux/ixp4xx/patches-2.6.25/303-avila_gw23x7_phy_quirk.patch b/target/linux/ixp4xx/patches-2.6.25/303-avila_gw23x7_phy_quirk.patch new file mode 100644 index 000000000..ffba2bb39 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.25/303-avila_gw23x7_phy_quirk.patch @@ -0,0 +1,52 @@ +Index: linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c +=================================================================== +--- linux-2.6.24.2.orig/arch/arm/mach-ixp4xx/avila-setup.c ++++ linux-2.6.24.2/arch/arm/mach-ixp4xx/avila-setup.c +@@ -276,6 +276,7 @@ static void __init avila_gw2345_setup(vo + + static void __init avila_gw2347_setup(void) + { ++ avila_npeb_data.quirks |= IXP4XX_ETH_QUIRK_GW23X7; + platform_device_register(&avila_npeb_device); + + avila_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; +@@ -310,6 +311,7 @@ static void __init avila_gw2355_setup(vo + + static void __init avila_gw2357_setup(void) + { ++ avila_npeb_data.quirks |= IXP4XX_ETH_QUIRK_GW23X7; + platform_device_register(&avila_npeb_device); + + avila_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; +Index: linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c +=================================================================== +--- linux-2.6.24.2.orig/drivers/net/arm/ixp4xx_eth.c ++++ linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c +@@ -347,6 +347,14 @@ static void phy_reset(struct net_device + return; + } + ++ if (port->plat->quirks & IXP4XX_ETH_QUIRK_GW23X7) { ++ mdio_write(dev, 1, 0x19, ++ (mdio_read(dev, 1, 0x19) & 0xfffe) | 0x8000); ++ ++ printk(KERN_DEBUG "%s: phy_id of the DP83848 changed to 0\n", ++ dev->name); ++ } ++ + /* restart auto negotiation */ + bmcr = mdio_read(dev, phy_id, MII_BMCR); + bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); +Index: linux-2.6.24.2/include/asm-arm/arch-ixp4xx/platform.h +=================================================================== +--- linux-2.6.24.2.orig/include/asm-arm/arch-ixp4xx/platform.h ++++ linux-2.6.24.2/include/asm-arm/arch-ixp4xx/platform.h +@@ -115,6 +115,8 @@ struct eth_plat_info { + u8 txreadyq; + u8 hwaddr[6]; + u32 phy_mask; ++ u32 quirks; ++#define IXP4XX_ETH_QUIRK_GW23X7 0x00000001 + }; + + /* Information about built-in HSS (synchronous serial) interfaces */ |