1/* $NetBSD: ipmivar.h,v 1.3 2019/05/18 08:38:00 mlelstv Exp $ */
2
3/*
4 * Copyright (c) 2005 Jordan Hargrave
5 * All rights reserved.
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 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30#include <sys/mutex.h>
31#include <sys/condvar.h>
32
33#include <dev/sysmon/sysmonvar.h>
34
35#ifndef _IPMIVAR_H_
36#define _IPMIVAR_H_
37
38#define IPMI_IF_KCS		1
39#define IPMI_IF_SMIC		2
40#define IPMI_IF_BT		3
41#define IPMI_IF_SSIF		4
42
43#define IPMI_IF_KCS_NREGS	2
44#define IPMI_IF_SMIC_NREGS	3
45#define IPMI_IF_BT_NREGS	3
46#define IPMI_IF_SSIF_NREGS	2
47
48struct ipmi_thread;
49struct ipmi_softc;
50
51struct ipmi_attach_args {
52	bus_space_tag_t	iaa_iot;
53	bus_space_tag_t	iaa_memt;
54
55	int		iaa_if_type;
56	int		iaa_if_rev;
57	int		iaa_if_iotype;
58	bus_addr_t	iaa_if_iobase;
59	int		iaa_if_iospacing;
60	int		iaa_if_irq;
61	int		iaa_if_irqlvl;
62};
63
64struct ipmi_if {
65	const char	*name;
66	int		nregs;
67	void		*(*buildmsg)(struct ipmi_softc *, int, int, int,
68			    const void *, int *);
69	int		(*sendmsg)(struct ipmi_softc *, int, const uint8_t *);
70	int		(*recvmsg)(struct ipmi_softc *, int, int *, uint8_t *);
71	int		(*reset)(struct ipmi_softc *);
72	int		(*probe)(struct ipmi_softc *);
73};
74
75struct ipmi_softc {
76	device_t		sc_dev;
77
78	struct ipmi_if		*sc_if;		/* Interface layer */
79	int			sc_if_iospacing; /* Spacing of I/O ports */
80	int			sc_if_rev;	/* IPMI Revision */
81	struct ipmi_attach_args	sc_ia;
82
83	void			*sc_ih;		/* Interrupt/IO handles */
84	bus_space_tag_t		sc_iot;
85	bus_space_handle_t	sc_ioh;
86
87	int			sc_btseq;
88
89	struct lwp		*sc_kthread;
90
91	int			sc_max_retries;
92
93	kmutex_t		sc_poll_mtx;
94	kcondvar_t		sc_poll_cv;
95	kcondvar_t		sc_mode_cv;
96
97	kmutex_t		sc_cmd_mtx;
98	kmutex_t		sc_sleep_mtx;
99	kcondvar_t		sc_cmd_sleep;
100
101	struct ipmi_bmc_args	*sc_iowait_args;
102
103	struct ipmi_sensor	*current_sensor;
104	volatile bool		sc_thread_running;
105	volatile bool		sc_tickle_due;
106	struct sysmon_wdog	sc_wdog;
107	struct sysmon_envsys	*sc_envsys;
108	envsys_data_t		*sc_sensor;
109	int 		sc_nsensors; /* total number of sensors */
110
111	char		sc_buf[1024 + 3]; /* IPMI_MAX_RX + 3 */
112	bool		sc_buf_rsvd;
113
114	/* request busy */
115	int		sc_mode;
116#define IPMI_MODE_IDLE		0
117#define IPMI_MODE_COMMAND	1
118#define IPMI_MODE_ENVSYS	2
119	bool		sc_sent;
120
121	/* dummy */
122	int		sc_address;
123	int		sc_lun;
124
125	/* saved from last SEND_COMMAND */
126	int		sc_msgid;
127	int		sc_netfn;
128	int		sc_cmd;
129};
130
131struct ipmi_device_id {
132	uint8_t		deviceid;
133	uint8_t		revision;
134	uint8_t		fwrev1;
135	uint8_t		fwrev2;
136	uint8_t		version;
137	uint8_t		additional;
138	uint8_t		manufacturer[3];
139	uint8_t		product[2];
140	uint8_t		vendor[4];
141} __packed;
142
143struct ipmi_thread {
144	struct ipmi_softc   *sc;
145	volatile int	    running;
146};
147
148#define IPMI_WDOG_USE_NOLOG		__BIT(7)
149#define IPMI_WDOG_USE_NOSTOP		__BIT(6)
150#define IPMI_WDOG_USE_RSVD1		__BITS(5, 3)
151#define IPMI_WDOG_USE_USE_MASK		__BITS(2, 0)
152#define IPMI_WDOG_USE_USE_RSVD		__SHIFTIN(0, IPMI_WDOG_USE_USE_MASK);
153#define IPMI_WDOG_USE_USE_FRB2		__SHIFTIN(1, IPMI_WDOG_USE_USE_MASK);
154#define IPMI_WDOG_USE_USE_POST		__SHIFTIN(2, IPMI_WDOG_USE_USE_MASK);
155#define IPMI_WDOG_USE_USE_OSLOAD	__SHIFTIN(3, IPMI_WDOG_USE_USE_MASK);
156#define IPMI_WDOG_USE_USE_OS		__SHIFTIN(4, IPMI_WDOG_USE_USE_MASK);
157#define IPMI_WDOG_USE_USE_OEM		__SHIFTIN(5, IPMI_WDOG_USE_USE_MASK);
158
159#define IPMI_WDOG_ACT_PRE_RSVD1		__BIT(7)
160#define IPMI_WDOG_ACT_PRE_MASK		__BITS(6, 4)
161#define IPMI_WDOG_ACT_PRE_DISABLED	__SHIFTIN(0, IPMI_WDOG_ACT_MASK)
162#define IPMI_WDOG_ACT_PRE_SMI		__SHIFTIN(1, IPMI_WDOG_ACT_MASK)
163#define IPMI_WDOG_ACT_PRE_NMI		__SHIFTIN(2, IPMI_WDOG_ACT_MASK)
164#define IPMI_WDOG_ACT_PRE_INTERRUPT	__SHIFTIN(3, IPMI_WDOG_ACT_MASK)
165#define IPMI_WDOG_ACT_PRE_RSVD0		__BIT(3)
166#define IPMI_WDOG_ACT_MASK		__BITS(2, 0)
167#define IPMI_WDOG_ACT_DISABLED		__SHIFTIN(0, IPMI_WDOG_ACT_MASK)
168#define IPMI_WDOG_ACT_RESET		__SHIFTIN(1, IPMI_WDOG_ACT_MASK)
169#define IPMI_WDOG_ACT_PWROFF		__SHIFTIN(2, IPMI_WDOG_ACT_MASK)
170#define IPMI_WDOG_ACT_PWRCYCLE		__SHIFTIN(3, IPMI_WDOG_ACT_MASK)
171
172#define IPMI_WDOG_FLAGS_RSVD1		__BITS(7, 6)
173#define IPMI_WDOG_FLAGS_OEM		__BIT(5)
174#define IPMI_WDOG_FLAGS_OS		__BIT(4)
175#define IPMI_WDOG_FLAGS_OSLOAD		__BIT(3)
176#define IPMI_WDOG_FLAGS_POST		__BIT(2)
177#define IPMI_WDOG_FLAGS_FRB2		__BIT(1)
178#define IPMI_WDOG_FLAGS_RSVD0		__BIT(0)
179
180struct ipmi_set_watchdog {
181	uint8_t		wdog_use;
182	uint8_t		wdog_action;
183	uint8_t		wdog_pretimeout;
184	uint8_t		wdog_flags;
185	uint16_t		wdog_timeout;
186} __packed;
187
188struct ipmi_get_watchdog {
189	uint8_t		wdog_use;
190	uint8_t		wdog_action;
191	uint8_t		wdog_pretimeout;
192	uint8_t		wdog_flags;
193	uint16_t		wdog_timeout;
194	uint16_t		wdog_countdown;
195} __packed;
196
197struct dmd_ipmi {
198	uint8_t	dmd_sig[4];		/* Signature 'IPMI' */
199	uint8_t	dmd_i2c_address;	/* Address of BMC */
200	uint8_t	dmd_nvram_address;	/* Address of NVRAM */
201	uint8_t	dmd_if_type;		/* IPMI Interface Type */
202	uint8_t	dmd_if_rev;		/* IPMI Interface Revision */
203} __packed;
204
205#define APP_NETFN			0x06
206#define APP_GET_DEVICE_ID		0x01
207#define APP_RESET_WATCHDOG		0x22
208#define APP_SET_WATCHDOG_TIMER		0x24
209#define APP_GET_WATCHDOG_TIMER		0x25
210
211#define TRANSPORT_NETFN			0xC
212#define BRIDGE_NETFN			0x2
213
214#define STORAGE_NETFN			0x0A
215#define STORAGE_GET_FRU_INV_AREA	0x10
216#define STORAGE_READ_FRU_DATA		0x11
217#define STORAGE_RESERVE_SDR		0x22
218#define STORAGE_GET_SDR			0x23
219#define STORAGE_ADD_SDR			0x24
220#define STORAGE_ADD_PARTIAL_SDR		0x25
221#define STORAGE_DELETE_SDR		0x26
222#define STORAGE_RESERVE_SEL		0x42
223#define STORAGE_GET_SEL			0x43
224#define STORAGE_ADD_SEL			0x44
225#define STORAGE_ADD_PARTIAL_SEL		0x45
226#define STORAGE_DELETE_SEL		0x46
227
228#define SE_NETFN			0x04
229#define SE_GET_SDR_INFO			0x20
230#define SE_GET_SDR			0x21
231#define SE_RESERVE_SDR			0x22
232#define SE_GET_SENSOR_FACTOR		0x23
233#define SE_SET_SENSOR_HYSTERESIS	0x24
234#define SE_GET_SENSOR_HYSTERESIS	0x25
235#define SE_SET_SENSOR_THRESHOLD		0x26
236#define SE_GET_SENSOR_THRESHOLD		0x27
237#define SE_SET_SENSOR_EVENT_ENABLE	0x28
238#define SE_GET_SENSOR_EVENT_ENABLE	0x29
239#define SE_REARM_SENSOR_EVENTS		0x2A
240#define SE_GET_SENSOR_EVENT_STATUS	0x2B
241#define SE_GET_SENSOR_READING		0x2D
242#define SE_SET_SENSOR_TYPE		0x2E
243#define SE_GET_SENSOR_TYPE		0x2F
244
245struct sdrhdr {
246	uint16_t	record_id;		/* SDR Record ID */
247	uint8_t	sdr_version;		/* SDR Version */
248	uint8_t	record_type;		/* SDR Record Type */
249	uint8_t	record_length;		/* SDR Record Length */
250} __packed;
251
252/* SDR: Record Type 1 */
253struct sdrtype1 {
254	struct sdrhdr	sdrhdr;
255
256	uint8_t	owner_id;
257	uint8_t	owner_lun;
258	uint8_t	sensor_num;
259
260	uint8_t	entity_id;
261	uint8_t	entity_instance;
262	uint8_t	sensor_init;
263	uint8_t	sensor_caps;
264	uint8_t	sensor_type;
265	uint8_t	event_code;
266	uint16_t	trigger_mask;
267	uint16_t	reading_mask;
268	uint16_t	settable_mask;
269	uint8_t	units1;
270	uint8_t	units2;
271	uint8_t	units3;
272	uint8_t	linear;
273	uint8_t	m;
274	uint8_t	m_tolerance;
275	uint8_t	b;
276	uint8_t	b_accuracy;
277	uint8_t	accuracyexp;
278	uint8_t	rbexp;
279	uint8_t	analogchars;
280	uint8_t	nominalreading;
281	uint8_t	normalmax;
282	uint8_t	normalmin;
283	uint8_t	sensormax;
284	uint8_t	sensormin;
285	uint8_t	uppernr;
286	uint8_t	upperc;
287	uint8_t	uppernc;
288	uint8_t	lowernr;
289	uint8_t	lowerc;
290	uint8_t	lowernc;
291	uint8_t	physt;
292	uint8_t	nhyst;
293	uint8_t	resvd[2];
294	uint8_t	oem;
295	uint8_t	typelen;
296	uint8_t	name[1];
297} __packed;
298
299/* SDR: Record Type 2 */
300struct sdrtype2 {
301	struct sdrhdr	sdrhdr;
302
303	uint8_t	owner_id;
304	uint8_t	owner_lun;
305	uint8_t	sensor_num;
306
307	uint8_t	entity_id;
308	uint8_t	entity_instance;
309	uint8_t	sensor_init;
310	uint8_t	sensor_caps;
311	uint8_t	sensor_type;
312	uint8_t	event_code;
313	uint16_t	trigger_mask;
314	uint16_t	reading_mask;
315	uint16_t	set_mask;
316	uint8_t	units1;
317	uint8_t	units2;
318	uint8_t	units3;
319	uint8_t	share1;
320	uint8_t	share2;
321	uint8_t	physt;
322	uint8_t	nhyst;
323	uint8_t	resvd[3];
324	uint8_t	oem;
325	uint8_t	typelen;
326	uint8_t	name[1];
327} __packed;
328
329#endif				/* _IPMIVAR_H_ */
330