forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/scsi/qla2xxx/qla_init.c
....@@ -1,8 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * QLogic Fibre Channel HBA Driver
34 * Copyright (c) 2003-2014 QLogic Corporation
4
- *
5
- * See LICENSE.qla2xxx for copyright and licensing details.
65 */
76 #include "qla_def.h"
87 #include "qla_gbl.h"
....@@ -17,7 +16,6 @@
1716 #include <asm/prom.h>
1817 #endif
1918
20
-#include <target/target_core_base.h>
2119 #include "qla_target.h"
2220
2321 /*
....@@ -37,8 +35,8 @@
3735 static int qla84xx_init_chip(scsi_qla_host_t *);
3836 static int qla25xx_init_queues(struct qla_hw_data *);
3937 static int qla24xx_post_prli_work(struct scsi_qla_host*, fc_port_t *);
40
-static void qla24xx_handle_plogi_done_event(struct scsi_qla_host *,
41
- struct event_arg *);
38
+static void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha,
39
+ struct event_arg *ea);
4240 static void qla24xx_handle_prli_done_event(struct scsi_qla_host *,
4341 struct event_arg *);
4442 static void __qla24xx_handle_gpdb_event(scsi_qla_host_t *, struct event_arg *);
....@@ -50,27 +48,28 @@
5048 {
5149 srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer);
5250 struct srb_iocb *iocb;
53
- struct req_que *req;
54
- unsigned long flags;
55
- struct qla_hw_data *ha = sp->vha->hw;
5651
57
- WARN_ON_ONCE(irqs_disabled());
58
- spin_lock_irqsave(&ha->hardware_lock, flags);
59
- req = sp->qpair->req;
60
- req->outstanding_cmds[sp->handle] = NULL;
52
+ WARN_ON(irqs_disabled());
6153 iocb = &sp->u.iocb_cmd;
62
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
6354 iocb->timeout(sp);
6455 }
6556
66
-void
67
-qla2x00_sp_free(void *ptr)
57
+void qla2x00_sp_free(srb_t *sp)
6858 {
69
- srb_t *sp = ptr;
7059 struct srb_iocb *iocb = &sp->u.iocb_cmd;
7160
7261 del_timer(&iocb->timer);
7362 qla2x00_rel_sp(sp);
63
+}
64
+
65
+void qla2xxx_rel_done_warning(srb_t *sp, int res)
66
+{
67
+ WARN_ONCE(1, "Calling done() of an already freed srb %p object\n", sp);
68
+}
69
+
70
+void qla2xxx_rel_free_warning(srb_t *sp)
71
+{
72
+ WARN_ONCE(1, "Calling free() of an already freed srb %p object\n", sp);
7473 }
7574
7675 /* Asynchronous Login/Logout Routines -------------------------------------- */
....@@ -93,6 +92,106 @@
9392 tmo = ha->login_timeout;
9493 }
9594 return tmo;
95
+}
96
+
97
+static void qla24xx_abort_iocb_timeout(void *data)
98
+{
99
+ srb_t *sp = data;
100
+ struct srb_iocb *abt = &sp->u.iocb_cmd;
101
+ struct qla_qpair *qpair = sp->qpair;
102
+ u32 handle;
103
+ unsigned long flags;
104
+
105
+ if (sp->cmd_sp)
106
+ ql_dbg(ql_dbg_async, sp->vha, 0x507c,
107
+ "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n",
108
+ sp->cmd_sp->handle, sp->cmd_sp->type,
109
+ sp->handle, sp->type);
110
+ else
111
+ ql_dbg(ql_dbg_async, sp->vha, 0x507c,
112
+ "Abort timeout 2 - hdl=%x, type=%x\n",
113
+ sp->handle, sp->type);
114
+
115
+ spin_lock_irqsave(qpair->qp_lock_ptr, flags);
116
+ for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
117
+ if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
118
+ sp->cmd_sp))
119
+ qpair->req->outstanding_cmds[handle] = NULL;
120
+
121
+ /* removing the abort */
122
+ if (qpair->req->outstanding_cmds[handle] == sp) {
123
+ qpair->req->outstanding_cmds[handle] = NULL;
124
+ break;
125
+ }
126
+ }
127
+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
128
+
129
+ if (sp->cmd_sp)
130
+ sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
131
+
132
+ abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
133
+ sp->done(sp, QLA_OS_TIMER_EXPIRED);
134
+}
135
+
136
+static void qla24xx_abort_sp_done(srb_t *sp, int res)
137
+{
138
+ struct srb_iocb *abt = &sp->u.iocb_cmd;
139
+
140
+ del_timer(&sp->u.iocb_cmd.timer);
141
+ if (sp->flags & SRB_WAKEUP_ON_COMP)
142
+ complete(&abt->u.abt.comp);
143
+ else
144
+ sp->free(sp);
145
+}
146
+
147
+int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
148
+{
149
+ scsi_qla_host_t *vha = cmd_sp->vha;
150
+ struct srb_iocb *abt_iocb;
151
+ srb_t *sp;
152
+ int rval = QLA_FUNCTION_FAILED;
153
+
154
+ sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
155
+ GFP_ATOMIC);
156
+ if (!sp)
157
+ return rval;
158
+
159
+ abt_iocb = &sp->u.iocb_cmd;
160
+ sp->type = SRB_ABT_CMD;
161
+ sp->name = "abort";
162
+ sp->qpair = cmd_sp->qpair;
163
+ sp->cmd_sp = cmd_sp;
164
+ if (wait)
165
+ sp->flags = SRB_WAKEUP_ON_COMP;
166
+
167
+ abt_iocb->timeout = qla24xx_abort_iocb_timeout;
168
+ init_completion(&abt_iocb->u.abt.comp);
169
+ /* FW can send 2 x ABTS's timeout/20s */
170
+ qla2x00_init_timer(sp, 42);
171
+
172
+ abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
173
+ abt_iocb->u.abt.req_que_no = cpu_to_le16(cmd_sp->qpair->req->id);
174
+
175
+ sp->done = qla24xx_abort_sp_done;
176
+
177
+ ql_dbg(ql_dbg_async, vha, 0x507c,
178
+ "Abort command issued - hdl=%x, type=%x\n", cmd_sp->handle,
179
+ cmd_sp->type);
180
+
181
+ rval = qla2x00_start_sp(sp);
182
+ if (rval != QLA_SUCCESS) {
183
+ sp->free(sp);
184
+ return rval;
185
+ }
186
+
187
+ if (wait) {
188
+ wait_for_completion(&abt_iocb->u.abt.comp);
189
+ rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
190
+ QLA_SUCCESS : QLA_FUNCTION_FAILED;
191
+ sp->free(sp);
192
+ }
193
+
194
+ return rval;
96195 }
97196
98197 void
....@@ -145,6 +244,7 @@
145244 case SRB_NACK_PRLI:
146245 case SRB_NACK_LOGO:
147246 case SRB_CTRL_VP:
247
+ default:
148248 rc = qla24xx_async_abort_cmd(sp, false);
149249 if (rc) {
150250 spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
....@@ -164,10 +264,8 @@
164264 }
165265 }
166266
167
-static void
168
-qla2x00_async_login_sp_done(void *ptr, int res)
267
+static void qla2x00_async_login_sp_done(srb_t *sp, int res)
169268 {
170
- srb_t *sp = ptr;
171269 struct scsi_qla_host *vha = sp->vha;
172270 struct srb_iocb *lio = &sp->u.iocb_cmd;
173271 struct event_arg ea;
....@@ -179,14 +277,13 @@
179277
180278 if (!test_bit(UNLOADING, &vha->dpc_flags)) {
181279 memset(&ea, 0, sizeof(ea));
182
- ea.event = FCME_PLOGI_DONE;
183280 ea.fcport = sp->fcport;
184281 ea.data[0] = lio->u.logio.data[0];
185282 ea.data[1] = lio->u.logio.data[1];
186283 ea.iop[0] = lio->u.logio.iop[0];
187284 ea.iop[1] = lio->u.logio.iop[1];
188285 ea.sp = sp;
189
- qla2x00_fcport_event_handler(vha, &ea);
286
+ qla24xx_handle_plogi_done_event(vha, &ea);
190287 }
191288
192289 sp->free(sp);
....@@ -228,10 +325,10 @@
228325 if (!sp)
229326 goto done;
230327
328
+ qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
231329 fcport->flags |= FCF_ASYNC_SENT;
232330 fcport->logout_completed = 0;
233331
234
- fcport->disc_state = DSC_LOGIN_PEND;
235332 sp->type = SRB_LOGIN_CMD;
236333 sp->name = "login";
237334 sp->gen1 = fcport->rscn_gen;
....@@ -247,7 +344,7 @@
247344 else
248345 lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
249346
250
- if (fcport->fc4f_nvme)
347
+ if (NVME_TARGET(vha->hw, fcport))
251348 lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;
252349
253350 ql_dbg(ql_dbg_disc, vha, 0x2072,
....@@ -273,11 +370,8 @@
273370 return rval;
274371 }
275372
276
-static void
277
-qla2x00_async_logout_sp_done(void *ptr, int res)
373
+static void qla2x00_async_logout_sp_done(srb_t *sp, int res)
278374 {
279
- srb_t *sp = ptr;
280
-
281375 sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
282376 sp->fcport->login_gen++;
283377 qlt_logo_completion_handler(sp->fcport, res);
....@@ -330,14 +424,12 @@
330424 fcport->flags &= ~FCF_ASYNC_ACTIVE;
331425 /* Don't re-login in target mode */
332426 if (!fcport->tgt_session)
333
- qla2x00_mark_device_lost(vha, fcport, 1, 0);
427
+ qla2x00_mark_device_lost(vha, fcport, 1);
334428 qlt_logo_completion_handler(fcport, data[0]);
335429 }
336430
337
-static void
338
-qla2x00_async_prlo_sp_done(void *s, int res)
431
+static void qla2x00_async_prlo_sp_done(srb_t *sp, int res)
339432 {
340
- srb_t *sp = (srb_t *)s;
341433 struct srb_iocb *lio = &sp->u.iocb_cmd;
342434 struct scsi_qla_host *vha = sp->vha;
343435
....@@ -368,14 +460,16 @@
368460 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
369461
370462 sp->done = qla2x00_async_prlo_sp_done;
371
- rval = qla2x00_start_sp(sp);
372
- if (rval != QLA_SUCCESS)
373
- goto done_free_sp;
374463
375464 ql_dbg(ql_dbg_disc, vha, 0x2070,
376465 "Async-prlo - hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
377466 sp->handle, fcport->loop_id, fcport->d_id.b.domain,
378467 fcport->d_id.b.area, fcport->d_id.b.al_pa);
468
+
469
+ rval = qla2x00_start_sp(sp);
470
+ if (rval != QLA_SUCCESS)
471
+ goto done_free_sp;
472
+
379473 return rval;
380474
381475 done_free_sp:
....@@ -389,6 +483,7 @@
389483 void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
390484 {
391485 struct fc_port *fcport = ea->fcport;
486
+ unsigned long flags;
392487
393488 ql_dbg(ql_dbg_disc, vha, 0x20d2,
394489 "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
....@@ -396,10 +491,22 @@
396491 fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
397492 fcport->rscn_gen, ea->sp->gen1, fcport->loop_id);
398493
494
+ WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
495
+ ea->data[0]);
496
+
399497 if (ea->data[0] != MBS_COMMAND_COMPLETE) {
400498 ql_dbg(ql_dbg_disc, vha, 0x2066,
401499 "%s %8phC: adisc fail: post delete\n",
402500 __func__, ea->fcport->port_name);
501
+
502
+ spin_lock_irqsave(&vha->work_lock, flags);
503
+ /* deleted = 0 & logout_on_delete = force fw cleanup */
504
+ if (fcport->deleted == QLA_SESS_DELETED)
505
+ fcport->deleted = 0;
506
+
507
+ fcport->logout_on_delete = 1;
508
+ spin_unlock_irqrestore(&vha->work_lock, flags);
509
+
403510 qlt_schedule_sess_for_deletion(ea->fcport);
404511 return;
405512 }
....@@ -414,16 +521,15 @@
414521 __func__, ea->fcport->port_name);
415522 return;
416523 } else if (ea->sp->gen1 != ea->fcport->rscn_gen) {
417
- ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
418
- __func__, __LINE__, ea->fcport->port_name);
419
- qla24xx_post_gidpn_work(vha, ea->fcport);
524
+ qla_rscn_replay(fcport);
525
+ qlt_schedule_sess_for_deletion(fcport);
420526 return;
421527 }
422528
423529 __qla24xx_handle_gpdb_event(vha, ea);
424530 }
425531
426
-int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
532
+static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
427533 {
428534 struct qla_work_evt *e;
429535
....@@ -433,14 +539,12 @@
433539
434540 e->u.fcport.fcport = fcport;
435541 fcport->flags |= FCF_ASYNC_ACTIVE;
436
- fcport->disc_state = DSC_LOGIN_PEND;
542
+ qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
437543 return qla2x00_post_work(vha, e);
438544 }
439545
440
-static void
441
-qla2x00_async_adisc_sp_done(void *ptr, int res)
546
+static void qla2x00_async_adisc_sp_done(srb_t *sp, int res)
442547 {
443
- srb_t *sp = ptr;
444548 struct scsi_qla_host *vha = sp->vha;
445549 struct event_arg ea;
446550 struct srb_iocb *lio = &sp->u.iocb_cmd;
....@@ -452,7 +556,6 @@
452556 sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
453557
454558 memset(&ea, 0, sizeof(ea));
455
- ea.event = FCME_ADISC_DONE;
456559 ea.rc = res;
457560 ea.data[0] = lio->u.logio.data[0];
458561 ea.data[1] = lio->u.logio.data[1];
....@@ -461,7 +564,7 @@
461564 ea.fcport = sp->fcport;
462565 ea.sp = sp;
463566
464
- qla2x00_fcport_event_handler(vha, &ea);
567
+ qla24xx_handle_adisc_event(vha, &ea);
465568
466569 sp->free(sp);
467570 }
....@@ -472,9 +575,19 @@
472575 {
473576 srb_t *sp;
474577 struct srb_iocb *lio;
475
- int rval;
578
+ int rval = QLA_FUNCTION_FAILED;
476579
477
- rval = QLA_FUNCTION_FAILED;
580
+ if (IS_SESSION_DELETED(fcport)) {
581
+ ql_log(ql_log_warn, vha, 0xffff,
582
+ "%s: %8phC is being delete - not sending command.\n",
583
+ __func__, fcport->port_name);
584
+ fcport->flags &= ~FCF_ASYNC_ACTIVE;
585
+ return rval;
586
+ }
587
+
588
+ if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
589
+ return rval;
590
+
478591 fcport->flags |= FCF_ASYNC_SENT;
479592 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
480593 if (!sp)
....@@ -511,6 +624,72 @@
511624 return rval;
512625 }
513626
627
+static bool qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)
628
+{
629
+ struct qla_hw_data *ha = vha->hw;
630
+
631
+ if (IS_FWI2_CAPABLE(ha))
632
+ return loop_id > NPH_LAST_HANDLE;
633
+
634
+ return (loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
635
+ loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST;
636
+}
637
+
638
+/**
639
+ * qla2x00_find_new_loop_id - scan through our port list and find a new usable loop ID
640
+ * @vha: adapter state pointer.
641
+ * @dev: port structure pointer.
642
+ *
643
+ * Returns:
644
+ * qla2x00 local function return status code.
645
+ *
646
+ * Context:
647
+ * Kernel context.
648
+ */
649
+static int qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
650
+{
651
+ int rval;
652
+ struct qla_hw_data *ha = vha->hw;
653
+ unsigned long flags = 0;
654
+
655
+ rval = QLA_SUCCESS;
656
+
657
+ spin_lock_irqsave(&ha->vport_slock, flags);
658
+
659
+ dev->loop_id = find_first_zero_bit(ha->loop_id_map, LOOPID_MAP_SIZE);
660
+ if (dev->loop_id >= LOOPID_MAP_SIZE ||
661
+ qla2x00_is_reserved_id(vha, dev->loop_id)) {
662
+ dev->loop_id = FC_NO_LOOP_ID;
663
+ rval = QLA_FUNCTION_FAILED;
664
+ } else {
665
+ set_bit(dev->loop_id, ha->loop_id_map);
666
+ }
667
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
668
+
669
+ if (rval == QLA_SUCCESS)
670
+ ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
671
+ "Assigning new loopid=%x, portid=%x.\n",
672
+ dev->loop_id, dev->d_id.b24);
673
+ else
674
+ ql_log(ql_log_warn, dev->vha, 0x2087,
675
+ "No loop_id's available, portid=%x.\n",
676
+ dev->d_id.b24);
677
+
678
+ return rval;
679
+}
680
+
681
+void qla2x00_clear_loop_id(fc_port_t *fcport)
682
+{
683
+ struct qla_hw_data *ha = fcport->vha->hw;
684
+
685
+ if (fcport->loop_id == FC_NO_LOOP_ID ||
686
+ qla2x00_is_reserved_id(fcport->vha, fcport->loop_id))
687
+ return;
688
+
689
+ clear_bit(fcport->loop_id, ha->loop_id_map);
690
+ fcport->loop_id = FC_NO_LOOP_ID;
691
+}
692
+
514693 static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
515694 struct event_arg *ea)
516695 {
....@@ -520,7 +699,7 @@
520699 port_id_t id;
521700 u64 wwn;
522701 u16 data[2];
523
- u8 current_login_state;
702
+ u8 current_login_state, nvme_cls;
524703
525704 fcport = ea->fcport;
526705 ql_dbg(ql_dbg_disc, vha, 0xffff,
....@@ -543,11 +722,8 @@
543722 }
544723
545724 if (fcport->last_rscn_gen != fcport->rscn_gen) {
546
- ql_dbg(ql_dbg_disc, vha, 0x20df,
547
- "%s %8phC rscn gen changed rscn %d|%d \n",
548
- __func__, fcport->port_name,
549
- fcport->last_rscn_gen, fcport->rscn_gen);
550
- qla24xx_post_gidpn_work(vha, fcport);
725
+ qla_rscn_replay(fcport);
726
+ qlt_schedule_sess_for_deletion(fcport);
551727 return;
552728 } else if (fcport->last_login_gen != fcport->login_gen) {
553729 ql_dbg(ql_dbg_disc, vha, 0x20e0,
....@@ -582,19 +758,24 @@
582758
583759 loop_id = le16_to_cpu(e->nport_handle);
584760 loop_id = (loop_id & 0x7fff);
585
- if (fcport->fc4f_nvme)
586
- current_login_state = e->current_login_state >> 4;
587
- else
588
- current_login_state = e->current_login_state & 0xf;
761
+ nvme_cls = e->current_login_state >> 4;
762
+ current_login_state = e->current_login_state & 0xf;
589763
764
+ if (PRLI_PHASE(nvme_cls)) {
765
+ current_login_state = nvme_cls;
766
+ fcport->fc4_type &= ~FS_FC4TYPE_FCP;
767
+ fcport->fc4_type |= FS_FC4TYPE_NVME;
768
+ } else if (PRLI_PHASE(current_login_state)) {
769
+ fcport->fc4_type |= FS_FC4TYPE_FCP;
770
+ fcport->fc4_type &= ~FS_FC4TYPE_NVME;
771
+ }
590772
591773 ql_dbg(ql_dbg_disc, vha, 0x20e2,
592
- "%s found %8phC CLS [%x|%x] nvme %d ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n",
774
+ "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n",
593775 __func__, fcport->port_name,
594776 e->current_login_state, fcport->fw_login_state,
595
- fcport->fc4f_nvme, id.b.domain, id.b.area, id.b.al_pa,
596
- fcport->d_id.b.domain, fcport->d_id.b.area,
597
- fcport->d_id.b.al_pa, loop_id, fcport->loop_id);
777
+ fcport->fc4_type, id.b24, fcport->d_id.b24,
778
+ loop_id, fcport->loop_id);
598779
599780 switch (fcport->disc_state) {
600781 case DSC_DELETE_PEND:
....@@ -602,12 +783,15 @@
602783 break;
603784 default:
604785 if ((id.b24 != fcport->d_id.b24 &&
605
- fcport->d_id.b24) ||
786
+ fcport->d_id.b24 &&
787
+ fcport->loop_id != FC_NO_LOOP_ID) ||
606788 (fcport->loop_id != FC_NO_LOOP_ID &&
607789 fcport->loop_id != loop_id)) {
608790 ql_dbg(ql_dbg_disc, vha, 0x20e3,
609791 "%s %d %8phC post del sess\n",
610792 __func__, __LINE__, fcport->port_name);
793
+ if (fcport->n2n_flag)
794
+ fcport->d_id.b24 = 0;
611795 qlt_schedule_sess_for_deletion(fcport);
612796 return;
613797 }
....@@ -615,6 +799,8 @@
615799 }
616800
617801 fcport->loop_id = loop_id;
802
+ if (fcport->n2n_flag)
803
+ fcport->d_id.b24 = id.b24;
618804
619805 wwn = wwn_to_u64(fcport->port_name);
620806 qlt_find_sess_invalidate_other(vha, wwn,
....@@ -664,6 +850,16 @@
664850 fcport->fw_login_state = current_login_state;
665851 fcport->d_id = id;
666852 switch (current_login_state) {
853
+ case DSC_LS_PRLI_PEND:
854
+ /*
855
+ * In the middle of PRLI. Let it finish.
856
+ * Allow relogin code to recheck state again
857
+ * with GNL. Push disc_state back to DELETED
858
+ * so GNL can go out again
859
+ */
860
+ qla2x00_set_fcport_disc_state(fcport,
861
+ DSC_DELETED);
862
+ break;
667863 case DSC_LS_PRLI_COMP:
668864 if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
669865 fcport->port_type = FCT_INITIATOR;
....@@ -685,7 +881,7 @@
685881 fcport);
686882 break;
687883 }
688
- /* drop through */
884
+ fallthrough;
689885 default:
690886 if (fcport_is_smaller(fcport)) {
691887 /* local adapter is bigger */
....@@ -738,7 +934,7 @@
738934 qla24xx_fcport_handle_login(vha, fcport);
739935 break;
740936 case ISP_CFG_N:
741
- fcport->disc_state = DSC_DELETED;
937
+ qla2x00_set_fcport_disc_state(fcport, DSC_DELETED);
742938 if (time_after_eq(jiffies, fcport->dm_login_expire)) {
743939 if (fcport->n2n_link_reset_cnt < 2) {
744940 fcport->n2n_link_reset_cnt++;
....@@ -772,16 +968,17 @@
772968 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
773969 }
774970 break;
971
+ case ISP_CFG_NL:
972
+ qla24xx_fcport_handle_login(vha, fcport);
973
+ break;
775974 default:
776975 break;
777976 }
778977 }
779978 } /* gnl_event */
780979
781
-static void
782
-qla24xx_async_gnl_sp_done(void *s, int res)
980
+static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
783981 {
784
- struct srb *sp = s;
785982 struct scsi_qla_host *vha = sp->vha;
786983 unsigned long flags;
787984 struct fc_port *fcport = NULL, *tf;
....@@ -802,7 +999,6 @@
802999 memset(&ea, 0, sizeof(ea));
8031000 ea.sp = sp;
8041001 ea.rc = res;
805
- ea.event = FCME_GNL_DONE;
8061002
8071003 if (sp->u.iocb_cmd.u.mbx.in_mb[1] >=
8081004 sizeof(struct get_name_list_extended)) {
....@@ -819,9 +1015,9 @@
8191015 set_bit(loop_id, vha->hw->loop_id_map);
8201016 wwn = wwn_to_u64(e->port_name);
8211017
822
- ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20e8,
823
- "%s %8phC %02x:%02x:%02x state %d/%d lid %x \n",
824
- __func__, (void *)&wwn, e->port_id[2], e->port_id[1],
1018
+ ql_dbg(ql_dbg_disc, vha, 0x20e8,
1019
+ "%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n",
1020
+ __func__, &wwn, e->port_id[2], e->port_id[1],
8251021 e->port_id[0], e->current_login_state, e->last_login_state,
8261022 (loop_id & 0x7fff));
8271023 }
....@@ -841,7 +1037,7 @@
8411037 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
8421038 ea.fcport = fcport;
8431039
844
- qla2x00_fcport_event_handler(vha, &ea);
1040
+ qla24xx_handle_gnl_done_event(vha, &ea);
8451041 }
8461042
8471043 /* create new fcport if fw has knowledge of new sessions */
....@@ -872,12 +1068,22 @@
8721068 __func__, __LINE__, (u8 *)&wwn, id.b24);
8731069 wwnn = wwn_to_u64(e->node_name);
8741070 qla24xx_post_newsess_work(vha, &id, (u8 *)&wwn,
875
- (u8 *)&wwnn, NULL, FC4_TYPE_UNKNOWN);
1071
+ (u8 *)&wwnn, NULL, 0);
8761072 }
8771073 }
8781074
8791075 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
8801076 vha->gnl.sent = 0;
1077
+ if (!list_empty(&vha->gnl.fcports)) {
1078
+ /* retrigger gnl */
1079
+ list_for_each_entry_safe(fcport, tf, &vha->gnl.fcports,
1080
+ gnl_entry) {
1081
+ list_del_init(&fcport->gnl_entry);
1082
+ fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
1083
+ if (qla24xx_post_gnl_work(vha, fcport) == QLA_SUCCESS)
1084
+ break;
1085
+ }
1086
+ }
8811087 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
8821088
8831089 sp->free(sp);
....@@ -899,7 +1105,7 @@
8991105
9001106 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
9011107 fcport->flags |= FCF_ASYNC_SENT;
902
- fcport->disc_state = DSC_GNL;
1108
+ qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
9031109 fcport->last_rscn_gen = fcport->rscn_gen;
9041110 fcport->last_login_gen = fcport->login_gen;
9051111
....@@ -936,20 +1142,20 @@
9361142
9371143 sp->done = qla24xx_async_gnl_sp_done;
9381144
939
- rval = qla2x00_start_sp(sp);
940
- if (rval != QLA_SUCCESS)
941
- goto done_free_sp;
942
-
9431145 ql_dbg(ql_dbg_disc, vha, 0x20da,
9441146 "Async-%s - OUT WWPN %8phC hndl %x\n",
9451147 sp->name, fcport->port_name, sp->handle);
1148
+
1149
+ rval = qla2x00_start_sp(sp);
1150
+ if (rval != QLA_SUCCESS)
1151
+ goto done_free_sp;
9461152
9471153 return rval;
9481154
9491155 done_free_sp:
9501156 sp->free(sp);
951
- fcport->flags &= ~FCF_ASYNC_SENT;
9521157 done:
1158
+ fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT);
9531159 return rval;
9541160 }
9551161
....@@ -963,14 +1169,11 @@
9631169
9641170 e->u.fcport.fcport = fcport;
9651171 fcport->flags |= FCF_ASYNC_ACTIVE;
966
- fcport->disc_state = DSC_LOGIN_PEND;
9671172 return qla2x00_post_work(vha, e);
9681173 }
9691174
970
-static
971
-void qla24xx_async_gpdb_sp_done(void *s, int res)
1175
+static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res)
9721176 {
973
- struct srb *sp = s;
9741177 struct scsi_qla_host *vha = sp->vha;
9751178 struct qla_hw_data *ha = vha->hw;
9761179 fc_port_t *fcport = sp->fcport;
....@@ -987,11 +1190,10 @@
9871190 goto done;
9881191
9891192 memset(&ea, 0, sizeof(ea));
990
- ea.event = FCME_GPDB_DONE;
9911193 ea.fcport = fcport;
9921194 ea.sp = sp;
9931195
994
- qla2x00_fcport_event_handler(vha, &ea);
1196
+ qla24xx_handle_gpdb_event(vha, &ea);
9951197
9961198 done:
9971199 dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
....@@ -1004,6 +1206,9 @@
10041206 {
10051207 struct qla_work_evt *e;
10061208
1209
+ if (vha->host->active_mode == MODE_TARGET)
1210
+ return QLA_FUNCTION_FAILED;
1211
+
10071212 e = qla2x00_alloc_work(vha, QLA_EVT_PRLI);
10081213 if (!e)
10091214 return QLA_FUNCTION_FAILED;
....@@ -1013,10 +1218,8 @@
10131218 return qla2x00_post_work(vha, e);
10141219 }
10151220
1016
-static void
1017
-qla2x00_async_prli_sp_done(void *ptr, int res)
1221
+static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
10181222 {
1019
- srb_t *sp = ptr;
10201223 struct scsi_qla_host *vha = sp->vha;
10211224 struct srb_iocb *lio = &sp->u.iocb_cmd;
10221225 struct event_arg ea;
....@@ -1029,7 +1232,6 @@
10291232
10301233 if (!test_bit(UNLOADING, &vha->dpc_flags)) {
10311234 memset(&ea, 0, sizeof(ea));
1032
- ea.event = FCME_PRLI_DONE;
10331235 ea.fcport = sp->fcport;
10341236 ea.data[0] = lio->u.logio.data[0];
10351237 ea.data[1] = lio->u.logio.data[1];
....@@ -1037,7 +1239,7 @@
10371239 ea.iop[1] = lio->u.logio.iop[1];
10381240 ea.sp = sp;
10391241
1040
- qla2x00_fcport_event_handler(vha, &ea);
1242
+ qla24xx_handle_prli_done_event(vha, &ea);
10411243 }
10421244
10431245 sp->free(sp);
....@@ -1050,12 +1252,19 @@
10501252 struct srb_iocb *lio;
10511253 int rval = QLA_FUNCTION_FAILED;
10521254
1053
- if (!vha->flags.online)
1255
+ if (!vha->flags.online) {
1256
+ ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
1257
+ __func__, __LINE__, fcport->port_name);
10541258 return rval;
1259
+ }
10551260
1056
- if (fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
1057
- fcport->fw_login_state == DSC_LS_PRLI_PEND)
1261
+ if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
1262
+ fcport->fw_login_state == DSC_LS_PRLI_PEND) &&
1263
+ qla_dual_mode_enabled(vha)) {
1264
+ ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
1265
+ __func__, __LINE__, fcport->port_name);
10581266 return rval;
1267
+ }
10591268
10601269 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
10611270 if (!sp)
....@@ -1074,8 +1283,14 @@
10741283 sp->done = qla2x00_async_prli_sp_done;
10751284 lio->u.logio.flags = 0;
10761285
1077
- if (fcport->fc4f_nvme)
1286
+ if (NVME_TARGET(vha->hw, fcport))
10781287 lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
1288
+
1289
+ ql_dbg(ql_dbg_disc, vha, 0x211b,
1290
+ "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d fc4type %x priority %x %s.\n",
1291
+ fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
1292
+ fcport->login_retry, fcport->fc4_type, vha->hw->fc4_type_priority,
1293
+ NVME_TARGET(vha->hw, fcport) ? "nvme" : "fcp");
10791294
10801295 rval = qla2x00_start_sp(sp);
10811296 if (rval != QLA_SUCCESS) {
....@@ -1083,11 +1298,6 @@
10831298 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
10841299 goto done_free_sp;
10851300 }
1086
-
1087
- ql_dbg(ql_dbg_disc, vha, 0x211b,
1088
- "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
1089
- fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
1090
- fcport->login_retry, fcport->fc4f_nvme ? "nvme" : "fc");
10911301
10921302 return rval;
10931303
....@@ -1121,19 +1331,26 @@
11211331 struct port_database_24xx *pd;
11221332 struct qla_hw_data *ha = vha->hw;
11231333
1124
- if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT) ||
1125
- fcport->loop_id == FC_NO_LOOP_ID) {
1334
+ if (IS_SESSION_DELETED(fcport)) {
11261335 ql_log(ql_log_warn, vha, 0xffff,
1127
- "%s: %8phC - not sending command.\n",
1128
- __func__, fcport->port_name);
1336
+ "%s: %8phC is being delete - not sending command.\n",
1337
+ __func__, fcport->port_name);
1338
+ fcport->flags &= ~FCF_ASYNC_ACTIVE;
11291339 return rval;
11301340 }
11311341
1132
- fcport->disc_state = DSC_GPDB;
1342
+ if (!vha->flags.online || fcport->flags & FCF_ASYNC_SENT) {
1343
+ ql_log(ql_log_warn, vha, 0xffff,
1344
+ "%s: %8phC online %d flags %x - not sending command.\n",
1345
+ __func__, fcport->port_name, vha->flags.online, fcport->flags);
1346
+ goto done;
1347
+ }
11331348
11341349 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
11351350 if (!sp)
11361351 goto done;
1352
+
1353
+ qla2x00_set_fcport_disc_state(fcport, DSC_GPDB);
11371354
11381355 fcport->flags |= FCF_ASYNC_SENT;
11391356 sp->type = SRB_MB_IOCB;
....@@ -1162,7 +1379,7 @@
11621379 mb[9] = vha->vp_idx;
11631380 mb[10] = opt;
11641381
1165
- mbx->u.mbx.in = (void *)pd;
1382
+ mbx->u.mbx.in = pd;
11661383 mbx->u.mbx.in_dma = pd_dma;
11671384
11681385 sp->done = qla24xx_async_gpdb_sp_done;
....@@ -1183,6 +1400,7 @@
11831400 sp->free(sp);
11841401 fcport->flags &= ~FCF_ASYNC_SENT;
11851402 done:
1403
+ fcport->flags &= ~FCF_ASYNC_ACTIVE;
11861404 qla24xx_post_gpdb_work(vha, fcport, opt);
11871405 return rval;
11881406 }
....@@ -1194,7 +1412,6 @@
11941412
11951413 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
11961414 ea->fcport->login_gen++;
1197
- ea->fcport->deleted = 0;
11981415 ea->fcport->logout_on_delete = 1;
11991416
12001417 if (!ea->fcport->login_succ && !IS_SW_RESV_ADDR(ea->fcport->d_id)) {
....@@ -1213,7 +1430,7 @@
12131430 ql_dbg(ql_dbg_disc, vha, 0x20d6,
12141431 "%s %d %8phC session revalidate success\n",
12151432 __func__, __LINE__, ea->fcport->port_name);
1216
- ea->fcport->disc_state = DSC_LOGIN_COMPLETE;
1433
+ qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_COMPLETE);
12171434 }
12181435 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
12191436 }
....@@ -1231,17 +1448,30 @@
12311448 fcport->flags &= ~FCF_ASYNC_SENT;
12321449
12331450 ql_dbg(ql_dbg_disc, vha, 0x20d2,
1234
- "%s %8phC DS %d LS %d nvme %x rc %d\n", __func__, fcport->port_name,
1235
- fcport->disc_state, pd->current_login_state, fcport->fc4f_nvme,
1236
- ea->rc);
1451
+ "%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__,
1452
+ fcport->port_name, fcport->disc_state, pd->current_login_state,
1453
+ fcport->fc4_type, ea->rc);
12371454
12381455 if (fcport->disc_state == DSC_DELETE_PEND)
12391456 return;
12401457
1241
- if (fcport->fc4f_nvme)
1458
+ if (NVME_TARGET(vha->hw, fcport))
12421459 ls = pd->current_login_state >> 4;
12431460 else
12441461 ls = pd->current_login_state & 0xf;
1462
+
1463
+ if (ea->sp->gen2 != fcport->login_gen) {
1464
+ /* target side must have changed it. */
1465
+
1466
+ ql_dbg(ql_dbg_disc, vha, 0x20d3,
1467
+ "%s %8phC generation changed\n",
1468
+ __func__, fcport->port_name);
1469
+ return;
1470
+ } else if (ea->sp->gen1 != fcport->rscn_gen) {
1471
+ qla_rscn_replay(fcport);
1472
+ qlt_schedule_sess_for_deletion(fcport);
1473
+ return;
1474
+ }
12451475
12461476 switch (ls) {
12471477 case PDS_PRLI_COMPLETE:
....@@ -1254,7 +1484,7 @@
12541484 /* Set discovery state back to GNL to Relogin attempt */
12551485 if (qla_dual_mode_enabled(vha) ||
12561486 qla_ini_mode_enabled(vha)) {
1257
- fcport->disc_state = DSC_GNL;
1487
+ qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
12581488 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
12591489 }
12601490 return;
....@@ -1273,6 +1503,11 @@
12731503 {
12741504 u8 login = 0;
12751505 int rc;
1506
+
1507
+ ql_dbg(ql_dbg_disc, vha, 0x307b,
1508
+ "%s %8phC DS %d LS %d lid %d retries=%d\n",
1509
+ __func__, fcport->port_name, fcport->disc_state,
1510
+ fcport->fw_login_state, fcport->loop_id, fcport->login_retry);
12761511
12771512 if (qla_tgt_mode_enabled(vha))
12781513 return;
....@@ -1297,7 +1532,8 @@
12971532 login = 1;
12981533 }
12991534
1300
- if (login) {
1535
+ if (login && fcport->login_retry) {
1536
+ fcport->login_retry--;
13011537 if (fcport->loop_id == FC_NO_LOOP_ID) {
13021538 fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
13031539 rc = qla2x00_find_new_loop_id(vha, fcport);
....@@ -1324,33 +1560,35 @@
13241560 u16 sec;
13251561
13261562 ql_dbg(ql_dbg_disc, vha, 0x20d8,
1327
- "%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d retry %d lid %d scan %d\n",
1563
+ "%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d lid %d scan %d\n",
13281564 __func__, fcport->port_name, fcport->disc_state,
13291565 fcport->fw_login_state, fcport->login_pause, fcport->flags,
13301566 fcport->conflict, fcport->last_rscn_gen, fcport->rscn_gen,
1331
- fcport->login_gen, fcport->login_retry,
1332
- fcport->loop_id, fcport->scan_state);
1567
+ fcport->login_gen, fcport->loop_id, fcport->scan_state);
13331568
1334
- if (fcport->scan_state != QLA_FCPORT_FOUND)
1569
+ if (fcport->scan_state != QLA_FCPORT_FOUND ||
1570
+ fcport->disc_state == DSC_DELETE_PEND)
13351571 return 0;
13361572
13371573 if ((fcport->loop_id != FC_NO_LOOP_ID) &&
1574
+ qla_dual_mode_enabled(vha) &&
13381575 ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
13391576 (fcport->fw_login_state == DSC_LS_PRLI_PEND)))
13401577 return 0;
13411578
1342
- if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
1579
+ if (fcport->fw_login_state == DSC_LS_PLOGI_COMP &&
1580
+ !N2N_TOPO(vha->hw)) {
13431581 if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
13441582 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
13451583 return 0;
13461584 }
13471585 }
13481586
1349
- /* for pure Target Mode. Login will not be initiated */
1350
- if (vha->host->active_mode == MODE_TARGET)
1587
+ /* Target won't initiate port login if fabric is present */
1588
+ if (vha->host->active_mode == MODE_TARGET && !N2N_TOPO(vha->hw))
13511589 return 0;
13521590
1353
- if (fcport->flags & FCF_ASYNC_SENT) {
1591
+ if (fcport->flags & (FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE)) {
13541592 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
13551593 return 0;
13561594 }
....@@ -1410,13 +1648,19 @@
14101648 qla24xx_post_gpdb_work(vha, fcport, 0);
14111649 } else {
14121650 ql_dbg(ql_dbg_disc, vha, 0x2118,
1413
- "%s %d %8phC post NVMe PRLI\n",
1414
- __func__, __LINE__, fcport->port_name);
1651
+ "%s %d %8phC post %s PRLI\n",
1652
+ __func__, __LINE__, fcport->port_name,
1653
+ NVME_TARGET(vha->hw, fcport) ? "NVME" :
1654
+ "FC");
14151655 qla24xx_post_prli_work(vha, fcport);
14161656 }
14171657 break;
14181658 default:
14191659 if (fcport->login_pause) {
1660
+ ql_dbg(ql_dbg_disc, vha, 0x20d8,
1661
+ "%s %d %8phC exit\n",
1662
+ __func__, __LINE__,
1663
+ fcport->port_name);
14201664 fcport->last_rscn_gen = fcport->rscn_gen;
14211665 fcport->last_login_gen = fcport->login_gen;
14221666 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
....@@ -1428,22 +1672,14 @@
14281672 break;
14291673
14301674 case DSC_LOGIN_FAILED:
1431
- fcport->login_retry--;
1432
- ql_dbg(ql_dbg_disc, vha, 0x20d0,
1433
- "%s %d %8phC post gidpn\n",
1434
- __func__, __LINE__, fcport->port_name);
14351675 if (N2N_TOPO(vha->hw))
14361676 qla_chk_n2n_b4_login(vha, fcport);
14371677 else
1438
- qla24xx_post_gidpn_work(vha, fcport);
1678
+ qlt_schedule_sess_for_deletion(fcport);
14391679 break;
14401680
14411681 case DSC_LOGIN_COMPLETE:
14421682 /* recheck login state */
1443
- ql_dbg(ql_dbg_disc, vha, 0x20d1,
1444
- "%s %d %8phC post adisc\n",
1445
- __func__, __LINE__, fcport->port_name);
1446
- fcport->login_retry--;
14471683 data[0] = data[1] = 0;
14481684 qla2x00_post_async_adisc_work(vha, fcport, data);
14491685 break;
....@@ -1476,33 +1712,11 @@
14761712 return 0;
14771713 }
14781714
1479
-static
1480
-void qla24xx_handle_rscn_event(fc_port_t *fcport, struct event_arg *ea)
1481
-{
1482
- fcport->rscn_gen++;
1483
-
1484
- ql_dbg(ql_dbg_disc, fcport->vha, 0x210c,
1485
- "%s %8phC DS %d LS %d\n",
1486
- __func__, fcport->port_name, fcport->disc_state,
1487
- fcport->fw_login_state);
1488
-
1489
- if (fcport->flags & FCF_ASYNC_SENT)
1490
- return;
1491
-
1492
- switch (fcport->disc_state) {
1493
- case DSC_DELETED:
1494
- case DSC_LOGIN_COMPLETE:
1495
- qla24xx_post_gpnid_work(fcport->vha, &ea->id);
1496
- break;
1497
- default:
1498
- break;
1499
- }
1500
-}
1501
-
15021715 int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id,
15031716 u8 *port_name, u8 *node_name, void *pla, u8 fc4_type)
15041717 {
15051718 struct qla_work_evt *e;
1719
+
15061720 e = qla2x00_alloc_work(vha, QLA_EVT_NEW_SESS);
15071721 if (!e)
15081722 return QLA_FUNCTION_FAILED;
....@@ -1517,11 +1731,79 @@
15171731 return qla2x00_post_work(vha, e);
15181732 }
15191733
1520
-static
1734
+void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
1735
+{
1736
+ fc_port_t *fcport;
1737
+ unsigned long flags;
1738
+
1739
+ switch (ea->id.b.rsvd_1) {
1740
+ case RSCN_PORT_ADDR:
1741
+ fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
1742
+ if (fcport) {
1743
+ if (fcport->flags & FCF_FCP2_DEVICE &&
1744
+ atomic_read(&fcport->state) == FCS_ONLINE) {
1745
+ ql_dbg(ql_dbg_disc, vha, 0x2115,
1746
+ "Delaying session delete for FCP2 portid=%06x %8phC ",
1747
+ fcport->d_id.b24, fcport->port_name);
1748
+ return;
1749
+ }
1750
+ fcport->scan_needed = 1;
1751
+ fcport->rscn_gen++;
1752
+ }
1753
+ break;
1754
+ case RSCN_AREA_ADDR:
1755
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
1756
+ if (fcport->flags & FCF_FCP2_DEVICE &&
1757
+ atomic_read(&fcport->state) == FCS_ONLINE)
1758
+ continue;
1759
+
1760
+ if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) {
1761
+ fcport->scan_needed = 1;
1762
+ fcport->rscn_gen++;
1763
+ }
1764
+ }
1765
+ break;
1766
+ case RSCN_DOM_ADDR:
1767
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
1768
+ if (fcport->flags & FCF_FCP2_DEVICE &&
1769
+ atomic_read(&fcport->state) == FCS_ONLINE)
1770
+ continue;
1771
+
1772
+ if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) {
1773
+ fcport->scan_needed = 1;
1774
+ fcport->rscn_gen++;
1775
+ }
1776
+ }
1777
+ break;
1778
+ case RSCN_FAB_ADDR:
1779
+ default:
1780
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
1781
+ if (fcport->flags & FCF_FCP2_DEVICE &&
1782
+ atomic_read(&fcport->state) == FCS_ONLINE)
1783
+ continue;
1784
+
1785
+ fcport->scan_needed = 1;
1786
+ fcport->rscn_gen++;
1787
+ }
1788
+ break;
1789
+ }
1790
+
1791
+ spin_lock_irqsave(&vha->work_lock, flags);
1792
+ if (vha->scan.scan_flags == 0) {
1793
+ ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__);
1794
+ vha->scan.scan_flags |= SF_QUEUED;
1795
+ schedule_delayed_work(&vha->scan.scan_work, 5);
1796
+ }
1797
+ spin_unlock_irqrestore(&vha->work_lock, flags);
1798
+}
1799
+
15211800 void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
15221801 struct event_arg *ea)
15231802 {
15241803 fc_port_t *fcport = ea->fcport;
1804
+
1805
+ if (test_bit(UNLOADING, &vha->dpc_flags))
1806
+ return;
15251807
15261808 ql_dbg(ql_dbg_disc, vha, 0x2102,
15271809 "%s %8phC DS %d LS %d P %d del %d cnfl %p rscn %d|%d login %d|%d fl %x\n",
....@@ -1532,146 +1814,49 @@
15321814 fcport->last_login_gen, fcport->login_gen,
15331815 fcport->flags);
15341816
1535
- if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
1536
- (fcport->fw_login_state == DSC_LS_PRLI_PEND))
1537
- return;
1538
-
1539
- if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
1540
- if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
1541
- set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
1542
- return;
1543
- }
1544
- }
1545
-
15461817 if (fcport->last_rscn_gen != fcport->rscn_gen) {
1547
- ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gidpn\n",
1818
+ ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gnl\n",
15481819 __func__, __LINE__, fcport->port_name);
1549
-
1550
- qla24xx_post_gidpn_work(vha, fcport);
1820
+ qla24xx_post_gnl_work(vha, fcport);
15511821 return;
15521822 }
15531823
15541824 qla24xx_fcport_handle_login(vha, fcport);
15551825 }
15561826
1557
-
1558
-void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea)
1827
+void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
1828
+ struct event_arg *ea)
15591829 {
1830
+ /* for pure Target Mode, PRLI will not be initiated */
1831
+ if (vha->host->active_mode == MODE_TARGET)
1832
+ return;
1833
+
15601834 ql_dbg(ql_dbg_disc, vha, 0x2118,
15611835 "%s %d %8phC post PRLI\n",
15621836 __func__, __LINE__, ea->fcport->port_name);
15631837 qla24xx_post_prli_work(vha, ea->fcport);
15641838 }
15651839
1566
-void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
1840
+/*
1841
+ * RSCN(s) came in for this fcport, but the RSCN(s) was not able
1842
+ * to be consumed by the fcport
1843
+ */
1844
+void qla_rscn_replay(fc_port_t *fcport)
15671845 {
1568
- fc_port_t *f, *tf;
1569
- uint32_t id = 0, mask, rid;
1570
- unsigned long flags;
1571
- fc_port_t *fcport;
1846
+ struct event_arg ea;
15721847
1573
- switch (ea->event) {
1574
- case FCME_RELOGIN:
1575
- if (test_bit(UNLOADING, &vha->dpc_flags))
1576
- return;
1577
-
1578
- qla24xx_handle_relogin_event(vha, ea);
1579
- break;
1580
- case FCME_RSCN:
1581
- if (test_bit(UNLOADING, &vha->dpc_flags))
1582
- return;
1583
- switch (ea->id.b.rsvd_1) {
1584
- case RSCN_PORT_ADDR:
1585
- fcport = qla2x00_find_fcport_by_nportid
1586
- (vha, &ea->id, 1);
1587
- if (fcport) {
1588
- fcport->scan_needed = 1;
1589
- fcport->rscn_gen++;
1590
- }
1591
-
1592
- spin_lock_irqsave(&vha->work_lock, flags);
1593
- if (vha->scan.scan_flags == 0) {
1594
- ql_dbg(ql_dbg_disc, vha, 0xffff,
1595
- "%s: schedule\n", __func__);
1596
- vha->scan.scan_flags |= SF_QUEUED;
1597
- schedule_delayed_work(&vha->scan.scan_work, 5);
1598
- }
1599
- spin_unlock_irqrestore(&vha->work_lock, flags);
1600
-
1601
- break;
1602
- case RSCN_AREA_ADDR:
1603
- case RSCN_DOM_ADDR:
1604
- if (ea->id.b.rsvd_1 == RSCN_AREA_ADDR) {
1605
- mask = 0xffff00;
1606
- ql_dbg(ql_dbg_async, vha, 0x5044,
1607
- "RSCN: Area 0x%06x was affected\n",
1608
- ea->id.b24);
1609
- } else {
1610
- mask = 0xff0000;
1611
- ql_dbg(ql_dbg_async, vha, 0x507a,
1612
- "RSCN: Domain 0x%06x was affected\n",
1613
- ea->id.b24);
1614
- }
1615
-
1616
- rid = ea->id.b24 & mask;
1617
- list_for_each_entry_safe(f, tf, &vha->vp_fcports,
1618
- list) {
1619
- id = f->d_id.b24 & mask;
1620
- if (rid == id) {
1621
- ea->fcport = f;
1622
- qla24xx_handle_rscn_event(f, ea);
1623
- }
1624
- }
1625
- break;
1626
- case RSCN_FAB_ADDR:
1627
- default:
1628
- ql_log(ql_log_warn, vha, 0xd045,
1629
- "RSCN: Fabric was affected. Addr format %d\n",
1630
- ea->id.b.rsvd_1);
1631
- qla2x00_mark_all_devices_lost(vha, 1);
1632
- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
1633
- set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
1634
- }
1635
- break;
1636
- case FCME_GIDPN_DONE:
1637
- qla24xx_handle_gidpn_event(vha, ea);
1638
- break;
1639
- case FCME_GNL_DONE:
1640
- qla24xx_handle_gnl_done_event(vha, ea);
1641
- break;
1642
- case FCME_GPSC_DONE:
1643
- qla24xx_handle_gpsc_event(vha, ea);
1644
- break;
1645
- case FCME_PLOGI_DONE: /* Initiator side sent LLIOCB */
1646
- qla24xx_handle_plogi_done_event(vha, ea);
1647
- break;
1648
- case FCME_PRLI_DONE:
1649
- qla24xx_handle_prli_done_event(vha, ea);
1650
- break;
1651
- case FCME_GPDB_DONE:
1652
- qla24xx_handle_gpdb_event(vha, ea);
1653
- break;
1654
- case FCME_GPNID_DONE:
1655
- qla24xx_handle_gpnid_event(vha, ea);
1656
- break;
1657
- case FCME_GFFID_DONE:
1658
- qla24xx_handle_gffid_event(vha, ea);
1659
- break;
1660
- case FCME_ADISC_DONE:
1661
- qla24xx_handle_adisc_event(vha, ea);
1662
- break;
1663
- case FCME_GNNID_DONE:
1664
- qla24xx_handle_gnnid_event(vha, ea);
1665
- break;
1666
- case FCME_GFPNID_DONE:
1667
- qla24xx_handle_gfpnid_event(vha, ea);
1668
- break;
1669
- case FCME_ELS_PLOGI_DONE:
1670
- qla_handle_els_plogi_done(vha, ea);
1671
- break;
1848
+ switch (fcport->disc_state) {
1849
+ case DSC_DELETE_PEND:
1850
+ return;
16721851 default:
1673
- BUG_ON(1);
16741852 break;
1853
+ }
1854
+
1855
+ if (fcport->scan_needed) {
1856
+ memset(&ea, 0, sizeof(ea));
1857
+ ea.id = fcport->d_id;
1858
+ ea.id.b.rsvd_1 = RSCN_PORT_ADDR;
1859
+ qla2x00_handle_rscn(fcport->vha, &ea);
16751860 }
16761861 }
16771862
....@@ -1680,15 +1865,27 @@
16801865 {
16811866 srb_t *sp = data;
16821867 struct srb_iocb *tmf = &sp->u.iocb_cmd;
1868
+ int rc, h;
1869
+ unsigned long flags;
16831870
1684
- tmf->u.tmf.comp_status = CS_TIMEOUT;
1685
- complete(&tmf->u.tmf.comp);
1871
+ rc = qla24xx_async_abort_cmd(sp, false);
1872
+ if (rc) {
1873
+ spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
1874
+ for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
1875
+ if (sp->qpair->req->outstanding_cmds[h] == sp) {
1876
+ sp->qpair->req->outstanding_cmds[h] = NULL;
1877
+ break;
1878
+ }
1879
+ }
1880
+ spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
1881
+ tmf->u.tmf.comp_status = cpu_to_le16(CS_TIMEOUT);
1882
+ tmf->u.tmf.data = QLA_FUNCTION_FAILED;
1883
+ complete(&tmf->u.tmf.comp);
1884
+ }
16861885 }
16871886
1688
-static void
1689
-qla2x00_tmf_sp_done(void *ptr, int res)
1887
+static void qla2x00_tmf_sp_done(srb_t *sp, int res)
16901888 {
1691
- srb_t *sp = ptr;
16921889 struct srb_iocb *tmf = &sp->u.iocb_cmd;
16931890
16941891 complete(&tmf->u.tmf.comp);
....@@ -1742,89 +1939,14 @@
17421939 lun = (uint16_t)tm_iocb->u.tmf.lun;
17431940
17441941 /* Issue Marker IOCB */
1745
- qla2x00_marker(vha, vha->hw->req_q_map[0],
1746
- vha->hw->rsp_q_map[0], fcport->loop_id, lun,
1942
+ qla2x00_marker(vha, vha->hw->base_qpair,
1943
+ fcport->loop_id, lun,
17471944 flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
17481945 }
17491946
17501947 done_free_sp:
17511948 sp->free(sp);
17521949 fcport->flags &= ~FCF_ASYNC_SENT;
1753
-done:
1754
- return rval;
1755
-}
1756
-
1757
-static void
1758
-qla24xx_abort_iocb_timeout(void *data)
1759
-{
1760
- srb_t *sp = data;
1761
- struct srb_iocb *abt = &sp->u.iocb_cmd;
1762
-
1763
- abt->u.abt.comp_status = CS_TIMEOUT;
1764
- sp->done(sp, QLA_FUNCTION_TIMEOUT);
1765
-}
1766
-
1767
-static void
1768
-qla24xx_abort_sp_done(void *ptr, int res)
1769
-{
1770
- srb_t *sp = ptr;
1771
- struct srb_iocb *abt = &sp->u.iocb_cmd;
1772
-
1773
- if (del_timer(&sp->u.iocb_cmd.timer)) {
1774
- if (sp->flags & SRB_WAKEUP_ON_COMP)
1775
- complete(&abt->u.abt.comp);
1776
- else
1777
- sp->free(sp);
1778
- }
1779
-}
1780
-
1781
-int
1782
-qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
1783
-{
1784
- scsi_qla_host_t *vha = cmd_sp->vha;
1785
- struct srb_iocb *abt_iocb;
1786
- srb_t *sp;
1787
- int rval = QLA_FUNCTION_FAILED;
1788
-
1789
- sp = qla2xxx_get_qpair_sp(cmd_sp->qpair, cmd_sp->fcport, GFP_KERNEL);
1790
- if (!sp)
1791
- goto done;
1792
-
1793
- abt_iocb = &sp->u.iocb_cmd;
1794
- sp->type = SRB_ABT_CMD;
1795
- sp->name = "abort";
1796
- sp->qpair = cmd_sp->qpair;
1797
- if (wait)
1798
- sp->flags = SRB_WAKEUP_ON_COMP;
1799
-
1800
- abt_iocb->timeout = qla24xx_abort_iocb_timeout;
1801
- init_completion(&abt_iocb->u.abt.comp);
1802
- /* FW can send 2 x ABTS's timeout/20s */
1803
- qla2x00_init_timer(sp, 42);
1804
-
1805
- abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
1806
- abt_iocb->u.abt.req_que_no = cpu_to_le16(cmd_sp->qpair->req->id);
1807
-
1808
- sp->done = qla24xx_abort_sp_done;
1809
-
1810
- ql_dbg(ql_dbg_async, vha, 0x507c,
1811
- "Abort command issued - hdl=%x, type=%x\n",
1812
- cmd_sp->handle, cmd_sp->type);
1813
-
1814
- rval = qla2x00_start_sp(sp);
1815
- if (rval != QLA_SUCCESS)
1816
- goto done_free_sp;
1817
-
1818
- if (wait) {
1819
- wait_for_completion(&abt_iocb->u.abt.comp);
1820
- rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
1821
- QLA_SUCCESS : QLA_FUNCTION_FAILED;
1822
- } else {
1823
- goto done;
1824
- }
1825
-
1826
-done_free_sp:
1827
- sp->free(sp);
18281950 done:
18291951 return rval;
18301952 }
....@@ -1836,19 +1958,17 @@
18361958
18371959 uint32_t handle;
18381960 fc_port_t *fcport = sp->fcport;
1961
+ struct qla_qpair *qpair = sp->qpair;
18391962 struct scsi_qla_host *vha = fcport->vha;
1840
- struct qla_hw_data *ha = vha->hw;
1841
- struct req_que *req = vha->req;
1963
+ struct req_que *req = qpair->req;
18421964
1843
- if (vha->flags.qpairs_available && sp->qpair)
1844
- req = sp->qpair->req;
1845
-
1846
- spin_lock_irqsave(&ha->hardware_lock, flags);
1965
+ spin_lock_irqsave(qpair->qp_lock_ptr, flags);
18471966 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
18481967 if (req->outstanding_cmds[handle] == sp)
18491968 break;
18501969 }
1851
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
1970
+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
1971
+
18521972 if (handle == req->num_outstanding_cmds) {
18531973 /* Command not found. */
18541974 return QLA_FUNCTION_FAILED;
....@@ -1863,6 +1983,9 @@
18631983 static void
18641984 qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
18651985 {
1986
+ WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
1987
+ ea->data[0]);
1988
+
18661989 switch (ea->data[0]) {
18671990 case MBS_COMMAND_COMPLETE:
18681991 ql_dbg(ql_dbg_disc, vha, 0x2118,
....@@ -1871,6 +1994,12 @@
18711994
18721995 ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
18731996 ea->fcport->logout_on_delete = 1;
1997
+ ea->fcport->nvme_prli_service_param = ea->iop[0];
1998
+ if (ea->iop[0] & NVME_PRLI_SP_FIRST_BURST)
1999
+ ea->fcport->nvme_first_burst_size =
2000
+ (ea->iop[1] & 0xffff) * 512;
2001
+ else
2002
+ ea->fcport->nvme_first_burst_size = 0;
18742003 qla24xx_post_gpdb_work(vha, ea->fcport, 0);
18752004 break;
18762005 default:
....@@ -1881,22 +2010,63 @@
18812010 break;
18822011 }
18832012
1884
- if (ea->fcport->n2n_flag) {
1885
- ql_dbg(ql_dbg_disc, vha, 0x2118,
1886
- "%s %d %8phC post fc4 prli\n",
1887
- __func__, __LINE__, ea->fcport->port_name);
1888
- ea->fcport->fc4f_nvme = 0;
1889
- ea->fcport->n2n_flag = 0;
1890
- qla24xx_post_prli_work(vha, ea->fcport);
2013
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
2014
+ "%s %d %8phC priority %s, fc4type %x\n",
2015
+ __func__, __LINE__, ea->fcport->port_name,
2016
+ vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
2017
+ "FCP" : "NVMe", ea->fcport->fc4_type);
2018
+
2019
+ if (N2N_TOPO(vha->hw)) {
2020
+ if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) {
2021
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
2022
+ ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
2023
+ } else {
2024
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
2025
+ ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
2026
+ }
2027
+
2028
+ if (ea->fcport->n2n_link_reset_cnt < 3) {
2029
+ ea->fcport->n2n_link_reset_cnt++;
2030
+ vha->relogin_jif = jiffies + 2 * HZ;
2031
+ /*
2032
+ * PRLI failed. Reset link to kick start
2033
+ * state machine
2034
+ */
2035
+ set_bit(N2N_LINK_RESET, &vha->dpc_flags);
2036
+ } else {
2037
+ ql_log(ql_log_warn, vha, 0x2119,
2038
+ "%s %d %8phC Unable to reconnect\n",
2039
+ __func__, __LINE__,
2040
+ ea->fcport->port_name);
2041
+ }
2042
+ } else {
2043
+ /*
2044
+ * switch connect. login failed. Take connection down
2045
+ * and allow relogin to retrigger
2046
+ */
2047
+ if (NVME_FCP_TARGET(ea->fcport)) {
2048
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
2049
+ "%s %d %8phC post %s prli\n",
2050
+ __func__, __LINE__,
2051
+ ea->fcport->port_name,
2052
+ (ea->fcport->fc4_type & FS_FC4TYPE_NVME)
2053
+ ? "NVMe" : "FCP");
2054
+ if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
2055
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
2056
+ else
2057
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
2058
+ }
2059
+
2060
+ ea->fcport->flags &= ~FCF_ASYNC_SENT;
2061
+ ea->fcport->keep_nport_handle = 0;
2062
+ ea->fcport->logout_on_delete = 1;
2063
+ qlt_schedule_sess_for_deletion(ea->fcport);
18912064 }
1892
- ql_dbg(ql_dbg_disc, vha, 0x2119,
1893
- "%s %d %8phC unhandle event of %x\n",
1894
- __func__, __LINE__, ea->fcport->port_name, ea->data[0]);
18952065 break;
18962066 }
18972067 }
18982068
1899
-static void
2069
+void
19002070 qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
19012071 {
19022072 port_id_t cid; /* conflict Nport id */
....@@ -1909,7 +2079,7 @@
19092079 "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d data %x|%x iop %x|%x\n",
19102080 __func__, fcport->port_name, fcport->disc_state,
19112081 fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
1912
- ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1,
2082
+ ea->sp->gen1, fcport->rscn_gen,
19132083 ea->data[0], ea->data[1], ea->iop[0], ea->iop[1]);
19142084
19152085 if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
....@@ -1934,11 +2104,16 @@
19342104 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
19352105 return;
19362106 } else if (ea->sp->gen1 != fcport->rscn_gen) {
1937
- ql_dbg(ql_dbg_disc, vha, 0x20d4, "%s %d %8phC post gidpn\n",
1938
- __func__, __LINE__, fcport->port_name);
1939
- qla24xx_post_gidpn_work(vha, fcport);
2107
+ ql_dbg(ql_dbg_disc, vha, 0x20d3,
2108
+ "%s %8phC RSCN generation changed\n",
2109
+ __func__, fcport->port_name);
2110
+ qla_rscn_replay(fcport);
2111
+ qlt_schedule_sess_for_deletion(fcport);
19402112 return;
19412113 }
2114
+
2115
+ WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
2116
+ ea->data[0]);
19422117
19432118 switch (ea->data[0]) {
19442119 case MBS_COMMAND_COMPLETE:
....@@ -1947,14 +2122,14 @@
19472122 * force a relogin attempt via implicit LOGO, PLOGI, and PRLI
19482123 * requests.
19492124 */
1950
- if (ea->fcport->fc4f_nvme) {
2125
+ if (NVME_TARGET(vha->hw, ea->fcport)) {
19512126 ql_dbg(ql_dbg_disc, vha, 0x2117,
19522127 "%s %d %8phC post prli\n",
19532128 __func__, __LINE__, ea->fcport->port_name);
19542129 qla24xx_post_prli_work(vha, ea->fcport);
19552130 } else {
19562131 ql_dbg(ql_dbg_disc, vha, 0x20ea,
1957
- "%s %d %8phC LoopID 0x%x in use with %06x. post gnl\n",
2132
+ "%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n",
19582133 __func__, __LINE__, ea->fcport->port_name,
19592134 ea->fcport->loop_id, ea->fcport->d_id.b24);
19602135
....@@ -1973,12 +2148,7 @@
19732148 ql_dbg(ql_dbg_disc, vha, 0x20eb, "%s %d %8phC cmd error %x\n",
19742149 __func__, __LINE__, ea->fcport->port_name, ea->data[1]);
19752150
1976
- ea->fcport->flags &= ~FCF_ASYNC_SENT;
1977
- ea->fcport->disc_state = DSC_LOGIN_FAILED;
1978
- if (ea->data[1] & QLA_LOGIO_LOGIN_RETRIED)
1979
- set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
1980
- else
1981
- qla2x00_mark_device_lost(vha, ea->fcport, 1, 0);
2151
+ qlt_schedule_sess_for_deletion(ea->fcport);
19822152 break;
19832153 case MBS_LOOP_ID_USED:
19842154 /* data[1] = IO PARAM 1 = nport ID */
....@@ -2015,8 +2185,6 @@
20152185 "%s %d %8phC NPortId %06x inuse with loopid 0x%x. post gidpn\n",
20162186 __func__, __LINE__, ea->fcport->port_name,
20172187 ea->fcport->d_id.b24, lid);
2018
- qla2x00_clear_loop_id(ea->fcport);
2019
- qla24xx_post_gidpn_work(vha, ea->fcport);
20202188 } else {
20212189 ql_dbg(ql_dbg_disc, vha, 0x20ed,
20222190 "%s %d %8phC NPortId %06x inuse with loopid 0x%x. sched delete\n",
....@@ -2027,40 +2195,11 @@
20272195 set_bit(lid, vha->hw->loop_id_map);
20282196 ea->fcport->loop_id = lid;
20292197 ea->fcport->keep_nport_handle = 0;
2198
+ ea->fcport->logout_on_delete = 1;
20302199 qlt_schedule_sess_for_deletion(ea->fcport);
20312200 }
20322201 break;
20332202 }
2034
- return;
2035
-}
2036
-
2037
-void
2038
-qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
2039
- uint16_t *data)
2040
-{
2041
- qlt_logo_completion_handler(fcport, data[0]);
2042
- fcport->login_gen++;
2043
- fcport->flags &= ~FCF_ASYNC_ACTIVE;
2044
- return;
2045
-}
2046
-
2047
-void
2048
-qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
2049
- uint16_t *data)
2050
-{
2051
- fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
2052
- if (data[0] == MBS_COMMAND_COMPLETE) {
2053
- qla2x00_update_fcport(vha, fcport);
2054
-
2055
- return;
2056
- }
2057
-
2058
- /* Retry login. */
2059
- if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
2060
- set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
2061
- else
2062
- qla2x00_mark_device_lost(vha, fcport, 1, 0);
2063
-
20642203 return;
20652204 }
20662205
....@@ -2157,6 +2296,7 @@
21572296 int rval;
21582297 struct qla_hw_data *ha = vha->hw;
21592298 struct req_que *req = ha->req_q_map[0];
2299
+ struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
21602300
21612301 memset(&vha->qla_stats, 0, sizeof(vha->qla_stats));
21622302 memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat));
....@@ -2191,6 +2331,15 @@
21912331
21922332 ha->isp_ops->reset_chip(vha);
21932333
2334
+ /* Check for secure flash support */
2335
+ if (IS_QLA28XX(ha)) {
2336
+ if (rd_reg_word(&reg->mailbox12) & BIT_0)
2337
+ ha->flags.secure_adapter = 1;
2338
+ ql_log(ql_log_info, vha, 0xffff, "Secure Adapter: %s\n",
2339
+ (ha->flags.secure_adapter) ? "Yes" : "No");
2340
+ }
2341
+
2342
+
21942343 rval = qla2xxx_get_flash_info(vha);
21952344 if (rval) {
21962345 ql_log(ql_log_fatal, vha, 0x004f,
....@@ -2213,7 +2362,17 @@
22132362 ql_dbg(ql_dbg_init, vha, 0x0061,
22142363 "Configure NVRAM parameters...\n");
22152364
2365
+ /* Let priority default to FCP, can be overridden by nvram_config */
2366
+ ha->fc4_type_priority = FC4_PRIORITY_FCP;
2367
+
22162368 ha->isp_ops->nvram_config(vha);
2369
+
2370
+ if (ha->fc4_type_priority != FC4_PRIORITY_FCP &&
2371
+ ha->fc4_type_priority != FC4_PRIORITY_NVME)
2372
+ ha->fc4_type_priority = FC4_PRIORITY_FCP;
2373
+
2374
+ ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n",
2375
+ ha->fc4_type_priority == FC4_PRIORITY_FCP ? "FCP" : "NVMe");
22172376
22182377 if (ha->flags.disable_serdes) {
22192378 /* Mask HBA via NVRAM settings? */
....@@ -2224,6 +2383,12 @@
22242383
22252384 ql_dbg(ql_dbg_init, vha, 0x0078,
22262385 "Verifying loaded RISC code...\n");
2386
+
2387
+ /* If smartsan enabled then require fdmi and rdp enabled */
2388
+ if (ql2xsmartsan) {
2389
+ ql2xfdmienable = 1;
2390
+ ql2xrdpenable = 1;
2391
+ }
22272392
22282393 if (qla2x00_isp_firmware(vha) != QLA_SUCCESS) {
22292394 rval = ha->isp_ops->chip_diag(vha);
....@@ -2245,6 +2410,10 @@
22452410
22462411 if (qla_ini_mode_enabled(vha) || qla_dual_mode_enabled(vha))
22472412 rval = qla2x00_init_rings(vha);
2413
+
2414
+ /* No point in continuing if firmware initialization failed. */
2415
+ if (rval != QLA_SUCCESS)
2416
+ return rval;
22482417
22492418 ha->flags.chip_reset_done = 1;
22502419
....@@ -2302,7 +2471,7 @@
23022471
23032472 /* Get PCI bus information. */
23042473 spin_lock_irqsave(&ha->hardware_lock, flags);
2305
- ha->pci_attr = RD_REG_WORD(&reg->ctrl_status);
2474
+ ha->pci_attr = rd_reg_word(&reg->ctrl_status);
23062475 spin_unlock_irqrestore(&ha->hardware_lock, flags);
23072476
23082477 return QLA_SUCCESS;
....@@ -2344,17 +2513,17 @@
23442513 spin_lock_irqsave(&ha->hardware_lock, flags);
23452514
23462515 /* Pause RISC. */
2347
- WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
2516
+ wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
23482517 for (cnt = 0; cnt < 30000; cnt++) {
2349
- if ((RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) != 0)
2518
+ if ((rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) != 0)
23502519 break;
23512520
23522521 udelay(10);
23532522 }
23542523
23552524 /* Select FPM registers. */
2356
- WRT_REG_WORD(&reg->ctrl_status, 0x20);
2357
- RD_REG_WORD(&reg->ctrl_status);
2525
+ wrt_reg_word(&reg->ctrl_status, 0x20);
2526
+ rd_reg_word(&reg->ctrl_status);
23582527
23592528 /* Get the fb rev level */
23602529 ha->fb_rev = RD_FB_CMD_REG(ha, reg);
....@@ -2363,13 +2532,13 @@
23632532 pci_clear_mwi(ha->pdev);
23642533
23652534 /* Deselect FPM registers. */
2366
- WRT_REG_WORD(&reg->ctrl_status, 0x0);
2367
- RD_REG_WORD(&reg->ctrl_status);
2535
+ wrt_reg_word(&reg->ctrl_status, 0x0);
2536
+ rd_reg_word(&reg->ctrl_status);
23682537
23692538 /* Release RISC module. */
2370
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
2539
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
23712540 for (cnt = 0; cnt < 30000; cnt++) {
2372
- if ((RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0)
2541
+ if ((rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) == 0)
23732542 break;
23742543
23752544 udelay(10);
....@@ -2384,7 +2553,7 @@
23842553
23852554 /* Get PCI bus information. */
23862555 spin_lock_irqsave(&ha->hardware_lock, flags);
2387
- ha->pci_attr = RD_REG_WORD(&reg->ctrl_status);
2556
+ ha->pci_attr = rd_reg_word(&reg->ctrl_status);
23882557 spin_unlock_irqrestore(&ha->hardware_lock, flags);
23892558
23902559 return QLA_SUCCESS;
....@@ -2428,7 +2597,7 @@
24282597
24292598 /* Get PCI bus information. */
24302599 spin_lock_irqsave(&ha->hardware_lock, flags);
2431
- ha->pci_attr = RD_REG_DWORD(&reg->ctrl_status);
2600
+ ha->pci_attr = rd_reg_dword(&reg->ctrl_status);
24322601 spin_unlock_irqrestore(&ha->hardware_lock, flags);
24332602
24342603 return QLA_SUCCESS;
....@@ -2507,7 +2676,7 @@
25072676 *
25082677 * Returns 0 on success.
25092678 */
2510
-void
2679
+int
25112680 qla2x00_reset_chip(scsi_qla_host_t *vha)
25122681 {
25132682 unsigned long flags = 0;
....@@ -2515,9 +2684,10 @@
25152684 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
25162685 uint32_t cnt;
25172686 uint16_t cmd;
2687
+ int rval = QLA_FUNCTION_FAILED;
25182688
25192689 if (unlikely(pci_channel_offline(ha->pdev)))
2520
- return;
2690
+ return rval;
25212691
25222692 ha->isp_ops->disable_intrs(ha);
25232693
....@@ -2531,36 +2701,36 @@
25312701
25322702 if (!IS_QLA2100(ha)) {
25332703 /* Pause RISC. */
2534
- WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
2704
+ wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
25352705 if (IS_QLA2200(ha) || IS_QLA2300(ha)) {
25362706 for (cnt = 0; cnt < 30000; cnt++) {
2537
- if ((RD_REG_WORD(&reg->hccr) &
2707
+ if ((rd_reg_word(&reg->hccr) &
25382708 HCCR_RISC_PAUSE) != 0)
25392709 break;
25402710 udelay(100);
25412711 }
25422712 } else {
2543
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2713
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
25442714 udelay(10);
25452715 }
25462716
25472717 /* Select FPM registers. */
2548
- WRT_REG_WORD(&reg->ctrl_status, 0x20);
2549
- RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
2718
+ wrt_reg_word(&reg->ctrl_status, 0x20);
2719
+ rd_reg_word(&reg->ctrl_status); /* PCI Posting. */
25502720
25512721 /* FPM Soft Reset. */
2552
- WRT_REG_WORD(&reg->fpm_diag_config, 0x100);
2553
- RD_REG_WORD(&reg->fpm_diag_config); /* PCI Posting. */
2722
+ wrt_reg_word(&reg->fpm_diag_config, 0x100);
2723
+ rd_reg_word(&reg->fpm_diag_config); /* PCI Posting. */
25542724
25552725 /* Toggle Fpm Reset. */
25562726 if (!IS_QLA2200(ha)) {
2557
- WRT_REG_WORD(&reg->fpm_diag_config, 0x0);
2558
- RD_REG_WORD(&reg->fpm_diag_config); /* PCI Posting. */
2727
+ wrt_reg_word(&reg->fpm_diag_config, 0x0);
2728
+ rd_reg_word(&reg->fpm_diag_config); /* PCI Posting. */
25592729 }
25602730
25612731 /* Select frame buffer registers. */
2562
- WRT_REG_WORD(&reg->ctrl_status, 0x10);
2563
- RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
2732
+ wrt_reg_word(&reg->ctrl_status, 0x10);
2733
+ rd_reg_word(&reg->ctrl_status); /* PCI Posting. */
25642734
25652735 /* Reset frame buffer FIFOs. */
25662736 if (IS_QLA2200(ha)) {
....@@ -2578,23 +2748,23 @@
25782748 }
25792749
25802750 /* Select RISC module registers. */
2581
- WRT_REG_WORD(&reg->ctrl_status, 0);
2582
- RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
2751
+ wrt_reg_word(&reg->ctrl_status, 0);
2752
+ rd_reg_word(&reg->ctrl_status); /* PCI Posting. */
25832753
25842754 /* Reset RISC processor. */
2585
- WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
2586
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2755
+ wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
2756
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
25872757
25882758 /* Release RISC processor. */
2589
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
2590
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2759
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
2760
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
25912761 }
25922762
2593
- WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
2594
- WRT_REG_WORD(&reg->hccr, HCCR_CLR_HOST_INT);
2763
+ wrt_reg_word(&reg->hccr, HCCR_CLR_RISC_INT);
2764
+ wrt_reg_word(&reg->hccr, HCCR_CLR_HOST_INT);
25952765
25962766 /* Reset ISP chip. */
2597
- WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
2767
+ wrt_reg_word(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
25982768
25992769 /* Wait for RISC to recover from reset. */
26002770 if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
....@@ -2605,7 +2775,7 @@
26052775 */
26062776 udelay(20);
26072777 for (cnt = 30000; cnt; cnt--) {
2608
- if ((RD_REG_WORD(&reg->ctrl_status) &
2778
+ if ((rd_reg_word(&reg->ctrl_status) &
26092779 CSR_ISP_SOFT_RESET) == 0)
26102780 break;
26112781 udelay(100);
....@@ -2614,13 +2784,13 @@
26142784 udelay(10);
26152785
26162786 /* Reset RISC processor. */
2617
- WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
2787
+ wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
26182788
2619
- WRT_REG_WORD(&reg->semaphore, 0);
2789
+ wrt_reg_word(&reg->semaphore, 0);
26202790
26212791 /* Release RISC processor. */
2622
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
2623
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2792
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
2793
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
26242794
26252795 if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
26262796 for (cnt = 0; cnt < 30000; cnt++) {
....@@ -2638,11 +2808,13 @@
26382808
26392809 /* Disable RISC pause on FPM parity error. */
26402810 if (!IS_QLA2100(ha)) {
2641
- WRT_REG_WORD(&reg->hccr, HCCR_DISABLE_PARITY_PAUSE);
2642
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2811
+ wrt_reg_word(&reg->hccr, HCCR_DISABLE_PARITY_PAUSE);
2812
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
26432813 }
26442814
26452815 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2816
+
2817
+ return QLA_SUCCESS;
26462818 }
26472819
26482820 /**
....@@ -2682,32 +2854,32 @@
26822854 spin_lock_irqsave(&ha->hardware_lock, flags);
26832855
26842856 /* Reset RISC. */
2685
- WRT_REG_DWORD(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
2857
+ wrt_reg_dword(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
26862858 for (cnt = 0; cnt < 30000; cnt++) {
2687
- if ((RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
2859
+ if ((rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
26882860 break;
26892861
26902862 udelay(10);
26912863 }
26922864
2693
- if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
2865
+ if (!(rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
26942866 set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
26952867
26962868 ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017e,
26972869 "HCCR: 0x%x, Control Status %x, DMA active status:0x%x\n",
2698
- RD_REG_DWORD(&reg->hccr),
2699
- RD_REG_DWORD(&reg->ctrl_status),
2700
- (RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE));
2870
+ rd_reg_dword(&reg->hccr),
2871
+ rd_reg_dword(&reg->ctrl_status),
2872
+ (rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE));
27012873
2702
- WRT_REG_DWORD(&reg->ctrl_status,
2874
+ wrt_reg_dword(&reg->ctrl_status,
27032875 CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
27042876 pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
27052877
27062878 udelay(100);
27072879
27082880 /* Wait for firmware to complete NVRAM accesses. */
2709
- RD_REG_WORD(&reg->mailbox0);
2710
- for (cnt = 10000; RD_REG_WORD(&reg->mailbox0) != 0 &&
2881
+ rd_reg_word(&reg->mailbox0);
2882
+ for (cnt = 10000; rd_reg_word(&reg->mailbox0) != 0 &&
27112883 rval == QLA_SUCCESS; cnt--) {
27122884 barrier();
27132885 if (cnt)
....@@ -2721,26 +2893,26 @@
27212893
27222894 ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017f,
27232895 "HCCR: 0x%x, MailBox0 Status 0x%x\n",
2724
- RD_REG_DWORD(&reg->hccr),
2725
- RD_REG_DWORD(&reg->mailbox0));
2896
+ rd_reg_dword(&reg->hccr),
2897
+ rd_reg_word(&reg->mailbox0));
27262898
27272899 /* Wait for soft-reset to complete. */
2728
- RD_REG_DWORD(&reg->ctrl_status);
2900
+ rd_reg_dword(&reg->ctrl_status);
27292901 for (cnt = 0; cnt < 60; cnt++) {
27302902 barrier();
2731
- if ((RD_REG_DWORD(&reg->ctrl_status) &
2903
+ if ((rd_reg_dword(&reg->ctrl_status) &
27322904 CSRX_ISP_SOFT_RESET) == 0)
27332905 break;
27342906
27352907 udelay(5);
27362908 }
2737
- if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
2909
+ if (!(rd_reg_dword(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
27382910 set_bit(ISP_SOFT_RESET_CMPL, &ha->fw_dump_cap_flags);
27392911
27402912 ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015d,
27412913 "HCCR: 0x%x, Soft Reset status: 0x%x\n",
2742
- RD_REG_DWORD(&reg->hccr),
2743
- RD_REG_DWORD(&reg->ctrl_status));
2914
+ rd_reg_dword(&reg->hccr),
2915
+ rd_reg_dword(&reg->ctrl_status));
27442916
27452917 /* If required, do an MPI FW reset now */
27462918 if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) {
....@@ -2759,17 +2931,17 @@
27592931 }
27602932 }
27612933
2762
- WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
2763
- RD_REG_DWORD(&reg->hccr);
2934
+ wrt_reg_dword(&reg->hccr, HCCRX_SET_RISC_RESET);
2935
+ rd_reg_dword(&reg->hccr);
27642936
2765
- WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
2766
- RD_REG_DWORD(&reg->hccr);
2937
+ wrt_reg_dword(&reg->hccr, HCCRX_REL_RISC_PAUSE);
2938
+ rd_reg_dword(&reg->hccr);
27672939
2768
- WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
2769
- RD_REG_DWORD(&reg->hccr);
2940
+ wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_RESET);
2941
+ rd_reg_dword(&reg->hccr);
27702942
2771
- RD_REG_WORD(&reg->mailbox0);
2772
- for (cnt = 60; RD_REG_WORD(&reg->mailbox0) != 0 &&
2943
+ rd_reg_word(&reg->mailbox0);
2944
+ for (cnt = 60; rd_reg_word(&reg->mailbox0) != 0 &&
27732945 rval == QLA_SUCCESS; cnt--) {
27742946 barrier();
27752947 if (cnt)
....@@ -2782,8 +2954,8 @@
27822954
27832955 ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015e,
27842956 "Host Risc 0x%x, mailbox0 0x%x\n",
2785
- RD_REG_DWORD(&reg->hccr),
2786
- RD_REG_WORD(&reg->mailbox0));
2957
+ rd_reg_dword(&reg->hccr),
2958
+ rd_reg_word(&reg->mailbox0));
27872959
27882960 spin_unlock_irqrestore(&ha->hardware_lock, flags);
27892961
....@@ -2802,9 +2974,8 @@
28022974 {
28032975 struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
28042976
2805
- WRT_REG_DWORD(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
2806
- *data = RD_REG_DWORD(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFET);
2807
-
2977
+ wrt_reg_dword(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
2978
+ *data = rd_reg_dword(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFSET);
28082979 }
28092980
28102981 static void
....@@ -2812,8 +2983,8 @@
28122983 {
28132984 struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
28142985
2815
- WRT_REG_DWORD(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
2816
- WRT_REG_DWORD(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFET, data);
2986
+ wrt_reg_dword(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
2987
+ wrt_reg_dword(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFSET, data);
28172988 }
28182989
28192990 static void
....@@ -2829,7 +3000,7 @@
28293000 vha->hw->pdev->subsystem_device != 0x0240)
28303001 return;
28313002
2832
- WRT_REG_DWORD(&vha->hw->iobase->isp24.hccr, HCCRX_SET_RISC_PAUSE);
3003
+ wrt_reg_dword(&vha->hw->iobase->isp24.hccr, HCCRX_SET_RISC_PAUSE);
28333004 udelay(100);
28343005
28353006 attempt:
....@@ -2883,14 +3054,15 @@
28833054 *
28843055 * Returns 0 on success.
28853056 */
2886
-void
3057
+int
28873058 qla24xx_reset_chip(scsi_qla_host_t *vha)
28883059 {
28893060 struct qla_hw_data *ha = vha->hw;
3061
+ int rval = QLA_FUNCTION_FAILED;
28903062
28913063 if (pci_channel_offline(ha->pdev) &&
28923064 ha->flags.pci_channel_io_perm_failure) {
2893
- return;
3065
+ return rval;
28943066 }
28953067
28963068 ha->isp_ops->disable_intrs(ha);
....@@ -2898,7 +3070,9 @@
28983070 qla25xx_manipulate_risc_semaphore(vha);
28993071
29003072 /* Perform RISC reset. */
2901
- qla24xx_reset_risc(vha);
3073
+ rval = qla24xx_reset_risc(vha);
3074
+
3075
+ return rval;
29023076 }
29033077
29043078 /**
....@@ -2928,7 +3102,7 @@
29283102 spin_lock_irqsave(&ha->hardware_lock, flags);
29293103
29303104 /* Reset ISP chip. */
2931
- WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
3105
+ wrt_reg_word(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
29323106
29333107 /*
29343108 * We need to have a delay here since the card will not respond while
....@@ -2938,7 +3112,7 @@
29383112 data = qla2x00_debounce_register(&reg->ctrl_status);
29393113 for (cnt = 6000000 ; cnt && (data & CSR_ISP_SOFT_RESET); cnt--) {
29403114 udelay(5);
2941
- data = RD_REG_WORD(&reg->ctrl_status);
3115
+ data = rd_reg_word(&reg->ctrl_status);
29423116 barrier();
29433117 }
29443118
....@@ -2949,8 +3123,8 @@
29493123 "Reset register cleared by chip reset.\n");
29503124
29513125 /* Reset RISC processor. */
2952
- WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
2953
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
3126
+ wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
3127
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
29543128
29553129 /* Workaround for QLA2312 PCI parity error */
29563130 if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
....@@ -3056,89 +3230,102 @@
30563230 }
30573231
30583232 static void
3059
-qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
3233
+qla2x00_init_fce_trace(scsi_qla_host_t *vha)
30603234 {
30613235 int rval;
30623236 dma_addr_t tc_dma;
30633237 void *tc;
30643238 struct qla_hw_data *ha = vha->hw;
30653239
3240
+ if (!IS_FWI2_CAPABLE(ha))
3241
+ return;
3242
+
3243
+ if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
3244
+ !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
3245
+ return;
3246
+
3247
+ if (ha->fce) {
3248
+ ql_dbg(ql_dbg_init, vha, 0x00bd,
3249
+ "%s: FCE Mem is already allocated.\n",
3250
+ __func__);
3251
+ return;
3252
+ }
3253
+
3254
+ /* Allocate memory for Fibre Channel Event Buffer. */
3255
+ tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
3256
+ GFP_KERNEL);
3257
+ if (!tc) {
3258
+ ql_log(ql_log_warn, vha, 0x00be,
3259
+ "Unable to allocate (%d KB) for FCE.\n",
3260
+ FCE_SIZE / 1024);
3261
+ return;
3262
+ }
3263
+
3264
+ rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS,
3265
+ ha->fce_mb, &ha->fce_bufs);
3266
+ if (rval) {
3267
+ ql_log(ql_log_warn, vha, 0x00bf,
3268
+ "Unable to initialize FCE (%d).\n", rval);
3269
+ dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma);
3270
+ return;
3271
+ }
3272
+
3273
+ ql_dbg(ql_dbg_init, vha, 0x00c0,
3274
+ "Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024);
3275
+
3276
+ ha->flags.fce_enabled = 1;
3277
+ ha->fce_dma = tc_dma;
3278
+ ha->fce = tc;
3279
+}
3280
+
3281
+static void
3282
+qla2x00_init_eft_trace(scsi_qla_host_t *vha)
3283
+{
3284
+ int rval;
3285
+ dma_addr_t tc_dma;
3286
+ void *tc;
3287
+ struct qla_hw_data *ha = vha->hw;
3288
+
3289
+ if (!IS_FWI2_CAPABLE(ha))
3290
+ return;
3291
+
30663292 if (ha->eft) {
30673293 ql_dbg(ql_dbg_init, vha, 0x00bd,
3068
- "%s: Offload Mem is already allocated.\n",
3294
+ "%s: EFT Mem is already allocated.\n",
30693295 __func__);
30703296 return;
30713297 }
30723298
3073
- if (IS_FWI2_CAPABLE(ha)) {
3074
- /* Allocate memory for Fibre Channel Event Buffer. */
3075
- if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
3076
- !IS_QLA27XX(ha))
3077
- goto try_eft;
3078
-
3079
- if (ha->fce)
3080
- dma_free_coherent(&ha->pdev->dev,
3081
- FCE_SIZE, ha->fce, ha->fce_dma);
3082
-
3083
- /* Allocate memory for Fibre Channel Event Buffer. */
3084
- tc = dma_zalloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
3085
- GFP_KERNEL);
3086
- if (!tc) {
3087
- ql_log(ql_log_warn, vha, 0x00be,
3088
- "Unable to allocate (%d KB) for FCE.\n",
3089
- FCE_SIZE / 1024);
3090
- goto try_eft;
3091
- }
3092
-
3093
- rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS,
3094
- ha->fce_mb, &ha->fce_bufs);
3095
- if (rval) {
3096
- ql_log(ql_log_warn, vha, 0x00bf,
3097
- "Unable to initialize FCE (%d).\n", rval);
3098
- dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc,
3099
- tc_dma);
3100
- ha->flags.fce_enabled = 0;
3101
- goto try_eft;
3102
- }
3103
- ql_dbg(ql_dbg_init, vha, 0x00c0,
3104
- "Allocate (%d KB) for FCE...\n", FCE_SIZE / 1024);
3105
-
3106
- ha->flags.fce_enabled = 1;
3107
- ha->fce_dma = tc_dma;
3108
- ha->fce = tc;
3109
-
3110
-try_eft:
3111
- if (ha->eft)
3112
- dma_free_coherent(&ha->pdev->dev,
3113
- EFT_SIZE, ha->eft, ha->eft_dma);
3114
-
3115
- /* Allocate memory for Extended Trace Buffer. */
3116
- tc = dma_zalloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
3117
- GFP_KERNEL);
3118
- if (!tc) {
3119
- ql_log(ql_log_warn, vha, 0x00c1,
3120
- "Unable to allocate (%d KB) for EFT.\n",
3121
- EFT_SIZE / 1024);
3122
- goto eft_err;
3123
- }
3124
-
3125
- rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
3126
- if (rval) {
3127
- ql_log(ql_log_warn, vha, 0x00c2,
3128
- "Unable to initialize EFT (%d).\n", rval);
3129
- dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc,
3130
- tc_dma);
3131
- goto eft_err;
3132
- }
3133
- ql_dbg(ql_dbg_init, vha, 0x00c3,
3134
- "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
3135
-
3136
- ha->eft_dma = tc_dma;
3137
- ha->eft = tc;
3299
+ /* Allocate memory for Extended Trace Buffer. */
3300
+ tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
3301
+ GFP_KERNEL);
3302
+ if (!tc) {
3303
+ ql_log(ql_log_warn, vha, 0x00c1,
3304
+ "Unable to allocate (%d KB) for EFT.\n",
3305
+ EFT_SIZE / 1024);
3306
+ return;
31383307 }
31393308
3140
-eft_err:
3141
- return;
3309
+ rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
3310
+ if (rval) {
3311
+ ql_log(ql_log_warn, vha, 0x00c2,
3312
+ "Unable to initialize EFT (%d).\n", rval);
3313
+ dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, tc_dma);
3314
+ return;
3315
+ }
3316
+
3317
+ ql_dbg(ql_dbg_init, vha, 0x00c3,
3318
+ "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
3319
+
3320
+ ha->eft_dma = tc_dma;
3321
+ ha->eft = tc;
3322
+}
3323
+
3324
+static void
3325
+qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
3326
+{
3327
+ qla2x00_init_fce_trace(vha);
3328
+ qla2x00_init_eft_trace(vha);
31423329 }
31433330
31443331 void
....@@ -3151,6 +3338,14 @@
31513338 struct rsp_que *rsp = ha->rsp_q_map[0];
31523339 struct qla2xxx_fw_dump *fw_dump;
31533340
3341
+ if (ha->fw_dump) {
3342
+ ql_dbg(ql_dbg_init, vha, 0x00bd,
3343
+ "Firmware dump already allocated.\n");
3344
+ return;
3345
+ }
3346
+
3347
+ ha->fw_dumped = 0;
3348
+ ha->fw_dump_cap_flags = 0;
31543349 dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
31553350 req_q_size = rsp_q_size = 0;
31563351
....@@ -3161,7 +3356,7 @@
31613356 mem_size = (ha->fw_memory_size - 0x11000 + 1) *
31623357 sizeof(uint16_t);
31633358 } else if (IS_FWI2_CAPABLE(ha)) {
3164
- if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
3359
+ if (IS_QLA83XX(ha))
31653360 fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem);
31663361 else if (IS_QLA81XX(ha))
31673362 fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem);
....@@ -3173,94 +3368,127 @@
31733368 mem_size = (ha->fw_memory_size - 0x100000 + 1) *
31743369 sizeof(uint32_t);
31753370 if (ha->mqenable) {
3176
- if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
3371
+ if (!IS_QLA83XX(ha))
31773372 mq_size = sizeof(struct qla2xxx_mq_chain);
31783373 /*
3179
- * Allocate maximum buffer size for all queues.
3374
+ * Allocate maximum buffer size for all queues - Q0.
31803375 * Resizing must be done at end-of-dump processing.
31813376 */
3182
- mq_size += ha->max_req_queues *
3377
+ mq_size += (ha->max_req_queues - 1) *
31833378 (req->length * sizeof(request_t));
3184
- mq_size += ha->max_rsp_queues *
3379
+ mq_size += (ha->max_rsp_queues - 1) *
31853380 (rsp->length * sizeof(response_t));
31863381 }
31873382 if (ha->tgt.atio_ring)
31883383 mq_size += ha->tgt.atio_q_length * sizeof(request_t);
3189
- /* Allocate memory for Fibre Channel Event Buffer. */
3190
- if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
3191
- !IS_QLA27XX(ha))
3192
- goto try_eft;
31933384
3194
- fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
3195
-try_eft:
3196
- ql_dbg(ql_dbg_init, vha, 0x00c3,
3197
- "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
3198
- eft_size = EFT_SIZE;
3385
+ qla2x00_init_fce_trace(vha);
3386
+ if (ha->fce)
3387
+ fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
3388
+ qla2x00_init_eft_trace(vha);
3389
+ if (ha->eft)
3390
+ eft_size = EFT_SIZE;
31993391 }
32003392
3201
- if (IS_QLA27XX(ha)) {
3202
- if (!ha->fw_dump_template) {
3203
- ql_log(ql_log_warn, vha, 0x00ba,
3204
- "Failed missing fwdump template\n");
3205
- return;
3393
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
3394
+ struct fwdt *fwdt = ha->fwdt;
3395
+ uint j;
3396
+
3397
+ for (j = 0; j < 2; j++, fwdt++) {
3398
+ if (!fwdt->template) {
3399
+ ql_dbg(ql_dbg_init, vha, 0x00ba,
3400
+ "-> fwdt%u no template\n", j);
3401
+ continue;
3402
+ }
3403
+ ql_dbg(ql_dbg_init, vha, 0x00fa,
3404
+ "-> fwdt%u calculating fwdump size...\n", j);
3405
+ fwdt->dump_size = qla27xx_fwdt_calculate_dump_size(
3406
+ vha, fwdt->template);
3407
+ ql_dbg(ql_dbg_init, vha, 0x00fa,
3408
+ "-> fwdt%u calculated fwdump size = %#lx bytes\n",
3409
+ j, fwdt->dump_size);
3410
+ dump_size += fwdt->dump_size;
32063411 }
3207
- dump_size = qla27xx_fwdt_calculate_dump_size(vha);
3208
- ql_dbg(ql_dbg_init, vha, 0x00fa,
3209
- "-> allocating fwdump (%x bytes)...\n", dump_size);
3210
- goto allocate;
3412
+ /* Add space for spare MPI fw dump. */
3413
+ dump_size += ha->fwdt[1].dump_size;
3414
+ } else {
3415
+ req_q_size = req->length * sizeof(request_t);
3416
+ rsp_q_size = rsp->length * sizeof(response_t);
3417
+ dump_size = offsetof(struct qla2xxx_fw_dump, isp);
3418
+ dump_size += fixed_size + mem_size + req_q_size + rsp_q_size
3419
+ + eft_size;
3420
+ ha->chain_offset = dump_size;
3421
+ dump_size += mq_size + fce_size;
3422
+ if (ha->exchoffld_buf)
3423
+ dump_size += sizeof(struct qla2xxx_offld_chain) +
3424
+ ha->exchoffld_size;
3425
+ if (ha->exlogin_buf)
3426
+ dump_size += sizeof(struct qla2xxx_offld_chain) +
3427
+ ha->exlogin_size;
32113428 }
32123429
3213
- req_q_size = req->length * sizeof(request_t);
3214
- rsp_q_size = rsp->length * sizeof(response_t);
3215
- dump_size = offsetof(struct qla2xxx_fw_dump, isp);
3216
- dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + eft_size;
3217
- ha->chain_offset = dump_size;
3218
- dump_size += mq_size + fce_size;
3430
+ if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) {
32193431
3220
- if (ha->exchoffld_buf)
3221
- dump_size += sizeof(struct qla2xxx_offld_chain) +
3222
- ha->exchoffld_size;
3223
- if (ha->exlogin_buf)
3224
- dump_size += sizeof(struct qla2xxx_offld_chain) +
3225
- ha->exlogin_size;
3432
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
3433
+ "%s dump_size %d fw_dump_len %d fw_dump_alloc_len %d\n",
3434
+ __func__, dump_size, ha->fw_dump_len,
3435
+ ha->fw_dump_alloc_len);
32263436
3227
-allocate:
3228
- if (!ha->fw_dump_len || dump_size != ha->fw_dump_len) {
32293437 fw_dump = vmalloc(dump_size);
32303438 if (!fw_dump) {
32313439 ql_log(ql_log_warn, vha, 0x00c4,
32323440 "Unable to allocate (%d KB) for firmware dump.\n",
32333441 dump_size / 1024);
32343442 } else {
3235
- if (ha->fw_dump)
3443
+ mutex_lock(&ha->optrom_mutex);
3444
+ if (ha->fw_dumped) {
3445
+ memcpy(fw_dump, ha->fw_dump, ha->fw_dump_len);
32363446 vfree(ha->fw_dump);
3237
- ha->fw_dump = fw_dump;
3447
+ ha->fw_dump = fw_dump;
3448
+ ha->fw_dump_alloc_len = dump_size;
3449
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
3450
+ "Re-Allocated (%d KB) and save firmware dump.\n",
3451
+ dump_size / 1024);
3452
+ } else {
3453
+ if (ha->fw_dump)
3454
+ vfree(ha->fw_dump);
3455
+ ha->fw_dump = fw_dump;
32383456
3239
- ha->fw_dump_len = dump_size;
3240
- ql_dbg(ql_dbg_init, vha, 0x00c5,
3241
- "Allocated (%d KB) for firmware dump.\n",
3242
- dump_size / 1024);
3457
+ ha->fw_dump_len = ha->fw_dump_alloc_len =
3458
+ dump_size;
3459
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
3460
+ "Allocated (%d KB) for firmware dump.\n",
3461
+ dump_size / 1024);
32433462
3244
- if (IS_QLA27XX(ha))
3245
- return;
3463
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
3464
+ ha->mpi_fw_dump = (char *)fw_dump +
3465
+ ha->fwdt[1].dump_size;
3466
+ mutex_unlock(&ha->optrom_mutex);
3467
+ return;
3468
+ }
32463469
3247
- ha->fw_dump->signature[0] = 'Q';
3248
- ha->fw_dump->signature[1] = 'L';
3249
- ha->fw_dump->signature[2] = 'G';
3250
- ha->fw_dump->signature[3] = 'C';
3251
- ha->fw_dump->version = htonl(1);
3470
+ ha->fw_dump->signature[0] = 'Q';
3471
+ ha->fw_dump->signature[1] = 'L';
3472
+ ha->fw_dump->signature[2] = 'G';
3473
+ ha->fw_dump->signature[3] = 'C';
3474
+ ha->fw_dump->version = htonl(1);
32523475
3253
- ha->fw_dump->fixed_size = htonl(fixed_size);
3254
- ha->fw_dump->mem_size = htonl(mem_size);
3255
- ha->fw_dump->req_q_size = htonl(req_q_size);
3256
- ha->fw_dump->rsp_q_size = htonl(rsp_q_size);
3476
+ ha->fw_dump->fixed_size = htonl(fixed_size);
3477
+ ha->fw_dump->mem_size = htonl(mem_size);
3478
+ ha->fw_dump->req_q_size = htonl(req_q_size);
3479
+ ha->fw_dump->rsp_q_size = htonl(rsp_q_size);
32573480
3258
- ha->fw_dump->eft_size = htonl(eft_size);
3259
- ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma));
3260
- ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma));
3481
+ ha->fw_dump->eft_size = htonl(eft_size);
3482
+ ha->fw_dump->eft_addr_l =
3483
+ htonl(LSD(ha->eft_dma));
3484
+ ha->fw_dump->eft_addr_h =
3485
+ htonl(MSD(ha->eft_dma));
32613486
3262
- ha->fw_dump->header_size =
3263
- htonl(offsetof(struct qla2xxx_fw_dump, isp));
3487
+ ha->fw_dump->header_size =
3488
+ htonl(offsetof
3489
+ (struct qla2xxx_fw_dump, isp));
3490
+ }
3491
+ mutex_unlock(&ha->optrom_mutex);
32643492 }
32653493 }
32663494 }
....@@ -3446,53 +3674,100 @@
34463674 }
34473675
34483676
3449
-/*
3450
- * Return Code:
3451
- * QLA_SUCCESS: no action
3452
- * QLA_INTERFACE_ERROR: SFP is not there.
3453
- * QLA_FUNCTION_FAILED: detected New SFP
3677
+/**
3678
+ * qla24xx_detect_sfp()
3679
+ *
3680
+ * @vha: adapter state pointer.
3681
+ *
3682
+ * @return
3683
+ * 0 -- Configure firmware to use short-range settings -- normal
3684
+ * buffer-to-buffer credits.
3685
+ *
3686
+ * 1 -- Configure firmware to use long-range settings -- extra
3687
+ * buffer-to-buffer credits should be allocated with
3688
+ * ha->lr_distance containing distance settings from NVRAM or SFP
3689
+ * (if supported).
34543690 */
34553691 int
34563692 qla24xx_detect_sfp(scsi_qla_host_t *vha)
34573693 {
3458
- int rc = QLA_SUCCESS;
3694
+ int rc, used_nvram;
34593695 struct sff_8247_a0 *a;
34603696 struct qla_hw_data *ha = vha->hw;
3697
+ struct nvram_81xx *nv = ha->nvram;
3698
+#define LR_DISTANCE_UNKNOWN 2
3699
+ static const char * const types[] = { "Short", "Long" };
3700
+ static const char * const lengths[] = { "(10km)", "(5km)", "" };
3701
+ u8 ll = 0;
34613702
3462
- if (!AUTO_DETECT_SFP_SUPPORT(vha))
3703
+ /* Seed with NVRAM settings. */
3704
+ used_nvram = 0;
3705
+ ha->flags.lr_detected = 0;
3706
+ if (IS_BPM_RANGE_CAPABLE(ha) &&
3707
+ (nv->enhanced_features & NEF_LR_DIST_ENABLE)) {
3708
+ used_nvram = 1;
3709
+ ha->flags.lr_detected = 1;
3710
+ ha->lr_distance =
3711
+ (nv->enhanced_features >> LR_DIST_NV_POS)
3712
+ & LR_DIST_NV_MASK;
3713
+ }
3714
+
3715
+ if (!IS_BPM_ENABLED(vha))
34633716 goto out;
3464
-
3717
+ /* Determine SR/LR capabilities of SFP/Transceiver. */
34653718 rc = qla2x00_read_sfp_dev(vha, NULL, 0);
34663719 if (rc)
34673720 goto out;
34683721
3722
+ used_nvram = 0;
34693723 a = (struct sff_8247_a0 *)vha->hw->sfp_data;
34703724 qla2xxx_print_sfp_info(vha);
34713725
3472
- if (a->fc_ll_cc7 & FC_LL_VL || a->fc_ll_cc7 & FC_LL_L) {
3473
- /* long range */
3474
- ha->flags.detected_lr_sfp = 1;
3726
+ ha->flags.lr_detected = 0;
3727
+ ll = a->fc_ll_cc7;
3728
+ if (ll & FC_LL_VL || ll & FC_LL_L) {
3729
+ /* Long range, track length. */
3730
+ ha->flags.lr_detected = 1;
34753731
34763732 if (a->length_km > 5 || a->length_100m > 50)
3477
- ha->long_range_distance = LR_DISTANCE_10K;
3733
+ ha->lr_distance = LR_DISTANCE_10K;
34783734 else
3479
- ha->long_range_distance = LR_DISTANCE_5K;
3480
-
3481
- if (ha->flags.detected_lr_sfp != ha->flags.using_lr_setting)
3482
- ql_dbg(ql_dbg_async, vha, 0x507b,
3483
- "Detected Long Range SFP.\n");
3484
- } else {
3485
- /* short range */
3486
- ha->flags.detected_lr_sfp = 0;
3487
- if (ha->flags.using_lr_setting)
3488
- ql_dbg(ql_dbg_async, vha, 0x5084,
3489
- "Detected Short Range SFP.\n");
3735
+ ha->lr_distance = LR_DISTANCE_5K;
34903736 }
34913737
3492
- if (!vha->flags.init_done)
3493
- rc = QLA_SUCCESS;
34943738 out:
3495
- return rc;
3739
+ ql_dbg(ql_dbg_async, vha, 0x507b,
3740
+ "SFP detect: %s-Range SFP %s (nvr=%x ll=%x lr=%x lrd=%x).\n",
3741
+ types[ha->flags.lr_detected],
3742
+ ha->flags.lr_detected ? lengths[ha->lr_distance] :
3743
+ lengths[LR_DISTANCE_UNKNOWN],
3744
+ used_nvram, ll, ha->flags.lr_detected, ha->lr_distance);
3745
+ return ha->flags.lr_detected;
3746
+}
3747
+
3748
+void qla_init_iocb_limit(scsi_qla_host_t *vha)
3749
+{
3750
+ u16 i, num_qps;
3751
+ u32 limit;
3752
+ struct qla_hw_data *ha = vha->hw;
3753
+
3754
+ num_qps = ha->num_qpairs + 1;
3755
+ limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100;
3756
+
3757
+ ha->base_qpair->fwres.iocbs_total = ha->orig_fw_iocb_count;
3758
+ ha->base_qpair->fwres.iocbs_limit = limit;
3759
+ ha->base_qpair->fwres.iocbs_qp_limit = limit / num_qps;
3760
+ ha->base_qpair->fwres.iocbs_used = 0;
3761
+ for (i = 0; i < ha->max_qpairs; i++) {
3762
+ if (ha->queue_pair_map[i]) {
3763
+ ha->queue_pair_map[i]->fwres.iocbs_total =
3764
+ ha->orig_fw_iocb_count;
3765
+ ha->queue_pair_map[i]->fwres.iocbs_limit = limit;
3766
+ ha->queue_pair_map[i]->fwres.iocbs_qp_limit =
3767
+ limit / num_qps;
3768
+ ha->queue_pair_map[i]->fwres.iocbs_used = 0;
3769
+ }
3770
+ }
34963771 }
34973772
34983773 /**
....@@ -3510,6 +3785,7 @@
35103785 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
35113786 unsigned long flags;
35123787 uint16_t fw_major_version;
3788
+ int done_once = 0;
35133789
35143790 if (IS_P3P_TYPE(ha)) {
35153791 rval = ha->isp_ops->load_risc(vha, &srisc_address);
....@@ -3523,13 +3799,14 @@
35233799 if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
35243800 /* Disable SRAM, Instruction RAM and GP RAM parity. */
35253801 spin_lock_irqsave(&ha->hardware_lock, flags);
3526
- WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x0));
3527
- RD_REG_WORD(&reg->hccr);
3802
+ wrt_reg_word(&reg->hccr, (HCCR_ENABLE_PARITY + 0x0));
3803
+ rd_reg_word(&reg->hccr);
35283804 spin_unlock_irqrestore(&ha->hardware_lock, flags);
35293805 }
35303806
35313807 qla81xx_mpi_sync(vha);
35323808
3809
+execute_fw_with_lr:
35333810 /* Load firmware sequences */
35343811 rval = ha->isp_ops->load_risc(vha, &srisc_address);
35353812 if (rval == QLA_SUCCESS) {
....@@ -3551,7 +3828,19 @@
35513828 rval = qla2x00_execute_fw(vha, srisc_address);
35523829 /* Retrieve firmware information. */
35533830 if (rval == QLA_SUCCESS) {
3554
- qla24xx_detect_sfp(vha);
3831
+ /* Enable BPM support? */
3832
+ if (!done_once++ && qla24xx_detect_sfp(vha)) {
3833
+ ql_dbg(ql_dbg_init, vha, 0x00ca,
3834
+ "Re-starting firmware -- BPM.\n");
3835
+ /* Best-effort - re-init. */
3836
+ ha->isp_ops->reset_chip(vha);
3837
+ ha->isp_ops->chip_diag(vha);
3838
+ goto execute_fw_with_lr;
3839
+ }
3840
+
3841
+ if (IS_ZIO_THRESHOLD_CAPABLE(ha))
3842
+ qla27xx_set_zio_threshold(vha,
3843
+ ha->last_zio_threshold);
35553844
35563845 rval = qla2x00_set_exlogins_buffer(vha);
35573846 if (rval != QLA_SUCCESS)
....@@ -3580,6 +3869,7 @@
35803869 MIN_MULTI_ID_FABRIC - 1;
35813870 }
35823871 qla2x00_get_resource_cnts(vha);
3872
+ qla_init_iocb_limit(vha);
35833873
35843874 /*
35853875 * Allocate the array of outstanding commands
....@@ -3604,6 +3894,10 @@
36043894 "ISP Firmware failed checksum.\n");
36053895 goto failed;
36063896 }
3897
+
3898
+ /* Enable PUREX PASSTHRU */
3899
+ if (ql2xrdpenable || ha->flags.scm_supported_f)
3900
+ qla25xx_set_els_cmds_supported(vha);
36073901 } else
36083902 goto failed;
36093903
....@@ -3612,15 +3906,15 @@
36123906 spin_lock_irqsave(&ha->hardware_lock, flags);
36133907 if (IS_QLA2300(ha))
36143908 /* SRAM parity */
3615
- WRT_REG_WORD(&reg->hccr, HCCR_ENABLE_PARITY + 0x1);
3909
+ wrt_reg_word(&reg->hccr, HCCR_ENABLE_PARITY + 0x1);
36163910 else
36173911 /* SRAM, Instruction RAM and GP RAM parity */
3618
- WRT_REG_WORD(&reg->hccr, HCCR_ENABLE_PARITY + 0x7);
3619
- RD_REG_WORD(&reg->hccr);
3912
+ wrt_reg_word(&reg->hccr, HCCR_ENABLE_PARITY + 0x7);
3913
+ rd_reg_word(&reg->hccr);
36203914 spin_unlock_irqrestore(&ha->hardware_lock, flags);
36213915 }
36223916
3623
- if (IS_QLA27XX(ha))
3917
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
36243918 ha->flags.fac_supported = 1;
36253919 else if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) {
36263920 uint32_t size;
....@@ -3635,7 +3929,7 @@
36353929 ha->fw_major_version, ha->fw_minor_version,
36363930 ha->fw_subminor_version);
36373931
3638
- if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
3932
+ if (IS_QLA83XX(ha)) {
36393933 ha->flags.fac_supported = 0;
36403934 rval = QLA_SUCCESS;
36413935 }
....@@ -3697,8 +3991,7 @@
36973991 ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0115,
36983992 "Serial link options.\n");
36993993 ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0109,
3700
- (uint8_t *)&ha->fw_seriallink_options,
3701
- sizeof(ha->fw_seriallink_options));
3994
+ ha->fw_seriallink_options, sizeof(ha->fw_seriallink_options));
37023995
37033996 ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
37043997 if (ha->fw_seriallink_options[3] & BIT_2) {
....@@ -3788,7 +4081,7 @@
37884081
37894082 /* Move PUREX, ABTS RX & RIDA to ATIOQ */
37904083 if (ql2xmvasynctoatio &&
3791
- (IS_QLA83XX(ha) || IS_QLA27XX(ha))) {
4084
+ (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) {
37924085 if (qla_tgt_mode_enabled(vha) ||
37934086 qla_dual_mode_enabled(vha))
37944087 ha->fw_options[2] |= BIT_11;
....@@ -3796,7 +4089,8 @@
37964089 ha->fw_options[2] &= ~BIT_11;
37974090 }
37984091
3799
- if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
4092
+ if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
4093
+ IS_QLA28XX(ha)) {
38004094 /*
38014095 * Tell FW to track each exchange to prevent
38024096 * driver from using stale exchange.
....@@ -3813,6 +4107,13 @@
38134107 else
38144108 ha->fw_options[2] &= ~BIT_8;
38154109 }
4110
+
4111
+ if (ql2xrdpenable || ha->flags.scm_supported_f)
4112
+ ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
4113
+
4114
+ /* Enable Async 8130/8131 events -- transceiver insertion/removal */
4115
+ if (IS_BPM_RANGE_CAPABLE(ha))
4116
+ ha->fw_options[3] |= BIT_10;
38164117
38174118 ql_dbg(ql_dbg_init, vha, 0x00e8,
38184119 "%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
....@@ -3849,16 +4150,14 @@
38494150 ha->init_cb->response_q_inpointer = cpu_to_le16(0);
38504151 ha->init_cb->request_q_length = cpu_to_le16(req->length);
38514152 ha->init_cb->response_q_length = cpu_to_le16(rsp->length);
3852
- ha->init_cb->request_q_address[0] = cpu_to_le32(LSD(req->dma));
3853
- ha->init_cb->request_q_address[1] = cpu_to_le32(MSD(req->dma));
3854
- ha->init_cb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma));
3855
- ha->init_cb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma));
4153
+ put_unaligned_le64(req->dma, &ha->init_cb->request_q_address);
4154
+ put_unaligned_le64(rsp->dma, &ha->init_cb->response_q_address);
38564155
3857
- WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), 0);
3858
- WRT_REG_WORD(ISP_REQ_Q_OUT(ha, reg), 0);
3859
- WRT_REG_WORD(ISP_RSP_Q_IN(ha, reg), 0);
3860
- WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), 0);
3861
- RD_REG_WORD(ISP_RSP_Q_OUT(ha, reg)); /* PCI Posting. */
4156
+ wrt_reg_word(ISP_REQ_Q_IN(ha, reg), 0);
4157
+ wrt_reg_word(ISP_REQ_Q_OUT(ha, reg), 0);
4158
+ wrt_reg_word(ISP_RSP_Q_IN(ha, reg), 0);
4159
+ wrt_reg_word(ISP_RSP_Q_OUT(ha, reg), 0);
4160
+ rd_reg_word(ISP_RSP_Q_OUT(ha, reg)); /* PCI Posting. */
38624161 }
38634162
38644163 void
....@@ -3879,21 +4178,19 @@
38794178 icb->response_q_inpointer = cpu_to_le16(0);
38804179 icb->request_q_length = cpu_to_le16(req->length);
38814180 icb->response_q_length = cpu_to_le16(rsp->length);
3882
- icb->request_q_address[0] = cpu_to_le32(LSD(req->dma));
3883
- icb->request_q_address[1] = cpu_to_le32(MSD(req->dma));
3884
- icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma));
3885
- icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma));
4181
+ put_unaligned_le64(req->dma, &icb->request_q_address);
4182
+ put_unaligned_le64(rsp->dma, &icb->response_q_address);
38864183
38874184 /* Setup ATIO queue dma pointers for target mode */
38884185 icb->atio_q_inpointer = cpu_to_le16(0);
38894186 icb->atio_q_length = cpu_to_le16(ha->tgt.atio_q_length);
3890
- icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma));
3891
- icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma));
4187
+ put_unaligned_le64(ha->tgt.atio_dma, &icb->atio_q_address);
38924188
38934189 if (IS_SHADOW_REG_CAPABLE(ha))
38944190 icb->firmware_options_2 |= cpu_to_le32(BIT_30|BIT_29);
38954191
3896
- if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
4192
+ if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
4193
+ IS_QLA28XX(ha)) {
38974194 icb->qos = cpu_to_le16(QLA_DEFAULT_QUE_QOS);
38984195 icb->rid = cpu_to_le16(rid);
38994196 if (ha->flags.msix_enabled) {
....@@ -3922,20 +4219,29 @@
39224219 }
39234220 icb->firmware_options_2 |= cpu_to_le32(BIT_23);
39244221
3925
- WRT_REG_DWORD(&reg->isp25mq.req_q_in, 0);
3926
- WRT_REG_DWORD(&reg->isp25mq.req_q_out, 0);
3927
- WRT_REG_DWORD(&reg->isp25mq.rsp_q_in, 0);
3928
- WRT_REG_DWORD(&reg->isp25mq.rsp_q_out, 0);
4222
+ wrt_reg_dword(&reg->isp25mq.req_q_in, 0);
4223
+ wrt_reg_dword(&reg->isp25mq.req_q_out, 0);
4224
+ wrt_reg_dword(&reg->isp25mq.rsp_q_in, 0);
4225
+ wrt_reg_dword(&reg->isp25mq.rsp_q_out, 0);
39294226 } else {
3930
- WRT_REG_DWORD(&reg->isp24.req_q_in, 0);
3931
- WRT_REG_DWORD(&reg->isp24.req_q_out, 0);
3932
- WRT_REG_DWORD(&reg->isp24.rsp_q_in, 0);
3933
- WRT_REG_DWORD(&reg->isp24.rsp_q_out, 0);
4227
+ wrt_reg_dword(&reg->isp24.req_q_in, 0);
4228
+ wrt_reg_dword(&reg->isp24.req_q_out, 0);
4229
+ wrt_reg_dword(&reg->isp24.rsp_q_in, 0);
4230
+ wrt_reg_dword(&reg->isp24.rsp_q_out, 0);
39344231 }
4232
+
39354233 qlt_24xx_config_rings(vha);
39364234
4235
+ /* If the user has configured the speed, set it here */
4236
+ if (ha->set_data_rate) {
4237
+ ql_dbg(ql_dbg_init, vha, 0x00fd,
4238
+ "Speed set by user : %s Gbps \n",
4239
+ qla2x00_get_link_speed_str(ha, ha->set_data_rate));
4240
+ icb->firmware_options_3 = cpu_to_le32(ha->set_data_rate << 13);
4241
+ }
4242
+
39374243 /* PCI posting */
3938
- RD_REG_DWORD(&ioreg->hccr);
4244
+ rd_reg_word(&ioreg->hccr);
39394245 }
39404246
39414247 /**
....@@ -3966,7 +4272,7 @@
39664272 req = ha->req_q_map[que];
39674273 if (!req || !test_bit(que, ha->req_qid_map))
39684274 continue;
3969
- req->out_ptr = (void *)(req->ring + req->length);
4275
+ req->out_ptr = (uint16_t *)(req->ring + req->length);
39704276 *req->out_ptr = 0;
39714277 for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++)
39724278 req->outstanding_cmds[cnt] = NULL;
....@@ -3983,7 +4289,7 @@
39834289 rsp = ha->rsp_q_map[que];
39844290 if (!rsp || !test_bit(que, ha->rsp_qid_map))
39854291 continue;
3986
- rsp->in_ptr = (void *)(rsp->ring + rsp->length);
4292
+ rsp->in_ptr = (uint16_t *)(rsp->ring + rsp->length);
39874293 *rsp->in_ptr = 0;
39884294 /* Initialize response queue entries */
39894295 if (IS_QLAFX00(ha))
....@@ -4022,25 +4328,31 @@
40224328 mid_init_cb->init_cb.execution_throttle =
40234329 cpu_to_le16(ha->cur_fw_xcb_count);
40244330 ha->flags.dport_enabled =
4025
- (mid_init_cb->init_cb.firmware_options_1 & BIT_7) != 0;
4331
+ (le32_to_cpu(mid_init_cb->init_cb.firmware_options_1) &
4332
+ BIT_7) != 0;
40264333 ql_dbg(ql_dbg_init, vha, 0x0191, "DPORT Support: %s.\n",
40274334 (ha->flags.dport_enabled) ? "enabled" : "disabled");
40284335 /* FA-WWPN Status */
40294336 ha->flags.fawwpn_enabled =
4030
- (mid_init_cb->init_cb.firmware_options_1 & BIT_6) != 0;
4337
+ (le32_to_cpu(mid_init_cb->init_cb.firmware_options_1) &
4338
+ BIT_6) != 0;
40314339 ql_dbg(ql_dbg_init, vha, 0x00bc, "FA-WWPN Support: %s.\n",
40324340 (ha->flags.fawwpn_enabled) ? "enabled" : "disabled");
4341
+ /* Init_cb will be reused for other command(s). Save a backup copy of port_name */
4342
+ memcpy(ha->port_name, ha->init_cb->port_name, WWN_SIZE);
40334343 }
40344344
4345
+ QLA_FW_STARTED(ha);
40354346 rval = qla2x00_init_firmware(vha, ha->init_cb_size);
40364347 next_check:
40374348 if (rval) {
4349
+ QLA_FW_STOPPED(ha);
40384350 ql_log(ql_log_fatal, vha, 0x00d2,
40394351 "Init Firmware **** FAILED ****.\n");
40404352 } else {
40414353 ql_dbg(ql_dbg_init, vha, 0x00d3,
40424354 "Init Firmware -- success.\n");
4043
- QLA_FW_STARTED(ha);
4355
+ vha->u_ql2xexchoffld = vha->u_ql2xiniexchg = 0;
40444356 }
40454357
40464358 return (rval);
....@@ -4302,16 +4614,19 @@
43024614
43034615 inline void
43044616 qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
4305
- char *def)
4617
+ const char *def)
43064618 {
43074619 char *st, *en;
43084620 uint16_t index;
4621
+ uint64_t zero[2] = { 0 };
43094622 struct qla_hw_data *ha = vha->hw;
43104623 int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
43114624 !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha);
43124625
4313
- if (memcmp(model, BINZERO, len) != 0) {
4314
- strncpy(ha->model_number, model, len);
4626
+ if (len > sizeof(zero))
4627
+ len = sizeof(zero);
4628
+ if (memcmp(model, &zero, len) != 0) {
4629
+ memcpy(ha->model_number, model, len);
43154630 st = en = ha->model_number;
43164631 en += len - 1;
43174632 while (en > st) {
....@@ -4324,21 +4639,23 @@
43244639 if (use_tbl &&
43254640 ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
43264641 index < QLA_MODEL_NAMES)
4327
- strncpy(ha->model_desc,
4642
+ strlcpy(ha->model_desc,
43284643 qla2x00_model_name[index * 2 + 1],
4329
- sizeof(ha->model_desc) - 1);
4644
+ sizeof(ha->model_desc));
43304645 } else {
43314646 index = (ha->pdev->subsystem_device & 0xff);
43324647 if (use_tbl &&
43334648 ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
43344649 index < QLA_MODEL_NAMES) {
4335
- strcpy(ha->model_number,
4336
- qla2x00_model_name[index * 2]);
4337
- strncpy(ha->model_desc,
4650
+ strlcpy(ha->model_number,
4651
+ qla2x00_model_name[index * 2],
4652
+ sizeof(ha->model_number));
4653
+ strlcpy(ha->model_desc,
43384654 qla2x00_model_name[index * 2 + 1],
4339
- sizeof(ha->model_desc) - 1);
4655
+ sizeof(ha->model_desc));
43404656 } else {
4341
- strcpy(ha->model_number, def);
4657
+ strlcpy(ha->model_number, def,
4658
+ sizeof(ha->model_number));
43424659 }
43434660 }
43444661 if (IS_FWI2_CAPABLE(ha))
....@@ -4397,10 +4714,10 @@
43974714 rval = QLA_SUCCESS;
43984715
43994716 /* Determine NVRAM starting address. */
4400
- ha->nvram_size = sizeof(nvram_t);
4717
+ ha->nvram_size = sizeof(*nv);
44014718 ha->nvram_base = 0;
44024719 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha))
4403
- if ((RD_REG_WORD(&reg->ctrl_status) >> 14) == 1)
4720
+ if ((rd_reg_word(&reg->ctrl_status) >> 14) == 1)
44044721 ha->nvram_base = 0x80;
44054722
44064723 /* Get NVRAM data and calculate checksum. */
....@@ -4411,16 +4728,15 @@
44114728 ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x010f,
44124729 "Contents of NVRAM.\n");
44134730 ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0110,
4414
- (uint8_t *)nv, ha->nvram_size);
4731
+ nv, ha->nvram_size);
44154732
44164733 /* Bad NVRAM data, set defaults parameters. */
4417
- if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
4418
- nv->id[2] != 'P' || nv->id[3] != ' ' || nv->nvram_version < 1) {
4734
+ if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
4735
+ nv->nvram_version < 1) {
44194736 /* Reset NVRAM data. */
44204737 ql_log(ql_log_warn, vha, 0x0064,
4421
- "Inconsistent NVRAM "
4422
- "detected: checksum=0x%x id=%c version=0x%x.\n",
4423
- chksum, nv->id[0], nv->nvram_version);
4738
+ "Inconsistent NVRAM detected: checksum=%#x id=%.4s version=%#x.\n",
4739
+ chksum, nv->id, nv->nvram_version);
44244740 ql_log(ql_log_warn, vha, 0x0065,
44254741 "Falling back to "
44264742 "functioning (yet invalid -- WWPN) defaults.\n");
....@@ -4436,18 +4752,18 @@
44364752 nv->firmware_options[1] = BIT_7 | BIT_5;
44374753 nv->add_firmware_options[0] = BIT_5;
44384754 nv->add_firmware_options[1] = BIT_5 | BIT_4;
4439
- nv->frame_payload_size = 2048;
4755
+ nv->frame_payload_size = cpu_to_le16(2048);
44404756 nv->special_options[1] = BIT_7;
44414757 } else if (IS_QLA2200(ha)) {
44424758 nv->firmware_options[0] = BIT_2 | BIT_1;
44434759 nv->firmware_options[1] = BIT_7 | BIT_5;
44444760 nv->add_firmware_options[0] = BIT_5;
44454761 nv->add_firmware_options[1] = BIT_5 | BIT_4;
4446
- nv->frame_payload_size = 1024;
4762
+ nv->frame_payload_size = cpu_to_le16(1024);
44474763 } else if (IS_QLA2100(ha)) {
44484764 nv->firmware_options[0] = BIT_3 | BIT_1;
44494765 nv->firmware_options[1] = BIT_5;
4450
- nv->frame_payload_size = 1024;
4766
+ nv->frame_payload_size = cpu_to_le16(1024);
44514767 }
44524768
44534769 nv->max_iocb_allocation = cpu_to_le16(256);
....@@ -4474,20 +4790,6 @@
44744790
44754791 rval = 1;
44764792 }
4477
-
4478
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
4479
- /*
4480
- * The SN2 does not provide BIOS emulation which means you can't change
4481
- * potentially bogus BIOS settings. Force the use of default settings
4482
- * for link rate and frame size. Hope that the rest of the settings
4483
- * are valid.
4484
- */
4485
- if (ia64_platform_is("sn2")) {
4486
- nv->frame_payload_size = 2048;
4487
- if (IS_QLA23XX(ha))
4488
- nv->special_options[1] = BIT_7;
4489
- }
4490
-#endif
44914793
44924794 /* Reset Initialization control block */
44934795 memset(icb, 0, ha->init_cb_size);
....@@ -4669,7 +4971,7 @@
46694971 ha->zio_mode = icb->add_firmware_options[0] &
46704972 (BIT_3 | BIT_2 | BIT_1 | BIT_0);
46714973 ha->zio_timer = icb->interrupt_delay_timer ?
4672
- icb->interrupt_delay_timer: 2;
4974
+ icb->interrupt_delay_timer : 2;
46734975 }
46744976 icb->add_firmware_options[0] &=
46754977 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
....@@ -4702,7 +5004,7 @@
47025004 unsigned long flags;
47035005
47045006 spin_lock_irqsave(fcport->vha->host->host_lock, flags);
4705
- rport = fcport->drport ? fcport->drport: fcport->rport;
5007
+ rport = fcport->drport ? fcport->drport : fcport->rport;
47065008 fcport->drport = NULL;
47075009 spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
47085010 if (rport) {
....@@ -4712,6 +5014,23 @@
47125014 rport->roles);
47135015
47145016 fc_remote_port_delete(rport);
5017
+ }
5018
+}
5019
+
5020
+void qla2x00_set_fcport_state(fc_port_t *fcport, int state)
5021
+{
5022
+ int old_state;
5023
+
5024
+ old_state = atomic_read(&fcport->state);
5025
+ atomic_set(&fcport->state, state);
5026
+
5027
+ /* Don't print state transitions during initial allocation of fcport */
5028
+ if (old_state && old_state != state) {
5029
+ ql_dbg(ql_dbg_disc, fcport->vha, 0x207d,
5030
+ "FCPort %8phC state transitioned from %s to %s - portid=%02x%02x%02x.\n",
5031
+ fcport->port_name, port_state_str[old_state],
5032
+ port_state_str[state], fcport->d_id.b.domain,
5033
+ fcport->d_id.b.area, fcport->d_id.b.al_pa);
47155034 }
47165035 }
47175036
....@@ -4731,6 +5050,16 @@
47315050 if (!fcport)
47325051 return NULL;
47335052
5053
+ fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev,
5054
+ sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma,
5055
+ flags);
5056
+ if (!fcport->ct_desc.ct_sns) {
5057
+ ql_log(ql_log_warn, vha, 0xd049,
5058
+ "Failed to allocate ct_sns request.\n");
5059
+ kfree(fcport);
5060
+ return NULL;
5061
+ }
5062
+
47345063 /* Setup fcport template structure. */
47355064 fcport->vha = vha;
47365065 fcport->port_type = FCT_UNKNOWN;
....@@ -4739,13 +5068,11 @@
47395068 fcport->supported_classes = FC_COS_UNSPECIFIED;
47405069 fcport->fp_speed = PORT_SPEED_UNKNOWN;
47415070
4742
- fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev,
4743
- sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma,
4744
- flags);
47455071 fcport->disc_state = DSC_DELETED;
47465072 fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
47475073 fcport->deleted = QLA_SESS_DELETED;
47485074 fcport->login_retry = vha->hw->login_retry_count;
5075
+ fcport->chip_reset = vha->hw->base_qpair->chip_reset;
47495076 fcport->logout_on_delete = 1;
47505077
47515078 if (!fcport->ct_desc.ct_sns) {
....@@ -4754,7 +5081,9 @@
47545081 kfree(fcport);
47555082 return NULL;
47565083 }
5084
+
47575085 INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn);
5086
+ INIT_WORK(&fcport->free_work, qlt_free_session_done);
47585087 INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
47595088 INIT_LIST_HEAD(&fcport->gnl_entry);
47605089 INIT_LIST_HEAD(&fcport->list);
....@@ -4772,7 +5101,32 @@
47725101
47735102 fcport->ct_desc.ct_sns = NULL;
47745103 }
5104
+ list_del(&fcport->list);
5105
+ qla2x00_clear_loop_id(fcport);
47755106 kfree(fcport);
5107
+}
5108
+
5109
+static void qla_get_login_template(scsi_qla_host_t *vha)
5110
+{
5111
+ struct qla_hw_data *ha = vha->hw;
5112
+ int rval;
5113
+ u32 *bp, sz;
5114
+ __be32 *q;
5115
+
5116
+ memset(ha->init_cb, 0, ha->init_cb_size);
5117
+ sz = min_t(int, sizeof(struct fc_els_flogi), ha->init_cb_size);
5118
+ rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
5119
+ ha->init_cb, sz);
5120
+ if (rval != QLA_SUCCESS) {
5121
+ ql_dbg(ql_dbg_init, vha, 0x00d1,
5122
+ "PLOGI ELS param read fail.\n");
5123
+ return;
5124
+ }
5125
+ q = (__be32 *)&ha->plogi_els_payld.fl_csp;
5126
+
5127
+ bp = (uint32_t *)ha->init_cb;
5128
+ cpu_to_be32_array(q, bp, sz / 4);
5129
+ ha->flags.plogi_template_valid = 1;
47765130 }
47775131
47785132 /*
....@@ -4793,6 +5147,7 @@
47935147 int rval;
47945148 unsigned long flags, save_flags;
47955149 struct qla_hw_data *ha = vha->hw;
5150
+
47965151 rval = QLA_SUCCESS;
47975152
47985153 /* Get Initiator ID */
....@@ -4817,14 +5172,11 @@
48175172 clear_bit(RSCN_UPDATE, &vha->dpc_flags);
48185173
48195174 qla2x00_get_data_rate(vha);
5175
+ qla_get_login_template(vha);
48205176
48215177 /* Determine what we need to do */
4822
- if (ha->current_topology == ISP_CFG_FL &&
4823
- (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
4824
-
4825
- set_bit(RSCN_UPDATE, &flags);
4826
-
4827
- } else if (ha->current_topology == ISP_CFG_F &&
5178
+ if ((ha->current_topology == ISP_CFG_FL ||
5179
+ ha->current_topology == ISP_CFG_F) &&
48285180 (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
48295181
48305182 set_bit(RSCN_UPDATE, &flags);
....@@ -4903,6 +5255,48 @@
49035255 return (rval);
49045256 }
49055257
5258
+static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
5259
+{
5260
+ unsigned long flags;
5261
+ fc_port_t *fcport;
5262
+
5263
+ if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags))
5264
+ set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
5265
+
5266
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
5267
+ if (fcport->n2n_flag) {
5268
+ qla24xx_fcport_handle_login(vha, fcport);
5269
+ return QLA_SUCCESS;
5270
+ }
5271
+ }
5272
+
5273
+ spin_lock_irqsave(&vha->work_lock, flags);
5274
+ vha->scan.scan_retry++;
5275
+ spin_unlock_irqrestore(&vha->work_lock, flags);
5276
+
5277
+ if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
5278
+ set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
5279
+ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
5280
+ }
5281
+ return QLA_FUNCTION_FAILED;
5282
+}
5283
+
5284
+static void
5285
+qla_reinitialize_link(scsi_qla_host_t *vha)
5286
+{
5287
+ int rval;
5288
+
5289
+ atomic_set(&vha->loop_state, LOOP_DOWN);
5290
+ atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
5291
+ rval = qla2x00_full_login_lip(vha);
5292
+ if (rval == QLA_SUCCESS) {
5293
+ ql_dbg(ql_dbg_disc, vha, 0xd050, "Link reinitialized\n");
5294
+ } else {
5295
+ ql_dbg(ql_dbg_disc, vha, 0xd051,
5296
+ "Link reinitialization failed (%d)\n", rval);
5297
+ }
5298
+}
5299
+
49065300 /*
49075301 * qla2x00_configure_local_loop
49085302 * Updates Fibre Channel Device Database with local loop devices.
....@@ -4920,39 +5314,17 @@
49205314 int found_devs;
49215315 int found;
49225316 fc_port_t *fcport, *new_fcport;
4923
-
49245317 uint16_t index;
49255318 uint16_t entries;
4926
- char *id_iter;
5319
+ struct gid_list_info *gid;
49275320 uint16_t loop_id;
49285321 uint8_t domain, area, al_pa;
49295322 struct qla_hw_data *ha = vha->hw;
49305323 unsigned long flags;
49315324
49325325 /* Inititae N2N login. */
4933
- if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
4934
- /* borrowing */
4935
- u32 *bp, i, sz;
4936
-
4937
- memset(ha->init_cb, 0, ha->init_cb_size);
4938
- sz = min_t(int, sizeof(struct els_plogi_payload),
4939
- ha->init_cb_size);
4940
- rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
4941
- (void *)ha->init_cb, sz);
4942
- if (rval == QLA_SUCCESS) {
4943
- bp = (uint32_t *)ha->init_cb;
4944
- for (i = 0; i < sz/4 ; i++, bp++)
4945
- *bp = cpu_to_be32(*bp);
4946
-
4947
- memcpy(&ha->plogi_els_payld.data, (void *)ha->init_cb,
4948
- sizeof(ha->plogi_els_payld.data));
4949
- set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
4950
- } else {
4951
- ql_dbg(ql_dbg_init, vha, 0x00d1,
4952
- "PLOGI ELS param read fail.\n");
4953
- }
4954
- return QLA_SUCCESS;
4955
- }
5326
+ if (N2N_TOPO(ha))
5327
+ return qla2x00_configure_n2n_loop(vha);
49565328
49575329 found_devs = 0;
49585330 new_fcport = NULL;
....@@ -4963,13 +5335,38 @@
49635335 rval = qla2x00_get_id_list(vha, ha->gid_list, ha->gid_list_dma,
49645336 &entries);
49655337 if (rval != QLA_SUCCESS)
4966
- goto cleanup_allocation;
5338
+ goto err;
49675339
49685340 ql_dbg(ql_dbg_disc, vha, 0x2011,
49695341 "Entries in ID list (%d).\n", entries);
49705342 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2075,
4971
- (uint8_t *)ha->gid_list,
4972
- entries * sizeof(struct gid_list_info));
5343
+ ha->gid_list, entries * sizeof(*ha->gid_list));
5344
+
5345
+ if (entries == 0) {
5346
+ spin_lock_irqsave(&vha->work_lock, flags);
5347
+ vha->scan.scan_retry++;
5348
+ spin_unlock_irqrestore(&vha->work_lock, flags);
5349
+
5350
+ if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
5351
+ u8 loop_map_entries = 0;
5352
+ int rc;
5353
+
5354
+ rc = qla2x00_get_fcal_position_map(vha, NULL,
5355
+ &loop_map_entries);
5356
+ if (rc == QLA_SUCCESS && loop_map_entries > 1) {
5357
+ /*
5358
+ * There are devices that are still not logged
5359
+ * in. Reinitialize to give them a chance.
5360
+ */
5361
+ qla_reinitialize_link(vha);
5362
+ return QLA_FUNCTION_FAILED;
5363
+ }
5364
+ set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
5365
+ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
5366
+ }
5367
+ } else {
5368
+ vha->scan.scan_retry = 0;
5369
+ }
49735370
49745371 list_for_each_entry(fcport, &vha->vp_fcports, list) {
49755372 fcport->scan_state = QLA_FCPORT_SCAN;
....@@ -4981,32 +5378,32 @@
49815378 ql_log(ql_log_warn, vha, 0x2012,
49825379 "Memory allocation failed for fcport.\n");
49835380 rval = QLA_MEMORY_ALLOC_FAILED;
4984
- goto cleanup_allocation;
5381
+ goto err;
49855382 }
49865383 new_fcport->flags &= ~FCF_FABRIC_DEVICE;
49875384
49885385 /* Add devices to port list. */
4989
- id_iter = (char *)ha->gid_list;
5386
+ gid = ha->gid_list;
49905387 for (index = 0; index < entries; index++) {
4991
- domain = ((struct gid_list_info *)id_iter)->domain;
4992
- area = ((struct gid_list_info *)id_iter)->area;
4993
- al_pa = ((struct gid_list_info *)id_iter)->al_pa;
5388
+ domain = gid->domain;
5389
+ area = gid->area;
5390
+ al_pa = gid->al_pa;
49945391 if (IS_QLA2100(ha) || IS_QLA2200(ha))
4995
- loop_id = (uint16_t)
4996
- ((struct gid_list_info *)id_iter)->loop_id_2100;
5392
+ loop_id = gid->loop_id_2100;
49975393 else
4998
- loop_id = le16_to_cpu(
4999
- ((struct gid_list_info *)id_iter)->loop_id);
5000
- id_iter += ha->gid_list_info_size;
5394
+ loop_id = le16_to_cpu(gid->loop_id);
5395
+ gid = (void *)gid + ha->gid_list_info_size;
50015396
50025397 /* Bypass reserved domain fields. */
50035398 if ((domain & 0xf0) == 0xf0)
50045399 continue;
50055400
50065401 /* Bypass if not same domain and area of adapter. */
5007
- if (area && domain &&
5008
- (area != vha->d_id.b.area || domain != vha->d_id.b.domain))
5402
+ if (area && domain && ((area != vha->d_id.b.area) ||
5403
+ (domain != vha->d_id.b.domain)) &&
5404
+ (ha->current_topology == ISP_CFG_NL))
50095405 continue;
5406
+
50105407
50115408 /* Bypass invalid local loop ID. */
50125409 if (loop_id > LAST_LOCAL_LOOP_ID)
....@@ -5052,6 +5449,13 @@
50525449 memcpy(fcport->node_name, new_fcport->node_name,
50535450 WWN_SIZE);
50545451 fcport->scan_state = QLA_FCPORT_FOUND;
5452
+ if (fcport->login_retry == 0) {
5453
+ fcport->login_retry = vha->hw->login_retry_count;
5454
+ ql_dbg(ql_dbg_disc, vha, 0x2135,
5455
+ "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
5456
+ fcport->port_name, fcport->loop_id,
5457
+ fcport->login_retry);
5458
+ }
50555459 found++;
50565460 break;
50575461 }
....@@ -5071,7 +5475,7 @@
50715475 ql_log(ql_log_warn, vha, 0xd031,
50725476 "Failed to allocate memory for fcport.\n");
50735477 rval = QLA_MEMORY_ALLOC_FAILED;
5074
- goto cleanup_allocation;
5478
+ goto err;
50755479 }
50765480 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
50775481 new_fcport->flags &= ~FCF_FABRIC_DEVICE;
....@@ -5094,7 +5498,7 @@
50945498 qla_ini_mode_enabled(vha)) &&
50955499 atomic_read(&fcport->state) == FCS_ONLINE) {
50965500 qla2x00_mark_device_lost(vha, fcport,
5097
- ql2xplogiabsentdevice, 0);
5501
+ ql2xplogiabsentdevice);
50985502 if (fcport->loop_id != FC_NO_LOOP_ID &&
50995503 (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
51005504 fcport->port_type != FCT_INITIATOR &&
....@@ -5114,15 +5518,14 @@
51145518 qla24xx_fcport_handle_login(vha, fcport);
51155519 }
51165520
5117
-cleanup_allocation:
5118
- kfree(new_fcport);
5521
+ qla2x00_free_fcport(new_fcport);
51195522
5120
- if (rval != QLA_SUCCESS) {
5121
- ql_dbg(ql_dbg_disc, vha, 0x2098,
5122
- "Configure local loop error exit: rval=%x.\n", rval);
5123
- }
5523
+ return rval;
51245524
5125
- return (rval);
5525
+err:
5526
+ ql_dbg(ql_dbg_disc, vha, 0x2098,
5527
+ "Configure local loop error exit: rval=%x.\n", rval);
5528
+ return rval;
51265529 }
51275530
51285531 static void
....@@ -5204,16 +5607,23 @@
52045607
52055608 rport->supported_classes = fcport->supported_classes;
52065609
5207
- rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
5610
+ rport_ids.roles = FC_PORT_ROLE_UNKNOWN;
52085611 if (fcport->port_type == FCT_INITIATOR)
5209
- rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
5612
+ rport_ids.roles |= FC_PORT_ROLE_FCP_INITIATOR;
52105613 if (fcport->port_type == FCT_TARGET)
5211
- rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
5614
+ rport_ids.roles |= FC_PORT_ROLE_FCP_TARGET;
5615
+ if (fcport->port_type & FCT_NVME_INITIATOR)
5616
+ rport_ids.roles |= FC_PORT_ROLE_NVME_INITIATOR;
5617
+ if (fcport->port_type & FCT_NVME_TARGET)
5618
+ rport_ids.roles |= FC_PORT_ROLE_NVME_TARGET;
5619
+ if (fcport->port_type & FCT_NVME_DISCOVERY)
5620
+ rport_ids.roles |= FC_PORT_ROLE_NVME_DISCOVERY;
52125621
52135622 ql_dbg(ql_dbg_disc, vha, 0x20ee,
52145623 "%s %8phN. rport %p is %s mode\n",
52155624 __func__, fcport->port_name, rport,
5216
- (fcport->port_type == FCT_TARGET) ? "tgt" : "ini");
5625
+ (fcport->port_type == FCT_TARGET) ? "tgt" :
5626
+ ((fcport->port_type & FCT_NVME) ? "nvme" : "ini"));
52175627
52185628 fc_remote_port_rolechg(rport, rport_ids.roles);
52195629 }
....@@ -5236,21 +5646,27 @@
52365646 void
52375647 qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
52385648 {
5649
+ unsigned long flags;
5650
+
52395651 if (IS_SW_RESV_ADDR(fcport->d_id))
52405652 return;
52415653
52425654 ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n",
52435655 __func__, fcport->port_name);
52445656
5245
- fcport->disc_state = DSC_UPD_FCPORT;
5657
+ qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
52465658 fcport->login_retry = vha->hw->login_retry_count;
52475659 fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
5248
- fcport->deleted = 0;
5249
- fcport->logout_on_delete = 1;
5250
- fcport->login_retry = vha->hw->login_retry_count;
5251
- fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0;
52525660
5253
- qla2x00_iidma_fcport(vha, fcport);
5661
+ spin_lock_irqsave(&vha->work_lock, flags);
5662
+ fcport->deleted = 0;
5663
+ spin_unlock_irqrestore(&vha->work_lock, flags);
5664
+
5665
+ if (vha->hw->current_topology == ISP_CFG_NL)
5666
+ fcport->logout_on_delete = 0;
5667
+ else
5668
+ fcport->logout_on_delete = 1;
5669
+ fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0;
52545670
52555671 switch (vha->hw->current_topology) {
52565672 case ISP_CFG_N:
....@@ -5261,9 +5677,13 @@
52615677 break;
52625678 }
52635679
5264
- if (fcport->fc4f_nvme) {
5680
+ qla2x00_iidma_fcport(vha, fcport);
5681
+
5682
+ qla2x00_dfs_create_rport(vha, fcport);
5683
+
5684
+ if (NVME_TARGET(vha->hw, fcport)) {
52655685 qla_nvme_register_remote(vha, fcport);
5266
- fcport->disc_state = DSC_LOGIN_COMPLETE;
5686
+ qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
52675687 qla2x00_set_fcport_state(fcport, FCS_ONLINE);
52685688 return;
52695689 }
....@@ -5289,6 +5709,8 @@
52895709 break;
52905710 }
52915711
5712
+ qla2x00_set_fcport_state(fcport, FCS_ONLINE);
5713
+
52925714 if (IS_IIDMA_CAPABLE(vha->hw) && vha->hw->flags.gpsc_supported) {
52935715 if (fcport->id_changed) {
52945716 fcport->id_changed = 0;
....@@ -5305,9 +5727,8 @@
53055727 qla24xx_post_gpsc_work(vha, fcport);
53065728 }
53075729 }
5308
- qla2x00_set_fcport_state(fcport, FCS_ONLINE);
53095730
5310
- fcport->disc_state = DSC_LOGIN_COMPLETE;
5731
+ qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
53115732 }
53125733
53135734 void qla_register_fcport_fn(struct work_struct *work)
....@@ -5375,23 +5796,21 @@
53755796 }
53765797 vha->device_flags |= SWITCH_FOUND;
53775798
5799
+ rval = qla2x00_get_port_name(vha, loop_id, vha->fabric_port_name, 0);
5800
+ if (rval != QLA_SUCCESS)
5801
+ ql_dbg(ql_dbg_disc, vha, 0x20ff,
5802
+ "Failed to get Fabric Port Name\n");
53785803
53795804 if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha)) {
53805805 rval = qla2x00_send_change_request(vha, 0x3, 0);
53815806 if (rval != QLA_SUCCESS)
53825807 ql_log(ql_log_warn, vha, 0x121,
5383
- "Failed to enable receiving of RSCN requests: 0x%x.\n",
5384
- rval);
5808
+ "Failed to enable receiving of RSCN requests: 0x%x.\n",
5809
+ rval);
53855810 }
5386
-
53875811
53885812 do {
53895813 qla2x00_mgmt_svr_login(vha);
5390
-
5391
- /* FDMI support. */
5392
- if (ql2xfdmienable &&
5393
- test_and_clear_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags))
5394
- qla2x00_fdmi_register(vha);
53955814
53965815 /* Ensure we are logged into the SNS. */
53975816 loop_id = NPH_SNS_LID(ha);
....@@ -5404,6 +5823,12 @@
54045823 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
54055824 return rval;
54065825 }
5826
+
5827
+ /* FDMI support. */
5828
+ if (ql2xfdmienable &&
5829
+ test_and_clear_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags))
5830
+ qla2x00_fdmi_register(vha);
5831
+
54075832 if (test_and_clear_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags)) {
54085833 if (qla2x00_rft_id(vha)) {
54095834 /* EMPTY */
....@@ -5588,11 +6013,8 @@
55886013 new_fcport->fc4_type = swl[swl_idx].fc4_type;
55896014
55906015 new_fcport->nvme_flag = 0;
5591
- new_fcport->fc4f_nvme = 0;
55926016 if (vha->flags.nvme_enabled &&
5593
- swl[swl_idx].fc4f_nvme) {
5594
- new_fcport->fc4f_nvme =
5595
- swl[swl_idx].fc4f_nvme;
6017
+ swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) {
55966018 ql_log(ql_log_info, vha, 0x2131,
55976019 "FOUND: NVME port %8phC as FC Type 28h\n",
55986020 new_fcport->port_name);
....@@ -5648,8 +6070,8 @@
56486070
56496071 /* Bypass ports whose FCP-4 type is not FCP_SCSI */
56506072 if (ql2xgffidenable &&
5651
- (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
5652
- new_fcport->fc4_type != FC4_TYPE_UNKNOWN))
6073
+ (!(new_fcport->fc4_type & FS_FC4TYPE_FCP) &&
6074
+ new_fcport->fc4_type != 0))
56536075 continue;
56546076
56556077 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
....@@ -5717,9 +6139,9 @@
57176139 break;
57186140 }
57196141
5720
- if (fcport->fc4f_nvme) {
6142
+ if (found && NVME_TARGET(vha->hw, fcport)) {
57216143 if (fcport->disc_state == DSC_DELETE_PEND) {
5722
- fcport->disc_state = DSC_GNL;
6144
+ qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
57236145 vha->fcport_count--;
57246146 fcport->login_succ = 0;
57256147 }
....@@ -5765,7 +6187,7 @@
57656187 qla_ini_mode_enabled(vha)) &&
57666188 atomic_read(&fcport->state) == FCS_ONLINE) {
57676189 qla2x00_mark_device_lost(vha, fcport,
5768
- ql2xplogiabsentdevice, 0);
6190
+ ql2xplogiabsentdevice);
57696191 if (fcport->loop_id != FC_NO_LOOP_ID &&
57706192 (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
57716193 fcport->port_type != FCT_INITIATOR &&
....@@ -5786,55 +6208,6 @@
57866208 }
57876209 return (rval);
57886210 }
5789
-
5790
-/*
5791
- * qla2x00_find_new_loop_id
5792
- * Scan through our port list and find a new usable loop ID.
5793
- *
5794
- * Input:
5795
- * ha: adapter state pointer.
5796
- * dev: port structure pointer.
5797
- *
5798
- * Returns:
5799
- * qla2x00 local function return status code.
5800
- *
5801
- * Context:
5802
- * Kernel context.
5803
- */
5804
-int
5805
-qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
5806
-{
5807
- int rval;
5808
- struct qla_hw_data *ha = vha->hw;
5809
- unsigned long flags = 0;
5810
-
5811
- rval = QLA_SUCCESS;
5812
-
5813
- spin_lock_irqsave(&ha->vport_slock, flags);
5814
-
5815
- dev->loop_id = find_first_zero_bit(ha->loop_id_map,
5816
- LOOPID_MAP_SIZE);
5817
- if (dev->loop_id >= LOOPID_MAP_SIZE ||
5818
- qla2x00_is_reserved_id(vha, dev->loop_id)) {
5819
- dev->loop_id = FC_NO_LOOP_ID;
5820
- rval = QLA_FUNCTION_FAILED;
5821
- } else
5822
- set_bit(dev->loop_id, ha->loop_id_map);
5823
-
5824
- spin_unlock_irqrestore(&ha->vport_slock, flags);
5825
-
5826
- if (rval == QLA_SUCCESS)
5827
- ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
5828
- "Assigning new loopid=%x, portid=%x.\n",
5829
- dev->loop_id, dev->d_id.b24);
5830
- else
5831
- ql_log(ql_log_warn, dev->vha, 0x2087,
5832
- "No loop_id's available, portid=%x.\n",
5833
- dev->d_id.b24);
5834
-
5835
- return (rval);
5836
-}
5837
-
58386211
58396212 /* FW does not set aside Loop id for MGMT Server/FFFFFAh */
58406213 int
....@@ -5980,7 +6353,7 @@
59806353 ha->isp_ops->fabric_logout(vha, fcport->loop_id,
59816354 fcport->d_id.b.domain, fcport->d_id.b.area,
59826355 fcport->d_id.b.al_pa);
5983
- qla2x00_mark_device_lost(vha, fcport, 1, 0);
6356
+ qla2x00_mark_device_lost(vha, fcport, 1);
59846357
59856358 rval = 1;
59866359 break;
....@@ -6057,11 +6430,6 @@
60576430 {
60586431 int rval = QLA_SUCCESS;
60596432 uint32_t wait_time;
6060
- struct req_que *req;
6061
- struct rsp_que *rsp;
6062
-
6063
- req = vha->req;
6064
- rsp = req->rsp;
60656433
60666434 clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
60676435 if (vha->flags.online) {
....@@ -6074,8 +6442,8 @@
60746442 * Issue a marker after FW becomes
60756443 * ready.
60766444 */
6077
- qla2x00_marker(vha, req, rsp, 0, 0,
6078
- MK_SYNC_ALL);
6445
+ qla2x00_marker(vha, vha->hw->base_qpair,
6446
+ 0, 0, MK_SYNC_ALL);
60796447 vha->marker_needed = 0;
60806448 }
60816449
....@@ -6332,6 +6700,7 @@
63326700 qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
63336701 } else {
63346702 const char *state = qla83xx_dev_state_to_string(dev_state);
6703
+
63356704 ql_log(ql_log_info, vha, 0xb057, "HW State: %s.\n", state);
63366705
63376706 /* SV: XXX: Is timeout required here? */
....@@ -6498,16 +6867,17 @@
64986867 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
64996868 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
65006869 atomic_set(&vha->loop_state, LOOP_DOWN);
6501
- qla2x00_mark_all_devices_lost(vha, 0);
6870
+ qla2x00_mark_all_devices_lost(vha);
65026871 list_for_each_entry(vp, &ha->vp_list, list)
6503
- qla2x00_mark_all_devices_lost(vp, 0);
6872
+ qla2x00_mark_all_devices_lost(vp);
65046873 } else {
65056874 if (!atomic_read(&vha->loop_down_timer))
65066875 atomic_set(&vha->loop_down_timer,
65076876 LOOP_DOWN_TIME);
65086877 }
65096878 /* Wait for pending cmds to complete */
6510
- qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST);
6879
+ WARN_ON_ONCE(qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST)
6880
+ != QLA_SUCCESS);
65116881 }
65126882
65136883 void
....@@ -6545,7 +6915,7 @@
65456915 ha->flags.n2n_ae = 0;
65466916 ha->flags.lip_ae = 0;
65476917 ha->current_topology = 0;
6548
- ha->flags.fw_started = 0;
6918
+ QLA_FW_STOPPED(ha);
65496919 ha->flags.fw_init_done = 0;
65506920 ha->chip_reset++;
65516921 ha->base_qpair->chip_reset = ha->chip_reset;
....@@ -6556,14 +6926,15 @@
65566926 }
65576927
65586928 /* purge MBox commands */
6559
- if (atomic_read(&ha->num_pend_mbx_stage3)) {
6929
+ spin_lock_irqsave(&ha->hardware_lock, flags);
6930
+ if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) {
65606931 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
65616932 complete(&ha->mbx_intr_comp);
65626933 }
6934
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
65636935
65646936 i = 0;
6565
- while (atomic_read(&ha->num_pend_mbx_stage3) ||
6566
- atomic_read(&ha->num_pend_mbx_stage2) ||
6937
+ while (atomic_read(&ha->num_pend_mbx_stage2) ||
65676938 atomic_read(&ha->num_pend_mbx_stage1)) {
65686939 msleep(20);
65696940 i++;
....@@ -6575,14 +6946,14 @@
65756946 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
65766947 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
65776948 atomic_set(&vha->loop_state, LOOP_DOWN);
6578
- qla2x00_mark_all_devices_lost(vha, 0);
6949
+ qla2x00_mark_all_devices_lost(vha);
65796950
65806951 spin_lock_irqsave(&ha->vport_slock, flags);
65816952 list_for_each_entry(vp, &ha->vp_list, list) {
65826953 atomic_inc(&vp->vref_count);
65836954 spin_unlock_irqrestore(&ha->vport_slock, flags);
65846955
6585
- qla2x00_mark_all_devices_lost(vp, 0);
6956
+ qla2x00_mark_all_devices_lost(vp);
65866957
65876958 spin_lock_irqsave(&ha->vport_slock, flags);
65886959 atomic_dec(&vp->vref_count);
....@@ -6612,22 +6983,18 @@
66126983 }
66136984 spin_unlock_irqrestore(&ha->vport_slock, flags);
66146985
6615
- if (!ha->flags.eeh_busy) {
6616
- /* Make sure for ISP 82XX IO DMA is complete */
6617
- if (IS_P3P_TYPE(ha)) {
6618
- qla82xx_chip_reset_cleanup(vha);
6619
- ql_log(ql_log_info, vha, 0x00b4,
6620
- "Done chip reset cleanup.\n");
6986
+ /* Make sure for ISP 82XX IO DMA is complete */
6987
+ if (IS_P3P_TYPE(ha)) {
6988
+ qla82xx_chip_reset_cleanup(vha);
6989
+ ql_log(ql_log_info, vha, 0x00b4,
6990
+ "Done chip reset cleanup.\n");
66216991
6622
- /* Done waiting for pending commands.
6623
- * Reset the online flag.
6624
- */
6625
- vha->flags.online = 0;
6626
- }
6627
-
6628
- /* Requeue all commands in outstanding command list. */
6629
- qla2x00_abort_all_cmds(vha, DID_RESET << 16);
6992
+ /* Done waiting for pending commands. Reset online flag */
6993
+ vha->flags.online = 0;
66306994 }
6995
+
6996
+ /* Requeue all commands in outstanding command list. */
6997
+ qla2x00_abort_all_cmds(vha, DID_RESET << 16);
66316998 /* memory barrier */
66326999 wmb();
66337000 }
....@@ -6655,6 +7022,20 @@
66557022 if (vha->flags.online) {
66567023 qla2x00_abort_isp_cleanup(vha);
66577024
7025
+ if (qla2x00_isp_reg_stat(ha)) {
7026
+ ql_log(ql_log_info, vha, 0x803f,
7027
+ "ISP Abort - ISP reg disconnect, exiting.\n");
7028
+ return status;
7029
+ }
7030
+
7031
+ if (test_and_clear_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags)) {
7032
+ ha->flags.chip_reset_done = 1;
7033
+ vha->flags.online = 1;
7034
+ status = 0;
7035
+ clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
7036
+ return status;
7037
+ }
7038
+
66587039 if (IS_QLA8031(ha)) {
66597040 ql_dbg(ql_dbg_p3p, vha, 0xb05c,
66607041 "Clearing fcoe driver presence.\n");
....@@ -6670,10 +7051,35 @@
66707051 return status;
66717052 }
66727053
7054
+ switch (vha->qlini_mode) {
7055
+ case QLA2XXX_INI_MODE_DISABLED:
7056
+ if (!qla_tgt_mode_enabled(vha))
7057
+ return 0;
7058
+ break;
7059
+ case QLA2XXX_INI_MODE_DUAL:
7060
+ if (!qla_dual_mode_enabled(vha) &&
7061
+ !qla_ini_mode_enabled(vha))
7062
+ return 0;
7063
+ break;
7064
+ case QLA2XXX_INI_MODE_ENABLED:
7065
+ default:
7066
+ break;
7067
+ }
7068
+
66737069 ha->isp_ops->get_flash_version(vha, req->ring);
66747070
7071
+ if (qla2x00_isp_reg_stat(ha)) {
7072
+ ql_log(ql_log_info, vha, 0x803f,
7073
+ "ISP Abort - ISP reg disconnect pre nvram config, exiting.\n");
7074
+ return status;
7075
+ }
66757076 ha->isp_ops->nvram_config(vha);
66767077
7078
+ if (qla2x00_isp_reg_stat(ha)) {
7079
+ ql_log(ql_log_info, vha, 0x803f,
7080
+ "ISP Abort - ISP reg disconnect post nvmram config, exiting.\n");
7081
+ return status;
7082
+ }
66777083 if (!qla2x00_restart_isp(vha)) {
66787084 clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
66797085
....@@ -6799,38 +7205,41 @@
67997205 static int
68007206 qla2x00_restart_isp(scsi_qla_host_t *vha)
68017207 {
6802
- int status = 0;
7208
+ int status;
68037209 struct qla_hw_data *ha = vha->hw;
6804
- struct req_que *req = ha->req_q_map[0];
6805
- struct rsp_que *rsp = ha->rsp_q_map[0];
68067210
68077211 /* If firmware needs to be loaded */
68087212 if (qla2x00_isp_firmware(vha)) {
68097213 vha->flags.online = 0;
68107214 status = ha->isp_ops->chip_diag(vha);
6811
- if (!status)
6812
- status = qla2x00_setup_chip(vha);
7215
+ if (status)
7216
+ return status;
7217
+ status = qla2x00_setup_chip(vha);
7218
+ if (status)
7219
+ return status;
68137220 }
68147221
6815
- if (!status && !(status = qla2x00_init_rings(vha))) {
6816
- clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
6817
- ha->flags.chip_reset_done = 1;
7222
+ status = qla2x00_init_rings(vha);
7223
+ if (status)
7224
+ return status;
68187225
6819
- /* Initialize the queues in use */
6820
- qla25xx_init_queues(ha);
7226
+ clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
7227
+ ha->flags.chip_reset_done = 1;
68217228
6822
- status = qla2x00_fw_ready(vha);
6823
- if (!status) {
6824
- /* Issue a marker after FW becomes ready. */
6825
- qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
6826
- set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
6827
- }
7229
+ /* Initialize the queues in use */
7230
+ qla25xx_init_queues(ha);
68287231
7232
+ status = qla2x00_fw_ready(vha);
7233
+ if (status) {
68297234 /* if no cable then assume it's good */
6830
- if ((vha->device_flags & DFLG_NO_CABLE))
6831
- status = 0;
7235
+ return vha->device_flags & DFLG_NO_CABLE ? 0 : status;
68327236 }
6833
- return (status);
7237
+
7238
+ /* Issue a marker after FW becomes ready. */
7239
+ qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
7240
+ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
7241
+
7242
+ return 0;
68347243 }
68357244
68367245 static int
....@@ -6883,7 +7292,7 @@
68837292 * Input:
68847293 * ha = adapter block pointer.
68857294 */
6886
-void
7295
+int
68877296 qla2x00_reset_adapter(scsi_qla_host_t *vha)
68887297 {
68897298 unsigned long flags = 0;
....@@ -6894,14 +7303,16 @@
68947303 ha->isp_ops->disable_intrs(ha);
68957304
68967305 spin_lock_irqsave(&ha->hardware_lock, flags);
6897
- WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
6898
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
6899
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
6900
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
7306
+ wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
7307
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
7308
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
7309
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
69017310 spin_unlock_irqrestore(&ha->hardware_lock, flags);
7311
+
7312
+ return QLA_SUCCESS;
69027313 }
69037314
6904
-void
7315
+int
69057316 qla24xx_reset_adapter(scsi_qla_host_t *vha)
69067317 {
69077318 unsigned long flags = 0;
....@@ -6909,20 +7320,22 @@
69097320 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
69107321
69117322 if (IS_P3P_TYPE(ha))
6912
- return;
7323
+ return QLA_SUCCESS;
69137324
69147325 vha->flags.online = 0;
69157326 ha->isp_ops->disable_intrs(ha);
69167327
69177328 spin_lock_irqsave(&ha->hardware_lock, flags);
6918
- WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
6919
- RD_REG_DWORD(&reg->hccr);
6920
- WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
6921
- RD_REG_DWORD(&reg->hccr);
7329
+ wrt_reg_dword(&reg->hccr, HCCRX_SET_RISC_RESET);
7330
+ rd_reg_dword(&reg->hccr);
7331
+ wrt_reg_dword(&reg->hccr, HCCRX_REL_RISC_PAUSE);
7332
+ rd_reg_dword(&reg->hccr);
69227333 spin_unlock_irqrestore(&ha->hardware_lock, flags);
69237334
69247335 if (IS_NOPOLLING_TYPE(ha))
69257336 ha->isp_ops->enable_intrs(ha);
7337
+
7338
+ return QLA_SUCCESS;
69267339 }
69277340
69287341 /* On sparc systems, obtain port and node WWN from firmware
....@@ -6954,7 +7367,7 @@
69547367 int rval;
69557368 struct init_cb_24xx *icb;
69567369 struct nvram_24xx *nv;
6957
- uint32_t *dptr;
7370
+ __le32 *dptr;
69587371 uint8_t *dptr1, *dptr2;
69597372 uint32_t chksum;
69607373 uint16_t cnt;
....@@ -6973,34 +7386,33 @@
69737386 ha->vpd_base = FA_NVRAM_VPD1_ADDR;
69747387 }
69757388
6976
- ha->nvram_size = sizeof(struct nvram_24xx);
7389
+ ha->nvram_size = sizeof(*nv);
69777390 ha->vpd_size = FA_NVRAM_VPD_SIZE;
69787391
69797392 /* Get VPD data into cache */
69807393 ha->vpd = ha->nvram + VPD_OFFSET;
6981
- ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd,
7394
+ ha->isp_ops->read_nvram(vha, ha->vpd,
69827395 ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4);
69837396
69847397 /* Get NVRAM data into cache and calculate checksum. */
6985
- dptr = (uint32_t *)nv;
6986
- ha->isp_ops->read_nvram(vha, (uint8_t *)dptr, ha->nvram_base,
6987
- ha->nvram_size);
7398
+ dptr = (__force __le32 *)nv;
7399
+ ha->isp_ops->read_nvram(vha, dptr, ha->nvram_base, ha->nvram_size);
69887400 for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
69897401 chksum += le32_to_cpu(*dptr);
69907402
69917403 ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x006a,
69927404 "Contents of NVRAM\n");
69937405 ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010d,
6994
- (uint8_t *)nv, ha->nvram_size);
7406
+ nv, ha->nvram_size);
69957407
69967408 /* Bad NVRAM data, set defaults parameters. */
6997
- if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'
6998
- || nv->id[3] != ' ' ||
6999
- nv->nvram_version < cpu_to_le16(ICB_VERSION)) {
7409
+ if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
7410
+ le16_to_cpu(nv->nvram_version) < ICB_VERSION) {
70007411 /* Reset NVRAM data. */
70017412 ql_log(ql_log_warn, vha, 0x006b,
7002
- "Inconsistent NVRAM detected: checksum=0x%x id=%c "
7003
- "version=0x%x.\n", chksum, nv->id[0], nv->nvram_version);
7413
+ "Inconsistent NVRAM checksum=%#x id=%.4s version=%#x.\n",
7414
+ chksum, nv->id, nv->nvram_version);
7415
+ ql_dump_buffer(ql_dbg_init, vha, 0x006b, nv, sizeof(*nv));
70047416 ql_log(ql_log_warn, vha, 0x006c,
70057417 "Falling back to functioning (yet invalid -- WWPN) "
70067418 "defaults.\n");
....@@ -7011,7 +7423,7 @@
70117423 memset(nv, 0, ha->nvram_size);
70127424 nv->nvram_version = cpu_to_le16(ICB_VERSION);
70137425 nv->version = cpu_to_le16(ICB_VERSION);
7014
- nv->frame_payload_size = 2048;
7426
+ nv->frame_payload_size = cpu_to_le16(2048);
70157427 nv->execution_throttle = cpu_to_le16(0xFFFF);
70167428 nv->exchange_count = cpu_to_le16(0);
70177429 nv->hard_address = cpu_to_le16(124);
....@@ -7108,11 +7520,11 @@
71087520 ha->flags.disable_risc_code_load = 0;
71097521 ha->flags.enable_lip_reset = 0;
71107522 ha->flags.enable_lip_full_login =
7111
- le32_to_cpu(nv->host_p) & BIT_10 ? 1: 0;
7523
+ le32_to_cpu(nv->host_p) & BIT_10 ? 1 : 0;
71127524 ha->flags.enable_target_reset =
7113
- le32_to_cpu(nv->host_p) & BIT_11 ? 1: 0;
7525
+ le32_to_cpu(nv->host_p) & BIT_11 ? 1 : 0;
71147526 ha->flags.enable_led_scheme = 0;
7115
- ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0;
7527
+ ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1 : 0;
71167528
71177529 ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) &
71187530 (BIT_6 | BIT_5 | BIT_4)) >> 4;
....@@ -7179,14 +7591,14 @@
71797591 ha->login_retry_count = ql2xloginretrycount;
71807592
71817593 /* N2N: driver will initiate Login instead of FW */
7182
- icb->firmware_options_3 |= BIT_8;
7594
+ icb->firmware_options_3 |= cpu_to_le32(BIT_8);
71837595
71847596 /* Enable ZIO. */
71857597 if (!vha->flags.init_done) {
71867598 ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
71877599 (BIT_3 | BIT_2 | BIT_1 | BIT_0);
71887600 ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ?
7189
- le16_to_cpu(icb->interrupt_delay_timer): 2;
7601
+ le16_to_cpu(icb->interrupt_delay_timer) : 2;
71907602 }
71917603 icb->firmware_options_2 &= cpu_to_le32(
71927604 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
....@@ -7209,128 +7621,315 @@
72097621 return (rval);
72107622 }
72117623
7212
-uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha)
7624
+static void
7625
+qla27xx_print_image(struct scsi_qla_host *vha, char *name,
7626
+ struct qla27xx_image_status *image_status)
72137627 {
7214
- struct qla27xx_image_status pri_image_status, sec_image_status;
7215
- uint8_t valid_pri_image, valid_sec_image;
7216
- uint32_t *wptr;
7217
- uint32_t cnt, chksum, size;
7218
- struct qla_hw_data *ha = vha->hw;
7628
+ ql_dbg(ql_dbg_init, vha, 0x018b,
7629
+ "%s %s: mask=%#02x gen=%#04x ver=%u.%u map=%#01x sum=%#08x sig=%#08x\n",
7630
+ name, "status",
7631
+ image_status->image_status_mask,
7632
+ le16_to_cpu(image_status->generation),
7633
+ image_status->ver_major,
7634
+ image_status->ver_minor,
7635
+ image_status->bitmap,
7636
+ le32_to_cpu(image_status->checksum),
7637
+ le32_to_cpu(image_status->signature));
7638
+}
72197639
7220
- valid_pri_image = valid_sec_image = 1;
7221
- ha->active_image = 0;
7222
- size = sizeof(struct qla27xx_image_status) / sizeof(uint32_t);
7640
+static bool
7641
+qla28xx_check_aux_image_status_signature(
7642
+ struct qla27xx_image_status *image_status)
7643
+{
7644
+ ulong signature = le32_to_cpu(image_status->signature);
7645
+
7646
+ return signature != QLA28XX_AUX_IMG_STATUS_SIGN;
7647
+}
7648
+
7649
+static bool
7650
+qla27xx_check_image_status_signature(struct qla27xx_image_status *image_status)
7651
+{
7652
+ ulong signature = le32_to_cpu(image_status->signature);
7653
+
7654
+ return
7655
+ signature != QLA27XX_IMG_STATUS_SIGN &&
7656
+ signature != QLA28XX_IMG_STATUS_SIGN;
7657
+}
7658
+
7659
+static ulong
7660
+qla27xx_image_status_checksum(struct qla27xx_image_status *image_status)
7661
+{
7662
+ __le32 *p = (__force __le32 *)image_status;
7663
+ uint n = sizeof(*image_status) / sizeof(*p);
7664
+ uint32_t sum = 0;
7665
+
7666
+ for ( ; n--; p++)
7667
+ sum += le32_to_cpup(p);
7668
+
7669
+ return sum;
7670
+}
7671
+
7672
+static inline uint
7673
+qla28xx_component_bitmask(struct qla27xx_image_status *aux, uint bitmask)
7674
+{
7675
+ return aux->bitmap & bitmask ?
7676
+ QLA27XX_SECONDARY_IMAGE : QLA27XX_PRIMARY_IMAGE;
7677
+}
7678
+
7679
+static void
7680
+qla28xx_component_status(
7681
+ struct active_regions *active_regions, struct qla27xx_image_status *aux)
7682
+{
7683
+ active_regions->aux.board_config =
7684
+ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_BOARD_CONFIG);
7685
+
7686
+ active_regions->aux.vpd_nvram =
7687
+ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_VPD_NVRAM);
7688
+
7689
+ active_regions->aux.npiv_config_0_1 =
7690
+ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_0_1);
7691
+
7692
+ active_regions->aux.npiv_config_2_3 =
7693
+ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_2_3);
7694
+}
7695
+
7696
+static int
7697
+qla27xx_compare_image_generation(
7698
+ struct qla27xx_image_status *pri_image_status,
7699
+ struct qla27xx_image_status *sec_image_status)
7700
+{
7701
+ /* calculate generation delta as uint16 (this accounts for wrap) */
7702
+ int16_t delta =
7703
+ le16_to_cpu(pri_image_status->generation) -
7704
+ le16_to_cpu(sec_image_status->generation);
7705
+
7706
+ ql_dbg(ql_dbg_init, NULL, 0x0180, "generation delta = %d\n", delta);
7707
+
7708
+ return delta;
7709
+}
7710
+
7711
+void
7712
+qla28xx_get_aux_images(
7713
+ struct scsi_qla_host *vha, struct active_regions *active_regions)
7714
+{
7715
+ struct qla_hw_data *ha = vha->hw;
7716
+ struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status;
7717
+ bool valid_pri_image = false, valid_sec_image = false;
7718
+ bool active_pri_image = false, active_sec_image = false;
7719
+
7720
+ if (!ha->flt_region_aux_img_status_pri) {
7721
+ ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n");
7722
+ goto check_sec_image;
7723
+ }
7724
+
7725
+ qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
7726
+ ha->flt_region_aux_img_status_pri,
7727
+ sizeof(pri_aux_image_status) >> 2);
7728
+ qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status);
7729
+
7730
+ if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) {
7731
+ ql_dbg(ql_dbg_init, vha, 0x018b,
7732
+ "Primary aux image signature (%#x) not valid\n",
7733
+ le32_to_cpu(pri_aux_image_status.signature));
7734
+ goto check_sec_image;
7735
+ }
7736
+
7737
+ if (qla27xx_image_status_checksum(&pri_aux_image_status)) {
7738
+ ql_dbg(ql_dbg_init, vha, 0x018c,
7739
+ "Primary aux image checksum failed\n");
7740
+ goto check_sec_image;
7741
+ }
7742
+
7743
+ valid_pri_image = true;
7744
+
7745
+ if (pri_aux_image_status.image_status_mask & 1) {
7746
+ ql_dbg(ql_dbg_init, vha, 0x018d,
7747
+ "Primary aux image is active\n");
7748
+ active_pri_image = true;
7749
+ }
7750
+
7751
+check_sec_image:
7752
+ if (!ha->flt_region_aux_img_status_sec) {
7753
+ ql_dbg(ql_dbg_init, vha, 0x018a,
7754
+ "Secondary aux image not addressed\n");
7755
+ goto check_valid_image;
7756
+ }
7757
+
7758
+ qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
7759
+ ha->flt_region_aux_img_status_sec,
7760
+ sizeof(sec_aux_image_status) >> 2);
7761
+ qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status);
7762
+
7763
+ if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) {
7764
+ ql_dbg(ql_dbg_init, vha, 0x018b,
7765
+ "Secondary aux image signature (%#x) not valid\n",
7766
+ le32_to_cpu(sec_aux_image_status.signature));
7767
+ goto check_valid_image;
7768
+ }
7769
+
7770
+ if (qla27xx_image_status_checksum(&sec_aux_image_status)) {
7771
+ ql_dbg(ql_dbg_init, vha, 0x018c,
7772
+ "Secondary aux image checksum failed\n");
7773
+ goto check_valid_image;
7774
+ }
7775
+
7776
+ valid_sec_image = true;
7777
+
7778
+ if (sec_aux_image_status.image_status_mask & 1) {
7779
+ ql_dbg(ql_dbg_init, vha, 0x018d,
7780
+ "Secondary aux image is active\n");
7781
+ active_sec_image = true;
7782
+ }
7783
+
7784
+check_valid_image:
7785
+ if (valid_pri_image && active_pri_image &&
7786
+ valid_sec_image && active_sec_image) {
7787
+ if (qla27xx_compare_image_generation(&pri_aux_image_status,
7788
+ &sec_aux_image_status) >= 0) {
7789
+ qla28xx_component_status(active_regions,
7790
+ &pri_aux_image_status);
7791
+ } else {
7792
+ qla28xx_component_status(active_regions,
7793
+ &sec_aux_image_status);
7794
+ }
7795
+ } else if (valid_pri_image && active_pri_image) {
7796
+ qla28xx_component_status(active_regions, &pri_aux_image_status);
7797
+ } else if (valid_sec_image && active_sec_image) {
7798
+ qla28xx_component_status(active_regions, &sec_aux_image_status);
7799
+ }
7800
+
7801
+ ql_dbg(ql_dbg_init, vha, 0x018f,
7802
+ "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u\n",
7803
+ active_regions->aux.board_config,
7804
+ active_regions->aux.vpd_nvram,
7805
+ active_regions->aux.npiv_config_0_1,
7806
+ active_regions->aux.npiv_config_2_3);
7807
+}
7808
+
7809
+void
7810
+qla27xx_get_active_image(struct scsi_qla_host *vha,
7811
+ struct active_regions *active_regions)
7812
+{
7813
+ struct qla_hw_data *ha = vha->hw;
7814
+ struct qla27xx_image_status pri_image_status, sec_image_status;
7815
+ bool valid_pri_image = false, valid_sec_image = false;
7816
+ bool active_pri_image = false, active_sec_image = false;
72237817
72247818 if (!ha->flt_region_img_status_pri) {
7225
- valid_pri_image = 0;
7819
+ ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n");
72267820 goto check_sec_image;
72277821 }
72287822
7229
- qla24xx_read_flash_data(vha, (uint32_t *)(&pri_image_status),
7230
- ha->flt_region_img_status_pri, size);
7823
+ if (qla24xx_read_flash_data(vha, (uint32_t *)&pri_image_status,
7824
+ ha->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
7825
+ QLA_SUCCESS) {
7826
+ WARN_ON_ONCE(true);
7827
+ goto check_sec_image;
7828
+ }
7829
+ qla27xx_print_image(vha, "Primary image", &pri_image_status);
72317830
7232
- if (pri_image_status.signature != QLA27XX_IMG_STATUS_SIGN) {
7831
+ if (qla27xx_check_image_status_signature(&pri_image_status)) {
72337832 ql_dbg(ql_dbg_init, vha, 0x018b,
7234
- "Primary image signature (0x%x) not valid\n",
7235
- pri_image_status.signature);
7236
- valid_pri_image = 0;
7833
+ "Primary image signature (%#x) not valid\n",
7834
+ le32_to_cpu(pri_image_status.signature));
72377835 goto check_sec_image;
72387836 }
72397837
7240
- wptr = (uint32_t *)(&pri_image_status);
7241
- cnt = size;
7242
-
7243
- for (chksum = 0; cnt--; wptr++)
7244
- chksum += le32_to_cpu(*wptr);
7245
-
7246
- if (chksum) {
7838
+ if (qla27xx_image_status_checksum(&pri_image_status)) {
72477839 ql_dbg(ql_dbg_init, vha, 0x018c,
7248
- "Checksum validation failed for primary image (0x%x)\n",
7249
- chksum);
7250
- valid_pri_image = 0;
7840
+ "Primary image checksum failed\n");
7841
+ goto check_sec_image;
7842
+ }
7843
+
7844
+ valid_pri_image = true;
7845
+
7846
+ if (pri_image_status.image_status_mask & 1) {
7847
+ ql_dbg(ql_dbg_init, vha, 0x018d,
7848
+ "Primary image is active\n");
7849
+ active_pri_image = true;
72517850 }
72527851
72537852 check_sec_image:
72547853 if (!ha->flt_region_img_status_sec) {
7255
- valid_sec_image = 0;
7854
+ ql_dbg(ql_dbg_init, vha, 0x018a, "Secondary image not addressed\n");
72567855 goto check_valid_image;
72577856 }
72587857
72597858 qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
7260
- ha->flt_region_img_status_sec, size);
7859
+ ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2);
7860
+ qla27xx_print_image(vha, "Secondary image", &sec_image_status);
72617861
7262
- if (sec_image_status.signature != QLA27XX_IMG_STATUS_SIGN) {
7263
- ql_dbg(ql_dbg_init, vha, 0x018d,
7264
- "Secondary image signature(0x%x) not valid\n",
7265
- sec_image_status.signature);
7266
- valid_sec_image = 0;
7862
+ if (qla27xx_check_image_status_signature(&sec_image_status)) {
7863
+ ql_dbg(ql_dbg_init, vha, 0x018b,
7864
+ "Secondary image signature (%#x) not valid\n",
7865
+ le32_to_cpu(sec_image_status.signature));
72677866 goto check_valid_image;
72687867 }
72697868
7270
- wptr = (uint32_t *)(&sec_image_status);
7271
- cnt = size;
7272
- for (chksum = 0; cnt--; wptr++)
7273
- chksum += le32_to_cpu(*wptr);
7274
- if (chksum) {
7275
- ql_dbg(ql_dbg_init, vha, 0x018e,
7276
- "Checksum validation failed for secondary image (0x%x)\n",
7277
- chksum);
7278
- valid_sec_image = 0;
7869
+ if (qla27xx_image_status_checksum(&sec_image_status)) {
7870
+ ql_dbg(ql_dbg_init, vha, 0x018c,
7871
+ "Secondary image checksum failed\n");
7872
+ goto check_valid_image;
7873
+ }
7874
+
7875
+ valid_sec_image = true;
7876
+
7877
+ if (sec_image_status.image_status_mask & 1) {
7878
+ ql_dbg(ql_dbg_init, vha, 0x018d,
7879
+ "Secondary image is active\n");
7880
+ active_sec_image = true;
72797881 }
72807882
72817883 check_valid_image:
7282
- if (valid_pri_image && (pri_image_status.image_status_mask & 0x1))
7283
- ha->active_image = QLA27XX_PRIMARY_IMAGE;
7284
- if (valid_sec_image && (sec_image_status.image_status_mask & 0x1)) {
7285
- if (!ha->active_image ||
7286
- pri_image_status.generation_number <
7287
- sec_image_status.generation_number)
7288
- ha->active_image = QLA27XX_SECONDARY_IMAGE;
7884
+ if (valid_pri_image && active_pri_image)
7885
+ active_regions->global = QLA27XX_PRIMARY_IMAGE;
7886
+
7887
+ if (valid_sec_image && active_sec_image) {
7888
+ if (!active_regions->global ||
7889
+ qla27xx_compare_image_generation(
7890
+ &pri_image_status, &sec_image_status) < 0) {
7891
+ active_regions->global = QLA27XX_SECONDARY_IMAGE;
7892
+ }
72897893 }
72907894
7291
- ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x018f, "%s image\n",
7292
- ha->active_image == 0 ? "default bootld and fw" :
7293
- ha->active_image == 1 ? "primary" :
7294
- ha->active_image == 2 ? "secondary" :
7295
- "Invalid");
7895
+ ql_dbg(ql_dbg_init, vha, 0x018f, "active image %s (%u)\n",
7896
+ active_regions->global == QLA27XX_DEFAULT_IMAGE ?
7897
+ "default (boot/fw)" :
7898
+ active_regions->global == QLA27XX_PRIMARY_IMAGE ?
7899
+ "primary" :
7900
+ active_regions->global == QLA27XX_SECONDARY_IMAGE ?
7901
+ "secondary" : "invalid",
7902
+ active_regions->global);
7903
+}
72967904
7297
- return ha->active_image;
7905
+bool qla24xx_risc_firmware_invalid(uint32_t *dword)
7906
+{
7907
+ return
7908
+ !(dword[4] | dword[5] | dword[6] | dword[7]) ||
7909
+ !(~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]);
72987910 }
72997911
73007912 static int
73017913 qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
73027914 uint32_t faddr)
73037915 {
7304
- int rval = QLA_SUCCESS;
7305
- int segments, fragment;
7306
- uint32_t *dcode, dlen;
7307
- uint32_t risc_addr;
7308
- uint32_t risc_size;
7309
- uint32_t i;
7916
+ int rval;
7917
+ uint templates, segments, fragment;
7918
+ ulong i;
7919
+ uint j;
7920
+ ulong dlen;
7921
+ uint32_t *dcode;
7922
+ uint32_t risc_addr, risc_size, risc_attr = 0;
73107923 struct qla_hw_data *ha = vha->hw;
73117924 struct req_que *req = ha->req_q_map[0];
7925
+ struct fwdt *fwdt = ha->fwdt;
73127926
73137927 ql_dbg(ql_dbg_init, vha, 0x008b,
73147928 "FW: Loading firmware from flash (%x).\n", faddr);
73157929
7316
- rval = QLA_SUCCESS;
7317
-
7318
- segments = FA_RISC_CODE_SEGMENTS;
73197930 dcode = (uint32_t *)req->ring;
7320
- *srisc_addr = 0;
7321
-
7322
- if (IS_QLA27XX(ha) &&
7323
- qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE)
7324
- faddr = ha->flt_region_fw_sec;
7325
-
7326
- /* Validate firmware image by checking version. */
7327
- qla24xx_read_flash_data(vha, dcode, faddr + 4, 4);
7328
- for (i = 0; i < 4; i++)
7329
- dcode[i] = be32_to_cpu(dcode[i]);
7330
- if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff &&
7331
- dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) ||
7332
- (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
7333
- dcode[3] == 0)) {
7931
+ qla24xx_read_flash_data(vha, dcode, faddr, 8);
7932
+ if (qla24xx_risc_firmware_invalid(dcode)) {
73347933 ql_log(ql_log_fatal, vha, 0x008c,
73357934 "Unable to verify the integrity of flash firmware "
73367935 "image.\n");
....@@ -7341,34 +7940,36 @@
73417940 return QLA_FUNCTION_FAILED;
73427941 }
73437942
7344
- while (segments && rval == QLA_SUCCESS) {
7345
- /* Read segment's load information. */
7346
- qla24xx_read_flash_data(vha, dcode, faddr, 4);
7943
+ dcode = (uint32_t *)req->ring;
7944
+ *srisc_addr = 0;
7945
+ segments = FA_RISC_CODE_SEGMENTS;
7946
+ for (j = 0; j < segments; j++) {
7947
+ ql_dbg(ql_dbg_init, vha, 0x008d,
7948
+ "-> Loading segment %u...\n", j);
7949
+ qla24xx_read_flash_data(vha, dcode, faddr, 10);
7950
+ risc_addr = be32_to_cpu((__force __be32)dcode[2]);
7951
+ risc_size = be32_to_cpu((__force __be32)dcode[3]);
7952
+ if (!*srisc_addr) {
7953
+ *srisc_addr = risc_addr;
7954
+ risc_attr = be32_to_cpu((__force __be32)dcode[9]);
7955
+ }
73477956
7348
- risc_addr = be32_to_cpu(dcode[2]);
7349
- *srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
7350
- risc_size = be32_to_cpu(dcode[3]);
7351
-
7352
- fragment = 0;
7353
- while (risc_size > 0 && rval == QLA_SUCCESS) {
7354
- dlen = (uint32_t)(ha->fw_transfer_size >> 2);
7957
+ dlen = ha->fw_transfer_size >> 2;
7958
+ for (fragment = 0; risc_size; fragment++) {
73557959 if (dlen > risc_size)
73567960 dlen = risc_size;
73577961
73587962 ql_dbg(ql_dbg_init, vha, 0x008e,
7359
- "Loading risc segment@ risc addr %x "
7360
- "number of dwords 0x%x offset 0x%x.\n",
7361
- risc_addr, dlen, faddr);
7362
-
7963
+ "-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n",
7964
+ fragment, risc_addr, faddr, dlen);
73637965 qla24xx_read_flash_data(vha, dcode, faddr, dlen);
73647966 for (i = 0; i < dlen; i++)
73657967 dcode[i] = swab32(dcode[i]);
73667968
7367
- rval = qla2x00_load_ram(vha, req->dma, risc_addr,
7368
- dlen);
7969
+ rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen);
73697970 if (rval) {
73707971 ql_log(ql_log_fatal, vha, 0x008f,
7371
- "Failed to load segment %d of firmware.\n",
7972
+ "-> Failed load firmware fragment %u.\n",
73727973 fragment);
73737974 return QLA_FUNCTION_FAILED;
73747975 }
....@@ -7376,107 +7977,82 @@
73767977 faddr += dlen;
73777978 risc_addr += dlen;
73787979 risc_size -= dlen;
7379
- fragment++;
7980
+ }
7981
+ }
7982
+
7983
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
7984
+ return QLA_SUCCESS;
7985
+
7986
+ templates = (risc_attr & BIT_9) ? 2 : 1;
7987
+ ql_dbg(ql_dbg_init, vha, 0x0160, "-> templates = %u\n", templates);
7988
+ for (j = 0; j < templates; j++, fwdt++) {
7989
+ if (fwdt->template)
7990
+ vfree(fwdt->template);
7991
+ fwdt->template = NULL;
7992
+ fwdt->length = 0;
7993
+
7994
+ dcode = (uint32_t *)req->ring;
7995
+ qla24xx_read_flash_data(vha, dcode, faddr, 7);
7996
+ risc_size = be32_to_cpu((__force __be32)dcode[2]);
7997
+ ql_dbg(ql_dbg_init, vha, 0x0161,
7998
+ "-> fwdt%u template array at %#x (%#x dwords)\n",
7999
+ j, faddr, risc_size);
8000
+ if (!risc_size || !~risc_size) {
8001
+ ql_dbg(ql_dbg_init, vha, 0x0162,
8002
+ "-> fwdt%u failed to read array\n", j);
8003
+ goto failed;
73808004 }
73818005
7382
- /* Next segment. */
7383
- segments--;
8006
+ /* skip header and ignore checksum */
8007
+ faddr += 7;
8008
+ risc_size -= 8;
8009
+
8010
+ ql_dbg(ql_dbg_init, vha, 0x0163,
8011
+ "-> fwdt%u template allocate template %#x words...\n",
8012
+ j, risc_size);
8013
+ fwdt->template = vmalloc(risc_size * sizeof(*dcode));
8014
+ if (!fwdt->template) {
8015
+ ql_log(ql_log_warn, vha, 0x0164,
8016
+ "-> fwdt%u failed allocate template.\n", j);
8017
+ goto failed;
8018
+ }
8019
+
8020
+ dcode = fwdt->template;
8021
+ qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
8022
+
8023
+ if (!qla27xx_fwdt_template_valid(dcode)) {
8024
+ ql_log(ql_log_warn, vha, 0x0165,
8025
+ "-> fwdt%u failed template validate\n", j);
8026
+ goto failed;
8027
+ }
8028
+
8029
+ dlen = qla27xx_fwdt_template_size(dcode);
8030
+ ql_dbg(ql_dbg_init, vha, 0x0166,
8031
+ "-> fwdt%u template size %#lx bytes (%#lx words)\n",
8032
+ j, dlen, dlen / sizeof(*dcode));
8033
+ if (dlen > risc_size * sizeof(*dcode)) {
8034
+ ql_log(ql_log_warn, vha, 0x0167,
8035
+ "-> fwdt%u template exceeds array (%-lu bytes)\n",
8036
+ j, dlen - risc_size * sizeof(*dcode));
8037
+ goto failed;
8038
+ }
8039
+
8040
+ fwdt->length = dlen;
8041
+ ql_dbg(ql_dbg_init, vha, 0x0168,
8042
+ "-> fwdt%u loaded template ok\n", j);
8043
+
8044
+ faddr += risc_size + 1;
73848045 }
73858046
7386
- if (!IS_QLA27XX(ha))
7387
- return rval;
8047
+ return QLA_SUCCESS;
73888048
7389
- if (ha->fw_dump_template)
7390
- vfree(ha->fw_dump_template);
7391
- ha->fw_dump_template = NULL;
7392
- ha->fw_dump_template_len = 0;
8049
+failed:
8050
+ if (fwdt->template)
8051
+ vfree(fwdt->template);
8052
+ fwdt->template = NULL;
8053
+ fwdt->length = 0;
73938054
7394
- ql_dbg(ql_dbg_init, vha, 0x0161,
7395
- "Loading fwdump template from %x\n", faddr);
7396
- qla24xx_read_flash_data(vha, dcode, faddr, 7);
7397
- risc_size = be32_to_cpu(dcode[2]);
7398
- ql_dbg(ql_dbg_init, vha, 0x0162,
7399
- "-> array size %x dwords\n", risc_size);
7400
- if (risc_size == 0 || risc_size == ~0)
7401
- goto default_template;
7402
-
7403
- dlen = (risc_size - 8) * sizeof(*dcode);
7404
- ql_dbg(ql_dbg_init, vha, 0x0163,
7405
- "-> template allocating %x bytes...\n", dlen);
7406
- ha->fw_dump_template = vmalloc(dlen);
7407
- if (!ha->fw_dump_template) {
7408
- ql_log(ql_log_warn, vha, 0x0164,
7409
- "Failed fwdump template allocate %x bytes.\n", risc_size);
7410
- goto default_template;
7411
- }
7412
-
7413
- faddr += 7;
7414
- risc_size -= 8;
7415
- dcode = ha->fw_dump_template;
7416
- qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
7417
- for (i = 0; i < risc_size; i++)
7418
- dcode[i] = le32_to_cpu(dcode[i]);
7419
-
7420
- if (!qla27xx_fwdt_template_valid(dcode)) {
7421
- ql_log(ql_log_warn, vha, 0x0165,
7422
- "Failed fwdump template validate\n");
7423
- goto default_template;
7424
- }
7425
-
7426
- dlen = qla27xx_fwdt_template_size(dcode);
7427
- ql_dbg(ql_dbg_init, vha, 0x0166,
7428
- "-> template size %x bytes\n", dlen);
7429
- if (dlen > risc_size * sizeof(*dcode)) {
7430
- ql_log(ql_log_warn, vha, 0x0167,
7431
- "Failed fwdump template exceeds array by %zx bytes\n",
7432
- (size_t)(dlen - risc_size * sizeof(*dcode)));
7433
- goto default_template;
7434
- }
7435
- ha->fw_dump_template_len = dlen;
7436
- return rval;
7437
-
7438
-default_template:
7439
- ql_log(ql_log_warn, vha, 0x0168, "Using default fwdump template\n");
7440
- if (ha->fw_dump_template)
7441
- vfree(ha->fw_dump_template);
7442
- ha->fw_dump_template = NULL;
7443
- ha->fw_dump_template_len = 0;
7444
-
7445
- dlen = qla27xx_fwdt_template_default_size();
7446
- ql_dbg(ql_dbg_init, vha, 0x0169,
7447
- "-> template allocating %x bytes...\n", dlen);
7448
- ha->fw_dump_template = vmalloc(dlen);
7449
- if (!ha->fw_dump_template) {
7450
- ql_log(ql_log_warn, vha, 0x016a,
7451
- "Failed fwdump template allocate %x bytes.\n", risc_size);
7452
- goto failed_template;
7453
- }
7454
-
7455
- dcode = ha->fw_dump_template;
7456
- risc_size = dlen / sizeof(*dcode);
7457
- memcpy(dcode, qla27xx_fwdt_template_default(), dlen);
7458
- for (i = 0; i < risc_size; i++)
7459
- dcode[i] = be32_to_cpu(dcode[i]);
7460
-
7461
- if (!qla27xx_fwdt_template_valid(ha->fw_dump_template)) {
7462
- ql_log(ql_log_warn, vha, 0x016b,
7463
- "Failed fwdump template validate\n");
7464
- goto failed_template;
7465
- }
7466
-
7467
- dlen = qla27xx_fwdt_template_size(ha->fw_dump_template);
7468
- ql_dbg(ql_dbg_init, vha, 0x016c,
7469
- "-> template size %x bytes\n", dlen);
7470
- ha->fw_dump_template_len = dlen;
7471
- return rval;
7472
-
7473
-failed_template:
7474
- ql_log(ql_log_warn, vha, 0x016d, "Failed default fwdump template\n");
7475
- if (ha->fw_dump_template)
7476
- vfree(ha->fw_dump_template);
7477
- ha->fw_dump_template = NULL;
7478
- ha->fw_dump_template_len = 0;
7479
- return rval;
8055
+ return QLA_SUCCESS;
74808056 }
74818057
74828058 #define QLA_FW_URL "http://ldriver.qlogic.com/firmware/"
....@@ -7486,7 +8062,8 @@
74868062 {
74878063 int rval;
74888064 int i, fragment;
7489
- uint16_t *wcode, *fwcode;
8065
+ uint16_t *wcode;
8066
+ __be16 *fwcode;
74908067 uint32_t risc_addr, risc_size, fwclen, wlen, *seg;
74918068 struct fw_blob *blob;
74928069 struct qla_hw_data *ha = vha->hw;
....@@ -7506,7 +8083,7 @@
75068083
75078084 wcode = (uint16_t *)req->ring;
75088085 *srisc_addr = 0;
7509
- fwcode = (uint16_t *)blob->fw->data;
8086
+ fwcode = (__force __be16 *)blob->fw->data;
75108087 fwclen = 0;
75118088
75128089 /* Validate firmware image by checking version. */
....@@ -7554,7 +8131,7 @@
75548131 "words 0x%x.\n", risc_addr, wlen);
75558132
75568133 for (i = 0; i < wlen; i++)
7557
- wcode[i] = swab16(fwcode[i]);
8134
+ wcode[i] = swab16((__force u32)fwcode[i]);
75588135
75598136 rval = qla2x00_load_ram(vha, req->dma, risc_addr,
75608137 wlen);
....@@ -7584,54 +8161,33 @@
75848161 qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
75858162 {
75868163 int rval;
7587
- int segments, fragment;
7588
- uint32_t *dcode, dlen;
7589
- uint32_t risc_addr;
7590
- uint32_t risc_size;
7591
- uint32_t i;
8164
+ uint templates, segments, fragment;
8165
+ uint32_t *dcode;
8166
+ ulong dlen;
8167
+ uint32_t risc_addr, risc_size, risc_attr = 0;
8168
+ ulong i;
8169
+ uint j;
75928170 struct fw_blob *blob;
7593
- const uint32_t *fwcode;
7594
- uint32_t fwclen;
8171
+ __be32 *fwcode;
75958172 struct qla_hw_data *ha = vha->hw;
75968173 struct req_que *req = ha->req_q_map[0];
8174
+ struct fwdt *fwdt = ha->fwdt;
75978175
7598
- /* Load firmware blob. */
8176
+ ql_dbg(ql_dbg_init, vha, 0x0090,
8177
+ "-> FW: Loading via request-firmware.\n");
8178
+
75998179 blob = qla2x00_request_firmware(vha);
76008180 if (!blob) {
7601
- ql_log(ql_log_warn, vha, 0x0090,
7602
- "Firmware image unavailable.\n");
7603
- ql_log(ql_log_warn, vha, 0x0091,
7604
- "Firmware images can be retrieved from: "
7605
- QLA_FW_URL ".\n");
8181
+ ql_log(ql_log_warn, vha, 0x0092,
8182
+ "-> Firmware file not found.\n");
76068183
76078184 return QLA_FUNCTION_FAILED;
76088185 }
76098186
7610
- ql_dbg(ql_dbg_init, vha, 0x0092,
7611
- "FW: Loading via request-firmware.\n");
7612
-
7613
- rval = QLA_SUCCESS;
7614
-
7615
- segments = FA_RISC_CODE_SEGMENTS;
7616
- dcode = (uint32_t *)req->ring;
7617
- *srisc_addr = 0;
7618
- fwcode = (uint32_t *)blob->fw->data;
7619
- fwclen = 0;
7620
-
7621
- /* Validate firmware image by checking version. */
7622
- if (blob->fw->size < 8 * sizeof(uint32_t)) {
8187
+ fwcode = (__force __be32 *)blob->fw->data;
8188
+ dcode = (__force uint32_t *)fwcode;
8189
+ if (qla24xx_risc_firmware_invalid(dcode)) {
76238190 ql_log(ql_log_fatal, vha, 0x0093,
7624
- "Unable to verify integrity of firmware image (%zd).\n",
7625
- blob->fw->size);
7626
- return QLA_FUNCTION_FAILED;
7627
- }
7628
- for (i = 0; i < 4; i++)
7629
- dcode[i] = be32_to_cpu(fwcode[i + 4]);
7630
- if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff &&
7631
- dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) ||
7632
- (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
7633
- dcode[3] == 0)) {
7634
- ql_log(ql_log_fatal, vha, 0x0094,
76358191 "Unable to verify integrity of firmware image (%zd).\n",
76368192 blob->fw->size);
76378193 ql_log(ql_log_fatal, vha, 0x0095,
....@@ -7640,38 +8196,38 @@
76408196 return QLA_FUNCTION_FAILED;
76418197 }
76428198
7643
- while (segments && rval == QLA_SUCCESS) {
8199
+ dcode = (uint32_t *)req->ring;
8200
+ *srisc_addr = 0;
8201
+ segments = FA_RISC_CODE_SEGMENTS;
8202
+ for (j = 0; j < segments; j++) {
8203
+ ql_dbg(ql_dbg_init, vha, 0x0096,
8204
+ "-> Loading segment %u...\n", j);
76448205 risc_addr = be32_to_cpu(fwcode[2]);
7645
- *srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
76468206 risc_size = be32_to_cpu(fwcode[3]);
76478207
7648
- /* Validate firmware image size. */
7649
- fwclen += risc_size * sizeof(uint32_t);
7650
- if (blob->fw->size < fwclen) {
7651
- ql_log(ql_log_fatal, vha, 0x0096,
7652
- "Unable to verify integrity of firmware image "
7653
- "(%zd).\n", blob->fw->size);
7654
- return QLA_FUNCTION_FAILED;
8208
+ if (!*srisc_addr) {
8209
+ *srisc_addr = risc_addr;
8210
+ risc_attr = be32_to_cpu(fwcode[9]);
76558211 }
76568212
7657
- fragment = 0;
7658
- while (risc_size > 0 && rval == QLA_SUCCESS) {
7659
- dlen = (uint32_t)(ha->fw_transfer_size >> 2);
8213
+ dlen = ha->fw_transfer_size >> 2;
8214
+ for (fragment = 0; risc_size; fragment++) {
76608215 if (dlen > risc_size)
76618216 dlen = risc_size;
76628217
76638218 ql_dbg(ql_dbg_init, vha, 0x0097,
7664
- "Loading risc segment@ risc addr %x "
7665
- "number of dwords 0x%x.\n", risc_addr, dlen);
8219
+ "-> Loading fragment %u: %#x <- %#x (%#lx words)...\n",
8220
+ fragment, risc_addr,
8221
+ (uint32_t)(fwcode - (typeof(fwcode))blob->fw->data),
8222
+ dlen);
76668223
76678224 for (i = 0; i < dlen; i++)
7668
- dcode[i] = swab32(fwcode[i]);
8225
+ dcode[i] = swab32((__force u32)fwcode[i]);
76698226
7670
- rval = qla2x00_load_ram(vha, req->dma, risc_addr,
7671
- dlen);
8227
+ rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen);
76728228 if (rval) {
76738229 ql_log(ql_log_fatal, vha, 0x0098,
7674
- "Failed to load segment %d of firmware.\n",
8230
+ "-> Failed load firmware fragment %u.\n",
76758231 fragment);
76768232 return QLA_FUNCTION_FAILED;
76778233 }
....@@ -7679,106 +8235,82 @@
76798235 fwcode += dlen;
76808236 risc_addr += dlen;
76818237 risc_size -= dlen;
7682
- fragment++;
8238
+ }
8239
+ }
8240
+
8241
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
8242
+ return QLA_SUCCESS;
8243
+
8244
+ templates = (risc_attr & BIT_9) ? 2 : 1;
8245
+ ql_dbg(ql_dbg_init, vha, 0x0170, "-> templates = %u\n", templates);
8246
+ for (j = 0; j < templates; j++, fwdt++) {
8247
+ if (fwdt->template)
8248
+ vfree(fwdt->template);
8249
+ fwdt->template = NULL;
8250
+ fwdt->length = 0;
8251
+
8252
+ risc_size = be32_to_cpu(fwcode[2]);
8253
+ ql_dbg(ql_dbg_init, vha, 0x0171,
8254
+ "-> fwdt%u template array at %#x (%#x dwords)\n",
8255
+ j, (uint32_t)((void *)fwcode - (void *)blob->fw->data),
8256
+ risc_size);
8257
+ if (!risc_size || !~risc_size) {
8258
+ ql_dbg(ql_dbg_init, vha, 0x0172,
8259
+ "-> fwdt%u failed to read array\n", j);
8260
+ goto failed;
76838261 }
76848262
7685
- /* Next segment. */
7686
- segments--;
8263
+ /* skip header and ignore checksum */
8264
+ fwcode += 7;
8265
+ risc_size -= 8;
8266
+
8267
+ ql_dbg(ql_dbg_init, vha, 0x0173,
8268
+ "-> fwdt%u template allocate template %#x words...\n",
8269
+ j, risc_size);
8270
+ fwdt->template = vmalloc(risc_size * sizeof(*dcode));
8271
+ if (!fwdt->template) {
8272
+ ql_log(ql_log_warn, vha, 0x0174,
8273
+ "-> fwdt%u failed allocate template.\n", j);
8274
+ goto failed;
8275
+ }
8276
+
8277
+ dcode = fwdt->template;
8278
+ for (i = 0; i < risc_size; i++)
8279
+ dcode[i] = (__force u32)fwcode[i];
8280
+
8281
+ if (!qla27xx_fwdt_template_valid(dcode)) {
8282
+ ql_log(ql_log_warn, vha, 0x0175,
8283
+ "-> fwdt%u failed template validate\n", j);
8284
+ goto failed;
8285
+ }
8286
+
8287
+ dlen = qla27xx_fwdt_template_size(dcode);
8288
+ ql_dbg(ql_dbg_init, vha, 0x0176,
8289
+ "-> fwdt%u template size %#lx bytes (%#lx words)\n",
8290
+ j, dlen, dlen / sizeof(*dcode));
8291
+ if (dlen > risc_size * sizeof(*dcode)) {
8292
+ ql_log(ql_log_warn, vha, 0x0177,
8293
+ "-> fwdt%u template exceeds array (%-lu bytes)\n",
8294
+ j, dlen - risc_size * sizeof(*dcode));
8295
+ goto failed;
8296
+ }
8297
+
8298
+ fwdt->length = dlen;
8299
+ ql_dbg(ql_dbg_init, vha, 0x0178,
8300
+ "-> fwdt%u loaded template ok\n", j);
8301
+
8302
+ fwcode += risc_size + 1;
76878303 }
76888304
7689
- if (!IS_QLA27XX(ha))
7690
- return rval;
8305
+ return QLA_SUCCESS;
76918306
7692
- if (ha->fw_dump_template)
7693
- vfree(ha->fw_dump_template);
7694
- ha->fw_dump_template = NULL;
7695
- ha->fw_dump_template_len = 0;
8307
+failed:
8308
+ if (fwdt->template)
8309
+ vfree(fwdt->template);
8310
+ fwdt->template = NULL;
8311
+ fwdt->length = 0;
76968312
7697
- ql_dbg(ql_dbg_init, vha, 0x171,
7698
- "Loading fwdump template from %x\n",
7699
- (uint32_t)((void *)fwcode - (void *)blob->fw->data));
7700
- risc_size = be32_to_cpu(fwcode[2]);
7701
- ql_dbg(ql_dbg_init, vha, 0x172,
7702
- "-> array size %x dwords\n", risc_size);
7703
- if (risc_size == 0 || risc_size == ~0)
7704
- goto default_template;
7705
-
7706
- dlen = (risc_size - 8) * sizeof(*fwcode);
7707
- ql_dbg(ql_dbg_init, vha, 0x0173,
7708
- "-> template allocating %x bytes...\n", dlen);
7709
- ha->fw_dump_template = vmalloc(dlen);
7710
- if (!ha->fw_dump_template) {
7711
- ql_log(ql_log_warn, vha, 0x0174,
7712
- "Failed fwdump template allocate %x bytes.\n", risc_size);
7713
- goto default_template;
7714
- }
7715
-
7716
- fwcode += 7;
7717
- risc_size -= 8;
7718
- dcode = ha->fw_dump_template;
7719
- for (i = 0; i < risc_size; i++)
7720
- dcode[i] = le32_to_cpu(fwcode[i]);
7721
-
7722
- if (!qla27xx_fwdt_template_valid(dcode)) {
7723
- ql_log(ql_log_warn, vha, 0x0175,
7724
- "Failed fwdump template validate\n");
7725
- goto default_template;
7726
- }
7727
-
7728
- dlen = qla27xx_fwdt_template_size(dcode);
7729
- ql_dbg(ql_dbg_init, vha, 0x0176,
7730
- "-> template size %x bytes\n", dlen);
7731
- if (dlen > risc_size * sizeof(*fwcode)) {
7732
- ql_log(ql_log_warn, vha, 0x0177,
7733
- "Failed fwdump template exceeds array by %zx bytes\n",
7734
- (size_t)(dlen - risc_size * sizeof(*fwcode)));
7735
- goto default_template;
7736
- }
7737
- ha->fw_dump_template_len = dlen;
7738
- return rval;
7739
-
7740
-default_template:
7741
- ql_log(ql_log_warn, vha, 0x0178, "Using default fwdump template\n");
7742
- if (ha->fw_dump_template)
7743
- vfree(ha->fw_dump_template);
7744
- ha->fw_dump_template = NULL;
7745
- ha->fw_dump_template_len = 0;
7746
-
7747
- dlen = qla27xx_fwdt_template_default_size();
7748
- ql_dbg(ql_dbg_init, vha, 0x0179,
7749
- "-> template allocating %x bytes...\n", dlen);
7750
- ha->fw_dump_template = vmalloc(dlen);
7751
- if (!ha->fw_dump_template) {
7752
- ql_log(ql_log_warn, vha, 0x017a,
7753
- "Failed fwdump template allocate %x bytes.\n", risc_size);
7754
- goto failed_template;
7755
- }
7756
-
7757
- dcode = ha->fw_dump_template;
7758
- risc_size = dlen / sizeof(*fwcode);
7759
- fwcode = qla27xx_fwdt_template_default();
7760
- for (i = 0; i < risc_size; i++)
7761
- dcode[i] = be32_to_cpu(fwcode[i]);
7762
-
7763
- if (!qla27xx_fwdt_template_valid(ha->fw_dump_template)) {
7764
- ql_log(ql_log_warn, vha, 0x017b,
7765
- "Failed fwdump template validate\n");
7766
- goto failed_template;
7767
- }
7768
-
7769
- dlen = qla27xx_fwdt_template_size(ha->fw_dump_template);
7770
- ql_dbg(ql_dbg_init, vha, 0x017c,
7771
- "-> template size %x bytes\n", dlen);
7772
- ha->fw_dump_template_len = dlen;
7773
- return rval;
7774
-
7775
-failed_template:
7776
- ql_log(ql_log_warn, vha, 0x017d, "Failed default fwdump template\n");
7777
- if (ha->fw_dump_template)
7778
- vfree(ha->fw_dump_template);
7779
- ha->fw_dump_template = NULL;
7780
- ha->fw_dump_template_len = 0;
7781
- return rval;
8313
+ return QLA_SUCCESS;
77828314 }
77838315
77848316 int
....@@ -7807,32 +8339,50 @@
78078339 {
78088340 int rval;
78098341 struct qla_hw_data *ha = vha->hw;
8342
+ struct active_regions active_regions = { };
78108343
78118344 if (ql2xfwloadbin == 2)
78128345 goto try_blob_fw;
78138346
7814
- /*
7815
- * FW Load priority:
8347
+ /* FW Load priority:
78168348 * 1) Firmware residing in flash.
78178349 * 2) Firmware via request-firmware interface (.bin file).
7818
- * 3) Golden-Firmware residing in flash -- limited operation.
8350
+ * 3) Golden-Firmware residing in flash -- (limited operation).
78198351 */
8352
+
8353
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
8354
+ goto try_primary_fw;
8355
+
8356
+ qla27xx_get_active_image(vha, &active_regions);
8357
+
8358
+ if (active_regions.global != QLA27XX_SECONDARY_IMAGE)
8359
+ goto try_primary_fw;
8360
+
8361
+ ql_dbg(ql_dbg_init, vha, 0x008b,
8362
+ "Loading secondary firmware image.\n");
8363
+ rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw_sec);
8364
+ if (!rval)
8365
+ return rval;
8366
+
8367
+try_primary_fw:
8368
+ ql_dbg(ql_dbg_init, vha, 0x008b,
8369
+ "Loading primary firmware image.\n");
78208370 rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw);
7821
- if (rval == QLA_SUCCESS)
8371
+ if (!rval)
78228372 return rval;
78238373
78248374 try_blob_fw:
78258375 rval = qla24xx_load_risc_blob(vha, srisc_addr);
7826
- if (rval == QLA_SUCCESS || !ha->flt_region_gold_fw)
8376
+ if (!rval || !ha->flt_region_gold_fw)
78278377 return rval;
78288378
78298379 ql_log(ql_log_info, vha, 0x0099,
78308380 "Attempting to fallback to golden firmware.\n");
78318381 rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_gold_fw);
7832
- if (rval != QLA_SUCCESS)
8382
+ if (rval)
78338383 return rval;
78348384
7835
- ql_log(ql_log_info, vha, 0x009a, "Update operational firmware.\n");
8385
+ ql_log(ql_log_info, vha, 0x009a, "Need firmware flash update.\n");
78368386 ha->flags.running_gold_fw = 1;
78378387 return rval;
78388388 }
....@@ -7877,22 +8427,15 @@
78778427 uint16_t mb[MAILBOX_REGISTER_COUNT];
78788428 struct qla_hw_data *ha = vha->hw;
78798429 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
7880
- struct req_que *req;
7881
- struct rsp_que *rsp;
78828430
78838431 if (!vha->vp_idx)
78848432 return -EINVAL;
78858433
78868434 rval = qla2x00_fw_ready(base_vha);
7887
- if (vha->qpair)
7888
- req = vha->qpair->req;
7889
- else
7890
- req = ha->req_q_map[0];
7891
- rsp = req->rsp;
78928435
78938436 if (rval == QLA_SUCCESS) {
78948437 clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
7895
- qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
8438
+ qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
78968439 }
78978440
78988441 vha->flags.management_server_logged_in = 0;
....@@ -7974,6 +8517,7 @@
79748517 qla84xx_put_chip(struct scsi_qla_host *vha)
79758518 {
79768519 struct qla_hw_data *ha = vha->hw;
8520
+
79778521 if (ha->cs84xx)
79788522 kref_put(&ha->cs84xx->kref, __qla84xx_chip_release);
79798523 }
....@@ -7991,7 +8535,7 @@
79918535
79928536 mutex_unlock(&ha->cs84xx->fw_update_mutex);
79938537
7994
- return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED:
8538
+ return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED :
79958539 QLA_SUCCESS;
79968540 }
79978541
....@@ -8003,48 +8547,70 @@
80038547 int rval;
80048548 struct init_cb_81xx *icb;
80058549 struct nvram_81xx *nv;
8006
- uint32_t *dptr;
8550
+ __le32 *dptr;
80078551 uint8_t *dptr1, *dptr2;
80088552 uint32_t chksum;
80098553 uint16_t cnt;
80108554 struct qla_hw_data *ha = vha->hw;
8555
+ uint32_t faddr;
8556
+ struct active_regions active_regions = { };
80118557
80128558 rval = QLA_SUCCESS;
80138559 icb = (struct init_cb_81xx *)ha->init_cb;
80148560 nv = ha->nvram;
80158561
80168562 /* Determine NVRAM starting address. */
8017
- ha->nvram_size = sizeof(struct nvram_81xx);
8563
+ ha->nvram_size = sizeof(*nv);
80188564 ha->vpd_size = FA_NVRAM_VPD_SIZE;
80198565 if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
80208566 ha->vpd_size = FA_VPD_SIZE_82XX;
80218567
8568
+ if (IS_QLA28XX(ha) || IS_QLA27XX(ha))
8569
+ qla28xx_get_aux_images(vha, &active_regions);
8570
+
80228571 /* Get VPD data into cache */
80238572 ha->vpd = ha->nvram + VPD_OFFSET;
8024
- ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
8025
- ha->vpd_size);
8573
+
8574
+ faddr = ha->flt_region_vpd;
8575
+ if (IS_QLA28XX(ha)) {
8576
+ if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
8577
+ faddr = ha->flt_region_vpd_sec;
8578
+ ql_dbg(ql_dbg_init, vha, 0x0110,
8579
+ "Loading %s nvram image.\n",
8580
+ active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
8581
+ "primary" : "secondary");
8582
+ }
8583
+ ha->isp_ops->read_optrom(vha, ha->vpd, faddr << 2, ha->vpd_size);
80268584
80278585 /* Get NVRAM data into cache and calculate checksum. */
8028
- ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2,
8029
- ha->nvram_size);
8030
- dptr = (uint32_t *)nv;
8586
+ faddr = ha->flt_region_nvram;
8587
+ if (IS_QLA28XX(ha)) {
8588
+ if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
8589
+ faddr = ha->flt_region_nvram_sec;
8590
+ }
8591
+ ql_dbg(ql_dbg_init, vha, 0x0110,
8592
+ "Loading %s nvram image.\n",
8593
+ active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
8594
+ "primary" : "secondary");
8595
+ ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size);
8596
+
8597
+ dptr = (__force __le32 *)nv;
80318598 for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
80328599 chksum += le32_to_cpu(*dptr);
80338600
80348601 ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0111,
80358602 "Contents of NVRAM:\n");
80368603 ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0112,
8037
- (uint8_t *)nv, ha->nvram_size);
8604
+ nv, ha->nvram_size);
80388605
80398606 /* Bad NVRAM data, set defaults parameters. */
8040
- if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'
8041
- || nv->id[3] != ' ' ||
8042
- nv->nvram_version < cpu_to_le16(ICB_VERSION)) {
8607
+ if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
8608
+ le16_to_cpu(nv->nvram_version) < ICB_VERSION) {
80438609 /* Reset NVRAM data. */
80448610 ql_log(ql_log_info, vha, 0x0073,
8045
- "Inconsistent NVRAM detected: checksum=0x%x id=%c "
8046
- "version=0x%x.\n", chksum, nv->id[0],
8047
- le16_to_cpu(nv->nvram_version));
8611
+ "Inconsistent NVRAM checksum=%#x id=%.4s version=%#x.\n",
8612
+ chksum, nv->id, le16_to_cpu(nv->nvram_version));
8613
+ ql_dump_buffer(ql_dbg_init, vha, 0x0073, nv, sizeof(*nv));
80488614 ql_log(ql_log_info, vha, 0x0074,
80498615 "Falling back to functioning (yet invalid -- WWPN) "
80508616 "defaults.\n");
....@@ -8055,7 +8621,7 @@
80558621 memset(nv, 0, ha->nvram_size);
80568622 nv->nvram_version = cpu_to_le16(ICB_VERSION);
80578623 nv->version = cpu_to_le16(ICB_VERSION);
8058
- nv->frame_payload_size = 2048;
8624
+ nv->frame_payload_size = cpu_to_le16(2048);
80598625 nv->execution_throttle = cpu_to_le16(0xFFFF);
80608626 nv->exchange_count = cpu_to_le16(0);
80618627 nv->port_name[0] = 0x21;
....@@ -8099,7 +8665,7 @@
80998665 }
81008666
81018667 if (IS_T10_PI_CAPABLE(ha))
8102
- nv->frame_payload_size &= ~7;
8668
+ nv->frame_payload_size &= cpu_to_le16(~7);
81038669
81048670 qlt_81xx_config_nvram_stage1(vha, nv);
81058671
....@@ -8161,15 +8727,20 @@
81618727 icb->node_name[0] &= 0xF0;
81628728 }
81638729
8730
+ if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
8731
+ if ((nv->enhanced_features & BIT_7) == 0)
8732
+ ha->flags.scm_supported_a = 1;
8733
+ }
8734
+
81648735 /* Set host adapter parameters. */
81658736 ha->flags.disable_risc_code_load = 0;
81668737 ha->flags.enable_lip_reset = 0;
81678738 ha->flags.enable_lip_full_login =
8168
- le32_to_cpu(nv->host_p) & BIT_10 ? 1: 0;
8739
+ le32_to_cpu(nv->host_p) & BIT_10 ? 1 : 0;
81698740 ha->flags.enable_target_reset =
8170
- le32_to_cpu(nv->host_p) & BIT_11 ? 1: 0;
8741
+ le32_to_cpu(nv->host_p) & BIT_11 ? 1 : 0;
81718742 ha->flags.enable_led_scheme = 0;
8172
- ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0;
8743
+ ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1 : 0;
81738744
81748745 ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) &
81758746 (BIT_6 | BIT_5 | BIT_4)) >> 4;
....@@ -8233,7 +8804,8 @@
82338804 ha->login_retry_count = ql2xloginretrycount;
82348805
82358806 /* if not running MSI-X we need handshaking on interrupts */
8236
- if (!vha->hw->flags.msix_enabled && (IS_QLA83XX(ha) || IS_QLA27XX(ha)))
8807
+ if (!vha->hw->flags.msix_enabled &&
8808
+ (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)))
82378809 icb->firmware_options_2 |= cpu_to_le32(BIT_22);
82388810
82398811 /* Enable ZIO. */
....@@ -8241,7 +8813,7 @@
82418813 ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
82428814 (BIT_3 | BIT_2 | BIT_1 | BIT_0);
82438815 ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ?
8244
- le16_to_cpu(icb->interrupt_delay_timer): 2;
8816
+ le16_to_cpu(icb->interrupt_delay_timer) : 2;
82458817 }
82468818 icb->firmware_options_2 &= cpu_to_le32(
82478819 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
....@@ -8261,16 +8833,13 @@
82618833 }
82628834
82638835 /* enable RIDA Format2 */
8264
- icb->firmware_options_3 |= BIT_0;
8836
+ icb->firmware_options_3 |= cpu_to_le32(BIT_0);
82658837
82668838 /* N2N: driver will initiate Login instead of FW */
8267
- icb->firmware_options_3 |= BIT_8;
8839
+ icb->firmware_options_3 |= cpu_to_le32(BIT_8);
82688840
8269
- if (IS_QLA27XX(ha)) {
8270
- icb->firmware_options_3 |= BIT_8;
8271
- ql_dbg(ql_log_info, vha, 0x0075,
8272
- "Enabling direct connection.\n");
8273
- }
8841
+ /* Determine NVMe/FCP priority for target ports */
8842
+ ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha);
82748843
82758844 if (rval) {
82768845 ql_log(ql_log_warn, vha, 0x0076,
....@@ -8284,8 +8853,6 @@
82848853 {
82858854 int status, rval;
82868855 struct qla_hw_data *ha = vha->hw;
8287
- struct req_que *req = ha->req_q_map[0];
8288
- struct rsp_que *rsp = ha->rsp_q_map[0];
82898856 struct scsi_qla_host *vp;
82908857 unsigned long flags;
82918858
....@@ -8297,7 +8864,7 @@
82978864 status = qla2x00_fw_ready(vha);
82988865 if (!status) {
82998866 /* Issue a marker after FW becomes ready. */
8300
- qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
8867
+ qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
83018868 vha->flags.online = 1;
83028869 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
83038870 }
....@@ -8377,61 +8944,6 @@
83778944 }
83788945
83798946 return status;
8380
-}
8381
-
8382
-void
8383
-qla81xx_update_fw_options(scsi_qla_host_t *vha)
8384
-{
8385
- struct qla_hw_data *ha = vha->hw;
8386
-
8387
- /* Hold status IOCBs until ABTS response received. */
8388
- if (ql2xfwholdabts)
8389
- ha->fw_options[3] |= BIT_12;
8390
-
8391
- /* Set Retry FLOGI in case of P2P connection */
8392
- if (ha->operating_mode == P2P) {
8393
- ha->fw_options[2] |= BIT_3;
8394
- ql_dbg(ql_dbg_disc, vha, 0x2103,
8395
- "(%s): Setting FLOGI retry BIT in fw_options[2]: 0x%x\n",
8396
- __func__, ha->fw_options[2]);
8397
- }
8398
-
8399
- /* Move PUREX, ABTS RX & RIDA to ATIOQ */
8400
- if (ql2xmvasynctoatio) {
8401
- if (qla_tgt_mode_enabled(vha) ||
8402
- qla_dual_mode_enabled(vha))
8403
- ha->fw_options[2] |= BIT_11;
8404
- else
8405
- ha->fw_options[2] &= ~BIT_11;
8406
- }
8407
-
8408
- if (qla_tgt_mode_enabled(vha) ||
8409
- qla_dual_mode_enabled(vha)) {
8410
- /* FW auto send SCSI status during */
8411
- ha->fw_options[1] |= BIT_8;
8412
- ha->fw_options[10] |= (u16)SAM_STAT_BUSY << 8;
8413
-
8414
- /* FW perform Exchange validation */
8415
- ha->fw_options[2] |= BIT_4;
8416
- } else {
8417
- ha->fw_options[1] &= ~BIT_8;
8418
- ha->fw_options[10] &= 0x00ff;
8419
-
8420
- ha->fw_options[2] &= ~BIT_4;
8421
- }
8422
-
8423
- if (ql2xetsenable) {
8424
- /* Enable ETS Burst. */
8425
- memset(ha->fw_options, 0, sizeof(ha->fw_options));
8426
- ha->fw_options[2] |= BIT_9;
8427
- }
8428
-
8429
- ql_dbg(ql_dbg_init, vha, 0x00e9,
8430
- "%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
8431
- __func__, ha->fw_options[1], ha->fw_options[2],
8432
- ha->fw_options[3], vha->host->active_mode);
8433
-
8434
- qla2x00_set_fw_options(vha, ha->fw_options);
84358947 }
84368948
84378949 /*
....@@ -8634,7 +9146,6 @@
86349146 "Failed to allocate memory for queue pair.\n");
86359147 return NULL;
86369148 }
8637
- memset(qpair, 0, sizeof(struct qla_qpair));
86389149
86399150 qpair->hw = vha->hw;
86409151 qpair->vha = vha;
....@@ -8681,7 +9192,7 @@
86819192 qpair->msix->in_use = 1;
86829193 list_add_tail(&qpair->qp_list_elem, &vha->qp_list);
86839194 qpair->pdev = ha->pdev;
8684
- if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
9195
+ if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha))
86859196 qpair->reqq_start_iocbs = qla_83xx_start_iocbs;
86869197
86879198 mutex_unlock(&ha->mq_lock);
....@@ -8709,7 +9220,7 @@
87099220 qpair->rsp->req = qpair->req;
87109221 qpair->rsp->qpair = qpair;
87119222 /* init qpair to this cpu. Will adjust at run time. */
8712
- qla_cpu_update(qpair, smp_processor_id());
9223
+ qla_cpu_update(qpair, raw_smp_processor_id());
87139224
87149225 if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
87159226 if (ha->fw_attributes & BIT_4)