gianfar: Optimize interrupt coalescing configuration
authorDai Haruki <dai.haruki@freescale.com>
Tue, 16 Dec 2008 23:29:52 +0000 (15:29 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 16 Dec 2008 23:29:52 +0000 (15:29 -0800)
Store the interrupt coalescing values in the form in which they will be
written to the interrupt coalescing registers.  This puts a little overhead
into the ethtool configuration, and takes it out of the interrupt handler

Signed-off-by: Dai Haruki <dai.haruki@freescale.com>
Acked-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/gianfar_ethtool.c

index 7398704c4b55acfa5dc48771598744ddc57cfa4a..5100f75238afc433363e6f81c09c19db5e56b137 100644 (file)
@@ -428,11 +428,9 @@ static int gfar_probe(struct of_device *ofdev,
        priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
 
        priv->txcoalescing = DEFAULT_TX_COALESCE;
-       priv->txcount = DEFAULT_TXCOUNT;
-       priv->txtime = DEFAULT_TXTIME;
+       priv->txic = DEFAULT_TXIC;
        priv->rxcoalescing = DEFAULT_RX_COALESCE;
-       priv->rxcount = DEFAULT_RXCOUNT;
-       priv->rxtime = DEFAULT_RXTIME;
+       priv->rxic = DEFAULT_RXIC;
 
        /* Enable most messages by default */
        priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
@@ -1060,17 +1058,13 @@ int startup_gfar(struct net_device *dev)
        phy_start(priv->phydev);
 
        /* Configure the coalescing support */
+       gfar_write(&regs->txic, 0);
        if (priv->txcoalescing)
-               gfar_write(&regs->txic,
-                          mk_ic_value(priv->txcount, priv->txtime));
-       else
-               gfar_write(&regs->txic, 0);
+               gfar_write(&regs->txic, priv->txic);
 
+       gfar_write(&regs->rxic, 0);
        if (priv->rxcoalescing)
-               gfar_write(&regs->rxic,
-                          mk_ic_value(priv->rxcount, priv->rxtime));
-       else
-               gfar_write(&regs->rxic, 0);
+               gfar_write(&regs->rxic, priv->rxic);
 
        if (priv->rx_csum_enable)
                rctrl |= RCTRL_CHECKSUMMING;
@@ -1538,8 +1532,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id)
        /* Otherwise, clear it */
        if (likely(priv->txcoalescing)) {
                gfar_write(&priv->regs->txic, 0);
-               gfar_write(&priv->regs->txic,
-                          mk_ic_value(priv->txcount, priv->txtime));
+               gfar_write(&priv->regs->txic, priv->txic);
        }
 
        spin_unlock(&priv->txlock);
@@ -1825,8 +1818,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
                /* Otherwise, clear it */
                if (likely(priv->rxcoalescing)) {
                        gfar_write(&priv->regs->rxic, 0);
-                       gfar_write(&priv->regs->rxic,
-                                  mk_ic_value(priv->rxcount, priv->rxtime));
+                       gfar_write(&priv->regs->rxic, priv->rxic);
                }
        }
 
index ca7f0a6a68c59398f22caaf6f6525df29952eba4..449f508a564031a2cc510838890ec931877fd09f 100644 (file)
@@ -189,6 +189,12 @@ extern const char gfar_driver_version[];
 #define mk_ic_value(count, time) (IC_ICEN | \
                                mk_ic_icft(count) | \
                                mk_ic_ictt(time))
+#define get_icft_value(ic)     (((unsigned long)ic & IC_ICFT_MASK) >> \
+                                IC_ICFT_SHIFT)
+#define get_ictt_value(ic)     ((unsigned long)ic & IC_ICTT_MASK)
+
+#define DEFAULT_TXIC mk_ic_value(DEFAULT_TXCOUNT, DEFAULT_TXTIME)
+#define DEFAULT_RXIC mk_ic_value(DEFAULT_RXCOUNT, DEFAULT_RXTIME)
 
 #define RCTRL_PAL_MASK         0x001f0000
 #define RCTRL_VLEX             0x00002000
