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

Reply via email to