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>
This commit is contained in:
committed by
David S. Miller
parent
b31a1d8b41
commit
b46a8454cd
@@ -428,11 +428,9 @@ static int gfar_probe(struct of_device *ofdev,
|
|||||||
priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
|
priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
|
||||||
|
|
||||||
priv->txcoalescing = DEFAULT_TX_COALESCE;
|
priv->txcoalescing = DEFAULT_TX_COALESCE;
|
||||||
priv->txcount = DEFAULT_TXCOUNT;
|
priv->txic = DEFAULT_TXIC;
|
||||||
priv->txtime = DEFAULT_TXTIME;
|
|
||||||
priv->rxcoalescing = DEFAULT_RX_COALESCE;
|
priv->rxcoalescing = DEFAULT_RX_COALESCE;
|
||||||
priv->rxcount = DEFAULT_RXCOUNT;
|
priv->rxic = DEFAULT_RXIC;
|
||||||
priv->rxtime = DEFAULT_RXTIME;
|
|
||||||
|
|
||||||
/* Enable most messages by default */
|
/* Enable most messages by default */
|
||||||
priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
|
priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
|
||||||
@@ -1060,17 +1058,13 @@ int startup_gfar(struct net_device *dev)
|
|||||||
phy_start(priv->phydev);
|
phy_start(priv->phydev);
|
||||||
|
|
||||||
/* Configure the coalescing support */
|
/* Configure the coalescing support */
|
||||||
|
gfar_write(®s->txic, 0);
|
||||||
if (priv->txcoalescing)
|
if (priv->txcoalescing)
|
||||||
gfar_write(®s->txic,
|
gfar_write(®s->txic, priv->txic);
|
||||||
mk_ic_value(priv->txcount, priv->txtime));
|
|
||||||
else
|
|
||||||
gfar_write(®s->txic, 0);
|
|
||||||
|
|
||||||
|
gfar_write(®s->rxic, 0);
|
||||||
if (priv->rxcoalescing)
|
if (priv->rxcoalescing)
|
||||||
gfar_write(®s->rxic,
|
gfar_write(®s->rxic, priv->rxic);
|
||||||
mk_ic_value(priv->rxcount, priv->rxtime));
|
|
||||||
else
|
|
||||||
gfar_write(®s->rxic, 0);
|
|
||||||
|
|
||||||
if (priv->rx_csum_enable)
|
if (priv->rx_csum_enable)
|
||||||
rctrl |= RCTRL_CHECKSUMMING;
|
rctrl |= RCTRL_CHECKSUMMING;
|
||||||
@@ -1538,8 +1532,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id)
|
|||||||
/* Otherwise, clear it */
|
/* Otherwise, clear it */
|
||||||
if (likely(priv->txcoalescing)) {
|
if (likely(priv->txcoalescing)) {
|
||||||
gfar_write(&priv->regs->txic, 0);
|
gfar_write(&priv->regs->txic, 0);
|
||||||
gfar_write(&priv->regs->txic,
|
gfar_write(&priv->regs->txic, priv->txic);
|
||||||
mk_ic_value(priv->txcount, priv->txtime));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&priv->txlock);
|
spin_unlock(&priv->txlock);
|
||||||
@@ -1825,8 +1818,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
|
|||||||
/* Otherwise, clear it */
|
/* Otherwise, clear it */
|
||||||
if (likely(priv->rxcoalescing)) {
|
if (likely(priv->rxcoalescing)) {
|
||||||
gfar_write(&priv->regs->rxic, 0);
|
gfar_write(&priv->regs->rxic, 0);
|
||||||
gfar_write(&priv->regs->rxic,
|
gfar_write(&priv->regs->rxic, priv->rxic);
|
||||||
mk_ic_value(priv->rxcount, priv->rxtime));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -189,6 +189,12 @@ extern const char gfar_driver_version[];
|
|||||||
#define mk_ic_value(count, time) (IC_ICEN | \
|
#define mk_ic_value(count, time) (IC_ICEN | \
|
||||||
mk_ic_icft(count) | \
|
mk_ic_icft(count) | \
|
||||||
mk_ic_ictt(time))
|
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_PAL_MASK 0x001f0000
|
||||||
#define RCTRL_VLEX 0x00002000
|
#define RCTRL_VLEX 0x00002000
|
||||||
@@ -694,8 +700,7 @@ struct gfar_private {
|
|||||||
|
|
||||||
/* Configuration info for the coalescing features */
|
/* Configuration info for the coalescing features */
|
||||||
unsigned char txcoalescing;
|
unsigned char txcoalescing;
|
||||||
unsigned short txcount;
|
unsigned long txic;
|
||||||
unsigned short txtime;
|
|
||||||
|
|
||||||
/* Buffer descriptor pointers */
|
/* Buffer descriptor pointers */
|
||||||
struct txbd8 *tx_bd_base; /* First tx buffer descriptor */
|
struct txbd8 *tx_bd_base; /* First tx buffer descriptor */
|
||||||
@@ -717,8 +722,7 @@ struct gfar_private {
|
|||||||
|
|
||||||
/* RX Coalescing values */
|
/* RX Coalescing values */
|
||||||
unsigned char rxcoalescing;
|
unsigned char rxcoalescing;
|
||||||
unsigned short rxcount;
|
unsigned long rxic;
|
||||||
unsigned short rxtime;
|
|
||||||
|
|
||||||
struct rxbd8 *rx_bd_base; /* First Rx buffers */
|
struct rxbd8 *rx_bd_base; /* First Rx buffers */
|
||||||
struct rxbd8 *cur_rx; /* Next free rx ring entry */
|
struct rxbd8 *cur_rx; /* Next free rx ring entry */
|
||||||
|
@@ -201,8 +201,8 @@ static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||||||
if (NULL == phydev)
|
if (NULL == phydev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
cmd->maxtxpkt = priv->txcount;
|
cmd->maxtxpkt = get_icft_value(priv->txic);
|
||||||
cmd->maxrxpkt = priv->rxcount;
|
cmd->maxrxpkt = get_icft_value(priv->rxic);
|
||||||
|
|
||||||
return phy_ethtool_gset(phydev, cmd);
|
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)
|
static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
|
||||||
{
|
{
|
||||||
struct gfar_private *priv = netdev_priv(dev);
|
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))
|
if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@@ -286,11 +290,15 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
|
|||||||
if (NULL == priv->phydev)
|
if (NULL == priv->phydev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
|
rxtime = get_ictt_value(priv->rxic);
|
||||||
cvals->rx_max_coalesced_frames = priv->rxcount;
|
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_coalesce_usecs = gfar_ticks2usecs(priv, txtime);
|
||||||
cvals->tx_max_coalesced_frames = priv->txcount;
|
cvals->tx_max_coalesced_frames = txcount;
|
||||||
|
|
||||||
cvals->use_adaptive_rx_coalesce = 0;
|
cvals->use_adaptive_rx_coalesce = 0;
|
||||||
cvals->use_adaptive_tx_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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
|
priv->rxic = mk_ic_value(
|
||||||
priv->rxcount = cvals->rx_max_coalesced_frames;
|
gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs),
|
||||||
|
cvals->rx_max_coalesced_frames);
|
||||||
|
|
||||||
/* Set up tx coalescing */
|
/* Set up tx coalescing */
|
||||||
if ((cvals->tx_coalesce_usecs == 0) ||
|
if ((cvals->tx_coalesce_usecs == 0) ||
|
||||||
@@ -381,20 +390,17 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
|
priv->txic = mk_ic_value(
|
||||||
priv->txcount = cvals->tx_max_coalesced_frames;
|
gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs),
|
||||||
|
cvals->tx_max_coalesced_frames);
|
||||||
|
|
||||||
|
gfar_write(&priv->regs->rxic, 0);
|
||||||
if (priv->rxcoalescing)
|
if (priv->rxcoalescing)
|
||||||
gfar_write(&priv->regs->rxic,
|
gfar_write(&priv->regs->rxic, priv->rxic);
|
||||||
mk_ic_value(priv->rxcount, priv->rxtime));
|
|
||||||
else
|
|
||||||
gfar_write(&priv->regs->rxic, 0);
|
|
||||||
|
|
||||||
|
gfar_write(&priv->regs->txic, 0);
|
||||||
if (priv->txcoalescing)
|
if (priv->txcoalescing)
|
||||||
gfar_write(&priv->regs->txic,
|
gfar_write(&priv->regs->txic, priv->txic);
|
||||||
mk_ic_value(priv->txcount, priv->txtime));
|
|
||||||
else
|
|
||||||
gfar_write(&priv->regs->txic, 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user