Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * bnx2fc_els.c: QLogic Linux FCoE offload driver.
0003  * This file contains helper routines that handle ELS requests
0004  * and responses.
0005  *
0006  * Copyright (c) 2008-2013 Broadcom Corporation
0007  * Copyright (c) 2014-2016 QLogic Corporation
0008  * Copyright (c) 2016-2017 Cavium Inc.
0009  *
0010  * This program is free software; you can redistribute it and/or modify
0011  * it under the terms of the GNU General Public License as published by
0012  * the Free Software Foundation.
0013  *
0014  * Written by: Bhanu Prakash Gollapudi (bprakash@broadcom.com)
0015  */
0016 
0017 #include "bnx2fc.h"
0018 
0019 static void bnx2fc_logo_resp(struct fc_seq *seq, struct fc_frame *fp,
0020                  void *arg);
0021 static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp,
0022                   void *arg);
0023 static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
0024             void *data, u32 data_len,
0025             void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg),
0026             struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec);
0027 
0028 static void bnx2fc_rrq_compl(struct bnx2fc_els_cb_arg *cb_arg)
0029 {
0030     struct bnx2fc_cmd *orig_io_req;
0031     struct bnx2fc_cmd *rrq_req;
0032     int rc = 0;
0033 
0034     BUG_ON(!cb_arg);
0035     rrq_req = cb_arg->io_req;
0036     orig_io_req = cb_arg->aborted_io_req;
0037     BUG_ON(!orig_io_req);
0038     BNX2FC_ELS_DBG("rrq_compl: orig xid = 0x%x, rrq_xid = 0x%x\n",
0039            orig_io_req->xid, rrq_req->xid);
0040 
0041     kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
0042 
0043     if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rrq_req->req_flags)) {
0044         /*
0045          * els req is timed out. cleanup the IO with FW and
0046          * drop the completion. Remove from active_cmd_queue.
0047          */
0048         BNX2FC_ELS_DBG("rrq xid - 0x%x timed out, clean it up\n",
0049                rrq_req->xid);
0050 
0051         if (rrq_req->on_active_queue) {
0052             list_del_init(&rrq_req->link);
0053             rrq_req->on_active_queue = 0;
0054             rc = bnx2fc_initiate_cleanup(rrq_req);
0055             BUG_ON(rc);
0056         }
0057     }
0058     kfree(cb_arg);
0059 }
0060 int bnx2fc_send_rrq(struct bnx2fc_cmd *aborted_io_req)
0061 {
0062 
0063     struct fc_els_rrq rrq;
0064     struct bnx2fc_rport *tgt = aborted_io_req->tgt;
0065     struct fc_lport *lport = NULL;
0066     struct bnx2fc_els_cb_arg *cb_arg = NULL;
0067     u32 sid = 0;
0068     u32 r_a_tov = 0;
0069     unsigned long start = jiffies;
0070     int rc;
0071 
0072     if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))
0073         return -EINVAL;
0074 
0075     lport = tgt->rdata->local_port;
0076     sid = tgt->sid;
0077     r_a_tov = lport->r_a_tov;
0078 
0079     BNX2FC_ELS_DBG("Sending RRQ orig_xid = 0x%x\n",
0080            aborted_io_req->xid);
0081     memset(&rrq, 0, sizeof(rrq));
0082 
0083     cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_NOIO);
0084     if (!cb_arg) {
0085         printk(KERN_ERR PFX "Unable to allocate cb_arg for RRQ\n");
0086         rc = -ENOMEM;
0087         goto rrq_err;
0088     }
0089 
0090     cb_arg->aborted_io_req = aborted_io_req;
0091 
0092     rrq.rrq_cmd = ELS_RRQ;
0093     hton24(rrq.rrq_s_id, sid);
0094     rrq.rrq_ox_id = htons(aborted_io_req->xid);
0095     rrq.rrq_rx_id = htons(aborted_io_req->task->rxwr_txrd.var_ctx.rx_id);
0096 
0097 retry_rrq:
0098     rc = bnx2fc_initiate_els(tgt, ELS_RRQ, &rrq, sizeof(rrq),
0099                  bnx2fc_rrq_compl, cb_arg,
0100                  r_a_tov);
0101     if (rc == -ENOMEM) {
0102         if (time_after(jiffies, start + (10 * HZ))) {
0103             BNX2FC_ELS_DBG("rrq Failed\n");
0104             rc = FAILED;
0105             goto rrq_err;
0106         }
0107         msleep(20);
0108         goto retry_rrq;
0109     }
0110 rrq_err:
0111     if (rc) {
0112         BNX2FC_ELS_DBG("RRQ failed - release orig io req 0x%x\n",
0113             aborted_io_req->xid);
0114         kfree(cb_arg);
0115         spin_lock_bh(&tgt->tgt_lock);
0116         kref_put(&aborted_io_req->refcount, bnx2fc_cmd_release);
0117         spin_unlock_bh(&tgt->tgt_lock);
0118     }
0119     return rc;
0120 }
0121 
0122 static void bnx2fc_l2_els_compl(struct bnx2fc_els_cb_arg *cb_arg)
0123 {
0124     struct bnx2fc_cmd *els_req;
0125     struct bnx2fc_rport *tgt;
0126     struct bnx2fc_mp_req *mp_req;
0127     struct fc_frame_header *fc_hdr;
0128     unsigned char *buf;
0129     void *resp_buf;
0130     u32 resp_len, hdr_len;
0131     u16 l2_oxid;
0132     int frame_len;
0133     int rc = 0;
0134 
0135     l2_oxid = cb_arg->l2_oxid;
0136     BNX2FC_ELS_DBG("ELS COMPL - l2_oxid = 0x%x\n", l2_oxid);
0137 
0138     els_req = cb_arg->io_req;
0139     if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &els_req->req_flags)) {
0140         /*
0141          * els req is timed out. cleanup the IO with FW and
0142          * drop the completion. libfc will handle the els timeout
0143          */
0144         if (els_req->on_active_queue) {
0145             list_del_init(&els_req->link);
0146             els_req->on_active_queue = 0;
0147             rc = bnx2fc_initiate_cleanup(els_req);
0148             BUG_ON(rc);
0149         }
0150         goto free_arg;
0151     }
0152 
0153     tgt = els_req->tgt;
0154     mp_req = &(els_req->mp_req);
0155     fc_hdr = &(mp_req->resp_fc_hdr);
0156     resp_len = mp_req->resp_len;
0157     resp_buf = mp_req->resp_buf;
0158 
0159     buf = kzalloc(PAGE_SIZE, GFP_ATOMIC);
0160     if (!buf) {
0161         printk(KERN_ERR PFX "Unable to alloc mp buf\n");
0162         goto free_arg;
0163     }
0164     hdr_len = sizeof(*fc_hdr);
0165     if (hdr_len + resp_len > PAGE_SIZE) {
0166         printk(KERN_ERR PFX "l2_els_compl: resp len is "
0167                     "beyond page size\n");
0168         goto free_buf;
0169     }
0170     memcpy(buf, fc_hdr, hdr_len);
0171     memcpy(buf + hdr_len, resp_buf, resp_len);
0172     frame_len = hdr_len + resp_len;
0173 
0174     bnx2fc_process_l2_frame_compl(tgt, buf, frame_len, l2_oxid);
0175 
0176 free_buf:
0177     kfree(buf);
0178 free_arg:
0179     kfree(cb_arg);
0180 }
0181 
0182 int bnx2fc_send_adisc(struct bnx2fc_rport *tgt, struct fc_frame *fp)
0183 {
0184     struct fc_els_adisc *adisc;
0185     struct fc_frame_header *fh;
0186     struct bnx2fc_els_cb_arg *cb_arg;
0187     struct fc_lport *lport = tgt->rdata->local_port;
0188     u32 r_a_tov = lport->r_a_tov;
0189     int rc;
0190 
0191     fh = fc_frame_header_get(fp);
0192     cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
0193     if (!cb_arg) {
0194         printk(KERN_ERR PFX "Unable to allocate cb_arg for ADISC\n");
0195         return -ENOMEM;
0196     }
0197 
0198     cb_arg->l2_oxid = ntohs(fh->fh_ox_id);
0199 
0200     BNX2FC_ELS_DBG("send ADISC: l2_oxid = 0x%x\n", cb_arg->l2_oxid);
0201     adisc = fc_frame_payload_get(fp, sizeof(*adisc));
0202     /* adisc is initialized by libfc */
0203     rc = bnx2fc_initiate_els(tgt, ELS_ADISC, adisc, sizeof(*adisc),
0204                  bnx2fc_l2_els_compl, cb_arg, 2 * r_a_tov);
0205     if (rc)
0206         kfree(cb_arg);
0207     return rc;
0208 }
0209 
0210 int bnx2fc_send_logo(struct bnx2fc_rport *tgt, struct fc_frame *fp)
0211 {
0212     struct fc_els_logo *logo;
0213     struct fc_frame_header *fh;
0214     struct bnx2fc_els_cb_arg *cb_arg;
0215     struct fc_lport *lport = tgt->rdata->local_port;
0216     u32 r_a_tov = lport->r_a_tov;
0217     int rc;
0218 
0219     fh = fc_frame_header_get(fp);
0220     cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
0221     if (!cb_arg) {
0222         printk(KERN_ERR PFX "Unable to allocate cb_arg for LOGO\n");
0223         return -ENOMEM;
0224     }
0225 
0226     cb_arg->l2_oxid = ntohs(fh->fh_ox_id);
0227 
0228     BNX2FC_ELS_DBG("Send LOGO: l2_oxid = 0x%x\n", cb_arg->l2_oxid);
0229     logo = fc_frame_payload_get(fp, sizeof(*logo));
0230     /* logo is initialized by libfc */
0231     rc = bnx2fc_initiate_els(tgt, ELS_LOGO, logo, sizeof(*logo),
0232                  bnx2fc_l2_els_compl, cb_arg, 2 * r_a_tov);
0233     if (rc)
0234         kfree(cb_arg);
0235     return rc;
0236 }
0237 
0238 int bnx2fc_send_rls(struct bnx2fc_rport *tgt, struct fc_frame *fp)
0239 {
0240     struct fc_els_rls *rls;
0241     struct fc_frame_header *fh;
0242     struct bnx2fc_els_cb_arg *cb_arg;
0243     struct fc_lport *lport = tgt->rdata->local_port;
0244     u32 r_a_tov = lport->r_a_tov;
0245     int rc;
0246 
0247     fh = fc_frame_header_get(fp);
0248     cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
0249     if (!cb_arg) {
0250         printk(KERN_ERR PFX "Unable to allocate cb_arg for LOGO\n");
0251         return -ENOMEM;
0252     }
0253 
0254     cb_arg->l2_oxid = ntohs(fh->fh_ox_id);
0255 
0256     rls = fc_frame_payload_get(fp, sizeof(*rls));
0257     /* rls is initialized by libfc */
0258     rc = bnx2fc_initiate_els(tgt, ELS_RLS, rls, sizeof(*rls),
0259                   bnx2fc_l2_els_compl, cb_arg, 2 * r_a_tov);
0260     if (rc)
0261         kfree(cb_arg);
0262     return rc;
0263 }
0264 
0265 static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
0266 {
0267     struct bnx2fc_mp_req *mp_req;
0268     struct fc_frame_header *fc_hdr, *fh;
0269     struct bnx2fc_cmd *srr_req;
0270     struct bnx2fc_cmd *orig_io_req;
0271     struct fc_frame *fp;
0272     unsigned char *buf;
0273     void *resp_buf;
0274     u32 resp_len, hdr_len;
0275     u8 opcode;
0276     int rc = 0;
0277 
0278     orig_io_req = cb_arg->aborted_io_req;
0279     srr_req = cb_arg->io_req;
0280     if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &srr_req->req_flags)) {
0281         /* SRR timedout */
0282         BNX2FC_IO_DBG(srr_req, "srr timed out, abort "
0283                "orig_io - 0x%x\n",
0284             orig_io_req->xid);
0285         rc = bnx2fc_initiate_abts(srr_req);
0286         if (rc != SUCCESS) {
0287             BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
0288                 "failed. issue cleanup\n");
0289             bnx2fc_initiate_cleanup(srr_req);
0290         }
0291         if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags) ||
0292             test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
0293             BNX2FC_IO_DBG(srr_req, "srr_compl:xid 0x%x flags = %lx",
0294                       orig_io_req->xid, orig_io_req->req_flags);
0295             goto srr_compl_done;
0296         }
0297         orig_io_req->srr_retry++;
0298         if (orig_io_req->srr_retry <= SRR_RETRY_COUNT) {
0299             struct bnx2fc_rport *tgt = orig_io_req->tgt;
0300             spin_unlock_bh(&tgt->tgt_lock);
0301             rc = bnx2fc_send_srr(orig_io_req,
0302                          orig_io_req->srr_offset,
0303                          orig_io_req->srr_rctl);
0304             spin_lock_bh(&tgt->tgt_lock);
0305             if (!rc)
0306                 goto srr_compl_done;
0307         }
0308 
0309         rc = bnx2fc_initiate_abts(orig_io_req);
0310         if (rc != SUCCESS) {
0311             BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
0312                 "failed xid = 0x%x. issue cleanup\n",
0313                 orig_io_req->xid);
0314             bnx2fc_initiate_cleanup(orig_io_req);
0315         }
0316         goto srr_compl_done;
0317     }
0318     if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags) ||
0319         test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
0320         BNX2FC_IO_DBG(srr_req, "srr_compl:xid - 0x%x flags = %lx",
0321                   orig_io_req->xid, orig_io_req->req_flags);
0322         goto srr_compl_done;
0323     }
0324     mp_req = &(srr_req->mp_req);
0325     fc_hdr = &(mp_req->resp_fc_hdr);
0326     resp_len = mp_req->resp_len;
0327     resp_buf = mp_req->resp_buf;
0328 
0329     hdr_len = sizeof(*fc_hdr);
0330     buf = kzalloc(PAGE_SIZE, GFP_ATOMIC);
0331     if (!buf) {
0332         printk(KERN_ERR PFX "srr buf: mem alloc failure\n");
0333         goto srr_compl_done;
0334     }
0335     memcpy(buf, fc_hdr, hdr_len);
0336     memcpy(buf + hdr_len, resp_buf, resp_len);
0337 
0338     fp = fc_frame_alloc(NULL, resp_len);
0339     if (!fp) {
0340         printk(KERN_ERR PFX "fc_frame_alloc failure\n");
0341         goto free_buf;
0342     }
0343 
0344     fh = (struct fc_frame_header *) fc_frame_header_get(fp);
0345     /* Copy FC Frame header and payload into the frame */
0346     memcpy(fh, buf, hdr_len + resp_len);
0347 
0348     opcode = fc_frame_payload_op(fp);
0349     switch (opcode) {
0350     case ELS_LS_ACC:
0351         BNX2FC_IO_DBG(srr_req, "SRR success\n");
0352         break;
0353     case ELS_LS_RJT:
0354         BNX2FC_IO_DBG(srr_req, "SRR rejected\n");
0355         rc = bnx2fc_initiate_abts(orig_io_req);
0356         if (rc != SUCCESS) {
0357             BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
0358                 "failed xid = 0x%x. issue cleanup\n",
0359                 orig_io_req->xid);
0360             bnx2fc_initiate_cleanup(orig_io_req);
0361         }
0362         break;
0363     default:
0364         BNX2FC_IO_DBG(srr_req, "srr compl - invalid opcode = %d\n",
0365             opcode);
0366         break;
0367     }
0368     fc_frame_free(fp);
0369 free_buf:
0370     kfree(buf);
0371 srr_compl_done:
0372     kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
0373 }
0374 
0375 static void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg)
0376 {
0377     struct bnx2fc_cmd *orig_io_req, *new_io_req;
0378     struct bnx2fc_cmd *rec_req;
0379     struct bnx2fc_mp_req *mp_req;
0380     struct fc_frame_header *fc_hdr, *fh;
0381     struct fc_els_ls_rjt *rjt;
0382     struct fc_els_rec_acc *acc;
0383     struct bnx2fc_rport *tgt;
0384     struct fcoe_err_report_entry *err_entry;
0385     struct scsi_cmnd *sc_cmd;
0386     enum fc_rctl r_ctl;
0387     unsigned char *buf;
0388     void *resp_buf;
0389     struct fc_frame *fp;
0390     u8 opcode;
0391     u32 offset;
0392     u32 e_stat;
0393     u32 resp_len, hdr_len;
0394     int rc = 0;
0395     bool send_seq_clnp = false;
0396     bool abort_io = false;
0397 
0398     BNX2FC_MISC_DBG("Entered rec_compl callback\n");
0399     rec_req = cb_arg->io_req;
0400     orig_io_req = cb_arg->aborted_io_req;
0401     BNX2FC_IO_DBG(rec_req, "rec_compl: orig xid = 0x%x", orig_io_req->xid);
0402     tgt = orig_io_req->tgt;
0403 
0404     /* Handle REC timeout case */
0405     if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rec_req->req_flags)) {
0406         BNX2FC_IO_DBG(rec_req, "timed out, abort "
0407                "orig_io - 0x%x\n",
0408             orig_io_req->xid);
0409         /* els req is timed out. send abts for els */
0410         rc = bnx2fc_initiate_abts(rec_req);
0411         if (rc != SUCCESS) {
0412             BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
0413                 "failed. issue cleanup\n");
0414             bnx2fc_initiate_cleanup(rec_req);
0415         }
0416         orig_io_req->rec_retry++;
0417         /* REC timedout. send ABTS to the orig IO req */
0418         if (orig_io_req->rec_retry <= REC_RETRY_COUNT) {
0419             spin_unlock_bh(&tgt->tgt_lock);
0420             rc = bnx2fc_send_rec(orig_io_req);
0421             spin_lock_bh(&tgt->tgt_lock);
0422             if (!rc)
0423                 goto rec_compl_done;
0424         }
0425         rc = bnx2fc_initiate_abts(orig_io_req);
0426         if (rc != SUCCESS) {
0427             BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
0428                 "failed xid = 0x%x. issue cleanup\n",
0429                 orig_io_req->xid);
0430             bnx2fc_initiate_cleanup(orig_io_req);
0431         }
0432         goto rec_compl_done;
0433     }
0434 
0435     if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) {
0436         BNX2FC_IO_DBG(rec_req, "completed"
0437                "orig_io - 0x%x\n",
0438             orig_io_req->xid);
0439         goto rec_compl_done;
0440     }
0441     if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
0442         BNX2FC_IO_DBG(rec_req, "abts in prog "
0443                "orig_io - 0x%x\n",
0444             orig_io_req->xid);
0445         goto rec_compl_done;
0446     }
0447 
0448     mp_req = &(rec_req->mp_req);
0449     fc_hdr = &(mp_req->resp_fc_hdr);
0450     resp_len = mp_req->resp_len;
0451     acc = resp_buf = mp_req->resp_buf;
0452 
0453     hdr_len = sizeof(*fc_hdr);
0454 
0455     buf = kzalloc(PAGE_SIZE, GFP_ATOMIC);
0456     if (!buf) {
0457         printk(KERN_ERR PFX "rec buf: mem alloc failure\n");
0458         goto rec_compl_done;
0459     }
0460     memcpy(buf, fc_hdr, hdr_len);
0461     memcpy(buf + hdr_len, resp_buf, resp_len);
0462 
0463     fp = fc_frame_alloc(NULL, resp_len);
0464     if (!fp) {
0465         printk(KERN_ERR PFX "fc_frame_alloc failure\n");
0466         goto free_buf;
0467     }
0468 
0469     fh = (struct fc_frame_header *) fc_frame_header_get(fp);
0470     /* Copy FC Frame header and payload into the frame */
0471     memcpy(fh, buf, hdr_len + resp_len);
0472 
0473     opcode = fc_frame_payload_op(fp);
0474     if (opcode == ELS_LS_RJT) {
0475         BNX2FC_IO_DBG(rec_req, "opcode is RJT\n");
0476         rjt = fc_frame_payload_get(fp, sizeof(*rjt));
0477         if ((rjt->er_reason == ELS_RJT_LOGIC ||
0478             rjt->er_reason == ELS_RJT_UNAB) &&
0479             rjt->er_explan == ELS_EXPL_OXID_RXID) {
0480             BNX2FC_IO_DBG(rec_req, "handle CMD LOST case\n");
0481             new_io_req = bnx2fc_cmd_alloc(tgt);
0482             if (!new_io_req)
0483                 goto abort_io;
0484             new_io_req->sc_cmd = orig_io_req->sc_cmd;
0485             /* cleanup orig_io_req that is with the FW */
0486             set_bit(BNX2FC_FLAG_CMD_LOST,
0487                 &orig_io_req->req_flags);
0488             bnx2fc_initiate_cleanup(orig_io_req);
0489             /* Post a new IO req with the same sc_cmd */
0490             BNX2FC_IO_DBG(rec_req, "Post IO request again\n");
0491             rc = bnx2fc_post_io_req(tgt, new_io_req);
0492             if (!rc)
0493                 goto free_frame;
0494             BNX2FC_IO_DBG(rec_req, "REC: io post err\n");
0495         }
0496 abort_io:
0497         rc = bnx2fc_initiate_abts(orig_io_req);
0498         if (rc != SUCCESS) {
0499             BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
0500                 "failed. issue cleanup\n");
0501             bnx2fc_initiate_cleanup(orig_io_req);
0502         }
0503     } else if (opcode == ELS_LS_ACC) {
0504         /* REVISIT: Check if the exchange is already aborted */
0505         offset = ntohl(acc->reca_fc4value);
0506         e_stat = ntohl(acc->reca_e_stat);
0507         if (e_stat & ESB_ST_SEQ_INIT)  {
0508             BNX2FC_IO_DBG(rec_req, "target has the seq init\n");
0509             goto free_frame;
0510         }
0511         BNX2FC_IO_DBG(rec_req, "e_stat = 0x%x, offset = 0x%x\n",
0512             e_stat, offset);
0513         /* Seq initiative is with us */
0514         err_entry = (struct fcoe_err_report_entry *)
0515                  &orig_io_req->err_entry;
0516         sc_cmd = orig_io_req->sc_cmd;
0517         if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
0518             /* SCSI WRITE command */
0519             if (offset == orig_io_req->data_xfer_len) {
0520                 BNX2FC_IO_DBG(rec_req, "WRITE - resp lost\n");
0521                 /* FCP_RSP lost */
0522                 r_ctl = FC_RCTL_DD_CMD_STATUS;
0523                 offset = 0;
0524             } else  {
0525                 /* start transmitting from offset */
0526                 BNX2FC_IO_DBG(rec_req, "XFER_RDY/DATA lost\n");
0527                 send_seq_clnp = true;
0528                 r_ctl = FC_RCTL_DD_DATA_DESC;
0529                 if (bnx2fc_initiate_seq_cleanup(orig_io_req,
0530                                 offset, r_ctl))
0531                     abort_io = true;
0532                 /* XFER_RDY */
0533             }
0534         } else {
0535             /* SCSI READ command */
0536             if (err_entry->data.rx_buf_off ==
0537                     orig_io_req->data_xfer_len) {
0538                 /* FCP_RSP lost */
0539                 BNX2FC_IO_DBG(rec_req, "READ - resp lost\n");
0540                 r_ctl = FC_RCTL_DD_CMD_STATUS;
0541                 offset = 0;
0542             } else  {
0543                 /* request retransmission from this offset */
0544                 send_seq_clnp = true;
0545                 offset = err_entry->data.rx_buf_off;
0546                 BNX2FC_IO_DBG(rec_req, "RD DATA lost\n");
0547                 /* FCP_DATA lost */
0548                 r_ctl = FC_RCTL_DD_SOL_DATA;
0549                 if (bnx2fc_initiate_seq_cleanup(orig_io_req,
0550                                 offset, r_ctl))
0551                     abort_io = true;
0552             }
0553         }
0554         if (abort_io) {
0555             rc = bnx2fc_initiate_abts(orig_io_req);
0556             if (rc != SUCCESS) {
0557                 BNX2FC_IO_DBG(rec_req, "rec_compl:initiate_abts"
0558                           " failed. issue cleanup\n");
0559                 bnx2fc_initiate_cleanup(orig_io_req);
0560             }
0561         } else if (!send_seq_clnp) {
0562             BNX2FC_IO_DBG(rec_req, "Send SRR - FCP_RSP\n");
0563             spin_unlock_bh(&tgt->tgt_lock);
0564             rc = bnx2fc_send_srr(orig_io_req, offset, r_ctl);
0565             spin_lock_bh(&tgt->tgt_lock);
0566 
0567             if (rc) {
0568                 BNX2FC_IO_DBG(rec_req, "Unable to send SRR"
0569                     " IO will abort\n");
0570             }
0571         }
0572     }
0573 free_frame:
0574     fc_frame_free(fp);
0575 free_buf:
0576     kfree(buf);
0577 rec_compl_done:
0578     kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
0579     kfree(cb_arg);
0580 }
0581 
0582 int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req)
0583 {
0584     struct fc_els_rec rec;
0585     struct bnx2fc_rport *tgt = orig_io_req->tgt;
0586     struct fc_lport *lport = tgt->rdata->local_port;
0587     struct bnx2fc_els_cb_arg *cb_arg = NULL;
0588     u32 sid = tgt->sid;
0589     u32 r_a_tov = lport->r_a_tov;
0590     int rc;
0591 
0592     BNX2FC_IO_DBG(orig_io_req, "Sending REC\n");
0593     memset(&rec, 0, sizeof(rec));
0594 
0595     cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
0596     if (!cb_arg) {
0597         printk(KERN_ERR PFX "Unable to allocate cb_arg for REC\n");
0598         rc = -ENOMEM;
0599         goto rec_err;
0600     }
0601     kref_get(&orig_io_req->refcount);
0602 
0603     cb_arg->aborted_io_req = orig_io_req;
0604 
0605     rec.rec_cmd = ELS_REC;
0606     hton24(rec.rec_s_id, sid);
0607     rec.rec_ox_id = htons(orig_io_req->xid);
0608     rec.rec_rx_id = htons(orig_io_req->task->rxwr_txrd.var_ctx.rx_id);
0609 
0610     rc = bnx2fc_initiate_els(tgt, ELS_REC, &rec, sizeof(rec),
0611                  bnx2fc_rec_compl, cb_arg,
0612                  r_a_tov);
0613     if (rc) {
0614         BNX2FC_IO_DBG(orig_io_req, "REC failed - release\n");
0615         spin_lock_bh(&tgt->tgt_lock);
0616         kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
0617         spin_unlock_bh(&tgt->tgt_lock);
0618         kfree(cb_arg);
0619     }
0620 rec_err:
0621     return rc;
0622 }
0623 
0624 int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl)
0625 {
0626     struct fcp_srr srr;
0627     struct bnx2fc_rport *tgt = orig_io_req->tgt;
0628     struct fc_lport *lport = tgt->rdata->local_port;
0629     struct bnx2fc_els_cb_arg *cb_arg = NULL;
0630     u32 r_a_tov = lport->r_a_tov;
0631     int rc;
0632 
0633     BNX2FC_IO_DBG(orig_io_req, "Sending SRR\n");
0634     memset(&srr, 0, sizeof(srr));
0635 
0636     cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
0637     if (!cb_arg) {
0638         printk(KERN_ERR PFX "Unable to allocate cb_arg for SRR\n");
0639         rc = -ENOMEM;
0640         goto srr_err;
0641     }
0642     kref_get(&orig_io_req->refcount);
0643 
0644     cb_arg->aborted_io_req = orig_io_req;
0645 
0646     srr.srr_op = ELS_SRR;
0647     srr.srr_ox_id = htons(orig_io_req->xid);
0648     srr.srr_rx_id = htons(orig_io_req->task->rxwr_txrd.var_ctx.rx_id);
0649     srr.srr_rel_off = htonl(offset);
0650     srr.srr_r_ctl = r_ctl;
0651     orig_io_req->srr_offset = offset;
0652     orig_io_req->srr_rctl = r_ctl;
0653 
0654     rc = bnx2fc_initiate_els(tgt, ELS_SRR, &srr, sizeof(srr),
0655                  bnx2fc_srr_compl, cb_arg,
0656                  r_a_tov);
0657     if (rc) {
0658         BNX2FC_IO_DBG(orig_io_req, "SRR failed - release\n");
0659         spin_lock_bh(&tgt->tgt_lock);
0660         kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
0661         spin_unlock_bh(&tgt->tgt_lock);
0662         kfree(cb_arg);
0663     } else
0664         set_bit(BNX2FC_FLAG_SRR_SENT, &orig_io_req->req_flags);
0665 
0666 srr_err:
0667     return rc;
0668 }
0669 
0670 static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
0671             void *data, u32 data_len,
0672             void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg),
0673             struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec)
0674 {
0675     struct fcoe_port *port = tgt->port;
0676     struct bnx2fc_interface *interface = port->priv;
0677     struct fc_rport *rport = tgt->rport;
0678     struct fc_lport *lport = port->lport;
0679     struct bnx2fc_cmd *els_req;
0680     struct bnx2fc_mp_req *mp_req;
0681     struct fc_frame_header *fc_hdr;
0682     struct fcoe_task_ctx_entry *task;
0683     struct fcoe_task_ctx_entry *task_page;
0684     int rc = 0;
0685     int task_idx, index;
0686     u32 did, sid;
0687     u16 xid;
0688 
0689     rc = fc_remote_port_chkready(rport);
0690     if (rc) {
0691         printk(KERN_ERR PFX "els 0x%x: rport not ready\n", op);
0692         rc = -EINVAL;
0693         goto els_err;
0694     }
0695     if (lport->state != LPORT_ST_READY || !(lport->link_up)) {
0696         printk(KERN_ERR PFX "els 0x%x: link is not ready\n", op);
0697         rc = -EINVAL;
0698         goto els_err;
0699     }
0700     if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) {
0701         printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op);
0702         rc = -EINVAL;
0703         goto els_err;
0704     }
0705     els_req = bnx2fc_elstm_alloc(tgt, BNX2FC_ELS);
0706     if (!els_req) {
0707         rc = -ENOMEM;
0708         goto els_err;
0709     }
0710 
0711     els_req->sc_cmd = NULL;
0712     els_req->port = port;
0713     els_req->tgt = tgt;
0714     els_req->cb_func = cb_func;
0715     cb_arg->io_req = els_req;
0716     els_req->cb_arg = cb_arg;
0717     els_req->data_xfer_len = data_len;
0718 
0719     mp_req = (struct bnx2fc_mp_req *)&(els_req->mp_req);
0720     rc = bnx2fc_init_mp_req(els_req);
0721     if (rc == FAILED) {
0722         printk(KERN_ERR PFX "ELS MP request init failed\n");
0723         spin_lock_bh(&tgt->tgt_lock);
0724         kref_put(&els_req->refcount, bnx2fc_cmd_release);
0725         spin_unlock_bh(&tgt->tgt_lock);
0726         rc = -ENOMEM;
0727         goto els_err;
0728     } else {
0729         /* rc SUCCESS */
0730         rc = 0;
0731     }
0732 
0733     /* Set the data_xfer_len to the size of ELS payload */
0734     mp_req->req_len = data_len;
0735     els_req->data_xfer_len = mp_req->req_len;
0736 
0737     /* Fill ELS Payload */
0738     if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS)) {
0739         memcpy(mp_req->req_buf, data, data_len);
0740     } else {
0741         printk(KERN_ERR PFX "Invalid ELS op 0x%x\n", op);
0742         els_req->cb_func = NULL;
0743         els_req->cb_arg = NULL;
0744         spin_lock_bh(&tgt->tgt_lock);
0745         kref_put(&els_req->refcount, bnx2fc_cmd_release);
0746         spin_unlock_bh(&tgt->tgt_lock);
0747         rc = -EINVAL;
0748     }
0749 
0750     if (rc)
0751         goto els_err;
0752 
0753     /* Fill FC header */
0754     fc_hdr = &(mp_req->req_fc_hdr);
0755 
0756     did = tgt->rport->port_id;
0757     sid = tgt->sid;
0758 
0759     if (op == ELS_SRR)
0760         __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS4_REQ, did, sid,
0761                    FC_TYPE_FCP, FC_FC_FIRST_SEQ |
0762                    FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
0763     else
0764         __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, did, sid,
0765                    FC_TYPE_ELS, FC_FC_FIRST_SEQ |
0766                    FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
0767 
0768     /* Obtain exchange id */
0769     xid = els_req->xid;
0770     task_idx = xid/BNX2FC_TASKS_PER_PAGE;
0771     index = xid % BNX2FC_TASKS_PER_PAGE;
0772 
0773     /* Initialize task context for this IO request */
0774     task_page = (struct fcoe_task_ctx_entry *)
0775             interface->hba->task_ctx[task_idx];
0776     task = &(task_page[index]);
0777     bnx2fc_init_mp_task(els_req, task);
0778 
0779     spin_lock_bh(&tgt->tgt_lock);
0780 
0781     if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) {
0782         printk(KERN_ERR PFX "initiate_els.. session not ready\n");
0783         els_req->cb_func = NULL;
0784         els_req->cb_arg = NULL;
0785         kref_put(&els_req->refcount, bnx2fc_cmd_release);
0786         spin_unlock_bh(&tgt->tgt_lock);
0787         return -EINVAL;
0788     }
0789 
0790     if (timer_msec)
0791         bnx2fc_cmd_timer_set(els_req, timer_msec);
0792     bnx2fc_add_2_sq(tgt, xid);
0793 
0794     els_req->on_active_queue = 1;
0795     list_add_tail(&els_req->link, &tgt->els_queue);
0796 
0797     /* Ring doorbell */
0798     bnx2fc_ring_doorbell(tgt);
0799     spin_unlock_bh(&tgt->tgt_lock);
0800 
0801 els_err:
0802     return rc;
0803 }
0804 
0805 void bnx2fc_process_els_compl(struct bnx2fc_cmd *els_req,
0806                   struct fcoe_task_ctx_entry *task, u8 num_rq)
0807 {
0808     struct bnx2fc_mp_req *mp_req;
0809     struct fc_frame_header *fc_hdr;
0810     u64 *hdr;
0811     u64 *temp_hdr;
0812 
0813     BNX2FC_ELS_DBG("Entered process_els_compl xid = 0x%x"
0814             "cmd_type = %d\n", els_req->xid, els_req->cmd_type);
0815 
0816     if (test_and_set_bit(BNX2FC_FLAG_ELS_DONE,
0817                  &els_req->req_flags)) {
0818         BNX2FC_ELS_DBG("Timer context finished processing this "
0819                "els - 0x%x\n", els_req->xid);
0820         /* This IO doesn't receive cleanup completion */
0821         kref_put(&els_req->refcount, bnx2fc_cmd_release);
0822         return;
0823     }
0824 
0825     /* Cancel the timeout_work, as we received the response */
0826     if (cancel_delayed_work(&els_req->timeout_work))
0827         kref_put(&els_req->refcount,
0828              bnx2fc_cmd_release); /* drop timer hold */
0829 
0830     if (els_req->on_active_queue) {
0831         list_del_init(&els_req->link);
0832         els_req->on_active_queue = 0;
0833     }
0834 
0835     mp_req = &(els_req->mp_req);
0836     fc_hdr = &(mp_req->resp_fc_hdr);
0837 
0838     hdr = (u64 *)fc_hdr;
0839     temp_hdr = (u64 *)
0840         &task->rxwr_only.union_ctx.comp_info.mp_rsp.fc_hdr;
0841     hdr[0] = cpu_to_be64(temp_hdr[0]);
0842     hdr[1] = cpu_to_be64(temp_hdr[1]);
0843     hdr[2] = cpu_to_be64(temp_hdr[2]);
0844 
0845     mp_req->resp_len =
0846         task->rxwr_only.union_ctx.comp_info.mp_rsp.mp_payload_len;
0847 
0848     /* Parse ELS response */
0849     if ((els_req->cb_func) && (els_req->cb_arg)) {
0850         els_req->cb_func(els_req->cb_arg);
0851         els_req->cb_arg = NULL;
0852     }
0853 
0854     kref_put(&els_req->refcount, bnx2fc_cmd_release);
0855 }
0856 
0857 #define     BNX2FC_FCOE_MAC_METHOD_GRANGED_MAC  1
0858 #define     BNX2FC_FCOE_MAC_METHOD_FCF_MAP      2
0859 #define     BNX2FC_FCOE_MAC_METHOD_FCOE_SET_MAC 3
0860 static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp,
0861                   void *arg)
0862 {
0863     struct fcoe_ctlr *fip = arg;
0864     struct fc_exch *exch = fc_seq_exch(seq);
0865     struct fc_lport *lport = exch->lp;
0866 
0867     struct fc_frame_header *fh;
0868     u8 *granted_mac;
0869     u8 fcoe_mac[6];
0870     u8 fc_map[3];
0871     int method;
0872 
0873     if (IS_ERR(fp))
0874         goto done;
0875 
0876     fh = fc_frame_header_get(fp);
0877     granted_mac = fr_cb(fp)->granted_mac;
0878 
0879     /*
0880      * We set the source MAC for FCoE traffic based on the Granted MAC
0881      * address from the switch.
0882      *
0883      * If granted_mac is non-zero, we use that.
0884      * If the granted_mac is zeroed out, create the FCoE MAC based on
0885      * the sel_fcf->fc_map and the d_id fo the FLOGI frame.
0886      * If sel_fcf->fc_map is 0, then we use the default FCF-MAC plus the
0887      * d_id of the FLOGI frame.
0888      */
0889     if (!is_zero_ether_addr(granted_mac)) {
0890         ether_addr_copy(fcoe_mac, granted_mac);
0891         method = BNX2FC_FCOE_MAC_METHOD_GRANGED_MAC;
0892     } else if (fip->sel_fcf && fip->sel_fcf->fc_map != 0) {
0893         hton24(fc_map, fip->sel_fcf->fc_map);
0894         fcoe_mac[0] = fc_map[0];
0895         fcoe_mac[1] = fc_map[1];
0896         fcoe_mac[2] = fc_map[2];
0897         fcoe_mac[3] = fh->fh_d_id[0];
0898         fcoe_mac[4] = fh->fh_d_id[1];
0899         fcoe_mac[5] = fh->fh_d_id[2];
0900         method = BNX2FC_FCOE_MAC_METHOD_FCF_MAP;
0901     } else {
0902         fc_fcoe_set_mac(fcoe_mac, fh->fh_d_id);
0903         method = BNX2FC_FCOE_MAC_METHOD_FCOE_SET_MAC;
0904     }
0905 
0906     BNX2FC_HBA_DBG(lport, "fcoe_mac=%pM method=%d\n", fcoe_mac, method);
0907     fip->update_mac(lport, fcoe_mac);
0908 done:
0909     fc_lport_flogi_resp(seq, fp, lport);
0910 }
0911 
0912 static void bnx2fc_logo_resp(struct fc_seq *seq, struct fc_frame *fp,
0913                  void *arg)
0914 {
0915     struct fcoe_ctlr *fip = arg;
0916     struct fc_exch *exch = fc_seq_exch(seq);
0917     struct fc_lport *lport = exch->lp;
0918     static u8 zero_mac[ETH_ALEN] = { 0 };
0919 
0920     if (!IS_ERR(fp))
0921         fip->update_mac(lport, zero_mac);
0922     fc_lport_logo_resp(seq, fp, lport);
0923 }
0924 
0925 struct fc_seq *bnx2fc_elsct_send(struct fc_lport *lport, u32 did,
0926                       struct fc_frame *fp, unsigned int op,
0927                       void (*resp)(struct fc_seq *,
0928                            struct fc_frame *,
0929                            void *),
0930                       void *arg, u32 timeout)
0931 {
0932     struct fcoe_port *port = lport_priv(lport);
0933     struct bnx2fc_interface *interface = port->priv;
0934     struct fcoe_ctlr *fip = bnx2fc_to_ctlr(interface);
0935     struct fc_frame_header *fh = fc_frame_header_get(fp);
0936 
0937     switch (op) {
0938     case ELS_FLOGI:
0939     case ELS_FDISC:
0940         return fc_elsct_send(lport, did, fp, op, bnx2fc_flogi_resp,
0941                      fip, timeout);
0942     case ELS_LOGO:
0943         /* only hook onto fabric logouts, not port logouts */
0944         if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
0945             break;
0946         return fc_elsct_send(lport, did, fp, op, bnx2fc_logo_resp,
0947                      fip, timeout);
0948     }
0949     return fc_elsct_send(lport, did, fp, op, resp, arg, timeout);
0950 }