ar7: 2.6.25.1 support

SVN-Revision: 11023
This commit is contained in:
Matteo Croce 2008-05-03 15:33:38 +00:00
parent b6b32f8131
commit 2036ae2056
10 changed files with 723 additions and 0 deletions

View file

@ -0,0 +1,94 @@
Index: linux-2.6.25.1/arch/mips/Kconfig
===================================================================
--- linux-2.6.25.1.orig/arch/mips/Kconfig 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/arch/mips/Kconfig 2008-05-03 16:17:54.000000000 +0200
@@ -18,6 +18,24 @@
prompt "System type"
default SGI_IP22
+config AR7
+ bool "Texas Instruments AR7"
+ select BOOT_ELF32
+ select DMA_NONCOHERENT
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select NO_EXCEPT_FILL
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_KGDB
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select GENERIC_GPIO
+ select GENERIC_HARDIRQS_NO__DO_IRQ
+
config MACH_ALCHEMY
bool "Alchemy processor based machines"
Index: linux-2.6.25.1/arch/mips/kernel/traps.c
===================================================================
--- linux-2.6.25.1.orig/arch/mips/kernel/traps.c 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/arch/mips/kernel/traps.c 2008-05-03 16:17:54.000000000 +0200
@@ -1112,9 +1112,22 @@
exception_handlers[n] = handler;
if (n == 0 && cpu_has_divec) {
- *(u32 *)(ebase + 0x200) = 0x08000000 |
- (0x03ffffff & (handler >> 2));
- flush_icache_range(ebase + 0x200, ebase + 0x204);
+ if ((handler ^ (ebase + 4)) & 0xfc000000) {
+ /* lui k0, 0x0000 */
+ *(u32 *)(ebase + 0x200) = 0x3c1a0000 | (handler >> 16);
+ /* ori k0, 0x0000 */
+ *(u32 *)(ebase + 0x204) =
+ 0x375a0000 | (handler & 0xffff);
+ /* jr k0 */
+ *(u32 *)(ebase + 0x208) = 0x03400008;
+ /* nop */
+ *(u32 *)(ebase + 0x20C) = 0x00000000;
+ flush_icache_range(ebase + 0x200, ebase + 0x210);
+ } else {
+ *(u32 *)(ebase + 0x200) =
+ 0x08000000 | (0x03ffffff & (handler >> 2));
+ flush_icache_range(ebase + 0x200, ebase + 0x204);
+ }
}
return (void *)old_handler;
}
Index: linux-2.6.25.1/arch/mips/Makefile
===================================================================
--- linux-2.6.25.1.orig/arch/mips/Makefile 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/arch/mips/Makefile 2008-05-03 16:17:54.000000000 +0200
@@ -167,6 +167,13 @@
#
#
+# Texas Instruments AR7
+#
+core-$(CONFIG_AR7) += arch/mips/ar7/
+cflags-$(CONFIG_AR7) += -Iinclude/asm-mips/ar7
+load-$(CONFIG_AR7) += 0xffffffff94100000
+
+#
# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
#
core-$(CONFIG_MACH_JAZZ) += arch/mips/jazz/
Index: linux-2.6.25.1/include/asm-mips/page.h
===================================================================
--- linux-2.6.25.1.orig/include/asm-mips/page.h 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/include/asm-mips/page.h 2008-05-03 16:17:54.000000000 +0200
@@ -182,8 +182,10 @@
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
-#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
+#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \
+ PHYS_OFFSET)
+#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \
+ PHYS_OFFSET)
#include <asm-generic/memory_model.h>
#include <asm-generic/page.h>

View file

@ -0,0 +1,43 @@
Index: linux-2.6.25.1/drivers/mtd/Kconfig
===================================================================
--- linux-2.6.25.1.orig/drivers/mtd/Kconfig 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/mtd/Kconfig 2008-05-03 16:18:06.000000000 +0200
@@ -158,6 +158,12 @@
the partition map from the children of the flash node,
as described in Documentation/powerpc/booting-without-of.txt.
+config MTD_AR7_PARTS
+ tristate "TI AR7 partitioning support"
+ depends on MTD_PARTITIONS
+ ---help---
+ TI AR7 partitioning support
+
comment "User Modules And Translation Layers"
config MTD_CHAR
Index: linux-2.6.25.1/drivers/mtd/Makefile
===================================================================
--- linux-2.6.25.1.orig/drivers/mtd/Makefile 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/mtd/Makefile 2008-05-03 16:18:06.000000000 +0200
@@ -12,6 +12,7 @@
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
+obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_CHAR) += mtdchar.o
Index: linux-2.6.25.1/drivers/mtd/maps/physmap.c
===================================================================
--- linux-2.6.25.1.orig/drivers/mtd/maps/physmap.c 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/mtd/maps/physmap.c 2008-05-03 16:18:06.000000000 +0200
@@ -87,7 +87,8 @@
static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };
#ifdef CONFIG_MTD_PARTITIONS
-static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
+static const char *part_probe_types[] = {"cmdlinepart", "RedBoot",
+ "ar7part", NULL };
#endif
static int physmap_flash_probe(struct platform_device *dev)

