netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/2] sky2: convert to new VLAN model
@ 2011-01-07  4:41 Stephen Hemminger
  2011-01-07 17:14 ` Jesse Gross
  0 siblings, 1 reply; 7+ messages in thread
From: Stephen Hemminger @ 2011-01-07  4:41 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

This converts sky2 to new VLAN offload flags control via ethtool.
It also allows for transmit offload of vlan tagged frames which
was not possible before.

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


--- a/drivers/net/sky2.c	2011-01-06 17:44:00.643524039 -0800
+++ b/drivers/net/sky2.c	2011-01-06 19:05:06.100968234 -0800
@@ -46,10 +46,6 @@
 
 #include <asm/irq.h>
 
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define SKY2_VLAN_TAG_USED 1
-#endif
-
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
@@ -1326,40 +1322,33 @@ static int sky2_ioctl(struct net_device
 	return err;
 }
 
-#ifdef SKY2_VLAN_TAG_USED
-static void sky2_set_vlan_mode(struct sky2_hw *hw, u16 port, bool onoff)
+/* Features available on VLAN with transmit tag stripped */
+#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO)
+
+static void sky2_vlan_mode(struct net_device *dev)
 {
-	if (onoff) {
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	u16 port = sky2->port;
+
+	if (dev->features & NETIF_F_HW_VLAN_RX)
 		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
 			     RX_VLAN_STRIP_ON);
+	else
+		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+			     RX_VLAN_STRIP_OFF);
+
+	if (dev->features & NETIF_F_HW_VLAN_TX) {
 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
 			     TX_VLAN_TAG_ON);
+		dev->vlan_features = dev->features & VLAN_FEAT;
 	} else {
-		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
-			     RX_VLAN_STRIP_OFF);
 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
 			     TX_VLAN_TAG_OFF);
+		dev->vlan_features = dev->features & NETIF_F_HIGHDMA;
 	}
 }
 
-static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
-	struct sky2_port *sky2 = netdev_priv(dev);
-	struct sky2_hw *hw = sky2->hw;
-	u16 port = sky2->port;
-
-	netif_tx_lock_bh(dev);
-	napi_disable(&hw->napi);
-
-	sky2->vlgrp = grp;
-	sky2_set_vlan_mode(hw, port, grp != NULL);
-
-	sky2_read32(hw, B0_Y2_SP_LISR);
-	napi_enable(&hw->napi);
-	netif_tx_unlock_bh(dev);
-}
-#endif
-
 /* Amount of required worst case padding in rx buffer */
 static inline unsigned sky2_rx_pad(const struct sky2_hw *hw)
 {
@@ -1635,9 +1624,7 @@ static void sky2_hw_up(struct sky2_port
 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
 			   sky2->tx_ring_size - 1);
 
-#ifdef SKY2_VLAN_TAG_USED
-	sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL);
-#endif
+	sky2_vlan_mode(sky2->netdev);
 
 	sky2_rx_start(sky2);
 }
@@ -1780,7 +1767,7 @@ static netdev_tx_t sky2_xmit_frame(struc
 	}
 
 	ctrl = 0;
-#ifdef SKY2_VLAN_TAG_USED
+
 	/* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
 	if (vlan_tx_tag_present(skb)) {
 		if (!le) {
@@ -1792,7 +1779,6 @@ static netdev_tx_t sky2_xmit_frame(struc
 		le->length = cpu_to_be16(vlan_tx_tag_get(skb));
 		ctrl |= INS_VLAN;
 	}
-#endif
 
 	/* Handle TCP checksum offload */
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -2432,11 +2418,8 @@ static struct sk_buff *sky2_receive(stru
 	struct sk_buff *skb = NULL;
 	u16 count = (status & GMR_FS_LEN) >> 16;
 
-#ifdef SKY2_VLAN_TAG_USED
-	/* Account for vlan tag */
-	if (sky2->vlgrp && (status & GMR_FS_VLAN))
-		count -= VLAN_HLEN;
-#endif
+	if (status & GMR_FS_VLAN)
+		count -= VLAN_HLEN; 	/* Account for vlan tag */
 
 	netif_printk(sky2, rx_status, KERN_DEBUG, dev,
 		     "rx slot %u status 0x%x len %d\n",
@@ -2504,17 +2487,9 @@ static inline void sky2_tx_done(struct n
 static inline void sky2_skb_rx(const struct sky2_port *sky2,
 			       u32 status, struct sk_buff *skb)
 {
-#ifdef SKY2_VLAN_TAG_USED
-	u16 vlan_tag = be16_to_cpu(sky2->rx_tag);
-	if (sky2->vlgrp && (status & GMR_FS_VLAN)) {
-		if (skb->ip_summed == CHECKSUM_NONE)
-			vlan_hwaccel_receive_skb(skb, sky2->vlgrp, vlan_tag);
-		else
-			vlan_gro_receive(&sky2->hw->napi, sky2->vlgrp,
-					 vlan_tag, skb);
-		return;
-	}
-#endif
+	if (status & GMR_FS_VLAN)
+		__vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
+
 	if (skb->ip_summed == CHECKSUM_NONE)
 		netif_receive_skb(skb);
 	else
@@ -2631,7 +2606,6 @@ static int sky2_status_intr(struct sky2_
 				goto exit_loop;
 			break;
 
-#ifdef SKY2_VLAN_TAG_USED
 		case OP_RXVLAN:
 			sky2->rx_tag = length;
 			break;
@@ -2639,7 +2613,6 @@ static int sky2_status_intr(struct sky2_
 		case OP_RXCHKSVLAN:
 			sky2->rx_tag = length;
 			/* fall through */
-#endif
 		case OP_RXCHKS:
 			if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
 				sky2_rx_checksum(sky2, status);
@@ -3042,6 +3015,10 @@ static int __devinit sky2_init(struct sk
 			| SKY2_HW_NEW_LE
 			| SKY2_HW_AUTO_TX_SUM
 			| SKY2_HW_ADV_POWER_CTL;
+
+		/* The workaround for status conflicts VLAN tag detection. */
+		if (hw->chip_rev == CHIP_REV_YU_FE2_A0)
+			hw->flags |= SKY2_HW_VLAN_BROKEN;
 		break;
 
 	case CHIP_ID_YUKON_SUPR:
@@ -4237,15 +4214,28 @@ static int sky2_set_eeprom(struct net_de
 static int sky2_set_flags(struct net_device *dev, u32 data)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
-	u32 supported =
-		(sky2->hw->flags & SKY2_HW_RSS_BROKEN) ? 0 : ETH_FLAG_RXHASH;
+	unsigned long old_feat = dev->features;
+	u32 supported = 0;
 	int rc;
 
+	if (!(sky2->hw->flags & SKY2_HW_RSS_BROKEN))
+		supported |= ETH_FLAG_RXHASH;
+
+	if (!(sky2->hw->flags & SKY2_HW_VLAN_BROKEN))
+		supported |= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN;
+
+	printk(KERN_DEBUG "sky2 set_flags: supported %x data %x\n",
+	       supported, data);
+
 	rc = ethtool_op_set_flags(dev, data, supported);
 	if (rc)
 		return rc;
 
-	rx_set_rss(dev);
+	if ((old_feat ^ dev->features) & NETIF_F_RXHASH)
+		rx_set_rss(dev);
+
+	if ((old_feat ^ dev->features) & (NETIF_F_HW_VLAN_RX|NETIF_F_HW_VLAN_TX))
+		sky2_vlan_mode(dev);
 
 	return 0;
 }
@@ -4281,6 +4271,7 @@ static const struct ethtool_ops sky2_eth
 	.get_sset_count = sky2_get_sset_count,
 	.get_ethtool_stats = sky2_get_ethtool_stats,
 	.set_flags	= sky2_set_flags,
+	.get_flags	= ethtool_op_get_flags,
 };
 
 #ifdef CONFIG_SKY2_DEBUG
@@ -4562,9 +4553,6 @@ static const struct net_device_ops sky2_
 	.ndo_change_mtu		= sky2_change_mtu,
 	.ndo_tx_timeout		= sky2_tx_timeout,
 	.ndo_get_stats64	= sky2_get_stats,
-#ifdef SKY2_VLAN_TAG_USED
-	.ndo_vlan_rx_register	= sky2_vlan_rx_register,
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= sky2_netpoll,
 #endif
@@ -4580,9 +4568,6 @@ static const struct net_device_ops sky2_
 	.ndo_change_mtu		= sky2_change_mtu,
 	.ndo_tx_timeout		= sky2_tx_timeout,
 	.ndo_get_stats64	= sky2_get_stats,
-#ifdef SKY2_VLAN_TAG_USED
-	.ndo_vlan_rx_register	= sky2_vlan_rx_register,
-#endif
   },
 };
 
@@ -4633,7 +4618,8 @@ static __devinit struct net_device *sky2
 	sky2->port = port;
 
 	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG
-		| NETIF_F_TSO  | NETIF_F_GRO;
+		| NETIF_F_TSO | NETIF_F_GRO;
+
 	if (highmem)
 		dev->features |= NETIF_F_HIGHDMA;
 
@@ -4641,13 +4627,8 @@ static __devinit struct net_device *sky2
 	if (!(hw->flags & SKY2_HW_RSS_BROKEN))
 		dev->features |= NETIF_F_RXHASH;
 
-#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 &&
-	      sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) {
+	if (!(hw->flags & SKY2_HW_VLAN_BROKEN))
 		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	}
-#endif
 
 	/* read the mac address */
 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
--- a/drivers/net/sky2.h	2011-01-06 17:44:01.939546184 -0800
+++ b/drivers/net/sky2.h	2011-01-06 17:59:12.430966390 -0800
@@ -2236,11 +2236,8 @@ struct sky2_port {
 	u16		     rx_pending;
 	u16		     rx_data_size;
 	u16		     rx_nfrags;
-
-#ifdef SKY2_VLAN_TAG_USED
 	u16		     rx_tag;
-	struct vlan_group    *vlgrp;
-#endif
+
 	struct {
 		unsigned long last;
 		u32	mac_rp;
@@ -2284,6 +2281,7 @@ struct sky2_hw {
 #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
+#define SKY2_HW_VLAN_BROKEN     0x00000200
 
 	u8	     	     chip_id;
 	u8		     chip_rev;

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

* Re: [PATCH 2/2] sky2: convert to new VLAN model
  2011-01-07  4:41 [PATCH 2/2] sky2: convert to new VLAN model Stephen Hemminger
@ 2011-01-07 17:14 ` Jesse Gross
  2011-01-07 17:27   ` Stephen Hemminger
  2011-01-08  4:13   ` [PATCH 2/2] sky2: convert to new VLAN model (v0.2) Stephen Hemminger
  0 siblings, 2 replies; 7+ messages in thread
