mirror of https://gitee.com/openkylin/linux.git
ixgbe: change handling of multicast filters
In line with changes done by Alex Duyck regarding unicast filters, we now only set multicast filters when the interface is not in promiscuous mode for multicast packets. This also has an impact on the RAR usage such that SR-IOV has some RARs reserved for its own usage. Reported-by: Alex Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
a9b8943ee1
commit
b335e75bab
|
@ -3845,6 +3845,36 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
|
|||
ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_write_mc_addr_list - write multicast addresses to MTA
|
||||
* @netdev: network interface device structure
|
||||
*
|
||||
* Writes multicast address list to the MTA hash table.
|
||||
* Returns: -ENOMEM on failure
|
||||
* 0 on no addresses written
|
||||
* X on writing X addresses to MTA
|
||||
**/
|
||||
static int ixgbe_write_mc_addr_list(struct net_device *netdev)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = netdev_priv(netdev);
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
||||
if (!netif_running(netdev))
|
||||
return 0;
|
||||
|
||||
if (hw->mac.ops.update_mc_addr_list)
|
||||
hw->mac.ops.update_mc_addr_list(hw, netdev);
|
||||
else
|
||||
return -ENOMEM;
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
if (adapter->num_vfs)
|
||||
ixgbe_restore_vf_multicasts(adapter);
|
||||
#endif
|
||||
|
||||
return netdev_mc_count(netdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_write_uc_addr_list - write unicast addresses to RAR table
|
||||
* @netdev: network interface device structure
|
||||
|
@ -3908,7 +3938,6 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
|
|||
int count;
|
||||
|
||||
/* Check for Promiscuous and All Multicast modes */
|
||||
|
||||
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
|
||||
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
|
||||
|
||||
|
@ -3924,7 +3953,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
|
|||
if (netdev->flags & IFF_PROMISC) {
|
||||
hw->addr_ctrl.user_set_promisc = true;
|
||||
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
|
||||
vmolr |= (IXGBE_VMOLR_ROPE | IXGBE_VMOLR_MPE);
|
||||
vmolr |= IXGBE_VMOLR_MPE;
|
||||
/* Only disable hardware filter vlans in promiscuous mode
|
||||
* if SR-IOV and VMDQ are disabled - otherwise ensure
|
||||
* that hardware VLAN filters remain enabled.
|
||||
|
@ -3956,11 +3985,13 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
|
|||
* then we should just turn on promiscuous mode so
|
||||
* that we can at least receive multicast traffic
|
||||
*/
|
||||
hw->mac.ops.update_mc_addr_list(hw, netdev);
|
||||
vmolr |= IXGBE_VMOLR_ROMPE;
|
||||
|
||||
if (adapter->num_vfs)
|
||||
ixgbe_restore_vf_multicasts(adapter);
|
||||
count = ixgbe_write_mc_addr_list(netdev);
|
||||
if (count < 0) {
|
||||
fctrl |= IXGBE_FCTRL_MPE;
|
||||
vmolr |= IXGBE_VMOLR_MPE;
|
||||
} else if (count) {
|
||||
vmolr |= IXGBE_VMOLR_ROMPE;
|
||||
}
|
||||
|
||||
if (hw->mac.type != ixgbe_mac_82598EB) {
|
||||
vmolr |= IXGBE_READ_REG(hw, IXGBE_VMOLR(VMDQ_P(0))) &
|
||||
|
|
|
@ -327,6 +327,7 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
|
|||
u32 vector_bit;
|
||||
u32 vector_reg;
|
||||
u32 mta_reg;
|
||||
u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
|
||||
|
||||
/* only so many hash values supported */
|
||||
entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES);
|
||||
|
@ -353,10 +354,13 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
|
|||
mta_reg |= (1 << vector_bit);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
|
||||
}
|
||||
vmolr |= IXGBE_VMOLR_ROMPE;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
@ -382,6 +386,7 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
|
|||
u32 mta_reg;
|
||||
|
||||
for (i = 0; i < adapter->num_vfs; i++) {
|
||||
u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(i));
|
||||
vfinfo = &adapter->vfinfo[i];
|
||||
for (j = 0; j < vfinfo->num_vf_mc_hashes; j++) {
|
||||
hw->addr_ctrl.mta_in_use++;
|
||||
|
@ -391,11 +396,18 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
|
|||
mta_reg |= (1 << vector_bit);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
|
||||
}
|
||||
|
||||
if (vfinfo->num_vf_mc_hashes)
|
||||
vmolr |= IXGBE_VMOLR_ROMPE;
|
||||
else
|
||||
vmolr &= ~IXGBE_VMOLR_ROMPE;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VMOLR(i), vmolr);
|
||||
}
|
||||
|
||||
/* Restore any VF macvlans */
|
||||
ixgbe_restore_vf_macvlans(adapter);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
|
||||
u32 vf)
|
||||
|
@ -495,8 +507,7 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
|
|||
static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
|
||||
{
|
||||
u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
|
||||
vmolr |= (IXGBE_VMOLR_ROMPE |
|
||||
IXGBE_VMOLR_BAM);
|
||||
vmolr |= IXGBE_VMOLR_BAM;
|
||||
if (aupe)
|
||||
vmolr |= IXGBE_VMOLR_AUPE;
|
||||
else
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
*/
|
||||
#define IXGBE_MAX_VFS_DRV_LIMIT (IXGBE_MAX_VF_FUNCTIONS - 1)
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
|
||||
#endif
|
||||
void ixgbe_msg_task(struct ixgbe_adapter *adapter);
|
||||
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
|
||||
void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
|
||||
|
|
Loading…
Reference in New Issue