aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c110
1 files changed, 106 insertions, 4 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index ee66c48e28bc..b12bba795f2e 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -81,6 +81,8 @@ static struct cnic_ops cnic_bnx2x_ops = {
81 .cnic_ctl = cnic_ctl, 81 .cnic_ctl = cnic_ctl,
82}; 82};
83 83
84static struct workqueue_struct *cnic_wq;
85
84static void cnic_shutdown_rings(struct cnic_dev *); 86static void cnic_shutdown_rings(struct cnic_dev *);
85static void cnic_init_rings(struct cnic_dev *); 87static void cnic_init_rings(struct cnic_dev *);
86static int cnic_cm_set_pg(struct cnic_sock *); 88static int cnic_cm_set_pg(struct cnic_sock *);
@@ -1629,10 +1631,11 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[],
1629 struct iscsi_kwqe_conn_offload1 *req1; 1631 struct iscsi_kwqe_conn_offload1 *req1;
1630 struct iscsi_kwqe_conn_offload2 *req2; 1632 struct iscsi_kwqe_conn_offload2 *req2;
1631 struct cnic_local *cp = dev->cnic_priv; 1633 struct cnic_local *cp = dev->cnic_priv;
1634 struct cnic_context *ctx;
1632 struct iscsi_kcqe kcqe; 1635 struct iscsi_kcqe kcqe;
1633 struct kcqe *cqes[1]; 1636 struct kcqe *cqes[1];
1634 u32 l5_cid; 1637 u32 l5_cid;
1635 int ret; 1638 int ret = 0;
1636 1639
1637 if (num < 2) { 1640 if (num < 2) {
1638 *work = num; 1641 *work = num;
@@ -1656,9 +1659,15 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[],
1656 kcqe.iscsi_conn_id = l5_cid; 1659 kcqe.iscsi_conn_id = l5_cid;
1657 kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE; 1660 kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE;
1658 1661
1662 ctx = &cp->ctx_tbl[l5_cid];
1663 if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) {
1664 kcqe.completion_status =
1665 ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY;
1666 goto done;
1667 }
1668
1659 if (atomic_inc_return(&cp->iscsi_conn) > dev->max_iscsi_conn) { 1669 if (atomic_inc_return(&cp->iscsi_conn) > dev->max_iscsi_conn) {
1660 atomic_dec(&cp->iscsi_conn); 1670 atomic_dec(&cp->iscsi_conn);
1661 ret = 0;
1662 goto done; 1671 goto done;
1663 } 1672 }
1664 ret = cnic_alloc_bnx2x_conn_resc(dev, l5_cid); 1673 ret = cnic_alloc_bnx2x_conn_resc(dev, l5_cid);
@@ -1748,8 +1757,16 @@ static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe)
1748 if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) 1757 if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
1749 goto skip_cfc_delete; 1758 goto skip_cfc_delete;
1750 1759
1751 while (!time_after(jiffies, ctx->timestamp + (2 * HZ))) 1760 if (!time_after(jiffies, ctx->timestamp + (2 * HZ))) {
1752 msleep(250); 1761 unsigned long delta = ctx->timestamp + (2 * HZ) - jiffies;
1762
1763 if (delta > (2 * HZ))
1764 delta = 0;
1765
1766 set_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags);
1767 queue_delayed_work(cnic_wq, &cp->delete_task, delta);
1768 goto destroy_reply;
1769 }
1753 1770
1754 ret = cnic_bnx2x_destroy_ramrod(dev, l5_cid); 1771 ret = cnic_bnx2x_destroy_ramrod(dev, l5_cid);
1755 1772
@@ -1757,7 +1774,9 @@ skip_cfc_delete:
1757 cnic_free_bnx2x_conn_resc(dev, l5_cid); 1774 cnic_free_bnx2x_conn_resc(dev, l5_cid);
1758 1775
1759 atomic_dec(&cp->iscsi_conn); 1776 atomic_dec(&cp->iscsi_conn);
1777 clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags);
1760 1778
1779destroy_reply:
1761 memset(&kcqe, 0, sizeof(kcqe)); 1780 memset(&kcqe, 0, sizeof(kcqe));
1762 kcqe.op_code = ISCSI_KCQE_OPCODE_DESTROY_CONN; 1781 kcqe.op_code = ISCSI_KCQE_OPCODE_DESTROY_CONN;
1763 kcqe.iscsi_conn_id = l5_cid; 1782 kcqe.iscsi_conn_id = l5_cid;
@@ -2748,6 +2767,13 @@ static int cnic_cm_create(struct cnic_dev *dev, int ulp_type, u32 cid,
2748 if (l5_cid >= MAX_CM_SK_TBL_SZ) 2767 if (l5_cid >= MAX_CM_SK_TBL_SZ)
2749 return -EINVAL; 2768 return -EINVAL;
2750 2769
2770 if (cp->ctx_tbl) {
2771 struct cnic_context *ctx = &cp->ctx_tbl[l5_cid];
2772
2773 if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
2774 return -EAGAIN;
2775 }
2776
2751 csk1 = &cp->csk_tbl[l5_cid]; 2777 csk1 = &cp->csk_tbl[l5_cid];
2752 if (atomic_read(&csk1->ref_count)) 2778 if (atomic_read(&csk1->ref_count))
2753 return -EAGAIN; 2779 return -EAGAIN;
@@ -3299,6 +3325,32 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode)
3299 3325
3300static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) 3326static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev)
3301{ 3327{
3328 struct cnic_local *cp = dev->cnic_priv;
3329 int i;
3330
3331 if (!cp->ctx_tbl)
3332 return;
3333
3334 if (!netif_running(dev->netdev))
3335 return;
3336
3337 for (i = 0; i < cp->max_cid_space; i++) {
3338 struct cnic_context *ctx = &cp->ctx_tbl[i];
3339
3340 while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
3341 msleep(10);
3342
3343 if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags))
3344 netdev_warn(dev->netdev, "CID %x not deleted\n",
3345 ctx->cid);
3346 }
3347
3348 cancel_delayed_work(&cp->delete_task);
3349 flush_workqueue(cnic_wq);
3350
3351 if (atomic_read(&cp->iscsi_conn) != 0)
3352 netdev_warn(dev->netdev, "%d iSCSI connections not destroyed\n",
3353 atomic_read(&cp->iscsi_conn));
3302} 3354}
3303 3355
3304static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) 3356static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev)
@@ -3333,6 +3385,46 @@ static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev)
3333 return 0; 3385 return 0;
3334} 3386}
3335 3387
3388static void cnic_delete_task(struct work_struct *work)
3389{
3390 struct cnic_local *cp;
3391 struct cnic_dev *dev;
3392 u32 i;
3393 int need_resched = 0;
3394
3395 cp = container_of(work, struct cnic_local, delete_task.work);
3396 dev = cp->dev;
3397
3398 for (i = 0; i < cp->max_cid_space; i++) {
3399 struct cnic_context *ctx = &cp->ctx_tbl[i];
3400
3401 if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags) ||
3402 !test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
3403 continue;
3404
3405 if (!time_after(jiffies, ctx->timestamp + (2 * HZ))) {
3406 need_resched = 1;
3407 continue;
3408 }
3409
3410 if (!test_and_clear_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags))
3411 continue;
3412
3413 cnic_bnx2x_destroy_ramrod(dev, i);
3414
3415 cnic_free_bnx2x_conn_resc(dev, i);
3416 if (ctx->ulp_proto_id == CNIC_ULP_ISCSI)
3417 atomic_dec(&cp->iscsi_conn);
3418
3419 clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags);
3420 }
3421
3422 if (need_resched)
3423 queue_delayed_work(cnic_wq, &cp->delete_task,
3424 msecs_to_jiffies(10));
3425
3426}
3427
3336static int cnic_cm_open(struct cnic_dev *dev) 3428static int cnic_cm_open(struct cnic_dev *dev)
3337{ 3429{
3338 struct cnic_local *cp = dev->cnic_priv; 3430 struct cnic_local *cp = dev->cnic_priv;
@@ -3347,6 +3439,8 @@ static int cnic_cm_open(struct cnic_dev *dev)
3347 if (err) 3439 if (err)
3348 goto err_out; 3440 goto err_out;
3349 3441
3442 INIT_DELAYED_WORK(&cp->delete_task, cnic_delete_task);
3443
3350 dev->cm_create = cnic_cm_create; 3444 dev->cm_create = cnic_cm_create;
3351 dev->cm_destroy = cnic_cm_destroy; 3445 dev->cm_destroy = cnic_cm_destroy;
3352 dev->cm_connect = cnic_cm_connect; 3446 dev->cm_connect = cnic_cm_connect;
@@ -4735,6 +4829,13 @@ static int __init cnic_init(void)
4735 return rc; 4829 return rc;
4736 } 4830 }
4737 4831
4832 cnic_wq = create_singlethread_workqueue("cnic_wq");
4833 if (!cnic_wq) {
4834 cnic_release();
4835 unregister_netdevice_notifier(&cnic_netdev_notifier);
4836 return -ENOMEM;
4837 }
4838
4738 return 0; 4839 return 0;
4739} 4840}
4740 4841
@@ -4742,6 +4843,7 @@ static void __exit cnic_exit(void)
4742{ 4843{
4743 unregister_netdevice_notifier(&cnic_netdev_notifier); 4844 unregister_netdevice_notifier(&cnic_netdev_notifier);
4744 cnic_release(); 4845 cnic_release();
4846 destroy_workqueue(cnic_wq);
4745} 4847}
4746 4848
4747module_init(cnic_init); 4849module_init(cnic_init);