--- /dev/null
+From de2cba89e1b6c3325259691964ea2dd3d7fd0bc7 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@emulex.com>
+Date: Mon, 10 Mar 2014 17:06:44 +0530
+Subject: [PATCH] be2net: Fixing vlan crash in RHEL 6.5 and 6.4
+
+Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
+---
+ drivers/net/ethernet/emulex/benet/be_compat.h | 7 +++++
+ drivers/net/ethernet/emulex/benet/be_main.c | 32 ++++++++++++++++++-------
+ 2 files changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_compat.h b/drivers/net/ethernet/emulex/benet/be_compat.h
+index 3daa68a..d30267e 100644
+--- a/drivers/net/ethernet/emulex/benet/be_compat.h
++++ b/drivers/net/ethernet/emulex/benet/be_compat.h
+@@ -11,6 +11,13 @@
+ #define USE_NEW_VLAN_MODEL
+ #endif
+
++#if defined(USE_NEW_VLAN_MODEL) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
++/* vlan_gro_frags() can be safely called when vlan_group is NULL
++ * * for kernels >= 3.0 or when kernels uses USE_NEW_VLAN_MODEL.
++ */
++#define NULL_VLAN_GRP_SAFE
++#endif
++
+ static inline struct sk_buff *__vlan_put_tag_fixed(struct sk_buff *skb,
+ __be16 vlan_proto,
+ ushort vlan_tag)
+diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
+index 2ff0d29..6f12546 100644
+--- a/drivers/net/ethernet/emulex/benet/be_main.c
++++ b/drivers/net/ethernet/emulex/benet/be_main.c
+@@ -1135,17 +1135,18 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ return status;
+ #else
+- return;
++ return;
+ #endif
+
+ adapter->vlan_tag[vid] = 1;
++ adapter->vlans_added++;
+ if (adapter->vlans_added <= (be_max_vlans(adapter) + 1))
+ status = be_vid_config(adapter);
+
+- if (!status)
+- adapter->vlans_added++;
+- else
++ if (status) {
++ adapter->vlans_added--;
+ adapter->vlan_tag[vid] = 0;
++ }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ return status;
+ #endif
+@@ -1165,7 +1166,7 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+ return status;
+ #else
+- return;
++ return;
+ #endif
+
+ adapter->vlan_tag[vid] = 0;
+@@ -1572,6 +1573,12 @@ static void be_rx_compl_process(struct be_rx_obj *rxo,
+ else
+ skb_checksum_none_assert(skb);
+
++#ifndef NULL_VLAN_GRP_SAFE
++ if (rxcp->vlanf && !adapter->vlan_grp) {
++ __vlan_put_tag(skb, rxcp->vlan_tag);
++ rxcp->vlanf = 0;
++ }
++#endif
+ skb->protocol = eth_type_trans(skb, netdev);
+ skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
+ if (netdev->features & NETIF_F_RXHASH)
+@@ -1637,7 +1644,7 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
+
+ if (rxcp->vlanf)
+
+- vlan_gro_frags(napi, NULL, rxcp->vlan_tag);
++ vlan_gro_frags(napi, adapter->vlan_grp, rxcp->vlan_tag);
+ else
+ napi_gro_frags(napi);
+ }
+@@ -2250,9 +2257,16 @@ static irqreturn_t be_msix(int irq, void *dev)
+ return IRQ_HANDLED;
+ }
+
+-static inline bool do_gro(struct be_rx_compl_info *rxcp)
++static inline bool do_gro(struct be_adapter *adapter,
++ struct be_rx_compl_info *rxcp)
+ {
+- return (rxcp->tcpf && !rxcp->err && rxcp->l4_csum) ? true : false;
++ bool insert_tag = false;
++
++#ifndef NULL_VLAN_GRP_SAFE
++ insert_tag = rxcp->vlanf && !adapter->vlan_grp;
++#endif
++ return rxcp->tcpf && !rxcp->err &&
++ rxcp->l4_csum && !insert_tag;
+ }
+
+ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
+@@ -2287,7 +2301,7 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
+ goto loop_continue;
+ }
+
+- if (do_gro(rxcp))
++ if (do_gro(adapter, rxcp))
+ be_rx_compl_process_gro(rxo, napi, rxcp);
+ else
+ be_rx_compl_process(rxo, rxcp);
+--
+1.7.1
+