All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/14] Move vlan acceleration into networking core.
@ 2010-10-20 23:56 Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 01/14] ebtables: Allow filtering of hardware accelerated vlan frames Jesse Gross
                   ` (15 more replies)
  0 siblings, 16 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Hardware vlan acceleration behaves fairly differently from other types of
offloading, which limits its usefulness.  This patch series aims to bring
it more in line with other common forms of acceleration, such as checksum
offloading and TSO.  In doing this it eliminates common driver bugs, increases
flexibility, and improves performance, while reducing the number of lines of
code.

The first eleven patches can be applied immediately, while the last three need
to wait until all drivers that support vlan acceleration are updated.  If
people agree that this patch set makes sense I will go ahead and switch over
the dozen or so drivers that would need to change.

Changes since v1:
 * Break apart patches and use temporary variables for better readibility.
 * Use rcu_dereference_rtnl() in vlan_find_dev().
 * Restructure netif_needs_gso() for better common case performance.
 * Make ebtables consistently use the outer vlan tag if two are present.
 * Drop check for vlan group on transmit in all drivers.
 * Send vlan traffic through __netif_receive_skb both tagged and untagged for
   consistent results between accelerated and non-acclerated traffic.
 * Add support for Ethtool.
 * Enable vlan accleration on bridge devices.
 * Convert bnx2x driver.

Hao Zheng (1):
  bnx2x: Update bnx2x to use new vlan accleration.

Jesse Gross (13):
  ebtables: Allow filtering of hardware accelerated vlan frames.
  vlan: Rename VLAN_GROUP_ARRAY_LEN to VLAN_N_VID.
  vlan: Don't check for vlan group before vlan_tx_tag_present.
  vlan: Enable software emulation for vlan accleration.
  vlan: Avoid hash table lookup to find group.
  vlan: Centralize handling of hardware acceleration.
  ethtool: Add support for vlan accleration.
  bridge: Add support for TX vlan offload.
  bnx2: Update bnx2 to use new vlan accleration.
  ixgbe: Update ixgbe to use new vlan accleration.
  lro: Remove explicit vlan support.
  bonding: Update bonding for new vlan model.
  vlan: Remove accleration legacy functions.

 drivers/net/8139cp.c               |    2 +-
 drivers/net/amd8111e.c             |    2 +-
 drivers/net/atl1c/atl1c_main.c     |    2 +-
 drivers/net/atl1e/atl1e_main.c     |    2 +-
 drivers/net/atlx/atl1.c            |    2 +-
 drivers/net/atlx/atl2.c            |    2 +-
 drivers/net/benet/be.h             |    2 +-
 drivers/net/benet/be_main.c        |    9 +-
 drivers/net/bna/bnad.c             |    2 +-
 drivers/net/bnx2.c                 |   99 +++++++------------------
 drivers/net/bnx2.h                 |    4 -
 drivers/net/bnx2x/bnx2x.h          |   10 ---
 drivers/net/bnx2x/bnx2x_cmn.c      |   63 +++-------------
 drivers/net/bnx2x/bnx2x_ethtool.c  |   33 ++++----
 drivers/net/bnx2x/bnx2x_main.c     |    8 --
 drivers/net/bonding/bond_alb.c     |    8 +-
 drivers/net/bonding/bond_ipv6.c    |    5 +-
 drivers/net/bonding/bond_main.c    |  143 +++++++-----------------------------
 drivers/net/bonding/bonding.h      |    1 -
 drivers/net/chelsio/sge.c          |    2 +-
 drivers/net/cxgb3/sge.c            |    4 +-
 drivers/net/e1000/e1000_main.c     |    4 +-
 drivers/net/e1000e/netdev.c        |    4 +-
 drivers/net/ehea/ehea_main.c       |    2 +-
 drivers/net/enic/enic_main.c       |    2 +-
 drivers/net/forcedeth.c            |   11 +--
 drivers/net/gianfar.c              |    4 +-
 drivers/net/igb/igb_main.c         |    4 +-
 drivers/net/igbvf/netdev.c         |    2 +-
 drivers/net/ixgb/ixgb_main.c       |    2 +-
 drivers/net/ixgbe/ixgbe.h          |    4 +-
 drivers/net/ixgbe/ixgbe_ethtool.c  |   12 +++-
 drivers/net/ixgbe/ixgbe_main.c     |  139 +++++++++++++++-------------------
 drivers/net/ixgbevf/ixgbevf_main.c |    4 +-
 drivers/net/mlx4/en_tx.c           |    4 +-
 drivers/net/qlcnic/qlcnic_main.c   |    2 +-
 drivers/net/qlge/qlge_main.c       |    2 +-
 drivers/net/r8169.c                |    2 +-
 drivers/net/s2io.c                 |    2 +-
 drivers/net/sky2.c                 |    2 +-
 drivers/net/tg3.c                  |    4 +-
 drivers/net/via-velocity.c         |    2 +-
 drivers/net/vmxnet3/vmxnet3_drv.c  |    2 +-
 drivers/net/vxge/vxge-main.c       |    4 +-
 drivers/s390/net/qeth_l3_main.c    |    6 +-
 include/linux/ethtool.h            |    2 +
 include/linux/if_vlan.h            |   88 +++++++---------------
 include/linux/inet_lro.h           |   20 -----
 include/linux/netdevice.h          |   28 ++++---
 net/8021q/vlan.c                   |   84 ++++-----------------
 net/8021q/vlan.h                   |   17 ----
 net/8021q/vlan_core.c              |  132 +++++----------------------------
 net/8021q/vlan_dev.c               |    2 +-
 net/bridge/br_device.c             |    8 ++-
 net/bridge/br_netfilter.c          |   16 ++--
 net/bridge/netfilter/ebt_vlan.c    |   25 ++++--
 net/bridge/netfilter/ebtables.c    |   15 +++-
 net/core/dev.c                     |   83 ++++++++++++---------
 net/core/ethtool.c                 |    3 +-
 net/ipv4/inet_lro.c                |   74 +++----------------
 60 files changed, 395 insertions(+), 833 deletions(-)


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

* [PATCH v2 01/14] ebtables: Allow filtering of hardware accelerated vlan frames.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 02/14] vlan: Rename VLAN_GROUP_ARRAY_LEN to VLAN_N_VID Jesse Gross
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

An upcoming commit will allow packets with hardware vlan acceleration
information to be passed though more parts of the network stack, including
packets trunked through the bridge.  This adds support for matching and
filtering those packets through ebtables.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 net/bridge/br_netfilter.c       |   16 +++++++++-------
 net/bridge/netfilter/ebt_vlan.c |   21 ++++++++++++++-------
 net/bridge/netfilter/ebtables.c |   15 +++++++++++----
 3 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 7f9ce96..47c2dab 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -64,22 +64,24 @@ static int brnf_filter_pppoe_tagged __read_mostly = 0;
 
 static inline __be16 vlan_proto(const struct sk_buff *skb)
 {
-	return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+	if (vlan_tx_tag_present(skb))
+		return skb->protocol;
+	else if (skb->protocol == htons(ETH_P_8021Q))
+		return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+	else
+		return 0;
 }
 
 #define IS_VLAN_IP(skb) \
-	(skb->protocol == htons(ETH_P_8021Q) && \
-	 vlan_proto(skb) == htons(ETH_P_IP) && 	\
+	(vlan_proto(skb) == htons(ETH_P_IP) && \
 	 brnf_filter_vlan_tagged)
 
 #define IS_VLAN_IPV6(skb) \
-	(skb->protocol == htons(ETH_P_8021Q) && \
-	 vlan_proto(skb) == htons(ETH_P_IPV6) &&\
+	(vlan_proto(skb) == htons(ETH_P_IPV6) && \
 	 brnf_filter_vlan_tagged)
 
 #define IS_VLAN_ARP(skb) \
-	(skb->protocol == htons(ETH_P_8021Q) &&	\
-	 vlan_proto(skb) == htons(ETH_P_ARP) &&	\
+	(vlan_proto(skb) == htons(ETH_P_ARP) &&	\
 	 brnf_filter_vlan_tagged)
 
 static inline __be16 pppoe_proto(const struct sk_buff *skb)
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
index 87b53b3..cc11d6b 100644
--- a/net/bridge/netfilter/ebt_vlan.c
+++ b/net/bridge/netfilter/ebt_vlan.c
@@ -39,8 +39,6 @@ static bool
 ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
 	const struct ebt_vlan_info *info = par->matchinfo;
-	const struct vlan_hdr *fp;
-	struct vlan_hdr _frame;
 
 	unsigned short TCI;	/* Whole TCI, given from parsed frame */
 	unsigned short id;	/* VLAN ID, given from frame TCI */
@@ -48,9 +46,20 @@ ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par)
 	/* VLAN encapsulated Type/Length field, given from orig frame */
 	__be16 encap;
 
-	fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
-	if (fp == NULL)
-		return false;
+	if (vlan_tx_tag_present(skb)) {
+		TCI = vlan_tx_tag_get(skb);
+		encap = skb->protocol;
+	} else {
+		const struct vlan_hdr *fp;
+		struct vlan_hdr _frame;
+
+		fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
+		if (fp == NULL)
+			return false;
+
+		TCI = ntohs(fp->h_vlan_TCI);
+		encap = fp->h_vlan_encapsulated_proto;
+	}
 
 	/* Tag Control Information (TCI) consists of the following elements:
 	 * - User_priority. The user_priority field is three bits in length,
@@ -59,10 +68,8 @@ ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par)
 	 * (CFI) is a single bit flag value. Currently ignored.
 	 * - VLAN Identifier (VID). The VID is encoded as
 	 * an unsigned binary number. */
-	TCI = ntohs(fp->h_vlan_TCI);
 	id = TCI & VLAN_VID_MASK;
 	prio = (TCI >> 13) & 0x7;
-	encap = fp->h_vlan_encapsulated_proto;
 
 	/* Checking VLAN Identifier (VID) */
 	if (GET_BITMASK(EBT_VLAN_ID))
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index bcc102e..a1dcf83 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -124,16 +124,23 @@ ebt_dev_check(const char *entry, const struct net_device *device)
 #define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg))
 /* process standard matches */
 static inline int
-ebt_basic_match(const struct ebt_entry *e, const struct ethhdr *h,
+ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb,
                 const struct net_device *in, const struct net_device *out)
 {
+	const struct ethhdr *h = eth_hdr(skb);
+	__be16 ethproto;
 	int verdict, i;
 
+	if (vlan_tx_tag_present(skb))
+		ethproto = htons(ETH_P_8021Q);
+	else
+		ethproto = h->h_proto;
+
 	if (e->bitmask & EBT_802_3) {
-		if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO))
+		if (FWINV2(ntohs(ethproto) >= 1536, EBT_IPROTO))
 			return 1;
 	} else if (!(e->bitmask & EBT_NOPROTO) &&
-	   FWINV2(e->ethproto != h->h_proto, EBT_IPROTO))
+	   FWINV2(e->ethproto != ethproto, EBT_IPROTO))
 		return 1;
 
 	if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN))
@@ -213,7 +220,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
 	base = private->entries;
 	i = 0;
 	while (i < nentries) {
-		if (ebt_basic_match(point, eth_hdr(skb), in, out))
+		if (ebt_basic_match(point, skb, in, out))
 			goto letscontinue;
 
 		if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &acpar) != 0)
-- 
1.7.1


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

* [PATCH v2 02/14] vlan: Rename VLAN_GROUP_ARRAY_LEN to VLAN_N_VID.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 01/14] ebtables: Allow filtering of hardware accelerated vlan frames Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 03/14] vlan: Don't check for vlan group before vlan_tx_tag_present Jesse Gross
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

VLAN_GROUP_ARRAY_LEN is simply the number of possible vlan VIDs.
Since vlan groups will soon be more of an implementation detail
for vlan devices, rename the constant to be descriptive of its
actual purpose.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 drivers/net/benet/be.h             |    2 +-
 drivers/net/benet/be_main.c        |    2 +-
 drivers/net/e1000/e1000_main.c     |    2 +-
 drivers/net/e1000e/netdev.c        |    2 +-
 drivers/net/igb/igb_main.c         |    2 +-
 drivers/net/igbvf/netdev.c         |    2 +-
 drivers/net/ixgb/ixgb_main.c       |    2 +-
 drivers/net/ixgbe/ixgbe_main.c     |    2 +-
 drivers/net/ixgbevf/ixgbevf_main.c |    2 +-
 drivers/net/qlcnic/qlcnic_main.c   |    2 +-
 drivers/net/vmxnet3/vmxnet3_drv.c  |    2 +-
 drivers/net/vxge/vxge-main.c       |    2 +-
 drivers/s390/net/qeth_l3_main.c    |    6 +++---
 include/linux/if_vlan.h            |    4 ++--
 net/8021q/vlan.c                   |   16 ++++++++--------
 net/bridge/netfilter/ebt_vlan.c    |    4 ++--
 16 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 1afabb1..59a17b5 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -263,7 +263,7 @@ struct be_adapter {
 	struct vlan_group *vlan_grp;
 	u16 vlans_added;
 	u16 max_vlans;	/* Number of vlans supported */
-	u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
+	u8 vlan_tag[VLAN_N_VID];
 	struct be_dma_mem mc_cmd_mem;
 
 	struct be_dma_mem stats_cmd;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 9a1cd28..4b59e53 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -626,7 +626,7 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
 
 	if (adapter->vlans_added <= adapter->max_vlans)  {
 		/* Construct VLAN Table to give to HW */
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+		for (i = 0; i < VLAN_N_VID; i++) {
 			if (adapter->vlan_tag[i]) {
 				vtag[ntags] = cpu_to_le16(i);
 				ntags++;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index cb3f84b..232ac2d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -4541,7 +4541,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter)
 
 	if (adapter->vlgrp) {
 		u16 vid;
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		for (vid = 0; vid < VLAN_N_VID; vid++) {
 			if (!vlan_group_get_device(adapter->vlgrp, vid))
 				continue;
 			e1000_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 992b622..5d6cdea 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2545,7 +2545,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter)
 	if (!adapter->vlgrp)
 		return;
 
-	for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+	for (vid = 0; vid < VLAN_N_VID; vid++) {
 		if (!vlan_group_get_device(adapter->vlgrp, vid))
 			continue;
 		e1000_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index b8dccc0..0f0939c 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -6153,7 +6153,7 @@ static void igb_restore_vlan(struct igb_adapter *adapter)
 
 	if (adapter->vlgrp) {
 		u16 vid;
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		for (vid = 0; vid < VLAN_N_VID; vid++) {
 			if (!vlan_group_get_device(adapter->vlgrp, vid))
 				continue;
 			igb_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index 6693323..ebfaa68 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -1254,7 +1254,7 @@ static void igbvf_restore_vlan(struct igbvf_adapter *adapter)
 	if (!adapter->vlgrp)
 		return;
 
-	for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+	for (vid = 0; vid < VLAN_N_VID; vid++) {
 		if (!vlan_group_get_device(adapter->vlgrp, vid))
 			continue;
 		igbvf_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 80e6257..666207a 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -2223,7 +2223,7 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter)
 
 	if (adapter->vlgrp) {
 		u16 vid;
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		for (vid = 0; vid < VLAN_N_VID; vid++) {
 			if (!vlan_group_get_device(adapter->vlgrp, vid))
 				continue;
 			ixgb_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 790a0da..1d42442 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -3185,7 +3185,7 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
 
 	if (adapter->vlgrp) {
 		u16 vid;
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		for (vid = 0; vid < VLAN_N_VID; vid++) {
 			if (!vlan_group_get_device(adapter->vlgrp, vid))
 				continue;
 			ixgbe_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 0866a1c..78bfbe4 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -1495,7 +1495,7 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
 
 	if (adapter->vlgrp) {
 		u16 vid;
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		for (vid = 0; vid < VLAN_N_VID; vid++) {
 			if (!vlan_group_get_device(adapter->vlgrp, vid))
 				continue;
 			ixgbevf_vlan_rx_add_vid(adapter->netdev, vid);
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 4aada0b..f047c7c 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -4093,7 +4093,7 @@ qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event)
 	if (!adapter->vlgrp)
 		return;
 
-	for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+	for (vid = 0; vid < VLAN_N_VID; vid++) {
 		dev = vlan_group_get_device(adapter->vlgrp, vid);
 		if (!dev)
 			continue;
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 198ce92..b1de73b 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -1634,7 +1634,7 @@ vmxnet3_restore_vlan(struct vmxnet3_adapter *adapter)
 		u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
 		bool activeVlan = false;
 
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		for (vid = 0; vid < VLAN_N_VID; vid++) {
 			if (vlan_group_get_device(adapter->vlan_grp, vid)) {
 				VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
 				activeVlan = true;
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 5378b84..0bda7fe 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -1862,7 +1862,7 @@ enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath)
 
 	if (vdev->vlgrp && vpath->is_open) {
 
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+		for (vid = 0; vid < VLAN_N_VID; vid++) {
 			if (!vlan_group_get_device(vdev->vlgrp, vid))
 				continue;
 			/* Add these vlan to the vid table */
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index c094707..74d1401 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1820,7 +1820,7 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card)
 		return;
 
 	vg = card->vlangrp;
-	for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+	for (i = 0; i < VLAN_N_VID; i++) {
 		struct net_device *netdev = vlan_group_get_device(vg, i);
 		if (netdev == NULL ||
 		    !(netdev->flags & IFF_UP))
@@ -1883,7 +1883,7 @@ static void qeth_l3_add_vlan_mc6(struct qeth_card *card)
 		return;
 
 	vg = card->vlangrp;
-	for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+	for (i = 0; i < VLAN_N_VID; i++) {
 		struct net_device *netdev = vlan_group_get_device(vg, i);
 		if (netdev == NULL ||
 		    !(netdev->flags & IFF_UP))
@@ -2247,7 +2247,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev,
 	if (!vg)
 		return rc;
 
-	for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+	for (i = 0; i < VLAN_N_VID; i++) {
 		if (vlan_group_get_device(vg, i) == dev) {
 			rc = QETH_VLAN_CARD;
 			break;
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index a523207..494cce8 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -68,6 +68,7 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
 #define VLAN_CFI_MASK		0x1000 /* Canonical Format Indicator */
 #define VLAN_TAG_PRESENT	VLAN_CFI_MASK
 #define VLAN_VID_MASK		0x0fff /* VLAN Identifier */
+#define VLAN_N_VID		4096
 
 /* found in socket.c */
 extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
@@ -76,9 +77,8 @@ extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
  * depends on completely exhausting the VLAN identifier space.  Thus
  * it gives constant time look-up, but in many cases it wastes memory.
  */
-#define VLAN_GROUP_ARRAY_LEN          4096
 #define VLAN_GROUP_ARRAY_SPLIT_PARTS  8
-#define VLAN_GROUP_ARRAY_PART_LEN     (VLAN_GROUP_ARRAY_LEN/VLAN_GROUP_ARRAY_SPLIT_PARTS)
+#define VLAN_GROUP_ARRAY_PART_LEN     (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS)
 
 struct vlan_group {
 	struct net_device	*real_dev; /* The ethernet(like) device
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 25c2133..54f22d8 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -439,7 +439,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 	switch (event) {
 	case NETDEV_CHANGE:
 		/* Propagate real device state to vlan devices */
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+		for (i = 0; i < VLAN_N_VID; i++) {
 			vlandev = vlan_group_get_device(grp, i);
 			if (!vlandev)
 				continue;
@@ -450,7 +450,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 
 	case NETDEV_CHANGEADDR:
 		/* Adjust unicast filters on underlying device */
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+		for (i = 0; i < VLAN_N_VID; i++) {
 			vlandev = vlan_group_get_device(grp, i);
 			if (!vlandev)
 				continue;
@@ -464,7 +464,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 		break;
 
 	case NETDEV_CHANGEMTU:
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+		for (i = 0; i < VLAN_N_VID; i++) {
 			vlandev = vlan_group_get_device(grp, i);
 			if (!vlandev)
 				continue;
@@ -478,7 +478,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 
 	case NETDEV_FEAT_CHANGE:
 		/* Propagate device features to underlying device */
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+		for (i = 0; i < VLAN_N_VID; i++) {
 			vlandev = vlan_group_get_device(grp, i);
 			if (!vlandev)
 				continue;
@@ -490,7 +490,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 
 	case NETDEV_DOWN:
 		/* Put all VLANs for this dev in the down state too.  */
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+		for (i = 0; i < VLAN_N_VID; i++) {
 			vlandev = vlan_group_get_device(grp, i);
 			if (!vlandev)
 				continue;
@@ -508,7 +508,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 
 	case NETDEV_UP:
 		/* Put all VLANs for this dev in the up state too.  */
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+		for (i = 0; i < VLAN_N_VID; i++) {
 			vlandev = vlan_group_get_device(grp, i);
 			if (!vlandev)
 				continue;
@@ -532,7 +532,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 		/* Delete all VLANs for this dev. */
 		grp->killall = 1;
 
-		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+		for (i = 0; i < VLAN_N_VID; i++) {
 			vlandev = vlan_group_get_device(grp, i);
 			if (!vlandev)
 				continue;
@@ -540,7 +540,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 			/* unregistration of last vlan destroys group, abort
 			 * afterwards */
 			if (grp->nr_vlans == 1)
-				i = VLAN_GROUP_ARRAY_LEN;
+				i = VLAN_N_VID;
 
 			unregister_vlan_dev(vlandev, &list);
 		}
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
index cc11d6b..eae67bf 100644
--- a/net/bridge/netfilter/ebt_vlan.c
+++ b/net/bridge/netfilter/ebt_vlan.c
@@ -118,10 +118,10 @@ static int ebt_vlan_mt_check(const struct xt_mtchk_param *par)
 	 * 0 - The null VLAN ID.
 	 * 1 - The default Port VID (PVID)
 	 * 0x0FFF - Reserved for implementation use.
-	 * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096. */
+	 * if_vlan.h: VLAN_N_VID 4096. */
 	if (GET_BITMASK(EBT_VLAN_ID)) {
 		if (!!info->id) { /* if id!=0 => check vid range */
-			if (info->id > VLAN_GROUP_ARRAY_LEN) {
+			if (info->id > VLAN_N_VID) {
 				pr_debug("id %d is out of range (1-4096)\n",
 					 info->id);
 				return -EINVAL;
-- 
1.7.1


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

* [PATCH v2 03/14] vlan: Don't check for vlan group before vlan_tx_tag_present.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 01/14] ebtables: Allow filtering of hardware accelerated vlan frames Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 02/14] vlan: Rename VLAN_GROUP_ARRAY_LEN to VLAN_N_VID Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration Jesse Gross
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Many (but not all) drivers check to see whether there is a vlan
group configured before using a tag stored in the skb.  There's
not much point in this check since it just throws away data that
should only be present in the expected circumstances.  However,
it will soon be legal and expected to get a vlan tag when no
vlan group is configured, so remove this check from all drivers
to avoid dropping the tags.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 drivers/net/8139cp.c               |    2 +-
 drivers/net/amd8111e.c             |    2 +-
 drivers/net/atl1c/atl1c_main.c     |    2 +-
 drivers/net/atl1e/atl1e_main.c     |    2 +-
 drivers/net/atlx/atl1.c            |    2 +-
 drivers/net/atlx/atl2.c            |    2 +-
 drivers/net/benet/be_main.c        |    7 +++----
 drivers/net/bna/bnad.c             |    2 +-
 drivers/net/bnx2.c                 |    2 +-
 drivers/net/bnx2x/bnx2x_cmn.c      |    3 +--
 drivers/net/chelsio/sge.c          |    2 +-
 drivers/net/cxgb3/sge.c            |    4 ++--
 drivers/net/e1000/e1000_main.c     |    2 +-
 drivers/net/e1000e/netdev.c        |    2 +-
 drivers/net/ehea/ehea_main.c       |    2 +-
 drivers/net/enic/enic_main.c       |    2 +-
 drivers/net/forcedeth.c            |   11 ++++-------
 drivers/net/gianfar.c              |    4 ++--
 drivers/net/igb/igb_main.c         |    2 +-
 drivers/net/ixgbe/ixgbe_main.c     |    2 +-
 drivers/net/ixgbevf/ixgbevf_main.c |    2 +-
 drivers/net/mlx4/en_tx.c           |    4 ++--
 drivers/net/qlge/qlge_main.c       |    2 +-
 drivers/net/r8169.c                |    2 +-
 drivers/net/s2io.c                 |    2 +-
 drivers/net/sky2.c                 |    2 +-
 drivers/net/tg3.c                  |    4 ++--
 drivers/net/via-velocity.c         |    2 +-
 drivers/net/vxge/vxge-main.c       |    2 +-
 29 files changed, 38 insertions(+), 43 deletions(-)

diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 237d4ea..ac422cd 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -754,7 +754,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
 	}
 
 #if CP_VLAN_TAG_USED
-	if (cp->vlgrp && vlan_tx_tag_present(skb))
+	if (vlan_tx_tag_present(skb))
 		vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb));
 #endif
 
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 58a0ab4..2ca880b 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1315,7 +1315,7 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
 	lp->tx_ring[tx_index].tx_flags = 0;
 
 #if AMD8111E_VLAN_TAG_USED
-	if((lp->vlgrp != NULL) && vlan_tx_tag_present(skb)){
+	if (vlan_tx_tag_present(skb)) {
 		lp->tx_ring[tx_index].tag_ctrl_cmd |=
 				cpu_to_le16(TCC_VLAN_INSERT);
 		lp->tx_ring[tx_index].tag_ctrl_info =
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index 553230e..99ffcf6 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -2243,7 +2243,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
 		return NETDEV_TX_OK;
 	}
 
-	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+	if (unlikely(vlan_tx_tag_present(skb))) {
 		u16 vlan = vlan_tx_tag_get(skb);
 		__le16 tag;
 
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 56ace3f..ef6349b 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1814,7 +1814,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb,
 
 	tpd = atl1e_get_tpd(adapter);
 
-	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+	if (unlikely(vlan_tx_tag_present(skb))) {
 		u16 vlan_tag = vlan_tx_tag_get(skb);
 		u16 atl1e_vlan_tag;
 
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index b8c053f..dbd27b8 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2408,7 +2408,7 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
 		(u16) atomic_read(&tpd_ring->next_to_use));
 	memset(ptpd, 0, sizeof(struct tx_packet_desc));
 
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		vlan_tag = vlan_tx_tag_get(skb);
 		vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
 			((vlan_tag >> 9) & 0x8);
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 29c0265..35b14be 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -870,7 +870,7 @@ static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb,
 		offset = ((u32)(skb->len-copy_len + 3) & ~3);
 	}
 #ifdef NETIF_F_HW_VLAN_TX
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		u16 vlan_tag = vlan_tx_tag_get(skb);
 		vlan_tag = (vlan_tag << 4) |
 			(vlan_tag >> 13) |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 4b59e53..d5e7968 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -430,7 +430,7 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
 }
 
 static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
-		bool vlan, u32 wrb_cnt, u32 len)
+		u32 wrb_cnt, u32 len)
 {
 	memset(hdr, 0, sizeof(*hdr));
 
@@ -449,7 +449,7 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
 			AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
 	}
 
-	if (vlan && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
 		AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag,
 			hdr, vlan_tx_tag_get(skb));
@@ -532,8 +532,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
 		queue_head_inc(txq);
 	}
 
-	wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false,
-		wrb_cnt, copied);
+	wrb_fill_hdr(hdr, first_skb, wrb_cnt, copied);
 	be_dws_cpu_to_le(hdr, sizeof(*hdr));
 
 	return copied;
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c
index 74c64d6..7e839b9 100644
--- a/drivers/net/bna/bnad.c
+++ b/drivers/net/bna/bnad.c
@@ -2501,7 +2501,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 		htons((skb_is_gso(skb) ? BNA_TXQ_WI_SEND_LSO :
 		       BNA_TXQ_WI_SEND));
 
-	if (bnad->vlan_grp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		vlan_tag = (u16) vlan_tx_tag_get(skb);
 		flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN);
 	}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index ae894bc..363ca8b 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -6429,7 +6429,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 #ifdef BCM_VLAN
-	if (bp->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		vlan_tag_flags |=
 			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
 	}
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 1966cee..6905b2e 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -2026,8 +2026,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	   pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
 
 #ifdef BCM_VLAN
-	if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) &&
-	    (bp->flags & HW_VLAN_TX_FLAG)) {
+	if (vlan_tx_tag_present(skb)) {
 		tx_start_bd->vlan_or_ethertype =
 		    cpu_to_le16(vlan_tx_tag_get(skb));
 		tx_start_bd->bd_flags.as_bitfield |=
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 340b537..70221ca 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1870,7 +1870,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	cpl->iff = dev->if_port;
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-	if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		cpl->vlan_valid = 1;
 		cpl->vlan = htons(vlan_tx_tag_get(skb));
 		st->vlan_insert++;
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index c5a142b..7ad4625 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1145,7 +1145,7 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
 	cpl->len = htonl(skb->len);
 	cntrl = V_TXPKT_INTF(pi->port_id);
 
-	if (vlan_tx_tag_present(skb) && pi->vlan_grp)
+	if (vlan_tx_tag_present(skb))
 		cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(vlan_tx_tag_get(skb));
 
 	tso_info = V_LSO_MSS(skb_shinfo(skb)->gso_size);
@@ -1279,7 +1279,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 		qs->port_stats[SGE_PSTAT_TX_CSUM]++;
 	if (skb_shinfo(skb)->gso_size)
 		qs->port_stats[SGE_PSTAT_TSO]++;
-	if (vlan_tx_tag_present(skb) && pi->vlan_grp)
+	if (vlan_tx_tag_present(skb))
 		qs->port_stats[SGE_PSTAT_VLANINS]++;
 
 	/*
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 232ac2d..a117f2a 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3119,7 +3119,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 		}
 	}
 
-	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+	if (unlikely(vlan_tx_tag_present(skb))) {
 		tx_flags |= E1000_TX_FLAGS_VLAN;
 		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
 	}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 5d6cdea..ec8cf3f 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4800,7 +4800,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 	if (e1000_maybe_stop_tx(netdev, count + 2))
 		return NETDEV_TX_BUSY;
 
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		tx_flags |= E1000_TX_FLAGS_VLAN;
 		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
 	}
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 6932578..a0d1170 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2272,7 +2272,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	pr->swqe_id_counter += 1;
 
-	if (port->vgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		swqe->tx_control |= EHEA_SWQE_VLAN_INSERT;
 		swqe->vlan_tag = vlan_tx_tag_get(skb);
 	}
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index a1f92f1..cfb6db4 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -743,7 +743,7 @@ static inline void enic_queue_wq_skb(struct enic *enic,
 	int vlan_tag_insert = 0;
 	int loopback = 0;
 
-	if (enic->vlan_group && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		/* VLAN tag from trunking driver */
 		vlan_tag_insert = 1;
 		vlan_tag = vlan_tx_tag_get(skb);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index ddac63c..0fa1776 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2321,14 +2321,11 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
 			 NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0;
 
 	/* vlan tag */
-	if (likely(!np->vlangrp)) {
+	if (vlan_tx_tag_present(skb))
+		start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT |
+					vlan_tx_tag_get(skb));
+	else
 		start_tx->txvlan = 0;
-	} else {
-		if (vlan_tx_tag_present(skb))
-			start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb));
-		else
-			start_tx->txvlan = 0;
-	}
 
 	spin_lock_irqsave(&np->lock, flags);
 
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 6180089..4c4cc80 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2075,7 +2075,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* make space for additional header when fcb is needed */
 	if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
-			(priv->vlgrp && vlan_tx_tag_present(skb)) ||
+			vlan_tx_tag_present(skb) ||
 			unlikely(do_tstamp)) &&
 			(skb_headroom(skb) < GMAC_FCB_LEN)) {
 		struct sk_buff *skb_new;
@@ -2161,7 +2161,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		gfar_tx_checksum(skb, fcb);
 	}
 
-	if (priv->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		if (unlikely(NULL == fcb)) {
 			fcb = gfar_add_fcb(skb);
 			lstatus |= BD_LFLAG(TXBD_TOE);
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 0f0939c..75155a2 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -4128,7 +4128,7 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
 		tx_flags |= IGB_TX_FLAGS_TSTAMP;
 	}
 
-	if (vlan_tx_tag_present(skb) && adapter->vlgrp) {
+	if (vlan_tx_tag_present(skb)) {
 		tx_flags |= IGB_TX_FLAGS_VLAN;
 		tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
 	}
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 1d42442..998debe 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6311,7 +6311,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev
 	int count = 0;
 	unsigned int f;
 
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		tx_flags |= vlan_tx_tag_get(skb);
 		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
 			tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK;
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 78bfbe4..dc03c96 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -3134,7 +3134,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 	tx_ring = &adapter->tx_ring[r_idx];
 
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		tx_flags |= vlan_tx_tag_get(skb);
 		tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
 		tx_flags |= IXGBE_TX_FLAGS_VLAN;
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 98dd620..a680cd4 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -583,7 +583,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
 	/* If we support per priority flow control and the packet contains
 	 * a vlan tag, send the packet to the TX ring assigned to that priority
 	 */
-	if (priv->prof->rx_ppp && priv->vlgrp && vlan_tx_tag_present(skb)) {
+	if (priv->prof->rx_ppp && vlan_tx_tag_present(skb)) {
 		vlan_tag = vlan_tx_tag_get(skb);
 		return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13);
 	}
@@ -634,7 +634,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	tx_ind = skb->queue_mapping;
 	ring = &priv->tx_ring[tx_ind];
-	if (priv->vlgrp && vlan_tx_tag_present(skb))
+	if (vlan_tx_tag_present(skb))
 		vlan_tag = vlan_tx_tag_get(skb);
 
 	/* Check available TXBBs And 2K spare for prefetch */
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 4ffebe8..ba0053d 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2572,7 +2572,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
 
 	mac_iocb_ptr->frame_len = cpu_to_le16((u16) skb->len);
 
-	if (qdev->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev,
 			     "Adding a vlan tag %d.\n", vlan_tx_tag_get(skb));
 		mac_iocb_ptr->flags3 |= OB_MAC_IOCB_V;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 1760533..242748b 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1034,7 +1034,7 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
 static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
 				      struct sk_buff *skb)
 {
-	return (tp->vlgrp && vlan_tx_tag_present(skb)) ?
+	return (vlan_tx_tag_present(skb)) ?
 		TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
 }
 
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index c70ad51..ecc25aa 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -4101,7 +4101,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	queue = 0;
-	if (sp->vlgrp && vlan_tx_tag_present(skb))
+	if (vlan_tx_tag_present(skb))
 		vlan_tag = vlan_tx_tag_get(skb);
 	if (sp->config.tx_steering_type == TX_DEFAULT_STEERING) {
 		if (skb->protocol == htons(ETH_P_IP)) {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 3ef9b67..d657708 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1782,7 +1782,7 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
 	ctrl = 0;
 #ifdef SKY2_VLAN_TAG_USED
 	/* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
-	if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		if (!le) {
 			le = get_tx_le(sky2, &slot);
 			le->addr = 0;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5b4c510..22720ee 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5745,7 +5745,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
 	}
 
 #if TG3_VLAN_TAG_USED
-	if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+	if (vlan_tx_tag_present(skb))
 		base_flags |= (TXD_FLAG_VLAN |
 			       (vlan_tx_tag_get(skb) << 16));
 #endif
@@ -5991,7 +5991,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
 		}
 	}
 #if TG3_VLAN_TAG_USED
-	if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+	if (vlan_tx_tag_present(skb))
 		base_flags |= (TXD_FLAG_VLAN |
 			       (vlan_tx_tag_get(skb) << 16));
 #endif
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index f199561..cab96ad 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -2592,7 +2592,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
 
 	td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16;
 
-	if (vptr->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		td_ptr->tdesc1.vlan = cpu_to_le16(vlan_tx_tag_get(skb));
 		td_ptr->tdesc1.TCR |= TCR0_VETAG;
 	}
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 0bda7fe..a69542e 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -822,7 +822,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
 		dev->name, __func__, __LINE__,
 		fifo_hw, dtr, dtr_priv);
 
-	if (vdev->vlgrp && vlan_tx_tag_present(skb)) {
+	if (vlan_tx_tag_present(skb)) {
 		u16 vlan_tag = vlan_tx_tag_get(skb);
 		vxge_hw_fifo_txdl_vlan_set(dtr, vlan_tag);
 	}
-- 
1.7.1


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

* [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (2 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 03/14] vlan: Don't check for vlan group before vlan_tx_tag_present Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-21  3:32   ` John Fastabend
  2010-10-21 15:30   ` Ben Hutchings
  2010-10-20 23:56 ` [PATCH v2 05/14] vlan: Avoid hash table lookup to find group Jesse Gross
                   ` (11 subsequent siblings)
  15 siblings, 2 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Currently users of hardware vlan accleration need to know whether
the device supports it before generating packets.  However, vlan
acceleration will soon be available in a more flexible manner so
knowing ahead of time becomes much more difficult.  This adds
a software fallback path for vlan packets on devices without the
necessary offloading support, similar to other types of hardware
accleration.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 include/linux/netdevice.h |   14 +++++++++++---
 net/core/dev.c            |   36 +++++++++++++++++++++++++++++++++---
 2 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 880d565..2861565 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2248,9 +2248,17 @@ static inline int skb_gso_ok(struct sk_buff *skb, int features)
 
 static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
 {
-	return skb_is_gso(skb) &&
-	       (!skb_gso_ok(skb, dev->features) ||
-		unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
+	if (skb_is_gso(skb)) {
+		int features = dev->features;
+
+		if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci)
+			features &= dev->vlan_features;
+
+		return (!skb_gso_ok(skb, features) ||
+			unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
+	}
+
+	return 0;
 }
 
 static inline void netif_set_gso_max_size(struct net_device *dev,
diff --git a/net/core/dev.c b/net/core/dev.c
index 4c3ac53..1bfd96b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1694,7 +1694,12 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
 
 static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
 {
-	if (can_checksum_protocol(dev->features, skb->protocol))
+	int features = dev->features;
+
+	if (vlan_tx_tag_present(skb))
+		features &= dev->vlan_features;
+
+	if (can_checksum_protocol(features, skb->protocol))
 		return true;
 
 	if (skb->protocol == htons(ETH_P_8021Q)) {
@@ -1793,6 +1798,16 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
 	__be16 type = skb->protocol;
 	int err;
 
+	if (type == htons(ETH_P_8021Q)) {
+		struct vlan_ethhdr *veh;
+
+		if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
+			return ERR_PTR(-EINVAL);
+
+		veh = (struct vlan_ethhdr *)skb->data;
+		type = veh->h_vlan_encapsulated_proto;
+	}
+
 	skb_reset_mac_header(skb);
 	skb->mac_len = skb->network_header - skb->mac_header;
 	__skb_pull(skb, skb->mac_len);
@@ -1964,9 +1979,14 @@ static inline void skb_orphan_try(struct sk_buff *skb)
 static inline int skb_needs_linearize(struct sk_buff *skb,
 				      struct net_device *dev)
 {
+	int features = dev->features;
+
+	if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb))
+		features &= dev->vlan_features;
+
 	return skb_is_nonlinear(skb) &&
-	       ((skb_has_frag_list(skb) && !(dev->features & NETIF_F_FRAGLIST)) ||
-	        (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) ||
+	       ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) ||
+		(skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) ||
 					      illegal_highdma(dev, skb))));
 }
 
@@ -1989,6 +2009,15 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 
 		skb_orphan_try(skb);
 
+		if (vlan_tx_tag_present(skb) &&
+		    !(dev->features & NETIF_F_HW_VLAN_TX)) {
+			skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
+			if (unlikely(!skb))
+				goto out;
+
+			skb->vlan_tci = 0;
+		}
+
 		if (netif_needs_gso(dev, skb)) {
 			if (unlikely(dev_gso_segment(skb)))
 				goto out_kfree_skb;
@@ -2050,6 +2079,7 @@ out_kfree_gso_skb:
 		skb->destructor = DEV_GSO_CB(skb)->destructor;
 out_kfree_skb:
 	kfree_skb(skb);
+out:
 	return rc;
 }
 
-- 
1.7.1


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

* [PATCH v2 05/14] vlan: Avoid hash table lookup to find group.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (3 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 06/14] vlan: Centralize handling of hardware acceleration Jesse Gross
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

A struct net_device always maps to zero or one vlan groups and we
always know the device when we are looking up a group.  We currently
do a hash table lookup on the device to find the group but it is
much simpler to just store a pointer.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 include/linux/if_vlan.h   |   19 +++++++++++++
 include/linux/netdevice.h |    5 +++-
 net/8021q/vlan.c          |   64 +++++++--------------------------------------
 net/8021q/vlan.h          |   17 ------------
 net/8021q/vlan_dev.c      |    2 +-
 5 files changed, 34 insertions(+), 73 deletions(-)

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 494cce8..4047781 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -16,6 +16,7 @@
 #ifdef __KERNEL__
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
 
 #define VLAN_HLEN	4		/* The additional bytes (on top of the Ethernet header)
 					 * that VLAN requires.
@@ -114,6 +115,18 @@ static inline void vlan_group_set_device(struct vlan_group *vg,
 #define vlan_tx_tag_get(__skb)		((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+/* Must be invoked with rcu_read_lock or with RTNL. */
+static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
+					       u16 vlan_id)
+{
+	struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp);
+
+	if (grp)
+		return vlan_group_get_device(grp, vlan_id);
+
+	return NULL;
+}
+
 extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
 extern u16 vlan_dev_vlan_id(const struct net_device *dev);
 
@@ -128,6 +141,12 @@ vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
 	       unsigned int vlan_tci);
 
 #else
+static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
+					       u16 vlan_id)
+{
+	return NULL;
+}
+
 static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
 {
 	BUG();
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 2861565..9c78312 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -942,7 +942,10 @@ struct net_device {
 
 
 	/* Protocol specific pointers */
-	
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+	struct vlan_group	*vlgrp;		/* VLAN group */
+#endif
 #ifdef CONFIG_NET_DSA
 	void			*dsa_ptr;	/* dsa specific data */
 #endif
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 54f22d8..f862dcc 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -44,9 +44,6 @@
 
 int vlan_net_id __read_mostly;
 
-/* Our listing of VLAN group(s) */
-static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
-
 const char vlan_fullname[] = "802.1Q VLAN Support";
 const char vlan_version[] = DRV_VERSION;
 static const char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
@@ -59,40 +56,6 @@ static struct packet_type vlan_packet_type __read_mostly = {
 
 /* End of global variables definitions. */
 
-static inline unsigned int vlan_grp_hashfn(unsigned int idx)
-{
-	return ((idx >> VLAN_GRP_HASH_SHIFT) ^ idx) & VLAN_GRP_HASH_MASK;
-}
-
-/* Must be invoked with RCU read lock (no preempt) */
-static struct vlan_group *__vlan_find_group(struct net_device *real_dev)
-{
-	struct vlan_group *grp;
-	struct hlist_node *n;
-	int hash = vlan_grp_hashfn(real_dev->ifindex);
-
-	hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) {
-		if (grp->real_dev == real_dev)
-			return grp;
-	}
-
-	return NULL;
-}
-
-/*  Find the protocol handler.  Assumes VID < VLAN_VID_MASK.
- *
- * Must be invoked with RCU read lock (no preempt)
- */
-struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id)
-{
-	struct vlan_group *grp = __vlan_find_group(real_dev);
-
-	if (grp)
-		return vlan_group_get_device(grp, vlan_id);
-
-	return NULL;
-}
-
 static void vlan_group_free(struct vlan_group *grp)
 {
 	int i;
@@ -111,8 +74,6 @@ static struct vlan_group *vlan_group_alloc(struct net_device *real_dev)
 		return NULL;
 
 	grp->real_dev = real_dev;
-	hlist_add_head_rcu(&grp->hlist,
-			&vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]);
 	return grp;
 }
 
@@ -151,7 +112,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 
 	ASSERT_RTNL();
 
-	grp = __vlan_find_group(real_dev);
+	grp = real_dev->vlgrp;
 	BUG_ON(!grp);
 
 	/* Take it out of our own structures, but be sure to interlock with
@@ -173,11 +134,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 	if (grp->nr_vlans == 0) {
 		vlan_gvrp_uninit_applicant(real_dev);
 
+		rcu_assign_pointer(real_dev->vlgrp, NULL);
 		if (real_dev->features & NETIF_F_HW_VLAN_RX)
 			ops->ndo_vlan_rx_register(real_dev, NULL);
 
-		hlist_del_rcu(&grp->hlist);
-
 		/* Free the group, after all cpu's are done. */
 		call_rcu(&grp->rcu, vlan_rcu_free);
 	}
@@ -207,7 +167,7 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
 		return -EOPNOTSUPP;
 	}
 
-	if (__find_vlan_dev(real_dev, vlan_id) != NULL)
+	if (vlan_find_dev(real_dev, vlan_id) != NULL)
 		return -EEXIST;
 
 	return 0;
@@ -222,7 +182,7 @@ int register_vlan_dev(struct net_device *dev)
 	struct vlan_group *grp, *ngrp = NULL;
 	int err;
 
-	grp = __vlan_find_group(real_dev);
+	grp = real_dev->vlgrp;
 	if (!grp) {
 		ngrp = grp = vlan_group_alloc(real_dev);
 		if (!grp)
@@ -252,8 +212,11 @@ int register_vlan_dev(struct net_device *dev)
 	vlan_group_set_device(grp, vlan_id, dev);
 	grp->nr_vlans++;
 
-	if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
-		ops->ndo_vlan_rx_register(real_dev, ngrp);
+	if (ngrp) {
+		if (real_dev->features & NETIF_F_HW_VLAN_RX)
+			ops->ndo_vlan_rx_register(real_dev, ngrp);
+		rcu_assign_pointer(real_dev->vlgrp, ngrp);
+	}
 	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
 		ops->ndo_vlan_rx_add_vid(real_dev, vlan_id);
 
@@ -264,7 +227,6 @@ out_uninit_applicant:
 		vlan_gvrp_uninit_applicant(real_dev);
 out_free_group:
 	if (ngrp) {
-		hlist_del_rcu(&ngrp->hlist);
 		/* Free the group, after all cpu's are done. */
 		call_rcu(&ngrp->rcu, vlan_rcu_free);
 	}
@@ -428,7 +390,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 		dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0);
 	}
 
-	grp = __vlan_find_group(dev);
+	grp = dev->vlgrp;
 	if (!grp)
 		goto out;
 
@@ -746,8 +708,6 @@ err0:
 
 static void __exit vlan_cleanup_module(void)
 {
-	unsigned int i;
-
 	vlan_ioctl_set(NULL);
 	vlan_netlink_fini();
 
@@ -755,10 +715,6 @@ static void __exit vlan_cleanup_module(void)
 
 	dev_remove_pack(&vlan_packet_type);
 
-	/* This table must be empty if there are no module references left. */
-	for (i = 0; i < VLAN_GRP_HASH_SIZE; i++)
-		BUG_ON(!hlist_empty(&vlan_group_hash[i]));
-
 	unregister_pernet_subsys(&vlan_net_ops);
 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
 
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 8d9503a..db01b31 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -72,23 +72,6 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev)
 	return netdev_priv(dev);
 }
 
-#define VLAN_GRP_HASH_SHIFT	5
-#define VLAN_GRP_HASH_SIZE	(1 << VLAN_GRP_HASH_SHIFT)
-#define VLAN_GRP_HASH_MASK	(VLAN_GRP_HASH_SIZE - 1)
-
-/*  Find a VLAN device by the MAC address of its Ethernet device, and
- *  it's VLAN ID.  The default configuration is to have VLAN's scope
- *  to be box-wide, so the MAC will be ignored.  The mac will only be
- *  looked at if we are configured to have a separate set of VLANs per
- *  each MAC addressable interface.  Note that this latter option does
- *  NOT follow the spec for VLANs, but may be useful for doing very
- *  large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs.
- *
- *  Must be invoked with rcu_read_lock (ie preempt disabled)
- *  or with RTNL.
- */
-struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id);
-
 /* found in vlan_dev.c */
 int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
 		  struct packet_type *ptype, struct net_device *orig_dev);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index f54251e..14e3d1f 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -158,7 +158,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	vlan_id = vlan_tci & VLAN_VID_MASK;
 
 	rcu_read_lock();
-	vlan_dev = __find_vlan_dev(dev, vlan_id);
+	vlan_dev = vlan_find_dev(dev, vlan_id);
 
 	/* If the VLAN device is defined, we use it.
 	 * If not, and the VID is 0, it is a 802.1p packet (not
-- 
1.7.1


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

* [PATCH v2 06/14] vlan: Centralize handling of hardware acceleration.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (4 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 05/14] vlan: Avoid hash table lookup to find group Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 07/14] ethtool: Add support for vlan accleration Jesse Gross
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Currently each driver that is capable of vlan hardware acceleration
must be aware of the vlan groups that are configured and then pass
the stripped tag to a specialized receive function.  This is
different from other types of hardware offload in that it places a
significant amount of knowledge in the driver itself rather keeping
it in the networking core.

This makes vlan offloading function more similarly to other forms
of offloading (such as checksum offloading or TSO) by doing the
following:
* On receive, stripped vlans are passed directly to the network
core, without attempting to check for vlan groups or reconstructing
the header if no group
* vlans are made less special by folding the logic into the main
receive routines
* On transmit, the device layer will add the vlan header in software
if the hardware doesn't support it, instead of spreading that logic
out in upper layers, such as bonding.

There are a number of advantages to this:
* Fixes all bugs with drivers incorrectly dropping vlan headers at once.
* Avoids having to disable VLAN acceleration when in promiscuous mode
(good for bridging since it always puts devices in promiscuous mode).
* Keeps VLAN tag separate until given to ultimate consumer, which
avoids needing to do header reconstruction as in tg3 unless absolutely
necessary.
* Consolidates common code in core networking.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 include/linux/if_vlan.h   |    6 ++-
 include/linux/netdevice.h |    1 -
 net/8021q/vlan.c          |    9 +---
 net/8021q/vlan_core.c     |  125 ++++++++++-----------------------------------
 net/core/dev.c            |   47 +++++------------
 5 files changed, 48 insertions(+), 140 deletions(-)

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 4047781..a0d9786 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -132,7 +132,7 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev);
 
 extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 			     u16 vlan_tci, int polling);
-extern void vlan_hwaccel_do_receive(struct sk_buff *skb);
+extern bool vlan_hwaccel_do_receive(struct sk_buff **skb);
 extern gro_result_t
 vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
 		 unsigned int vlan_tci, struct sk_buff *skb);
@@ -166,8 +166,10 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 	return NET_XMIT_SUCCESS;
 }
 
-static inline void vlan_hwaccel_do_receive(struct sk_buff *skb)
+static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb)
 {
+	BUG();
+	return false;
 }
 
 static inline gro_result_t
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9c78312..ed7db7e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1768,7 +1768,6 @@ extern int netdev_rx_handler_register(struct net_device *dev,
 				      void *rx_handler_data);
 extern void netdev_rx_handler_unregister(struct net_device *dev);
 
-extern void		netif_nit_deliver(struct sk_buff *skb);
 extern int		dev_valid_name(const char *name);
 extern int		dev_ioctl(struct net *net, unsigned int cmd, void __user *);
 extern int		dev_ethtool(struct net *net, struct ifreq *);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index f862dcc..05b867e 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -135,7 +135,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 		vlan_gvrp_uninit_applicant(real_dev);
 
 		rcu_assign_pointer(real_dev->vlgrp, NULL);
-		if (real_dev->features & NETIF_F_HW_VLAN_RX)
+		if (ops->ndo_vlan_rx_register)
 			ops->ndo_vlan_rx_register(real_dev, NULL);
 
 		/* Free the group, after all cpu's are done. */
@@ -156,11 +156,6 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
 		return -EOPNOTSUPP;
 	}
 
-	if ((real_dev->features & NETIF_F_HW_VLAN_RX) && !ops->ndo_vlan_rx_register) {
-		pr_info("8021q: device %s has buggy VLAN hw accel\n", name);
-		return -EOPNOTSUPP;
-	}
-
 	if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
 	    (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) {
 		pr_info("8021q: Device %s has buggy VLAN hw accel\n", name);
@@ -213,7 +208,7 @@ int register_vlan_dev(struct net_device *dev)
 	grp->nr_vlans++;
 
 	if (ngrp) {
-		if (real_dev->features & NETIF_F_HW_VLAN_RX)
+		if (ops->ndo_vlan_rx_register)
 			ops->ndo_vlan_rx_register(real_dev, ngrp);
 		rcu_assign_pointer(real_dev->vlgrp, ngrp);
 	}
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index dee727c..69b2f79 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -4,54 +4,29 @@
 #include <linux/netpoll.h>
 #include "vlan.h"
 
-/* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
-int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
-		      u16 vlan_tci, int polling)
+bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
 {
+	struct sk_buff *skb = *skbp;
+	u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
 	struct net_device *vlan_dev;
-	u16 vlan_id;
-
-	if (netpoll_rx(skb))
-		return NET_RX_DROP;
-
-	if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
-		skb->deliver_no_wcard = 1;
+	struct vlan_rx_stats *rx_stats;
 
-	skb->skb_iif = skb->dev->ifindex;
-	__vlan_hwaccel_put_tag(skb, vlan_tci);
-	vlan_id = vlan_tci & VLAN_VID_MASK;
-	vlan_dev = vlan_group_get_device(grp, vlan_id);
-
-	if (vlan_dev)
-		skb->dev = vlan_dev;
-	else if (vlan_id) {
-		if (!(skb->dev->flags & IFF_PROMISC))
-			goto drop;
-		skb->pkt_type = PACKET_OTHERHOST;
+	vlan_dev = vlan_find_dev(skb->dev, vlan_id);
+	if (!vlan_dev) {
+		if (vlan_id)
+			skb->pkt_type = PACKET_OTHERHOST;
+		return false;
 	}
 
-	return polling ? netif_receive_skb(skb) : netif_rx(skb);
+	skb = *skbp = skb_share_check(skb, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return false;
 
-drop:
-	atomic_long_inc(&skb->dev->rx_dropped);
-	dev_kfree_skb_any(skb);
-	return NET_RX_DROP;
-}
-EXPORT_SYMBOL(__vlan_hwaccel_rx);
-
-void vlan_hwaccel_do_receive(struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-	struct vlan_rx_stats     *rx_stats;
-
-	skb->dev = vlan_dev_real_dev(dev);
-	netif_nit_deliver(skb);
-
-	skb->dev = dev;
-	skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci);
+	skb->dev = vlan_dev;
+	skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
 	skb->vlan_tci = 0;
 
-	rx_stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats);
+	rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_rx_stats);
 
 	u64_stats_update_begin(&rx_stats->syncp);
 	rx_stats->rx_packets++;
@@ -68,11 +43,13 @@ void vlan_hwaccel_do_receive(struct sk_buff *skb)
 		 * This allows the VLAN to have a different MAC than the
 		 * underlying device, and still route correctly. */
 		if (!compare_ether_addr(eth_hdr(skb)->h_dest,
-					dev->dev_addr))
+					vlan_dev->dev_addr))
 			skb->pkt_type = PACKET_HOST;
 		break;
 	}
 	u64_stats_update_end(&rx_stats->syncp);
+
+	return true;
 }
 
 struct net_device *vlan_dev_real_dev(const struct net_device *dev)
@@ -87,75 +64,27 @@ u16 vlan_dev_vlan_id(const struct net_device *dev)
 }
 EXPORT_SYMBOL(vlan_dev_vlan_id);
 
-static gro_result_t
-vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
-		unsigned int vlan_tci, struct sk_buff *skb)
+/* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
+int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
+		      u16 vlan_tci, int polling)
 {
-	struct sk_buff *p;
-	struct net_device *vlan_dev;
-	u16 vlan_id;
-
-	if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
-		skb->deliver_no_wcard = 1;
-
-	skb->skb_iif = skb->dev->ifindex;
 	__vlan_hwaccel_put_tag(skb, vlan_tci);
-	vlan_id = vlan_tci & VLAN_VID_MASK;
-	vlan_dev = vlan_group_get_device(grp, vlan_id);
-
-	if (vlan_dev)
-		skb->dev = vlan_dev;
-	else if (vlan_id) {
-		if (!(skb->dev->flags & IFF_PROMISC))
-			goto drop;
-		skb->pkt_type = PACKET_OTHERHOST;
-	}
-
-	for (p = napi->gro_list; p; p = p->next) {
-		unsigned long diffs;
-
-		diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
-		diffs |= compare_ether_header(skb_mac_header(p),
-					      skb_gro_mac_header(skb));
-		NAPI_GRO_CB(p)->same_flow = !diffs;
-		NAPI_GRO_CB(p)->flush = 0;
-	}
-
-	return dev_gro_receive(napi, skb);
-
-drop:
-	atomic_long_inc(&skb->dev->rx_dropped);
-	return GRO_DROP;
+	return polling ? netif_receive_skb(skb) : netif_rx(skb);
 }
+EXPORT_SYMBOL(__vlan_hwaccel_rx);
 
 gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
 			      unsigned int vlan_tci, struct sk_buff *skb)
 {
-	if (netpoll_rx_on(skb))
-		return vlan_hwaccel_receive_skb(skb, grp, vlan_tci)
-			? GRO_DROP : GRO_NORMAL;
-
-	skb_gro_reset_offset(skb);
-
-	return napi_skb_finish(vlan_gro_common(napi, grp, vlan_tci, skb), skb);
+	__vlan_hwaccel_put_tag(skb, vlan_tci);
+	return napi_gro_receive(napi, skb);
 }
 EXPORT_SYMBOL(vlan_gro_receive);
 
 gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
 			    unsigned int vlan_tci)
 {
-	struct sk_buff *skb = napi_frags_skb(napi);
-
-	if (!skb)
-		return GRO_DROP;
-
-	if (netpoll_rx_on(skb)) {
-		skb->protocol = eth_type_trans(skb, skb->dev);
-		return vlan_hwaccel_receive_skb(skb, grp, vlan_tci)
-			? GRO_DROP : GRO_NORMAL;
-	}
-
-	return napi_frags_finish(napi, skb,
-				 vlan_gro_common(napi, grp, vlan_tci, skb));
+	__vlan_hwaccel_put_tag(napi->skb, vlan_tci);
+	return napi_gro_frags(napi);
 }
 EXPORT_SYMBOL(vlan_gro_frags);
diff --git a/net/core/dev.c b/net/core/dev.c
index 1bfd96b..97fd6bc 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2789,33 +2789,6 @@ out:
 }
 #endif
 
-/*
- * 	netif_nit_deliver - deliver received packets to network taps
- * 	@skb: buffer
- *
- * 	This function is used to deliver incoming packets to network
- * 	taps. It should be used when the normal netif_receive_skb path
- * 	is bypassed, for example because of VLAN acceleration.
- */
-void netif_nit_deliver(struct sk_buff *skb)
-{
-	struct packet_type *ptype;
-
-	if (list_empty(&ptype_all))
-		return;
-
-	skb_reset_network_header(skb);
-	skb_reset_transport_header(skb);
-	skb->mac_len = skb->network_header - skb->mac_header;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(ptype, &ptype_all, list) {
-		if (!ptype->dev || ptype->dev == skb->dev)
-			deliver_skb(skb, ptype, skb->dev);
-	}
-	rcu_read_unlock();
-}
-
 /**
  *	netdev_rx_handler_register - register receive handler
  *	@dev: device to register a handler for
@@ -2925,9 +2898,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
 	if (!netdev_tstamp_prequeue)
 		net_timestamp_check(skb);
 
-	if (vlan_tx_tag_present(skb))
-		vlan_hwaccel_do_receive(skb);
-
 	/* if we've gotten here through NAPI, check netpoll */
 	if (netpoll_receive_skb(skb))
 		return NET_RX_DROP;
@@ -2940,8 +2910,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
 	 * be delivered to pkt handlers that are exact matches.  Also
 	 * the deliver_no_wcard flag will be set.  If packet handlers
 	 * are sensitive to duplicate packets these skbs will need to
-	 * be dropped at the handler.  The vlan accel path may have
-	 * already set the deliver_no_wcard flag.
+	 * be dropped at the handler.
 	 */
 	null_or_orig = NULL;
 	orig_dev = skb->dev;
@@ -3000,6 +2969,18 @@ ncls:
 			goto out;
 	}
 
+	if (vlan_tx_tag_present(skb)) {
+		if (pt_prev) {
+			ret = deliver_skb(skb, pt_prev, orig_dev);
+			pt_prev = NULL;
+		}
+		if (vlan_hwaccel_do_receive(&skb)) {
+			ret = __netif_receive_skb(skb);
+			goto out;
+		} else if (unlikely(!skb))
+			goto out;
+	}
+
 	/*
 	 * Make sure frames received on VLAN interfaces stacked on
 	 * bonding interfaces still make their way to any base bonding
@@ -3264,6 +3245,7 @@ __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 		unsigned long diffs;
 
 		diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
+		diffs |= p->vlan_tci ^ skb->vlan_tci;
 		diffs |= compare_ether_header(skb_mac_header(p),
 					      skb_gro_mac_header(skb));
 		NAPI_GRO_CB(p)->same_flow = !diffs;
@@ -3323,6 +3305,7 @@ void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
 {
 	__skb_pull(skb, skb_headlen(skb));
 	skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb));
+	skb->vlan_tci = 0;
 
 	napi->skb = skb;
 }
-- 
1.7.1


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

* [PATCH v2 07/14] ethtool: Add support for vlan accleration.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (5 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 06/14] vlan: Centralize handling of hardware acceleration Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-21  3:27   ` John Fastabend
  2010-10-20 23:56 ` [PATCH v2 08/14] bridge: Add support for TX vlan offload Jesse Gross
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Now that vlan acceleration is handled consistently regardless of usage,
it is possible to enable and disable it at will.  This adds support for
Ethtool operations that change the offloading status for debugging
purposes, similar to other forms of hardware acceleration.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 include/linux/ethtool.h |    2 ++
 net/core/ethtool.c      |    3 ++-
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 8a3338c..6628a50 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -309,6 +309,8 @@ struct ethtool_perm_addr {
  * flag differs from the read-only value.
  */
 enum ethtool_flags {
+	ETH_FLAG_TXVLAN		= (1 << 7),	/* TX VLAN offload enabled */
+	ETH_FLAG_RXVLAN		= (1 << 8),	/* RX VLAN offload enabled */
 	ETH_FLAG_LRO		= (1 << 15),	/* LRO is enabled */
 	ETH_FLAG_NTUPLE		= (1 << 27),	/* N-tuple filters enabled */
 	ETH_FLAG_RXHASH		= (1 << 28),
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 685c700..956a9f4 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -132,7 +132,8 @@ EXPORT_SYMBOL(ethtool_op_set_ufo);
  * NETIF_F_xxx values in include/linux/netdevice.h
  */
 static const u32 flags_dup_features =
-	(ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH);
+	(ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
+	 ETH_FLAG_RXHASH);
 
 u32 ethtool_op_get_flags(struct net_device *dev)
 {
-- 
1.7.1


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

* [PATCH v2 08/14] bridge: Add support for TX vlan offload.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (6 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 07/14] ethtool: Add support for vlan accleration Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 09/14] bnx2: Update bnx2 to use new vlan accleration Jesse Gross
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

If some of the underlying devices support it, enable vlan offload on
transmit for bridge devices.  This allows senders to take advantage of the
hardware support, similar to other forms of acceleration.

Signed-off-by: Jesse Gross <jesse@nicira.com>
---
 net/bridge/br_device.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index cf09fe5..17cb0b6 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -212,6 +212,11 @@ static int br_set_tx_csum(struct net_device *dev, u32 data)
 	return 0;
 }
 
+static int br_set_flags(struct net_device *netdev, u32 data)
+{
+	return ethtool_op_set_flags(netdev, data, ETH_FLAG_TXVLAN);
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void br_poll_controller(struct net_device *br_dev)
 {
@@ -304,6 +309,7 @@ static const struct ethtool_ops br_ethtool_ops = {
 	.get_ufo	= ethtool_op_get_ufo,
 	.set_ufo	= ethtool_op_set_ufo,
 	.get_flags	= ethtool_op_get_flags,
+	.set_flags	= br_set_flags,
 };
 
 static const struct net_device_ops br_netdev_ops = {
@@ -343,5 +349,5 @@ void br_dev_setup(struct net_device *dev)
 
 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
 			NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX |
-			NETIF_F_NETNS_LOCAL | NETIF_F_GSO;
+			NETIF_F_NETNS_LOCAL | NETIF_F_GSO | NETIF_F_HW_VLAN_TX;
 }
-- 
1.7.1


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

* [PATCH v2 09/14] bnx2: Update bnx2 to use new vlan accleration.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (7 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 08/14] bridge: Add support for TX vlan offload Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-21 15:31   ` Ben Hutchings
  2010-10-20 23:56 ` [PATCH v2 10/14] ixgbe: Update ixgbe " Jesse Gross
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Michael Chan

Make the bnx2 driver use the new vlan accleration model.

Signed-off-by: Jesse Gross <jesse@nicira.com>
CC: Michael Chan <mchan@broadcom.com>
---
 drivers/net/bnx2.c |   97 +++++++++++++++-------------------------------------
 drivers/net/bnx2.h |    4 --
 2 files changed, 28 insertions(+), 73 deletions(-)

diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 363ca8b..bf3c830 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -37,9 +37,6 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define BCM_VLAN 1
-#endif
 #include <net/ip.h>
 #include <net/tcp.h>
 #include <net/checksum.h>
@@ -3087,8 +3084,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 		struct sw_bd *rx_buf, *next_rx_buf;
 		struct sk_buff *skb;
 		dma_addr_t dma_addr;
-		u16 vtag = 0;
-		int hw_vlan __maybe_unused = 0;
 
 		sw_ring_cons = RX_RING_IDX(sw_cons);
 		sw_ring_prod = RX_RING_IDX(sw_prod);
@@ -3168,23 +3163,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 			goto next_rx;
 
 		if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
-		    !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
-			vtag = rx_hdr->l2_fhdr_vlan_tag;
-#ifdef BCM_VLAN
-			if (bp->vlgrp)
-				hw_vlan = 1;
-			else
-#endif
-			{
-				struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
-					__skb_push(skb, 4);
-
-				memmove(ve, skb->data + 4, ETH_ALEN * 2);
-				ve->h_vlan_proto = htons(ETH_P_8021Q);
-				ve->h_vlan_TCI = htons(vtag);
-				len += 4;
-			}
-		}
+		    !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG))
+			__vlan_hwaccel_put_tag(skb, rx_hdr->l2_fhdr_vlan_tag);
 
 		skb->protocol = eth_type_trans(skb, bp->dev);
 
@@ -3211,14 +3191,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 			skb->rxhash = rx_hdr->l2_fhdr_hash;
 
 		skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]);
-
-#ifdef BCM_VLAN
-		if (hw_vlan)
-			vlan_gro_receive(&bnapi->napi, bp->vlgrp, vtag, skb);
-		else
-#endif
-			napi_gro_receive(&bnapi->napi, skb);
-
+		napi_gro_receive(&bnapi->napi, skb);
 		rx_pkt++;
 
 next_rx:
@@ -3533,13 +3506,9 @@ bnx2_set_rx_mode(struct net_device *dev)
 	rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
 				  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
 	sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
-#ifdef BCM_VLAN
-	if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
+	if (!(dev->features & NETIF_F_HW_VLAN_RX) &&
+	     (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
 		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
-#else
-	if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
-		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
-#endif
 	if (dev->flags & IFF_PROMISC) {
 		/* Promiscuous mode. */
 		rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
@@ -6365,29 +6334,6 @@ bnx2_tx_timeout(struct net_device *dev)
 	schedule_work(&bp->reset_task);
 }
 
-#ifdef BCM_VLAN
-/* Called with rtnl_lock */
-static void
-bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
-{
-	struct bnx2 *bp = netdev_priv(dev);
-
-	if (netif_running(dev))
-		bnx2_netif_stop(bp, false);
-
-	bp->vlgrp = vlgrp;
-
-	if (!netif_running(dev))
-		return;
-
-	bnx2_set_rx_mode(dev);
-	if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
-		bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
-
-	bnx2_netif_start(bp, false);
-}
-#endif
-
 /* Called with netif_tx_lock.
  * bnx2_tx_int() runs without netif_tx_lock unless it needs to call
  * netif_wake_queue().
@@ -6428,12 +6374,11 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
 	}
 
-#ifdef BCM_VLAN
 	if (vlan_tx_tag_present(skb)) {
 		vlan_tag_flags |=
 			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
 	}
-#endif
+
 	if ((mss = skb_shinfo(skb)->gso_size)) {
 		u32 tcp_opt_len;
 		struct iphdr *iph;
@@ -7578,7 +7523,28 @@ bnx2_set_tx_csum(struct net_device *dev, u32 data)
 static int
 bnx2_set_flags(struct net_device *dev, u32 data)
 {
-	return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH);
+	struct bnx2 *bp = netdev_priv(dev);
+	int rc;
+
+	if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) &&
+	    !(data & ETH_FLAG_RXVLAN))
+		return -EOPNOTSUPP;
+
+	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN |
+				  ETH_FLAG_TXVLAN);
+	if (rc)
+		return rc;
+
+	if ((!!(data & ETH_FLAG_RXVLAN) !=
+	    !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) &&
+	    netif_running(dev)) {
+		bnx2_netif_stop(bp, false);
+		bnx2_set_rx_mode(dev);
+		bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
+		bnx2_netif_start(bp, false);
+	}
+
+	return 0;
 }
 
 static const struct ethtool_ops bnx2_ethtool_ops = {
@@ -8318,9 +8284,6 @@ static const struct net_device_ops bnx2_netdev_ops = {
 	.ndo_set_mac_address	= bnx2_change_mac_addr,
 	.ndo_change_mtu		= bnx2_change_mtu,
 	.ndo_tx_timeout		= bnx2_tx_timeout,
-#ifdef BCM_VLAN
-	.ndo_vlan_rx_register	= bnx2_vlan_rx_register,
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= poll_bnx2,
 #endif
@@ -8328,9 +8291,7 @@ static const struct net_device_ops bnx2_netdev_ops = {
 
 static void inline vlan_features_add(struct net_device *dev, unsigned long flags)
 {
-#ifdef BCM_VLAN
 	dev->vlan_features |= flags;
-#endif
 }
 
 static int __devinit
@@ -8379,9 +8340,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev->features |= NETIF_F_IPV6_CSUM;
 		vlan_features_add(dev, NETIF_F_IPV6_CSUM);
 	}
-#ifdef BCM_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-#endif
 	dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
 	vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN);
 	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index efdfbc2..4f44db6 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6742,10 +6742,6 @@ struct bnx2 {
 
 	struct bnx2_napi	bnx2_napi[BNX2_MAX_MSIX_VEC];
 
-#ifdef BCM_VLAN
-	struct			vlan_group *vlgrp;
-#endif
-
 	u32			rx_buf_use_size;	/* useable size */
 	u32			rx_buf_size;		/* with alignment */
 	u32			rx_copy_thresh;
-- 
1.7.1


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

* [PATCH v2 10/14] ixgbe: Update ixgbe to use new vlan accleration.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (8 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 09/14] bnx2: Update bnx2 to use new vlan accleration Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-22 13:24   ` Michał Mirosław
  2010-10-20 23:56 ` [PATCH v2 11/14] bnx2x: Update bnx2x " Jesse Gross
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Peter Waskiewicz, Emil Tantilov, Jeff Kirsher

Make the ixgbe driver use the new vlan accleration model.

Signed-off-by: Jesse Gross <jesse@nicira.com>
CC: Peter Waskiewicz <peter.p.waskiewicz.jr@intel.com>
CC: Emil Tantilov <emil.s.tantilov@intel.com>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ixgbe/ixgbe.h         |    4 +-
 drivers/net/ixgbe/ixgbe_ethtool.c |   12 +++-
 drivers/net/ixgbe/ixgbe_main.c    |  137 ++++++++++++++++---------------------
 3 files changed, 74 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index a8c47b0..5e38de7 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -28,11 +28,13 @@
 #ifndef _IXGBE_H_
 #define _IXGBE_H_
 
+#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/cpumask.h>
 #include <linux/aer.h>
+#include <linux/if_vlan.h>
 
 #include "ixgbe_type.h"
 #include "ixgbe_common.h"
@@ -287,7 +289,7 @@ struct ixgbe_q_vector {
 /* board specific private data structure */
 struct ixgbe_adapter {
 	struct timer_list watchdog_timer;
-	struct vlan_group *vlgrp;
+	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	u16 bd_number;
 	struct work_struct reset_task;
 	struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index d4ac943..dbfd62f 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -2113,7 +2113,17 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
 	bool need_reset = false;
 	int rc;
 
-	rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE);
+#ifdef CONFIG_IXGBE_DCB
+	if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
+	    !(data & ETH_FLAG_RXVLAN))
+		return -EINVAL;
+#endif
+
+	need_reset = (data & ETH_FLAG_RXVLAN) !=
+		     (netdev->features & NETIF_F_HW_VLAN_RX);
+
+	rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO |
+					ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
 	if (rc)
 		return rc;
 
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 998debe..56f6b80 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
 	bool is_vlan = (status & IXGBE_RXD_STAT_VP);
 	u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
 
-	if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
-		if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
-			vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
-		else
-			napi_gro_receive(napi, skb);
-	} else {
-		if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
-			vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
-		else
-			netif_rx(skb);
-	}
+	if (is_vlan && (tag & VLAN_VID_MASK))
+		__vlan_hwaccel_put_tag(skb, tag);
+
+	if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
+		napi_gro_receive(napi, skb);
+	else
+		netif_rx(skb);
 }
 
 /**
@@ -3065,6 +3061,7 @@ static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
 
 	/* add VID to filter table */
 	hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, true);
+	set_bit(vid, adapter->active_vlans);
 }
 
 static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -3073,16 +3070,9 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 	struct ixgbe_hw *hw = &adapter->hw;
 	int pool_ndx = adapter->num_vfs;
 
-	if (!test_bit(__IXGBE_DOWN, &adapter->state))
-		ixgbe_irq_disable(adapter);
-
-	vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
-	if (!test_bit(__IXGBE_DOWN, &adapter->state))
-		ixgbe_irq_enable(adapter, true, true);
-
 	/* remove VID from filter table */
 	hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false);
+	clear_bit(vid, adapter->active_vlans);
 }
 
 /**
@@ -3092,27 +3082,45 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+	u32 vlnctrl;
+
+	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+	vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
+	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+}
+
+/**
+ * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering
+ * @adapter: driver data
+ */
+static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vlnctrl;
+
+	vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+	vlnctrl |= IXGBE_VLNCTRL_VFE;
+	vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+	IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+}
+
+/**
+ * ixgbe_vlan_strip_disable - helper to disable hw vlan stripping
+ * @adapter: driver data
+ */
+static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 vlnctrl;
 	int i, j;
 
 	switch (hw->mac.type) {
 	case ixgbe_mac_82598EB:
-		vlnctrl &= ~IXGBE_VLNCTRL_VFE;
-#ifdef CONFIG_IXGBE_DCB
-		if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
-			vlnctrl &= ~IXGBE_VLNCTRL_VME;
-#endif
-		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+		vlnctrl &= ~IXGBE_VLNCTRL_VME;
 		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 		break;
 	case ixgbe_mac_82599EB:
-		vlnctrl &= ~IXGBE_VLNCTRL_VFE;
-		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
-		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
-#ifdef CONFIG_IXGBE_DCB
-		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
-			break;
-#endif
 		for (i = 0; i < adapter->num_rx_queues; i++) {
 			j = adapter->rx_ring[i]->reg_idx;
 			vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
@@ -3126,25 +3134,22 @@ static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter)
 }
 
 /**
- * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering
+ * ixgbe_vlan_strip_enable - helper to enable hw vlan stripping
  * @adapter: driver data
  */
-static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
+static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+	u32 vlnctrl;
 	int i, j;
 
 	switch (hw->mac.type) {
 	case ixgbe_mac_82598EB:
-		vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
-		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+		vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
+		vlnctrl |= IXGBE_VLNCTRL_VME;
 		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 		break;
 	case ixgbe_mac_82599EB:
-		vlnctrl |= IXGBE_VLNCTRL_VFE;
-		vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
-		IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 		for (i = 0; i < adapter->num_rx_queues; i++) {
 			j = adapter->rx_ring[i]->reg_idx;
 			vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
@@ -3157,40 +3162,14 @@ static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
 	}
 }
 
-static void ixgbe_vlan_rx_register(struct net_device *netdev,
-				   struct vlan_group *grp)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
-	if (!test_bit(__IXGBE_DOWN, &adapter->state))
-		ixgbe_irq_disable(adapter);
-	adapter->vlgrp = grp;
-
-	/*
-	 * For a DCB driver, always enable VLAN tag stripping so we can
-	 * still receive traffic from a DCB-enabled host even if we're
-	 * not in DCB mode.
-	 */
-	ixgbe_vlan_filter_enable(adapter);
-
-	ixgbe_vlan_rx_add_vid(netdev, 0);
-
-	if (!test_bit(__IXGBE_DOWN, &adapter->state))
-		ixgbe_irq_enable(adapter, true, true);
-}
-
 static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
 {
-	ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+	u16 vid;
 
-	if (adapter->vlgrp) {
-		u16 vid;
-		for (vid = 0; vid < VLAN_N_VID; vid++) {
-			if (!vlan_group_get_device(adapter->vlgrp, vid))
-				continue;
-			ixgbe_vlan_rx_add_vid(adapter->netdev, vid);
-		}
-	}
+	ixgbe_vlan_rx_add_vid(adapter->netdev, 0);
+
+	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
+		ixgbe_vlan_rx_add_vid(adapter->netdev, vid);
 }
 
 /**
@@ -3305,6 +3284,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
 	}
 
 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+
+	if (netdev->features & NETIF_F_HW_VLAN_RX)
+		ixgbe_vlan_strip_enable(adapter);
+	else
+		ixgbe_vlan_strip_disable(adapter);
 }
 
 static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
@@ -3388,7 +3372,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
 		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
 	}
 	/* Enable VLAN tag insert/strip */
-	ixgbe_vlan_filter_enable(adapter);
+	adapter->netdev->features |= NETIF_F_HW_VLAN_RX;
 
 	hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
 }
@@ -3400,13 +3384,13 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
 	struct ixgbe_hw *hw = &adapter->hw;
 	int i;
 
-	ixgbe_set_rx_mode(netdev);
-
-	ixgbe_restore_vlan(adapter);
 #ifdef CONFIG_IXGBE_DCB
 	ixgbe_configure_dcb(adapter);
 #endif
 
+	ixgbe_set_rx_mode(netdev);
+	ixgbe_restore_vlan(adapter);
+
 #ifdef IXGBE_FCOE
 	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
 		ixgbe_configure_fcoe(adapter);
@@ -6569,7 +6553,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_set_mac_address	= ixgbe_set_mac,
 	.ndo_change_mtu		= ixgbe_change_mtu,
 	.ndo_tx_timeout		= ixgbe_tx_timeout,
-	.ndo_vlan_rx_register	= ixgbe_vlan_rx_register,
 	.ndo_vlan_rx_add_vid	= ixgbe_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= ixgbe_vlan_rx_kill_vid,
 	.ndo_do_ioctl		= ixgbe_ioctl,
-- 
1.7.1


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

* [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (9 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 10/14] ixgbe: Update ixgbe " Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-21 13:54   ` Vladislav Zolotarov
  2010-10-20 23:56 ` [PATCH v2 12/14] lro: Remove explicit vlan support Jesse Gross
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Hao Zheng, Eilon Greenstein

From: Hao Zheng <hzheng@nicira.com>

Make the bnx2x driver use the new vlan accleration model.

Signed-off-by: Hao Zheng <hzheng@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
CC: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x.h         |   10 ------
 drivers/net/bnx2x/bnx2x_cmn.c     |   60 +++++++------------------------------
 drivers/net/bnx2x/bnx2x_ethtool.c |   33 ++++++++++----------
 drivers/net/bnx2x/bnx2x_main.c    |    8 -----
 4 files changed, 27 insertions(+), 84 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 3bf236b..9571ecf 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -24,10 +24,6 @@
 #define DRV_MODULE_RELDATE      "2010/10/19"
 #define BNX2X_BC_VER            0x040200
 
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define BCM_VLAN			1
-#endif
-
 #define BNX2X_MULTI_QUEUE
 
 #define BNX2X_NEW_NAPI
@@ -858,10 +854,6 @@ struct bnx2x {
 
 	int			tx_ring_size;
 
-#ifdef BCM_VLAN
-	struct vlan_group	*vlgrp;
-#endif
-
 	u32			rx_csum;
 	u32			rx_buf_size;
 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
@@ -925,8 +917,6 @@ struct bnx2x {
 #define NO_MCP_FLAG			0x100
 #define DISABLE_MSI_FLAG		0x200
 #define BP_NOMCP(bp)			(bp->flags & NO_MCP_FLAG)
-#define HW_VLAN_TX_FLAG			0x400
-#define HW_VLAN_RX_FLAG			0x800
 #define MF_FUNC_DIS			0x1000
 
 	int			pf_num;	/* absolute PF number */
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 6905b2e..bc58375 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -16,16 +16,13 @@
  */
 
 #include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <net/ipv6.h>
 #include <net/ip6_checksum.h>
 #include <linux/firmware.h>
 #include "bnx2x_cmn.h"
 
-#ifdef BCM_VLAN
-#include <linux/if_vlan.h>
-#endif
-
 #include "bnx2x_init.h"
 
 
@@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 	if (likely(new_skb)) {
 		/* fix ip xsum and give it to the stack */
 		/* (no need to map the new skb) */
-#ifdef BCM_VLAN
-		int is_vlan_cqe =
-			(le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
-			 PARSING_FLAGS_VLAN);
-		int is_not_hwaccel_vlan_cqe =
-			(is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
-#endif
 
 		prefetch(skb);
 		prefetch(((char *)(skb)) + L1_CACHE_BYTES);
@@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 			struct iphdr *iph;
 
 			iph = (struct iphdr *)skb->data;
-#ifdef BCM_VLAN
-			/* If there is no Rx VLAN offloading -
-			   take VLAN tag into an account */
-			if (unlikely(is_not_hwaccel_vlan_cqe))
-				iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
-#endif
 			iph->check = 0;
 			iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
 		}
 
 		if (!bnx2x_fill_frag_skb(bp, fp, skb,
 					 &cqe->fast_path_cqe, cqe_idx)) {
-#ifdef BCM_VLAN
-			if ((bp->vlgrp != NULL) &&
-				(le16_to_cpu(cqe->fast_path_cqe.
-				pars_flags.flags) & PARSING_FLAGS_VLAN))
-				vlan_gro_receive(&fp->napi, bp->vlgrp,
+			if ((le16_to_cpu(cqe->fast_path_cqe.
+			    pars_flags.flags) & PARSING_FLAGS_VLAN))
+				__vlan_hwaccel_put_tag(skb,
 						 le16_to_cpu(cqe->fast_path_cqe.
-							     vlan_tag), skb);
-			else
-#endif
-				napi_gro_receive(&fp->napi, skb);
+							     vlan_tag));
+			napi_gro_receive(&fp->napi, skb);
 		} else {
 			DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages"
 			   " - dropping packet!\n");
@@ -633,15 +613,11 @@ reuse_rx:
 
 		skb_record_rx_queue(skb, fp->index);
 
-#ifdef BCM_VLAN
-		if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
-		    (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
-		     PARSING_FLAGS_VLAN))
-			vlan_gro_receive(&fp->napi, bp->vlgrp,
-				le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb);
-		else
-#endif
-			napi_gro_receive(&fp->napi, skb);
+		if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
+		     PARSING_FLAGS_VLAN)
+			__vlan_hwaccel_put_tag(skb,
+				le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
+		napi_gro_receive(&fp->napi, skb);
 
 
 next_rx:
@@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	   "sending pkt %u @%p  next_idx %u  bd %u @%p\n",
 	   pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
 
-#ifdef BCM_VLAN
 	if (vlan_tx_tag_present(skb)) {
 		tx_start_bd->vlan_or_ethertype =
 		    cpu_to_le16(vlan_tx_tag_get(skb));
 		tx_start_bd->bd_flags.as_bitfield |=
 		    (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
 	} else
-#endif
 		tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
 
 	/* turn on parsing and get a BD */
@@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev)
 	schedule_delayed_work(&bp->reset_task, 0);
 }
 
-#ifdef BCM_VLAN
-/* called with rtnl_lock */
-void bnx2x_vlan_rx_register(struct net_device *dev,
-				   struct vlan_group *vlgrp)
-{
-	struct bnx2x *bp = netdev_priv(dev);
-
-	bp->vlgrp = vlgrp;
-}
-
-#endif
-
 int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 54fe061..daefef6 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device *dev, u32 data)
 	int changed = 0;
 	int rc = 0;
 
-	if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
-		return -EINVAL;
-
 	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
 		printk(KERN_ERR "Handling parity error recovery. Try again later\n");
 		return -EAGAIN;
 	}
 
+	if (!(data & ETH_FLAG_RXVLAN))
+		return -EOPNOTSUPP;
+
+	if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
+		return -EINVAL;
+
+	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN |
+					ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
+	if (rc)
+		return rc;
+
 	/* TPA requires Rx CSUM offloading */
 	if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
-		if (!bp->disable_tpa) {
-			if (!(dev->features & NETIF_F_LRO)) {
-				dev->features |= NETIF_F_LRO;
-				bp->flags |= TPA_ENABLE_FLAG;
-				changed = 1;
-			}
-		} else
-			rc = -EINVAL;
-	} else if (dev->features & NETIF_F_LRO) {
+		if (!(bp->flags & TPA_ENABLE_FLAG)) {
+			bp->flags |= TPA_ENABLE_FLAG;
+			changed = 1;
+		}
+	} else if (bp->flags & TPA_ENABLE_FLAG) {
 		dev->features &= ~NETIF_F_LRO;
 		bp->flags &= ~TPA_ENABLE_FLAG;
 		changed = 1;
 	}
 
-	if (data & ETH_FLAG_RXHASH)
-		dev->features |= NETIF_F_RXHASH;
-	else
-		dev->features &= ~NETIF_F_RXHASH;
-
 	if (changed && netif_running(dev)) {
 		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
 		rc = bnx2x_nic_load(bp, LOAD_NORMAL);
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index f22e283..ff99a2f 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp,
 	flags |= QUEUE_FLG_HC;
 	flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
 
-#ifdef BCM_VLAN
 	flags |= QUEUE_FLG_VLAN;
 	DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
-#endif
 
 	if (!fp->disable_tpa)
 		flags |= QUEUE_FLG_TPA;
@@ -8630,9 +8628,6 @@ static const struct net_device_ops bnx2x_netdev_ops = {
 	.ndo_do_ioctl		= bnx2x_ioctl,
 	.ndo_change_mtu		= bnx2x_change_mtu,
 	.ndo_tx_timeout		= bnx2x_tx_timeout,
-#ifdef BCM_VLAN
-	.ndo_vlan_rx_register	= bnx2x_vlan_rx_register,
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= poll_bnx2x,
 #endif
@@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 		dev->features |= NETIF_F_HIGHDMA;
 	dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
 	dev->features |= NETIF_F_TSO6;
-#ifdef BCM_VLAN
 	dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
-	bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
 
 	dev->vlan_features |= NETIF_F_SG;
 	dev->vlan_features |= NETIF_F_HW_CSUM;
@@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 		dev->vlan_features |= NETIF_F_HIGHDMA;
 	dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
 	dev->vlan_features |= NETIF_F_TSO6;
-#endif
 
 	/* get_port_hwinfo() will set prtad and mmds properly */
 	bp->mdio.prtad = MDIO_PRTAD_NONE;
-- 
1.7.1


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

* [PATCH v2 12/14] lro: Remove explicit vlan support.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (10 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 11/14] bnx2x: Update bnx2x " Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 13/14] bonding: Update bonding for new vlan model Jesse Gross
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Using the new vlan accleration model, LRO no longer needs to be
explicitly passed the vlan information because it is contained in
the skb.  Since all LRO did was pass the vlan through, this removes
that knowledge.

Signed-off-by: Jesse Gross <jesse@nicira.com>
--
This patch can only be applied once all drivers that use LRO and vlan acceleration
have been converted over to the new model.
---
 include/linux/inet_lro.h |   20 ------------
 net/ipv4/inet_lro.c      |   74 +++++++---------------------------------------
 2 files changed, 11 insertions(+), 83 deletions(-)

diff --git a/include/linux/inet_lro.h b/include/linux/inet_lro.h
index c4335fa..667281a 100644
--- a/include/linux/inet_lro.h
+++ b/include/linux/inet_lro.h
@@ -50,7 +50,6 @@ struct net_lro_desc {
 	struct skb_frag_struct *next_frag;
 	struct iphdr *iph;
 	struct tcphdr *tcph;
-	struct vlan_group *vgrp;
 	__wsum  data_csum;
 	__be32 tcp_rcv_tsecr;
 	__be32 tcp_rcv_tsval;
@@ -60,9 +59,7 @@ struct net_lro_desc {
 	u16 ip_tot_len;
 	u16 tcp_saw_tstamp; 		/* timestamps enabled */
 	__be16 tcp_window;
-	u16 vlan_tag;
 	int pkt_aggr_cnt;		/* counts aggregated packets */
-	int vlan_packet;
 	int mss;
 	int active;
 };
@@ -137,16 +134,6 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr,
 		     void *priv);
 
 /*
- * Processes a SKB with VLAN HW acceleration support
- */
-
-void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
-				  struct sk_buff *skb,
-				  struct vlan_group *vgrp,
-				  u16 vlan_tag,
-				  void *priv);
-
-/*
  * Processes a fragment list
  *
  * This functions aggregate fragments and generate SKBs do pass
@@ -165,13 +152,6 @@ void lro_receive_frags(struct net_lro_mgr *lro_mgr,
 		       struct skb_frag_struct *frags,
 		       int len, int true_size, void *priv, __wsum sum);
 
-void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
-				    struct skb_frag_struct *frags,
-				    int len, int true_size,
-				    struct vlan_group *vgrp,
-				    u16 vlan_tag,
-				    void *priv, __wsum sum);
-
 /*
  * Forward all aggregated SKBs held by lro_mgr to network stack
  */
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c
index 47038cb..8945a1d 100644
--- a/net/ipv4/inet_lro.c
+++ b/net/ipv4/inet_lro.c
@@ -146,8 +146,7 @@ static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len)
 }
 
 static void lro_init_desc(struct net_lro_desc *lro_desc, struct sk_buff *skb,
-			  struct iphdr *iph, struct tcphdr *tcph,
-			  u16 vlan_tag, struct vlan_group *vgrp)
+			  struct iphdr *iph, struct tcphdr *tcph)
 {
 	int nr_frags;
 	__be32 *ptr;
@@ -173,8 +172,6 @@ static void lro_init_desc(struct net_lro_desc *lro_desc, struct sk_buff *skb,
 	}
 
 	lro_desc->mss = tcp_data_len;
-	lro_desc->vgrp = vgrp;
-	lro_desc->vlan_tag = vlan_tag;
 	lro_desc->active = 1;
 
 	lro_desc->data_csum = lro_tcp_data_csum(iph, tcph,
@@ -309,29 +306,17 @@ static void lro_flush(struct net_lro_mgr *lro_mgr,
 
 	skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss;
 
-	if (lro_desc->vgrp) {
-		if (lro_mgr->features & LRO_F_NAPI)
-			vlan_hwaccel_receive_skb(lro_desc->parent,
-						 lro_desc->vgrp,
-						 lro_desc->vlan_tag);
-		else
-			vlan_hwaccel_rx(lro_desc->parent,
-					lro_desc->vgrp,
-					lro_desc->vlan_tag);
-
-	} else {
-		if (lro_mgr->features & LRO_F_NAPI)
-			netif_receive_skb(lro_desc->parent);
-		else
-			netif_rx(lro_desc->parent);
-	}
+	if (lro_mgr->features & LRO_F_NAPI)
+		netif_receive_skb(lro_desc->parent);
+	else
+		netif_rx(lro_desc->parent);
 
 	LRO_INC_STATS(lro_mgr, flushed);
 	lro_clear_desc(lro_desc);
 }
 
 static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
-			  struct vlan_group *vgrp, u16 vlan_tag, void *priv)
+			  void *priv)
 {
 	struct net_lro_desc *lro_desc;
 	struct iphdr *iph;
@@ -360,7 +345,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
 			goto out;
 
 		skb->ip_summed = lro_mgr->ip_summed_aggr;
-		lro_init_desc(lro_desc, skb, iph, tcph, vlan_tag, vgrp);
+		lro_init_desc(lro_desc, skb, iph, tcph);
 		LRO_INC_STATS(lro_mgr, aggregated);
 		return 0;
 	}
@@ -433,8 +418,7 @@ static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr,
 static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr,
 					  struct skb_frag_struct *frags,
 					  int len, int true_size,
-					  struct vlan_group *vgrp,
-					  u16 vlan_tag, void *priv, __wsum sum)
+					  void *priv, __wsum sum)
 {
 	struct net_lro_desc *lro_desc;
 	struct iphdr *iph;
@@ -480,7 +464,7 @@ static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr,
 		tcph = (void *)((u8 *)skb->data + vlan_hdr_len
 				+ IP_HDR_LEN(iph));
 
-		lro_init_desc(lro_desc, skb, iph, tcph, 0, NULL);
+		lro_init_desc(lro_desc, skb, iph, tcph);
 		LRO_INC_STATS(lro_mgr, aggregated);
 		return NULL;
 	}
@@ -514,7 +498,7 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr,
 		     struct sk_buff *skb,
 		     void *priv)
 {
-	if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) {
+	if (__lro_proc_skb(lro_mgr, skb, priv)) {
 		if (lro_mgr->features & LRO_F_NAPI)
 			netif_receive_skb(skb);
 		else
@@ -523,29 +507,13 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr,
 }
 EXPORT_SYMBOL(lro_receive_skb);
 
-void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,
-				  struct sk_buff *skb,
-				  struct vlan_group *vgrp,
-				  u16 vlan_tag,
-				  void *priv)
-{
-	if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) {
-		if (lro_mgr->features & LRO_F_NAPI)
-			vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
-		else
-			vlan_hwaccel_rx(skb, vgrp, vlan_tag);
-	}
-}
-EXPORT_SYMBOL(lro_vlan_hwaccel_receive_skb);
-
 void lro_receive_frags(struct net_lro_mgr *lro_mgr,
 		       struct skb_frag_struct *frags,
 		       int len, int true_size, void *priv, __wsum sum)
 {
 	struct sk_buff *skb;
 
-	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, NULL, 0,
-				 priv, sum);
+	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, priv, sum);
 	if (!skb)
 		return;
 
@@ -556,26 +524,6 @@ void lro_receive_frags(struct net_lro_mgr *lro_mgr,
 }
 EXPORT_SYMBOL(lro_receive_frags);
 
-void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,
-				    struct skb_frag_struct *frags,
-				    int len, int true_size,
-				    struct vlan_group *vgrp,
-				    u16 vlan_tag, void *priv, __wsum sum)
-{
-	struct sk_buff *skb;
-
-	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, vgrp,
-				 vlan_tag, priv, sum);
-	if (!skb)
-		return;
-
-	if (lro_mgr->features & LRO_F_NAPI)
-		vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);
-	else
-		vlan_hwaccel_rx(skb, vgrp, vlan_tag);
-}
-EXPORT_SYMBOL(lro_vlan_hwaccel_receive_frags);
-
 void lro_flush_all(struct net_lro_mgr *lro_mgr)
 {
 	int i;
-- 
1.7.1


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

* [PATCH v2 13/14] bonding: Update bonding for new vlan model.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (11 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 12/14] lro: Remove explicit vlan support Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-20 23:56 ` [PATCH v2 14/14] vlan: Remove accleration legacy functions Jesse Gross
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

