Skip to content

Commit

Permalink
net/ibmvnic: Update MAC address settings after adapter reset
Browse files Browse the repository at this point in the history
It was discovered in testing that the underlying hardware MAC
address will revert to initial settings following a device reset,
but the driver fails to resend the current OS MAC settings. This
oversight can result in dropped packets should the scenario occur.
Fix this by informing hardware of current MAC address settings
following any adapter initialization or resets.

Signed-off-by: Thomas Falcon <tlfalcon@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Thomas Falcon authored and David S. Miller committed May 10, 2019
1 parent b96a541 commit 62740e9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 27 deletions.
53 changes: 28 additions & 25 deletions drivers/net/ethernet/ibm/ibmvnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter);
static int ibmvnic_init(struct ibmvnic_adapter *);
static int ibmvnic_reset_init(struct ibmvnic_adapter *);
static void release_crq_queue(struct ibmvnic_adapter *);
static int __ibmvnic_set_mac(struct net_device *netdev, struct sockaddr *p);
static int __ibmvnic_set_mac(struct net_device *, u8 *);
static int init_crq_queue(struct ibmvnic_adapter *adapter);
static int send_query_phys_parms(struct ibmvnic_adapter *adapter);

Expand Down Expand Up @@ -849,11 +849,7 @@ static int ibmvnic_login(struct net_device *netdev)
}
} while (retry);

/* 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;
}
__ibmvnic_set_mac(netdev, adapter->mac_addr);

return 0;
}
Expand Down Expand Up @@ -1686,28 +1682,40 @@ static void ibmvnic_set_multi(struct net_device *netdev)
}
}

static int __ibmvnic_set_mac(struct net_device *netdev, struct sockaddr *p)
static int __ibmvnic_set_mac(struct net_device *netdev, u8 *dev_addr)
{
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
struct sockaddr *addr = p;
union ibmvnic_crq crq;
int rc;

if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
if (!is_valid_ether_addr(dev_addr)) {
rc = -EADDRNOTAVAIL;
goto err;
}

memset(&crq, 0, sizeof(crq));
crq.change_mac_addr.first = IBMVNIC_CRQ_CMD;
crq.change_mac_addr.cmd = CHANGE_MAC_ADDR;
ether_addr_copy(&crq.change_mac_addr.mac_addr[0], addr->sa_data);
ether_addr_copy(&crq.change_mac_addr.mac_addr[0], dev_addr);

init_completion(&adapter->fw_done);
rc = ibmvnic_send_crq(adapter, &crq);
if (rc)
return rc;
if (rc) {
rc = -EIO;
goto err;
}

wait_for_completion(&adapter->fw_done);
/* netdev->dev_addr is changed in handle_change_mac_rsp function */
return adapter->fw_done_rc ? -EIO : 0;
if (adapter->fw_done_rc) {
rc = -EIO;
goto err;
}

return 0;
err:
ether_addr_copy(adapter->mac_addr, netdev->dev_addr);
return rc;
}

static int ibmvnic_set_mac(struct net_device *netdev, void *p)
Expand All @@ -1716,13 +1724,10 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p)
struct sockaddr *addr = p;
int rc;

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

rc = __ibmvnic_set_mac(netdev, addr);
rc = 0;
ether_addr_copy(adapter->mac_addr, addr->sa_data);
if (adapter->state != VNIC_PROBED)
rc = __ibmvnic_set_mac(netdev, addr->sa_data);

return rc;
}
Expand Down Expand Up @@ -3937,8 +3942,8 @@ static int handle_change_mac_rsp(union ibmvnic_crq *crq,
dev_err(dev, "Error %ld in CHANGE_MAC_ADDR_RSP\n", rc);
goto out;
}
memcpy(netdev->dev_addr, &crq->change_mac_addr_rsp.mac_addr[0],
ETH_ALEN);
ether_addr_copy(netdev->dev_addr,
&crq->change_mac_addr_rsp.mac_addr[0]);
out:
complete(&adapter->fw_done);
return rc;
Expand Down Expand Up @@ -4852,8 +4857,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
init_completion(&adapter->init_done);
adapter->resetting = false;

adapter->mac_change_pending = false;

do {
rc = init_crq_queue(adapter);
if (rc) {
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/ibm/ibmvnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,6 @@ struct ibmvnic_tunables {
u64 rx_entries;
u64 tx_entries;
u64 mtu;
struct sockaddr mac;
};

struct ibmvnic_adapter {
Expand Down Expand Up @@ -1091,7 +1090,6 @@ struct ibmvnic_adapter {
bool resetting;
bool napi_enabled, from_passive_init;

bool mac_change_pending;
bool failover_pending;
bool force_reset_recovery;

Expand Down

0 comments on commit 62740e9

Please sign in to comment.