]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
ixgbe: consolidate the configuration of spoof checking
[mirror_ubuntu-bionic-kernel.git] / drivers / net / ethernet / intel / ixgbe / ixgbe_sriov.c
index 8025a3f93598069c7b03c34cf00463cf33111117..cc635ced15d618c4a880660a5afb14db92a48a93 100644 (file)
@@ -589,40 +589,40 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf)
 static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
 {
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 i;
+       u32 vlvfb_mask, pool_mask, i;
+
+       /* create mask for VF and other pools */
+       pool_mask = ~(1 << (VMDQ_P(0) % 32));
+       vlvfb_mask = 1 << (vf % 32);
 
        /* post increment loop, covers VLVF_ENTRIES - 1 to 0 */
        for (i = IXGBE_VLVF_ENTRIES; i--;) {
                u32 bits[2], vlvfb, vid, vfta, vlvf;
                u32 word = i * 2 + vf / 32;
-               u32 mask = 1 << (vf % 32);
+               u32 mask;
 
                vlvfb = IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
 
                /* if our bit isn't set we can skip it */
-               if (!(vlvfb & mask))
+               if (!(vlvfb & vlvfb_mask))
                        continue;
 
                /* clear our bit from vlvfb */
-               vlvfb ^= mask;
+               vlvfb ^= vlvfb_mask;
 
                /* create 64b mask to chedk to see if we should clear VLVF */
                bits[word % 2] = vlvfb;
                bits[~word % 2] = IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1));
 
-               /* if promisc is enabled, PF will be present, leave VFTA */
-               if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) {
-                       bits[VMDQ_P(0) / 32] &= ~(1 << (VMDQ_P(0) % 32));
-
-                       if (bits[0] || bits[1])
-                               goto update_vlvfb;
-                       goto update_vlvf;
-               }
-
                /* if other pools are present, just remove ourselves */
-               if (bits[0] || bits[1])
+               if (bits[(VMDQ_P(0) / 32) ^ 1] ||
+                   (bits[VMDQ_P(0) / 32] & pool_mask))
                        goto update_vlvfb;
 
+               /* if PF is present, leave VFTA */
+               if (bits[0] || bits[1])
+                       goto update_vlvf;
+
                /* if we cannot determine VLAN just remove ourselves */
                vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
                if (!vlvf)
@@ -638,6 +638,9 @@ static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
 update_vlvf:
                /* clear POOL selection enable */
                IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0);
+
+               if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
+                       vlvfb = 0;
 update_vlvfb:
                /* clear pool bits */
                IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb);
@@ -887,7 +890,7 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
                return -1;
        }
 
-       if (adapter->vfinfo[vf].pf_set_mac &&
+       if (adapter->vfinfo[vf].pf_set_mac && !adapter->vfinfo[vf].trusted &&
            !ether_addr_equal(adapter->vfinfo[vf].vf_mac_addresses, new_mac)) {
                e_warn(drv,
                       "VF %d attempted to override administratively set MAC address\n"
@@ -961,8 +964,11 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,
                 * If the VF is allowed to set MAC filters then turn off
                 * anti-spoofing to avoid false positives.
                 */
-               if (adapter->vfinfo[vf].spoofchk_enabled)
-                       ixgbe_ndo_set_vf_spoofchk(adapter->netdev, vf, false);
+               if (adapter->vfinfo[vf].spoofchk_enabled) {
+                       struct ixgbe_hw *hw = &adapter->hw;
+
+                       hw->mac.ops.set_mac_anti_spoofing(hw, false, vf);
+               }
        }
 
        err = ixgbe_set_vf_macvlan(adapter, vf, index, new_mac);
@@ -1395,7 +1401,7 @@ out:
        return err;
 }
 
-static int ixgbe_link_mbps(struct ixgbe_adapter *adapter)
+int ixgbe_link_mbps(struct ixgbe_adapter *adapter)
 {
        switch (adapter->link_speed) {
        case IXGBE_LINK_SPEED_100_FULL:
@@ -1522,27 +1528,35 @@ int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
 int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       int vf_target_reg = vf >> 3;
-       int vf_target_shift = vf % 8;
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 regval;
 
        if (vf >= adapter->num_vfs)
                return -EINVAL;
 
        adapter->vfinfo[vf].spoofchk_enabled = setting;
 
-       regval = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
-       regval &= ~(1 << vf_target_shift);
-       regval |= (setting << vf_target_shift);
-       IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), regval);
-
-       if (adapter->vfinfo[vf].vlan_count) {
-               vf_target_shift += IXGBE_SPOOF_VLANAS_SHIFT;
-               regval = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
-               regval &= ~(1 << vf_target_shift);
-               regval |= (setting << vf_target_shift);
-               IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), regval);
+       /* configure MAC spoofing */
+       hw->mac.ops.set_mac_anti_spoofing(hw, setting, vf);
+
+       /* configure VLAN spoofing */
+       if (adapter->vfinfo[vf].vlan_count)
+               hw->mac.ops.set_vlan_anti_spoofing(hw, setting, vf);
+
+       /* Ensure LLDP and FC is set for Ethertype Antispoofing if we will be
+        * calling set_ethertype_anti_spoofing for each VF in loop below
+        */
+       if (hw->mac.ops.set_ethertype_anti_spoofing) {
+               IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_LLDP),
+                               (IXGBE_ETQF_FILTER_EN    |
+                                IXGBE_ETQF_TX_ANTISPOOF |
+                                IXGBE_ETH_P_LLDP));
+
+               IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FC),
+                               (IXGBE_ETQF_FILTER_EN |
+                                IXGBE_ETQF_TX_ANTISPOOF |
+                                ETH_P_PAUSE));
+
+               hw->mac.ops.set_ethertype_anti_spoofing(hw, setting, vf);
        }
 
        return 0;