From: "Eugene San (eugenesan)" <eugene...@gmail.com>
Signed-off-by: Eugene San (eugenesan) <eugene...@gmail.com> --- target/linux/kirkwood/Makefile | 4 +- target/linux/kirkwood/README | 37 ++ .../base-files-rd88f6281/etc/config/network | 25 ++ target/linux/kirkwood/base-files/sbin/install2ubi | 14 + target/linux/kirkwood/config-default | 107 +++++-- target/linux/kirkwood/image/Makefile | 8 +- .../patches/001-openwrt_partition_map.patch | 11 + .../patches/300-mv88f6281_rev_z0_tclock.patch | 11 + ...ardware-bridging-support-for-DSA-switches.patch | 381 ++++++++++++++++++++ target/linux/kirkwood/profiles/100-Sheevaplug.mk | 6 +- target/linux/kirkwood/profiles/200-Dockstar.mk | 6 +- target/linux/kirkwood/profiles/300-Iconnect.mk | 6 +- target/linux/kirkwood/profiles/400-rd88f6281.mk | 17 + 13 files changed, 596 insertions(+), 37 deletions(-) create mode 100644 target/linux/kirkwood/README create mode 100644 target/linux/kirkwood/base-files-rd88f6281/etc/config/network create mode 100755 target/linux/kirkwood/base-files/sbin/install2ubi create mode 100644 target/linux/kirkwood/patches/300-mv88f6281_rev_z0_tclock.patch create mode 100644 target/linux/kirkwood/patches/400-hardware-bridging-support-for-DSA-switches.patch create mode 100644 target/linux/kirkwood/profiles/400-rd88f6281.mk diff --git a/target/linux/kirkwood/Makefile b/target/linux/kirkwood/Makefile index 06b6fc7..09e66c4 100644 --- a/target/linux/kirkwood/Makefile +++ b/target/linux/kirkwood/Makefile @@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk ARCH:=arm BOARD:=kirkwood BOARDNAME:=Marvell Kirkwood -FEATURES:=targz usb jffs2 +FEATURES:=targz usb jffs2 squashfs MAINTAINER:=Imre Kaloz <ka...@openwrt.org> -LINUX_VERSION:=2.6.37.6 +LINUX_VERSION:=3.0.3 include $(INCLUDE_DIR)/target.mk diff --git a/target/linux/kirkwood/README b/target/linux/kirkwood/README new file mode 100644 index 0000000..ef6d8e1 --- /dev/null +++ b/target/linux/kirkwood/README @@ -0,0 +1,37 @@ +This Kirkwood target is intended to be used with devices based on Marvell Kirkwood 6281/2 ARM-compatible CPU (aka Feroceon). + +Among supported devices are: + * Globalscale Sheevaplug + * Seagate Dockstar + * Iomega iConnect Wireless + * Marvell RD88F6281 Reference Boards + +Marvell RD88F6281 Reference Boards currently utilize UBIFS on NAND scheme for rootfs +and uImage is stored in raw NAND area. +Currently only manual install/upgrade procedure tested. +To perform manual/initial installation you will need a TFTP server and board specific images, +for example: openwrt-kirkwood-uImage and openwrt-kirkwood-rd88f6281-squashfs.uimg. + +Follow below steps to install firmware in to device's NAND flash. +(Remember to use apropriate network parameters) + +1. Prepare uBoot environment (In uBoot): + >>resetenv; reset + >>setenv mainlineLinux yes; save; reset + >>setenv ipaddr 192.168.2.200; setenv serverip 192.168.1.2 + >>setenv loadaddr 0x2000000; setenv console 'console=ttyS0,115200 panic=30' + >>setenv bootargs_root 'ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs rw' + >>setenv image_name openwrt-kirkwood-uImage + >>setenv root_name openwrt-kirkwood-rd88f6281-squashfs.uimg + >>setenv update_image 'tftpboot $(loadaddr) $(image_name); nand erase 0x100000 0x200000; nand write $(loadaddr) 0x100000 0x200000' + >>setenv load_firmware 'tftpboot $(loadaddr) $(root_name); setenv bootargs $(console) root=/dev/ram0 rw; bootm $(loadaddr)' + >>setenv bootcmd 'setenv bootargs $(console) $(bootargs_root); nand read $(loadaddr) 0x100000 0x200000; bootm $(loadaddr)' + >>save + +2. Load initial firmare (In uBoot): + >>run update_image + >>run load_firmware + +3. Install firmware into NAND (In Linux): + $ install2ubifs + $ reboot diff --git a/target/linux/kirkwood/base-files-rd88f6281/etc/config/network b/target/linux/kirkwood/base-files-rd88f6281/etc/config/network new file mode 100644 index 0000000..24d7a39 --- /dev/null +++ b/target/linux/kirkwood/base-files-rd88f6281/etc/config/network @@ -0,0 +1,25 @@ +# Copyright (C) 2011 OpenWrt.org + +config 'interface' 'loopback' + option 'ifname' 'lo' + option 'proto' 'static' + option 'ipaddr' '127.0.0.1' + option 'netmask' '255.0.0.0' + +config 'interface' 'eth0' + option 'ifname' 'eth0' + option 'proto' 'none' + +config 'interface' 'wan' + option 'hostname' 'OpenWrt' + option 'proto' 'dhcp' + option 'type' 'bridge' + option 'ifname' 'wan eth1 eth2' + +config 'interface' 'lan' + option 'type' 'bridge' + option 'proto' 'static' + option 'netmask' '255.255.255.0' + option 'nat' '1' + option 'ipaddr' '192.168.2.1' + option 'ifname' 'lan1 lan2 lan3 lan4' diff --git a/target/linux/kirkwood/base-files/sbin/install2ubi b/target/linux/kirkwood/base-files/sbin/install2ubi new file mode 100755 index 0000000..ec9dd07 --- /dev/null +++ b/target/linux/kirkwood/base-files/sbin/install2ubi @@ -0,0 +1,14 @@ +#!/bin/sh + +# Copyright (C) 2011 Marvell Smiconductors + +read -p "Do you want to install currently running firmware to NAND flash using UBI, [y/n]?" input + +if [ "${input}" == "y" ]; then + echo "Performing install into NAND flash using UBI..." + ubiformat /dev/mtd2 -s 512 && ubiattach /dev/ubi_ctrl -m 2 && ubimkvol /dev/ubi0 -N rootfs -m && mount -t ubifs ubi0:rootfs /mnt + cd /; ls -1 | grep -vE "proc|sys|tmp|mnt" | awk '{print "cp -a "$1" /mnt/"}' | sh; mkdir -p /mnt/proc /mnt/sys /mnt/tmp /mnt/mnt; cd - + echo "Performed install into NAND flash using UBI, you may reboot into new system." +else + echo "Skipping install into NAND flash." +fi diff --git a/target/linux/kirkwood/config-default b/target/linux/kirkwood/config-default index d37d8ab..f1b7b01 100644 --- a/target/linux/kirkwood/config-default +++ b/target/linux/kirkwood/config-default @@ -1,21 +1,26 @@ CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_ARCH_KIRKWOOD=y -# CONFIG_ARCH_NUC93X is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_ARCH_USES_GETTIMEOFFSET is not set CONFIG_ARM=y CONFIG_ARM_L1_CACHE_SHIFT=5 # CONFIG_ARM_THUMB is not set # CONFIG_ARPD is not set -CONFIG_BITREVERSE=y +CONFIG_ATA=y +CONFIG_BCMA_POSSIBLE=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 CONFIG_BLK_DEV_SD=y CONFIG_CACHE_FEROCEON_L2=y # CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set -CONFIG_CMDLINE="rootdelay=1 root=/dev/mmcblk0p1 noinitrd console=ttyS0,115200" +CONFIG_CLKSRC_MMIO=y +CONFIG_CMDLINE="rootdelay=1 console=ttyS0,115200" +CONFIG_CMDLINE_FROM_BOOTLOADER=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y CONFIG_CPU_CACHE_VIVT=y @@ -29,24 +34,35 @@ CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_PABRT_LEGACY=y CONFIG_CPU_TLB_FEROCEON=y -CONFIG_DEBUG_KERNEL=y +CONFIG_CPU_USE_DOMAINS=y +CONFIG_CRC16=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DEV_MV_CESA=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_USER is not set CONFIG_DECOMPRESS_LZMA=y -CONFIG_DEVPORT=y -# CONFIG_DLCI is not set -# CONFIG_DM9000 is not set CONFIG_DNOTIFY=y +CONFIG_EFI_PARTITION=y CONFIG_EXT4_FS=y -# CONFIG_FPE_FASTFPE is not set -# CONFIG_FPE_NWFPE is not set +# CONFIG_EXT4_FS_XATTR is not set CONFIG_FRAME_POINTER=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_GENERIC_GPIO=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y # CONFIG_HAMRADIO is not set CONFIG_HARDIRQS_SW_RESEND=y CONFIG_HAS_DMA=y @@ -54,29 +70,45 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAVE_AOUT=y CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_HARDIRQS=y CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_WORK=y CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_KERNEL_XZ=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMBLOCK=y CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SCHED_CLOCK=y +CONFIG_HAVE_SPARSE_IRQ=y CONFIG_HW_RANDOM=y -# CONFIG_I2C_MV64XXX is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MV64XXX=y +# CONFIG_I2C_PXA_PCI is not set CONFIG_INET_LRO=y CONFIG_INITRAMFS_SOURCE="" -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_JBD=y +# CONFIG_ISDN is not set +CONFIG_JBD2=y +CONFIG_KTIME_SCALAR=y CONFIG_LEDS_GPIO=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y # CONFIG_MACH_D2NET_V2 is not set # CONFIG_MACH_DB88F6281_BP is not set CONFIG_MACH_DOCKSTAR=y @@ -89,15 +121,19 @@ CONFIG_MACH_ICONNECT=y # CONFIG_MACH_NET5BIG_V2 is not set # CONFIG_MACH_NETSPACE_MAX_V2 is not set # CONFIG_MACH_NETSPACE_V2 is not set +CONFIG_MACH_OPENRD=y CONFIG_MACH_OPENRD_BASE=y CONFIG_MACH_OPENRD_CLIENT=y # CONFIG_MACH_OPENRD_ULTIMATE is not set # CONFIG_MACH_RD88F6192_NAS is not set -# CONFIG_MACH_RD88F6281 is not set +CONFIG_MACH_RD88F6281=y CONFIG_MACH_SHEEVAPLUG=y # CONFIG_MACH_T5325 is not set # CONFIG_MACH_TS219 is not set # CONFIG_MACH_TS41X is not set +CONFIG_MARVELL_PHY=y +# CONFIG_MFD_SUPPORT is not set +# CONFIG_MISC_DEVICES is not set CONFIG_MMC=y CONFIG_MMC_BLOCK=y CONFIG_MMC_MVSDIO=y @@ -110,17 +146,24 @@ CONFIG_MTD_NAND_ORION=y # CONFIG_MTD_ROOTFS_ROOT_DEV is not set # CONFIG_MTD_ROOTFS_SPLIT is not set # CONFIG_MTD_SM_COMMON is not set +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MV643XX_ETH=y CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y CONFIG_NET_DSA=y # CONFIG_NET_DSA_MV88E6060 is not set -# CONFIG_NET_DSA_MV88E6123_61_65 is not set +CONFIG_NET_DSA_MV88E6123_61_65=y CONFIG_NET_DSA_MV88E6131=y CONFIG_NET_DSA_MV88E6XXX=y CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y CONFIG_NET_DSA_TAG_DSA=y -# CONFIG_NET_DSA_TAG_EDSA is not set +CONFIG_NET_DSA_TAG_EDSA=y # CONFIG_NET_DSA_TAG_TRAILER is not set +# CONFIG_NET_ETHERNET is not set CONFIG_NLS=y CONFIG_OUTER_CACHE=y CONFIG_PAGEFLAGS_EXTENDED=y @@ -129,25 +172,39 @@ CONFIG_PCI=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PHYLIB=y CONFIG_PLAT_ORION=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_QUOTACTL is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MV=y +CONFIG_SATA_MV=y +CONFIG_SATA_PMP=y CONFIG_SCSI=y -CONFIG_SCSI_MOD=y # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SDIO_UART is not set -# CONFIG_SERIAL_8250_EXTENDED is not set CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_STAGING is not set CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +# CONFIG_UBIFS_FS_XATTR is not set +CONFIG_UBIFS_FS_ZLIB=y CONFIG_UID16=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_TT_NEWSCHED=y CONFIG_USB_STORAGE=y CONFIG_USB_SUPPORT=y # CONFIG_USB_UHCI_HCD is not set CONFIG_VECTORS_BASE=0xffff0000 # CONFIG_VFP is not set CONFIG_VM_EVENT_COUNTERS=y -CONFIG_WAN=y +# CONFIG_WATCHDOG is not set +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/kirkwood/image/Makefile b/target/linux/kirkwood/image/Makefile index c93be67..ebd52d9 100644 --- a/target/linux/kirkwood/image/Makefile +++ b/target/linux/kirkwood/image/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009-2010 OpenWrt.org +# Copyright (C) 2009-2011 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -8,9 +8,11 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/image.mk JFFS2OPTS += --little-endian --pagesize=0x800 --no-cleanmarkers --pad +JFFS2_BLOCKSIZE = 128k define Image/Prepare cp $(LINUX_DIR)/arch/arm/boot/uImage $(KDIR)/uImage + cp $(LINUX_DIR)/arch/arm/boot/zImage $(KDIR)/zImage endef define Image/BuildKernel @@ -31,6 +33,10 @@ define Image/Build/jffs2-128k endef define Image/Build/squashfs + $(STAGING_DIR_HOST)/bin/mkimage -A arm -O linux -T multi \ + -C none -a 0x00008000 -e 0x00008000 -n 'Linux-$(LINUX_VERSION)-initrd' \ + -d $(KDIR)/zImage:$(KDIR)/root.squashfs $(BIN_DIR)/$(IMG_PREFIX)-$(PROFILE)-$(1).uimg + $(call prepare_generic_squashfs,$(KDIR)/root.squashfs) ( \ dd if=$(KDIR)/uImage bs=4096k conv=sync; \ diff --git a/target/linux/kirkwood/patches/001-openwrt_partition_map.patch b/target/linux/kirkwood/patches/001-openwrt_partition_map.patch index 0f94adc..3893b77 100644 --- a/target/linux/kirkwood/patches/001-openwrt_partition_map.patch +++ b/target/linux/kirkwood/patches/001-openwrt_partition_map.patch @@ -1,3 +1,14 @@ +--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c ++++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c +@@ -34,7 +34,7 @@ static struct mtd_partition rd88f6281_na + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_2M + }, { +- .name = "root", ++ .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, --- a/arch/arm/mach-kirkwood/sheevaplug-setup.c +++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c @@ -33,7 +33,7 @@ static struct mtd_partition sheevaplug_n diff --git a/target/linux/kirkwood/patches/300-mv88f6281_rev_z0_tclock.patch b/target/linux/kirkwood/patches/300-mv88f6281_rev_z0_tclock.patch new file mode 100644 index 0000000..283c006 --- /dev/null +++ b/target/linux/kirkwood/patches/300-mv88f6281_rev_z0_tclock.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/mach-kirkwood/common.c ++++ b/arch/arm/mach-kirkwood/common.c +@@ -854,7 +854,7 @@ int __init kirkwood_find_tclk(void) + + kirkwood_pcie_id(&dev, &rev); + +- if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID) ++ if ((dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) || dev == MV88F6282_DEV_ID) + if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0) + return 200000000; + diff --git a/target/linux/kirkwood/patches/400-hardware-bridging-support-for-DSA-switches.patch b/target/linux/kirkwood/patches/400-hardware-bridging-support-for-DSA-switches.patch new file mode 100644 index 0000000..8d81d49 --- /dev/null +++ b/target/linux/kirkwood/patches/400-hardware-bridging-support-for-DSA-switches.patch @@ -0,0 +1,381 @@ +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -919,6 +919,12 @@ struct net_device_ops { + struct rtnl_link_stats64 *storage); + struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); + ++ void (*ndo_bridge_join)(struct net_device *dev, ++ void *bridge); ++ void (*ndo_bridge_set_stp_state)(struct net_device *dev, ++ int state); ++ void (*ndo_bridge_leave)(struct net_device *dev); ++ + void (*ndo_vlan_rx_register)(struct net_device *dev, + struct vlan_group *grp); + void (*ndo_vlan_rx_add_vid)(struct net_device *dev, +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -138,6 +138,9 @@ static void del_nbp(struct net_bridge_port *p) + br_stp_disable_port(p); + spin_unlock_bh(&br->lock); + ++ if (dev->netdev_ops->ndo_bridge_leave != NULL) ++ dev->netdev_ops->ndo_bridge_leave(dev); ++ + br_ifinfo_notify(RTM_DELLINK, p); + + br_fdb_delete_by_port(br, p, 1); +@@ -380,6 +383,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) + spin_lock_bh(&br->lock); + changed_addr = br_stp_recalculate_bridge_id(br); + ++ if (dev->netdev_ops->ndo_bridge_join != NULL) ++ dev->netdev_ops->ndo_bridge_join(dev, (void *)br); ++ + if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && + (br->dev->flags & IFF_UP)) + br_stp_enable_port(p); +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -34,6 +34,9 @@ void br_log_state(const struct net_bridge_port *p) + br_info(p->br, "port %u(%s) entering %s state\n", + (unsigned) p->port_no, p->dev->name, + br_port_state_names[p->state]); ++ ++ if (p->dev->netdev_ops->ndo_bridge_set_stp_state != NULL) ++ p->dev->netdev_ops->ndo_bridge_set_stp_state(p->dev, p->state); + } + + /* called under bridge lock */ +--- a/net/bridge/br_stp_if.c ++++ b/net/bridge/br_stp_if.c +@@ -96,11 +96,12 @@ void br_stp_disable_port(struct net_bridge_port *p) + struct net_bridge *br = p->br; + int wasroot; + +- br_log_state(p); +- + wasroot = br_is_root_bridge(br); + br_become_designated_port(p); + p->state = BR_STATE_DISABLED; ++ ++ br_log_state(p); ++ + p->topology_change_ack = 0; + p->config_pending = 0; + +--- a/net/dsa/dsa_priv.h ++++ b/net/dsa/dsa_priv.h +@@ -155,6 +155,15 @@ struct dsa_switch_driver { + void (*get_ethtool_stats)(struct dsa_switch *ds, + int port, uint64_t *data); + int (*get_sset_count)(struct dsa_switch *ds); ++ ++ /* ++ * Hardware bridging. ++ */ ++ void (*bridge_join)(struct dsa_switch *ds, int port, ++ void *bridge); ++ void (*bridge_set_stp_state)(struct dsa_switch *ds, int port, ++ int state); ++ void (*bridge_leave)(struct dsa_switch *ds, int port); + }; + + /* dsa.c */ +--- a/net/dsa/mv88e6123_61_65.c ++++ b/net/dsa/mv88e6123_61_65.c +@@ -8,6 +8,7 @@ + * (at your option) any later version. + */ + ++#include <linux/if_bridge.h> + #include <linux/list.h> + #include <linux/netdevice.h> + #include <linux/phy.h> +@@ -232,10 +233,9 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p) + REG_WRITE(addr, 0x04, val); + + /* +- * Port Control 1: disable trunking. Also, if this is the +- * CPU port, enable learn messages to be sent to this port. ++ * Port Control 1: disable trunking. + */ +- REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000); ++ REG_WRITE(addr, 0x05, 0x0000); + + /* + * Port based VLAN map: give each port its own address +@@ -316,6 +316,8 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p) + return 0; + } + ++static void mv88e6123_61_65_hw_bridge_sync_work(struct work_struct *ugly); ++ + static int mv88e6123_61_65_setup(struct dsa_switch *ds) + { + struct mv88e6xxx_priv_state *ps = (void *)(ds + 1); +@@ -324,6 +326,8 @@ static int mv88e6123_61_65_setup(struct dsa_switch *ds) + + mutex_init(&ps->smi_mutex); + mutex_init(&ps->stats_mutex); ++ spin_lock_init(&ps->hw_bridge_state); ++ INIT_WORK(&ps->hw_bridge_work, mv88e6123_61_65_hw_bridge_sync_work); + + ret = mv88e6123_61_65_switch_reset(ds); + if (ret < 0) +@@ -339,6 +343,10 @@ static int mv88e6123_61_65_setup(struct dsa_switch *ds) + ret = mv88e6123_61_65_setup_port(ds, i); + if (ret < 0) + return ret; ++ ++ // @@@ ++ ps->fid[i] = i; ++ ps->stp_state[i] = 3; + } + + return 0; +@@ -419,6 +427,159 @@ static int mv88e6123_61_65_get_sset_count(struct dsa_switch *ds) + return ARRAY_SIZE(mv88e6123_61_65_hw_stats); + } + ++static void mv88e6123_61_65_hw_bridge_sync_work(struct work_struct *ugly) ++{ ++ struct mv88e6xxx_priv_state *ps; ++ struct dsa_switch *ds; ++ int i; ++ ++ ps = container_of(ugly, struct mv88e6xxx_priv_state, hw_bridge_work); ++ ds = ((struct dsa_switch *)ps) - 1; ++ ++ spin_lock(&ps->hw_bridge_state); ++ for (i = 0; i < MV88E6XXX_MAX_PORTS; i++) { ++ if (ps->fid_dirty[i]) { ++ int reg; ++ int j; ++ ++ reg = (ps->fid[i] << 12) | (1 << ds->dst->cpu_port); ++ ps->fid_dirty[i] = 0; ++ ++ for (j = 0; j < MV88E6XXX_MAX_PORTS; j++) { ++ if (i != j && ps->bridge[i] != NULL && ++ ps->bridge[i] == ps->bridge[j]) { ++ reg |= 1 << j; ++ } ++ } ++ ++ spin_unlock(&ps->hw_bridge_state); ++ mv88e6xxx_reg_write(ds, REG_PORT(i), 6, reg); ++ spin_lock(&ps->hw_bridge_state); ++ } ++ ++ if (ps->stp_state_dirty[i]) { ++ int new_state; ++ int reg; ++ ++ new_state = ps->stp_state[i]; ++ ps->stp_state_dirty[i] = 0; ++ spin_unlock(&ps->hw_bridge_state); ++ reg = mv88e6xxx_reg_read(ds, REG_PORT(i), 4); ++ if (reg >= 0) { ++ reg &= ~0x0003; ++ reg |= new_state; ++ mv88e6xxx_reg_write(ds, REG_PORT(i), 4, reg); ++ } ++ spin_lock(&ps->hw_bridge_state); ++ } ++ } ++ spin_unlock(&ps->hw_bridge_state); ++} ++ ++static void ++set_stp_state(struct dsa_switch *ds, int port, int state) ++{ ++ struct mv88e6xxx_priv_state *ps = (void *)(ds + 1); ++ int hw_state = 0; ++ ++ switch (state) { ++ case BR_STATE_DISABLED: ++ hw_state = 0; ++ break; ++ case BR_STATE_BLOCKING: ++ case BR_STATE_LISTENING: ++ hw_state = 1; ++ break; ++ case BR_STATE_LEARNING: ++ hw_state = 2; ++ break; ++ case BR_STATE_FORWARDING: ++ hw_state = 3; ++ break; ++ default: ++ BUG(); ++ } ++ ++ if (ps->stp_state[port] != hw_state) { ++ ps->stp_state_dirty[port] = 1; ++ ps->stp_state[port] = hw_state; ++ } ++} ++ ++static void ++mv88e6123_61_65_bridge_join(struct dsa_switch *ds, int port, void *bridge) ++{ ++ struct mv88e6xxx_priv_state *ps = (void *)(ds + 1); ++ int fid; ++ int i; ++ ++ spin_lock(&ps->hw_bridge_state); ++ ++ fid = 65536; ++ for (i = 0; i < MV88E6XXX_MAX_PORTS; i++) { ++ if (ps->bridge[i] == bridge) { ++ if (ps->fid[i] < fid) ++ fid = ps->fid[i]; ++ ps->fid_dirty[i] = 1; ++ } ++ } ++ ++ ps->bridge[port] = bridge; ++ ++ ps->fid_dirty[port] = 1; ++ if (fid != 65536) ++ ps->fid[port] = fid; ++ ++ set_stp_state(ds, port, BR_STATE_DISABLED); ++ ++ spin_unlock(&ps->hw_bridge_state); ++ ++ schedule_work(&ps->hw_bridge_work); ++} ++ ++static void ++mv88e6123_61_65_bridge_set_stp_state(struct dsa_switch *ds, int port, int state) ++{ ++ struct mv88e6xxx_priv_state *ps = (void *)(ds + 1); ++ ++ spin_lock(&ps->hw_bridge_state); ++ set_stp_state(ds, port, state); ++ spin_unlock(&ps->hw_bridge_state); ++ ++ schedule_work(&ps->hw_bridge_work); ++} ++ ++static void mv88e6123_61_65_bridge_leave(struct dsa_switch *ds, int port) ++{ ++ struct mv88e6xxx_priv_state *ps = (void *)(ds + 1); ++ u16 free_fids; ++ int i; ++ int fid; ++ ++ spin_lock(&ps->hw_bridge_state); ++ ++ free_fids = 0xffff; ++ for (i = 0; i < MV88E6XXX_MAX_PORTS; i++) { ++ if (dsa_is_cpu_port(ds, i) || ds->dsa_port_mask & (1 << i)) { ++ if (ps->bridge[i] == ps->bridge[port]) ++ ps->fid_dirty[i] = 1; ++ if (i != port) ++ free_fids &= ~(1 << ps->fid[i]); ++ } ++ } ++ ++ fid = ffs(free_fids) - 1; ++ ++ ps->fid[port] = fid; ++ ps->bridge[port] = NULL; ++ ++ set_stp_state(ds, port, BR_STATE_FORWARDING); ++ ++ spin_unlock(&ps->hw_bridge_state); ++ ++ schedule_work(&ps->hw_bridge_work); ++} ++ + static struct dsa_switch_driver mv88e6123_61_65_switch_driver = { + .tag_protocol = cpu_to_be16(ETH_P_EDSA), + .priv_size = sizeof(struct mv88e6xxx_priv_state), +@@ -431,6 +592,9 @@ static struct dsa_switch_driver mv88e6123_61_65_switch_driver = { + .get_strings = mv88e6123_61_65_get_strings, + .get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats, + .get_sset_count = mv88e6123_61_65_get_sset_count, ++ .bridge_join = mv88e6123_61_65_bridge_join, ++ .bridge_set_stp_state = mv88e6123_61_65_bridge_set_stp_state, ++ .bridge_leave = mv88e6123_61_65_bridge_leave, + }; + + static int __init mv88e6123_61_65_init(void) +--- a/net/dsa/mv88e6xxx.h ++++ b/net/dsa/mv88e6xxx.h +@@ -15,6 +15,8 @@ + #define REG_GLOBAL 0x1b + #define REG_GLOBAL2 0x1c + ++#define MV88E6XXX_MAX_PORTS 11 ++ + struct mv88e6xxx_priv_state { + /* + * When using multi-chip addressing, this mutex protects +@@ -40,6 +42,17 @@ struct mv88e6xxx_priv_state { + */ + struct mutex stats_mutex; + ++ /* ++ * Hardware bridging state. ++ */ ++ spinlock_t hw_bridge_state; ++ struct work_struct hw_bridge_work; ++ void *bridge[MV88E6XXX_MAX_PORTS]; ++ int fid_dirty[MV88E6XXX_MAX_PORTS]; ++ int fid[MV88E6XXX_MAX_PORTS]; ++ int stp_state_dirty[MV88E6XXX_MAX_PORTS]; ++ int stp_state[MV88E6XXX_MAX_PORTS]; ++ + int id; /* switch product id */ + }; + +--- a/net/dsa/slave.c ++++ b/net/dsa/slave.c +@@ -171,6 +171,33 @@ static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + return -EOPNOTSUPP; + } + ++static void dsa_bridge_join(struct net_device *dev, void *bridge) ++{ ++ struct dsa_slave_priv *p = netdev_priv(dev); ++ struct dsa_switch *ds = p->parent; ++ ++ if (ds->drv->bridge_join != NULL) ++ ds->drv->bridge_join(ds, p->port, bridge); ++} ++ ++static void dsa_bridge_set_stp_state(struct net_device *dev, int state) ++{ ++ struct dsa_slave_priv *p = netdev_priv(dev); ++ struct dsa_switch *ds = p->parent; ++ ++ if (ds->drv->bridge_set_stp_state != NULL) ++ ds->drv->bridge_set_stp_state(ds, p->port, state); ++} ++ ++static void dsa_bridge_leave(struct net_device *dev) ++{ ++ struct dsa_slave_priv *p = netdev_priv(dev); ++ struct dsa_switch *ds = p->parent; ++ ++ if (ds->drv->bridge_leave != NULL) ++ ds->drv->bridge_leave(ds, p->port); ++} ++ + + /* ethtool operations *******************************************************/ + static int +@@ -304,6 +331,9 @@ static const struct net_device_ops dsa_netdev_ops = { + .ndo_set_multicast_list = dsa_slave_set_rx_mode, + .ndo_set_mac_address = dsa_slave_set_mac_address, + .ndo_do_ioctl = dsa_slave_ioctl, ++ .ndo_bridge_join = dsa_bridge_join, ++ .ndo_bridge_set_stp_state = dsa_bridge_set_stp_state, ++ .ndo_bridge_leave = dsa_bridge_leave, + }; + #endif + #ifdef CONFIG_NET_DSA_TAG_EDSA diff --git a/target/linux/kirkwood/profiles/100-Sheevaplug.mk b/target/linux/kirkwood/profiles/100-Sheevaplug.mk index 65008fe..d4b92eb 100644 --- a/target/linux/kirkwood/profiles/100-Sheevaplug.mk +++ b/target/linux/kirkwood/profiles/100-Sheevaplug.mk @@ -6,12 +6,12 @@ # define Profile/Sheevaplug - NAME:=Globalscale Sheevaplug - PACKAGES:= + NAME:=Globalscale Sheevaplug + PACKAGES:= endef define Profile/Sheevaplug/Description - Globalscale Sheevaplug Profile + Globalscale Sheevaplug Profile endef $(eval $(call Profile,Sheevaplug)) diff --git a/target/linux/kirkwood/profiles/200-Dockstar.mk b/target/linux/kirkwood/profiles/200-Dockstar.mk index 5b5d9cb..6025166 100644 --- a/target/linux/kirkwood/profiles/200-Dockstar.mk +++ b/target/linux/kirkwood/profiles/200-Dockstar.mk @@ -6,12 +6,12 @@ # define Profile/Dockstar - NAME:=Seagate Dockstar - PACKAGES:= + NAME:=Seagate Dockstar + PACKAGES:= endef define Profile/Dockstar/Description - Seagate Dockstar Profile + Seagate Dockstar Profile endef $(eval $(call Profile,Dockstar)) diff --git a/target/linux/kirkwood/profiles/300-Iconnect.mk b/target/linux/kirkwood/profiles/300-Iconnect.mk index 230e419..b220767 100644 --- a/target/linux/kirkwood/profiles/300-Iconnect.mk +++ b/target/linux/kirkwood/profiles/300-Iconnect.mk @@ -6,12 +6,12 @@ # define Profile/Iconnect - NAME:=Iomega iConnect Wireless - PACKAGES:=kmod-i2c-mv64xxx kmod-hwmon-core kmod-hwmon-lm63 + NAME:=Iomega iConnect Wireless + PACKAGES:=kmod-hwmon-core kmod-hwmon-lm63 endef define Profile/Iconnect/Description - Iomega iConnect Wireless + Iomega iConnect Wireless endef $(eval $(call Profile,Iconnect)) diff --git a/target/linux/kirkwood/profiles/400-rd88f6281.mk b/target/linux/kirkwood/profiles/400-rd88f6281.mk new file mode 100644 index 0000000..6636c59 --- /dev/null +++ b/target/linux/kirkwood/profiles/400-rd88f6281.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/rd88f6281 + NAME:=Marvell RD88F6281 Reference Boards + PACKAGES:=mtd-utils kmod-ath9k kmod-mwl8k wpad-mini +endef + +define Profile/rd88f6281/Description + Marvell RD88F6281 Reference Boards Profile +endef + +$(eval $(call Profile,rd88f6281)) -- 1.7.6 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel