[SCSI] libiscsi_tcp: support padding offload

cxgb3i does not offload the processing of the header,
but it will always process the padding. This patch
adds a padding offload flag to detect when the LLD
supports this.

The patch also modifies the header processing so that
we do not try to read/bypass the header dugest in the
skb. cxgb3i will not include it with the header like
with other offload cards.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index 9df6b34..a745f91 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -159,6 +159,7 @@
 
 /**
  * iscsi_tcp_segment_done - check whether the segment is complete
+ * @tcp_conn: iscsi tcp connection
  * @segment: iscsi segment to check
  * @recv: set to one of this is called from the recv path
  * @copied: number of bytes copied
@@ -172,7 +173,8 @@
  *
  * This function must be re-entrant.
  */
-int iscsi_tcp_segment_done(struct iscsi_segment *segment, int recv,
+int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
+			   struct iscsi_segment *segment, int recv,
 			   unsigned copied)
 {
 	static unsigned char padbuf[ISCSI_PAD_LEN];
@@ -225,13 +227,15 @@
 	}
 
 	/* Do we need to handle padding? */
-	pad = iscsi_padding(segment->total_copied);
-	if (pad != 0) {
-		debug_tcp("consume %d pad bytes\n", pad);
-		segment->total_size += pad;
-		segment->size = pad;
-		segment->data = padbuf;
-		return 0;
+	if (!(tcp_conn->iscsi_conn->session->tt->caps & CAP_PADDING_OFFLOAD)) {
+		pad = iscsi_padding(segment->total_copied);
+		if (pad != 0) {
+			debug_tcp("consume %d pad bytes\n", pad);
+			segment->total_size += pad;
+			segment->size = pad;
+			segment->data = padbuf;
+			return 0;
+		}
 	}
 
 	/*
@@ -273,7 +277,7 @@
 {
 	unsigned int copy = 0, copied = 0;
 
-	while (!iscsi_tcp_segment_done(segment, 1, copy)) {
+	while (!iscsi_tcp_segment_done(tcp_conn, segment, 1, copy)) {
 		if (copied == len) {
 			debug_tcp("iscsi_tcp_segment_recv copied %d bytes\n",
 				  len);
@@ -794,7 +798,8 @@
 	/* We're done processing the header. See if we're doing
 	 * header digests; if so, set up the recv_digest buffer
 	 * and go back for more. */
-	if (conn->hdrdgst_en) {
+	if (conn->hdrdgst_en &&
+	    !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD)) {
 		if (segment->digest_len == 0) {
 			/*
 			 * Even if we offload the digest processing we
@@ -806,14 +811,12 @@
 			return 0;
 		}
 
-		if (!(conn->session->tt->caps & CAP_DIGEST_OFFLOAD)) {
-			iscsi_tcp_dgst_header(tcp_conn->rx_hash, hdr,
-				segment->total_copied - ISCSI_DIGEST_SIZE,
-				segment->digest);
+		iscsi_tcp_dgst_header(tcp_conn->rx_hash, hdr,
+				      segment->total_copied - ISCSI_DIGEST_SIZE,
+				      segment->digest);
 
-			if (!iscsi_tcp_dgst_verify(tcp_conn, segment))
-				return ISCSI_ERR_HDR_DGST;
-		}
+		if (!iscsi_tcp_dgst_verify(tcp_conn, segment))
+			return ISCSI_ERR_HDR_DGST;
 	}
 
 	tcp_conn->in.hdr = hdr;