xref: /openbsd-src/sys/dev/ipmivar.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /* $OpenBSD: ipmivar.h,v 1.28 2016/02/05 06:29:01 uebayasi 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 #ifndef _IPMIVAR_H_
31 #define _IPMIVAR_H_
32 
33 #include <sys/rwlock.h>
34 #include <sys/sensors.h>
35 #include <sys/task.h>
36 
37 #include <dev/ipmi.h>
38 
39 #define IPMI_IF_KCS		1
40 #define IPMI_IF_SMIC		2
41 #define IPMI_IF_BT		3
42 
43 #define IPMI_IF_KCS_NREGS	2
44 #define IPMI_IF_SMIC_NREGS	3
45 #define IPMI_IF_BT_NREGS	3
46 
47 struct ipmi_thread;
48 struct ipmi_softc;
49 struct ipmi_cmd;
50 
51 struct ipmi_iowait {
52 	int			offset;
53 	u_int8_t		mask;
54 	u_int8_t		value;
55 	volatile u_int8_t	*v;
56 	const char		*lbl;
57 };
58 
59 struct ipmi_attach_args {
60 	char		*iaa_name;
61 	bus_space_tag_t	iaa_iot;
62 	bus_space_tag_t	iaa_memt;
63 
64 	int		iaa_if_type;
65 	int		iaa_if_rev;
66 	int		iaa_if_iotype;
67 	int		iaa_if_iobase;
68 	int		iaa_if_iospacing;
69 	int		iaa_if_irq;
70 	int		iaa_if_irqlvl;
71 };
72 
73 struct ipmi_if {
74 	const char	*name;
75 	int		nregs;
76 	void		(*buildmsg)(struct ipmi_cmd *);
77 	int		(*sendmsg)(struct ipmi_cmd *);
78 	int		(*recvmsg)(struct ipmi_cmd *);
79 	int		(*reset)(struct ipmi_softc *);
80 	int		(*probe)(struct ipmi_softc *);
81 	int		datasnd;
82 	int		datarcv;
83 };
84 
85 struct ipmi_cmd {
86 	struct ipmi_softc	*c_sc;
87 
88 	int			c_rssa;
89 	int			c_rslun;
90 	int			c_netfn;
91 	int			c_cmd;
92 
93 	int			c_txlen;
94 	int			c_maxrxlen;
95 	int			c_rxlen;
96 
97 	void			*c_data;
98 	u_int			c_ccode;
99 };
100 
101 struct ipmi_softc {
102 	struct device		sc_dev;
103 
104 	struct ipmi_if		*sc_if;			/* Interface layer */
105 	int			sc_if_iospacing;	/* Spacing of I/O ports */
106 	int			sc_if_rev;		/* IPMI Revision */
107 
108 	void			*sc_ih;			/* Interrupt/IO handles */
109 	bus_space_tag_t		sc_iot;
110 	bus_space_handle_t	sc_ioh;
111 
112 	int			sc_btseq;
113 	u_int8_t		sc_buf[IPMI_MAX_RX + 16];
114 	struct taskq		*sc_cmd_taskq;
115 	struct mutex		sc_cmd_mtx;
116 
117 	struct ipmi_ioctl {
118 		struct rwlock		lock;
119 		struct ipmi_req		req;
120 		struct ipmi_cmd		cmd;
121 		uint8_t			buf[IPMI_MAX_RX];
122 	} sc_ioctl;
123 
124 	int			sc_wdog_period;
125 	struct task		sc_wdog_tickle_task;
126 
127 	struct ipmi_thread	*sc_thread;
128 
129 	struct ipmi_sensor	*current_sensor;
130 	struct ksensordev	sc_sensordev;
131 };
132 
133 struct ipmi_thread {
134 	struct ipmi_softc   *sc;
135 	volatile int	    running;
136 };
137 
138 #define IPMI_WDOG_DONTSTOP	0x40
139 
140 #define IPMI_WDOG_MASK		0x03
141 #define IPMI_WDOG_DISABLED	0x00
142 #define IPMI_WDOG_REBOOT	0x01
143 #define IPMI_WDOG_PWROFF	0x02
144 #define IPMI_WDOG_PWRCYCLE	0x03
145 
146 #define IPMI_WDOG_PRE_DISABLED	0x00
147 #define IPMI_WDOG_PRE_SMI	0x01
148 #define IPMI_WDOG_PRE_NMI	0x02
149 #define IPMI_WDOG_PRE_INTERRUPT	0x03
150 
151 #define	IPMI_SET_WDOG_TIMER	0
152 #define	IPMI_SET_WDOG_ACTION	1
153 #define	IPMI_SET_WDOG_PRETIMO	2
154 #define	IPMI_SET_WDOG_FLAGS	3
155 #define	IPMI_SET_WDOG_TIMOL	4
156 #define	IPMI_SET_WDOG_TIMOM	5
157 #define	IPMI_SET_WDOG_MAX	6
158 
159 #define	IPMI_GET_WDOG_TIMER	IPMI_SET_WDOG_TIMER
160 #define	IPMI_GET_WDOG_ACTION	IPMI_SET_WDOG_ACTION
161 #define	IPMI_GET_WDOG_PRETIMO	IPMI_SET_WDOG_PRETIMO
162 #define	IPMI_GET_WDOG_FLAGS	IPMI_SET_WDOG_FLAGS
163 #define	IPMI_GET_WDOG_TIMOL	IPMI_SET_WDOG_TIMOL
164 #define	IPMI_GET_WDOG_TIMOM	IPMI_SET_WDOG_TIMOM
165 #define	IPMI_GET_WDOG_PRECDL	6
166 #define	IPMI_GET_WDOG_PRECDM	7
167 #define	IPMI_GET_WDOG_MAX	8
168 
169 void	ipmi_create_thread(void *);
170 void	ipmi_poll_thread(void *);
171 
172 int	kcs_probe(struct ipmi_softc *);
173 int	kcs_reset(struct ipmi_softc *);
174 int	kcs_sendmsg(struct ipmi_cmd *);
175 int	kcs_recvmsg(struct ipmi_cmd *);
176 
177 int	bt_probe(struct ipmi_softc *);
178 int	bt_reset(struct ipmi_softc *);
179 int	bt_sendmsg(struct ipmi_cmd *);
180 int	bt_recvmsg(struct ipmi_cmd *);
181 
182 int	smic_probe(struct ipmi_softc *);
183 int	smic_reset(struct ipmi_softc *);
184 int	smic_sendmsg(struct ipmi_cmd *);
185 int	smic_recvmsg(struct ipmi_cmd *);
186 
187 struct dmd_ipmi {
188 	u_int8_t	dmd_sig[4];		/* Signature 'IPMI' */
189 	u_int8_t	dmd_i2c_address;	/* Address of BMC */
190 	u_int8_t	dmd_nvram_address;	/* Address of NVRAM */
191 	u_int8_t	dmd_if_type;		/* IPMI Interface Type */
192 	u_int8_t	dmd_if_rev;		/* IPMI Interface Revision */
193 } __packed;
194 
195 
196 #define APP_NETFN			0x06
197 #define APP_GET_DEVICE_ID		0x01
198 #define APP_RESET_WATCHDOG		0x22
199 #define APP_SET_WATCHDOG_TIMER		0x24
200 #define APP_GET_WATCHDOG_TIMER		0x25
201 
202 #define TRANSPORT_NETFN			0xC
203 #define BRIDGE_NETFN			0x2
204 
205 #define STORAGE_NETFN			0x0A
206 #define STORAGE_GET_FRU_INV_AREA	0x10
207 #define STORAGE_READ_FRU_DATA		0x11
208 #define STORAGE_RESERVE_SDR		0x22
209 #define STORAGE_GET_SDR			0x23
210 #define STORAGE_ADD_SDR			0x24
211 #define STORAGE_ADD_PARTIAL_SDR		0x25
212 #define STORAGE_DELETE_SDR		0x26
213 #define STORAGE_RESERVE_SEL		0x42
214 #define STORAGE_GET_SEL			0x43
215 #define STORAGE_ADD_SEL			0x44
216 #define STORAGE_ADD_PARTIAL_SEL		0x45
217 #define STORAGE_DELETE_SEL		0x46
218 
219 #define SE_NETFN			0x04
220 #define SE_GET_SDR_INFO			0x20
221 #define SE_GET_SDR			0x21
222 #define SE_RESERVE_SDR			0x22
223 #define SE_GET_SENSOR_FACTOR		0x23
224 #define SE_SET_SENSOR_HYSTERESIS	0x24
225 #define SE_GET_SENSOR_HYSTERESIS	0x25
226 #define SE_SET_SENSOR_THRESHOLD		0x26
227 #define SE_GET_SENSOR_THRESHOLD		0x27
228 #define SE_SET_SENSOR_EVENT_ENABLE	0x28
229 #define SE_GET_SENSOR_EVENT_ENABLE	0x29
230 #define SE_REARM_SENSOR_EVENTS		0x2A
231 #define SE_GET_SENSOR_EVENT_STATUS	0x2B
232 #define SE_GET_SENSOR_READING		0x2D
233 #define SE_SET_SENSOR_TYPE		0x2E
234 #define SE_GET_SENSOR_TYPE		0x2F
235 
236 struct sdrhdr {
237 	u_int16_t	record_id;		/* SDR Record ID */
238 	u_int8_t	sdr_version;		/* SDR Version */
239 	u_int8_t	record_type;		/* SDR Record Type */
240 	u_int8_t	record_length;		/* SDR Record Length */
241 } __packed;
242 
243 /* SDR: Record Type 1 */
244 struct sdrtype1 {
245 	struct sdrhdr	sdrhdr;
246 
247 	u_int8_t	owner_id;
248 	u_int8_t	owner_lun;
249 	u_int8_t	sensor_num;
250 
251 	u_int8_t	entity_id;
252 	u_int8_t	entity_instance;
253 	u_int8_t	sensor_init;
254 	u_int8_t	sensor_caps;
255 	u_int8_t	sensor_type;
256 	u_int8_t	event_code;
257 	u_int16_t	trigger_mask;
258 	u_int16_t	reading_mask;
259 	u_int16_t	settable_mask;
260 	u_int8_t	units1;
261 	u_int8_t	units2;
262 	u_int8_t	units3;
263 	u_int8_t	linear;
264 	u_int8_t	m;
265 	u_int8_t	m_tolerance;
266 	u_int8_t	b;
267 	u_int8_t	b_accuracy;
268 	u_int8_t	accuracyexp;
269 	u_int8_t	rbexp;
270 	u_int8_t	analogchars;
271 	u_int8_t	nominalreading;
272 	u_int8_t	normalmax;
273 	u_int8_t	normalmin;
274 	u_int8_t	sensormax;
275 	u_int8_t	sensormin;
276 	u_int8_t	uppernr;
277 	u_int8_t	upperc;
278 	u_int8_t	uppernc;
279 	u_int8_t	lowernr;
280 	u_int8_t	lowerc;
281 	u_int8_t	lowernc;
282 	u_int8_t	physt;
283 	u_int8_t	nhyst;
284 	u_int8_t	resvd[2];
285 	u_int8_t	oem;
286 	u_int8_t	typelen;
287 	u_int8_t	name[1];
288 } __packed;
289 
290 /* SDR: Record Type 2 */
291 struct sdrtype2 {
292 	struct sdrhdr	sdrhdr;
293 
294 	u_int8_t	owner_id;
295 	u_int8_t	owner_lun;
296 	u_int8_t	sensor_num;
297 
298 	u_int8_t	entity_id;
299 	u_int8_t	entity_instance;
300 	u_int8_t	sensor_init;
301 	u_int8_t	sensor_caps;
302 	u_int8_t	sensor_type;
303 	u_int8_t	event_code;
304 	u_int16_t	trigger_mask;
305 	u_int16_t	reading_mask;
306 	u_int16_t	set_mask;
307 	u_int8_t	units1;
308 	u_int8_t	units2;
309 	u_int8_t	units3;
310 	u_int8_t	share1;
311 	u_int8_t	share2;
312 	u_int8_t	physt;
313 	u_int8_t	nhyst;
314 	u_int8_t	resvd[3];
315 	u_int8_t	oem;
316 	u_int8_t	typelen;
317 	u_int8_t	name[1];
318 } __packed;
319 
320 int ipmi_probe(void *);
321 
322 #endif				/* _IPMIVAR_H_ */
323