diff options
Diffstat (limited to 'target/linux/ar7/patches-2.6.24/140-cpmac_fix.patch')
-rw-r--r-- | target/linux/ar7/patches-2.6.24/140-cpmac_fix.patch | 268 |
1 files changed, 0 insertions, 268 deletions
diff --git a/target/linux/ar7/patches-2.6.24/140-cpmac_fix.patch b/target/linux/ar7/patches-2.6.24/140-cpmac_fix.patch deleted file mode 100644 index 7658932..0000000 --- a/target/linux/ar7/patches-2.6.24/140-cpmac_fix.patch +++ /dev/null @@ -1,268 +0,0 @@ -Index: linux-2.6.24.7/drivers/net/cpmac.c -=================================================================== ---- linux-2.6.24.7.orig/drivers/net/cpmac.c -+++ linux-2.6.24.7/drivers/net/cpmac.c -@@ -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 cpmac_priv { - 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 @@ static int cpmac_start_xmit(struct sk_bu - 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 @@ static void cpmac_clear_tx(struct net_de - 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 @@ static void cpmac_hw_error(struct work_s - 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) -@@ -661,9 +705,6 @@ static irqreturn_t cpmac_irq(int irq, vo - int queue; - u32 status; - -- if (!dev) -- return IRQ_NONE; -- - priv = netdev_priv(dev); - - status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR); -@@ -685,49 +726,33 @@ static irqreturn_t cpmac_irq(int irq, vo - - 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) -@@ -848,15 +873,6 @@ static void cpmac_adjust_link(struct net - spin_unlock(&priv->lock); - } - --static int cpmac_link_update(struct net_device *dev, -- struct fixed_phy_status *status) --{ -- status->link = 1; -- status->speed = 100; -- status->duplex = 1; -- return 0; --} -- - static int cpmac_open(struct net_device *dev) - { - int i, size, res; -@@ -923,6 +939,7 @@ static int cpmac_open(struct net_device - goto fail_irq; - } - -+ atomic_set(&priv->reset_pending, 0); - INIT_WORK(&priv->reset_work, cpmac_hw_error); - cpmac_hw_start(dev); - -@@ -999,11 +1016,11 @@ static int external_switch; - static int __devinit cpmac_probe(struct platform_device *pdev) - { - int rc, phy_id, i; -+ int mdio_bus_id = cpmac_mii.id; - struct resource *mem; - struct cpmac_priv *priv; - struct net_device *dev; - struct plat_cpmac_data *pdata; -- struct fixed_info *fixed_phy; - DECLARE_MAC_BUF(mac); - - pdata = pdev->dev.platform_data; -@@ -1017,9 +1034,23 @@ static int __devinit cpmac_probe(struct - } - - if (phy_id == PHY_MAX_ADDR) { -- if (external_switch || dumb_switch) -+ 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; -- else { -+ status.link = 1; -+ status.duplex = 1; -+ status.speed = 100; -+ fixed_phy_add(PHY_POLL, phy_id, &status); -+ } else { - printk(KERN_ERR "cpmac: no PHY present\n"); - return -ENODEV; - } -@@ -1063,32 +1094,8 @@ static int __devinit cpmac_probe(struct - priv->msg_enable = netif_msg_init(debug_level, 0xff); - memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); - -- if (phy_id == 31) { -- snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, cpmac_mii.id, -- phy_id); -- } else { -- /* Let's try to get a free fixed phy... */ -- for (i = 0; i < MAX_PHY_AMNT; i++) { -- fixed_phy = fixed_mdio_get_phydev(i); -- if (!fixed_phy) -- continue; -- if (!fixed_phy->phydev->attached_dev) { -- strncpy(priv->phy_name, -- fixed_phy->phydev->dev.bus_id, -- BUS_ID_SIZE); -- fixed_mdio_set_link_update(fixed_phy->phydev, -- &cpmac_link_update); -- goto phy_found; -- } -- } -- if (netif_msg_drv(priv)) -- printk(KERN_ERR "%s: Could not find fixed PHY\n", -- dev->name); -- rc = -ENODEV; -- goto fail; -- } -+ snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); - --phy_found: - priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0, - PHY_INTERFACE_MODE_MII); - if (IS_ERR(priv->phy)) { |