[Intel-wired-lan] [PATCH] ixgbe: Fix packet loss when updating multicast table
Piotr Skajewski
piotrx.skajewski at intel.com
Thu Jan 10 11:29:01 UTC 2019
This change fixing 2 issues with:
- Packet loss when updating the MTA
- Multicast packets are received even after leaving the MC group
Signed-off-by: Piotr Skajewski <piotrx.skajewski at intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 4 ----
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 10 +++++-----
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 22 ++++++++--------------
4 files changed, 14 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 08d85e3..3f58a16 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -918,6 +918,7 @@ int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
#ifdef CONFIG_IXGBE_DCB
void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter);
#endif
+int ixgbe_write_mc_addr_list(struct net_device *netdev);
int ixgbe_setup_tc(struct net_device *dev, u8 tc);
void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32);
void ixgbe_do_reset(struct net_device *netdev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 0bd1294..ce7b2d8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -2075,10 +2075,6 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw,
hw->addr_ctrl.num_mc_addrs = netdev_mc_count(netdev);
hw->addr_ctrl.mta_in_use = 0;
- /* Clear mta_shadow */
- hw_dbg(hw, " Clearing MTA\n");
- memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
-
/* Update mta shadow */
netdev_for_each_mc_addr(ha, netdev) {
hw_dbg(hw, " Adding the multicast addresses:\n");
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index daff818..1899489 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -4695,7 +4695,7 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
* 0 on no addresses written
* X on writing X addresses to MTA
**/
-static int ixgbe_write_mc_addr_list(struct net_device *netdev)
+int ixgbe_write_mc_addr_list(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
@@ -4703,15 +4703,15 @@ static int ixgbe_write_mc_addr_list(struct net_device *netdev)
if (!netif_running(netdev))
return 0;
+#ifdef CONFIG_PCI_IOV
+ ixgbe_restore_vf_multicasts(adapter);
+#endif
+
if (hw->mac.ops.update_mc_addr_list)
hw->mac.ops.update_mc_addr_list(hw, netdev);
else
return -ENOMEM;
-#ifdef CONFIG_PCI_IOV
- ixgbe_restore_vf_multicasts(adapter);
-#endif
-
return netdev_mc_count(netdev);
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 345701a..97e0d88 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -364,9 +364,6 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
struct ixgbe_hw *hw = &adapter->hw;
int i;
- u32 vector_bit;
- u32 vector_reg;
- u32 mta_reg;
u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
/* only so many hash values supported */
@@ -387,16 +384,12 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
vfinfo->vf_mc_hashes[i] = hash_list[i];
}
- for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) {
- vector_reg = (vfinfo->vf_mc_hashes[i] >> 5) & 0x7F;
- vector_bit = vfinfo->vf_mc_hashes[i] & 0x1F;
- mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));
- mta_reg |= BIT(vector_bit);
- IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
- }
vmolr |= IXGBE_VMOLR_ROMPE;
IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
+ /* Sync up the PF and VF in the same MTA table */
+ ixgbe_write_mc_addr_list(adapter->netdev);
+
return 0;
}
@@ -408,7 +401,10 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
int i, j;
u32 vector_bit;
u32 vector_reg;
- u32 mta_reg;
+
+ /* Clear mta_shadow */
+ hw_dbg(hw, " Clearing MTA\n");
+ memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
for (i = 0; i < adapter->num_vfs; i++) {
u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(i));
@@ -417,9 +413,7 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
hw->addr_ctrl.mta_in_use++;
vector_reg = (vfinfo->vf_mc_hashes[j] >> 5) & 0x7F;
vector_bit = vfinfo->vf_mc_hashes[j] & 0x1F;
- mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));
- mta_reg |= BIT(vector_bit);
- IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
+ hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit);
}
if (vfinfo->num_vf_mc_hashes)
--
1.8.3.1
More information about the Intel-wired-lan
mailing list