diff options
Diffstat (limited to 'drivers/net/hyperv/netvsc_drv.c')
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 8f8ed332042..8e23c084c4a 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -341,6 +341,34 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) return 0; } + +static int netvsc_set_mac_addr(struct net_device *ndev, void *p) +{ + struct net_device_context *ndevctx = netdev_priv(ndev); + struct hv_device *hdev = ndevctx->device_ctx; + struct sockaddr *addr = p; + char save_adr[14]; + unsigned char save_aatype; + int err; + + memcpy(save_adr, ndev->dev_addr, ETH_ALEN); + save_aatype = ndev->addr_assign_type; + + err = eth_mac_addr(ndev, p); + if (err != 0) + return err; + + err = rndis_filter_set_device_mac(hdev, addr->sa_data); + if (err != 0) { + /* roll back to saved MAC */ + memcpy(ndev->dev_addr, save_adr, ETH_ALEN); + ndev->addr_assign_type = save_aatype; + } + + return err; +} + + static const struct ethtool_ops ethtool_ops = { .get_drvinfo = netvsc_get_drvinfo, .get_link = ethtool_op_get_link, @@ -353,7 +381,7 @@ static const struct net_device_ops device_ops = { .ndo_set_rx_mode = netvsc_set_multicast_list, .ndo_change_mtu = netvsc_change_mtu, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = netvsc_set_mac_addr, }; /* |