It is no longer necessary to register vlan groups, so update bonding
to not do that on its slaves.  Although the new vlan accleration
model allows additional flexibility, bonding continues to require vlan
devices since it needs addtional system state to handle ARP/IGMP.  This
also removes fallback code for non-vlan acclerated slaves since core
networking now handles that.

Signed-off-by: Jesse Gross <jesse@nicira.com>
--
This patch can only be applied once all drivers that use vlan acceleration
have been converted over to the new model.
---
 drivers/net/bonding/bond_alb.c  |    8 +--
 drivers/net/bonding/bond_ipv6.c |    5 +-
 drivers/net/bonding/bond_main.c |  143 ++++++++-------------------------------
 drivers/net/bonding/bonding.h   |    1 -
 4 files changed, 32 insertions(+), 125 deletions(-)

diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 26bb118..c911456 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -685,10 +685,8 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
 			client_info->ntt = 0;
 		}
 
-		if (bond->vlgrp) {
-			if (!vlan_get_tag(skb, &client_info->vlan_id))
-				client_info->tag = 1;
-		}
+		if (!vlan_get_tag(skb, &client_info->vlan_id))
+			client_info->tag = 1;
 
 		if (!client_info->assigned) {
 			u32 prev_tbl_head = bond_info->rx_hashtbl_head;
@@ -907,7 +905,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
 		skb->priority = TC_PRIO_CONTROL;
 		skb->dev = slave->dev;
 
-		if (bond->vlgrp) {
+		if (!list_empty(&bond->vlan_list)) {
 			struct vlan_entry *vlan;
 
 			vlan = bond_next_vlan(bond,
diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c
index 121b073..c276b5a 100644
--- a/drivers/net/bonding/bond_ipv6.c
+++ b/drivers/net/bonding/bond_ipv6.c
@@ -178,10 +178,7 @@ static int bond_inet6addr_event(struct notifier_block *this,
 		}
 
 		list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-			if (!bond->vlgrp)
-				continue;
-			vlan_dev = vlan_group_get_device(bond->vlgrp,
-							 vlan->vlan_id);
+			vlan_dev = vlan_find_dev(bond->dev, vlan->vlan_id);
 			if (vlan_dev == event_dev) {
 				switch (event) {
 				case NETDEV_UP:
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6b9a7bd..1b89b61 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -418,36 +418,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
  * @bond: bond device that got this skb for tx.
  * @skb: hw accel VLAN tagged skb to transmit
  * @slave_dev: slave that is supposed to xmit this skbuff
- *
- * When the bond gets an skb to transmit that is
- * already hardware accelerated VLAN tagged, and it
- * needs to relay this skb to a slave that is not
- * hw accel capable, the skb needs to be "unaccelerated",
- * i.e. strip the hwaccel tag and re-insert it as part
- * of the payload.
  */
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
 			struct net_device *slave_dev)
 {
-	unsigned short uninitialized_var(vlan_id);
-
-	/* Test vlan_list not vlgrp to catch and handle 802.1p tags */
-	if (!list_empty(&bond->vlan_list) &&
-	    !(slave_dev->features & NETIF_F_HW_VLAN_TX) &&
-	    vlan_get_tag(skb, &vlan_id) == 0) {
-		skb->dev = slave_dev;
-		skb = vlan_put_tag(skb, vlan_id);
-		if (!skb) {
-			/* vlan_put_tag() frees the skb in case of error,
-			 * so return success here so the calling functions
-			 * won't attempt to free is again.
-			 */
-			return 0;
-		}
-	} else {
-		skb->dev = slave_dev;
-	}
-
+	skb->dev = slave_dev;
 	skb->priority = 1;
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) {
@@ -464,8 +439,8 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
 }
 
 /*
- * In the following 3 functions, bond_vlan_rx_register(), bond_vlan_rx_add_vid
- * and bond_vlan_rx_kill_vid, We don't protect the slave list iteration with a
+ * In the following 2 functions, bond_vlan_rx_add_vid and
+ * bond_vlan_rx_kill_vid, we don't protect the slave list iteration with a
  * lock because:
  * a. This operation is performed in IOCTL context,
  * b. The operation is protected by the RTNL semaphore in the 8021q code,
@@ -482,33 +457,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
 */
 
 /**
- * bond_vlan_rx_register - Propagates registration to slaves
- * @bond_dev: bonding net device that got called
- * @grp: vlan group being registered
- */
-static void bond_vlan_rx_register(struct net_device *bond_dev,
-				  struct vlan_group *grp)
-{
-	struct bonding *bond = netdev_priv(bond_dev);
-	struct slave *slave;
-	int i;
-
-	write_lock(&bond->lock);
-	bond->vlgrp = grp;
-	write_unlock(&bond->lock);
-
-	bond_for_each_slave(bond, slave, i) {
-		struct net_device *slave_dev = slave->dev;
-		const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
-
-		if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
-		    slave_ops->ndo_vlan_rx_register) {
-			slave_ops->ndo_vlan_rx_register(slave_dev, grp);
-		}
-	}
-}
-
-/**
  * bond_vlan_rx_add_vid - Propagates adding an id to slaves
  * @bond_dev: bonding net device that got called
  * @vid: vlan id being added
@@ -545,7 +493,6 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct slave *slave;
-	struct net_device *vlan_dev;
 	int i, res;
 
 	bond_for_each_slave(bond, slave, i) {
@@ -553,14 +500,8 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
 		const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
 
 		if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) &&
-		    slave_ops->ndo_vlan_rx_kill_vid) {
-			/* Save and then restore vlan_dev in the grp array,
-			 * since the slave's driver might clear it.
-			 */
-			vlan_dev = vlan_group_get_device(bond->vlgrp, vid);
+		    slave_ops->ndo_vlan_rx_kill_vid)
 			slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vid);
-			vlan_group_set_device(bond->vlgrp, vid, vlan_dev);
-		}
 	}
 
 	res = bond_del_vlan(bond, vid);
