xref: /openbmc/u-boot/drivers/nvme/nvme.h (revision e8f80a5a)
1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
2982388eaSZhikang Zhang /*
3982388eaSZhikang Zhang  * Copyright (C) 2017 NXP Semiconductors
4982388eaSZhikang Zhang  * Copyright (C) 2017 Bin Meng <bmeng.cn@gmail.com>
5982388eaSZhikang Zhang  */
6982388eaSZhikang Zhang 
7982388eaSZhikang Zhang #ifndef __DRIVER_NVME_H__
8982388eaSZhikang Zhang #define __DRIVER_NVME_H__
9982388eaSZhikang Zhang 
10982388eaSZhikang Zhang #include <asm/io.h>
11982388eaSZhikang Zhang 
12982388eaSZhikang Zhang struct nvme_id_power_state {
13982388eaSZhikang Zhang 	__le16			max_power;	/* centiwatts */
14982388eaSZhikang Zhang 	__u8			rsvd2;
15982388eaSZhikang Zhang 	__u8			flags;
16982388eaSZhikang Zhang 	__le32			entry_lat;	/* microseconds */
17982388eaSZhikang Zhang 	__le32			exit_lat;	/* microseconds */
18982388eaSZhikang Zhang 	__u8			read_tput;
19982388eaSZhikang Zhang 	__u8			read_lat;
20982388eaSZhikang Zhang 	__u8			write_tput;
21982388eaSZhikang Zhang 	__u8			write_lat;
22982388eaSZhikang Zhang 	__le16			idle_power;
23982388eaSZhikang Zhang 	__u8			idle_scale;
24982388eaSZhikang Zhang 	__u8			rsvd19;
25982388eaSZhikang Zhang 	__le16			active_power;
26982388eaSZhikang Zhang 	__u8			active_work_scale;
27982388eaSZhikang Zhang 	__u8			rsvd23[9];
28982388eaSZhikang Zhang };
29982388eaSZhikang Zhang 
30982388eaSZhikang Zhang enum {
31982388eaSZhikang Zhang 	NVME_PS_FLAGS_MAX_POWER_SCALE	= 1 << 0,
32982388eaSZhikang Zhang 	NVME_PS_FLAGS_NON_OP_STATE	= 1 << 1,
33982388eaSZhikang Zhang };
34982388eaSZhikang Zhang 
35982388eaSZhikang Zhang struct nvme_id_ctrl {
36982388eaSZhikang Zhang 	__le16			vid;
37982388eaSZhikang Zhang 	__le16			ssvid;
38982388eaSZhikang Zhang 	char			sn[20];
39982388eaSZhikang Zhang 	char			mn[40];
40982388eaSZhikang Zhang 	char			fr[8];
41982388eaSZhikang Zhang 	__u8			rab;
42982388eaSZhikang Zhang 	__u8			ieee[3];
43982388eaSZhikang Zhang 	__u8			mic;
44982388eaSZhikang Zhang 	__u8			mdts;
45982388eaSZhikang Zhang 	__u16			cntlid;
46982388eaSZhikang Zhang 	__u32			ver;
47982388eaSZhikang Zhang 	__u8			rsvd84[172];
48982388eaSZhikang Zhang 	__le16			oacs;
49982388eaSZhikang Zhang 	__u8			acl;
50982388eaSZhikang Zhang 	__u8			aerl;
51982388eaSZhikang Zhang 	__u8			frmw;
52982388eaSZhikang Zhang 	__u8			lpa;
53982388eaSZhikang Zhang 	__u8			elpe;
54982388eaSZhikang Zhang 	__u8			npss;
55982388eaSZhikang Zhang 	__u8			avscc;
56982388eaSZhikang Zhang 	__u8			apsta;
57982388eaSZhikang Zhang 	__le16			wctemp;
58982388eaSZhikang Zhang 	__le16			cctemp;
59982388eaSZhikang Zhang 	__u8			rsvd270[242];
60982388eaSZhikang Zhang 	__u8			sqes;
61982388eaSZhikang Zhang 	__u8			cqes;
62982388eaSZhikang Zhang 	__u8			rsvd514[2];
63982388eaSZhikang Zhang 	__le32			nn;
64982388eaSZhikang Zhang 	__le16			oncs;
65982388eaSZhikang Zhang 	__le16			fuses;
66982388eaSZhikang Zhang 	__u8			fna;
67982388eaSZhikang Zhang 	__u8			vwc;
68982388eaSZhikang Zhang 	__le16			awun;
69982388eaSZhikang Zhang 	__le16			awupf;
70982388eaSZhikang Zhang 	__u8			nvscc;
71982388eaSZhikang Zhang 	__u8			rsvd531;
72982388eaSZhikang Zhang 	__le16			acwu;
73982388eaSZhikang Zhang 	__u8			rsvd534[2];
74982388eaSZhikang Zhang 	__le32			sgls;
75982388eaSZhikang Zhang 	__u8			rsvd540[1508];
76982388eaSZhikang Zhang 	struct nvme_id_power_state	psd[32];
77982388eaSZhikang Zhang 	__u8			vs[1024];
78982388eaSZhikang Zhang };
79982388eaSZhikang Zhang 
80982388eaSZhikang Zhang enum {
81982388eaSZhikang Zhang 	NVME_CTRL_ONCS_COMPARE			= 1 << 0,
82982388eaSZhikang Zhang 	NVME_CTRL_ONCS_WRITE_UNCORRECTABLE	= 1 << 1,
83982388eaSZhikang Zhang 	NVME_CTRL_ONCS_DSM			= 1 << 2,
84982388eaSZhikang Zhang 	NVME_CTRL_VWC_PRESENT			= 1 << 0,
85982388eaSZhikang Zhang };
86982388eaSZhikang Zhang 
87982388eaSZhikang Zhang struct nvme_lbaf {
88982388eaSZhikang Zhang 	__le16			ms;
89982388eaSZhikang Zhang 	__u8			ds;
90982388eaSZhikang Zhang 	__u8			rp;
91982388eaSZhikang Zhang };
92982388eaSZhikang Zhang 
93982388eaSZhikang Zhang struct nvme_id_ns {
94982388eaSZhikang Zhang 	__le64			nsze;
95982388eaSZhikang Zhang 	__le64			ncap;
96982388eaSZhikang Zhang 	__le64			nuse;
97982388eaSZhikang Zhang 	__u8			nsfeat;
98982388eaSZhikang Zhang 	__u8			nlbaf;
99982388eaSZhikang Zhang 	__u8			flbas;
100982388eaSZhikang Zhang 	__u8			mc;
101982388eaSZhikang Zhang 	__u8			dpc;
102982388eaSZhikang Zhang 	__u8			dps;
103982388eaSZhikang Zhang 	__u8			nmic;
104982388eaSZhikang Zhang 	__u8			rescap;
105982388eaSZhikang Zhang 	__u8			fpi;
106982388eaSZhikang Zhang 	__u8			rsvd33;
107982388eaSZhikang Zhang 	__le16			nawun;
108982388eaSZhikang Zhang 	__le16			nawupf;
109982388eaSZhikang Zhang 	__le16			nacwu;
110982388eaSZhikang Zhang 	__le16			nabsn;
111982388eaSZhikang Zhang 	__le16			nabo;
112982388eaSZhikang Zhang 	__le16			nabspf;
113982388eaSZhikang Zhang 	__u16			rsvd46;
114982388eaSZhikang Zhang 	__le64			nvmcap[2];
115982388eaSZhikang Zhang 	__u8			rsvd64[40];
116982388eaSZhikang Zhang 	__u8			nguid[16];
117982388eaSZhikang Zhang 	__u8			eui64[8];
118982388eaSZhikang Zhang 	struct nvme_lbaf	lbaf[16];
119982388eaSZhikang Zhang 	__u8			rsvd192[192];
120982388eaSZhikang Zhang 	__u8			vs[3712];
121982388eaSZhikang Zhang };
122982388eaSZhikang Zhang 
123982388eaSZhikang Zhang enum {
124982388eaSZhikang Zhang 	NVME_NS_FEAT_THIN	= 1 << 0,
125982388eaSZhikang Zhang 	NVME_NS_FLBAS_LBA_MASK	= 0xf,
126982388eaSZhikang Zhang 	NVME_NS_FLBAS_META_EXT	= 0x10,
127982388eaSZhikang Zhang 	NVME_LBAF_RP_BEST	= 0,
128982388eaSZhikang Zhang 	NVME_LBAF_RP_BETTER	= 1,
129982388eaSZhikang Zhang 	NVME_LBAF_RP_GOOD	= 2,
130982388eaSZhikang Zhang 	NVME_LBAF_RP_DEGRADED	= 3,
131982388eaSZhikang Zhang 	NVME_NS_DPC_PI_LAST	= 1 << 4,
132982388eaSZhikang Zhang 	NVME_NS_DPC_PI_FIRST	= 1 << 3,
133982388eaSZhikang Zhang 	NVME_NS_DPC_PI_TYPE3	= 1 << 2,
134982388eaSZhikang Zhang 	NVME_NS_DPC_PI_TYPE2	= 1 << 1,
135982388eaSZhikang Zhang 	NVME_NS_DPC_PI_TYPE1	= 1 << 0,
136982388eaSZhikang Zhang 	NVME_NS_DPS_PI_FIRST	= 1 << 3,
137982388eaSZhikang Zhang 	NVME_NS_DPS_PI_MASK	= 0x7,
138982388eaSZhikang Zhang 	NVME_NS_DPS_PI_TYPE1	= 1,
139982388eaSZhikang Zhang 	NVME_NS_DPS_PI_TYPE2	= 2,
140982388eaSZhikang Zhang 	NVME_NS_DPS_PI_TYPE3	= 3,
141982388eaSZhikang Zhang };
142982388eaSZhikang Zhang 
143982388eaSZhikang Zhang struct nvme_smart_log {
144982388eaSZhikang Zhang 	__u8			critical_warning;
145982388eaSZhikang Zhang 	__u8			temperature[2];
146982388eaSZhikang Zhang 	__u8			avail_spare;
147982388eaSZhikang Zhang 	__u8			spare_thresh;
148982388eaSZhikang Zhang 	__u8			percent_used;
149982388eaSZhikang Zhang 	__u8			rsvd6[26];
150982388eaSZhikang Zhang 	__u8			data_units_read[16];
151982388eaSZhikang Zhang 	__u8			data_units_written[16];
152982388eaSZhikang Zhang 	__u8			host_reads[16];
153982388eaSZhikang Zhang 	__u8			host_writes[16];
154982388eaSZhikang Zhang 	__u8			ctrl_busy_time[16];
155982388eaSZhikang Zhang 	__u8			power_cycles[16];
156982388eaSZhikang Zhang 	__u8			power_on_hours[16];
157982388eaSZhikang Zhang 	__u8			unsafe_shutdowns[16];
158982388eaSZhikang Zhang 	__u8			media_errors[16];
159982388eaSZhikang Zhang 	__u8			num_err_log_entries[16];
160982388eaSZhikang Zhang 	__le32			warning_temp_time;
161982388eaSZhikang Zhang 	__le32			critical_comp_time;
162982388eaSZhikang Zhang 	__le16			temp_sensor[8];
163982388eaSZhikang Zhang 	__u8			rsvd216[296];
164982388eaSZhikang Zhang };
165982388eaSZhikang Zhang 
166982388eaSZhikang Zhang enum {
167982388eaSZhikang Zhang 	NVME_SMART_CRIT_SPARE		= 1 << 0,
168982388eaSZhikang Zhang 	NVME_SMART_CRIT_TEMPERATURE	= 1 << 1,
169982388eaSZhikang Zhang 	NVME_SMART_CRIT_RELIABILITY	= 1 << 2,
170982388eaSZhikang Zhang 	NVME_SMART_CRIT_MEDIA		= 1 << 3,
171982388eaSZhikang Zhang 	NVME_SMART_CRIT_VOLATILE_MEMORY	= 1 << 4,
172982388eaSZhikang Zhang };
173982388eaSZhikang Zhang 
174982388eaSZhikang Zhang struct nvme_lba_range_type {
175982388eaSZhikang Zhang 	__u8			type;
176982388eaSZhikang Zhang 	__u8			attributes;
177982388eaSZhikang Zhang 	__u8			rsvd2[14];
178982388eaSZhikang Zhang 	__u64			slba;
179982388eaSZhikang Zhang 	__u64			nlb;
180982388eaSZhikang Zhang 	__u8			guid[16];
181982388eaSZhikang Zhang 	__u8			rsvd48[16];
182982388eaSZhikang Zhang };
183982388eaSZhikang Zhang 
184982388eaSZhikang Zhang enum {
185982388eaSZhikang Zhang 	NVME_LBART_TYPE_FS	= 0x01,
186982388eaSZhikang Zhang 	NVME_LBART_TYPE_RAID	= 0x02,
187982388eaSZhikang Zhang 	NVME_LBART_TYPE_CACHE	= 0x03,
188982388eaSZhikang Zhang 	NVME_LBART_TYPE_SWAP	= 0x04,
189982388eaSZhikang Zhang 
190982388eaSZhikang Zhang 	NVME_LBART_ATTRIB_TEMP	= 1 << 0,
191982388eaSZhikang Zhang 	NVME_LBART_ATTRIB_HIDE	= 1 << 1,
192982388eaSZhikang Zhang };
193982388eaSZhikang Zhang 
194982388eaSZhikang Zhang struct nvme_reservation_status {
195982388eaSZhikang Zhang 	__le32	gen;
196982388eaSZhikang Zhang 	__u8	rtype;
197982388eaSZhikang Zhang 	__u8	regctl[2];
198982388eaSZhikang Zhang 	__u8	resv5[2];
199982388eaSZhikang Zhang 	__u8	ptpls;
200982388eaSZhikang Zhang 	__u8	resv10[13];
201982388eaSZhikang Zhang 	struct {
202982388eaSZhikang Zhang 		__le16	cntlid;
203982388eaSZhikang Zhang 		__u8	rcsts;
204982388eaSZhikang Zhang 		__u8	resv3[5];
205982388eaSZhikang Zhang 		__le64	hostid;
206982388eaSZhikang Zhang 		__le64	rkey;
207982388eaSZhikang Zhang 	} regctl_ds[];
208982388eaSZhikang Zhang };
209982388eaSZhikang Zhang 
210982388eaSZhikang Zhang /* I/O commands */
211982388eaSZhikang Zhang 
212982388eaSZhikang Zhang enum nvme_opcode {
213982388eaSZhikang Zhang 	nvme_cmd_flush		= 0x00,
214982388eaSZhikang Zhang 	nvme_cmd_write		= 0x01,
215982388eaSZhikang Zhang 	nvme_cmd_read		= 0x02,
216982388eaSZhikang Zhang 	nvme_cmd_write_uncor	= 0x04,
217982388eaSZhikang Zhang 	nvme_cmd_compare	= 0x05,
218982388eaSZhikang Zhang 	nvme_cmd_write_zeroes	= 0x08,
219982388eaSZhikang Zhang 	nvme_cmd_dsm		= 0x09,
220982388eaSZhikang Zhang 	nvme_cmd_resv_register	= 0x0d,
221982388eaSZhikang Zhang 	nvme_cmd_resv_report	= 0x0e,
222982388eaSZhikang Zhang 	nvme_cmd_resv_acquire	= 0x11,
223982388eaSZhikang Zhang 	nvme_cmd_resv_release	= 0x15,
224982388eaSZhikang Zhang };
225982388eaSZhikang Zhang 
226982388eaSZhikang Zhang struct nvme_common_command {
227982388eaSZhikang Zhang 	__u8			opcode;
228982388eaSZhikang Zhang 	__u8			flags;
229982388eaSZhikang Zhang 	__u16			command_id;
230982388eaSZhikang Zhang 	__le32			nsid;
231982388eaSZhikang Zhang 	__le32			cdw2[2];
232982388eaSZhikang Zhang 	__le64			metadata;
233982388eaSZhikang Zhang 	__le64			prp1;
234982388eaSZhikang Zhang 	__le64			prp2;
235982388eaSZhikang Zhang 	__le32			cdw10[6];
236982388eaSZhikang Zhang };
237982388eaSZhikang Zhang 
238982388eaSZhikang Zhang struct nvme_rw_command {
239982388eaSZhikang Zhang 	__u8			opcode;
240982388eaSZhikang Zhang 	__u8			flags;
241982388eaSZhikang Zhang 	__u16			command_id;
242982388eaSZhikang Zhang 	__le32			nsid;
243982388eaSZhikang Zhang 	__u64			rsvd2;
244982388eaSZhikang Zhang 	__le64			metadata;
245982388eaSZhikang Zhang 	__le64			prp1;
246982388eaSZhikang Zhang 	__le64			prp2;
247982388eaSZhikang Zhang 	__le64			slba;
248982388eaSZhikang Zhang 	__le16			length;
249982388eaSZhikang Zhang 	__le16			control;
250982388eaSZhikang Zhang 	__le32			dsmgmt;
251982388eaSZhikang Zhang 	__le32			reftag;
252982388eaSZhikang Zhang 	__le16			apptag;
253982388eaSZhikang Zhang 	__le16			appmask;
254982388eaSZhikang Zhang };
255982388eaSZhikang Zhang 
256982388eaSZhikang Zhang enum {
257982388eaSZhikang Zhang 	NVME_RW_LR			= 1 << 15,
258982388eaSZhikang Zhang 	NVME_RW_FUA			= 1 << 14,
259982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_UNSPEC		= 0,
260982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_TYPICAL	= 1,
261982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_RARE		= 2,
262982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_READS		= 3,
263982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_WRITES		= 4,
264982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_RW		= 5,
265982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_ONCE		= 6,
266982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_PREFETCH	= 7,
267982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_TEMP		= 8,
268982388eaSZhikang Zhang 	NVME_RW_DSM_LATENCY_NONE	= 0 << 4,
269982388eaSZhikang Zhang 	NVME_RW_DSM_LATENCY_IDLE	= 1 << 4,
270982388eaSZhikang Zhang 	NVME_RW_DSM_LATENCY_NORM	= 2 << 4,
271982388eaSZhikang Zhang 	NVME_RW_DSM_LATENCY_LOW		= 3 << 4,
272982388eaSZhikang Zhang 	NVME_RW_DSM_SEQ_REQ		= 1 << 6,
273982388eaSZhikang Zhang 	NVME_RW_DSM_COMPRESSED		= 1 << 7,
274982388eaSZhikang Zhang 	NVME_RW_PRINFO_PRCHK_REF	= 1 << 10,
275982388eaSZhikang Zhang 	NVME_RW_PRINFO_PRCHK_APP	= 1 << 11,
276982388eaSZhikang Zhang 	NVME_RW_PRINFO_PRCHK_GUARD	= 1 << 12,
277982388eaSZhikang Zhang 	NVME_RW_PRINFO_PRACT		= 1 << 13,
278982388eaSZhikang Zhang };
279982388eaSZhikang Zhang 
280982388eaSZhikang Zhang struct nvme_dsm_cmd {
281982388eaSZhikang Zhang 	__u8			opcode;
282982388eaSZhikang Zhang 	__u8			flags;
283982388eaSZhikang Zhang 	__u16			command_id;
284982388eaSZhikang Zhang 	__le32			nsid;
285982388eaSZhikang Zhang 	__u64			rsvd2[2];
286982388eaSZhikang Zhang 	__le64			prp1;
287982388eaSZhikang Zhang 	__le64			prp2;
288982388eaSZhikang Zhang 	__le32			nr;
289982388eaSZhikang Zhang 	__le32			attributes;
290982388eaSZhikang Zhang 	__u32			rsvd12[4];
291982388eaSZhikang Zhang };
292982388eaSZhikang Zhang 
293982388eaSZhikang Zhang enum {
294982388eaSZhikang Zhang 	NVME_DSMGMT_IDR		= 1 << 0,
295982388eaSZhikang Zhang 	NVME_DSMGMT_IDW		= 1 << 1,
296982388eaSZhikang Zhang 	NVME_DSMGMT_AD		= 1 << 2,
297982388eaSZhikang Zhang };
298982388eaSZhikang Zhang 
299982388eaSZhikang Zhang struct nvme_dsm_range {
300982388eaSZhikang Zhang 	__le32			cattr;
301982388eaSZhikang Zhang 	__le32			nlb;
302982388eaSZhikang Zhang 	__le64			slba;
303982388eaSZhikang Zhang };
304982388eaSZhikang Zhang 
305982388eaSZhikang Zhang /* Admin commands */
306982388eaSZhikang Zhang 
307982388eaSZhikang Zhang enum nvme_admin_opcode {
308982388eaSZhikang Zhang 	nvme_admin_delete_sq		= 0x00,
309982388eaSZhikang Zhang 	nvme_admin_create_sq		= 0x01,
310982388eaSZhikang Zhang 	nvme_admin_get_log_page		= 0x02,
311982388eaSZhikang Zhang 	nvme_admin_delete_cq		= 0x04,
312982388eaSZhikang Zhang 	nvme_admin_create_cq		= 0x05,
313982388eaSZhikang Zhang 	nvme_admin_identify		= 0x06,
314982388eaSZhikang Zhang 	nvme_admin_abort_cmd		= 0x08,
315982388eaSZhikang Zhang 	nvme_admin_set_features		= 0x09,
316982388eaSZhikang Zhang 	nvme_admin_get_features		= 0x0a,
317982388eaSZhikang Zhang 	nvme_admin_async_event		= 0x0c,
318982388eaSZhikang Zhang 	nvme_admin_activate_fw		= 0x10,
319982388eaSZhikang Zhang 	nvme_admin_download_fw		= 0x11,
320982388eaSZhikang Zhang 	nvme_admin_format_nvm		= 0x80,
321982388eaSZhikang Zhang 	nvme_admin_security_send	= 0x81,
322982388eaSZhikang Zhang 	nvme_admin_security_recv	= 0x82,
323982388eaSZhikang Zhang };
324982388eaSZhikang Zhang 
325982388eaSZhikang Zhang enum {
326982388eaSZhikang Zhang 	NVME_QUEUE_PHYS_CONTIG	= (1 << 0),
327982388eaSZhikang Zhang 	NVME_CQ_IRQ_ENABLED	= (1 << 1),
328982388eaSZhikang Zhang 	NVME_SQ_PRIO_URGENT	= (0 << 1),
329982388eaSZhikang Zhang 	NVME_SQ_PRIO_HIGH	= (1 << 1),
330982388eaSZhikang Zhang 	NVME_SQ_PRIO_MEDIUM	= (2 << 1),
331982388eaSZhikang Zhang 	NVME_SQ_PRIO_LOW	= (3 << 1),
332982388eaSZhikang Zhang 	NVME_FEAT_ARBITRATION	= 0x01,
333982388eaSZhikang Zhang 	NVME_FEAT_POWER_MGMT	= 0x02,
334982388eaSZhikang Zhang 	NVME_FEAT_LBA_RANGE	= 0x03,
335982388eaSZhikang Zhang 	NVME_FEAT_TEMP_THRESH	= 0x04,
336982388eaSZhikang Zhang 	NVME_FEAT_ERR_RECOVERY	= 0x05,
337982388eaSZhikang Zhang 	NVME_FEAT_VOLATILE_WC	= 0x06,
338982388eaSZhikang Zhang 	NVME_FEAT_NUM_QUEUES	= 0x07,
339982388eaSZhikang Zhang 	NVME_FEAT_IRQ_COALESCE	= 0x08,
340982388eaSZhikang Zhang 	NVME_FEAT_IRQ_CONFIG	= 0x09,
341982388eaSZhikang Zhang 	NVME_FEAT_WRITE_ATOMIC	= 0x0a,
342982388eaSZhikang Zhang 	NVME_FEAT_ASYNC_EVENT	= 0x0b,
343982388eaSZhikang Zhang 	NVME_FEAT_AUTO_PST	= 0x0c,
344982388eaSZhikang Zhang 	NVME_FEAT_SW_PROGRESS	= 0x80,
345982388eaSZhikang Zhang 	NVME_FEAT_HOST_ID	= 0x81,
346982388eaSZhikang Zhang 	NVME_FEAT_RESV_MASK	= 0x82,
347982388eaSZhikang Zhang 	NVME_FEAT_RESV_PERSIST	= 0x83,
348982388eaSZhikang Zhang 	NVME_LOG_ERROR		= 0x01,
349982388eaSZhikang Zhang 	NVME_LOG_SMART		= 0x02,
350982388eaSZhikang Zhang 	NVME_LOG_FW_SLOT	= 0x03,
351982388eaSZhikang Zhang 	NVME_LOG_RESERVATION	= 0x80,
352982388eaSZhikang Zhang 	NVME_FWACT_REPL		= (0 << 3),
353982388eaSZhikang Zhang 	NVME_FWACT_REPL_ACTV	= (1 << 3),
354982388eaSZhikang Zhang 	NVME_FWACT_ACTV		= (2 << 3),
355982388eaSZhikang Zhang };
356982388eaSZhikang Zhang 
357982388eaSZhikang Zhang struct nvme_identify {
358982388eaSZhikang Zhang 	__u8			opcode;
359982388eaSZhikang Zhang 	__u8			flags;
360982388eaSZhikang Zhang 	__u16			command_id;
361982388eaSZhikang Zhang 	__le32			nsid;
362982388eaSZhikang Zhang 	__u64			rsvd2[2];
363982388eaSZhikang Zhang 	__le64			prp1;
364982388eaSZhikang Zhang 	__le64			prp2;
365982388eaSZhikang Zhang 	__le32			cns;
366982388eaSZhikang Zhang 	__u32			rsvd11[5];
367982388eaSZhikang Zhang };
368982388eaSZhikang Zhang 
369982388eaSZhikang Zhang struct nvme_features {
370982388eaSZhikang Zhang 	__u8			opcode;
371982388eaSZhikang Zhang 	__u8			flags;
372982388eaSZhikang Zhang 	__u16			command_id;
373982388eaSZhikang Zhang 	__le32			nsid;
374982388eaSZhikang Zhang 	__u64			rsvd2[2];
375982388eaSZhikang Zhang 	__le64			prp1;
376982388eaSZhikang Zhang 	__le64			prp2;
377982388eaSZhikang Zhang 	__le32			fid;
378982388eaSZhikang Zhang 	__le32			dword11;
379982388eaSZhikang Zhang 	__u32			rsvd12[4];
380982388eaSZhikang Zhang };
381982388eaSZhikang Zhang 
382982388eaSZhikang Zhang struct nvme_create_cq {
383982388eaSZhikang Zhang 	__u8			opcode;
384982388eaSZhikang Zhang 	__u8			flags;
385982388eaSZhikang Zhang 	__u16			command_id;
386982388eaSZhikang Zhang 	__u32			rsvd1[5];
387982388eaSZhikang Zhang 	__le64			prp1;
388982388eaSZhikang Zhang 	__u64			rsvd8;
389982388eaSZhikang Zhang 	__le16			cqid;
390982388eaSZhikang Zhang 	__le16			qsize;
391982388eaSZhikang Zhang 	__le16			cq_flags;
392982388eaSZhikang Zhang 	__le16			irq_vector;
393982388eaSZhikang Zhang 	__u32			rsvd12[4];
394982388eaSZhikang Zhang };
395982388eaSZhikang Zhang 
396982388eaSZhikang Zhang struct nvme_create_sq {
397982388eaSZhikang Zhang 	__u8			opcode;
398982388eaSZhikang Zhang 	__u8			flags;
399982388eaSZhikang Zhang 	__u16			command_id;
400982388eaSZhikang Zhang 	__u32			rsvd1[5];
401982388eaSZhikang Zhang 	__le64			prp1;
402982388eaSZhikang Zhang 	__u64			rsvd8;
403982388eaSZhikang Zhang 	__le16			sqid;
404982388eaSZhikang Zhang 	__le16			qsize;
405982388eaSZhikang Zhang 	__le16			sq_flags;
406982388eaSZhikang Zhang 	__le16			cqid;
407982388eaSZhikang Zhang 	__u32			rsvd12[4];
408982388eaSZhikang Zhang };
409982388eaSZhikang Zhang 
410982388eaSZhikang Zhang struct nvme_delete_queue {
411982388eaSZhikang Zhang 	__u8			opcode;
412982388eaSZhikang Zhang 	__u8			flags;
413982388eaSZhikang Zhang 	__u16			command_id;
414982388eaSZhikang Zhang 	__u32			rsvd1[9];
415982388eaSZhikang Zhang 	__le16			qid;
416982388eaSZhikang Zhang 	__u16			rsvd10;
417982388eaSZhikang Zhang 	__u32			rsvd11[5];
418982388eaSZhikang Zhang };
419982388eaSZhikang Zhang 
420982388eaSZhikang Zhang struct nvme_abort_cmd {
421982388eaSZhikang Zhang 	__u8			opcode;
422982388eaSZhikang Zhang 	__u8			flags;
423982388eaSZhikang Zhang 	__u16			command_id;
424982388eaSZhikang Zhang 	__u32			rsvd1[9];
425982388eaSZhikang Zhang 	__le16			sqid;
426982388eaSZhikang Zhang 	__u16			cid;
427982388eaSZhikang Zhang 	__u32			rsvd11[5];
428982388eaSZhikang Zhang };
429982388eaSZhikang Zhang 
430982388eaSZhikang Zhang struct nvme_download_firmware {
431982388eaSZhikang Zhang 	__u8			opcode;
432982388eaSZhikang Zhang 	__u8			flags;
433982388eaSZhikang Zhang 	__u16			command_id;
434982388eaSZhikang Zhang 	__u32			rsvd1[5];
435982388eaSZhikang Zhang 	__le64			prp1;
436982388eaSZhikang Zhang 	__le64			prp2;
437982388eaSZhikang Zhang 	__le32			numd;
438982388eaSZhikang Zhang 	__le32			offset;
439982388eaSZhikang Zhang 	__u32			rsvd12[4];
440982388eaSZhikang Zhang };
441982388eaSZhikang Zhang 
442982388eaSZhikang Zhang struct nvme_format_cmd {
443982388eaSZhikang Zhang 	__u8			opcode;
444982388eaSZhikang Zhang 	__u8			flags;
445982388eaSZhikang Zhang 	__u16			command_id;
446982388eaSZhikang Zhang 	__le32			nsid;
447982388eaSZhikang Zhang 	__u64			rsvd2[4];
448982388eaSZhikang Zhang 	__le32			cdw10;
449982388eaSZhikang Zhang 	__u32			rsvd11[5];
450982388eaSZhikang Zhang };
451982388eaSZhikang Zhang 
452982388eaSZhikang Zhang struct nvme_command {
453982388eaSZhikang Zhang 	union {
454982388eaSZhikang Zhang 		struct nvme_common_command common;
455982388eaSZhikang Zhang 		struct nvme_rw_command rw;
456982388eaSZhikang Zhang 		struct nvme_identify identify;
457982388eaSZhikang Zhang 		struct nvme_features features;
458982388eaSZhikang Zhang 		struct nvme_create_cq create_cq;
459982388eaSZhikang Zhang 		struct nvme_create_sq create_sq;
460982388eaSZhikang Zhang 		struct nvme_delete_queue delete_queue;
461982388eaSZhikang Zhang 		struct nvme_download_firmware dlfw;
462982388eaSZhikang Zhang 		struct nvme_format_cmd format;
463982388eaSZhikang Zhang 		struct nvme_dsm_cmd dsm;
464982388eaSZhikang Zhang 		struct nvme_abort_cmd abort;
465982388eaSZhikang Zhang 	};
466982388eaSZhikang Zhang };
467982388eaSZhikang Zhang 
468982388eaSZhikang Zhang enum {
469982388eaSZhikang Zhang 	NVME_SC_SUCCESS			= 0x0,
470982388eaSZhikang Zhang 	NVME_SC_INVALID_OPCODE		= 0x1,
471982388eaSZhikang Zhang 	NVME_SC_INVALID_FIELD		= 0x2,
472982388eaSZhikang Zhang 	NVME_SC_CMDID_CONFLICT		= 0x3,
473982388eaSZhikang Zhang 	NVME_SC_DATA_XFER_ERROR		= 0x4,
474982388eaSZhikang Zhang 	NVME_SC_POWER_LOSS		= 0x5,
475982388eaSZhikang Zhang 	NVME_SC_INTERNAL		= 0x6,
476982388eaSZhikang Zhang 	NVME_SC_ABORT_REQ		= 0x7,
477982388eaSZhikang Zhang 	NVME_SC_ABORT_QUEUE		= 0x8,
478982388eaSZhikang Zhang 	NVME_SC_FUSED_FAIL		= 0x9,
479982388eaSZhikang Zhang 	NVME_SC_FUSED_MISSING		= 0xa,
480982388eaSZhikang Zhang 	NVME_SC_INVALID_NS		= 0xb,
481982388eaSZhikang Zhang 	NVME_SC_CMD_SEQ_ERROR		= 0xc,
482982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_LAST	= 0xd,
483982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_COUNT	= 0xe,
484982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_DATA	= 0xf,
485982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_METADATA	= 0x10,
486982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_TYPE	= 0x11,
487982388eaSZhikang Zhang 	NVME_SC_LBA_RANGE		= 0x80,
488982388eaSZhikang Zhang 	NVME_SC_CAP_EXCEEDED		= 0x81,
489982388eaSZhikang Zhang 	NVME_SC_NS_NOT_READY		= 0x82,
490982388eaSZhikang Zhang 	NVME_SC_RESERVATION_CONFLICT	= 0x83,
491982388eaSZhikang Zhang 	NVME_SC_CQ_INVALID		= 0x100,
492982388eaSZhikang Zhang 	NVME_SC_QID_INVALID		= 0x101,
493982388eaSZhikang Zhang 	NVME_SC_QUEUE_SIZE		= 0x102,
494982388eaSZhikang Zhang 	NVME_SC_ABORT_LIMIT		= 0x103,
495982388eaSZhikang Zhang 	NVME_SC_ABORT_MISSING		= 0x104,
496982388eaSZhikang Zhang 	NVME_SC_ASYNC_LIMIT		= 0x105,
497982388eaSZhikang Zhang 	NVME_SC_FIRMWARE_SLOT		= 0x106,
498982388eaSZhikang Zhang 	NVME_SC_FIRMWARE_IMAGE		= 0x107,
499982388eaSZhikang Zhang 	NVME_SC_INVALID_VECTOR		= 0x108,
500982388eaSZhikang Zhang 	NVME_SC_INVALID_LOG_PAGE	= 0x109,
501982388eaSZhikang Zhang 	NVME_SC_INVALID_FORMAT		= 0x10a,
502982388eaSZhikang Zhang 	NVME_SC_FIRMWARE_NEEDS_RESET	= 0x10b,
503982388eaSZhikang Zhang 	NVME_SC_INVALID_QUEUE		= 0x10c,
504982388eaSZhikang Zhang 	NVME_SC_FEATURE_NOT_SAVEABLE	= 0x10d,
505982388eaSZhikang Zhang 	NVME_SC_FEATURE_NOT_CHANGEABLE	= 0x10e,
506982388eaSZhikang Zhang 	NVME_SC_FEATURE_NOT_PER_NS	= 0x10f,
507982388eaSZhikang Zhang 	NVME_SC_FW_NEEDS_RESET_SUBSYS	= 0x110,
508982388eaSZhikang Zhang 	NVME_SC_BAD_ATTRIBUTES		= 0x180,
509982388eaSZhikang Zhang 	NVME_SC_INVALID_PI		= 0x181,
510982388eaSZhikang Zhang 	NVME_SC_READ_ONLY		= 0x182,
511982388eaSZhikang Zhang 	NVME_SC_WRITE_FAULT		= 0x280,
512982388eaSZhikang Zhang 	NVME_SC_READ_ERROR		= 0x281,
513982388eaSZhikang Zhang 	NVME_SC_GUARD_CHECK		= 0x282,
514982388eaSZhikang Zhang 	NVME_SC_APPTAG_CHECK		= 0x283,
515982388eaSZhikang Zhang 	NVME_SC_REFTAG_CHECK		= 0x284,
516982388eaSZhikang Zhang 	NVME_SC_COMPARE_FAILED		= 0x285,
517982388eaSZhikang Zhang 	NVME_SC_ACCESS_DENIED		= 0x286,
518982388eaSZhikang Zhang 	NVME_SC_DNR			= 0x4000,
519982388eaSZhikang Zhang };
520982388eaSZhikang Zhang 
521982388eaSZhikang Zhang struct nvme_completion {
522982388eaSZhikang Zhang 	__le32	result;		/* Used by admin commands to return data */
523982388eaSZhikang Zhang 	__u32	rsvd;
524982388eaSZhikang Zhang 	__le16	sq_head;	/* how much of this queue may be reclaimed */
525982388eaSZhikang Zhang 	__le16	sq_id;		/* submission queue that generated this entry */
526982388eaSZhikang Zhang 	__u16	command_id;	/* of the command which completed */
527982388eaSZhikang Zhang 	__le16	status;		/* did the command fail, and if so, why? */
528982388eaSZhikang Zhang };
529982388eaSZhikang Zhang 
530982388eaSZhikang Zhang /*
531982388eaSZhikang Zhang  * Registers should always be accessed with double word or quad word
532982388eaSZhikang Zhang  * accesses. Registers with 64-bit address pointers should be written
533982388eaSZhikang Zhang  * to with dword accesses by writing the low dword first (ptr[0]),
534982388eaSZhikang Zhang  * then the high dword (ptr[1]) second.
535982388eaSZhikang Zhang  */
nvme_readq(__le64 volatile * regs)536982388eaSZhikang Zhang static inline u64 nvme_readq(__le64 volatile *regs)
537982388eaSZhikang Zhang {
538982388eaSZhikang Zhang #if BITS_PER_LONG == 64
539982388eaSZhikang Zhang 	return readq(regs);
540982388eaSZhikang Zhang #else
541982388eaSZhikang Zhang 	__u32 *ptr = (__u32 *)regs;
542982388eaSZhikang Zhang 	u64 val_lo = readl(ptr);
543982388eaSZhikang Zhang 	u64 val_hi = readl(ptr + 1);
544982388eaSZhikang Zhang 
545982388eaSZhikang Zhang 	return val_lo + (val_hi << 32);
546982388eaSZhikang Zhang #endif
547982388eaSZhikang Zhang }
548982388eaSZhikang Zhang 
nvme_writeq(const u64 val,__le64 volatile * regs)549982388eaSZhikang Zhang static inline void nvme_writeq(const u64 val, __le64 volatile *regs)
550982388eaSZhikang Zhang {
551982388eaSZhikang Zhang #if BITS_PER_LONG == 64
552982388eaSZhikang Zhang 	writeq(val, regs);
553982388eaSZhikang Zhang #else
554982388eaSZhikang Zhang 	__u32 *ptr = (__u32 *)regs;
555982388eaSZhikang Zhang 	u32 val_lo = lower_32_bits(val);
556982388eaSZhikang Zhang 	u32 val_hi = upper_32_bits(val);
557982388eaSZhikang Zhang 	writel(val_lo, ptr);
558982388eaSZhikang Zhang 	writel(val_hi, ptr + 1);
559982388eaSZhikang Zhang #endif
560982388eaSZhikang Zhang }
561982388eaSZhikang Zhang 
562982388eaSZhikang Zhang struct nvme_bar {
563982388eaSZhikang Zhang 	__u64 cap;	/* Controller Capabilities */
564982388eaSZhikang Zhang 	__u32 vs;	/* Version */
565982388eaSZhikang Zhang 	__u32 intms;	/* Interrupt Mask Set */
566982388eaSZhikang Zhang 	__u32 intmc;	/* Interrupt Mask Clear */
567982388eaSZhikang Zhang 	__u32 cc;	/* Controller Configuration */
568982388eaSZhikang Zhang 	__u32 rsvd1;	/* Reserved */
569982388eaSZhikang Zhang 	__u32 csts;	/* Controller Status */
570982388eaSZhikang Zhang 	__u32 rsvd2;	/* Reserved */
571982388eaSZhikang Zhang 	__u32 aqa;	/* Admin Queue Attributes */
572982388eaSZhikang Zhang 	__u64 asq;	/* Admin SQ Base Address */
573982388eaSZhikang Zhang 	__u64 acq;	/* Admin CQ Base Address */
574982388eaSZhikang Zhang };
575982388eaSZhikang Zhang 
576982388eaSZhikang Zhang #define NVME_CAP_MQES(cap)	((cap) & 0xffff)
577982388eaSZhikang Zhang #define NVME_CAP_TIMEOUT(cap)	(((cap) >> 24) & 0xff)
578982388eaSZhikang Zhang #define NVME_CAP_STRIDE(cap)	(((cap) >> 32) & 0xf)
579982388eaSZhikang Zhang #define NVME_CAP_MPSMIN(cap)	(((cap) >> 48) & 0xf)
580982388eaSZhikang Zhang #define NVME_CAP_MPSMAX(cap)	(((cap) >> 52) & 0xf)
581982388eaSZhikang Zhang 
582982388eaSZhikang Zhang #define NVME_VS(major, minor)	(((major) << 16) | ((minor) << 8))
583982388eaSZhikang Zhang 
584982388eaSZhikang Zhang enum {
585982388eaSZhikang Zhang 	NVME_CC_ENABLE		= 1 << 0,
586982388eaSZhikang Zhang 	NVME_CC_CSS_NVM		= 0 << 4,
587982388eaSZhikang Zhang 	NVME_CC_MPS_SHIFT	= 7,
588982388eaSZhikang Zhang 	NVME_CC_ARB_RR		= 0 << 11,
589982388eaSZhikang Zhang 	NVME_CC_ARB_WRRU	= 1 << 11,
590982388eaSZhikang Zhang 	NVME_CC_ARB_VS		= 7 << 11,
591982388eaSZhikang Zhang 	NVME_CC_SHN_NONE	= 0 << 14,
592982388eaSZhikang Zhang 	NVME_CC_SHN_NORMAL	= 1 << 14,
593982388eaSZhikang Zhang 	NVME_CC_SHN_ABRUPT	= 2 << 14,
594982388eaSZhikang Zhang 	NVME_CC_SHN_MASK	= 3 << 14,
595982388eaSZhikang Zhang 	NVME_CC_IOSQES		= 6 << 16,
596982388eaSZhikang Zhang 	NVME_CC_IOCQES		= 4 << 20,
597982388eaSZhikang Zhang 	NVME_CSTS_RDY		= 1 << 0,
598982388eaSZhikang Zhang 	NVME_CSTS_CFS		= 1 << 1,
599982388eaSZhikang Zhang 	NVME_CSTS_SHST_NORMAL	= 0 << 2,
600982388eaSZhikang Zhang 	NVME_CSTS_SHST_OCCUR	= 1 << 2,
601982388eaSZhikang Zhang 	NVME_CSTS_SHST_CMPLT	= 2 << 2,
602982388eaSZhikang Zhang 	NVME_CSTS_SHST_MASK	= 3 << 2,
603982388eaSZhikang Zhang };
604982388eaSZhikang Zhang 
605982388eaSZhikang Zhang /* Represents an NVM Express device. Each nvme_dev is a PCI function. */
606982388eaSZhikang Zhang struct nvme_dev {
607982388eaSZhikang Zhang 	struct list_head node;
608982388eaSZhikang Zhang 	struct nvme_queue **queues;
609982388eaSZhikang Zhang 	u32 __iomem *dbs;
610982388eaSZhikang Zhang 	int instance;
611982388eaSZhikang Zhang 	unsigned queue_count;
612982388eaSZhikang Zhang 	unsigned online_queues;
613982388eaSZhikang Zhang 	unsigned max_qid;
614982388eaSZhikang Zhang 	int q_depth;
615982388eaSZhikang Zhang 	u32 db_stride;
616982388eaSZhikang Zhang 	u32 ctrl_config;
617982388eaSZhikang Zhang 	struct nvme_bar __iomem *bar;
618982388eaSZhikang Zhang 	struct list_head namespaces;
619982388eaSZhikang Zhang 	char serial[20];
620982388eaSZhikang Zhang 	char model[40];
621982388eaSZhikang Zhang 	char firmware_rev[8];
622982388eaSZhikang Zhang 	u32 max_transfer_shift;
623b65c6921SBin Meng 	u64 cap;
624982388eaSZhikang Zhang 	u32 stripe_size;
625982388eaSZhikang Zhang 	u32 page_size;
626982388eaSZhikang Zhang 	u8 vwc;
627982388eaSZhikang Zhang 	u64 *prp_pool;
628982388eaSZhikang Zhang 	u32 prp_entry_num;
629982388eaSZhikang Zhang 	u32 nn;
630982388eaSZhikang Zhang };
631982388eaSZhikang Zhang 
632982388eaSZhikang Zhang /*
633982388eaSZhikang Zhang  * An NVM Express namespace is equivalent to a SCSI LUN.
634982388eaSZhikang Zhang  * Each namespace is operated as an independent "device".
635982388eaSZhikang Zhang  */
636982388eaSZhikang Zhang struct nvme_ns {
637982388eaSZhikang Zhang 	struct list_head list;
638982388eaSZhikang Zhang 	struct nvme_dev *dev;
639982388eaSZhikang Zhang 	unsigned ns_id;
640982388eaSZhikang Zhang 	int devnum;
641982388eaSZhikang Zhang 	int lba_shift;
642982388eaSZhikang Zhang 	u8 flbas;
643982388eaSZhikang Zhang 	u64 mode_select_num_blocks;
644982388eaSZhikang Zhang 	u32 mode_select_block_len;
645982388eaSZhikang Zhang };
646982388eaSZhikang Zhang 
647982388eaSZhikang Zhang #endif /* __DRIVER_NVME_H__ */
648