View file

@ -0,0 +1,32 @@
Index: linux-2.6.25.1/drivers/char/Kconfig
===================================================================
--- linux-2.6.25.1.orig/drivers/char/Kconfig 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/char/Kconfig 2008-05-03 16:18:26.000000000 +0200
@@ -913,6 +913,15 @@
To compile this driver as a module, choose M here: the
module will be called mwave.
+config AR7_GPIO
+ tristate "TI AR7 GPIO Support"
+ depends on AR7
+ help
+ Give userspace access to the GPIO pins on the Texas Instruments AR7
+ processors.
+
+ If compiled as a module, it will be called ar7_gpio.
+
config SCx200_GPIO
tristate "NatSemi SCx200 GPIO Support"
depends on SCx200
Index: linux-2.6.25.1/drivers/char/Makefile
===================================================================
--- linux-2.6.25.1.orig/drivers/char/Makefile 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/char/Makefile 2008-05-03 16:18:26.000000000 +0200
@@ -90,6 +90,7 @@
obj-$(CONFIG_PPDEV) += ppdev.o
obj-$(CONFIG_NWBUTTON) += nwbutton.o
obj-$(CONFIG_NWFLASH) += nwflash.o
+obj-$(CONFIG_AR7_GPIO) += ar7_gpio.o
obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o

View file

@ -0,0 +1,22 @@
Index: linux-2.6.25.1/drivers/Kconfig
===================================================================
--- linux-2.6.25.1.orig/drivers/Kconfig 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/Kconfig 2008-05-03 16:19:06.000000000 +0200
@@ -97,4 +97,6 @@
source "drivers/auxdisplay/Kconfig"
source "drivers/uio/Kconfig"
+
+source "drivers/vlynq/Kconfig"
endmenu
Index: linux-2.6.25.1/drivers/Makefile
===================================================================
--- linux-2.6.25.1.orig/drivers/Makefile 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/Makefile 2008-05-03 16:18:37.000000000 +0200
@@ -91,5 +91,6 @@
obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/
obj-$(CONFIG_OF) += of/
+obj-$(CONFIG_VLYNQ) += vlynq/
obj-$(CONFIG_SSB) += ssb/
obj-$(CONFIG_VIRTIO) += virtio/

View file