@@ -575,13 +516,6 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla
 	struct vlan_entry *vlan;
 	const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
 
-	if (!bond->vlgrp)
-		return;
-
-	if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
-	    slave_ops->ndo_vlan_rx_register)
-		slave_ops->ndo_vlan_rx_register(slave_dev, bond->vlgrp);
-
 	if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
 	    !(slave_ops->ndo_vlan_rx_add_vid))
 		return;
@@ -595,30 +529,17 @@ static void bond_del_vlans_from_slave(struct bonding *bond,
 {
 	const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
 	struct vlan_entry *vlan;
-	struct net_device *vlan_dev;
-
-	if (!bond->vlgrp)
-		return;
 
 	if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
 	    !(slave_ops->ndo_vlan_rx_kill_vid))
-		goto unreg;
+		return;
 
 	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
 		if (!vlan->vlan_id)
 			continue;
-		/* Save and then restore vlan_dev in the grp array,
-		 * since the slave's driver might clear it.
-		 */
-		vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
+
 		slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vlan->vlan_id);
-		vlan_group_set_device(bond->vlgrp, vlan->vlan_id, vlan_dev);
 	}
-
-unreg:
-	if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
-	    slave_ops->ndo_vlan_rx_register)
-		slave_ops->ndo_vlan_rx_register(slave_dev, NULL);
 }
 
 /*------------------------------- Link status -------------------------------*/
