diff options
-rw-r--r-- | drivers/net/igb/igb.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 39 |
2 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index b2c98dea9eed..7126fea26fec 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h | |||
@@ -70,6 +70,7 @@ struct vf_data_storage { | |||
70 | unsigned char vf_mac_addresses[ETH_ALEN]; | 70 | unsigned char vf_mac_addresses[ETH_ALEN]; |
71 | u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES]; | 71 | u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES]; |
72 | u16 num_vf_mc_hashes; | 72 | u16 num_vf_mc_hashes; |
73 | u16 vlans_enabled; | ||
73 | bool clear_to_send; | 74 | bool clear_to_send; |
74 | }; | 75 | }; |
75 | 76 | ||
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 1d03fcb0bd6c..90b0b1b91730 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -154,6 +154,12 @@ static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size, | |||
154 | struct e1000_hw *hw = &adapter->hw; | 154 | struct e1000_hw *hw = &adapter->hw; |
155 | u32 vmolr; | 155 | u32 vmolr; |
156 | 156 | ||
157 | /* if it isn't the PF check to see if VFs are enabled and | ||
158 | * increase the size to support vlan tags */ | ||
159 | if (vfn < adapter->vfs_allocated_count && | ||
160 | adapter->vf_data[vfn].vlans_enabled) | ||
161 | size += VLAN_TAG_SIZE; | ||
162 | |||
157 | vmolr = rd32(E1000_VMOLR(vfn)); | 163 | vmolr = rd32(E1000_VMOLR(vfn)); |
158 | vmolr &= ~E1000_VMOLR_RLPML_MASK; | 164 | vmolr &= ~E1000_VMOLR_RLPML_MASK; |
159 | vmolr |= size | E1000_VMOLR_LPE; | 165 | vmolr |= size | E1000_VMOLR_LPE; |
@@ -4006,6 +4012,8 @@ static void igb_clear_vf_vfta(struct igb_adapter *adapter, u32 vf) | |||
4006 | 4012 | ||
4007 | wr32(E1000_VLVF(i), reg); | 4013 | wr32(E1000_VLVF(i), reg); |
4008 | } | 4014 | } |
4015 | |||
4016 | adapter->vf_data[vf].vlans_enabled = 0; | ||
4009 | } | 4017 | } |
4010 | 4018 | ||
4011 | static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) | 4019 | static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) |
@@ -4054,6 +4062,22 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) | |||
4054 | reg |= vid; | 4062 | reg |= vid; |
4055 | 4063 | ||
4056 | wr32(E1000_VLVF(i), reg); | 4064 | wr32(E1000_VLVF(i), reg); |
4065 | |||
4066 | /* do not modify RLPML for PF devices */ | ||
4067 | if (vf >= adapter->vfs_allocated_count) | ||
4068 | return 0; | ||
4069 | |||
4070 | if (!adapter->vf_data[vf].vlans_enabled) { | ||
4071 | u32 size; | ||
4072 | reg = rd32(E1000_VMOLR(vf)); | ||
4073 | size = reg & E1000_VMOLR_RLPML_MASK; | ||
4074 | size += 4; | ||
4075 | reg &= ~E1000_VMOLR_RLPML_MASK; | ||
4076 | reg |= size; | ||
4077 | wr32(E1000_VMOLR(vf), reg); | ||
4078 | } | ||
4079 | adapter->vf_data[vf].vlans_enabled++; | ||
4080 | |||
4057 | return 0; | 4081 | return 0; |
4058 | } | 4082 | } |
4059 | } else { | 4083 | } else { |
@@ -4066,6 +4090,21 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) | |||
4066 | igb_vfta_set(hw, vid, false); | 4090 | igb_vfta_set(hw, vid, false); |
4067 | } | 4091 | } |
4068 | wr32(E1000_VLVF(i), reg); | 4092 | wr32(E1000_VLVF(i), reg); |
4093 | |||
4094 | /* do not modify RLPML for PF devices */ | ||
4095 | if (vf >= adapter->vfs_allocated_count) | ||
4096 | return 0; | ||
4097 | |||
4098 | adapter->vf_data[vf].vlans_enabled--; | ||
4099 | if (!adapter->vf_data[vf].vlans_enabled) { | ||
4100 | u32 size; | ||
4101 | reg = rd32(E1000_VMOLR(vf)); | ||
4102 | size = reg & E1000_VMOLR_RLPML_MASK; | ||
4103 | size -= 4; | ||
4104 | reg &= ~E1000_VMOLR_RLPML_MASK; | ||
4105 | reg |= size; | ||
4106 | wr32(E1000_VMOLR(vf), reg); | ||
4107 | } | ||
4069 | return 0; | 4108 | return 0; |
4070 | } | 4109 | } |
4071 | } | 4110 | } |