]> Pileus Git - ~andy/linux/blob - drivers/scsi/bnx2fc/bnx2fc_els.c
Merge branch 'omap_clock_fixes_3.2' of git://git.pwsan.com/linux-2.6 into fixes
[~andy/linux] / drivers / scsi / bnx2fc / bnx2fc_els.c
1 /*
2  * bnx2fc_els.c: Broadcom NetXtreme II Linux FCoE offload driver.
3  * This file contains helper routines that handle ELS requests
4  * and responses.
5  *
6  * Copyright (c) 2008 - 2011 Broadcom Corporation
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation.
11  *
12  * Written by: Bhanu Prakash Gollapudi (bprakash@broadcom.com)
13  */
14
15 #include "bnx2fc.h"
16
17 static void bnx2fc_logo_resp(struct fc_seq *seq, struct fc_frame *fp,
18                              void *arg);
19 static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp,
20                               void *arg);
21 static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
22                         void *data, u32 data_len,
23                         void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg),
24                         struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec);
25
26 static void bnx2fc_rrq_compl(struct bnx2fc_els_cb_arg *cb_arg)
27 {
28         struct bnx2fc_cmd *orig_io_req;
29         struct bnx2fc_cmd *rrq_req;
30         int rc = 0;
31
32         BUG_ON(!cb_arg);
33         rrq_req = cb_arg->io_req;
34         orig_io_req = cb_arg->aborted_io_req;
35         BUG_ON(!orig_io_req);
36         BNX2FC_ELS_DBG("rrq_compl: orig xid = 0x%x, rrq_xid = 0x%x\n",
37                    orig_io_req->xid, rrq_req->xid);
38
39         kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
40
41         if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rrq_req->req_flags)) {
42                 /*
43                  * els req is timed out. cleanup the IO with FW and
44                  * drop the completion. Remove from active_cmd_queue.
45                  */
46                 BNX2FC_ELS_DBG("rrq xid - 0x%x timed out, clean it up\n",
47                            rrq_req->xid);
48
49                 if (rrq_req->on_active_queue) {
50                         list_del_init(&rrq_req->link);
51                         rrq_req->on_active_queue = 0;
52                         rc = bnx2fc_initiate_cleanup(rrq_req);
53                         BUG_ON(rc);
54                 }
55         }
56         kfree(cb_arg);
57 }
58 int bnx2fc_send_rrq(struct bnx2fc_cmd *aborted_io_req)
59 {
60
61         struct fc_els_rrq rrq;
62         struct bnx2fc_rport *tgt = aborted_io_req->tgt;
63         struct fc_lport *lport = tgt->rdata->local_port;
64         struct bnx2fc_els_cb_arg *cb_arg = NULL;
65         u32 sid = tgt->sid;
66         u32 r_a_tov = lport->r_a_tov;
67         unsigned long start = jiffies;
68         int rc;
69
70         BNX2FC_ELS_DBG("Sending RRQ orig_xid = 0x%x\n",
71                    aborted_io_req->xid);
72         memset(&rrq, 0, sizeof(rrq));
73
74         cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_NOIO);
75         if (!cb_arg) {
76                 printk(KERN_ERR PFX "Unable to allocate cb_arg for RRQ\n");
77                 rc = -ENOMEM;
78                 goto rrq_err;
79         }
80
81         cb_arg->aborted_io_req = aborted_io_req;
82
83         rrq.rrq_cmd = ELS_RRQ;
84         hton24(rrq.rrq_s_id, sid);
85         rrq.rrq_ox_id = htons(aborted_io_req->xid);
86         rrq.rrq_rx_id = htons(aborted_io_req->task->rxwr_txrd.var_ctx.rx_id);
87
88 retry_rrq:
89         rc = bnx2fc_initiate_els(tgt, ELS_RRQ, &rrq, sizeof(rrq),
90                                  bnx2fc_rrq_compl, cb_arg,
91                                  r_a_tov);
92         if (rc == -ENOMEM) {
93                 if (time_after(jiffies, start + (10 * HZ))) {
94                         BNX2FC_ELS_DBG("rrq Failed\n");
95                         rc = FAILED;
96                         goto rrq_err;
97                 }
98                 msleep(20);
99                 goto retry_rrq;
100         }
101 rrq_err:
102         if (rc) {
103                 BNX2FC_ELS_DBG("RRQ failed - release orig io req 0x%x\n",
104                         aborted_io_req->xid);
105                 kfree(cb_arg);
106                 spin_lock_bh(&tgt->tgt_lock);
107                 kref_put(&aborted_io_req->refcount, bnx2fc_cmd_release);
108                 spin_unlock_bh(&tgt->tgt_lock);
109         }
110         return rc;
111 }
112
113 static void bnx2fc_l2_els_compl(struct bnx2fc_els_cb_arg *cb_arg)
114 {
115         struct bnx2fc_cmd *els_req;
116         struct bnx2fc_rport *tgt;
117         struct bnx2fc_mp_req *mp_req;
118         struct fc_frame_header *fc_hdr;
119         unsigned char *buf;
120         void *resp_buf;
121         u32 resp_len, hdr_len;
122         u16 l2_oxid;
123         int frame_len;
124         int rc = 0;
125
126         l2_oxid = cb_arg->l2_oxid;
127         BNX2FC_ELS_DBG("ELS COMPL - l2_oxid = 0x%x\n", l2_oxid);
128
129         els_req = cb_arg->io_req;
130         if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &els_req->req_flags)) {
131                 /*
132                  * els req is timed out. cleanup the IO with FW and
133                  * drop the completion. libfc will handle the els timeout
134                  */
135                 if (els_req->on_active_queue) {
136                         list_del_init(&els_req->link);
137                         els_req->on_active_queue = 0;
138                         rc = bnx2fc_initiate_cleanup(els_req);
139                         BUG_ON(rc);
140                 }
141                 goto free_arg;
142         }
143
144         tgt = els_req->tgt;
145         mp_req = &(els_req->mp_req);
146         fc_hdr = &(mp_req->resp_fc_hdr);
147         resp_len = mp_req->resp_len;
148         resp_buf = mp_req->resp_buf;
149
150         buf = kzalloc(PAGE_SIZE, GFP_ATOMIC);
151         if (!buf) {
152                 printk(KERN_ERR PFX "Unable to alloc mp buf\n");
153                 goto free_arg;
154         }
155         hdr_len = sizeof(*fc_hdr);
156         if (hdr_len + resp_len > PAGE_SIZE) {
157                 printk(KERN_ERR PFX "l2_els_compl: resp len is "
158                                     "beyond page size\n");
159                 goto free_buf;
160         }
161         memcpy(buf, fc_hdr, hdr_len);
162         memcpy(buf + hdr_len, resp_buf, resp_len);
163         frame_len = hdr_len + resp_len;
164
165         bnx2fc_process_l2_frame_compl(tgt, buf, frame_len, l2_oxid);
166
167 free_buf:
168         kfree(buf);
169 free_arg:
170         kfree(cb_arg);
171 }
172
173 int bnx2fc_send_adisc(struct bnx2fc_rport *tgt, struct fc_frame *fp)
174 {
175         struct fc_els_adisc *adisc;
176         struct fc_frame_header *fh;
177         struct bnx2fc_els_cb_arg *cb_arg;
178         struct fc_lport *lport = tgt->rdata->local_port;
179         u32 r_a_tov = lport->r_a_tov;
180         int rc;
181
182         fh = fc_frame_header_get(fp);
183         cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
184         if (!cb_arg) {
185                 printk(KERN_ERR PFX "Unable to allocate cb_arg for ADISC\n");
186                 return -ENOMEM;
187         }
188
189         cb_arg->l2_oxid = ntohs(fh->fh_ox_id);
190
191         BNX2FC_ELS_DBG("send ADISC: l2_oxid = 0x%x\n", cb_arg->l2_oxid);
192         adisc = fc_frame_payload_get(fp, sizeof(*adisc));
193         /* adisc is initialized by libfc */
194         rc = bnx2fc_initiate_els(tgt, ELS_ADISC, adisc, sizeof(*adisc),
195                                  bnx2fc_l2_els_compl, cb_arg, 2 * r_a_tov);
196         if (rc)
197                 kfree(cb_arg);
198         return rc;
199 }
200
201 int bnx2fc_send_logo(struct bnx2fc_rport *tgt, struct fc_frame *fp)
202 {
203         struct fc_els_logo *logo;
204         struct fc_frame_header *fh;
205         struct bnx2fc_els_cb_arg *cb_arg;
206         struct fc_lport *lport = tgt->rdata->local_port;
207         u32 r_a_tov = lport->r_a_tov;
208         int rc;
209
210         fh = fc_frame_header_get(fp);
211         cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
212         if (!cb_arg) {
213                 printk(KERN_ERR PFX "Unable to allocate cb_arg for LOGO\n");
214                 return -ENOMEM;
215         }
216
217         cb_arg->l2_oxid = ntohs(fh->fh_ox_id);
218
219         BNX2FC_ELS_DBG("Send LOGO: l2_oxid = 0x%x\n", cb_arg->l2_oxid);
220         logo = fc_frame_payload_get(fp, sizeof(*logo));
221         /* logo is initialized by libfc */
222         rc = bnx2fc_initiate_els(tgt, ELS_LOGO, logo, sizeof(*logo),
223                                  bnx2fc_l2_els_compl, cb_arg, 2 * r_a_tov);
224         if (rc)
225                 kfree(cb_arg);
226         return rc;
227 }
228
229 int bnx2fc_send_rls(struct bnx2fc_rport *tgt, struct fc_frame *fp)
230 {
231         struct fc_els_rls *rls;
232         struct fc_frame_header *fh;
233         struct bnx2fc_els_cb_arg *cb_arg;
234         struct fc_lport *lport = tgt->rdata->local_port;
235         u32 r_a_tov = lport->r_a_tov;
236         int rc;
237
238         fh = fc_frame_header_get(fp);
239         cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
240         if (!cb_arg) {
241                 printk(KERN_ERR PFX "Unable to allocate cb_arg for LOGO\n");
242                 return -ENOMEM;
243         }
244
245         cb_arg->l2_oxid = ntohs(fh->fh_ox_id);
246
247         rls = fc_frame_payload_get(fp, sizeof(*rls));
248         /* rls is initialized by libfc */
249         rc = bnx2fc_initiate_els(tgt, ELS_RLS, rls, sizeof(*rls),
250                                   bnx2fc_l2_els_compl, cb_arg, 2 * r_a_tov);
251         if (rc)
252                 kfree(cb_arg);
253         return rc;
254 }
255
256 void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
257 {
258         struct bnx2fc_mp_req *mp_req;
259         struct fc_frame_header *fc_hdr, *fh;
260         struct bnx2fc_cmd *srr_req;
261         struct bnx2fc_cmd *orig_io_req;
262         struct fc_frame *fp;
263         unsigned char *buf;
264         void *resp_buf;
265         u32 resp_len, hdr_len;
266         u8 opcode;
267         int rc = 0;
268
269         orig_io_req = cb_arg->aborted_io_req;
270         srr_req = cb_arg->io_req;
271         if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) {
272                 BNX2FC_IO_DBG(srr_req, "srr_compl: xid - 0x%x completed",
273                         orig_io_req->xid);
274                 goto srr_compl_done;
275         }
276         if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
277                 BNX2FC_IO_DBG(srr_req, "rec abts in prog "
278                        "orig_io - 0x%x\n",
279                         orig_io_req->xid);
280                 goto srr_compl_done;
281         }
282         if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &srr_req->req_flags)) {
283                 /* SRR timedout */
284                 BNX2FC_IO_DBG(srr_req, "srr timed out, abort "
285                        "orig_io - 0x%x\n",
286                         orig_io_req->xid);
287                 rc = bnx2fc_initiate_abts(srr_req);
288                 if (rc != SUCCESS) {
289                         BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
290                                 "failed. issue cleanup\n");
291                         bnx2fc_initiate_cleanup(srr_req);
292                 }
293                 orig_io_req->srr_retry++;
294                 if (orig_io_req->srr_retry <= SRR_RETRY_COUNT) {
295                         struct bnx2fc_rport *tgt = orig_io_req->tgt;
296                         spin_unlock_bh(&tgt->tgt_lock);
297                         rc = bnx2fc_send_srr(orig_io_req,
298                                              orig_io_req->srr_offset,
299                                              orig_io_req->srr_rctl);
300                         spin_lock_bh(&tgt->tgt_lock);
301                         if (!rc)
302                                 goto srr_compl_done;
303                 }
304
305                 rc = bnx2fc_initiate_abts(orig_io_req);
306                 if (rc != SUCCESS) {
307                         BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
308                                 "failed xid = 0x%x. issue cleanup\n",
309                                 orig_io_req->xid);
310                         bnx2fc_initiate_cleanup(orig_io_req);
311                 }
312                 goto srr_compl_done;
313         }
314         mp_req = &(srr_req->mp_req);
315         fc_hdr = &(mp_req->resp_fc_hdr);
316         resp_len = mp_req->resp_len;
317         resp_buf = mp_req->resp_buf;
318
319         hdr_len = sizeof(*fc_hdr);
320         buf = kzalloc(PAGE_SIZE, GFP_ATOMIC);
321         if (!buf) {
322                 printk(KERN_ERR PFX "srr buf: mem alloc failure\n");
323                 goto srr_compl_done;
324         }
325         memcpy(buf, fc_hdr, hdr_len);
326         memcpy(buf + hdr_len, resp_buf, resp_len);
327
328         fp = fc_frame_alloc(NULL, resp_len);
329         if (!fp) {
330                 printk(KERN_ERR PFX "fc_frame_alloc failure\n");
331                 goto free_buf;
332         }
333
334         fh = (struct fc_frame_header *) fc_frame_header_get(fp);
335         /* Copy FC Frame header and payload into the frame */
336         memcpy(fh, buf, hdr_len + resp_len);
337
338         opcode = fc_frame_payload_op(fp);
339         switch (opcode) {
340         case ELS_LS_ACC:
341                 BNX2FC_IO_DBG(srr_req, "SRR success\n");
342                 break;
343         case ELS_LS_RJT:
344                 BNX2FC_IO_DBG(srr_req, "SRR rejected\n");
345                 rc = bnx2fc_initiate_abts(orig_io_req);
346                 if (rc != SUCCESS) {
347                         BNX2FC_IO_DBG(srr_req, "srr_compl: initiate_abts "
348                                 "failed xid = 0x%x. issue cleanup\n",
349                                 orig_io_req->xid);
350                         bnx2fc_initiate_cleanup(orig_io_req);
351                 }
352                 break;
353         default:
354                 BNX2FC_IO_DBG(srr_req, "srr compl - invalid opcode = %d\n",
355                         opcode);
356                 break;
357         }
358         fc_frame_free(fp);
359 free_buf:
360         kfree(buf);
361 srr_compl_done:
362         kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
363 }
364
365 void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg)
366 {
367         struct bnx2fc_cmd *orig_io_req, *new_io_req;
368         struct bnx2fc_cmd *rec_req;
369         struct bnx2fc_mp_req *mp_req;
370         struct fc_frame_header *fc_hdr, *fh;
371         struct fc_els_ls_rjt *rjt;
372         struct fc_els_rec_acc *acc;
373         struct bnx2fc_rport *tgt;
374         struct fcoe_err_report_entry *err_entry;
375         struct scsi_cmnd *sc_cmd;
376         enum fc_rctl r_ctl;
377         unsigned char *buf;
378         void *resp_buf;
379         struct fc_frame *fp;
380         u8 opcode;
381         u32 offset;
382         u32 e_stat;
383         u32 resp_len, hdr_len;
384         int rc = 0;
385         bool send_seq_clnp = false;
386         bool abort_io = false;
387
388         BNX2FC_MISC_DBG("Entered rec_compl callback\n");
389         rec_req = cb_arg->io_req;
390         orig_io_req = cb_arg->aborted_io_req;
391         BNX2FC_IO_DBG(rec_req, "rec_compl: orig xid = 0x%x", orig_io_req->xid);
392         tgt = orig_io_req->tgt;
393
394         /* Handle REC timeout case */
395         if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rec_req->req_flags)) {
396                 BNX2FC_IO_DBG(rec_req, "timed out, abort "
397                        "orig_io - 0x%x\n",
398                         orig_io_req->xid);
399                 /* els req is timed out. send abts for els */
400                 rc = bnx2fc_initiate_abts(rec_req);
401                 if (rc != SUCCESS) {
402                         BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
403                                 "failed. issue cleanup\n");
404                         bnx2fc_initiate_cleanup(rec_req);
405                 }
406                 orig_io_req->rec_retry++;
407                 /* REC timedout. send ABTS to the orig IO req */
408                 if (orig_io_req->rec_retry <= REC_RETRY_COUNT) {
409                         spin_unlock_bh(&tgt->tgt_lock);
410                         rc = bnx2fc_send_rec(orig_io_req);
411                         spin_lock_bh(&tgt->tgt_lock);
412                         if (!rc)
413                                 goto rec_compl_done;
414                 }
415                 rc = bnx2fc_initiate_abts(orig_io_req);
416                 if (rc != SUCCESS) {
417                         BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
418                                 "failed xid = 0x%x. issue cleanup\n",
419                                 orig_io_req->xid);
420                         bnx2fc_initiate_cleanup(orig_io_req);
421                 }
422                 goto rec_compl_done;
423         }
424
425         if (test_bit(BNX2FC_FLAG_IO_COMPL, &orig_io_req->req_flags)) {
426                 BNX2FC_IO_DBG(rec_req, "completed"
427                        "orig_io - 0x%x\n",
428                         orig_io_req->xid);
429                 goto rec_compl_done;
430         }
431         if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &orig_io_req->req_flags)) {
432                 BNX2FC_IO_DBG(rec_req, "abts in prog "
433                        "orig_io - 0x%x\n",
434                         orig_io_req->xid);
435                 goto rec_compl_done;
436         }
437
438         mp_req = &(rec_req->mp_req);
439         fc_hdr = &(mp_req->resp_fc_hdr);
440         resp_len = mp_req->resp_len;
441         acc = resp_buf = mp_req->resp_buf;
442
443         hdr_len = sizeof(*fc_hdr);
444
445         buf = kzalloc(PAGE_SIZE, GFP_ATOMIC);
446         if (!buf) {
447                 printk(KERN_ERR PFX "rec buf: mem alloc failure\n");
448                 goto rec_compl_done;
449         }
450         memcpy(buf, fc_hdr, hdr_len);
451         memcpy(buf + hdr_len, resp_buf, resp_len);
452
453         fp = fc_frame_alloc(NULL, resp_len);
454         if (!fp) {
455                 printk(KERN_ERR PFX "fc_frame_alloc failure\n");
456                 goto free_buf;
457         }
458
459         fh = (struct fc_frame_header *) fc_frame_header_get(fp);
460         /* Copy FC Frame header and payload into the frame */
461         memcpy(fh, buf, hdr_len + resp_len);
462
463         opcode = fc_frame_payload_op(fp);
464         if (opcode == ELS_LS_RJT) {
465                 BNX2FC_IO_DBG(rec_req, "opcode is RJT\n");
466                 rjt = fc_frame_payload_get(fp, sizeof(*rjt));
467                 if ((rjt->er_reason == ELS_RJT_LOGIC ||
468                     rjt->er_reason == ELS_RJT_UNAB) &&
469                     rjt->er_explan == ELS_EXPL_OXID_RXID) {
470                         BNX2FC_IO_DBG(rec_req, "handle CMD LOST case\n");
471                         new_io_req = bnx2fc_cmd_alloc(tgt);
472                         if (!new_io_req)
473                                 goto abort_io;
474                         new_io_req->sc_cmd = orig_io_req->sc_cmd;
475                         /* cleanup orig_io_req that is with the FW */
476                         set_bit(BNX2FC_FLAG_CMD_LOST,
477                                 &orig_io_req->req_flags);
478                         bnx2fc_initiate_cleanup(orig_io_req);
479                         /* Post a new IO req with the same sc_cmd */
480                         BNX2FC_IO_DBG(rec_req, "Post IO request again\n");
481                         spin_unlock_bh(&tgt->tgt_lock);
482                         rc = bnx2fc_post_io_req(tgt, new_io_req);
483                         spin_lock_bh(&tgt->tgt_lock);
484                         if (!rc)
485                                 goto free_frame;
486                         BNX2FC_IO_DBG(rec_req, "REC: io post err\n");
487                 }
488 abort_io:
489                 rc = bnx2fc_initiate_abts(orig_io_req);
490                 if (rc != SUCCESS) {
491                         BNX2FC_IO_DBG(rec_req, "rec_compl: initiate_abts "
492                                 "failed. issue cleanup\n");
493                         bnx2fc_initiate_cleanup(orig_io_req);
494                 }
495         } else if (opcode == ELS_LS_ACC) {
496                 /* REVISIT: Check if the exchange is already aborted */
497                 offset = ntohl(acc->reca_fc4value);
498                 e_stat = ntohl(acc->reca_e_stat);
499                 if (e_stat & ESB_ST_SEQ_INIT)  {
500                         BNX2FC_IO_DBG(rec_req, "target has the seq init\n");
501                         goto free_frame;
502                 }
503                 BNX2FC_IO_DBG(rec_req, "e_stat = 0x%x, offset = 0x%x\n",
504                         e_stat, offset);
505                 /* Seq initiative is with us */
506                 err_entry = (struct fcoe_err_report_entry *)
507                              &orig_io_req->err_entry;
508                 sc_cmd = orig_io_req->sc_cmd;
509                 if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
510                         /* SCSI WRITE command */
511                         if (offset == orig_io_req->data_xfer_len) {
512                                 BNX2FC_IO_DBG(rec_req, "WRITE - resp lost\n");
513                                 /* FCP_RSP lost */
514                                 r_ctl = FC_RCTL_DD_CMD_STATUS;
515                                 offset = 0;
516                         } else  {
517                                 /* start transmitting from offset */
518                                 BNX2FC_IO_DBG(rec_req, "XFER_RDY/DATA lost\n");
519                                 send_seq_clnp = true;
520                                 r_ctl = FC_RCTL_DD_DATA_DESC;
521                                 if (bnx2fc_initiate_seq_cleanup(orig_io_req,
522                                                                 offset, r_ctl))
523                                         abort_io = true;
524                                 /* XFER_RDY */
525                         }
526                 } else {
527                         /* SCSI READ command */
528                         if (err_entry->data.rx_buf_off ==
529                                         orig_io_req->data_xfer_len) {
530                                 /* FCP_RSP lost */
531                                 BNX2FC_IO_DBG(rec_req, "READ - resp lost\n");
532                                 r_ctl = FC_RCTL_DD_CMD_STATUS;
533                                 offset = 0;
534                         } else  {
535                                 /* request retransmission from this offset */
536                                 send_seq_clnp = true;
537                                 offset = err_entry->data.rx_buf_off;
538                                 BNX2FC_IO_DBG(rec_req, "RD DATA lost\n");
539                                 /* FCP_DATA lost */
540                                 r_ctl = FC_RCTL_DD_SOL_DATA;
541                                 if (bnx2fc_initiate_seq_cleanup(orig_io_req,
542                                                                 offset, r_ctl))
543                                         abort_io = true;
544                         }
545                 }
546                 if (abort_io) {
547                         rc = bnx2fc_initiate_abts(orig_io_req);
548                         if (rc != SUCCESS) {
549                                 BNX2FC_IO_DBG(rec_req, "rec_compl:initiate_abts"
550                                               " failed. issue cleanup\n");
551                                 bnx2fc_initiate_cleanup(orig_io_req);
552                         }
553                 } else if (!send_seq_clnp) {
554                         BNX2FC_IO_DBG(rec_req, "Send SRR - FCP_RSP\n");
555                         spin_unlock_bh(&tgt->tgt_lock);
556                         rc = bnx2fc_send_srr(orig_io_req, offset, r_ctl);
557                         spin_lock_bh(&tgt->tgt_lock);
558
559                         if (rc) {
560                                 BNX2FC_IO_DBG(rec_req, "Unable to send SRR"
561                                         " IO will abort\n");
562                         }
563                 }
564         }
565 free_frame:
566         fc_frame_free(fp);
567 free_buf:
568         kfree(buf);
569 rec_compl_done:
570         kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
571         kfree(cb_arg);
572 }
573
574 int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req)
575 {
576         struct fc_els_rec rec;
577         struct bnx2fc_rport *tgt = orig_io_req->tgt;
578         struct fc_lport *lport = tgt->rdata->local_port;
579         struct bnx2fc_els_cb_arg *cb_arg = NULL;
580         u32 sid = tgt->sid;
581         u32 r_a_tov = lport->r_a_tov;
582         int rc;
583
584         BNX2FC_IO_DBG(orig_io_req, "Sending REC\n");
585         memset(&rec, 0, sizeof(rec));
586
587         cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
588         if (!cb_arg) {
589                 printk(KERN_ERR PFX "Unable to allocate cb_arg for REC\n");
590                 rc = -ENOMEM;
591                 goto rec_err;
592         }
593         kref_get(&orig_io_req->refcount);
594
595         cb_arg->aborted_io_req = orig_io_req;
596
597         rec.rec_cmd = ELS_REC;
598         hton24(rec.rec_s_id, sid);
599         rec.rec_ox_id = htons(orig_io_req->xid);
600         rec.rec_rx_id = htons(orig_io_req->task->rxwr_txrd.var_ctx.rx_id);
601
602         rc = bnx2fc_initiate_els(tgt, ELS_REC, &rec, sizeof(rec),
603                                  bnx2fc_rec_compl, cb_arg,
604                                  r_a_tov);
605 rec_err:
606         if (rc) {
607                 BNX2FC_IO_DBG(orig_io_req, "REC failed - release\n");
608                 spin_lock_bh(&tgt->tgt_lock);
609                 kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
610                 spin_unlock_bh(&tgt->tgt_lock);
611                 kfree(cb_arg);
612         }
613         return rc;
614 }
615
616 int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl)
617 {
618         struct fcp_srr srr;
619         struct bnx2fc_rport *tgt = orig_io_req->tgt;
620         struct fc_lport *lport = tgt->rdata->local_port;
621         struct bnx2fc_els_cb_arg *cb_arg = NULL;
622         u32 r_a_tov = lport->r_a_tov;
623         int rc;
624
625         BNX2FC_IO_DBG(orig_io_req, "Sending SRR\n");
626         memset(&srr, 0, sizeof(srr));
627
628         cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
629         if (!cb_arg) {
630                 printk(KERN_ERR PFX "Unable to allocate cb_arg for SRR\n");
631                 rc = -ENOMEM;
632                 goto srr_err;
633         }
634         kref_get(&orig_io_req->refcount);
635
636         cb_arg->aborted_io_req = orig_io_req;
637
638         srr.srr_op = ELS_SRR;
639         srr.srr_ox_id = htons(orig_io_req->xid);
640         srr.srr_rx_id = htons(orig_io_req->task->rxwr_txrd.var_ctx.rx_id);
641         srr.srr_rel_off = htonl(offset);
642         srr.srr_r_ctl = r_ctl;
643         orig_io_req->srr_offset = offset;
644         orig_io_req->srr_rctl = r_ctl;
645
646         rc = bnx2fc_initiate_els(tgt, ELS_SRR, &srr, sizeof(srr),
647                                  bnx2fc_srr_compl, cb_arg,
648                                  r_a_tov);
649 srr_err:
650         if (rc) {
651                 BNX2FC_IO_DBG(orig_io_req, "SRR failed - release\n");
652                 spin_lock_bh(&tgt->tgt_lock);
653                 kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
654                 spin_unlock_bh(&tgt->tgt_lock);
655                 kfree(cb_arg);
656         } else
657                 set_bit(BNX2FC_FLAG_SRR_SENT, &orig_io_req->req_flags);
658
659         return rc;
660 }
661
662 static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
663                         void *data, u32 data_len,
664                         void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg),
665                         struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec)
666 {
667         struct fcoe_port *port = tgt->port;
668         struct bnx2fc_interface *interface = port->priv;
669         struct fc_rport *rport = tgt->rport;
670         struct fc_lport *lport = port->lport;
671         struct bnx2fc_cmd *els_req;
672         struct bnx2fc_mp_req *mp_req;
673         struct fc_frame_header *fc_hdr;
674         struct fcoe_task_ctx_entry *task;
675         struct fcoe_task_ctx_entry *task_page;
676         int rc = 0;
677         int task_idx, index;
678         u32 did, sid;
679         u16 xid;
680
681         rc = fc_remote_port_chkready(rport);
682         if (rc) {
683                 printk(KERN_ERR PFX "els 0x%x: rport not ready\n", op);
684                 rc = -EINVAL;
685                 goto els_err;
686         }
687         if (lport->state != LPORT_ST_READY || !(lport->link_up)) {
688                 printk(KERN_ERR PFX "els 0x%x: link is not ready\n", op);
689                 rc = -EINVAL;
690                 goto els_err;
691         }
692         if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) ||
693              (test_bit(BNX2FC_FLAG_EXPL_LOGO, &tgt->flags))) {
694                 printk(KERN_ERR PFX "els 0x%x: tgt not ready\n", op);
695                 rc = -EINVAL;
696                 goto els_err;
697         }
698         els_req = bnx2fc_elstm_alloc(tgt, BNX2FC_ELS);
699         if (!els_req) {
700                 rc = -ENOMEM;
701                 goto els_err;
702         }
703
704         els_req->sc_cmd = NULL;
705         els_req->port = port;
706         els_req->tgt = tgt;
707         els_req->cb_func = cb_func;
708         cb_arg->io_req = els_req;
709         els_req->cb_arg = cb_arg;
710
711         mp_req = (struct bnx2fc_mp_req *)&(els_req->mp_req);
712         rc = bnx2fc_init_mp_req(els_req);
713         if (rc == FAILED) {
714                 printk(KERN_ERR PFX "ELS MP request init failed\n");
715                 spin_lock_bh(&tgt->tgt_lock);
716                 kref_put(&els_req->refcount, bnx2fc_cmd_release);
717                 spin_unlock_bh(&tgt->tgt_lock);
718                 rc = -ENOMEM;
719                 goto els_err;
720         } else {
721                 /* rc SUCCESS */
722                 rc = 0;
723         }
724
725         /* Set the data_xfer_len to the size of ELS payload */
726         mp_req->req_len = data_len;
727         els_req->data_xfer_len = mp_req->req_len;
728
729         /* Fill ELS Payload */
730         if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS)) {
731                 memcpy(mp_req->req_buf, data, data_len);
732         } else {
733                 printk(KERN_ERR PFX "Invalid ELS op 0x%x\n", op);
734                 els_req->cb_func = NULL;
735                 els_req->cb_arg = NULL;
736                 spin_lock_bh(&tgt->tgt_lock);
737                 kref_put(&els_req->refcount, bnx2fc_cmd_release);
738                 spin_unlock_bh(&tgt->tgt_lock);
739                 rc = -EINVAL;
740         }
741
742         if (rc)
743                 goto els_err;
744
745         /* Fill FC header */
746         fc_hdr = &(mp_req->req_fc_hdr);
747
748         did = tgt->rport->port_id;
749         sid = tgt->sid;
750
751         if (op == ELS_SRR)
752                 __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS4_REQ, did, sid,
753                                    FC_TYPE_FCP, FC_FC_FIRST_SEQ |
754                                    FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
755         else
756                 __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, did, sid,
757                                    FC_TYPE_ELS, FC_FC_FIRST_SEQ |
758                                    FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
759
760         /* Obtain exchange id */
761         xid = els_req->xid;
762         task_idx = xid/BNX2FC_TASKS_PER_PAGE;
763         index = xid % BNX2FC_TASKS_PER_PAGE;
764
765         /* Initialize task context for this IO request */
766         task_page = (struct fcoe_task_ctx_entry *)
767                         interface->hba->task_ctx[task_idx];
768         task = &(task_page[index]);
769         bnx2fc_init_mp_task(els_req, task);
770
771         spin_lock_bh(&tgt->tgt_lock);
772
773         if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) {
774                 printk(KERN_ERR PFX "initiate_els.. session not ready\n");
775                 els_req->cb_func = NULL;
776                 els_req->cb_arg = NULL;
777                 kref_put(&els_req->refcount, bnx2fc_cmd_release);
778                 spin_unlock_bh(&tgt->tgt_lock);
779                 return -EINVAL;
780         }
781
782         if (timer_msec)
783                 bnx2fc_cmd_timer_set(els_req, timer_msec);
784         bnx2fc_add_2_sq(tgt, xid);
785
786         els_req->on_active_queue = 1;
787         list_add_tail(&els_req->link, &tgt->els_queue);
788
789         /* Ring doorbell */
790         bnx2fc_ring_doorbell(tgt);
791         spin_unlock_bh(&tgt->tgt_lock);
792
793 els_err:
794         return rc;
795 }
796
797 void bnx2fc_process_els_compl(struct bnx2fc_cmd *els_req,
798                               struct fcoe_task_ctx_entry *task, u8 num_rq)
799 {
800         struct bnx2fc_mp_req *mp_req;
801         struct fc_frame_header *fc_hdr;
802         u64 *hdr;
803         u64 *temp_hdr;
804
805         BNX2FC_ELS_DBG("Entered process_els_compl xid = 0x%x"
806                         "cmd_type = %d\n", els_req->xid, els_req->cmd_type);
807
808         if (test_and_set_bit(BNX2FC_FLAG_ELS_DONE,
809                              &els_req->req_flags)) {
810                 BNX2FC_ELS_DBG("Timer context finished processing this "
811                            "els - 0x%x\n", els_req->xid);
812                 /* This IO doesn't receive cleanup completion */
813                 kref_put(&els_req->refcount, bnx2fc_cmd_release);
814                 return;
815         }
816
817         /* Cancel the timeout_work, as we received the response */
818         if (cancel_delayed_work(&els_req->timeout_work))
819                 kref_put(&els_req->refcount,
820                          bnx2fc_cmd_release); /* drop timer hold */
821
822         if (els_req->on_active_queue) {
823                 list_del_init(&els_req->link);
824                 els_req->on_active_queue = 0;
825         }
826
827         mp_req = &(els_req->mp_req);
828         fc_hdr = &(mp_req->resp_fc_hdr);
829
830         hdr = (u64 *)fc_hdr;
831         temp_hdr = (u64 *)
832                 &task->rxwr_only.union_ctx.comp_info.mp_rsp.fc_hdr;
833         hdr[0] = cpu_to_be64(temp_hdr[0]);
834         hdr[1] = cpu_to_be64(temp_hdr[1]);
835         hdr[2] = cpu_to_be64(temp_hdr[2]);
836
837         mp_req->resp_len =
838                 task->rxwr_only.union_ctx.comp_info.mp_rsp.mp_payload_len;
839
840         /* Parse ELS response */
841         if ((els_req->cb_func) && (els_req->cb_arg)) {
842                 els_req->cb_func(els_req->cb_arg);
843                 els_req->cb_arg = NULL;
844         }
845
846         kref_put(&els_req->refcount, bnx2fc_cmd_release);
847 }
848
849 static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp,
850                               void *arg)
851 {
852         struct fcoe_ctlr *fip = arg;
853         struct fc_exch *exch = fc_seq_exch(seq);
854         struct fc_lport *lport = exch->lp;
855         u8 *mac;
856         struct fc_frame_header *fh;
857         u8 op;
858
859         if (IS_ERR(fp))
860                 goto done;
861
862         mac = fr_cb(fp)->granted_mac;
863         if (is_zero_ether_addr(mac)) {
864                 fh = fc_frame_header_get(fp);
865                 if (fh->fh_type != FC_TYPE_ELS) {
866                         printk(KERN_ERR PFX "bnx2fc_flogi_resp:"
867                                 "fh_type != FC_TYPE_ELS\n");
868                         fc_frame_free(fp);
869                         return;
870                 }
871                 op = fc_frame_payload_op(fp);
872                 if (lport->vport) {
873                         if (op == ELS_LS_RJT) {
874                                 printk(KERN_ERR PFX "bnx2fc_flogi_resp is LS_RJT\n");
875                                 fc_vport_terminate(lport->vport);
876                                 fc_frame_free(fp);
877                                 return;
878                         }
879                 }
880                 if (fcoe_ctlr_recv_flogi(fip, lport, fp)) {
881                         fc_frame_free(fp);
882                         return;
883                 }
884         }
885         fip->update_mac(lport, mac);
886 done:
887         fc_lport_flogi_resp(seq, fp, lport);
888 }
889
890 static void bnx2fc_logo_resp(struct fc_seq *seq, struct fc_frame *fp,
891                              void *arg)
892 {
893         struct fcoe_ctlr *fip = arg;
894         struct fc_exch *exch = fc_seq_exch(seq);
895         struct fc_lport *lport = exch->lp;
896         static u8 zero_mac[ETH_ALEN] = { 0 };
897
898         if (!IS_ERR(fp))
899                 fip->update_mac(lport, zero_mac);
900         fc_lport_logo_resp(seq, fp, lport);
901 }
902
903 struct fc_seq *bnx2fc_elsct_send(struct fc_lport *lport, u32 did,
904                                       struct fc_frame *fp, unsigned int op,
905                                       void (*resp)(struct fc_seq *,
906                                                    struct fc_frame *,
907                                                    void *),
908                                       void *arg, u32 timeout)
909 {
910         struct fcoe_port *port = lport_priv(lport);
911         struct bnx2fc_interface *interface = port->priv;
912         struct fcoe_ctlr *fip = &interface->ctlr;
913         struct fc_frame_header *fh = fc_frame_header_get(fp);
914
915         switch (op) {
916         case ELS_FLOGI:
917         case ELS_FDISC:
918                 return fc_elsct_send(lport, did, fp, op, bnx2fc_flogi_resp,
919                                      fip, timeout);
920         case ELS_LOGO:
921                 /* only hook onto fabric logouts, not port logouts */
922                 if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
923                         break;
924                 return fc_elsct_send(lport, did, fp, op, bnx2fc_logo_resp,
925                                      fip, timeout);
926         }
927         return fc_elsct_send(lport, did, fp, op, resp, arg, timeout);
928 }