@@ -896,23 +817,22 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
 	struct vlan_entry *vlan;
 
 	read_lock(&bond->lock);
+	rcu_read_lock();
 
 	/* rejoin all groups on bond device */
 	__bond_resend_igmp_join_requests(bond->dev);
 
 	/* rejoin all groups on vlan devices */
-	if (bond->vlgrp) {
-		list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-			vlan_dev = vlan_group_get_device(bond->vlgrp,
-							 vlan->vlan_id);
-			if (vlan_dev)
-				__bond_resend_igmp_join_requests(vlan_dev);
-		}
+	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
+		vlan_dev = vlan_find_dev(bond->dev, vlan->vlan_id);
+		if (vlan_dev)
+			__bond_resend_igmp_join_requests(vlan_dev);
 	}
 
 	if (--bond->igmp_retrans > 0)
 		queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
 
+	rcu_read_unlock();
 	read_unlock(&bond->lock);
 }
 
@@ -1386,8 +1306,7 @@ static int bond_sethwaddr(struct net_device *bond_dev,
 }
 
 #define BOND_VLAN_FEATURES \
-	(NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
-	 NETIF_F_HW_VLAN_FILTER)
+	(NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER)
 
 /*
  * Compute the common dev->feature set available to all slaves.  Some
@@ -1483,7 +1402,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 	/* no need to lock since we're protected by rtnl_lock */
 	if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
 		pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
-		if (bond->vlgrp) {
+		if (!list_empty(&bond->vlan_list)) {
 			pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
 			       bond_dev->name, slave_dev->name, bond_dev->name);
 			return -EPERM;
@@ -1976,9 +1895,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 		 */
 		memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
 
-		if (!bond->vlgrp) {
-			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
-		} else {
+		if (!list_empty(&bond->vlan_list)) {
 			pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
 				   bond_dev->name, bond_dev->name);
 			pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
@@ -2167,9 +2084,7 @@ static int bond_release_all(struct net_device *bond_dev)
 	 */
 	memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
 
-	if (!bond->vlgrp) {
-		bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
-	} else {
+	if (!list_empty(&bond->vlan_list)) {
 		pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
 			   bond_dev->name, bond_dev->name);
 		pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
@@ -2604,11 +2519,13 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 	struct flowi fl;
 	struct rtable *rt;
 
+	rcu_read_lock();
+
 	for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
 		if (!targets[i])
 			break;
 		pr_debug("basa: target %x\n", targets[i]);
-		if (!bond->vlgrp) {
+		if (list_empty(&bond->vlan_list)) {
 			pr_debug("basa: empty vlan: arp_send\n");
 			bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
 				      bond->master_ip, 0);
@@ -2646,7 +2563,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 
 		vlan_id = 0;
 		list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-			vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
+			vlan_dev = vlan_find_dev(bond->dev, vlan->vlan_id);
 			if (vlan_dev == rt->dst.dev) {
 				vlan_id = vlan->vlan_id;
 				pr_debug("basa: vlan match on %s %d\n",
@@ -2669,6 +2586,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 		}
 		ip_rt_put(rt);
 	}
+
+	rcu_read_unlock();
 }
 
 /*
@@ -2697,16 +2616,17 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
 				bond->master_ip, 0);
 	}
 
-	if (!bond->vlgrp)
-		return;
+	rcu_read_lock();
 
 	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-		vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
+		vlan_dev = vlan_find_dev(bond->dev, vlan->vlan_id);
 		if (vlan->vlan_ip) {
 			bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip,
 				      vlan->vlan_ip, vlan->vlan_id);
 		}
 	}
+
+	rcu_read_unlock();
 }
 
 static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip)
@@ -3660,9 +3580,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
 		}
 
 		list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-			if (!bond->vlgrp)
-				continue;
-			vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
+			vlan_dev = vlan_find_dev(bond->dev, vlan->vlan_id);
 			if (vlan_dev == event_dev) {
 				switch (event) {
 				case NETDEV_UP:
@@ -4670,7 +4588,6 @@ static const struct net_device_ops bond_netdev_ops = {
 	.ndo_change_mtu		= bond_change_mtu,
 	.ndo_set_mac_address 	= bond_set_mac_address,
 	.ndo_neigh_setup	= bond_neigh_setup,
-	.ndo_vlan_rx_register	= bond_vlan_rx_register,
 	.ndo_vlan_rx_add_vid 	= bond_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= bond_vlan_rx_kill_vid,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4730,13 +4647,9 @@ static void bond_setup(struct net_device *bond_dev)
 	bond_dev->features |= NETIF_F_LLTX;
 
 	/* By default, we declare the bond to be fully
-	 * VLAN hardware accelerated capable. Special
-	 * care is taken in the various xmit functions
-	 * when there are slaves that are not hw accel
-	 * capable
+	 * VLAN hardware accelerated capable.
 	 */
 	bond_dev->features |= (NETIF_F_HW_VLAN_TX |
-			       NETIF_F_HW_VLAN_RX |
 			       NETIF_F_HW_VLAN_FILTER);
 
 	/* By default, we enable GRO on bonding devices.
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 2c12a5f..e9de73a 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -248,7 +248,6 @@ struct bonding {
 	struct   alb_bond_info alb_info;
 	struct   bond_params params;
 	struct   list_head vlan_list;
-	struct   vlan_group *vlgrp;
 	struct   packet_type arp_mon_pt;
 	struct   workqueue_struct *wq;
 	struct   delayed_work mii_work;
-- 
1.7.1


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

* [PATCH v2 14/14] vlan: Remove accleration legacy functions.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (12 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 13/14] bonding: Update bonding for new vlan model Jesse Gross
@ 2010-10-20 23:56 ` Jesse Gross
  2010-10-21  2:02 ` [PATCH v2 00/14] Move vlan acceleration into networking core David Dillow
  2010-10-21  8:33 ` David Miller
  15 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-20 23:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

This removes the explicit vlan accleration functions that acted
as shims in favor of the main receive functions that can now
handle vlans.

Signed-off-by: Jesse Gross <jesse@nicira.com>
--
This patch can only be applied once all drivers that use vlan acceleration
have been converted over to the new model.
---
 include/linux/if_vlan.h   |   63 +++------------------------------------------
 include/linux/netdevice.h |    8 -----
 net/8021q/vlan.c          |    7 +----
 net/8021q/vlan_core.c     |   25 ------------------
 4 files changed, 5 insertions(+), 98 deletions(-)

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index a0d9786..e607256 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -74,6 +74,10 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
 /* found in socket.c */
 extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
 
+#define vlan_tx_tag_present(__skb)	((__skb)->vlan_tci & VLAN_TAG_PRESENT)
+#define vlan_tx_tag_get(__skb)		((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 /* if this changes, algorithm will have to be reworked because this
  * depends on completely exhausting the VLAN identifier space.  Thus
  * it gives constant time look-up, but in many cases it wastes memory.
@@ -111,10 +115,6 @@ static inline void vlan_group_set_device(struct vlan_group *vg,
 	array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
 }
 
-#define vlan_tx_tag_present(__skb)	((__skb)->vlan_tci & VLAN_TAG_PRESENT)
-#define vlan_tx_tag_get(__skb)		((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
-
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 /* Must be invoked with rcu_read_lock or with RTNL. */
 static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
 					       u16 vlan_id)
@@ -130,15 +130,7 @@ static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
 extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
 extern u16 vlan_dev_vlan_id(const struct net_device *dev);
 
-extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
-			     u16 vlan_tci, int polling);
 extern bool vlan_hwaccel_do_receive(struct sk_buff **skb);
-extern gro_result_t
-vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
-		 unsigned int vlan_tci, struct sk_buff *skb);
-extern gro_result_t
-vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
-	       unsigned int vlan_tci);
 
 #else
 static inline struct net_device *vlan_find_dev(struct net_device *real_dev,
@@ -159,61 +151,14 @@ static inline u16 vlan_dev_vlan_id(const struct net_device *dev)
 	return 0;
 }
 
-static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
-				    u16 vlan_tci, int polling)
-{
-	BUG();
-	return NET_XMIT_SUCCESS;
-}
-
 static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb)
 {
 	BUG();
 	return false;
 }
-
-static inline gro_result_t
-vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
-		 unsigned int vlan_tci, struct sk_buff *skb)
-{
-	return GRO_DROP;
-}
-
-static inline gro_result_t
-vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
-	       unsigned int vlan_tci)
-{
-	return GRO_DROP;
-}
 #endif
 
 /**
- * vlan_hwaccel_rx - netif_rx wrapper for VLAN RX acceleration
- * @skb: buffer
- * @grp: vlan group
- * @vlan_tci: VLAN TCI as received from the card
- */
-static inline int vlan_hwaccel_rx(struct sk_buff *skb,
-				  struct vlan_group *grp,
-				  u16 vlan_tci)
-{
-	return __vlan_hwaccel_rx(skb, grp, vlan_tci, 0);
-}
-
-/**
- * vlan_hwaccel_receive_skb - netif_receive_skb wrapper for VLAN RX acceleration
- * @skb: buffer
- * @grp: vlan group
- * @vlan_tci: VLAN TCI as received from the card
- */
-static inline int vlan_hwaccel_receive_skb(struct sk_buff *skb,
-					   struct vlan_group *grp,
-					   u16 vlan_tci)
-{
-	return __vlan_hwaccel_rx(skb, grp, vlan_tci, 1);
-}
-
-/**
  * __vlan_put_tag - regular VLAN tag inserting
  * @skb: skbuff to tag
  * @vlan_tci: VLAN TCI to insert
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ed7db7e..22c3c46 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -682,12 +682,6 @@ struct netdev_rx_queue {
  *	3. Update dev->stats asynchronously and atomically, and define
  *	   neither operation.
  *
- * void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp);
- *	If device support VLAN receive accleration
- *	(ie. dev->features & NETIF_F_HW_VLAN_RX), then this function is called
- *	when vlan groups for the device changes.  Note: grp is NULL
- *	if no vlan's groups are being used.
- *
  * void (*ndo_vlan_rx_add_vid)(struct net_device *dev, unsigned short vid);
  *	If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER)
  *	this function is called when a VLAN id is registered.
@@ -739,8 +733,6 @@ struct net_device_ops {
 						     struct rtnl_link_stats64 *storage);
 	struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
 
-	void			(*ndo_vlan_rx_register)(struct net_device *dev,
-						        struct vlan_group *grp);
 	void			(*ndo_vlan_rx_add_vid)(struct net_device *dev,
 						       unsigned short vid);
 	void			(*ndo_vlan_rx_kill_vid)(struct net_device *dev,
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 05b867e..4e91db3 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -135,8 +135,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 		vlan_gvrp_uninit_applicant(real_dev);
 
 		rcu_assign_pointer(real_dev->vlgrp, NULL);
-		if (ops->ndo_vlan_rx_register)
-			ops->ndo_vlan_rx_register(real_dev, NULL);
 
 		/* Free the group, after all cpu's are done. */
 		call_rcu(&grp->rcu, vlan_rcu_free);
@@ -207,11 +205,8 @@ int register_vlan_dev(struct net_device *dev)
 	vlan_group_set_device(grp, vlan_id, dev);
 	grp->nr_vlans++;
 
-	if (ngrp) {
-		if (ops->ndo_vlan_rx_register)
-			ops->ndo_vlan_rx_register(real_dev, ngrp);
+	if (ngrp)
 		rcu_assign_pointer(real_dev->vlgrp, ngrp);
-	}
 	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
 		ops->ndo_vlan_rx_add_vid(real_dev, vlan_id);
 
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 69b2f79..4d6a2b8 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -63,28 +63,3 @@ u16 vlan_dev_vlan_id(const struct net_device *dev)
 	return vlan_dev_info(dev)->vlan_id;
 }
 EXPORT_SYMBOL(vlan_dev_vlan_id);
