+ ++config AR2313
++ tristate "AR2313 Ethernet support"
++ depends on NET_ETHERNET && ATHEROS
++ help
++ Support for the AR231x/531x ethernet controller
++
+ config MACE
+ tristate "MACE (Power Mac ethernet) support"
+ depends on PPC_PMAC && PPC32
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -195,6 +195,7 @@
+ obj-$(CONFIG_KORINA) += korina.o
+ obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
+ obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
++obj-$(CONFIG_AR2313) += ar2313/
+ obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
+ obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
+ obj-$(CONFIG_DECLANCE) += declance.o
@@ -0,0 +1,11 @@
+--- a/drivers/net/ar2313/ar2313.c
++++ b/drivers/net/ar2313/ar2313.c
+@@ -291,7 +291,7 @@
+ sp->mii_bus.write = mdiobus_write;
+ sp->mii_bus.reset = mdiobus_reset;
+ sp->mii_bus.name = "ar2313_eth_mii";
+- sp->mii_bus.id = 0;
++ snprintf(sp->mii_bus.id, MII_BUS_ID_SIZE, "0");
+ sp->mii_bus.irq = kmalloc(sizeof(int), GFP_KERNEL);
+ *sp->mii_bus.irq = PHY_POLL;
+
@@ -0,0 +1,54 @@
+--- a/drivers/mtd/redboot.c
++++ b/drivers/mtd/redboot.c
+@@ -60,31 +60,32 @@
+ static char nullstring[] = "unallocated";
+ #endif
+
++ buf = vmalloc(master->erasesize);
++ if (!buf)
++ return -ENOMEM;
++
++ restart:
+ if ( directory < 0 ) {
+ offset = master->size + directory * master->erasesize;
+- while (master->block_isbad &&
++ while (master->block_isbad &&
+ master->block_isbad(master, offset)) {
+ if (!offset) {
+ nogood:
+ printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n");
++ vfree(buf);
+ return -EIO;
+ }
+ offset -= master->erasesize;
+ }
+ } else {
+ offset = directory * master->erasesize;
+- while (master->block_isbad &&
++ while (master->block_isbad &&
+ master->block_isbad(master, offset)) {
+ offset += master->erasesize;
+ if (offset == master->size)
+ goto nogood;
+ }
+ }
+- buf = vmalloc(master->erasesize);
+-
+- if (!buf)
+- return -ENOMEM;
+-
+ printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n",
+ master->name, offset);
+
+@@ -156,6 +157,11 @@
+ }
+ if (i == numslots) {
+ /* Didn't find it */
++ if (offset + master->erasesize < master->size) {
++ /* not at the end of the flash yet, maybe next block :) */
++ directory++;
++ goto restart;
++ }
+ printk(KERN_NOTICE "No RedBoot partition table detected in %s\n",
+ master->name);
+ ret = 0;
@@ -0,0 +1,26 @@
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3983,8 +3983,8 @@
+ /* Fix illegal SG+CSUM combinations. */
+ if ((dev->features & NETIF_F_SG) &&
+ !(dev->features & NETIF_F_ALL_CSUM)) {
+- printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no checksum feature.\n",
+- dev->name);
++ //printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no checksum feature.\n",
++ // dev->name);
+ dev->features &= ~NETIF_F_SG;
+ }
+
+@@ -3997,9 +3997,9 @@
+ }
+ if (dev->features & NETIF_F_UFO) {
+ if (!(dev->features & NETIF_F_HW_CSUM)) {
+- printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no "
+- "NETIF_F_HW_CSUM feature.\n",
+- dev->name);
++ //printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no "
++ // "NETIF_F_HW_CSUM feature.\n",
++ // dev->name);
+ dev->features &= ~NETIF_F_UFO;
+ }
+ if (!(dev->features & NETIF_F_SG)) {
@@ -0,0 +1,34 @@
+--- a/drivers/net/ar2313/ar2313.c
++++ b/drivers/net/ar2313/ar2313.c
+@@ -953,9 +953,9 @@
+ ((status >> DMA_RX_LEN_SHIFT) & 0x3fff) - CRC_LEN);
+
+ dev->stats.rx_bytes += skb->len;
+- skb->protocol = eth_type_trans(skb, dev);
++
+ /* pass the packet to upper layers */
+- netif_rx(skb);
++ sp->rx(skb);
+
+ skb_new->dev = dev;
+ /* 16 bit align */
+@@ -1370,6 +1370,8 @@
+ return PTR_ERR(phydev);
+ }
+
++ sp->rx = phydev->netif_rx;
++
+ /* mask with MAC supported features */
+ phydev->supported &= (SUPPORTED_10baseT_Half
+ | SUPPORTED_10baseT_Full
+--- a/drivers/net/ar2313/ar2313.h
++++ b/drivers/net/ar2313/ar2313.h
+@@ -107,6 +107,8 @@
+ */
+ struct ar2313_private {
+ struct net_device *dev;
++ int (*rx)(struct sk_buff *skb);
++
+ int version;
+ u32 mb[2];
+
@@ -0,0 +1,43 @@
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -45,6 +45,7 @@
+ #include <asm/mmu_context.h>
+ #include <asm/types.h>
+ #include <asm/stacktrace.h>
++#include <asm/time.h>
+
+ extern void check_wait(void);
+ extern asmlinkage void r4k_wait(void);
+@@ -1484,6 +1485,8 @@
+ */
+ if (cpu_has_mips_r2) {
+ cp0_compare_irq = (read_c0_intctl() >> 29) & 7;
++ if (get_c0_compare_irq)
++ cp0_compare_irq = get_c0_compare_irq();
+ cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7;
+ if (cp0_perfcount_irq == cp0_compare_irq)
+ cp0_perfcount_irq = -1;
+--- a/include/asm-mips/time.h
++++ b/include/asm-mips/time.h
+@@ -53,6 +53,7 @@
+ #ifdef CONFIG_CEVT_R4K
+ extern int mips_clockevent_init(void);
+ extern unsigned int __weak get_c0_compare_int(void);
++extern unsigned int __weak get_c0_compare_irq(void);
+ #else
+ static inline int mips_clockevent_init(void)
+ {
+--- a/arch/mips/atheros/board.c
++++ b/arch/mips/atheros/board.c
+@@ -205,6 +205,11 @@
+ void __init plat_time_init(void) {
+ board_time_init();
+ }
++
++unsigned int __cpuinit get_c0_compare_irq(void)
++{
++ return CP0_LEGACY_COMPARE_IRQ;
++}
+ #endif
+
+ void __init arch_init_irq(void)
@@ -0,0 +1,56 @@
+--- a/arch/mips/kernel/cevt-r4k.c
++++ b/arch/mips/kernel/cevt-r4k.c
+@@ -15,6 +15,22 @@
+ #include <asm/cevt-r4k.h>
+
+ /*
++ * Compare interrupt can be routed and latched outside the core,
++ * so a single execution hazard barrier may not be enough to give
++ * it time to clear as seen in the Cause register. 4 time the
++ * pipeline depth seems reasonably conservative, and empirically
++ * works better in configurations with high CPU/bus clock ratios.
++ */
++
++#define compare_change_hazard() \
++ do { \
++ irq_disable_hazard(); \
++ irq_disable_hazard(); \
++ irq_disable_hazard(); \
++ irq_disable_hazard(); \
++ } while (0)
++
++/*
+ * The SMTC Kernel for the 34K, 1004K, et. al. replaces several
+ * of these routines with SMTC-specific variants.
+ */
+@@ -30,6 +46,7 @@
+ cnt = read_c0_count();
+ cnt += delta;
+ write_c0_compare(cnt);
++ compare_change_hazard();
+ res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
+ return res;
+ }
+@@ -99,22 +116,6 @@
+ return (read_c0_cause() >> cp0_compare_irq) & 0x100;
+ }
+
+-/*
+- * Compare interrupt can be routed and latched outside the core,
+- * so a single execution hazard barrier may not be enough to give
+- * it time to clear as seen in the Cause register. 4 time the
+- * pipeline depth seems reasonably conservative, and empirically
+- * works better in configurations with high CPU/bus clock ratios.
+- */
+-
+-#define compare_change_hazard() \
+- do { \
+- irq_disable_hazard(); \
+- irq_disable_hazard(); \
+- irq_disable_hazard(); \
+- irq_disable_hazard(); \
+- } while (0)
+-
+ int c0_compare_int_usable(void)
+ {
+ unsigned int delta;