@ -0,0 +1,169 @@
Index: linux-2.6.25.1/drivers/net/cpmac.c
===================================================================
--- linux-2.6.25.1.orig/drivers/net/cpmac.c 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/net/cpmac.c 2008-05-03 16:21:17.000000000 +0200
@@ -38,6 +38,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/gpio.h>
+#include <asm/atomic.h>
MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");
MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)");
@@ -207,6 +208,7 @@
struct work_struct reset_work;
struct platform_device *pdev;
struct napi_struct napi;
+ atomic_t reset_pending;
};
static irqreturn_t cpmac_irq(int, void *);
@@ -455,6 +457,9 @@
struct cpmac_desc *desc;
struct cpmac_priv *priv = netdev_priv(dev);
+ if (unlikely(atomic_read(&priv->reset_pending)))
+ return NETDEV_TX_BUSY;
+
if (unlikely(skb_padto(skb, ETH_ZLEN)))
return NETDEV_TX_OK;
@@ -634,14 +639,14 @@
priv->desc_ring[i].dataflags = 0;
if (priv->desc_ring[i].skb) {
dev_kfree_skb_any(priv->desc_ring[i].skb);
- if (netif_subqueue_stopped(dev, i))
- netif_wake_subqueue(dev, i);
+ priv->desc_ring[i].skb = NULL;
}
}
}
static void cpmac_hw_error(struct work_struct *work)
{
+ int i;
struct cpmac_priv *priv =
container_of(work, struct cpmac_priv, reset_work);
@@ -650,8 +655,47 @@
spin_unlock(&priv->rx_lock);
cpmac_clear_tx(priv->dev);
cpmac_hw_start(priv->dev);
- napi_enable(&priv->napi);
- netif_start_queue(priv->dev);
+ barrier();
+ atomic_dec(&priv->reset_pending);
+
+ for (i = 0; i < CPMAC_QUEUES; i++) {
+ netif_wake_subqueue(priv->dev, i);
+ }
+ netif_wake_queue(priv->dev);
+ cpmac_write(priv->regs, CPMAC_MAC_INT_ENABLE, 3);
+}
+
+static void cpmac_check_status(struct net_device *dev)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ u32 macstatus = cpmac_read(priv->regs, CPMAC_MAC_STATUS);
+ int rx_channel = (macstatus >> 8) & 7;
+ int rx_code = (macstatus >> 12) & 15;
+ int tx_channel = (macstatus >> 16) & 7;
+ int tx_code = (macstatus >> 20) & 15;
+
+ if (rx_code || tx_code) {
+ if (netif_msg_drv(priv) && net_ratelimit()) {
+ /* Can't find any documentation on what these error codes actually are.
+ * So just log them and hope..
+ */
+ if (rx_code)
+ printk(KERN_WARNING "%s: host error %d on rx channel %d (macstatus %08x), resetting\n",
+ dev->name, rx_code, rx_channel, macstatus);
+ if (tx_code)
+ printk(KERN_WARNING "%s: host error %d on tx channel %d (macstatus %08x), resetting\n",
+ dev->name, tx_code, tx_channel, macstatus);
+ }
+
+ netif_stop_queue(dev);
+ cpmac_hw_stop(dev);
+ if (schedule_work(&priv->reset_work))
+ atomic_inc(&priv->reset_pending);
+ if (unlikely(netif_msg_hw(priv)))
+ cpmac_dump_regs(dev);
+ }
+ cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff);
}
static irqreturn_t cpmac_irq(int irq, void *dev_id)
@@ -682,49 +726,33 @@
cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0);
- if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS))) {
- if (netif_msg_drv(priv) && net_ratelimit())
- printk(KERN_ERR "%s: hw error, resetting...\n",
- dev->name);
- netif_stop_queue(dev);
- napi_disable(&priv->napi);
- cpmac_hw_stop(dev);
- schedule_work(&priv->reset_work);
- if (unlikely(netif_msg_hw(priv)))
- cpmac_dump_regs(dev);
- }
+ if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS)))
+ cpmac_check_status(dev);
return IRQ_HANDLED;
}
static void cpmac_tx_timeout(struct net_device *dev)
{
- struct cpmac_priv *priv = netdev_priv(dev);
int i;
+ struct cpmac_priv *priv = netdev_priv(dev);
spin_lock(&priv->lock);
dev->stats.tx_errors++;
spin_unlock(&priv->lock);
if (netif_msg_tx_err(priv) && net_ratelimit())
printk(KERN_WARNING "%s: transmit timeout\n", dev->name);
- /*
- * FIXME: waking up random queue is not the best thing to
- * do... on the other hand why we got here at all?
- */
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < CPMAC_QUEUES; i++)
- if (priv->desc_ring[i].skb) {
- priv->desc_ring[i].dataflags = 0;
- dev_kfree_skb_any(priv->desc_ring[i].skb);
- netif_wake_subqueue(dev, i);
- break;
- }
-#else
- priv->desc_ring[0].dataflags = 0;
- if (priv->desc_ring[0].skb)
- dev_kfree_skb_any(priv->desc_ring[0].skb);
- netif_wake_queue(dev);
-#endif
+
+ atomic_inc(&priv->reset_pending);
+ barrier();
+ cpmac_clear_tx(dev);
+ barrier();
+ atomic_dec(&priv->reset_pending);
+
+ netif_wake_queue(priv->dev);
+ for (i = 0; i < CPMAC_QUEUES; i++) {
+ netif_wake_subqueue(dev, i);
+ }
}
static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -911,6 +939,7 @@
goto fail_irq;
}
+ atomic_set(&priv->reset_pending, 0);
INIT_WORK(&priv->reset_work, cpmac_hw_error);
cpmac_hw_start(dev);

