diff options
author | Michael Chan <mchan@broadcom.com> | 2011-07-20 10:55:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-21 15:38:32 -0400 |
commit | 74e49bbdabbac34c77b280152b1de9bef9bf9be7 (patch) | |
tree | b234bc89050abda03bb29103b416eebe3d5ff510 /drivers/net/cnic.c | |
parent | b37a41e390310429d4171b0f7b6c6eab04512dc0 (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.c | 45 |
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 | ||
2451 | static 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 | |||
2451 | static int cnic_bnx2x_fcoe_fw_destroy(struct cnic_dev *dev, struct kwqe *kwqe) | 2475 | static 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) | |||
3930 | static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) | 3956 | static 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); |