From: Jesse Gross @ 2011-01-07 17:14 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev

On Thu, Jan 6, 2011 at 11:41 PM, Stephen Hemminger
<shemminger@vyatta.com> wrote:
> +/* Features available on VLAN with transmit tag stripped */
> +#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO)
> +
> +static void sky2_vlan_mode(struct net_device *dev)
>  {
> -       if (onoff) {
> +       struct sky2_port *sky2 = netdev_priv(dev);
> +       struct sky2_hw *hw = sky2->hw;
> +       u16 port = sky2->port;
> +
> +       if (dev->features & NETIF_F_HW_VLAN_RX)
>                sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
>                             RX_VLAN_STRIP_ON);
> +       else
> +               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
> +                            RX_VLAN_STRIP_OFF);
> +
> +       if (dev->features & NETIF_F_HW_VLAN_TX) {
>                sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
>                             TX_VLAN_TAG_ON);
> +               dev->vlan_features = dev->features & VLAN_FEAT;
>        } else {
> -               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
> -                            RX_VLAN_STRIP_OFF);
>                sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
>                             TX_VLAN_TAG_OFF);
> +               dev->vlan_features = dev->features & NETIF_F_HIGHDMA;

Hmm, the chip supports SG only when TX vlan is on and HIGHDMA only
when it is off?  Currently skb_needs_linearize() assumes that when not
using vlan acceleration, the DMA engine doesn't care about the
presence of a vlan tag and directly uses dev->features.

