Skip to content

Commit 875386b

Browse files
mrangankarmartinkpetersen
authored andcommitted
scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe
Introduce infrastructure in the driver to support the processing of unsolicited LS (Link Service) requests. This will involve the utilization of a new pass-up of unsolicited FC-NVMe request IOCB interface. Unsolicited requests will be submitted to the NVMe transport layer through nvme_fc_rcv_ls_req(). Any received LS responses, which are sent using xmt_ls_rsp(), will be forwarded to the firmware through the existing Pass-Through IOCB interface, responsible for sending FC-NVMe Link Service requests and responses. Signed-off-by: Manish Rangankar <mrangankar@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://lore.kernel.org/r/20230821130045.34850-2-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent ae25f65 commit 875386b

File tree

11 files changed

+642
-34
lines changed

11 files changed

+642
-34
lines changed

drivers/scsi/qla2xxx/qla_dbg.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
* ----------------------------------------------------------------------
1313
* | Module Init and Probe | 0x0199 | |
1414
* | Mailbox commands | 0x1206 | 0x11a5-0x11ff |
15-
* | Device Discovery | 0x2134 | 0x210e-0x2115 |
16-
* | | | 0x211c-0x2128 |
17-
* | | | 0x212c-0x2134 |
15+
* | Device Discovery | 0x2134 | 0x2112-0x2115 |
16+
* | | | 0x2127-0x2128 |
1817
* | Queue Command and IO tracing | 0x3074 | 0x300b |
1918
* | | | 0x3027-0x3028 |
2019
* | | | 0x303d-0x3041 |

drivers/scsi/qla2xxx/qla_dbg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ ql_log_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...);
368368
#define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */
369369
#define ql_dbg_tgt_dif 0x00000800 /* Target mode dif */
370370
#define ql_dbg_edif 0x00000400 /* edif and purex debug */
371+
#define ql_dbg_unsol 0x00000100 /* Unsolicited path debug */
371372

372373
extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
373374
uint32_t, void **);

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,12 @@ struct name_list_extended {
346346
u8 sent;
347347
};
348348

349+
struct qla_nvme_fc_rjt {
350+
struct fcnvme_ls_rjt *c;
351+
dma_addr_t cdma;
352+
u16 size;
353+
};
354+
349355
struct els_reject {
350356
struct fc_els_ls_rjt *c;
351357
dma_addr_t cdma;
@@ -503,6 +509,20 @@ struct ct_arg {
503509
port_id_t id;
504510
};
505511

512+
struct qla_nvme_lsrjt_pt_arg {
513+
struct fc_port *fcport;
514+
u8 opcode;
515+
u8 vp_idx;
516+
u8 reason;
517+
u8 explanation;
518+
__le16 nport_handle;
519+
u16 control_flags;
520+
__le16 ox_id;
521+
__le32 xchg_address;
522+
u32 tx_byte_count, rx_byte_count;
523+
dma_addr_t tx_addr, rx_addr;
524+
};
525+
506526
/*
507527
* SRB extensions.
508528
*/
@@ -611,13 +631,16 @@ struct srb_iocb {
611631
void *desc;
612632

613633
/* These are only used with ls4 requests */
614-
int cmd_len;
615-
int rsp_len;
634+
__le32 cmd_len;
635+
__le32 rsp_len;
616636
dma_addr_t cmd_dma;
617637
dma_addr_t rsp_dma;
618638
enum nvmefc_fcp_datadir dir;
619639
uint32_t dl;
620640
uint32_t timeout_sec;
641+
__le32 exchange_address;
642+
__le16 nport_handle;
643+
__le16 ox_id;
621644
struct list_head entry;
622645
} nvme;
623646
struct {
@@ -707,6 +730,10 @@ typedef struct srb {
707730
struct fc_port *fcport;
708731
struct scsi_qla_host *vha;
709732
unsigned int start_timer:1;
733+
unsigned int abort:1;
734+
unsigned int aborted:1;
735+
unsigned int completed:1;
736+
unsigned int unsol_rsp:1;
710737

711738
uint32_t handle;
712739
uint16_t flags;
@@ -2542,6 +2569,7 @@ enum rscn_addr_format {
25422569
typedef struct fc_port {
25432570
struct list_head list;
25442571
struct scsi_qla_host *vha;
2572+
struct list_head unsol_ctx_head;
25452573

25462574
unsigned int conf_compl_supported:1;
25472575
unsigned int deleted:2;
@@ -4802,6 +4830,7 @@ struct qla_hw_data {
48024830
struct els_reject elsrej;
48034831
u8 edif_post_stop_cnt_down;
48044832
struct qla_vp_map *vp_map;
4833+
struct qla_nvme_fc_rjt lsrjt;
48054834
};
48064835

48074836
#define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES))
@@ -4834,6 +4863,7 @@ struct active_regions {
48344863
* is variable) starting at "iocb".
48354864
*/
48364865
struct purex_item {
4866+
void *purls_context;
48374867
struct list_head list;
48384868
struct scsi_qla_host *vha;
48394869
void (*process_item)(struct scsi_qla_host *vha,

drivers/scsi/qla2xxx/qla_gbl.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,11 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id);
611611
fc_port_t *qla2x00_find_fcport_by_loopid(scsi_qla_host_t *, uint16_t);
612612
fc_port_t *qla2x00_find_fcport_by_wwpn(scsi_qla_host_t *, u8 *, u8);
613613
fc_port_t *qla2x00_find_fcport_by_nportid(scsi_qla_host_t *, port_id_t *, u8);
614-
void __qla_consume_iocb(struct scsi_qla_host *vha, void **pkt, struct rsp_que **rsp);
614+
void qla24xx_queue_purex_item(scsi_qla_host_t *, struct purex_item *,
615+
void (*process_item)(struct scsi_qla_host *,
616+
struct purex_item *));
617+
void __qla_consume_iocb(struct scsi_qla_host *, void **, struct rsp_que **);
618+
void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp);
615619

616620
/*
617621
* Global Function Prototypes in qla_sup.c source file.
@@ -674,9 +678,11 @@ extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
674678
extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
675679
extern int qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *);
676680
extern int qla2x00_mailbox_passthru(struct bsg_job *bsg_job);
677-
int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha, void **pkt,
678-
struct rsp_que **rsp, u8 *buf, u32 buf_len);
679-
681+
int qla2x00_sys_ld_info(struct bsg_job *bsg_job);
682+
int __qla_copy_purex_to_buffer(struct scsi_qla_host *, void **,
683+
struct rsp_que **, u8 *, u32);
684+
struct purex_item *qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha,
685+
void **pkt, struct rsp_que **rsp, bool is_purls, bool byte_order);
680686
int qla_mailbox_passthru(scsi_qla_host_t *vha, uint16_t *mbx_in,
681687
uint16_t *mbx_out);
682688

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5554,6 +5554,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
55545554
INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
55555555
INIT_LIST_HEAD(&fcport->gnl_entry);
55565556
INIT_LIST_HEAD(&fcport->list);
5557+
INIT_LIST_HEAD(&fcport->unsol_ctx_head);
55575558

55585559
INIT_LIST_HEAD(&fcport->sess_cmd_list);
55595560
spin_lock_init(&fcport->sess_cmd_lock);

drivers/scsi/qla2xxx/qla_iocb.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3771,21 +3771,28 @@ qla_nvme_ls(srb_t *sp, struct pt_ls4_request *cmd_pkt)
37713771
nvme = &sp->u.iocb_cmd;
37723772
cmd_pkt->entry_type = PT_LS4_REQUEST;
37733773
cmd_pkt->entry_count = 1;
3774-
cmd_pkt->control_flags = cpu_to_le16(CF_LS4_ORIGINATOR << CF_LS4_SHIFT);
3775-
37763774
cmd_pkt->timeout = cpu_to_le16(nvme->u.nvme.timeout_sec);
3777-
cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
37783775
cmd_pkt->vp_index = sp->fcport->vha->vp_idx;
37793776

3777+
if (sp->unsol_rsp) {
3778+
cmd_pkt->control_flags =
3779+
cpu_to_le16(CF_LS4_RESPONDER << CF_LS4_SHIFT);
3780+
cmd_pkt->nport_handle = nvme->u.nvme.nport_handle;
3781+
cmd_pkt->exchange_address = nvme->u.nvme.exchange_address;
3782+
} else {
3783+
cmd_pkt->control_flags =
3784+
cpu_to_le16(CF_LS4_ORIGINATOR << CF_LS4_SHIFT);
3785+
cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
3786+
cmd_pkt->rx_dseg_count = cpu_to_le16(1);
3787+
cmd_pkt->rx_byte_count = nvme->u.nvme.rsp_len;
3788+
cmd_pkt->dsd[1].length = nvme->u.nvme.rsp_len;
3789+
put_unaligned_le64(nvme->u.nvme.rsp_dma, &cmd_pkt->dsd[1].address);
3790+
}
3791+
37803792
cmd_pkt->tx_dseg_count = cpu_to_le16(1);
3781-
cmd_pkt->tx_byte_count = cpu_to_le32(nvme->u.nvme.cmd_len);
3782-
cmd_pkt->dsd[0].length = cpu_to_le32(nvme->u.nvme.cmd_len);
3793+
cmd_pkt->tx_byte_count = nvme->u.nvme.cmd_len;
3794+
cmd_pkt->dsd[0].length = nvme->u.nvme.cmd_len;
37833795
put_unaligned_le64(nvme->u.nvme.cmd_dma, &cmd_pkt->dsd[0].address);
3784-
3785-
cmd_pkt->rx_dseg_count = cpu_to_le16(1);
3786-
cmd_pkt->rx_byte_count = cpu_to_le32(nvme->u.nvme.rsp_len);
3787-
cmd_pkt->dsd[1].length = cpu_to_le32(nvme->u.nvme.rsp_len);
3788-
put_unaligned_le64(nvme->u.nvme.rsp_dma, &cmd_pkt->dsd[1].address);
37893796
}
37903797

37913798
static void

drivers/scsi/qla2xxx/qla_isr.c

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,135 @@ qla83xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
823823
}
824824
}
825825

826+
/**
827+
* qla27xx_copy_multiple_pkt() - Copy over purex/purls packets that can
828+
* span over multiple IOCBs.
829+
* @vha: SCSI driver HA context
830+
* @pkt: ELS packet
831+
* @rsp: Response queue
832+
* @is_purls: True, for Unsolicited Received FC-NVMe LS rsp IOCB
833+
* false, for Unsolicited Received ELS IOCB
834+
* @byte_order: True, to change the byte ordering of iocb payload
835+
*/
836+
struct purex_item *
837+
qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt,
838+
struct rsp_que **rsp, bool is_purls,
839+
bool byte_order)
840+
{
841+
struct purex_entry_24xx *purex = NULL;
842+
struct pt_ls4_rx_unsol *purls = NULL;
843+
struct rsp_que *rsp_q = *rsp;
844+
sts_cont_entry_t *new_pkt;
845+
uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0;
846+
uint16_t buffer_copy_offset = 0, payload_size = 0;
847+
uint16_t entry_count, entry_count_remaining;
848+
struct purex_item *item;
849+
void *iocb_pkt = NULL;
850+
851+
if (is_purls) {
852+
purls = *pkt;
853+
total_bytes = (le16_to_cpu(purls->frame_size) & 0x0FFF) -
854+
PURX_ELS_HEADER_SIZE;
855+
entry_count = entry_count_remaining = purls->entry_count;
856+
payload_size = sizeof(purls->payload);
857+
} else {
858+
purex = *pkt;
859+
total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF) -
860+
PURX_ELS_HEADER_SIZE;
861+
entry_count = entry_count_remaining = purex->entry_count;
862+
payload_size = sizeof(purex->els_frame_payload);
863+
}
864+
865+
pending_bytes = total_bytes;
866+
no_bytes = (pending_bytes > payload_size) ? payload_size :
867+
pending_bytes;
868+
ql_dbg(ql_dbg_async, vha, 0x509a,
869+
"%s LS, frame_size 0x%x, entry count %d\n",
870+
(is_purls ? "PURLS" : "FPIN"), total_bytes, entry_count);
871+
872+
item = qla24xx_alloc_purex_item(vha, total_bytes);
873+
if (!item)
874+
return item;
875+
876+
iocb_pkt = &item->iocb;
877+
878+
if (is_purls)
879+
memcpy(iocb_pkt, &purls->payload[0], no_bytes);
880+
else
881+
memcpy(iocb_pkt, &purex->els_frame_payload[0], no_bytes);
882+
buffer_copy_offset += no_bytes;
883+
pending_bytes -= no_bytes;
884+
--entry_count_remaining;
885+
886+
if (is_purls)
887+
((response_t *)purls)->signature = RESPONSE_PROCESSED;
888+
else
889+
((response_t *)purex)->signature = RESPONSE_PROCESSED;
890+
wmb();
891+
892+
do {
893+
while ((total_bytes > 0) && (entry_count_remaining > 0)) {
894+
if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) {
895+
ql_dbg(ql_dbg_async, vha, 0x5084,
896+
"Ran out of IOCBs, partial data 0x%x\n",
897+
buffer_copy_offset);
898+
cpu_relax();
899+
continue;
900+
}
901+
902+
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
903+
*pkt = new_pkt;
904+
905+
if (new_pkt->entry_type != STATUS_CONT_TYPE) {
906+
ql_log(ql_log_warn, vha, 0x507a,
907+
"Unexpected IOCB type, partial data 0x%x\n",
908+
buffer_copy_offset);
909+
break;
910+
}
911+
912+
rsp_q->ring_index++;
913+
if (rsp_q->ring_index == rsp_q->length) {
914+
rsp_q->ring_index = 0;
915+
rsp_q->ring_ptr = rsp_q->ring;
916+
} else {
917+
rsp_q->ring_ptr++;
918+
}
919+
no_bytes = (pending_bytes > sizeof(new_pkt->data)) ?
920+
sizeof(new_pkt->data) : pending_bytes;
921+
if ((buffer_copy_offset + no_bytes) <= total_bytes) {
922+
memcpy(((uint8_t *)iocb_pkt + buffer_copy_offset),
923+
new_pkt->data, no_bytes);
924+
buffer_copy_offset += no_bytes;
925+
pending_bytes -= no_bytes;
926+
--entry_count_remaining;
927+
} else {
928+
ql_log(ql_log_warn, vha, 0x5044,
929+
"Attempt to copy more that we got, optimizing..%x\n",
930+
buffer_copy_offset);
931+
memcpy(((uint8_t *)iocb_pkt + buffer_copy_offset),
932+
new_pkt->data,
933+
total_bytes - buffer_copy_offset);
934+
}
935+
936+
((response_t *)new_pkt)->signature = RESPONSE_PROCESSED;
937+
wmb();
938+
}
939+
940+
if (pending_bytes != 0 || entry_count_remaining != 0) {
941+
ql_log(ql_log_fatal, vha, 0x508b,
942+
"Dropping partial FPIN, underrun bytes = 0x%x, entry cnts 0x%x\n",
943+
total_bytes, entry_count_remaining);
944+
qla24xx_free_purex_item(item);
945+
return NULL;
946+
}
947+
} while (entry_count_remaining > 0);
948+
949+
if (byte_order)
950+
host_to_fcp_swap((uint8_t *)&item->iocb, total_bytes);
951+
952+
return item;
953+
}
954+
826955
int
827956
qla2x00_is_a_vp_did(scsi_qla_host_t *vha, uint32_t rscn_entry)
828957
{
@@ -958,7 +1087,7 @@ qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size)
9581087
return item;
9591088
}
9601089

961-
static void
1090+
void
9621091
qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
9631092
void (*process_item)(struct scsi_qla_host *vha,
9641093
struct purex_item *pkt))
@@ -3811,6 +3940,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
38113940
struct qla_hw_data *ha = vha->hw;
38123941
struct purex_entry_24xx *purex_entry;
38133942
struct purex_item *pure_item;
3943+
struct pt_ls4_rx_unsol *p;
38143944
u16 rsp_in = 0, cur_ring_index;
38153945
int is_shadow_hba;
38163946

@@ -3983,7 +4113,19 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
39834113
qla28xx_sa_update_iocb_entry(vha, rsp->req,
39844114
(struct sa_update_28xx *)pkt);
39854115
break;
3986-
4116+
case PT_LS4_UNSOL:
4117+
p = (void *)pkt;
4118+
if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt, rsp_in)) {
4119+
rsp->ring_ptr = (response_t *)pkt;
4120+
rsp->ring_index = cur_ring_index;
4121+
4122+
ql_dbg(ql_dbg_init, vha, 0x2124,
4123+
"Defer processing UNSOL LS req opcode %#x...\n",
4124+
p->payload[0]);
4125+
return;
4126+
}
4127+
qla2xxx_process_purls_iocb((void **)&pkt, &rsp);
4128+
break;
39874129
default:
39884130
/* Type Not Supported. */
39894131
ql_dbg(ql_dbg_async, vha, 0x5042,

0 commit comments

Comments
 (0)