be2net: fix to ignore transparent vlan ids wrongly indicated by NIC
authorAjit Khaparde <ajit.khaparde@emulex.com>
Sun, 20 Feb 2011 11:41:53 +0000 (11:41 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 22 Feb 2011 18:26:46 +0000 (10:26 -0800)
With transparent VLAN tagging, the ASIC wrongly indicates packets with VLAN ID.
Strip them off in the driver. The VLAN Tag to be stripped will be given to the host
as an async message.

Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/benet/be.h
drivers/net/benet/be_cmds.c
drivers/net/benet/be_cmds.h
drivers/net/benet/be_main.c

index fb605e83446c4ea2c07f988e47b60adfdd9436fc..7bf8dd4edeb4c596f7896dd0159e750eae2529a6 100644 (file)
@@ -311,6 +311,7 @@ struct be_adapter {
        struct be_vf_cfg vf_cfg[BE_MAX_VF];
        u8 is_virtfn;
        u32 sli_family;
+       u16 pvid;
 };
 
 #define be_physfn(adapter) (!adapter->is_virtfn)
index 7120106db8cb31f3b0eb2309ece9cd6728a8f5cc..59d25acf4374e40be2ceefcc5e03ba9f125549ee 100644 (file)
@@ -124,6 +124,16 @@ static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
        }
 }
 
+/*Grp5 PVID evt*/
+static void be_async_grp5_pvid_state_process(struct be_adapter *adapter,
+               struct be_async_event_grp5_pvid_state *evt)
+{
+       if (evt->enabled)
+               adapter->pvid = evt->tag;
+       else
+               adapter->pvid = 0;
+}
+
 static void be_async_grp5_evt_process(struct be_adapter *adapter,
                u32 trailer, struct be_mcc_compl *evt)
 {
@@ -141,6 +151,10 @@ static void be_async_grp5_evt_process(struct be_adapter *adapter,
                be_async_grp5_qos_speed_process(adapter,
                (struct be_async_event_grp5_qos_link_speed *)evt);
        break;
+       case ASYNC_EVENT_PVID_STATE:
+               be_async_grp5_pvid_state_process(adapter,
+               (struct be_async_event_grp5_pvid_state *)evt);
+       break;
        default:
                dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n");
                break;
index 331e9540bc74e0c57f64e5088c740d426893b592..a5af2963e7ef69043fc0d621ad118669dda94beb 100644 (file)
@@ -88,6 +88,7 @@ struct be_mcc_compl {
 #define ASYNC_EVENT_CODE_GRP_5         0x5
 #define ASYNC_EVENT_QOS_SPEED          0x1
 #define ASYNC_EVENT_COS_PRIORITY       0x2
+#define ASYNC_EVENT_PVID_STATE         0x3
 struct be_async_event_trailer {
        u32 code;
 };
@@ -134,6 +135,18 @@ struct be_async_event_grp5_cos_priority {
        struct be_async_event_trailer trailer;
 } __packed;
 
+/* When the event code of an async trailer is GRP5 and event type is
+ * PVID state, the mcc_compl must be interpreted as follows
+ */
+struct be_async_event_grp5_pvid_state {
+       u8 enabled;
+       u8 rsvd0;
+       u16 tag;
+       u32 event_tag;
+       u32 rsvd1;
+       struct be_async_event_trailer trailer;
+} __packed;
+
 struct be_mcc_mailbox {
        struct be_mcc_wrb wrb;
        struct be_mcc_compl compl;
index b9e170da12deab4fd237b7a2407de5bd759295f2..cd6fda776d8d3e074ff3bb40c0d470d8d66e72c7 100644 (file)
@@ -1047,6 +1047,9 @@ static void be_rx_compl_process(struct be_adapter *adapter,
        if ((adapter->function_mode & 0x400) && !vtm)
                vlanf = 0;
 
+       if ((adapter->pvid == vlanf) && !adapter->vlan_tag[vlanf])
+               vlanf = 0;
+
        if (unlikely(vlanf)) {
                if (!adapter->vlan_grp || adapter->vlans_added == 0) {
                        kfree_skb(skb);
@@ -1087,6 +1090,9 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
        if ((adapter->function_mode & 0x400) && !vtm)
                vlanf = 0;
 
+       if ((adapter->pvid == vlanf) && !adapter->vlan_tag[vlanf])
+               vlanf = 0;
+
        skb = napi_get_frags(&eq_obj->napi);
        if (!skb) {
                be_rx_compl_discard(adapter, rxo, rxcp);