diff options
author | Sandeep Gopalpet <Sandeep.Kumar@freescale.com> | 2009-11-02 10:03:00 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-03 10:40:55 +0300 |
commit | a12f801d4b349bc57622584e70e45a4ccbef53b6 (patch) | |
tree | 1b081795127d9e47aa5bac516fededa736dfc394 /drivers/net/gianfar_ethtool.c | |
parent | 123b43e9716115302a0095e14f2c545811712715 (diff) | |
download | linux-a12f801d4b349bc57622584e70e45a4ccbef53b6.tar.xz |
gianfar: Add per queue structure support
This patch introduces per tx and per rx queue structures.
Earlier the members of these structures were inside the
gfar_private structure.
Moving forward if we want to support multiple queues, we need
to refactor the gfar_private structure so that introduction of
multiple queues is easier.
Signed-off-by: Sandeep Gopalpet <Sandeep.Kumar@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/gianfar_ethtool.c')
-rw-r--r-- | drivers/net/gianfar_ethtool.c | 100 |
1 files changed, 65 insertions, 35 deletions
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 6c144b525b47..6d0d1714c2f2 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -7,8 +7,9 @@ * * Author: Andy Fleming * Maintainer: Kumar Gala + * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> * - * Copyright (c) 2003,2004 Freescale Semiconductor, Inc. + * Copyright 2003-2006, 2008-2009 Freescale Semiconductor, Inc. * * This software may be used and distributed according to * the terms of the GNU Public License, Version 2, incorporated herein @@ -41,7 +42,7 @@ #include "gianfar.h" extern void gfar_start(struct net_device *dev); -extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); +extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit); #define GFAR_MAX_COAL_USECS 0xffff #define GFAR_MAX_COAL_FRAMES 0xff @@ -197,12 +198,16 @@ static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd) { struct gfar_private *priv = netdev_priv(dev); struct phy_device *phydev = priv->phydev; + struct gfar_priv_rx_q *rx_queue = NULL; + struct gfar_priv_tx_q *tx_queue = NULL; if (NULL == phydev) return -ENODEV; + tx_queue = priv->tx_queue; + rx_queue = priv->rx_queue; - cmd->maxtxpkt = get_icft_value(priv->txic); - cmd->maxrxpkt = get_icft_value(priv->rxic); + cmd->maxtxpkt = get_icft_value(tx_queue->txic); + cmd->maxrxpkt = get_icft_value(rx_queue->rxic); return phy_ethtool_gset(phydev, cmd); } @@ -279,6 +284,8 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) { struct gfar_private *priv = netdev_priv(dev); + struct gfar_priv_rx_q *rx_queue = NULL; + struct gfar_priv_tx_q *tx_queue = NULL; unsigned long rxtime; unsigned long rxcount; unsigned long txtime; @@ -290,10 +297,13 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals if (NULL == priv->phydev) return -ENODEV; - rxtime = get_ictt_value(priv->rxic); - rxcount = get_icft_value(priv->rxic); - txtime = get_ictt_value(priv->txic); - txcount = get_icft_value(priv->txic); + rx_queue = priv->rx_queue; + tx_queue = priv->tx_queue; + + rxtime = get_ictt_value(rx_queue->rxic); + rxcount = get_icft_value(rx_queue->rxic); + txtime = get_ictt_value(tx_queue->txic); + txcount = get_icft_value(tx_queue->txic); cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime); cvals->rx_max_coalesced_frames = rxcount; @@ -339,16 +349,21 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) { struct gfar_private *priv = netdev_priv(dev); + struct gfar_priv_tx_q *tx_queue = NULL; + struct gfar_priv_rx_q *rx_queue = NULL; if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE)) return -EOPNOTSUPP; + tx_queue = priv->tx_queue; + rx_queue = priv->rx_queue; + /* Set up rx coalescing */ if ((cvals->rx_coalesce_usecs == 0) || (cvals->rx_max_coalesced_frames == 0)) - priv->rxcoalescing = 0; + rx_queue->rxcoalescing = 0; else - priv->rxcoalescing = 1; + rx_queue->rxcoalescing = 1; if (NULL == priv->phydev) return -ENODEV; @@ -366,15 +381,15 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals return -EINVAL; } - priv->rxic = mk_ic_value(cvals->rx_max_coalesced_frames, + rx_queue->rxic = mk_ic_value(cvals->rx_max_coalesced_frames, gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs)); /* Set up tx coalescing */ if ((cvals->tx_coalesce_usecs == 0) || (cvals->tx_max_coalesced_frames == 0)) - priv->txcoalescing = 0; + tx_queue->txcoalescing = 0; else - priv->txcoalescing = 1; + tx_queue->txcoalescing = 1; /* Check the bounds of the values */ if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) { @@ -389,16 +404,16 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals return -EINVAL; } - priv->txic = mk_ic_value(cvals->tx_max_coalesced_frames, + tx_queue->txic = mk_ic_value(cvals->tx_max_coalesced_frames, gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs)); gfar_write(&priv->regs->rxic, 0); - if (priv->rxcoalescing) - gfar_write(&priv->regs->rxic, priv->rxic); + if (rx_queue->rxcoalescing) + gfar_write(&priv->regs->rxic, rx_queue->rxic); gfar_write(&priv->regs->txic, 0); - if (priv->txcoalescing) - gfar_write(&priv->regs->txic, priv->txic); + if (tx_queue->txcoalescing) + gfar_write(&priv->regs->txic, tx_queue->txic); return 0; } @@ -409,6 +424,11 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) { struct gfar_private *priv = netdev_priv(dev); + struct gfar_priv_tx_q *tx_queue = NULL; + struct gfar_priv_rx_q *rx_queue = NULL; + + tx_queue = priv->tx_queue; + rx_queue = priv->rx_queue; rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE; rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE; @@ -418,10 +438,10 @@ static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rv /* Values changeable by the user. The valid values are * in the range 1 to the "*_max_pending" counterpart above. */ - rvals->rx_pending = priv->rx_ring_size; - rvals->rx_mini_pending = priv->rx_ring_size; - rvals->rx_jumbo_pending = priv->rx_ring_size; - rvals->tx_pending = priv->tx_ring_size; + rvals->rx_pending = rx_queue->rx_ring_size; + rvals->rx_mini_pending = rx_queue->rx_ring_size; + rvals->rx_jumbo_pending = rx_queue->rx_ring_size; + rvals->tx_pending = tx_queue->tx_ring_size; } /* Change the current ring parameters, stopping the controller if @@ -431,6 +451,8 @@ static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rv static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) { struct gfar_private *priv = netdev_priv(dev); + struct gfar_priv_tx_q *tx_queue = NULL; + struct gfar_priv_rx_q *rx_queue = NULL; int err = 0; if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE) @@ -451,29 +473,32 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva return -EINVAL; } + tx_queue = priv->tx_queue; + rx_queue = priv->rx_queue; + if (dev->flags & IFF_UP) { unsigned long flags; /* Halt TX and RX, and process the frames which * have already been received */ - spin_lock_irqsave(&priv->txlock, flags); - spin_lock(&priv->rxlock); + spin_lock_irqsave(&tx_queue->txlock, flags); + spin_lock(&rx_queue->rxlock); gfar_halt(dev); - spin_unlock(&priv->rxlock); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock(&rx_queue->rxlock); + spin_unlock_irqrestore(&tx_queue->txlock, flags); - gfar_clean_rx_ring(dev, priv->rx_ring_size); + gfar_clean_rx_ring(rx_queue, rx_queue->rx_ring_size); /* Now we take down the rings to rebuild them */ stop_gfar(dev); } /* Change the size */ - priv->rx_ring_size = rvals->rx_pending; - priv->tx_ring_size = rvals->tx_pending; - priv->num_txbdfree = priv->tx_ring_size; + rx_queue->rx_ring_size = rvals->rx_pending; + tx_queue->tx_ring_size = rvals->tx_pending; + tx_queue->num_txbdfree = tx_queue->tx_ring_size; /* Rebuild the rings with the new size */ if (dev->flags & IFF_UP) { @@ -486,24 +511,29 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) { struct gfar_private *priv = netdev_priv(dev); + struct gfar_priv_rx_q *rx_queue = NULL; + struct gfar_priv_tx_q *tx_queue = NULL; unsigned long flags; int err = 0; if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) return -EOPNOTSUPP; + tx_queue = priv->tx_queue; + rx_queue = priv->rx_queue; + if (dev->flags & IFF_UP) { /* Halt TX and RX, and process the frames which * have already been received */ - spin_lock_irqsave(&priv->txlock, flags); - spin_lock(&priv->rxlock); + spin_lock_irqsave(&tx_queue->txlock, flags); + spin_lock(&rx_queue->rxlock); gfar_halt(dev); - spin_unlock(&priv->rxlock); - spin_unlock_irqrestore(&priv->txlock, flags); + spin_unlock(&rx_queue->rxlock); + spin_unlock_irqrestore(&tx_queue->txlock, flags); - gfar_clean_rx_ring(dev, priv->rx_ring_size); + gfar_clean_rx_ring(rx_queue, rx_queue->rx_ring_size); /* Now we take down the rings to rebuild them */ stop_gfar(dev); |