-
-/* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
-int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
-		      u16 vlan_tci, int polling)
-{
-	__vlan_hwaccel_put_tag(skb, vlan_tci);
-	return polling ? netif_receive_skb(skb) : netif_rx(skb);
-}
-EXPORT_SYMBOL(__vlan_hwaccel_rx);
-
-gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
-			      unsigned int vlan_tci, struct sk_buff *skb)
-{
-	__vlan_hwaccel_put_tag(skb, vlan_tci);
-	return napi_gro_receive(napi, skb);
-}
-EXPORT_SYMBOL(vlan_gro_receive);
-
-gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
-			    unsigned int vlan_tci)
-{
-	__vlan_hwaccel_put_tag(napi->skb, vlan_tci);
-	return napi_gro_frags(napi);
-}
-EXPORT_SYMBOL(vlan_gro_frags);
-- 
1.7.1


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

* Re: [PATCH v2 00/14] Move vlan acceleration into networking core.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (13 preceding siblings ...)
  2010-10-20 23:56 ` [PATCH v2 14/14] vlan: Remove accleration legacy functions Jesse Gross
@ 2010-10-21  2:02 ` David Dillow
  2010-10-21 19:32   ` Jesse Gross
  2010-10-21  8:33 ` David Miller
  15 siblings, 1 reply; 48+ messages in thread
From: David Dillow @ 2010-10-21  2:02 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev

On Wed, 2010-10-20 at 16:56 -0700, Jesse Gross wrote:
> The first eleven patches can be applied immediately, while the last three need
> to wait until all drivers that support vlan acceleration are updated.  If
> people agree that this patch set makes sense I will go ahead and switch over
> the dozen or so drivers that would need to change.

Here's a first pass at converting typhoon to the new methods. It is
compile tested, but I have to put the hardware back in a machine to do
some testing, which I may not be able to do before the weekend.

Of course, we could just change it to not offload by default if we need
to push this sooner.

Applies to net-next-2.6 with the vlan changes.



diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 1cc6713..5ee0324 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -280,8 +280,6 @@ struct typhoon {
 	struct pci_dev *	pdev;
 	struct net_device *	dev;
 	struct napi_struct	napi;
-	spinlock_t		state_lock;
-	struct vlan_group *	vlgrp;
 	struct basic_ring	rxHiRing;
 	struct basic_ring	rxBuffRing;
 	struct rxbuff_ent	rxbuffers[RXENT_ENTRIES];
@@ -695,42 +693,39 @@ out:
 	return err;
 }
 
-static void
-typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+static int
+typhoon_offload_vlan(struct net_device *dev, bool enabled)
 {
 	struct typhoon *tp = netdev_priv(dev);
+	__le32 offload = tp->offload;
 	struct cmd_desc xp_cmd;
 	int err;
 
-	spin_lock_bh(&tp->state_lock);
-	if(!tp->vlgrp != !grp) {
-		/* We've either been turned on for the first time, or we've
-		 * been turned off. Update the 3XP.
-		 */
-		if(grp)
-			tp->offload |= TYPHOON_OFFLOAD_VLAN;
-		else
-			tp->offload &= ~TYPHOON_OFFLOAD_VLAN;
-
-		/* If the interface is up, the runtime is running -- and we
-		 * must be up for the vlan core to call us.
-		 *
-		 * Do the command outside of the spin lock, as it is slow.
-		 */
-		INIT_COMMAND_WITH_RESPONSE(&xp_cmd,
-					TYPHOON_CMD_SET_OFFLOAD_TASKS);
-		xp_cmd.parm2 = tp->offload;
-		xp_cmd.parm3 = tp->offload;
-		spin_unlock_bh(&tp->state_lock);
-		err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
-		if(err < 0)
-			netdev_err(tp->dev, "vlan offload error %d\n", -err);
-		spin_lock_bh(&tp->state_lock);
-	}
-
-	/* now make the change visible */
-	tp->vlgrp = grp;
-	spin_unlock_bh(&tp->state_lock);
+	if (enabled)
+		offload |= TYPHOON_OFFLOAD_VLAN;
+	else
+		offload &= ~TYPHOON_OFFLOAD_VLAN;
+
+	if (offload == tp->offload)
+		return 0;
+
+	/* We've either been turned on for the first time, or we've
+	 * been turned off. Save the setting, and update the 3XP if the
+	 * runtime is active.
+	 *
+	 * Caller must hold the RTNL lock.
+	 */
+	tp->offload = offload;
+	if (!netif_running(dev))
+		return 0;
+
+	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS);
+	xp_cmd.parm2 = tp->offload;
+	xp_cmd.parm3 = tp->offload;
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		netdev_err(tp->dev, "vlan offload error %d\n", -err);
+	return err;
 }
 
 static inline void
@@ -1198,6 +1193,30 @@ typhoon_get_rx_csum(struct net_device *dev)
 	return 1;
 }
 
+static int
+typhoon_set_flags(struct net_device *dev, u32 data)
+{
+	u32 orig_flags = dev->features;
+	int rc;
+
+	/* VLAN offloading is a package deal on the 3XP -- if enabled,
+	 * we'll always have RX offload active, but we can choose to
+	 * not use the TX offload.
+	 */
+	if ((data & ETH_FLAG_TXVLAN) && !(data & ETH_FLAG_RXVLAN))
+		return -EINVAL;
+
+	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
+	if (rc)
+		return rc;
+
+	data &= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN;
+	rc = typhoon_offload_vlan(dev, data);
+	if (rc)
+		dev->features = orig_flags;
+	return rc;
+}
+
 static void
 typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
@@ -1224,6 +1243,8 @@ static const struct ethtool_ops typhoon_ethtool_ops = {
 	.set_sg			= ethtool_op_set_sg,
 	.set_tso		= ethtool_op_set_tso,
 	.get_ringparam		= typhoon_get_ringparam,
+	.set_flags		= typhoon_set_flags,
+	.get_flags		= ethtool_op_get_flags,
 };
 
 static int
@@ -1309,9 +1330,9 @@ typhoon_init_interface(struct typhoon *tp)
 
 	tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
 	tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
+	tp->offload |= TYPHOON_OFFLOAD_VLAN;
 
 	spin_lock_init(&tp->command_lock);
-	spin_lock_init(&tp->state_lock);
 
 	/* Force the writes to the shared memory area out before continuing. */
 	wmb();
@@ -1762,13 +1783,10 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read
 		} else
 			skb_checksum_none_assert(new_skb);
 
-		spin_lock(&tp->state_lock);
-		if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN)
-			vlan_hwaccel_receive_skb(new_skb, tp->vlgrp,
-						 ntohl(rx->vlanTag) & 0xffff);
-		else
-			netif_receive_skb(new_skb);
-		spin_unlock(&tp->state_lock);
+		if (rx->rxStatus & TYPHOON_RX_VLAN)
+			__vlan_hwaccel_put_tag(new_skb,
+					       ntohl(rx->vlanTag) & 0xffff);
+		netif_receive_skb(new_skb);
 
 		received++;
 		budget--;
@@ -1989,11 +2007,9 @@ typhoon_start_runtime(struct typhoon *tp)
 		goto error_out;
 
 	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS);
-	spin_lock_bh(&tp->state_lock);
 	xp_cmd.parm2 = tp->offload;
 	xp_cmd.parm3 = tp->offload;
 	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
-	spin_unlock_bh(&tp->state_lock);
 	if(err < 0)
 		goto error_out;
 
@@ -2231,13 +2247,9 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
 	if(!netif_running(dev))
 		return 0;
 
-	spin_lock_bh(&tp->state_lock);
-	if(tp->vlgrp && tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) {
-		spin_unlock_bh(&tp->state_lock);
-		netdev_err(dev, "cannot do WAKE_MAGIC with VLANS\n");
-		return -EBUSY;
-	}
-	spin_unlock_bh(&tp->state_lock);
+	if(tp->offload & TYPHOON_OFFLOAD_VLAN &&
+				tp->wol_events & TYPHOON_WAKE_MAGIC_PKT)
+		netdev_warn(dev, "WAKE_MAGIC does not work with VLANS\n");
 
 	netif_device_detach(dev);
 
@@ -2338,7 +2350,6 @@ static const struct net_device_ops typhoon_netdev_ops = {
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= typhoon_set_mac_address,
 	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_vlan_rx_register	= typhoon_vlan_rx_register,
 };
 
 static int __devinit



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

* Re: [PATCH v2 07/14] ethtool: Add support for vlan accleration.
  2010-10-20 23:56 ` [PATCH v2 07/14] ethtool: Add support for vlan accleration Jesse Gross
@ 2010-10-21  3:27   ` John Fastabend
  2010-10-21 19:43     ` Jesse Gross
  0 siblings, 1 reply; 48+ messages in thread
From: John Fastabend @ 2010-10-21  3:27 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev

On 10/20/2010 4:56 PM, Jesse Gross wrote:
> Now that vlan acceleration is handled consistently regardless of usage,
> it is possible to enable and disable it at will.  This adds support for
> Ethtool operations that change the offloading status for debugging
> purposes, similar to other forms of hardware acceleration.
> 

Jesse,

Not sure if this is enough to get dynamic toggling like this
dev->hard_header_len is set depending on offloads at init time in
vlan_dev_init(). By changing this LL_RESERVED_SPACE won't work
correctly and we end up having to call pskb_expand_head(). I think
this might end up hurting performance.

That said I think I can probably get this working by fixing up the
header_ops in vlan_dev.c.  And while I'm at it add a vlan_header_cache
and vlan_header_cache_update routines. I'll try to get something out
tomorrow in the meantime nothing too bad is happening.

Thanks,
John.

> Signed-off-by: Jesse Gross <jesse@nicira.com>
> ---
>  include/linux/ethtool.h |    2 ++
>  net/core/ethtool.c      |    3 ++-
>  2 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
> index 8a3338c..6628a50 100644
> --- a/include/linux/ethtool.h
> +++ b/include/linux/ethtool.h
> @@ -309,6 +309,8 @@ struct ethtool_perm_addr {
>   * flag differs from the read-only value.
>   */
>  enum ethtool_flags {
> +	ETH_FLAG_TXVLAN		= (1 << 7),	/* TX VLAN offload enabled */
> +	ETH_FLAG_RXVLAN		= (1 << 8),	/* RX VLAN offload enabled */
>  	ETH_FLAG_LRO		= (1 << 15),	/* LRO is enabled */
>  	ETH_FLAG_NTUPLE		= (1 << 27),	/* N-tuple filters enabled */
>  	ETH_FLAG_RXHASH		= (1 << 28),
> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> index 685c700..956a9f4 100644
> --- a/net/core/ethtool.c
> +++ b/net/core/ethtool.c
> @@ -132,7 +132,8 @@ EXPORT_SYMBOL(ethtool_op_set_ufo);
>   * NETIF_F_xxx values in include/linux/netdevice.h
>   */
>  static const u32 flags_dup_features =
> -	(ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH);
> +	(ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
> +	 ETH_FLAG_RXHASH);
>  
>  u32 ethtool_op_get_flags(struct net_device *dev)
>  {


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

* Re: [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration.
  2010-10-20 23:56 ` [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration Jesse Gross
@ 2010-10-21  3:32   ` John Fastabend
  2010-10-21 15:30   ` Ben Hutchings
  1 sibling, 0 replies; 48+ messages in thread
From: John Fastabend @ 2010-10-21  3:32 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev

On 10/20/2010 4:56 PM, Jesse Gross wrote:
> Currently users of hardware vlan accleration need to know whether
> the device supports it before generating packets.  However, vlan
> acceleration will soon be available in a more flexible manner so
> knowing ahead of time becomes much more difficult.  This adds
> a software fallback path for vlan packets on devices without the
> necessary offloading support, similar to other types of hardware
> accleration.
> 
> Signed-off-by: Jesse Gross <jesse@nicira.com>
> ---
>  include/linux/netdevice.h |   14 +++++++++++---
>  net/core/dev.c            |   36 +++++++++++++++++++++++++++++++++---
>  2 files changed, 44 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 880d565..2861565 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -2248,9 +2248,17 @@ static inline int skb_gso_ok(struct sk_buff *skb, int features)
>  
>  static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
>  {
> -	return skb_is_gso(skb) &&
> -	       (!skb_gso_ok(skb, dev->features) ||
> -		unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
> +	if (skb_is_gso(skb)) {
> +		int features = dev->features;
> +
> +		if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci)
> +			features &= dev->vlan_features;
> +
> +		return (!skb_gso_ok(skb, features) ||
> +			unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
> +	}
> +
> +	return 0;
>  }
>  
>  static inline void netif_set_gso_max_size(struct net_device *dev,
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 4c3ac53..1bfd96b 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1694,7 +1694,12 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
>  
>  static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
>  {
> -	if (can_checksum_protocol(dev->features, skb->protocol))
> +	int features = dev->features;
> +
> +	if (vlan_tx_tag_present(skb))
> +		features &= dev->vlan_features;
> +
> +	if (can_checksum_protocol(features, skb->protocol))
>  		return true;
>  
>  	if (skb->protocol == htons(ETH_P_8021Q)) {
> @@ -1793,6 +1798,16 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
>  	__be16 type = skb->protocol;
>  	int err;
>  
> +	if (type == htons(ETH_P_8021Q)) {
> +		struct vlan_ethhdr *veh;
> +
> +		if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
> +			return ERR_PTR(-EINVAL);
> +
> +		veh = (struct vlan_ethhdr *)skb->data;
> +		type = veh->h_vlan_encapsulated_proto;
> +	}
> +
>  	skb_reset_mac_header(skb);
>  	skb->mac_len = skb->network_header - skb->mac_header;
>  	__skb_pull(skb, skb->mac_len);
> @@ -1964,9 +1979,14 @@ static inline void skb_orphan_try(struct sk_buff *skb)
>  static inline int skb_needs_linearize(struct sk_buff *skb,
>  				      struct net_device *dev)
>  {
> +	int features = dev->features;
> +
> +	if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb))
> +		features &= dev->vlan_features;
> +
>  	return skb_is_nonlinear(skb) &&
> -	       ((skb_has_frag_list(skb) && !(dev->features & NETIF_F_FRAGLIST)) ||
> -	        (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) ||
> +	       ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) ||
> +		(skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) ||
>  					      illegal_highdma(dev, skb))));
>  }
>  
> @@ -1989,6 +2009,15 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
>  
>  		skb_orphan_try(skb);
>  
> +		if (vlan_tx_tag_present(skb) &&
> +		    !(dev->features & NETIF_F_HW_VLAN_TX)) {
> +			skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
> +			if (unlikely(!skb))
> +				goto out;
> +
> +			skb->vlan_tci = 0;
> +		}
> +

Nice set of patches! If we tag frames in dev_hard_start_xmit() can we consolidate
the offload enabled and non-offloaded net_device_ops in 8021q. And then not tag in
vlan_dev_hard_start_xmit? I'll post an example thinking out loud here.

Thanks,
John.


>  		if (netif_needs_gso(dev, skb)) {
>  			if (unlikely(dev_gso_segment(skb)))
>  				goto out_kfree_skb;
> @@ -2050,6 +2079,7 @@ out_kfree_gso_skb:
>  		skb->destructor = DEV_GSO_CB(skb)->destructor;
>  out_kfree_skb:
>  	kfree_skb(skb);
> +out:
>  	return rc;
>  }
>  


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

* Re: [PATCH v2 00/14] Move vlan acceleration into networking core.
  2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
                   ` (14 preceding siblings ...)
  2010-10-21  2:02 ` [PATCH v2 00/14] Move vlan acceleration into networking core David Dillow
@ 2010-10-21  8:33 ` David Miller
  15 siblings, 0 replies; 48+ messages in thread
From: David Miller @ 2010-10-21  8:33 UTC (permalink / raw)
  To: jesse; +Cc: netdev

From: Jesse Gross <jesse@nicira.com>
Date: Wed, 20 Oct 2010 16:56:00 -0700

> Hardware vlan acceleration behaves fairly differently from other types of
> offloading, which limits its usefulness.  This patch series aims to bring
> it more in line with other common forms of acceleration, such as checksum
> offloading and TSO.  In doing this it eliminates common driver bugs, increases
> flexibility, and improves performance, while reducing the number of lines of
> code.
> 
> The first eleven patches can be applied immediately, while the last three need
> to wait until all drivers that support vlan acceleration are updated.  If
> people agree that this patch set makes sense I will go ahead and switch over
> the dozen or so drivers that would need to change.

First 11 patches applied, thanks!

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

* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-20 23:56 ` [PATCH v2 11/14] bnx2x: Update bnx2x " Jesse Gross
@ 2010-10-21 13:54   ` Vladislav Zolotarov
  2010-10-21 14:02     ` Vladislav Zolotarov
  0 siblings, 1 reply; 48+ messages in thread
From: Vladislav Zolotarov @ 2010-10-21 13:54 UTC (permalink / raw)
  To: Jesse Gross, David Miller; +Cc: netdev, Hao Zheng, Eilon Greenstein



> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Jesse Gross
> Sent: Thursday, October 21, 2010 1:56 AM
> To: David Miller
> Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> Subject: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> accleration.
> 
> From: Hao Zheng <hzheng@nicira.com>
> 
> Make the bnx2x driver use the new vlan accleration model.
> 
> Signed-off-by: Hao Zheng <hzheng@nicira.com>
> Signed-off-by: Jesse Gross <jesse@nicira.com>
> CC: Eilon Greenstein <eilong@broadcom.com>
> ---
>  drivers/net/bnx2x/bnx2x.h         |   10 ------
>  drivers/net/bnx2x/bnx2x_cmn.c     |   60 +++++++----------------------
> --------
>  drivers/net/bnx2x/bnx2x_ethtool.c |   33 ++++++++++----------
>  drivers/net/bnx2x/bnx2x_main.c    |    8 -----
>  4 files changed, 27 insertions(+), 84 deletions(-)
> 
> diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> index 3bf236b..9571ecf 100644
> --- a/drivers/net/bnx2x/bnx2x.h
> +++ b/drivers/net/bnx2x/bnx2x.h
> @@ -24,10 +24,6 @@
>  #define DRV_MODULE_RELDATE      "2010/10/19"
>  #define BNX2X_BC_VER            0x040200
> 
> -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
> -#define BCM_VLAN			1
> -#endif
> -
>  #define BNX2X_MULTI_QUEUE
> 
>  #define BNX2X_NEW_NAPI
> @@ -858,10 +854,6 @@ struct bnx2x {
> 
>  	int			tx_ring_size;
> 
> -#ifdef BCM_VLAN
> -	struct vlan_group	*vlgrp;
> -#endif
> -
>  	u32			rx_csum;
>  	u32			rx_buf_size;
>  /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
> @@ -925,8 +917,6 @@ struct bnx2x {
>  #define NO_MCP_FLAG			0x100
>  #define DISABLE_MSI_FLAG		0x200
>  #define BP_NOMCP(bp)			(bp->flags & NO_MCP_FLAG)
> -#define HW_VLAN_TX_FLAG			0x400
> -#define HW_VLAN_RX_FLAG			0x800
>  #define MF_FUNC_DIS			0x1000
> 
>  	int			pf_num;	/* absolute PF number */
> diff --git a/drivers/net/bnx2x/bnx2x_cmn.c
> b/drivers/net/bnx2x/bnx2x_cmn.c
> index 6905b2e..bc58375 100644
> --- a/drivers/net/bnx2x/bnx2x_cmn.c
> +++ b/drivers/net/bnx2x/bnx2x_cmn.c
> @@ -16,16 +16,13 @@
>   */
> 
>  #include <linux/etherdevice.h>
> +#include <linux/if_vlan.h>
>  #include <linux/ip.h>
>  #include <net/ipv6.h>
>  #include <net/ip6_checksum.h>
>  #include <linux/firmware.h>
>  #include "bnx2x_cmn.h"
> 
> -#ifdef BCM_VLAN
> -#include <linux/if_vlan.h>
> -#endif
> -
>  #include "bnx2x_init.h"
> 
> 
> @@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> struct bnx2x_fastpath *fp,
>  	if (likely(new_skb)) {
>  		/* fix ip xsum and give it to the stack */
>  		/* (no need to map the new skb) */
> -#ifdef BCM_VLAN
> -		int is_vlan_cqe =
> -			(le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> -			 PARSING_FLAGS_VLAN);
> -		int is_not_hwaccel_vlan_cqe =
> -			(is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
> -#endif
> 
>  		prefetch(skb);
>  		prefetch(((char *)(skb)) + L1_CACHE_BYTES);
> @@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> struct bnx2x_fastpath *fp,
>  			struct iphdr *iph;
> 
>  			iph = (struct iphdr *)skb->data;
> -#ifdef BCM_VLAN
> -			/* If there is no Rx VLAN offloading -
> -			   take VLAN tag into an account */
> -			if (unlikely(is_not_hwaccel_vlan_cqe))
> -				iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
> -#endif
>  			iph->check = 0;
>  			iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
>  		}
> 
>  		if (!bnx2x_fill_frag_skb(bp, fp, skb,
>  					 &cqe->fast_path_cqe, cqe_idx)) {
> -#ifdef BCM_VLAN
> -			if ((bp->vlgrp != NULL) &&
> -				(le16_to_cpu(cqe->fast_path_cqe.
> -				pars_flags.flags) & PARSING_FLAGS_VLAN))
> -				vlan_gro_receive(&fp->napi, bp->vlgrp,
> +			if ((le16_to_cpu(cqe->fast_path_cqe.
> +			    pars_flags.flags) & PARSING_FLAGS_VLAN))
> +				__vlan_hwaccel_put_tag(skb,
>  						 le16_to_cpu(cqe->fast_path_cqe.
> -							     vlan_tag), skb);
> -			else
> -#endif
> -				napi_gro_receive(&fp->napi, skb);
> +							     vlan_tag));
> +			napi_gro_receive(&fp->napi, skb);
>  		} else {
>  			DP(NETIF_MSG_RX_STATUS, "Failed to allocate new
> pages"
>  			   " - dropping packet!\n");
> @@ -633,15 +613,11 @@ reuse_rx:
> 
>  		skb_record_rx_queue(skb, fp->index);
> 
> -#ifdef BCM_VLAN
> -		if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
> -		    (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> -		     PARSING_FLAGS_VLAN))
> -			vlan_gro_receive(&fp->napi, bp->vlgrp,
> -				le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb);
> -		else
> -#endif
> -			napi_gro_receive(&fp->napi, skb);
> +		if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> +		     PARSING_FLAGS_VLAN)
> +			__vlan_hwaccel_put_tag(skb,
> +				le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
> +		napi_gro_receive(&fp->napi, skb);
> 
> 
>  next_rx:
> @@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff
> *skb, struct net_device *dev)
>  	   "sending pkt %u @%p  next_idx %u  bd %u @%p\n",
>  	   pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
> 
> -#ifdef BCM_VLAN
>  	if (vlan_tx_tag_present(skb)) {
>  		tx_start_bd->vlan_or_ethertype =
>  		    cpu_to_le16(vlan_tx_tag_get(skb));
>  		tx_start_bd->bd_flags.as_bitfield |=
>  		    (X_ETH_OUTBAND_VLAN <<
> ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
>  	} else
> -#endif
>  		tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
> 
>  	/* turn on parsing and get a BD */
> @@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev)
>  	schedule_delayed_work(&bp->reset_task, 0);
>  }
> 
> -#ifdef BCM_VLAN
> -/* called with rtnl_lock */
> -void bnx2x_vlan_rx_register(struct net_device *dev,
> -				   struct vlan_group *vlgrp)
> -{
> -	struct bnx2x *bp = netdev_priv(dev);
> -
> -	bp->vlgrp = vlgrp;
> -}
> -
> -#endif
> -
>  int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
>  {
>  	struct net_device *dev = pci_get_drvdata(pdev);
> diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c
> b/drivers/net/bnx2x/bnx2x_ethtool.c
> index 54fe061..daefef6 100644
> --- a/drivers/net/bnx2x/bnx2x_ethtool.c
> +++ b/drivers/net/bnx2x/bnx2x_ethtool.c
> @@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device
> *dev, u32 data)
>  	int changed = 0;
>  	int rc = 0;
> 
> -	if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
> -		return -EINVAL;
> -
>  	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
>  		printk(KERN_ERR "Handling parity error recovery. Try again
> later\n");
>  		return -EAGAIN;
>  	}
> 
> +	if (!(data & ETH_FLAG_RXVLAN))
> +		return -EOPNOTSUPP;
> +
> +	if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
> +		return -EINVAL;
> +
> +	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO |
> ETH_FLAG_RXVLAN |
> +					ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
> +	if (rc)
> +		return rc;
> +
>  	/* TPA requires Rx CSUM offloading */
>  	if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
> -		if (!bp->disable_tpa) {
> -			if (!(dev->features & NETIF_F_LRO)) {
> -				dev->features |= NETIF_F_LRO;
> -				bp->flags |= TPA_ENABLE_FLAG;
> -				changed = 1;
> -			}
> -		} else
> -			rc = -EINVAL;
> -	} else if (dev->features & NETIF_F_LRO) {
> +		if (!(bp->flags & TPA_ENABLE_FLAG)) {
> +			bp->flags |= TPA_ENABLE_FLAG;
> +			changed = 1;
> +		}
> +	} else if (bp->flags & TPA_ENABLE_FLAG) {
>  		dev->features &= ~NETIF_F_LRO;
>  		bp->flags &= ~TPA_ENABLE_FLAG;
>  		changed = 1;
>  	}
> 
> -	if (data & ETH_FLAG_RXHASH)
> -		dev->features |= NETIF_F_RXHASH;
> -	else
> -		dev->features &= ~NETIF_F_RXHASH;
> -
>  	if (changed && netif_running(dev)) {
>  		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
>  		rc = bnx2x_nic_load(bp, LOAD_NORMAL);
> diff --git a/drivers/net/bnx2x/bnx2x_main.c
> b/drivers/net/bnx2x/bnx2x_main.c
> index f22e283..ff99a2f 100644
> --- a/drivers/net/bnx2x/bnx2x_main.c
> +++ b/drivers/net/bnx2x/bnx2x_main.c
> @@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct
> bnx2x *bp,
>  	flags |= QUEUE_FLG_HC;
>  	flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
> 
> -#ifdef BCM_VLAN
>  	flags |= QUEUE_FLG_VLAN;
>  	DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
> -#endif
> 
>  	if (!fp->disable_tpa)
>  		flags |= QUEUE_FLG_TPA;
> @@ -8630,9 +8628,6 @@ static const struct net_device_ops
> bnx2x_netdev_ops = {
>  	.ndo_do_ioctl		= bnx2x_ioctl,
>  	.ndo_change_mtu		= bnx2x_change_mtu,
>  	.ndo_tx_timeout		= bnx2x_tx_timeout,
> -#ifdef BCM_VLAN
> -	.ndo_vlan_rx_register	= bnx2x_vlan_rx_register,
> -#endif
>  #ifdef CONFIG_NET_POLL_CONTROLLER
>  	.ndo_poll_controller	= poll_bnx2x,
>  #endif
> @@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct
> pci_dev *pdev,
>  		dev->features |= NETIF_F_HIGHDMA;
>  	dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
>  	dev->features |= NETIF_F_TSO6;
> -#ifdef BCM_VLAN
>  	dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
> -	bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
> 
>  	dev->vlan_features |= NETIF_F_SG;
>  	dev->vlan_features |= NETIF_F_HW_CSUM;
> @@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct
> pci_dev *pdev,
>  		dev->vlan_features |= NETIF_F_HIGHDMA;
>  	dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
>  	dev->vlan_features |= NETIF_F_TSO6;
> -#endif
> 
>  	/* get_port_hwinfo() will set prtad and mmds properly */
>  	bp->mdio.prtad = MDIO_PRTAD_NONE;
> --
> 1.7.1

Guys, when I compiled the kernel with these patches without VLAN 
support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged 
frames from the remote side to the bnx2x interface the kernel panicked. 

The stack trace got cut with the __netif_receive_skb() on top by the 
IPKVM and I'll have to connect a serial to get it all. But until I
did that maybe somebody will have any ideas anyway...

It happens regardless there is HW RX VLAN stripping enabled or not.

Thanks,
vlad

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



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

* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-21 13:54   ` Vladislav Zolotarov
@ 2010-10-21 14:02     ` Vladislav Zolotarov
  2010-10-21 14:50       ` Vladislav Zolotarov
  2010-10-21 21:34       ` Jesse Gross
  0 siblings, 2 replies; 48+ messages in thread
From: Vladislav Zolotarov @ 2010-10-21 14:02 UTC (permalink / raw)
  To: Vladislav Zolotarov, Jesse Gross, David Miller
  Cc: netdev, Hao Zheng, Eilon Greenstein



> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Vladislav Zolotarov
> Sent: Thursday, October 21, 2010 3:55 PM
> To: Jesse Gross; David Miller
> Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> Subject: RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> accleration.
> 
> 
> 
> > -----Original Message-----
> > From: netdev-owner@vger.kernel.org [mailto:netdev-
> > owner@vger.kernel.org] On Behalf Of Jesse Gross
> > Sent: Thursday, October 21, 2010 1:56 AM
> > To: David Miller
> > Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> > Subject: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> > accleration.
> >
> > From: Hao Zheng <hzheng@nicira.com>
> >
> > Make the bnx2x driver use the new vlan accleration model.
> >
> > Signed-off-by: Hao Zheng <hzheng@nicira.com>
> > Signed-off-by: Jesse Gross <jesse@nicira.com>
> > CC: Eilon Greenstein <eilong@broadcom.com>
> > ---
> >  drivers/net/bnx2x/bnx2x.h         |   10 ------
> >  drivers/net/bnx2x/bnx2x_cmn.c     |   60 +++++++--------------------
> --
> > --------
> >  drivers/net/bnx2x/bnx2x_ethtool.c |   33 ++++++++++----------
> >  drivers/net/bnx2x/bnx2x_main.c    |    8 -----
> >  4 files changed, 27 insertions(+), 84 deletions(-)
> >
> > diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> > index 3bf236b..9571ecf 100644
> > --- a/drivers/net/bnx2x/bnx2x.h
> > +++ b/drivers/net/bnx2x/bnx2x.h
> > @@ -24,10 +24,6 @@
> >  #define DRV_MODULE_RELDATE      "2010/10/19"
> >  #define BNX2X_BC_VER            0x040200
> >
> > -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
> > -#define BCM_VLAN			1
> > -#endif
> > -
> >  #define BNX2X_MULTI_QUEUE
> >
> >  #define BNX2X_NEW_NAPI
> > @@ -858,10 +854,6 @@ struct bnx2x {
> >
> >  	int			tx_ring_size;
> >
> > -#ifdef BCM_VLAN
> > -	struct vlan_group	*vlgrp;
> > -#endif
> > -
> >  	u32			rx_csum;
> >  	u32			rx_buf_size;
> >  /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
> > @@ -925,8 +917,6 @@ struct bnx2x {
> >  #define NO_MCP_FLAG			0x100
> >  #define DISABLE_MSI_FLAG		0x200
> >  #define BP_NOMCP(bp)			(bp->flags & NO_MCP_FLAG)
> > -#define HW_VLAN_TX_FLAG			0x400
> > -#define HW_VLAN_RX_FLAG			0x800
> >  #define MF_FUNC_DIS			0x1000
> >
> >  	int			pf_num;	/* absolute PF number */
> > diff --git a/drivers/net/bnx2x/bnx2x_cmn.c
> > b/drivers/net/bnx2x/bnx2x_cmn.c
> > index 6905b2e..bc58375 100644
> > --- a/drivers/net/bnx2x/bnx2x_cmn.c
> > +++ b/drivers/net/bnx2x/bnx2x_cmn.c
> > @@ -16,16 +16,13 @@
> >   */
> >
> >  #include <linux/etherdevice.h>
> > +#include <linux/if_vlan.h>
> >  #include <linux/ip.h>
> >  #include <net/ipv6.h>
> >  #include <net/ip6_checksum.h>
> >  #include <linux/firmware.h>
> >  #include "bnx2x_cmn.h"
> >
> > -#ifdef BCM_VLAN
> > -#include <linux/if_vlan.h>
> > -#endif
> > -
> >  #include "bnx2x_init.h"
> >
> >
> > @@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> > struct bnx2x_fastpath *fp,
> >  	if (likely(new_skb)) {
> >  		/* fix ip xsum and give it to the stack */
> >  		/* (no need to map the new skb) */
> > -#ifdef BCM_VLAN
> > -		int is_vlan_cqe =
> > -			(le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > -			 PARSING_FLAGS_VLAN);
> > -		int is_not_hwaccel_vlan_cqe =
> > -			(is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
> > -#endif
> >
> >  		prefetch(skb);
> >  		prefetch(((char *)(skb)) + L1_CACHE_BYTES);
> > @@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> > struct bnx2x_fastpath *fp,
> >  			struct iphdr *iph;
> >
> >  			iph = (struct iphdr *)skb->data;
> > -#ifdef BCM_VLAN
> > -			/* If there is no Rx VLAN offloading -
> > -			   take VLAN tag into an account */
> > -			if (unlikely(is_not_hwaccel_vlan_cqe))
> > -				iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
> > -#endif
> >  			iph->check = 0;
> >  			iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
> >  		}
> >
> >  		if (!bnx2x_fill_frag_skb(bp, fp, skb,
> >  					 &cqe->fast_path_cqe, cqe_idx)) {
> > -#ifdef BCM_VLAN
> > -			if ((bp->vlgrp != NULL) &&
> > -				(le16_to_cpu(cqe->fast_path_cqe.
> > -				pars_flags.flags) & PARSING_FLAGS_VLAN))
> > -				vlan_gro_receive(&fp->napi, bp->vlgrp,
> > +			if ((le16_to_cpu(cqe->fast_path_cqe.
> > +			    pars_flags.flags) & PARSING_FLAGS_VLAN))
> > +				__vlan_hwaccel_put_tag(skb,
> >  						 le16_to_cpu(cqe->fast_path_cqe.
> > -							     vlan_tag), skb);
> > -			else
> > -#endif
> > -				napi_gro_receive(&fp->napi, skb);
> > +							     vlan_tag));
> > +			napi_gro_receive(&fp->napi, skb);
> >  		} else {
> >  			DP(NETIF_MSG_RX_STATUS, "Failed to allocate new
> > pages"
> >  			   " - dropping packet!\n");
> > @@ -633,15 +613,11 @@ reuse_rx:
> >
> >  		skb_record_rx_queue(skb, fp->index);
> >
> > -#ifdef BCM_VLAN
> > -		if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
> > -		    (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > -		     PARSING_FLAGS_VLAN))
> > -			vlan_gro_receive(&fp->napi, bp->vlgrp,
> > -				le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb);
> > -		else
> > -#endif
> > -			napi_gro_receive(&fp->napi, skb);
> > +		if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > +		     PARSING_FLAGS_VLAN)
> > +			__vlan_hwaccel_put_tag(skb,
> > +				le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
> > +		napi_gro_receive(&fp->napi, skb);
> >
> >
> >  next_rx:
> > @@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff
> > *skb, struct net_device *dev)
> >  	   "sending pkt %u @%p  next_idx %u  bd %u @%p\n",
> >  	   pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
> >
> > -#ifdef BCM_VLAN
> >  	if (vlan_tx_tag_present(skb)) {
> >  		tx_start_bd->vlan_or_ethertype =
> >  		    cpu_to_le16(vlan_tx_tag_get(skb));
> >  		tx_start_bd->bd_flags.as_bitfield |=
> >  		    (X_ETH_OUTBAND_VLAN <<
> > ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
> >  	} else
> > -#endif
> >  		tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
> >
> >  	/* turn on parsing and get a BD */
> > @@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev)
> >  	schedule_delayed_work(&bp->reset_task, 0);
> >  }
> >
> > -#ifdef BCM_VLAN
> > -/* called with rtnl_lock */
> > -void bnx2x_vlan_rx_register(struct net_device *dev,
> > -				   struct vlan_group *vlgrp)
> > -{
> > -	struct bnx2x *bp = netdev_priv(dev);
> > -
> > -	bp->vlgrp = vlgrp;
> > -}
> > -
> > -#endif
> > -
> >  int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
> >  {
> >  	struct net_device *dev = pci_get_drvdata(pdev);
> > diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c
> > b/drivers/net/bnx2x/bnx2x_ethtool.c
> > index 54fe061..daefef6 100644
> > --- a/drivers/net/bnx2x/bnx2x_ethtool.c
> > +++ b/drivers/net/bnx2x/bnx2x_ethtool.c
> > @@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device
> > *dev, u32 data)
> >  	int changed = 0;
> >  	int rc = 0;
> >
> > -	if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
> > -		return -EINVAL;
> > -
> >  	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
> >  		printk(KERN_ERR "Handling parity error recovery. Try again
> > later\n");
> >  		return -EAGAIN;
> >  	}
> >
> > +	if (!(data & ETH_FLAG_RXVLAN))
> > +		return -EOPNOTSUPP;
> > +
> > +	if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
> > +		return -EINVAL;
> > +
> > +	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO |
> > ETH_FLAG_RXVLAN |
> > +					ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
> > +	if (rc)
> > +		return rc;
> > +
> >  	/* TPA requires Rx CSUM offloading */
> >  	if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
> > -		if (!bp->disable_tpa) {
> > -			if (!(dev->features & NETIF_F_LRO)) {
> > -				dev->features |= NETIF_F_LRO;
> > -				bp->flags |= TPA_ENABLE_FLAG;
> > -				changed = 1;
> > -			}
> > -		} else
> > -			rc = -EINVAL;
> > -	} else if (dev->features & NETIF_F_LRO) {
> > +		if (!(bp->flags & TPA_ENABLE_FLAG)) {
> > +			bp->flags |= TPA_ENABLE_FLAG;
> > +			changed = 1;
> > +		}
> > +	} else if (bp->flags & TPA_ENABLE_FLAG) {
> >  		dev->features &= ~NETIF_F_LRO;
> >  		bp->flags &= ~TPA_ENABLE_FLAG;
> >  		changed = 1;
> >  	}
> >
> > -	if (data & ETH_FLAG_RXHASH)
> > -		dev->features |= NETIF_F_RXHASH;
> > -	else
> > -		dev->features &= ~NETIF_F_RXHASH;
> > -
> >  	if (changed && netif_running(dev)) {
> >  		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
> >  		rc = bnx2x_nic_load(bp, LOAD_NORMAL);
> > diff --git a/drivers/net/bnx2x/bnx2x_main.c
> > b/drivers/net/bnx2x/bnx2x_main.c
> > index f22e283..ff99a2f 100644
> > --- a/drivers/net/bnx2x/bnx2x_main.c
> > +++ b/drivers/net/bnx2x/bnx2x_main.c
> > @@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct
> > bnx2x *bp,
> >  	flags |= QUEUE_FLG_HC;
> >  	flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
> >
> > -#ifdef BCM_VLAN
> >  	flags |= QUEUE_FLG_VLAN;
> >  	DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
> > -#endif
> >
> >  	if (!fp->disable_tpa)
> >  		flags |= QUEUE_FLG_TPA;
> > @@ -8630,9 +8628,6 @@ static const struct net_device_ops
> > bnx2x_netdev_ops = {
> >  	.ndo_do_ioctl		= bnx2x_ioctl,
> >  	.ndo_change_mtu		= bnx2x_change_mtu,
> >  	.ndo_tx_timeout		= bnx2x_tx_timeout,
> > -#ifdef BCM_VLAN
> > -	.ndo_vlan_rx_register	= bnx2x_vlan_rx_register,
> > -#endif
> >  #ifdef CONFIG_NET_POLL_CONTROLLER
> >  	.ndo_poll_controller	= poll_bnx2x,
> >  #endif
> > @@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct
> > pci_dev *pdev,
> >  		dev->features |= NETIF_F_HIGHDMA;
> >  	dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> >  	dev->features |= NETIF_F_TSO6;
> > -#ifdef BCM_VLAN
> >  	dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
> > -	bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
> >
> >  	dev->vlan_features |= NETIF_F_SG;
> >  	dev->vlan_features |= NETIF_F_HW_CSUM;
> > @@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct
> > pci_dev *pdev,
> >  		dev->vlan_features |= NETIF_F_HIGHDMA;
> >  	dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> >  	dev->vlan_features |= NETIF_F_TSO6;
> > -#endif
> >
> >  	/* get_port_hwinfo() will set prtad and mmds properly */
> >  	bp->mdio.prtad = MDIO_PRTAD_NONE;
> > --
> > 1.7.1
> 
> Guys, when I compiled the kernel with these patches without VLAN
> support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged
> frames from the remote side to the bnx2x interface the kernel panicked.
> 
> The stack trace got cut with the __netif_receive_skb() on top by the
> IPKVM and I'll have to connect a serial to get it all. But until I
> did that maybe somebody will have any ideas anyway...
> 
> It happens regardless there is HW RX VLAN stripping enabled or not.

When RX VLAN stripping is enabled we hit the BUG() in the 
vlan_hwaccel_do_receive().





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



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

* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-21 14:02     ` Vladislav Zolotarov
@ 2010-10-21 14:50       ` Vladislav Zolotarov
  2010-10-21 21:36         ` Jesse Gross
  2010-10-21 21:34       ` Jesse Gross
  1 sibling, 1 reply; 48+ messages in thread
From: Vladislav Zolotarov @ 2010-10-21 14:50 UTC (permalink / raw)
  To: Jesse Gross, David Miller; +Cc: netdev, Hao Zheng, Eilon Greenstein



> -----Original Message-----
> From: Vladislav Zolotarov
> Sent: Thursday, October 21, 2010 4:03 PM
> To: Vladislav Zolotarov; Jesse Gross; David Miller
> Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> Subject: RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> accleration.
> 
> 
> 
> > -----Original Message-----
> > From: netdev-owner@vger.kernel.org [mailto:netdev-
> > owner@vger.kernel.org] On Behalf Of Vladislav Zolotarov
> > Sent: Thursday, October 21, 2010 3:55 PM
> > To: Jesse Gross; David Miller
> > Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> > Subject: RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> > accleration.
> >
> >
> >
> > > -----Original Message-----
> > > From: netdev-owner@vger.kernel.org [mailto:netdev-
> > > owner@vger.kernel.org] On Behalf Of Jesse Gross
> > > Sent: Thursday, October 21, 2010 1:56 AM
> > > To: David Miller
> > > Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> > > Subject: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> > > accleration.
> > >
> > > From: Hao Zheng <hzheng@nicira.com>
> > >
> > > Make the bnx2x driver use the new vlan accleration model.
> > >
> > > Signed-off-by: Hao Zheng <hzheng@nicira.com>
> > > Signed-off-by: Jesse Gross <jesse@nicira.com>
> > > CC: Eilon Greenstein <eilong@broadcom.com>
> > > ---
> > >  drivers/net/bnx2x/bnx2x.h         |   10 ------
> > >  drivers/net/bnx2x/bnx2x_cmn.c     |   60 +++++++------------------
> --
> > --
> > > --------
> > >  drivers/net/bnx2x/bnx2x_ethtool.c |   33 ++++++++++----------
> > >  drivers/net/bnx2x/bnx2x_main.c    |    8 -----
> > >  4 files changed, 27 insertions(+), 84 deletions(-)
> > >
> > > diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> > > index 3bf236b..9571ecf 100644
> > > --- a/drivers/net/bnx2x/bnx2x.h
> > > +++ b/drivers/net/bnx2x/bnx2x.h
> > > @@ -24,10 +24,6 @@
> > >  #define DRV_MODULE_RELDATE      "2010/10/19"
> > >  #define BNX2X_BC_VER            0x040200
> > >
> > > -#if defined(CONFIG_VLAN_8021Q) ||
> defined(CONFIG_VLAN_8021Q_MODULE)
> > > -#define BCM_VLAN			1
> > > -#endif
> > > -
> > >  #define BNX2X_MULTI_QUEUE
> > >
> > >  #define BNX2X_NEW_NAPI
> > > @@ -858,10 +854,6 @@ struct bnx2x {
> > >
> > >  	int			tx_ring_size;
> > >
> > > -#ifdef BCM_VLAN
> > > -	struct vlan_group	*vlgrp;
> > > -#endif
> > > -
> > >  	u32			rx_csum;
> > >  	u32			rx_buf_size;
> > >  /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
> > > @@ -925,8 +917,6 @@ struct bnx2x {
> > >  #define NO_MCP_FLAG			0x100
> > >  #define DISABLE_MSI_FLAG		0x200
> > >  #define BP_NOMCP(bp)			(bp->flags & NO_MCP_FLAG)
> > > -#define HW_VLAN_TX_FLAG			0x400
> > > -#define HW_VLAN_RX_FLAG			0x800
> > >  #define MF_FUNC_DIS			0x1000
> > >
> > >  	int			pf_num;	/* absolute PF number */
> > > diff --git a/drivers/net/bnx2x/bnx2x_cmn.c
> > > b/drivers/net/bnx2x/bnx2x_cmn.c
> > > index 6905b2e..bc58375 100644
> > > --- a/drivers/net/bnx2x/bnx2x_cmn.c
> > > +++ b/drivers/net/bnx2x/bnx2x_cmn.c
> > > @@ -16,16 +16,13 @@
> > >   */
> > >
> > >  #include <linux/etherdevice.h>
> > > +#include <linux/if_vlan.h>
> > >  #include <linux/ip.h>
> > >  #include <net/ipv6.h>
> > >  #include <net/ip6_checksum.h>
> > >  #include <linux/firmware.h>
> > >  #include "bnx2x_cmn.h"
> > >
> > > -#ifdef BCM_VLAN
> > > -#include <linux/if_vlan.h>
> > > -#endif
> > > -
> > >  #include "bnx2x_init.h"
> > >
> > >
> > > @@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> > > struct bnx2x_fastpath *fp,
> > >  	if (likely(new_skb)) {
> > >  		/* fix ip xsum and give it to the stack */
> > >  		/* (no need to map the new skb) */
> > > -#ifdef BCM_VLAN
> > > -		int is_vlan_cqe =
> > > -			(le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > > -			 PARSING_FLAGS_VLAN);
> > > -		int is_not_hwaccel_vlan_cqe =
> > > -			(is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
> > > -#endif
> > >
> > >  		prefetch(skb);
> > >  		prefetch(((char *)(skb)) + L1_CACHE_BYTES);
> > > @@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> > > struct bnx2x_fastpath *fp,
> > >  			struct iphdr *iph;
> > >
> > >  			iph = (struct iphdr *)skb->data;
> > > -#ifdef BCM_VLAN
> > > -			/* If there is no Rx VLAN offloading -
> > > -			   take VLAN tag into an account */
> > > -			if (unlikely(is_not_hwaccel_vlan_cqe))
> > > -				iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
> > > -#endif
> > >  			iph->check = 0;
> > >  			iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
> > >  		}
> > >
> > >  		if (!bnx2x_fill_frag_skb(bp, fp, skb,
> > >  					 &cqe->fast_path_cqe, cqe_idx)) {
> > > -#ifdef BCM_VLAN
> > > -			if ((bp->vlgrp != NULL) &&
> > > -				(le16_to_cpu(cqe->fast_path_cqe.
> > > -				pars_flags.flags) & PARSING_FLAGS_VLAN))
> > > -				vlan_gro_receive(&fp->napi, bp->vlgrp,
> > > +			if ((le16_to_cpu(cqe->fast_path_cqe.
> > > +			    pars_flags.flags) & PARSING_FLAGS_VLAN))
> > > +				__vlan_hwaccel_put_tag(skb,
> > >  						 le16_to_cpu(cqe->fast_path_cqe.
> > > -							     vlan_tag), skb);
> > > -			else
> > > -#endif
> > > -				napi_gro_receive(&fp->napi, skb);
> > > +							     vlan_tag));
> > > +			napi_gro_receive(&fp->napi, skb);
> > >  		} else {
> > >  			DP(NETIF_MSG_RX_STATUS, "Failed to allocate new
> > > pages"
> > >  			   " - dropping packet!\n");
> > > @@ -633,15 +613,11 @@ reuse_rx:
> > >
> > >  		skb_record_rx_queue(skb, fp->index);
> > >
> > > -#ifdef BCM_VLAN
> > > -		if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
> > > -		    (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > > -		     PARSING_FLAGS_VLAN))
> > > -			vlan_gro_receive(&fp->napi, bp->vlgrp,
> > > -				le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb);
> > > -		else
> > > -#endif
> > > -			napi_gro_receive(&fp->napi, skb);
> > > +		if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > > +		     PARSING_FLAGS_VLAN)
> > > +			__vlan_hwaccel_put_tag(skb,
> > > +				le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
> > > +		napi_gro_receive(&fp->napi, skb);
> > >
> > >
> > >  next_rx:
> > > @@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff
> > > *skb, struct net_device *dev)
> > >  	   "sending pkt %u @%p  next_idx %u  bd %u @%p\n",
> > >  	   pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
> > >
> > > -#ifdef BCM_VLAN
> > >  	if (vlan_tx_tag_present(skb)) {
> > >  		tx_start_bd->vlan_or_ethertype =
> > >  		    cpu_to_le16(vlan_tx_tag_get(skb));
> > >  		tx_start_bd->bd_flags.as_bitfield |=
> > >  		    (X_ETH_OUTBAND_VLAN <<
> > > ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
> > >  	} else
> > > -#endif
> > >  		tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
> > >
> > >  	/* turn on parsing and get a BD */
> > > @@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device
> *dev)
> > >  	schedule_delayed_work(&bp->reset_task, 0);
> > >  }
> > >
> > > -#ifdef BCM_VLAN
> > > -/* called with rtnl_lock */
> > > -void bnx2x_vlan_rx_register(struct net_device *dev,
> > > -				   struct vlan_group *vlgrp)
> > > -{
> > > -	struct bnx2x *bp = netdev_priv(dev);
> > > -
> > > -	bp->vlgrp = vlgrp;
> > > -}
> > > -
> > > -#endif
> > > -
> > >  int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
> > >  {
> > >  	struct net_device *dev = pci_get_drvdata(pdev);
> > > diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c
> > > b/drivers/net/bnx2x/bnx2x_ethtool.c
> > > index 54fe061..daefef6 100644
> > > --- a/drivers/net/bnx2x/bnx2x_ethtool.c
> > > +++ b/drivers/net/bnx2x/bnx2x_ethtool.c
> > > @@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct
> net_device
> > > *dev, u32 data)
> > >  	int changed = 0;
> > >  	int rc = 0;
> > >
> > > -	if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
> > > -		return -EINVAL;
> > > -
> > >  	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
> > >  		printk(KERN_ERR "Handling parity error recovery. Try again
> > > later\n");
> > >  		return -EAGAIN;
> > >  	}
> > >
> > > +	if (!(data & ETH_FLAG_RXVLAN))
> > > +		return -EOPNOTSUPP;
> > > +
> > > +	if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
> > > +		return -EINVAL;
> > > +
> > > +	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO |
> > > ETH_FLAG_RXVLAN |
> > > +					ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
> > > +	if (rc)
> > > +		return rc;
> > > +
> > >  	/* TPA requires Rx CSUM offloading */
> > >  	if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
> > > -		if (!bp->disable_tpa) {
> > > -			if (!(dev->features & NETIF_F_LRO)) {
> > > -				dev->features |= NETIF_F_LRO;
> > > -				bp->flags |= TPA_ENABLE_FLAG;
> > > -				changed = 1;
> > > -			}
> > > -		} else
> > > -			rc = -EINVAL;
> > > -	} else if (dev->features & NETIF_F_LRO) {
> > > +		if (!(bp->flags & TPA_ENABLE_FLAG)) {
> > > +			bp->flags |= TPA_ENABLE_FLAG;
> > > +			changed = 1;
> > > +		}
> > > +	} else if (bp->flags & TPA_ENABLE_FLAG) {
> > >  		dev->features &= ~NETIF_F_LRO;
> > >  		bp->flags &= ~TPA_ENABLE_FLAG;
> > >  		changed = 1;
> > >  	}
> > >
> > > -	if (data & ETH_FLAG_RXHASH)
> > > -		dev->features |= NETIF_F_RXHASH;
> > > -	else
> > > -		dev->features &= ~NETIF_F_RXHASH;
> > > -
> > >  	if (changed && netif_running(dev)) {
> > >  		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
> > >  		rc = bnx2x_nic_load(bp, LOAD_NORMAL);
> > > diff --git a/drivers/net/bnx2x/bnx2x_main.c
> > > b/drivers/net/bnx2x/bnx2x_main.c
> > > index f22e283..ff99a2f 100644
> > > --- a/drivers/net/bnx2x/bnx2x_main.c
> > > +++ b/drivers/net/bnx2x/bnx2x_main.c
> > > @@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct
> > > bnx2x *bp,
> > >  	flags |= QUEUE_FLG_HC;
> > >  	flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
> > >
> > > -#ifdef BCM_VLAN
> > >  	flags |= QUEUE_FLG_VLAN;
> > >  	DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
> > > -#endif
> > >
> > >  	if (!fp->disable_tpa)
> > >  		flags |= QUEUE_FLG_TPA;
> > > @@ -8630,9 +8628,6 @@ static const struct net_device_ops
> > > bnx2x_netdev_ops = {
> > >  	.ndo_do_ioctl		= bnx2x_ioctl,
> > >  	.ndo_change_mtu		= bnx2x_change_mtu,
> > >  	.ndo_tx_timeout		= bnx2x_tx_timeout,
> > > -#ifdef BCM_VLAN
> > > -	.ndo_vlan_rx_register	= bnx2x_vlan_rx_register,
> > > -#endif
> > >  #ifdef CONFIG_NET_POLL_CONTROLLER
> > >  	.ndo_poll_controller	= poll_bnx2x,
> > >  #endif
> > > @@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct
> > > pci_dev *pdev,
> > >  		dev->features |= NETIF_F_HIGHDMA;
> > >  	dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> > >  	dev->features |= NETIF_F_TSO6;
> > > -#ifdef BCM_VLAN
> > >  	dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
> > > -	bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
> > >
> > >  	dev->vlan_features |= NETIF_F_SG;
> > >  	dev->vlan_features |= NETIF_F_HW_CSUM;
> > > @@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct
> > > pci_dev *pdev,
> > >  		dev->vlan_features |= NETIF_F_HIGHDMA;
> > >  	dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> > >  	dev->vlan_features |= NETIF_F_TSO6;
> > > -#endif
> > >
> > >  	/* get_port_hwinfo() will set prtad and mmds properly */
> > >  	bp->mdio.prtad = MDIO_PRTAD_NONE;
> > > --
> > > 1.7.1
> >
> > Guys, when I compiled the kernel with these patches without VLAN
> > support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged
> > frames from the remote side to the bnx2x interface the kernel
> panicked.
> >
> > The stack trace got cut with the __netif_receive_skb() on top by the
> > IPKVM and I'll have to connect a serial to get it all. But until I
> > did that maybe somebody will have any ideas anyway...
> >
> > It happens regardless there is HW RX VLAN stripping enabled or not.
> 
> When RX VLAN stripping is enabled we hit the BUG() in the
> vlan_hwaccel_do_receive().:

We hit the same BUG() both when VLAN stripping is disabled. 

Thanks,
vlad

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



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

* Re: [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration.
  2010-10-20 23:56 ` [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration Jesse Gross
  2010-10-21  3:32   ` John Fastabend
@ 2010-10-21 15:30   ` Ben Hutchings
  2010-10-21 21:44     ` Jesse Gross
  1 sibling, 1 reply; 48+ messages in thread
From: Ben Hutchings @ 2010-10-21 15:30 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev

On Wed, 2010-10-20 at 16:56 -0700, Jesse Gross wrote:
> Currently users of hardware vlan accleration need to know whether
> the device supports it before generating packets.  However, vlan
> acceleration will soon be available in a more flexible manner so
> knowing ahead of time becomes much more difficult.  This adds
> a software fallback path for vlan packets on devices without the
> necessary offloading support, similar to other types of hardware
> accleration.
[...]
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 4c3ac53..1bfd96b 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1694,7 +1694,12 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
>  
>  static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
>  {
> -	if (can_checksum_protocol(dev->features, skb->protocol))
> +	int features = dev->features;
> +
> +	if (vlan_tx_tag_present(skb))
> +		features &= dev->vlan_features;
> +
> +	if (can_checksum_protocol(features, skb->protocol))
>  		return true;
>  
>  	if (skb->protocol == htons(ETH_P_8021Q)) {
[...]

Additional context:

		struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
		if (can_checksum_protocol(dev->features & dev->vlan_features,
					  veh->h_vlan_encapsulated_proto))
			return true;
	}

	return false;
}

I don't think this will do the right thing if the NIC does VLAN tag
insertion and checksum offload with only one layer of VLAN
encapsulation, but the skb has two layers of VLAN encapsulation.

I think we actually want something like:

static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
{
	__be16 protocol = skb->protocol;
	int features = dev->features;

	if (vlan_tx_tag_present(skb)) {
		features &= dev->vlan_features;
	} else if (skb->protocol == htons(ETH_P_8021Q)) {
		struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
		protocol = veh->h_vlan_encapsulated_proto;
		features &= dev->vlan_features;
	}

	return can_checksum_protocol(features, protocol);
}

Does that look right?

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* Re: [PATCH v2 09/14] bnx2: Update bnx2 to use new vlan accleration.
  2010-10-20 23:56 ` [PATCH v2 09/14] bnx2: Update bnx2 to use new vlan accleration Jesse Gross
@ 2010-10-21 15:31   ` Ben Hutchings
  2010-10-21 21:38     ` Jesse Gross
  0 siblings, 1 reply; 48+ messages in thread
From: Ben Hutchings @ 2010-10-21 15:31 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev, Michael Chan

On Wed, 2010-10-20 at 16:56 -0700, Jesse Gross wrote:
> Make the bnx2 driver use the new vlan accleration model.
> 
> Signed-off-by: Jesse Gross <jesse@nicira.com>
> CC: Michael Chan <mchan@broadcom.com>
> ---
>  drivers/net/bnx2.c |   97 +++++++++++++++-------------------------------------
>  drivers/net/bnx2.h |    4 --
>  2 files changed, 28 insertions(+), 73 deletions(-)
> 
> diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
> index 363ca8b..bf3c830 100644
> --- a/drivers/net/bnx2.c
> +++ b/drivers/net/bnx2.c
[...]
> @@ -7578,7 +7523,28 @@ bnx2_set_tx_csum(struct net_device *dev, u32 data)
>  static int
>  bnx2_set_flags(struct net_device *dev, u32 data)
>  {
> -	return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH);
> +	struct bnx2 *bp = netdev_priv(dev);
> +	int rc;
> +
> +	if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) &&
> +	    !(data & ETH_FLAG_RXVLAN))
> +		return -EOPNOTSUPP;
[...]

Should be -EINVAL.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* Re: [PATCH v2 00/14] Move vlan acceleration into networking core.
  2010-10-21  2:02 ` [PATCH v2 00/14] Move vlan acceleration into networking core David Dillow
@ 2010-10-21 19:32   ` Jesse Gross
  0 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-21 19:32 UTC (permalink / raw)
  To: David Dillow; +Cc: David Miller, netdev

On Wed, Oct 20, 2010 at 7:02 PM, David Dillow <dave@thedillows.org> wrote:
> On Wed, 2010-10-20 at 16:56 -0700, Jesse Gross wrote:
>> The first eleven patches can be applied immediately, while the last three need
>> to wait until all drivers that support vlan acceleration are updated.  If
>> people agree that this patch set makes sense I will go ahead and switch over
>> the dozen or so drivers that would need to change.
>
> Here's a first pass at converting typhoon to the new methods. It is
> compile tested, but I have to put the hardware back in a machine to do
> some testing, which I may not be able to do before the weekend.
>
> Of course, we could just change it to not offload by default if we need
> to push this sooner.
>
> Applies to net-next-2.6 with the vlan changes.

This is great, thanks.  Much better to have someone who actually knows
what's going on, rather than me trying to randomly guess...

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

* Re: [PATCH v2 07/14] ethtool: Add support for vlan accleration.
  2010-10-21  3:27   ` John Fastabend
@ 2010-10-21 19:43     ` Jesse Gross
  0 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-21 19:43 UTC (permalink / raw)
  To: John Fastabend; +Cc: David Miller, netdev

On Wed, Oct 20, 2010 at 8:27 PM, John Fastabend
<john.r.fastabend@intel.com> wrote:
> On 10/20/2010 4:56 PM, Jesse Gross wrote:
>> Now that vlan acceleration is handled consistently regardless of usage,
>> it is possible to enable and disable it at will.  This adds support for
>> Ethtool operations that change the offloading status for debugging
>> purposes, similar to other forms of hardware acceleration.
>>
>
> Jesse,
>
> Not sure if this is enough to get dynamic toggling like this
> dev->hard_header_len is set depending on offloads at init time in
> vlan_dev_init(). By changing this LL_RESERVED_SPACE won't work
> correctly and we end up having to call pskb_expand_head(). I think
> this might end up hurting performance.

That's a good point.

>
> That said I think I can probably get this working by fixing up the
> header_ops in vlan_dev.c.  And while I'm at it add a vlan_header_cache
> and vlan_header_cache_update routines. I'll try to get something out
> tomorrow in the meantime nothing too bad is happening.

That sounds great, thanks.

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

* Re: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-21 14:02     ` Vladislav Zolotarov
  2010-10-21 14:50       ` Vladislav Zolotarov
@ 2010-10-21 21:34       ` Jesse Gross
  1 sibling, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-21 21:34 UTC (permalink / raw)
  To: Vladislav Zolotarov; +Cc: David Miller, netdev, Hao Zheng, Eilon Greenstein

On Thu, Oct 21, 2010 at 7:02 AM, Vladislav Zolotarov <vladz@broadcom.com> wrote:
>> Guys, when I compiled the kernel with these patches without VLAN
>> support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged
>> frames from the remote side to the bnx2x interface the kernel panicked.
>>
>> The stack trace got cut with the __netif_receive_skb() on top by the
>> IPKVM and I'll have to connect a serial to get it all. But until I
>> did that maybe somebody will have any ideas anyway...
>>
>> It happens regardless there is HW RX VLAN stripping enabled or not.
>
> When RX VLAN stripping is enabled we hit the BUG() in the
> vlan_hwaccel_do_receive().

Thanks, this is just a stupid mistake - I didn't update the
non-CONFIG_VLAN_8021Q version when I changed the semantics of that
function.  I've sent out a patch to fix it.

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

* Re: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-21 14:50       ` Vladislav Zolotarov
@ 2010-10-21 21:36         ` Jesse Gross
  2010-10-22  0:57           ` Dmitry Kravkov
  2010-10-24  9:21           ` Vladislav Zolotarov
  0 siblings, 2 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-21 21:36 UTC (permalink / raw)
  To: Vladislav Zolotarov; +Cc: David Miller, netdev, Hao Zheng, Eilon Greenstein

On Thu, Oct 21, 2010 at 7:50 AM, Vladislav Zolotarov <vladz@broadcom.com> wrote:
>> > Guys, when I compiled the kernel with these patches without VLAN
>> > support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged
>> > frames from the remote side to the bnx2x interface the kernel
>> panicked.
>> >
>> > The stack trace got cut with the __netif_receive_skb() on top by the
>> > IPKVM and I'll have to connect a serial to get it all. But until I
>> > did that maybe somebody will have any ideas anyway...
>> >
>> > It happens regardless there is HW RX VLAN stripping enabled or not.
>>
>> When RX VLAN stripping is enabled we hit the BUG() in the
>> vlan_hwaccel_do_receive().:
>
> We hit the same BUG() both when VLAN stripping is disabled.

This one surprises me because that function shouldn't get called at
all when VLAN stripping is disabled.  Are you sure that it is
disabled?  From my reading of the bnx2x driver it seems like it is
always enabled.

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

* Re: [PATCH v2 09/14] bnx2: Update bnx2 to use new vlan accleration.
  2010-10-21 15:31   ` Ben Hutchings
@ 2010-10-21 21:38     ` Jesse Gross
  0 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-21 21:38 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev, Michael Chan

On Thu, Oct 21, 2010 at 8:31 AM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
> On Wed, 2010-10-20 at 16:56 -0700, Jesse Gross wrote:
>> Make the bnx2 driver use the new vlan accleration model.
>>
>> Signed-off-by: Jesse Gross <jesse@nicira.com>
>> CC: Michael Chan <mchan@broadcom.com>
>> ---
>>  drivers/net/bnx2.c |   97 +++++++++++++++-------------------------------------
>>  drivers/net/bnx2.h |    4 --
>>  2 files changed, 28 insertions(+), 73 deletions(-)
>>
>> diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
>> index 363ca8b..bf3c830 100644
>> --- a/drivers/net/bnx2.c
>> +++ b/drivers/net/bnx2.c
> [...]
>> @@ -7578,7 +7523,28 @@ bnx2_set_tx_csum(struct net_device *dev, u32 data)
>>  static int
>>  bnx2_set_flags(struct net_device *dev, u32 data)
>>  {
>> -     return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH);
>> +     struct bnx2 *bp = netdev_priv(dev);
>> +     int rc;
>> +
>> +     if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) &&
>> +         !(data & ETH_FLAG_RXVLAN))
>> +             return -EOPNOTSUPP;
> [...]
>
> Should be -EINVAL.

OK, thanks.  I've sent out a patch to fix this (and a similar one in
the bnx2x driver).

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

* Re: [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration.
  2010-10-21 15:30   ` Ben Hutchings
@ 2010-10-21 21:44     ` Jesse Gross
  2010-10-22 14:12       ` [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum() Ben Hutchings
  0 siblings, 1 reply; 48+ messages in thread
From: Jesse Gross @ 2010-10-21 21:44 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev

On Thu, Oct 21, 2010 at 8:30 AM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
> On Wed, 2010-10-20 at 16:56 -0700, Jesse Gross wrote:
>> Currently users of hardware vlan accleration need to know whether
>> the device supports it before generating packets.  However, vlan
>> acceleration will soon be available in a more flexible manner so
>> knowing ahead of time becomes much more difficult.  This adds
>> a software fallback path for vlan packets on devices without the
>> necessary offloading support, similar to other types of hardware
>> accleration.
> [...]
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 4c3ac53..1bfd96b 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -1694,7 +1694,12 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
>>
>>  static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
>>  {
>> -     if (can_checksum_protocol(dev->features, skb->protocol))
>> +     int features = dev->features;
>> +
>> +     if (vlan_tx_tag_present(skb))
>> +             features &= dev->vlan_features;
>> +
>> +     if (can_checksum_protocol(features, skb->protocol))
>>               return true;
>>
>>       if (skb->protocol == htons(ETH_P_8021Q)) {
> [...]
>
> Additional context:
>
>                struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
>                if (can_checksum_protocol(dev->features & dev->vlan_features,
>                                          veh->h_vlan_encapsulated_proto))
>                        return true;
>        }
>
>        return false;
> }
>
> I don't think this will do the right thing if the NIC does VLAN tag
> insertion and checksum offload with only one layer of VLAN
> encapsulation, but the skb has two layers of VLAN encapsulation.
>
> I think we actually want something like:
>
> static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
> {
>        __be16 protocol = skb->protocol;
>        int features = dev->features;
>
>        if (vlan_tx_tag_present(skb)) {
>                features &= dev->vlan_features;
>        } else if (skb->protocol == htons(ETH_P_8021Q)) {
>                struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
>                protocol = veh->h_vlan_encapsulated_proto;
>                features &= dev->vlan_features;
>        }
>
>        return can_checksum_protocol(features, protocol);
> }
>
> Does that look right?

Thanks, good catch.  Yes, that looks right.  Will you submit a patch
to fix this?

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

* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-21 21:36         ` Jesse Gross
@ 2010-10-22  0:57           ` Dmitry Kravkov
  2010-10-24  9:21           ` Vladislav Zolotarov
  1 sibling, 0 replies; 48+ messages in thread
From: Dmitry Kravkov @ 2010-10-22  0:57 UTC (permalink / raw)
  To: Jesse Gross, Vladislav Zolotarov
  Cc: David Miller, netdev, Hao Zheng, Eilon Greenstein

With the latest patch this one also disappeared and I do see the packets with vlan tag on the receiver's side
(For this purpose the driver was patched do not configure the stripping)

-----Original Message-----
From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On Behalf Of Jesse Gross
Sent: Thursday, October 21, 2010 11:37 PM
To: Vladislav Zolotarov
Cc: David Miller; netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
Subject: Re: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.

On Thu, Oct 21, 2010 at 7:50 AM, Vladislav Zolotarov <vladz@broadcom.com> wrote:
>> > Guys, when I compiled the kernel with these patches without VLAN
>> > support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged
>> > frames from the remote side to the bnx2x interface the kernel
>> panicked.
>> >
>> > The stack trace got cut with the __netif_receive_skb() on top by the
>> > IPKVM and I'll have to connect a serial to get it all. But until I
>> > did that maybe somebody will have any ideas anyway...
>> >
>> > It happens regardless there is HW RX VLAN stripping enabled or not.
>>
>> When RX VLAN stripping is enabled we hit the BUG() in the
>> vlan_hwaccel_do_receive().:
>
> We hit the same BUG() both when VLAN stripping is disabled.

This one surprises me because that function shouldn't get called at
all when VLAN stripping is disabled.  Are you sure that it is
disabled?  From my reading of the bnx2x driver it seems like it is
always enabled.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



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

* Re: [PATCH v2 10/14] ixgbe: Update ixgbe to use new vlan accleration.
  2010-10-20 23:56 ` [PATCH v2 10/14] ixgbe: Update ixgbe " Jesse Gross
@ 2010-10-22 13:24   ` Michał Mirosław
  2010-10-25 17:50     ` Peter P Waskiewicz Jr
  0 siblings, 1 reply; 48+ messages in thread
From: Michał Mirosław @ 2010-10-22 13:24 UTC (permalink / raw)
  To: Jesse Gross
  Cc: David Miller, netdev, Peter Waskiewicz, Emil Tantilov, Jeff Kirsher

2010/10/21 Jesse Gross <jesse@nicira.com>:
> Make the ixgbe driver use the new vlan accleration model.
[...]
> --- a/drivers/net/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ixgbe/ixgbe_main.c
> @@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
>        bool is_vlan = (status & IXGBE_RXD_STAT_VP);
>        u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
>
> -       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
> -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
> -                       vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
> -               else
> -                       napi_gro_receive(napi, skb);
> -       } else {
> -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
> -                       vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
> -               else
> -                       netif_rx(skb);
> -       }
> +       if (is_vlan && (tag & VLAN_VID_MASK))
> +               __vlan_hwaccel_put_tag(skb, tag);

I know that this is carried over from the driver, but why tag == 0 is
treated differently here? VID0 is somewhat special, as normally it
means 802.1p packet, but i.e. in embedded world people are using it as
normal VID. It would be nice to have this handled consistently in the
VLAN core - deliver to base dev (tag stripped) if vlan 0 is not
configured and to vlan dev if it is.

> +
> +       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
> +               napi_gro_receive(napi, skb);
> +       else
> +               netif_rx(skb);
>  }
>
>  /**

Best Regards,
Michał Mirosław

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

* [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum()
  2010-10-21 21:44     ` Jesse Gross
@ 2010-10-22 14:12       ` Ben Hutchings
  2010-10-22 14:18         ` Ben Hutchings
                           ` (2 more replies)
  0 siblings, 3 replies; 48+ messages in thread
From: Ben Hutchings @ 2010-10-22 14:12 UTC (permalink / raw)
  To: David Miller; +Cc: Jesse Gross, netdev

dev_can_checksum() incorrectly returns true in these cases:

1. The skb has both out-of-band and in-band VLAN tags and the device
   supports checksum offload for the encapsulated protocol but only with
   one layer of encapsulation.
2. The skb has a VLAN tag and the device supports generic checksumming
   but not in conjunction with VLAN encapsulation.

Rearrange the VLAN tag checks to avoid these.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
I don't know whether I have hardware that would cover these cases (our
NICs certainly don't), so instead I wrote some unit tests; I'll
follow-up with the test program.

Ben.

 net/core/dev.c |   16 ++++++----------
 1 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 6d4218c..a698252 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1694,22 +1694,18 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
 
 static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
 {
+	__be16 protocol = skb->protocol;
 	int features = dev->features;
 
-	if (vlan_tx_tag_present(skb))
+	if (vlan_tx_tag_present(skb)) {
 		features &= dev->vlan_features;
-
-	if (can_checksum_protocol(features, skb->protocol))
-		return true;
-
-	if (skb->protocol == htons(ETH_P_8021Q)) {
+	} else if (protocol == htons(ETH_P_8021Q)) {
 		struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
-		if (can_checksum_protocol(dev->features & dev->vlan_features,
-					  veh->h_vlan_encapsulated_proto))
-			return true;
+		protocol = veh->h_vlan_encapsulated_proto;
+		features &= dev->vlan_features;
 	}
 
-	return false;
+	return can_checksum_protocol(features, protocol);
 }
 
 /**
-- 
1.7.2.1


-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* Re: [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum()
  2010-10-22 14:12       ` [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum() Ben Hutchings
@ 2010-10-22 14:18         ` Ben Hutchings
  2010-10-26  0:21         ` Jesse Gross
  2010-10-27 18:00         ` David Miller
  2 siblings, 0 replies; 48+ messages in thread
From: Ben Hutchings @ 2010-10-22 14:18 UTC (permalink / raw)
  To: David Miller; +Cc: Jesse Gross, netdev

Of the following tests, the current implementation fails
'test_no_2vlan_ob_ip' and 'test_vlan_ib_unknown'.

Ben.

#include <assert.h>
#include <stdbool.h>
#include <string.h>

/* Dummy definitions */

typedef unsigned short __be16, __u16, u16;

static inline __be16 htons(u16 value)
{
	return value >> 8 | value << 8;
}

struct net_device {
	unsigned long		features;
#define NETIF_F_SG		1	/* Scatter/gather IO. */
#define NETIF_F_IP_CSUM		2	/* Can checksum TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM		4	/* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM		8	/* Can checksum all the packets. */
#define NETIF_F_IPV6_CSUM	16	/* Can checksum TCP/UDP over IPV6 */
#define NETIF_F_FCOE_CRC	(1 << 24) /* FCoE CRC32 */
#define NETIF_F_GEN_CSUM	(NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
#define NETIF_F_V4_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
#define NETIF_F_V6_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
#define NETIF_F_ALL_CSUM	(NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
	unsigned long vlan_features;
};

struct sk_buff {
	__be16 protocol;
	__u16			vlan_tci;
	void *data;
};

#define ETH_ALEN 6

struct ethhdr {
	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/
	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/
	__be16		h_proto;		/* packet type ID field	*/
};

struct vlan_ethhdr {
	unsigned char	h_dest[ETH_ALEN];
	unsigned char	h_source[ETH_ALEN];
	__be16		h_vlan_proto;
	__be16		h_vlan_TCI;
	__be16		h_vlan_encapsulated_proto;
};

#define ETH_P_IP	0x0800		/* Internet Protocol packet	*/
#define ETH_P_8021Q	0x8100          /* 802.1Q VLAN Extended Header  */
#define ETH_P_IPV6	0x86DD		/* IPv6 over bluebook		*/
#define ETH_P_FCOE	0x8906		/* Fibre Channel over Ethernet  */

#define VLAN_CFI_MASK		0x1000 /* Canonical Format Indicator */
#define VLAN_TAG_PRESENT	VLAN_CFI_MASK

#define vlan_tx_tag_present(__skb)	((__skb)->vlan_tci & VLAN_TAG_PRESENT)
#define vlan_tx_tag_get(__skb)		((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)

/* Functions to test */

static bool can_checksum_protocol(unsigned long features, __be16 protocol)
{
	return ((features & NETIF_F_GEN_CSUM) ||
		((features & NETIF_F_IP_CSUM) &&
		 protocol == htons(ETH_P_IP)) ||
		((features & NETIF_F_IPV6_CSUM) &&
		 protocol == htons(ETH_P_IPV6)) ||
		((features & NETIF_F_FCOE_CRC) &&
		 protocol == htons(ETH_P_FCOE)));
}

static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
{
       __be16 protocol = skb->protocol;
       int features = dev->features;

       if (vlan_tx_tag_present(skb)) {
               features &= dev->vlan_features;
       } else if (protocol == htons(ETH_P_8021Q)) {
               struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
               protocol = veh->h_vlan_encapsulated_proto;
               features &= dev->vlan_features;
       }

       return can_checksum_protocol(features, protocol);
}

/* Test suite */

struct test_data {
	union {
		struct ethhdr eh;
		struct vlan_ethhdr veh;
	};
	struct sk_buff skb;
	struct net_device dev;
};

typedef void test_fn(struct test_data *);

static void test_unknown(struct test_data *data)
{
	data->dev.features = NETIF_F_IP_CSUM;
	assert(!dev_can_checksum(&data->dev, &data->skb));
}

static void test_no_ip(struct test_data *data)
{
	data->skb.protocol = htons(ETH_P_IP);
	assert(!dev_can_checksum(&data->dev, &data->skb));
}

static void test_ip(struct test_data *data)
{
	data->skb.protocol = htons(ETH_P_IP);
	data->dev.features = NETIF_F_IP_CSUM;
	assert(dev_can_checksum(&data->dev, &data->skb));
}

static void test_vlan_ob_unknown(struct test_data *data)
{
	data->skb.vlan_tci = VLAN_CFI_MASK | 1;
	data->dev.features = NETIF_F_GEN_CSUM;
	assert(!dev_can_checksum(&data->dev, &data->skb));
}

static void test_no_vlan_ob_ip(struct test_data *data)
{
	data->skb.protocol = htons(ETH_P_IP);
	data->skb.vlan_tci = VLAN_CFI_MASK | 1;
	data->dev.features = NETIF_F_IP_CSUM;
	data->dev.vlan_features = 0;
	assert(!dev_can_checksum(&data->dev, &data->skb));
}

static void test_vlan_ob_ip(struct test_data *data)
{
	data->skb.protocol = htons(ETH_P_IP);
	data->skb.vlan_tci = VLAN_CFI_MASK | 1;
	data->dev.features = NETIF_F_IP_CSUM;
	data->dev.vlan_features = NETIF_F_IP_CSUM;
	assert(dev_can_checksum(&data->dev, &data->skb));
}

static void test_vlan_ib_unknown(struct test_data *data)
{
	data->skb.protocol = htons(ETH_P_8021Q);
	data->dev.features = NETIF_F_GEN_CSUM;
	assert(!dev_can_checksum(&data->dev, &data->skb));
}

static void test_no_vlan_ib_ip(struct test_data *data)
{
	data->skb.protocol = htons(ETH_P_8021Q);
	data->veh.h_vlan_encapsulated_proto = htons(ETH_P_IP);
	data->dev.features = NETIF_F_IP_CSUM;
	data->dev.vlan_features = 0;
	assert(!dev_can_checksum(&data->dev, &data->skb));
}

static void test_vlan_ib_ip(struct test_data *data)
{
	data->skb.protocol = htons(ETH_P_8021Q);
	data->veh.h_vlan_encapsulated_proto = htons(ETH_P_IP);
	data->dev.features = NETIF_F_IP_CSUM;
	data->dev.vlan_features = NETIF_F_IP_CSUM;
	assert(dev_can_checksum(&data->dev, &data->skb));
}

static void test_no_2vlan_ob_ip(struct test_data *data)
{
	data->skb.protocol = htons(ETH_P_8021Q);
	data->skb.vlan_tci = VLAN_CFI_MASK | 1;
	data->veh.h_vlan_encapsulated_proto = htons(ETH_P_IP);
	data->dev.features = NETIF_F_IP_CSUM;
	data->dev.vlan_features = NETIF_F_IP_CSUM;
	assert(!dev_can_checksum(&data->dev, &data->skb));
}

static test_fn *tests[] = {
	test_unknown, test_no_ip, test_ip,
	test_vlan_ob_unknown, test_no_vlan_ob_ip, test_vlan_ob_ip,
	test_vlan_ib_unknown, test_no_vlan_ib_ip, test_vlan_ib_ip,
	test_no_2vlan_ob_ip,
};

int main(void)
{
	struct test_data data;
	test_fn **test;

	for (test = tests;
	     test != tests + sizeof(tests) / sizeof(tests[0]);
	     ++test) {
		memset(&data, 0, sizeof(data));
		data.skb.data = &data.eh;
		(**test)(&data);
	}

	return 0;
}

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


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

* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-21 21:36         ` Jesse Gross
  2010-10-22  0:57           ` Dmitry Kravkov
@ 2010-10-24  9:21           ` Vladislav Zolotarov
  2010-10-24 10:11             ` Vladislav Zolotarov
  1 sibling, 1 reply; 48+ messages in thread
From: Vladislav Zolotarov @ 2010-10-24  9:21 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev, Hao Zheng, Eilon Greenstein



> >
> > We hit the same BUG() both when VLAN stripping is disabled.
> 
> This one surprises me because that function shouldn't get called at
> all when VLAN stripping is disabled.  Are you sure that it is
> disabled?  From my reading of the bnx2x driver it seems like it is
> always enabled.

I tried to check all possibilities and to check at which level the problem is,
so I patched the bnx2x not to do the stripping and recompiled it with the
kernel having CONFIG_VLAN_8021Q disabled. Then I saw the (same) BUG() message
again. It seems to me that your patch series were meant to remove the 
handling of this configuration (CONFIG_VLAN_8021Q) from the L2 drivers 
as well, isn't it? This means that the same VLAN flows, both accelerated and none
accelerated should be "active" both when this configuration is present and 
when it's not... Do I get it right?

Thanks,
vlad




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

* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-24  9:21           ` Vladislav Zolotarov
@ 2010-10-24 10:11             ` Vladislav Zolotarov
  2010-10-26  0:29               ` Jesse Gross
  0 siblings, 1 reply; 48+ messages in thread
From: Vladislav Zolotarov @ 2010-10-24 10:11 UTC (permalink / raw)
  To: Vladislav Zolotarov, Jesse Gross
  Cc: David Miller, netdev, Hao Zheng, Eilon Greenstein



> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Vladislav Zolotarov
> Sent: Sunday, October 24, 2010 11:22 AM
> To: Jesse Gross
> Cc: David Miller; netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> Subject: RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> accleration.
> 
> 
> 
> > >
> > > We hit the same BUG() both when VLAN stripping is disabled.
> >
> > This one surprises me because that function shouldn't get called at
> > all when VLAN stripping is disabled.  Are you sure that it is
> > disabled?  From my reading of the bnx2x driver it seems like it is
> > always enabled.
> 
> I tried to check all possibilities and to check at which level the
> problem is,
> so I patched the bnx2x not to do the stripping and recompiled it with
> the
> kernel having CONFIG_VLAN_8021Q disabled. Then I saw the (same) BUG()
> message
> again. It seems to me that your patch series were meant to remove the
> handling of this configuration (CONFIG_VLAN_8021Q) from the L2 drivers
> as well, isn't it? This means that the same VLAN flows, both
> accelerated and none
> accelerated should be "active" both when this configuration is present
> and
> when it's not... Do I get it right?
> 
> Thanks,
> vlad

Jesse, from the fix u posted I conclude that the answer on the above questions is
obviously "yes"... ;) 

I first answered your question and only then looked at the "fixing" 
thread, my apologies... ;)

thanks,
vlad

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



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

* Re: [PATCH v2 10/14] ixgbe: Update ixgbe to use new vlan accleration.
  2010-10-22 13:24   ` Michał Mirosław
@ 2010-10-25 17:50     ` Peter P Waskiewicz Jr
  2010-10-25 21:40       ` Michał Mirosław
  0 siblings, 1 reply; 48+ messages in thread
From: Peter P Waskiewicz Jr @ 2010-10-25 17:50 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: Jesse Gross, David Miller, netdev, Tantilov, Emil S, Kirsher, Jeffrey T

[-- Attachment #1: Type: text/plain, Size: 2322 bytes --]

On Fri, 2010-10-22 at 06:24 -0700, Michał Mirosław wrote:
> 2010/10/21 Jesse Gross <jesse@nicira.com>:
> > Make the ixgbe driver use the new vlan accleration model.
> [...]
> > --- a/drivers/net/ixgbe/ixgbe_main.c
> > +++ b/drivers/net/ixgbe/ixgbe_main.c
> > @@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
> >        bool is_vlan = (status & IXGBE_RXD_STAT_VP);
> >        u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
> >
> > -       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
> > -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
> > -                       vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
> > -               else
> > -                       napi_gro_receive(napi, skb);
> > -       } else {
> > -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
> > -                       vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
> > -               else
> > -                       netif_rx(skb);
> > -       }
> > +       if (is_vlan && (tag & VLAN_VID_MASK))
> > +               __vlan_hwaccel_put_tag(skb, tag);
> 
> I know that this is carried over from the driver, but why tag == 0 is
> treated differently here? VID0 is somewhat special, as normally it
> means 802.1p packet, but i.e. in embedded world people are using it as
> normal VID. It would be nice to have this handled consistently in the
> VLAN core - deliver to base dev (tag stripped) if vlan 0 is not
> configured and to vlan dev if it is.

ixgbe handles VLAN 0 differently because that's the tag that's used when
DCB is enabled, and no VLAN is configured.  We have to insert the 802.1p
tag for DCB to work, but the OS won't know about the 802.1q tag, and
ends up dropping the frame.  So we enable VLAN ID 0 in the HW and tell
it to strip the tag, so we can still pass the frame up the stack.

> 
> > +
> > +       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
> > +               napi_gro_receive(napi, skb);
> > +       else
> > +               netif_rx(skb);
> >  }
> >
> >  /**
> 
> Best Regards,
> Michał Mirosław

-- 
-----------------------------------------------------------
Peter P Waskiewicz Jr                   LAN Access Division
peter.p.waskiewicz.jr@intel.com         Intel Corp.

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 4394 bytes --]

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

* Re: [PATCH v2 10/14] ixgbe: Update ixgbe to use new vlan accleration.
  2010-10-25 17:50     ` Peter P Waskiewicz Jr
@ 2010-10-25 21:40       ` Michał Mirosław
  2010-10-25 22:02         ` John Fastabend
  0 siblings, 1 reply; 48+ messages in thread
From: Michał Mirosław @ 2010-10-25 21:40 UTC (permalink / raw)
  To: Peter P Waskiewicz Jr
  Cc: Jesse Gross, David Miller, netdev, Tantilov, Emil S, Kirsher, Jeffrey T

W dniu 25 października 2010 19:50 użytkownik Peter P Waskiewicz Jr
<peter.p.waskiewicz.jr@intel.com> napisał:
> On Fri, 2010-10-22 at 06:24 -0700, Michał Mirosław wrote:
>> 2010/10/21 Jesse Gross <jesse@nicira.com>:
>> > Make the ixgbe driver use the new vlan accleration model.
>> [...]
>> > --- a/drivers/net/ixgbe/ixgbe_main.c
>> > +++ b/drivers/net/ixgbe/ixgbe_main.c
>> > @@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
>> >        bool is_vlan = (status & IXGBE_RXD_STAT_VP);
>> >        u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
>> >
>> > -       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
>> > -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
>> > -                       vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
>> > -               else
>> > -                       napi_gro_receive(napi, skb);
>> > -       } else {
>> > -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
>> > -                       vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
>> > -               else
>> > -                       netif_rx(skb);
>> > -       }
>> > +       if (is_vlan && (tag & VLAN_VID_MASK))
>> > +               __vlan_hwaccel_put_tag(skb, tag);
>>
>> I know that this is carried over from the driver, but why tag == 0 is
>> treated differently here? VID0 is somewhat special, as normally it
>> means 802.1p packet, but i.e. in embedded world people are using it as
>> normal VID. It would be nice to have this handled consistently in the
>> VLAN core - deliver to base dev (tag stripped) if vlan 0 is not
>> configured and to vlan dev if it is.
>
> ixgbe handles VLAN 0 differently because that's the tag that's used when
> DCB is enabled, and no VLAN is configured.  We have to insert the 802.1p
> tag for DCB to work, but the OS won't know about the 802.1q tag, and
> ends up dropping the frame.  So we enable VLAN ID 0 in the HW and tell
> it to strip the tag, so we can still pass the frame up the stack.

So that's actually (part of) what I'm proposing but done at driver level.

BTW, What happens If you both configure VLAN 0 and enable DCB?

Best Regards,
Michał Mirosław

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

* Re: [PATCH v2 10/14] ixgbe: Update ixgbe to use new vlan accleration.
  2010-10-25 21:40       ` Michał Mirosław
@ 2010-10-25 22:02         ` John Fastabend
  2010-10-25 23:23           ` Michał Mirosław
  0 siblings, 1 reply; 48+ messages in thread
From: John Fastabend @ 2010-10-25 22:02 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: Waskiewicz Jr, Peter P, Jesse Gross, David Miller, netdev,
	Tantilov, Emil S, Kirsher, Jeffrey T

On 10/25/2010 2:40 PM, Michał Mirosław wrote:
> W dniu 25 października 2010 19:50 użytkownik Peter P Waskiewicz Jr
> <peter.p.waskiewicz.jr@intel.com> napisał:
>> On Fri, 2010-10-22 at 06:24 -0700, Michał Mirosław wrote:
>>> 2010/10/21 Jesse Gross <jesse@nicira.com>:
>>>> Make the ixgbe driver use the new vlan accleration model.
>>> [...]
>>>> --- a/drivers/net/ixgbe/ixgbe_main.c
>>>> +++ b/drivers/net/ixgbe/ixgbe_main.c
>>>> @@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
>>>>        bool is_vlan = (status & IXGBE_RXD_STAT_VP);
>>>>        u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
>>>>
>>>> -       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
>>>> -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
>>>> -                       vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
>>>> -               else
>>>> -                       napi_gro_receive(napi, skb);
>>>> -       } else {
>>>> -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
>>>> -                       vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
>>>> -               else
>>>> -                       netif_rx(skb);
>>>> -       }
>>>> +       if (is_vlan && (tag & VLAN_VID_MASK))
>>>> +               __vlan_hwaccel_put_tag(skb, tag);
>>>
>>> I know that this is carried over from the driver, but why tag == 0 is
>>> treated differently here? VID0 is somewhat special, as normally it
>>> means 802.1p packet, but i.e. in embedded world people are using it as
>>> normal VID. It would be nice to have this handled consistently in the
>>> VLAN core - deliver to base dev (tag stripped) if vlan 0 is not
>>> configured and to vlan dev if it is.
>>
>> ixgbe handles VLAN 0 differently because that's the tag that's used when
>> DCB is enabled, and no VLAN is configured.  We have to insert the 802.1p
>> tag for DCB to work, but the OS won't know about the 802.1q tag, and
>> ends up dropping the frame.  So we enable VLAN ID 0 in the HW and tell
>> it to strip the tag, so we can still pass the frame up the stack.
> 
> So that's actually (part of) what I'm proposing but done at driver level.
> 

Michal,

I agree this should be handled outside the driver. Something like this should
do,

--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -12,10 +12,12 @@ Hunk #1, a/net/8021q/vlan_core.c bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
        struct vlan_rx_stats *rx_stats;

        vlan_dev = vlan_find_dev(skb->dev, vlan_id);
-       if (!vlan_dev) {
-               if (vlan_id)
-                       skb->pkt_type = PACKET_OTHERHOST;
+       if (!vlan_dev && vlan_id) {
+               skb->pkt_type = PACKET_OTHERHOST;
                return false;
+       } else if (!vlan_dev) {
+               skb->vlan_tci = 0;
+               return true;
        }

        skb = *skbp = skb_share_check(skb, GFP_ATOMIC);
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -134,14 +134,14 @@ Hunk #1, a/net/8021q/vlan_dev.c int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
         * wrapped proto: we do nothing here.
         */

-       if (!vlan_dev) {
+       if (!vlan_dev && vlan_id) {
                if (vlan_id) {
                        pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n",
                                 __func__, vlan_id, dev->name);
                        goto err_unlock;
                }
                rx_stats = NULL;
-       } else {
+       } else if (vlan_id) {
                skb->dev = vlan_dev;

                rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats);



> BTW, What happens If you both configure VLAN 0 and enable DCB?
> 

Currently, on ixgbe VLAN0 will not work with DCB. We should just remove it
on net-next. I'll put together a formal patch for the first part.

Thanks,
John

> Best Regards,
> Michał Mirosław
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH v2 10/14] ixgbe: Update ixgbe to use new vlan accleration.
  2010-10-25 22:02         ` John Fastabend
@ 2010-10-25 23:23           ` Michał Mirosław
  2010-10-26  0:08             ` Jesse Gross
  0 siblings, 1 reply; 48+ messages in thread
From: Michał Mirosław @ 2010-10-25 23:23 UTC (permalink / raw)
  To: John Fastabend
  Cc: Waskiewicz Jr, Peter P, Jesse Gross, David Miller, netdev,
	Tantilov, Emil S, Kirsher, Jeffrey T

W dniu 26 października 2010 00:02 użytkownik John Fastabend
<john.r.fastabend@intel.com> napisał:
> On 10/25/2010 2:40 PM, Michał Mirosław wrote:
>> W dniu 25 października 2010 19:50 użytkownik Peter P Waskiewicz Jr
>> <peter.p.waskiewicz.jr@intel.com> napisał:
>>> On Fri, 2010-10-22 at 06:24 -0700, Michał Mirosław wrote:
>>>> 2010/10/21 Jesse Gross <jesse@nicira.com>:
>>>>> Make the ixgbe driver use the new vlan accleration model.
>>>> [...]
>>>>> --- a/drivers/net/ixgbe/ixgbe_main.c
>>>>> +++ b/drivers/net/ixgbe/ixgbe_main.c
>>>>> @@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
>>>>>        bool is_vlan = (status & IXGBE_RXD_STAT_VP);
>>>>>        u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
>>>>>
>>>>> -       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
>>>>> -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
>>>>> -                       vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
>>>>> -               else
>>>>> -                       napi_gro_receive(napi, skb);
>>>>> -       } else {
>>>>> -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
>>>>> -                       vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
>>>>> -               else
>>>>> -                       netif_rx(skb);
>>>>> -       }
>>>>> +       if (is_vlan && (tag & VLAN_VID_MASK))
>>>>> +               __vlan_hwaccel_put_tag(skb, tag);
>>>>
>>>> I know that this is carried over from the driver, but why tag == 0 is
>>>> treated differently here? VID0 is somewhat special, as normally it
>>>> means 802.1p packet, but i.e. in embedded world people are using it as
>>>> normal VID. It would be nice to have this handled consistently in the
>>>> VLAN core - deliver to base dev (tag stripped) if vlan 0 is not
>>>> configured and to vlan dev if it is.
>>>
>>> ixgbe handles VLAN 0 differently because that's the tag that's used when
>>> DCB is enabled, and no VLAN is configured.  We have to insert the 802.1p
>>> tag for DCB to work, but the OS won't know about the 802.1q tag, and
>>> ends up dropping the frame.  So we enable VLAN ID 0 in the HW and tell
>>> it to strip the tag, so we can still pass the frame up the stack.
>>
>> So that's actually (part of) what I'm proposing but done at driver level.
> I agree this should be handled outside the driver. Something like this should
> do,