@@ -694,8 +700,7 @@ struct gfar_private {
 
        /* Configuration info for the coalescing features */
        unsigned char txcoalescing;
-       unsigned short txcount;
-       unsigned short txtime;
+       unsigned long txic;
 
        /* Buffer descriptor pointers */
        struct txbd8 *tx_bd_base;       /* First tx buffer descriptor */
@@ -717,8 +722,7 @@ struct gfar_private {
 
        /* RX Coalescing values */
        unsigned char rxcoalescing;
-       unsigned short rxcount;
-       unsigned short rxtime;
+       unsigned long rxic;
 
        struct rxbd8 *rx_bd_base;       /* First Rx buffers */
        struct rxbd8 *cur_rx;           /* Next free rx ring entry */
index 53944b120a3db85a19de72e99c078964355ffd65..c111c532f7b3c7976316140705c8144f26bd4c5c 100644 (file)
@@ -201,8 +201,8 @@ static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
        if (NULL == phydev)
                return -ENODEV;
 
-       cmd->maxtxpkt = priv->txcount;
-       cmd->maxrxpkt = priv->rxcount;
+       cmd->maxtxpkt = get_icft_value(priv->txic);
+       cmd->maxrxpkt = get_icft_value(priv->rxic);
 
        return phy_ethtool_gset(phydev, cmd);
 }
@@ -279,6 +279,10 @@ 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);
+       unsigned long rxtime;
+       unsigned long rxcount;
+       unsigned long txtime;
+       unsigned long txcount;
 
        if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
                return -EOPNOTSUPP;
@@ -286,11 +290,15 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
        if (NULL == priv->phydev)
                return -ENODEV;
 
-       cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
-       cvals->rx_max_coalesced_frames = priv->rxcount;
+       rxtime  = get_ictt_value(priv->rxic);
+       rxcount = get_icft_value(priv->rxic);
+       txtime  = get_ictt_value(priv->txic);
+       txcount = get_icft_value(priv->txic);;
+       cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime);
+       cvals->rx_max_coalesced_frames = rxcount;
 
-       cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, priv->txtime);
-       cvals->tx_max_coalesced_frames = priv->txcount;
+       cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, txtime);
+       cvals->tx_max_coalesced_frames = txcount;
 
        cvals->use_adaptive_rx_coalesce = 0;
        cvals->use_adaptive_tx_coalesce = 0;
@@ -358,8 +366,9 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
                return -EINVAL;
        }
 
-       priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
-       priv->rxcount = cvals->rx_max_coalesced_frames;
+       priv->rxic = mk_ic_value(
+               gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs),
+               cvals->rx_max_coalesced_frames);
 
        /* Set up tx coalescing */
        if ((cvals->tx_coalesce_usecs == 0) ||
@@ -381,20 +390,17 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
                return -EINVAL;
        }
 
-       priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
-       priv->txcount = cvals->tx_max_coalesced_frames;
+       priv->txic = mk_ic_value(
+               gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs),
+               cvals->tx_max_coalesced_frames);
 
+       gfar_write(&priv->regs->rxic, 0);
        if (priv->rxcoalescing)
-               gfar_write(&priv->regs->rxic,
-                          mk_ic_value(priv->rxcount, priv->rxtime));
-       else
-               gfar_write(&priv->regs->rxic, 0);
+               gfar_write(&priv->regs->rxic, priv->rxic);
 
+       gfar_write(&priv->regs->txic, 0);
        if (priv->txcoalescing)
-               gfar_write(&priv->regs->txic,
-                          mk_ic_value(priv->txcount, priv->txtime));
-       else
-               gfar_write(&priv->regs->txic, 0);
+               gfar_write(&priv->regs->txic, priv->txic);
 
        return 0;
 }