@@ -153,6 +153,7 @@ struct vf_data_storage {
u16 vlan_count;
u8 spoofchk_enabled;
bool rss_query_enabled;
+ u8 mc_promisc_allowed;
unsigned int vf_api;
};
@@ -3662,6 +3662,10 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
/* Enable/Disable RSS query feature */
ixgbe_ndo_set_vf_rss_query_en(adapter->netdev, i,
adapter->vfinfo[i].rss_query_enabled);
+
+ /* Reconfigure multicast promiscuous mode */
+ ixgbe_ndo_set_vf_mc_promisc(adapter->netdev, i,
+ adapter->vfinfo[i].mc_promisc_allowed);
}
}
@@ -8165,6 +8169,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_vf_rate = ixgbe_ndo_set_vf_bw,
.ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk,
.ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en,
+ .ndo_set_vf_mc_promisc = ixgbe_ndo_set_vf_mc_promisc,
.ndo_get_vf_config = ixgbe_ndo_get_vf_config,
.ndo_get_stats64 = ixgbe_get_stats64,
#ifdef CONFIG_IXGBE_DCB
@@ -117,8 +117,11 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
*/
adapter->vfinfo[i].rss_query_enabled = 0;
- /* Turn multicast promiscuous mode off for all VFs */
+ /* Disallow VF multicast promiscuous capability
+ * and turn it off for all VFs
+ */
adapter->vfinfo[i].mc_promisc = false;
+ adapter->vfinfo[i].mc_promisc_allowed = false;
}
return 0;
@@ -1068,7 +1071,7 @@ static int ixgbe_set_vf_mc_promisc(struct ixgbe_adapter *adapter,
adapter->vfinfo[vf].mc_promisc = enable;
- if (enable)
+ if (enable && adapter->vfinfo[vf].mc_promisc_allowed)
return ixgbe_enable_vf_mc_promisc(adapter, vf);
else
return ixgbe_disable_vf_mc_promisc(adapter, vf);
@@ -1492,6 +1495,30 @@ int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,
return 0;
}
+int ixgbe_ndo_set_vf_mc_promisc(struct net_device *netdev, int vf, bool setting)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ if (vf >= adapter->num_vfs)
+ return -EINVAL;
+
+ /* nothing to do */
+ if (adapter->vfinfo[vf].mc_promisc_allowed == setting)
+ return 0;
+
+ adapter->vfinfo[vf].mc_promisc_allowed = setting;
+
+ /* if VF requests multicast promiscuous */
+ if (adapter->vfinfo[vf].mc_promisc) {
+ if (setting)
+ ixgbe_enable_vf_mc_promisc(adapter, vf);
+ else
+ ixgbe_disable_vf_mc_promisc(adapter, vf);
+ }
+
+ return 0;
+}
+
int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi)
{
@@ -1506,5 +1533,6 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
ivi->qos = adapter->vfinfo[vf].pf_qos;
ivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled;
ivi->rss_query_en = adapter->vfinfo[vf].rss_query_enabled;
+ ivi->mc_promisc = adapter->vfinfo[vf].mc_promisc_allowed;
return 0;
}
@@ -49,6 +49,8 @@ int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting);
int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,
bool setting);
+int ixgbe_ndo_set_vf_mc_promisc(struct net_device *netdev,
+ int vf, bool setting);
int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi);
void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);