xref: /openbmc/ipmitool/lib/ipmi_firewall.c (revision 2d79e69f)
1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen  * Copyright (c) 2005 International Business Machines, Inc.  All Rights Reserved.
3c18ec02fSPetter Reinholdtsen  * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
4c18ec02fSPetter Reinholdtsen  *
5c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
6c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
7c18ec02fSPetter Reinholdtsen  * are met:
8c18ec02fSPetter Reinholdtsen  *
9c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
10c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
11c18ec02fSPetter Reinholdtsen  *
12c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
13c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
14c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
15c18ec02fSPetter Reinholdtsen  *
16c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
17c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
18c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
19c18ec02fSPetter Reinholdtsen  *
20c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
21c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
24c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
25c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
26c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
27c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
28c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
29c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
30c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
31c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32c18ec02fSPetter Reinholdtsen  */
33c18ec02fSPetter Reinholdtsen 
34c18ec02fSPetter Reinholdtsen #include <stdlib.h>
35c18ec02fSPetter Reinholdtsen #include <string.h>
36c18ec02fSPetter Reinholdtsen #include <stdio.h>
37c18ec02fSPetter Reinholdtsen #include <time.h>
38c18ec02fSPetter Reinholdtsen 
39c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
40c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
41c18ec02fSPetter Reinholdtsen #include <ipmitool/bswap.h>
42c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
43c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
44c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_firewall.h>
45c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h>
46c18ec02fSPetter Reinholdtsen 
47c18ec02fSPetter Reinholdtsen static void
printf_firewall_usage(void)48c18ec02fSPetter Reinholdtsen printf_firewall_usage(void)
49c18ec02fSPetter Reinholdtsen {
50c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
51c18ec02fSPetter Reinholdtsen "Firmware Firewall Commands:");
52c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
53c18ec02fSPetter Reinholdtsen "\tinfo [channel H] [lun L]");
54c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
55c18ec02fSPetter Reinholdtsen "\tinfo [channel H] [lun L [netfn N [command C [subfn S]]]]");
56c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
57c18ec02fSPetter Reinholdtsen "\tenable [channel H] [lun L [netfn N [command C [subfn S]]]]");
58c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
59c18ec02fSPetter Reinholdtsen "\tdisable [channel H] [lun L [netfn N [command C [subfn S]]]] [force])");
60c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
61c18ec02fSPetter Reinholdtsen "\treset [channel H]");
62c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
63c18ec02fSPetter Reinholdtsen "\t\twhere H is a Channel, L is a LUN, N is a NetFn,");
64c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
65c18ec02fSPetter Reinholdtsen "\t\tC is a Command and S is a Sub-Function");
66c18ec02fSPetter Reinholdtsen }
67c18ec02fSPetter Reinholdtsen 
68c18ec02fSPetter Reinholdtsen void
printf_firewall_info_usage(void)69c18ec02fSPetter Reinholdtsen printf_firewall_info_usage(void)
70c18ec02fSPetter Reinholdtsen {
71c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
72c18ec02fSPetter Reinholdtsen "info [channel H]");
73c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
74c18ec02fSPetter Reinholdtsen "\tList all of the firewall information for all LUNs, NetFns");
75c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
76c18ec02fSPetter Reinholdtsen "\tand Commands, This is a long list and is not very human readable.");
77c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
78c18ec02fSPetter Reinholdtsen "info [channel H] lun L");
79c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
80c18ec02fSPetter Reinholdtsen "\tThis also prints a long list that is not very human readable.");
81c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
82c18ec02fSPetter Reinholdtsen "info [channel H] lun L netfn N");
83c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
84c18ec02fSPetter Reinholdtsen "\tThis prints out information for a single LUN/NetFn pair.");
85c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
86c18ec02fSPetter Reinholdtsen "\tThat is not really very usable, but at least it is short.");
87c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
88c18ec02fSPetter Reinholdtsen "info [channel H] lun L netfn N command C");
89c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
90c18ec02fSPetter Reinholdtsen "\tThis is the one you want -- it prints out detailed human");
91c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
92c18ec02fSPetter Reinholdtsen "\treadable information.  It shows the support, configurable, and");
93c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
94c18ec02fSPetter Reinholdtsen "\tenabled bits for the Command C on LUN/NetFn pair L,N and the");
95c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
96c18ec02fSPetter Reinholdtsen "\tsame information about each of its Sub-functions.");
97c18ec02fSPetter Reinholdtsen }
98c18ec02fSPetter Reinholdtsen 
99c18ec02fSPetter Reinholdtsen // print n bytes of bit field bf (if invert, print ~bf)
print_bitfield(const unsigned char * bf,int n,int invert,int loglevel)100c18ec02fSPetter Reinholdtsen static void print_bitfield(const unsigned char * bf, int n, int invert, int loglevel) {
101c18ec02fSPetter Reinholdtsen 	int i = 0;
102c18ec02fSPetter Reinholdtsen 	if (loglevel < 0) {
103c18ec02fSPetter Reinholdtsen 		while (i<n) {
104c18ec02fSPetter Reinholdtsen 			printf("%02x", (unsigned char) (invert?~bf[i]:bf[i]));
105c18ec02fSPetter Reinholdtsen 			if (++i % 4 == 0)
106c18ec02fSPetter Reinholdtsen 				printf(" ");
107c18ec02fSPetter Reinholdtsen 		}
108c18ec02fSPetter Reinholdtsen 		printf("\n");
109c18ec02fSPetter Reinholdtsen 	} else {
110c18ec02fSPetter Reinholdtsen 		while (i<n) {
111c18ec02fSPetter Reinholdtsen 			lprintf(loglevel, "%02x", (unsigned char) (invert?~bf[i]:bf[i]));
112c18ec02fSPetter Reinholdtsen 			if (++i % 4 == 0)
113c18ec02fSPetter Reinholdtsen 				lprintf(loglevel, " ");
114c18ec02fSPetter Reinholdtsen 		}
115c18ec02fSPetter Reinholdtsen 		lprintf(loglevel, "\n");
116c18ec02fSPetter Reinholdtsen 	}
117c18ec02fSPetter Reinholdtsen 
118c18ec02fSPetter Reinholdtsen }
119c18ec02fSPetter Reinholdtsen 
120c18ec02fSPetter Reinholdtsen static int
ipmi_firewall_parse_args(int argc,char ** argv,struct ipmi_function_params * p)121c18ec02fSPetter Reinholdtsen ipmi_firewall_parse_args(int argc, char ** argv, struct ipmi_function_params * p)
122c18ec02fSPetter Reinholdtsen {
123c18ec02fSPetter Reinholdtsen 	int i;
124c18ec02fSPetter Reinholdtsen 	uint8_t conv_err = 0;
125c18ec02fSPetter Reinholdtsen 
126c18ec02fSPetter Reinholdtsen 	if (!p) {
127c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "ipmi_firewall_parse_args: p is NULL");
128c18ec02fSPetter Reinholdtsen 		return -1;
129c18ec02fSPetter Reinholdtsen 	}
130c18ec02fSPetter Reinholdtsen 	for (i=0; i<argc; i++) {
131c18ec02fSPetter Reinholdtsen 		if (strncmp(argv[i], "channel", 7) == 0 && (++i < argc)) {
132c18ec02fSPetter Reinholdtsen 			uint8_t channel_tmp = 0;
133c18ec02fSPetter Reinholdtsen 			if (is_ipmi_channel_num(argv[i], &channel_tmp) != 0) {
134c18ec02fSPetter Reinholdtsen 				conv_err = 1;
135c18ec02fSPetter Reinholdtsen 				break;
136c18ec02fSPetter Reinholdtsen 			} else {
137c18ec02fSPetter Reinholdtsen 				p->channel = channel_tmp;
138c18ec02fSPetter Reinholdtsen 			}
139c18ec02fSPetter Reinholdtsen 		}
140c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[i], "lun", 3) == 0 && (++i < argc)) {
141c18ec02fSPetter Reinholdtsen 			if (str2int(argv[i], &(p->lun)) != 0) {
142c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Given lun '%s' is invalid.", argv[i]);
143c18ec02fSPetter Reinholdtsen 				conv_err = 1;
144c18ec02fSPetter Reinholdtsen 				break;
145c18ec02fSPetter Reinholdtsen 			}
146c18ec02fSPetter Reinholdtsen 		}
147c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[i], "force", 5) == 0) {
148c18ec02fSPetter Reinholdtsen 			p->force = 1;
149c18ec02fSPetter Reinholdtsen 		}
150c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[i], "netfn", 5) == 0 && (++i < argc)) {
151c18ec02fSPetter Reinholdtsen 			if (str2int(argv[i], &(p->netfn)) != 0) {
152c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Given netfn '%s' is invalid.", argv[i]);
153c18ec02fSPetter Reinholdtsen 				conv_err = 1;
154c18ec02fSPetter Reinholdtsen 				break;
155c18ec02fSPetter Reinholdtsen 			}
156c18ec02fSPetter Reinholdtsen 		}
157c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[i], "command", 7) == 0 && (++i < argc)) {
158c18ec02fSPetter Reinholdtsen 			if (str2int(argv[i], &(p->command)) != 0) {
159c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Given command '%s' is invalid.", argv[i]);
160c18ec02fSPetter Reinholdtsen 				conv_err = 1;
161c18ec02fSPetter Reinholdtsen 				break;
162c18ec02fSPetter Reinholdtsen 			}
163c18ec02fSPetter Reinholdtsen 		}
164c18ec02fSPetter Reinholdtsen 		else if (strncmp(argv[i], "subfn", 5) == 0 && (++i < argc)) {
165c18ec02fSPetter Reinholdtsen 			if (str2int(argv[i], &(p->subfn)) != 0) {
166c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Given subfn '%s' is invalid.", argv[i]);
167c18ec02fSPetter Reinholdtsen 				conv_err = 1;
168c18ec02fSPetter Reinholdtsen 				break;
169c18ec02fSPetter Reinholdtsen 			}
170c18ec02fSPetter Reinholdtsen 		}
171c18ec02fSPetter Reinholdtsen 	}
172c18ec02fSPetter Reinholdtsen 	if (conv_err != 0) {
173c18ec02fSPetter Reinholdtsen 		return (-1);
174c18ec02fSPetter Reinholdtsen 	}
175c18ec02fSPetter Reinholdtsen 	if (p->subfn >= MAX_SUBFN) {
176c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "subfn is out of range (0-%d)", MAX_SUBFN-1);
177c18ec02fSPetter Reinholdtsen 		return -1;
178c18ec02fSPetter Reinholdtsen 	}
179c18ec02fSPetter Reinholdtsen 	if (p->command >= MAX_COMMAND) {
180c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "command is out of range (0-%d)", MAX_COMMAND-1);
181c18ec02fSPetter Reinholdtsen 		return -1;
182c18ec02fSPetter Reinholdtsen 	}
183c18ec02fSPetter Reinholdtsen 	if (p->netfn >= MAX_NETFN) {
184c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "netfn is out of range (0-%d)", MAX_NETFN-1);
185c18ec02fSPetter Reinholdtsen 		return -1;
186c18ec02fSPetter Reinholdtsen 	}
187c18ec02fSPetter Reinholdtsen 	if (p->lun >= MAX_LUN) {
188c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "lun is out of range (0-%d)", MAX_LUN-1);
189c18ec02fSPetter Reinholdtsen 		return -1;
190c18ec02fSPetter Reinholdtsen 	}
191c18ec02fSPetter Reinholdtsen 	if (p->netfn >= 0 && p->lun < 0) {
192c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "if netfn is set, so must be lun");
193c18ec02fSPetter Reinholdtsen 		return -1;
194c18ec02fSPetter Reinholdtsen 	}
195c18ec02fSPetter Reinholdtsen 	if (p->command >= 0 && p->netfn < 0) {
196c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "if command is set, so must be netfn");
197c18ec02fSPetter Reinholdtsen 		return -1;
198c18ec02fSPetter Reinholdtsen 	}
199c18ec02fSPetter Reinholdtsen 	if (p->subfn >= 0 && p->command < 0) {
200c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "if subfn is set, so must be command");
201c18ec02fSPetter Reinholdtsen 		return -1;
202c18ec02fSPetter Reinholdtsen 	}
203c18ec02fSPetter Reinholdtsen 	return 0;
204c18ec02fSPetter Reinholdtsen }
205c18ec02fSPetter Reinholdtsen 
206c18ec02fSPetter Reinholdtsen /* _get_netfn_suport
207c18ec02fSPetter Reinholdtsen  *
208c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
209c18ec02fSPetter Reinholdtsen  * @channel:	ipmi channel
210c18ec02fSPetter Reinholdtsen  * @lun:	a pointer to a 4 byte field
211c18ec02fSPetter Reinholdtsen  * @netfn:	a pointer to a 128-bit bitfield (16 bytes)
212c18ec02fSPetter Reinholdtsen  *
213c18ec02fSPetter Reinholdtsen  * returns 0 on success and fills in the bitfield for
214c18ec02fSPetter Reinholdtsen  * the 32 netfn * 4 LUN pairs that support commands
215c18ec02fSPetter Reinholdtsen  * returns -1 on error
216c18ec02fSPetter Reinholdtsen  */
217c18ec02fSPetter Reinholdtsen static int
_get_netfn_support(struct ipmi_intf * intf,int channel,unsigned char * lun,unsigned char * netfn)218c18ec02fSPetter Reinholdtsen _get_netfn_support(struct ipmi_intf * intf, int channel, unsigned char * lun, unsigned char * netfn)
219c18ec02fSPetter Reinholdtsen {
220c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
221c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
222c18ec02fSPetter Reinholdtsen 	unsigned char * d, rqdata;
223c18ec02fSPetter Reinholdtsen 	unsigned int l;
224c18ec02fSPetter Reinholdtsen 
225c18ec02fSPetter Reinholdtsen 	if (!lun || !netfn) {
226c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_get_netfn_suport: lun or netfn is NULL");
227c18ec02fSPetter Reinholdtsen 		return -1;
228c18ec02fSPetter Reinholdtsen 	}
229c18ec02fSPetter Reinholdtsen 
230c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
231c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
232c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_NETFN_SUPPORT;
233c18ec02fSPetter Reinholdtsen 	rqdata = (unsigned char) channel;
234c18ec02fSPetter Reinholdtsen 	req.msg.data = &rqdata;
235c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 1;
236c18ec02fSPetter Reinholdtsen 
237c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
238c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
239c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get NetFn Support command failed");
240c18ec02fSPetter Reinholdtsen 		return -1;
241c18ec02fSPetter Reinholdtsen 	}
242c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
243c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get NetFn Support command failed: %s",
244c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
245c18ec02fSPetter Reinholdtsen 		return -1;
246c18ec02fSPetter Reinholdtsen 	}
247c18ec02fSPetter Reinholdtsen 
248c18ec02fSPetter Reinholdtsen 	d = rsp->data;
249c18ec02fSPetter Reinholdtsen 	for (l=0; l<4; l++) {
250c18ec02fSPetter Reinholdtsen 		lun[l] = (*d)>>(2*l) & 0x3;
251c18ec02fSPetter Reinholdtsen 	}
252c18ec02fSPetter Reinholdtsen 	d++;
253c18ec02fSPetter Reinholdtsen 
254c18ec02fSPetter Reinholdtsen 	memcpy(netfn, d, 16);
255c18ec02fSPetter Reinholdtsen 
256c18ec02fSPetter Reinholdtsen 	return 0;
257c18ec02fSPetter Reinholdtsen }
258c18ec02fSPetter Reinholdtsen 
259c18ec02fSPetter Reinholdtsen /* _get_command_suport
260c18ec02fSPetter Reinholdtsen  *
261c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
262c18ec02fSPetter Reinholdtsen  * @p:		a pointer to a struct ipmi_function_params
263c18ec02fSPetter Reinholdtsen  * @lnfn:	a pointer to a struct lun_netfn_support
264c18ec02fSPetter Reinholdtsen  *
265c18ec02fSPetter Reinholdtsen  * returns 0 on success and fills in lnfn according to the request in p
266c18ec02fSPetter Reinholdtsen  * returns -1 on error
267c18ec02fSPetter Reinholdtsen  */
268c18ec02fSPetter Reinholdtsen static int
_get_command_support(struct ipmi_intf * intf,struct ipmi_function_params * p,struct lun_netfn_support * lnfn)269c18ec02fSPetter Reinholdtsen _get_command_support(struct ipmi_intf * intf,
270c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params * p, struct lun_netfn_support * lnfn)
271c18ec02fSPetter Reinholdtsen {
272c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
273c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
274c18ec02fSPetter Reinholdtsen 	unsigned char * d, rqdata[3];
275c18ec02fSPetter Reinholdtsen 	unsigned int c;
276c18ec02fSPetter Reinholdtsen 
277c18ec02fSPetter Reinholdtsen 	if (!p || !lnfn) {
278c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_get_netfn_suport: p or lnfn is NULL");
279c18ec02fSPetter Reinholdtsen 		return -1;
280c18ec02fSPetter Reinholdtsen 	}
281c18ec02fSPetter Reinholdtsen 
282c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
283c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
284c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_COMMAND_SUPPORT;
285c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
286c18ec02fSPetter Reinholdtsen 	rqdata[1] = p->netfn;
287c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
288c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
289c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 3;
290c18ec02fSPetter Reinholdtsen 
291c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
292c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
293c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Support (LUN=%d, NetFn=%d, op=0) command failed", p->lun, p->netfn);
294c18ec02fSPetter Reinholdtsen 		return -1;
295c18ec02fSPetter Reinholdtsen 	}
296c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
297c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Support (LUN=%d, NetFn=%d, op=0) command failed: %s",
298c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals));
299c18ec02fSPetter Reinholdtsen 		return -1;
300c18ec02fSPetter Reinholdtsen 	}
301c18ec02fSPetter Reinholdtsen 
302c18ec02fSPetter Reinholdtsen 	d = rsp->data;
303c18ec02fSPetter Reinholdtsen 	for (c=0; c<128; c++) {
304c18ec02fSPetter Reinholdtsen 		if (!(d[c>>3] & (1<<(c%8))))
305c18ec02fSPetter Reinholdtsen 			lnfn->command[c].support |= BIT_AVAILABLE;
306c18ec02fSPetter Reinholdtsen 	}
307c18ec02fSPetter Reinholdtsen 	memcpy(lnfn->command_mask, d, MAX_COMMAND_BYTES/2);
308c18ec02fSPetter Reinholdtsen 
309c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
310c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
311c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_COMMAND_SUPPORT;
312c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
313c18ec02fSPetter Reinholdtsen 	rqdata[1] = 0x40 | p->netfn;
314c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
315c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
316c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 3;
317c18ec02fSPetter Reinholdtsen 
318c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
319c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
320c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Support (LUN=%d, NetFn=%d, op=1) command failed", p->lun, p->netfn);
321c18ec02fSPetter Reinholdtsen 		return -1;
322c18ec02fSPetter Reinholdtsen 	}
323c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
324c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Support (LUN=%d, NetFn=%d, op=1) command failed: %s",
325c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals));
326c18ec02fSPetter Reinholdtsen 		return -1;
327c18ec02fSPetter Reinholdtsen 	}
328c18ec02fSPetter Reinholdtsen 
329c18ec02fSPetter Reinholdtsen 	d = rsp->data;
330c18ec02fSPetter Reinholdtsen 	for (c=0; c<128; c++) {
331c18ec02fSPetter Reinholdtsen 		if (!(d[c>>3] & (1<<(c%8))))
332c18ec02fSPetter Reinholdtsen 			lnfn->command[128+c].support |= BIT_AVAILABLE;
333c18ec02fSPetter Reinholdtsen 	}
334c18ec02fSPetter Reinholdtsen 	memcpy(lnfn->command_mask+MAX_COMMAND_BYTES/2, d, MAX_COMMAND_BYTES/2);
335c18ec02fSPetter Reinholdtsen 	return 0;
336c18ec02fSPetter Reinholdtsen }
337c18ec02fSPetter Reinholdtsen 
338c18ec02fSPetter Reinholdtsen /* _get_command_configurable
339c18ec02fSPetter Reinholdtsen  *
340c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
341c18ec02fSPetter Reinholdtsen  * @p:		a pointer to a struct ipmi_function_params
342c18ec02fSPetter Reinholdtsen  * @lnfn:	a pointer to a struct lun_netfn_support
343c18ec02fSPetter Reinholdtsen  *
344c18ec02fSPetter Reinholdtsen  * returns 0 on success and fills in lnfn according to the request in p
345c18ec02fSPetter Reinholdtsen  * returns -1 on error
346c18ec02fSPetter Reinholdtsen  */
347c18ec02fSPetter Reinholdtsen static int
_get_command_configurable(struct ipmi_intf * intf,struct ipmi_function_params * p,struct lun_netfn_support * lnfn)348c18ec02fSPetter Reinholdtsen _get_command_configurable(struct ipmi_intf * intf,
349c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params * p, struct lun_netfn_support * lnfn)
350c18ec02fSPetter Reinholdtsen {
351c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
352c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
353c18ec02fSPetter Reinholdtsen 	unsigned char * d, rqdata[3];
354c18ec02fSPetter Reinholdtsen 	unsigned int c;
355c18ec02fSPetter Reinholdtsen 
356c18ec02fSPetter Reinholdtsen 	if (!p || !lnfn) {
357c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_get_command_configurable: p or lnfn is NULL");
358c18ec02fSPetter Reinholdtsen 		return -1;
359c18ec02fSPetter Reinholdtsen 	}
360c18ec02fSPetter Reinholdtsen 
361c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
362c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
363c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_CONFIGURABLE_COMMANDS;
364c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
365c18ec02fSPetter Reinholdtsen 	rqdata[1] = p->netfn;
366c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
367c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
368c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 3;
369c18ec02fSPetter Reinholdtsen 
370c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
371c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
372c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Configurable Command (LUN=%d, NetFn=%d, op=0) command failed", p->lun, p->netfn);
373c18ec02fSPetter Reinholdtsen 		return -1;
374c18ec02fSPetter Reinholdtsen 	}
375c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
376c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Configurable Command (LUN=%d, NetFn=%d, op=0) command failed: %s",
377c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals));
378c18ec02fSPetter Reinholdtsen 		return -1;
379c18ec02fSPetter Reinholdtsen 	}
380c18ec02fSPetter Reinholdtsen 
381c18ec02fSPetter Reinholdtsen 	d = rsp->data;
382c18ec02fSPetter Reinholdtsen 	for (c=0; c<128; c++) {
383c18ec02fSPetter Reinholdtsen 		if (d[c>>3] & (1<<(c%8)))
384c18ec02fSPetter Reinholdtsen 			lnfn->command[c].support |= BIT_CONFIGURABLE;
385c18ec02fSPetter Reinholdtsen 	}
386c18ec02fSPetter Reinholdtsen 	memcpy(lnfn->config_mask, d, MAX_COMMAND_BYTES/2);
387c18ec02fSPetter Reinholdtsen 
388c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
389c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
390c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_CONFIGURABLE_COMMANDS;
391c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
392c18ec02fSPetter Reinholdtsen 	rqdata[1] = 0x40 | p->netfn;
393c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
394c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
395c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 3;
396c18ec02fSPetter Reinholdtsen 
397c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
398c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
399c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Configurable Command (LUN=%d, NetFn=%d, op=1) command failed", p->lun, p->netfn);
400c18ec02fSPetter Reinholdtsen 		return -1;
401c18ec02fSPetter Reinholdtsen 	}
402c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
403c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Configurable Command (LUN=%d, NetFn=%d, op=1) command failed: %s",
404c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals));
405c18ec02fSPetter Reinholdtsen 		return -1;
406c18ec02fSPetter Reinholdtsen 	}
407c18ec02fSPetter Reinholdtsen 
408c18ec02fSPetter Reinholdtsen 	d = rsp->data;
409c18ec02fSPetter Reinholdtsen 	for (c=0; c<128; c++) {
410c18ec02fSPetter Reinholdtsen 		if (d[c>>3] & (1<<(c%8)))
411c18ec02fSPetter Reinholdtsen 			lnfn->command[128+c].support |= BIT_CONFIGURABLE;
412c18ec02fSPetter Reinholdtsen 	}
413c18ec02fSPetter Reinholdtsen 	memcpy(lnfn->config_mask+MAX_COMMAND_BYTES/2, d, MAX_COMMAND_BYTES/2);
414c18ec02fSPetter Reinholdtsen 	return 0;
415c18ec02fSPetter Reinholdtsen }
416c18ec02fSPetter Reinholdtsen 
417c18ec02fSPetter Reinholdtsen /* _get_command_enables
418c18ec02fSPetter Reinholdtsen  *
419c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
420c18ec02fSPetter Reinholdtsen  * @p:		a pointer to a struct ipmi_function_params
421c18ec02fSPetter Reinholdtsen  * @lnfn:	a pointer to a struct lun_netfn_support
422c18ec02fSPetter Reinholdtsen  *
423c18ec02fSPetter Reinholdtsen  * returns 0 on success and fills in lnfn according to the request in p
424c18ec02fSPetter Reinholdtsen  * returns -1 on error
425c18ec02fSPetter Reinholdtsen  */
426c18ec02fSPetter Reinholdtsen static int
_get_command_enables(struct ipmi_intf * intf,struct ipmi_function_params * p,struct lun_netfn_support * lnfn)427c18ec02fSPetter Reinholdtsen _get_command_enables(struct ipmi_intf * intf,
428c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params * p, struct lun_netfn_support * lnfn)
429c18ec02fSPetter Reinholdtsen {
430c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
431c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
432c18ec02fSPetter Reinholdtsen 	unsigned char * d, rqdata[3];
433c18ec02fSPetter Reinholdtsen 	unsigned int c;
434c18ec02fSPetter Reinholdtsen 
435c18ec02fSPetter Reinholdtsen 	if (!p || !lnfn) {
436c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_get_command_enables: p or lnfn is NULL");
437c18ec02fSPetter Reinholdtsen 		return -1;
438c18ec02fSPetter Reinholdtsen 	}
439c18ec02fSPetter Reinholdtsen 
440c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
441c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
442c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_COMMAND_ENABLES;
443c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
444c18ec02fSPetter Reinholdtsen 	rqdata[1] = p->netfn;
445c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
446c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
447c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 3;
448c18ec02fSPetter Reinholdtsen 
449c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
450c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
451c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Enables (LUN=%d, NetFn=%d, op=0) command failed", p->lun, p->netfn);
452c18ec02fSPetter Reinholdtsen 		return -1;
453c18ec02fSPetter Reinholdtsen 	}
454c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
455c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Enables (LUN=%d, NetFn=%d, op=0) command failed: %s",
456c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals));
457c18ec02fSPetter Reinholdtsen 		return -1;
458c18ec02fSPetter Reinholdtsen 	}
459c18ec02fSPetter Reinholdtsen 
460c18ec02fSPetter Reinholdtsen 	d = rsp->data;
461c18ec02fSPetter Reinholdtsen 	for (c=0; c<128; c++) {
462c18ec02fSPetter Reinholdtsen 		if (d[c>>3] & (1<<(c%8)))
463c18ec02fSPetter Reinholdtsen 			lnfn->command[c].support |= BIT_ENABLED;
464c18ec02fSPetter Reinholdtsen 	}
465c18ec02fSPetter Reinholdtsen 	memcpy(lnfn->enable_mask, d, MAX_COMMAND_BYTES/2);
466c18ec02fSPetter Reinholdtsen 
467c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
468c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
469c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_COMMAND_ENABLES;
470c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
471c18ec02fSPetter Reinholdtsen 	rqdata[1] = 0x40 | p->netfn;
472c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
473c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
474c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 3;
475c18ec02fSPetter Reinholdtsen 
476c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
477c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
478c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Enables (LUN=%d, NetFn=%d, op=1) command failed", p->lun, p->netfn);
479c18ec02fSPetter Reinholdtsen 		return -1;
480c18ec02fSPetter Reinholdtsen 	}
481c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
482c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Enables (LUN=%d, NetFn=%d, op=1) command failed: %s",
483c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals));
484c18ec02fSPetter Reinholdtsen 		return -1;
485c18ec02fSPetter Reinholdtsen 	}
486c18ec02fSPetter Reinholdtsen 
487c18ec02fSPetter Reinholdtsen 	d = rsp->data;
488c18ec02fSPetter Reinholdtsen 	for (c=0; c<128; c++) {
489c18ec02fSPetter Reinholdtsen 		if (d[c>>3] & (1<<(c%8)))
490c18ec02fSPetter Reinholdtsen 			lnfn->command[128+c].support |= BIT_ENABLED;
491c18ec02fSPetter Reinholdtsen 	}
492c18ec02fSPetter Reinholdtsen 	memcpy(lnfn->enable_mask+MAX_COMMAND_BYTES/2, d, MAX_COMMAND_BYTES/2);
493c18ec02fSPetter Reinholdtsen 	return 0;
494c18ec02fSPetter Reinholdtsen }
495c18ec02fSPetter Reinholdtsen 
496c18ec02fSPetter Reinholdtsen /* _set_command_enables
497c18ec02fSPetter Reinholdtsen  *
498c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
499c18ec02fSPetter Reinholdtsen  * @p:		a pointer to a struct ipmi_function_params
500c18ec02fSPetter Reinholdtsen  * @lnfn:	a pointer to a struct lun_netfn_support that contains current info
501c18ec02fSPetter Reinholdtsen  * @enable:	a pointer to a 32 byte bitfield that contains the desired enable state
502c18ec02fSPetter Reinholdtsen  * @gun:	here is a gun to shoot yourself in the foot.  If this is true
503c18ec02fSPetter Reinholdtsen  * 		you are allowed to disable this command
504c18ec02fSPetter Reinholdtsen  *
505c18ec02fSPetter Reinholdtsen  * returns 0 on success
506c18ec02fSPetter Reinholdtsen  * returns -1 on error
507c18ec02fSPetter Reinholdtsen  */
508c18ec02fSPetter Reinholdtsen static int
_set_command_enables(struct ipmi_intf * intf,struct ipmi_function_params * p,struct lun_netfn_support * lnfn,unsigned char * enable,int gun)509c18ec02fSPetter Reinholdtsen _set_command_enables(struct ipmi_intf * intf,
510c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params * p, struct lun_netfn_support * lnfn,
511c18ec02fSPetter Reinholdtsen 	unsigned char * enable, int gun)
512c18ec02fSPetter Reinholdtsen {
513c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
514c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
51503d8aa18SZdenek Styblik 	unsigned char rqdata[19];
516c18ec02fSPetter Reinholdtsen 	unsigned int c;
517c18ec02fSPetter Reinholdtsen 
518c18ec02fSPetter Reinholdtsen 	if (!p || !lnfn) {
519c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_set_command_enables: p or lnfn is NULL");
520c18ec02fSPetter Reinholdtsen 		return -1;
521c18ec02fSPetter Reinholdtsen 	}
522c18ec02fSPetter Reinholdtsen 
523c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "support:            ");
524c18ec02fSPetter Reinholdtsen 	print_bitfield(lnfn->command_mask, MAX_COMMAND_BYTES, 1, LOG_INFO);
525c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "configurable:       ");
526c18ec02fSPetter Reinholdtsen 	print_bitfield(lnfn->config_mask, MAX_COMMAND_BYTES, 0, LOG_INFO);
527c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "enabled:            ");
528c18ec02fSPetter Reinholdtsen 	print_bitfield(lnfn->enable_mask, MAX_COMMAND_BYTES, 0, LOG_INFO);
529c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "enable mask before: ");
530c18ec02fSPetter Reinholdtsen 	print_bitfield(enable, MAX_COMMAND_BYTES, 0, LOG_INFO);
531c18ec02fSPetter Reinholdtsen 
532c18ec02fSPetter Reinholdtsen 	// mask off the appropriate bits (if not configurable, set enable bit
533c18ec02fSPetter Reinholdtsen 	// must be the same as the current enable bit)
534c18ec02fSPetter Reinholdtsen 	for (c=0; c<(MAX_COMMAND_BYTES); c++) {
535c18ec02fSPetter Reinholdtsen 		enable[c] = (lnfn->config_mask[c] & enable[c]) |
536c18ec02fSPetter Reinholdtsen 			(~lnfn->config_mask[c] & lnfn->enable_mask[c]);
537c18ec02fSPetter Reinholdtsen 	}
538c18ec02fSPetter Reinholdtsen 
539c18ec02fSPetter Reinholdtsen 	// take the gun out of their hand if they are not supposed to have it
540c18ec02fSPetter Reinholdtsen 	if (!gun) {
541c18ec02fSPetter Reinholdtsen 		enable[SET_COMMAND_ENABLE_BYTE] =
542c18ec02fSPetter Reinholdtsen 			(lnfn->config_mask[SET_COMMAND_ENABLE_BYTE]
543c18ec02fSPetter Reinholdtsen 			 & SET_COMMAND_ENABLE_BIT) |
544c18ec02fSPetter Reinholdtsen 			(~lnfn->config_mask[SET_COMMAND_ENABLE_BYTE]
545c18ec02fSPetter Reinholdtsen 			 & lnfn->enable_mask[SET_COMMAND_ENABLE_BYTE]);
546c18ec02fSPetter Reinholdtsen 	}
547c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "enable mask after: ");
548c18ec02fSPetter Reinholdtsen 	print_bitfield(enable, MAX_COMMAND_BYTES, 0, LOG_INFO);
549c18ec02fSPetter Reinholdtsen 
550c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
551c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
552c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_SET_COMMAND_ENABLES;
553c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
554c18ec02fSPetter Reinholdtsen 	rqdata[1] = p->netfn;
555c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
556c18ec02fSPetter Reinholdtsen 	memcpy(&rqdata[3], enable, MAX_COMMAND_BYTES/2);
557c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
558c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 19;
559c18ec02fSPetter Reinholdtsen 
560c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
561c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
562c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Set Command Enables (LUN=%d, NetFn=%d, op=0) command failed", p->lun, p->netfn);
563c18ec02fSPetter Reinholdtsen 		return -1;
564c18ec02fSPetter Reinholdtsen 	}
565c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
566c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Set Command Enables (LUN=%d, NetFn=%d, op=0) command failed: %s",
567c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals));
568c18ec02fSPetter Reinholdtsen 		return -1;
569c18ec02fSPetter Reinholdtsen 	}
570c18ec02fSPetter Reinholdtsen 
571c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
572c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
573c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_SET_COMMAND_ENABLES;
574c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
575c18ec02fSPetter Reinholdtsen 	rqdata[1] = 0x40 | p->netfn;
576c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
577c18ec02fSPetter Reinholdtsen 	memcpy(&rqdata[3], enable+MAX_COMMAND_BYTES/2, MAX_COMMAND_BYTES/2);
578c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
579c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 19;
580c18ec02fSPetter Reinholdtsen 
581c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
582c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
583c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Set Command Enables (LUN=%d, NetFn=%d, op=1) command failed", p->lun, p->netfn);
584c18ec02fSPetter Reinholdtsen 		return -1;
585c18ec02fSPetter Reinholdtsen 	}
586c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
587c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Set Command Enables (LUN=%d, NetFn=%d, op=1) command failed: %s",
588c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, val2str(rsp->ccode, completion_code_vals));
589c18ec02fSPetter Reinholdtsen 		return -1;
590c18ec02fSPetter Reinholdtsen 	}
591c18ec02fSPetter Reinholdtsen 
592c18ec02fSPetter Reinholdtsen 	return 0;
593c18ec02fSPetter Reinholdtsen }
594c18ec02fSPetter Reinholdtsen 
595c18ec02fSPetter Reinholdtsen /* _get_subfn_support
596c18ec02fSPetter Reinholdtsen  *
597c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
598c18ec02fSPetter Reinholdtsen  * @p:		a pointer to a struct ipmi_function_params
599c18ec02fSPetter Reinholdtsen  * @cmd:	a pointer to a struct command_support
600c18ec02fSPetter Reinholdtsen  *
601c18ec02fSPetter Reinholdtsen  * returns 0 on success and fills in cmd according to the request in p
602c18ec02fSPetter Reinholdtsen  * returns -1 on error
603c18ec02fSPetter Reinholdtsen  */
604c18ec02fSPetter Reinholdtsen static int
_get_subfn_support(struct ipmi_intf * intf,struct ipmi_function_params * p,struct command_support * cmd)605c18ec02fSPetter Reinholdtsen _get_subfn_support(struct ipmi_intf * intf,
606c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params * p, struct command_support * cmd)
607c18ec02fSPetter Reinholdtsen {
608c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
609c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
610c18ec02fSPetter Reinholdtsen 	unsigned char rqdata[4];
611c18ec02fSPetter Reinholdtsen 
612c18ec02fSPetter Reinholdtsen 	if (!p || !cmd) {
613c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_get_subfn_support: p or cmd is NULL");
614c18ec02fSPetter Reinholdtsen 		return -1;
615c18ec02fSPetter Reinholdtsen 	}
616c18ec02fSPetter Reinholdtsen 
617c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
618c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
619c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_COMMAND_SUBFUNCTION_SUPPORT;
620c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
621c18ec02fSPetter Reinholdtsen 	rqdata[1] = p->netfn;
622c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
623c18ec02fSPetter Reinholdtsen 	rqdata[3] = p->command;
624c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
625c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 4;
626c18ec02fSPetter Reinholdtsen 
627c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
628c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
629c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Sub-function Support (LUN=%d, NetFn=%d, command=%d) command failed", p->lun, p->netfn, p->command);
630c18ec02fSPetter Reinholdtsen 		return -1;
631c18ec02fSPetter Reinholdtsen 	}
632c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
633c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Sub-function Support (LUN=%d, NetFn=%d, command=%d) command failed: %s",
634c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, p->command, val2str(rsp->ccode, completion_code_vals));
635c18ec02fSPetter Reinholdtsen 		return -1;
636c18ec02fSPetter Reinholdtsen 	}
637c18ec02fSPetter Reinholdtsen 
638c18ec02fSPetter Reinholdtsen 	memcpy(cmd->subfn_support, rsp->data, sizeof(cmd->subfn_support));
639c18ec02fSPetter Reinholdtsen 	return 0;
640c18ec02fSPetter Reinholdtsen }
641c18ec02fSPetter Reinholdtsen 
642c18ec02fSPetter Reinholdtsen /* _get_subfn_configurable
643c18ec02fSPetter Reinholdtsen  *
644c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
645c18ec02fSPetter Reinholdtsen  * @p:		a pointer to a struct ipmi_function_params
646c18ec02fSPetter Reinholdtsen  * @cmd:	a pointer to a struct command_support
647c18ec02fSPetter Reinholdtsen  *
648c18ec02fSPetter Reinholdtsen  * returns 0 on success and fills in cmd according to the request in p
649c18ec02fSPetter Reinholdtsen  * returns -1 on error
650c18ec02fSPetter Reinholdtsen  */
651c18ec02fSPetter Reinholdtsen static int
_get_subfn_configurable(struct ipmi_intf * intf,struct ipmi_function_params * p,struct command_support * cmd)652c18ec02fSPetter Reinholdtsen _get_subfn_configurable(struct ipmi_intf * intf,
653c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params * p, struct command_support * cmd)
654c18ec02fSPetter Reinholdtsen {
655c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
656c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
657c18ec02fSPetter Reinholdtsen 	unsigned char rqdata[4];
658c18ec02fSPetter Reinholdtsen 
659c18ec02fSPetter Reinholdtsen 	if (!p || !cmd) {
660c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_get_subfn_configurable: p or cmd is NULL");
661c18ec02fSPetter Reinholdtsen 		return -1;
662c18ec02fSPetter Reinholdtsen 	}
663c18ec02fSPetter Reinholdtsen 
664c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
665c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
666c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_CONFIGURABLE_COMMAND_SUBFUNCTIONS;
667c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
668c18ec02fSPetter Reinholdtsen 	rqdata[1] = p->netfn;
669c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
670c18ec02fSPetter Reinholdtsen 	rqdata[3] = p->command;
671c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
672c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 4;
673c18ec02fSPetter Reinholdtsen 
674c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
675c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
676c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Configurable Command Sub-function (LUN=%d, NetFn=%d, command=%d) command failed", p->lun, p->netfn, p->command);
677c18ec02fSPetter Reinholdtsen 		return -1;
678c18ec02fSPetter Reinholdtsen 	}
679c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
680c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Configurable Command Sub-function (LUN=%d, NetFn=%d, command=%d) command failed: %s",
681c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, p->command, val2str(rsp->ccode, completion_code_vals));
682c18ec02fSPetter Reinholdtsen 		return -1;
683c18ec02fSPetter Reinholdtsen 	}
684c18ec02fSPetter Reinholdtsen 
685c18ec02fSPetter Reinholdtsen 	memcpy(cmd->subfn_config, rsp->data, sizeof(cmd->subfn_config));
686c18ec02fSPetter Reinholdtsen 	return 0;
687c18ec02fSPetter Reinholdtsen }
688c18ec02fSPetter Reinholdtsen 
689c18ec02fSPetter Reinholdtsen /* _get_subfn_enables
690c18ec02fSPetter Reinholdtsen  *
691c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
692c18ec02fSPetter Reinholdtsen  * @p:		a pointer to a struct ipmi_function_params
693c18ec02fSPetter Reinholdtsen  * @cmd:	a pointer to a struct command_support
694c18ec02fSPetter Reinholdtsen  *
695c18ec02fSPetter Reinholdtsen  * returns 0 on success and fills in cmd according to the request in p
696c18ec02fSPetter Reinholdtsen  * returns -1 on error
697c18ec02fSPetter Reinholdtsen  */
698c18ec02fSPetter Reinholdtsen static int
_get_subfn_enables(struct ipmi_intf * intf,struct ipmi_function_params * p,struct command_support * cmd)699c18ec02fSPetter Reinholdtsen _get_subfn_enables(struct ipmi_intf * intf,
700c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params * p, struct command_support * cmd)
701c18ec02fSPetter Reinholdtsen {
702c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
703c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
704c18ec02fSPetter Reinholdtsen 	unsigned char rqdata[4];
705c18ec02fSPetter Reinholdtsen 
706c18ec02fSPetter Reinholdtsen 	if (!p || !cmd) {
707c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_get_subfn_enables: p or cmd is NULL");
708c18ec02fSPetter Reinholdtsen 		return -1;
709c18ec02fSPetter Reinholdtsen 	}
710c18ec02fSPetter Reinholdtsen 
711c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
712c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
713c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_GET_COMMAND_SUBFUNCTION_ENABLES;
714c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
715c18ec02fSPetter Reinholdtsen 	rqdata[1] = p->netfn;
716c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
717c18ec02fSPetter Reinholdtsen 	rqdata[3] = p->command;
718c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
719c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 4;
720c18ec02fSPetter Reinholdtsen 
721c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
722c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
723c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Sub-function Enables (LUN=%d, NetFn=%d, command=%d) command failed", p->lun, p->netfn, p->command);
724c18ec02fSPetter Reinholdtsen 		return -1;
725c18ec02fSPetter Reinholdtsen 	}
726c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
727c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Get Command Sub-function Enables (LUN=%d, NetFn=%d, command=%d) command failed: %s",
728c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, p->command, val2str(rsp->ccode, completion_code_vals));
729c18ec02fSPetter Reinholdtsen 		return -1;
730c18ec02fSPetter Reinholdtsen 	}
731c18ec02fSPetter Reinholdtsen 
732c18ec02fSPetter Reinholdtsen 	memcpy(cmd->subfn_enable, rsp->data, sizeof(cmd->subfn_enable));
733c18ec02fSPetter Reinholdtsen 	return 0;
734c18ec02fSPetter Reinholdtsen }
735c18ec02fSPetter Reinholdtsen 
736c18ec02fSPetter Reinholdtsen /* _set_subfn_enables
737c18ec02fSPetter Reinholdtsen  *
738c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
739c18ec02fSPetter Reinholdtsen  * @p:  	a pointer to a struct ipmi_function_params
740c18ec02fSPetter Reinholdtsen  * @cmd:	a pointer to a struct command_support
741c18ec02fSPetter Reinholdtsen  * @enable:	a pointer to a 4 byte bitfield that contains the desired enable state
742c18ec02fSPetter Reinholdtsen  *
743c18ec02fSPetter Reinholdtsen  * returns 0 on success (and modifies enable to be the bits it actually set)
744c18ec02fSPetter Reinholdtsen  * returns -1 on error
745c18ec02fSPetter Reinholdtsen  */
746c18ec02fSPetter Reinholdtsen static int
_set_subfn_enables(struct ipmi_intf * intf,struct ipmi_function_params * p,struct command_support * cmd,unsigned char * enable)747c18ec02fSPetter Reinholdtsen _set_subfn_enables(struct ipmi_intf * intf,
748c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params * p, struct command_support * cmd,
749c18ec02fSPetter Reinholdtsen 	unsigned char * enable)
750c18ec02fSPetter Reinholdtsen {
751c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
752c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
753c18ec02fSPetter Reinholdtsen 	unsigned char rqdata[8];
754c18ec02fSPetter Reinholdtsen 	unsigned int c;
755c18ec02fSPetter Reinholdtsen 
756c18ec02fSPetter Reinholdtsen 	if (!p || !cmd) {
757c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "_set_subfn_enables: p or cmd is NULL");
758c18ec02fSPetter Reinholdtsen 		return -1;
759c18ec02fSPetter Reinholdtsen 	}
760c18ec02fSPetter Reinholdtsen 
761c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "support:            ");
762c18ec02fSPetter Reinholdtsen 	print_bitfield(cmd->subfn_support, MAX_SUBFN_BYTES, 1, LOG_INFO);
763c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "configurable:       ");
764c18ec02fSPetter Reinholdtsen 	print_bitfield(cmd->subfn_config, MAX_SUBFN_BYTES, 0, LOG_INFO);
765c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "enabled:            ");
766c18ec02fSPetter Reinholdtsen 	print_bitfield(cmd->subfn_enable, MAX_SUBFN_BYTES, 0, LOG_INFO);
767c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "enable mask before: ");
768c18ec02fSPetter Reinholdtsen 	print_bitfield(enable, MAX_SUBFN_BYTES, 0, LOG_INFO);
769c18ec02fSPetter Reinholdtsen 	// mask off the appropriate bits (if not configurable, set enable bit
770c18ec02fSPetter Reinholdtsen 	// must be the same as the current enable bit)
771c18ec02fSPetter Reinholdtsen 	for (c=0; c<sizeof(cmd->subfn_enable); c++) {
772c18ec02fSPetter Reinholdtsen 		enable[c] = (cmd->subfn_config[c] & enable[c]) |
773c18ec02fSPetter Reinholdtsen 			(~cmd->subfn_config[c] & cmd->subfn_enable[c]);
774c18ec02fSPetter Reinholdtsen 	}
775c18ec02fSPetter Reinholdtsen 	lprintf(LOG_INFO, "enable mask after: ");
776c18ec02fSPetter Reinholdtsen 	print_bitfield(enable, MAX_SUBFN_BYTES, 0, LOG_INFO);
777c18ec02fSPetter Reinholdtsen 
778c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
779c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
780c18ec02fSPetter Reinholdtsen 	req.msg.cmd = BMC_SET_COMMAND_SUBFUNCTION_ENABLES;
781c18ec02fSPetter Reinholdtsen 	rqdata[0] = (unsigned char) p->channel;
782c18ec02fSPetter Reinholdtsen 	rqdata[1] = p->netfn;
783c18ec02fSPetter Reinholdtsen 	rqdata[2] = p->lun;
784c18ec02fSPetter Reinholdtsen 	rqdata[3] = p->command;
785c18ec02fSPetter Reinholdtsen 	memcpy(&rqdata[4], enable, MAX_SUBFN_BYTES);
786c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
787c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 8;
788c18ec02fSPetter Reinholdtsen 
789c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
790c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
791c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Set Command Sub-function Enables (LUN=%d, NetFn=%d, command=%d) command failed", p->lun, p->netfn, p->command);
792c18ec02fSPetter Reinholdtsen 		return -1;
793c18ec02fSPetter Reinholdtsen 	}
794c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
795c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Set Command Sub-function Enables (LUN=%d, NetFn=%d, command=%d) command failed: %s",
796c18ec02fSPetter Reinholdtsen 			p->lun, p->netfn, p->command, val2str(rsp->ccode, completion_code_vals));
797c18ec02fSPetter Reinholdtsen 		return -1;
798c18ec02fSPetter Reinholdtsen 	}
799c18ec02fSPetter Reinholdtsen 
800c18ec02fSPetter Reinholdtsen 	return 0;
801c18ec02fSPetter Reinholdtsen }
802c18ec02fSPetter Reinholdtsen 
803c18ec02fSPetter Reinholdtsen /* _gather_info
804c18ec02fSPetter Reinholdtsen  *
805c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
806c18ec02fSPetter Reinholdtsen  * @p:		a pointer to a struct ipmi_function_params
807c18ec02fSPetter Reinholdtsen  * @bmc:	a pointer to a struct bmc_fn_support
808c18ec02fSPetter Reinholdtsen  * @enable:	a pointer to a 4 byte bitfield that contains the desired enable state
809c18ec02fSPetter Reinholdtsen  *
810c18ec02fSPetter Reinholdtsen  * returns 0 on success and fills in bmc according to request p
811c18ec02fSPetter Reinholdtsen  * returns -1 on error
812c18ec02fSPetter Reinholdtsen  */
_gather_info(struct ipmi_intf * intf,struct ipmi_function_params * p,struct bmc_fn_support * bmc)813c18ec02fSPetter Reinholdtsen static int _gather_info(struct ipmi_intf * intf, struct ipmi_function_params * p, struct bmc_fn_support * bmc)
814c18ec02fSPetter Reinholdtsen {
815c18ec02fSPetter Reinholdtsen 	int ret, l, n;
816c18ec02fSPetter Reinholdtsen 	unsigned char lun[MAX_LUN], netfn[16];
817c18ec02fSPetter Reinholdtsen 
818c18ec02fSPetter Reinholdtsen 	ret = _get_netfn_support(intf, p->channel, lun, netfn);
819c18ec02fSPetter Reinholdtsen 	if (!ret) {
820c18ec02fSPetter Reinholdtsen 		for (l=0; l<MAX_LUN; l++) {
821c18ec02fSPetter Reinholdtsen 			if (p->lun >= 0 && p->lun != l)
822c18ec02fSPetter Reinholdtsen 				continue;
823c18ec02fSPetter Reinholdtsen 			bmc->lun[l].support = lun[l];
824c18ec02fSPetter Reinholdtsen 			if (lun[l]) {
825c18ec02fSPetter Reinholdtsen 				for (n=0; n<MAX_NETFN_PAIR; n++) {
826c18ec02fSPetter Reinholdtsen 					int offset = l*MAX_NETFN_PAIR+n;
827c18ec02fSPetter Reinholdtsen 					bmc->lun[l].netfn[n].support =
828c18ec02fSPetter Reinholdtsen 						!!(netfn[offset>>3] & (1<<(offset%8)));
829c18ec02fSPetter Reinholdtsen 				}
830c18ec02fSPetter Reinholdtsen 			}
831c18ec02fSPetter Reinholdtsen 		}
832c18ec02fSPetter Reinholdtsen 	}
833c18ec02fSPetter Reinholdtsen 	if (p->netfn >= 0) {
834c18ec02fSPetter Reinholdtsen 		if (!((p->lun < 0 || bmc->lun[p->lun].support) &&
835c18ec02fSPetter Reinholdtsen 		      (p->netfn < 0 || bmc->lun[p->lun].netfn[p->netfn>>1].support))) {
836c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "LUN or LUN/NetFn pair %d,%d not supported", p->lun, p->netfn);
837c18ec02fSPetter Reinholdtsen 			return 0;
838c18ec02fSPetter Reinholdtsen 		}
839c18ec02fSPetter Reinholdtsen 		ret = _get_command_support(intf, p, &(bmc->lun[p->lun].netfn[p->netfn>>1]));
840c18ec02fSPetter Reinholdtsen 		ret |= _get_command_configurable(intf, p, &(bmc->lun[p->lun].netfn[p->netfn>>1]));
841c18ec02fSPetter Reinholdtsen 		ret |= _get_command_enables(intf, p, &(bmc->lun[p->lun].netfn[p->netfn>>1]));
842c18ec02fSPetter Reinholdtsen 		if (!ret && p->command >= 0) {
843c18ec02fSPetter Reinholdtsen 			ret = _get_subfn_support(intf, p,
844c18ec02fSPetter Reinholdtsen 						 &(bmc->lun[p->lun].netfn[p->netfn>>1].command[p->command]));
845c18ec02fSPetter Reinholdtsen 			ret |= _get_subfn_configurable(intf, p,
846c18ec02fSPetter Reinholdtsen 						       &(bmc->lun[p->lun].netfn[p->netfn>>1].command[p->command]));
847c18ec02fSPetter Reinholdtsen 			ret |= _get_subfn_enables(intf, p,
848c18ec02fSPetter Reinholdtsen 						  &(bmc->lun[p->lun].netfn[p->netfn>>1].command[p->command]));
849c18ec02fSPetter Reinholdtsen 		}
850c18ec02fSPetter Reinholdtsen 	}
851c18ec02fSPetter Reinholdtsen 	else if (p->lun >= 0) {
852c18ec02fSPetter Reinholdtsen 		l = p->lun;
853c18ec02fSPetter Reinholdtsen 		if (bmc->lun[l].support) {
854c18ec02fSPetter Reinholdtsen 			for (n=0; n<MAX_NETFN_PAIR; n++) {
855c18ec02fSPetter Reinholdtsen 				p->netfn = n*2;
856c18ec02fSPetter Reinholdtsen 				if (bmc->lun[l].netfn[n].support) {
857c18ec02fSPetter Reinholdtsen 					ret = _get_command_support(intf, p, &(bmc->lun[l].netfn[n]));
858c18ec02fSPetter Reinholdtsen 					ret |= _get_command_configurable(intf, p, &(bmc->lun[l].netfn[n]));
859c18ec02fSPetter Reinholdtsen 					ret |= _get_command_enables(intf, p, &(bmc->lun[l].netfn[n]));
860c18ec02fSPetter Reinholdtsen 				}
861c18ec02fSPetter Reinholdtsen 				if (ret)
862c18ec02fSPetter Reinholdtsen 					bmc->lun[l].netfn[n].support = 0;
863c18ec02fSPetter Reinholdtsen 			}
864c18ec02fSPetter Reinholdtsen 		}
865c18ec02fSPetter Reinholdtsen 		p->netfn = -1;
866c18ec02fSPetter Reinholdtsen 	} else {
867c18ec02fSPetter Reinholdtsen 		for (l=0; l<4; l++) {
868c18ec02fSPetter Reinholdtsen 			p->lun = l;
869c18ec02fSPetter Reinholdtsen 			if (bmc->lun[l].support) {
870c18ec02fSPetter Reinholdtsen 				for (n=0; n<MAX_NETFN_PAIR; n++) {
871c18ec02fSPetter Reinholdtsen 					p->netfn = n*2;
872c18ec02fSPetter Reinholdtsen 					if (bmc->lun[l].netfn[n].support) {
873c18ec02fSPetter Reinholdtsen 						ret = _get_command_support(intf, p, &(bmc->lun[l].netfn[n]));
874c18ec02fSPetter Reinholdtsen 						ret |= _get_command_configurable(intf, p, &(bmc->lun[l].netfn[n]));
875c18ec02fSPetter Reinholdtsen 						ret |= _get_command_enables(intf, p, &(bmc->lun[l].netfn[n]));
876c18ec02fSPetter Reinholdtsen 					}
877c18ec02fSPetter Reinholdtsen 					if (ret)
878c18ec02fSPetter Reinholdtsen 						bmc->lun[l].netfn[n].support = 0;
879c18ec02fSPetter Reinholdtsen 				}
880c18ec02fSPetter Reinholdtsen 			}
881c18ec02fSPetter Reinholdtsen 		}
882c18ec02fSPetter Reinholdtsen 		p->lun = -1;
883c18ec02fSPetter Reinholdtsen 		p->netfn = -1;
884c18ec02fSPetter Reinholdtsen 	}
885c18ec02fSPetter Reinholdtsen 
886c18ec02fSPetter Reinholdtsen 	return 0;
887c18ec02fSPetter Reinholdtsen }
888c18ec02fSPetter Reinholdtsen 
889c18ec02fSPetter Reinholdtsen /* ipmi_firewall_info - print out info for firewall functions
890c18ec02fSPetter Reinholdtsen  *
891c18ec02fSPetter Reinholdtsen  * @intf:	ipmi inteface
892c18ec02fSPetter Reinholdtsen  * @argc:	argument count
893c18ec02fSPetter Reinholdtsen  * @argv:	argument list
894c18ec02fSPetter Reinholdtsen  *
895c18ec02fSPetter Reinholdtsen  * returns 0 on success
896c18ec02fSPetter Reinholdtsen  * returns -1 on error
897c18ec02fSPetter Reinholdtsen  */
898c18ec02fSPetter Reinholdtsen static int
ipmi_firewall_info(struct ipmi_intf * intf,int argc,char ** argv)899c18ec02fSPetter Reinholdtsen ipmi_firewall_info(struct ipmi_intf * intf, int argc, char ** argv)
900c18ec02fSPetter Reinholdtsen {
901c18ec02fSPetter Reinholdtsen 	int ret = 0;
902c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params p = {0xe, -1, -1, -1, -1};
903c18ec02fSPetter Reinholdtsen 	struct bmc_fn_support * bmc_fn_support;
904c18ec02fSPetter Reinholdtsen 	unsigned int l, n, c;
905c18ec02fSPetter Reinholdtsen 
906c18ec02fSPetter Reinholdtsen 	if ((argc > 0 && strncmp(argv[0], "help", 4) == 0) || ipmi_firewall_parse_args(argc, argv, &p) < 0)
907c18ec02fSPetter Reinholdtsen 	{
908c18ec02fSPetter Reinholdtsen 		printf_firewall_info_usage();
909c18ec02fSPetter Reinholdtsen 		return 0;
910c18ec02fSPetter Reinholdtsen 	}
911c18ec02fSPetter Reinholdtsen 
912c18ec02fSPetter Reinholdtsen 	bmc_fn_support = malloc(sizeof(struct bmc_fn_support));
913c18ec02fSPetter Reinholdtsen 	if (!bmc_fn_support) {
914c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "malloc struct bmc_fn_support failed");
915c18ec02fSPetter Reinholdtsen 		return -1;
916c18ec02fSPetter Reinholdtsen 	}
917c18ec02fSPetter Reinholdtsen 
918c18ec02fSPetter Reinholdtsen 	ret = _gather_info(intf, &p, bmc_fn_support);
919c18ec02fSPetter Reinholdtsen 
920c18ec02fSPetter Reinholdtsen 	if (p.command >= 0) {
921c18ec02fSPetter Reinholdtsen       struct command_support * cmd;
922c18ec02fSPetter Reinholdtsen 		if (!((p.lun < 0 || bmc_fn_support->lun[p.lun].support) &&
923c18ec02fSPetter Reinholdtsen 			(p.netfn < 0 || bmc_fn_support->lun[p.lun].netfn[p.netfn>>1].support) &&
924c18ec02fSPetter Reinholdtsen 			bmc_fn_support->lun[p.lun].netfn[p.netfn>>1].command[p.command].support))
925c18ec02fSPetter Reinholdtsen 		{
926c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Command 0x%02x not supported on LUN/NetFn pair %02x,%02x",
927c18ec02fSPetter Reinholdtsen 				p.command, p.lun, p.netfn);
928c18ec02fSPetter Reinholdtsen 			free(bmc_fn_support);
929c18ec02fSPetter Reinholdtsen 			bmc_fn_support = NULL;
930c18ec02fSPetter Reinholdtsen 			return 0;
931c18ec02fSPetter Reinholdtsen 		}
932c18ec02fSPetter Reinholdtsen 		cmd =
933c18ec02fSPetter Reinholdtsen 			&bmc_fn_support->lun[p.lun].netfn[p.netfn>>1].command[p.command];
934c18ec02fSPetter Reinholdtsen 		c = cmd->support;
935c18ec02fSPetter Reinholdtsen 		printf("(A)vailable, (C)onfigurable, (E)nabled: | A | C | E |\n");
936c18ec02fSPetter Reinholdtsen 		printf("-----------------------------------------------------\n");
937c18ec02fSPetter Reinholdtsen 		printf("LUN %01d, NetFn 0x%02x, Command 0x%02x:        | %c | %c | %c |\n",
938c18ec02fSPetter Reinholdtsen 			p.lun, p.netfn, p.command,
939c18ec02fSPetter Reinholdtsen 			(c & BIT_AVAILABLE) ? 'X' : ' ',
940c18ec02fSPetter Reinholdtsen 			(c & BIT_CONFIGURABLE) ? 'X' : ' ',
941c18ec02fSPetter Reinholdtsen 			(c & BIT_ENABLED) ? 'X': ' ');
942c18ec02fSPetter Reinholdtsen 
943c18ec02fSPetter Reinholdtsen 		for (n=0; n<MAX_SUBFN; n++) {
944c18ec02fSPetter Reinholdtsen 			printf("sub-function 0x%02x:                      | %c | %c | %c |\n", n,
945c18ec02fSPetter Reinholdtsen 				(!bit_test(cmd->subfn_support, n)) ? 'X' : ' ',
946c18ec02fSPetter Reinholdtsen 				(bit_test(cmd->subfn_config, n)) ? 'X' : ' ',
947c18ec02fSPetter Reinholdtsen 				(bit_test(cmd->subfn_enable, n)) ? 'X' : ' ');
948c18ec02fSPetter Reinholdtsen 		}
949c18ec02fSPetter Reinholdtsen 	}
950c18ec02fSPetter Reinholdtsen 	else if (p.netfn >= 0) {
951c18ec02fSPetter Reinholdtsen 		if (!((p.lun < 0 || bmc_fn_support->lun[p.lun].support) &&
952c18ec02fSPetter Reinholdtsen 			(bmc_fn_support->lun[p.lun].netfn[p.netfn>>1].support)))
953c18ec02fSPetter Reinholdtsen 		{
954c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "LUN or LUN/NetFn pair %02x,%02x not supported",
955c18ec02fSPetter Reinholdtsen 				p.lun, p.netfn);
956c18ec02fSPetter Reinholdtsen 			free(bmc_fn_support);
957c18ec02fSPetter Reinholdtsen 			bmc_fn_support = NULL;
958c18ec02fSPetter Reinholdtsen 			return 0;
959c18ec02fSPetter Reinholdtsen 		}
960c18ec02fSPetter Reinholdtsen 		n = p.netfn >> 1;
961c18ec02fSPetter Reinholdtsen 		l = p.lun;
962c18ec02fSPetter Reinholdtsen 		printf("Commands on LUN 0x%02x, NetFn 0x%02x\n", p.lun, p.netfn);
963c18ec02fSPetter Reinholdtsen 		printf("support:      ");
964c18ec02fSPetter Reinholdtsen 		print_bitfield(bmc_fn_support->lun[l].netfn[n].command_mask,
965c18ec02fSPetter Reinholdtsen 				MAX_COMMAND_BYTES, 1, -1);
966c18ec02fSPetter Reinholdtsen 		printf("configurable: ");
967c18ec02fSPetter Reinholdtsen 		print_bitfield(bmc_fn_support->lun[l].netfn[n].config_mask,
968c18ec02fSPetter Reinholdtsen 				MAX_COMMAND_BYTES, 0, -1);
969c18ec02fSPetter Reinholdtsen 		printf("enabled:      ");
970c18ec02fSPetter Reinholdtsen 		print_bitfield(bmc_fn_support->lun[l].netfn[n].enable_mask,
971c18ec02fSPetter Reinholdtsen 				MAX_COMMAND_BYTES, 0, -1);
972c18ec02fSPetter Reinholdtsen 	}
973c18ec02fSPetter Reinholdtsen 	else {
974c18ec02fSPetter Reinholdtsen 	    for (l=0; l<4; l++) {
975c18ec02fSPetter Reinholdtsen                 p.lun = l;
976c18ec02fSPetter Reinholdtsen                 if (bmc_fn_support->lun[l].support) {
977c18ec02fSPetter Reinholdtsen                     for (n=0; n<MAX_NETFN_PAIR; n++) {
978c18ec02fSPetter Reinholdtsen                         p.netfn = n*2;
979c18ec02fSPetter Reinholdtsen                         if (bmc_fn_support->lun[l].netfn[n].support) {
980c18ec02fSPetter Reinholdtsen                             printf("%02x,%02x support:      ", p.lun, p.netfn);
981c18ec02fSPetter Reinholdtsen                             print_bitfield(bmc_fn_support->lun[l].netfn[n].command_mask,
982c18ec02fSPetter Reinholdtsen                                     MAX_COMMAND_BYTES, 1, -1);
983c18ec02fSPetter Reinholdtsen                             printf("%02x,%02x configurable: ", p.lun, p.netfn);
984c18ec02fSPetter Reinholdtsen                             print_bitfield(bmc_fn_support->lun[l].netfn[n].config_mask,
985c18ec02fSPetter Reinholdtsen                                     MAX_COMMAND_BYTES, 0, -1);
986c18ec02fSPetter Reinholdtsen                             printf("%02x,%02x enabled:      ", p.lun, p.netfn);
987c18ec02fSPetter Reinholdtsen                             print_bitfield(bmc_fn_support->lun[l].netfn[n].enable_mask,
988c18ec02fSPetter Reinholdtsen                                     MAX_COMMAND_BYTES, 0, -1);
989c18ec02fSPetter Reinholdtsen                         }
990c18ec02fSPetter Reinholdtsen                     }
991c18ec02fSPetter Reinholdtsen                 }
992c18ec02fSPetter Reinholdtsen             }
993c18ec02fSPetter Reinholdtsen             p.lun = -1;
994c18ec02fSPetter Reinholdtsen             p.netfn = -1;
995c18ec02fSPetter Reinholdtsen 	}
996c18ec02fSPetter Reinholdtsen 
997c18ec02fSPetter Reinholdtsen 	free(bmc_fn_support);
998c18ec02fSPetter Reinholdtsen 	bmc_fn_support = NULL;
999c18ec02fSPetter Reinholdtsen 	return ret;
1000c18ec02fSPetter Reinholdtsen }
1001c18ec02fSPetter Reinholdtsen 
1002c18ec02fSPetter Reinholdtsen /* ipmi_firewall_enable_disable  -  enable/disable BMC functions
1003c18ec02fSPetter Reinholdtsen  *
1004c18ec02fSPetter Reinholdtsen  * @intf:	ipmi inteface
1005c18ec02fSPetter Reinholdtsen  * @enable:     whether to enable or disable
1006c18ec02fSPetter Reinholdtsen  * @argc:	argument count
1007c18ec02fSPetter Reinholdtsen  * @argv:	argument list
1008c18ec02fSPetter Reinholdtsen  *
1009c18ec02fSPetter Reinholdtsen  * returns 0 on success
1010c18ec02fSPetter Reinholdtsen  * returns -1 on error
1011c18ec02fSPetter Reinholdtsen  */
1012c18ec02fSPetter Reinholdtsen static int
ipmi_firewall_enable_disable(struct ipmi_intf * intf,int enable,int argc,char ** argv)1013c18ec02fSPetter Reinholdtsen ipmi_firewall_enable_disable(struct ipmi_intf * intf, int enable, int argc, char ** argv)
1014c18ec02fSPetter Reinholdtsen {
1015c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params p = {0xe, -1, -1, -1, -1};
1016c18ec02fSPetter Reinholdtsen 	struct bmc_fn_support * bmc_fn_support;
1017*32c46909SZdenek Styblik 	int ret;
1018*32c46909SZdenek Styblik 	unsigned int l, n, c;
1019c18ec02fSPetter Reinholdtsen 	unsigned char enables[MAX_COMMAND_BYTES];
1020c18ec02fSPetter Reinholdtsen 
1021c18ec02fSPetter Reinholdtsen 	if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
1022c18ec02fSPetter Reinholdtsen 		char * s1 = enable?"en":"dis";
1023c18ec02fSPetter Reinholdtsen 		char * s2 = enable?"":" [force]";
1024c18ec02fSPetter Reinholdtsen 		printf("%sable [channel H] lun L netfn N%s\n", s1, s2);
1025c18ec02fSPetter Reinholdtsen 		printf("\t%sable all commands on this LUN/NetFn pair\n", s1);
1026c18ec02fSPetter Reinholdtsen 		printf("%sable [channel H] lun L netfn N command C%s\n", s1, s2);
1027c18ec02fSPetter Reinholdtsen 		printf("\t%sable Command C and all its Sub-functions for this LUN/NetFn pair\n", s1);
1028c18ec02fSPetter Reinholdtsen 		printf("%sable [channel H] lun L netfn N command C subfn S\n", s1);
1029c18ec02fSPetter Reinholdtsen 		printf("\t%sable Sub-function S for Command C for this LUN/NetFn pair\n", s1);
1030c18ec02fSPetter Reinholdtsen 		if (!enable) {
1031c18ec02fSPetter Reinholdtsen 			printf("* force will allow you to disable the \"Command Set Enable\" command\n");
1032c18ec02fSPetter Reinholdtsen 			printf("\tthereby letting you shoot yourself in the foot\n");
1033c18ec02fSPetter Reinholdtsen 			printf("\tthis is only recommended for advanced users\n");
1034c18ec02fSPetter Reinholdtsen 		}
1035c18ec02fSPetter Reinholdtsen 		return 0;
1036c18ec02fSPetter Reinholdtsen 	}
1037c18ec02fSPetter Reinholdtsen 	if (ipmi_firewall_parse_args(argc, argv, &p) < 0)
1038c18ec02fSPetter Reinholdtsen 		return -1;
1039c18ec02fSPetter Reinholdtsen 
1040c18ec02fSPetter Reinholdtsen 	bmc_fn_support = malloc(sizeof(struct bmc_fn_support));
1041c18ec02fSPetter Reinholdtsen 	if (!bmc_fn_support) {
1042c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "malloc struct bmc_fn_support failed");
1043c18ec02fSPetter Reinholdtsen 		return -1;
1044c18ec02fSPetter Reinholdtsen 	}
1045c18ec02fSPetter Reinholdtsen 
1046c18ec02fSPetter Reinholdtsen 	ret = _gather_info(intf, &p, bmc_fn_support);
1047c18ec02fSPetter Reinholdtsen 	if (ret < 0) {
1048c18ec02fSPetter Reinholdtsen 		free(bmc_fn_support);
1049c18ec02fSPetter Reinholdtsen 		bmc_fn_support = NULL;
1050c18ec02fSPetter Reinholdtsen 		return ret;
1051c18ec02fSPetter Reinholdtsen 	}
1052c18ec02fSPetter Reinholdtsen 
1053c18ec02fSPetter Reinholdtsen 	l = p.lun;
1054c18ec02fSPetter Reinholdtsen 	n = p.netfn>>1;
1055c18ec02fSPetter Reinholdtsen 	c = p.command;
1056c18ec02fSPetter Reinholdtsen 	if (p.subfn >= 0) {
1057c18ec02fSPetter Reinholdtsen 		// firewall (en|dis)able [channel c] lun l netfn n command m subfn s
1058c18ec02fSPetter Reinholdtsen 		// (en|dis)able this sub-function for this commnad on this lun/netfn pair
1059c18ec02fSPetter Reinholdtsen 		memcpy(enables,
1060c18ec02fSPetter Reinholdtsen 			bmc_fn_support->lun[l].netfn[n].command[c].subfn_enable,
1061c18ec02fSPetter Reinholdtsen 			MAX_SUBFN_BYTES);
1062c18ec02fSPetter Reinholdtsen 		bit_set(enables, p.subfn, enable);
1063c18ec02fSPetter Reinholdtsen 		ret = _set_subfn_enables(intf, &p,
1064c18ec02fSPetter Reinholdtsen 			&bmc_fn_support->lun[l].netfn[n].command[c], enables);
1065c18ec02fSPetter Reinholdtsen 
1066c18ec02fSPetter Reinholdtsen 	} else if (p.command >= 0) {
1067c18ec02fSPetter Reinholdtsen 		// firewall (en|dis)able [channel c] lun l netfn n command m
1068c18ec02fSPetter Reinholdtsen 		//    (en|dis)able all subfn and command for this commnad on this lun/netfn pair
1069c18ec02fSPetter Reinholdtsen 		memset(enables, enable?0xff:0, MAX_SUBFN_BYTES);
1070c18ec02fSPetter Reinholdtsen 		ret = _set_subfn_enables(intf, &p,
1071c18ec02fSPetter Reinholdtsen 			&bmc_fn_support->lun[l].netfn[n].command[c], enables);
1072c18ec02fSPetter Reinholdtsen 		memcpy(enables,
1073c18ec02fSPetter Reinholdtsen 			&bmc_fn_support->lun[l].netfn[n].enable_mask, sizeof(enables));
1074c18ec02fSPetter Reinholdtsen 		bit_set(enables, p.command, enable);
1075c18ec02fSPetter Reinholdtsen 		ret |= _set_command_enables(intf, &p,
1076c18ec02fSPetter Reinholdtsen 			&bmc_fn_support->lun[l].netfn[n], enables, p.force);
1077c18ec02fSPetter Reinholdtsen 	} else if (p.netfn >= 0) {
1078c18ec02fSPetter Reinholdtsen 		// firewall (en|dis)able [channel c] lun l netfn n
1079c18ec02fSPetter Reinholdtsen 		//    (en|dis)able all commnads on this lun/netfn pair
1080c18ec02fSPetter Reinholdtsen 		memset(enables, enable?0xff:0, sizeof(enables));
1081c18ec02fSPetter Reinholdtsen 		ret = _set_command_enables(intf, &p,
1082c18ec02fSPetter Reinholdtsen 			&bmc_fn_support->lun[l].netfn[n], enables, p.force);
1083c18ec02fSPetter Reinholdtsen 		/*
1084c18ec02fSPetter Reinholdtsen 		   } else if (p.lun >= 0) {
1085c18ec02fSPetter Reinholdtsen 		// firewall (en|dis)able [channel c] lun l
1086c18ec02fSPetter Reinholdtsen 		//    (en|dis)able all commnads on all netfn pairs for this lun
1087c18ec02fSPetter Reinholdtsen 		*/
1088c18ec02fSPetter Reinholdtsen 	}
1089c18ec02fSPetter Reinholdtsen 	free(bmc_fn_support);
1090c18ec02fSPetter Reinholdtsen 	bmc_fn_support = NULL;
1091c18ec02fSPetter Reinholdtsen 	return ret;
1092c18ec02fSPetter Reinholdtsen }
1093c18ec02fSPetter Reinholdtsen 
1094c18ec02fSPetter Reinholdtsen /* ipmi_firewall_reset - reset firmware firewall to enable everything
1095c18ec02fSPetter Reinholdtsen  *
1096c18ec02fSPetter Reinholdtsen  * @intf:	ipmi inteface
1097c18ec02fSPetter Reinholdtsen  * @argc:	argument count
1098c18ec02fSPetter Reinholdtsen  * @argv:	argument list
1099c18ec02fSPetter Reinholdtsen  *
1100c18ec02fSPetter Reinholdtsen  * returns 0 on success
1101c18ec02fSPetter Reinholdtsen  * returns -1 on error
1102c18ec02fSPetter Reinholdtsen  */
1103c18ec02fSPetter Reinholdtsen static int
ipmi_firewall_reset(struct ipmi_intf * intf,int argc,char ** argv)1104c18ec02fSPetter Reinholdtsen ipmi_firewall_reset(struct ipmi_intf * intf, int argc, char ** argv)
1105c18ec02fSPetter Reinholdtsen {
1106c18ec02fSPetter Reinholdtsen 	struct ipmi_function_params p = {0xe, -1, -1, -1, -1};
1107c18ec02fSPetter Reinholdtsen 	struct bmc_fn_support * bmc_fn_support;
1108*32c46909SZdenek Styblik 	int ret;
1109*32c46909SZdenek Styblik 	unsigned int l, n, c;
1110c18ec02fSPetter Reinholdtsen 	unsigned char enables[MAX_COMMAND_BYTES];
1111c18ec02fSPetter Reinholdtsen 
1112c2e65d0dSZdenek Styblik 	if (argc < 1) {
1113c2e65d0dSZdenek Styblik 		lprintf(LOG_ERR, "Not enough parameters given.");
1114c2e65d0dSZdenek Styblik 		printf_firewall_usage();
1115c2e65d0dSZdenek Styblik 		return (-1);
1116c2e65d0dSZdenek Styblik 	} else if (argc > 0 && strncmp(argv[0], "help", 4) == 0) {
1117c18ec02fSPetter Reinholdtsen 		printf_firewall_usage();
1118c18ec02fSPetter Reinholdtsen 		return 0;
1119c18ec02fSPetter Reinholdtsen 	}
1120c18ec02fSPetter Reinholdtsen 	if (ipmi_firewall_parse_args(argc, argv, &p) < 0)
1121c18ec02fSPetter Reinholdtsen 		return -1;
1122c18ec02fSPetter Reinholdtsen 
1123c18ec02fSPetter Reinholdtsen 	bmc_fn_support = malloc(sizeof(struct bmc_fn_support));
1124c18ec02fSPetter Reinholdtsen 	if (!bmc_fn_support) {
1125c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "malloc struct bmc_fn_support failed");
1126c18ec02fSPetter Reinholdtsen 		return -1;
1127c18ec02fSPetter Reinholdtsen 	}
1128c18ec02fSPetter Reinholdtsen 
1129c18ec02fSPetter Reinholdtsen 	ret = _gather_info(intf, &p, bmc_fn_support);
1130c18ec02fSPetter Reinholdtsen 	if (ret < 0) {
1131c18ec02fSPetter Reinholdtsen 		free(bmc_fn_support);
1132c18ec02fSPetter Reinholdtsen 		bmc_fn_support = NULL;
1133c18ec02fSPetter Reinholdtsen 		return ret;
1134c18ec02fSPetter Reinholdtsen 	}
1135c18ec02fSPetter Reinholdtsen 
1136c18ec02fSPetter Reinholdtsen 	for (l=0; l<MAX_LUN; l++) {
1137c18ec02fSPetter Reinholdtsen 		p.lun = l;
1138c18ec02fSPetter Reinholdtsen 		for (n=0; n<MAX_NETFN; n+=2) {
1139c18ec02fSPetter Reinholdtsen 			p.netfn = n;
1140c18ec02fSPetter Reinholdtsen 			for (c=0; c<MAX_COMMAND; c++) {
1141c18ec02fSPetter Reinholdtsen 				p.command = c;
1142c18ec02fSPetter Reinholdtsen 				printf("reset lun %d, netfn %d, command %d, subfn\n", l, n, c);
1143c18ec02fSPetter Reinholdtsen 				memset(enables, 0xff, MAX_SUBFN_BYTES);
1144c18ec02fSPetter Reinholdtsen 				ret = _set_subfn_enables(intf, &p,
1145c18ec02fSPetter Reinholdtsen 					&bmc_fn_support->lun[l].netfn[n].command[c], enables);
1146c18ec02fSPetter Reinholdtsen 			}
1147c18ec02fSPetter Reinholdtsen 			printf("reset lun %d, netfn %d, command\n", l, n);
1148c18ec02fSPetter Reinholdtsen 			memset(enables, 0xff, sizeof(enables));
1149c18ec02fSPetter Reinholdtsen 			ret = _set_command_enables(intf, &p,
1150c18ec02fSPetter Reinholdtsen 				&bmc_fn_support->lun[l].netfn[n], enables, 0);
1151c18ec02fSPetter Reinholdtsen 		}
1152c18ec02fSPetter Reinholdtsen 	}
1153c18ec02fSPetter Reinholdtsen 
1154c18ec02fSPetter Reinholdtsen 	free(bmc_fn_support);
1155c18ec02fSPetter Reinholdtsen 	bmc_fn_support = NULL;
1156c18ec02fSPetter Reinholdtsen 	return ret;
1157c18ec02fSPetter Reinholdtsen }
1158c18ec02fSPetter Reinholdtsen 
1159c18ec02fSPetter Reinholdtsen 
1160c18ec02fSPetter Reinholdtsen /* ipmi_firewall_main - top-level handler for firmware firewall functions
1161c18ec02fSPetter Reinholdtsen  *
1162c18ec02fSPetter Reinholdtsen  * @intf:	ipmi interface
1163c18ec02fSPetter Reinholdtsen  * @argc:	number of arguments
1164c18ec02fSPetter Reinholdtsen  * @argv:	argument list
1165c18ec02fSPetter Reinholdtsen  *
1166c18ec02fSPetter Reinholdtsen  * returns 0 on success
1167c18ec02fSPetter Reinholdtsen  * returns -1 on error
1168c18ec02fSPetter Reinholdtsen  */
1169c18ec02fSPetter Reinholdtsen int
ipmi_firewall_main(struct ipmi_intf * intf,int argc,char ** argv)1170c18ec02fSPetter Reinholdtsen ipmi_firewall_main(struct ipmi_intf * intf, int argc, char ** argv)
1171c18ec02fSPetter Reinholdtsen {
1172c18ec02fSPetter Reinholdtsen 	int rc = 0;
1173c18ec02fSPetter Reinholdtsen 
1174c18ec02fSPetter Reinholdtsen 	if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
1175c18ec02fSPetter Reinholdtsen 		printf_firewall_usage();
1176c18ec02fSPetter Reinholdtsen 	}
1177c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "info", 4) == 0) {
1178c18ec02fSPetter Reinholdtsen 		rc = ipmi_firewall_info(intf, argc-1, &(argv[1]));
1179c18ec02fSPetter Reinholdtsen 	}
1180c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "enable", 6) == 0) {
1181c18ec02fSPetter Reinholdtsen 		rc = ipmi_firewall_enable_disable(intf, 1, argc-1, &(argv[1]));
1182c18ec02fSPetter Reinholdtsen 	}
1183c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "disable", 7) == 0) {
1184c18ec02fSPetter Reinholdtsen 		rc = ipmi_firewall_enable_disable(intf, 0, argc-1, &(argv[1]));
1185c18ec02fSPetter Reinholdtsen 	}
1186c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "reset", 5) == 0) {
1187c18ec02fSPetter Reinholdtsen 		rc = ipmi_firewall_reset(intf, argc-1, &(argv[1]));
1188c18ec02fSPetter Reinholdtsen 	}
1189c18ec02fSPetter Reinholdtsen 	else {
1190c18ec02fSPetter Reinholdtsen 		printf_firewall_usage();
1191c18ec02fSPetter Reinholdtsen 	}
1192c18ec02fSPetter Reinholdtsen 
1193c18ec02fSPetter Reinholdtsen 	return rc;
1194c18ec02fSPetter Reinholdtsen }
1195