From fd41f2bfb71ba161309797de1ae1966810c19703 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 28 Mar 2018 15:15:36 -0700 Subject: [PATCH 1/3] net: systemport: Remove adaptive TX coalescing Adaptive TX coalescing is not currently giving us any advantages and ends up making the CPU spin more frequently until TX completion. Deny and disable adaptive TX coalescing for now and rely on static configuration, we can always add it back later. Reviewed-by: Tal Gilboa Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 61 +++------------------- drivers/net/ethernet/broadcom/bcmsysport.h | 1 - 2 files changed, 8 insertions(+), 54 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 4e26f606a7f2..1e52bb7d822e 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -588,7 +587,8 @@ static void bcm_sysport_set_rx_coalesce(struct bcm_sysport_priv *priv) rdma_writel(priv, reg, RDMA_MBDONE_INTR); } -static void bcm_sysport_set_tx_coalesce(struct bcm_sysport_tx_ring *ring) +static void bcm_sysport_set_tx_coalesce(struct bcm_sysport_tx_ring *ring, + struct ethtool_coalesce *ec) { struct bcm_sysport_priv *priv = ring->priv; u32 reg; @@ -596,8 +596,8 @@ static void bcm_sysport_set_tx_coalesce(struct bcm_sysport_tx_ring *ring) reg = tdma_readl(priv, TDMA_DESC_RING_INTR_CONTROL(ring->index)); reg &= ~(RING_INTR_THRESH_MASK | RING_TIMEOUT_MASK << RING_TIMEOUT_SHIFT); - reg |= ring->dim.coal_pkts; - reg |= DIV_ROUND_UP(ring->dim.coal_usecs * 1000, 8192) << + reg |= ec->tx_max_coalesced_frames; + reg |= DIV_ROUND_UP(ec->tx_coalesce_usecs * 1000, 8192) << RING_TIMEOUT_SHIFT; tdma_writel(priv, reg, TDMA_DESC_RING_INTR_CONTROL(ring->index)); } @@ -606,18 +606,12 @@ static int bcm_sysport_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) { struct bcm_sysport_priv *priv = netdev_priv(dev); - struct bcm_sysport_tx_ring *ring; - unsigned int i; u32 reg; reg = tdma_readl(priv, TDMA_DESC_RING_INTR_CONTROL(0)); ec->tx_coalesce_usecs = (reg >> RING_TIMEOUT_SHIFT) * 8192 / 1000; ec->tx_max_coalesced_frames = reg & RING_INTR_THRESH_MASK; - for (i = 0; i < dev->num_tx_queues; i++) { - ring = &priv->tx_rings[i]; - ec->use_adaptive_tx_coalesce |= ring->dim.use_dim; - } reg = rdma_readl(priv, RDMA_MBDONE_INTR); @@ -632,7 +626,6 @@ static int bcm_sysport_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) { struct bcm_sysport_priv *priv = netdev_priv(dev); - struct bcm_sysport_tx_ring *ring; unsigned int i; /* Base system clock is 125Mhz, DMA timeout is this reference clock @@ -646,20 +639,12 @@ static int bcm_sysport_set_coalesce(struct net_device *dev, return -EINVAL; if ((ec->tx_coalesce_usecs == 0 && ec->tx_max_coalesced_frames == 0) || - (ec->rx_coalesce_usecs == 0 && ec->rx_max_coalesced_frames == 0)) + (ec->rx_coalesce_usecs == 0 && ec->rx_max_coalesced_frames == 0) || + ec->use_adaptive_tx_coalesce) return -EINVAL; - for (i = 0; i < dev->num_tx_queues; i++) { - ring = &priv->tx_rings[i]; - ring->dim.coal_pkts = ec->tx_max_coalesced_frames; - ring->dim.coal_usecs = ec->tx_coalesce_usecs; - if (!ec->use_adaptive_tx_coalesce && ring->dim.use_dim) { - ring->dim.coal_pkts = 1; - ring->dim.coal_usecs = 0; - } - ring->dim.use_dim = ec->use_adaptive_tx_coalesce; - bcm_sysport_set_tx_coalesce(ring); - } + for (i = 0; i < dev->num_tx_queues; i++) + bcm_sysport_set_tx_coalesce(&priv->tx_rings[i], ec); priv->dim.coal_usecs = ec->rx_coalesce_usecs; priv->dim.coal_pkts = ec->rx_max_coalesced_frames; @@ -940,8 +925,6 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv, ring->packets += pkts_compl; ring->bytes += bytes_compl; u64_stats_update_end(&priv->syncp); - ring->dim.packets = pkts_compl; - ring->dim.bytes = bytes_compl; ring->c_index = c_index; @@ -987,7 +970,6 @@ static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget) { struct bcm_sysport_tx_ring *ring = container_of(napi, struct bcm_sysport_tx_ring, napi); - struct net_dim_sample dim_sample; unsigned int work_done = 0; work_done = bcm_sysport_tx_reclaim(ring->priv, ring); @@ -1004,12 +986,6 @@ static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget) return 0; } - if (ring->dim.use_dim) { - net_dim_sample(ring->dim.event_ctr, ring->dim.packets, - ring->dim.bytes, &dim_sample); - net_dim(&ring->dim.dim, dim_sample); - } - return budget; } @@ -1089,23 +1065,6 @@ static void bcm_sysport_dim_work(struct work_struct *work) dim->state = NET_DIM_START_MEASURE; } -static void bcm_sysport_dim_tx_work(struct work_struct *work) -{ - struct net_dim *dim = container_of(work, struct net_dim, work); - struct bcm_sysport_net_dim *ndim = - container_of(dim, struct bcm_sysport_net_dim, dim); - struct bcm_sysport_tx_ring *ring = - container_of(ndim, struct bcm_sysport_tx_ring, dim); - struct net_dim_cq_moder cur_profile = - net_dim_get_profile(dim->mode, dim->profile_ix); - - ring->dim.coal_usecs = cur_profile.usec; - ring->dim.coal_pkts = cur_profile.pkts; - - bcm_sysport_set_tx_coalesce(ring); - dim->state = NET_DIM_START_MEASURE; -} - /* RX and misc interrupt routine */ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id) { @@ -1152,7 +1111,6 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id) continue; txr = &priv->tx_rings[ring]; - txr->dim.event_ctr++; if (likely(napi_schedule_prep(&txr->napi))) { intrl2_0_mask_set(priv, ring_bit); @@ -1185,7 +1143,6 @@ static irqreturn_t bcm_sysport_tx_isr(int irq, void *dev_id) continue; txr = &priv->tx_rings[ring]; - txr->dim.event_ctr++; if (likely(napi_schedule_prep(&txr->napi))) { intrl2_1_mask_set(priv, BIT(ring)); @@ -1551,7 +1508,6 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, reg |= (1 << index); tdma_writel(priv, reg, TDMA_TIER1_ARB_0_QUEUE_EN); - bcm_sysport_init_dim(&ring->dim, bcm_sysport_dim_tx_work); napi_enable(&ring->napi); netif_dbg(priv, hw, priv->netdev, @@ -1582,7 +1538,6 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv, return; napi_disable(&ring->napi); - cancel_work_sync(&ring->dim.dim.work); netif_napi_del(&ring->napi); bcm_sysport_tx_clean(priv, ring); diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h index e1c97d4a82b4..57e18ef8f206 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.h +++ b/drivers/net/ethernet/broadcom/bcmsysport.h @@ -723,7 +723,6 @@ struct bcm_sysport_tx_ring { struct bcm_sysport_priv *priv; /* private context backpointer */ unsigned long packets; /* packets statistics */ unsigned long bytes; /* bytes statistics */ - struct bcm_sysport_net_dim dim; /* Net DIM context */ unsigned int switch_queue; /* switch port queue number */ unsigned int switch_port; /* switch port queue number */ bool inspect; /* inspect switch port and queue */ From a8cdfbdf885f3d3b4940ea31696a4492afd331f7 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 28 Mar 2018 15:15:37 -0700 Subject: [PATCH 2/3] net: systemport: Fix coalescing settings handling There were a number of issues with setting the RX coalescing parameters: - we would not be preserving values that would have been configured across close/open calls, instead we would always reset to no timeout and 1 interrupt per packet, this would also prevent DIM from setting its default usec/pkts values - when adaptive RX would be turned on, we woud not be fetching the default parameters, we would stay with no timeout/1 packet per interrupt until the estimator kicks in and changes that - finally disabling adaptive RX coalescing while providing parameters would not be honored, and we would stay with whatever DIM had previously determined instead of the user requested parameters Fixes: b6e0e875421e ("net: systemport: Implement adaptive interrupt coalescing") Signed-off-by: Florian Fainelli Reviewed-by: Tal Gilboa Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcmsysport.c | 62 +++++++++++++++------- drivers/net/ethernet/broadcom/bcmsysport.h | 4 +- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 1e52bb7d822e..4a75b1de22e0 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -574,16 +574,16 @@ static int bcm_sysport_set_wol(struct net_device *dev, return 0; } -static void bcm_sysport_set_rx_coalesce(struct bcm_sysport_priv *priv) +static void bcm_sysport_set_rx_coalesce(struct bcm_sysport_priv *priv, + u32 usecs, u32 pkts) { u32 reg; reg = rdma_readl(priv, RDMA_MBDONE_INTR); reg &= ~(RDMA_INTR_THRESH_MASK | RDMA_TIMEOUT_MASK << RDMA_TIMEOUT_SHIFT); - reg |= priv->dim.coal_pkts; - reg |= DIV_ROUND_UP(priv->dim.coal_usecs * 1000, 8192) << - RDMA_TIMEOUT_SHIFT; + reg |= pkts; + reg |= DIV_ROUND_UP(usecs * 1000, 8192) << RDMA_TIMEOUT_SHIFT; rdma_writel(priv, reg, RDMA_MBDONE_INTR); } @@ -626,6 +626,8 @@ static int bcm_sysport_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) { struct bcm_sysport_priv *priv = netdev_priv(dev); + struct net_dim_cq_moder moder; + u32 usecs, pkts; unsigned int i; /* Base system clock is 125Mhz, DMA timeout is this reference clock @@ -646,15 +648,21 @@ static int bcm_sysport_set_coalesce(struct net_device *dev, for (i = 0; i < dev->num_tx_queues; i++) bcm_sysport_set_tx_coalesce(&priv->tx_rings[i], ec); - priv->dim.coal_usecs = ec->rx_coalesce_usecs; - priv->dim.coal_pkts = ec->rx_max_coalesced_frames; + priv->rx_coalesce_usecs = ec->rx_coalesce_usecs; + priv->rx_max_coalesced_frames = ec->rx_max_coalesced_frames; + usecs = priv->rx_coalesce_usecs; + pkts = priv->rx_max_coalesced_frames; - if (!ec->use_adaptive_rx_coalesce && priv->dim.use_dim) { - priv->dim.coal_pkts = 1; - priv->dim.coal_usecs = 0; + if (ec->use_adaptive_rx_coalesce && !priv->dim.use_dim) { + moder = net_dim_get_def_profile(priv->dim.dim.mode); + usecs = moder.usec; + pkts = moder.pkts; } + priv->dim.use_dim = ec->use_adaptive_rx_coalesce; - bcm_sysport_set_rx_coalesce(priv); + + /* Apply desired coalescing parameters */ + bcm_sysport_set_rx_coalesce(priv, usecs, pkts); return 0; } @@ -1058,10 +1066,7 @@ static void bcm_sysport_dim_work(struct work_struct *work) struct net_dim_cq_moder cur_profile = net_dim_get_profile(dim->mode, dim->profile_ix); - priv->dim.coal_usecs = cur_profile.usec; - priv->dim.coal_pkts = cur_profile.pkts; - - bcm_sysport_set_rx_coalesce(priv); + bcm_sysport_set_rx_coalesce(priv, cur_profile.usec, cur_profile.pkts); dim->state = NET_DIM_START_MEASURE; } @@ -1408,9 +1413,11 @@ out: phy_print_status(phydev); } -static void bcm_sysport_init_dim(struct bcm_sysport_net_dim *dim, +static void bcm_sysport_init_dim(struct bcm_sysport_priv *priv, void (*cb)(struct work_struct *work)) { + struct bcm_sysport_net_dim *dim = &priv->dim; + INIT_WORK(&dim->dim.work, cb); dim->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE; dim->event_ctr = 0; @@ -1418,6 +1425,25 @@ static void bcm_sysport_init_dim(struct bcm_sysport_net_dim *dim, dim->bytes = 0; } +static void bcm_sysport_init_rx_coalesce(struct bcm_sysport_priv *priv) +{ + struct bcm_sysport_net_dim *dim = &priv->dim; + struct net_dim_cq_moder moder; + u32 usecs, pkts; + + usecs = priv->rx_coalesce_usecs; + pkts = priv->rx_max_coalesced_frames; + + /* If DIM was enabled, re-apply default parameters */ + if (dim->use_dim) { + moder = net_dim_get_def_profile(dim->dim.mode); + usecs = moder.usec; + pkts = moder.pkts; + } + + bcm_sysport_set_rx_coalesce(priv, usecs, pkts); +} + static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, unsigned int index) { @@ -1658,8 +1684,6 @@ static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv) rdma_writel(priv, 0, RDMA_END_ADDR_HI); rdma_writel(priv, priv->num_rx_desc_words - 1, RDMA_END_ADDR_LO); - rdma_writel(priv, 1, RDMA_MBDONE_INTR); - netif_dbg(priv, hw, priv->netdev, "RDMA cfg, num_rx_bds=%d, rx_bds=%p\n", priv->num_rx_bds, priv->rx_bds); @@ -1827,7 +1851,8 @@ static void bcm_sysport_netif_start(struct net_device *dev) struct bcm_sysport_priv *priv = netdev_priv(dev); /* Enable NAPI */ - bcm_sysport_init_dim(&priv->dim, bcm_sysport_dim_work); + bcm_sysport_init_dim(priv, bcm_sysport_dim_work); + bcm_sysport_init_rx_coalesce(priv); napi_enable(&priv->napi); /* Enable RX interrupt and TX ring full interrupt */ @@ -2333,6 +2358,7 @@ static int bcm_sysport_probe(struct platform_device *pdev) /* libphy will adjust the link state accordingly */ netif_carrier_off(dev); + priv->rx_max_coalesced_frames = 1; u64_stats_init(&priv->syncp); priv->dsa_notifier.notifier_call = bcm_sysport_dsa_notifier; diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h index 57e18ef8f206..d6e5d0cbf3a3 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.h +++ b/drivers/net/ethernet/broadcom/bcmsysport.h @@ -701,8 +701,6 @@ struct bcm_sysport_net_dim { u16 event_ctr; unsigned long packets; unsigned long bytes; - u32 coal_usecs; - u32 coal_pkts; struct net_dim dim; }; @@ -755,6 +753,8 @@ struct bcm_sysport_priv { unsigned int rx_c_index; struct bcm_sysport_net_dim dim; + u32 rx_max_coalesced_frames; + u32 rx_coalesce_usecs; /* PHY device */ struct device_node *phy_dn; From 5e6ce1f1a4ca83878f2966dd67afb39b631c4320 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 28 Mar 2018 15:15:38 -0700 Subject: [PATCH 3/3] net: bcmgenet: Fix coalescing settings handling There were a number of issues with setting the RX coalescing parameters: - we would not be preserving values that would have been configured across close/open calls, instead we would always reset to no timeout and 1 interrupt per packet, this would also prevent DIM from setting its default usec/pkts values - when adaptive RX would be turned on, we woud not be fetching the default parameters, we would stay with no timeout/1 packet per interrupt until the estimator kicks in and changes that - finally disabling adaptive RX coalescing while providing parameters would not be honored, and we would stay with whatever DIM had previously determined instead of the user requested parameters Fixes: 9f4ca05827a2 ("net: bcmgenet: Add support for adaptive RX coalescing") Signed-off-by: Florian Fainelli Reviewed-by: Tal Gilboa Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/genet/bcmgenet.c | 92 ++++++++++++------- .../net/ethernet/broadcom/genet/bcmgenet.h | 4 +- 2 files changed, 61 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 2f4cb5c11e18..264fb37dd341 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -625,26 +625,46 @@ static int bcmgenet_get_coalesce(struct net_device *dev, return 0; } -static void bcmgenet_set_rx_coalesce(struct bcmgenet_rx_ring *ring) +static void bcmgenet_set_rx_coalesce(struct bcmgenet_rx_ring *ring, + u32 usecs, u32 pkts) { struct bcmgenet_priv *priv = ring->priv; unsigned int i = ring->index; u32 reg; - bcmgenet_rdma_ring_writel(priv, i, ring->dim.coal_pkts, - DMA_MBUF_DONE_THRESH); + bcmgenet_rdma_ring_writel(priv, i, pkts, DMA_MBUF_DONE_THRESH); reg = bcmgenet_rdma_readl(priv, DMA_RING0_TIMEOUT + i); reg &= ~DMA_TIMEOUT_MASK; - reg |= DIV_ROUND_UP(ring->dim.coal_usecs * 1000, 8192); + reg |= DIV_ROUND_UP(usecs * 1000, 8192); bcmgenet_rdma_writel(priv, reg, DMA_RING0_TIMEOUT + i); } +static void bcmgenet_set_ring_rx_coalesce(struct bcmgenet_rx_ring *ring, + struct ethtool_coalesce *ec) +{ + struct net_dim_cq_moder moder; + u32 usecs, pkts; + + ring->rx_coalesce_usecs = ec->rx_coalesce_usecs; + ring->rx_max_coalesced_frames = ec->rx_max_coalesced_frames; + usecs = ring->rx_coalesce_usecs; + pkts = ring->rx_max_coalesced_frames; + + if (ec->use_adaptive_rx_coalesce && !ring->dim.use_dim) { + moder = net_dim_get_def_profile(ring->dim.dim.mode); + usecs = moder.usec; + pkts = moder.pkts; + } + + ring->dim.use_dim = ec->use_adaptive_rx_coalesce; + bcmgenet_set_rx_coalesce(ring, usecs, pkts); +} + static int bcmgenet_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) { struct bcmgenet_priv *priv = netdev_priv(dev); - struct bcmgenet_rx_ring *ring; unsigned int i; /* Base system clock is 125Mhz, DMA timeout is this reference clock @@ -680,27 +700,9 @@ static int bcmgenet_set_coalesce(struct net_device *dev, ec->tx_max_coalesced_frames, DMA_MBUF_DONE_THRESH); - for (i = 0; i < priv->hw_params->rx_queues; i++) { - ring = &priv->rx_rings[i]; - ring->dim.coal_usecs = ec->rx_coalesce_usecs; - ring->dim.coal_pkts = ec->rx_max_coalesced_frames; - if (!ec->use_adaptive_rx_coalesce && ring->dim.use_dim) { - ring->dim.coal_pkts = 1; - ring->dim.coal_usecs = 0; - } - ring->dim.use_dim = ec->use_adaptive_rx_coalesce; - bcmgenet_set_rx_coalesce(ring); - } - - ring = &priv->rx_rings[DESC_INDEX]; - ring->dim.coal_usecs = ec->rx_coalesce_usecs; - ring->dim.coal_pkts = ec->rx_max_coalesced_frames; - if (!ec->use_adaptive_rx_coalesce && ring->dim.use_dim) { - ring->dim.coal_pkts = 1; - ring->dim.coal_usecs = 0; - } - ring->dim.use_dim = ec->use_adaptive_rx_coalesce; - bcmgenet_set_rx_coalesce(ring); + for (i = 0; i < priv->hw_params->rx_queues; i++) + bcmgenet_set_ring_rx_coalesce(&priv->rx_rings[i], ec); + bcmgenet_set_ring_rx_coalesce(&priv->rx_rings[DESC_INDEX], ec); return 0; } @@ -1924,10 +1926,7 @@ static void bcmgenet_dim_work(struct work_struct *work) struct net_dim_cq_moder cur_profile = net_dim_get_profile(dim->mode, dim->profile_ix); - ring->dim.coal_usecs = cur_profile.usec; - ring->dim.coal_pkts = cur_profile.pkts; - - bcmgenet_set_rx_coalesce(ring); + bcmgenet_set_rx_coalesce(ring, cur_profile.usec, cur_profile.pkts); dim->state = NET_DIM_START_MEASURE; } @@ -2079,9 +2078,11 @@ static void init_umac(struct bcmgenet_priv *priv) dev_dbg(kdev, "done init umac\n"); } -static void bcmgenet_init_dim(struct bcmgenet_net_dim *dim, +static void bcmgenet_init_dim(struct bcmgenet_rx_ring *ring, void (*cb)(struct work_struct *work)) { + struct bcmgenet_net_dim *dim = &ring->dim; + INIT_WORK(&dim->dim.work, cb); dim->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE; dim->event_ctr = 0; @@ -2089,6 +2090,25 @@ static void bcmgenet_init_dim(struct bcmgenet_net_dim *dim, dim->bytes = 0; } +static void bcmgenet_init_rx_coalesce(struct bcmgenet_rx_ring *ring) +{ + struct bcmgenet_net_dim *dim = &ring->dim; + struct net_dim_cq_moder moder; + u32 usecs, pkts; + + usecs = ring->rx_coalesce_usecs; + pkts = ring->rx_max_coalesced_frames; + + /* If DIM was enabled, re-apply default parameters */ + if (dim->use_dim) { + moder = net_dim_get_def_profile(dim->dim.mode); + usecs = moder.usec; + pkts = moder.pkts; + } + + bcmgenet_set_rx_coalesce(ring, usecs, pkts); +} + /* Initialize a Tx ring along with corresponding hardware registers */ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv, unsigned int index, unsigned int size, @@ -2178,7 +2198,8 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, if (ret) return ret; - bcmgenet_init_dim(&ring->dim, bcmgenet_dim_work); + bcmgenet_init_dim(ring, bcmgenet_dim_work); + bcmgenet_init_rx_coalesce(ring); /* Initialize Rx NAPI */ netif_napi_add(priv->dev, &ring->napi, bcmgenet_rx_poll, @@ -2186,7 +2207,6 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv, bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX); bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX); - bcmgenet_rdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH); bcmgenet_rdma_ring_writel(priv, index, ((size << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH), DMA_RING_BUF_SIZE); @@ -3424,6 +3444,7 @@ static int bcmgenet_probe(struct platform_device *pdev) struct net_device *dev; const void *macaddr; struct resource *r; + unsigned int i; int err = -EIO; const char *phy_mode_str; @@ -3552,6 +3573,11 @@ static int bcmgenet_probe(struct platform_device *pdev) netif_set_real_num_tx_queues(priv->dev, priv->hw_params->tx_queues + 1); netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1); + /* Set default coalescing parameters */ + for (i = 0; i < priv->hw_params->rx_queues; i++) + priv->rx_rings[i].rx_max_coalesced_frames = 1; + priv->rx_rings[DESC_INDEX].rx_max_coalesced_frames = 1; + /* libphy will determine the link state */ netif_carrier_off(dev); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 22c41e0430fb..b773bc07edf7 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -578,8 +578,6 @@ struct bcmgenet_net_dim { u16 event_ctr; unsigned long packets; unsigned long bytes; - u32 coal_usecs; - u32 coal_pkts; struct net_dim dim; }; @@ -598,6 +596,8 @@ struct bcmgenet_rx_ring { unsigned int end_ptr; /* Rx ring end CB ptr */ unsigned int old_discards; struct bcmgenet_net_dim dim; + u32 rx_max_coalesced_frames; + u32 rx_coalesce_usecs; void (*int_enable)(struct bcmgenet_rx_ring *); void (*int_disable)(struct bcmgenet_rx_ring *); struct bcmgenet_priv *priv;