forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
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:
....@@ -396,10 +490,16 @@
396490 fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
397491 fcport->rscn_gen, ea->sp->gen1, fcport->loop_id);
398492
493
+ WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
494
+ ea->data[0]);
495
+
399496 if (ea->data[0] != MBS_COMMAND_COMPLETE) {
400497 ql_dbg(ql_dbg_disc, vha, 0x2066,
401498 "%s %8phC: adisc fail: post delete\n",
402499 __func__, ea->fcport->port_name);
500
+ /* deleted = 0 & logout_on_delete = force fw cleanup */
501
+ fcport->deleted = 0;
502
+ fcport->logout_on_delete = 1;
403503 qlt_schedule_sess_for_deletion(ea->fcport);
404504 return;
405505 }
....@@ -414,16 +514,15 @@
414514 __func__, ea->fcport->port_name);
415515 return;
416516 } 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);
517
+ qla_rscn_replay(fcport);
518
+ qlt_schedule_sess_for_deletion(fcport);
420519 return;
421520 }
422521
423522 __qla24xx_handle_gpdb_event(vha, ea);
424523 }
425524
426
-int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
525
+static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
427526 {
428527 struct qla_work_evt *e;
429528
....@@ -433,14 +532,12 @@
433532
434533 e->u.fcport.fcport = fcport;
435534 fcport->flags |= FCF_ASYNC_ACTIVE;
436
- fcport->disc_state = DSC_LOGIN_PEND;
535
+ qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
437536 return qla2x00_post_work(vha, e);
438537 }
439538
440
-static void
441
-qla2x00_async_adisc_sp_done(void *ptr, int res)
539
+static void qla2x00_async_adisc_sp_done(srb_t *sp, int res)
442540 {
443
- srb_t *sp = ptr;
444541 struct scsi_qla_host *vha = sp->vha;
445542 struct event_arg ea;
446543 struct srb_iocb *lio = &sp->u.iocb_cmd;
....@@ -452,7 +549,6 @@
452549 sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
453550
454551 memset(&ea, 0, sizeof(ea));
455
- ea.event = FCME_ADISC_DONE;
456552 ea.rc = res;
457553 ea.data[0] = lio->u.logio.data[0];
458554 ea.data[1] = lio->u.logio.data[1];
....@@ -461,7 +557,7 @@
461557 ea.fcport = sp->fcport;
462558 ea.sp = sp;
463559
464
- qla2x00_fcport_event_handler(vha, &ea);
560
+ qla24xx_handle_adisc_event(vha, &ea);
465561
466562 sp->free(sp);
467563 }
....@@ -472,9 +568,19 @@
472568 {
473569 srb_t *sp;
474570 struct srb_iocb *lio;
475
- int rval;
571
+ int rval = QLA_FUNCTION_FAILED;
476572
477
- rval = QLA_FUNCTION_FAILED;
573
+ if (IS_SESSION_DELETED(fcport)) {
574
+ ql_log(ql_log_warn, vha, 0xffff,
575
+ "%s: %8phC is being delete - not sending command.\n",
576
+ __func__, fcport->port_name);
577
+ fcport->flags &= ~FCF_ASYNC_ACTIVE;
578
+ return rval;
579
+ }
580
+
581
+ if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
582
+ return rval;
583
+
478584 fcport->flags |= FCF_ASYNC_SENT;
479585 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
480586 if (!sp)
....@@ -511,6 +617,72 @@
511617 return rval;
512618 }
513619
620
+static bool qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)
621
+{
622
+ struct qla_hw_data *ha = vha->hw;
623
+
624
+ if (IS_FWI2_CAPABLE(ha))
625
+ return loop_id > NPH_LAST_HANDLE;
626
+
627
+ return (loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
628
+ loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST;
629
+}
630
+
631
+/**
632
+ * qla2x00_find_new_loop_id - scan through our port list and find a new usable loop ID
633
+ * @vha: adapter state pointer.
634
+ * @dev: port structure pointer.
635
+ *
636
+ * Returns:
637
+ * qla2x00 local function return status code.
638
+ *
639
+ * Context:
640
+ * Kernel context.
641
+ */
642
+static int qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
643
+{
644
+ int rval;
645
+ struct qla_hw_data *ha = vha->hw;
646
+ unsigned long flags = 0;
647
+
648
+ rval = QLA_SUCCESS;
649
+
650
+ spin_lock_irqsave(&ha->vport_slock, flags);
651
+
652
+ dev->loop_id = find_first_zero_bit(ha->loop_id_map, LOOPID_MAP_SIZE);
653
+ if (dev->loop_id >= LOOPID_MAP_SIZE ||
654
+ qla2x00_is_reserved_id(vha, dev->loop_id)) {
655
+ dev->loop_id = FC_NO_LOOP_ID;
656
+ rval = QLA_FUNCTION_FAILED;
657
+ } else {
658
+ set_bit(dev->loop_id, ha->loop_id_map);
659
+ }
660
+ spin_unlock_irqrestore(&ha->vport_slock, flags);
661
+
662
+ if (rval == QLA_SUCCESS)
663
+ ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
664
+ "Assigning new loopid=%x, portid=%x.\n",
665
+ dev->loop_id, dev->d_id.b24);
666
+ else
667
+ ql_log(ql_log_warn, dev->vha, 0x2087,
668
+ "No loop_id's available, portid=%x.\n",
669
+ dev->d_id.b24);
670
+
671
+ return rval;
672
+}
673
+
674
+void qla2x00_clear_loop_id(fc_port_t *fcport)
675
+{
676
+ struct qla_hw_data *ha = fcport->vha->hw;
677
+
678
+ if (fcport->loop_id == FC_NO_LOOP_ID ||
679
+ qla2x00_is_reserved_id(fcport->vha, fcport->loop_id))
680
+ return;
681
+
682
+ clear_bit(fcport->loop_id, ha->loop_id_map);
683
+ fcport->loop_id = FC_NO_LOOP_ID;
684
+}
685
+
514686 static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
515687 struct event_arg *ea)
516688 {
....@@ -520,7 +692,7 @@
520692 port_id_t id;
521693 u64 wwn;
522694 u16 data[2];
523
- u8 current_login_state;
695
+ u8 current_login_state, nvme_cls;
524696
525697 fcport = ea->fcport;
526698 ql_dbg(ql_dbg_disc, vha, 0xffff,
....@@ -543,11 +715,8 @@
543715 }
544716
545717 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);
718
+ qla_rscn_replay(fcport);
719
+ qlt_schedule_sess_for_deletion(fcport);
551720 return;
552721 } else if (fcport->last_login_gen != fcport->login_gen) {
553722 ql_dbg(ql_dbg_disc, vha, 0x20e0,
....@@ -582,19 +751,24 @@
582751
583752 loop_id = le16_to_cpu(e->nport_handle);
584753 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;
754
+ nvme_cls = e->current_login_state >> 4;
755
+ current_login_state = e->current_login_state & 0xf;
589756
757
+ if (PRLI_PHASE(nvme_cls)) {
758
+ current_login_state = nvme_cls;
759
+ fcport->fc4_type &= ~FS_FC4TYPE_FCP;
760
+ fcport->fc4_type |= FS_FC4TYPE_NVME;
761
+ } else if (PRLI_PHASE(current_login_state)) {
762
+ fcport->fc4_type |= FS_FC4TYPE_FCP;
763
+ fcport->fc4_type &= ~FS_FC4TYPE_NVME;
764
+ }
590765
591766 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",
767
+ "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n",
593768 __func__, fcport->port_name,
594769 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);
770
+ fcport->fc4_type, id.b24, fcport->d_id.b24,
771
+ loop_id, fcport->loop_id);
598772
599773 switch (fcport->disc_state) {
600774 case DSC_DELETE_PEND:
....@@ -602,12 +776,15 @@
602776 break;
603777 default:
604778 if ((id.b24 != fcport->d_id.b24 &&
605
- fcport->d_id.b24) ||
779
+ fcport->d_id.b24 &&
780
+ fcport->loop_id != FC_NO_LOOP_ID) ||
606781 (fcport->loop_id != FC_NO_LOOP_ID &&
607782 fcport->loop_id != loop_id)) {
608783 ql_dbg(ql_dbg_disc, vha, 0x20e3,
609784 "%s %d %8phC post del sess\n",
610785 __func__, __LINE__, fcport->port_name);
786
+ if (fcport->n2n_flag)
787
+ fcport->d_id.b24 = 0;
611788 qlt_schedule_sess_for_deletion(fcport);
612789 return;
613790 }
....@@ -615,6 +792,8 @@
615792 }
616793
617794 fcport->loop_id = loop_id;
795
+ if (fcport->n2n_flag)
796
+ fcport->d_id.b24 = id.b24;
618797
619798 wwn = wwn_to_u64(fcport->port_name);
620799 qlt_find_sess_invalidate_other(vha, wwn,
....@@ -664,6 +843,16 @@
664843 fcport->fw_login_state = current_login_state;
665844 fcport->d_id = id;
666845 switch (current_login_state) {
846
+ case DSC_LS_PRLI_PEND:
847
+ /*
848
+ * In the middle of PRLI. Let it finish.
849
+ * Allow relogin code to recheck state again
850
+ * with GNL. Push disc_state back to DELETED
851
+ * so GNL can go out again
852
+ */
853
+ qla2x00_set_fcport_disc_state(fcport,
854
+ DSC_DELETED);
855
+ break;
667856 case DSC_LS_PRLI_COMP:
668857 if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
669858 fcport->port_type = FCT_INITIATOR;
....@@ -685,7 +874,7 @@
685874 fcport);
686875 break;
687876 }
688
- /* drop through */
877
+ fallthrough;
689878 default:
690879 if (fcport_is_smaller(fcport)) {
691880 /* local adapter is bigger */
....@@ -738,7 +927,7 @@
738927 qla24xx_fcport_handle_login(vha, fcport);
739928 break;
740929 case ISP_CFG_N:
741
- fcport->disc_state = DSC_DELETED;
930
+ qla2x00_set_fcport_disc_state(fcport, DSC_DELETED);
742931 if (time_after_eq(jiffies, fcport->dm_login_expire)) {
743932 if (fcport->n2n_link_reset_cnt < 2) {
744933 fcport->n2n_link_reset_cnt++;
....@@ -772,16 +961,17 @@
772961 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
773962 }
774963 break;
964
+ case ISP_CFG_NL:
965
+ qla24xx_fcport_handle_login(vha, fcport);
966
+ break;
775967 default:
776968 break;
777969 }
778970 }
779971 } /* gnl_event */
780972
781
-static void
782
-qla24xx_async_gnl_sp_done(void *s, int res)
973
+static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
783974 {
784
- struct srb *sp = s;
785975 struct scsi_qla_host *vha = sp->vha;
786976 unsigned long flags;
787977 struct fc_port *fcport = NULL, *tf;
....@@ -802,7 +992,6 @@
802992 memset(&ea, 0, sizeof(ea));
803993 ea.sp = sp;
804994 ea.rc = res;
805
- ea.event = FCME_GNL_DONE;
806995
807996 if (sp->u.iocb_cmd.u.mbx.in_mb[1] >=
808997 sizeof(struct get_name_list_extended)) {
....@@ -819,9 +1008,9 @@
8191008 set_bit(loop_id, vha->hw->loop_id_map);
8201009 wwn = wwn_to_u64(e->port_name);
8211010
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],
1011
+ ql_dbg(ql_dbg_disc, vha, 0x20e8,
1012
+ "%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n",
1013
+ __func__, &wwn, e->port_id[2], e->port_id[1],
8251014 e->port_id[0], e->current_login_state, e->last_login_state,
8261015 (loop_id & 0x7fff));
8271016 }
....@@ -841,7 +1030,7 @@
8411030 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
8421031 ea.fcport = fcport;
8431032
844
- qla2x00_fcport_event_handler(vha, &ea);
1033
+ qla24xx_handle_gnl_done_event(vha, &ea);
8451034 }
8461035
8471036 /* create new fcport if fw has knowledge of new sessions */
....@@ -872,12 +1061,22 @@
8721061 __func__, __LINE__, (u8 *)&wwn, id.b24);
8731062 wwnn = wwn_to_u64(e->node_name);
8741063 qla24xx_post_newsess_work(vha, &id, (u8 *)&wwn,
875
- (u8 *)&wwnn, NULL, FC4_TYPE_UNKNOWN);
1064
+ (u8 *)&wwnn, NULL, 0);
8761065 }
8771066 }
8781067
8791068 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
8801069 vha->gnl.sent = 0;
1070
+ if (!list_empty(&vha->gnl.fcports)) {
1071
+ /* retrigger gnl */
1072
+ list_for_each_entry_safe(fcport, tf, &vha->gnl.fcports,
1073
+ gnl_entry) {
1074
+ list_del_init(&fcport->gnl_entry);
1075
+ fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
1076
+ if (qla24xx_post_gnl_work(vha, fcport) == QLA_SUCCESS)
1077
+ break;
1078
+ }
1079
+ }
8811080 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
8821081
8831082 sp->free(sp);
....@@ -899,7 +1098,7 @@
8991098
9001099 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
9011100 fcport->flags |= FCF_ASYNC_SENT;
902
- fcport->disc_state = DSC_GNL;
1101
+ qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
9031102 fcport->last_rscn_gen = fcport->rscn_gen;
9041103 fcport->last_login_gen = fcport->login_gen;
9051104
....@@ -936,20 +1135,20 @@
9361135
9371136 sp->done = qla24xx_async_gnl_sp_done;
9381137
939
- rval = qla2x00_start_sp(sp);
940
- if (rval != QLA_SUCCESS)
941
- goto done_free_sp;
942
-
9431138 ql_dbg(ql_dbg_disc, vha, 0x20da,
9441139 "Async-%s - OUT WWPN %8phC hndl %x\n",
9451140 sp->name, fcport->port_name, sp->handle);
1141
+
1142
+ rval = qla2x00_start_sp(sp);
1143
+ if (rval != QLA_SUCCESS)
1144
+ goto done_free_sp;
9461145
9471146 return rval;
9481147
9491148 done_free_sp:
9501149 sp->free(sp);
951
- fcport->flags &= ~FCF_ASYNC_SENT;
9521150 done:
1151
+ fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT);
9531152 return rval;
9541153 }
9551154
....@@ -963,14 +1162,11 @@
9631162
9641163 e->u.fcport.fcport = fcport;
9651164 fcport->flags |= FCF_ASYNC_ACTIVE;
966
- fcport->disc_state = DSC_LOGIN_PEND;
9671165 return qla2x00_post_work(vha, e);
9681166 }
9691167
970
-static
971
-void qla24xx_async_gpdb_sp_done(void *s, int res)
1168
+static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res)
9721169 {
973
- struct srb *sp = s;
9741170 struct scsi_qla_host *vha = sp->vha;
9751171 struct qla_hw_data *ha = vha->hw;
9761172 fc_port_t *fcport = sp->fcport;
....@@ -987,11 +1183,10 @@
9871183 goto done;
9881184
9891185 memset(&ea, 0, sizeof(ea));
990
- ea.event = FCME_GPDB_DONE;
9911186 ea.fcport = fcport;
9921187 ea.sp = sp;
9931188
994
- qla2x00_fcport_event_handler(vha, &ea);
1189
+ qla24xx_handle_gpdb_event(vha, &ea);
9951190
9961191 done:
9971192 dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
....@@ -1004,6 +1199,9 @@
10041199 {
10051200 struct qla_work_evt *e;
10061201
1202
+ if (vha->host->active_mode == MODE_TARGET)
1203
+ return QLA_FUNCTION_FAILED;
1204
+
10071205 e = qla2x00_alloc_work(vha, QLA_EVT_PRLI);
10081206 if (!e)
10091207 return QLA_FUNCTION_FAILED;
....@@ -1013,10 +1211,8 @@
10131211 return qla2x00_post_work(vha, e);
10141212 }
10151213
1016
-static void
1017
-qla2x00_async_prli_sp_done(void *ptr, int res)
1214
+static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
10181215 {
1019
- srb_t *sp = ptr;
10201216 struct scsi_qla_host *vha = sp->vha;
10211217 struct srb_iocb *lio = &sp->u.iocb_cmd;
10221218 struct event_arg ea;
....@@ -1029,7 +1225,6 @@
10291225
10301226 if (!test_bit(UNLOADING, &vha->dpc_flags)) {
10311227 memset(&ea, 0, sizeof(ea));
1032
- ea.event = FCME_PRLI_DONE;
10331228 ea.fcport = sp->fcport;
10341229 ea.data[0] = lio->u.logio.data[0];
10351230 ea.data[1] = lio->u.logio.data[1];
....@@ -1037,7 +1232,7 @@
10371232 ea.iop[1] = lio->u.logio.iop[1];
10381233 ea.sp = sp;
10391234
1040
- qla2x00_fcport_event_handler(vha, &ea);
1235
+ qla24xx_handle_prli_done_event(vha, &ea);
10411236 }
10421237
10431238 sp->free(sp);
....@@ -1050,12 +1245,19 @@
10501245 struct srb_iocb *lio;
10511246 int rval = QLA_FUNCTION_FAILED;
10521247
1053
- if (!vha->flags.online)
1248
+ if (!vha->flags.online) {
1249
+ ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
1250
+ __func__, __LINE__, fcport->port_name);
10541251 return rval;
1252
+ }
10551253
1056
- if (fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
1057
- fcport->fw_login_state == DSC_LS_PRLI_PEND)
1254
+ if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
1255
+ fcport->fw_login_state == DSC_LS_PRLI_PEND) &&
1256
+ qla_dual_mode_enabled(vha)) {
1257
+ ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
1258
+ __func__, __LINE__, fcport->port_name);
10581259 return rval;
1260
+ }
10591261
10601262 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
10611263 if (!sp)
....@@ -1074,8 +1276,14 @@
10741276 sp->done = qla2x00_async_prli_sp_done;
10751277 lio->u.logio.flags = 0;
10761278
1077
- if (fcport->fc4f_nvme)
1279
+ if (NVME_TARGET(vha->hw, fcport))
10781280 lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
1281
+
1282
+ ql_dbg(ql_dbg_disc, vha, 0x211b,
1283
+ "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d fc4type %x priority %x %s.\n",
1284
+ fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
1285
+ fcport->login_retry, fcport->fc4_type, vha->hw->fc4_type_priority,
1286
+ NVME_TARGET(vha->hw, fcport) ? "nvme" : "fcp");
10791287
10801288 rval = qla2x00_start_sp(sp);
10811289 if (rval != QLA_SUCCESS) {
....@@ -1083,11 +1291,6 @@
10831291 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
10841292 goto done_free_sp;
10851293 }
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");
10911294
10921295 return rval;
10931296
....@@ -1121,19 +1324,26 @@
11211324 struct port_database_24xx *pd;
11221325 struct qla_hw_data *ha = vha->hw;
11231326
1124
- if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT) ||
1125
- fcport->loop_id == FC_NO_LOOP_ID) {
1327
+ if (IS_SESSION_DELETED(fcport)) {
11261328 ql_log(ql_log_warn, vha, 0xffff,
1127
- "%s: %8phC - not sending command.\n",
1128
- __func__, fcport->port_name);
1329
+ "%s: %8phC is being delete - not sending command.\n",
1330
+ __func__, fcport->port_name);
1331
+ fcport->flags &= ~FCF_ASYNC_ACTIVE;
11291332 return rval;
11301333 }
11311334
1132
- fcport->disc_state = DSC_GPDB;
1335
+ if (!vha->flags.online || fcport->flags & FCF_ASYNC_SENT) {
1336
+ ql_log(ql_log_warn, vha, 0xffff,
1337
+ "%s: %8phC online %d flags %x - not sending command.\n",
1338
+ __func__, fcport->port_name, vha->flags.online, fcport->flags);
1339
+ goto done;
1340
+ }
11331341
11341342 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
11351343 if (!sp)
11361344 goto done;
1345
+
1346
+ qla2x00_set_fcport_disc_state(fcport, DSC_GPDB);
11371347
11381348 fcport->flags |= FCF_ASYNC_SENT;
11391349 sp->type = SRB_MB_IOCB;
....@@ -1162,7 +1372,7 @@
11621372 mb[9] = vha->vp_idx;
11631373 mb[10] = opt;
11641374
1165
- mbx->u.mbx.in = (void *)pd;
1375
+ mbx->u.mbx.in = pd;
11661376 mbx->u.mbx.in_dma = pd_dma;
11671377
11681378 sp->done = qla24xx_async_gpdb_sp_done;
....@@ -1183,6 +1393,7 @@
11831393 sp->free(sp);
11841394 fcport->flags &= ~FCF_ASYNC_SENT;
11851395 done:
1396
+ fcport->flags &= ~FCF_ASYNC_ACTIVE;
11861397 qla24xx_post_gpdb_work(vha, fcport, opt);
11871398 return rval;
11881399 }
....@@ -1213,7 +1424,7 @@
12131424 ql_dbg(ql_dbg_disc, vha, 0x20d6,
12141425 "%s %d %8phC session revalidate success\n",
12151426 __func__, __LINE__, ea->fcport->port_name);
1216
- ea->fcport->disc_state = DSC_LOGIN_COMPLETE;
1427
+ qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_COMPLETE);
12171428 }
12181429 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
12191430 }
....@@ -1231,17 +1442,30 @@
12311442 fcport->flags &= ~FCF_ASYNC_SENT;
12321443
12331444 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);
1445
+ "%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__,
1446
+ fcport->port_name, fcport->disc_state, pd->current_login_state,
1447
+ fcport->fc4_type, ea->rc);
12371448
12381449 if (fcport->disc_state == DSC_DELETE_PEND)
12391450 return;
12401451
1241
- if (fcport->fc4f_nvme)
1452
+ if (NVME_TARGET(vha->hw, fcport))
12421453 ls = pd->current_login_state >> 4;
12431454 else
12441455 ls = pd->current_login_state & 0xf;
1456
+
1457
+ if (ea->sp->gen2 != fcport->login_gen) {
1458
+ /* target side must have changed it. */
1459
+
1460
+ ql_dbg(ql_dbg_disc, vha, 0x20d3,
1461
+ "%s %8phC generation changed\n",
1462
+ __func__, fcport->port_name);
1463
+ return;
1464
+ } else if (ea->sp->gen1 != fcport->rscn_gen) {
1465
+ qla_rscn_replay(fcport);
1466
+ qlt_schedule_sess_for_deletion(fcport);
1467
+ return;
1468
+ }
12451469
12461470 switch (ls) {
12471471 case PDS_PRLI_COMPLETE:
....@@ -1254,7 +1478,7 @@
12541478 /* Set discovery state back to GNL to Relogin attempt */
12551479 if (qla_dual_mode_enabled(vha) ||
12561480 qla_ini_mode_enabled(vha)) {
1257
- fcport->disc_state = DSC_GNL;
1481
+ qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
12581482 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
12591483 }
12601484 return;
....@@ -1273,6 +1497,11 @@
12731497 {
12741498 u8 login = 0;
12751499 int rc;
1500
+
1501
+ ql_dbg(ql_dbg_disc, vha, 0x307b,
1502
+ "%s %8phC DS %d LS %d lid %d retries=%d\n",
1503
+ __func__, fcport->port_name, fcport->disc_state,
1504
+ fcport->fw_login_state, fcport->loop_id, fcport->login_retry);
12761505
12771506 if (qla_tgt_mode_enabled(vha))
12781507 return;
....@@ -1297,7 +1526,8 @@
12971526 login = 1;
12981527 }
12991528
1300
- if (login) {
1529
+ if (login && fcport->login_retry) {
1530
+ fcport->login_retry--;
13011531 if (fcport->loop_id == FC_NO_LOOP_ID) {
13021532 fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
13031533 rc = qla2x00_find_new_loop_id(vha, fcport);
....@@ -1324,33 +1554,35 @@
13241554 u16 sec;
13251555
13261556 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",
1557
+ "%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d lid %d scan %d\n",
13281558 __func__, fcport->port_name, fcport->disc_state,
13291559 fcport->fw_login_state, fcport->login_pause, fcport->flags,
13301560 fcport->conflict, fcport->last_rscn_gen, fcport->rscn_gen,
1331
- fcport->login_gen, fcport->login_retry,
1332
- fcport->loop_id, fcport->scan_state);
1561
+ fcport->login_gen, fcport->loop_id, fcport->scan_state);
13331562
1334
- if (fcport->scan_state != QLA_FCPORT_FOUND)
1563
+ if (fcport->scan_state != QLA_FCPORT_FOUND ||
1564
+ fcport->disc_state == DSC_DELETE_PEND)
13351565 return 0;
13361566
13371567 if ((fcport->loop_id != FC_NO_LOOP_ID) &&
1568
+ qla_dual_mode_enabled(vha) &&
13381569 ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
13391570 (fcport->fw_login_state == DSC_LS_PRLI_PEND)))
13401571 return 0;
13411572
1342
- if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
1573
+ if (fcport->fw_login_state == DSC_LS_PLOGI_COMP &&
1574
+ !N2N_TOPO(vha->hw)) {
13431575 if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
13441576 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
13451577 return 0;
13461578 }
13471579 }
13481580
1349
- /* for pure Target Mode. Login will not be initiated */
1350
- if (vha->host->active_mode == MODE_TARGET)
1581
+ /* Target won't initiate port login if fabric is present */
1582
+ if (vha->host->active_mode == MODE_TARGET && !N2N_TOPO(vha->hw))
13511583 return 0;
13521584
1353
- if (fcport->flags & FCF_ASYNC_SENT) {
1585
+ if (fcport->flags & (FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE)) {
13541586 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
13551587 return 0;
13561588 }
....@@ -1410,13 +1642,19 @@
14101642 qla24xx_post_gpdb_work(vha, fcport, 0);
14111643 } else {
14121644 ql_dbg(ql_dbg_disc, vha, 0x2118,
1413
- "%s %d %8phC post NVMe PRLI\n",
1414
- __func__, __LINE__, fcport->port_name);
1645
+ "%s %d %8phC post %s PRLI\n",
1646
+ __func__, __LINE__, fcport->port_name,
1647
+ NVME_TARGET(vha->hw, fcport) ? "NVME" :
1648
+ "FC");
14151649 qla24xx_post_prli_work(vha, fcport);
14161650 }
14171651 break;
14181652 default:
14191653 if (fcport->login_pause) {
1654
+ ql_dbg(ql_dbg_disc, vha, 0x20d8,
1655
+ "%s %d %8phC exit\n",
1656
+ __func__, __LINE__,
1657
+ fcport->port_name);
14201658 fcport->last_rscn_gen = fcport->rscn_gen;
14211659 fcport->last_login_gen = fcport->login_gen;
14221660 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
....@@ -1428,22 +1666,14 @@
14281666 break;
14291667
14301668 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);
14351669 if (N2N_TOPO(vha->hw))
14361670 qla_chk_n2n_b4_login(vha, fcport);
14371671 else
1438
- qla24xx_post_gidpn_work(vha, fcport);
1672
+ qlt_schedule_sess_for_deletion(fcport);
14391673 break;
14401674
14411675 case DSC_LOGIN_COMPLETE:
14421676 /* 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--;
14471677 data[0] = data[1] = 0;
14481678 qla2x00_post_async_adisc_work(vha, fcport, data);
14491679 break;
....@@ -1476,33 +1706,11 @@
14761706 return 0;
14771707 }
14781708
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
-
15021709 int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id,
15031710 u8 *port_name, u8 *node_name, void *pla, u8 fc4_type)
15041711 {
15051712 struct qla_work_evt *e;
1713
+
15061714 e = qla2x00_alloc_work(vha, QLA_EVT_NEW_SESS);
15071715 if (!e)
15081716 return QLA_FUNCTION_FAILED;
....@@ -1517,11 +1725,79 @@
15171725 return qla2x00_post_work(vha, e);
15181726 }
15191727
1520
-static
1728
+void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
1729
+{
1730
+ fc_port_t *fcport;
1731
+ unsigned long flags;
1732
+
1733
+ switch (ea->id.b.rsvd_1) {
1734
+ case RSCN_PORT_ADDR:
1735
+ fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
1736
+ if (fcport) {
1737
+ if (fcport->flags & FCF_FCP2_DEVICE &&
1738
+ atomic_read(&fcport->state) == FCS_ONLINE) {
1739
+ ql_dbg(ql_dbg_disc, vha, 0x2115,
1740
+ "Delaying session delete for FCP2 portid=%06x %8phC ",
1741
+ fcport->d_id.b24, fcport->port_name);
1742
+ return;
1743
+ }
1744
+ fcport->scan_needed = 1;
1745
+ fcport->rscn_gen++;
1746
+ }
1747
+ break;
1748
+ case RSCN_AREA_ADDR:
1749
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
1750
+ if (fcport->flags & FCF_FCP2_DEVICE &&
1751
+ atomic_read(&fcport->state) == FCS_ONLINE)
1752
+ continue;
1753
+
1754
+ if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) {
1755
+ fcport->scan_needed = 1;
1756
+ fcport->rscn_gen++;
1757
+ }
1758
+ }
1759
+ break;
1760
+ case RSCN_DOM_ADDR:
1761
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
1762
+ if (fcport->flags & FCF_FCP2_DEVICE &&
1763
+ atomic_read(&fcport->state) == FCS_ONLINE)
1764
+ continue;
1765
+
1766
+ if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) {
1767
+ fcport->scan_needed = 1;
1768
+ fcport->rscn_gen++;
1769
+ }
1770
+ }
1771
+ break;
1772
+ case RSCN_FAB_ADDR:
1773
+ default:
1774
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
1775
+ if (fcport->flags & FCF_FCP2_DEVICE &&
1776
+ atomic_read(&fcport->state) == FCS_ONLINE)
1777
+ continue;
1778
+
1779
+ fcport->scan_needed = 1;
1780
+ fcport->rscn_gen++;
1781
+ }
1782
+ break;
1783
+ }
1784
+
1785
+ spin_lock_irqsave(&vha->work_lock, flags);
1786
+ if (vha->scan.scan_flags == 0) {
1787
+ ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__);
1788
+ vha->scan.scan_flags |= SF_QUEUED;
1789
+ schedule_delayed_work(&vha->scan.scan_work, 5);
1790
+ }
1791
+ spin_unlock_irqrestore(&vha->work_lock, flags);
1792
+}
1793
+
15211794 void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
15221795 struct event_arg *ea)
15231796 {
15241797 fc_port_t *fcport = ea->fcport;
1798
+
1799
+ if (test_bit(UNLOADING, &vha->dpc_flags))
1800
+ return;
15251801
15261802 ql_dbg(ql_dbg_disc, vha, 0x2102,
15271803 "%s %8phC DS %d LS %d P %d del %d cnfl %p rscn %d|%d login %d|%d fl %x\n",
....@@ -1532,146 +1808,49 @@
15321808 fcport->last_login_gen, fcport->login_gen,
15331809 fcport->flags);
15341810
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
-
15461811 if (fcport->last_rscn_gen != fcport->rscn_gen) {
1547
- ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gidpn\n",
1812
+ ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gnl\n",
15481813 __func__, __LINE__, fcport->port_name);
1549
-
1550
- qla24xx_post_gidpn_work(vha, fcport);
1814
+ qla24xx_post_gnl_work(vha, fcport);
15511815 return;
15521816 }
15531817
15541818 qla24xx_fcport_handle_login(vha, fcport);
15551819 }
15561820
1557
-
1558
-void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea)
1821
+void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
1822
+ struct event_arg *ea)
15591823 {
1824
+ /* for pure Target Mode, PRLI will not be initiated */
1825
+ if (vha->host->active_mode == MODE_TARGET)
1826
+ return;
1827
+
15601828 ql_dbg(ql_dbg_disc, vha, 0x2118,
15611829 "%s %d %8phC post PRLI\n",
15621830 __func__, __LINE__, ea->fcport->port_name);
15631831 qla24xx_post_prli_work(vha, ea->fcport);
15641832 }
15651833
1566
-void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
1834
+/*
1835
+ * RSCN(s) came in for this fcport, but the RSCN(s) was not able
1836
+ * to be consumed by the fcport
1837
+ */
1838
+void qla_rscn_replay(fc_port_t *fcport)
15671839 {
1568
- fc_port_t *f, *tf;
1569
- uint32_t id = 0, mask, rid;
1570
- unsigned long flags;
1571
- fc_port_t *fcport;
1840
+ struct event_arg ea;
15721841
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;
1842
+ switch (fcport->disc_state) {
1843
+ case DSC_DELETE_PEND:
1844
+ return;
16721845 default:
1673
- BUG_ON(1);
16741846 break;
1847
+ }
1848
+
1849
+ if (fcport->scan_needed) {
1850
+ memset(&ea, 0, sizeof(ea));
1851
+ ea.id = fcport->d_id;
1852
+ ea.id.b.rsvd_1 = RSCN_PORT_ADDR;
1853
+ qla2x00_handle_rscn(fcport->vha, &ea);
16751854 }
16761855 }
16771856
....@@ -1680,15 +1859,27 @@
16801859 {
16811860 srb_t *sp = data;
16821861 struct srb_iocb *tmf = &sp->u.iocb_cmd;
1862
+ int rc, h;
1863
+ unsigned long flags;
16831864
1684
- tmf->u.tmf.comp_status = CS_TIMEOUT;
1685
- complete(&tmf->u.tmf.comp);
1865
+ rc = qla24xx_async_abort_cmd(sp, false);
1866
+ if (rc) {
1867
+ spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
1868
+ for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
1869
+ if (sp->qpair->req->outstanding_cmds[h] == sp) {
1870
+ sp->qpair->req->outstanding_cmds[h] = NULL;
1871
+ break;
1872
+ }
1873
+ }
1874
+ spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
1875
+ tmf->u.tmf.comp_status = cpu_to_le16(CS_TIMEOUT);
1876
+ tmf->u.tmf.data = QLA_FUNCTION_FAILED;
1877
+ complete(&tmf->u.tmf.comp);
1878
+ }
16861879 }
16871880
1688
-static void
1689
-qla2x00_tmf_sp_done(void *ptr, int res)
1881
+static void qla2x00_tmf_sp_done(srb_t *sp, int res)
16901882 {
1691
- srb_t *sp = ptr;
16921883 struct srb_iocb *tmf = &sp->u.iocb_cmd;
16931884
16941885 complete(&tmf->u.tmf.comp);
....@@ -1742,89 +1933,14 @@
17421933 lun = (uint16_t)tm_iocb->u.tmf.lun;
17431934
17441935 /* Issue Marker IOCB */
1745
- qla2x00_marker(vha, vha->hw->req_q_map[0],
1746
- vha->hw->rsp_q_map[0], fcport->loop_id, lun,
1936
+ qla2x00_marker(vha, vha->hw->base_qpair,
1937
+ fcport->loop_id, lun,
17471938 flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
17481939 }
17491940
17501941 done_free_sp:
17511942 sp->free(sp);
17521943 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);
18281944 done:
18291945 return rval;
18301946 }
....@@ -1836,19 +1952,17 @@
18361952
18371953 uint32_t handle;
18381954 fc_port_t *fcport = sp->fcport;
1955
+ struct qla_qpair *qpair = sp->qpair;
18391956 struct scsi_qla_host *vha = fcport->vha;
1840
- struct qla_hw_data *ha = vha->hw;
1841
- struct req_que *req = vha->req;
1957
+ struct req_que *req = qpair->req;
18421958
1843
- if (vha->flags.qpairs_available && sp->qpair)
1844
- req = sp->qpair->req;
1845
-
1846
- spin_lock_irqsave(&ha->hardware_lock, flags);
1959
+ spin_lock_irqsave(qpair->qp_lock_ptr, flags);
18471960 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
18481961 if (req->outstanding_cmds[handle] == sp)
18491962 break;
18501963 }
1851
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
1964
+ spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
1965
+
18521966 if (handle == req->num_outstanding_cmds) {
18531967 /* Command not found. */
18541968 return QLA_FUNCTION_FAILED;
....@@ -1863,6 +1977,9 @@
18631977 static void
18641978 qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
18651979 {
1980
+ WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
1981
+ ea->data[0]);
1982
+
18661983 switch (ea->data[0]) {
18671984 case MBS_COMMAND_COMPLETE:
18681985 ql_dbg(ql_dbg_disc, vha, 0x2118,
....@@ -1871,6 +1988,12 @@
18711988
18721989 ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
18731990 ea->fcport->logout_on_delete = 1;
1991
+ ea->fcport->nvme_prli_service_param = ea->iop[0];
1992
+ if (ea->iop[0] & NVME_PRLI_SP_FIRST_BURST)
1993
+ ea->fcport->nvme_first_burst_size =
1994
+ (ea->iop[1] & 0xffff) * 512;
1995
+ else
1996
+ ea->fcport->nvme_first_burst_size = 0;
18741997 qla24xx_post_gpdb_work(vha, ea->fcport, 0);
18751998 break;
18761999 default:
....@@ -1881,22 +2004,63 @@
18812004 break;
18822005 }
18832006
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);
2007
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
2008
+ "%s %d %8phC priority %s, fc4type %x\n",
2009
+ __func__, __LINE__, ea->fcport->port_name,
2010
+ vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
2011
+ "FCP" : "NVMe", ea->fcport->fc4_type);
2012
+
2013
+ if (N2N_TOPO(vha->hw)) {
2014
+ if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) {
2015
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
2016
+ ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
2017
+ } else {
2018
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
2019
+ ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
2020
+ }
2021
+
2022
+ if (ea->fcport->n2n_link_reset_cnt < 3) {
2023
+ ea->fcport->n2n_link_reset_cnt++;
2024
+ vha->relogin_jif = jiffies + 2 * HZ;
2025
+ /*
2026
+ * PRLI failed. Reset link to kick start
2027
+ * state machine
2028
+ */
2029
+ set_bit(N2N_LINK_RESET, &vha->dpc_flags);
2030
+ } else {
2031
+ ql_log(ql_log_warn, vha, 0x2119,
2032
+ "%s %d %8phC Unable to reconnect\n",
2033
+ __func__, __LINE__,
2034
+ ea->fcport->port_name);
2035
+ }
2036
+ } else {
2037
+ /*
2038
+ * switch connect. login failed. Take connection down
2039
+ * and allow relogin to retrigger
2040
+ */
2041
+ if (NVME_FCP_TARGET(ea->fcport)) {
2042
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
2043
+ "%s %d %8phC post %s prli\n",
2044
+ __func__, __LINE__,
2045
+ ea->fcport->port_name,
2046
+ (ea->fcport->fc4_type & FS_FC4TYPE_NVME)
2047
+ ? "NVMe" : "FCP");
2048
+ if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
2049
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
2050
+ else
2051
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
2052
+ }
2053
+
2054
+ ea->fcport->flags &= ~FCF_ASYNC_SENT;
2055
+ ea->fcport->keep_nport_handle = 0;
2056
+ ea->fcport->logout_on_delete = 1;
2057
+ qlt_schedule_sess_for_deletion(ea->fcport);
18912058 }
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]);
18952059 break;
18962060 }
18972061 }
18982062
1899
-static void
2063
+void
19002064 qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
19012065 {
19022066 port_id_t cid; /* conflict Nport id */
....@@ -1909,7 +2073,7 @@
19092073 "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d data %x|%x iop %x|%x\n",
19102074 __func__, fcport->port_name, fcport->disc_state,
19112075 fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
1912
- ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1,
2076
+ ea->sp->gen1, fcport->rscn_gen,
19132077 ea->data[0], ea->data[1], ea->iop[0], ea->iop[1]);
19142078
19152079 if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
....@@ -1934,11 +2098,16 @@
19342098 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
19352099 return;
19362100 } 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);
2101
+ ql_dbg(ql_dbg_disc, vha, 0x20d3,
2102
+ "%s %8phC RSCN generation changed\n",
2103
+ __func__, fcport->port_name);
2104
+ qla_rscn_replay(fcport);
2105
+ qlt_schedule_sess_for_deletion(fcport);
19402106 return;
19412107 }
2108
+
2109
+ WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
2110
+ ea->data[0]);
19422111
19432112 switch (ea->data[0]) {
19442113 case MBS_COMMAND_COMPLETE:
....@@ -1947,14 +2116,14 @@
19472116 * force a relogin attempt via implicit LOGO, PLOGI, and PRLI
19482117 * requests.
19492118 */
1950
- if (ea->fcport->fc4f_nvme) {
2119
+ if (NVME_TARGET(vha->hw, ea->fcport)) {
19512120 ql_dbg(ql_dbg_disc, vha, 0x2117,
19522121 "%s %d %8phC post prli\n",
19532122 __func__, __LINE__, ea->fcport->port_name);
19542123 qla24xx_post_prli_work(vha, ea->fcport);
19552124 } else {
19562125 ql_dbg(ql_dbg_disc, vha, 0x20ea,
1957
- "%s %d %8phC LoopID 0x%x in use with %06x. post gnl\n",
2126
+ "%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n",
19582127 __func__, __LINE__, ea->fcport->port_name,
19592128 ea->fcport->loop_id, ea->fcport->d_id.b24);
19602129
....@@ -1973,12 +2142,7 @@
19732142 ql_dbg(ql_dbg_disc, vha, 0x20eb, "%s %d %8phC cmd error %x\n",
19742143 __func__, __LINE__, ea->fcport->port_name, ea->data[1]);
19752144
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);
2145
+ qlt_schedule_sess_for_deletion(ea->fcport);
19822146 break;
19832147 case MBS_LOOP_ID_USED:
19842148 /* data[1] = IO PARAM 1 = nport ID */
....@@ -2015,8 +2179,6 @@
20152179 "%s %d %8phC NPortId %06x inuse with loopid 0x%x. post gidpn\n",
20162180 __func__, __LINE__, ea->fcport->port_name,
20172181 ea->fcport->d_id.b24, lid);
2018
- qla2x00_clear_loop_id(ea->fcport);
2019
- qla24xx_post_gidpn_work(vha, ea->fcport);
20202182 } else {
20212183 ql_dbg(ql_dbg_disc, vha, 0x20ed,
20222184 "%s %d %8phC NPortId %06x inuse with loopid 0x%x. sched delete\n",
....@@ -2027,40 +2189,11 @@
20272189 set_bit(lid, vha->hw->loop_id_map);
20282190 ea->fcport->loop_id = lid;
20292191 ea->fcport->keep_nport_handle = 0;
2192
+ ea->fcport->logout_on_delete = 1;
20302193 qlt_schedule_sess_for_deletion(ea->fcport);
20312194 }
20322195 break;
20332196 }
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
-
20642197 return;
20652198 }
20662199
....@@ -2157,6 +2290,7 @@
21572290 int rval;
21582291 struct qla_hw_data *ha = vha->hw;
21592292 struct req_que *req = ha->req_q_map[0];
2293
+ struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
21602294
21612295 memset(&vha->qla_stats, 0, sizeof(vha->qla_stats));
21622296 memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat));
....@@ -2191,6 +2325,15 @@
21912325
21922326 ha->isp_ops->reset_chip(vha);
21932327
2328
+ /* Check for secure flash support */
2329
+ if (IS_QLA28XX(ha)) {
2330
+ if (rd_reg_word(&reg->mailbox12) & BIT_0)
2331
+ ha->flags.secure_adapter = 1;
2332
+ ql_log(ql_log_info, vha, 0xffff, "Secure Adapter: %s\n",
2333
+ (ha->flags.secure_adapter) ? "Yes" : "No");
2334
+ }
2335
+
2336
+
21942337 rval = qla2xxx_get_flash_info(vha);
21952338 if (rval) {
21962339 ql_log(ql_log_fatal, vha, 0x004f,
....@@ -2213,7 +2356,17 @@
22132356 ql_dbg(ql_dbg_init, vha, 0x0061,
22142357 "Configure NVRAM parameters...\n");
22152358
2359
+ /* Let priority default to FCP, can be overridden by nvram_config */
2360
+ ha->fc4_type_priority = FC4_PRIORITY_FCP;
2361
+
22162362 ha->isp_ops->nvram_config(vha);
2363
+
2364
+ if (ha->fc4_type_priority != FC4_PRIORITY_FCP &&
2365
+ ha->fc4_type_priority != FC4_PRIORITY_NVME)
2366
+ ha->fc4_type_priority = FC4_PRIORITY_FCP;
2367
+
2368
+ ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n",
2369
+ ha->fc4_type_priority == FC4_PRIORITY_FCP ? "FCP" : "NVMe");
22172370
22182371 if (ha->flags.disable_serdes) {
22192372 /* Mask HBA via NVRAM settings? */
....@@ -2224,6 +2377,12 @@
22242377
22252378 ql_dbg(ql_dbg_init, vha, 0x0078,
22262379 "Verifying loaded RISC code...\n");
2380
+
2381
+ /* If smartsan enabled then require fdmi and rdp enabled */
2382
+ if (ql2xsmartsan) {
2383
+ ql2xfdmienable = 1;
2384
+ ql2xrdpenable = 1;
2385
+ }
22272386
22282387 if (qla2x00_isp_firmware(vha) != QLA_SUCCESS) {
22292388 rval = ha->isp_ops->chip_diag(vha);
....@@ -2245,6 +2404,10 @@
22452404
22462405 if (qla_ini_mode_enabled(vha) || qla_dual_mode_enabled(vha))
22472406 rval = qla2x00_init_rings(vha);
2407
+
2408
+ /* No point in continuing if firmware initialization failed. */
2409
+ if (rval != QLA_SUCCESS)
2410
+ return rval;
22482411
22492412 ha->flags.chip_reset_done = 1;
22502413
....@@ -2302,7 +2465,7 @@
23022465
23032466 /* Get PCI bus information. */
23042467 spin_lock_irqsave(&ha->hardware_lock, flags);
2305
- ha->pci_attr = RD_REG_WORD(&reg->ctrl_status);
2468
+ ha->pci_attr = rd_reg_word(&reg->ctrl_status);
23062469 spin_unlock_irqrestore(&ha->hardware_lock, flags);
23072470
23082471 return QLA_SUCCESS;
....@@ -2344,17 +2507,17 @@
23442507 spin_lock_irqsave(&ha->hardware_lock, flags);
23452508
23462509 /* Pause RISC. */
2347
- WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
2510
+ wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
23482511 for (cnt = 0; cnt < 30000; cnt++) {
2349
- if ((RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) != 0)
2512
+ if ((rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) != 0)
23502513 break;
23512514
23522515 udelay(10);
23532516 }
23542517
23552518 /* Select FPM registers. */
2356
- WRT_REG_WORD(&reg->ctrl_status, 0x20);
2357
- RD_REG_WORD(&reg->ctrl_status);
2519
+ wrt_reg_word(&reg->ctrl_status, 0x20);
2520
+ rd_reg_word(&reg->ctrl_status);
23582521
23592522 /* Get the fb rev level */
23602523 ha->fb_rev = RD_FB_CMD_REG(ha, reg);
....@@ -2363,13 +2526,13 @@
23632526 pci_clear_mwi(ha->pdev);
23642527
23652528 /* Deselect FPM registers. */
2366
- WRT_REG_WORD(&reg->ctrl_status, 0x0);
2367
- RD_REG_WORD(&reg->ctrl_status);
2529
+ wrt_reg_word(&reg->ctrl_status, 0x0);
2530
+ rd_reg_word(&reg->ctrl_status);
23682531
23692532 /* Release RISC module. */
2370
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
2533
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
23712534 for (cnt = 0; cnt < 30000; cnt++) {
2372
- if ((RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0)
2535
+ if ((rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) == 0)
23732536 break;
23742537
23752538 udelay(10);
....@@ -2384,7 +2547,7 @@
23842547
23852548 /* Get PCI bus information. */
23862549 spin_lock_irqsave(&ha->hardware_lock, flags);
2387
- ha->pci_attr = RD_REG_WORD(&reg->ctrl_status);
2550
+ ha->pci_attr = rd_reg_word(&reg->ctrl_status);
23882551 spin_unlock_irqrestore(&ha->hardware_lock, flags);
23892552
23902553 return QLA_SUCCESS;
....@@ -2428,7 +2591,7 @@
24282591
24292592 /* Get PCI bus information. */
24302593 spin_lock_irqsave(&ha->hardware_lock, flags);
2431
- ha->pci_attr = RD_REG_DWORD(&reg->ctrl_status);
2594
+ ha->pci_attr = rd_reg_dword(&reg->ctrl_status);
24322595 spin_unlock_irqrestore(&ha->hardware_lock, flags);
24332596
24342597 return QLA_SUCCESS;
....@@ -2507,7 +2670,7 @@
25072670 *
25082671 * Returns 0 on success.
25092672 */
2510
-void
2673
+int
25112674 qla2x00_reset_chip(scsi_qla_host_t *vha)
25122675 {
25132676 unsigned long flags = 0;
....@@ -2515,9 +2678,10 @@
25152678 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
25162679 uint32_t cnt;
25172680 uint16_t cmd;
2681
+ int rval = QLA_FUNCTION_FAILED;
25182682
25192683 if (unlikely(pci_channel_offline(ha->pdev)))
2520
- return;
2684
+ return rval;
25212685
25222686 ha->isp_ops->disable_intrs(ha);
25232687
....@@ -2531,36 +2695,36 @@
25312695
25322696 if (!IS_QLA2100(ha)) {
25332697 /* Pause RISC. */
2534
- WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
2698
+ wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
25352699 if (IS_QLA2200(ha) || IS_QLA2300(ha)) {
25362700 for (cnt = 0; cnt < 30000; cnt++) {
2537
- if ((RD_REG_WORD(&reg->hccr) &
2701
+ if ((rd_reg_word(&reg->hccr) &
25382702 HCCR_RISC_PAUSE) != 0)
25392703 break;
25402704 udelay(100);
25412705 }
25422706 } else {
2543
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2707
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
25442708 udelay(10);
25452709 }
25462710
25472711 /* Select FPM registers. */
2548
- WRT_REG_WORD(&reg->ctrl_status, 0x20);
2549
- RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
2712
+ wrt_reg_word(&reg->ctrl_status, 0x20);
2713
+ rd_reg_word(&reg->ctrl_status); /* PCI Posting. */
25502714
25512715 /* FPM Soft Reset. */
2552
- WRT_REG_WORD(&reg->fpm_diag_config, 0x100);
2553
- RD_REG_WORD(&reg->fpm_diag_config); /* PCI Posting. */
2716
+ wrt_reg_word(&reg->fpm_diag_config, 0x100);
2717
+ rd_reg_word(&reg->fpm_diag_config); /* PCI Posting. */
25542718
25552719 /* Toggle Fpm Reset. */
25562720 if (!IS_QLA2200(ha)) {
2557
- WRT_REG_WORD(&reg->fpm_diag_config, 0x0);
2558
- RD_REG_WORD(&reg->fpm_diag_config); /* PCI Posting. */
2721
+ wrt_reg_word(&reg->fpm_diag_config, 0x0);
2722
+ rd_reg_word(&reg->fpm_diag_config); /* PCI Posting. */
25592723 }
25602724
25612725 /* Select frame buffer registers. */
2562
- WRT_REG_WORD(&reg->ctrl_status, 0x10);
2563
- RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
2726
+ wrt_reg_word(&reg->ctrl_status, 0x10);
2727
+ rd_reg_word(&reg->ctrl_status); /* PCI Posting. */
25642728
25652729 /* Reset frame buffer FIFOs. */
25662730 if (IS_QLA2200(ha)) {
....@@ -2578,23 +2742,23 @@
25782742 }
25792743
25802744 /* Select RISC module registers. */
2581
- WRT_REG_WORD(&reg->ctrl_status, 0);
2582
- RD_REG_WORD(&reg->ctrl_status); /* PCI Posting. */
2745
+ wrt_reg_word(&reg->ctrl_status, 0);
2746
+ rd_reg_word(&reg->ctrl_status); /* PCI Posting. */
25832747
25842748 /* Reset RISC processor. */
2585
- WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
2586
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2749
+ wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
2750
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
25872751
25882752 /* Release RISC processor. */
2589
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
2590
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2753
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
2754
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
25912755 }
25922756
2593
- WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
2594
- WRT_REG_WORD(&reg->hccr, HCCR_CLR_HOST_INT);
2757
+ wrt_reg_word(&reg->hccr, HCCR_CLR_RISC_INT);
2758
+ wrt_reg_word(&reg->hccr, HCCR_CLR_HOST_INT);
25952759
25962760 /* Reset ISP chip. */
2597
- WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
2761
+ wrt_reg_word(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
25982762
25992763 /* Wait for RISC to recover from reset. */
26002764 if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
....@@ -2605,7 +2769,7 @@
26052769 */
26062770 udelay(20);
26072771 for (cnt = 30000; cnt; cnt--) {
2608
- if ((RD_REG_WORD(&reg->ctrl_status) &
2772
+ if ((rd_reg_word(&reg->ctrl_status) &
26092773 CSR_ISP_SOFT_RESET) == 0)
26102774 break;
26112775 udelay(100);
....@@ -2614,13 +2778,13 @@
26142778 udelay(10);
26152779
26162780 /* Reset RISC processor. */
2617
- WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
2781
+ wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
26182782
2619
- WRT_REG_WORD(&reg->semaphore, 0);
2783
+ wrt_reg_word(&reg->semaphore, 0);
26202784
26212785 /* Release RISC processor. */
2622
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
2623
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2786
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
2787
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
26242788
26252789 if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
26262790 for (cnt = 0; cnt < 30000; cnt++) {
....@@ -2638,11 +2802,13 @@
26382802
26392803 /* Disable RISC pause on FPM parity error. */
26402804 if (!IS_QLA2100(ha)) {
2641
- WRT_REG_WORD(&reg->hccr, HCCR_DISABLE_PARITY_PAUSE);
2642
- RD_REG_WORD(&reg->hccr); /* PCI Posting. */
2805
+ wrt_reg_word(&reg->hccr, HCCR_DISABLE_PARITY_PAUSE);
2806
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
26432807 }
26442808
26452809 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2810
+
2811
+ return QLA_SUCCESS;
26462812 }
26472813
26482814 /**
....@@ -2682,32 +2848,32 @@
26822848 spin_lock_irqsave(&ha->hardware_lock, flags);
26832849
26842850 /* Reset RISC. */
2685
- WRT_REG_DWORD(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
2851
+ wrt_reg_dword(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
26862852 for (cnt = 0; cnt < 30000; cnt++) {
2687
- if ((RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
2853
+ if ((rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
26882854 break;
26892855
26902856 udelay(10);
26912857 }
26922858
2693
- if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
2859
+ if (!(rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
26942860 set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
26952861
26962862 ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017e,
26972863 "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));
2864
+ rd_reg_dword(&reg->hccr),
2865
+ rd_reg_dword(&reg->ctrl_status),
2866
+ (rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE));
27012867
2702
- WRT_REG_DWORD(&reg->ctrl_status,
2868
+ wrt_reg_dword(&reg->ctrl_status,
27032869 CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
27042870 pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
27052871
27062872 udelay(100);
27072873
27082874 /* Wait for firmware to complete NVRAM accesses. */
2709
- RD_REG_WORD(&reg->mailbox0);
2710
- for (cnt = 10000; RD_REG_WORD(&reg->mailbox0) != 0 &&
2875
+ rd_reg_word(&reg->mailbox0);
2876
+ for (cnt = 10000; rd_reg_word(&reg->mailbox0) != 0 &&
27112877 rval == QLA_SUCCESS; cnt--) {
27122878 barrier();
27132879 if (cnt)
....@@ -2721,26 +2887,26 @@
27212887
27222888 ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017f,
27232889 "HCCR: 0x%x, MailBox0 Status 0x%x\n",
2724
- RD_REG_DWORD(&reg->hccr),
2725
- RD_REG_DWORD(&reg->mailbox0));
2890
+ rd_reg_dword(&reg->hccr),
2891
+ rd_reg_word(&reg->mailbox0));
27262892
27272893 /* Wait for soft-reset to complete. */
2728
- RD_REG_DWORD(&reg->ctrl_status);
2894
+ rd_reg_dword(&reg->ctrl_status);
27292895 for (cnt = 0; cnt < 60; cnt++) {
27302896 barrier();
2731
- if ((RD_REG_DWORD(&reg->ctrl_status) &
2897
+ if ((rd_reg_dword(&reg->ctrl_status) &
27322898 CSRX_ISP_SOFT_RESET) == 0)
27332899 break;
27342900
27352901 udelay(5);
27362902 }
2737
- if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
2903
+ if (!(rd_reg_dword(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
27382904 set_bit(ISP_SOFT_RESET_CMPL, &ha->fw_dump_cap_flags);
27392905
27402906 ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015d,
27412907 "HCCR: 0x%x, Soft Reset status: 0x%x\n",
2742
- RD_REG_DWORD(&reg->hccr),
2743
- RD_REG_DWORD(&reg->ctrl_status));
2908
+ rd_reg_dword(&reg->hccr),
2909
+ rd_reg_dword(&reg->ctrl_status));
27442910
27452911 /* If required, do an MPI FW reset now */
27462912 if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) {
....@@ -2759,17 +2925,17 @@
27592925 }
27602926 }
27612927
2762
- WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
2763
- RD_REG_DWORD(&reg->hccr);
2928
+ wrt_reg_dword(&reg->hccr, HCCRX_SET_RISC_RESET);
2929
+ rd_reg_dword(&reg->hccr);
27642930
2765
- WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
2766
- RD_REG_DWORD(&reg->hccr);
2931
+ wrt_reg_dword(&reg->hccr, HCCRX_REL_RISC_PAUSE);
2932
+ rd_reg_dword(&reg->hccr);
27672933
2768
- WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
2769
- RD_REG_DWORD(&reg->hccr);
2934
+ wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_RESET);
2935
+ rd_reg_dword(&reg->hccr);
27702936
2771
- RD_REG_WORD(&reg->mailbox0);
2772
- for (cnt = 60; RD_REG_WORD(&reg->mailbox0) != 0 &&
2937
+ rd_reg_word(&reg->mailbox0);
2938
+ for (cnt = 60; rd_reg_word(&reg->mailbox0) != 0 &&
27732939 rval == QLA_SUCCESS; cnt--) {
27742940 barrier();
27752941 if (cnt)
....@@ -2782,8 +2948,8 @@
27822948
27832949 ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015e,
27842950 "Host Risc 0x%x, mailbox0 0x%x\n",
2785
- RD_REG_DWORD(&reg->hccr),
2786
- RD_REG_WORD(&reg->mailbox0));
2951
+ rd_reg_dword(&reg->hccr),
2952
+ rd_reg_word(&reg->mailbox0));
27872953
27882954 spin_unlock_irqrestore(&ha->hardware_lock, flags);
27892955
....@@ -2802,9 +2968,8 @@
28022968 {
28032969 struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
28042970
2805
- WRT_REG_DWORD(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
2806
- *data = RD_REG_DWORD(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFET);
2807
-
2971
+ wrt_reg_dword(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
2972
+ *data = rd_reg_dword(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFSET);
28082973 }
28092974
28102975 static void
....@@ -2812,8 +2977,8 @@
28122977 {
28132978 struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
28142979
2815
- WRT_REG_DWORD(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
2816
- WRT_REG_DWORD(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFET, data);
2980
+ wrt_reg_dword(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
2981
+ wrt_reg_dword(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFSET, data);
28172982 }
28182983
28192984 static void
....@@ -2829,7 +2994,7 @@
28292994 vha->hw->pdev->subsystem_device != 0x0240)
28302995 return;
28312996
2832
- WRT_REG_DWORD(&vha->hw->iobase->isp24.hccr, HCCRX_SET_RISC_PAUSE);
2997
+ wrt_reg_dword(&vha->hw->iobase->isp24.hccr, HCCRX_SET_RISC_PAUSE);
28332998 udelay(100);
28342999
28353000 attempt:
....@@ -2883,14 +3048,15 @@
28833048 *
28843049 * Returns 0 on success.
28853050 */
2886
-void
3051
+int
28873052 qla24xx_reset_chip(scsi_qla_host_t *vha)
28883053 {
28893054 struct qla_hw_data *ha = vha->hw;
3055
+ int rval = QLA_FUNCTION_FAILED;
28903056
28913057 if (pci_channel_offline(ha->pdev) &&
28923058 ha->flags.pci_channel_io_perm_failure) {
2893
- return;
3059
+ return rval;
28943060 }
28953061
28963062 ha->isp_ops->disable_intrs(ha);
....@@ -2898,7 +3064,9 @@
28983064 qla25xx_manipulate_risc_semaphore(vha);
28993065
29003066 /* Perform RISC reset. */
2901
- qla24xx_reset_risc(vha);
3067
+ rval = qla24xx_reset_risc(vha);
3068
+
3069
+ return rval;
29023070 }
29033071
29043072 /**
....@@ -2928,7 +3096,7 @@
29283096 spin_lock_irqsave(&ha->hardware_lock, flags);
29293097
29303098 /* Reset ISP chip. */
2931
- WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
3099
+ wrt_reg_word(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
29323100
29333101 /*
29343102 * We need to have a delay here since the card will not respond while
....@@ -2938,7 +3106,7 @@
29383106 data = qla2x00_debounce_register(&reg->ctrl_status);
29393107 for (cnt = 6000000 ; cnt && (data & CSR_ISP_SOFT_RESET); cnt--) {
29403108 udelay(5);
2941
- data = RD_REG_WORD(&reg->ctrl_status);
3109
+ data = rd_reg_word(&reg->ctrl_status);
29423110 barrier();
29433111 }
29443112
....@@ -2949,8 +3117,8 @@
29493117 "Reset register cleared by chip reset.\n");
29503118
29513119 /* Reset RISC processor. */
2952
- WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
2953
- WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
3120
+ wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
3121
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
29543122
29553123 /* Workaround for QLA2312 PCI parity error */
29563124 if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
....@@ -3056,89 +3224,102 @@
30563224 }
30573225
30583226 static void
3059
-qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
3227
+qla2x00_init_fce_trace(scsi_qla_host_t *vha)
30603228 {
30613229 int rval;
30623230 dma_addr_t tc_dma;
30633231 void *tc;
30643232 struct qla_hw_data *ha = vha->hw;
30653233
3234
+ if (!IS_FWI2_CAPABLE(ha))
3235
+ return;
3236
+
3237
+ if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
3238
+ !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
3239
+ return;
3240
+
3241
+ if (ha->fce) {
3242
+ ql_dbg(ql_dbg_init, vha, 0x00bd,
3243
+ "%s: FCE Mem is already allocated.\n",
3244
+ __func__);
3245
+ return;
3246
+ }
3247
+
3248
+ /* Allocate memory for Fibre Channel Event Buffer. */
3249
+ tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
3250
+ GFP_KERNEL);
3251
+ if (!tc) {
3252
+ ql_log(ql_log_warn, vha, 0x00be,
3253
+ "Unable to allocate (%d KB) for FCE.\n",
3254
+ FCE_SIZE / 1024);
3255
+ return;
3256
+ }
3257
+
3258
+ rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS,
3259
+ ha->fce_mb, &ha->fce_bufs);
3260
+ if (rval) {
3261
+ ql_log(ql_log_warn, vha, 0x00bf,
3262
+ "Unable to initialize FCE (%d).\n", rval);
3263
+ dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma);
3264
+ return;
3265
+ }
3266
+
3267
+ ql_dbg(ql_dbg_init, vha, 0x00c0,
3268
+ "Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024);
3269
+
3270
+ ha->flags.fce_enabled = 1;
3271
+ ha->fce_dma = tc_dma;
3272
+ ha->fce = tc;
3273
+}
3274
+
3275
+static void
3276
+qla2x00_init_eft_trace(scsi_qla_host_t *vha)
3277
+{
3278
+ int rval;
3279
+ dma_addr_t tc_dma;
3280
+ void *tc;
3281
+ struct qla_hw_data *ha = vha->hw;
3282
+
3283
+ if (!IS_FWI2_CAPABLE(ha))
3284
+ return;
3285
+
30663286 if (ha->eft) {
30673287 ql_dbg(ql_dbg_init, vha, 0x00bd,
3068
- "%s: Offload Mem is already allocated.\n",
3288
+ "%s: EFT Mem is already allocated.\n",
30693289 __func__);
30703290 return;
30713291 }
30723292
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;
3293
+ /* Allocate memory for Extended Trace Buffer. */
3294
+ tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
3295
+ GFP_KERNEL);
3296
+ if (!tc) {
3297
+ ql_log(ql_log_warn, vha, 0x00c1,
3298
+ "Unable to allocate (%d KB) for EFT.\n",
3299
+ EFT_SIZE / 1024);
3300
+ return;
31383301 }
31393302
3140
-eft_err:
3141
- return;
3303
+ rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
3304
+ if (rval) {
3305
+ ql_log(ql_log_warn, vha, 0x00c2,
3306
+ "Unable to initialize EFT (%d).\n", rval);
3307
+ dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, tc_dma);
3308
+ return;
3309
+ }
3310
+
3311
+ ql_dbg(ql_dbg_init, vha, 0x00c3,
3312
+ "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
3313
+
3314
+ ha->eft_dma = tc_dma;
3315
+ ha->eft = tc;
3316
+}
3317
+
3318
+static void
3319
+qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
3320
+{
3321
+ qla2x00_init_fce_trace(vha);
3322
+ qla2x00_init_eft_trace(vha);
31423323 }
31433324
31443325 void
....@@ -3151,6 +3332,14 @@
31513332 struct rsp_que *rsp = ha->rsp_q_map[0];
31523333 struct qla2xxx_fw_dump *fw_dump;
31533334
3335
+ if (ha->fw_dump) {
3336
+ ql_dbg(ql_dbg_init, vha, 0x00bd,
3337
+ "Firmware dump already allocated.\n");
3338
+ return;
3339
+ }
3340
+
3341
+ ha->fw_dumped = 0;
3342
+ ha->fw_dump_cap_flags = 0;
31543343 dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
31553344 req_q_size = rsp_q_size = 0;
31563345
....@@ -3161,7 +3350,7 @@
31613350 mem_size = (ha->fw_memory_size - 0x11000 + 1) *
31623351 sizeof(uint16_t);
31633352 } else if (IS_FWI2_CAPABLE(ha)) {
3164
- if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
3353
+ if (IS_QLA83XX(ha))
31653354 fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem);
31663355 else if (IS_QLA81XX(ha))
31673356 fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem);
....@@ -3173,94 +3362,127 @@
31733362 mem_size = (ha->fw_memory_size - 0x100000 + 1) *
31743363 sizeof(uint32_t);
31753364 if (ha->mqenable) {
3176
- if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
3365
+ if (!IS_QLA83XX(ha))
31773366 mq_size = sizeof(struct qla2xxx_mq_chain);
31783367 /*
3179
- * Allocate maximum buffer size for all queues.
3368
+ * Allocate maximum buffer size for all queues - Q0.
31803369 * Resizing must be done at end-of-dump processing.
31813370 */
3182
- mq_size += ha->max_req_queues *
3371
+ mq_size += (ha->max_req_queues - 1) *
31833372 (req->length * sizeof(request_t));
3184
- mq_size += ha->max_rsp_queues *
3373
+ mq_size += (ha->max_rsp_queues - 1) *
31853374 (rsp->length * sizeof(response_t));
31863375 }
31873376 if (ha->tgt.atio_ring)
31883377 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;
31933378
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;
3379
+ qla2x00_init_fce_trace(vha);
3380
+ if (ha->fce)
3381
+ fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
3382
+ qla2x00_init_eft_trace(vha);
3383
+ if (ha->eft)
3384
+ eft_size = EFT_SIZE;
31993385 }
32003386
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;
3387
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
3388
+ struct fwdt *fwdt = ha->fwdt;
3389
+ uint j;
3390
+
3391
+ for (j = 0; j < 2; j++, fwdt++) {
3392
+ if (!fwdt->template) {
3393
+ ql_dbg(ql_dbg_init, vha, 0x00ba,
3394
+ "-> fwdt%u no template\n", j);
3395
+ continue;
3396
+ }
3397
+ ql_dbg(ql_dbg_init, vha, 0x00fa,
3398
+ "-> fwdt%u calculating fwdump size...\n", j);
3399
+ fwdt->dump_size = qla27xx_fwdt_calculate_dump_size(
3400
+ vha, fwdt->template);
3401
+ ql_dbg(ql_dbg_init, vha, 0x00fa,
3402
+ "-> fwdt%u calculated fwdump size = %#lx bytes\n",
3403
+ j, fwdt->dump_size);
3404
+ dump_size += fwdt->dump_size;
32063405 }
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;
3406
+ /* Add space for spare MPI fw dump. */
3407
+ dump_size += ha->fwdt[1].dump_size;
3408
+ } else {
3409
+ req_q_size = req->length * sizeof(request_t);
3410
+ rsp_q_size = rsp->length * sizeof(response_t);
3411
+ dump_size = offsetof(struct qla2xxx_fw_dump, isp);
3412
+ dump_size += fixed_size + mem_size + req_q_size + rsp_q_size
3413
+ + eft_size;
3414
+ ha->chain_offset = dump_size;
3415
+ dump_size += mq_size + fce_size;
3416
+ if (ha->exchoffld_buf)
3417
+ dump_size += sizeof(struct qla2xxx_offld_chain) +
3418
+ ha->exchoffld_size;
3419
+ if (ha->exlogin_buf)
3420
+ dump_size += sizeof(struct qla2xxx_offld_chain) +
3421
+ ha->exlogin_size;
32113422 }
32123423
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;
3424
+ if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) {
32193425
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;
3426
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
3427
+ "%s dump_size %d fw_dump_len %d fw_dump_alloc_len %d\n",
3428
+ __func__, dump_size, ha->fw_dump_len,
3429
+ ha->fw_dump_alloc_len);
32263430
3227
-allocate:
3228
- if (!ha->fw_dump_len || dump_size != ha->fw_dump_len) {
32293431 fw_dump = vmalloc(dump_size);
32303432 if (!fw_dump) {
32313433 ql_log(ql_log_warn, vha, 0x00c4,
32323434 "Unable to allocate (%d KB) for firmware dump.\n",
32333435 dump_size / 1024);
32343436 } else {
3235
- if (ha->fw_dump)
3437
+ mutex_lock(&ha->optrom_mutex);
3438
+ if (ha->fw_dumped) {
3439
+ memcpy(fw_dump, ha->fw_dump, ha->fw_dump_len);
32363440 vfree(ha->fw_dump);
3237
- ha->fw_dump = fw_dump;
3441
+ ha->fw_dump = fw_dump;
3442
+ ha->fw_dump_alloc_len = dump_size;
3443
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
3444
+ "Re-Allocated (%d KB) and save firmware dump.\n",
3445
+ dump_size / 1024);
3446
+ } else {
3447
+ if (ha->fw_dump)
3448
+ vfree(ha->fw_dump);
3449
+ ha->fw_dump = fw_dump;
32383450
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);
3451
+ ha->fw_dump_len = ha->fw_dump_alloc_len =
3452
+ dump_size;
3453
+ ql_dbg(ql_dbg_init, vha, 0x00c5,
3454
+ "Allocated (%d KB) for firmware dump.\n",
3455
+ dump_size / 1024);
32433456
3244
- if (IS_QLA27XX(ha))
3245
- return;
3457
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
3458
+ ha->mpi_fw_dump = (char *)fw_dump +
3459
+ ha->fwdt[1].dump_size;
3460
+ mutex_unlock(&ha->optrom_mutex);
3461
+ return;
3462
+ }
32463463
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);
3464
+ ha->fw_dump->signature[0] = 'Q';
3465
+ ha->fw_dump->signature[1] = 'L';
3466
+ ha->fw_dump->signature[2] = 'G';
3467
+ ha->fw_dump->signature[3] = 'C';
3468
+ ha->fw_dump->version = htonl(1);
32523469
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);
3470
+ ha->fw_dump->fixed_size = htonl(fixed_size);
3471
+ ha->fw_dump->mem_size = htonl(mem_size);
3472
+ ha->fw_dump->req_q_size = htonl(req_q_size);
3473
+ ha->fw_dump->rsp_q_size = htonl(rsp_q_size);
32573474
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));
3475
+ ha->fw_dump->eft_size = htonl(eft_size);
3476
+ ha->fw_dump->eft_addr_l =
3477
+ htonl(LSD(ha->eft_dma));
3478
+ ha->fw_dump->eft_addr_h =
3479
+ htonl(MSD(ha->eft_dma));
32613480
3262
- ha->fw_dump->header_size =
3263
- htonl(offsetof(struct qla2xxx_fw_dump, isp));
3481
+ ha->fw_dump->header_size =
3482
+ htonl(offsetof
3483
+ (struct qla2xxx_fw_dump, isp));
3484
+ }
3485
+ mutex_unlock(&ha->optrom_mutex);
32643486 }
32653487 }
32663488 }
....@@ -3446,53 +3668,100 @@
34463668 }
34473669
34483670
3449
-/*
3450
- * Return Code:
3451
- * QLA_SUCCESS: no action
3452
- * QLA_INTERFACE_ERROR: SFP is not there.
3453
- * QLA_FUNCTION_FAILED: detected New SFP
3671
+/**
3672
+ * qla24xx_detect_sfp()
3673
+ *
3674
+ * @vha: adapter state pointer.
3675
+ *
3676
+ * @return
3677
+ * 0 -- Configure firmware to use short-range settings -- normal
3678
+ * buffer-to-buffer credits.
3679
+ *
3680
+ * 1 -- Configure firmware to use long-range settings -- extra
3681
+ * buffer-to-buffer credits should be allocated with
3682
+ * ha->lr_distance containing distance settings from NVRAM or SFP
3683
+ * (if supported).
34543684 */
34553685 int
34563686 qla24xx_detect_sfp(scsi_qla_host_t *vha)
34573687 {
3458
- int rc = QLA_SUCCESS;
3688
+ int rc, used_nvram;
34593689 struct sff_8247_a0 *a;
34603690 struct qla_hw_data *ha = vha->hw;
3691
+ struct nvram_81xx *nv = ha->nvram;
3692
+#define LR_DISTANCE_UNKNOWN 2
3693
+ static const char * const types[] = { "Short", "Long" };
3694
+ static const char * const lengths[] = { "(10km)", "(5km)", "" };
3695
+ u8 ll = 0;
34613696
3462
- if (!AUTO_DETECT_SFP_SUPPORT(vha))
3697
+ /* Seed with NVRAM settings. */
3698
+ used_nvram = 0;
3699
+ ha->flags.lr_detected = 0;
3700
+ if (IS_BPM_RANGE_CAPABLE(ha) &&
3701
+ (nv->enhanced_features & NEF_LR_DIST_ENABLE)) {
3702
+ used_nvram = 1;
3703
+ ha->flags.lr_detected = 1;
3704
+ ha->lr_distance =
3705
+ (nv->enhanced_features >> LR_DIST_NV_POS)
3706
+ & LR_DIST_NV_MASK;
3707
+ }
3708
+
3709
+ if (!IS_BPM_ENABLED(vha))
34633710 goto out;
3464
-
3711
+ /* Determine SR/LR capabilities of SFP/Transceiver. */
34653712 rc = qla2x00_read_sfp_dev(vha, NULL, 0);
34663713 if (rc)
34673714 goto out;
34683715
3716
+ used_nvram = 0;
34693717 a = (struct sff_8247_a0 *)vha->hw->sfp_data;
34703718 qla2xxx_print_sfp_info(vha);
34713719
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;
3720
+ ha->flags.lr_detected = 0;
3721
+ ll = a->fc_ll_cc7;
3722
+ if (ll & FC_LL_VL || ll & FC_LL_L) {
3723
+ /* Long range, track length. */
3724
+ ha->flags.lr_detected = 1;
34753725
34763726 if (a->length_km > 5 || a->length_100m > 50)
3477
- ha->long_range_distance = LR_DISTANCE_10K;
3727
+ ha->lr_distance = LR_DISTANCE_10K;
34783728 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");
3729
+ ha->lr_distance = LR_DISTANCE_5K;
34903730 }
34913731
3492
- if (!vha->flags.init_done)
3493
- rc = QLA_SUCCESS;
34943732 out:
3495
- return rc;
3733
+ ql_dbg(ql_dbg_async, vha, 0x507b,
3734
+ "SFP detect: %s-Range SFP %s (nvr=%x ll=%x lr=%x lrd=%x).\n",
3735
+ types[ha->flags.lr_detected],
3736
+ ha->flags.lr_detected ? lengths[ha->lr_distance] :
3737
+ lengths[LR_DISTANCE_UNKNOWN],
3738
+ used_nvram, ll, ha->flags.lr_detected, ha->lr_distance);
3739
+ return ha->flags.lr_detected;
3740
+}
3741
+
3742
+void qla_init_iocb_limit(scsi_qla_host_t *vha)
3743
+{
3744
+ u16 i, num_qps;
3745
+ u32 limit;
3746
+ struct qla_hw_data *ha = vha->hw;
3747
+
3748
+ num_qps = ha->num_qpairs + 1;
3749
+ limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100;
3750
+
3751
+ ha->base_qpair->fwres.iocbs_total = ha->orig_fw_iocb_count;
3752
+ ha->base_qpair->fwres.iocbs_limit = limit;
3753
+ ha->base_qpair->fwres.iocbs_qp_limit = limit / num_qps;
3754
+ ha->base_qpair->fwres.iocbs_used = 0;
3755
+ for (i = 0; i < ha->max_qpairs; i++) {
3756
+ if (ha->queue_pair_map[i]) {
3757
+ ha->queue_pair_map[i]->fwres.iocbs_total =
3758
+ ha->orig_fw_iocb_count;
3759
+ ha->queue_pair_map[i]->fwres.iocbs_limit = limit;
3760
+ ha->queue_pair_map[i]->fwres.iocbs_qp_limit =
3761
+ limit / num_qps;
3762
+ ha->queue_pair_map[i]->fwres.iocbs_used = 0;
3763
+ }
3764
+ }
34963765 }
34973766
34983767 /**
....@@ -3510,6 +3779,7 @@
35103779 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
35113780 unsigned long flags;
35123781 uint16_t fw_major_version;
3782
+ int done_once = 0;
35133783
35143784 if (IS_P3P_TYPE(ha)) {
35153785 rval = ha->isp_ops->load_risc(vha, &srisc_address);
....@@ -3523,13 +3793,14 @@
35233793 if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
35243794 /* Disable SRAM, Instruction RAM and GP RAM parity. */
35253795 spin_lock_irqsave(&ha->hardware_lock, flags);
3526
- WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x0));
3527
- RD_REG_WORD(&reg->hccr);
3796
+ wrt_reg_word(&reg->hccr, (HCCR_ENABLE_PARITY + 0x0));
3797
+ rd_reg_word(&reg->hccr);
35283798 spin_unlock_irqrestore(&ha->hardware_lock, flags);
35293799 }
35303800
35313801 qla81xx_mpi_sync(vha);
35323802
3803
+execute_fw_with_lr:
35333804 /* Load firmware sequences */
35343805 rval = ha->isp_ops->load_risc(vha, &srisc_address);
35353806 if (rval == QLA_SUCCESS) {
....@@ -3551,7 +3822,19 @@
35513822 rval = qla2x00_execute_fw(vha, srisc_address);
35523823 /* Retrieve firmware information. */
35533824 if (rval == QLA_SUCCESS) {
3554
- qla24xx_detect_sfp(vha);
3825
+ /* Enable BPM support? */
3826
+ if (!done_once++ && qla24xx_detect_sfp(vha)) {
3827
+ ql_dbg(ql_dbg_init, vha, 0x00ca,
3828
+ "Re-starting firmware -- BPM.\n");
3829
+ /* Best-effort - re-init. */
3830
+ ha->isp_ops->reset_chip(vha);
3831
+ ha->isp_ops->chip_diag(vha);
3832
+ goto execute_fw_with_lr;
3833
+ }
3834
+
3835
+ if (IS_ZIO_THRESHOLD_CAPABLE(ha))
3836
+ qla27xx_set_zio_threshold(vha,
3837
+ ha->last_zio_threshold);
35553838
35563839 rval = qla2x00_set_exlogins_buffer(vha);
35573840 if (rval != QLA_SUCCESS)
....@@ -3580,6 +3863,7 @@
35803863 MIN_MULTI_ID_FABRIC - 1;
35813864 }
35823865 qla2x00_get_resource_cnts(vha);
3866
+ qla_init_iocb_limit(vha);
35833867
35843868 /*
35853869 * Allocate the array of outstanding commands
....@@ -3604,6 +3888,10 @@
36043888 "ISP Firmware failed checksum.\n");
36053889 goto failed;
36063890 }
3891
+
3892
+ /* Enable PUREX PASSTHRU */
3893
+ if (ql2xrdpenable || ha->flags.scm_supported_f)
3894
+ qla25xx_set_els_cmds_supported(vha);
36073895 } else
36083896 goto failed;
36093897
....@@ -3612,15 +3900,15 @@
36123900 spin_lock_irqsave(&ha->hardware_lock, flags);
36133901 if (IS_QLA2300(ha))
36143902 /* SRAM parity */
3615
- WRT_REG_WORD(&reg->hccr, HCCR_ENABLE_PARITY + 0x1);
3903
+ wrt_reg_word(&reg->hccr, HCCR_ENABLE_PARITY + 0x1);
36163904 else
36173905 /* SRAM, Instruction RAM and GP RAM parity */
3618
- WRT_REG_WORD(&reg->hccr, HCCR_ENABLE_PARITY + 0x7);
3619
- RD_REG_WORD(&reg->hccr);
3906
+ wrt_reg_word(&reg->hccr, HCCR_ENABLE_PARITY + 0x7);
3907
+ rd_reg_word(&reg->hccr);
36203908 spin_unlock_irqrestore(&ha->hardware_lock, flags);
36213909 }
36223910
3623
- if (IS_QLA27XX(ha))
3911
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
36243912 ha->flags.fac_supported = 1;
36253913 else if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) {
36263914 uint32_t size;
....@@ -3635,7 +3923,7 @@
36353923 ha->fw_major_version, ha->fw_minor_version,
36363924 ha->fw_subminor_version);
36373925
3638
- if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
3926
+ if (IS_QLA83XX(ha)) {
36393927 ha->flags.fac_supported = 0;
36403928 rval = QLA_SUCCESS;
36413929 }
....@@ -3697,8 +3985,7 @@
36973985 ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0115,
36983986 "Serial link options.\n");
36993987 ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0109,
3700
- (uint8_t *)&ha->fw_seriallink_options,
3701
- sizeof(ha->fw_seriallink_options));
3988
+ ha->fw_seriallink_options, sizeof(ha->fw_seriallink_options));
37023989
37033990 ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
37043991 if (ha->fw_seriallink_options[3] & BIT_2) {
....@@ -3788,7 +4075,7 @@
37884075
37894076 /* Move PUREX, ABTS RX & RIDA to ATIOQ */
37904077 if (ql2xmvasynctoatio &&
3791
- (IS_QLA83XX(ha) || IS_QLA27XX(ha))) {
4078
+ (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) {
37924079 if (qla_tgt_mode_enabled(vha) ||
37934080 qla_dual_mode_enabled(vha))
37944081 ha->fw_options[2] |= BIT_11;
....@@ -3796,7 +4083,8 @@
37964083 ha->fw_options[2] &= ~BIT_11;
37974084 }
37984085
3799
- if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
4086
+ if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
4087
+ IS_QLA28XX(ha)) {
38004088 /*
38014089 * Tell FW to track each exchange to prevent
38024090 * driver from using stale exchange.
....@@ -3813,6 +4101,13 @@
38134101 else
38144102 ha->fw_options[2] &= ~BIT_8;
38154103 }
4104
+
4105
+ if (ql2xrdpenable || ha->flags.scm_supported_f)
4106
+ ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
4107
+
4108
+ /* Enable Async 8130/8131 events -- transceiver insertion/removal */
4109
+ if (IS_BPM_RANGE_CAPABLE(ha))
4110
+ ha->fw_options[3] |= BIT_10;
38164111
38174112 ql_dbg(ql_dbg_init, vha, 0x00e8,
38184113 "%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
....@@ -3849,16 +4144,14 @@
38494144 ha->init_cb->response_q_inpointer = cpu_to_le16(0);
38504145 ha->init_cb->request_q_length = cpu_to_le16(req->length);
38514146 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));
4147
+ put_unaligned_le64(req->dma, &ha->init_cb->request_q_address);
4148
+ put_unaligned_le64(rsp->dma, &ha->init_cb->response_q_address);
38564149
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. */
4150
+ wrt_reg_word(ISP_REQ_Q_IN(ha, reg), 0);
4151
+ wrt_reg_word(ISP_REQ_Q_OUT(ha, reg), 0);
4152
+ wrt_reg_word(ISP_RSP_Q_IN(ha, reg), 0);
4153
+ wrt_reg_word(ISP_RSP_Q_OUT(ha, reg), 0);
4154
+ rd_reg_word(ISP_RSP_Q_OUT(ha, reg)); /* PCI Posting. */
38624155 }
38634156
38644157 void
....@@ -3879,21 +4172,19 @@
38794172 icb->response_q_inpointer = cpu_to_le16(0);
38804173 icb->request_q_length = cpu_to_le16(req->length);
38814174 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));
4175
+ put_unaligned_le64(req->dma, &icb->request_q_address);
4176
+ put_unaligned_le64(rsp->dma, &icb->response_q_address);
38864177
38874178 /* Setup ATIO queue dma pointers for target mode */
38884179 icb->atio_q_inpointer = cpu_to_le16(0);
38894180 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));
4181
+ put_unaligned_le64(ha->tgt.atio_dma, &icb->atio_q_address);
38924182
38934183 if (IS_SHADOW_REG_CAPABLE(ha))
38944184 icb->firmware_options_2 |= cpu_to_le32(BIT_30|BIT_29);
38954185
3896
- if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
4186
+ if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
4187
+ IS_QLA28XX(ha)) {
38974188 icb->qos = cpu_to_le16(QLA_DEFAULT_QUE_QOS);
38984189 icb->rid = cpu_to_le16(rid);
38994190 if (ha->flags.msix_enabled) {
....@@ -3922,20 +4213,29 @@
39224213 }
39234214 icb->firmware_options_2 |= cpu_to_le32(BIT_23);
39244215
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);
4216
+ wrt_reg_dword(&reg->isp25mq.req_q_in, 0);
4217
+ wrt_reg_dword(&reg->isp25mq.req_q_out, 0);
4218
+ wrt_reg_dword(&reg->isp25mq.rsp_q_in, 0);
4219
+ wrt_reg_dword(&reg->isp25mq.rsp_q_out, 0);
39294220 } 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);
4221
+ wrt_reg_dword(&reg->isp24.req_q_in, 0);
4222
+ wrt_reg_dword(&reg->isp24.req_q_out, 0);
4223
+ wrt_reg_dword(&reg->isp24.rsp_q_in, 0);
4224
+ wrt_reg_dword(&reg->isp24.rsp_q_out, 0);
39344225 }
4226
+
39354227 qlt_24xx_config_rings(vha);
39364228
4229
+ /* If the user has configured the speed, set it here */
4230
+ if (ha->set_data_rate) {
4231
+ ql_dbg(ql_dbg_init, vha, 0x00fd,
4232
+ "Speed set by user : %s Gbps \n",
4233
+ qla2x00_get_link_speed_str(ha, ha->set_data_rate));
4234
+ icb->firmware_options_3 = cpu_to_le32(ha->set_data_rate << 13);
4235
+ }
4236
+
39374237 /* PCI posting */
3938
- RD_REG_DWORD(&ioreg->hccr);
4238
+ rd_reg_word(&ioreg->hccr);
39394239 }
39404240
39414241 /**
....@@ -3966,7 +4266,7 @@
39664266 req = ha->req_q_map[que];
39674267 if (!req || !test_bit(que, ha->req_qid_map))
39684268 continue;
3969
- req->out_ptr = (void *)(req->ring + req->length);
4269
+ req->out_ptr = (uint16_t *)(req->ring + req->length);
39704270 *req->out_ptr = 0;
39714271 for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++)
39724272 req->outstanding_cmds[cnt] = NULL;
....@@ -3983,7 +4283,7 @@
39834283 rsp = ha->rsp_q_map[que];
39844284 if (!rsp || !test_bit(que, ha->rsp_qid_map))
39854285 continue;
3986
- rsp->in_ptr = (void *)(rsp->ring + rsp->length);
4286
+ rsp->in_ptr = (uint16_t *)(rsp->ring + rsp->length);
39874287 *rsp->in_ptr = 0;
39884288 /* Initialize response queue entries */
39894289 if (IS_QLAFX00(ha))
....@@ -4022,14 +4322,18 @@
40224322 mid_init_cb->init_cb.execution_throttle =
40234323 cpu_to_le16(ha->cur_fw_xcb_count);
40244324 ha->flags.dport_enabled =
4025
- (mid_init_cb->init_cb.firmware_options_1 & BIT_7) != 0;
4325
+ (le32_to_cpu(mid_init_cb->init_cb.firmware_options_1) &
4326
+ BIT_7) != 0;
40264327 ql_dbg(ql_dbg_init, vha, 0x0191, "DPORT Support: %s.\n",
40274328 (ha->flags.dport_enabled) ? "enabled" : "disabled");
40284329 /* FA-WWPN Status */
40294330 ha->flags.fawwpn_enabled =
4030
- (mid_init_cb->init_cb.firmware_options_1 & BIT_6) != 0;
4331
+ (le32_to_cpu(mid_init_cb->init_cb.firmware_options_1) &
4332
+ BIT_6) != 0;
40314333 ql_dbg(ql_dbg_init, vha, 0x00bc, "FA-WWPN Support: %s.\n",
40324334 (ha->flags.fawwpn_enabled) ? "enabled" : "disabled");
4335
+ /* Init_cb will be reused for other command(s). Save a backup copy of port_name */
4336
+ memcpy(ha->port_name, ha->init_cb->port_name, WWN_SIZE);
40334337 }
40344338
40354339 rval = qla2x00_init_firmware(vha, ha->init_cb_size);
....@@ -4041,6 +4345,7 @@
40414345 ql_dbg(ql_dbg_init, vha, 0x00d3,
40424346 "Init Firmware -- success.\n");
40434347 QLA_FW_STARTED(ha);
4348
+ vha->u_ql2xexchoffld = vha->u_ql2xiniexchg = 0;
40444349 }
40454350
40464351 return (rval);
....@@ -4302,16 +4607,19 @@
43024607
43034608 inline void
43044609 qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
4305
- char *def)
4610
+ const char *def)
43064611 {
43074612 char *st, *en;
43084613 uint16_t index;
4614
+ uint64_t zero[2] = { 0 };
43094615 struct qla_hw_data *ha = vha->hw;
43104616 int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
43114617 !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha);
43124618
4313
- if (memcmp(model, BINZERO, len) != 0) {
4314
- strncpy(ha->model_number, model, len);
4619
+ if (len > sizeof(zero))
4620
+ len = sizeof(zero);
4621
+ if (memcmp(model, &zero, len) != 0) {
4622
+ memcpy(ha->model_number, model, len);
43154623 st = en = ha->model_number;
43164624 en += len - 1;
43174625 while (en > st) {
....@@ -4324,21 +4632,23 @@
43244632 if (use_tbl &&
43254633 ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
43264634 index < QLA_MODEL_NAMES)
4327
- strncpy(ha->model_desc,
4635
+ strlcpy(ha->model_desc,
43284636 qla2x00_model_name[index * 2 + 1],
4329
- sizeof(ha->model_desc) - 1);
4637
+ sizeof(ha->model_desc));
43304638 } else {
43314639 index = (ha->pdev->subsystem_device & 0xff);
43324640 if (use_tbl &&
43334641 ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
43344642 index < QLA_MODEL_NAMES) {
4335
- strcpy(ha->model_number,
4336
- qla2x00_model_name[index * 2]);
4337
- strncpy(ha->model_desc,
4643
+ strlcpy(ha->model_number,
4644
+ qla2x00_model_name[index * 2],
4645
+ sizeof(ha->model_number));
4646
+ strlcpy(ha->model_desc,
43384647 qla2x00_model_name[index * 2 + 1],
4339
- sizeof(ha->model_desc) - 1);
4648
+ sizeof(ha->model_desc));
43404649 } else {
4341
- strcpy(ha->model_number, def);
4650
+ strlcpy(ha->model_number, def,
4651
+ sizeof(ha->model_number));
43424652 }
43434653 }
43444654 if (IS_FWI2_CAPABLE(ha))
....@@ -4397,10 +4707,10 @@
43974707 rval = QLA_SUCCESS;
43984708
43994709 /* Determine NVRAM starting address. */
4400
- ha->nvram_size = sizeof(nvram_t);
4710
+ ha->nvram_size = sizeof(*nv);
44014711 ha->nvram_base = 0;
44024712 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha))
4403
- if ((RD_REG_WORD(&reg->ctrl_status) >> 14) == 1)
4713
+ if ((rd_reg_word(&reg->ctrl_status) >> 14) == 1)
44044714 ha->nvram_base = 0x80;
44054715
44064716 /* Get NVRAM data and calculate checksum. */
....@@ -4411,16 +4721,15 @@
44114721 ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x010f,
44124722 "Contents of NVRAM.\n");
44134723 ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0110,
4414
- (uint8_t *)nv, ha->nvram_size);
4724
+ nv, ha->nvram_size);
44154725
44164726 /* 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) {
4727
+ if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
4728
+ nv->nvram_version < 1) {
44194729 /* Reset NVRAM data. */
44204730 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);
4731
+ "Inconsistent NVRAM detected: checksum=%#x id=%.4s version=%#x.\n",
4732
+ chksum, nv->id, nv->nvram_version);
44244733 ql_log(ql_log_warn, vha, 0x0065,
44254734 "Falling back to "
44264735 "functioning (yet invalid -- WWPN) defaults.\n");
....@@ -4436,18 +4745,18 @@
44364745 nv->firmware_options[1] = BIT_7 | BIT_5;
44374746 nv->add_firmware_options[0] = BIT_5;
44384747 nv->add_firmware_options[1] = BIT_5 | BIT_4;
4439
- nv->frame_payload_size = 2048;
4748
+ nv->frame_payload_size = cpu_to_le16(2048);
44404749 nv->special_options[1] = BIT_7;
44414750 } else if (IS_QLA2200(ha)) {
44424751 nv->firmware_options[0] = BIT_2 | BIT_1;
44434752 nv->firmware_options[1] = BIT_7 | BIT_5;
44444753 nv->add_firmware_options[0] = BIT_5;
44454754 nv->add_firmware_options[1] = BIT_5 | BIT_4;
4446
- nv->frame_payload_size = 1024;
4755
+ nv->frame_payload_size = cpu_to_le16(1024);
44474756 } else if (IS_QLA2100(ha)) {
44484757 nv->firmware_options[0] = BIT_3 | BIT_1;
44494758 nv->firmware_options[1] = BIT_5;
4450
- nv->frame_payload_size = 1024;
4759
+ nv->frame_payload_size = cpu_to_le16(1024);
44514760 }
44524761
44534762 nv->max_iocb_allocation = cpu_to_le16(256);
....@@ -4474,20 +4783,6 @@
44744783
44754784 rval = 1;
44764785 }
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
44914786
44924787 /* Reset Initialization control block */
44934788 memset(icb, 0, ha->init_cb_size);
....@@ -4669,7 +4964,7 @@
46694964 ha->zio_mode = icb->add_firmware_options[0] &
46704965 (BIT_3 | BIT_2 | BIT_1 | BIT_0);
46714966 ha->zio_timer = icb->interrupt_delay_timer ?
4672
- icb->interrupt_delay_timer: 2;
4967
+ icb->interrupt_delay_timer : 2;
46734968 }
46744969 icb->add_firmware_options[0] &=
46754970 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
....@@ -4702,7 +4997,7 @@
47024997 unsigned long flags;
47034998
47044999 spin_lock_irqsave(fcport->vha->host->host_lock, flags);
4705
- rport = fcport->drport ? fcport->drport: fcport->rport;
5000
+ rport = fcport->drport ? fcport->drport : fcport->rport;
47065001 fcport->drport = NULL;
47075002 spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
47085003 if (rport) {
....@@ -4712,6 +5007,23 @@
47125007 rport->roles);
47135008
47145009 fc_remote_port_delete(rport);
5010
+ }
5011
+}
5012
+
5013
+void qla2x00_set_fcport_state(fc_port_t *fcport, int state)
5014
+{
5015
+ int old_state;
5016
+
5017
+ old_state = atomic_read(&fcport->state);
5018
+ atomic_set(&fcport->state, state);
5019
+
5020
+ /* Don't print state transitions during initial allocation of fcport */
5021
+ if (old_state && old_state != state) {
5022
+ ql_dbg(ql_dbg_disc, fcport->vha, 0x207d,
5023
+ "FCPort %8phC state transitioned from %s to %s - portid=%02x%02x%02x.\n",
5024
+ fcport->port_name, port_state_str[old_state],
5025
+ port_state_str[state], fcport->d_id.b.domain,
5026
+ fcport->d_id.b.area, fcport->d_id.b.al_pa);
47155027 }
47165028 }
47175029
....@@ -4731,6 +5043,16 @@
47315043 if (!fcport)
47325044 return NULL;
47335045
5046
+ fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev,
5047
+ sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma,
5048
+ flags);
5049
+ if (!fcport->ct_desc.ct_sns) {
5050
+ ql_log(ql_log_warn, vha, 0xd049,
5051
+ "Failed to allocate ct_sns request.\n");
5052
+ kfree(fcport);
5053
+ return NULL;
5054
+ }
5055
+
47345056 /* Setup fcport template structure. */
47355057 fcport->vha = vha;
47365058 fcport->port_type = FCT_UNKNOWN;
....@@ -4739,13 +5061,11 @@
47395061 fcport->supported_classes = FC_COS_UNSPECIFIED;
47405062 fcport->fp_speed = PORT_SPEED_UNKNOWN;
47415063
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);
47455064 fcport->disc_state = DSC_DELETED;
47465065 fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
47475066 fcport->deleted = QLA_SESS_DELETED;
47485067 fcport->login_retry = vha->hw->login_retry_count;
5068
+ fcport->chip_reset = vha->hw->base_qpair->chip_reset;
47495069 fcport->logout_on_delete = 1;
47505070
47515071 if (!fcport->ct_desc.ct_sns) {
....@@ -4754,7 +5074,9 @@
47545074 kfree(fcport);
47555075 return NULL;
47565076 }
5077
+
47575078 INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn);
5079
+ INIT_WORK(&fcport->free_work, qlt_free_session_done);
47585080 INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
47595081 INIT_LIST_HEAD(&fcport->gnl_entry);
47605082 INIT_LIST_HEAD(&fcport->list);
....@@ -4772,7 +5094,32 @@
47725094
47735095 fcport->ct_desc.ct_sns = NULL;
47745096 }
5097
+ list_del(&fcport->list);
5098
+ qla2x00_clear_loop_id(fcport);
47755099 kfree(fcport);
5100
+}
5101
+
5102
+static void qla_get_login_template(scsi_qla_host_t *vha)
5103
+{
5104
+ struct qla_hw_data *ha = vha->hw;
5105
+ int rval;
5106
+ u32 *bp, sz;
5107
+ __be32 *q;
5108
+
5109
+ memset(ha->init_cb, 0, ha->init_cb_size);
5110
+ sz = min_t(int, sizeof(struct fc_els_flogi), ha->init_cb_size);
5111
+ rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
5112
+ ha->init_cb, sz);
5113
+ if (rval != QLA_SUCCESS) {
5114
+ ql_dbg(ql_dbg_init, vha, 0x00d1,
5115
+ "PLOGI ELS param read fail.\n");
5116
+ return;
5117
+ }
5118
+ q = (__be32 *)&ha->plogi_els_payld.fl_csp;
5119
+
5120
+ bp = (uint32_t *)ha->init_cb;
5121
+ cpu_to_be32_array(q, bp, sz / 4);
5122
+ ha->flags.plogi_template_valid = 1;
47765123 }
47775124
47785125 /*
....@@ -4793,6 +5140,7 @@
47935140 int rval;
47945141 unsigned long flags, save_flags;
47955142 struct qla_hw_data *ha = vha->hw;
5143
+
47965144 rval = QLA_SUCCESS;
47975145
47985146 /* Get Initiator ID */
....@@ -4817,14 +5165,11 @@
48175165 clear_bit(RSCN_UPDATE, &vha->dpc_flags);
48185166
48195167 qla2x00_get_data_rate(vha);
5168
+ qla_get_login_template(vha);
48205169
48215170 /* 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 &&
5171
+ if ((ha->current_topology == ISP_CFG_FL ||
5172
+ ha->current_topology == ISP_CFG_F) &&
48285173 (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
48295174
48305175 set_bit(RSCN_UPDATE, &flags);
....@@ -4903,6 +5248,48 @@
49035248 return (rval);
49045249 }
49055250
5251
+static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
5252
+{
5253
+ unsigned long flags;
5254
+ fc_port_t *fcport;
5255
+
5256
+ if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags))
5257
+ set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
5258
+
5259
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
5260
+ if (fcport->n2n_flag) {
5261
+ qla24xx_fcport_handle_login(vha, fcport);
5262
+ return QLA_SUCCESS;
5263
+ }
5264
+ }
5265
+
5266
+ spin_lock_irqsave(&vha->work_lock, flags);
5267
+ vha->scan.scan_retry++;
5268
+ spin_unlock_irqrestore(&vha->work_lock, flags);
5269
+
5270
+ if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
5271
+ set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
5272
+ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
5273
+ }
5274
+ return QLA_FUNCTION_FAILED;
5275
+}
5276
+
5277
+static void
5278
+qla_reinitialize_link(scsi_qla_host_t *vha)
5279
+{
5280
+ int rval;
5281
+
5282
+ atomic_set(&vha->loop_state, LOOP_DOWN);
5283
+ atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
5284
+ rval = qla2x00_full_login_lip(vha);
5285
+ if (rval == QLA_SUCCESS) {
5286
+ ql_dbg(ql_dbg_disc, vha, 0xd050, "Link reinitialized\n");
5287
+ } else {
5288
+ ql_dbg(ql_dbg_disc, vha, 0xd051,
5289
+ "Link reinitialization failed (%d)\n", rval);
5290
+ }
5291
+}
5292
+
49065293 /*
49075294 * qla2x00_configure_local_loop
49085295 * Updates Fibre Channel Device Database with local loop devices.
....@@ -4920,39 +5307,17 @@
49205307 int found_devs;
49215308 int found;
49225309 fc_port_t *fcport, *new_fcport;
4923
-
49245310 uint16_t index;
49255311 uint16_t entries;
4926
- char *id_iter;
5312
+ struct gid_list_info *gid;
49275313 uint16_t loop_id;
49285314 uint8_t domain, area, al_pa;
49295315 struct qla_hw_data *ha = vha->hw;
49305316 unsigned long flags;
49315317
49325318 /* 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
- }
5319
+ if (N2N_TOPO(ha))
5320
+ return qla2x00_configure_n2n_loop(vha);
49565321
49575322 found_devs = 0;
49585323 new_fcport = NULL;
....@@ -4963,13 +5328,38 @@
49635328 rval = qla2x00_get_id_list(vha, ha->gid_list, ha->gid_list_dma,
49645329 &entries);
49655330 if (rval != QLA_SUCCESS)
4966
- goto cleanup_allocation;
5331
+ goto err;
49675332
49685333 ql_dbg(ql_dbg_disc, vha, 0x2011,
49695334 "Entries in ID list (%d).\n", entries);
49705335 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2075,
4971
- (uint8_t *)ha->gid_list,
4972
- entries * sizeof(struct gid_list_info));
5336
+ ha->gid_list, entries * sizeof(*ha->gid_list));
5337
+
5338
+ if (entries == 0) {
5339
+ spin_lock_irqsave(&vha->work_lock, flags);
5340
+ vha->scan.scan_retry++;
5341
+ spin_unlock_irqrestore(&vha->work_lock, flags);
5342
+
5343
+ if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
5344
+ u8 loop_map_entries = 0;
5345
+ int rc;
5346
+
5347
+ rc = qla2x00_get_fcal_position_map(vha, NULL,
5348
+ &loop_map_entries);
5349
+ if (rc == QLA_SUCCESS && loop_map_entries > 1) {
5350
+ /*
5351
+ * There are devices that are still not logged
5352
+ * in. Reinitialize to give them a chance.
5353
+ */
5354
+ qla_reinitialize_link(vha);
5355
+ return QLA_FUNCTION_FAILED;
5356
+ }
5357
+ set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
5358
+ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
5359
+ }
5360
+ } else {
5361
+ vha->scan.scan_retry = 0;
5362
+ }
49735363
49745364 list_for_each_entry(fcport, &vha->vp_fcports, list) {
49755365 fcport->scan_state = QLA_FCPORT_SCAN;
....@@ -4981,32 +5371,32 @@
49815371 ql_log(ql_log_warn, vha, 0x2012,
49825372 "Memory allocation failed for fcport.\n");
49835373 rval = QLA_MEMORY_ALLOC_FAILED;
4984
- goto cleanup_allocation;
5374
+ goto err;
49855375 }
49865376 new_fcport->flags &= ~FCF_FABRIC_DEVICE;
49875377
49885378 /* Add devices to port list. */
4989
- id_iter = (char *)ha->gid_list;
5379
+ gid = ha->gid_list;
49905380 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;
5381
+ domain = gid->domain;
5382
+ area = gid->area;
5383
+ al_pa = gid->al_pa;
49945384 if (IS_QLA2100(ha) || IS_QLA2200(ha))
4995
- loop_id = (uint16_t)
4996
- ((struct gid_list_info *)id_iter)->loop_id_2100;
5385
+ loop_id = gid->loop_id_2100;
49975386 else
4998
- loop_id = le16_to_cpu(
4999
- ((struct gid_list_info *)id_iter)->loop_id);
5000
- id_iter += ha->gid_list_info_size;
5387
+ loop_id = le16_to_cpu(gid->loop_id);
5388
+ gid = (void *)gid + ha->gid_list_info_size;
50015389
50025390 /* Bypass reserved domain fields. */
50035391 if ((domain & 0xf0) == 0xf0)
50045392 continue;
50055393
50065394 /* 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))
5395
+ if (area && domain && ((area != vha->d_id.b.area) ||
5396
+ (domain != vha->d_id.b.domain)) &&
5397
+ (ha->current_topology == ISP_CFG_NL))
50095398 continue;
5399
+
50105400
50115401 /* Bypass invalid local loop ID. */
50125402 if (loop_id > LAST_LOCAL_LOOP_ID)
....@@ -5052,6 +5442,13 @@
50525442 memcpy(fcport->node_name, new_fcport->node_name,
50535443 WWN_SIZE);
50545444 fcport->scan_state = QLA_FCPORT_FOUND;
5445
+ if (fcport->login_retry == 0) {
5446
+ fcport->login_retry = vha->hw->login_retry_count;
5447
+ ql_dbg(ql_dbg_disc, vha, 0x2135,
5448
+ "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
5449
+ fcport->port_name, fcport->loop_id,
5450
+ fcport->login_retry);
5451
+ }
50555452 found++;
50565453 break;
50575454 }
....@@ -5071,7 +5468,7 @@
50715468 ql_log(ql_log_warn, vha, 0xd031,
50725469 "Failed to allocate memory for fcport.\n");
50735470 rval = QLA_MEMORY_ALLOC_FAILED;
5074
- goto cleanup_allocation;
5471
+ goto err;
50755472 }
50765473 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
50775474 new_fcport->flags &= ~FCF_FABRIC_DEVICE;
....@@ -5094,7 +5491,7 @@
50945491 qla_ini_mode_enabled(vha)) &&
50955492 atomic_read(&fcport->state) == FCS_ONLINE) {
50965493 qla2x00_mark_device_lost(vha, fcport,
5097
- ql2xplogiabsentdevice, 0);
5494
+ ql2xplogiabsentdevice);
50985495 if (fcport->loop_id != FC_NO_LOOP_ID &&
50995496 (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
51005497 fcport->port_type != FCT_INITIATOR &&
....@@ -5114,15 +5511,14 @@
51145511 qla24xx_fcport_handle_login(vha, fcport);
51155512 }
51165513
5117
-cleanup_allocation:
5118
- kfree(new_fcport);
5514
+ qla2x00_free_fcport(new_fcport);
51195515
5120
- if (rval != QLA_SUCCESS) {
5121
- ql_dbg(ql_dbg_disc, vha, 0x2098,
5122
- "Configure local loop error exit: rval=%x.\n", rval);
5123
- }
5516
+ return rval;
51245517
5125
- return (rval);
5518
+err:
5519
+ ql_dbg(ql_dbg_disc, vha, 0x2098,
5520
+ "Configure local loop error exit: rval=%x.\n", rval);
5521
+ return rval;
51265522 }
51275523
51285524 static void
....@@ -5204,16 +5600,23 @@
52045600
52055601 rport->supported_classes = fcport->supported_classes;
52065602
5207
- rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
5603
+ rport_ids.roles = FC_PORT_ROLE_UNKNOWN;
52085604 if (fcport->port_type == FCT_INITIATOR)
5209
- rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
5605
+ rport_ids.roles |= FC_PORT_ROLE_FCP_INITIATOR;
52105606 if (fcport->port_type == FCT_TARGET)
5211
- rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
5607
+ rport_ids.roles |= FC_PORT_ROLE_FCP_TARGET;
5608
+ if (fcport->port_type & FCT_NVME_INITIATOR)
5609
+ rport_ids.roles |= FC_PORT_ROLE_NVME_INITIATOR;
5610
+ if (fcport->port_type & FCT_NVME_TARGET)
5611
+ rport_ids.roles |= FC_PORT_ROLE_NVME_TARGET;
5612
+ if (fcport->port_type & FCT_NVME_DISCOVERY)
5613
+ rport_ids.roles |= FC_PORT_ROLE_NVME_DISCOVERY;
52125614
52135615 ql_dbg(ql_dbg_disc, vha, 0x20ee,
52145616 "%s %8phN. rport %p is %s mode\n",
52155617 __func__, fcport->port_name, rport,
5216
- (fcport->port_type == FCT_TARGET) ? "tgt" : "ini");
5618
+ (fcport->port_type == FCT_TARGET) ? "tgt" :
5619
+ ((fcport->port_type & FCT_NVME) ? "nvme" : "ini"));
52175620
52185621 fc_remote_port_rolechg(rport, rport_ids.roles);
52195622 }
....@@ -5242,15 +5645,15 @@
52425645 ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n",
52435646 __func__, fcport->port_name);
52445647
5245
- fcport->disc_state = DSC_UPD_FCPORT;
5648
+ qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
52465649 fcport->login_retry = vha->hw->login_retry_count;
52475650 fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
52485651 fcport->deleted = 0;
5249
- fcport->logout_on_delete = 1;
5250
- fcport->login_retry = vha->hw->login_retry_count;
5652
+ if (vha->hw->current_topology == ISP_CFG_NL)
5653
+ fcport->logout_on_delete = 0;
5654
+ else
5655
+ fcport->logout_on_delete = 1;
52515656 fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0;
5252
-
5253
- qla2x00_iidma_fcport(vha, fcport);
52545657
52555658 switch (vha->hw->current_topology) {
52565659 case ISP_CFG_N:
....@@ -5261,9 +5664,13 @@
52615664 break;
52625665 }
52635666
5264
- if (fcport->fc4f_nvme) {
5667
+ qla2x00_iidma_fcport(vha, fcport);
5668
+
5669
+ qla2x00_dfs_create_rport(vha, fcport);
5670
+
5671
+ if (NVME_TARGET(vha->hw, fcport)) {
52655672 qla_nvme_register_remote(vha, fcport);
5266
- fcport->disc_state = DSC_LOGIN_COMPLETE;
5673
+ qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
52675674 qla2x00_set_fcport_state(fcport, FCS_ONLINE);
52685675 return;
52695676 }
....@@ -5289,6 +5696,8 @@
52895696 break;
52905697 }
52915698
5699
+ qla2x00_set_fcport_state(fcport, FCS_ONLINE);
5700
+
52925701 if (IS_IIDMA_CAPABLE(vha->hw) && vha->hw->flags.gpsc_supported) {
52935702 if (fcport->id_changed) {
52945703 fcport->id_changed = 0;
....@@ -5305,9 +5714,8 @@
53055714 qla24xx_post_gpsc_work(vha, fcport);
53065715 }
53075716 }
5308
- qla2x00_set_fcport_state(fcport, FCS_ONLINE);
53095717
5310
- fcport->disc_state = DSC_LOGIN_COMPLETE;
5718
+ qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
53115719 }
53125720
53135721 void qla_register_fcport_fn(struct work_struct *work)
....@@ -5375,23 +5783,21 @@
53755783 }
53765784 vha->device_flags |= SWITCH_FOUND;
53775785
5786
+ rval = qla2x00_get_port_name(vha, loop_id, vha->fabric_port_name, 0);
5787
+ if (rval != QLA_SUCCESS)
5788
+ ql_dbg(ql_dbg_disc, vha, 0x20ff,
5789
+ "Failed to get Fabric Port Name\n");
53785790
53795791 if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha)) {
53805792 rval = qla2x00_send_change_request(vha, 0x3, 0);
53815793 if (rval != QLA_SUCCESS)
53825794 ql_log(ql_log_warn, vha, 0x121,
5383
- "Failed to enable receiving of RSCN requests: 0x%x.\n",
5384
- rval);
5795
+ "Failed to enable receiving of RSCN requests: 0x%x.\n",
5796
+ rval);
53855797 }
5386
-
53875798
53885799 do {
53895800 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);
53955801
53965802 /* Ensure we are logged into the SNS. */
53975803 loop_id = NPH_SNS_LID(ha);
....@@ -5404,6 +5810,12 @@
54045810 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
54055811 return rval;
54065812 }
5813
+
5814
+ /* FDMI support. */
5815
+ if (ql2xfdmienable &&
5816
+ test_and_clear_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags))
5817
+ qla2x00_fdmi_register(vha);
5818
+
54075819 if (test_and_clear_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags)) {
54085820 if (qla2x00_rft_id(vha)) {
54095821 /* EMPTY */
....@@ -5588,11 +6000,8 @@
55886000 new_fcport->fc4_type = swl[swl_idx].fc4_type;
55896001
55906002 new_fcport->nvme_flag = 0;
5591
- new_fcport->fc4f_nvme = 0;
55926003 if (vha->flags.nvme_enabled &&
5593
- swl[swl_idx].fc4f_nvme) {
5594
- new_fcport->fc4f_nvme =
5595
- swl[swl_idx].fc4f_nvme;
6004
+ swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) {
55966005 ql_log(ql_log_info, vha, 0x2131,
55976006 "FOUND: NVME port %8phC as FC Type 28h\n",
55986007 new_fcport->port_name);
....@@ -5648,8 +6057,8 @@
56486057
56496058 /* Bypass ports whose FCP-4 type is not FCP_SCSI */
56506059 if (ql2xgffidenable &&
5651
- (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
5652
- new_fcport->fc4_type != FC4_TYPE_UNKNOWN))
6060
+ (!(new_fcport->fc4_type & FS_FC4TYPE_FCP) &&
6061
+ new_fcport->fc4_type != 0))
56536062 continue;
56546063
56556064 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
....@@ -5717,9 +6126,9 @@
57176126 break;
57186127 }
57196128
5720
- if (fcport->fc4f_nvme) {
6129
+ if (found && NVME_TARGET(vha->hw, fcport)) {
57216130 if (fcport->disc_state == DSC_DELETE_PEND) {
5722
- fcport->disc_state = DSC_GNL;
6131
+ qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
57236132 vha->fcport_count--;
57246133 fcport->login_succ = 0;
57256134 }
....@@ -5765,7 +6174,7 @@
57656174 qla_ini_mode_enabled(vha)) &&
57666175 atomic_read(&fcport->state) == FCS_ONLINE) {
57676176 qla2x00_mark_device_lost(vha, fcport,
5768
- ql2xplogiabsentdevice, 0);
6177
+ ql2xplogiabsentdevice);
57696178 if (fcport->loop_id != FC_NO_LOOP_ID &&
57706179 (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
57716180 fcport->port_type != FCT_INITIATOR &&
....@@ -5786,55 +6195,6 @@
57866195 }
57876196 return (rval);
57886197 }
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
-
58386198
58396199 /* FW does not set aside Loop id for MGMT Server/FFFFFAh */
58406200 int
....@@ -5980,7 +6340,7 @@
59806340 ha->isp_ops->fabric_logout(vha, fcport->loop_id,
59816341 fcport->d_id.b.domain, fcport->d_id.b.area,
59826342 fcport->d_id.b.al_pa);
5983
- qla2x00_mark_device_lost(vha, fcport, 1, 0);
6343
+ qla2x00_mark_device_lost(vha, fcport, 1);
59846344
59856345 rval = 1;
59866346 break;
....@@ -6057,11 +6417,6 @@
60576417 {
60586418 int rval = QLA_SUCCESS;
60596419 uint32_t wait_time;
6060
- struct req_que *req;
6061
- struct rsp_que *rsp;
6062
-
6063
- req = vha->req;
6064
- rsp = req->rsp;
60656420
60666421 clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
60676422 if (vha->flags.online) {
....@@ -6074,8 +6429,8 @@
60746429 * Issue a marker after FW becomes
60756430 * ready.
60766431 */
6077
- qla2x00_marker(vha, req, rsp, 0, 0,
6078
- MK_SYNC_ALL);
6432
+ qla2x00_marker(vha, vha->hw->base_qpair,
6433
+ 0, 0, MK_SYNC_ALL);
60796434 vha->marker_needed = 0;
60806435 }
60816436
....@@ -6332,6 +6687,7 @@
63326687 qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
63336688 } else {
63346689 const char *state = qla83xx_dev_state_to_string(dev_state);
6690
+
63356691 ql_log(ql_log_info, vha, 0xb057, "HW State: %s.\n", state);
63366692
63376693 /* SV: XXX: Is timeout required here? */
....@@ -6498,16 +6854,17 @@
64986854 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
64996855 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
65006856 atomic_set(&vha->loop_state, LOOP_DOWN);
6501
- qla2x00_mark_all_devices_lost(vha, 0);
6857
+ qla2x00_mark_all_devices_lost(vha);
65026858 list_for_each_entry(vp, &ha->vp_list, list)
6503
- qla2x00_mark_all_devices_lost(vp, 0);
6859
+ qla2x00_mark_all_devices_lost(vp);
65046860 } else {
65056861 if (!atomic_read(&vha->loop_down_timer))
65066862 atomic_set(&vha->loop_down_timer,
65076863 LOOP_DOWN_TIME);
65086864 }
65096865 /* Wait for pending cmds to complete */
6510
- qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST);
6866
+ WARN_ON_ONCE(qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST)
6867
+ != QLA_SUCCESS);
65116868 }
65126869
65136870 void
....@@ -6545,7 +6902,7 @@
65456902 ha->flags.n2n_ae = 0;
65466903 ha->flags.lip_ae = 0;
65476904 ha->current_topology = 0;
6548
- ha->flags.fw_started = 0;
6905
+ QLA_FW_STOPPED(ha);
65496906 ha->flags.fw_init_done = 0;
65506907 ha->chip_reset++;
65516908 ha->base_qpair->chip_reset = ha->chip_reset;
....@@ -6575,14 +6932,14 @@
65756932 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
65766933 if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
65776934 atomic_set(&vha->loop_state, LOOP_DOWN);
6578
- qla2x00_mark_all_devices_lost(vha, 0);
6935
+ qla2x00_mark_all_devices_lost(vha);
65796936
65806937 spin_lock_irqsave(&ha->vport_slock, flags);
65816938 list_for_each_entry(vp, &ha->vp_list, list) {
65826939 atomic_inc(&vp->vref_count);
65836940 spin_unlock_irqrestore(&ha->vport_slock, flags);
65846941
6585
- qla2x00_mark_all_devices_lost(vp, 0);
6942
+ qla2x00_mark_all_devices_lost(vp);
65866943
65876944 spin_lock_irqsave(&ha->vport_slock, flags);
65886945 atomic_dec(&vp->vref_count);
....@@ -6655,6 +7012,14 @@
66557012 if (vha->flags.online) {
66567013 qla2x00_abort_isp_cleanup(vha);
66577014
7015
+ if (test_and_clear_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags)) {
7016
+ ha->flags.chip_reset_done = 1;
7017
+ vha->flags.online = 1;
7018
+ status = 0;
7019
+ clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
7020
+ return status;
7021
+ }
7022
+
66587023 if (IS_QLA8031(ha)) {
66597024 ql_dbg(ql_dbg_p3p, vha, 0xb05c,
66607025 "Clearing fcoe driver presence.\n");
....@@ -6668,6 +7033,21 @@
66687033 clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
66697034 status = 0;
66707035 return status;
7036
+ }
7037
+
7038
+ switch (vha->qlini_mode) {
7039
+ case QLA2XXX_INI_MODE_DISABLED:
7040
+ if (!qla_tgt_mode_enabled(vha))
7041
+ return 0;
7042
+ break;
7043
+ case QLA2XXX_INI_MODE_DUAL:
7044
+ if (!qla_dual_mode_enabled(vha) &&
7045
+ !qla_ini_mode_enabled(vha))
7046
+ return 0;
7047
+ break;
7048
+ case QLA2XXX_INI_MODE_ENABLED:
7049
+ default:
7050
+ break;
66717051 }
66727052
66737053 ha->isp_ops->get_flash_version(vha, req->ring);
....@@ -6799,38 +7179,41 @@
67997179 static int
68007180 qla2x00_restart_isp(scsi_qla_host_t *vha)
68017181 {
6802
- int status = 0;
7182
+ int status;
68037183 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];
68067184
68077185 /* If firmware needs to be loaded */
68087186 if (qla2x00_isp_firmware(vha)) {
68097187 vha->flags.online = 0;
68107188 status = ha->isp_ops->chip_diag(vha);
6811
- if (!status)
6812
- status = qla2x00_setup_chip(vha);
7189
+ if (status)
7190
+ return status;
7191
+ status = qla2x00_setup_chip(vha);
7192
+ if (status)
7193
+ return status;
68137194 }
68147195
6815
- if (!status && !(status = qla2x00_init_rings(vha))) {
6816
- clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
6817
- ha->flags.chip_reset_done = 1;
7196
+ status = qla2x00_init_rings(vha);
7197
+ if (status)
7198
+ return status;
68187199
6819
- /* Initialize the queues in use */
6820
- qla25xx_init_queues(ha);
7200
+ clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
7201
+ ha->flags.chip_reset_done = 1;
68217202
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
- }
7203
+ /* Initialize the queues in use */
7204
+ qla25xx_init_queues(ha);
68287205
7206
+ status = qla2x00_fw_ready(vha);
7207
+ if (status) {
68297208 /* if no cable then assume it's good */
6830
- if ((vha->device_flags & DFLG_NO_CABLE))
6831
- status = 0;
7209
+ return vha->device_flags & DFLG_NO_CABLE ? 0 : status;
68327210 }
6833
- return (status);
7211
+
7212
+ /* Issue a marker after FW becomes ready. */
7213
+ qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
7214
+ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
7215
+
7216
+ return 0;
68347217 }
68357218
68367219 static int
....@@ -6883,7 +7266,7 @@
68837266 * Input:
68847267 * ha = adapter block pointer.
68857268 */
6886
-void
7269
+int
68877270 qla2x00_reset_adapter(scsi_qla_host_t *vha)
68887271 {
68897272 unsigned long flags = 0;
....@@ -6894,14 +7277,16 @@
68947277 ha->isp_ops->disable_intrs(ha);
68957278
68967279 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. */
7280
+ wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
7281
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
7282
+ wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
7283
+ rd_reg_word(&reg->hccr); /* PCI Posting. */
69017284 spin_unlock_irqrestore(&ha->hardware_lock, flags);
7285
+
7286
+ return QLA_SUCCESS;
69027287 }
69037288
6904
-void
7289
+int
69057290 qla24xx_reset_adapter(scsi_qla_host_t *vha)
69067291 {
69077292 unsigned long flags = 0;
....@@ -6909,20 +7294,22 @@
69097294 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
69107295
69117296 if (IS_P3P_TYPE(ha))
6912
- return;
7297
+ return QLA_SUCCESS;
69137298
69147299 vha->flags.online = 0;
69157300 ha->isp_ops->disable_intrs(ha);
69167301
69177302 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);
7303
+ wrt_reg_dword(&reg->hccr, HCCRX_SET_RISC_RESET);
7304
+ rd_reg_dword(&reg->hccr);
7305
+ wrt_reg_dword(&reg->hccr, HCCRX_REL_RISC_PAUSE);
7306
+ rd_reg_dword(&reg->hccr);
69227307 spin_unlock_irqrestore(&ha->hardware_lock, flags);
69237308
69247309 if (IS_NOPOLLING_TYPE(ha))
69257310 ha->isp_ops->enable_intrs(ha);
7311
+
7312
+ return QLA_SUCCESS;
69267313 }
69277314
69287315 /* On sparc systems, obtain port and node WWN from firmware
....@@ -6954,7 +7341,7 @@
69547341 int rval;
69557342 struct init_cb_24xx *icb;
69567343 struct nvram_24xx *nv;
6957
- uint32_t *dptr;
7344
+ __le32 *dptr;
69587345 uint8_t *dptr1, *dptr2;
69597346 uint32_t chksum;
69607347 uint16_t cnt;
....@@ -6973,34 +7360,33 @@
69737360 ha->vpd_base = FA_NVRAM_VPD1_ADDR;
69747361 }
69757362
6976
- ha->nvram_size = sizeof(struct nvram_24xx);
7363
+ ha->nvram_size = sizeof(*nv);
69777364 ha->vpd_size = FA_NVRAM_VPD_SIZE;
69787365
69797366 /* Get VPD data into cache */
69807367 ha->vpd = ha->nvram + VPD_OFFSET;
6981
- ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd,
7368
+ ha->isp_ops->read_nvram(vha, ha->vpd,
69827369 ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4);
69837370
69847371 /* 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);
7372
+ dptr = (__force __le32 *)nv;
7373
+ ha->isp_ops->read_nvram(vha, dptr, ha->nvram_base, ha->nvram_size);
69887374 for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
69897375 chksum += le32_to_cpu(*dptr);
69907376
69917377 ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x006a,
69927378 "Contents of NVRAM\n");
69937379 ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010d,
6994
- (uint8_t *)nv, ha->nvram_size);
7380
+ nv, ha->nvram_size);
69957381
69967382 /* 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)) {
7383
+ if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
7384
+ le16_to_cpu(nv->nvram_version) < ICB_VERSION) {
70007385 /* Reset NVRAM data. */
70017386 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);
7387
+ "Inconsistent NVRAM checksum=%#x id=%.4s version=%#x.\n",
7388
+ chksum, nv->id, nv->nvram_version);
7389
+ ql_dump_buffer(ql_dbg_init, vha, 0x006b, nv, sizeof(*nv));
70047390 ql_log(ql_log_warn, vha, 0x006c,
70057391 "Falling back to functioning (yet invalid -- WWPN) "
70067392 "defaults.\n");
....@@ -7011,7 +7397,7 @@
70117397 memset(nv, 0, ha->nvram_size);
70127398 nv->nvram_version = cpu_to_le16(ICB_VERSION);
70137399 nv->version = cpu_to_le16(ICB_VERSION);
7014
- nv->frame_payload_size = 2048;
7400
+ nv->frame_payload_size = cpu_to_le16(2048);
70157401 nv->execution_throttle = cpu_to_le16(0xFFFF);
70167402 nv->exchange_count = cpu_to_le16(0);
70177403 nv->hard_address = cpu_to_le16(124);
....@@ -7108,11 +7494,11 @@
71087494 ha->flags.disable_risc_code_load = 0;
71097495 ha->flags.enable_lip_reset = 0;
71107496 ha->flags.enable_lip_full_login =
7111
- le32_to_cpu(nv->host_p) & BIT_10 ? 1: 0;
7497
+ le32_to_cpu(nv->host_p) & BIT_10 ? 1 : 0;
71127498 ha->flags.enable_target_reset =
7113
- le32_to_cpu(nv->host_p) & BIT_11 ? 1: 0;
7499
+ le32_to_cpu(nv->host_p) & BIT_11 ? 1 : 0;
71147500 ha->flags.enable_led_scheme = 0;
7115
- ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0;
7501
+ ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1 : 0;
71167502
71177503 ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) &
71187504 (BIT_6 | BIT_5 | BIT_4)) >> 4;
....@@ -7179,14 +7565,14 @@
71797565 ha->login_retry_count = ql2xloginretrycount;
71807566
71817567 /* N2N: driver will initiate Login instead of FW */
7182
- icb->firmware_options_3 |= BIT_8;
7568
+ icb->firmware_options_3 |= cpu_to_le32(BIT_8);
71837569
71847570 /* Enable ZIO. */
71857571 if (!vha->flags.init_done) {
71867572 ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
71877573 (BIT_3 | BIT_2 | BIT_1 | BIT_0);
71887574 ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ?
7189
- le16_to_cpu(icb->interrupt_delay_timer): 2;
7575
+ le16_to_cpu(icb->interrupt_delay_timer) : 2;
71907576 }
71917577 icb->firmware_options_2 &= cpu_to_le32(
71927578 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
....@@ -7209,128 +7595,315 @@
72097595 return (rval);
72107596 }
72117597
7212
-uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha)
7598
+static void
7599
+qla27xx_print_image(struct scsi_qla_host *vha, char *name,
7600
+ struct qla27xx_image_status *image_status)
72137601 {
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;
7602
+ ql_dbg(ql_dbg_init, vha, 0x018b,
7603
+ "%s %s: mask=%#02x gen=%#04x ver=%u.%u map=%#01x sum=%#08x sig=%#08x\n",
7604
+ name, "status",
7605
+ image_status->image_status_mask,
7606
+ le16_to_cpu(image_status->generation),
7607
+ image_status->ver_major,
7608
+ image_status->ver_minor,
7609
+ image_status->bitmap,
7610
+ le32_to_cpu(image_status->checksum),
7611
+ le32_to_cpu(image_status->signature));
7612
+}
72197613
7220
- valid_pri_image = valid_sec_image = 1;
7221
- ha->active_image = 0;
7222
- size = sizeof(struct qla27xx_image_status) / sizeof(uint32_t);
7614
+static bool
7615
+qla28xx_check_aux_image_status_signature(
7616
+ struct qla27xx_image_status *image_status)
7617
+{
7618
+ ulong signature = le32_to_cpu(image_status->signature);
7619
+
7620
+ return signature != QLA28XX_AUX_IMG_STATUS_SIGN;
7621
+}
7622
+
7623
+static bool
7624
+qla27xx_check_image_status_signature(struct qla27xx_image_status *image_status)
7625
+{
7626
+ ulong signature = le32_to_cpu(image_status->signature);
7627
+
7628
+ return
7629
+ signature != QLA27XX_IMG_STATUS_SIGN &&
7630
+ signature != QLA28XX_IMG_STATUS_SIGN;
7631
+}
7632
+
7633
+static ulong
7634
+qla27xx_image_status_checksum(struct qla27xx_image_status *image_status)
7635
+{
7636
+ __le32 *p = (__force __le32 *)image_status;
7637
+ uint n = sizeof(*image_status) / sizeof(*p);
7638
+ uint32_t sum = 0;
7639
+
7640
+ for ( ; n--; p++)
7641
+ sum += le32_to_cpup(p);
7642
+
7643
+ return sum;
7644
+}
7645
+
7646
+static inline uint
7647
+qla28xx_component_bitmask(struct qla27xx_image_status *aux, uint bitmask)
7648
+{
7649
+ return aux->bitmap & bitmask ?
7650
+ QLA27XX_SECONDARY_IMAGE : QLA27XX_PRIMARY_IMAGE;
7651
+}
7652
+
7653
+static void
7654
+qla28xx_component_status(
7655
+ struct active_regions *active_regions, struct qla27xx_image_status *aux)
7656
+{
7657
+ active_regions->aux.board_config =
7658
+ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_BOARD_CONFIG);
7659
+
7660
+ active_regions->aux.vpd_nvram =
7661
+ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_VPD_NVRAM);
7662
+
7663
+ active_regions->aux.npiv_config_0_1 =
7664
+ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_0_1);
7665
+
7666
+ active_regions->aux.npiv_config_2_3 =
7667
+ qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_2_3);
7668
+}
7669
+
7670
+static int
7671
+qla27xx_compare_image_generation(
7672
+ struct qla27xx_image_status *pri_image_status,
7673
+ struct qla27xx_image_status *sec_image_status)
7674
+{
7675
+ /* calculate generation delta as uint16 (this accounts for wrap) */
7676
+ int16_t delta =
7677
+ le16_to_cpu(pri_image_status->generation) -
7678
+ le16_to_cpu(sec_image_status->generation);
7679
+
7680
+ ql_dbg(ql_dbg_init, NULL, 0x0180, "generation delta = %d\n", delta);
7681
+
7682
+ return delta;
7683
+}
7684
+
7685
+void
7686
+qla28xx_get_aux_images(
7687
+ struct scsi_qla_host *vha, struct active_regions *active_regions)
7688
+{
7689
+ struct qla_hw_data *ha = vha->hw;
7690
+ struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status;
7691
+ bool valid_pri_image = false, valid_sec_image = false;
7692
+ bool active_pri_image = false, active_sec_image = false;
7693
+
7694
+ if (!ha->flt_region_aux_img_status_pri) {
7695
+ ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n");
7696
+ goto check_sec_image;
7697
+ }
7698
+
7699
+ qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
7700
+ ha->flt_region_aux_img_status_pri,
7701
+ sizeof(pri_aux_image_status) >> 2);
7702
+ qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status);
7703
+
7704
+ if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) {
7705
+ ql_dbg(ql_dbg_init, vha, 0x018b,
7706
+ "Primary aux image signature (%#x) not valid\n",
7707
+ le32_to_cpu(pri_aux_image_status.signature));
7708
+ goto check_sec_image;
7709
+ }
7710
+
7711
+ if (qla27xx_image_status_checksum(&pri_aux_image_status)) {
7712
+ ql_dbg(ql_dbg_init, vha, 0x018c,
7713
+ "Primary aux image checksum failed\n");
7714
+ goto check_sec_image;
7715
+ }
7716
+
7717
+ valid_pri_image = true;
7718
+
7719
+ if (pri_aux_image_status.image_status_mask & 1) {
7720
+ ql_dbg(ql_dbg_init, vha, 0x018d,
7721
+ "Primary aux image is active\n");
7722
+ active_pri_image = true;
7723
+ }
7724
+
7725
+check_sec_image:
7726
+ if (!ha->flt_region_aux_img_status_sec) {
7727
+ ql_dbg(ql_dbg_init, vha, 0x018a,
7728
+ "Secondary aux image not addressed\n");
7729
+ goto check_valid_image;
7730
+ }
7731
+
7732
+ qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
7733
+ ha->flt_region_aux_img_status_sec,
7734
+ sizeof(sec_aux_image_status) >> 2);
7735
+ qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status);
7736
+
7737
+ if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) {
7738
+ ql_dbg(ql_dbg_init, vha, 0x018b,
7739
+ "Secondary aux image signature (%#x) not valid\n",
7740
+ le32_to_cpu(sec_aux_image_status.signature));
7741
+ goto check_valid_image;
7742
+ }
7743
+
7744
+ if (qla27xx_image_status_checksum(&sec_aux_image_status)) {
7745
+ ql_dbg(ql_dbg_init, vha, 0x018c,
7746
+ "Secondary aux image checksum failed\n");
7747
+ goto check_valid_image;
7748
+ }
7749
+
7750
+ valid_sec_image = true;
7751
+
7752
+ if (sec_aux_image_status.image_status_mask & 1) {
7753
+ ql_dbg(ql_dbg_init, vha, 0x018d,
7754
+ "Secondary aux image is active\n");
7755
+ active_sec_image = true;
7756
+ }
7757
+
7758
+check_valid_image:
7759
+ if (valid_pri_image && active_pri_image &&
7760
+ valid_sec_image && active_sec_image) {
7761
+ if (qla27xx_compare_image_generation(&pri_aux_image_status,
7762
+ &sec_aux_image_status) >= 0) {
7763
+ qla28xx_component_status(active_regions,
7764
+ &pri_aux_image_status);
7765
+ } else {
7766
+ qla28xx_component_status(active_regions,
7767
+ &sec_aux_image_status);
7768
+ }
7769
+ } else if (valid_pri_image && active_pri_image) {
7770
+ qla28xx_component_status(active_regions, &pri_aux_image_status);
7771
+ } else if (valid_sec_image && active_sec_image) {
7772
+ qla28xx_component_status(active_regions, &sec_aux_image_status);
7773
+ }
7774
+
7775
+ ql_dbg(ql_dbg_init, vha, 0x018f,
7776
+ "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u\n",
7777
+ active_regions->aux.board_config,
7778
+ active_regions->aux.vpd_nvram,
7779
+ active_regions->aux.npiv_config_0_1,
7780
+ active_regions->aux.npiv_config_2_3);
7781
+}
7782
+
7783
+void
7784
+qla27xx_get_active_image(struct scsi_qla_host *vha,
7785
+ struct active_regions *active_regions)
7786
+{
7787
+ struct qla_hw_data *ha = vha->hw;
7788
+ struct qla27xx_image_status pri_image_status, sec_image_status;
7789
+ bool valid_pri_image = false, valid_sec_image = false;
7790
+ bool active_pri_image = false, active_sec_image = false;
72237791
72247792 if (!ha->flt_region_img_status_pri) {
7225
- valid_pri_image = 0;
7793
+ ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n");
72267794 goto check_sec_image;
72277795 }
72287796
7229
- qla24xx_read_flash_data(vha, (uint32_t *)(&pri_image_status),
7230
- ha->flt_region_img_status_pri, size);
7797
+ if (qla24xx_read_flash_data(vha, (uint32_t *)&pri_image_status,
7798
+ ha->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
7799
+ QLA_SUCCESS) {
7800
+ WARN_ON_ONCE(true);
7801
+ goto check_sec_image;
7802
+ }
7803
+ qla27xx_print_image(vha, "Primary image", &pri_image_status);
72317804
7232
- if (pri_image_status.signature != QLA27XX_IMG_STATUS_SIGN) {
7805
+ if (qla27xx_check_image_status_signature(&pri_image_status)) {
72337806 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;
7807
+ "Primary image signature (%#x) not valid\n",
7808
+ le32_to_cpu(pri_image_status.signature));
72377809 goto check_sec_image;
72387810 }
72397811
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) {
7812
+ if (qla27xx_image_status_checksum(&pri_image_status)) {
72477813 ql_dbg(ql_dbg_init, vha, 0x018c,
7248
- "Checksum validation failed for primary image (0x%x)\n",
7249
- chksum);
7250
- valid_pri_image = 0;
7814
+ "Primary image checksum failed\n");
7815
+ goto check_sec_image;
7816
+ }
7817
+
7818
+ valid_pri_image = true;
7819
+
7820
+ if (pri_image_status.image_status_mask & 1) {
7821
+ ql_dbg(ql_dbg_init, vha, 0x018d,
7822
+ "Primary image is active\n");
7823
+ active_pri_image = true;
72517824 }
72527825
72537826 check_sec_image:
72547827 if (!ha->flt_region_img_status_sec) {
7255
- valid_sec_image = 0;
7828
+ ql_dbg(ql_dbg_init, vha, 0x018a, "Secondary image not addressed\n");
72567829 goto check_valid_image;
72577830 }
72587831
72597832 qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
7260
- ha->flt_region_img_status_sec, size);
7833
+ ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2);
7834
+ qla27xx_print_image(vha, "Secondary image", &sec_image_status);
72617835
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;
7836
+ if (qla27xx_check_image_status_signature(&sec_image_status)) {
7837
+ ql_dbg(ql_dbg_init, vha, 0x018b,
7838
+ "Secondary image signature (%#x) not valid\n",
7839
+ le32_to_cpu(sec_image_status.signature));
72677840 goto check_valid_image;
72687841 }
72697842
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;
7843
+ if (qla27xx_image_status_checksum(&sec_image_status)) {
7844
+ ql_dbg(ql_dbg_init, vha, 0x018c,
7845
+ "Secondary image checksum failed\n");
7846
+ goto check_valid_image;
7847
+ }
7848
+
7849
+ valid_sec_image = true;
7850
+
7851
+ if (sec_image_status.image_status_mask & 1) {
7852
+ ql_dbg(ql_dbg_init, vha, 0x018d,
7853
+ "Secondary image is active\n");
7854
+ active_sec_image = true;
72797855 }
72807856
72817857 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;
7858
+ if (valid_pri_image && active_pri_image)
7859
+ active_regions->global = QLA27XX_PRIMARY_IMAGE;
7860
+
7861
+ if (valid_sec_image && active_sec_image) {
7862
+ if (!active_regions->global ||
7863
+ qla27xx_compare_image_generation(
7864
+ &pri_image_status, &sec_image_status) < 0) {
7865
+ active_regions->global = QLA27XX_SECONDARY_IMAGE;
7866
+ }
72897867 }
72907868
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");
7869
+ ql_dbg(ql_dbg_init, vha, 0x018f, "active image %s (%u)\n",
7870
+ active_regions->global == QLA27XX_DEFAULT_IMAGE ?
7871
+ "default (boot/fw)" :
7872
+ active_regions->global == QLA27XX_PRIMARY_IMAGE ?
7873
+ "primary" :
7874
+ active_regions->global == QLA27XX_SECONDARY_IMAGE ?
7875
+ "secondary" : "invalid",
7876
+ active_regions->global);
7877
+}
72967878
7297
- return ha->active_image;
7879
+bool qla24xx_risc_firmware_invalid(uint32_t *dword)
7880
+{
7881
+ return
7882
+ !(dword[4] | dword[5] | dword[6] | dword[7]) ||
7883
+ !(~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]);
72987884 }
72997885
73007886 static int
73017887 qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
73027888 uint32_t faddr)
73037889 {
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;
7890
+ int rval;
7891
+ uint templates, segments, fragment;
7892
+ ulong i;
7893
+ uint j;
7894
+ ulong dlen;
7895
+ uint32_t *dcode;
7896
+ uint32_t risc_addr, risc_size, risc_attr = 0;
73107897 struct qla_hw_data *ha = vha->hw;
73117898 struct req_que *req = ha->req_q_map[0];
7899
+ struct fwdt *fwdt = ha->fwdt;
73127900
73137901 ql_dbg(ql_dbg_init, vha, 0x008b,
73147902 "FW: Loading firmware from flash (%x).\n", faddr);
73157903
7316
- rval = QLA_SUCCESS;
7317
-
7318
- segments = FA_RISC_CODE_SEGMENTS;
73197904 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)) {
7905
+ qla24xx_read_flash_data(vha, dcode, faddr, 8);
7906
+ if (qla24xx_risc_firmware_invalid(dcode)) {
73347907 ql_log(ql_log_fatal, vha, 0x008c,
73357908 "Unable to verify the integrity of flash firmware "
73367909 "image.\n");
....@@ -7341,34 +7914,36 @@
73417914 return QLA_FUNCTION_FAILED;
73427915 }
73437916
7344
- while (segments && rval == QLA_SUCCESS) {
7345
- /* Read segment's load information. */
7346
- qla24xx_read_flash_data(vha, dcode, faddr, 4);
7917
+ dcode = (uint32_t *)req->ring;
7918
+ *srisc_addr = 0;
7919
+ segments = FA_RISC_CODE_SEGMENTS;
7920
+ for (j = 0; j < segments; j++) {
7921
+ ql_dbg(ql_dbg_init, vha, 0x008d,
7922
+ "-> Loading segment %u...\n", j);
7923
+ qla24xx_read_flash_data(vha, dcode, faddr, 10);
7924
+ risc_addr = be32_to_cpu((__force __be32)dcode[2]);
7925
+ risc_size = be32_to_cpu((__force __be32)dcode[3]);
7926
+ if (!*srisc_addr) {
7927
+ *srisc_addr = risc_addr;
7928
+ risc_attr = be32_to_cpu((__force __be32)dcode[9]);
7929
+ }
73477930
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);
7931
+ dlen = ha->fw_transfer_size >> 2;
7932
+ for (fragment = 0; risc_size; fragment++) {
73557933 if (dlen > risc_size)
73567934 dlen = risc_size;
73577935
73587936 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
-
7937
+ "-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n",
7938
+ fragment, risc_addr, faddr, dlen);
73637939 qla24xx_read_flash_data(vha, dcode, faddr, dlen);
73647940 for (i = 0; i < dlen; i++)
73657941 dcode[i] = swab32(dcode[i]);
73667942
7367
- rval = qla2x00_load_ram(vha, req->dma, risc_addr,
7368
- dlen);
7943
+ rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen);
73697944 if (rval) {
73707945 ql_log(ql_log_fatal, vha, 0x008f,
7371
- "Failed to load segment %d of firmware.\n",
7946
+ "-> Failed load firmware fragment %u.\n",
73727947 fragment);
73737948 return QLA_FUNCTION_FAILED;
73747949 }
....@@ -7376,107 +7951,82 @@
73767951 faddr += dlen;
73777952 risc_addr += dlen;
73787953 risc_size -= dlen;
7379
- fragment++;
7954
+ }
7955
+ }
7956
+
7957
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
7958
+ return QLA_SUCCESS;
7959
+
7960
+ templates = (risc_attr & BIT_9) ? 2 : 1;
7961
+ ql_dbg(ql_dbg_init, vha, 0x0160, "-> templates = %u\n", templates);
7962
+ for (j = 0; j < templates; j++, fwdt++) {
7963
+ if (fwdt->template)
7964
+ vfree(fwdt->template);
7965
+ fwdt->template = NULL;
7966
+ fwdt->length = 0;
7967
+
7968
+ dcode = (uint32_t *)req->ring;
7969
+ qla24xx_read_flash_data(vha, dcode, faddr, 7);
7970
+ risc_size = be32_to_cpu((__force __be32)dcode[2]);
7971
+ ql_dbg(ql_dbg_init, vha, 0x0161,
7972
+ "-> fwdt%u template array at %#x (%#x dwords)\n",
7973
+ j, faddr, risc_size);
7974
+ if (!risc_size || !~risc_size) {
7975
+ ql_dbg(ql_dbg_init, vha, 0x0162,
7976
+ "-> fwdt%u failed to read array\n", j);
7977
+ goto failed;
73807978 }
73817979
7382
- /* Next segment. */
7383
- segments--;
7980
+ /* skip header and ignore checksum */
7981
+ faddr += 7;
7982
+ risc_size -= 8;
7983
+
7984
+ ql_dbg(ql_dbg_init, vha, 0x0163,
7985
+ "-> fwdt%u template allocate template %#x words...\n",
7986
+ j, risc_size);
7987
+ fwdt->template = vmalloc(risc_size * sizeof(*dcode));
7988
+ if (!fwdt->template) {
7989
+ ql_log(ql_log_warn, vha, 0x0164,
7990
+ "-> fwdt%u failed allocate template.\n", j);
7991
+ goto failed;
7992
+ }
7993
+
7994
+ dcode = fwdt->template;
7995
+ qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
7996
+
7997
+ if (!qla27xx_fwdt_template_valid(dcode)) {
7998
+ ql_log(ql_log_warn, vha, 0x0165,
7999
+ "-> fwdt%u failed template validate\n", j);
8000
+ goto failed;
8001
+ }
8002
+
8003
+ dlen = qla27xx_fwdt_template_size(dcode);
8004
+ ql_dbg(ql_dbg_init, vha, 0x0166,
8005
+ "-> fwdt%u template size %#lx bytes (%#lx words)\n",
8006
+ j, dlen, dlen / sizeof(*dcode));
8007
+ if (dlen > risc_size * sizeof(*dcode)) {
8008
+ ql_log(ql_log_warn, vha, 0x0167,
8009
+ "-> fwdt%u template exceeds array (%-lu bytes)\n",
8010
+ j, dlen - risc_size * sizeof(*dcode));
8011
+ goto failed;
8012
+ }
8013
+
8014
+ fwdt->length = dlen;
8015
+ ql_dbg(ql_dbg_init, vha, 0x0168,
8016
+ "-> fwdt%u loaded template ok\n", j);
8017
+
8018
+ faddr += risc_size + 1;
73848019 }
73858020
7386
- if (!IS_QLA27XX(ha))
7387
- return rval;
8021
+ return QLA_SUCCESS;
73888022
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;
8023
+failed:
8024
+ if (fwdt->template)
8025
+ vfree(fwdt->template);
8026
+ fwdt->template = NULL;
8027
+ fwdt->length = 0;
73938028
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;
8029
+ return QLA_SUCCESS;
74808030 }
74818031
74828032 #define QLA_FW_URL "http://ldriver.qlogic.com/firmware/"
....@@ -7486,7 +8036,8 @@
74868036 {
74878037 int rval;
74888038 int i, fragment;
7489
- uint16_t *wcode, *fwcode;
8039
+ uint16_t *wcode;
8040
+ __be16 *fwcode;
74908041 uint32_t risc_addr, risc_size, fwclen, wlen, *seg;
74918042 struct fw_blob *blob;
74928043 struct qla_hw_data *ha = vha->hw;
....@@ -7506,7 +8057,7 @@
75068057
75078058 wcode = (uint16_t *)req->ring;
75088059 *srisc_addr = 0;
7509
- fwcode = (uint16_t *)blob->fw->data;
8060
+ fwcode = (__force __be16 *)blob->fw->data;
75108061 fwclen = 0;
75118062
75128063 /* Validate firmware image by checking version. */
....@@ -7554,7 +8105,7 @@
75548105 "words 0x%x.\n", risc_addr, wlen);
75558106
75568107 for (i = 0; i < wlen; i++)
7557
- wcode[i] = swab16(fwcode[i]);
8108
+ wcode[i] = swab16((__force u32)fwcode[i]);
75588109
75598110 rval = qla2x00_load_ram(vha, req->dma, risc_addr,
75608111 wlen);
....@@ -7584,54 +8135,33 @@
75848135 qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
75858136 {
75868137 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;
8138
+ uint templates, segments, fragment;
8139
+ uint32_t *dcode;
8140
+ ulong dlen;
8141
+ uint32_t risc_addr, risc_size, risc_attr = 0;
8142
+ ulong i;
8143
+ uint j;
75928144 struct fw_blob *blob;
7593
- const uint32_t *fwcode;
7594
- uint32_t fwclen;
8145
+ __be32 *fwcode;
75958146 struct qla_hw_data *ha = vha->hw;
75968147 struct req_que *req = ha->req_q_map[0];
8148
+ struct fwdt *fwdt = ha->fwdt;
75978149
7598
- /* Load firmware blob. */
8150
+ ql_dbg(ql_dbg_init, vha, 0x0090,
8151
+ "-> FW: Loading via request-firmware.\n");
8152
+
75998153 blob = qla2x00_request_firmware(vha);
76008154 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");
8155
+ ql_log(ql_log_warn, vha, 0x0092,
8156
+ "-> Firmware file not found.\n");
76068157
76078158 return QLA_FUNCTION_FAILED;
76088159 }
76098160
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)) {
8161
+ fwcode = (__force __be32 *)blob->fw->data;
8162
+ dcode = (__force uint32_t *)fwcode;
8163
+ if (qla24xx_risc_firmware_invalid(dcode)) {
76238164 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,
76358165 "Unable to verify integrity of firmware image (%zd).\n",
76368166 blob->fw->size);
76378167 ql_log(ql_log_fatal, vha, 0x0095,
....@@ -7640,38 +8170,38 @@
76408170 return QLA_FUNCTION_FAILED;
76418171 }
76428172
7643
- while (segments && rval == QLA_SUCCESS) {
8173
+ dcode = (uint32_t *)req->ring;
8174
+ *srisc_addr = 0;
8175
+ segments = FA_RISC_CODE_SEGMENTS;
8176
+ for (j = 0; j < segments; j++) {
8177
+ ql_dbg(ql_dbg_init, vha, 0x0096,
8178
+ "-> Loading segment %u...\n", j);
76448179 risc_addr = be32_to_cpu(fwcode[2]);
7645
- *srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
76468180 risc_size = be32_to_cpu(fwcode[3]);
76478181
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;
8182
+ if (!*srisc_addr) {
8183
+ *srisc_addr = risc_addr;
8184
+ risc_attr = be32_to_cpu(fwcode[9]);
76558185 }
76568186
7657
- fragment = 0;
7658
- while (risc_size > 0 && rval == QLA_SUCCESS) {
7659
- dlen = (uint32_t)(ha->fw_transfer_size >> 2);
8187
+ dlen = ha->fw_transfer_size >> 2;
8188
+ for (fragment = 0; risc_size; fragment++) {
76608189 if (dlen > risc_size)
76618190 dlen = risc_size;
76628191
76638192 ql_dbg(ql_dbg_init, vha, 0x0097,
7664
- "Loading risc segment@ risc addr %x "
7665
- "number of dwords 0x%x.\n", risc_addr, dlen);
8193
+ "-> Loading fragment %u: %#x <- %#x (%#lx words)...\n",
8194
+ fragment, risc_addr,
8195
+ (uint32_t)(fwcode - (typeof(fwcode))blob->fw->data),
8196
+ dlen);
76668197
76678198 for (i = 0; i < dlen; i++)
7668
- dcode[i] = swab32(fwcode[i]);
8199
+ dcode[i] = swab32((__force u32)fwcode[i]);
76698200
7670
- rval = qla2x00_load_ram(vha, req->dma, risc_addr,
7671
- dlen);
8201
+ rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen);
76728202 if (rval) {
76738203 ql_log(ql_log_fatal, vha, 0x0098,
7674
- "Failed to load segment %d of firmware.\n",
8204
+ "-> Failed load firmware fragment %u.\n",
76758205 fragment);
76768206 return QLA_FUNCTION_FAILED;
76778207 }
....@@ -7679,106 +8209,82 @@
76798209 fwcode += dlen;
76808210 risc_addr += dlen;
76818211 risc_size -= dlen;
7682
- fragment++;
8212
+ }
8213
+ }
8214
+
8215
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
8216
+ return QLA_SUCCESS;
8217
+
8218
+ templates = (risc_attr & BIT_9) ? 2 : 1;
8219
+ ql_dbg(ql_dbg_init, vha, 0x0170, "-> templates = %u\n", templates);
8220
+ for (j = 0; j < templates; j++, fwdt++) {
8221
+ if (fwdt->template)
8222
+ vfree(fwdt->template);
8223
+ fwdt->template = NULL;
8224
+ fwdt->length = 0;
8225
+
8226
+ risc_size = be32_to_cpu(fwcode[2]);
8227
+ ql_dbg(ql_dbg_init, vha, 0x0171,
8228
+ "-> fwdt%u template array at %#x (%#x dwords)\n",
8229
+ j, (uint32_t)((void *)fwcode - (void *)blob->fw->data),
8230
+ risc_size);
8231
+ if (!risc_size || !~risc_size) {
8232
+ ql_dbg(ql_dbg_init, vha, 0x0172,
8233
+ "-> fwdt%u failed to read array\n", j);
8234
+ goto failed;
76838235 }
76848236
7685
- /* Next segment. */
7686
- segments--;
8237
+ /* skip header and ignore checksum */
8238
+ fwcode += 7;
8239
+ risc_size -= 8;
8240
+
8241
+ ql_dbg(ql_dbg_init, vha, 0x0173,
8242
+ "-> fwdt%u template allocate template %#x words...\n",
8243
+ j, risc_size);
8244
+ fwdt->template = vmalloc(risc_size * sizeof(*dcode));
8245
+ if (!fwdt->template) {
8246
+ ql_log(ql_log_warn, vha, 0x0174,
8247
+ "-> fwdt%u failed allocate template.\n", j);
8248
+ goto failed;
8249
+ }
8250
+
8251
+ dcode = fwdt->template;
8252
+ for (i = 0; i < risc_size; i++)
8253
+ dcode[i] = (__force u32)fwcode[i];
8254
+
8255
+ if (!qla27xx_fwdt_template_valid(dcode)) {
8256
+ ql_log(ql_log_warn, vha, 0x0175,
8257
+ "-> fwdt%u failed template validate\n", j);
8258
+ goto failed;
8259
+ }
8260
+
8261
+ dlen = qla27xx_fwdt_template_size(dcode);
8262
+ ql_dbg(ql_dbg_init, vha, 0x0176,
8263
+ "-> fwdt%u template size %#lx bytes (%#lx words)\n",
8264
+ j, dlen, dlen / sizeof(*dcode));
8265
+ if (dlen > risc_size * sizeof(*dcode)) {
8266
+ ql_log(ql_log_warn, vha, 0x0177,
8267
+ "-> fwdt%u template exceeds array (%-lu bytes)\n",
8268
+ j, dlen - risc_size * sizeof(*dcode));
8269
+ goto failed;
8270
+ }
8271
+
8272
+ fwdt->length = dlen;
8273
+ ql_dbg(ql_dbg_init, vha, 0x0178,
8274
+ "-> fwdt%u loaded template ok\n", j);
8275
+
8276
+ fwcode += risc_size + 1;
76878277 }
76888278
7689
- if (!IS_QLA27XX(ha))
7690
- return rval;
8279
+ return QLA_SUCCESS;
76918280
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;
8281
+failed:
8282
+ if (fwdt->template)
8283
+ vfree(fwdt->template);
8284
+ fwdt->template = NULL;
8285
+ fwdt->length = 0;
76968286
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;
8287
+ return QLA_SUCCESS;
77828288 }
77838289
77848290 int
....@@ -7807,32 +8313,50 @@
78078313 {
78088314 int rval;
78098315 struct qla_hw_data *ha = vha->hw;
8316
+ struct active_regions active_regions = { };
78108317
78118318 if (ql2xfwloadbin == 2)
78128319 goto try_blob_fw;
78138320
7814
- /*
7815
- * FW Load priority:
8321
+ /* FW Load priority:
78168322 * 1) Firmware residing in flash.
78178323 * 2) Firmware via request-firmware interface (.bin file).
7818
- * 3) Golden-Firmware residing in flash -- limited operation.
8324
+ * 3) Golden-Firmware residing in flash -- (limited operation).
78198325 */
8326
+
8327
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
8328
+ goto try_primary_fw;
8329
+
8330
+ qla27xx_get_active_image(vha, &active_regions);
8331
+
8332
+ if (active_regions.global != QLA27XX_SECONDARY_IMAGE)
8333
+ goto try_primary_fw;
8334
+
8335
+ ql_dbg(ql_dbg_init, vha, 0x008b,
8336
+ "Loading secondary firmware image.\n");
8337
+ rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw_sec);
8338
+ if (!rval)
8339
+ return rval;
8340
+
8341
+try_primary_fw:
8342
+ ql_dbg(ql_dbg_init, vha, 0x008b,
8343
+ "Loading primary firmware image.\n");
78208344 rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw);
7821
- if (rval == QLA_SUCCESS)
8345
+ if (!rval)
78228346 return rval;
78238347
78248348 try_blob_fw:
78258349 rval = qla24xx_load_risc_blob(vha, srisc_addr);
7826
- if (rval == QLA_SUCCESS || !ha->flt_region_gold_fw)
8350
+ if (!rval || !ha->flt_region_gold_fw)
78278351 return rval;
78288352
78298353 ql_log(ql_log_info, vha, 0x0099,
78308354 "Attempting to fallback to golden firmware.\n");
78318355 rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_gold_fw);
7832
- if (rval != QLA_SUCCESS)
8356
+ if (rval)
78338357 return rval;
78348358
7835
- ql_log(ql_log_info, vha, 0x009a, "Update operational firmware.\n");
8359
+ ql_log(ql_log_info, vha, 0x009a, "Need firmware flash update.\n");
78368360 ha->flags.running_gold_fw = 1;
78378361 return rval;
78388362 }
....@@ -7877,22 +8401,15 @@
78778401 uint16_t mb[MAILBOX_REGISTER_COUNT];
78788402 struct qla_hw_data *ha = vha->hw;
78798403 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
7880
- struct req_que *req;
7881
- struct rsp_que *rsp;
78828404
78838405 if (!vha->vp_idx)
78848406 return -EINVAL;
78858407
78868408 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;
78928409
78938410 if (rval == QLA_SUCCESS) {
78948411 clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
7895
- qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
8412
+ qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
78968413 }
78978414
78988415 vha->flags.management_server_logged_in = 0;
....@@ -7974,6 +8491,7 @@
79748491 qla84xx_put_chip(struct scsi_qla_host *vha)
79758492 {
79768493 struct qla_hw_data *ha = vha->hw;
8494
+
79778495 if (ha->cs84xx)
79788496 kref_put(&ha->cs84xx->kref, __qla84xx_chip_release);
79798497 }
....@@ -7991,7 +8509,7 @@
79918509
79928510 mutex_unlock(&ha->cs84xx->fw_update_mutex);
79938511
7994
- return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED:
8512
+ return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED :
79958513 QLA_SUCCESS;
79968514 }
79978515
....@@ -8003,48 +8521,70 @@
80038521 int rval;
80048522 struct init_cb_81xx *icb;
80058523 struct nvram_81xx *nv;
8006
- uint32_t *dptr;
8524
+ __le32 *dptr;
80078525 uint8_t *dptr1, *dptr2;
80088526 uint32_t chksum;
80098527 uint16_t cnt;
80108528 struct qla_hw_data *ha = vha->hw;
8529
+ uint32_t faddr;
8530
+ struct active_regions active_regions = { };
80118531
80128532 rval = QLA_SUCCESS;
80138533 icb = (struct init_cb_81xx *)ha->init_cb;
80148534 nv = ha->nvram;
80158535
80168536 /* Determine NVRAM starting address. */
8017
- ha->nvram_size = sizeof(struct nvram_81xx);
8537
+ ha->nvram_size = sizeof(*nv);
80188538 ha->vpd_size = FA_NVRAM_VPD_SIZE;
80198539 if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
80208540 ha->vpd_size = FA_VPD_SIZE_82XX;
80218541
8542
+ if (IS_QLA28XX(ha) || IS_QLA27XX(ha))
8543
+ qla28xx_get_aux_images(vha, &active_regions);
8544
+
80228545 /* Get VPD data into cache */
80238546 ha->vpd = ha->nvram + VPD_OFFSET;
8024
- ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
8025
- ha->vpd_size);
8547
+
8548
+ faddr = ha->flt_region_vpd;
8549
+ if (IS_QLA28XX(ha)) {
8550
+ if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
8551
+ faddr = ha->flt_region_vpd_sec;
8552
+ ql_dbg(ql_dbg_init, vha, 0x0110,
8553
+ "Loading %s nvram image.\n",
8554
+ active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
8555
+ "primary" : "secondary");
8556
+ }
8557
+ ha->isp_ops->read_optrom(vha, ha->vpd, faddr << 2, ha->vpd_size);
80268558
80278559 /* 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;
8560
+ faddr = ha->flt_region_nvram;
8561
+ if (IS_QLA28XX(ha)) {
8562
+ if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
8563
+ faddr = ha->flt_region_nvram_sec;
8564
+ }
8565
+ ql_dbg(ql_dbg_init, vha, 0x0110,
8566
+ "Loading %s nvram image.\n",
8567
+ active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
8568
+ "primary" : "secondary");
8569
+ ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size);
8570
+
8571
+ dptr = (__force __le32 *)nv;
80318572 for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
80328573 chksum += le32_to_cpu(*dptr);
80338574
80348575 ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0111,
80358576 "Contents of NVRAM:\n");
80368577 ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0112,
8037
- (uint8_t *)nv, ha->nvram_size);
8578
+ nv, ha->nvram_size);
80388579
80398580 /* 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)) {
8581
+ if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
8582
+ le16_to_cpu(nv->nvram_version) < ICB_VERSION) {
80438583 /* Reset NVRAM data. */
80448584 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));
8585
+ "Inconsistent NVRAM checksum=%#x id=%.4s version=%#x.\n",
8586
+ chksum, nv->id, le16_to_cpu(nv->nvram_version));
8587
+ ql_dump_buffer(ql_dbg_init, vha, 0x0073, nv, sizeof(*nv));
80488588 ql_log(ql_log_info, vha, 0x0074,
80498589 "Falling back to functioning (yet invalid -- WWPN) "
80508590 "defaults.\n");
....@@ -8055,7 +8595,7 @@
80558595 memset(nv, 0, ha->nvram_size);
80568596 nv->nvram_version = cpu_to_le16(ICB_VERSION);
80578597 nv->version = cpu_to_le16(ICB_VERSION);
8058
- nv->frame_payload_size = 2048;
8598
+ nv->frame_payload_size = cpu_to_le16(2048);
80598599 nv->execution_throttle = cpu_to_le16(0xFFFF);
80608600 nv->exchange_count = cpu_to_le16(0);
80618601 nv->port_name[0] = 0x21;
....@@ -8099,7 +8639,7 @@
80998639 }
81008640
81018641 if (IS_T10_PI_CAPABLE(ha))
8102
- nv->frame_payload_size &= ~7;
8642
+ nv->frame_payload_size &= cpu_to_le16(~7);
81038643
81048644 qlt_81xx_config_nvram_stage1(vha, nv);
81058645
....@@ -8161,15 +8701,20 @@
81618701 icb->node_name[0] &= 0xF0;
81628702 }
81638703
8704
+ if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
8705
+ if ((nv->enhanced_features & BIT_7) == 0)
8706
+ ha->flags.scm_supported_a = 1;
8707
+ }
8708
+
81648709 /* Set host adapter parameters. */
81658710 ha->flags.disable_risc_code_load = 0;
81668711 ha->flags.enable_lip_reset = 0;
81678712 ha->flags.enable_lip_full_login =
8168
- le32_to_cpu(nv->host_p) & BIT_10 ? 1: 0;
8713
+ le32_to_cpu(nv->host_p) & BIT_10 ? 1 : 0;
81698714 ha->flags.enable_target_reset =
8170
- le32_to_cpu(nv->host_p) & BIT_11 ? 1: 0;
8715
+ le32_to_cpu(nv->host_p) & BIT_11 ? 1 : 0;
81718716 ha->flags.enable_led_scheme = 0;
8172
- ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0;
8717
+ ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1 : 0;
81738718
81748719 ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) &
81758720 (BIT_6 | BIT_5 | BIT_4)) >> 4;
....@@ -8233,7 +8778,8 @@
82338778 ha->login_retry_count = ql2xloginretrycount;
82348779
82358780 /* if not running MSI-X we need handshaking on interrupts */
8236
- if (!vha->hw->flags.msix_enabled && (IS_QLA83XX(ha) || IS_QLA27XX(ha)))
8781
+ if (!vha->hw->flags.msix_enabled &&
8782
+ (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)))
82378783 icb->firmware_options_2 |= cpu_to_le32(BIT_22);
82388784
82398785 /* Enable ZIO. */
....@@ -8241,7 +8787,7 @@
82418787 ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
82428788 (BIT_3 | BIT_2 | BIT_1 | BIT_0);
82438789 ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ?
8244
- le16_to_cpu(icb->interrupt_delay_timer): 2;
8790
+ le16_to_cpu(icb->interrupt_delay_timer) : 2;
82458791 }
82468792 icb->firmware_options_2 &= cpu_to_le32(
82478793 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
....@@ -8261,16 +8807,13 @@
82618807 }
82628808
82638809 /* enable RIDA Format2 */
8264
- icb->firmware_options_3 |= BIT_0;
8810
+ icb->firmware_options_3 |= cpu_to_le32(BIT_0);
82658811
82668812 /* N2N: driver will initiate Login instead of FW */
8267
- icb->firmware_options_3 |= BIT_8;
8813
+ icb->firmware_options_3 |= cpu_to_le32(BIT_8);
82688814
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
- }
8815
+ /* Determine NVMe/FCP priority for target ports */
8816
+ ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha);
82748817
82758818 if (rval) {
82768819 ql_log(ql_log_warn, vha, 0x0076,
....@@ -8284,8 +8827,6 @@
82848827 {
82858828 int status, rval;
82868829 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];
82898830 struct scsi_qla_host *vp;
82908831 unsigned long flags;
82918832
....@@ -8297,7 +8838,7 @@
82978838 status = qla2x00_fw_ready(vha);
82988839 if (!status) {
82998840 /* Issue a marker after FW becomes ready. */
8300
- qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
8841
+ qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
83018842 vha->flags.online = 1;
83028843 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
83038844 }
....@@ -8377,61 +8918,6 @@
83778918 }
83788919
83798920 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);
84358921 }
84368922
84378923 /*
....@@ -8634,7 +9120,6 @@
86349120 "Failed to allocate memory for queue pair.\n");
86359121 return NULL;
86369122 }
8637
- memset(qpair, 0, sizeof(struct qla_qpair));
86389123
86399124 qpair->hw = vha->hw;
86409125 qpair->vha = vha;
....@@ -8681,7 +9166,7 @@
86819166 qpair->msix->in_use = 1;
86829167 list_add_tail(&qpair->qp_list_elem, &vha->qp_list);
86839168 qpair->pdev = ha->pdev;
8684
- if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
9169
+ if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha))
86859170 qpair->reqq_start_iocbs = qla_83xx_start_iocbs;
86869171
86879172 mutex_unlock(&ha->mq_lock);
....@@ -8709,7 +9194,7 @@
87099194 qpair->rsp->req = qpair->req;
87109195 qpair->rsp->qpair = qpair;
87119196 /* init qpair to this cpu. Will adjust at run time. */
8712
- qla_cpu_update(qpair, smp_processor_id());
9197
+ qla_cpu_update(qpair, raw_smp_processor_id());
87139198
87149199 if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
87159200 if (ha->fw_attributes & BIT_4)