From: Alexander Duyck <aduyck@mirantis.com>
To: intel-wired-lan@osuosl.org
Subject: [Intel-wired-lan] [next PATCH 02/11] igb: Refactor VFTA configuration
Date: Wed, 06 Jan 2016 23:10:30 -0800 [thread overview]
Message-ID: <20160107071030.13648.82290.stgit@localhost.localdomain> (raw)
In-Reply-To: <20160107070850.13648.21033.stgit@localhost.localdomain>
This patch starts the clean-up process on the VFTA configuration.
Specifically in this patch I attempt to address and simplify several items
while also updating the code to bring it more inline with what is already
in ixgbe.
Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
---
drivers/net/ethernet/intel/igb/e1000_82575.c | 37 ++++++++-
drivers/net/ethernet/intel/igb/e1000_hw.h | 2 -
drivers/net/ethernet/intel/igb/e1000_mac.c | 102 ++++++++------------------
drivers/net/ethernet/intel/igb/e1000_mac.h | 2 -
4 files changed, 67 insertions(+), 76 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index adb33e2a0137..fff50523b440 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -34,6 +34,7 @@
#include "e1000_mac.h"
#include "e1000_82575.h"
#include "e1000_i210.h"
+#include "igb.h"
static s32 igb_get_invariants_82575(struct e1000_hw *);
static s32 igb_acquire_phy_82575(struct e1000_hw *);
@@ -71,6 +72,32 @@ static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw);
static const u16 e1000_82580_rxpbs_table[] = {
36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
+/* 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_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.
+ **/
+static void igb_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value)
+{
+ struct igb_adapter *adapter = hw->back;
+ int i;
+
+ for (i = 10; i--;)
+ array_wr32(E1000_VFTA, offset, value);
+
+ wrfl();
+ adapter->shadow_vfta[offset] = value;
+}
+
/**
* igb_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
* @hw: pointer to the HW structure
@@ -429,6 +456,11 @@ static s32 igb_init_mac_params_82575(struct e1000_hw *hw)
mac->ops.release_swfw_sync = igb_release_swfw_sync_82575;
}
+ if ((hw->mac.type == e1000_i350) || (hw->mac.type == e1000_i354))
+ mac->ops.write_vfta = igb_write_vfta_i350;
+ else
+ mac->ops.write_vfta = igb_write_vfta;
+
/* Set if part includes ASF firmware */
mac->asf_firmware_present = true;
/* Set if manageability features are enabled. */
@@ -1517,10 +1549,7 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
/* Disabling VLAN filtering */
hw_dbg("Initializing the IEEE VLAN\n");
- if ((hw->mac.type == e1000_i350) || (hw->mac.type == e1000_i354))
- igb_clear_vfta_i350(hw);
- else
- igb_clear_vfta(hw);
+ igb_clear_vfta(hw);
/* Setup the receive address */
igb_init_rx_addrs(hw, rar_count);
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index 4034207eb5cc..f0c416e21d2c 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -325,7 +325,7 @@ struct e1000_mac_operations {
s32 (*get_thermal_sensor_data)(struct e1000_hw *);
s32 (*init_thermal_sensor_thresh)(struct e1000_hw *);
#endif
-
+ void (*write_vfta)(struct e1000_hw *, u32, u32);
};
struct e1000_phy_operations {
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c
index 2a88595f956c..97f6fae48d1d 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -92,10 +92,8 @@ void igb_clear_vfta(struct e1000_hw *hw)
{
u32 offset;
- for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
- array_wr32(E1000_VFTA, offset, 0);
- wrfl();
- }
+ for (offset = E1000_VLAN_FILTER_TBL_SIZE; offset--;)
+ hw->mac.ops.write_vfta(hw, offset, 0);
}
/**
@@ -107,54 +105,14 @@ void igb_clear_vfta(struct e1000_hw *hw)
* Writes value at the given offset in the register array which stores
* the VLAN filter table.
**/
-static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
+void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
{
+ struct igb_adapter *adapter = hw->back;
+
array_wr32(E1000_VFTA, offset, value);
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@the given offset in the register array which stores
- * the VLAN filter table.
- **/
-static 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();
+ adapter->shadow_vfta[offset] = value;
}
/**
@@ -185,38 +143,42 @@ void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
/**
* igb_vfta_set - enable or disable vlan in VLAN filter table
* @hw: pointer to the HW structure
- * @vid: VLAN id to add or remove
- * @add: if true add filter, if false remove
+ * @vlan: VLAN id to add or remove
+ * @vlan_on: if true add filter, if false remove
*
* Sets or clears a bit in the VLAN filter table array based on VLAN id
* and if we are adding or removing the filter
**/
-s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
+s32 igb_vfta_set(struct e1000_hw *hw, u32 vlan, bool vlan_on)
{
- u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
- u32 mask = 1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
- u32 vfta;
struct igb_adapter *adapter = hw->back;
- s32 ret_val = 0;
+ u32 regidx, vfta_delta, vfta;
+
+ if (vlan > 4095)
+ return E1000_ERR_PARAM;
+
+ /* Part 1
+ * The VFTA is a bitstring made up of 128 32-bit registers
+ * that enable the particular VLAN id, much like the MTA:
+ * bits[11-5]: which register
+ * bits[4-0]: which bit in the register
+ */
+ regidx = vlan / 32;
+ vfta_delta = 1 << (vlan % 32);
+ vfta = adapter->shadow_vfta[regidx];
- vfta = adapter->shadow_vfta[index];
+ /* vfta_delta represents the difference between the current value
+ * of vfta and the value we want in the register. Since the diff
+ * is an XOR mask we can just update vfta using an XOR.
+ */
+ vfta_delta &= vlan_on ? ~vfta : vfta;
+ vfta ^= vfta_delta;
/* bit was set/cleared before we started */
- if ((!!(vfta & mask)) == add) {
- ret_val = -E1000_ERR_CONFIG;
- } else {
- if (add)
- vfta |= mask;
- else
- vfta &= ~mask;
- }
- if ((hw->mac.type == e1000_i350) || (hw->mac.type == e1000_i354))
- igb_write_vfta_i350(hw, index, vfta);
- else
- igb_write_vfta(hw, index, vfta);
- adapter->shadow_vfta[index] = vfta;
+ if (vfta_delta)
+ hw->mac.ops.write_vfta(hw, regidx, vfta);
- return ret_val;
+ return 0;
}
/**
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h
index ea24961b0d70..4fbb953012d0 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.h
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.h
@@ -56,7 +56,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_vfta(struct e1000_hw *hw);
-void igb_clear_vfta_i350(struct e1000_hw *hw);
+void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
void igb_config_collision_dist(struct e1000_hw *hw);
void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
next prev parent reply other threads:[~2016-01-07 7:10 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-07 7:10 [Intel-wired-lan] [next PATCH 00/11] Enable use of PF for switch or bridge when using SR-IOV Alexander Duyck
2016-01-07 7:10 ` [Intel-wired-lan] [next PATCH 01/11] igb: clean up code for setting MAC address Alexander Duyck
2016-01-14 3:06 ` Brown, Aaron F
2016-01-07 7:10 ` Alexander Duyck [this message]
2016-01-14 3:09 ` [Intel-wired-lan] [next PATCH 02/11] igb: Refactor VFTA configuration Brown, Aaron F
2016-01-07 7:10 ` [Intel-wired-lan] [next PATCH 03/11] igb: Allow asymmetric configuration of MTU versus Rx frame size Alexander Duyck
2016-01-12 18:03 ` Hisashi T Fujinaka
2016-01-12 21:34 ` Alexander Duyck
2016-01-12 23:13 ` Hisashi T Fujinaka
2016-01-14 3:07 ` Brown, Aaron F
2016-01-07 7:10 ` [Intel-wired-lan] [next PATCH 04/11] igb: Do not factor VLANs into RLPML calculation Alexander Duyck
2016-01-14 3:10 ` Brown, Aaron F
2016-01-07 7:10 ` [Intel-wired-lan] [next PATCH 05/11] igb: Always enable VLAN 0 even if 8021q is not loaded Alexander Duyck
2016-01-14 3:11 ` Brown, Aaron F
2016-01-07 7:11 ` [Intel-wired-lan] [next PATCH 06/11] igb: Merge VLVF configuration into igb_vfta_set Alexander Duyck
2016-01-14 3:12 ` Brown, Aaron F
2016-01-07 7:11 ` [Intel-wired-lan] [next PATCH 07/11] igb: Clean-up configuration of VF port VLANs Alexander Duyck
2016-01-14 3:13 ` Brown, Aaron F
2016-01-07 7:11 ` [Intel-wired-lan] [next PATCH 08/11] igb: Add support for VLAN promiscuous with SR-IOV and NTUPLE Alexander Duyck
2016-01-14 3:14 ` Brown, Aaron F
2016-01-07 7:11 ` [Intel-wired-lan] [next PATCH 09/11] igb: Drop unnecessary checks in transmit path Alexander Duyck
2016-01-14 3:15 ` Brown, Aaron F
2016-01-07 7:11 ` [Intel-wired-lan] [next PATCH 10/11] igb: Enable use of "bridge fdb add" to set unicast table entries Alexander Duyck
2016-01-14 3:16 ` Brown, Aaron F
2016-01-07 7:11 ` [Intel-wired-lan] [next PATCH 11/11] igb: Add workaround for VLAN tag stripping on 82576 Alexander Duyck
2016-01-14 3:17 ` Brown, Aaron F
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160107071030.13648.82290.stgit@localhost.localdomain \
--to=aduyck@mirantis.com \
--cc=intel-wired-lan@osuosl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox