target/cxgbit: Enable DDP for T6 only if data sequence and pdu are in order
authorVarun Prakash <varun@chelsio.com>
Fri, 13 Jan 2017 15:23:24 +0000 (20:53 +0530)
committerNicholas Bellinger <nab@linux-iscsi.org>
Sun, 19 Feb 2017 05:24:20 +0000 (21:24 -0800)
Enable DDP for T6 only if DataSequenceInOrder=YES and
DataPDUInOrder=YES to ensure inorder delivery of iSCSI pdus.

Signed-off-by: Varun Prakash <varun@chelsio.com>
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/iscsi/cxgbit/cxgbit_target.c

index 8ae399dfe84f16d4aec85d231bb505ca8494a49b..4780fae2a1d1593edc6837c06b8e59e79d382317 100644 (file)
@@ -653,26 +653,6 @@ static int cxgbit_set_iso_npdu(struct cxgbit_sock *csk)
        u32 max_npdu, max_iso_npdu;
 
        if (conn->login->leading_connection) {
-               param = iscsi_find_param_from_key(DATASEQUENCEINORDER,
-                                                 conn->param_list);
-               if (!param) {
-                       pr_err("param not found key %s\n", DATASEQUENCEINORDER);
-                       return -1;
-               }
-
-               if (strcmp(param->value, YES))
-                       return 0;
-
-               param = iscsi_find_param_from_key(DATAPDUINORDER,
-                                                 conn->param_list);
-               if (!param) {
-                       pr_err("param not found key %s\n", DATAPDUINORDER);
-                       return -1;
-               }
-
-               if (strcmp(param->value, YES))
-                       return 0;
-
                param = iscsi_find_param_from_key(MAXBURSTLENGTH,
                                                  conn->param_list);
                if (!param) {
@@ -683,11 +663,6 @@ static int cxgbit_set_iso_npdu(struct cxgbit_sock *csk)
                if (kstrtou32(param->value, 0, &mbl) < 0)
                        return -1;
        } else {
-               if (!conn->sess->sess_ops->DataSequenceInOrder)
-                       return 0;
-               if (!conn->sess->sess_ops->DataPDUInOrder)
-                       return 0;
-
                mbl = conn->sess->sess_ops->MaxBurstLength;
        }
 
@@ -706,6 +681,53 @@ static int cxgbit_set_iso_npdu(struct cxgbit_sock *csk)
        return 0;
 }
 
+/*
+ * cxgbit_seq_pdu_inorder()
+ * @csk: pointer to cxgbit socket structure
+ *
+ * This function checks whether data sequence and data
+ * pdu are in order.
+ *
+ * Return: returns -1 on error, 0 if data sequence and
+ * data pdu are in order, 1 if data sequence or data pdu
+ * is not in order.
+ */
+static int cxgbit_seq_pdu_inorder(struct cxgbit_sock *csk)
+{
+       struct iscsi_conn *conn = csk->conn;
+       struct iscsi_param *param;
+
+       if (conn->login->leading_connection) {
+               param = iscsi_find_param_from_key(DATASEQUENCEINORDER,
+                                                 conn->param_list);
+               if (!param) {
+                       pr_err("param not found key %s\n", DATASEQUENCEINORDER);
+                       return -1;
+               }
+
+               if (strcmp(param->value, YES))
+                       return 1;
+
+               param = iscsi_find_param_from_key(DATAPDUINORDER,
+                                                 conn->param_list);
+               if (!param) {
+                       pr_err("param not found key %s\n", DATAPDUINORDER);
+                       return -1;
+               }
+
+               if (strcmp(param->value, YES))
+                       return 1;
+
+       } else {
+               if (!conn->sess->sess_ops->DataSequenceInOrder)
+                       return 1;
+               if (!conn->sess->sess_ops->DataPDUInOrder)
+                       return 1;
+       }
+
+       return 0;
+}
+
 static int cxgbit_set_params(struct iscsi_conn *conn)
 {
        struct cxgbit_sock *csk = conn->context;
@@ -732,11 +754,24 @@ static int cxgbit_set_params(struct iscsi_conn *conn)
        }
 
        if (!erl) {
+               int ret;
+
+               ret = cxgbit_seq_pdu_inorder(csk);
+               if (ret < 0) {
+                       return -1;
+               } else if (ret > 0) {
+                       if (is_t5(cdev->lldi.adapter_type))
+                               goto enable_ddp;
+                       else
+                               goto enable_digest;
+               }
+
                if (test_bit(CDEV_ISO_ENABLE, &cdev->flags)) {
                        if (cxgbit_set_iso_npdu(csk))
                                return -1;
                }
 
+enable_ddp:
                if (test_bit(CDEV_DDP_ENABLE, &cdev->flags)) {
                        if (cxgbit_setup_conn_pgidx(csk,
                                                    ppm->tformat.pgsz_idx_dflt))
@@ -745,6 +780,7 @@ static int cxgbit_set_params(struct iscsi_conn *conn)
                }
        }
 
+enable_digest:
        if (cxgbit_set_digest(csk))
                return -1;