xref: /openbmc/ipmitool/lib/ipmi_pef.c (revision 2d79e69f)
1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen  * Copyright (c) 2004 Dell Computers.  All Rights Reserved.
3c18ec02fSPetter Reinholdtsen  *
4c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
5c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
6c18ec02fSPetter Reinholdtsen  * are met:
7c18ec02fSPetter Reinholdtsen  *
8c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
9c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
10c18ec02fSPetter Reinholdtsen  *
11c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
12c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
13c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
14c18ec02fSPetter Reinholdtsen  *
15c18ec02fSPetter Reinholdtsen  * Neither the name of Dell Computers, or the names of
16c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
17c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
18c18ec02fSPetter Reinholdtsen  *
19c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
20c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23c18ec02fSPetter Reinholdtsen  * DELL COMPUTERS ("DELL") AND ITS LICENSORS SHALL NOT BE LIABLE
24c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26c18ec02fSPetter Reinholdtsen  * DELL OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30c18ec02fSPetter Reinholdtsen  * EVEN IF DELL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31c18ec02fSPetter Reinholdtsen  */
32c18ec02fSPetter Reinholdtsen 
33c18ec02fSPetter Reinholdtsen #include <string.h>
34c18ec02fSPetter Reinholdtsen #include <math.h>
35c18ec02fSPetter Reinholdtsen #include <time.h>
36c18ec02fSPetter Reinholdtsen 
37c18ec02fSPetter Reinholdtsen #include <ipmitool/bswap.h>
38c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
39c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
40c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
41c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
42c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_pef.h>
43c18ec02fSPetter Reinholdtsen 
44c18ec02fSPetter Reinholdtsen extern int verbose;
45c18ec02fSPetter Reinholdtsen /*
46c18ec02fSPetter Reinholdtsen // common kywd/value printf() templates
47c18ec02fSPetter Reinholdtsen */
48c18ec02fSPetter Reinholdtsen static const char * pef_fld_fmts[][2] = {
49c18ec02fSPetter Reinholdtsen 	{"%-*s : %u\n",          " | %u"},			/* F_DEC: unsigned value */
50c18ec02fSPetter Reinholdtsen 	{"%-*s : %d\n",          " | %d"},			/* F_INT: signed value   */
51c18ec02fSPetter Reinholdtsen 	{"%-*s : %s\n",          " | %s"},			/* F_STR: string value   */
52c18ec02fSPetter Reinholdtsen 	{"%-*s : 0x%x\n",        " | 0x%x"},		/* F_HEX: "N hex digits" */
53c18ec02fSPetter Reinholdtsen 	{"%-*s : 0x%04x\n",      " | 0x%04x"},		/* F_2XD: "2 hex digits" */
54c18ec02fSPetter Reinholdtsen 	{"%-*s : 0x%02x\n",      " | 0x%02x"},		/* F_1XD: "1 hex digit"  */
55c18ec02fSPetter Reinholdtsen 	{"%-*s : %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
56c18ec02fSPetter Reinholdtsen 	     " | %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"},
57c18ec02fSPetter Reinholdtsen };
58c18ec02fSPetter Reinholdtsen typedef enum {
59c18ec02fSPetter Reinholdtsen 	F_DEC,
60c18ec02fSPetter Reinholdtsen 	F_INT,
61c18ec02fSPetter Reinholdtsen 	F_STR,
62c18ec02fSPetter Reinholdtsen 	F_HEX,
63c18ec02fSPetter Reinholdtsen 	F_2XD,
64c18ec02fSPetter Reinholdtsen 	F_1XD,
65c18ec02fSPetter Reinholdtsen 	F_UID,
66c18ec02fSPetter Reinholdtsen } fmt_e;
67c18ec02fSPetter Reinholdtsen #define KYWD_LENGTH 24
68c18ec02fSPetter Reinholdtsen static int first_field = 1;
69c18ec02fSPetter Reinholdtsen 
70c18ec02fSPetter Reinholdtsen static const char * pef_flag_fmts[][3] = {
71c18ec02fSPetter Reinholdtsen 	{"",          "false",  "true"},
72c18ec02fSPetter Reinholdtsen 	{"supported", "un",         ""},
73c18ec02fSPetter Reinholdtsen 	{"active",    "in",         ""},
74c18ec02fSPetter Reinholdtsen 	{"abled",     "dis",      "en"},
75c18ec02fSPetter Reinholdtsen };
76c18ec02fSPetter Reinholdtsen static const char * listitem[] =	{" | %s", ",%s", "%s"};
77c18ec02fSPetter Reinholdtsen 
78c18ec02fSPetter Reinholdtsen const char *
ipmi_pef_bit_desc(struct bit_desc_map * map,uint32_t value)79c18ec02fSPetter Reinholdtsen ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t value)
80c18ec02fSPetter Reinholdtsen {	/*
81c18ec02fSPetter Reinholdtsen 	// return description/text label(s) for the given value.
82c18ec02fSPetter Reinholdtsen 	//  NB: uses a static buffer
83c18ec02fSPetter Reinholdtsen 	*/
84c18ec02fSPetter Reinholdtsen 	static char buf[128];
85c18ec02fSPetter Reinholdtsen 	char * p;
86c18ec02fSPetter Reinholdtsen 	struct desc_map * pmap;
87c18ec02fSPetter Reinholdtsen 	uint32_t match, index;
88c18ec02fSPetter Reinholdtsen 
89c18ec02fSPetter Reinholdtsen 	*(p = buf) = '\0';
90c18ec02fSPetter Reinholdtsen 	index = 2;
91c18ec02fSPetter Reinholdtsen 	for (pmap=map->desc_maps; pmap && pmap->desc; pmap++) {
92c18ec02fSPetter Reinholdtsen 		if (map->desc_map_type == BIT_DESC_MAP_LIST)
93c18ec02fSPetter Reinholdtsen 			match = (value == pmap->mask);
94c18ec02fSPetter Reinholdtsen 		else
95c18ec02fSPetter Reinholdtsen 			match = ((value & pmap->mask) == pmap->mask);
96c18ec02fSPetter Reinholdtsen 
97c18ec02fSPetter Reinholdtsen 		if (match) {
98c18ec02fSPetter Reinholdtsen 			sprintf(p, listitem[index], pmap->desc);
99c18ec02fSPetter Reinholdtsen 			p = strchr(p, '\0');
100c18ec02fSPetter Reinholdtsen 			if (map->desc_map_type != BIT_DESC_MAP_ALL)
101c18ec02fSPetter Reinholdtsen 				break;
102c18ec02fSPetter Reinholdtsen 			index = 1;
103c18ec02fSPetter Reinholdtsen 		}
104c18ec02fSPetter Reinholdtsen 	}
105c18ec02fSPetter Reinholdtsen 	if (p == buf)
106c18ec02fSPetter Reinholdtsen 		return("None");
107c18ec02fSPetter Reinholdtsen 
108c18ec02fSPetter Reinholdtsen 	return((const char *)buf);
109c18ec02fSPetter Reinholdtsen }
110c18ec02fSPetter Reinholdtsen 
111c18ec02fSPetter Reinholdtsen void
ipmi_pef_print_flags(struct bit_desc_map * map,flg_e type,uint32_t val)112c18ec02fSPetter Reinholdtsen ipmi_pef_print_flags(struct bit_desc_map * map, flg_e type, uint32_t val)
113c18ec02fSPetter Reinholdtsen {	/*
114c18ec02fSPetter Reinholdtsen 	// print features/flags, using val (a bitmask), according to map.
115c18ec02fSPetter Reinholdtsen 	// observe the verbose flag, and print any labels, etc. based on type
116c18ec02fSPetter Reinholdtsen 	*/
117c18ec02fSPetter Reinholdtsen 	struct desc_map * pmap;
118c18ec02fSPetter Reinholdtsen 	uint32_t maskval, index;
119c18ec02fSPetter Reinholdtsen 
120c18ec02fSPetter Reinholdtsen 	index = 0;
121c18ec02fSPetter Reinholdtsen 	for (pmap=map->desc_maps; pmap && pmap->desc; pmap++) {
122c18ec02fSPetter Reinholdtsen 		maskval = (val & pmap->mask);
123c18ec02fSPetter Reinholdtsen 		if (verbose)
124c18ec02fSPetter Reinholdtsen 			printf("%-*s : %s%s\n", KYWD_LENGTH,
125c18ec02fSPetter Reinholdtsen 				ipmi_pef_bit_desc(map, pmap->mask),
126c18ec02fSPetter Reinholdtsen 				pef_flag_fmts[type][1 + (maskval != 0)],
127c18ec02fSPetter Reinholdtsen 				pef_flag_fmts[type][0]);
128c18ec02fSPetter Reinholdtsen 		else if (maskval != 0) {
129c18ec02fSPetter Reinholdtsen 			printf(listitem[index], ipmi_pef_bit_desc(map, maskval));
130c18ec02fSPetter Reinholdtsen 			index = 1;
131c18ec02fSPetter Reinholdtsen 		}
132c18ec02fSPetter Reinholdtsen 	}
133c18ec02fSPetter Reinholdtsen }
134c18ec02fSPetter Reinholdtsen 
135c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_field(const char * fmt[2],const char * label,unsigned long val)136c18ec02fSPetter Reinholdtsen ipmi_pef_print_field(const char * fmt[2], const char * label, unsigned long val)
137c18ec02fSPetter Reinholdtsen {	/*
138c18ec02fSPetter Reinholdtsen 	// print a 'field' (observes 'verbose' flag)
139c18ec02fSPetter Reinholdtsen 	*/
140c18ec02fSPetter Reinholdtsen 	if (verbose)
141c18ec02fSPetter Reinholdtsen 		printf(fmt[0], KYWD_LENGTH, label, val);
142c18ec02fSPetter Reinholdtsen 	else if (first_field)
143c18ec02fSPetter Reinholdtsen 		printf(&fmt[1][2], val);	/* skip field separator */
144c18ec02fSPetter Reinholdtsen 	else
145c18ec02fSPetter Reinholdtsen 		printf(fmt[1], val);
146c18ec02fSPetter Reinholdtsen 
147c18ec02fSPetter Reinholdtsen 	first_field = 0;
148c18ec02fSPetter Reinholdtsen }
149c18ec02fSPetter Reinholdtsen 
150c18ec02fSPetter Reinholdtsen void
ipmi_pef_print_dec(const char * text,uint32_t val)151c18ec02fSPetter Reinholdtsen ipmi_pef_print_dec(const char * text, uint32_t val)
152c18ec02fSPetter Reinholdtsen {	/* unsigned */
153c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_field(pef_fld_fmts[F_DEC], text, val);
154c18ec02fSPetter Reinholdtsen }
155c18ec02fSPetter Reinholdtsen 
156c18ec02fSPetter Reinholdtsen void
ipmi_pef_print_int(const char * text,uint32_t val)157c18ec02fSPetter Reinholdtsen ipmi_pef_print_int(const char * text, uint32_t val)
158c18ec02fSPetter Reinholdtsen {	/* signed */
159c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_field(pef_fld_fmts[F_INT], text, val);
160c18ec02fSPetter Reinholdtsen }
161c18ec02fSPetter Reinholdtsen 
162c18ec02fSPetter Reinholdtsen void
ipmi_pef_print_hex(const char * text,uint32_t val)163c18ec02fSPetter Reinholdtsen ipmi_pef_print_hex(const char * text, uint32_t val)
164c18ec02fSPetter Reinholdtsen {	/* hex */
165c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_field(pef_fld_fmts[F_HEX], text, val);
166c18ec02fSPetter Reinholdtsen }
167c18ec02fSPetter Reinholdtsen 
168c18ec02fSPetter Reinholdtsen void
ipmi_pef_print_str(const char * text,const char * val)169c18ec02fSPetter Reinholdtsen ipmi_pef_print_str(const char * text, const char * val)
170c18ec02fSPetter Reinholdtsen {	/* string */
171c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_field(pef_fld_fmts[F_STR], text, (unsigned long)val);
172c18ec02fSPetter Reinholdtsen }
173c18ec02fSPetter Reinholdtsen 
174c18ec02fSPetter Reinholdtsen void
ipmi_pef_print_2xd(const char * text,uint8_t u1,uint8_t u2)175c18ec02fSPetter Reinholdtsen ipmi_pef_print_2xd(const char * text, uint8_t u1, uint8_t u2)
176c18ec02fSPetter Reinholdtsen {	/* 2 hex digits */
177c18ec02fSPetter Reinholdtsen 	uint32_t val = ((u1 << 8) + u2) & 0xffff;
178c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_field(pef_fld_fmts[F_2XD], text, val);
179c18ec02fSPetter Reinholdtsen }
180c18ec02fSPetter Reinholdtsen 
181c18ec02fSPetter Reinholdtsen void
ipmi_pef_print_1xd(const char * text,uint32_t val)182c18ec02fSPetter Reinholdtsen ipmi_pef_print_1xd(const char * text, uint32_t val)
183c18ec02fSPetter Reinholdtsen {	/* 1 hex digit */
184c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_field(pef_fld_fmts[F_1XD], text, val);
185c18ec02fSPetter Reinholdtsen }
186c18ec02fSPetter Reinholdtsen 
187c18ec02fSPetter Reinholdtsen static struct ipmi_rs *
ipmi_pef_msg_exchange(struct ipmi_intf * intf,struct ipmi_rq * req,char * txt)188c18ec02fSPetter Reinholdtsen ipmi_pef_msg_exchange(struct ipmi_intf * intf, struct ipmi_rq * req, char * txt)
189c18ec02fSPetter Reinholdtsen {	/*
190c18ec02fSPetter Reinholdtsen 	// common IPMItool rqst/resp handling
191c18ec02fSPetter Reinholdtsen 	*/
192c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = intf->sendrecv(intf, req);
193c18ec02fSPetter Reinholdtsen 	if (!rsp) {
194c18ec02fSPetter Reinholdtsen 		return(NULL);
195c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode == 0x80)	{
196c18ec02fSPetter Reinholdtsen 		return(NULL);   /* Do not output error, just unsupported parameters */
197c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode) {
198c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error %x in '%s' command", rsp->ccode, txt);
199c18ec02fSPetter Reinholdtsen 		return(NULL);
200c18ec02fSPetter Reinholdtsen 	}
201c18ec02fSPetter Reinholdtsen 	if (verbose > 2) {
202c18ec02fSPetter Reinholdtsen 		printbuf(rsp->data, rsp->data_len, txt);
203c18ec02fSPetter Reinholdtsen 	}
204c18ec02fSPetter Reinholdtsen 	return(rsp);
205c18ec02fSPetter Reinholdtsen }
206c18ec02fSPetter Reinholdtsen 
207c18ec02fSPetter Reinholdtsen static uint8_t
ipmi_pef_get_policy_table(struct ipmi_intf * intf,struct pef_cfgparm_policy_table_entry ** table)208c18ec02fSPetter Reinholdtsen ipmi_pef_get_policy_table(struct ipmi_intf * intf,
209c18ec02fSPetter Reinholdtsen 									struct pef_cfgparm_policy_table_entry ** table)
210c18ec02fSPetter Reinholdtsen {	/*
211c18ec02fSPetter Reinholdtsen 	// get the PEF policy table: allocate space, fillin, and return its size
212c18ec02fSPetter Reinholdtsen 	//  NB: the caller must free the returned area (when returned size > 0)
213c18ec02fSPetter Reinholdtsen 	*/
214c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
215c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
216c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_selector psel;
217c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_policy_table_entry * ptbl, * ptmp;
218c18ec02fSPetter Reinholdtsen 	uint32_t i;
219c18ec02fSPetter Reinholdtsen 	uint8_t tbl_size;
220c18ec02fSPetter Reinholdtsen 
221c18ec02fSPetter Reinholdtsen 	memset(&psel, 0, sizeof(psel));
222c18ec02fSPetter Reinholdtsen 	psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_SIZE;
223c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
224c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
225c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
226c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *)&psel;
227c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(psel);
228c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Alert policy table size");
229c18ec02fSPetter Reinholdtsen 	if (!rsp)
230c18ec02fSPetter Reinholdtsen 		return(0);
231c18ec02fSPetter Reinholdtsen 	tbl_size = (rsp->data[1] & PEF_POLICY_TABLE_SIZE_MASK);
232c18ec02fSPetter Reinholdtsen 	i = (tbl_size * sizeof(struct pef_cfgparm_policy_table_entry));
233c18ec02fSPetter Reinholdtsen 	if (!i
234c18ec02fSPetter Reinholdtsen 	|| (ptbl = (struct pef_cfgparm_policy_table_entry *)malloc(i)) == NULL)
235c18ec02fSPetter Reinholdtsen 		return(0);
236c18ec02fSPetter Reinholdtsen 
237c18ec02fSPetter Reinholdtsen 	memset(&psel, 0, sizeof(psel));
238c18ec02fSPetter Reinholdtsen 	psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY;
239c18ec02fSPetter Reinholdtsen 	for (ptmp=ptbl, i=1; i<=tbl_size; i++) {
240c18ec02fSPetter Reinholdtsen 		psel.set = (i & PEF_POLICY_TABLE_ID_MASK);
241c18ec02fSPetter Reinholdtsen 		rsp = ipmi_pef_msg_exchange(intf, &req, "Alert policy table entry");
242c18ec02fSPetter Reinholdtsen 		if (!rsp
243c18ec02fSPetter Reinholdtsen 		|| i != (rsp->data[1] & PEF_POLICY_TABLE_ID_MASK)) {
244c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, " **Error retrieving %s",
245c18ec02fSPetter Reinholdtsen 				"Alert policy table entry");
246c18ec02fSPetter Reinholdtsen 			free(ptbl);
247c18ec02fSPetter Reinholdtsen 			ptbl = NULL;
248c18ec02fSPetter Reinholdtsen 			tbl_size = 0;
249c18ec02fSPetter Reinholdtsen 			break;
250c18ec02fSPetter Reinholdtsen 		}
251c18ec02fSPetter Reinholdtsen 		memcpy(ptmp, &rsp->data[1], sizeof(*ptmp));
252c18ec02fSPetter Reinholdtsen 		ptmp++;
253c18ec02fSPetter Reinholdtsen 	}
254c18ec02fSPetter Reinholdtsen 
255c18ec02fSPetter Reinholdtsen 	*table = ptbl;
256c18ec02fSPetter Reinholdtsen 	return(tbl_size);
257c18ec02fSPetter Reinholdtsen }
258c18ec02fSPetter Reinholdtsen 
259c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_lan_dest(struct ipmi_intf * intf,uint8_t ch,uint8_t dest)260c18ec02fSPetter Reinholdtsen ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
261c18ec02fSPetter Reinholdtsen {	/*
262c18ec02fSPetter Reinholdtsen 	// print LAN alert destination info
263c18ec02fSPetter Reinholdtsen 	*/
264c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
265c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
266c18ec02fSPetter Reinholdtsen 	struct pef_lan_cfgparm_selector lsel;
267c18ec02fSPetter Reinholdtsen 	struct pef_lan_cfgparm_dest_type * ptype;
268c18ec02fSPetter Reinholdtsen 	struct pef_lan_cfgparm_dest_info * pinfo;
269c18ec02fSPetter Reinholdtsen 	char buf[32];
270c18ec02fSPetter Reinholdtsen 	uint8_t tbl_size, dsttype, timeout, retries;
271c18ec02fSPetter Reinholdtsen 
272c18ec02fSPetter Reinholdtsen 	memset(&lsel, 0, sizeof(lsel));
273c18ec02fSPetter Reinholdtsen 	lsel.id = PEF_LAN_CFGPARM_ID_DEST_COUNT;
274c18ec02fSPetter Reinholdtsen 	lsel.ch = ch;
275c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
276c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_TRANSPORT;
277c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_LAN_GET_CONFIG;
278c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *)&lsel;
279c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(lsel);
280c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination count");
281c18ec02fSPetter Reinholdtsen 	if (!rsp) {
282c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
283c18ec02fSPetter Reinholdtsen 			"Alert destination count");
284c18ec02fSPetter Reinholdtsen 		return;
285c18ec02fSPetter Reinholdtsen 	}
286c18ec02fSPetter Reinholdtsen 	tbl_size = (rsp->data[1] & PEF_LAN_DEST_TABLE_SIZE_MASK);
287c18ec02fSPetter Reinholdtsen 	//if (tbl_size == 0 || dest == 0)	/* LAN alerting not supported */
288c18ec02fSPetter Reinholdtsen 	//	return;
289c18ec02fSPetter Reinholdtsen 
290c18ec02fSPetter Reinholdtsen 	lsel.id = PEF_LAN_CFGPARM_ID_DESTTYPE;
291c18ec02fSPetter Reinholdtsen 	lsel.set = dest;
292c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination type");
293c18ec02fSPetter Reinholdtsen 	if (!rsp || rsp->data[1] != lsel.set) {
294c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
295c18ec02fSPetter Reinholdtsen 			"Alert destination type");
296c18ec02fSPetter Reinholdtsen 		return;
297c18ec02fSPetter Reinholdtsen 	}
298c18ec02fSPetter Reinholdtsen 	ptype = (struct pef_lan_cfgparm_dest_type *)&rsp->data[1];
299c18ec02fSPetter Reinholdtsen 	dsttype = (ptype->dest_type & PEF_LAN_DEST_TYPE_MASK);
300c18ec02fSPetter Reinholdtsen 	timeout = ptype->alert_timeout;
301c18ec02fSPetter Reinholdtsen 	retries = (ptype->retries & PEF_LAN_RETRIES_MASK);
302c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_str("Alert destination type",
303c18ec02fSPetter Reinholdtsen 				ipmi_pef_bit_desc(&pef_b2s_lan_desttype, dsttype));
304c18ec02fSPetter Reinholdtsen 	if (dsttype == PEF_LAN_DEST_TYPE_PET) {
305c18ec02fSPetter Reinholdtsen 		lsel.id = PEF_LAN_CFGPARM_ID_PET_COMMUNITY;
306c18ec02fSPetter Reinholdtsen 		lsel.set = 0;
307c18ec02fSPetter Reinholdtsen 		rsp = ipmi_pef_msg_exchange(intf, &req, "PET community");
308c18ec02fSPetter Reinholdtsen 		if (!rsp)
309c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, " **Error retrieving %s",
310c18ec02fSPetter Reinholdtsen 				"PET community");
311c18ec02fSPetter Reinholdtsen 		else {
312c18ec02fSPetter Reinholdtsen 			rsp->data[19] = '\0';
313c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_str("PET Community", (const char *)&rsp->data[1]);
314c18ec02fSPetter Reinholdtsen 		}
315c18ec02fSPetter Reinholdtsen 	}
316c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_dec("ACK timeout/retry (secs)", timeout);
317c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_dec("Retries", retries);
318c18ec02fSPetter Reinholdtsen 
319c18ec02fSPetter Reinholdtsen 	lsel.id = PEF_LAN_CFGPARM_ID_DESTADDR;
320c18ec02fSPetter Reinholdtsen 	lsel.set = dest;
321c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination info");
322c18ec02fSPetter Reinholdtsen 	if (!rsp || rsp->data[1] != lsel.set)
323c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
324c18ec02fSPetter Reinholdtsen 			"Alert destination info");
325c18ec02fSPetter Reinholdtsen 	else {
326c18ec02fSPetter Reinholdtsen 		pinfo = (struct pef_lan_cfgparm_dest_info *)&rsp->data[1];
327c18ec02fSPetter Reinholdtsen 		sprintf(buf, "%u.%u.%u.%u",
328c18ec02fSPetter Reinholdtsen 					pinfo->ip[0], pinfo->ip[1], pinfo->ip[2], pinfo->ip[3]);
329c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_str("IP address", buf);
330c18ec02fSPetter Reinholdtsen 
331c18ec02fSPetter Reinholdtsen 		sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
332c18ec02fSPetter Reinholdtsen 					pinfo->mac[0], pinfo->mac[1], pinfo->mac[2],
333c18ec02fSPetter Reinholdtsen 					pinfo->mac[3], pinfo->mac[4], pinfo->mac[5]);
334c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_str("MAC address", buf);
335c18ec02fSPetter Reinholdtsen 	}
336c18ec02fSPetter Reinholdtsen }
337c18ec02fSPetter Reinholdtsen 
338c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_serial_dest_dial(struct ipmi_intf * intf,char * label,struct pef_serial_cfgparm_selector * ssel)339c18ec02fSPetter Reinholdtsen ipmi_pef_print_serial_dest_dial(struct ipmi_intf * intf, char * label,
340c18ec02fSPetter Reinholdtsen 											struct pef_serial_cfgparm_selector * ssel)
341c18ec02fSPetter Reinholdtsen {	/*
342c18ec02fSPetter Reinholdtsen 	// print a dial string
343c18ec02fSPetter Reinholdtsen 	*/
344c18ec02fSPetter Reinholdtsen #define BLOCK_SIZE 16
345c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
346c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
347c18ec02fSPetter Reinholdtsen 	struct pef_serial_cfgparm_selector tmp;
348c18ec02fSPetter Reinholdtsen 	char * p, strval[(6 * BLOCK_SIZE) + 1];
349c18ec02fSPetter Reinholdtsen 
350c18ec02fSPetter Reinholdtsen 	memset(&tmp, 0, sizeof(tmp));
351c18ec02fSPetter Reinholdtsen 	tmp.id = PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING_COUNT;
352c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
353c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_TRANSPORT;
354c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG;
355c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *)&tmp;
356c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(tmp);
357c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Dial string count");
358c18ec02fSPetter Reinholdtsen 	if (!rsp || (rsp->data[1] & PEF_SERIAL_DIAL_STRING_COUNT_MASK) == 0)
359c18ec02fSPetter Reinholdtsen 		return;	/* sssh, not supported */
360c18ec02fSPetter Reinholdtsen 
361c18ec02fSPetter Reinholdtsen 	memcpy(&tmp, ssel, sizeof(tmp));
362c18ec02fSPetter Reinholdtsen 	tmp.id = PEF_SERIAL_CFGPARM_ID_DEST_DIAL_STRING;
363c18ec02fSPetter Reinholdtsen 	tmp.block = 1;
364c18ec02fSPetter Reinholdtsen 	memset(strval, 0, sizeof(strval));
365c18ec02fSPetter Reinholdtsen 	p = strval;
366c18ec02fSPetter Reinholdtsen 	for (;;) {
367c18ec02fSPetter Reinholdtsen 		rsp = ipmi_pef_msg_exchange(intf, &req, label);
368c18ec02fSPetter Reinholdtsen 		if (!rsp
369c18ec02fSPetter Reinholdtsen 		|| (rsp->data[1] != ssel->id)
370c18ec02fSPetter Reinholdtsen 		|| (rsp->data[2] != tmp.block)) {
371c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, " **Error retrieving %s", label);
372c18ec02fSPetter Reinholdtsen 			return;
373c18ec02fSPetter Reinholdtsen 		}
374c18ec02fSPetter Reinholdtsen 		memcpy(p, &rsp->data[3], BLOCK_SIZE);
375c18ec02fSPetter Reinholdtsen 		if (strchr(p, '\0') <= (p + BLOCK_SIZE))
376c18ec02fSPetter Reinholdtsen 			break;
377c18ec02fSPetter Reinholdtsen 		if ((p += BLOCK_SIZE) >= &strval[sizeof(strval)-1])
378c18ec02fSPetter Reinholdtsen 			break;
379c18ec02fSPetter Reinholdtsen 		tmp.block++;
380c18ec02fSPetter Reinholdtsen 	}
381c18ec02fSPetter Reinholdtsen 
382c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_str(label, strval);
383c18ec02fSPetter Reinholdtsen #undef BLOCK_SIZE
384c18ec02fSPetter Reinholdtsen }
385c18ec02fSPetter Reinholdtsen 
386c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_serial_dest_tap(struct ipmi_intf * intf,struct pef_serial_cfgparm_selector * ssel)387c18ec02fSPetter Reinholdtsen ipmi_pef_print_serial_dest_tap(struct ipmi_intf * intf,
388c18ec02fSPetter Reinholdtsen 											struct pef_serial_cfgparm_selector * ssel)
389c18ec02fSPetter Reinholdtsen {	/*
390c18ec02fSPetter Reinholdtsen 	// print TAP destination info
391c18ec02fSPetter Reinholdtsen 	*/
392c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
393c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
394c18ec02fSPetter Reinholdtsen 	struct pef_serial_cfgparm_selector tmp;
395c18ec02fSPetter Reinholdtsen 	struct pef_serial_cfgparm_tap_svc_settings * pset;
396c18ec02fSPetter Reinholdtsen 	uint8_t dialstr_id, setting_id;
397c18ec02fSPetter Reinholdtsen 
398c18ec02fSPetter Reinholdtsen 	memset(&tmp, 0, sizeof(tmp));
399c18ec02fSPetter Reinholdtsen 	tmp.id = PEF_SERIAL_CFGPARM_ID_TAP_ACCT_COUNT;
400c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
401c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_TRANSPORT;
402c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG;
403c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *)&tmp;
404c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(tmp);
405c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Number of TAP accounts");
406c18ec02fSPetter Reinholdtsen 	if (!rsp || (rsp->data[1] & PEF_SERIAL_TAP_ACCT_COUNT_MASK) == 0)
407c18ec02fSPetter Reinholdtsen 		return;	/* sssh, not supported */
408c18ec02fSPetter Reinholdtsen 
409c18ec02fSPetter Reinholdtsen 	memcpy(&tmp, ssel, sizeof(tmp));
410c18ec02fSPetter Reinholdtsen 	tmp.id = PEF_SERIAL_CFGPARM_ID_TAP_ACCT_INFO;
411c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "TAP account info");
412c18ec02fSPetter Reinholdtsen 	if (!rsp || (rsp->data[1] != tmp.set)) {
413c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
414c18ec02fSPetter Reinholdtsen 			"TAP account info");
415c18ec02fSPetter Reinholdtsen 		return;
416c18ec02fSPetter Reinholdtsen 	}
417c18ec02fSPetter Reinholdtsen 	dialstr_id = (rsp->data[2] & PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_MASK);
418c18ec02fSPetter Reinholdtsen 	dialstr_id >>= PEF_SERIAL_TAP_ACCT_INFO_DIAL_STRING_ID_SHIFT;
419c18ec02fSPetter Reinholdtsen 	setting_id = (rsp->data[2] & PEF_SERIAL_TAP_ACCT_INFO_SVC_SETTINGS_ID_MASK);
420c18ec02fSPetter Reinholdtsen 	tmp.set = dialstr_id;
421c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_serial_dest_dial(intf, "TAP Dial string", &tmp);
422c18ec02fSPetter Reinholdtsen 
423c18ec02fSPetter Reinholdtsen 	tmp.set = setting_id;
424c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "TAP service settings");
425c18ec02fSPetter Reinholdtsen 	if (!rsp || (rsp->data[1] != tmp.set)) {
426c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
427c18ec02fSPetter Reinholdtsen 			"TAP service settings");
428c18ec02fSPetter Reinholdtsen 		return;
429c18ec02fSPetter Reinholdtsen 	}
430c18ec02fSPetter Reinholdtsen 	pset = (struct pef_serial_cfgparm_tap_svc_settings *)&rsp->data[1];
431c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_str("TAP confirmation",
432c18ec02fSPetter Reinholdtsen 		ipmi_pef_bit_desc(&pef_b2s_tap_svc_confirm, pset->confirmation_flags));
433c18ec02fSPetter Reinholdtsen 
434c18ec02fSPetter Reinholdtsen 	/* TODO : additional TAP settings? */
435c18ec02fSPetter Reinholdtsen }
436c18ec02fSPetter Reinholdtsen 
437c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_serial_dest_ppp(struct ipmi_intf * intf,struct pef_serial_cfgparm_selector * ssel)438c18ec02fSPetter Reinholdtsen ipmi_pef_print_serial_dest_ppp(struct ipmi_intf * intf,
439c18ec02fSPetter Reinholdtsen 											struct pef_serial_cfgparm_selector * ssel)
440c18ec02fSPetter Reinholdtsen {	/*
441c18ec02fSPetter Reinholdtsen 	// print PPP destination info
442c18ec02fSPetter Reinholdtsen 	*/
443c18ec02fSPetter Reinholdtsen 
444c18ec02fSPetter Reinholdtsen 	/* TODO */
445c18ec02fSPetter Reinholdtsen }
446c18ec02fSPetter Reinholdtsen 
447c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_serial_dest_callback(struct ipmi_intf * intf,struct pef_serial_cfgparm_selector * ssel)448c18ec02fSPetter Reinholdtsen ipmi_pef_print_serial_dest_callback(struct ipmi_intf * intf,
449c18ec02fSPetter Reinholdtsen 												struct pef_serial_cfgparm_selector * ssel)
450c18ec02fSPetter Reinholdtsen {	/*
451c18ec02fSPetter Reinholdtsen 	// print callback destination info
452c18ec02fSPetter Reinholdtsen 	*/
453c18ec02fSPetter Reinholdtsen 
454c18ec02fSPetter Reinholdtsen 	/* TODO */
455c18ec02fSPetter Reinholdtsen }
456c18ec02fSPetter Reinholdtsen 
457c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_serial_dest(struct ipmi_intf * intf,uint8_t ch,uint8_t dest)458c18ec02fSPetter Reinholdtsen ipmi_pef_print_serial_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
459c18ec02fSPetter Reinholdtsen {	/*
460c18ec02fSPetter Reinholdtsen 	// print Serial/PPP alert destination info
461c18ec02fSPetter Reinholdtsen 	*/
462c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
463c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
464c18ec02fSPetter Reinholdtsen 	struct pef_serial_cfgparm_selector ssel;
465c18ec02fSPetter Reinholdtsen 	uint8_t tbl_size, wrk;
466c18ec02fSPetter Reinholdtsen 	struct pef_serial_cfgparm_dest_info * pinfo;
467c18ec02fSPetter Reinholdtsen 
468c18ec02fSPetter Reinholdtsen 	memset(&ssel, 0, sizeof(ssel));
469c18ec02fSPetter Reinholdtsen 	ssel.id = PEF_SERIAL_CFGPARM_ID_DEST_COUNT;
470c18ec02fSPetter Reinholdtsen 	ssel.ch = ch;
471c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
472c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_TRANSPORT;
473c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_SERIAL_GET_CONFIG;
474c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *)&ssel;
475c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(ssel);
476c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination count");
477c18ec02fSPetter Reinholdtsen 	if (!rsp) {
478c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
479c18ec02fSPetter Reinholdtsen 			"Alert destination count");
480c18ec02fSPetter Reinholdtsen 		return;
481c18ec02fSPetter Reinholdtsen 	}
482c18ec02fSPetter Reinholdtsen 	tbl_size = (rsp->data[1] & PEF_SERIAL_DEST_TABLE_SIZE_MASK);
483c18ec02fSPetter Reinholdtsen 	if (!dest || tbl_size == 0)	/* Page alerting not supported */
484c18ec02fSPetter Reinholdtsen 		return;
485c18ec02fSPetter Reinholdtsen 
486c18ec02fSPetter Reinholdtsen 	ssel.id = PEF_SERIAL_CFGPARM_ID_DESTINFO;
487c18ec02fSPetter Reinholdtsen 	ssel.set = dest;
488c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Alert destination info");
489c18ec02fSPetter Reinholdtsen 	if (!rsp || rsp->data[1] != ssel.set)
490c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
491c18ec02fSPetter Reinholdtsen 			"Alert destination info");
492c18ec02fSPetter Reinholdtsen 	else {
493c18ec02fSPetter Reinholdtsen 		pinfo = (struct pef_serial_cfgparm_dest_info *)rsp->data;
494c18ec02fSPetter Reinholdtsen 		wrk = (pinfo->dest_type & PEF_SERIAL_DEST_TYPE_MASK);
495c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_str("Alert destination type",
496c18ec02fSPetter Reinholdtsen 					ipmi_pef_bit_desc(&pef_b2s_serial_desttype, wrk));
497c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_dec("ACK timeout (secs)",
498c18ec02fSPetter Reinholdtsen 					pinfo->alert_timeout);
499c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_dec("Retries",
500c18ec02fSPetter Reinholdtsen 					(pinfo->retries & PEF_SERIAL_RETRIES_MASK));
501c18ec02fSPetter Reinholdtsen 		switch (wrk) {
502c18ec02fSPetter Reinholdtsen 			case PEF_SERIAL_DEST_TYPE_DIAL:
503c18ec02fSPetter Reinholdtsen 				ipmi_pef_print_serial_dest_dial(intf, "Serial dial string", &ssel);
504c18ec02fSPetter Reinholdtsen 				break;
505c18ec02fSPetter Reinholdtsen 			case PEF_SERIAL_DEST_TYPE_TAP:
506c18ec02fSPetter Reinholdtsen 				ipmi_pef_print_serial_dest_tap(intf, &ssel);
507c18ec02fSPetter Reinholdtsen 				break;
508c18ec02fSPetter Reinholdtsen 			case PEF_SERIAL_DEST_TYPE_PPP:
509c18ec02fSPetter Reinholdtsen 				ipmi_pef_print_serial_dest_ppp(intf, &ssel);
510c18ec02fSPetter Reinholdtsen 				break;
511c18ec02fSPetter Reinholdtsen 			case PEF_SERIAL_DEST_TYPE_BASIC_CALLBACK:
512c18ec02fSPetter Reinholdtsen 			case PEF_SERIAL_DEST_TYPE_PPP_CALLBACK:
513c18ec02fSPetter Reinholdtsen 				ipmi_pef_print_serial_dest_callback(intf, &ssel);
514c18ec02fSPetter Reinholdtsen 				break;
515c18ec02fSPetter Reinholdtsen 		}
516c18ec02fSPetter Reinholdtsen 	}
517c18ec02fSPetter Reinholdtsen }
518c18ec02fSPetter Reinholdtsen 
519c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_dest(struct ipmi_intf * intf,uint8_t ch,uint8_t dest)520c18ec02fSPetter Reinholdtsen ipmi_pef_print_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
521c18ec02fSPetter Reinholdtsen {	/*
522c18ec02fSPetter Reinholdtsen 	// print generic alert destination info
523c18ec02fSPetter Reinholdtsen 	*/
524c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_dec("Destination ID", dest);
525c18ec02fSPetter Reinholdtsen }
526c18ec02fSPetter Reinholdtsen 
527c18ec02fSPetter Reinholdtsen void
ipmi_pef_print_event_info(struct pef_cfgparm_filter_table_entry * pef,char * buf)528c18ec02fSPetter Reinholdtsen ipmi_pef_print_event_info(struct pef_cfgparm_filter_table_entry * pef, char * buf)
529c18ec02fSPetter Reinholdtsen {	/*
530c18ec02fSPetter Reinholdtsen 	//  print PEF entry Event info: class, severity, trigger, etc.
531c18ec02fSPetter Reinholdtsen 	*/
532c18ec02fSPetter Reinholdtsen 	static char * classes[] = {"Discrete", "Threshold", "OEM"};
533c18ec02fSPetter Reinholdtsen 	uint16_t offmask;
534c18ec02fSPetter Reinholdtsen 	char * p;
535c18ec02fSPetter Reinholdtsen 	int i;
536c18ec02fSPetter Reinholdtsen 	uint8_t t;
537c18ec02fSPetter Reinholdtsen 
538c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_str("Event severity",
539c18ec02fSPetter Reinholdtsen 				ipmi_pef_bit_desc(&pef_b2s_severities, pef->entry.severity));
540c18ec02fSPetter Reinholdtsen 
541c18ec02fSPetter Reinholdtsen 	t = pef->entry.event_trigger;
542c18ec02fSPetter Reinholdtsen 	if (t == PEF_EVENT_TRIGGER_THRESHOLD)
543c18ec02fSPetter Reinholdtsen 		i = 1;
544c18ec02fSPetter Reinholdtsen 	else if (t > PEF_EVENT_TRIGGER_SENSOR_SPECIFIC)
545c18ec02fSPetter Reinholdtsen 		i = 2;
546c18ec02fSPetter Reinholdtsen 	else
547c18ec02fSPetter Reinholdtsen 		i = 0;
548c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_str("Event class", classes[i]);
549c18ec02fSPetter Reinholdtsen 
550c18ec02fSPetter Reinholdtsen 	offmask = ((pef->entry.event_data_1_offset_mask[1] << 8)
551c18ec02fSPetter Reinholdtsen 	          + pef->entry.event_data_1_offset_mask[0]);
552c18ec02fSPetter Reinholdtsen 
553c18ec02fSPetter Reinholdtsen 	if (offmask == 0xffff || t == PEF_EVENT_TRIGGER_MATCH_ANY)
554c18ec02fSPetter Reinholdtsen 		strcpy(buf, "Any");
555c18ec02fSPetter Reinholdtsen 	else if (t == PEF_EVENT_TRIGGER_UNSPECIFIED)
556c18ec02fSPetter Reinholdtsen 		strcpy(buf, "Unspecified");
557c18ec02fSPetter Reinholdtsen 	else if (t == PEF_EVENT_TRIGGER_SENSOR_SPECIFIC)
558c18ec02fSPetter Reinholdtsen 		strcpy(buf, "Sensor-specific");
559c18ec02fSPetter Reinholdtsen 	else if (t > PEF_EVENT_TRIGGER_SENSOR_SPECIFIC)
560c18ec02fSPetter Reinholdtsen 		strcpy(buf, "OEM");
561c18ec02fSPetter Reinholdtsen 	else {
562c18ec02fSPetter Reinholdtsen 		sprintf(buf, "(0x%02x/0x%04x)", t, offmask);
563c18ec02fSPetter Reinholdtsen 		p = strchr(buf, '\0');
564c18ec02fSPetter Reinholdtsen 		for (i=0; i<PEF_B2S_GENERIC_ER_ENTRIES; i++) {
565c18ec02fSPetter Reinholdtsen 			if (offmask & 1) {
566c18ec02fSPetter Reinholdtsen 				if ((t-1) >= PEF_B2S_GENERIC_ER_ENTRIES) {
567c18ec02fSPetter Reinholdtsen 					sprintf(p, ", Unrecognized event trigger");
568c18ec02fSPetter Reinholdtsen 				} else {
569c18ec02fSPetter Reinholdtsen 					sprintf(p, ",%s", ipmi_pef_bit_desc(pef_b2s_generic_ER[t-1], i));
570c18ec02fSPetter Reinholdtsen 				}
571c18ec02fSPetter Reinholdtsen 				p = strchr(p, '\0');
572c18ec02fSPetter Reinholdtsen 			}
573c18ec02fSPetter Reinholdtsen 			offmask >>= 1;
574c18ec02fSPetter Reinholdtsen 		}
575c18ec02fSPetter Reinholdtsen 	}
576c18ec02fSPetter Reinholdtsen 
577c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_str("Event trigger(s)", buf);
578c18ec02fSPetter Reinholdtsen }
579c18ec02fSPetter Reinholdtsen 
580c18ec02fSPetter Reinholdtsen static void
ipmi_pef_print_entry(struct ipmi_rs * rsp,uint8_t id,struct pef_cfgparm_filter_table_entry * pef)581c18ec02fSPetter Reinholdtsen ipmi_pef_print_entry(struct ipmi_rs * rsp, uint8_t id,
582c18ec02fSPetter Reinholdtsen 							struct pef_cfgparm_filter_table_entry * pef)
583c18ec02fSPetter Reinholdtsen {	/*
584c18ec02fSPetter Reinholdtsen 	// print a PEF table entry
585c18ec02fSPetter Reinholdtsen 	*/
586c18ec02fSPetter Reinholdtsen 	uint8_t wrk, set;
587c18ec02fSPetter Reinholdtsen 	char buf[128];
588c18ec02fSPetter Reinholdtsen 
589c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_dec("PEF table entry", id);
590c18ec02fSPetter Reinholdtsen 
591c18ec02fSPetter Reinholdtsen 	wrk = !!(pef->entry.config & PEF_CONFIG_ENABLED);
592c18ec02fSPetter Reinholdtsen 	sprintf(buf, "%sactive", (wrk ? "" : "in"));
593c18ec02fSPetter Reinholdtsen 	if (pef->entry.config & PEF_CONFIG_PRECONFIGURED)
594c18ec02fSPetter Reinholdtsen 		strcat(buf, ", pre-configured");
595c18ec02fSPetter Reinholdtsen 
596c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_str("Status", buf);
597c18ec02fSPetter Reinholdtsen 
598c18ec02fSPetter Reinholdtsen 	if (wrk != 0) {
599c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_1xd("Version", rsp->data[0]);
600c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_str("Sensor type",
601c18ec02fSPetter Reinholdtsen 					ipmi_pef_bit_desc(&pef_b2s_sensortypes, pef->entry.sensor_type));
602c18ec02fSPetter Reinholdtsen 
603c18ec02fSPetter Reinholdtsen 		if (pef->entry.sensor_number == PEF_SENSOR_NUMBER_MATCH_ANY)
604c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_str("Sensor number", "Any");
605c18ec02fSPetter Reinholdtsen 		else
606c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_dec("Sensor number", pef->entry.sensor_number);
607c18ec02fSPetter Reinholdtsen 
608c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_event_info(pef, buf);
609c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_str("Action",
610c18ec02fSPetter Reinholdtsen 					ipmi_pef_bit_desc(&pef_b2s_actions, pef->entry.action));
611c18ec02fSPetter Reinholdtsen 
612c18ec02fSPetter Reinholdtsen 		if (pef->entry.action & PEF_ACTION_ALERT) {
613c18ec02fSPetter Reinholdtsen 			set = (pef->entry.policy_number & PEF_POLICY_NUMBER_MASK);
614c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_int("Policy set", set);
615c18ec02fSPetter Reinholdtsen 		}
616c18ec02fSPetter Reinholdtsen 	}
617c18ec02fSPetter Reinholdtsen }
618c18ec02fSPetter Reinholdtsen 
619c18ec02fSPetter Reinholdtsen static void
ipmi_pef_list_entries(struct ipmi_intf * intf)620c18ec02fSPetter Reinholdtsen ipmi_pef_list_entries(struct ipmi_intf * intf)
621c18ec02fSPetter Reinholdtsen {	/*
622c18ec02fSPetter Reinholdtsen 	// list all PEF table entries
623c18ec02fSPetter Reinholdtsen 	*/
624c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
625c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
626c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_selector psel;
627c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_filter_table_entry * pcfg;
628c18ec02fSPetter Reinholdtsen 	uint32_t i;
629c18ec02fSPetter Reinholdtsen 	uint8_t max_filters;
630c18ec02fSPetter Reinholdtsen 
631c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
632c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
633c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES;
634c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "PEF capabilities");
635c18ec02fSPetter Reinholdtsen 	if (!rsp
636c18ec02fSPetter Reinholdtsen 	|| (max_filters = ((struct pef_capabilities *)rsp->data)->tblsize) == 0)
637c18ec02fSPetter Reinholdtsen 		return;	/* sssh, not supported */
638c18ec02fSPetter Reinholdtsen 
639c18ec02fSPetter Reinholdtsen 	memset(&psel, 0, sizeof(psel));
640c18ec02fSPetter Reinholdtsen 	psel.id = PEF_CFGPARM_ID_PEF_FILTER_TABLE_ENTRY;
641c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
642c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
643c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
644c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *)&psel;
645c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(psel);
646c18ec02fSPetter Reinholdtsen 	for (i=1; i<=max_filters; i++) {
647c18ec02fSPetter Reinholdtsen 		if (i > 1)
648c18ec02fSPetter Reinholdtsen 			printf("\n");
649c18ec02fSPetter Reinholdtsen 		psel.set = (i & PEF_FILTER_TABLE_ID_MASK);
650c18ec02fSPetter Reinholdtsen 		rsp = ipmi_pef_msg_exchange(intf, &req, "PEF table entry");
651c18ec02fSPetter Reinholdtsen 		if (!rsp
652c18ec02fSPetter Reinholdtsen 		|| (psel.set != (rsp->data[1] & PEF_FILTER_TABLE_ID_MASK))) {
653c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, " **Error retrieving %s",
654c18ec02fSPetter Reinholdtsen 				"PEF table entry");
655c18ec02fSPetter Reinholdtsen 			continue;
656c18ec02fSPetter Reinholdtsen 		}
657c18ec02fSPetter Reinholdtsen 		pcfg = (struct pef_cfgparm_filter_table_entry *)&rsp->data[1];
658c18ec02fSPetter Reinholdtsen 		first_field = 1;
659c18ec02fSPetter Reinholdtsen 		ipmi_pef_print_entry(rsp, psel.set, pcfg);
660c18ec02fSPetter Reinholdtsen 	}
661c18ec02fSPetter Reinholdtsen }
662c18ec02fSPetter Reinholdtsen 
663c18ec02fSPetter Reinholdtsen static void
ipmi_pef_list_policies(struct ipmi_intf * intf)664c18ec02fSPetter Reinholdtsen ipmi_pef_list_policies(struct ipmi_intf * intf)
665c18ec02fSPetter Reinholdtsen {	/*
666c18ec02fSPetter Reinholdtsen 	// list PEF alert policies
667c18ec02fSPetter Reinholdtsen 	*/
668c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
669c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
670c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_policy_table_entry * ptbl = NULL;
671c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_policy_table_entry * ptmp = NULL;
672c18ec02fSPetter Reinholdtsen 	uint32_t i;
673c18ec02fSPetter Reinholdtsen 	uint8_t wrk, ch, medium, tbl_size;
674c18ec02fSPetter Reinholdtsen 
675c18ec02fSPetter Reinholdtsen 	tbl_size = ipmi_pef_get_policy_table(intf, &ptbl);
676c18ec02fSPetter Reinholdtsen 	if (!tbl_size) {
677*2d66f8d5SZdenek Styblik 		if (ptbl != NULL) {
678c18ec02fSPetter Reinholdtsen 			free(ptbl);
679c18ec02fSPetter Reinholdtsen 			ptbl = NULL;
680c18ec02fSPetter Reinholdtsen 		}
681c18ec02fSPetter Reinholdtsen 		return;
682c18ec02fSPetter Reinholdtsen 	}
683c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
684c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
685c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_CHANNEL_INFO;
686c18ec02fSPetter Reinholdtsen 	req.msg.data = &ch;
687c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(ch);
688c18ec02fSPetter Reinholdtsen 	for (ptmp=ptbl, i=1; i<=tbl_size; i++, ptmp++) {
689c18ec02fSPetter Reinholdtsen 		if ((ptmp->entry.policy & PEF_POLICY_ENABLED) == PEF_POLICY_ENABLED) {
690c18ec02fSPetter Reinholdtsen 			if (i > 1)
691c18ec02fSPetter Reinholdtsen 				printf("\n");
692c18ec02fSPetter Reinholdtsen 			first_field = 1;
693c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_dec("Alert policy table entry",
694c18ec02fSPetter Reinholdtsen 						(ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
695c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_dec("Policy set",
696c18ec02fSPetter Reinholdtsen 						(ptmp->entry.policy & PEF_POLICY_ID_MASK) >> PEF_POLICY_ID_SHIFT);
697c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_str("Policy entry rule",
698c18ec02fSPetter Reinholdtsen 						ipmi_pef_bit_desc(&pef_b2s_policies, (ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
699c18ec02fSPetter Reinholdtsen 
700c18ec02fSPetter Reinholdtsen 			if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
701c18ec02fSPetter Reinholdtsen 				ipmi_pef_print_str("Event-specific", "true");
702c18ec02fSPetter Reinholdtsen //				continue;
703c18ec02fSPetter Reinholdtsen 			}
704c18ec02fSPetter Reinholdtsen 			wrk = ptmp->entry.chan_dest;
705c18ec02fSPetter Reinholdtsen 
706c18ec02fSPetter Reinholdtsen 			/* channel/description */
707c18ec02fSPetter Reinholdtsen 			ch = (wrk & PEF_POLICY_CHANNEL_MASK) >> PEF_POLICY_CHANNEL_SHIFT;
708c18ec02fSPetter Reinholdtsen 			rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
709c18ec02fSPetter Reinholdtsen 			if (!rsp || rsp->data[0] != ch) {
710c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, " **Error retrieving %s",
711c18ec02fSPetter Reinholdtsen 					"Channel info");
712c18ec02fSPetter Reinholdtsen 				continue;
713c18ec02fSPetter Reinholdtsen 			}
714c18ec02fSPetter Reinholdtsen 			medium = rsp->data[1];
715c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_dec("Channel number", ch);
716c18ec02fSPetter Reinholdtsen 			ipmi_pef_print_str("Channel medium",
717c18ec02fSPetter Reinholdtsen 						ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
718c18ec02fSPetter Reinholdtsen 
719c18ec02fSPetter Reinholdtsen 			/* destination/description */
720c18ec02fSPetter Reinholdtsen 			wrk &= PEF_POLICY_DESTINATION_MASK;
721c18ec02fSPetter Reinholdtsen 			switch (medium) {
722c18ec02fSPetter Reinholdtsen 				case PEF_CH_MEDIUM_TYPE_LAN:
723c18ec02fSPetter Reinholdtsen 					ipmi_pef_print_lan_dest(intf, ch, wrk);
724c18ec02fSPetter Reinholdtsen 					break;
725c18ec02fSPetter Reinholdtsen 				case PEF_CH_MEDIUM_TYPE_SERIAL:
726c18ec02fSPetter Reinholdtsen 					ipmi_pef_print_serial_dest(intf, ch, wrk);
727c18ec02fSPetter Reinholdtsen 					break;
728c18ec02fSPetter Reinholdtsen 				default:
729c18ec02fSPetter Reinholdtsen 					ipmi_pef_print_dest(intf, ch, wrk);
730c18ec02fSPetter Reinholdtsen 					break;
731c18ec02fSPetter Reinholdtsen 			}
732c18ec02fSPetter Reinholdtsen 		}
733c18ec02fSPetter Reinholdtsen 	}
734c18ec02fSPetter Reinholdtsen 	free(ptbl);
735c18ec02fSPetter Reinholdtsen 	ptbl = NULL;
736c18ec02fSPetter Reinholdtsen }
737c18ec02fSPetter Reinholdtsen 
738c18ec02fSPetter Reinholdtsen static void
ipmi_pef_get_status(struct ipmi_intf * intf)739c18ec02fSPetter Reinholdtsen ipmi_pef_get_status(struct ipmi_intf * intf)
740c18ec02fSPetter Reinholdtsen {	/*
741c18ec02fSPetter Reinholdtsen 	// report the PEF status
742c18ec02fSPetter Reinholdtsen 	*/
743c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
744c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
745c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_selector psel;
746c18ec02fSPetter Reinholdtsen 	char tbuf[40];
747c18ec02fSPetter Reinholdtsen 	uint32_t timei;
748c18ec02fSPetter Reinholdtsen 	time_t ts;
749c18ec02fSPetter Reinholdtsen 
750c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
751c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
752c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_LAST_PROCESSED_EVT_ID;
753c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "Last S/W processed ID");
754c18ec02fSPetter Reinholdtsen 	if (!rsp) {
755c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
756c18ec02fSPetter Reinholdtsen 			"Last S/W processed ID");
757c18ec02fSPetter Reinholdtsen 		return;
758c18ec02fSPetter Reinholdtsen 	}
759c18ec02fSPetter Reinholdtsen 	memcpy(&timei, rsp->data, sizeof(timei));
760c18ec02fSPetter Reinholdtsen #if WORDS_BIGENDIAN
761c18ec02fSPetter Reinholdtsen 	timei = BSWAP_32(timei);
762c18ec02fSPetter Reinholdtsen #endif
763c18ec02fSPetter Reinholdtsen 	ts = (time_t)timei;
764c18ec02fSPetter Reinholdtsen 
765c18ec02fSPetter Reinholdtsen 	strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&ts));
766c18ec02fSPetter Reinholdtsen 
767c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_str("Last SEL addition", tbuf);
768c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_2xd("Last SEL record ID", rsp->data[5], rsp->data[4]);
769c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_2xd("Last S/W processed ID", rsp->data[7], rsp->data[6]);
770c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_2xd("Last BMC processed ID", rsp->data[9], rsp->data[8]);
771c18ec02fSPetter Reinholdtsen 
772c18ec02fSPetter Reinholdtsen 	memset(&psel, 0, sizeof(psel));
773c18ec02fSPetter Reinholdtsen 	psel.id = PEF_CFGPARM_ID_PEF_CONTROL;
774c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
775c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
776c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
777c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *)&psel;
778c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(psel);
779c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "PEF control");
780c18ec02fSPetter Reinholdtsen 	if (!rsp) {
781c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
782c18ec02fSPetter Reinholdtsen 			"PEF control");
783c18ec02fSPetter Reinholdtsen 		return;
784c18ec02fSPetter Reinholdtsen 	}
785c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_flags(&pef_b2s_control, P_ABLE, rsp->data[1]);
786c18ec02fSPetter Reinholdtsen 
787c18ec02fSPetter Reinholdtsen 	psel.id = PEF_CFGPARM_ID_PEF_ACTION;
788c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "PEF action");
789c18ec02fSPetter Reinholdtsen 	if (!rsp) {
790c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " **Error retrieving %s",
791c18ec02fSPetter Reinholdtsen 			"PEF action");
792c18ec02fSPetter Reinholdtsen 		return;
793c18ec02fSPetter Reinholdtsen 	}
794c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_flags(&pef_b2s_actions, P_ACTV, rsp->data[1]);
795c18ec02fSPetter Reinholdtsen }
796c18ec02fSPetter Reinholdtsen 
797c18ec02fSPetter Reinholdtsen static void
ipmi_pef_get_info(struct ipmi_intf * intf)798c18ec02fSPetter Reinholdtsen ipmi_pef_get_info(struct ipmi_intf * intf)
799c18ec02fSPetter Reinholdtsen {	/*
800c18ec02fSPetter Reinholdtsen 	// report PEF capabilities + System GUID
801c18ec02fSPetter Reinholdtsen 	*/
802c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
803c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
804c18ec02fSPetter Reinholdtsen 	struct pef_capabilities * pcap;
805c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_selector psel;
806c18ec02fSPetter Reinholdtsen 	struct pef_cfgparm_policy_table_entry * ptbl = NULL;
807c18ec02fSPetter Reinholdtsen 	uint8_t * uid;
808c18ec02fSPetter Reinholdtsen 	uint8_t actions, tbl_size;
809c18ec02fSPetter Reinholdtsen 
810c18ec02fSPetter Reinholdtsen 	tbl_size = ipmi_pef_get_policy_table(intf, &ptbl);
811ecfaeb27SZdenek Styblik 	if (ptbl != NULL) {
812c18ec02fSPetter Reinholdtsen 		free(ptbl);
813c18ec02fSPetter Reinholdtsen 		ptbl = NULL;
814c18ec02fSPetter Reinholdtsen 	}
815c18ec02fSPetter Reinholdtsen 
816c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
817c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
818c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES;
819c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "PEF capabilities");
820c18ec02fSPetter Reinholdtsen 	if (!rsp)
821c18ec02fSPetter Reinholdtsen 		return;
822c18ec02fSPetter Reinholdtsen 	pcap = (struct pef_capabilities *)rsp->data;
823c18ec02fSPetter Reinholdtsen 
824c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_1xd("Version", pcap->version);
825c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_dec("PEF table size", pcap->tblsize);
826c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_dec("Alert policy table size", tbl_size);
827c18ec02fSPetter Reinholdtsen 	actions = pcap->actions;
828c18ec02fSPetter Reinholdtsen 
829c18ec02fSPetter Reinholdtsen 	memset(&psel, 0, sizeof(psel));
830c18ec02fSPetter Reinholdtsen 	psel.id = PEF_CFGPARM_ID_SYSTEM_GUID;
831c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
832c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
833c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
834c18ec02fSPetter Reinholdtsen 	req.msg.data = (uint8_t *)&psel;
835c18ec02fSPetter Reinholdtsen 	req.msg.data_len = sizeof(psel);
836c18ec02fSPetter Reinholdtsen 	rsp = ipmi_pef_msg_exchange(intf, &req, "System GUID");
837c18ec02fSPetter Reinholdtsen 	uid = NULL;
838c18ec02fSPetter Reinholdtsen 	if (rsp && (rsp->data[1] & PEF_SYSTEM_GUID_USED_IN_PET))
839c18ec02fSPetter Reinholdtsen 		uid = &rsp->data[2];
840c18ec02fSPetter Reinholdtsen 	else {
841c18ec02fSPetter Reinholdtsen 		memset(&req, 0, sizeof(req));
842c18ec02fSPetter Reinholdtsen 		req.msg.netfn = IPMI_NETFN_APP;
843c18ec02fSPetter Reinholdtsen 		req.msg.cmd = IPMI_CMD_GET_SYSTEM_GUID;
844c18ec02fSPetter Reinholdtsen 		rsp = ipmi_pef_msg_exchange(intf, &req, "System GUID");
845c18ec02fSPetter Reinholdtsen 		if (rsp)
846c18ec02fSPetter Reinholdtsen 			uid = &rsp->data[0];
847c18ec02fSPetter Reinholdtsen 	}
848c18ec02fSPetter Reinholdtsen 	if (uid) {		/* got GUID? */
849c18ec02fSPetter Reinholdtsen 		if (verbose)
850c18ec02fSPetter Reinholdtsen 			printf(pef_fld_fmts[F_UID][0], KYWD_LENGTH, "System GUID",
851c18ec02fSPetter Reinholdtsen 					uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7],
852c18ec02fSPetter Reinholdtsen 					uid[8], uid[9], uid[10],uid[11],uid[12],uid[13],uid[14],uid[15]);
853c18ec02fSPetter Reinholdtsen 		else
854c18ec02fSPetter Reinholdtsen 			printf(pef_fld_fmts[F_UID][1],
855c18ec02fSPetter Reinholdtsen 					uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7],
856c18ec02fSPetter Reinholdtsen 					uid[8], uid[9], uid[10],uid[11],uid[12],uid[13],uid[14],uid[15]);
857c18ec02fSPetter Reinholdtsen 	}
858c18ec02fSPetter Reinholdtsen 	ipmi_pef_print_flags(&pef_b2s_actions, P_SUPP, actions);
859c18ec02fSPetter Reinholdtsen }
860c18ec02fSPetter Reinholdtsen 
ipmi_pef_main(struct ipmi_intf * intf,int argc,char ** argv)861c18ec02fSPetter Reinholdtsen int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv)
862c18ec02fSPetter Reinholdtsen {	/*
863c18ec02fSPetter Reinholdtsen 	// PEF subcommand handling
864c18ec02fSPetter Reinholdtsen 	*/
865c18ec02fSPetter Reinholdtsen 	int help = 0;
866c18ec02fSPetter Reinholdtsen     int rc = 0;
867c18ec02fSPetter Reinholdtsen 
868c18ec02fSPetter Reinholdtsen 	if (!argc || !strncmp(argv[0], "info", 4))
869c18ec02fSPetter Reinholdtsen 		ipmi_pef_get_info(intf);
870c18ec02fSPetter Reinholdtsen 	else if (!strncmp(argv[0], "help", 4))
871c18ec02fSPetter Reinholdtsen 		help = 1;
872c18ec02fSPetter Reinholdtsen 	else if (!strncmp(argv[0], "status", 6))
873c18ec02fSPetter Reinholdtsen 		ipmi_pef_get_status(intf);
874c18ec02fSPetter Reinholdtsen 	else if (!strncmp(argv[0], "policy", 6))
875c18ec02fSPetter Reinholdtsen 		ipmi_pef_list_policies(intf);
876c18ec02fSPetter Reinholdtsen 	else if (!strncmp(argv[0], "list", 4))
877c18ec02fSPetter Reinholdtsen 		ipmi_pef_list_entries(intf);
878c18ec02fSPetter Reinholdtsen 	else {
879c18ec02fSPetter Reinholdtsen 		help = 1;
880c18ec02fSPetter Reinholdtsen         rc   = -1;
881c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]);
882c18ec02fSPetter Reinholdtsen 	}
883c18ec02fSPetter Reinholdtsen 
884c18ec02fSPetter Reinholdtsen 	if (help)
885c18ec02fSPetter Reinholdtsen 		lprintf(LOG_NOTICE, "PEF commands: info status policy list");
886c18ec02fSPetter Reinholdtsen 	else if (!verbose)
887c18ec02fSPetter Reinholdtsen 		printf("\n");
888c18ec02fSPetter Reinholdtsen 
889c18ec02fSPetter Reinholdtsen 	return rc;
890c18ec02fSPetter Reinholdtsen }
891