aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDai Haruki <dai.haruki@freescale.com>2008-12-16 18:29:52 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-16 18:29:52 -0500
commitb46a8454cd304b5376ba00d3457a612720e47269 (patch)
treecf6a119d3903b519b9540585684ba1eb2ef130d6
parentb31a1d8b41513b96e9c7ec2f68c5734cef0b26a4 (diff)
gianfar: Optimize interrupt coalescing configuration
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>
-rw-r--r--drivers/net/gianfar.c24
-rw-r--r--drivers/net/gianfar.h12
-rw-r--r--drivers/net/gianfar_ethtool.c42
3 files changed, 40 insertions, 38 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 7398704c4b55..5100f75238af 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -428,11 +428,9 @@ static int gfar_probe(struct of_device *ofdev,
428 priv->rx_ring_size = DEFAULT_RX_RING_SIZE; 428 priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
429 429
430 priv->txcoalescing = DEFAULT_TX_COALESCE; 430 priv->txcoalescing = DEFAULT_TX_COALESCE;
431 priv->txcount = DEFAULT_TXCOUNT; 431 priv->txic = DEFAULT_TXIC;
432 priv->txtime = DEFAULT_TXTIME;
433 priv->rxcoalescing = DEFAULT_RX_COALESCE; 432 priv->rxcoalescing = DEFAULT_RX_COALESCE;
434 priv->rxcount = DEFAULT_RXCOUNT; 433 priv->rxic = DEFAULT_RXIC;
435 priv->rxtime = DEFAULT_RXTIME;
436 434
437 /* Enable most messages by default */ 435 /* Enable most messages by default */
438 priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; 436 priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
@@ -1060,17 +1058,13 @@ int startup_gfar(struct net_device *dev)
1060 phy_start(priv->phydev); 1058 phy_start(priv->phydev);
1061 1059
1062 /* Configure the coalescing support */ 1060 /* Configure the coalescing support */
1061 gfar_write(&regs->txic, 0);
1063 if (priv->txcoalescing) 1062 if (priv->txcoalescing)
1064 gfar_write(&regs->txic, 1063 gfar_write(&regs->txic, priv->txic);
1065 mk_ic_value(priv->txcount, priv->txtime));
1066 else
1067 gfar_write(&regs->txic, 0);
1068 1064
1065 gfar_write(&regs->rxic, 0);
1069 if (priv->rxcoalescing) 1066 if (priv->rxcoalescing)
1070 gfar_write(&regs->rxic, 1067 gfar_write(&regs->rxic, priv->rxic);
1071 mk_ic_value(priv->rxcount, priv->rxtime));
1072 else
1073 gfar_write(&regs->rxic, 0);
1074 1068
1075 if (priv->rx_csum_enable) 1069 if (priv->rx_csum_enable)
1076 rctrl |= RCTRL_CHECKSUMMING; 1070 rctrl |= RCTRL_CHECKSUMMING;
@@ -1538,8 +1532,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id)
1538 /* Otherwise, clear it */ 1532 /* Otherwise, clear it */
1539 if (likely(priv->txcoalescing)) { 1533 if (likely(priv->txcoalescing)) {
1540 gfar_write(&priv->regs->txic, 0); 1534 gfar_write(&priv->regs->txic, 0);
1541 gfar_write(&priv->regs->txic, 1535 gfar_write(&priv->regs->txic, priv->txic);
1542 mk_ic_value(priv->txcount, priv->txtime));
1543 } 1536 }
1544 1537
1545 spin_unlock(&priv->txlock); 1538 spin_unlock(&priv->txlock);
@@ -1825,8 +1818,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
1825 /* Otherwise, clear it */ 1818 /* Otherwise, clear it */
1826 if (likely(priv->rxcoalescing)) { 1819 if (likely(priv->rxcoalescing)) {
1827 gfar_write(&priv->regs->rxic, 0); 1820 gfar_write(&priv->regs->rxic, 0);
1828 gfar_write(&priv->regs->rxic, 1821 gfar_write(&priv->regs->rxic, priv->rxic);
1829 mk_ic_value(priv->rxcount, priv->rxtime));
1830 } 1822 }
1831 } 1823 }
1832 1824
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index ca7f0a6a68c5..449f508a5640 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -189,6 +189,12 @@ extern const char gfar_driver_version[];
189#define mk_ic_value(count, time) (IC_ICEN | \ 189#define mk_ic_value(count, time) (IC_ICEN | \
190 mk_ic_icft(count) | \ 190 mk_ic_icft(count) | \
191 mk_ic_ictt(time)) 191 mk_ic_ictt(time))
192#define get_icft_value(ic) (((unsigned long)ic & IC_ICFT_MASK) >> \
193 IC_ICFT_SHIFT)
194#define get_ictt_value(ic) ((unsigned long)ic & IC_ICTT_MASK)
195
196#define DEFAULT_TXIC mk_ic_value(DEFAULT_TXCOUNT, DEFAULT_TXTIME)
197#define DEFAULT_RXIC mk_ic_value(DEFAULT_RXCOUNT, DEFAULT_RXTIME)
192 198
193#define RCTRL_PAL_MASK 0x001f0000 199#define RCTRL_PAL_MASK 0x001f0000
194#define RCTRL_VLEX 0x00002000 200#define RCTRL_VLEX 0x00002000
@@ -694,8 +700,7 @@ struct gfar_private {
694 700
695 /* Configuration info for the coalescing features */ 701 /* Configuration info for the coalescing features */
696 unsigned char txcoalescing; 702 unsigned char txcoalescing;
697 unsigned short txcount; 703 unsigned long txic;
698 unsigned short txtime;
699 704
700 /* Buffer descriptor pointers */ 705 /* Buffer descriptor pointers */
701 struct txbd8 *tx_bd_base; /* First tx buffer descriptor */ 706 struct txbd8 *tx_bd_base; /* First tx buffer descriptor */
@@ -717,8 +722,7 @@ struct gfar_private {
717 722
718 /* RX Coalescing values */ 723 /* RX Coalescing values */
719 unsigned char rxcoalescing; 724 unsigned char rxcoalescing;
720 unsigned short rxcount; 725 unsigned long rxic;
721 unsigned short rxtime;
722 726
723 struct rxbd8 *rx_bd_base; /* First Rx buffers */ 727 struct rxbd8 *rx_bd_base; /* First Rx buffers */
724 struct rxbd8 *cur_rx; /* Next free rx ring entry */ 728 struct rxbd8 *cur_rx; /* Next free rx ring entry */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 53944b120a3d..c111c532f7b3 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -201,8 +201,8 @@ static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
201 if (NULL == phydev) 201 if (NULL == phydev)
202 return -ENODEV; 202 return -ENODEV;
203 203
204 cmd->maxtxpkt = priv->txcount; 204 cmd->maxtxpkt = get_icft_value(priv->txic);
205 cmd->maxrxpkt = priv->rxcount; 205 cmd->maxrxpkt = get_icft_value(priv->rxic);
206 206
207 return phy_ethtool_gset(phydev, cmd); 207 return phy_ethtool_gset(phydev, cmd);
208} 208}
@@ -279,6 +279,10 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
279static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) 279static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
280{ 280{
281 struct gfar_private *priv = netdev_priv(dev); 281 struct gfar_private *priv = netdev_priv(dev);
282 unsigned long rxtime;
283 unsigned long rxcount;
284 unsigned long txtime;
285 unsigned long txcount;
282 286
283 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE)) 287 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
284 return -EOPNOTSUPP; 288 return -EOPNOTSUPP;
@@ -286,11 +290,15 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
286 if (NULL == priv->phydev) 290 if (NULL == priv->phydev)
287 return -ENODEV; 291 return -ENODEV;
288 292
289 cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime); 293 rxtime = get_ictt_value(priv->rxic);
290 cvals->rx_max_coalesced_frames = priv->rxcount; 294 rxcount = get_icft_value(priv->rxic);
295 txtime = get_ictt_value(priv->txic);
296 txcount = get_icft_value(priv->txic);;
297 cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime);
298 cvals->rx_max_coalesced_frames = rxcount;
291 299
292 cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, priv->txtime); 300 cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, txtime);
293 cvals->tx_max_coalesced_frames = priv->txcount; 301 cvals->tx_max_coalesced_frames = txcount;
294 302
295 cvals->use_adaptive_rx_coalesce = 0; 303 cvals->use_adaptive_rx_coalesce = 0;
296 cvals->use_adaptive_tx_coalesce = 0; 304 cvals->use_adaptive_tx_coalesce = 0;
@@ -358,8 +366,9 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
358 return -EINVAL; 366 return -EINVAL;
359 } 367 }
360 368
361 priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs); 369 priv->rxic = mk_ic_value(
362 priv->rxcount = cvals->rx_max_coalesced_frames; 370 gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs),
371 cvals->rx_max_coalesced_frames);
363 372
364 /* Set up tx coalescing */ 373 /* Set up tx coalescing */
365 if ((cvals->tx_coalesce_usecs == 0) || 374 if ((cvals->tx_coalesce_usecs == 0) ||
@@ -381,20 +390,17 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
381 return -EINVAL; 390 return -EINVAL;
382 } 391 }
383 392
384 priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs); 393 priv->txic = mk_ic_value(
385 priv->txcount = cvals->tx_max_coalesced_frames; 394 gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs),
395 cvals->tx_max_coalesced_frames);
386 396
397 gfar_write(&priv->regs->rxic, 0);
387 if (priv->rxcoalescing) 398 if (priv->rxcoalescing)
388 gfar_write(&priv->regs->rxic, 399 gfar_write(&priv->regs->rxic, priv->rxic);
389 mk_ic_value(priv->rxcount, priv->rxtime));
390 else
391 gfar_write(&priv->regs->rxic, 0);
392 400
401 gfar_write(&priv->regs->txic, 0);
393 if (priv->txcoalescing) 402 if (priv->txcoalescing)
394 gfar_write(&priv->regs->txic, 403 gfar_write(&priv->regs->txic, priv->txic);
395 mk_ic_value(priv->txcount, priv->txtime));
396 else
397 gfar_write(&priv->regs->txic, 0);
398 404
399 return 0; 405 return 0;
400} 406}