Also, can't we enable NETIF_F_GRO in vlan_features?  It will be set
initially by register_netdevice() but if we change the flags it gets
blown away.

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

* Re: [PATCH 2/2] sky2: convert to new VLAN model
  2011-01-07 17:14 ` Jesse Gross
@ 2011-01-07 17:27   ` Stephen Hemminger
  2011-01-09 15:50     ` Jesse Gross
  2011-01-08  4:13   ` [PATCH 2/2] sky2: convert to new VLAN model (v0.2) Stephen Hemminger
  1 sibling, 1 reply; 7+ messages in thread
From: Stephen Hemminger @ 2011-01-07 17:27 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev

On Fri, 7 Jan 2011 12:14:51 -0500
Jesse Gross <jesse@nicira.com> wrote:

> On Thu, Jan 6, 2011 at 11:41 PM, Stephen Hemminger
> <shemminger@vyatta.com> wrote:
> > +/* Features available on VLAN with transmit tag stripped */
> > +#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO)
> > +
> > +static void sky2_vlan_mode(struct net_device *dev)
> >  {
> > -       if (onoff) {
> > +       struct sky2_port *sky2 = netdev_priv(dev);
> > +       struct sky2_hw *hw = sky2->hw;
> > +       u16 port = sky2->port;
> > +
> > +       if (dev->features & NETIF_F_HW_VLAN_RX)
> >                sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
> >                             RX_VLAN_STRIP_ON);
> > +       else
> > +               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
> > +                            RX_VLAN_STRIP_OFF);
> > +
> > +       if (dev->features & NETIF_F_HW_VLAN_TX) {
> >                sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
> >                             TX_VLAN_TAG_ON);
> > +               dev->vlan_features = dev->features & VLAN_FEAT;
> >        } else {
> > -               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
> > -                            RX_VLAN_STRIP_OFF);
> >                sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
> >                             TX_VLAN_TAG_OFF);
> > +               dev->vlan_features = dev->features & NETIF_F_HIGHDMA;
> 
> Hmm, the chip supports SG only when TX vlan is on and HIGHDMA only
> when it is off?  Currently skb_needs_linearize() assumes that when not
> using vlan acceleration, the DMA engine doesn't care about the
> presence of a vlan tag and directly uses dev->features.

