diff options
author | Dai Haruki <dai.haruki@freescale.com> | 2008-12-16 18:29:52 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-16 18:29:52 -0500 |
commit | b46a8454cd304b5376ba00d3457a612720e47269 (patch) | |
tree | cf6a119d3903b519b9540585684ba1eb2ef130d6 /drivers/net | |
parent | b31a1d8b41513b96e9c7ec2f68c5734cef0b26a4 (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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/gianfar.c | 24 | ||||
-rw-r--r-- | drivers/net/gianfar.h | 12 | ||||
-rw-r--r-- | drivers/net/gianfar_ethtool.c | 42 |
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(®s->txic, 0); | ||
1063 | if (priv->txcoalescing) | 1062 | if (priv->txcoalescing) |
1064 | gfar_write(®s->txic, | 1063 | gfar_write(®s->txic, priv->txic); |
1065 | mk_ic_value(priv->txcount, priv->txtime)); | ||
1066 | else | ||
1067 | gfar_write(®s->txic, 0); | ||
1068 | 1064 | ||
1065 | gfar_write(®s->rxic, 0); | ||
1069 | if (priv->rxcoalescing) | 1066 | if (priv->rxcoalescing) |
1070 | gfar_write(®s->rxic, | 1067 | gfar_write(®s->rxic, priv->rxic); |
1071 | mk_ic_value(priv->rxcount, priv->rxtime)); | ||
1072 | else | ||
1073 | gfar_write(®s->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 | |||
279 | static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) | 279 | static 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 | } |