Commit 80ec396c authored by Claudiu Manoil's avatar Claudiu Manoil Committed by David S. Miller
Browse files

gianfar: Don't free/request irqs on device reset



Resetting the device (stop_gfar()/startup_gfar()) should
be fast and to the point, in order to timely recover
from an error condition (like Tx timeout) or during
device reconfig.  The irq free/ request routines are just
redundant here, and they should be part of the device
close/ open routines instead.

Signed-off-by: default avatarClaudiu Manoil <claudiu.manoil@freescale.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 88302648
Loading
Loading
Loading
Loading
+45 −32
Original line number Diff line number Diff line
@@ -1715,18 +1715,10 @@ void gfar_halt(struct gfar_private *priv)
	gfar_write(&regs->maccfg1, tempval);
}

static void free_grp_irqs(struct gfar_priv_grp *grp)
{
	free_irq(gfar_irq(grp, TX)->irq, grp);
	free_irq(gfar_irq(grp, RX)->irq, grp);
	free_irq(gfar_irq(grp, ER)->irq, grp);
}

void stop_gfar(struct net_device *dev)
{
	struct gfar_private *priv = netdev_priv(dev);
	unsigned long flags;
	int i;

	phy_stop(priv->phydev);

@@ -1742,16 +1734,6 @@ void stop_gfar(struct net_device *dev)
	unlock_tx_qs(priv);
	local_irq_restore(flags);

	/* Free the IRQs */
	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
		for (i = 0; i < priv->num_grps; i++)
			free_grp_irqs(&priv->gfargrp[i]);
	} else {
		for (i = 0; i < priv->num_grps; i++)
			free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
				 &priv->gfargrp[i]);
	}

	free_skb_resources(priv);
}

@@ -1919,6 +1901,13 @@ void gfar_configure_coalescing_all(struct gfar_private *priv)
	gfar_configure_coalescing(priv, 0xFF, 0xFF);
}

static void free_grp_irqs(struct gfar_priv_grp *grp)
{
	free_irq(gfar_irq(grp, TX)->irq, grp);
	free_irq(gfar_irq(grp, RX)->irq, grp);
	free_irq(gfar_irq(grp, ER)->irq, grp);
}

static int register_grp_irqs(struct gfar_priv_grp *grp)
{
	struct gfar_private *priv = grp->priv;
@@ -1975,11 +1964,42 @@ err_irq_fail:

}

static void gfar_free_irq(struct gfar_private *priv)
{
	int i;

	/* Free the IRQs */
	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
		for (i = 0; i < priv->num_grps; i++)
			free_grp_irqs(&priv->gfargrp[i]);
	} else {
		for (i = 0; i < priv->num_grps; i++)
			free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
				 &priv->gfargrp[i]);
	}
}

static int gfar_request_irq(struct gfar_private *priv)
{
	int err, i, j;

	for (i = 0; i < priv->num_grps; i++) {
		err = register_grp_irqs(&priv->gfargrp[i]);
		if (err) {
			for (j = 0; j < i; j++)
				free_grp_irqs(&priv->gfargrp[j]);
			return err;
		}
	}

	return 0;
}

/* Bring the controller up and running */
int startup_gfar(struct net_device *ndev)
{
	struct gfar_private *priv = netdev_priv(ndev);
	int err, i, j;
	int err;

	gfar_mac_reset(priv);

@@ -1989,25 +2009,12 @@ int startup_gfar(struct net_device *ndev)

	gfar_init_tx_rx_base(priv);

	for (i = 0; i < priv->num_grps; i++) {
		err = register_grp_irqs(&priv->gfargrp[i]);
		if (err) {
			for (j = 0; j < i; j++)
				free_grp_irqs(&priv->gfargrp[j]);
			goto irq_fail;
		}
	}

	/* Start the controller */
	gfar_start(priv);

	phy_start(priv->phydev);

	return 0;

irq_fail:
	free_skb_resources(priv);
	return err;
}

/* Called when something needs to use the ethernet device
@@ -2027,6 +2034,10 @@ static int gfar_enet_open(struct net_device *dev)
		return err;
	}

	err = gfar_request_irq(priv);
	if (err)
		return err;

	err = startup_gfar(dev);
	if (err) {
		disable_napi(priv);
@@ -2369,6 +2380,8 @@ static int gfar_close(struct net_device *dev)

	netif_tx_stop_all_queues(dev);

	gfar_free_irq(priv);

	return 0;
}