i40evf: Change a VF mac without reloading the VF driver
authorPaweł Jabłoński <pawel.jablonski@intel.com>
Mon, 20 Aug 2018 15:12:26 +0000 (08:12 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 30 Aug 2018 20:53:03 +0000 (13:53 -0700)
Add possibility to change a VF mac address from host side
without reloading the VF driver on the guest side. Without
this patch it is not possible to change the VF mac because
executing i40evf_virtchnl_completion function with
VIRTCHNL_OP_GET_VF_RESOURCES opcode resets the VF mac
address to previous value.

Signed-off-by: Paweł Jabłoński <pawel.jablonski@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c

index c6d24eaede184fdd9ad2fde19724af1b9406b9da..f56c645588f33117ac7be7fe0613eaa0868a668b 100644 (file)
@@ -2458,7 +2458,7 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
                    !is_multicast_ether_addr(addr) && vf->pf_set_mac &&
                    !ether_addr_equal(addr, vf->default_lan_addr.addr)) {
                        dev_err(&pf->pdev->dev,
-                               "VF attempting to override administratively set MAC address, reload the VF driver to resume normal operation\n");
+                               "VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n");
                        return -EPERM;
                }
        }
@@ -3873,9 +3873,11 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
                         mac, vf_id);
        }
 
-       /* Force the VF driver stop so it has to reload with new MAC address */
+       /* Force the VF interface down so it has to bring up with new MAC
+        * address
+        */
        i40e_vc_disable_vf(vf);
-       dev_info(&pf->pdev->dev, "Reload the VF driver to make this change effective.\n");
+       dev_info(&pf->pdev->dev, "Bring down and up the VF interface to make this change effective.\n");
 
 error_param:
        return ret;
index 565677de5ba376184d5acbe32644f13207d2767e..79b7be83b5c3ef75a50c4ca6a43d685476641be8 100644 (file)
@@ -1330,8 +1330,15 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
                          sizeof(struct virtchnl_vsi_resource);
                memcpy(adapter->vf_res, msg, min(msglen, len));
                i40e_vf_parse_hw_config(&adapter->hw, adapter->vf_res);
-               /* restore current mac address */
-               ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
+               if (is_zero_ether_addr(adapter->hw.mac.addr)) {
+                       /* restore current mac address */
+                       ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
+               } else {
+                       /* refresh current mac address if changed */
+                       ether_addr_copy(netdev->dev_addr, adapter->hw.mac.addr);
+                       ether_addr_copy(netdev->perm_addr,
+                                       adapter->hw.mac.addr);
+               }
                i40evf_process_config(adapter);
                }
                break;