The chip supports checksum offload only if TX_VLAN is enabled.
Scatter/gather without checksum offload is not allowed by kernel
because checksum offload is needed for sendfile.

highdma should always be on

> Also, can't we enable NETIF_F_GRO in vlan_features?  It will be set
> initially by register_netdevice() but if we change the flags it gets
> blown away.

I will revise. GRO is independent of all this.


-- 

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

* [PATCH 2/2] sky2: convert to new VLAN model (v0.2)
  2011-01-07 17:14 ` Jesse Gross
  2011-01-07 17:27   ` Stephen Hemminger
@ 2011-01-08  4:13   ` Stephen Hemminger
  2011-01-09 16:13     ` Jesse Gross
  1 sibling, 1 reply; 7+ messages in thread
From: Stephen Hemminger @ 2011-01-08  4:13 UTC (permalink / raw)
  To: Jesse Gross, David Miller; +Cc: netdev

This converts sky2 to new VLAN offload flags control via ethtool.
It also allows for transmit offload of vlan tagged frames which
was not possible before.

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

---
Changed the setting of vlan_features in this version to keep
non-offload settings (GRO|HIGHDMA) even if vlan offload is not
enabled.

--- a/drivers/net/sky2.c	2011-01-07 20:06:03.082168965 -0800
+++ b/drivers/net/sky2.c	2011-01-07 20:09:06.006180327 -0800
@@ -46,10 +46,6 @@
 
 #include <asm/irq.h>
 
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define SKY2_VLAN_TAG_USED 1
-#endif
-
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
@@ -1326,39 +1322,34 @@ static int sky2_ioctl(struct net_device
 	return err;
 }
 
