Commit 53da09e9 authored by Nathan Fontenot's avatar Nathan Fontenot Committed by David S. Miller

ibmvnic: Add set_link_state routine for setting adapter link state

Create a common routine for setting the link state for the vnic adapter.
This update moves the sending of the crq and waiting for the link state
response to a common place. The new routine also adds handling of
resending the crq in cases of getting a partial success response.
Signed-off-by: default avatarNathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d5e84eb
...@@ -561,6 +561,51 @@ static void release_resources(struct ibmvnic_adapter *adapter) ...@@ -561,6 +561,51 @@ static void release_resources(struct ibmvnic_adapter *adapter)
release_error_buffers(adapter); release_error_buffers(adapter);
} }
static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)
{
struct net_device *netdev = adapter->netdev;
unsigned long timeout = msecs_to_jiffies(30000);
union ibmvnic_crq crq;
bool resend;
int rc;
if (adapter->logical_link_state == link_state) {
netdev_dbg(netdev, "Link state already %d\n", link_state);
return 0;
}
netdev_err(netdev, "setting link state %d\n", link_state);
memset(&crq, 0, sizeof(crq));
crq.logical_link_state.first = IBMVNIC_CRQ_CMD;
crq.logical_link_state.cmd = LOGICAL_LINK_STATE;
crq.logical_link_state.link_state = link_state;
do {
resend = false;
reinit_completion(&adapter->init_done);
rc = ibmvnic_send_crq(adapter, &crq);
if (rc) {
netdev_err(netdev, "Failed to set link state\n");
return rc;
}
if (!wait_for_completion_timeout(&adapter->init_done,
timeout)) {
netdev_err(netdev, "timeout setting link state\n");
return -1;
}
if (adapter->init_done_rc == 1) {
/* Partuial success, delay and re-send */
mdelay(1000);
resend = true;
}
} while (resend);
return 0;
}
static int set_real_num_queues(struct net_device *netdev) static int set_real_num_queues(struct net_device *netdev)
{ {
struct ibmvnic_adapter *adapter = netdev_priv(netdev); struct ibmvnic_adapter *adapter = netdev_priv(netdev);
...@@ -583,7 +628,6 @@ static int ibmvnic_open(struct net_device *netdev) ...@@ -583,7 +628,6 @@ static int ibmvnic_open(struct net_device *netdev)
{ {
struct ibmvnic_adapter *adapter = netdev_priv(netdev); struct ibmvnic_adapter *adapter = netdev_priv(netdev);
struct device *dev = &adapter->vdev->dev; struct device *dev = &adapter->vdev->dev;
union ibmvnic_crq crq;
int rc = 0; int rc = 0;
int i; int i;
...@@ -643,11 +687,9 @@ static int ibmvnic_open(struct net_device *netdev) ...@@ -643,11 +687,9 @@ static int ibmvnic_open(struct net_device *netdev)
for (i = 0; i < adapter->req_tx_queues; i++) for (i = 0; i < adapter->req_tx_queues; i++)
enable_scrq_irq(adapter, adapter->tx_scrq[i]); enable_scrq_irq(adapter, adapter->tx_scrq[i]);
memset(&crq, 0, sizeof(crq)); rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
crq.logical_link_state.first = IBMVNIC_CRQ_CMD; if (rc)
crq.logical_link_state.cmd = LOGICAL_LINK_STATE; goto ibmvnic_open_fail;
crq.logical_link_state.link_state = IBMVNIC_LOGICAL_LNK_UP;
ibmvnic_send_crq(adapter, &crq);
netif_tx_start_all_queues(netdev); netif_tx_start_all_queues(netdev);
adapter->is_closed = false; adapter->is_closed = false;
...@@ -681,7 +723,7 @@ static void disable_sub_crqs(struct ibmvnic_adapter *adapter) ...@@ -681,7 +723,7 @@ static void disable_sub_crqs(struct ibmvnic_adapter *adapter)
static int ibmvnic_close(struct net_device *netdev) static int ibmvnic_close(struct net_device *netdev)
{ {
struct ibmvnic_adapter *adapter = netdev_priv(netdev); struct ibmvnic_adapter *adapter = netdev_priv(netdev);
union ibmvnic_crq crq; int rc = 0;
int i; int i;
adapter->closing = true; adapter->closing = true;
...@@ -693,17 +735,13 @@ static int ibmvnic_close(struct net_device *netdev) ...@@ -693,17 +735,13 @@ static int ibmvnic_close(struct net_device *netdev)
if (!adapter->failover) if (!adapter->failover)
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
memset(&crq, 0, sizeof(crq)); rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
crq.logical_link_state.first = IBMVNIC_CRQ_CMD;
crq.logical_link_state.cmd = LOGICAL_LINK_STATE;
crq.logical_link_state.link_state = IBMVNIC_LOGICAL_LNK_DN;
ibmvnic_send_crq(adapter, &crq);
release_resources(adapter); release_resources(adapter);
adapter->is_closed = true; adapter->is_closed = true;
adapter->closing = false; adapter->closing = false;
return 0; return rc;
} }
/** /**
...@@ -2945,9 +2983,14 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq, ...@@ -2945,9 +2983,14 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
handle_login_rsp(crq, adapter); handle_login_rsp(crq, adapter);
break; break;
case LOGICAL_LINK_STATE_RSP: case LOGICAL_LINK_STATE_RSP:
netdev_dbg(netdev, "Got Logical Link State Response\n"); netdev_dbg(netdev,
"Got Logical Link State Response, state: %d rc: %d\n",
crq->logical_link_state_rsp.link_state,
crq->logical_link_state_rsp.rc.code);
adapter->logical_link_state = adapter->logical_link_state =
crq->logical_link_state_rsp.link_state; crq->logical_link_state_rsp.link_state;
adapter->init_done_rc = crq->logical_link_state_rsp.rc.code;
complete(&adapter->init_done);
break; break;
case LINK_STATE_INDICATION: case LINK_STATE_INDICATION:
netdev_dbg(netdev, "Got Logical Link State Indication\n"); netdev_dbg(netdev, "Got Logical Link State Indication\n");
......
...@@ -964,6 +964,7 @@ struct ibmvnic_adapter { ...@@ -964,6 +964,7 @@ struct ibmvnic_adapter {
struct ibmvnic_tx_pool *tx_pool; struct ibmvnic_tx_pool *tx_pool;
bool closing; bool closing;
struct completion init_done; struct completion init_done;
int init_done_rc;
struct list_head errors; struct list_head errors;
spinlock_t error_list_lock; spinlock_t error_list_lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment