lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 21 Apr 2014 08:45:23 -0700
From:	Florian Fainelli <f.fainelli@...il.com>
To:	netdev@...r.kernel.org
Cc:	davem@...emloft.net, Florian Fainelli <f.fainelli@...il.com>
Subject: [PATCH net-next 3/4] net: bcmgenet: add support for ethtool rx-frames

Add support for the ethtool rx-frames coalescing parameter which allows
defining the number of RX interrupts per frames received. Make sure that
whenever the link speed changes, we also re-program a correct push timer
value.

We can no longer enable the BDONE/PDONE interrupts as those would
fire for each packet/buffer received, which would defeat the MBDONE
interrupt purpose. The MBDONE interrupt is guaranteed to correspond to a
PDONE/BDONE interrupt when the threshold is set to 1.

Signed-off-by: Florian Fainelli <f.fainelli@...il.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 44 ++++++++++++++++++++++----
 drivers/net/ethernet/broadcom/genet/bcmgenet.h |  1 +
 drivers/net/ethernet/broadcom/genet/bcmmii.c   |  3 ++
 3 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index f1b3969de10b..4922958ec4aa 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -78,13 +78,10 @@
 #define GENET_RDMA_REG_OFF	(priv->hw_params->rdma_offset + \
 				TOTAL_DESC * DMA_DESC_SIZE)
 
-/* TX DMA done mask: multiple buffer done */
+/* RX/TX DMA done mask: multiple buffer done */
 #define UMAC_TXDMA_DONE_MASK	(UMAC_IRQ_TXDMA_MBDONE)
 
-/* Rx DMA done masks: packet, buffer and multiple buffer done */
-#define UMAC_RXDMA_DONE_MASK	(UMAC_IRQ_RXDMA_BDONE | \
-				 UMAC_IRQ_RXDMA_PDONE | \
-				 UMAC_IRQ_RXDMA_MBDONE)
+#define UMAC_RXDMA_DONE_MASK	(UMAC_IRQ_RXDMA_MBDONE)
 
 static inline void dmadesc_set_length_status(struct bcmgenet_priv *priv,
 						void __iomem *d, u32 value)
@@ -210,6 +207,7 @@ enum dma_reg {
 	DMA_ARB_CTRL,
 	DMA_PRIORITY,
 	DMA_RING_PRIORITY,
+	DMA_RING16_TIMEOUT,
 };
 
 static const u8 bcmgenet_dma_regs_v3plus[] = {
@@ -220,6 +218,7 @@ static const u8 bcmgenet_dma_regs_v3plus[] = {
 	[DMA_ARB_CTRL]		= 0x2C,
 	[DMA_PRIORITY]		= 0x30,
 	[DMA_RING_PRIORITY]	= 0x38,
+	[DMA_RING16_TIMEOUT]	= 0x6C,
 };
 
 static const u8 bcmgenet_dma_regs_v2[] = {
@@ -230,6 +229,7 @@ static const u8 bcmgenet_dma_regs_v2[] = {
 	[DMA_ARB_CTRL]		= 0x30,
 	[DMA_PRIORITY]		= 0x34,
 	[DMA_RING_PRIORITY]	= 0x3C,
+	[DMA_RING16_TIMEOUT]	= 0x6C,
 };
 
 static const u8 bcmgenet_dma_regs_v1[] = {
@@ -239,6 +239,7 @@ static const u8 bcmgenet_dma_regs_v1[] = {
 	[DMA_ARB_CTRL]		= 0x30,
 	[DMA_PRIORITY]		= 0x34,
 	[DMA_RING_PRIORITY]	= 0x3C,
+	[DMA_RING16_TIMEOUT]	= 0x6C,
 };
 
 /* Set at runtime once bcmgenet version is known */
@@ -501,17 +502,42 @@ static int bcmgenet_get_coalesce(struct net_device *dev,
 
 	ec->tx_max_coalesced_frames = bcmgenet_tdma_ring_readl(priv,
 			DESC_INDEX, DMA_MBUF_DONE_THRESH);
+	ec->rx_max_coalesced_frames = bcmgenet_rdma_ring_readl(priv,
+			DESC_INDEX, DMA_MBUF_DONE_THRESH);
 
 	return 0;
 }
 
+/* Update RX coalescing scheme based on the current link speed, caller
+ * must have updated the ring threshold before calling us.
+ */
+void bcmgenet_update_rx_coal(struct net_device *dev)
+{
+	unsigned int speeds[] = { SPEED_10, SPEED_100, SPEED_1000, SPEED_2500 };
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+	u32 cur_speed;
+	u32 timeout;
+	u32 rx_coal;
+
+	rx_coal = bcmgenet_rdma_ring_readl(priv, DESC_INDEX,
+			DMA_MBUF_DONE_THRESH);
+
+	cur_speed = (bcmgenet_umac_readl(priv, UMAC_CMD) >> CMD_SPEED_SHIFT) &
+			CMD_SPEED_MASK;
+
+	timeout = 2 * (rx_coal * ENET_MAX_MTU_SIZE) / speeds[cur_speed];
+	bcmgenet_rdma_writel(priv, timeout, DMA_RING16_TIMEOUT);
+}
+
 static int bcmgenet_set_coalesce(struct net_device *dev,
 				 struct ethtool_coalesce *ec)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	unsigned int i;
 
-	if (ec->tx_max_coalesced_frames > 255)
+	if (ec->tx_max_coalesced_frames > 255 ||
+	    ec->rx_max_coalesced_frames < 1 ||
+	    ec->rx_max_coalesced_frames > 255)
 		return -EINVAL;
 
 	/* Program all TX queues with the same values, as there is no
@@ -523,6 +549,11 @@ static int bcmgenet_set_coalesce(struct net_device *dev,
 	bcmgenet_tdma_ring_writel(priv, DESC_INDEX,
 			ec->tx_max_coalesced_frames, DMA_MBUF_DONE_THRESH);
 
+	bcmgenet_rdma_ring_writel(priv, DESC_INDEX,
+			ec->rx_max_coalesced_frames, DMA_MBUF_DONE_THRESH);
+
+	bcmgenet_update_rx_coal(dev);
+
 	return 0;
 }
 
@@ -1680,6 +1711,7 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
 			(DMA_FC_THRESH_LO << DMA_XOFF_THRESHOLD_SHIFT) |
 			DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH);
 	bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_READ_PTR);
+	bcmgenet_rdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH);
 
 	return ret;
 }
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 0f117105fed1..e9c17dcbc9ab 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -624,5 +624,6 @@ int bcmgenet_mii_init(struct net_device *dev);
 int bcmgenet_mii_config(struct net_device *dev);
 void bcmgenet_mii_exit(struct net_device *dev);
 void bcmgenet_mii_reset(struct net_device *dev);
+void bcmgenet_update_rx_coal(struct net_device *dev);
 
 #endif /* __BCMGENET_H__ */
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 4608673beaff..fd2f9ba70977 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -143,6 +143,9 @@ static void bcmgenet_mii_setup(struct net_device *dev)
 			       CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE);
 		reg |= cmd_bits;
 		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+
+		/* Update coalescing scheme based on current speed */
+		bcmgenet_update_rx_coal(priv->dev);
 	}
 
 	if (status_changed)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists