i40e: Fix SR-IOV VF port VLAN
authorGreg Rose <gregory.v.rose@intel.com>
Thu, 28 Nov 2013 06:39:34 +0000 (06:39 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Mon, 6 Jan 2014 04:59:01 +0000 (20:59 -0800)
This patch fixes two different problems.
1) The port VLAN configuration was not persistent across VF driver
   loads and unloads.

2) The port VLAN configuration was only correct the first time it was
   set. Switching the port VLAN on and off would cause subsequent VLAN
   configurations to be corrupted in the VSI.  Ensure that the correct
   bits are being set for the VSI port VLAN configuration.

Change-Id: I7ebf5329f77eb8d73ccd3324eb346b3abeea737d
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h

index 55fd23d8d5fee3ef6824ce867d0588c0d3219174..d0b20465b45417acd986aa8497df496defbb1c52 100644 (file)
@@ -2016,8 +2016,9 @@ int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid)
 
        vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
        vsi->info.pvid = cpu_to_le16(vid);
-       vsi->info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_INSERT_PVID;
-       vsi->info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_UNTAGGED;
+       vsi->info.port_vlan_flags = I40E_AQ_VSI_PVLAN_MODE_TAGGED |
+                                   I40E_AQ_VSI_PVLAN_INSERT_PVID |
+                                   I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH;
 
        ctxt.seid = vsi->seid;
        memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
@@ -2040,8 +2041,9 @@ int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid)
  **/
 void i40e_vsi_remove_pvid(struct i40e_vsi *vsi)
 {
+       i40e_vlan_stripping_disable(vsi);
+
        vsi->info.pvid = 0;
-       i40e_vlan_rx_register(vsi->netdev, vsi->netdev->features);
 }
 
 /**
index 685b2851550c971d1de5181a77a0207e1258cfeb..2c042a264db0fb5905f2c55341ebecb9ea076964 100644 (file)
@@ -388,8 +388,16 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
                dev_info(&pf->pdev->dev,
                         "LAN VSI index %d, VSI id %d\n",
                         vsi->idx, vsi->id);
+               /* If the port VLAN has been configured and then the
+                * VF driver was removed then the VSI port VLAN
+                * configuration was destroyed.  Check if there is
+                * a port VLAN and restore the VSI configuration if
+                * needed.
+                */
+               if (vf->port_vlan_id)
+                       i40e_vsi_add_pvid(vsi, vf->port_vlan_id);
                f = i40e_add_filter(vsi, vf->default_lan_addr.addr,
-                                   0, true, false);
+                                   vf->port_vlan_id, true, false);
        }
 
        if (!f) {
@@ -1958,7 +1966,7 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
                ret = i40e_vsi_add_pvid(vsi,
                                vlan_id | (qos << I40E_VLAN_PRIORITY_SHIFT));
        else
-               i40e_vlan_stripping_disable(vsi);
+               i40e_vsi_remove_pvid(vsi);
 
        if (vlan_id) {
                dev_info(&pf->pdev->dev, "Setting VLAN %d, QOS 0x%x on VF %d\n",
@@ -1978,6 +1986,10 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
                dev_err(&pf->pdev->dev, "Unable to update VF vsi context\n");
                goto error_pvid;
        }
+       /* The Port VLAN needs to be saved across resets the same as the
+        * default LAN MAC address.
+        */
+       vf->port_vlan_id = le16_to_cpu(vsi->info.pvid);
        ret = 0;
 
 error_pvid:
index d0b712c4bef389adf4f1031f33e2931dcc49f8a8..bf3384f0abcb2a64511385cb078ed721e0374c77 100644 (file)
@@ -82,6 +82,7 @@ struct i40e_vf {
 
        struct i40e_virtchnl_ether_addr default_lan_addr;
        struct i40e_virtchnl_ether_addr default_fcoe_addr;
+       u16 port_vlan_id;
 
        /* VSI indices - actual VSI pointers are maintained in the PF structure
         * When assigned, these will be non-zero, because VSI 0 is always