1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
|
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright 2012 STEC, Inc.
* Copyright (c) 2017 Western Digital Corporation or its affiliates.
*/
#ifndef SKD_S1120_H
#define SKD_S1120_H
/*
* Q-channel, 64-bit r/w
*/
#define FIT_Q_COMMAND 0x400u
#define FIT_QCMD_QID_MASK (0x3 << 1)
#define FIT_QCMD_QID0 (0x0 << 1)
#define FIT_QCMD_QID_NORMAL FIT_QCMD_QID0
#define FIT_QCMD_QID1 (0x1 << 1)
#define FIT_QCMD_QID2 (0x2 << 1)
#define FIT_QCMD_QID3 (0x3 << 1)
#define FIT_QCMD_FLUSH_QUEUE (0ull) /* add QID */
#define FIT_QCMD_MSGSIZE_MASK (0x3 << 4)
#define FIT_QCMD_MSGSIZE_64 (0x0 << 4)
#define FIT_QCMD_MSGSIZE_128 (0x1 << 4)
#define FIT_QCMD_MSGSIZE_256 (0x2 << 4)
#define FIT_QCMD_MSGSIZE_512 (0x3 << 4)
#define FIT_QCMD_ALIGN L1_CACHE_BYTES
/*
* Control, 32-bit r/w
*/
#define FIT_CONTROL 0x500u
#define FIT_CR_HARD_RESET (1u << 0u)
#define FIT_CR_SOFT_RESET (1u << 1u)
#define FIT_CR_DIS_TIMESTAMPS (1u << 6u)
#define FIT_CR_ENABLE_INTERRUPTS (1u << 7u)
/*
* Status, 32-bit, r/o
*/
#define FIT_STATUS 0x510u
#define FIT_SR_DRIVE_STATE_MASK 0x000000FFu
#define FIT_SR_SIGNATURE (0xFF << 8)
#define FIT_SR_PIO_DMA (1 << 16)
#define FIT_SR_DRIVE_OFFLINE 0x00
#define FIT_SR_DRIVE_INIT 0x01
/* #define FIT_SR_DRIVE_READY 0x02 */
#define FIT_SR_DRIVE_ONLINE 0x03
#define FIT_SR_DRIVE_BUSY 0x04
#define FIT_SR_DRIVE_FAULT 0x05
#define FIT_SR_DRIVE_DEGRADED 0x06
#define FIT_SR_PCIE_LINK_DOWN 0x07
#define FIT_SR_DRIVE_SOFT_RESET 0x08
#define FIT_SR_DRIVE_INIT_FAULT 0x09
#define FIT_SR_DRIVE_BUSY_SANITIZE 0x0A
#define FIT_SR_DRIVE_BUSY_ERASE 0x0B
#define FIT_SR_DRIVE_FW_BOOTING 0x0C
#define FIT_SR_DRIVE_NEED_FW_DOWNLOAD 0xFE
#define FIT_SR_DEVICE_MISSING 0xFF
#define FIT_SR__RESERVED 0xFFFFFF00u
/*
* FIT_STATUS - Status register data definition
*/
#define FIT_SR_STATE_MASK (0xFF << 0)
#define FIT_SR_SIGNATURE (0xFF << 8)
#define FIT_SR_PIO_DMA (1 << 16)
/*
* Interrupt status, 32-bit r/w1c (w1c ==> write 1 to clear)
*/
#define FIT_INT_STATUS_HOST 0x520u
#define FIT_ISH_FW_STATE_CHANGE (1u << 0u)
#define FIT_ISH_COMPLETION_POSTED (1u << 1u)
#define FIT_ISH_MSG_FROM_DEV (1u << 2u)
#define FIT_ISH_UNDEFINED_3 (1u << 3u)
#define FIT_ISH_UNDEFINED_4 (1u << 4u)
#define FIT_ISH_Q0_FULL (1u << 5u)
#define FIT_ISH_Q1_FULL (1u << 6u)
#define FIT_ISH_Q2_FULL (1u << 7u)
#define FIT_ISH_Q3_FULL (1u << 8u)
#define FIT_ISH_QCMD_FIFO_OVERRUN (1u << 9u)
#define FIT_ISH_BAD_EXP_ROM_READ (1u << 10u)
#define FIT_INT_DEF_MASK \
(FIT_ISH_FW_STATE_CHANGE | \
FIT_ISH_COMPLETION_POSTED | \
FIT_ISH_MSG_FROM_DEV | \
FIT_ISH_Q0_FULL | \
FIT_ISH_Q1_FULL | \
FIT_ISH_Q2_FULL | \
FIT_ISH_Q3_FULL | \
FIT_ISH_QCMD_FIFO_OVERRUN | \
FIT_ISH_BAD_EXP_ROM_READ)
#define FIT_INT_QUEUE_FULL \
(FIT_ISH_Q0_FULL | \
FIT_ISH_Q1_FULL | \
FIT_ISH_Q2_FULL | \
FIT_ISH_Q3_FULL)
#define MSI_MSG_NWL_ERROR_0 0x00000000
#define MSI_MSG_NWL_ERROR_1 0x00000001
#define MSI_MSG_NWL_ERROR_2 0x00000002
#define MSI_MSG_NWL_ERROR_3 0x00000003
#define MSI_MSG_STATE_CHANGE 0x00000004
#define MSI_MSG_COMPLETION_POSTED 0x00000005
#define MSI_MSG_MSG_FROM_DEV 0x00000006
#define MSI_MSG_RESERVED_0 0x00000007
#define MSI_MSG_RESERVED_1 0x00000008
#define MSI_MSG_QUEUE_0_FULL 0x00000009
#define MSI_MSG_QUEUE_1_FULL 0x0000000A
#define MSI_MSG_QUEUE_2_FULL 0x0000000B
#define MSI_MSG_QUEUE_3_FULL 0x0000000C
#define FIT_INT_RESERVED_MASK \
(FIT_ISH_UNDEFINED_3 | \
FIT_ISH_UNDEFINED_4)
/*
* Interrupt mask, 32-bit r/w
* Bit definitions are the same as FIT_INT_STATUS_HOST
*/
#define FIT_INT_MASK_HOST 0x528u
/*
* Message to device, 32-bit r/w
*/
#define FIT_MSG_TO_DEVICE 0x540u
/*
* Message from device, 32-bit, r/o
*/
#define FIT_MSG_FROM_DEVICE 0x548u
/*
* 32-bit messages to/from device, composition/extraction macros
*/
#define FIT_MXD_CONS(TYPE, PARAM, DATA) \
((((TYPE) & 0xFFu) << 24u) | \
(((PARAM) & 0xFFu) << 16u) | \
(((DATA) & 0xFFFFu) << 0u))
#define FIT_MXD_TYPE(MXD) (((MXD) >> 24u) & 0xFFu)
#define FIT_MXD_PARAM(MXD) (((MXD) >> 16u) & 0xFFu)
#define FIT_MXD_DATA(MXD) (((MXD) >> 0u) & 0xFFFFu)
/*
* Types of messages to/from device
*/
#define FIT_MTD_FITFW_INIT 0x01u
#define FIT_MTD_GET_CMDQ_DEPTH 0x02u
#define FIT_MTD_SET_COMPQ_DEPTH 0x03u
#define FIT_MTD_SET_COMPQ_ADDR 0x04u
#define FIT_MTD_ARM_QUEUE 0x05u
#define FIT_MTD_CMD_LOG_HOST_ID 0x07u
#define FIT_MTD_CMD_LOG_TIME_STAMP_LO 0x08u
#define FIT_MTD_CMD_LOG_TIME_STAMP_HI 0x09u
#define FIT_MFD_SMART_EXCEEDED 0x10u
#define FIT_MFD_POWER_DOWN 0x11u
#define FIT_MFD_OFFLINE 0x12u
#define FIT_MFD_ONLINE 0x13u
#define FIT_MFD_FW_RESTARTING 0x14u
#define FIT_MFD_PM_ACTIVE 0x15u
#define FIT_MFD_PM_STANDBY 0x16u
#define FIT_MFD_PM_SLEEP 0x17u
#define FIT_MFD_CMD_PROGRESS 0x18u
#define FIT_MTD_DEBUG 0xFEu
#define FIT_MFD_DEBUG 0xFFu
#define FIT_MFD_MASK (0xFFu)
#define FIT_MFD_DATA_MASK (0xFFu)
#define FIT_MFD_MSG(x) (((x) >> 24) & FIT_MFD_MASK)
#define FIT_MFD_DATA(x) ((x) & FIT_MFD_MASK)
/*
* Extra arg to FIT_MSG_TO_DEVICE, 64-bit r/w
* Used to set completion queue address (FIT_MTD_SET_COMPQ_ADDR)
* (was Response buffer in docs)
*/
#define FIT_MSG_TO_DEVICE_ARG 0x580u
/*
* Hardware (ASIC) version, 32-bit r/o
*/
#define FIT_HW_VERSION 0x588u
/*
* Scatter/gather list descriptor.
* 32-bytes and must be aligned on a 32-byte boundary.
* All fields are in little endian order.
*/
struct fit_sg_descriptor {
uint32_t control;
uint32_t byte_count;
uint64_t host_side_addr;
uint64_t dev_side_addr;
uint64_t next_desc_ptr;
};
#define FIT_SGD_CONTROL_NOT_LAST 0x000u
#define FIT_SGD_CONTROL_LAST 0x40Eu
/*
* Header at the beginning of a FIT message. The header
* is followed by SSDI requests each 64 bytes.
* A FIT message can be up to 512 bytes long and must start
* on a 64-byte boundary.
*/
struct fit_msg_hdr {
uint8_t protocol_id;
uint8_t num_protocol_cmds_coalesced;
uint8_t _reserved[62];
};
#define FIT_PROTOCOL_ID_FIT 1
#define FIT_PROTOCOL_ID_SSDI 2
#define FIT_PROTOCOL_ID_SOFIT 3
#define FIT_PROTOCOL_MINOR_VER(mtd_val) ((mtd_val >> 16) & 0xF)
#define FIT_PROTOCOL_MAJOR_VER(mtd_val) ((mtd_val >> 20) & 0xF)
/*
* Format of a completion entry. The completion queue is circular
* and must have at least as many entries as the maximum number
* of commands that may be issued to the device.
*
* There are no head/tail pointers. The cycle value is used to
* infer the presence of new completion records.
* Initially the cycle in all entries is 0, the index is 0, and
* the cycle value to expect is 1. When completions are added
* their cycle values are set to 1. When the index wraps the
* cycle value to expect is incremented.
*
* Command_context is opaque and taken verbatim from the SSDI command.
* All other fields are big endian.
*/
#define FIT_PROTOCOL_VERSION_0 0
/*
* Protocol major version 1 completion entry.
* The major protocol version is found in bits
* 20-23 of the FIT_MTD_FITFW_INIT response.
*/
struct fit_completion_entry_v1 {
__be32 num_returned_bytes;
uint16_t tag;
uint8_t status; /* SCSI status */
uint8_t cycle;
};
#define FIT_PROTOCOL_VERSION_1 1
#define FIT_PROTOCOL_VERSION_CURRENT FIT_PROTOCOL_VERSION_1
struct fit_comp_error_info {
uint8_t type:7; /* 00: Bits0-6 indicates the type of sense data. */
uint8_t valid:1; /* 00: Bit 7 := 1 ==> info field is valid. */
uint8_t reserved0; /* 01: Obsolete field */
uint8_t key:4; /* 02: Bits0-3 indicate the sense key. */
uint8_t reserved2:1; /* 02: Reserved bit. */
uint8_t bad_length:1; /* 02: Incorrect Length Indicator */
uint8_t end_medium:1; /* 02: End of Medium */
uint8_t file_mark:1; /* 02: Filemark */
uint8_t info[4]; /* 03: */
uint8_t reserved1; /* 07: Additional Sense Length */
uint8_t cmd_spec[4]; /* 08: Command Specific Information */
uint8_t code; /* 0C: Additional Sense Code */
uint8_t qual; /* 0D: Additional Sense Code Qualifier */
uint8_t fruc; /* 0E: Field Replaceable Unit Code */
uint8_t sks_high:7; /* 0F: Sense Key Specific (MSB) */
uint8_t sks_valid:1; /* 0F: Sense Key Specific Valid */
uint16_t sks_low; /* 10: Sense Key Specific (LSW) */
uint16_t reserved3; /* 12: Part of additional sense bytes (unused) */
uint16_t uec; /* 14: Additional Sense Bytes */
uint64_t per __packed; /* 16: Additional Sense Bytes */
uint8_t reserved4[2]; /* 1E: Additional Sense Bytes (unused) */
};
/* Task management constants */
#define SOFT_TASK_SIMPLE 0x00
#define SOFT_TASK_HEAD_OF_QUEUE 0x01
#define SOFT_TASK_ORDERED 0x02
/* Version zero has the last 32 bits reserved,
* Version one has the last 32 bits sg_list_len_bytes;
*/
struct skd_command_header {
__be64 sg_list_dma_address;
uint16_t tag;
uint8_t attribute;
uint8_t add_cdb_len; /* In 32 bit words */
__be32 sg_list_len_bytes;
};
struct skd_scsi_request {
struct skd_command_header hdr;
unsigned char cdb[16];
/* unsigned char _reserved[16]; */
};
struct driver_inquiry_data {
uint8_t peripheral_device_type:5;
uint8_t qualifier:3;
uint8_t page_code;
__be16 page_length;
__be16 pcie_bus_number;
uint8_t pcie_device_number;
uint8_t pcie_function_number;
uint8_t pcie_link_speed;
uint8_t pcie_link_lanes;
__be16 pcie_vendor_id;
__be16 pcie_device_id;
__be16 pcie_subsystem_vendor_id;
__be16 pcie_subsystem_device_id;
uint8_t reserved1[2];
uint8_t reserved2[3];
uint8_t driver_version_length;
uint8_t driver_version[0x14];
};
#endif /* SKD_S1120_H */
|