|
@@ -117,6 +117,50 @@ static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
|
|
wrfl();
|
|
wrfl();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Due to a hw errata, if the host tries to configure the VFTA register
|
|
|
|
+ * while performing queries from the BMC or DMA, then the VFTA in some
|
|
|
|
+ * cases won't be written.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * igb_clear_vfta_i350 - Clear VLAN filter table
|
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
|
+ *
|
|
|
|
+ * Clears the register array which contains the VLAN filter table by
|
|
|
|
+ * setting all the values to 0.
|
|
|
|
+ **/
|
|
|
|
+void igb_clear_vfta_i350(struct e1000_hw *hw)
|
|
|
|
+{
|
|
|
|
+ u32 offset;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
|
|
|
|
+ for (i = 0; i < 10; i++)
|
|
|
|
+ array_wr32(E1000_VFTA, offset, 0);
|
|
|
|
+
|
|
|
|
+ wrfl();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * igb_write_vfta_i350 - Write value to VLAN filter table
|
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
|
+ * @offset: register offset in VLAN filter table
|
|
|
|
+ * @value: register value written to VLAN filter table
|
|
|
|
+ *
|
|
|
|
+ * Writes value at the given offset in the register array which stores
|
|
|
|
+ * the VLAN filter table.
|
|
|
|
+ **/
|
|
|
|
+void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < 10; i++)
|
|
|
|
+ array_wr32(E1000_VFTA, offset, value);
|
|
|
|
+
|
|
|
|
+ wrfl();
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* igb_init_rx_addrs - Initialize receive address's
|
|
* igb_init_rx_addrs - Initialize receive address's
|
|
* @hw: pointer to the HW structure
|
|
* @hw: pointer to the HW structure
|
|
@@ -155,9 +199,12 @@ 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 = array_rd32(E1000_VFTA, index);
|
|
|
|
|
|
+ u32 vfta;
|
|
|
|
+ struct igb_adapter *adapter = hw->back;
|
|
s32 ret_val = 0;
|
|
s32 ret_val = 0;
|
|
|
|
|
|
|
|
+ vfta = adapter->shadow_vfta[index];
|
|
|
|
+
|
|
/* bit was set/cleared before we started */
|
|
/* bit was set/cleared before we started */
|
|
if ((!!(vfta & mask)) == add) {
|
|
if ((!!(vfta & mask)) == add) {
|
|
ret_val = -E1000_ERR_CONFIG;
|
|
ret_val = -E1000_ERR_CONFIG;
|
|
@@ -167,8 +214,11 @@ s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
|
|
else
|
|
else
|
|
vfta &= ~mask;
|
|
vfta &= ~mask;
|
|
}
|
|
}
|
|
-
|
|
|
|
- igb_write_vfta(hw, index, vfta);
|
|
|
|
|
|
+ if (hw->mac.type == e1000_i350)
|
|
|
|
+ igb_write_vfta_i350(hw, index, vfta);
|
|
|
|
+ else
|
|
|
|
+ igb_write_vfta(hw, index, vfta);
|
|
|
|
+ adapter->shadow_vfta[index] = vfta;
|
|
|
|
|
|
return ret_val;
|
|
return ret_val;
|
|
}
|
|
}
|