aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/igb/igb.h1
-rw-r--r--drivers/net/igb/igb_main.c39
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
4011static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) 4019static 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 }