aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2011-07-20 10:55:23 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-21 15:38:32 -0400
commit74e49bbdabbac34c77b280152b1de9bef9bf9be7 (patch)
treeb234bc89050abda03bb29103b416eebe3d5ff510 /drivers/net/cnic.c
parentb37a41e390310429d4171b0f7b6c6eab04512dc0 (diff)
cnic: Wait for all Context IDs to be deleted before sending FCOE_DESTROY_FUNC
Otherwise, the firmware will not respond and we'll have to wait for timeout. Refactor the wait loop we already have into a separate function for this purpose. Signed-off-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 455fd0dacb38..9be0c261b8b0 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2448,6 +2448,30 @@ static int cnic_bnx2x_fcoe_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
2448 return ret; 2448 return ret;
2449} 2449}
2450 2450
2451static void cnic_bnx2x_delete_wait(struct cnic_dev *dev, u32 start_cid)
2452{
2453 struct cnic_local *cp = dev->cnic_priv;
2454 u32 i;
2455
2456 for (i = start_cid; i < cp->max_cid_space; i++) {
2457 struct cnic_context *ctx = &cp->ctx_tbl[i];
2458 int j;
2459
2460 while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
2461 msleep(10);
2462
2463 for (j = 0; j < 5; j++) {
2464 if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
2465 break;
2466 msleep(20);
2467 }
2468
2469 if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
2470 netdev_warn(dev->netdev, "CID %x not deleted\n",
2471 ctx->cid);
2472 }
2473}
2474
2451static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe) 2475static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
2452{ 2476{
2453 struct fcoe_kwqe_destroy *req; 2477 struct fcoe_kwqe_destroy *req;
@@ -2456,6 +2480,8 @@ static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
2456 int ret; 2480 int ret;
2457 u32 cid; 2481 u32 cid;
2458 2482
2483 cnic_bnx2x_delete_wait(dev, MAX_ISCSI_TBL_SZ);
2484
2459 req = (struct fcoe_kwqe_destroy *) kwqe; 2485 req = (struct fcoe_kwqe_destroy *) kwqe;
2460 cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid); 2486 cid = BNX2X_HW_CID(cp, cp->fcoe_init_cid);
2461 2487
@@ -3930,7 +3956,6 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode)
3930static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) 3956static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev)
3931{ 3957{
3932 struct cnic_local *cp = dev->cnic_priv; 3958 struct cnic_local *cp = dev->cnic_priv;
3933 int i;
3934 3959
3935 if (!cp->ctx_tbl) 3960 if (!cp->ctx_tbl)
3936 return; 3961 return;
@@ -3938,23 +3963,7 @@ static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev)
3938 if (!netif_running(dev->netdev)) 3963 if (!netif_running(dev->netdev))
3939 return; 3964 return;
3940 3965
3941 for (i = 0; i < cp->max_cid_space; i++) { 3966 cnic_bnx2x_delete_wait(dev, 0);
3942 struct cnic_context *ctx = &cp->ctx_tbl[i];
3943 int j;
3944
3945 while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
3946 msleep(10);
3947
3948 for (j = 0; j < 5; j++) {
3949 if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
3950 break;
3951 msleep(20);
3952 }
3953
3954 if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
3955 netdev_warn(dev->netdev, "CID %x not deleted\n",
3956 ctx->cid);
3957 }
3958 3967
3959 cancel_delayed_work(&cp->delete_task); 3968 cancel_delayed_work(&cp->delete_task);
3960 flush_workqueue(cnic_wq); 3969 flush_workqueue(cnic_wq);