Current code (Linus' tree, so with Jesse's VLAN rework applied) should
work exactly as I proposed in my original mail - VLAN 0 is treated as
802.1p (stripped and delivered to original dev) unless vlan device
with id 0 is configured. (Patch untested).

Best Regards,
Michał Mirosław
---

ixgbe: Enable VLAN 0

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>

diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index f856312..1544368 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -956,7 +956,7 @@ static void ixgbe_receive_skb(struct
ixgbe_q_vector *q_vector,
 	bool is_vlan = (status & IXGBE_RXD_STAT_VP);
 	u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);

-	if (is_vlan && (tag & VLAN_VID_MASK))
+	if (is_vlan)
 		__vlan_hwaccel_put_tag(skb, tag);

 	if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))

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

* Re: [PATCH v2 10/14] ixgbe: Update ixgbe to use new vlan accleration.
  2010-10-25 23:23           ` Michał Mirosław
@ 2010-10-26  0:08             ` Jesse Gross
  0 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-26  0:08 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: John Fastabend, Waskiewicz Jr, Peter P, David Miller, netdev,
	Tantilov, Emil S, Kirsher, Jeffrey T

2010/10/25 Michał Mirosław <mirqus@gmail.com>:
> W dniu 26 października 2010 00:02 użytkownik John Fastabend
> <john.r.fastabend@intel.com> napisał:
>> On 10/25/2010 2:40 PM, Michał Mirosław wrote:
>>> W dniu 25 października 2010 19:50 użytkownik Peter P Waskiewicz Jr
>>> <peter.p.waskiewicz.jr@intel.com> napisał:
>>>> On Fri, 2010-10-22 at 06:24 -0700, Michał Mirosław wrote:
>>>>> 2010/10/21 Jesse Gross <jesse@nicira.com>:
>>>>>> Make the ixgbe driver use the new vlan accleration model.
>>>>> [...]
>>>>>> --- a/drivers/net/ixgbe/ixgbe_main.c
>>>>>> +++ b/drivers/net/ixgbe/ixgbe_main.c
>>>>>> @@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
>>>>>>        bool is_vlan = (status & IXGBE_RXD_STAT_VP);
>>>>>>        u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
>>>>>>
>>>>>> -       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
>>>>>> -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
>>>>>> -                       vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
>>>>>> -               else
>>>>>> -                       napi_gro_receive(napi, skb);
>>>>>> -       } else {
>>>>>> -               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
>>>>>> -                       vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
>>>>>> -               else
>>>>>> -                       netif_rx(skb);
>>>>>> -       }
>>>>>> +       if (is_vlan && (tag & VLAN_VID_MASK))
>>>>>> +               __vlan_hwaccel_put_tag(skb, tag);
>>>>>
>>>>> I know that this is carried over from the driver, but why tag == 0 is
>>>>> treated differently here? VID0 is somewhat special, as normally it
>>>>> means 802.1p packet, but i.e. in embedded world people are using it as
>>>>> normal VID. It would be nice to have this handled consistently in the
>>>>> VLAN core - deliver to base dev (tag stripped) if vlan 0 is not
>>>>> configured and to vlan dev if it is.
>>>>
>>>> ixgbe handles VLAN 0 differently because that's the tag that's used when
>>>> DCB is enabled, and no VLAN is configured.  We have to insert the 802.1p
>>>> tag for DCB to work, but the OS won't know about the 802.1q tag, and
>>>> ends up dropping the frame.  So we enable VLAN ID 0 in the HW and tell
>>>> it to strip the tag, so we can still pass the frame up the stack.
>>>
>>> So that's actually (part of) what I'm proposing but done at driver level.
>> I agree this should be handled outside the driver. Something like this should
>> do,
>
> Current code (Linus' tree, so with Jesse's VLAN rework applied) should
> work exactly as I proposed in my original mail - VLAN 0 is treated as
> 802.1p (stripped and delivered to original dev) unless vlan device
> with id 0 is configured. (Patch untested).