-#ifdef SKY2_VLAN_TAG_USED
-static void sky2_set_vlan_mode(struct sky2_hw *hw, u16 port, bool onoff)
-{
-	if (onoff) {
-		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
-			     RX_VLAN_STRIP_ON);
-		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-			     TX_VLAN_TAG_ON);
-	} else {
-		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
-			     RX_VLAN_STRIP_OFF);
-		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-			     TX_VLAN_TAG_OFF);
-	}
-}
+#define NETIF_F_ALL_VLAN (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)
 
-static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+static void sky2_vlan_mode(struct net_device *dev)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 	u16 port = sky2->port;
 
-	netif_tx_lock_bh(dev);
-	napi_disable(&hw->napi);
+	if (dev->features & NETIF_F_HW_VLAN_RX)
+		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+			     RX_VLAN_STRIP_ON);
+	else
+		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+			     RX_VLAN_STRIP_OFF);
 
-	sky2->vlgrp = grp;
-	sky2_set_vlan_mode(hw, port, grp != NULL);
+	dev->vlan_features = dev->features &~ NETIF_F_ALL_VLAN;
+	if (dev->features & NETIF_F_HW_VLAN_TX)
+		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+			     TX_VLAN_TAG_ON);
+	else {
+		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+			     TX_VLAN_TAG_OFF);
 
-	sky2_read32(hw, B0_Y2_SP_LISR);
-	napi_enable(&hw->napi);
-	netif_tx_unlock_bh(dev);
+		/* Can't do transmit offload of vlan without hw vlan */
+		dev->vlan_features &= ~(NETIF_F_TSO | NETIF_F_SG
+					| NETIF_F_ALL_CSUM);
+	}
 }
-#endif
 
 /* Amount of required worst case padding in rx buffer */
 static inline unsigned sky2_rx_pad(const struct sky2_hw *hw)
@@ -1635,9 +1626,7 @@ static void sky2_hw_up(struct sky2_port
 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
 			   sky2->tx_ring_size - 1);
 
-#ifdef SKY2_VLAN_TAG_USED
-	sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL);
-#endif
+	sky2_vlan_mode(sky2->netdev);
 
 	sky2_rx_start(sky2);
 }
@@ -1780,7 +1769,7 @@ static netdev_tx_t sky2_xmit_frame(struc
 	}
 
 	ctrl = 0;
