Adds fcoe_exch_get to allocate and setup ddp for read types IOs, the exch_get gets called by libfc to allocate a new exchange from EM block of libfc.
Added fcoe_exch_get allocated exchange from other default em for all other types of IO. Adds fcoe_exch_recv to select a EM instance for a incoming frame and then pass received frame to libfc fc_exch_recv, the selected EM could be offload EM instance or default lp->emp based on xid of incoming frame. Signed-off-by: Vasu Dev <[email protected]> --- drivers/scsi/fcoe/fcoe.c | 60 ++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 6fe1662..504f42b 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -469,6 +469,59 @@ static int fcoe_if_destroy(struct net_device *netdev) return 0; } +/** + * fcoe_exch_recv() - receive a incoming frame + * @lp: the associated local port + * @fp: received fc_frame + * + * Locates exchange manager instance for received frame + * and pass it up to libfc using fc_exch_recv api. + */ +static void fcoe_exch_recv(struct fc_lport *lp, struct fc_frame *fp) +{ + struct fcoe_softc *fc = lport_priv(lp); + struct fc_frame_header *fh = fc_frame_header_get(fp); + u16 oxid = ntohs(fh->fh_ox_id); + u32 ctx; + + if (lp->lro_enabled && (oxid <= lp->lro_xid)) { + ctx = ntoh24(fh->fh_f_ctl) & (FC_FC_EX_CTX | FC_FC_SEQ_CTX); + if (ctx == FC_FC_EX_CTX) { + fc_exch_recv(lp, fc->oemp, fp); + return; + } + } + fc_exch_recv(lp, lp->emp, fp); +} + +/** + * fcoe_exch_get() - allocates an exchange + * @lp: the associated local port + * @fp: the fc_frame to be transmitted + * + * Allocates exchange from fc->oemp for offload eligible IOs + * otherwise allocates from other em instance. + */ +static struct fc_exch *fcoe_exch_get(struct fc_lport *lp, struct fc_frame *fp) +{ + struct fcoe_softc *fc = lport_priv(lp); + struct fc_exch *ep = NULL; + + if (fc_fcp_is_read(fr_fsp(fp))) + ep = fc_exch_alloc(fc->oemp); + + /* + * if valid ep allocated from fc->ofemp + * then set up ddp here, else allocate + * ep from other em. + */ + if (ep) + fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); + else + ep = fc_exch_alloc(lp->emp); + return ep; +} + /* * fcoe_ddp_setup - calls LLD's ddp_setup through net_device * @lp: the corresponding fc_lport @@ -630,6 +683,9 @@ static int fcoe_if_create(struct net_device *netdev) goto out_host_put; } + /* set exch_get if lro enabled */ + if (lp->lro_enabled) + fcoe_libfc_fcn_templ.exch_get = fcoe_exch_get; /* Initialize the library */ rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ); if (rc) { @@ -1303,7 +1359,7 @@ int fcoe_percpu_receive_thread(void *arg) fh = fc_frame_header_get(fp); if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && fh->fh_type == FC_TYPE_FCP) { - fc_exch_recv(lp, lp->emp, fp); + fcoe_exch_recv(lp, fp); continue; } if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) { @@ -1324,7 +1380,7 @@ int fcoe_percpu_receive_thread(void *arg) fc_frame_free(fp); continue; } - fc_exch_recv(lp, lp->emp, fp); + fcoe_exch_recv(lp, fp); } return 0; } _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