Yes, the current vlan acceleration path should work correctly in this
case.  There are definitely a few things that can be improved though:

1. The non-accelerated path doesn't handle things in the same way,
which is inherently not good.  It doesn't drop packets to vlan 0 but
it does run them through the network stack again on the same device.
The acceleration code simply allows it to continue onto the protocol
handlers.  This can have strange results, i.e. packets will show up
twice in tcpdump (tagged and untagged) on non-accelerated but once
(tagged) on accelerated.

2.  In the ixgbe driver we should be able to handle vlan 0 in a less
special manner.  In addition to delivering accelerated tags to vlan 0,
we should also be able to avoid DCB forcing on vlan stripping.

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

* Re: [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum()
  2010-10-22 14:12       ` [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum() Ben Hutchings
  2010-10-22 14:18         ` Ben Hutchings
@ 2010-10-26  0:21         ` Jesse Gross
  2010-10-26 13:29           ` Ben Hutchings
  2010-10-27 18:00         ` David Miller
  2 siblings, 1 reply; 48+ messages in thread
From: Jesse Gross @ 2010-10-26  0:21 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev

On Fri, Oct 22, 2010 at 7:12 AM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
> dev_can_checksum() incorrectly returns true in these cases:
>
> 1. The skb has both out-of-band and in-band VLAN tags and the device
>   supports checksum offload for the encapsulated protocol but only with
>   one layer of encapsulation.
> 2. The skb has a VLAN tag and the device supports generic checksumming
>   but not in conjunction with VLAN encapsulation.
>
> Rearrange the VLAN tag checks to avoid these.
>
> Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>

If we assume that cards cannot handle offloading for double tagged
packets, which is obviously the most conservative approach, we
probably also need to change the checks for TSO/SG.  There's no issue
with extracting the protocol from the right header but we might assume
that the card can handle double tag offloading when it can't.  For
both TSO/SG we check if there is either an in-band tag or out-of-band
tag and use dev->vlan_features if that is the case.  Maybe we need to
handle it in software if it is double tagged.

On the other hand, I don't know whether it's true that cards can't
handle offloading for packets tagged in both manners.  I suppose that
it depends on where the offloading and tagging are in the pipeline.
For example, when it comes to SG I doubt that the cards care about
vlan tags much at all.

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

* Re: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-24 10:11             ` Vladislav Zolotarov
@ 2010-10-26  0:29               ` Jesse Gross
  2010-10-26  9:14                 ` Vladislav Zolotarov
  0 siblings, 1 reply; 48+ messages in thread
From: Jesse Gross @ 2010-10-26  0:29 UTC (permalink / raw)
  To: Vladislav Zolotarov; +Cc: David Miller, netdev, Hao Zheng, Eilon Greenstein

On Sun, Oct 24, 2010 at 3:11 AM, Vladislav Zolotarov <vladz@broadcom.com> wrote:
>
>
>> -----Original Message-----
>> From: netdev-owner@vger.kernel.org [mailto:netdev-
>> owner@vger.kernel.org] On Behalf Of Vladislav Zolotarov
>> Sent: Sunday, October 24, 2010 11:22 AM
>> To: Jesse Gross
>> Cc: David Miller; netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
>> Subject: RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
>> accleration.
>>
>>
>>
>> > >
>> > > We hit the same BUG() both when VLAN stripping is disabled.
>> >
>> > This one surprises me because that function shouldn't get called at
>> > all when VLAN stripping is disabled.  Are you sure that it is
>> > disabled?  From my reading of the bnx2x driver it seems like it is
>> > always enabled.
>>
>> I tried to check all possibilities and to check at which level the
>> problem is,
>> so I patched the bnx2x not to do the stripping and recompiled it with
>> the
>> kernel having CONFIG_VLAN_8021Q disabled. Then I saw the (same) BUG()
>> message
>> again. It seems to me that your patch series were meant to remove the
>> handling of this configuration (CONFIG_VLAN_8021Q) from the L2 drivers
>> as well, isn't it? This means that the same VLAN flows, both
>> accelerated and none
>> accelerated should be "active" both when this configuration is present
>> and
>> when it's not... Do I get it right?
>>
>> Thanks,
>> vlad
>
> Jesse, from the fix u posted I conclude that the answer on the above questions is
> obviously "yes"... ;)

Yes, that's right.

>
> I first answered your question and only then looked at the "fixing"
> thread, my apologies... ;)

Even though the fix prevents the panic, I'm still a little concerned
that you ran into it at all when vlan stripping was disabled.  That
function should only be called when a tag was received by the card.
Is it possible that __vlan_hwaccel_put_tag is being called even in
cases when no tag was stripped?  Maybe we made a mistake when
converting the driver?

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

* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-26  0:29               ` Jesse Gross
@ 2010-10-26  9:14                 ` Vladislav Zolotarov
  2010-10-26 17:57                   ` Jesse Gross
  0 siblings, 1 reply; 48+ messages in thread
From: Vladislav Zolotarov @ 2010-10-26  9:14 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev, Hao Zheng, Eilon Greenstein

> 
> Even though the fix prevents the panic, I'm still a little concerned
> that you ran into it at all when vlan stripping was disabled.  That
> function should only be called when a tag was received by the card.
> Is it possible that __vlan_hwaccel_put_tag is being called even in
> cases when no tag was stripped?  

Correct, and that's because u've patched the driver to put it the
following way:

if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
                     PARSING_FLAGS_VLAN)
        __vlan_hwaccel_put_tag(skb, le16_to_cpu(cqe->fast_path_cqe.vlan_tag));

The condition above will be TRUE regardless VLAN stripping is enabled or
disabled as the parsing flags come from our PARSER HW block and simply
indicates whether this frame has a VLAN header or not. When I disabled a VLAN
stripping I should have fixed this lines too but I think I didn't... ;)

> Maybe we made a mistake when converting the driver?

Since the driver always configures the VLAN stripping now, regardless the kernel
configuration, I think your patch was just fine. ;)

Thanks,
vlad





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

* Re: [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum()
  2010-10-26  0:21         ` Jesse Gross
@ 2010-10-26 13:29           ` Ben Hutchings
  2010-10-26 18:11             ` Jesse Gross
  0 siblings, 1 reply; 48+ messages in thread
From: Ben Hutchings @ 2010-10-26 13:29 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev

Jesse Gross wrote:
> On Fri, Oct 22, 2010 at 7:12 AM, Ben Hutchings
> <bhutchings@solarflare.com> wrote:
> > dev_can_checksum() incorrectly returns true in these cases:
> >
> > 1. The skb has both out-of-band and in-band VLAN tags and the device
> >   supports checksum offload for the encapsulated protocol but only with
> >   one layer of encapsulation.
> > 2. The skb has a VLAN tag and the device supports generic checksumming
> >   but not in conjunction with VLAN encapsulation.
> >
> > Rearrange the VLAN tag checks to avoid these.
> >
> > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
> 
> If we assume that cards cannot handle offloading for double tagged
> packets, which is obviously the most conservative approach, we
> probably also need to change the checks for TSO/SG.  There's no issue
> with extracting the protocol from the right header but we might assume
> that the card can handle double tag offloading when it can't.  For
> both TSO/SG we check if there is either an in-band tag or out-of-band
> tag and use dev->vlan_features if that is the case.  Maybe we need to
> handle it in software if it is double tagged.

That's something to check.

> On the other hand, I don't know whether it's true that cards can't
> handle offloading for packets tagged in both manners.  I suppose that
> it depends on where the offloading and tagging are in the pipeline.
> For example, when it comes to SG I doubt that the cards care about
> vlan tags much at all.

I do know that current Solarflare controllers can parse two VLAN tags
and generate/validate TCP/IP-style checksums after them.  We could add
vlan2_features which would be copied to a VLAN sub-device's
vlan_features, but then what happens when people want to handle triple
VLAN encapsulation?

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

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

* Re: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
  2010-10-26  9:14                 ` Vladislav Zolotarov
@ 2010-10-26 17:57                   ` Jesse Gross
  0 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-26 17:57 UTC (permalink / raw)
  To: Vladislav Zolotarov; +Cc: David Miller, netdev, Hao Zheng, Eilon Greenstein

On Tue, Oct 26, 2010 at 2:14 AM, Vladislav Zolotarov <vladz@broadcom.com> wrote:
>>
>> Even though the fix prevents the panic, I'm still a little concerned
>> that you ran into it at all when vlan stripping was disabled.  That
>> function should only be called when a tag was received by the card.
>> Is it possible that __vlan_hwaccel_put_tag is being called even in
>> cases when no tag was stripped?
>
> Correct, and that's because u've patched the driver to put it the
> following way:
>
> if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
>                     PARSING_FLAGS_VLAN)
>        __vlan_hwaccel_put_tag(skb, le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
>
> The condition above will be TRUE regardless VLAN stripping is enabled or
> disabled as the parsing flags come from our PARSER HW block and simply
> indicates whether this frame has a VLAN header or not. When I disabled a VLAN
> stripping I should have fixed this lines too but I think I didn't... ;)
>
>> Maybe we made a mistake when converting the driver?
>
> Since the driver always configures the VLAN stripping now, regardless the kernel
> configuration, I think your patch was just fine. ;)

Great.  Thanks for the explanation and confirmation.

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

* Re: [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum()
  2010-10-26 13:29           ` Ben Hutchings
@ 2010-10-26 18:11             ` Jesse Gross
  0 siblings, 0 replies; 48+ messages in thread
From: Jesse Gross @ 2010-10-26 18:11 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev

On Tue, Oct 26, 2010 at 6:29 AM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
> Jesse Gross wrote:
>> On Fri, Oct 22, 2010 at 7:12 AM, Ben Hutchings
>> <bhutchings@solarflare.com> wrote:
>> > dev_can_checksum() incorrectly returns true in these cases:
>> >
>> > 1. The skb has both out-of-band and in-band VLAN tags and the device
>> >   supports checksum offload for the encapsulated protocol but only with
>> >   one layer of encapsulation.
>> > 2. The skb has a VLAN tag and the device supports generic checksumming
>> >   but not in conjunction with VLAN encapsulation.
>> >
>> > Rearrange the VLAN tag checks to avoid these.
>> >
>> > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
>>
>> If we assume that cards cannot handle offloading for double tagged
>> packets, which is obviously the most conservative approach, we
>> probably also need to change the checks for TSO/SG.  There's no issue
>> with extracting the protocol from the right header but we might assume
>> that the card can handle double tag offloading when it can't.  For
>> both TSO/SG we check if there is either an in-band tag or out-of-band
>> tag and use dev->vlan_features if that is the case.  Maybe we need to
>> handle it in software if it is double tagged.
>
> That's something to check.
>
>> On the other hand, I don't know whether it's true that cards can't
>> handle offloading for packets tagged in both manners.  I suppose that
>> it depends on where the offloading and tagging are in the pipeline.
>> For example, when it comes to SG I doubt that the cards care about
>> vlan tags much at all.
>
> I do know that current Solarflare controllers can parse two VLAN tags
> and generate/validate TCP/IP-style checksums after them.  We could add
> vlan2_features which would be copied to a VLAN sub-device's
> vlan_features, but then what happens when people want to handle triple
> VLAN encapsulation?

I agree, it's definitely a losing battle to keep adding vlan_features
to handle n + 1 tags.  I was just thinking that we might be able to
make some assumptions about packets tagged out-of-band, since the NIC
doesn't need to parse them at all.  If the tagging takes place late
enough in the pipeline, it might be completely transparent.

It may not be a valid assumption to make for all NICs though, so it's
probably better to be conservative.  As long as we handle it correctly
in software, we can potentially relax it later in the future.

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

* Re: [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum()
  2010-10-22 14:12       ` [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum() Ben Hutchings
  2010-10-22 14:18         ` Ben Hutchings
  2010-10-26  0:21         ` Jesse Gross
@ 2010-10-27 18:00         ` David Miller
  2 siblings, 0 replies; 48+ messages in thread
From: David Miller @ 2010-10-27 18:00 UTC (permalink / raw)
  To: bhutchings; +Cc: jesse, netdev

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Fri, 22 Oct 2010 15:12:19 +0100

> dev_can_checksum() incorrectly returns true in these cases:
> 
> 1. The skb has both out-of-band and in-band VLAN tags and the device
>    supports checksum offload for the encapsulated protocol but only with
>    one layer of encapsulation.
> 2. The skb has a VLAN tag and the device supports generic checksumming
>    but not in conjunction with VLAN encapsulation.
> 
> Rearrange the VLAN tag checks to avoid these.
> 
> Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>

Applied, thanks for fixing this Ben.

We really do need to figure out how to handle all of the various
"super vlan" encapsulation schemes (Cisco's RFC5517, 802.1ad,
802.1ah), and their offloads.

In fact, 802.1ad and 802.1ah use completely different framing than
the current VLAN bits.

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

end of thread, other threads:[~2010-10-27 18:00 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-20 23:56 [PATCH v2 00/14] Move vlan acceleration into networking core Jesse Gross
2010-10-20 23:56 ` [PATCH v2 01/14] ebtables: Allow filtering of hardware accelerated vlan frames Jesse Gross
2010-10-20 23:56 ` [PATCH v2 02/14] vlan: Rename VLAN_GROUP_ARRAY_LEN to VLAN_N_VID Jesse Gross
2010-10-20 23:56 ` [PATCH v2 03/14] vlan: Don't check for vlan group before vlan_tx_tag_present Jesse Gross
2010-10-20 23:56 ` [PATCH v2 04/14] vlan: Enable software emulation for vlan accleration Jesse Gross
2010-10-21  3:32   ` John Fastabend
2010-10-21 15:30   ` Ben Hutchings
2010-10-21 21:44     ` Jesse Gross
2010-10-22 14:12       ` [PATCH net-next-2.6] net: Fix some corner cases in dev_can_checksum() Ben Hutchings
2010-10-22 14:18         ` Ben Hutchings
2010-10-26  0:21         ` Jesse Gross
2010-10-26 13:29           ` Ben Hutchings
2010-10-26 18:11             ` Jesse Gross
2010-10-27 18:00         ` David Miller
2010-10-20 23:56 ` [PATCH v2 05/14] vlan: Avoid hash table lookup to find group Jesse Gross
2010-10-20 23:56 ` [PATCH v2 06/14] vlan: Centralize handling of hardware acceleration Jesse Gross
2010-10-20 23:56 ` [PATCH v2 07/14] ethtool: Add support for vlan accleration Jesse Gross
2010-10-21  3:27   ` John Fastabend
2010-10-21 19:43     ` Jesse Gross
2010-10-20 23:56 ` [PATCH v2 08/14] bridge: Add support for TX vlan offload Jesse Gross
2010-10-20 23:56 ` [PATCH v2 09/14] bnx2: Update bnx2 to use new vlan accleration Jesse Gross
2010-10-21 15:31   ` Ben Hutchings
2010-10-21 21:38     ` Jesse Gross
2010-10-20 23:56 ` [PATCH v2 10/14] ixgbe: Update ixgbe " Jesse Gross
2010-10-22 13:24   ` Michał Mirosław
2010-10-25 17:50     ` Peter P Waskiewicz Jr
2010-10-25 21:40       ` Michał Mirosław
2010-10-25 22:02         ` John Fastabend
2010-10-25 23:23           ` Michał Mirosław
2010-10-26  0:08             ` Jesse Gross
2010-10-20 23:56 ` [PATCH v2 11/14] bnx2x: Update bnx2x " Jesse Gross
2010-10-21 13:54   ` Vladislav Zolotarov
2010-10-21 14:02     ` Vladislav Zolotarov
2010-10-21 14:50       ` Vladislav Zolotarov
2010-10-21 21:36         ` Jesse Gross
2010-10-22  0:57           ` Dmitry Kravkov
2010-10-24  9:21           ` Vladislav Zolotarov
2010-10-24 10:11             ` Vladislav Zolotarov
2010-10-26  0:29               ` Jesse Gross
2010-10-26  9:14                 ` Vladislav Zolotarov
2010-10-26 17:57                   ` Jesse Gross
2010-10-21 21:34       ` Jesse Gross
2010-10-20 23:56 ` [PATCH v2 12/14] lro: Remove explicit vlan support Jesse Gross
2010-10-20 23:56 ` [PATCH v2 13/14] bonding: Update bonding for new vlan model Jesse Gross
2010-10-20 23:56 ` [PATCH v2 14/14] vlan: Remove accleration legacy functions Jesse Gross
2010-10-21  2:02 ` [PATCH v2 00/14] Move vlan acceleration into networking core David Dillow
2010-10-21 19:32   ` Jesse Gross
2010-10-21  8:33 ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.