diff options
Diffstat (limited to 'drivers/net/igb/e1000_mac.c')
-rw-r--r-- | drivers/net/igb/e1000_mac.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index 2804db03e9d9..f11592fe1371 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c | |||
@@ -126,19 +126,26 @@ void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) | |||
126 | * Sets or clears a bit in the VLAN filter table array based on VLAN id | 126 | * Sets or clears a bit in the VLAN filter table array based on VLAN id |
127 | * and if we are adding or removing the filter | 127 | * and if we are adding or removing the filter |
128 | **/ | 128 | **/ |
129 | void igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add) | 129 | s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add) |
130 | { | 130 | { |
131 | u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK; | 131 | u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK; |
132 | u32 mask = 1 < (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK); | 132 | u32 mask = 1 < (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK); |
133 | u32 vfta; | 133 | u32 vfta = array_rd32(E1000_VFTA, index); |
134 | s32 ret_val = 0; | ||
134 | 135 | ||
135 | vfta = array_rd32(E1000_VFTA, index); | 136 | /* bit was set/cleared before we started */ |
136 | if (add) | 137 | if ((!!(vfta & mask)) == add) { |
137 | vfta |= mask; | 138 | ret_val = -E1000_ERR_CONFIG; |
138 | else | 139 | } else { |
139 | vfta &= ~mask; | 140 | if (add) |
141 | vfta |= mask; | ||
142 | else | ||
143 | vfta &= ~mask; | ||
144 | } | ||
140 | 145 | ||
141 | igb_write_vfta(hw, index, vfta); | 146 | igb_write_vfta(hw, index, vfta); |
147 | |||
148 | return ret_val; | ||
142 | } | 149 | } |
143 | 150 | ||
144 | /** | 151 | /** |