Skip to content

Commit

Permalink
gianfar: Don't free/request irqs on device reset
Browse files Browse the repository at this point in the history
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: Claudiu Manoil <claudiu.manoil@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Claudiu Manoil authored and David S. Miller committed Feb 25, 2014
1 parent 8830264 commit 80ec396
Showing 1 changed file with 45 additions and 32 deletions.
77 changes: 45 additions & 32 deletions drivers/net/ethernet/freescale/gianfar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1975,11 +1964,42 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)

}

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);

Expand All @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -2369,6 +2380,8 @@ static int gfar_close(struct net_device *dev)

netif_tx_stop_all_queues(dev);

gfar_free_irq(priv);

return 0;
}

Expand Down

0 comments on commit 80ec396

Please sign in to comment.