1 | /* $NetBSD: ipmivar.h,v 1.11 2010/08/01 08:16:14 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 | |
42 | #define IPMI_IF_KCS_NREGS 2 |
43 | #define IPMI_IF_SMIC_NREGS 3 |
44 | #define IPMI_IF_BT_NREGS 3 |
45 | |
46 | struct ipmi_thread; |
47 | struct ipmi_softc; |
48 | |
49 | struct ipmi_attach_args { |
50 | bus_space_tag_t iaa_iot; |
51 | bus_space_tag_t iaa_memt; |
52 | |
53 | int iaa_if_type; |
54 | int iaa_if_rev; |
55 | int iaa_if_iotype; |
56 | int iaa_if_iobase; |
57 | int iaa_if_iospacing; |
58 | int iaa_if_irq; |
59 | int iaa_if_irqlvl; |
60 | }; |
61 | |
62 | struct ipmi_if { |
63 | const char *name; |
64 | int nregs; |
65 | void *(*buildmsg)(struct ipmi_softc *, int, int, int, |
66 | const void *, int *); |
67 | int (*sendmsg)(struct ipmi_softc *, int, const uint8_t *); |
68 | int (*recvmsg)(struct ipmi_softc *, int, int *, uint8_t *); |
69 | int (*reset)(struct ipmi_softc *); |
70 | int (*probe)(struct ipmi_softc *); |
71 | }; |
72 | |
73 | struct ipmi_softc { |
74 | device_t sc_dev; |
75 | |
76 | struct ipmi_if *sc_if; /* Interface layer */ |
77 | int sc_if_iospacing; /* Spacing of I/O ports */ |
78 | int sc_if_rev; /* IPMI Revision */ |
79 | struct ipmi_attach_args sc_ia; |
80 | |
81 | void *sc_ih; /* Interrupt/IO handles */ |
82 | bus_space_tag_t sc_iot; |
83 | bus_space_handle_t sc_ioh; |
84 | |
85 | int sc_btseq; |
86 | |
87 | struct lwp *sc_kthread; |
88 | |
89 | int sc_max_retries; |
90 | |
91 | kmutex_t sc_poll_mtx; |
92 | kcondvar_t sc_poll_cv; |
93 | |
94 | kmutex_t sc_cmd_mtx; |
95 | kmutex_t sc_sleep_mtx; |
96 | kcondvar_t sc_cmd_sleep; |
97 | |
98 | struct ipmi_bmc_args *sc_iowait_args; |
99 | |
100 | struct ipmi_sensor *current_sensor; |
101 | volatile bool sc_thread_running; |
102 | volatile bool sc_tickle_due; |
103 | struct sysmon_wdog sc_wdog; |
104 | struct sysmon_envsys *sc_envsys; |
105 | envsys_data_t *sc_sensor; |
106 | int sc_nsensors; /* total number of sensors */ |
107 | |
108 | char sc_buf[64]; |
109 | bool sc_buf_rsvd; |
110 | }; |
111 | |
112 | struct ipmi_thread { |
113 | struct ipmi_softc *sc; |
114 | volatile int running; |
115 | }; |
116 | |
117 | #define IPMI_WDOG_USE_NOLOG __BIT(7) |
118 | #define IPMI_WDOG_USE_NOSTOP __BIT(6) |
119 | #define IPMI_WDOG_USE_RSVD1 __BITS(5, 3) |
120 | #define IPMI_WDOG_USE_USE_MASK __BITS(2, 0) |
121 | #define IPMI_WDOG_USE_USE_RSVD __SHIFTIN(0, IPMI_WDOG_USE_USE_MASK); |
122 | #define IPMI_WDOG_USE_USE_FRB2 __SHIFTIN(1, IPMI_WDOG_USE_USE_MASK); |
123 | #define IPMI_WDOG_USE_USE_POST __SHIFTIN(2, IPMI_WDOG_USE_USE_MASK); |
124 | #define IPMI_WDOG_USE_USE_OSLOAD __SHIFTIN(3, IPMI_WDOG_USE_USE_MASK); |
125 | #define IPMI_WDOG_USE_USE_OS __SHIFTIN(4, IPMI_WDOG_USE_USE_MASK); |
126 | #define IPMI_WDOG_USE_USE_OEM __SHIFTIN(5, IPMI_WDOG_USE_USE_MASK); |
127 | |
128 | #define IPMI_WDOG_ACT_PRE_RSVD1 __BIT(7) |
129 | #define IPMI_WDOG_ACT_PRE_MASK __BITS(6, 4) |
130 | #define IPMI_WDOG_ACT_PRE_DISABLED __SHIFTIN(0, IPMI_WDOG_ACT_MASK) |
131 | #define IPMI_WDOG_ACT_PRE_SMI __SHIFTIN(1, IPMI_WDOG_ACT_MASK) |
132 | #define IPMI_WDOG_ACT_PRE_NMI __SHIFTIN(2, IPMI_WDOG_ACT_MASK) |
133 | #define IPMI_WDOG_ACT_PRE_INTERRUPT __SHIFTIN(3, IPMI_WDOG_ACT_MASK) |
134 | #define IPMI_WDOG_ACT_PRE_RSVD0 __BIT(3) |
135 | #define IPMI_WDOG_ACT_MASK __BITS(2, 0) |
136 | #define IPMI_WDOG_ACT_DISABLED __SHIFTIN(0, IPMI_WDOG_ACT_MASK) |
137 | #define IPMI_WDOG_ACT_RESET __SHIFTIN(1, IPMI_WDOG_ACT_MASK) |
138 | #define IPMI_WDOG_ACT_PWROFF __SHIFTIN(2, IPMI_WDOG_ACT_MASK) |
139 | #define IPMI_WDOG_ACT_PWRCYCLE __SHIFTIN(3, IPMI_WDOG_ACT_MASK) |
140 | |
141 | #define IPMI_WDOG_FLAGS_RSVD1 __BITS(7, 6) |
142 | #define IPMI_WDOG_FLAGS_OEM __BIT(5) |
143 | #define IPMI_WDOG_FLAGS_OS __BIT(4) |
144 | #define IPMI_WDOG_FLAGS_OSLOAD __BIT(3) |
145 | #define IPMI_WDOG_FLAGS_POST __BIT(2) |
146 | #define IPMI_WDOG_FLAGS_FRB2 __BIT(1) |
147 | #define IPMI_WDOG_FLAGS_RSVD0 __BIT(0) |
148 | |
149 | struct ipmi_set_watchdog { |
150 | uint8_t wdog_use; |
151 | uint8_t wdog_action; |
152 | uint8_t wdog_pretimeout; |
153 | uint8_t wdog_flags; |
154 | uint16_t wdog_timeout; |
155 | } __packed; |
156 | |
157 | struct ipmi_get_watchdog { |
158 | uint8_t wdog_use; |
159 | uint8_t wdog_action; |
160 | uint8_t wdog_pretimeout; |
161 | uint8_t wdog_flags; |
162 | uint16_t wdog_timeout; |
163 | uint16_t wdog_countdown; |
164 | } __packed; |
165 | |
166 | void ipmi_poll_thread(void *); |
167 | |
168 | int kcs_probe(struct ipmi_softc *); |
169 | int kcs_reset(struct ipmi_softc *); |
170 | int kcs_sendmsg(struct ipmi_softc *, int, const uint8_t *); |
171 | int kcs_recvmsg(struct ipmi_softc *, int, int *len, uint8_t *); |
172 | |
173 | int bt_probe(struct ipmi_softc *); |
174 | int bt_reset(struct ipmi_softc *); |
175 | int bt_sendmsg(struct ipmi_softc *, int, const uint8_t *); |
176 | int bt_recvmsg(struct ipmi_softc *, int, int *, uint8_t *); |
177 | |
178 | int smic_probe(struct ipmi_softc *); |
179 | int smic_reset(struct ipmi_softc *); |
180 | int smic_sendmsg(struct ipmi_softc *, int, const uint8_t *); |
181 | int smic_recvmsg(struct ipmi_softc *, int, int *, uint8_t *); |
182 | |
183 | struct dmd_ipmi { |
184 | uint8_t dmd_sig[4]; /* Signature 'IPMI' */ |
185 | uint8_t dmd_i2c_address; /* Address of BMC */ |
186 | uint8_t dmd_nvram_address; /* Address of NVRAM */ |
187 | uint8_t dmd_if_type; /* IPMI Interface Type */ |
188 | uint8_t dmd_if_rev; /* IPMI Interface Revision */ |
189 | } __packed; |
190 | |
191 | |
192 | #define APP_NETFN 0x06 |
193 | #define APP_GET_DEVICE_ID 0x01 |
194 | #define APP_RESET_WATCHDOG 0x22 |
195 | #define APP_SET_WATCHDOG_TIMER 0x24 |
196 | #define APP_GET_WATCHDOG_TIMER 0x25 |
197 | |
198 | #define TRANSPORT_NETFN 0xC |
199 | #define BRIDGE_NETFN 0x2 |
200 | |
201 | #define STORAGE_NETFN 0x0A |
202 | #define STORAGE_GET_FRU_INV_AREA 0x10 |
203 | #define STORAGE_READ_FRU_DATA 0x11 |
204 | #define STORAGE_RESERVE_SDR 0x22 |
205 | #define STORAGE_GET_SDR 0x23 |
206 | #define STORAGE_ADD_SDR 0x24 |
207 | #define STORAGE_ADD_PARTIAL_SDR 0x25 |
208 | #define STORAGE_DELETE_SDR 0x26 |
209 | #define STORAGE_RESERVE_SEL 0x42 |
210 | #define STORAGE_GET_SEL 0x43 |
211 | #define STORAGE_ADD_SEL 0x44 |
212 | #define STORAGE_ADD_PARTIAL_SEL 0x45 |
213 | #define STORAGE_DELETE_SEL 0x46 |
214 | |
215 | #define SE_NETFN 0x04 |
216 | #define SE_GET_SDR_INFO 0x20 |
217 | #define SE_GET_SDR 0x21 |
218 | #define SE_RESERVE_SDR 0x22 |
219 | #define SE_GET_SENSOR_FACTOR 0x23 |
220 | #define SE_SET_SENSOR_HYSTERESIS 0x24 |
221 | #define SE_GET_SENSOR_HYSTERESIS 0x25 |
222 | #define SE_SET_SENSOR_THRESHOLD 0x26 |
223 | #define SE_GET_SENSOR_THRESHOLD 0x27 |
224 | #define SE_SET_SENSOR_EVENT_ENABLE 0x28 |
225 | #define SE_GET_SENSOR_EVENT_ENABLE 0x29 |
226 | #define SE_REARM_SENSOR_EVENTS 0x2A |
227 | #define SE_GET_SENSOR_EVENT_STATUS 0x2B |
228 | #define SE_GET_SENSOR_READING 0x2D |
229 | #define SE_SET_SENSOR_TYPE 0x2E |
230 | #define SE_GET_SENSOR_TYPE 0x2F |
231 | |
232 | struct sdrhdr { |
233 | uint16_t record_id; /* SDR Record ID */ |
234 | uint8_t sdr_version; /* SDR Version */ |
235 | uint8_t record_type; /* SDR Record Type */ |
236 | uint8_t record_length; /* SDR Record Length */ |
237 | } __packed; |
238 | |
239 | /* SDR: Record Type 1 */ |
240 | struct sdrtype1 { |
241 | struct sdrhdr sdrhdr; |
242 | |
243 | uint8_t owner_id; |
244 | uint8_t owner_lun; |
245 | uint8_t sensor_num; |
246 | |
247 | uint8_t entity_id; |
248 | uint8_t entity_instance; |
249 | uint8_t sensor_init; |
250 | uint8_t sensor_caps; |
251 | uint8_t sensor_type; |
252 | uint8_t event_code; |
253 | uint16_t trigger_mask; |
254 | uint16_t reading_mask; |
255 | uint16_t settable_mask; |
256 | uint8_t units1; |
257 | uint8_t units2; |
258 | uint8_t units3; |
259 | uint8_t linear; |
260 | uint8_t m; |
261 | uint8_t m_tolerance; |
262 | uint8_t b; |
263 | uint8_t b_accuracy; |
264 | uint8_t accuracyexp; |
265 | uint8_t rbexp; |
266 | uint8_t analogchars; |
267 | uint8_t nominalreading; |
268 | uint8_t normalmax; |
269 | uint8_t normalmin; |
270 | uint8_t sensormax; |
271 | uint8_t sensormin; |
272 | uint8_t uppernr; |
273 | uint8_t upperc; |
274 | uint8_t uppernc; |
275 | uint8_t lowernr; |
276 | uint8_t lowerc; |
277 | uint8_t lowernc; |
278 | uint8_t physt; |
279 | uint8_t nhyst; |
280 | uint8_t resvd[2]; |
281 | uint8_t oem; |
282 | uint8_t typelen; |
283 | uint8_t name[1]; |
284 | } __packed; |
285 | |
286 | /* SDR: Record Type 2 */ |
287 | struct sdrtype2 { |
288 | struct sdrhdr sdrhdr; |
289 | |
290 | uint8_t owner_id; |
291 | uint8_t owner_lun; |
292 | uint8_t sensor_num; |
293 | |
294 | uint8_t entity_id; |
295 | uint8_t entity_instance; |
296 | uint8_t sensor_init; |
297 | uint8_t sensor_caps; |
298 | uint8_t sensor_type; |
299 | uint8_t event_code; |
300 | uint16_t trigger_mask; |
301 | uint16_t reading_mask; |
302 | uint16_t set_mask; |
303 | uint8_t units1; |
304 | uint8_t units2; |
305 | uint8_t units3; |
306 | uint8_t share1; |
307 | uint8_t share2; |
308 | uint8_t physt; |
309 | uint8_t nhyst; |
310 | uint8_t resvd[3]; |
311 | uint8_t oem; |
312 | uint8_t typelen; |
313 | uint8_t name[1]; |
314 | } __packed; |
315 | |
316 | int ipmi_probe(struct ipmi_attach_args *); |
317 | |
318 | #endif /* _IPMIVAR_H_ */ |
319 | |