1/*-
2 *   BSD LICENSE
3 *
4 *   Copyright (c) Intel Corporation. All rights reserved.
5 *   Copyright (c) 2017, Western Digital Corporation or its affiliates.
6 *
7 *   Redistribution and use in source and binary forms, with or without
8 *   modification, are permitted provided that the following conditions
9 *   are met:
10 *
11 *     * Redistributions of source code must retain the above copyright
12 *       notice, this list of conditions and the following disclaimer.
13 *     * Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in
15 *       the documentation and/or other materials provided with the
16 *       distribution.
17 *     * Neither the name of Intel Corporation nor the names of its
18 *       contributors may be used to endorse or promote products derived
19 *       from this software without specific prior written permission.
20 *
21 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * Intel NVMe vendor-specific definitions
36 * See: http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/ssd-dc-p3700-spec.pdf
37 */
38
39#ifndef __NVME_INTEL_H__
40#define __NVME_INTEL_H__
41
42#include <stdint.h>
43#include <stddef.h>
44
45enum nvme_intel_feat {
46	NVME_INTEL_FEAT_MAX_LBA				= 0xC1,
47	NVME_INTEL_FEAT_NATIVE_MAX_LBA			= 0xC2,
48	NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING		= 0xC6,
49	NVME_INTEL_FEAT_SMBUS_ADDRESS			= 0xC8,
50	NVME_INTEL_FEAT_LED_PATTERN			= 0xC9,
51	NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS	= 0xD5,
52	NVME_INTEL_FEAT_LATENCY_TRACKING		= 0xE2,
53};
54
55enum nvme_intel_set_max_lba_command_status_code {
56	NVME_INTEL_EXCEEDS_AVAILABLE_CAPACITY		= 0xC0,
57	NVME_INTEL_SMALLER_THAN_MIN_LIMIT	        = 0xC1,
58	NVME_INTEL_SMALLER_THAN_NS_REQUIREMENTS		= 0xC2,
59};
60
61enum nvme_intel_log_page {
62	NVME_INTEL_LOG_PAGE_DIR			        = 0xC0,
63	NVME_INTEL_LOG_READ_CMD_LATENCY			= 0xC1,
64	NVME_INTEL_LOG_WRITE_CMD_LATENCY		= 0xC2,
65	NVME_INTEL_LOG_TEMPERATURE			= 0xC5,
66	NVME_INTEL_LOG_SMART				= 0xCA,
67	NVME_INTEL_MARKETING_DESCRIPTION		= 0xDD,
68};
69
70enum nvme_intel_smart_attribute_code {
71	NVME_INTEL_SMART_PROGRAM_FAIL_COUNT		= 0xAB,
72	NVME_INTEL_SMART_ERASE_FAIL_COUNT		= 0xAC,
73	NVME_INTEL_SMART_WEAR_LEVELING_COUNT		= 0xAD,
74	NVME_INTEL_SMART_E2E_ERROR_COUNT		= 0xB8,
75	NVME_INTEL_SMART_CRC_ERROR_COUNT		= 0xC7,
76	NVME_INTEL_SMART_MEDIA_WEAR			= 0xE2,
77	NVME_INTEL_SMART_HOST_READ_PERCENTAGE		= 0xE3,
78	NVME_INTEL_SMART_TIMER				= 0xE4,
79	NVME_INTEL_SMART_THERMAL_THROTTLE_STATUS	= 0xEA,
80	NVME_INTEL_SMART_RETRY_BUFFER_OVERFLOW_COUNTER	= 0xF0,
81	NVME_INTEL_SMART_PLL_LOCK_LOSS_COUNT		= 0xF3,
82	NVME_INTEL_SMART_NAND_BYTES_WRITTEN		= 0xF4,
83	NVME_INTEL_SMART_HOST_BYTES_WRITTEN		= 0xF5,
84};
85
86struct nvme_intel_log_page_dir {
87	uint8_t		version[2];
88	uint8_t		reserved[384];
89	uint8_t		read_latency_log_len;
90	uint8_t		reserved2;
91	uint8_t		write_latency_log_len;
92	uint8_t		reserved3[5];
93	uint8_t		temperature_statistics_log_len;
94	uint8_t		reserved4[9];
95	uint8_t		smart_log_len;
96	uint8_t		reserved5[37];
97	uint8_t		marketing_description_log_len;
98	uint8_t		reserved6[69];
99};
100nvme_static_assert(sizeof(struct nvme_intel_log_page_dir) == 512,
101		   "Incorrect size");
102
103struct nvme_intel_rw_latency_page {
104	uint16_t	major_revison;
105	uint16_t	minor_revison;
106	uint32_t	buckets_32us[32];
107	uint32_t	buckets_1ms[31];
108	uint32_t	buckets_32ms[31];
109};
110nvme_static_assert(sizeof(struct nvme_intel_rw_latency_page) == 380,
111		   "Incorrect size");
112
113struct nvme_intel_temperature_page {
114	uint64_t	current_temperature;
115	uint64_t	shutdown_flag_last;
116	uint64_t	shutdown_flag_life;
117	uint64_t	highest_temperature;
118	uint64_t	lowest_temperature;
119	uint64_t	reserved[5];
120	uint64_t	specified_max_op_temperature;
121	uint64_t	reserved2;
122	uint64_t	specified_min_op_temperature;
123	uint64_t	estimated_offset;
124};
125nvme_static_assert(sizeof(struct nvme_intel_temperature_page) == 112,
126		   "Incorrect size");
127
128struct nvme_intel_smart_attribute {
129	uint8_t		code;
130	uint8_t		reserved[2];
131	uint8_t		normalized_value;
132	uint8_t		reserved2;
133	uint8_t		raw_value[6];
134	uint8_t		reserved3;
135};
136
137struct __attribute__((packed)) nvme_intel_smart_information_page {
138	struct nvme_intel_smart_attribute attributes[13];
139};
140nvme_static_assert(sizeof(struct nvme_intel_smart_information_page) == 156,
141		   "Incorrect size");
142
143union nvme_intel_feat_power_governor {
144	uint32_t	raw;
145	struct {
146		/* Power governor setting: 00h = 25W 01h = 20W 02h = 10W */
147		uint32_t power_governor_setting	: 8;
148		uint32_t reserved	        : 24;
149	} bits;
150};
151nvme_static_assert(sizeof(union nvme_intel_feat_power_governor) == 4,
152		   "Incorrect size");
153
154union nvme_intel_feat_smbus_address {
155	uint32_t	raw;
156	struct {
157		uint32_t reserved	           : 1;
158		uint32_t smbus_controller_address  : 8;
159		uint32_t reserved2	           : 23;
160	} bits;
161};
162nvme_static_assert(sizeof(union nvme_intel_feat_smbus_address) == 4,
163		   "Incorrect size");
164
165union nvme_intel_feat_led_pattern {
166	uint32_t	raw;
167	struct {
168		uint32_t feature_options : 24;
169		uint32_t value	         : 8;
170	} bits;
171};
172nvme_static_assert(sizeof(union nvme_intel_feat_led_pattern) == 4,
173		   "Incorrect size");
174
175union nvme_intel_feat_reset_timed_workload_counters {
176	uint32_t	raw;
177	struct {
178		/*
179		 * Write Usage: 00 = NOP, 1 = Reset E2, E3,E4 counters;
180		 * Read Usage: Not Supported
181		 */
182		uint32_t reset	   : 1;
183		uint32_t reserved  : 31;
184	} bits;
185};
186nvme_static_assert(sizeof(union nvme_intel_feat_reset_timed_workload_counters) == 4,
187		   "Incorrect size");
188
189union nvme_intel_feat_latency_tracking {
190	uint32_t	raw;
191	struct {
192		/*
193		 * Write Usage:
194		 * 00h = Disable Latency Tracking (Default)
195		 * 01h = Enable Latency Tracking
196		 */
197		uint32_t enable	: 32;
198	} bits;
199};
200nvme_static_assert(sizeof(union nvme_intel_feat_latency_tracking) == 4,
201		   "Incorrect size");
202
203struct nvme_intel_marketing_description_page {
204	uint8_t		marketing_product[512];
205};
206nvme_static_assert(sizeof(struct nvme_intel_marketing_description_page) == 512,
207		   "Incorrect size");
208
209#endif /* __NVME_INTEL_H__ */
210