Skip to content

Commit

Permalink
scsi: qla2xxx: Add FC-NVMe F/W initialization and transport registration
Browse files Browse the repository at this point in the history
This code provides the interfaces to register remote and local ports of
FC4 type 0x28 with the FC-NVMe transport and transports the requests
(FC-NVMe FC link services and FC-NVMe commands IUs) to the fabric. It
also provides the support for allocating h/w queues and aborting FC-NVMe
FC requests.

Signed-off-by: Darren Trapp <darren.trapp@cavium.com>
Signed-off-by: Duane Grigsby <duane.grigsby@cavium.com>
Signed-off-by: Anil Gurumurthy <anil.gurumurhty@cavium.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Duane Grigsby authored and martinkpetersen committed Jun 28, 2017
1 parent 7401bc1 commit e84067d
Show file tree
Hide file tree
Showing 11 changed files with 1,024 additions and 9 deletions.
2 changes: 1 addition & 1 deletion drivers/scsi/qla2xxx/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o
qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o

obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o
2 changes: 1 addition & 1 deletion drivers/scsi/qla2xxx/qla_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* | | | 0x015b-0x0160 |
* | | | 0x016e |
* | Mailbox commands | 0x1199 | 0x1193 |
* | Device Discovery | 0x2131 | 0x210e-0x2116 |
* | Device Discovery | 0x2134 | 0x210e-0x2116 |
* | | | 0x211a |
* | | | 0x211c-0x2128 |
* | | | 0x212a-0x2130 |
Expand Down
6 changes: 6 additions & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "qla_bsg.h"
#include "qla_nx.h"
#include "qla_nx2.h"
#include "qla_nvme.h"
#define QLA2XXX_DRIVER_NAME "qla2xxx"
#define QLA2XXX_APIDEV "ql2xapidev"
#define QLA2XXX_MANUFACTURER "QLogic Corporation"
Expand Down Expand Up @@ -423,6 +424,7 @@ struct srb_iocb {
int rsp_len;
dma_addr_t cmd_dma;
dma_addr_t rsp_dma;
enum nvmefc_fcp_datadir dir;
uint32_t dl;
uint32_t timeout_sec;
} nvme;
Expand Down Expand Up @@ -452,6 +454,7 @@ struct srb_iocb {
#define SRB_NACK_PRLI 17
#define SRB_NACK_LOGO 18
#define SRB_NVME_CMD 19
#define SRB_NVME_LS 20
#define SRB_PRLI_CMD 21

enum {
Expand All @@ -467,6 +470,7 @@ typedef struct srb {
uint8_t cmd_type;
uint8_t pad[3];
atomic_t ref_count;
wait_queue_head_t nvme_ls_waitQ;
struct fc_port *fcport;
struct scsi_qla_host *vha;
uint32_t handle;
Expand Down Expand Up @@ -2298,6 +2302,7 @@ typedef struct fc_port {

struct work_struct nvme_del_work;
atomic_t nvme_ref_count;
wait_queue_head_t nvme_waitQ;
uint32_t nvme_prli_service_param;
#define NVME_PRLI_SP_CONF BIT_7
#define NVME_PRLI_SP_INITIATOR BIT_5
Expand Down Expand Up @@ -4124,6 +4129,7 @@ typedef struct scsi_qla_host {

struct nvme_fc_local_port *nvme_local_port;
atomic_t nvme_ref_count;
wait_queue_head_t nvme_waitQ;
struct list_head nvme_rport_list;
atomic_t nvme_active_aen_cnt;
uint16_t nvme_last_rptd_aen;
Expand Down
11 changes: 11 additions & 0 deletions drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@

#include <linux/interrupt.h>

/*
* Global functions prototype in qla_nvme.c source file.
*/
extern void qla_nvme_register_hba(scsi_qla_host_t *);
extern int qla_nvme_register_remote(scsi_qla_host_t *, fc_port_t *);
extern void qla_nvme_delete(scsi_qla_host_t *);
extern void qla_nvme_abort(struct qla_hw_data *, srb_t *sp);
extern void qla24xx_nvme_ls4_iocb(scsi_qla_host_t *, struct pt_ls4_request *,
struct req_que *);

/*
* Global Function Prototypes in qla_init.c source file.
*/
Expand Down Expand Up @@ -141,6 +151,7 @@ extern int ql2xiniexchg;
extern int ql2xfwholdabts;
extern int ql2xmvasynctoatio;
extern int ql2xuctrlirq;
extern int ql2xnvmeenable;

extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
Expand Down
8 changes: 8 additions & 0 deletions drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -4520,6 +4520,11 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
fcport->deleted = 0;
fcport->logout_on_delete = 1;

if (fcport->fc4f_nvme) {
qla_nvme_register_remote(vha, fcport);
return;
}

qla2x00_set_fcport_state(fcport, FCS_ONLINE);
qla2x00_iidma_fcport(vha, fcport);
qla24xx_update_fcport_fcp_prio(vha, fcport);
Expand Down Expand Up @@ -4669,6 +4674,9 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
break;
} while (0);

if (!vha->nvme_local_port && vha->flags.nvme_enabled)
qla_nvme_register_hba(vha);

if (rval)
ql_dbg(ql_dbg_disc, vha, 0x2068,
"Configure fabric error exit rval=%d.\n", rval);
Expand Down
36 changes: 36 additions & 0 deletions drivers/scsi/qla2xxx/qla_iocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -3155,6 +3155,39 @@ static void qla2x00_send_notify_ack_iocb(srb_t *sp,
nack->u.isp24.vp_index = ntfy->u.isp24.vp_index;
}

/*
* Build NVME LS request
*/
static int
qla_nvme_ls(srb_t *sp, struct pt_ls4_request *cmd_pkt)
{
struct srb_iocb *nvme;
int rval = QLA_SUCCESS;

nvme = &sp->u.iocb_cmd;
cmd_pkt->entry_type = PT_LS4_REQUEST;
cmd_pkt->entry_count = 1;
cmd_pkt->control_flags = CF_LS4_ORIGINATOR << CF_LS4_SHIFT;

cmd_pkt->timeout = cpu_to_le16(nvme->u.nvme.timeout_sec);
cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
cmd_pkt->vp_index = sp->fcport->vha->vp_idx;

cmd_pkt->tx_dseg_count = 1;
cmd_pkt->tx_byte_count = nvme->u.nvme.cmd_len;
cmd_pkt->dseg0_len = nvme->u.nvme.cmd_len;
cmd_pkt->dseg0_address[0] = cpu_to_le32(LSD(nvme->u.nvme.cmd_dma));
cmd_pkt->dseg0_address[1] = cpu_to_le32(MSD(nvme->u.nvme.cmd_dma));

cmd_pkt->rx_dseg_count = 1;
cmd_pkt->rx_byte_count = nvme->u.nvme.rsp_len;
cmd_pkt->dseg1_len = nvme->u.nvme.rsp_len;
cmd_pkt->dseg1_address[0] = cpu_to_le32(LSD(nvme->u.nvme.rsp_dma));
cmd_pkt->dseg1_address[1] = cpu_to_le32(MSD(nvme->u.nvme.rsp_dma));

return rval;
}

int
qla2x00_start_sp(srb_t *sp)
{
Expand Down Expand Up @@ -3211,6 +3244,9 @@ qla2x00_start_sp(srb_t *sp)
case SRB_FXIOCB_BCMD:
qlafx00_fxdisc_iocb(sp, pkt);
break;
case SRB_NVME_LS:
qla_nvme_ls(sp, pkt);
break;
case SRB_ABT_CMD:
IS_QLAFX00(ha) ?
qlafx00_abort_iocb(sp, pkt) :
Expand Down
19 changes: 19 additions & 0 deletions drivers/scsi/qla2xxx/qla_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2828,6 +2828,21 @@ qla24xx_abort_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
sp->done(sp, 0);
}

void qla24xx_nvme_ls4_iocb(scsi_qla_host_t *vha, struct pt_ls4_request *pkt,
struct req_que *req)
{
srb_t *sp;
const char func[] = "LS4_IOCB";
uint16_t comp_status;

sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (!sp)
return;

comp_status = le16_to_cpu(pkt->status);
sp->done(sp, comp_status);
}

/**
* qla24xx_process_response_queue() - Process response queue entries.
* @ha: SCSI driver HA context
Expand Down Expand Up @@ -2901,6 +2916,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
case CTIO_CRC2:
qlt_response_pkt_all_vps(vha, rsp, (response_t *)pkt);
break;
case PT_LS4_REQUEST:
qla24xx_nvme_ls4_iocb(vha, (struct pt_ls4_request *)pkt,
rsp->req);
break;
case NOTIFY_ACK_TYPE:
if (pkt->handle == QLA_TGT_SKIP_HANDLE)
qlt_response_pkt_all_vps(vha, rsp,
Expand Down
21 changes: 21 additions & 0 deletions drivers/scsi/qla2xxx/qla_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
}

#define EXTENDED_BB_CREDITS BIT_0
#define NVME_ENABLE_FLAG BIT_3

/*
* qla2x00_execute_fw
* Start adapter firmware.
Expand Down Expand Up @@ -601,6 +603,9 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
} else
mcp->mb[4] = 0;

if (ql2xnvmeenable && IS_QLA27XX(ha))
mcp->mb[4] |= NVME_ENABLE_FLAG;

if (ha->flags.exlogins_enabled)
mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;

Expand Down Expand Up @@ -941,6 +946,22 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
"%s: Firmware supports Exchange Offload 0x%x\n",
__func__, ha->fw_attributes_h);

/* bit 26 of fw_attributes */
if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable) {
struct init_cb_24xx *icb;

icb = (struct init_cb_24xx *)ha->init_cb;
/*
* fw supports nvme and driver load
* parameter requested nvme
*/
vha->flags.nvme_enabled = 1;
icb->firmware_options_2 &= cpu_to_le32(~0xf);
ha->zio_mode = 0;
ha->zio_timer = 0;
}

}

if (IS_QLA27XX(ha)) {
Expand Down

0 comments on commit e84067d

Please sign in to comment.