View file

@ -0,0 +1,95 @@
From 0daaa095cefd9d7091a7ccce2ff89f1ff4feae7a Mon Sep 17 00:00:00 2001
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Date: Wed, 5 Mar 2008 14:52:26 +0300
Subject: [PATCH] AR7/cpmac: convert to new fixed phy infrastructure, now for real
This patch converts platform code to register fixed phys early.
cpmac driver modified to blindly accept fixed phy id (that is equal
to platform device id).
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/mips/ar7/platform.c | 17 +++++++++++++++++
drivers/net/cpmac.c | 19 +++----------------
2 files changed, 20 insertions(+), 16 deletions(-)
Index: linux-2.6.25.1/arch/mips/ar7/platform.c
===================================================================
--- linux-2.6.25.1.orig/arch/mips/ar7/platform.c 2008-05-03 16:17:30.000000000 +0200
+++ linux-2.6.25.1/arch/mips/ar7/platform.c 2008-05-03 16:24:08.000000000 +0200
@@ -33,6 +33,8 @@
#include <linux/vlynq.h>
#include <linux/leds.h>
#include <linux/string.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
#include <asm/addrspace.h>
#include <asm/ar7/ar7.h>
@@ -205,6 +207,13 @@
.width = 2,
};
+/* lets assume this is suitable for both high and low cpmacs links */
+static struct fixed_phy_status fixed_phy_status __initdata = {
+ .link = 1,
+ .speed = 100,
+ .duplex = 1,
+};
+
static struct plat_cpmac_data cpmac_low_data = {
.reset_bit = 17,
.power_bit = 20,
@@ -506,6 +515,10 @@
}
if (ar7_has_high_cpmac()) {
+ res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
+ if (res && res != -ENODEV)
+ return res;
+
cpmac_get_mac(1, cpmac_high_data.dev_addr);
res = platform_device_register(&cpmac_high);
if (res)
@@ -514,6 +527,10 @@
cpmac_low_data.phy_mask = 0xffffffff;
}
+ res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
+ if (res && res != -ENODEV)
+ return res;
+
cpmac_get_mac(0, cpmac_low_data.dev_addr);
res = platform_device_register(&cpmac_low);
if (res)
Index: linux-2.6.25.1/drivers/net/cpmac.c
===================================================================
--- linux-2.6.25.1.orig/drivers/net/cpmac.c 2008-05-03 16:21:17.000000000 +0200
+++ linux-2.6.25.1/drivers/net/cpmac.c 2008-05-03 16:24:08.000000000 +0200
@@ -1035,23 +1035,10 @@
if (phy_id == PHY_MAX_ADDR) {
if (external_switch || dumb_switch) {
- struct fixed_phy_status status = {};
-
- mdio_bus_id = 0;
-
- /*
- * FIXME: this should be in the platform code!
- * Since there is not platform code at all (that is,
- * no mainline users of that driver), place it here
- * for now.
- */
- phy_id = 0;
- status.link = 1;
- status.duplex = 1;
- status.speed = 100;
- fixed_phy_add(PHY_POLL, phy_id, &status);
+ mdio_bus_id = 0; /* fixed phys bus */
+ phy_id = pdev->id;
} else {
- printk(KERN_ERR "cpmac: no PHY present\n");
+ dev_err(&pdev->dev, "no PHY present\n");
return -ENODEV;
}
}

View file

