netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] sky2: rx hash offload
@ 2010-04-05 15:48 Stephen Hemminger
  2010-04-05 16:14 ` Eric Dumazet
  2010-04-06 12:33 ` Eric Dumazet
  0 siblings, 2 replies; 4+ messages in thread
From: Stephen Hemminger @ 2010-04-05 15:48 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Marvell Yukon 2 hardware supports hardware receive hash calculation.
Now that Receive Packet Steering is available, add support
to enable it.

Note: still experimental, tested on only a few variants.
No performance testing has been done.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 drivers/net/sky2.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 drivers/net/sky2.h |   23 ++++++++++++++++
 2 files changed, 96 insertions(+), 2 deletions(-)

--- a/drivers/net/sky2.c	2010-04-04 15:04:22.582288437 -0700
+++ b/drivers/net/sky2.c	2010-04-05 08:37:47.924236795 -0700
@@ -1195,6 +1195,39 @@ static void rx_set_checksum(struct sky2_
 		     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
 }
 
+/* Enable/disable receive hash calculation (RSS) */
+static void rx_set_rss(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	int i, nkeys = 4;
+
+	/* Supports IPv6 and other modes */
+	if (hw->flags & SKY2_HW_NEW_LE) {
+		nkeys = 10;
+		sky2_write32(hw, SK_REG(sky2->port, RSS_CFG), HASH_ALL);
+	}
+
+	/* Program RSS initial values */
+	if (dev->features & NETIF_F_RXHASH) {
+		u32 key[nkeys];
+
+		get_random_bytes(key, nkeys * sizeof(u32));
+		for (i = 0; i < nkeys; i++)
+			sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4),
+				     key[i]);
+
+		/* Need to turn on (undocumented) flag to make hashing work  */
+		sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T),
+			     RX_STFW_ENA);
+
+		sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+			     BMU_ENA_RX_RSS_HASH);
+	} else
+		sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+			     BMU_DIS_RX_RSS_HASH);
+}
+
 /*
  * The RX Stop command will not work for Yukon-2 if the BMU does not
  * reach the end of packet and since we can't make sure that we have
@@ -1427,6 +1460,9 @@ static void sky2_rx_start(struct sky2_po
 	if (!(hw->flags & SKY2_HW_NEW_LE))
 		rx_set_checksum(sky2);
 
+	if (!(hw->flags & SKY2_HW_RSS_BROKEN))
+		rx_set_rss(sky2->netdev);
+
 	/* submit Rx ring */
 	for (i = 0; i < sky2->rx_pending; i++) {
 		re = sky2->rx_ring + i;
@@ -2536,6 +2572,14 @@ static void sky2_rx_checksum(struct sky2
 	}
 }
 
