1 /*
2  * bmc.h
3  *
4  * MontaVista IPMI LAN server include file
5  *
6  * Author: MontaVista Software, Inc.
7  *         Corey Minyard <minyard@mvista.com>
8  *         source@mvista.com
9  *
10  * Copyright 2012 MontaVista Software Inc.
11  *
12  * This software is available to you under a choice of one of two
13  * licenses.  You may choose to be licensed under the terms of the GNU
14  * Lesser General Public License (GPL) Version 2 or the modified BSD
15  * license below.  The following disclamer applies to both licenses:
16  *
17  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
26  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * GNU Lesser General Public Licence
29  *
30  *  This program is free software; you can redistribute it and/or
31  *  modify it under the terms of the GNU Lesser General Public License
32  *  as published by the Free Software Foundation; either version 2 of
33  *  the License, or (at your option) any later version.
34  *
35  *  You should have received a copy of the GNU Lesser General Public
36  *  License along with this program; if not, write to the Free
37  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38  *
39  * Modified BSD Licence
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  *
45  *   1. Redistributions of source code must retain the above copyright
46  *      notice, this list of conditions and the following disclaimer.
47  *   2. Redistributions in binary form must reproduce the above
48  *      copyright notice, this list of conditions and the following
49  *      disclaimer in the documentation and/or other materials provided
50  *      with the distribution.
51  *   3. The name of the author may not be used to endorse or promote
52  *      products derived from this software without specific prior
53  *      written permission.
54  */
55 
56 #ifndef __BMC_H_
57 #define __BMC_H_
58 
59 #include <stdint.h>
60 #include <semaphore.h>
61 #include <OpenIPMI/mcserv.h>
62 #include "emu.h"
63 
64 #define WATCHDOG_SENSOR_NUM 0
65 
66 #define OPENIPMI_IANA		40820 /* OpenIPMI's own number */
67 
68 typedef struct sel_entry_s
69 {
70     uint16_t           record_id;
71     unsigned char      data[16];
72     struct sel_entry_s *next;
73 } sel_entry_t;
74 
75 typedef struct sel_s
76 {
77     sel_entry_t   *entries;
78     int           count;
79     int           max_count;
80     uint32_t      last_add_time;
81     uint32_t      last_erase_time;
82     unsigned char flags;
83     uint16_t      reservation;
84     uint16_t      next_entry;
85     long          time_offset;
86 } sel_t;
87 
88 #define MAX_SDR_LENGTH 261
89 #define MAX_NUM_SDRS   1024
90 typedef struct sdr_s
91 {
92     uint16_t      record_id;
93     unsigned int  length;
94     unsigned char *data;
95     struct sdr_s  *next;
96 } sdr_t;
97 
98 typedef struct sdrs_s
99 {
100     uint16_t      reservation;
101     uint16_t      sdr_count;
102     uint16_t      sensor_count;
103     uint32_t      last_add_time;
104     uint32_t      last_erase_time;
105     long          time_offset;
106     unsigned char flags;
107     uint16_t      next_entry;
108     unsigned int  sdrs_length;
109 
110     /* A linked list of SDR entries. */
111     sdr_t         *sdrs;
112 } sdrs_t;
113 
114 typedef struct sensor_s sensor_t;
115 struct sensor_s
116 {
117     lmc_data_t *mc;
118 
119     unsigned char num;
120     unsigned int  lun              : 2;
121     unsigned int  scanning_enabled : 1;
122     unsigned int  events_enabled   : 1;
123     unsigned int  enabled          : 1;
124 
125     unsigned char sensor_type;
126     unsigned char event_reading_code;
127 
128     unsigned char value;
129 
130     unsigned char hysteresis_support;
131     unsigned char positive_hysteresis;
132     unsigned char negative_hysteresis;
133 
134     unsigned char threshold_support;
135     uint16_t threshold_supported; /* Bitmask */
136     unsigned char thresholds[6];
137 
138     int event_only;
139 
140     unsigned char event_support;
141 
142     /* 0 for assertion, 1 for deassertion. */
143     uint16_t event_supported[2];
144     uint16_t event_enabled[2];
145     int (*rearm_handler)(void *cb_data, uint16_t assert, uint16_t deassert);
146     void *rearm_cb_data;
147 
148 
149     /* Current bit values */
150     uint16_t event_status;
151 
152     /* Called when the sensor changes values. */
153     void (*sensor_update_handler)(lmc_data_t *mc, sensor_t *sensor);
154 
155     ipmi_timer_t *poll_timer;
156     struct timeval poll_timer_time;
157     int (*poll)(void *cb_data, unsigned int *val, const char **errstr);
158     void *cb_data;
159 };
160 
161 typedef struct fru_data_s fru_data_t;
162 
163 typedef struct fru_session_s
164 {
165     unsigned char *data_to_free;
166     unsigned char *data;
167     unsigned int length;
168     unsigned int sid;
169     fru_data_t *fru;
170     struct fru_session_s *next;
171 } fru_session_t;
172 
173 struct fru_data_s
174 {
175     unsigned int   devid;
176     fru_io_cb      fru_io_cb;
177     unsigned int   length;
178     unsigned char  *data;
179     fru_session_t  *sessions;
180     get_frudata_f  get;
181     free_frudata_f free;
182     sem_t          sem;
183     fru_data_t     *next;
184 };
185 
186 typedef struct led_data_s
187 {
188     unsigned char off_dur;
189     unsigned char def_off_dur;
190     unsigned char on_dur;
191     unsigned char def_on_dur;
192     unsigned char color;
193     unsigned char color_sup;
194     unsigned char loc_cnt;
195     unsigned char loc_cnt_sup;
196     unsigned char def_loc_cnt_color;
197     unsigned char def_override_color;
198 } led_data_t;
199 
200 struct lmc_data_s
201 {
202     emu_data_t *emu;
203 
204     char enabled;
205     char configured;
206 
207     unsigned char ipmb;
208 
209     unsigned char guid_set;
210     unsigned char guid[16];
211 
212     channel_t *channels[IPMI_MAX_CHANNELS];
213 
214     channel_t sys_channel;
215     channel_t ipmb_channel;
216 
217     int users_changed;
218     user_t users[MAX_USERS + 1];
219 
220     pef_data_t pef;
221     pef_data_t pef_rollback;
222 
223     ipmi_tick_handler_t tick_handler;
224     ipmi_child_quit_t child_quit_handler;
225     startcmd_t startcmd;
226 
227     unsigned char evq[16];
228     char  ev_in_q;
229 
230     /* Get Device Id contents. */
231     unsigned char device_id;       /* byte 2 */
232     unsigned char has_device_sdrs; /* byte 3, bit 7 */
233     unsigned char device_revision; /* byte 3, bits 0-6 */
234     unsigned char major_fw_rev;    /* byte 4, bits 0-6 */
235     unsigned char minor_fw_rev;    /* byte 5 */
236     unsigned char device_support;  /* byte 7 */
237     unsigned char mfg_id[3];	   /* bytes 8-10 */
238     unsigned char product_id[2];   /* bytes 11-12 */
239     unsigned char aux_fw_rev[4];   /* bytes 13-16 */
240 
241 #define IPMI_MC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK	(1 << 3)
242 #define IPMI_MC_MSG_FLAG_EVT_BUF_FULL		(1 << 1)
243 #define IPMI_MC_MSG_FLAG_RCV_MSG_QUEUE		(1 << 0)
244 #define IPMI_MC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(mc) \
245     (IPMI_MC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK & (mc)->msg_flags)
246 #define IPMI_MC_MSG_FLAG_EVT_BUF_FULL_SET(mc) \
247     (IPMI_MC_MSG_FLAG_EVT_BUF_FULL & (mc)->msg_flags)
248 #define IPMI_MC_MSG_FLAG_RCV_MSG_QUEUE_SET(mc) \
249     (IPMI_MC_MSG_FLAG_RCV_MSG_QUEUE & (mc)->msg_flags)
250     unsigned char msg_flags;
251 
252 #define IPMI_MC_RCV_MSG_QUEUE_INT_BIT	0
253 #define IPMI_MC_EVBUF_FULL_INT_BIT	1
254 #define IPMI_MC_EVENT_MSG_BUF_BIT	2
255 #define IPMI_MC_EVENT_LOG_BIT		3
256 #define IPMI_MC_MSG_INTS_ON(mc) ((mc)->global_enables & \
257 				 (1 << IPMI_MC_RCV_MSG_QUEUE_INT_BIT))
258 #define IPMI_MC_EVBUF_FULL_INT_ENABLED(mc) ((mc)->global_enables & \
259 					(1 << IPMI_MC_EVBUF_FULL_INT_BIT))
260 #define IPMI_MC_EVENT_LOG_ENABLED(mc) ((mc)->global_enables & \
261 				       (1 << IPMI_MC_EVENT_LOG_BIT))
262 #define IPMI_MC_EVENT_MSG_BUF_ENABLED(mc) ((mc)->global_enables & \
263 					   (1 << IPMI_MC_EVENT_MSG_BUF_BIT))
264     unsigned char global_enables;
265 
266     sys_data_t *sysinfo;
267 
268     sel_t sel;
269 
270     sdrs_t main_sdrs;
271     sdr_t  *part_add_sdr;
272     unsigned int part_add_next;
273     int    in_update_mode;
274 
275     unsigned char event_receiver;
276     unsigned char event_receiver_lun;
277 
278     sdrs_t device_sdrs[4];
279     unsigned int dynamic_sensor_population : 1;
280     unsigned int sensors_enabled : 1;
281     unsigned char lun_has_sensors[4];
282     unsigned char num_sensors_per_lun[4];
283     sensor_t *(sensors[4][255]);
284     uint32_t sensor_population_change_time;
285 
286     fru_data_t *frulist;
287 
288     ipmi_sol_t sol;
289 
290     int (*chassis_control_set_func)(lmc_data_t *mc, int op, unsigned char *val,
291 				    void *cb_data);
292     int (*chassis_control_get_func)(lmc_data_t *mc, int op, unsigned char *val,
293 				    void *cb_data);
294     ipmi_timer_t *power_timer;
295     void *chassis_control_cb_data;
296     const char *chassis_control_prog;
297 
298     unsigned char power_value;
299 #define MAX_LEDS 8
300 #define MIN_ATCA_LEDS 2
301     unsigned int  num_leds;
302     led_data_t leds[MAX_LEDS];
303 
304     /* Will be NULL if not valid. */
305     sensor_t      *hs_sensor;
306 
307 #define IPMI_MC_WATCHDOG_USE_MASK 0xc7
308 #define IPMI_MC_WATCHDOG_ACTION_MASK 0x77
309 #define IPMI_MC_WATCHDOG_GET_USE(s) ((s)->watchdog_use & 0x7)
310 #define IPMI_MC_WATCHDOG_GET_DONT_LOG(s) (((s)->watchdog_use >> 7) & 0x1)
311 #define IPMI_MC_WATCHDOG_GET_DONT_STOP(s) (((s)->watchdog_use >> 6) & 0x1)
312 #define IPMI_MC_WATCHDOG_GET_PRE_ACTION(s) (((s)->watchdog_action >> 4) & 0x7)
313 #define IPMI_MC_WATCHDOG_PRE_NONE		0
314 #define IPMI_MC_WATCHDOG_PRE_SMI		1
315 #define IPMI_MC_WATCHDOG_PRE_NMI		2
316 #define IPMI_MC_WATCHDOG_PRE_MSG_INT		3
317 #define IPMI_MC_WATCHDOG_GET_ACTION(s) ((s)->watchdog_action & 0x7)
318 #define IPMI_MC_WATCHDOG_ACTION_NONE		0
319 #define IPMI_MC_WATCHDOG_ACTION_RESET		1
320 #define IPMI_MC_WATCHDOG_ACTION_POWER_DOWN	2
321 #define IPMI_MC_WATCHDOG_ACTION_POWER_CYCLE	3
322     unsigned char watchdog_use;
323     unsigned char watchdog_action;
324     unsigned char watchdog_pretimeout;
325     unsigned char watchdog_expired;
326     int watchdog_running;
327     int watchdog_preaction_ran;
328     int watchdog_initialized;
329     struct timeval watchdog_time; /* Set time */
330     struct timeval watchdog_expiry; /* Timeout time */
331     ipmi_timer_t *watchdog_timer;
332 };
333 
334 typedef struct atca_site_s
335 {
336     unsigned char valid;
337     unsigned char hw_address;
338     unsigned char site_type;
339     unsigned char site_number;
340 } atca_site_t;
341 
342 #define MAX_EMU_ADDR		16
343 #define MAX_EMU_ADDR_DATA	64
344 typedef struct emu_addr_s
345 {
346     unsigned char valid;
347     unsigned char addr_type;
348     unsigned char addr_data[MAX_EMU_ADDR_DATA];
349     unsigned int  addr_len;
350 } emu_addr_t;
351 
352 struct emu_data_s
353 {
354     sys_data_t *sysinfo;
355 
356     int users_changed;
357 
358     int          atca_mode;
359     atca_site_t  atca_sites[128]; /* Indexed by HW address. */
360     uint32_t     atca_fru_inv_curr_timestamp;
361     uint16_t     atca_fru_inv_curr_lock_id;
362     int          atca_fru_inv_locked;
363     int          atca_fru_inv_lock_timeout;
364 
365     unsigned char *temp_fru_inv_data;
366     unsigned int  temp_fru_inv_data_len;
367 
368     void *user_data;
369 
370     ipmi_emu_sleep_cb sleeper;
371 
372     struct timeval last_addr_change_time;
373     emu_addr_t addr[MAX_EMU_ADDR];
374 };
375 
376 /* Device ID support bits */
377 #define IPMI_DEVID_CHASSIS_DEVICE	(1 << 7)
378 #define IPMI_DEVID_BRIDGE		(1 << 6)
379 #define IPMI_DEVID_IPMB_EVENT_GEN	(1 << 5)
380 #define IPMI_DEVID_IPMB_EVENT_RCV	(1 << 4)
381 #define IPMI_DEVID_FRU_INVENTORY_DEV	(1 << 3)
382 #define IPMI_DEVID_SEL_DEVICE		(1 << 2)
383 #define IPMI_DEVID_SDR_REPOSITORY_DEV	(1 << 1)
384 #define IPMI_DEVID_SENSOR_DEV		(1 << 0)
385 
386 fru_data_t *find_fru(lmc_data_t *mc, unsigned int devid);
387 
388 int start_poweron_timer(lmc_data_t *mc);
389 
390 sdr_t *find_sdr_by_recid(sdrs_t     *sdrs,
391 			 uint16_t   record_id,
392 			 sdr_t      **prev);
393 
394 sdr_t *new_sdr_entry(sdrs_t *sdrs, unsigned char length);
395 void add_sdr_entry(lmc_data_t *mc, sdrs_t *sdrs, sdr_t *entry);
396 void read_mc_sdrs(lmc_data_t *mc, sdrs_t *sdrs, const char *sdrtype);
397 
398 void iterate_sdrs(lmc_data_t *mc,
399 		  sdrs_t     *sdrs,
400 		  int (*func)(lmc_data_t *mc, unsigned char *sdr,
401 			      unsigned int len, void *cb_data),
402 		  void *cb_data);
403 
404 void mc_new_event(lmc_data_t *mc,
405 		  unsigned char record_type,
406 		  unsigned char event[13]);
407 
408 #define IPMI_SDR_DELETE_SDR_SUPPORTED			(1 << 3)
409 #define IPMI_SDR_PARTIAL_ADD_SDR_SUPPORTED		(1 << 2)
410 #define IPMI_SDR_RESERVE_SDR_SUPPORTED			(1 << 1)
411 #define IPMI_SDR_GET_SDR_ALLOC_INFO_SDR_SUPPORTED	(1 << 0)
412 
413 void picmg_led_set(lmc_data_t *mc, sensor_t *sensor);
414 void set_sensor_bit(lmc_data_t *mc, sensor_t *sensor, unsigned char bit,
415 		    unsigned char value,
416 		    unsigned char evd1, unsigned char evd2, unsigned char evd3,
417 		    int gen_event);
418 
419 void watchdog_timeout(void *cb_data);
420 
421 extern cmd_handler_f storage_netfn_handlers[256];
422 extern cmd_handler_f app_netfn_handlers[256];
423 extern cmd_handler_f chassis_netfn_handlers[256];
424 extern cmd_handler_f transport_netfn_handlers[256];
425 extern cmd_handler_f sensor_event_netfn_handlers[256];
426 extern cmd_handler_f oem0_netfn_handlers[256];
427 
428 #define set_bit(m, b, v) (m) = (v) ? ((m) | (1 << (b))) : ((m) & ~(1 << (b)))
429 #define bit_set(m, b) (!!((m) & (1 << (b))))
430 
431 #endif /* __BMC_H_ */
432