@ -0,0 +1,180 @@
Index: linux-2.6.25.1/drivers/net/cpmac.c
===================================================================
--- linux-2.6.25.1.orig/drivers/net/cpmac.c 2008-05-03 16:24:08.000000000 +0200
+++ linux-2.6.25.1/drivers/net/cpmac.c 2008-05-03 16:24:37.000000000 +0200
@@ -187,6 +187,7 @@
#define CPMAC_EOQ 0x1000
struct sk_buff *skb;
struct cpmac_desc *next;
+ struct cpmac_desc *prev;
dma_addr_t mapping;
dma_addr_t data_mapping;
};
@@ -242,6 +243,16 @@
printk("\n");
}
+static void cpmac_dump_all_desc(struct net_device *dev)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+ struct cpmac_desc *dump = priv->rx_head;
+ do {
+ cpmac_dump_desc(dev, dump);
+ dump = dump->next;
+ } while (dump != priv->rx_head);
+}
+
static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb)
{
int i;
@@ -413,21 +424,40 @@
static int cpmac_poll(struct napi_struct *napi, int budget)
{
struct sk_buff *skb;
- struct cpmac_desc *desc;
- int received = 0;
+ struct cpmac_desc *desc, *restart;
struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi);
+ int received = 0, processed = 0;
spin_lock(&priv->rx_lock);
if (unlikely(!priv->rx_head)) {
if (netif_msg_rx_err(priv) && net_ratelimit())
printk(KERN_WARNING "%s: rx: polling, but no queue\n",
priv->dev->name);
+ spin_unlock(&priv->rx_lock);
netif_rx_complete(priv->dev, napi);
return 0;
}
desc = priv->rx_head;
+ restart = NULL;
while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) {
+ processed++;
+
+ if ((desc->dataflags & CPMAC_EOQ) != 0) {
+ /* The last update to eoq->hw_next didn't happen soon enough, and the
+ * receiver stopped here. Remember this descriptor so we can restart
+ * the receiver after freeing some space.
+ */
+ if (unlikely(restart)) {
+ if (netif_msg_rx_err(priv))
+ printk(KERN_ERR "%s: poll found a duplicate EOQ: %p and %p\n",
+ priv->dev->name, restart, desc);
+ goto fatal_error;
+ }
+
+ restart = desc->next;
+ }
+
skb = cpmac_rx_one(priv, desc);
if (likely(skb)) {
netif_receive_skb(skb);
@@ -436,19 +466,81 @@
desc = desc->next;
}
+ if (desc != priv->rx_head) {
+ /* We freed some buffers, but not the whole ring, add what we did free to the rx list */
+ desc->prev->hw_next = (u32)0;
+ priv->rx_head->prev->hw_next = priv->rx_head->mapping;
+ }
+
+ /* Optimization: If we did not actually process an EOQ (perhaps because of
+ * quota limits), check to see if the tail of the queue has EOQ set. We
+ * should immediately restart in that case so that the receiver can restart
+ * and run in parallel with more packet processing. This lets us handle slightly
+ * larger bursts before running out of ring space (assuming dev->weight < ring_size)
+ */
+ if (!restart &&
+ (priv->rx_head->prev->dataflags & (CPMAC_OWN|CPMAC_EOQ)) == CPMAC_EOQ &&
+ (priv->rx_head->dataflags & CPMAC_OWN) != 0) {
+ /* reset EOQ so the poll loop (above) doesn't try to restart this when it
+ * eventually gets to this descriptor.
+ */
+ priv->rx_head->prev->dataflags &= ~CPMAC_EOQ;
+ restart = priv->rx_head;
+ }
+
+ if (restart) {
+ priv->dev->stats.rx_errors++;
+ priv->dev->stats.rx_fifo_errors++;
+ if (netif_msg_rx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING "%s: rx dma ring overrun\n", priv->dev->name);
+
+ if (unlikely((restart->dataflags & CPMAC_OWN) == 0)) {
+ if (netif_msg_drv(priv))
+ printk(KERN_ERR "%s: cpmac_poll is trying to restart rx from a descriptor that's not free: %p\n",
+ priv->dev->name, restart);
+ goto fatal_error;
+ }
+
+ cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping);
+ }
+
priv->rx_head = desc;
spin_unlock(&priv->rx_lock);
if (unlikely(netif_msg_rx_status(priv)))
printk(KERN_DEBUG "%s: poll processed %d packets\n",
priv->dev->name, received);
- if (desc->dataflags & CPMAC_OWN) {
+ if (processed == 0) {
+ /* we ran out of packets to read, revert to interrupt-driven mode */
netif_rx_complete(priv->dev, napi);
- cpmac_write(priv->regs, CPMAC_RX_PTR(0), (u32)desc->mapping);
cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
return 0;
}
return 1;
+
+fatal_error:
+ /* Something went horribly wrong. Reset hardware to try to recover rather than wedging. */
+
+ if (netif_msg_drv(priv)) {
+ printk(KERN_ERR "%s: cpmac_poll is confused. Resetting hardware\n", priv->dev->name);
+ cpmac_dump_all_desc(priv->dev);
+ printk(KERN_DEBUG "%s: RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n",
+ priv->dev->name,
+ cpmac_read(priv->regs, CPMAC_RX_PTR(0)),
+ cpmac_read(priv->regs, CPMAC_RX_ACK(0)));
+ }
+
+ spin_unlock(&priv->rx_lock);
+ netif_rx_complete(priv->dev, napi);
+ netif_stop_queue(priv->dev);
+ napi_disable(&priv->napi);
+
+ atomic_inc(&priv->reset_pending);
+ cpmac_hw_stop(priv->dev);
+ if (!schedule_work(&priv->reset_work))
+ atomic_dec(&priv->reset_pending);
+ return 0;
+
}
static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -625,8 +717,10 @@
desc->dataflags = CPMAC_OWN;
dev->stats.rx_dropped++;
}
+ desc->hw_next = desc->next->mapping;
desc = desc->next;
}
+ priv->rx_head->prev->hw_next = 0;
}
static void cpmac_clear_tx(struct net_device *dev)
@@ -928,9 +1022,12 @@
desc->buflen = CPMAC_SKB_SIZE;
desc->dataflags = CPMAC_OWN;
desc->next = &priv->rx_head[(i + 1) % priv->ring_size];
+ desc->next->prev = desc;
desc->hw_next = (u32)desc->next->mapping;
}
+ priv->rx_head->prev->hw_next = (u32)0;
+
if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED,
dev->name, dev))) {
if (netif_msg_drv(priv))

View file

@ -0,0 +1,15 @@
Index: linux-2.6.25.1/drivers/net/cpmac.c
===================================================================
--- linux-2.6.25.1.orig/drivers/net/cpmac.c 2008-05-03 16:24:37.000000000 +0200
+++ linux-2.6.25.1/drivers/net/cpmac.c 2008-05-03 16:24:49.000000000 +0200
@@ -1178,9 +1178,7 @@
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
- snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
-
- priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
+ priv->phy = phy_connect(dev, cpmac_mii.phy_map[phy_id]->dev.bus_id, &cpmac_adjust_link, 0,
PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phy)) {
if (netif_msg_drv(priv))

View file

@ -0,0 +1,44 @@
Index: linux-2.6.25.1/drivers/serial/8250.c
===================================================================
--- linux-2.6.25.1.orig/drivers/serial/8250.c 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/drivers/serial/8250.c 2008-05-03 16:25:06.000000000 +0200
@@ -267,6 +267,13 @@
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO,
},
+ [PORT_AR7] = {
+ .name = "TI-AR7",
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
};
#if defined (CONFIG_SERIAL_8250_AU1X00)
@@ -2455,7 +2462,11 @@
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
+#ifdef CONFIG_AR7
+ wait_for_xmitr(up, BOTH_EMPTY);
+#else
wait_for_xmitr(up, UART_LSR_THRE);
+#endif
serial_out(up, UART_TX, ch);
}
Index: linux-2.6.25.1/include/linux/serial_core.h
===================================================================
--- linux-2.6.25.1.orig/include/linux/serial_core.h 2008-05-01 23:45:25.000000000 +0200
+++ linux-2.6.25.1/include/linux/serial_core.h 2008-05-03 16:25:06.000000000 +0200
@@ -40,7 +40,8 @@
#define PORT_NS16550A 14
#define PORT_XSCALE 15
#define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */
-#define PORT_MAX_8250 16 /* max port ID */
+#define PORT_AR7 17
+#define PORT_MAX_8250 17 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed

View file

@ -0,0 +1,29 @@
Index: linux-2.6.25.1/drivers/net/cpmac.c
===================================================================
--- linux-2.6.25.1.orig/drivers/net/cpmac.c 2008-05-03 16:24:49.000000000 +0200
+++ linux-2.6.25.1/drivers/net/cpmac.c 2008-05-03 16:25:17.000000000 +0200
@@ -936,7 +936,8 @@
int new_state = 0;
spin_lock(&priv->lock);
- if (priv->phy->link) {
+ if (1 /* priv->phy->link */ ) {
+ netif_carrier_on(dev);
netif_start_queue(dev);
if (priv->phy->duplex != priv->oldduplex) {
new_state = 1;
@@ -948,11 +949,11 @@
priv->oldspeed = priv->phy->speed;
}
- if (!priv->oldlink) {
+ /*if (!priv->oldlink) {
new_state = 1;
- priv->oldlink = 1;
+ priv->oldlink = 1;*/
netif_schedule(dev);
- }
+ /*}*/
} else if (priv->oldlink) {
netif_stop_queue(dev);
new_state = 1;