|
@@ -8718,7 +8718,8 @@ static void igb_rar_set_index(struct igb_adapter *adapter, u32 index)
|
|
|
|
|
|
/* Indicate to hardware the Address is Valid. */
|
|
|
if (adapter->mac_table[index].state & IGB_MAC_STATE_IN_USE) {
|
|
|
- rar_high |= E1000_RAH_AV;
|
|
|
+ if (is_valid_ether_addr(addr))
|
|
|
+ rar_high |= E1000_RAH_AV;
|
|
|
|
|
|
if (hw->mac.type == e1000_82575)
|
|
|
rar_high |= E1000_RAH_POOL_1 *
|
|
@@ -8756,17 +8757,36 @@ static int igb_set_vf_mac(struct igb_adapter *adapter,
|
|
|
static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
|
|
|
{
|
|
|
struct igb_adapter *adapter = netdev_priv(netdev);
|
|
|
- if (!is_valid_ether_addr(mac) || (vf >= adapter->vfs_allocated_count))
|
|
|
+
|
|
|
+ if (vf >= adapter->vfs_allocated_count)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /* Setting the VF MAC to 0 reverts the IGB_VF_FLAG_PF_SET_MAC
|
|
|
+ * flag and allows to overwrite the MAC via VF netdev. This
|
|
|
+ * is necessary to allow libvirt a way to restore the original
|
|
|
+ * MAC after unbinding vfio-pci and reloading igbvf after shutting
|
|
|
+ * down a VM.
|
|
|
+ */
|
|
|
+ if (is_zero_ether_addr(mac)) {
|
|
|
+ adapter->vf_data[vf].flags &= ~IGB_VF_FLAG_PF_SET_MAC;
|
|
|
+ dev_info(&adapter->pdev->dev,
|
|
|
+ "remove administratively set MAC on VF %d\n",
|
|
|
+ vf);
|
|
|
+ } else if (is_valid_ether_addr(mac)) {
|
|
|
+ adapter->vf_data[vf].flags |= IGB_VF_FLAG_PF_SET_MAC;
|
|
|
+ dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n",
|
|
|
+ mac, vf);
|
|
|
+ dev_info(&adapter->pdev->dev,
|
|
|
+ "Reload the VF driver to make this change effective.");
|
|
|
+ /* Generate additional warning if PF is down */
|
|
|
+ if (test_bit(__IGB_DOWN, &adapter->state)) {
|
|
|
+ dev_warn(&adapter->pdev->dev,
|
|
|
+ "The VF MAC address has been set, but the PF device is not up.\n");
|
|
|
+ dev_warn(&adapter->pdev->dev,
|
|
|
+ "Bring the PF device up before attempting to use the VF device.\n");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
return -EINVAL;
|
|
|
- adapter->vf_data[vf].flags |= IGB_VF_FLAG_PF_SET_MAC;
|
|
|
- dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf);
|
|
|
- dev_info(&adapter->pdev->dev,
|
|
|
- "Reload the VF driver to make this change effective.");
|
|
|
- if (test_bit(__IGB_DOWN, &adapter->state)) {
|
|
|
- dev_warn(&adapter->pdev->dev,
|
|
|
- "The VF MAC address has been set, but the PF device is not up.\n");
|
|
|
- dev_warn(&adapter->pdev->dev,
|
|
|
- "Bring the PF device up before attempting to use the VF device.\n");
|
|
|
}
|
|
|
return igb_set_vf_mac(adapter, vf, mac);
|
|
|
}
|