ixgbe: Add support for tracking the default user priority to SR-IOV
authorAlexander Duyck <alexander.h.duyck@intel.com>
Tue, 2 Oct 2012 00:17:03 +0000 (00:17 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 23 Oct 2012 04:14:32 +0000 (21:14 -0700)
It is necessary to track the default user priority in the PF so that we can
force it upon the VFs.  The motivation behind this is to keep the VFs from
getting access to user priorities meant for things like storage.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c

index ccb850500a9ae6ae681f62142533f3830202ecba..101e525e7fe3cc145657b6578b739801d1734ca9 100644 (file)
@@ -601,6 +601,8 @@ struct ixgbe_adapter {
 #ifdef CONFIG_DEBUG_FS
        struct dentry *ixgbe_dbg_adapter;
 #endif /*CONFIG_DEBUG_FS*/
+
+       u8 default_up;
 };
 
 struct ixgbe_fdir_filter {
index 3ef74f893c2e9362ee2c66a0024a30b0f4b57c93..35be7d38c58481491104e0633519c0ac01f8a247 100644 (file)
@@ -5460,6 +5460,23 @@ static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter)
        adapter->link_speed = link_speed;
 }
 
+static void ixgbe_update_default_up(struct ixgbe_adapter *adapter)
+{
+#ifdef CONFIG_IXGBE_DCB
+       struct net_device *netdev = adapter->netdev;
+       struct dcb_app app = {
+                             .selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE,
+                             .protocol = 0,
+                            };
+       u8 up = 0;
+
+       if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)
+               up = dcb_ieee_getapp_mask(netdev, &app);
+
+       adapter->default_up = (up > 1) ? (ffs(up) - 1) : 0;
+#endif
+}
+
 /**
  * ixgbe_watchdog_link_is_up - update netif_carrier status and
  *                             print link up message
@@ -5519,6 +5536,9 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
        netif_carrier_on(netdev);
        ixgbe_check_vf_rate_limit(adapter);
 
+       /* update the default user priority for VFs */
+       ixgbe_update_default_up(adapter);
+
        /* ping all the active vfs to let them know link has changed */
        ixgbe_ping_all_vfs(adapter);
 }
index f563625f1f49706196767ac044d7c51c6ac1135e..b330a1c6c4c61bd6b7f4081772c2df9a8cb0cef0 100644 (file)
@@ -431,35 +431,47 @@ static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
        IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
 }
 
-static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf)
+static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter,
+                           u16 vid, u16 qos, u32 vf)
 {
        struct ixgbe_hw *hw = &adapter->hw;
+       u32 vmvir = vid | (qos << VLAN_PRIO_SHIFT) | IXGBE_VMVIR_VLANA_DEFAULT;
 
-       if (vid)
-               IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf),
-                               (vid | IXGBE_VMVIR_VLANA_DEFAULT));
-       else
-               IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
+       IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), vmvir);
 }
 
+static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+
+       IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0);
+}
 static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
 {
        struct ixgbe_hw *hw = &adapter->hw;
+       struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
        int rar_entry = hw->mac.num_rar_entries - (vf + 1);
+       u8 num_tcs = netdev_get_num_tc(adapter->netdev);
+
+       /* add PF assigned VLAN or VLAN 0 */
+       ixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf);
 
        /* reset offloads to defaults */
-       if (adapter->vfinfo[vf].pf_vlan) {
-               ixgbe_set_vf_vlan(adapter, true,
-                                 adapter->vfinfo[vf].pf_vlan, vf);
-               ixgbe_set_vmvir(adapter,
-                               (adapter->vfinfo[vf].pf_vlan |
-                                (adapter->vfinfo[vf].pf_qos <<
-                                 VLAN_PRIO_SHIFT)), vf);
-               ixgbe_set_vmolr(hw, vf, false);
+       ixgbe_set_vmolr(hw, vf, !vfinfo->pf_vlan);
+
+       /* set outgoing tags for VFs */
+       if (!vfinfo->pf_vlan && !vfinfo->pf_qos && !num_tcs) {
+               ixgbe_clear_vmvir(adapter, vf);
        } else {
-               ixgbe_set_vf_vlan(adapter, true, 0, vf);
-               ixgbe_set_vmvir(adapter, 0, vf);
-               ixgbe_set_vmolr(hw, vf, true);
+               if (vfinfo->pf_qos || !num_tcs)
+                       ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
+                                       vfinfo->pf_qos, vf);
+               else
+                       ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
+                                       adapter->default_up, vf);
+
+               if (vfinfo->spoofchk_enabled)
+                       hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
        }
 
        /* reset multicast table array for vf */
@@ -661,8 +673,9 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
        int add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
        int vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);
        int err;
+       u8 tcs = netdev_get_num_tc(adapter->netdev);
 
-       if (adapter->vfinfo[vf].pf_vlan) {
+       if (adapter->vfinfo[vf].pf_vlan || tcs) {
                e_warn(drv,
                       "VF %d attempted to override administratively set VLAN configuration\n"
                       "Reload the VF driver to resume operations\n",
@@ -896,7 +909,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
                err = ixgbe_set_vf_vlan(adapter, true, vlan, vf);
                if (err)
                        goto out;
-               ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
+               ixgbe_set_vmvir(adapter, vlan, qos, vf);
                ixgbe_set_vmolr(hw, vf, false);
                if (adapter->vfinfo[vf].spoofchk_enabled)
                        hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
@@ -916,7 +929,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
        } else {
                err = ixgbe_set_vf_vlan(adapter, false,
                                        adapter->vfinfo[vf].pf_vlan, vf);
-               ixgbe_set_vmvir(adapter, vlan, vf);
+               ixgbe_clear_vmvir(adapter, vf);
                ixgbe_set_vmolr(hw, vf, true);
                hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
                if (adapter->vfinfo[vf].vlan_count)