[PATCH] Fix locking in gianfar
This patch fixes several bugs in the gianfar driver, including a major one where spinlocks were horribly broken: * Split gianfar locks into two types: TX and RX * Made it so gfar_start() now clears RHALT * Fixed a bug where calling gfar_start_xmit() with interrupts off would corrupt the interrupt state * Fixed a bug where a frame could potentially arrive, and never be handled (if no more frames arrived * Fixed a bug where the rx_work_limit would never be observed by the rx completion code * Fixed a bug where the interrupt handlers were not actually protected by their spinlocks Signed-off-by: Andy Fleming <afleming@freescale.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
committed by
Jeff Garzik
parent
f18b95c3e2
commit
fef6108d45
@@ -455,10 +455,14 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
|
||||
|
||||
/* Halt TX and RX, and process the frames which
|
||||
* have already been received */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->txlock, flags);
|
||||
spin_lock(&priv->rxlock);
|
||||
|
||||
gfar_halt(dev);
|
||||
gfar_clean_rx_ring(dev, priv->rx_ring_size);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
spin_unlock(&priv->rxlock);
|
||||
spin_unlock_irqrestore(&priv->txlock, flags);
|
||||
|
||||
/* Now we take down the rings to rebuild them */
|
||||
stop_gfar(dev);
|
||||
@@ -488,10 +492,14 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
|
||||
|
||||
/* Halt TX and RX, and process the frames which
|
||||
* have already been received */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->txlock, flags);
|
||||
spin_lock(&priv->rxlock);
|
||||
|
||||
gfar_halt(dev);
|
||||
gfar_clean_rx_ring(dev, priv->rx_ring_size);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
spin_unlock(&priv->rxlock);
|
||||
spin_unlock_irqrestore(&priv->txlock, flags);
|
||||
|
||||
/* Now we take down the rings to rebuild them */
|
||||
stop_gfar(dev);
|
||||
@@ -523,7 +531,7 @@ static int gfar_set_tx_csum(struct net_device *dev, uint32_t data)
|
||||
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->txlock, flags);
|
||||
gfar_halt(dev);
|
||||
|
||||
if (data)
|
||||
@@ -532,7 +540,7 @@ static int gfar_set_tx_csum(struct net_device *dev, uint32_t data)
|
||||
dev->features &= ~NETIF_F_IP_CSUM;
|
||||
|
||||
gfar_start(dev);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock_irqrestore(&priv->txlock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user