Skip to content

Commit

Permalink
ibmvnic: Fix pending MAC address changes
Browse files Browse the repository at this point in the history
Due to architecture limitations, the IBM VNIC client driver is unable
to perform MAC address changes unless the device has "logged in" to
its backing device. Currently, pending MAC changes are handled before
login, resulting in an error and failure to change the MAC address.
Moving that chunk to the end of the ibmvnic_login function, when we are
sure that it was successful, fixes that.

The MAC address can be changed when the device is up or down, so
only check if the device is in a "PROBED" state before setting the
MAC address.

Fixes: c26eba0 ("ibmvnic: Update reset infrastructure to support tunable parameters")
Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Reviewed-by: John Allen <jallen@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Thomas Falcon authored and David S. Miller committed Jan 16, 2018
1 parent 6311b7c commit 3d16613
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions drivers/net/ethernet/ibm/ibmvnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,12 @@ static int ibmvnic_login(struct net_device *netdev)
}
} while (adapter->renegotiate);

/* handle pending MAC address changes after successful login */
if (adapter->mac_change_pending) {
__ibmvnic_set_mac(netdev, &adapter->desired.mac);
adapter->mac_change_pending = false;
}

return 0;
}

Expand Down Expand Up @@ -993,11 +999,6 @@ static int ibmvnic_open(struct net_device *netdev)

mutex_lock(&adapter->reset_lock);

if (adapter->mac_change_pending) {
__ibmvnic_set_mac(netdev, &adapter->desired.mac);
adapter->mac_change_pending = false;
}

if (adapter->state != VNIC_CLOSED) {
rc = ibmvnic_login(netdev);
if (rc) {
Expand Down Expand Up @@ -1527,7 +1528,7 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p)
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
struct sockaddr *addr = p;

if (adapter->state != VNIC_OPEN) {
if (adapter->state == VNIC_PROBED) {
memcpy(&adapter->desired.mac, addr, sizeof(struct sockaddr));
adapter->mac_change_pending = true;
return 0;
Expand Down

0 comments on commit 3d16613

Please sign in to comment.