[Open-FCoE] [PATCH 1/2] libfc: modified fc_fcp_send_data() to send entire sequence burst data to LLD

Vasu Dev vasu.dev at intel.com
Thu Oct 2 17:18:11 UTC 2008


The fc_fcp_send_data() is modified to send down entire sequence burst data
(burst len from FCP_XFER_RDY) in one fc_frame/skb to let LLD transmit multiple
FC frames which could be offloaded in HW. The LLD can indicate seq offload
capability in newly added bit flag lp->seq_offload. Along this bit flag change
I also replaced lp->capabilities and its only bit flag TRANS_C_SG by bit
flag lp->sg_supp. If lp->seq_offload capability is not set then
fc_fcp_send_data() will send multiple fc_frame as it used to of size
max frame size between initiator and target pair. Not sure If I need to add
any limit on burst len due to any LLD or skb frags list limitations.

This patch is partly addressing the suggestion came off list to break
FCP layer to allow FCP IUs level interaction. I think FCP IUs of possible
interest to LLD such as sequence level data delivery action to send entire
burst len data can be accomplished by setting capability info in lport
and modifying FCP code paths for only those IUs (e.g seq offload and DDP) as
this patch does for seq offloading.

If LLD would like to use fc_fcp_send_data() kind of API directly then
fc_fcp_send_data() symbol can be exported easily but not sure we need
to add API for each FCP IU. So do we still need to add all FCP IU APIs ?
Do we need all FCP IU APIs used via libfc_function_template ? I think
this will be redundant.

Also cleaned up redundant args oldfp & sg_supp to fc_fcp_send_data()
and renamed few variables in fc_fcp_send_data() per modified code.

This patch doesn't allows enabling lp->seq_offload yet since sequence
count is yet to be updated in next patch for burst len when
lp->seq_offload is enabled.

Signed-off-by: Vasu Dev <vasu.dev at intel.com>
---

 drivers/scsi/fcoe/fcoe_if.c |    2 +-
 drivers/scsi/libfc/fc_fcp.c |   46 ++++++++++++++++++++++++-------------------
 include/scsi/libfc/libfc.h  |    8 ++-----
 3 files changed, 29 insertions(+), 27 deletions(-)


diff --git a/drivers/scsi/fcoe/fcoe_if.c b/drivers/scsi/fcoe/fcoe_if.c
index 477f6b7..586fe65 100644
--- a/drivers/scsi/fcoe/fcoe_if.c
+++ b/drivers/scsi/fcoe/fcoe_if.c
@@ -330,7 +330,7 @@ static int net_config(struct fc_lport *lp)
 		lp->link_status |= FC_LINK_UP;
 
 	if (fc->real_dev->features & NETIF_F_SG)
-		lp->capabilities = TRANS_C_SG;
+		lp->sg_supp = 1;
 
 
 	skb_queue_head_init(&fc->fcoe_pending_queue);
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 097880c..2a59c61 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -448,33 +448,36 @@ crc_err:
 /*
  * Send SCSI data to target.
  * Called after receiving a Transfer Ready data descriptor.
+ * if LLD is capable of seq offload then send down seq_blen
+ * size of data in single frame, otherwise send multiple FC
+ * frames of mfs supported by target port.
  */
 static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *sp,
