1/*-
2 * Copyright (c) 2018 VMware, Inc.
3 *
4 * SPDX-License-Identifier: (BSD-2-Clause OR GPL-2.0)
5 *
6 * $FreeBSD$
7 */
8
9#ifndef _PVSCSI_H_
10#define _PVSCSI_H_
11
12#define	MASK(v)	((1 << (v)) - 1)
13
14#define	PCI_VENDOR_ID_VMWARE		0x15ad
15#define	PCI_DEVICE_ID_VMWARE_PVSCSI	0x07c0
16
17enum pvscsi_reg_offset {
18	PVSCSI_REG_OFFSET_COMMAND		= 0x0000,
19	PVSCSI_REG_OFFSET_COMMAND_DATA		= 0x0004,
20	PVSCSI_REG_OFFSET_COMMAND_STATUS	= 0x0008,
21	PVSCSI_REG_OFFSET_LAST_STS_0		= 0x0100,
22	PVSCSI_REG_OFFSET_LAST_STS_1		= 0x0104,
23	PVSCSI_REG_OFFSET_LAST_STS_2		= 0x0108,
24	PVSCSI_REG_OFFSET_LAST_STS_3		= 0x010c,
25	PVSCSI_REG_OFFSET_INTR_STATUS		= 0x100c,
26	PVSCSI_REG_OFFSET_INTR_MASK		= 0x2010,
27	PVSCSI_REG_OFFSET_KICK_NON_RW_IO	= 0x3014,
28	PVSCSI_REG_OFFSET_DEBUG			= 0x3018,
29	PVSCSI_REG_OFFSET_KICK_RW_IO		= 0x4018,
30};
31
32enum pvscsi_commands {
33	PVSCSI_CMD_FIRST			= 0,
34
35	PVSCSI_CMD_ADAPTER_RESET		= 1,
36	PVSCSI_CMD_ISSUE_SCSI			= 2,
37	PVSCSI_CMD_SETUP_RINGS			= 3,
38	PVSCSI_CMD_RESET_BUS			= 4,
39	PVSCSI_CMD_RESET_DEVICE			= 5,
40	PVSCSI_CMD_ABORT_CMD			= 6,
41	PVSCSI_CMD_CONFIG			= 7,
42	PVSCSI_CMD_SETUP_MSG_RING		= 8,
43	PVSCSI_CMD_DEVICE_UNPLUG		= 9,
44	PVSCSI_CMD_SETUP_REQCALLTHRESHOLD	= 10,
45	PVSCSI_CMD_GET_MAX_TARGETS		= 11,
46
47	PVSCSI_CMD_LAST				= 12,
48};
49
50struct pvscsi_cmd_desc_reset_device {
51	uint32_t	target;
52	uint8_t		lun[8];
53};
54
55struct pvscsi_cmd_desc_abort_cmd {
56	uint64_t	context;
57	uint32_t	target;
58	uint32_t	pad;
59};
60
61#define	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES	32
62#define	PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES	16
63
64struct pvscsi_cmd_desc_setup_rings {
65	uint32_t	req_ring_num_pages;
66	uint32_t	cmp_ring_num_pages;
67	uint64_t	rings_state_ppn;
68	uint64_t	req_ring_ppns[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
69	uint64_t	cmp_ring_ppns[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
70};
71
72struct pvscsi_cmd_desc_setup_msg_ring {
73	uint32_t	num_pages;
74	uint32_t	pad_;
75	uint64_t	ring_ppns[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES];
76};
77
78struct pvscsi_rings_state {
79	uint32_t	req_prod_idx;
80	uint32_t	req_cons_idx;
81	uint32_t	req_num_entries_log2;
82	uint32_t	cmp_prod_idx;
83	uint32_t	cmp_cons_idx;
84	uint32_t	cmp_num_entries_log2;
85	uint32_t	req_call_threshold;
86	uint8_t		_pad[100];
87	uint32_t	msg_prod_idx;
88	uint32_t	msg_cons_idx;
89	uint32_t	msg_num_entries_log2;
90};
91
92#define	PVSCSI_FLAG_CMD_WITH_SG_LIST	(1 << 0)
93#define	PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB	(1 << 1)
94#define	PVSCSI_FLAG_CMD_DIR_NONE	(1 << 2)
95#define	PVSCSI_FLAG_CMD_DIR_TOHOST	(1 << 3)
96#define	PVSCSI_FLAG_CMD_DIR_TODEVICE	(1 << 4)
97
98#define	PVSCSI_FLAG_RESERVED_MASK	(~MASK(5))
99
100#define	PVSCSI_INTR_CMPL_0	(1 << 0)
101#define	PVSCSI_INTR_CMPL_1	(1 << 1)
102#define	PVSCSI_INTR_CMPL_MASK	MASK(2)
103
104#define	PVSCSI_INTR_MSG_0	(1 << 2)
105#define	PVSCSI_INTR_MSG_1	(1 << 3)
106#define	PVSCSI_INTR_MSG_MASK	(MASK(2) << 2)
107
108#define	PVSCSI_INTR_ALL_SUPPORTED	MASK(4)
109
110struct pvscsi_ring_req_desc {
111	uint64_t	context;
112	uint64_t	data_addr;
113	uint64_t	data_len;
114	uint64_t	sense_addr;
115	uint32_t	sense_len;
116	uint32_t	flags;
117	uint8_t		cdb[16];
118	uint8_t		cdb_len;
119	uint8_t		lun[8];
120	uint8_t		tag;
121	uint8_t		bus;
122	uint8_t		target;
123	uint8_t		vcpu_hint;
124	uint8_t		unused[59];
125};
126
127struct pvscsi_ring_cmp_desc {
128	uint64_t	context;
129	uint64_t	data_len;
130	uint32_t	sense_len;
131	uint16_t	host_status;
132	uint16_t	scsi_status;
133	uint32_t	_pad[2];
134};
135
136#define	PVSCSI_MAX_SG_ENTRIES_PER_SEGMENT	128
137#define	PVSCSI_MAX_NUM_SG_SEGMENTS		128
138#define	PVSCSI_SGE_FLAG_CHAIN_ELEMENT		(1 << 0)
139
140struct pvscsi_sg_element {
141	uint64_t	addr;
142	uint32_t	length;
143	uint32_t	flags;
144};
145
146enum pvscsi_msg_type {
147	PVSCSI_MSG_DEV_ADDED	= 0,
148	PVSCSI_MSG_DEV_REMOVED	= 1,
149	PVSCSI_MSG_LAST	= 2,
150};
151
152struct pvscsi_ring_msg_desc {
153	uint32_t	type;
154	uint32_t	args[31];
155};
156
157struct pvscsi_ring_msg_dev_status_changed {
158	uint32_t	type;
159	uint32_t	bus;
160	uint32_t	target;
161	uint8_t		lun[8];
162	uint32_t	pad[27];
163};
164
165struct pvscsi_cmd_desc_setup_req_call {
166	uint32_t	enable;
167};
168
169#define	PVSCSI_MAX_NUM_PAGES_REQ_RING	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
170#define	PVSCSI_MAX_NUM_PAGES_CMP_RING	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
171#define	PVSCSI_MAX_NUM_PAGES_MSG_RING	PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES
172
173#define	PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \
174	(PAGE_SIZE / sizeof(struct pvscsi_ring_req_desc))
175#define	PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE \
176	(PAGE_SIZE / sizeof(struct pvscs_ring_cmp_desc))
177#define	PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE \
178	(PAGE_SIZE / sizeof(struct pvscsi_ring_msg_desc))
179
180#define	PVSCSI_MAX_REQ_QUEUE_DEPTH \
181	(PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE)
182#define	PVSCSI_MAX_CMP_QUEUE_DEPTH \
183	(PVSCSI_MAX_NUM_PAGES_CMP_RING * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE)
184#define	PVSCSI_MAX_QUEUE_DEPTH \
185	MAX(PVSCSI_MAX_REQ_QUEUE_DEPTH, PVSCSI_MAX_CMP_QUEUE_DEPTH)
186
187enum pvscsi_host_status {
188	BTSTAT_SUCCESS		= 0x00,
189	BTSTAT_LINKED_COMMAND_COMPLETED			= 0x0a,
190	BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG	= 0x0b,
191	BTSTAT_DATA_UNDERRUN	= 0x0c,
192	BTSTAT_SELTIMEO		= 0x11,
193	BTSTAT_DATARUN		= 0x12,
194	BTSTAT_BUSFREE		= 0x13,
195	BTSTAT_INVPHASE		= 0x14,
196	BTSTAT_INVCODE		= 0x15,
197	BTSTAT_INVOPCODE	= 0x16,
198	BTSTAT_LUNMISMATCH	= 0x17,
199	BTSTAT_INVPARAM		= 0x1a,
200	BTSTAT_SENSFAILED	= 0x1b,
201	BTSTAT_TAGREJECT	= 0x1c,
202	BTSTAT_BADMSG		= 0x1d,
203	BTSTAT_HAHARDWARE	= 0x20,
204	BTSTAT_NORESPONSE	= 0x21,
205	BTSTAT_SENTRST		= 0x22,
206	BTSTAT_RECVRST		= 0x23,
207	BTSTAT_DISCONNECT	= 0x24,
208	BTSTAT_BUSRESET		= 0x25,
209	BTSTAT_ABORTQUEUE	= 0x26,
210	BTSTAT_HASOFTWARE	= 0x27,
211	BTSTAT_HATIMEOUT	= 0x30,
212	BTSTAT_SCSIPARITY	= 0x34,
213};
214
215#endif /* !_PVSCSI_H_ */
216