Commit 18775aa8 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

bnxt_en: Reorganize the coalescing parameters.

The current IRQ coalescing logic is a little messy.  The ethtool
parameters are mapped to hardware parameters in a way that is difficult
to understand.  The first step is to better organize the parameters
by adding the new structure bnxt_coal.  The structure is used by both
the RX and TX sets of coalescing parameters.

Adjust the default coal_ticks to 14 us and 28 us for RX and TX.
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 49f7972f
...@@ -4569,34 +4569,31 @@ int bnxt_hwrm_set_coal(struct bnxt *bp) ...@@ -4569,34 +4569,31 @@ int bnxt_hwrm_set_coal(struct bnxt *bp)
/* Each rx completion (2 records) should be DMAed immediately. /* Each rx completion (2 records) should be DMAed immediately.
* DMA 1/4 of the completion buffers at a time. * DMA 1/4 of the completion buffers at a time.
*/ */
max_buf = min_t(u16, bp->rx_coal_bufs / 4, 2); max_buf = min_t(u16, bp->rx_coal.coal_bufs / 4, 2);
/* max_buf must not be zero */ /* max_buf must not be zero */
max_buf = clamp_t(u16, max_buf, 1, 63); max_buf = clamp_t(u16, max_buf, 1, 63);
max_buf_irq = clamp_t(u16, bp->rx_coal_bufs_irq, 1, 63); max_buf_irq = clamp_t(u16, bp->rx_coal.coal_bufs_irq, 1, 63);
buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal_ticks); buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal.coal_ticks);
/* buf timer set to 1/4 of interrupt timer */ /* buf timer set to 1/4 of interrupt timer */
buf_tmr = max_t(u16, buf_tmr / 4, 1); buf_tmr = max_t(u16, buf_tmr / 4, 1);
buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal_ticks_irq); buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal.coal_ticks_irq);
buf_tmr_irq = max_t(u16, buf_tmr_irq, 1); buf_tmr_irq = max_t(u16, buf_tmr_irq, 1);
flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET; flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;
/* RING_IDLE generates more IRQs for lower latency. Enable it only if (bp->rx_coal.coal_ticks < bp->rx_coal.idle_thresh)
* if coal_ticks is less than 25 us.
*/
if (bp->rx_coal_ticks < 25)
flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE; flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE;
bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf, bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf,
buf_tmr_irq << 16 | buf_tmr, flags, &req_rx); buf_tmr_irq << 16 | buf_tmr, flags, &req_rx);
/* max_buf must not be zero */ /* max_buf must not be zero */
max_buf = clamp_t(u16, bp->tx_coal_bufs, 1, 63); max_buf = clamp_t(u16, bp->tx_coal.coal_bufs, 1, 63);
max_buf_irq = clamp_t(u16, bp->tx_coal_bufs_irq, 1, 63); max_buf_irq = clamp_t(u16, bp->tx_coal.coal_bufs_irq, 1, 63);
buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal_ticks); buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal.coal_ticks);
/* buf timer set to 1/4 of interrupt timer */ /* buf timer set to 1/4 of interrupt timer */
buf_tmr = max_t(u16, buf_tmr / 4, 1); buf_tmr = max_t(u16, buf_tmr / 4, 1);
buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal_ticks_irq); buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal.coal_ticks_irq);
buf_tmr_irq = max_t(u16, buf_tmr_irq, 1); buf_tmr_irq = max_t(u16, buf_tmr_irq, 1);
flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET; flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;
...@@ -7146,6 +7143,32 @@ static void bnxt_cleanup_pci(struct bnxt *bp) ...@@ -7146,6 +7143,32 @@ static void bnxt_cleanup_pci(struct bnxt *bp)
pci_disable_device(bp->pdev); pci_disable_device(bp->pdev);
} }
static void bnxt_init_dflt_coal(struct bnxt *bp)
{
struct bnxt_coal *coal;
/* Tick values in micro seconds.
* 1 coal_buf x bufs_per_record = 1 completion record.
*/
coal = &bp->rx_coal;
coal->coal_ticks = 14;
coal->coal_bufs = 30;
coal->coal_ticks_irq = 1;
coal->coal_bufs_irq = 2;
coal->idle_thresh = 25;
coal->bufs_per_record = 2;
coal->budget = 64; /* NAPI budget */
coal = &bp->tx_coal;
coal->coal_ticks = 28;
coal->coal_bufs = 30;
coal->coal_ticks_irq = 2;
coal->coal_bufs_irq = 2;
coal->bufs_per_record = 1;
bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS;
}
static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
{ {
int rc; int rc;
...@@ -7214,18 +7237,7 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) ...@@ -7214,18 +7237,7 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->rx_ring_size = BNXT_DEFAULT_RX_RING_SIZE; bp->rx_ring_size = BNXT_DEFAULT_RX_RING_SIZE;
bp->tx_ring_size = BNXT_DEFAULT_TX_RING_SIZE; bp->tx_ring_size = BNXT_DEFAULT_TX_RING_SIZE;
/* tick values in micro seconds */ bnxt_init_dflt_coal(bp);
bp->rx_coal_ticks = 12;
bp->rx_coal_bufs = 30;
bp->rx_coal_ticks_irq = 1;
bp->rx_coal_bufs_irq = 2;
bp->tx_coal_ticks = 25;
bp->tx_coal_bufs = 30;
bp->tx_coal_ticks_irq = 2;
bp->tx_coal_bufs_irq = 2;
bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS;
setup_timer(&bp->timer, bnxt_timer, (unsigned long)bp); setup_timer(&bp->timer, bnxt_timer, (unsigned long)bp);
bp->current_interval = BNXT_TIMER_INTERVAL; bp->current_interval = BNXT_TIMER_INTERVAL;
......
...@@ -944,6 +944,17 @@ struct bnxt_test_info { ...@@ -944,6 +944,17 @@ struct bnxt_test_info {
#define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014 #define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014
#define BNXT_CAG_REG_BASE 0x300000 #define BNXT_CAG_REG_BASE 0x300000
struct bnxt_coal {
u16 coal_ticks;
u16 coal_ticks_irq;
u16 coal_bufs;
u16 coal_bufs_irq;
/* RING_IDLE enabled when coal ticks < idle_thresh */
u16 idle_thresh;
u8 bufs_per_record;
u8 budget;
};
struct bnxt_tc_info { struct bnxt_tc_info {
bool enabled; bool enabled;
...@@ -1235,14 +1246,8 @@ struct bnxt { ...@@ -1235,14 +1246,8 @@ struct bnxt {
u8 port_count; u8 port_count;
u16 br_mode; u16 br_mode;
u16 rx_coal_ticks; struct bnxt_coal rx_coal;
u16 rx_coal_ticks_irq; struct bnxt_coal tx_coal;
u16 rx_coal_bufs;
u16 rx_coal_bufs_irq;
u16 tx_coal_ticks;
u16 tx_coal_ticks_irq;
u16 tx_coal_bufs;
u16 tx_coal_bufs_irq;
#define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2) #define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2)
......
...@@ -44,19 +44,24 @@ static int bnxt_get_coalesce(struct net_device *dev, ...@@ -44,19 +44,24 @@ static int bnxt_get_coalesce(struct net_device *dev,
struct ethtool_coalesce *coal) struct ethtool_coalesce *coal)
{ {
struct bnxt *bp = netdev_priv(dev); struct bnxt *bp = netdev_priv(dev);
struct bnxt_coal *hw_coal;
u16 mult;
memset(coal, 0, sizeof(*coal)); memset(coal, 0, sizeof(*coal));
coal->rx_coalesce_usecs = bp->rx_coal_ticks; hw_coal = &bp->rx_coal;
/* 2 completion records per rx packet */ mult = hw_coal->bufs_per_record;
coal->rx_max_coalesced_frames = bp->rx_coal_bufs / 2; coal->rx_coalesce_usecs = hw_coal->coal_ticks;
coal->rx_coalesce_usecs_irq = bp->rx_coal_ticks_irq; coal->rx_max_coalesced_frames = hw_coal->coal_bufs / mult;
coal->rx_max_coalesced_frames_irq = bp->rx_coal_bufs_irq / 2; coal->rx_coalesce_usecs_irq = hw_coal->coal_ticks_irq;
coal->rx_max_coalesced_frames_irq = hw_coal->coal_bufs_irq / mult;
coal->tx_coalesce_usecs = bp->tx_coal_ticks; hw_coal = &bp->tx_coal;
coal->tx_max_coalesced_frames = bp->tx_coal_bufs; mult = hw_coal->bufs_per_record;
coal->tx_coalesce_usecs_irq = bp->tx_coal_ticks_irq; coal->tx_coalesce_usecs = hw_coal->coal_ticks;
coal->tx_max_coalesced_frames_irq = bp->tx_coal_bufs_irq; coal->tx_max_coalesced_frames = hw_coal->coal_bufs / mult;
coal->tx_coalesce_usecs_irq = hw_coal->coal_ticks_irq;
coal->tx_max_coalesced_frames_irq = hw_coal->coal_bufs_irq / mult;
coal->stats_block_coalesce_usecs = bp->stats_coal_ticks; coal->stats_block_coalesce_usecs = bp->stats_coal_ticks;
...@@ -68,18 +73,23 @@ static int bnxt_set_coalesce(struct net_device *dev, ...@@ -68,18 +73,23 @@ static int bnxt_set_coalesce(struct net_device *dev,
{ {
struct bnxt *bp = netdev_priv(dev); struct bnxt *bp = netdev_priv(dev);
bool update_stats = false; bool update_stats = false;
struct bnxt_coal *hw_coal;
int rc = 0; int rc = 0;
u16 mult;
bp->rx_coal_ticks = coal->rx_coalesce_usecs;
/* 2 completion records per rx packet */ hw_coal = &bp->rx_coal;
bp->rx_coal_bufs = coal->rx_max_coalesced_frames * 2; mult = hw_coal->bufs_per_record;
bp->rx_coal_ticks_irq = coal->rx_coalesce_usecs_irq; hw_coal->coal_ticks = coal->rx_coalesce_usecs;
bp->rx_coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2; hw_coal->coal_bufs = coal->rx_max_coalesced_frames * mult;
hw_coal->coal_ticks_irq = coal->rx_coalesce_usecs_irq;
bp->tx_coal_ticks = coal->tx_coalesce_usecs; hw_coal->coal_bufs_irq = coal->rx_max_coalesced_frames_irq * mult;
bp->tx_coal_bufs = coal->tx_max_coalesced_frames;
bp->tx_coal_ticks_irq = coal->tx_coalesce_usecs_irq; hw_coal = &bp->rx_coal;
bp->tx_coal_bufs_irq = coal->tx_max_coalesced_frames_irq; mult = hw_coal->bufs_per_record;
hw_coal->coal_ticks = coal->tx_coalesce_usecs;
hw_coal->coal_bufs = coal->tx_max_coalesced_frames * mult;
hw_coal->coal_ticks_irq = coal->tx_coalesce_usecs_irq;
hw_coal->coal_bufs_irq = coal->tx_max_coalesced_frames_irq * mult;
if (bp->stats_coal_ticks != coal->stats_block_coalesce_usecs) { if (bp->stats_coal_ticks != coal->stats_block_coalesce_usecs) {
u32 stats_ticks = coal->stats_block_coalesce_usecs; u32 stats_ticks = coal->stats_block_coalesce_usecs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment