// SPDX-License-Identifier: GPL-2.0-only
/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2017 QLogic Corporation
*/
#include "qla_nvme.h"
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/nvme.h>
#include <linux/nvme-fc.h>
#include <linux/blk-mq-pci.h>
#include <linux/blk-mq.h>
static struct nvme_fc_port_template qla_nvme_fc_transport;
static int qla_nvme_ls_reject_iocb(struct scsi_qla_host *vha,
struct qla_qpair *qp,
struct qla_nvme_lsrjt_pt_arg *a,
bool is_xchg_terminate);
struct qla_nvme_unsol_ctx {
struct list_head elem;
struct scsi_qla_host *vha;
struct fc_port *fcport;
struct srb *sp;
struct nvmefc_ls_rsp lsrsp;
struct nvmefc_ls_rsp *fd_rsp;
struct work_struct lsrsp_work;
struct work_struct abort_work;
__le32 exchange_address;
__le16 nport_handle;
__le16 ox_id;
int comp_status;
spinlock_t cmd_lock;
};
int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
{
struct qla_nvme_rport *rport;
struct nvme_fc_port_info req;
int ret;
if (!IS_ENABLED(CONFIG_NVME_FC))
return 0;
if (!vha->flags.nvme_enabled) {
ql_log(ql_log_info, vha, 0x2100,
"%s: Not registering target since Host NVME is not enabled\n",
__func__);
return 0;
}
if (!vha->nvme_local_port && qla_nvme_register_hba(vha))
return 0;
if (!(fcport->nvme_prli_service_param &
(NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) ||
(fcport->nvme_flag & NVME_FLAG_REGISTERED))
return 0;
fcport->nvme_flag &= ~NVME_FLAG_RESETTING;
memset(&req, 0, sizeof(struct nvme_fc_port_info));
req.port_name = wwn_to_u64(fcport->port_name);
req.node_name = wwn_to_u64(fcport->node_name);
req.port_role = 0;
req.dev_loss_tmo = fcport->dev_loss_tmo;
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR)
req.port_role = FC_PORT_ROLE_NVME_INITIATOR;
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET)
req.port_role |= FC_PORT_ROLE_NVME_TARGET;
if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY)
req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY;
req.port_id = fcport->d_id.b24;
ql_log(ql_log_info, vha, 0x2102,
"%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n",
__func__, req.node_name, req.port_name,
req.port_id);
ret = nvme_fc_register_remoteport(vha->nvme_local_port, &req,
&fcport->nvme_remote_port);
if (