1f1c6118cSZdenek Styblik /*
2f1c6118cSZdenek Styblik * Copyright (c) 2014 Pigeon Point Systems. All right reserved
3f1c6118cSZdenek Styblik *
4f1c6118cSZdenek Styblik * Redistribution and use in source and binary forms, with or without
5f1c6118cSZdenek Styblik * modification, are permitted provided that the following conditions
6f1c6118cSZdenek Styblik * are met:
7f1c6118cSZdenek Styblik *
8f1c6118cSZdenek Styblik * Redistribution of source code must retain the above copyright
9f1c6118cSZdenek Styblik * notice, this list of conditions and the following disclaimer.
10f1c6118cSZdenek Styblik *
11f1c6118cSZdenek Styblik * Redistribution in binary form must reproduce the above copyright
12f1c6118cSZdenek Styblik * notice, this list of conditions and the following disclaimer in the
13f1c6118cSZdenek Styblik * documentation and/or other materials provided with the distribution.
14f1c6118cSZdenek Styblik *
15f1c6118cSZdenek Styblik * Neither the name of Pigeon Point Systems, or the names of
16f1c6118cSZdenek Styblik * contributors may be used to endorse or promote products derived
17f1c6118cSZdenek Styblik * from this software without specific prior written permission.
18f1c6118cSZdenek Styblik *
19f1c6118cSZdenek Styblik * This software is provided "AS IS, " without a warranty of any kind.
20f1c6118cSZdenek Styblik * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21f1c6118cSZdenek Styblik * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22f1c6118cSZdenek Styblik * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23f1c6118cSZdenek Styblik * PIGEON POINT SYSTEMS ("PPS") AND ITS LICENSORS SHALL NOT BE LIABLE
24f1c6118cSZdenek Styblik * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25f1c6118cSZdenek Styblik * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
26f1c6118cSZdenek Styblik * PPS OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27f1c6118cSZdenek Styblik * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28f1c6118cSZdenek Styblik * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29f1c6118cSZdenek Styblik * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30f1c6118cSZdenek Styblik * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31f1c6118cSZdenek Styblik */
32f1c6118cSZdenek Styblik
33f1c6118cSZdenek Styblik
34f1c6118cSZdenek Styblik #include <ipmitool/ipmi_intf.h>
35f1c6118cSZdenek Styblik #include <ipmitool/ipmi_picmg.h>
36f1c6118cSZdenek Styblik #include <ipmitool/ipmi_vita.h>
37f1c6118cSZdenek Styblik #include <ipmitool/ipmi_fru.h>
38f1c6118cSZdenek Styblik #include <ipmitool/ipmi_strings.h>
39f1c6118cSZdenek Styblik #include <ipmitool/log.h>
40f1c6118cSZdenek Styblik
41f1c6118cSZdenek Styblik /* Handled VITA 46.11 commands */
42f1c6118cSZdenek Styblik #define VITA_CMD_HELP 0
43f1c6118cSZdenek Styblik #define VITA_CMD_PROPERTIES 1
44f1c6118cSZdenek Styblik #define VITA_CMD_FRUCONTROL 2
45f1c6118cSZdenek Styblik #define VITA_CMD_ADDRINFO 3
46f1c6118cSZdenek Styblik #define VITA_CMD_ACTIVATE 4
47f1c6118cSZdenek Styblik #define VITA_CMD_DEACTIVATE 5
48f1c6118cSZdenek Styblik #define VITA_CMD_POLICY_GET 6
49f1c6118cSZdenek Styblik #define VITA_CMD_POLICY_SET 7
50f1c6118cSZdenek Styblik #define VITA_CMD_LED_PROP 8
51f1c6118cSZdenek Styblik #define VITA_CMD_LED_CAP 9
52f1c6118cSZdenek Styblik #define VITA_CMD_LED_GET 10
53f1c6118cSZdenek Styblik #define VITA_CMD_LED_SET 11
54f1c6118cSZdenek Styblik #define VITA_CMD_UNKNOWN 255
55f1c6118cSZdenek Styblik
56f1c6118cSZdenek Styblik /* VITA 46.11 Site Type strings */
57f1c6118cSZdenek Styblik static struct valstr vita_site_types[] = {
58f1c6118cSZdenek Styblik { VITA_FRONT_VPX_MODULE, "Front Loading VPX Plug-In Module" },
59f1c6118cSZdenek Styblik { VITA_POWER_ENTRY, "Power Entry Module" },
60f1c6118cSZdenek Styblik { VITA_CHASSIS_FRU, "Chassic FRU Information Module" },
61f1c6118cSZdenek Styblik { VITA_DEDICATED_CHMC, "Dedicated Chassis Manager" },
62f1c6118cSZdenek Styblik { VITA_FAN_TRAY, "Fan Tray" },
63f1c6118cSZdenek Styblik { VITA_FAN_TRAY_FILTER, "Fan Tray Filter" },
64f1c6118cSZdenek Styblik { VITA_ALARM_PANEL, "Alarm Panel" },
65f1c6118cSZdenek Styblik { VITA_XMC, "XMC" },
66f1c6118cSZdenek Styblik { VITA_VPX_RTM, "VPX Rear Transition Module" },
67f1c6118cSZdenek Styblik { VITA_FRONT_VME_MODULE, "Front Loading VME Plug-In Module" },
68f1c6118cSZdenek Styblik { VITA_FRONT_VXS_MODULE, "Front Loading VXS Plug-In Module" },
69f1c6118cSZdenek Styblik { VITA_POWER_SUPPLY, "Power Supply" },
70f1c6118cSZdenek Styblik { VITA_FRONT_VITA62_MODULE, "Front Loading VITA 62 Module\n" },
71f1c6118cSZdenek Styblik { VITA_71_MODULE, "VITA 71 Module\n" },
72f1c6118cSZdenek Styblik { VITA_FMC, "FMC\n" },
73f1c6118cSZdenek Styblik { 0, NULL }
74f1c6118cSZdenek Styblik };
75f1c6118cSZdenek Styblik
76f1c6118cSZdenek Styblik /* VITA 46.11 command help strings */
77f1c6118cSZdenek Styblik static struct valstr vita_help_strings[] = {
78f1c6118cSZdenek Styblik {
79f1c6118cSZdenek Styblik VITA_CMD_HELP,
80f1c6118cSZdenek Styblik "VITA commands:\n"
81f1c6118cSZdenek Styblik " properties - get VSO properties\n"
82f1c6118cSZdenek Styblik " frucontrol - FRU control\n"
83f1c6118cSZdenek Styblik " addrinfo - get address information\n"
84f1c6118cSZdenek Styblik " activate - activate a FRU\n"
85f1c6118cSZdenek Styblik " deactivate - deactivate a FRU\n"
86f1c6118cSZdenek Styblik " policy get - get the FRU activation policy\n"
87f1c6118cSZdenek Styblik " policy set - set the FRU activation policy\n"
88f1c6118cSZdenek Styblik " led prop - get led properties\n"
89f1c6118cSZdenek Styblik " led cap - get led color capabilities\n"
90f1c6118cSZdenek Styblik " led get - get led state\n"
91f1c6118cSZdenek Styblik " led set - set led state"
92f1c6118cSZdenek Styblik },
93f1c6118cSZdenek Styblik {
94f1c6118cSZdenek Styblik VITA_CMD_FRUCONTROL,
95f1c6118cSZdenek Styblik "usage: frucontrol <FRU-ID> <OPTION>\n"
96f1c6118cSZdenek Styblik " OPTION: 0 - Cold Reset\n"
97f1c6118cSZdenek Styblik " 1 - Warm Reset\n"
98f1c6118cSZdenek Styblik " 2 - Graceful Reboot\n"
99f1c6118cSZdenek Styblik " 3 - Issue Diagnostic Interrupt"
100f1c6118cSZdenek Styblik },
101f1c6118cSZdenek Styblik {
102f1c6118cSZdenek Styblik VITA_CMD_ADDRINFO,
103f1c6118cSZdenek Styblik "usage: addrinfo [<FRU-ID>]"
104f1c6118cSZdenek Styblik },
105f1c6118cSZdenek Styblik {
106f1c6118cSZdenek Styblik VITA_CMD_ACTIVATE,
107f1c6118cSZdenek Styblik "usage: activate <FRU-ID>"
108f1c6118cSZdenek Styblik },
109f1c6118cSZdenek Styblik {
110f1c6118cSZdenek Styblik VITA_CMD_DEACTIVATE,
111f1c6118cSZdenek Styblik "usage: deactivate <FRU-ID>"
112f1c6118cSZdenek Styblik },
113f1c6118cSZdenek Styblik {
114f1c6118cSZdenek Styblik VITA_CMD_POLICY_GET,
115f1c6118cSZdenek Styblik "usage: policy get <FRU-ID>"
116f1c6118cSZdenek Styblik },
117f1c6118cSZdenek Styblik {
118f1c6118cSZdenek Styblik VITA_CMD_POLICY_SET,
119f1c6118cSZdenek Styblik "usage: policy set <FRU-ID> <MASK> <VALUE>\n"
120f1c6118cSZdenek Styblik " MASK: [3] affect the Default-Activation-Locked Policy Bit\n"
121f1c6118cSZdenek Styblik " [2] affect the Commanded-Deactivation-Ignored Policy Bit\n"
122f1c6118cSZdenek Styblik " [1] affect the Deactivation-Locked Policy Bit\n"
123f1c6118cSZdenek Styblik " [0] affect the Activation-Locked Policy Bit\n"
124f1c6118cSZdenek Styblik " VALUE: [3] value for the Default-Activation-Locked Policy Bit\n"
125f1c6118cSZdenek Styblik " [2] value for the Commanded-Deactivation-Ignored Policy Bit\n"
126f1c6118cSZdenek Styblik " [1] value for the Deactivation-Locked Policy Bit\n"
127f1c6118cSZdenek Styblik " [0] value for the Activation-Locked Policy Bit"
128f1c6118cSZdenek Styblik },
129f1c6118cSZdenek Styblik {
130f1c6118cSZdenek Styblik VITA_CMD_LED_PROP,
131f1c6118cSZdenek Styblik "usage: led prop <FRU-ID>"
132f1c6118cSZdenek Styblik },
133f1c6118cSZdenek Styblik {
134f1c6118cSZdenek Styblik VITA_CMD_LED_CAP,
135f1c6118cSZdenek Styblik "usage: led cap <FRU-ID> <LED-ID"
136f1c6118cSZdenek Styblik },
137f1c6118cSZdenek Styblik {
138f1c6118cSZdenek Styblik VITA_CMD_LED_GET,
139f1c6118cSZdenek Styblik "usage: led get <FRU-ID> <LED-ID",
140f1c6118cSZdenek Styblik },
141f1c6118cSZdenek Styblik {
142f1c6118cSZdenek Styblik VITA_CMD_LED_SET,
143f1c6118cSZdenek Styblik "usage: led set <FRU-ID> <LED-ID> <FUNCTION> <DURATION> <COLOR>\n"
144f1c6118cSZdenek Styblik " <FRU-ID>\n"
145f1c6118cSZdenek Styblik " <LED-ID> 0-0xFE: Specified LED\n"
146f1c6118cSZdenek Styblik " 0xFF: All LEDs under management control\n"
147f1c6118cSZdenek Styblik " <FUNCTION> 0: LED OFF override\n"
148f1c6118cSZdenek Styblik " 1 - 250: LED blinking override (off duration)\n"
149f1c6118cSZdenek Styblik " 251: LED Lamp Test\n"
150f1c6118cSZdenek Styblik " 252: LED restore to local control\n"
151f1c6118cSZdenek Styblik " 255: LED ON override\n"
152f1c6118cSZdenek Styblik " <DURATION> 1 - 127: LED Lamp Test / on duration\n"
153f1c6118cSZdenek Styblik " <COLOR> 1: BLUE\n"
154f1c6118cSZdenek Styblik " 2: RED\n"
155f1c6118cSZdenek Styblik " 3: GREEN\n"
156f1c6118cSZdenek Styblik " 4: AMBER\n"
157f1c6118cSZdenek Styblik " 5: ORANGE\n"
158f1c6118cSZdenek Styblik " 6: WHITE\n"
159f1c6118cSZdenek Styblik " 0xE: do not change\n"
160f1c6118cSZdenek Styblik " 0xF: use default color"
161f1c6118cSZdenek Styblik },
162f1c6118cSZdenek Styblik {
163f1c6118cSZdenek Styblik VITA_CMD_UNKNOWN,
164f1c6118cSZdenek Styblik "Unknown command"
165f1c6118cSZdenek Styblik },
166f1c6118cSZdenek Styblik { 0, NULL }
167f1c6118cSZdenek Styblik };
168f1c6118cSZdenek Styblik
169f1c6118cSZdenek Styblik /* check if VITA 46.11 is supported */
170f1c6118cSZdenek Styblik uint8_t
vita_discover(struct ipmi_intf * intf)171f1c6118cSZdenek Styblik vita_discover(struct ipmi_intf *intf)
172f1c6118cSZdenek Styblik {
173f1c6118cSZdenek Styblik struct ipmi_rq req;
174f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
175f1c6118cSZdenek Styblik unsigned char msg_data;
176f1c6118cSZdenek Styblik int vita_avail = 0;
177f1c6118cSZdenek Styblik
178f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
179f1c6118cSZdenek Styblik
180f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
181f1c6118cSZdenek Styblik req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
182f1c6118cSZdenek Styblik req.msg.data = &msg_data;
183f1c6118cSZdenek Styblik req.msg.data_len = 1;
184f1c6118cSZdenek Styblik
185f1c6118cSZdenek Styblik msg_data = GROUP_EXT_VITA;
186f1c6118cSZdenek Styblik
187f1c6118cSZdenek Styblik lprintf(LOG_INFO, "Running Get VSO Capabilities my_addr %#x, "
188f1c6118cSZdenek Styblik "transit %#x, target %#x",
189f1c6118cSZdenek Styblik intf->my_addr, intf->transit_addr, intf->target_addr);
190f1c6118cSZdenek Styblik
191f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
192f1c6118cSZdenek Styblik
193f1c6118cSZdenek Styblik if (rsp == NULL) {
194f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received");
195372b458eSZdenek Styblik } else if (rsp->ccode == 0xC1) {
196*c04aa9bbSZdenek Styblik lprintf(LOG_INFO, "Invalid completion code received: %s",
197372b458eSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
198329281bbSZdenek Styblik } else if (rsp->ccode == 0xCC) {
199329281bbSZdenek Styblik lprintf(LOG_INFO, "Invalid data field received: %s",
200329281bbSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
201f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
202*c04aa9bbSZdenek Styblik lprintf(LOG_INFO, "Invalid completion code received: %s",
203f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
204f1c6118cSZdenek Styblik } else if (rsp->data_len < 5) {
205*c04aa9bbSZdenek Styblik lprintf(LOG_INFO, "Invalid response length %d",
206f1c6118cSZdenek Styblik rsp->data_len);
207f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
208*c04aa9bbSZdenek Styblik lprintf(LOG_INFO, "Invalid group extension %#x",
209f1c6118cSZdenek Styblik rsp->data[0]);
210f1c6118cSZdenek Styblik } else if ((rsp->data[3] & 0x03) != 0) {
211*c04aa9bbSZdenek Styblik lprintf(LOG_INFO, "Unknown VSO Standard %d",
212f1c6118cSZdenek Styblik (rsp->data[3] & 0x03));
213f1c6118cSZdenek Styblik } else if ((rsp->data[4] & 0x0F) != 1) {
214*c04aa9bbSZdenek Styblik lprintf(LOG_INFO, "Unknown VSO Specification Revision %d.%d",
215f1c6118cSZdenek Styblik (rsp->data[4] & 0x0F), (rsp->data[4] >> 4));
216f1c6118cSZdenek Styblik } else {
217f1c6118cSZdenek Styblik vita_avail = 1;
218f1c6118cSZdenek Styblik lprintf(LOG_INFO, "Discovered VITA 46.11 Revision %d.%d",
219f1c6118cSZdenek Styblik (rsp->data[4] & 0x0F), (rsp->data[4] >> 4));
220f1c6118cSZdenek Styblik }
221f1c6118cSZdenek Styblik
222f1c6118cSZdenek Styblik return vita_avail;
223f1c6118cSZdenek Styblik }
224f1c6118cSZdenek Styblik
225f1c6118cSZdenek Styblik uint8_t
ipmi_vita_ipmb_address(struct ipmi_intf * intf)226f1c6118cSZdenek Styblik ipmi_vita_ipmb_address(struct ipmi_intf *intf)
227f1c6118cSZdenek Styblik {
228f1c6118cSZdenek Styblik struct ipmi_rq req;
229f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
230f1c6118cSZdenek Styblik unsigned char msg_data;
231f1c6118cSZdenek Styblik
232f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
233f1c6118cSZdenek Styblik
234f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
235f1c6118cSZdenek Styblik req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
236f1c6118cSZdenek Styblik req.msg.data = &msg_data;
237f1c6118cSZdenek Styblik req.msg.data_len = 1;
238f1c6118cSZdenek Styblik
239f1c6118cSZdenek Styblik msg_data = GROUP_EXT_VITA;
240f1c6118cSZdenek Styblik
241f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
242f1c6118cSZdenek Styblik
243f1c6118cSZdenek Styblik if (rsp == NULL) {
244f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received");
245f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
246f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
247f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
248f1c6118cSZdenek Styblik } else if (rsp->data_len < 7) {
249f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d",
250f1c6118cSZdenek Styblik rsp->data_len);
251f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
252f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x",
253f1c6118cSZdenek Styblik rsp->data[0]);
254f1c6118cSZdenek Styblik } else {
255f1c6118cSZdenek Styblik return rsp->data[2];
256f1c6118cSZdenek Styblik }
257f1c6118cSZdenek Styblik
258f1c6118cSZdenek Styblik return 0;
259f1c6118cSZdenek Styblik }
260f1c6118cSZdenek Styblik
261f1c6118cSZdenek Styblik static int
ipmi_vita_getaddr(struct ipmi_intf * intf,int argc,char ** argv)262f1c6118cSZdenek Styblik ipmi_vita_getaddr(struct ipmi_intf *intf, int argc, char **argv)
263f1c6118cSZdenek Styblik {
264f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
265f1c6118cSZdenek Styblik struct ipmi_rq req;
266f1c6118cSZdenek Styblik unsigned char msg_data[2];
267f1c6118cSZdenek Styblik
268f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
269f1c6118cSZdenek Styblik
270f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
271f1c6118cSZdenek Styblik req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
272f1c6118cSZdenek Styblik req.msg.data = msg_data;
273f1c6118cSZdenek Styblik req.msg.data_len = 2;
274f1c6118cSZdenek Styblik
275f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
276f1c6118cSZdenek Styblik msg_data[1] = 0; /* default FRU ID */
277f1c6118cSZdenek Styblik
278f1c6118cSZdenek Styblik if (argc > 0) {
279f1c6118cSZdenek Styblik /* validate and get FRU Device ID */
280f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) {
281f1c6118cSZdenek Styblik return -1;
282f1c6118cSZdenek Styblik }
283f1c6118cSZdenek Styblik }
284f1c6118cSZdenek Styblik
285f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
286f1c6118cSZdenek Styblik
287f1c6118cSZdenek Styblik if (rsp == NULL) {
288f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received");
289f1c6118cSZdenek Styblik return -1;
290f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
291f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
292f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
293f1c6118cSZdenek Styblik return -1;
294f1c6118cSZdenek Styblik } else if (rsp->data_len < 7) {
295f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d",
296f1c6118cSZdenek Styblik rsp->data_len);
297f1c6118cSZdenek Styblik return -1;
298f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
299f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x",
300f1c6118cSZdenek Styblik rsp->data[0]);
301f1c6118cSZdenek Styblik return -1;
302f1c6118cSZdenek Styblik }
303f1c6118cSZdenek Styblik
304f1c6118cSZdenek Styblik printf("Hardware Address : 0x%02x\n", rsp->data[1]);
305f1c6118cSZdenek Styblik printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]);
306f1c6118cSZdenek Styblik printf("FRU ID : 0x%02x\n", rsp->data[4]);
307f1c6118cSZdenek Styblik printf("Site ID : 0x%02x\n", rsp->data[5]);
308f1c6118cSZdenek Styblik printf("Site Type : %s\n", val2str(rsp->data[6],
309f1c6118cSZdenek Styblik vita_site_types));
310f1c6118cSZdenek Styblik if (rsp->data_len > 8) {
311f1c6118cSZdenek Styblik printf("Channel 7 Address: 0x%02x\n", rsp->data[8]);
312f1c6118cSZdenek Styblik }
313f1c6118cSZdenek Styblik
314f1c6118cSZdenek Styblik return 0;
315f1c6118cSZdenek Styblik }
316f1c6118cSZdenek Styblik
317f1c6118cSZdenek Styblik static int
ipmi_vita_get_vso_capabilities(struct ipmi_intf * intf)318f1c6118cSZdenek Styblik ipmi_vita_get_vso_capabilities(struct ipmi_intf *intf)
319f1c6118cSZdenek Styblik {
320f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
321f1c6118cSZdenek Styblik struct ipmi_rq req;
322f1c6118cSZdenek Styblik unsigned char msg_data, tmp;
323f1c6118cSZdenek Styblik
324f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
325f1c6118cSZdenek Styblik
326f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
327f1c6118cSZdenek Styblik req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
328f1c6118cSZdenek Styblik req.msg.data = &msg_data;
329f1c6118cSZdenek Styblik req.msg.data_len = 1;
330f1c6118cSZdenek Styblik
331f1c6118cSZdenek Styblik msg_data = GROUP_EXT_VITA; /* VITA identifier */
332f1c6118cSZdenek Styblik
333f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
334f1c6118cSZdenek Styblik
335f1c6118cSZdenek Styblik if (rsp == NULL) {
336f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
337f1c6118cSZdenek Styblik return -1;
338f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
339f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
340f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
341f1c6118cSZdenek Styblik return -1;
342f1c6118cSZdenek Styblik } else if (rsp->data_len < 5) {
343f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
344f1c6118cSZdenek Styblik return -1;
345f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
346f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
347f1c6118cSZdenek Styblik return -1;
348f1c6118cSZdenek Styblik }
349f1c6118cSZdenek Styblik
350f1c6118cSZdenek Styblik printf("VSO Identifier : 0x%02x\n", rsp->data[0]);
351f1c6118cSZdenek Styblik printf("IPMC Identifier : 0x%02x\n", rsp->data[1]);
352f1c6118cSZdenek Styblik printf(" Tier %d\n", (rsp->data[1] & 0x03) + 1);
353f1c6118cSZdenek Styblik printf(" Layer %d\n", ((rsp->data[1] & 0x30) >> 4) + 1);
354f1c6118cSZdenek Styblik
355f1c6118cSZdenek Styblik printf("IPMB Capabilities : 0x%02x\n", rsp->data[2]);
356f1c6118cSZdenek Styblik
357f1c6118cSZdenek Styblik tmp = (rsp->data[2] & 0x30) >> 4;
358f1c6118cSZdenek Styblik
359f1c6118cSZdenek Styblik printf(" Frequency %skHz\n",
360f1c6118cSZdenek Styblik tmp == 0 ? "100" : tmp == 1 ? "400" : "RESERVED");
361f1c6118cSZdenek Styblik
362f1c6118cSZdenek Styblik tmp = rsp->data[2] & 3;
363f1c6118cSZdenek Styblik
364f1c6118cSZdenek Styblik if (tmp == 1) {
365f1c6118cSZdenek Styblik printf(" 2 IPMB interfaces supported\n");
366f1c6118cSZdenek Styblik } else if (tmp == 0) {
367f1c6118cSZdenek Styblik printf(" 1 IPMB interface supported\n");
368f1c6118cSZdenek Styblik }
369f1c6118cSZdenek Styblik
370f1c6118cSZdenek Styblik printf("VSO Standard : %s\n",
371f1c6118cSZdenek Styblik (rsp->data[3] & 0x3) == 0 ? "VITA 46.11" : "RESERVED");
372f1c6118cSZdenek Styblik
373f1c6118cSZdenek Styblik printf("VSO Spec Revision : %d.%d\n", rsp->data[4] & 0xf,
374f1c6118cSZdenek Styblik rsp->data[4] >> 4);
375f1c6118cSZdenek Styblik
376f1c6118cSZdenek Styblik printf("Max FRU Device ID : 0x%02x\n", rsp->data[5]);
377f1c6118cSZdenek Styblik printf("FRU Device ID : 0x%02x\n", rsp->data[6]);
378f1c6118cSZdenek Styblik
379f1c6118cSZdenek Styblik return 0;
380f1c6118cSZdenek Styblik }
381f1c6118cSZdenek Styblik
382f1c6118cSZdenek Styblik static int
ipmi_vita_set_fru_activation(struct ipmi_intf * intf,char ** argv,unsigned char command)383f1c6118cSZdenek Styblik ipmi_vita_set_fru_activation(struct ipmi_intf *intf,
384f1c6118cSZdenek Styblik char **argv, unsigned char command)
385f1c6118cSZdenek Styblik {
386f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
387f1c6118cSZdenek Styblik struct ipmi_rq req;
388f1c6118cSZdenek Styblik unsigned char msg_data[3];
389f1c6118cSZdenek Styblik
390f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
391f1c6118cSZdenek Styblik
392f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
393f1c6118cSZdenek Styblik req.msg.cmd = VITA_SET_FRU_ACTIVATION_CMD;
394f1c6118cSZdenek Styblik req.msg.data = msg_data;
395f1c6118cSZdenek Styblik req.msg.data_len = 3;
396f1c6118cSZdenek Styblik
397f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
398f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
399f1c6118cSZdenek Styblik return -1;
400f1c6118cSZdenek Styblik }
401f1c6118cSZdenek Styblik msg_data[2] = command; /* command */
402f1c6118cSZdenek Styblik
403f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
404f1c6118cSZdenek Styblik
405f1c6118cSZdenek Styblik if (rsp == NULL) {
406f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
407f1c6118cSZdenek Styblik return -1;
408f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
409f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
410f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
411f1c6118cSZdenek Styblik return -1;
412f1c6118cSZdenek Styblik } else if (rsp->data_len < 1) {
413f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
414f1c6118cSZdenek Styblik return -1;
415f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
416f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
417f1c6118cSZdenek Styblik return -1;
418f1c6118cSZdenek Styblik }
419f1c6118cSZdenek Styblik
420f1c6118cSZdenek Styblik printf("FRU has been successfully %s\n",
421f1c6118cSZdenek Styblik command ? "activated" : "deactivated");
422f1c6118cSZdenek Styblik
423f1c6118cSZdenek Styblik return 0;
424f1c6118cSZdenek Styblik }
425f1c6118cSZdenek Styblik
426f1c6118cSZdenek Styblik static int
ipmi_vita_get_fru_state_policy_bits(struct ipmi_intf * intf,char ** argv)427f1c6118cSZdenek Styblik ipmi_vita_get_fru_state_policy_bits(struct ipmi_intf *intf, char **argv)
428f1c6118cSZdenek Styblik {
429f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
430f1c6118cSZdenek Styblik struct ipmi_rq req;
431f1c6118cSZdenek Styblik unsigned char msg_data[2];
432f1c6118cSZdenek Styblik
433f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
434f1c6118cSZdenek Styblik
435f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
436f1c6118cSZdenek Styblik req.msg.cmd = VITA_GET_FRU_STATE_POLICY_BITS_CMD;
437f1c6118cSZdenek Styblik req.msg.data = msg_data;
438f1c6118cSZdenek Styblik req.msg.data_len = 2;
439f1c6118cSZdenek Styblik
440f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
441f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
442f1c6118cSZdenek Styblik return -1;
443f1c6118cSZdenek Styblik }
444f1c6118cSZdenek Styblik
445f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
446f1c6118cSZdenek Styblik
447f1c6118cSZdenek Styblik if (rsp == NULL) {
448f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
449f1c6118cSZdenek Styblik return -1;
450f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
451f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
452f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
453f1c6118cSZdenek Styblik return -1;
454f1c6118cSZdenek Styblik } else if (rsp->data_len < 2) {
455f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
456f1c6118cSZdenek Styblik return -1;
457f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
458f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
459f1c6118cSZdenek Styblik return -1;
460f1c6118cSZdenek Styblik }
461f1c6118cSZdenek Styblik
462f1c6118cSZdenek Styblik printf("FRU State Policy Bits: %xh\n", rsp->data[1]);
463f1c6118cSZdenek Styblik printf(" Default-Activation-Locked Policy Bit is %d\n",
464f1c6118cSZdenek Styblik rsp->data[1] & 0x08 ? 1 : 0);
465f1c6118cSZdenek Styblik printf(" Commanded-Deactivation-Ignored Policy Bit is %d\n",
466f1c6118cSZdenek Styblik rsp->data[1] & 0x04 ? 1 : 0);
467f1c6118cSZdenek Styblik printf(" Deactivation-Locked Policy Bit is %d\n",
468f1c6118cSZdenek Styblik rsp->data[1] & 0x02 ? 1 : 0);
469f1c6118cSZdenek Styblik printf(" Activation-Locked Policy Bit is %d\n",
470f1c6118cSZdenek Styblik rsp->data[1] & 0x01);
471f1c6118cSZdenek Styblik
472f1c6118cSZdenek Styblik return 0;
473f1c6118cSZdenek Styblik }
474f1c6118cSZdenek Styblik
475f1c6118cSZdenek Styblik static int
ipmi_vita_set_fru_state_policy_bits(struct ipmi_intf * intf,char ** argv)476f1c6118cSZdenek Styblik ipmi_vita_set_fru_state_policy_bits(struct ipmi_intf *intf, char **argv)
477f1c6118cSZdenek Styblik {
478f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
479f1c6118cSZdenek Styblik struct ipmi_rq req;
480f1c6118cSZdenek Styblik unsigned char msg_data[4];
481f1c6118cSZdenek Styblik
482f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
483f1c6118cSZdenek Styblik
484f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
485f1c6118cSZdenek Styblik req.msg.cmd = VITA_SET_FRU_STATE_POLICY_BITS_CMD;
486f1c6118cSZdenek Styblik req.msg.data = msg_data;
487f1c6118cSZdenek Styblik req.msg.data_len = 4;
488f1c6118cSZdenek Styblik
489f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
490f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
491f1c6118cSZdenek Styblik return -1;
492f1c6118cSZdenek Styblik }
493f1c6118cSZdenek Styblik if (str2uchar(argv[1], &msg_data[2]) != 0) { /* bits mask */
494f1c6118cSZdenek Styblik return -1;
495f1c6118cSZdenek Styblik }
496f1c6118cSZdenek Styblik if (str2uchar(argv[2], &msg_data[3]) != 0) { /* bits */
497f1c6118cSZdenek Styblik return -1;
498f1c6118cSZdenek Styblik }
499f1c6118cSZdenek Styblik
500f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
501f1c6118cSZdenek Styblik
502f1c6118cSZdenek Styblik if (rsp == NULL) {
503f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
504f1c6118cSZdenek Styblik return -1;
505f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
506f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
507f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
508f1c6118cSZdenek Styblik return -1;
509f1c6118cSZdenek Styblik } else if (rsp->data_len < 1) {
510f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
511f1c6118cSZdenek Styblik return -1;
512f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
513f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
514f1c6118cSZdenek Styblik return -1;
515f1c6118cSZdenek Styblik }
516f1c6118cSZdenek Styblik
517f1c6118cSZdenek Styblik printf("FRU state policy bits have been updated\n");
518f1c6118cSZdenek Styblik
519f1c6118cSZdenek Styblik return 0;
520f1c6118cSZdenek Styblik }
521f1c6118cSZdenek Styblik
522f1c6118cSZdenek Styblik static int
ipmi_vita_get_led_properties(struct ipmi_intf * intf,char ** argv)523f1c6118cSZdenek Styblik ipmi_vita_get_led_properties(struct ipmi_intf *intf, char **argv)
524f1c6118cSZdenek Styblik {
525f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
526f1c6118cSZdenek Styblik struct ipmi_rq req;
527f1c6118cSZdenek Styblik unsigned char msg_data[2];
528f1c6118cSZdenek Styblik
529f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
530f1c6118cSZdenek Styblik
531f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
532f1c6118cSZdenek Styblik req.msg.cmd = VITA_GET_FRU_LED_PROPERTIES_CMD;
533f1c6118cSZdenek Styblik req.msg.data = msg_data;
534f1c6118cSZdenek Styblik req.msg.data_len = 2;
535f1c6118cSZdenek Styblik
536f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
537f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
538f1c6118cSZdenek Styblik return -1;
539f1c6118cSZdenek Styblik }
540f1c6118cSZdenek Styblik
541f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
542f1c6118cSZdenek Styblik
543f1c6118cSZdenek Styblik if (rsp == NULL) {
544f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
545f1c6118cSZdenek Styblik return -1;
546f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
547f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
548f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
549f1c6118cSZdenek Styblik return -1;
550f1c6118cSZdenek Styblik } else if (rsp->data_len < 3) {
551f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
552f1c6118cSZdenek Styblik return -1;
553f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
554f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
555f1c6118cSZdenek Styblik return -1;
556f1c6118cSZdenek Styblik }
557f1c6118cSZdenek Styblik
558f1c6118cSZdenek Styblik printf("LED Count: %#x\n", rsp->data[2]);
559f1c6118cSZdenek Styblik
560f1c6118cSZdenek Styblik return 0;
561f1c6118cSZdenek Styblik }
562f1c6118cSZdenek Styblik
563f1c6118cSZdenek Styblik static int
ipmi_vita_get_led_color_capabilities(struct ipmi_intf * intf,char ** argv)564f1c6118cSZdenek Styblik ipmi_vita_get_led_color_capabilities(struct ipmi_intf *intf, char **argv)
565f1c6118cSZdenek Styblik {
566f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
567f1c6118cSZdenek Styblik struct ipmi_rq req;
568f1c6118cSZdenek Styblik unsigned char msg_data[3];
569f1c6118cSZdenek Styblik int i;
570f1c6118cSZdenek Styblik
571f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
572f1c6118cSZdenek Styblik
573f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
574f1c6118cSZdenek Styblik req.msg.cmd = VITA_GET_LED_COLOR_CAPABILITIES_CMD;
575f1c6118cSZdenek Styblik req.msg.data = msg_data;
576f1c6118cSZdenek Styblik req.msg.data_len = 3;
577f1c6118cSZdenek Styblik
578f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
579f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
580f1c6118cSZdenek Styblik return -1;
581f1c6118cSZdenek Styblik }
582f1c6118cSZdenek Styblik if (str2uchar(argv[1], &msg_data[2]) != 0) { /* LED-ID */
583f1c6118cSZdenek Styblik return -1;
584f1c6118cSZdenek Styblik }
585f1c6118cSZdenek Styblik
586f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
587f1c6118cSZdenek Styblik
588f1c6118cSZdenek Styblik if (rsp == NULL) {
589f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
590f1c6118cSZdenek Styblik return -1;
591f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
592f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
593f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
594f1c6118cSZdenek Styblik return -1;
595f1c6118cSZdenek Styblik } else if (rsp->data_len < 5) {
596f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
597f1c6118cSZdenek Styblik return -1;
598f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
599f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
600f1c6118cSZdenek Styblik return -1;
601f1c6118cSZdenek Styblik }
602f1c6118cSZdenek Styblik
603f1c6118cSZdenek Styblik printf("LED Color Capabilities: ");
604f1c6118cSZdenek Styblik for (i = 0; i < 8; i++) {
605f1c6118cSZdenek Styblik if (rsp->data[1] & (0x01 << i)) {
606f1c6118cSZdenek Styblik printf("%s, ", led_color_str[i]);
607f1c6118cSZdenek Styblik }
608f1c6118cSZdenek Styblik }
609f1c6118cSZdenek Styblik putchar('\n');
610f1c6118cSZdenek Styblik
611f1c6118cSZdenek Styblik printf("Default LED Color in\n");
612f1c6118cSZdenek Styblik printf(" LOCAL control: %s\n", led_color_str[rsp->data[2]]);
613f1c6118cSZdenek Styblik printf(" OVERRIDE state: %s\n", led_color_str[rsp->data[3]]);
614f1c6118cSZdenek Styblik
615f1c6118cSZdenek Styblik if (rsp->data_len == 5) {
616f1c6118cSZdenek Styblik printf("LED flags:\n");
617f1c6118cSZdenek Styblik if (rsp->data[4] & 2) {
618f1c6118cSZdenek Styblik printf(" [HW RESTRICT]\n");
619f1c6118cSZdenek Styblik }
620f1c6118cSZdenek Styblik if (rsp->data[4] & 1) {
621f1c6118cSZdenek Styblik printf(" [PAYLOAD PWR]\n");
622f1c6118cSZdenek Styblik }
623f1c6118cSZdenek Styblik }
624f1c6118cSZdenek Styblik
625f1c6118cSZdenek Styblik return 0;
626f1c6118cSZdenek Styblik }
627f1c6118cSZdenek Styblik
628f1c6118cSZdenek Styblik static int
ipmi_vita_get_led_state(struct ipmi_intf * intf,char ** argv)629f1c6118cSZdenek Styblik ipmi_vita_get_led_state(struct ipmi_intf *intf, char **argv)
630f1c6118cSZdenek Styblik {
631f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
632f1c6118cSZdenek Styblik struct ipmi_rq req;
633f1c6118cSZdenek Styblik unsigned char msg_data[3];
634f1c6118cSZdenek Styblik
635f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
636f1c6118cSZdenek Styblik
637f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
638f1c6118cSZdenek Styblik req.msg.cmd = VITA_GET_FRU_LED_STATE_CMD;
639f1c6118cSZdenek Styblik req.msg.data = msg_data;
640f1c6118cSZdenek Styblik req.msg.data_len = 3;
641f1c6118cSZdenek Styblik
642f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
643f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
644f1c6118cSZdenek Styblik return -1;
645f1c6118cSZdenek Styblik }
646f1c6118cSZdenek Styblik if (str2uchar(argv[1], &msg_data[2]) != 0) { /* LED-ID */
647f1c6118cSZdenek Styblik return -1;
648f1c6118cSZdenek Styblik }
649f1c6118cSZdenek Styblik
650f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
651f1c6118cSZdenek Styblik
652f1c6118cSZdenek Styblik if (rsp == NULL) {
653f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
654f1c6118cSZdenek Styblik return -1;
655f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
656f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
657f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
658f1c6118cSZdenek Styblik return -1;
659f1c6118cSZdenek Styblik } else if (rsp->data_len < 5
660f1c6118cSZdenek Styblik || ((rsp->data[1] & 0x2) && rsp->data_len < 8)
661f1c6118cSZdenek Styblik || ((rsp->data[1] & 0x4) && rsp->data_len < 9)) {
662f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
663f1c6118cSZdenek Styblik return -1;
664f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
665f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
666f1c6118cSZdenek Styblik return -1;
667f1c6118cSZdenek Styblik }
668f1c6118cSZdenek Styblik
669f1c6118cSZdenek Styblik printf("LED states: %x\t", rsp->data[1]);
670f1c6118cSZdenek Styblik if (rsp->data[1] & 0x1) {
671f1c6118cSZdenek Styblik printf("[LOCAL CONTROL] ");
672f1c6118cSZdenek Styblik }
673f1c6118cSZdenek Styblik if (rsp->data[1] & 0x2) {
674f1c6118cSZdenek Styblik printf("[OVERRIDE] ");
675f1c6118cSZdenek Styblik }
676f1c6118cSZdenek Styblik if (rsp->data[1] & 0x4) {
677f1c6118cSZdenek Styblik printf("[LAMPTEST] ");
678f1c6118cSZdenek Styblik }
679f1c6118cSZdenek Styblik if (rsp->data[1] & 0x8) {
680f1c6118cSZdenek Styblik printf("[HW RESTRICT] ");
681f1c6118cSZdenek Styblik }
682f1c6118cSZdenek Styblik putchar('\n');
683f1c6118cSZdenek Styblik
684f1c6118cSZdenek Styblik if (rsp->data[1] & 1) {
685f1c6118cSZdenek Styblik printf(" Local Control function: %x\t", rsp->data[2]);
686f1c6118cSZdenek Styblik if (rsp->data[2] == 0x0) {
687f1c6118cSZdenek Styblik printf("[OFF]\n");
688f1c6118cSZdenek Styblik } else if (rsp->data[2] == 0xff) {
689f1c6118cSZdenek Styblik printf("[ON]\n");
690f1c6118cSZdenek Styblik } else {
691f1c6118cSZdenek Styblik printf("[BLINKING]\n");
692f1c6118cSZdenek Styblik }
693f1c6118cSZdenek Styblik printf(" Local Control On-Duration: %x\n", rsp->data[3]);
694f1c6118cSZdenek Styblik printf(" Local Control Color: %x\t[%s]\n",
695f1c6118cSZdenek Styblik rsp->data[4], led_color_str[rsp->data[4] & 7]);
696f1c6118cSZdenek Styblik }
697f1c6118cSZdenek Styblik
698f1c6118cSZdenek Styblik /* override state or lamp test */
699f1c6118cSZdenek Styblik if (rsp->data[1] & 0x06) {
700f1c6118cSZdenek Styblik printf(" Override function: %x\t", rsp->data[5]);
701f1c6118cSZdenek Styblik if (rsp->data[5] == 0x0) {
702f1c6118cSZdenek Styblik printf("[OFF]\n");
703f1c6118cSZdenek Styblik } else if (rsp->data[5] == 0xff) {
704f1c6118cSZdenek Styblik printf("[ON]\n");
705f1c6118cSZdenek Styblik } else {
706f1c6118cSZdenek Styblik printf("[BLINKING]\n");
707f1c6118cSZdenek Styblik }
708f1c6118cSZdenek Styblik printf(" Override On-Duration: %x\n", rsp->data[6]);
709f1c6118cSZdenek Styblik printf(" Override Color: %x\t[%s]\n",
710f1c6118cSZdenek Styblik rsp->data[7], led_color_str[rsp->data[7] & 7]);
711f1c6118cSZdenek Styblik if (rsp->data[1] == 0x04) {
712f1c6118cSZdenek Styblik printf(" Lamp test duration: %x\n", rsp->data[8]);
713f1c6118cSZdenek Styblik }
714f1c6118cSZdenek Styblik }
715f1c6118cSZdenek Styblik
716f1c6118cSZdenek Styblik return 0;
717f1c6118cSZdenek Styblik }
718f1c6118cSZdenek Styblik
719f1c6118cSZdenek Styblik static int
ipmi_vita_set_led_state(struct ipmi_intf * intf,char ** argv)720f1c6118cSZdenek Styblik ipmi_vita_set_led_state(struct ipmi_intf *intf, char **argv)
721f1c6118cSZdenek Styblik {
722f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
723f1c6118cSZdenek Styblik struct ipmi_rq req;
724f1c6118cSZdenek Styblik unsigned char msg_data[6];
725f1c6118cSZdenek Styblik
726f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
727f1c6118cSZdenek Styblik
728f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
729f1c6118cSZdenek Styblik req.msg.cmd = VITA_SET_FRU_LED_STATE_CMD;
730f1c6118cSZdenek Styblik req.msg.data = msg_data;
731f1c6118cSZdenek Styblik req.msg.data_len = 6;
732f1c6118cSZdenek Styblik
733f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
734f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
735f1c6118cSZdenek Styblik return -1;
736f1c6118cSZdenek Styblik }
737f1c6118cSZdenek Styblik if (str2uchar(argv[1], &msg_data[2]) != 0) { /* LED-ID */
738f1c6118cSZdenek Styblik return -1;
739f1c6118cSZdenek Styblik }
740f1c6118cSZdenek Styblik if (str2uchar(argv[2], &msg_data[3]) != 0) { /* LED function */
741f1c6118cSZdenek Styblik return -1;
742f1c6118cSZdenek Styblik }
743f1c6118cSZdenek Styblik if (str2uchar(argv[3], &msg_data[4]) != 0) { /* LED on duration */
744f1c6118cSZdenek Styblik return -1;
745f1c6118cSZdenek Styblik }
746f1c6118cSZdenek Styblik if (str2uchar(argv[4], &msg_data[5]) != 0) { /* LED color */
747f1c6118cSZdenek Styblik return -1;
748f1c6118cSZdenek Styblik }
749f1c6118cSZdenek Styblik
750f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
751f1c6118cSZdenek Styblik
752f1c6118cSZdenek Styblik if (rsp == NULL) {
753f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
754f1c6118cSZdenek Styblik return -1;
755f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
756f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
757f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
758f1c6118cSZdenek Styblik return -1;
759f1c6118cSZdenek Styblik } else if (rsp->data_len < 1) {
760f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
761f1c6118cSZdenek Styblik return -1;
762f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
763f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
764f1c6118cSZdenek Styblik return -1;
765f1c6118cSZdenek Styblik }
766f1c6118cSZdenek Styblik
767f1c6118cSZdenek Styblik printf("LED state has been updated\n");
768f1c6118cSZdenek Styblik
769f1c6118cSZdenek Styblik return 0;
770f1c6118cSZdenek Styblik }
771f1c6118cSZdenek Styblik
772f1c6118cSZdenek Styblik static int
ipmi_vita_fru_control(struct ipmi_intf * intf,char ** argv)773f1c6118cSZdenek Styblik ipmi_vita_fru_control(struct ipmi_intf *intf, char **argv)
774f1c6118cSZdenek Styblik {
775f1c6118cSZdenek Styblik struct ipmi_rs *rsp;
776f1c6118cSZdenek Styblik struct ipmi_rq req;
777f1c6118cSZdenek Styblik unsigned char msg_data[3];
778f1c6118cSZdenek Styblik
779f1c6118cSZdenek Styblik memset(&req, 0, sizeof(req));
780f1c6118cSZdenek Styblik
781f1c6118cSZdenek Styblik req.msg.netfn = IPMI_NETFN_PICMG;
782f1c6118cSZdenek Styblik req.msg.cmd = VITA_FRU_CONTROL_CMD;
783f1c6118cSZdenek Styblik req.msg.data = msg_data;
784f1c6118cSZdenek Styblik req.msg.data_len = 3;
785f1c6118cSZdenek Styblik
786f1c6118cSZdenek Styblik msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
787f1c6118cSZdenek Styblik if (is_fru_id(argv[0], &msg_data[1]) != 0) { /* FRU ID */
788f1c6118cSZdenek Styblik return -1;
789f1c6118cSZdenek Styblik }
790f1c6118cSZdenek Styblik if (str2uchar(argv[1], &msg_data[2]) != 0) { /* control option */
791f1c6118cSZdenek Styblik return -1;
792f1c6118cSZdenek Styblik }
793f1c6118cSZdenek Styblik
794f1c6118cSZdenek Styblik printf("FRU Device Id: %d FRU Control Option: %s\n", msg_data[1],
795f1c6118cSZdenek Styblik val2str(msg_data[2], picmg_frucontrol_vals));
796f1c6118cSZdenek Styblik
797f1c6118cSZdenek Styblik rsp = intf->sendrecv(intf, &req);
798f1c6118cSZdenek Styblik
799f1c6118cSZdenek Styblik if (rsp == NULL) {
800f1c6118cSZdenek Styblik lprintf(LOG_ERR, "No valid response received.");
801f1c6118cSZdenek Styblik return -1;
802f1c6118cSZdenek Styblik } else if (rsp->ccode != 0) {
803f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid completion code received: %s",
804f1c6118cSZdenek Styblik val2str(rsp->ccode, completion_code_vals));
805f1c6118cSZdenek Styblik return -1;
806f1c6118cSZdenek Styblik } else if (rsp->data_len < 1) {
807f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid response length %d", rsp->data_len);
808f1c6118cSZdenek Styblik return -1;
809f1c6118cSZdenek Styblik } else if (rsp->data[0] != GROUP_EXT_VITA) {
810f1c6118cSZdenek Styblik lprintf(LOG_ERR, "Invalid group extension %#x", rsp->data[0]);
811f1c6118cSZdenek Styblik return -1;
812f1c6118cSZdenek Styblik }
813f1c6118cSZdenek Styblik
814f1c6118cSZdenek Styblik printf("FRU Control: ok\n");
815f1c6118cSZdenek Styblik
816f1c6118cSZdenek Styblik return 0;
817f1c6118cSZdenek Styblik }
818f1c6118cSZdenek Styblik
819f1c6118cSZdenek Styblik static int
ipmi_vita_get_cmd(int argc,char ** argv)820f1c6118cSZdenek Styblik ipmi_vita_get_cmd(int argc, char **argv)
821f1c6118cSZdenek Styblik {
822f1c6118cSZdenek Styblik if (argc < 1 || !strncmp(argv[0], "help", 4)) {
823f1c6118cSZdenek Styblik return VITA_CMD_HELP;
824f1c6118cSZdenek Styblik }
825f1c6118cSZdenek Styblik
826f1c6118cSZdenek Styblik /* Get VSO Properties */
827f1c6118cSZdenek Styblik if (!strncmp(argv[0], "properties", 10)) {
828f1c6118cSZdenek Styblik return VITA_CMD_PROPERTIES;
829f1c6118cSZdenek Styblik }
830f1c6118cSZdenek Styblik
831f1c6118cSZdenek Styblik /* FRU Control command */
832f1c6118cSZdenek Styblik if (!strncmp(argv[0], "frucontrol", 10)) {
833f1c6118cSZdenek Styblik return VITA_CMD_FRUCONTROL;
834f1c6118cSZdenek Styblik }
835f1c6118cSZdenek Styblik
836f1c6118cSZdenek Styblik /* Get FRU Address Info command */
837f1c6118cSZdenek Styblik if (!strncmp(argv[0], "addrinfo", 8)) {
838f1c6118cSZdenek Styblik return VITA_CMD_ADDRINFO;
839f1c6118cSZdenek Styblik }
840f1c6118cSZdenek Styblik
841f1c6118cSZdenek Styblik /* Set FRU Activation (activate) command */
842f1c6118cSZdenek Styblik if (!strncmp(argv[0], "activate", 8)) {
843f1c6118cSZdenek Styblik return VITA_CMD_ACTIVATE;
844f1c6118cSZdenek Styblik }
845f1c6118cSZdenek Styblik
846f1c6118cSZdenek Styblik /* Set FRU Activation (deactivate) command */
847f1c6118cSZdenek Styblik if (!strncmp(argv[0], "deactivate", 10)) {
848f1c6118cSZdenek Styblik return VITA_CMD_DEACTIVATE;
849f1c6118cSZdenek Styblik }
850f1c6118cSZdenek Styblik
851f1c6118cSZdenek Styblik /* FRU State Policy Bits commands */
852f1c6118cSZdenek Styblik if (!strncmp(argv[0], "policy", 6)) {
853f1c6118cSZdenek Styblik if (argc < 2) {
854f1c6118cSZdenek Styblik return VITA_CMD_UNKNOWN;
855f1c6118cSZdenek Styblik }
856f1c6118cSZdenek Styblik
857f1c6118cSZdenek Styblik /* Get FRU State Policy Bits command */
858f1c6118cSZdenek Styblik if (!strncmp(argv[1], "get", 3)) {
859f1c6118cSZdenek Styblik return VITA_CMD_POLICY_GET;
860f1c6118cSZdenek Styblik }
861f1c6118cSZdenek Styblik
862f1c6118cSZdenek Styblik /* Set FRU State Policy Bits command */
863f1c6118cSZdenek Styblik if (!strncmp(argv[1], "set", 3)) {
864f1c6118cSZdenek Styblik return VITA_CMD_POLICY_SET;
865f1c6118cSZdenek Styblik }
866f1c6118cSZdenek Styblik
867f1c6118cSZdenek Styblik /* unknown command */
868f1c6118cSZdenek Styblik return VITA_CMD_UNKNOWN;
869f1c6118cSZdenek Styblik }
870f1c6118cSZdenek Styblik
871f1c6118cSZdenek Styblik /* FRU LED commands */
872f1c6118cSZdenek Styblik if (!strncmp(argv[0], "led", 3)) {
873f1c6118cSZdenek Styblik if (argc < 2) {
874f1c6118cSZdenek Styblik return VITA_CMD_UNKNOWN;
875f1c6118cSZdenek Styblik }
876f1c6118cSZdenek Styblik
877f1c6118cSZdenek Styblik /* FRU LED Get Properties */
878f1c6118cSZdenek Styblik if (!strncmp(argv[1], "prop", 4)) {
879f1c6118cSZdenek Styblik return VITA_CMD_LED_PROP;
880f1c6118cSZdenek Styblik }
881f1c6118cSZdenek Styblik
882f1c6118cSZdenek Styblik /* FRU LED Get Capabilities */
883f1c6118cSZdenek Styblik if (!strncmp(argv[1], "cap", 3)) {
884f1c6118cSZdenek Styblik return VITA_CMD_LED_CAP;
885f1c6118cSZdenek Styblik }
886f1c6118cSZdenek Styblik
887f1c6118cSZdenek Styblik /* FRU LED Get State */
888f1c6118cSZdenek Styblik if (!strncmp(argv[1], "get", 3)) {
889f1c6118cSZdenek Styblik return VITA_CMD_LED_GET;
890f1c6118cSZdenek Styblik }
891f1c6118cSZdenek Styblik
892f1c6118cSZdenek Styblik /* FRU LED Set State */
893f1c6118cSZdenek Styblik if (!strncmp(argv[1], "set", 3)) {
894f1c6118cSZdenek Styblik return VITA_CMD_LED_SET;
895f1c6118cSZdenek Styblik }
896f1c6118cSZdenek Styblik
897f1c6118cSZdenek Styblik /* unknown command */
898f1c6118cSZdenek Styblik return VITA_CMD_UNKNOWN;
899f1c6118cSZdenek Styblik }
900f1c6118cSZdenek Styblik
901f1c6118cSZdenek Styblik /* unknown command */
902f1c6118cSZdenek Styblik return VITA_CMD_UNKNOWN;
903f1c6118cSZdenek Styblik }
904f1c6118cSZdenek Styblik
905f1c6118cSZdenek Styblik int
ipmi_vita_main(struct ipmi_intf * intf,int argc,char ** argv)906f1c6118cSZdenek Styblik ipmi_vita_main (struct ipmi_intf *intf, int argc, char **argv)
907f1c6118cSZdenek Styblik {
908f1c6118cSZdenek Styblik int rc = -1, show_help = 0;
909f1c6118cSZdenek Styblik int cmd = ipmi_vita_get_cmd(argc, argv);
910f1c6118cSZdenek Styblik
911f1c6118cSZdenek Styblik switch (cmd) {
912f1c6118cSZdenek Styblik case VITA_CMD_HELP:
913f1c6118cSZdenek Styblik cmd = ipmi_vita_get_cmd(argc - 1, &argv[1]);
914f1c6118cSZdenek Styblik show_help = 1;
915f1c6118cSZdenek Styblik rc = 0;
916f1c6118cSZdenek Styblik break;
917f1c6118cSZdenek Styblik
918f1c6118cSZdenek Styblik case VITA_CMD_PROPERTIES:
919f1c6118cSZdenek Styblik rc = ipmi_vita_get_vso_capabilities(intf);
920f1c6118cSZdenek Styblik break;
921f1c6118cSZdenek Styblik
922f1c6118cSZdenek Styblik case VITA_CMD_FRUCONTROL:
923f1c6118cSZdenek Styblik if (argc > 2) {
924f1c6118cSZdenek Styblik rc = ipmi_vita_fru_control(intf, &argv[1]);
925f1c6118cSZdenek Styblik } else {
926f1c6118cSZdenek Styblik show_help = 1;
927f1c6118cSZdenek Styblik }
928f1c6118cSZdenek Styblik break;
929f1c6118cSZdenek Styblik
930f1c6118cSZdenek Styblik case VITA_CMD_ADDRINFO:
931f1c6118cSZdenek Styblik rc = ipmi_vita_getaddr(intf, argc - 1, &argv[1]);
932f1c6118cSZdenek Styblik break;
933f1c6118cSZdenek Styblik
934f1c6118cSZdenek Styblik case VITA_CMD_ACTIVATE:
935f1c6118cSZdenek Styblik if (argc > 1) {
936f1c6118cSZdenek Styblik rc = ipmi_vita_set_fru_activation(intf, &argv[1], 1);
937f1c6118cSZdenek Styblik } else {
938f1c6118cSZdenek Styblik show_help = 1;
939f1c6118cSZdenek Styblik }
940f1c6118cSZdenek Styblik break;
941f1c6118cSZdenek Styblik
942f1c6118cSZdenek Styblik case VITA_CMD_DEACTIVATE:
943f1c6118cSZdenek Styblik if (argc > 1) {
944f1c6118cSZdenek Styblik rc = ipmi_vita_set_fru_activation(intf, &argv[1], 0);
945f1c6118cSZdenek Styblik } else {
946f1c6118cSZdenek Styblik show_help = 1;
947f1c6118cSZdenek Styblik }
948f1c6118cSZdenek Styblik break;
949f1c6118cSZdenek Styblik
950f1c6118cSZdenek Styblik case VITA_CMD_POLICY_GET:
951f1c6118cSZdenek Styblik if (argc > 2) {
952f1c6118cSZdenek Styblik rc = ipmi_vita_get_fru_state_policy_bits(intf,
953f1c6118cSZdenek Styblik &argv[2]);
954f1c6118cSZdenek Styblik } else {
955f1c6118cSZdenek Styblik show_help = 1;
956f1c6118cSZdenek Styblik }
957f1c6118cSZdenek Styblik break;
958f1c6118cSZdenek Styblik
959f1c6118cSZdenek Styblik case VITA_CMD_POLICY_SET:
960f1c6118cSZdenek Styblik if (argc > 4) {
961f1c6118cSZdenek Styblik rc = ipmi_vita_set_fru_state_policy_bits(intf,
962f1c6118cSZdenek Styblik &argv[2]);
963f1c6118cSZdenek Styblik } else {
964f1c6118cSZdenek Styblik show_help = 1;
965f1c6118cSZdenek Styblik }
966f1c6118cSZdenek Styblik break;
967f1c6118cSZdenek Styblik
968f1c6118cSZdenek Styblik case VITA_CMD_LED_PROP:
969f1c6118cSZdenek Styblik if (argc > 2) {
970f1c6118cSZdenek Styblik rc = ipmi_vita_get_led_properties(intf, &argv[2]);
971f1c6118cSZdenek Styblik } else {
972f1c6118cSZdenek Styblik show_help = 1;
973f1c6118cSZdenek Styblik }
974f1c6118cSZdenek Styblik break;
975f1c6118cSZdenek Styblik
976f1c6118cSZdenek Styblik case VITA_CMD_LED_CAP:
977f1c6118cSZdenek Styblik if (argc > 3) {
978f1c6118cSZdenek Styblik rc = ipmi_vita_get_led_color_capabilities(intf,
979f1c6118cSZdenek Styblik &argv[2]);
980f1c6118cSZdenek Styblik } else {
981f1c6118cSZdenek Styblik show_help = 1;
982f1c6118cSZdenek Styblik }
983f1c6118cSZdenek Styblik break;
984f1c6118cSZdenek Styblik
985f1c6118cSZdenek Styblik case VITA_CMD_LED_GET:
986f1c6118cSZdenek Styblik if (argc > 3) {
987f1c6118cSZdenek Styblik rc = ipmi_vita_get_led_state(intf, &argv[2]);
988f1c6118cSZdenek Styblik } else {
989f1c6118cSZdenek Styblik show_help = 1;
990f1c6118cSZdenek Styblik }
991f1c6118cSZdenek Styblik break;
992f1c6118cSZdenek Styblik
993f1c6118cSZdenek Styblik case VITA_CMD_LED_SET:
994f1c6118cSZdenek Styblik if (argc > 6) {
995f1c6118cSZdenek Styblik rc = ipmi_vita_set_led_state(intf, &argv[2]);
996f1c6118cSZdenek Styblik } else {
997f1c6118cSZdenek Styblik show_help = 1;
998f1c6118cSZdenek Styblik }
999f1c6118cSZdenek Styblik break;
1000f1c6118cSZdenek Styblik default:
1001f1c6118cSZdenek Styblik lprintf(LOG_NOTICE, "Unknown command");
1002f1c6118cSZdenek Styblik cmd = VITA_CMD_HELP;
1003f1c6118cSZdenek Styblik show_help = 1;
1004f1c6118cSZdenek Styblik break;
1005f1c6118cSZdenek Styblik }
1006f1c6118cSZdenek Styblik
1007f1c6118cSZdenek Styblik if (show_help) {
1008f1c6118cSZdenek Styblik lprintf(LOG_NOTICE, "%s", val2str(cmd, vita_help_strings));
1009f1c6118cSZdenek Styblik }
1010f1c6118cSZdenek Styblik
1011f1c6118cSZdenek Styblik return rc;
1012f1c6118cSZdenek Styblik }
1013