igb: add PF to pool
Add Pf to pool if adding a VLVF register value and the VFTA bit is already set. This patch addresses the unlikely situation that the PF adds a vlan entry when the vlvf is full, and a vf later adds the vlan to the vlvf. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>hifive-unleashed-5.1
parent
a2cf8b6ce1
commit
cad6d05f56
|
@ -126,19 +126,26 @@ void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
|
||||||
* Sets or clears a bit in the VLAN filter table array based on VLAN id
|
* Sets or clears a bit in the VLAN filter table array based on VLAN id
|
||||||
* and if we are adding or removing the filter
|
* and if we are adding or removing the filter
|
||||||
**/
|
**/
|
||||||
void igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
|
s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
|
||||||
{
|
{
|
||||||
u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
|
u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
|
||||||
u32 mask = 1 < (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
|
u32 mask = 1 < (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
|
||||||
u32 vfta;
|
u32 vfta = array_rd32(E1000_VFTA, index);
|
||||||
|
s32 ret_val = 0;
|
||||||
|
|
||||||
vfta = array_rd32(E1000_VFTA, index);
|
/* bit was set/cleared before we started */
|
||||||
|
if ((!!(vfta & mask)) == add) {
|
||||||
|
ret_val = -E1000_ERR_CONFIG;
|
||||||
|
} else {
|
||||||
if (add)
|
if (add)
|
||||||
vfta |= mask;
|
vfta |= mask;
|
||||||
else
|
else
|
||||||
vfta &= ~mask;
|
vfta &= ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
igb_write_vfta(hw, index, vfta);
|
igb_write_vfta(hw, index, vfta);
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -58,7 +58,7 @@ s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
|
||||||
|
|
||||||
void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
|
void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
|
||||||
void igb_clear_vfta(struct e1000_hw *hw);
|
void igb_clear_vfta(struct e1000_hw *hw);
|
||||||
void igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
|
s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
|
||||||
void igb_config_collision_dist(struct e1000_hw *hw);
|
void igb_config_collision_dist(struct e1000_hw *hw);
|
||||||
void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
|
void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
|
||||||
void igb_put_hw_semaphore(struct e1000_hw *hw);
|
void igb_put_hw_semaphore(struct e1000_hw *hw);
|
||||||
|
|
|
@ -3895,10 +3895,15 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
|
||||||
|
|
||||||
/* if !enabled we need to set this up in vfta */
|
/* if !enabled we need to set this up in vfta */
|
||||||
if (!(reg & E1000_VLVF_VLANID_ENABLE)) {
|
if (!(reg & E1000_VLVF_VLANID_ENABLE)) {
|
||||||
/* add VID to filter table */
|
/* add VID to filter table, if bit already set
|
||||||
igb_vfta_set(hw, vid, true);
|
* PF must have added it outside of table */
|
||||||
|
if (igb_vfta_set(hw, vid, true))
|
||||||
|
reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT +
|
||||||
|
adapter->vfs_allocated_count);
|
||||||
reg |= E1000_VLVF_VLANID_ENABLE;
|
reg |= E1000_VLVF_VLANID_ENABLE;
|
||||||
}
|
}
|
||||||
|
reg &= ~E1000_VLVF_VLANID_MASK;
|
||||||
|
reg |= vid;
|
||||||
|
|
||||||
wr32(E1000_VLVF(i), reg);
|
wr32(E1000_VLVF(i), reg);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue