aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/ibm/ibmvnic.c
diff options
context:
space:
mode:
authorJohn Allen <jallen@linux.vnet.ibm.com>2017-03-17 17:13:40 -0500
committerDavid S. Miller <davem@davemloft.net>2017-03-21 17:46:13 -0700
commitbd0b6723139416fd22acd5849b93edbd32d561f3 (patch)
treec971f8070787122eac038ff7cb6f8647e9f20de9 /drivers/net/ethernet/ibm/ibmvnic.c
parentnet: sun: sungem: rix a possible null dereference (diff)
downloadlinux-dev-bd0b6723139416fd22acd5849b93edbd32d561f3.tar.xz
linux-dev-bd0b6723139416fd22acd5849b93edbd32d561f3.zip
ibmvnic: Move login and queue negotiation into ibmvnic_open
VNIC server expects LINK_STATE_UP to be sent within 30s of the login. If we exceed the timeout, VNIC server will attempt to fail over. Since time between probe and open of the device is indeterminate, move login and queue negotiation into ibmvnic open so we can guarantee that login and sending LINK_STATE_UP occur within the 30s window. Signed-off-by: John Allen <jallen@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c88
1 files changed, 43 insertions, 45 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 5f11b4dc95d2..61d9d4045b4c 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -110,6 +110,9 @@ static int ibmvnic_poll(struct napi_struct *napi, int data);
static void send_map_query(struct ibmvnic_adapter *adapter);
static void send_request_map(struct ibmvnic_adapter *, dma_addr_t, __be32, u8);
static void send_request_unmap(struct ibmvnic_adapter *, u8);
+static void send_login(struct ibmvnic_adapter *adapter);
+static void send_cap_queries(struct ibmvnic_adapter *adapter);
+static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter);
struct ibmvnic_stat {
char name[ETH_GSTRING_LEN];
@@ -371,14 +374,51 @@ static void free_rx_pool(struct ibmvnic_adapter *adapter,
static int ibmvnic_open(struct net_device *netdev)
{
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
+ unsigned long timeout = msecs_to_jiffies(30000);
struct device *dev = &adapter->vdev->dev;
struct ibmvnic_tx_pool *tx_pool;
union ibmvnic_crq crq;
int rxadd_subcrqs;
u64 *size_array;
int tx_subcrqs;
+ int rc = 0;
int i, j;
+ do {
+ if (adapter->renegotiate) {
+ adapter->renegotiate = false;
+ release_sub_crqs_no_irqs(adapter);
+
+ reinit_completion(&adapter->init_done);
+ send_cap_queries(adapter);
+ if (!wait_for_completion_timeout(&adapter->init_done,
+ timeout)) {
+ dev_err(dev, "Capabilities query timeout\n");
+ return -1;
+ }
+ }
+
+ reinit_completion(&adapter->init_done);
+ send_login(adapter);
+ if (!wait_for_completion_timeout(&adapter->init_done,
+ timeout)) {
+ dev_err(dev, "Login timeout\n");
+ return -1;
+ }
+ } while (adapter->renegotiate);
+
+ rc = netif_set_real_num_tx_queues(netdev, adapter->req_tx_queues);
+ if (rc) {
+ dev_err(dev, "failed to set the number of tx queues\n");
+ return -1;
+ }
+
+ rc = init_sub_crq_irqs(adapter);
+ if (rc) {
+ dev_err(dev, "failed to initialize sub crq irqs\n");
+ return -1;
+ }
+
rxadd_subcrqs =
be32_to_cpu(adapter->login_rsp_buf->num_rxadd_subcrqs);
tx_subcrqs =
@@ -508,6 +548,7 @@ rx_pool_arr_alloc_failed:
for (i = 0; i < adapter->req_rx_queues; i++)
napi_disable(&adapter->napi[i]);
alloc_napi_failed:
+ release_sub_crqs(adapter);
return -ENOMEM;
}
@@ -3419,8 +3460,7 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
dma_unmap_single(dev, adapter->ip_offload_ctrl_tok,
sizeof(adapter->ip_offload_ctrl),
DMA_TO_DEVICE);
- /* We're done with the queries, perform the login */
- send_login(adapter);
+ complete(&adapter->init_done);
break;
case REQUEST_RAS_COMP_NUM_RSP:
netdev_dbg(netdev, "Got Request RAS Comp Num Response\n");
@@ -3700,26 +3740,6 @@ static void handle_crq_init_rsp(struct work_struct *work)
goto task_failed;
}
- do {
- if (adapter->renegotiate) {
- adapter->renegotiate = false;
- release_sub_crqs_no_irqs(adapter);
-
- reinit_completion(&adapter->init_done);
- send_cap_queries(adapter);
- if (!wait_for_completion_timeout(&adapter->init_done,
- timeout)) {
- dev_err(dev, "Passive init timeout\n");
- goto task_failed;
- }
- }
- } while (adapter->renegotiate);
- rc = init_sub_crq_irqs(adapter);
-
- if (rc)
- goto task_failed;
-
- netdev->real_num_tx_queues = adapter->req_tx_queues;
netdev->mtu = adapter->req_mtu - ETH_HLEN;
if (adapter->failover) {
@@ -3840,39 +3860,17 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
if (!wait_for_completion_timeout(&adapter->init_done, timeout))
return 0;
- do {
- if (adapter->renegotiate) {
- adapter->renegotiate = false;
- release_sub_crqs_no_irqs(adapter);
-
- reinit_completion(&adapter->init_done);
- send_cap_queries(adapter);
- if (!wait_for_completion_timeout(&adapter->init_done,
- timeout))
- return 0;
- }
- } while (adapter->renegotiate);
-
- rc = init_sub_crq_irqs(adapter);
- if (rc) {
- dev_err(&dev->dev, "failed to initialize sub crq irqs\n");
- goto free_debugfs;
- }
-
- netdev->real_num_tx_queues = adapter->req_tx_queues;
netdev->mtu = adapter->req_mtu - ETH_HLEN;
rc = register_netdev(netdev);
if (rc) {
dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc);
- goto free_sub_crqs;
+ goto free_debugfs;
}
dev_info(&dev->dev, "ibmvnic registered\n");
return 0;
-free_sub_crqs:
- release_sub_crqs(adapter);
free_debugfs:
if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir))
debugfs_remove_recursive(adapter->debugfs_dir);