diff options
author | Ricardo Ribalda <ricardo.ribalda@gmail.com> | 2011-11-07 18:31:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-09 15:37:38 -0500 |
commit | 50ec1538fac0e39078d45ca5f8a5186621830058 (patch) | |
tree | 0cf86765fed469bbfd5be682321cf5a895b1ae30 /drivers/net/ethernet | |
parent | 2bc8ca40f951163b3bb75949479e2755c12c1b96 (diff) |
net/temac: FIX segfault when process old irqs
Do not enable the irq until the scatter gather registers are ready to
handle the data. Otherwise an irq from a packet send/received before
last close can lead to an access to an invalid memory region on the irq
handler.
Also, stop the dma engine on close.
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/xilinx/ll_temac_main.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index caf3659e173c..05a1ffad20d2 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c | |||
@@ -203,6 +203,9 @@ static void temac_dma_bd_release(struct net_device *ndev) | |||
203 | struct temac_local *lp = netdev_priv(ndev); | 203 | struct temac_local *lp = netdev_priv(ndev); |
204 | int i; | 204 | int i; |
205 | 205 | ||
206 | /* Reset Local Link (DMA) */ | ||
207 | lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); | ||
208 | |||
206 | for (i = 0; i < RX_BD_NUM; i++) { | 209 | for (i = 0; i < RX_BD_NUM; i++) { |
207 | if (!lp->rx_skb[i]) | 210 | if (!lp->rx_skb[i]) |
208 | break; | 211 | break; |
@@ -860,6 +863,8 @@ static int temac_open(struct net_device *ndev) | |||
860 | phy_start(lp->phy_dev); | 863 | phy_start(lp->phy_dev); |
861 | } | 864 | } |
862 | 865 | ||
866 | temac_device_reset(ndev); | ||
867 | |||
863 | rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev); | 868 | rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev); |
864 | if (rc) | 869 | if (rc) |
865 | goto err_tx_irq; | 870 | goto err_tx_irq; |
@@ -867,7 +872,6 @@ static int temac_open(struct net_device *ndev) | |||
867 | if (rc) | 872 | if (rc) |
868 | goto err_rx_irq; | 873 | goto err_rx_irq; |
869 | 874 | ||
870 | temac_device_reset(ndev); | ||
871 | return 0; | 875 | return 0; |
872 | 876 | ||
873 | err_rx_irq: | 877 | err_rx_irq: |