aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Falcon <tlfalcon@linux.vnet.ibm.com>2018-01-29 14:45:05 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-29 18:03:24 -0500
commitf813614f531114db796ad66ced75c5dc8db7aa3a (patch)
treef02d6f9194a193821a6c72ad06617af505b93d63
parent233ac3891607f501f08879134d623b303838f478 (diff)
ibmvnic: Wait for device response when changing MAC
Wait for a response from the VNIC server before exiting after setting the MAC address. The resolves an issue with bonding a VNIC client in ALB or TLB modes. The bonding driver was changing the MAC address more rapidly than the device could respond, causing the following errors. "bond0: the hw address of slave eth2 is in use by the bond; couldn't find a slave with a free hw address to give it (this should not have happened)" If the function waits until the change is finalized, these errors are avoided. Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 8f2a77ecf4fb..8c3058d5d191 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1548,15 +1548,19 @@ static int __ibmvnic_set_mac(struct net_device *netdev, struct sockaddr *p)
1548 crq.change_mac_addr.first = IBMVNIC_CRQ_CMD; 1548 crq.change_mac_addr.first = IBMVNIC_CRQ_CMD;
1549 crq.change_mac_addr.cmd = CHANGE_MAC_ADDR; 1549 crq.change_mac_addr.cmd = CHANGE_MAC_ADDR;
1550 ether_addr_copy(&crq.change_mac_addr.mac_addr[0], addr->sa_data); 1550 ether_addr_copy(&crq.change_mac_addr.mac_addr[0], addr->sa_data);
1551
1552 init_completion(&adapter->fw_done);
1551 ibmvnic_send_crq(adapter, &crq); 1553 ibmvnic_send_crq(adapter, &crq);
1554 wait_for_completion(&adapter->fw_done);
1552 /* netdev->dev_addr is changed in handle_change_mac_rsp function */ 1555 /* netdev->dev_addr is changed in handle_change_mac_rsp function */
1553 return 0; 1556 return adapter->fw_done_rc ? -EIO : 0;
1554} 1557}
1555 1558
1556static int ibmvnic_set_mac(struct net_device *netdev, void *p) 1559static int ibmvnic_set_mac(struct net_device *netdev, void *p)
1557{ 1560{
1558 struct ibmvnic_adapter *adapter = netdev_priv(netdev); 1561 struct ibmvnic_adapter *adapter = netdev_priv(netdev);
1559 struct sockaddr *addr = p; 1562 struct sockaddr *addr = p;
1563 int rc;
1560 1564
1561 if (adapter->state == VNIC_PROBED) { 1565 if (adapter->state == VNIC_PROBED) {
1562 memcpy(&adapter->desired.mac, addr, sizeof(struct sockaddr)); 1566 memcpy(&adapter->desired.mac, addr, sizeof(struct sockaddr));
@@ -1564,9 +1568,9 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p)
1564 return 0; 1568 return 0;
1565 } 1569 }
1566 1570
1567 __ibmvnic_set_mac(netdev, addr); 1571 rc = __ibmvnic_set_mac(netdev, addr);
1568 1572
1569 return 0; 1573 return rc;
1570} 1574}
1571 1575
1572/** 1576/**
@@ -3569,8 +3573,8 @@ static void handle_error_indication(union ibmvnic_crq *crq,
3569 ibmvnic_reset(adapter, VNIC_RESET_NON_FATAL); 3573 ibmvnic_reset(adapter, VNIC_RESET_NON_FATAL);
3570} 3574}
3571 3575
3572static void handle_change_mac_rsp(union ibmvnic_crq *crq, 3576static int handle_change_mac_rsp(union ibmvnic_crq *crq,
3573 struct ibmvnic_adapter *adapter) 3577 struct ibmvnic_adapter *adapter)
3574{ 3578{
3575 struct net_device *netdev = adapter->netdev; 3579 struct net_device *netdev = adapter->netdev;
3576 struct device *dev = &adapter->vdev->dev; 3580 struct device *dev = &adapter->vdev->dev;
@@ -3579,10 +3583,13 @@ static void handle_change_mac_rsp(union ibmvnic_crq *crq,
3579 rc = crq->change_mac_addr_rsp.rc.code; 3583 rc = crq->change_mac_addr_rsp.rc.code;
3580 if (rc) { 3584 if (rc) {
3581 dev_err(dev, "Error %ld in CHANGE_MAC_ADDR_RSP\n", rc); 3585 dev_err(dev, "Error %ld in CHANGE_MAC_ADDR_RSP\n", rc);
3582 return; 3586 goto out;
3583 } 3587 }
3584 memcpy(netdev->dev_addr, &crq->change_mac_addr_rsp.mac_addr[0], 3588 memcpy(netdev->dev_addr, &crq->change_mac_addr_rsp.mac_addr[0],
3585 ETH_ALEN); 3589 ETH_ALEN);
3590out:
3591 complete(&adapter->fw_done);
3592 return rc;
3586} 3593}
3587 3594
3588static void handle_request_cap_rsp(union ibmvnic_crq *crq, 3595static void handle_request_cap_rsp(union ibmvnic_crq *crq,
@@ -4042,7 +4049,7 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
4042 break; 4049 break;
4043 case CHANGE_MAC_ADDR_RSP: 4050 case CHANGE_MAC_ADDR_RSP:
4044 netdev_dbg(netdev, "Got MAC address change Response\n"); 4051 netdev_dbg(netdev, "Got MAC address change Response\n");
4045 handle_change_mac_rsp(crq, adapter); 4052 adapter->fw_done_rc = handle_change_mac_rsp(crq, adapter);
4046 break; 4053 break;
4047 case ERROR_INDICATION: 4054 case ERROR_INDICATION:
4048 netdev_dbg(netdev, "Got Error Indication\n"); 4055 netdev_dbg(netdev, "Got Error Indication\n");