-			    size_t offset, size_t len,
-			    struct fc_frame *oldfp, int sg_supp)
+			    size_t offset, size_t seq_blen)
 {
 	struct scsi_cmnd *sc;
 	struct scatterlist *sg;
 	struct fc_frame *fp = NULL;
 	struct fc_lport *lp = fsp->lp;
 	size_t remaining;
-	size_t mfs;
+	size_t t_blen;
 	size_t tlen;
 	size_t sg_bytes;
 	size_t frame_offset;
 	int error;
 	void *data = NULL;
 	void *page_addr;
-	int using_sg = sg_supp;
+	int using_sg = lp->sg_supp;
 	u32 f_ctl;
 
-	if (unlikely(offset + len > fsp->data_len)) {
+	WARN_ON(seq_blen <= 0);
+	if (unlikely(offset + seq_blen > fsp->data_len)) {
 		/*
 		 * this should never happen
 		 */
 		if (fc_fcp_debug) {
-			FC_DBG("xfer-ready past end. len %zx offset %zx\n",
-			       len, offset);
+			FC_DBG("xfer-ready past end. seq_blen %zx offset %zx\n",
+			       seq_blen, offset);
 		}
 		fc_fcp_send_abort(fsp);
 		return 0;
@@ -484,19 +487,23 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *sp,
 		 */
 		if (fc_fcp_debug) {
 			FC_DBG("xfer-ready non-contiguous. "
-			       "len %zx offset %zx\n", len, offset);
+			       "seq_blen %zx offset %zx\n", seq_blen, offset);
 		}
 	}
-	mfs = fsp->max_payload;
-	WARN_ON(mfs > FC_MAX_PAYLOAD);
-	WARN_ON(mfs < FC_MIN_MAX_PAYLOAD);
-	if (mfs > 512)
-		mfs &= ~(512 - 1);	/* round down to block size */
-	WARN_ON(mfs < FC_MIN_MAX_PAYLOAD);	/* won't go below 256 */
-	WARN_ON(len <= 0);
+
+	/*
+	 * if LLD is capable of seq_offload then set transport
+	 * burst length (t_blen) to seq_blen, otherwise set t_blen
+	 * to mfs previously set in fsp->max_payload.
+	 */
+	t_blen = lp->seq_offload ? seq_blen : fsp->max_payload;
+	WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD);
+	if (t_blen > 512)
+		t_blen &= ~(512 - 1);	/* round down to block size */
+	WARN_ON(t_blen < FC_MIN_MAX_PAYLOAD);	/* won't go below 256 */
 	sc = fsp->cmd;
 
-	remaining = len;
+	remaining = seq_blen;
 	frame_offset = offset;
 	tlen = 0;
 	sp = lp->tt.seq_start_next(sp);
@@ -539,7 +546,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *sp,
 			continue;
 		}
 		if (!fp) {
-			tlen = min(mfs, remaining);
+			tlen = min(t_blen, remaining);
 
 			/*
 			 * TODO.  Temporary workaround.	 fc_seq_send() can't
@@ -620,7 +627,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *sp,
 			return 0;
 		}
 	}
-	fsp->xfer_len += len;	/* premature count? */
+	fsp->xfer_len += seq_blen;	/* premature count? */
 	return 0;
 }
 
@@ -740,8 +747,7 @@ static void fc_fcp_recv(struct fc_seq *sp, struct fc_frame *fp, void *arg)
 
 		rc = fc_fcp_send_data(fsp, sp,
 				      (size_t) ntohl(dd->ft_data_ro),
-				      (size_t) ntohl(dd->ft_burst_len), fp,
-				      lp->capabilities & TRANS_C_SG);
+				      (size_t) ntohl(dd->ft_burst_len));
 		if (!rc)
 			lp->tt.seq_set_rec_data(sp, fsp->xfer_len);
 		else if (rc == -ENOMEM)
diff --git a/include/scsi/libfc/libfc.h b/include/scsi/libfc/libfc.h
index 19faf49..7873b4d 100644
--- a/include/scsi/libfc/libfc.h
+++ b/include/scsi/libfc/libfc.h
@@ -82,11 +82,6 @@ struct fc_exch_mgr;
 /* for fc_softc */
 #define FC_MAX_OUTSTANDING_COMMANDS 1024
 
-/*
- * Transport Capabilities
- */
-#define TRANS_C_SG		    (1 << 0)  /* Scatter gather */
-
 enum fc_lport_state {
 	LPORT_ST_NONE = 0,
 	LPORT_ST_FLOGI,
@@ -421,7 +416,8 @@ struct fc_lport {
 
 	/* Capabilities */
 	char			ifname[IFNAMSIZ];
-	u32			capabilities;
+	u32			sg_supp:1;	/* scatter gather supported */
+	u32			seq_offload:1;	/* seq offload supported */
 	u32			mfs;	/* max FC payload size */
 	unsigned int		service_params;
 	unsigned int		e_d_tov;




More information about the devel mailing list