+static void sky2_rx_hash(struct sky2_port *sky2, u32 status)
+{
+	struct sk_buff *skb;
+
+	skb = sky2->rx_ring[sky2->rx_next].skb;
+	skb->rxhash = le32_to_cpu(status);
+}
+
 /* Process status response ring */
 static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
 {
@@ -2608,6 +2652,10 @@ static int sky2_status_intr(struct sky2_
 				sky2_rx_checksum(sky2, status);
 			break;
 
+		case OP_RSS_HASH:
+			sky2_rx_hash(sky2, status);
+			break;
+
 		case OP_TXINDEXLE:
 			/* TX index reports status for both ports */
 			sky2_tx_done(hw->dev[0], status & 0xfff);
@@ -2962,6 +3010,8 @@ static int __devinit sky2_init(struct sk
 	switch(hw->chip_id) {
 	case CHIP_ID_YUKON_XL:
 		hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY;
+		if (hw->chip_rev < CHIP_REV_YU_XL_A2)
+			hw->flags |= SKY2_HW_RSS_BROKEN;
 		break;
 
 	case CHIP_ID_YUKON_EC_U:
@@ -2987,10 +3037,11 @@ static int __devinit sky2_init(struct sk
 			dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n");
 			return -EOPNOTSUPP;
 		}
-		hw->flags = SKY2_HW_GIGABIT;
+		hw->flags = SKY2_HW_GIGABIT | SKY2_HW_RSS_BROKEN;
 		break;
 
 	case CHIP_ID_YUKON_FE:
+		hw->flags = SKY2_HW_RSS_BROKEN;
 		break;
 
 	case CHIP_ID_YUKON_FE_P:
@@ -4114,6 +4165,28 @@ static int sky2_set_eeprom(struct net_de
 	return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
 }
 
+static int sky2_set_flags(struct net_device *dev, u32 data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	if (data & ETH_FLAG_LRO)
+		return -EOPNOTSUPP;
+
+	if (data & ETH_FLAG_NTUPLE)
+		return -EOPNOTSUPP;
+
+	if (data & ETH_FLAG_RXHASH) {
+		if (sky2->hw->flags & SKY2_HW_RSS_BROKEN)
+			return -EINVAL;
+
+		dev->features |= NETIF_F_RXHASH;
+	} else
+		dev->features &= ~NETIF_F_RXHASH;
+
+	rx_set_rss(dev);
+
+	return 0;
+}
 
 static const struct ethtool_ops sky2_ethtool_ops = {
 	.get_settings	= sky2_get_settings,
@@ -4145,6 +4218,7 @@ static const struct ethtool_ops sky2_eth
 	.phys_id	= sky2_phys_id,
 	.get_sset_count = sky2_get_sset_count,
 	.get_ethtool_stats = sky2_get_ethtool_stats,
+	.set_flags	= sky2_set_flags,
 };
 
 #ifdef CONFIG_SKY2_DEBUG
@@ -4497,6 +4571,11 @@ static __devinit struct net_device *sky2
 	if (highmem)
 		dev->features |= NETIF_F_HIGHDMA;
 
+#ifdef CONFIG_RPS
+	if (!(hw->flags & SKY2_HW_RSS_BROKEN))
+		dev->features |= NETIF_F_RXHASH;
+#endif
+
 #ifdef SKY2_VLAN_TAG_USED
 	/* The workaround for FE+ status conflicts with VLAN tag detection. */
 	if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
--- a/drivers/net/sky2.h	2010-04-02 15:18:00.289206825 -0700
+++ b/drivers/net/sky2.h	2010-04-04 15:05:22.161352031 -0700
@@ -694,8 +694,21 @@ enum {
 	TXA_CTRL	= 0x0210,/*  8 bit	Tx Arbiter Control Register */
 	TXA_TEST	= 0x0211,/*  8 bit	Tx Arbiter Test Register */
 	TXA_STAT	= 0x0212,/*  8 bit	Tx Arbiter Status Register */
+
+	RSS_KEY		= 0x0220, /* RSS Key setup */
+	RSS_CFG		= 0x0248, /* RSS Configuration */
 };
 
+enum {
+	HASH_TCP_IPV6_EX_CTRL	= 1<<5,
+	HASH_IPV6_EX_CTRL	= 1<<4,
+	HASH_TCP_IPV6_CTRL	= 1<<3,
+	HASH_IPV6_CTRL		= 1<<2,
+	HASH_TCP_IPV4_CTRL	= 1<<1,
+	HASH_IPV4_CTRL		= 1<<0,
+
+	HASH_ALL		= 0x3f,
+};
 
 enum {
 	B6_EXT_REG	= 0x0300,/* External registers (GENESIS only) */
@@ -2261,6 +2274,7 @@ struct sky2_hw {
 #define SKY2_HW_NEW_LE		0x00000020	/* new LSOv2 format */
 #define SKY2_HW_AUTO_TX_SUM	0x00000040	/* new IP decode for Tx */
 #define SKY2_HW_ADV_POWER_CTL	0x00000080	/* additional PHY power regs */
+#define SKY2_HW_RSS_BROKEN	0x00000100
 
 	u8	     	     chip_id;
 	u8		     chip_rev;

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] sky2: rx hash offload
  2010-04-05 15:48 [PATCH] sky2: rx hash offload Stephen Hemminger
@ 2010-04-05 16:14 ` Eric Dumazet
  2010-04-06 12:33 ` Eric Dumazet
  1 sibling, 0 replies; 4+ messages in thread
From: Eric Dumazet @ 2010-04-05 16:14 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev

Le lundi 05 avril 2010 à 08:48 -0700, Stephen Hemminger a écrit :
> Marvell Yukon 2 hardware supports hardware receive hash calculation.
> Now that Receive Packet Steering is available, add support
> to enable it.
> 
> Note: still experimental, tested on only a few variants.
> No performance testing has been done.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
>  drivers/net/sky2.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++--
>  drivers/net/sky2.h |   23 ++++++++++++++++
>  2 files changed, 96 insertions(+), 2 deletions(-)
> 

Cool :)

I believe some bits are needed in receive_copy() to transfert rxhash to
new skb ?


diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index d8ec4c1..f420255 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2295,6 +2295,8 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
                skb_copy_from_linear_data(re->skb, skb->data, length);
                skb->ip_summed = re->skb->ip_summed;
                skb->csum = re->skb->csum;
+               skb->rxhash = re->skb->rxhash;
+               re->skb->rxhash = 0;
                pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
                                               length, PCI_DMA_FROMDEVICE);
                re->skb->ip_summed = CHECKSUM_NONE;



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] sky2: rx hash offload
  2010-04-05 15:48 [PATCH] sky2: rx hash offload Stephen Hemminger
  2010-04-05 16:14 ` Eric Dumazet
@ 2010-04-06 12:33 ` Eric Dumazet
  2010-04-08  5:04   ` David Miller
  1 sibling, 1 reply; 4+ messages in thread
From: Eric Dumazet @ 2010-04-06 12:33 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev, Tom Herbert

Le lundi 05 avril 2010 à 08:48 -0700, Stephen Hemminger a écrit :
> Marvell Yukon 2 hardware supports hardware receive hash calculation.
> Now that Receive Packet Steering is available, add support
> to enable it.
> 
> Note: still experimental, tested on only a few variants.
> No performance testing has been done.
> 
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
> 
> ---
>  drivers/net/sky2.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++--
>  drivers/net/sky2.h |   23 ++++++++++++++++
>  2 files changed, 96 insertions(+), 2 deletions(-)

I am wondering if introducing hardware computed rxhash wouldnt force us
to clear rxhash in several paths (tunneling...), so that we perform a
software recompute after decapsulation, to enable RFS

Not mandatory but recommended I would say...

diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 2f302d3..3f0aba4 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -379,6 +379,7 @@ static int ipip_rcv(struct sk_buff *skb)
 		skb_dst_drop(skb);
 		nf_reset(skb);
 		ipip_ecn_decapsulate(iph, skb);
+		skb->rxhash = 0;
 		netif_rx(skb);
 		rcu_read_unlock();
 		return 0;



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] sky2: rx hash offload
  2010-04-06 12:33 ` Eric Dumazet
@ 2010-04-08  5:04   ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2010-04-08  5:04 UTC (permalink / raw)
  To: eric.dumazet; +Cc: shemminger, netdev, therbert

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 06 Apr 2010 14:33:30 +0200

> Le lundi 05 avril 2010 à 08:48 -0700, Stephen Hemminger a écrit :
>> Marvell Yukon 2 hardware supports hardware receive hash calculation.
>> Now that Receive Packet Steering is available, add support
>> to enable it.
>> 
>> Note: still experimental, tested on only a few variants.
>> No performance testing has been done.
>> 
>> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>> 
>> ---
>>  drivers/net/sky2.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++--
>>  drivers/net/sky2.h |   23 ++++++++++++++++
>>  2 files changed, 96 insertions(+), 2 deletions(-)
> 
> I am wondering if introducing hardware computed rxhash wouldnt force us
> to clear rxhash in several paths (tunneling...), so that we perform a
> software recompute after decapsulation, to enable RFS
> 
> Not mandatory but recommended I would say...

nf_reset() and clearing things like this new rxhash thing
should be encapsulated into a helper function that we can
stick into the tunnel drivers and such.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-04-08  5:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-05 15:48 [PATCH] sky2: rx hash offload Stephen Hemminger
2010-04-05 16:14 ` Eric Dumazet
2010-04-06 12:33 ` Eric Dumazet
2010-04-08  5:04   ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).