Commit 032dc41b authored by Harini Katakam's avatar Harini Katakam Committed by David S. Miller

net: macb: Handle HRESP error

Handle HRESP error by doing a SW reset of RX and TX and
re-initializing the descriptors, RX and TX queue pointers.
Signed-off-by: default avatarHarini Katakam <harinik@xilinx.com>
Signed-off-by: default avatarMichal Simek <michal.simek@xilinx.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 468330e8
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/ptp_clock_kernel.h> #include <linux/ptp_clock_kernel.h>
#include <linux/net_tstamp.h> #include <linux/net_tstamp.h>
#include <linux/interrupt.h>
#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) || defined(CONFIG_MACB_USE_HWSTAMP) #if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) || defined(CONFIG_MACB_USE_HWSTAMP)
#define MACB_EXT_DESC #define MACB_EXT_DESC
...@@ -1200,6 +1201,8 @@ struct macb { ...@@ -1200,6 +1201,8 @@ struct macb {
struct ethtool_rx_fs_list rx_fs_list; struct ethtool_rx_fs_list rx_fs_list;
spinlock_t rx_fs_lock; spinlock_t rx_fs_lock;
unsigned int max_tuples; unsigned int max_tuples;
struct tasklet_struct hresp_err_tasklet;
}; };
#ifdef CONFIG_MACB_USE_HWSTAMP #ifdef CONFIG_MACB_USE_HWSTAMP
......
...@@ -1258,6 +1258,57 @@ static int macb_poll(struct napi_struct *napi, int budget) ...@@ -1258,6 +1258,57 @@ static int macb_poll(struct napi_struct *napi, int budget)
return work_done; return work_done;
} }
static void macb_hresp_error_task(unsigned long data)
{
struct macb *bp = (struct macb *)data;
struct net_device *dev = bp->dev;
struct macb_queue *queue = bp->queues;
unsigned int q;
u32 ctrl;
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
queue_writel(queue, IDR, MACB_RX_INT_FLAGS |
MACB_TX_INT_FLAGS |
MACB_BIT(HRESP));
}
ctrl = macb_readl(bp, NCR);
ctrl &= ~(MACB_BIT(RE) | MACB_BIT(TE));
macb_writel(bp, NCR, ctrl);
netif_tx_stop_all_queues(dev);
netif_carrier_off(dev);
bp->macbgem_ops.mog_init_rings(bp);
/* Initialize TX and RX buffers */
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
queue_writel(queue, RBQP, lower_32_bits(queue->rx_ring_dma));
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
if (bp->hw_dma_cap & HW_DMA_CAP_64B)
queue_writel(queue, RBQPH,
upper_32_bits(queue->rx_ring_dma));
#endif
queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma));
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
if (bp->hw_dma_cap & HW_DMA_CAP_64B)
queue_writel(queue, TBQPH,
upper_32_bits(queue->tx_ring_dma));
#endif
/* Enable interrupts */
queue_writel(queue, IER,
MACB_RX_INT_FLAGS |
MACB_TX_INT_FLAGS |
MACB_BIT(HRESP));
}
ctrl |= MACB_BIT(RE) | MACB_BIT(TE);
macb_writel(bp, NCR, ctrl);
netif_carrier_on(dev);
netif_tx_start_all_queues(dev);
}
static irqreturn_t macb_interrupt(int irq, void *dev_id) static irqreturn_t macb_interrupt(int irq, void *dev_id)
{ {
struct macb_queue *queue = dev_id; struct macb_queue *queue = dev_id;
...@@ -1347,10 +1398,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) ...@@ -1347,10 +1398,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
} }
if (status & MACB_BIT(HRESP)) { if (status & MACB_BIT(HRESP)) {
/* TODO: Reset the hardware, and maybe move the tasklet_schedule(&bp->hresp_err_tasklet);
* netdev_err to a lower-priority context as well
* (work queue?)
*/
netdev_err(dev, "DMA bus error: HRESP not OK\n"); netdev_err(dev, "DMA bus error: HRESP not OK\n");
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
...@@ -3937,6 +3985,9 @@ static int macb_probe(struct platform_device *pdev) ...@@ -3937,6 +3985,9 @@ static int macb_probe(struct platform_device *pdev)
goto err_out_unregister_mdio; goto err_out_unregister_mdio;
} }
tasklet_init(&bp->hresp_err_tasklet, macb_hresp_error_task,
(unsigned long)bp);
phy_attached_info(phydev); phy_attached_info(phydev);
netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n", netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment