xref: /titanic_52/usr/src/uts/common/io/nvme/nvme_reg.h (revision 1188b15922ed58bf45acc792330e9649bd3166cf)
13c9168faSHans Rosenfeld /*
23c9168faSHans Rosenfeld  * This file and its contents are supplied under the terms of the
33c9168faSHans Rosenfeld  * Common Development and Distribution License ("CDDL"), version 1.0.
43c9168faSHans Rosenfeld  * You may only use this file in accordance with the terms of version
53c9168faSHans Rosenfeld  * 1.0 of the CDDL.
63c9168faSHans Rosenfeld  *
73c9168faSHans Rosenfeld  * A full copy of the text of the CDDL should have accompanied this
83c9168faSHans Rosenfeld  * source.  A copy of the CDDL is also available via the Internet at
93c9168faSHans Rosenfeld  * http://www.illumos.org/license/CDDL.
103c9168faSHans Rosenfeld  */
113c9168faSHans Rosenfeld 
123c9168faSHans Rosenfeld /*
1337774c1bSHans Rosenfeld  * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
14*1188b159SRobert Mustacchi  * Copyright (c) 2018, Joyent, Inc.
153c9168faSHans Rosenfeld  */
163c9168faSHans Rosenfeld 
173c9168faSHans Rosenfeld /*
183c9168faSHans Rosenfeld  * NVMe hardware interface
193c9168faSHans Rosenfeld  */
203c9168faSHans Rosenfeld 
213c9168faSHans Rosenfeld #ifndef _NVME_REG_H
223c9168faSHans Rosenfeld #define	_NVME_REG_H
233c9168faSHans Rosenfeld 
24ecee5a1fSHans Rosenfeld #include <sys/nvme.h>
25ecee5a1fSHans Rosenfeld 
263c9168faSHans Rosenfeld #pragma pack(1)
273c9168faSHans Rosenfeld 
283c9168faSHans Rosenfeld #ifdef __cplusplus
293c9168faSHans Rosenfeld extern "C" {
303c9168faSHans Rosenfeld #endif
313c9168faSHans Rosenfeld 
323c9168faSHans Rosenfeld 
333c9168faSHans Rosenfeld /*
343c9168faSHans Rosenfeld  * NVMe constants
353c9168faSHans Rosenfeld  */
363c9168faSHans Rosenfeld #define	NVME_MAX_ADMIN_QUEUE_LEN	4096
373c9168faSHans Rosenfeld 
383c9168faSHans Rosenfeld /*
393c9168faSHans Rosenfeld  * NVMe registers and register fields
403c9168faSHans Rosenfeld  */
413c9168faSHans Rosenfeld #define	NVME_REG_CAP	0x0		/* Controller Capabilities */
423c9168faSHans Rosenfeld #define	NVME_REG_VS	0x8		/* Version */
433c9168faSHans Rosenfeld #define	NVME_REG_INTMS	0xc		/* Interrupt Mask Set */
443c9168faSHans Rosenfeld #define	NVME_REG_INTMC	0x10		/* Interrupt Mask Clear */
453c9168faSHans Rosenfeld #define	NVME_REG_CC	0x14		/* Controller Configuration */
463c9168faSHans Rosenfeld #define	NVME_REG_CSTS	0x1c		/* Controller Status */
473c9168faSHans Rosenfeld #define	NVME_REG_NSSR	0x20		/* NVM Subsystem Reset */
483c9168faSHans Rosenfeld #define	NVME_REG_AQA	0x24		/* Admin Queue Attributes */
493c9168faSHans Rosenfeld #define	NVME_REG_ASQ	0x28		/* Admin Submission Queue */
503c9168faSHans Rosenfeld #define	NVME_REG_ACQ	0x30		/* Admin Completion Qeueu */
51*1188b159SRobert Mustacchi #define	NVME_REG_CMBLOC	0x38		/* Controller Memory Buffer Location */
52*1188b159SRobert Mustacchi #define	NVME_REG_CMBSZ	0x3C		/* Controller Memory Buffer Size */
53*1188b159SRobert Mustacchi #define	NVME_REG_BPINFO	0x40		/* Boot Partition Information */
54*1188b159SRobert Mustacchi #define	NVME_REG_BPRSEL	0x44		/* Boot Partition Read Select */
55*1188b159SRobert Mustacchi #define	NVME_REG_BPMBL	0x48		/* Boot Partition Memory Buffer Loc */
563c9168faSHans Rosenfeld #define	NVME_REG_SQTDBL(nvme, n) \
573c9168faSHans Rosenfeld 	(0x1000 + ((2 * (n)) * nvme->n_doorbell_stride))
583c9168faSHans Rosenfeld #define	NVME_REG_CQHDBL(nvme, n) \
593c9168faSHans Rosenfeld 	(0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride))
603c9168faSHans Rosenfeld 
613c9168faSHans Rosenfeld #define	 NVME_CAP_CSS_NVM	1	/* NVM Command Set */
623c9168faSHans Rosenfeld #define	 NVME_CAP_AMS_WRR	1	/* Weighted Round-Robin */
633c9168faSHans Rosenfeld 
643c9168faSHans Rosenfeld /* CAP -- Controller Capabilities */
653c9168faSHans Rosenfeld typedef union {
663c9168faSHans Rosenfeld 	struct {
673c9168faSHans Rosenfeld 		uint16_t cap_mqes;	/* Maximum Queue Entries Supported */
683c9168faSHans Rosenfeld 		uint8_t cap_cqr:1;	/* Contiguous Queues Required */
693c9168faSHans Rosenfeld 		uint8_t cap_ams:2;	/* Arbitration Mechanisms Supported */
703c9168faSHans Rosenfeld 		uint8_t cap_rsvd1:5;
713c9168faSHans Rosenfeld 		uint8_t cap_to;		/* Timeout */
723c9168faSHans Rosenfeld 		uint16_t cap_dstrd:4;	/* Doorbell Stride */
733c9168faSHans Rosenfeld 		uint16_t cap_nssrs:1;	/* NVM Subsystem Reset Supported */
743c9168faSHans Rosenfeld 		uint16_t cap_css:8;	/* Command Sets Supported */
75*1188b159SRobert Mustacchi 		uint16_t cap_rsvd2:2;
76*1188b159SRobert Mustacchi 		uint8_t cap_bps:1;	/* Boot Partition Support */
773c9168faSHans Rosenfeld 		uint8_t cap_mpsmin:4;	/* Memory Page Size Minimum */
783c9168faSHans Rosenfeld 		uint8_t cap_mpsmax:4;	/* Memory Page Size Maximum */
793c9168faSHans Rosenfeld 		uint8_t cap_rsvd3;
803c9168faSHans Rosenfeld 	} b;
813c9168faSHans Rosenfeld 	uint64_t r;
823c9168faSHans Rosenfeld } nvme_reg_cap_t;
833c9168faSHans Rosenfeld 
843c9168faSHans Rosenfeld /* VS -- Version */
853c9168faSHans Rosenfeld typedef union {
863c9168faSHans Rosenfeld 	struct {
873c9168faSHans Rosenfeld 		uint8_t vs_rsvd;
883c9168faSHans Rosenfeld 		uint8_t vs_mnr;		/* Minor Version Number */
893c9168faSHans Rosenfeld 		uint16_t vs_mjr;	/* Major Version Number */
903c9168faSHans Rosenfeld 	} b;
913c9168faSHans Rosenfeld 	uint32_t r;
923c9168faSHans Rosenfeld } nvme_reg_vs_t;
933c9168faSHans Rosenfeld 
943c9168faSHans Rosenfeld /* CC -- Controller Configuration */
953c9168faSHans Rosenfeld #define	NVME_CC_SHN_NORMAL	1	/* Normal Shutdown Notification */
963c9168faSHans Rosenfeld #define	NVME_CC_SHN_ABRUPT	2	/* Abrupt Shutdown Notification */
973c9168faSHans Rosenfeld 
983c9168faSHans Rosenfeld typedef union {
993c9168faSHans Rosenfeld 	struct {
1003c9168faSHans Rosenfeld 		uint16_t cc_en:1;	/* Enable */
1013c9168faSHans Rosenfeld 		uint16_t cc_rsvd1:3;
1023c9168faSHans Rosenfeld 		uint16_t cc_css:3;	/* I/O Command Set Selected */
1033c9168faSHans Rosenfeld 		uint16_t cc_mps:4;	/* Memory Page Size */
1043c9168faSHans Rosenfeld 		uint16_t cc_ams:3;	/* Arbitration Mechanism Selected */
1053c9168faSHans Rosenfeld 		uint16_t cc_shn:2;	/* Shutdown Notification */
1063c9168faSHans Rosenfeld 		uint8_t cc_iosqes:4;	/* I/O Submission Queue Entry Size */
1073c9168faSHans Rosenfeld 		uint8_t cc_iocqes:4;	/* I/O Completion Queue Entry Size */
1083c9168faSHans Rosenfeld 		uint8_t cc_rsvd2;
1093c9168faSHans Rosenfeld 	} b;
1103c9168faSHans Rosenfeld 	uint32_t r;
1113c9168faSHans Rosenfeld } nvme_reg_cc_t;
1123c9168faSHans Rosenfeld 
1133c9168faSHans Rosenfeld /* CSTS -- Controller Status */
1143c9168faSHans Rosenfeld #define	NVME_CSTS_SHN_OCCURING	1	/* Shutdown Processing Occuring */
1153c9168faSHans Rosenfeld #define	NVME_CSTS_SHN_COMPLETE	2	/* Shutdown Processing Complete */
1163c9168faSHans Rosenfeld 
1173c9168faSHans Rosenfeld typedef union {
1183c9168faSHans Rosenfeld 	struct {
1193c9168faSHans Rosenfeld 		uint32_t csts_rdy:1;	/* Ready */
1203c9168faSHans Rosenfeld 		uint32_t csts_cfs:1;	/* Controller Fatal Status */
1213c9168faSHans Rosenfeld 		uint32_t csts_shst:2;	/* Shutdown Status */
1223c9168faSHans Rosenfeld 		uint32_t csts_nssro:1;	/* NVM Subsystem Reset Occured */
123*1188b159SRobert Mustacchi 		uint32_t csts_pp:1;	/* Processing Paused */
124*1188b159SRobert Mustacchi 		uint32_t csts_rsvd:26;
1253c9168faSHans Rosenfeld 	} b;
1263c9168faSHans Rosenfeld 	uint32_t r;
1273c9168faSHans Rosenfeld } nvme_reg_csts_t;
1283c9168faSHans Rosenfeld 
1293c9168faSHans Rosenfeld /* NSSR -- NVM Subsystem Reset */
1303c9168faSHans Rosenfeld #define	NVME_NSSR_NSSRC	0x4e564d65	/* NSSR magic value */
1313c9168faSHans Rosenfeld typedef uint32_t nvme_reg_nssr_t;
1323c9168faSHans Rosenfeld 
1333c9168faSHans Rosenfeld /* AQA -- Admin Queue Attributes */
1343c9168faSHans Rosenfeld typedef union {
1353c9168faSHans Rosenfeld 	struct {
1363c9168faSHans Rosenfeld 		uint16_t aqa_asqs:12;	/* Admin Submission Queue Size */
1373c9168faSHans Rosenfeld 		uint16_t aqa_rsvd1:4;
1383c9168faSHans Rosenfeld 		uint16_t aqa_acqs:12;	/* Admin Completion Queue Size */
1393c9168faSHans Rosenfeld 		uint16_t aqa_rsvd2:4;
1403c9168faSHans Rosenfeld 	} b;
1413c9168faSHans Rosenfeld 	uint32_t r;
1423c9168faSHans Rosenfeld } nvme_reg_aqa_t;
1433c9168faSHans Rosenfeld 
1443c9168faSHans Rosenfeld /*
1453c9168faSHans Rosenfeld  * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is
1463c9168faSHans Rosenfeld  * probably a specification bug. The full 64bit regs are used as base address,
1473c9168faSHans Rosenfeld  * and the lower bits must be zero to ensure alignment on the page size
1483c9168faSHans Rosenfeld  * specified in CC.MPS.
1493c9168faSHans Rosenfeld  */
1503c9168faSHans Rosenfeld /* ASQ -- Admin Submission Queue Base Address */
1513c9168faSHans Rosenfeld typedef uint64_t nvme_reg_asq_t;	/* Admin Submission Queue Base */
1523c9168faSHans Rosenfeld 
1533c9168faSHans Rosenfeld /* ACQ -- Admin Completion Queue Base Address */
1543c9168faSHans Rosenfeld typedef uint64_t nvme_reg_acq_t;	/* Admin Completion Queue Base */
1553c9168faSHans Rosenfeld 
156*1188b159SRobert Mustacchi /* CMBLOC - Controller Memory Buffer Location */
157*1188b159SRobert Mustacchi typedef union {
158*1188b159SRobert Mustacchi 	struct {
159*1188b159SRobert Mustacchi 		uint32_t cmbloc_bir:3;		/* Base Indicator Register */
160*1188b159SRobert Mustacchi 		uint32_t cmbloc_rsvd:9;
161*1188b159SRobert Mustacchi 		uint32_t cmbloc_ofst:20;	/* Offset */
162*1188b159SRobert Mustacchi 	} b;
163*1188b159SRobert Mustacchi 	uint32_t r;
164*1188b159SRobert Mustacchi } nvme_reg_cmbloc_t;
165*1188b159SRobert Mustacchi 
166*1188b159SRobert Mustacchi /* CMBSZ - Controller Memory Buffer Size */
167*1188b159SRobert Mustacchi typedef union {
168*1188b159SRobert Mustacchi 	struct {
169*1188b159SRobert Mustacchi 		uint32_t cmbsz_sqs:1;	/* Submission Queue Support */
170*1188b159SRobert Mustacchi 		uint32_t cmbsz_cqs:1;	/* Completion Queue Support */
171*1188b159SRobert Mustacchi 		uint32_t cmbsz_lists:1;	/* PRP SGL List Support */
172*1188b159SRobert Mustacchi 		uint32_t cmbsz_rds:1;	/* Read Data Support */
173*1188b159SRobert Mustacchi 		uint32_t cmbsz_wds:1;	/* Write Data Support */
174*1188b159SRobert Mustacchi 		uint32_t cmbsz_rsvd:3;
175*1188b159SRobert Mustacchi 		uint32_t cmbsz_szu:4;	/* Size Units */
176*1188b159SRobert Mustacchi 		uint32_t cmbsz_sz:20;	/* Size */
177*1188b159SRobert Mustacchi 	} b;
178*1188b159SRobert Mustacchi 	uint32_t r;
179*1188b159SRobert Mustacchi } nvme_reg_cmbsz_t;
180*1188b159SRobert Mustacchi 
181*1188b159SRobert Mustacchi /* BPINFO - Boot Partition Information */
182*1188b159SRobert Mustacchi typedef union {
183*1188b159SRobert Mustacchi 	struct {
184*1188b159SRobert Mustacchi 		uint32_t bpinfo_bpsz:15;	/* Boot Partition Size */
185*1188b159SRobert Mustacchi 		uint32_t bpinfo_rsvd:9;
186*1188b159SRobert Mustacchi 		uint32_t bpinfo_brs:2;		/* Boot Read Status */
187*1188b159SRobert Mustacchi 		uint32_t bpinfo_rsvd2:5;
188*1188b159SRobert Mustacchi 		uint32_t bpinfo_abpid:1;	/* Active Boot Partition ID */
189*1188b159SRobert Mustacchi 	} b;
190*1188b159SRobert Mustacchi 	uint32_t r;
191*1188b159SRobert Mustacchi } nvme_reg_bpinfo_t;
192*1188b159SRobert Mustacchi 
193*1188b159SRobert Mustacchi /* BPRSEL - Boot Partition Read Select */
194*1188b159SRobert Mustacchi typedef union {
195*1188b159SRobert Mustacchi 	struct {
196*1188b159SRobert Mustacchi 		uint32_t bprsel_bprsz:10;	/* Boot Partition Read Size */
197*1188b159SRobert Mustacchi 		uint32_t bprsel_bprof:20;	/* Boot Partition Read Offset */
198*1188b159SRobert Mustacchi 		uint32_t bprsel_rsvd:1;
199*1188b159SRobert Mustacchi 		uint32_t bprsel_bpid:1;		/* Boot Partition Identifier */
200*1188b159SRobert Mustacchi 	} b;
201*1188b159SRobert Mustacchi 	uint32_t r;
202*1188b159SRobert Mustacchi } nvme_reg_bprsel_t;
203*1188b159SRobert Mustacchi 
204*1188b159SRobert Mustacchi /* BPMBL - Boot Partition Memory Location Buffer Location */
205*1188b159SRobert Mustacchi typedef uint64_t nvme_reg_bpbml_t;	/* Memory Buffer Base Address */
206*1188b159SRobert Mustacchi 
2073c9168faSHans Rosenfeld /* SQyTDBL -- Submission Queue y Tail Doorbell */
2083c9168faSHans Rosenfeld typedef union {
2093c9168faSHans Rosenfeld 	struct {
2103c9168faSHans Rosenfeld 		uint16_t sqtdbl_sqt;	/* Submission Queue Tail */
2113c9168faSHans Rosenfeld 		uint16_t sqtdbl_rsvd;
2123c9168faSHans Rosenfeld 	} b;
2133c9168faSHans Rosenfeld 	uint32_t r;
2143c9168faSHans Rosenfeld } nvme_reg_sqtdbl_t;
2153c9168faSHans Rosenfeld 
2163c9168faSHans Rosenfeld /* CQyHDBL -- Completion Queue y Head Doorbell */
2173c9168faSHans Rosenfeld typedef union {
2183c9168faSHans Rosenfeld 	struct {
2193c9168faSHans Rosenfeld 		uint16_t cqhdbl_cqh;	/* Completion Queue Head */
2203c9168faSHans Rosenfeld 		uint16_t cqhdbl_rsvd;
2213c9168faSHans Rosenfeld 	} b;
2223c9168faSHans Rosenfeld 	uint32_t r;
2233c9168faSHans Rosenfeld } nvme_reg_cqhdbl_t;
2243c9168faSHans Rosenfeld 
2253c9168faSHans Rosenfeld /*
2263c9168faSHans Rosenfeld  * NVMe submission queue entries
2273c9168faSHans Rosenfeld  */
2283c9168faSHans Rosenfeld 
2293c9168faSHans Rosenfeld /* NVMe scatter/gather list descriptor */
2303c9168faSHans Rosenfeld typedef struct {
2313c9168faSHans Rosenfeld 	uint64_t sgl_addr;		/* Address */
2323c9168faSHans Rosenfeld 	uint32_t sgl_len;		/* Length */
2333c9168faSHans Rosenfeld 	uint8_t sgl_rsvd[3];
2343c9168faSHans Rosenfeld 	uint8_t sgl_zero:4;
2353c9168faSHans Rosenfeld 	uint8_t sgl_type:4;		/* SGL descriptor type */
2363c9168faSHans Rosenfeld } nvme_sgl_t;
2373c9168faSHans Rosenfeld 
2383c9168faSHans Rosenfeld /* NVMe SGL descriptor type */
2393c9168faSHans Rosenfeld #define	NVME_SGL_DATA_BLOCK	0
2403c9168faSHans Rosenfeld #define	NVME_SGL_BIT_BUCKET	1
2413c9168faSHans Rosenfeld #define	NVME_SGL_SEGMENT	2
2423c9168faSHans Rosenfeld #define	NVME_SGL_LAST_SEGMENT	3
2433c9168faSHans Rosenfeld #define	NVME_SGL_VENDOR		0xf
2443c9168faSHans Rosenfeld 
2453c9168faSHans Rosenfeld /* NVMe submission queue entry */
2463c9168faSHans Rosenfeld typedef struct {
2473c9168faSHans Rosenfeld 	uint8_t sqe_opc;		/* Opcode */
2483c9168faSHans Rosenfeld 	uint8_t sqe_fuse:2;		/* Fused Operation */
2493c9168faSHans Rosenfeld 	uint8_t sqe_rsvd:5;
2503c9168faSHans Rosenfeld 	uint8_t sqe_psdt:1;		/* PRP or SGL for Data Transfer */
2513c9168faSHans Rosenfeld 	uint16_t sqe_cid;		/* Command Identifier */
2523c9168faSHans Rosenfeld 	uint32_t sqe_nsid;		/* Namespace Identifier */
2533c9168faSHans Rosenfeld 	uint64_t sqe_rsvd1;
2543c9168faSHans Rosenfeld 	union {
2553c9168faSHans Rosenfeld 		uint64_t m_ptr;		/* Metadata Pointer */
2563c9168faSHans Rosenfeld 		uint64_t m_sglp;	/* Metadata SGL Segment Pointer */
2573c9168faSHans Rosenfeld 	} sqe_m;
2583c9168faSHans Rosenfeld 	union {
2593c9168faSHans Rosenfeld 		uint64_t d_prp[2];	/* Physical Page Region Entries 1 & 2 */
2603c9168faSHans Rosenfeld 		nvme_sgl_t d_sgl;	/* SGL Entry 1 */
2613c9168faSHans Rosenfeld 	} sqe_dptr;			/* Data Pointer */
2623c9168faSHans Rosenfeld 	uint32_t sqe_cdw10;		/* Number of Dwords in Data Transfer */
2633c9168faSHans Rosenfeld 	uint32_t sqe_cdw11;		/* Number of Dwords in Metadata Xfer */
2643c9168faSHans Rosenfeld 	uint32_t sqe_cdw12;
2653c9168faSHans Rosenfeld 	uint32_t sqe_cdw13;
2663c9168faSHans Rosenfeld 	uint32_t sqe_cdw14;
2673c9168faSHans Rosenfeld 	uint32_t sqe_cdw15;
2683c9168faSHans Rosenfeld } nvme_sqe_t;
2693c9168faSHans Rosenfeld 
2703c9168faSHans Rosenfeld /* NVMe admin command opcodes */
2713c9168faSHans Rosenfeld #define	NVME_OPC_DELETE_SQUEUE	0x0
2723c9168faSHans Rosenfeld #define	NVME_OPC_CREATE_SQUEUE	0x1
2733c9168faSHans Rosenfeld #define	NVME_OPC_GET_LOG_PAGE	0x2
2743c9168faSHans Rosenfeld #define	NVME_OPC_DELETE_CQUEUE	0x4
2753c9168faSHans Rosenfeld #define	NVME_OPC_CREATE_CQUEUE	0x5
2763c9168faSHans Rosenfeld #define	NVME_OPC_IDENTIFY	0x6
2773c9168faSHans Rosenfeld #define	NVME_OPC_ABORT		0x8
2783c9168faSHans Rosenfeld #define	NVME_OPC_SET_FEATURES	0x9
2793c9168faSHans Rosenfeld #define	NVME_OPC_GET_FEATURES	0xa
2803c9168faSHans Rosenfeld #define	NVME_OPC_ASYNC_EVENT	0xc
281*1188b159SRobert Mustacchi #define	NVME_OPC_NS_MGMT	0xd	/* 1.2 */
2823c9168faSHans Rosenfeld #define	NVME_OPC_FW_ACTIVATE	0x10
2833c9168faSHans Rosenfeld #define	NVME_OPC_FW_IMAGE_LOAD	0x11
284*1188b159SRobert Mustacchi #define	NVME_OPC_SELF_TEST	0x14	/* 1.3 */
285*1188b159SRobert Mustacchi #define	NVME_OPC_NS_ATTACH	0x15	/* 1.2 */
286*1188b159SRobert Mustacchi #define	NVME_OPC_KEEP_ALIVE	0x18	/* 1.3 */
287*1188b159SRobert Mustacchi #define	NVME_OPC_DIRECTIVE_SEND	0x19	/* 1.3 */
288*1188b159SRobert Mustacchi #define	NVME_OPC_DIRECTIVE_RECV	0x1A	/* 1.3 */
289*1188b159SRobert Mustacchi #define	NVME_OPC_VIRT_MGMT	0x1C	/* 1.3 */
290*1188b159SRobert Mustacchi #define	NVME_OPC_NVMEMI_SEND	0x1D	/* 1.3 */
291*1188b159SRobert Mustacchi #define	NVME_OPC_NVMEMI_RECV	0x1E	/* 1.3 */
292*1188b159SRobert Mustacchi #define	NVME_OPC_DB_CONFIG	0x7C	/* 1.3 */
2933c9168faSHans Rosenfeld 
2943c9168faSHans Rosenfeld /* NVMe NVM command set specific admin command opcodes */
2953c9168faSHans Rosenfeld #define	NVME_OPC_NVM_FORMAT	0x80
2963c9168faSHans Rosenfeld #define	NVME_OPC_NVM_SEC_SEND	0x81
2973c9168faSHans Rosenfeld #define	NVME_OPC_NVM_SEC_RECV	0x82
2983c9168faSHans Rosenfeld 
2993c9168faSHans Rosenfeld /* NVMe NVM command opcodes */
3003c9168faSHans Rosenfeld #define	NVME_OPC_NVM_FLUSH	0x0
3013c9168faSHans Rosenfeld #define	NVME_OPC_NVM_WRITE	0x1
3023c9168faSHans Rosenfeld #define	NVME_OPC_NVM_READ	0x2
3033c9168faSHans Rosenfeld #define	NVME_OPC_NVM_WRITE_UNC	0x4
3043c9168faSHans Rosenfeld #define	NVME_OPC_NVM_COMPARE	0x5
3053c9168faSHans Rosenfeld #define	NVME_OPC_NVM_WRITE_ZERO	0x8
3063c9168faSHans Rosenfeld #define	NVME_OPC_NVM_DSET_MGMT	0x9
3073c9168faSHans Rosenfeld #define	NVME_OPC_NVM_RESV_REG	0xd
3083c9168faSHans Rosenfeld #define	NVME_OPC_NVM_RESV_REPRT	0xe
3093c9168faSHans Rosenfeld #define	NVME_OPC_NVM_RESV_ACQ	0x11
3103c9168faSHans Rosenfeld #define	NVME_OPC_NVM_RESV_REL	0x12
3113c9168faSHans Rosenfeld 
3123c9168faSHans Rosenfeld /*
3133c9168faSHans Rosenfeld  * NVMe completion queue entry
3143c9168faSHans Rosenfeld  */
3153c9168faSHans Rosenfeld typedef struct {
3163c9168faSHans Rosenfeld 	uint32_t cqe_dw0;		/* Command Specific */
3173c9168faSHans Rosenfeld 	uint32_t cqe_rsvd1;
3183c9168faSHans Rosenfeld 	uint16_t cqe_sqhd;		/* SQ Head Pointer */
3193c9168faSHans Rosenfeld 	uint16_t cqe_sqid;		/* SQ Identifier */
3203c9168faSHans Rosenfeld 	uint16_t cqe_cid;		/* Command Identifier */
3213c9168faSHans Rosenfeld 	nvme_cqe_sf_t cqe_sf;		/* Status Field */
3223c9168faSHans Rosenfeld } nvme_cqe_t;
3233c9168faSHans Rosenfeld 
3243c9168faSHans Rosenfeld /* NVMe completion status code type */
3253c9168faSHans Rosenfeld #define	NVME_CQE_SCT_GENERIC	0	/* Generic Command Status */
3263c9168faSHans Rosenfeld #define	NVME_CQE_SCT_SPECIFIC	1	/* Command Specific Status */
3273c9168faSHans Rosenfeld #define	NVME_CQE_SCT_INTEGRITY	2	/* Media and Data Integrity Errors */
3283c9168faSHans Rosenfeld #define	NVME_CQE_SCT_VENDOR	7	/* Vendor Specific */
3293c9168faSHans Rosenfeld 
3303c9168faSHans Rosenfeld /* NVMe completion status code (generic) */
3313c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_SUCCESS		0x0	/* Successful Completion */
3323c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INV_OPC		0x1	/* Invalid Command Opcode */
3333c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INV_FLD		0x2	/* Invalid Field in Command */
3343c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_ID_CNFL		0x3	/* Command ID Conflict */
3353c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_DATA_XFR_ERR	0x4	/* Data Transfer Error */
3363c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_ABORT_PWRLOSS	0x5	/* Cmds Aborted / Pwr Loss */
3373c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INTERNAL_ERR	0x6	/* Internal Error */
3383c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_ABORT_REQUEST	0x7	/* Command Abort Requested */
3393c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_ABORT_SQ_DEL	0x8	/* Cmd Aborted / SQ deletion */
3403c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_ABORT_FUSE_FAIL	0x9	/* Cmd Aborted / Failed Fused */
3413c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_ABORT_FUSE_MISS	0xa	/* Cmd Aborted / Missing Fusd */
3423c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INV_NS		0xb	/* Inval Namespace or Format */
3433c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_CMD_SEQ_ERR	0xc	/* Command Sequence Error */
3443c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INV_SGL_LAST	0xd	/* Inval SGL Last Seg Desc */
3453c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INV_SGL_NUM	0xe	/* Inval Number of SGL Desc */
3463c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INV_DSGL_LEN	0xf	/* Data SGL Length Invalid */
3473c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INV_MSGL_LEN	0x10	/* Metadata SGL Length Inval */
3483c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_INV_SGL_DESC	0x11	/* SGL Descriptor Type Inval */
3493c9168faSHans Rosenfeld 
3503c9168faSHans Rosenfeld /* NVMe completion status code (generic NVM commands) */
3513c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_NVM_LBA_RANGE	0x80	/* LBA Out Of Range */
3523c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_NVM_CAP_EXC	0x81	/* Capacity Exceeded */
3533c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_NVM_NS_NOTRDY	0x82	/* Namespace Not Ready */
3543c9168faSHans Rosenfeld #define	NVME_CQE_SC_GEN_NVM_RSV_CNFLCT	0x83	/* Reservation Conflict */
3553c9168faSHans Rosenfeld 
3563c9168faSHans Rosenfeld /* NVMe completion status code (command specific) */
3573c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_INV_CQ		0x0	/* Completion Queue Invalid */
3583c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_INV_QID		0x1	/* Invalid Queue Identifier */
3593c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_MAX_QSZ_EXC	0x2	/* Max Queue Size Exceeded */
3603c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_ABRT_CMD_EXC	0x3	/* Abort Cmd Limit Exceeded */
3613c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC	0x5	/* Async Event Request Limit */
3623c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_INV_FW_SLOT	0x6	/* Invalid Firmware Slot */
3633c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_INV_FW_IMG	0x7	/* Invalid Firmware Image */
3643c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_INV_INT_VECT	0x8	/* Invalid Interrupt Vector */
3653c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_INV_LOG_PAGE	0x9	/* Invalid Log Page */
3663c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_INV_FORMAT	0xa	/* Invalid Format */
3673c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_FW_RESET	0xb	/* FW Application Reset Reqd */
3683c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_INV_Q_DEL	0xc	/* Invalid Queue Deletion */
3693c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_FEAT_SAVE	0xd	/* Feature Id Not Saveable */
3703c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_FEAT_CHG	0xe	/* Feature Not Changeable */
3713c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_FEAT_NS_SPEC	0xf	/* Feature Not Namespace Spec */
3723c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_FW_NSSR		0x10	/* FW Application NSSR Reqd */
3733c9168faSHans Rosenfeld 
3743c9168faSHans Rosenfeld /* NVMe completion status code (NVM command specific */
3753c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_NVM_CNFL_ATTR	0x80	/* Conflicting Attributes */
3763c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_NVM_INV_PROT	0x81	/* Invalid Protection */
3773c9168faSHans Rosenfeld #define	NVME_CQE_SC_SPC_NVM_READONLY	0x82	/* Write to Read Only Range */
3783c9168faSHans Rosenfeld 
3793c9168faSHans Rosenfeld /* NVMe completion status code (data / metadata integrity) */
3803c9168faSHans Rosenfeld #define	NVME_CQE_SC_INT_NVM_WRITE	0x80	/* Write Fault */
3813c9168faSHans Rosenfeld #define	NVME_CQE_SC_INT_NVM_READ	0x81	/* Unrecovered Read Error */
3823c9168faSHans Rosenfeld #define	NVME_CQE_SC_INT_NVM_GUARD	0x82	/* Guard Check Error */
3833c9168faSHans Rosenfeld #define	NVME_CQE_SC_INT_NVM_APPL_TAG	0x83	/* Application Tag Check Err */
3843c9168faSHans Rosenfeld #define	NVME_CQE_SC_INT_NVM_REF_TAG	0x84	/* Reference Tag Check Err */
3853c9168faSHans Rosenfeld #define	NVME_CQE_SC_INT_NVM_COMPARE	0x85	/* Compare Failure */
3863c9168faSHans Rosenfeld #define	NVME_CQE_SC_INT_NVM_ACCESS	0x86	/* Access Denied */
3873c9168faSHans Rosenfeld 
3883c9168faSHans Rosenfeld /*
3893c9168faSHans Rosenfeld  * NVMe Asynchronous Event Request
3903c9168faSHans Rosenfeld  */
3913c9168faSHans Rosenfeld #define	NVME_ASYNC_TYPE_ERROR		0x0	/* Error Status */
3923c9168faSHans Rosenfeld #define	NVME_ASYNC_TYPE_HEALTH		0x1	/* SMART/Health Status */
3933c9168faSHans Rosenfeld #define	NVME_ASYNC_TYPE_VENDOR		0x7	/* vendor specific */
3943c9168faSHans Rosenfeld 
3953c9168faSHans Rosenfeld #define	NVME_ASYNC_ERROR_INV_SQ		0x0	/* Invalid Submission Queue */
3963c9168faSHans Rosenfeld #define	NVME_ASYNC_ERROR_INV_DBL	0x1	/* Invalid Doorbell Write */
3973c9168faSHans Rosenfeld #define	NVME_ASYNC_ERROR_DIAGFAIL	0x2	/* Diagnostic Failure */
3983c9168faSHans Rosenfeld #define	NVME_ASYNC_ERROR_PERSISTENT	0x3	/* Persistent Internal Error */
3993c9168faSHans Rosenfeld #define	NVME_ASYNC_ERROR_TRANSIENT	0x4	/* Transient Internal Error */
4003c9168faSHans Rosenfeld #define	NVME_ASYNC_ERROR_FW_LOAD	0x5	/* Firmware Image Load Error */
4013c9168faSHans Rosenfeld 
4023c9168faSHans Rosenfeld #define	NVME_ASYNC_HEALTH_RELIABILITY	0x0	/* Device Reliability */
4033c9168faSHans Rosenfeld #define	NVME_ASYNC_HEALTH_TEMPERATURE	0x1	/* Temp. Above Threshold */
4043c9168faSHans Rosenfeld #define	NVME_ASYNC_HEALTH_SPARE		0x2	/* Spare Below Threshold */
4053c9168faSHans Rosenfeld 
4063c9168faSHans Rosenfeld typedef union {
4073c9168faSHans Rosenfeld 	struct {
4083c9168faSHans Rosenfeld 		uint8_t ae_type:3;		/* Asynchronous Event Type */
4093c9168faSHans Rosenfeld 		uint8_t ae_rsvd1:5;
4103c9168faSHans Rosenfeld 		uint8_t ae_info;		/* Asynchronous Event Info */
4113c9168faSHans Rosenfeld 		uint8_t ae_logpage;		/* Associated Log Page */
4123c9168faSHans Rosenfeld 		uint8_t ae_rsvd2;
4133c9168faSHans Rosenfeld 	} b;
4143c9168faSHans Rosenfeld 	uint32_t r;
4153c9168faSHans Rosenfeld } nvme_async_event_t;
4163c9168faSHans Rosenfeld 
4173c9168faSHans Rosenfeld /*
4183c9168faSHans Rosenfeld  * NVMe Create Completion/Submission Queue
4193c9168faSHans Rosenfeld  */
4203c9168faSHans Rosenfeld typedef union {
4213c9168faSHans Rosenfeld 	struct {
4223c9168faSHans Rosenfeld 		uint16_t q_qid;			/* Queue Identifier */
4233c9168faSHans Rosenfeld 		uint16_t q_qsize;		/* Queue Size */
4243c9168faSHans Rosenfeld 	} b;
4253c9168faSHans Rosenfeld 	uint32_t r;
4263c9168faSHans Rosenfeld } nvme_create_queue_dw10_t;
4273c9168faSHans Rosenfeld 
4283c9168faSHans Rosenfeld typedef union {
4293c9168faSHans Rosenfeld 	struct {
4303c9168faSHans Rosenfeld 		uint16_t cq_pc:1;		/* Physically Contiguous */
4313c9168faSHans Rosenfeld 		uint16_t cq_ien:1;		/* Interrupts Enabled */
4323c9168faSHans Rosenfeld 		uint16_t cq_rsvd:14;
4333c9168faSHans Rosenfeld 		uint16_t cq_iv;			/* Interrupt Vector */
4343c9168faSHans Rosenfeld 	} b;
4353c9168faSHans Rosenfeld 	uint32_t r;
4363c9168faSHans Rosenfeld } nvme_create_cq_dw11_t;
4373c9168faSHans Rosenfeld 
4383c9168faSHans Rosenfeld typedef union {
4393c9168faSHans Rosenfeld 	struct {
4403c9168faSHans Rosenfeld 		uint16_t sq_pc:1;		/* Physically Contiguous */
4413c9168faSHans Rosenfeld 		uint16_t sq_qprio:2;		/* Queue Priority */
4423c9168faSHans Rosenfeld 		uint16_t sq_rsvd:13;
4433c9168faSHans Rosenfeld 		uint16_t sq_cqid;		/* Completion Queue ID */
4443c9168faSHans Rosenfeld 	} b;
4453c9168faSHans Rosenfeld 	uint32_t r;
4463c9168faSHans Rosenfeld } nvme_create_sq_dw11_t;
4473c9168faSHans Rosenfeld 
4483c9168faSHans Rosenfeld /*
4493c9168faSHans Rosenfeld  * NVMe Identify
4503c9168faSHans Rosenfeld  */
4513c9168faSHans Rosenfeld 
4523c9168faSHans Rosenfeld /* NVMe Identify parameters (cdw10) */
4533c9168faSHans Rosenfeld #define	NVME_IDENTIFY_NSID	0x0	/* Identify Namespace */
4543c9168faSHans Rosenfeld #define	NVME_IDENTIFY_CTRL	0x1	/* Identify Controller */
4553c9168faSHans Rosenfeld #define	NVME_IDENTIFY_LIST	0x2	/* Identify List Namespaces */
4563c9168faSHans Rosenfeld 
457*1188b159SRobert Mustacchi #define	NVME_IDENTIFY_NSID_ALLOC_LIST	0x10	/* List Allocated NSID */
458*1188b159SRobert Mustacchi #define	NVME_IDENTIFY_NSID_ALLOC	0x11	/* Identify Allocated NSID */
459*1188b159SRobert Mustacchi #define	NVME_IDENTIFY_NSID_CTRL_LIST	0x12	/* List Controllers on NSID */
460*1188b159SRobert Mustacchi #define	NVME_IDENTIFY_CTRL_LIST		0x13	/* Controller List */
461*1188b159SRobert Mustacchi #define	NVME_IDENTIFY_PRIMARY_CAPS	0x14	/* Primary Controller Caps */
4623c9168faSHans Rosenfeld 
4633c9168faSHans Rosenfeld /*
4643c9168faSHans Rosenfeld  * NVMe Abort Command
4653c9168faSHans Rosenfeld  */
4663c9168faSHans Rosenfeld typedef union {
4673c9168faSHans Rosenfeld 	struct {
4683c9168faSHans Rosenfeld 		uint16_t ac_sqid;	/* Submission Queue ID */
4693c9168faSHans Rosenfeld 		uint16_t ac_cid;	/* Command ID */
4703c9168faSHans Rosenfeld 	} b;
4713c9168faSHans Rosenfeld 	uint32_t r;
4723c9168faSHans Rosenfeld } nvme_abort_cmd_t;
4733c9168faSHans Rosenfeld 
4743c9168faSHans Rosenfeld 
4753c9168faSHans Rosenfeld /*
4763c9168faSHans Rosenfeld  * NVMe Get Log Page
4773c9168faSHans Rosenfeld  */
4783c9168faSHans Rosenfeld typedef union {
4793c9168faSHans Rosenfeld 	struct {
4803c9168faSHans Rosenfeld 		uint8_t lp_lid;		/* Log Page Identifier */
4813c9168faSHans Rosenfeld 		uint8_t lp_rsvd1;
4823c9168faSHans Rosenfeld 		uint16_t lp_numd:12;	/* Number of Dwords */
4833c9168faSHans Rosenfeld 		uint16_t lp_rsvd2:4;
4843c9168faSHans Rosenfeld 	} b;
4853c9168faSHans Rosenfeld 	uint32_t r;
4863c9168faSHans Rosenfeld } nvme_getlogpage_t;
4873c9168faSHans Rosenfeld 
4883c9168faSHans Rosenfeld 
4893c9168faSHans Rosenfeld #ifdef __cplusplus
4903c9168faSHans Rosenfeld }
4913c9168faSHans Rosenfeld #endif
4923c9168faSHans Rosenfeld 
4933c9168faSHans Rosenfeld #pragma pack() /* pack(1) */
4943c9168faSHans Rosenfeld 
4953c9168faSHans Rosenfeld #endif /* _NVME_REG_H */
496