summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/sfc/efx.c
diff options
context:
space:
mode:
authorShradha Shah <sshah@solarflare.com>2015-05-20 11:09:30 +0100
committerDavid S. Miller <davem@davemloft.net>2015-05-21 18:43:53 -0400
commitcfc77c2fbadf5b806fea2e35738c7437fc62f522 (patch)
treec4d96fa883fb33f07b9ecfb844bb8dc4ad030112 /drivers/net/ethernet/sfc/efx.c
parent88a37de674f8a7c7622bb00d78437153b31e3797 (diff)
sfc: save old MAC address in case sriov_mac_address_changed fails
Otherwise the PF and VF can disagree on the VF's MAC address and this leads to strange behaviour, up to and including kernel panics. Signed-off-by: Shradha Shah <sshah@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/sfc/efx.c')
-rw-r--r--drivers/net/ethernet/sfc/efx.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 0f127a01b5e8..864c33789b8f 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -2196,6 +2196,8 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
struct efx_nic *efx = netdev_priv(net_dev);
struct sockaddr *addr = data;
u8 *new_addr = addr->sa_data;
+ u8 old_addr[6];
+ int rc;
if (!is_valid_ether_addr(new_addr)) {
netif_err(efx, drv, efx->net_dev,
@@ -2204,9 +2206,16 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
return -EADDRNOTAVAIL;
}
+ /* save old address */
+ ether_addr_copy(old_addr, net_dev->dev_addr);
ether_addr_copy(net_dev->dev_addr, new_addr);
- if (efx->type->sriov_mac_address_changed)
- efx->type->sriov_mac_address_changed(efx);
+ if (efx->type->sriov_mac_address_changed) {
+ rc = efx->type->sriov_mac_address_changed(efx);
+ if (rc) {
+ ether_addr_copy(net_dev->dev_addr, old_addr);
+ return rc;
+ }
+ }
/* Reconfigure the MAC */
mutex_lock(&efx->mac_lock);