0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
0046
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
0142
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
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
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
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
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
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
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
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
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
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
0486 set_bit(BNX2FC_FLAG_CMD_LOST,
0487 &orig_io_req->req_flags);
0488 bnx2fc_initiate_cleanup(orig_io_req);
0489
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
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
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
0519 if (offset == orig_io_req->data_xfer_len) {
0520 BNX2FC_IO_DBG(rec_req, "WRITE - resp lost\n");
0521
0522 r_ctl = FC_RCTL_DD_CMD_STATUS;
0523 offset = 0;
0524 } else {
0525
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
0533 }
0534 } else {
0535
0536 if (err_entry->data.rx_buf_off ==
0537 orig_io_req->data_xfer_len) {
0538
0539 BNX2FC_IO_DBG(rec_req, "READ - resp lost\n");
0540 r_ctl = FC_RCTL_DD_CMD_STATUS;
0541 offset = 0;
0542 } else {
0543
0544 send_seq_clnp = true;
0545 offset = err_entry->data.rx_buf_off;
0546 BNX2FC_IO_DBG(rec_req, "RD DATA lost\n");
0547
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
0730 rc = 0;
0731 }
0732
0733
0734 mp_req->req_len = data_len;
0735 els_req->data_xfer_len = mp_req->req_len;
0736
0737
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
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
0769 xid = els_req->xid;
0770 task_idx = xid/BNX2FC_TASKS_PER_PAGE;
0771 index = xid % BNX2FC_TASKS_PER_PAGE;
0772
0773
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
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
0821 kref_put(&els_req->refcount, bnx2fc_cmd_release);
0822 return;
0823 }
0824
0825
0826 if (cancel_delayed_work(&els_req->timeout_work))
0827 kref_put(&els_req->refcount,
0828 bnx2fc_cmd_release);
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
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
0881
0882
0883
0884
0885
0886
0887
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
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 }