-#ifdef SKY2_VLAN_TAG_USED
+
 	/* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
 	if (vlan_tx_tag_present(skb)) {
 		if (!le) {
@@ -1792,7 +1781,6 @@ static netdev_tx_t sky2_xmit_frame(struc
 		le->length = cpu_to_be16(vlan_tx_tag_get(skb));
 		ctrl |= INS_VLAN;
 	}
-#endif
 
 	/* Handle TCP checksum offload */
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -2432,11 +2420,8 @@ static struct sk_buff *sky2_receive(stru
 	struct sk_buff *skb = NULL;
 	u16 count = (status & GMR_FS_LEN) >> 16;
 
-#ifdef SKY2_VLAN_TAG_USED
-	/* Account for vlan tag */
-	if (sky2->vlgrp && (status & GMR_FS_VLAN))
-		count -= VLAN_HLEN;
-#endif
+	if (status & GMR_FS_VLAN)
+		count -= VLAN_HLEN;	/* Account for vlan tag */
 
 	netif_printk(sky2, rx_status, KERN_DEBUG, dev,
 		     "rx slot %u status 0x%x len %d\n",
@@ -2504,17 +2489,9 @@ static inline void sky2_tx_done(struct n
 static inline void sky2_skb_rx(const struct sky2_port *sky2,
 			       u32 status, struct sk_buff *skb)
 {
-#ifdef SKY2_VLAN_TAG_USED
-	u16 vlan_tag = be16_to_cpu(sky2->rx_tag);
-	if (sky2->vlgrp && (status & GMR_FS_VLAN)) {
-		if (skb->ip_summed == CHECKSUM_NONE)
-			vlan_hwaccel_receive_skb(skb, sky2->vlgrp, vlan_tag);
-		else
-			vlan_gro_receive(&sky2->hw->napi, sky2->vlgrp,
-					 vlan_tag, skb);
-		return;
-	}
-#endif
+	if (status & GMR_FS_VLAN)
+		__vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
+
 	if (skb->ip_summed == CHECKSUM_NONE)
 		netif_receive_skb(skb);
 	else
@@ -2631,7 +2608,6 @@ static int sky2_status_intr(struct sky2_
 				goto exit_loop;
 			break;
 
-#ifdef SKY2_VLAN_TAG_USED
 		case OP_RXVLAN:
 			sky2->rx_tag = length;
 			break;
@@ -2639,7 +2615,6 @@ static int sky2_status_intr(struct sky2_
 		case OP_RXCHKSVLAN:
 			sky2->rx_tag = length;
 			/* fall through */
-#endif
 		case OP_RXCHKS:
 			if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
 				sky2_rx_checksum(sky2, status);
@@ -3042,6 +3017,10 @@ static int __devinit sky2_init(struct sk
 			| SKY2_HW_NEW_LE
 			| SKY2_HW_AUTO_TX_SUM
 			| SKY2_HW_ADV_POWER_CTL;
+
+		/* The workaround for status conflicts VLAN tag detection. */
+		if (hw->chip_rev == CHIP_REV_YU_FE2_A0)
+			hw->flags |= SKY2_HW_VLAN_BROKEN;
 		break;
 
 	case CHIP_ID_YUKON_SUPR:
@@ -4237,15 +4216,28 @@ static int sky2_set_eeprom(struct net_de
 static int sky2_set_flags(struct net_device *dev, u32 data)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
-	u32 supported =
-		(sky2->hw->flags & SKY2_HW_RSS_BROKEN) ? 0 : ETH_FLAG_RXHASH;
+	unsigned long old_feat = dev->features;
+	u32 supported = 0;
 	int rc;
 
+	if (!(sky2->hw->flags & SKY2_HW_RSS_BROKEN))
+		supported |= ETH_FLAG_RXHASH;
+
+	if (!(sky2->hw->flags & SKY2_HW_VLAN_BROKEN))
+		supported |= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN;
+
+	printk(KERN_DEBUG "sky2 set_flags: supported %x data %x\n",
+	       supported, data);
+
 	rc = ethtool_op_set_flags(dev, data, supported);
 	if (rc)
 		return rc;
 
-	rx_set_rss(dev);
+	if ((old_feat ^ dev->features) & NETIF_F_RXHASH)
+		rx_set_rss(dev);
+
+	if ((old_feat ^ dev->features) & NETIF_F_ALL_VLAN)
+		sky2_vlan_mode(dev);
 
 	return 0;
 }
@@ -4281,6 +4273,7 @@ static const struct ethtool_ops sky2_eth
 	.get_sset_count = sky2_get_sset_count,
 	.get_ethtool_stats = sky2_get_ethtool_stats,
 	.set_flags	= sky2_set_flags,
+	.get_flags	= ethtool_op_get_flags,
 };
 
 #ifdef CONFIG_SKY2_DEBUG
@@ -4562,9 +4555,6 @@ static const struct net_device_ops sky2_
 	.ndo_change_mtu		= sky2_change_mtu,
 	.ndo_tx_timeout		= sky2_tx_timeout,
 	.ndo_get_stats64	= sky2_get_stats,
-#ifdef SKY2_VLAN_TAG_USED
-	.ndo_vlan_rx_register	= sky2_vlan_rx_register,
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= sky2_netpoll,
 #endif
@@ -4580,9 +4570,6 @@ static const struct net_device_ops sky2_
 	.ndo_change_mtu		= sky2_change_mtu,
 	.ndo_tx_timeout		= sky2_tx_timeout,
 	.ndo_get_stats64	= sky2_get_stats,
-#ifdef SKY2_VLAN_TAG_USED
-	.ndo_vlan_rx_register	= sky2_vlan_rx_register,
-#endif
   },
 };
 
@@ -4633,7 +4620,8 @@ static __devinit struct net_device *sky2
 	sky2->port = port;
 
 	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG
-		| NETIF_F_TSO  | NETIF_F_GRO;
+		| NETIF_F_TSO | NETIF_F_GRO;
+
 	if (highmem)
 		dev->features |= NETIF_F_HIGHDMA;
 
@@ -4641,13 +4629,8 @@ static __devinit struct net_device *sky2
 	if (!(hw->flags & SKY2_HW_RSS_BROKEN))
 		dev->features |= NETIF_F_RXHASH;
 
-#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 &&
-	      sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) {
+	if (!(hw->flags & SKY2_HW_VLAN_BROKEN))
 		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	}
-#endif
 
 	/* read the mac address */
 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
--- a/drivers/net/sky2.h	2011-01-07 20:05:59.982101189 -0800
+++ b/drivers/net/sky2.h	2011-01-07 20:06:03.094169226 -0800
@@ -2236,11 +2236,8 @@ struct sky2_port {
 	u16		     rx_pending;
 	u16		     rx_data_size;
 	u16		     rx_nfrags;
-
-#ifdef SKY2_VLAN_TAG_USED
 	u16		     rx_tag;
-	struct vlan_group    *vlgrp;
-#endif
+
 	struct {
 		unsigned long last;
 		u32	mac_rp;
@@ -2284,6 +2281,7 @@ struct sky2_hw {
 #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
+#define SKY2_HW_VLAN_BROKEN     0x00000200
 
 	u8	     	     chip_id;
 	u8		     chip_rev;

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

* Re: [PATCH 2/2] sky2: convert to new VLAN model
  2011-01-07 17:27   ` Stephen Hemminger
@ 2011-01-09 15:50     ` Jesse Gross
  0 siblings, 0 replies; 7+ messages in thread
From: Jesse Gross @ 2011-01-09 15:50 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev

On Fri, Jan 7, 2011 at 12:27 PM, Stephen Hemminger
<shemminger@vyatta.com> wrote:
> On Fri, 7 Jan 2011 12:14:51 -0500
> Jesse Gross <jesse@nicira.com> wrote:
>
>> On Thu, Jan 6, 2011 at 11:41 PM, Stephen Hemminger
>> <shemminger@vyatta.com> wrote:
>> > +/* Features available on VLAN with transmit tag stripped */
>> > +#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO)
>> > +
>> > +static void sky2_vlan_mode(struct net_device *dev)
>> >  {
>> > -       if (onoff) {
>> > +       struct sky2_port *sky2 = netdev_priv(dev);
>> > +       struct sky2_hw *hw = sky2->hw;
>> > +       u16 port = sky2->port;
>> > +
>> > +       if (dev->features & NETIF_F_HW_VLAN_RX)
>> >                sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
>> >                             RX_VLAN_STRIP_ON);
>> > +       else
>> > +               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
>> > +                            RX_VLAN_STRIP_OFF);
>> > +
>> > +       if (dev->features & NETIF_F_HW_VLAN_TX) {
>> >                sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
>> >                             TX_VLAN_TAG_ON);
>> > +               dev->vlan_features = dev->features & VLAN_FEAT;
>> >        } else {
>> > -               sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
>> > -                            RX_VLAN_STRIP_OFF);
>> >                sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
>> >                             TX_VLAN_TAG_OFF);
>> > +               dev->vlan_features = dev->features & NETIF_F_HIGHDMA;
>>
>> Hmm, the chip supports SG only when TX vlan is on and HIGHDMA only
>> when it is off?  Currently skb_needs_linearize() assumes that when not
>> using vlan acceleration, the DMA engine doesn't care about the
>> presence of a vlan tag and directly uses dev->features.
>
> The chip supports checksum offload only if TX_VLAN is enabled.
> Scatter/gather without checksum offload is not allowed by kernel
> because checksum offload is needed for sendfile.

OK, it sounds like skb_needs_linearize() needs to be more intelligent.
 I will send a patch for that shortly.

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

* Re: [PATCH 2/2] sky2: convert to new VLAN model (v0.2)
  2011-01-08  4:13   ` [PATCH 2/2] sky2: convert to new VLAN model (v0.2) Stephen Hemminger
@ 2011-01-09 16:13     ` Jesse Gross
  2011-01-09 23:54       ` David Miller
  0 siblings, 1 reply; 7+ messages in thread
From: Jesse Gross @ 2011-01-09 16:13 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev

On Fri, Jan 7, 2011 at 11:13 PM, Stephen Hemminger
<shemminger@vyatta.com> wrote:
> This converts sky2 to new VLAN offload flags control via ethtool.
> It also allows for transmit offload of vlan tagged frames which
> was not possible before.
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
> ---
> Changed the setting of vlan_features in this version to keep
> non-offload settings (GRO|HIGHDMA) even if vlan offload is not
> enabled.

Thanks Stephen.

Reviewed-by: Jesse Gross <jesse@nicira.com>

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

* Re: [PATCH 2/2] sky2: convert to new VLAN model (v0.2)
  2011-01-09 16:13     ` Jesse Gross
@ 2011-01-09 23:54       ` David Miller
  0 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2011-01-09 23:54 UTC (permalink / raw)
  To: jesse; +Cc: shemminger, netdev

From: Jesse Gross <jesse@nicira.com>
Date: Sun, 9 Jan 2011 11:13:31 -0500

> On Fri, Jan 7, 2011 at 11:13 PM, Stephen Hemminger
> <shemminger@vyatta.com> wrote:
>> This converts sky2 to new VLAN offload flags control via ethtool.
>> It also allows for transmit offload of vlan tagged frames which
>> was not possible before.
>>
>> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>>
>> ---
>> Changed the setting of vlan_features in this version to keep
>> non-offload settings (GRO|HIGHDMA) even if vlan offload is not
>> enabled.
> 
> Thanks Stephen.
> 
> Reviewed-by: Jesse Gross <jesse@nicira.com>

Applied, thanks everyone.

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

end of thread, other threads:[~2011-01-09 23:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-07  4:41 [PATCH 2/2] sky2: convert to new VLAN model Stephen Hemminger
2011-01-07 17:14 ` Jesse Gross
2011-01-07 17:27   ` Stephen Hemminger
2011-01-09 15:50     ` Jesse Gross
2011-01-08  4:13   ` [PATCH 2/2] sky2: convert to new VLAN model (v0.2) Stephen Hemminger
2011-01-09 16:13     ` Jesse Gross
2011-01-09 23:54       ` 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).