xref: /openbmc/ipmitool/lib/ipmi_delloem.c (revision 169d9ac3)
1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen  * Copyright (c) 2008, Dell Inc
3c18ec02fSPetter Reinholdtsen  * All rights reserved.
4c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
5c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions are met:
6c18ec02fSPetter Reinholdtsen  * - Redistributions of source code must retain the above copyright notice,
7c18ec02fSPetter Reinholdtsen  * this list of conditions and the following disclaimer.
8c18ec02fSPetter Reinholdtsen  *
9c18ec02fSPetter Reinholdtsen  * - Redistributions in binary form must reproduce the above copyright notice,
10c18ec02fSPetter Reinholdtsen  * this list of conditions and the following disclaimer in the documentation
11c18ec02fSPetter Reinholdtsen  * and/or other materials provided with the distribution.
12c18ec02fSPetter Reinholdtsen  * - Neither the name of Dell Inc nor the names of its contributors
13c18ec02fSPetter Reinholdtsen  * may be used to endorse or promote products derived from this software
14c18ec02fSPetter Reinholdtsen  * without specific prior written permission.
15c18ec02fSPetter Reinholdtsen  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16c18ec02fSPetter Reinholdtsen  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17c18ec02fSPetter Reinholdtsen  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18c18ec02fSPetter Reinholdtsen  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19c18ec02fSPetter Reinholdtsen  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20c18ec02fSPetter Reinholdtsen  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21c18ec02fSPetter Reinholdtsen  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22c18ec02fSPetter Reinholdtsen  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23c18ec02fSPetter Reinholdtsen  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24c18ec02fSPetter Reinholdtsen  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25c18ec02fSPetter Reinholdtsen  * POSSIBILITY OF SUCH DAMAGE.
26c18ec02fSPetter Reinholdtsen  */
27c18ec02fSPetter Reinholdtsen /*
28c18ec02fSPetter Reinholdtsen  * Thursday Oct 7 17:30:12 2009
29c18ec02fSPetter Reinholdtsen  * <deepaganesh_paulraj@dell.com>
30c18ec02fSPetter Reinholdtsen  *
31c18ec02fSPetter Reinholdtsen  * This code implements a dell OEM proprietary commands.
32c18ec02fSPetter Reinholdtsen  * This Code is edited and Implemented the License feature for Delloem
33c18ec02fSPetter Reinholdtsen  * Author Harsha S <Harsha_S1@dell.com>
34c18ec02fSPetter Reinholdtsen  */
35c18ec02fSPetter Reinholdtsen #include <stdlib.h>
36c18ec02fSPetter Reinholdtsen #include <stdio.h>
37c18ec02fSPetter Reinholdtsen #include <string.h>
38c18ec02fSPetter Reinholdtsen #include <sys/types.h>
39c18ec02fSPetter Reinholdtsen #include <sys/socket.h>
40c18ec02fSPetter Reinholdtsen #include <netinet/in.h>
41c18ec02fSPetter Reinholdtsen #include <arpa/inet.h>
42c18ec02fSPetter Reinholdtsen #include <errno.h>
43c18ec02fSPetter Reinholdtsen #include <unistd.h>
44c18ec02fSPetter Reinholdtsen #include <signal.h>
45c18ec02fSPetter Reinholdtsen #include <ctype.h>
46c18ec02fSPetter Reinholdtsen #include <limits.h>
47c18ec02fSPetter Reinholdtsen #include <time.h>
48c18ec02fSPetter Reinholdtsen 
49c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
50c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
51c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
52c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
53c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sel.h>
54c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_delloem.h>
55c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_fru.h>
56c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
57c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_mc.h>
58c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sensor.h>
59c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sel.h>
60c18ec02fSPetter Reinholdtsen #include <ipmitool/bswap.h>
61c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
62c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_entity.h>
63c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_fru.h>
64c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sensor.h>
65c18ec02fSPetter Reinholdtsen 
66c18ec02fSPetter Reinholdtsen #define DELL_OEM_NETFN	(uint8_t)(0x30)
67c18ec02fSPetter Reinholdtsen #define GET_IDRAC_VIRTUAL_MAC	(uint8_t)(0xC9)
68c18ec02fSPetter Reinholdtsen /* 11g Support Macros */
69c18ec02fSPetter Reinholdtsen #define INVALID	(-1)
70c18ec02fSPetter Reinholdtsen #define SHARED	0
71c18ec02fSPetter Reinholdtsen #define SHARED_WITH_FAILOVER_LOM2	1
72c18ec02fSPetter Reinholdtsen #define DEDICATED	2
73c18ec02fSPetter Reinholdtsen #define SHARED_WITH_FAILOVER_ALL_LOMS	3
74c18ec02fSPetter Reinholdtsen /* 11g Support Macros */
75c18ec02fSPetter Reinholdtsen #define SHARED 				0
76c18ec02fSPetter Reinholdtsen #define SHARED_WITH_FAILOVER_LOM2 	1
77c18ec02fSPetter Reinholdtsen #define DEDICATED 			2
78c18ec02fSPetter Reinholdtsen #define SHARED_WITH_FAILOVER_ALL_LOMS 	3
79c18ec02fSPetter Reinholdtsen /* 12g Support Strings for nic selection */
80c18ec02fSPetter Reinholdtsen #define	INVAILD_FAILOVER_MODE		-2
81c18ec02fSPetter Reinholdtsen #define	INVAILD_FAILOVER_MODE_SETTINGS	-3
82c18ec02fSPetter Reinholdtsen #define	INVAILD_SHARED_MODE		-4
83c18ec02fSPetter Reinholdtsen 
84c18ec02fSPetter Reinholdtsen #define	INVAILD_FAILOVER_MODE_STRING "ERROR: Cannot set shared with failover lom same as current shared lom."
85c18ec02fSPetter Reinholdtsen #define	INVAILD_FAILOVER_MODE_SET "ERROR: Cannot set shared with failover loms when NIC is set to dedicated Mode."
86c18ec02fSPetter Reinholdtsen #define	INVAILD_SHARED_MODE_SET_STRING "ERROR: Cannot set shared Mode for Blades."
87c18ec02fSPetter Reinholdtsen 
88c18ec02fSPetter Reinholdtsen char AciveLOM_String [6] [10] = {
89c18ec02fSPetter Reinholdtsen 	"None",
90c18ec02fSPetter Reinholdtsen 	"LOM1",
91c18ec02fSPetter Reinholdtsen 	"LOM2",
92c18ec02fSPetter Reinholdtsen 	"LOM3",
93c18ec02fSPetter Reinholdtsen 	"LOM4",
94c18ec02fSPetter Reinholdtsen 	"dedicated"
95c18ec02fSPetter Reinholdtsen };
96c18ec02fSPetter Reinholdtsen /* 11g Support Strings for nic selection */
97c18ec02fSPetter Reinholdtsen char NIC_Selection_Mode_String [4] [50] = {
98c18ec02fSPetter Reinholdtsen 	"shared",
99c18ec02fSPetter Reinholdtsen 	"shared with failover lom2",
100c18ec02fSPetter Reinholdtsen 	"dedicated",
101c18ec02fSPetter Reinholdtsen 	"shared with Failover all loms"
102c18ec02fSPetter Reinholdtsen };
103c18ec02fSPetter Reinholdtsen 
104c18ec02fSPetter Reinholdtsen char NIC_Selection_Mode_String_12g[] [50] = {
105c18ec02fSPetter Reinholdtsen 	"dedicated",
106c18ec02fSPetter Reinholdtsen 	"shared with lom1",
107c18ec02fSPetter Reinholdtsen 	"shared with lom2",
108c18ec02fSPetter Reinholdtsen 	"shared with lom3",
109c18ec02fSPetter Reinholdtsen 	"shared with lom4",
110c18ec02fSPetter Reinholdtsen 	"shared with failover lom1",
111c18ec02fSPetter Reinholdtsen 	"shared with failover lom2",
112c18ec02fSPetter Reinholdtsen 	"shared with failover lom3",
113c18ec02fSPetter Reinholdtsen 	"shared with failover lom4",
114c18ec02fSPetter Reinholdtsen 	"shared with failover all loms"
115c18ec02fSPetter Reinholdtsen };
116c18ec02fSPetter Reinholdtsen 
117c18ec02fSPetter Reinholdtsen const struct vFlashstr vFlash_completion_code_vals[] = {
118c18ec02fSPetter Reinholdtsen 	{0x00, "SUCCESS"},
119c18ec02fSPetter Reinholdtsen 	{0x01, "NO_SD_CARD"},
120c18ec02fSPetter Reinholdtsen 	{0x63, "UNKNOWN_ERROR"},
121c18ec02fSPetter Reinholdtsen 	{0x00, NULL}
122c18ec02fSPetter Reinholdtsen };
123c18ec02fSPetter Reinholdtsen 
124c18ec02fSPetter Reinholdtsen static int current_arg =0;
125c18ec02fSPetter Reinholdtsen uint8_t iDRAC_FLAG=0;
126859e8a45SZdenek Styblik 
127859e8a45SZdenek Styblik /*
128859e8a45SZdenek Styblik  * new flags for
129859e8a45SZdenek Styblik  * 11G || 12G || 13G  -> _ALL
130859e8a45SZdenek Styblik  * 12G || 13G -> _12_13
131859e8a45SZdenek Styblik  *
132859e8a45SZdenek Styblik  */
133859e8a45SZdenek Styblik uint8_t iDRAC_FLAG_ALL=0;
134859e8a45SZdenek Styblik uint8_t iDRAC_FLAG_12_13=0;
135859e8a45SZdenek Styblik 
136c18ec02fSPetter Reinholdtsen LCD_MODE lcd_mode;
137c18ec02fSPetter Reinholdtsen static uint8_t LcdSupported=0;
138c18ec02fSPetter Reinholdtsen static uint8_t SetLEDSupported=0;
139c18ec02fSPetter Reinholdtsen 
140c18ec02fSPetter Reinholdtsen volatile uint8_t IMC_Type = IMC_IDRAC_10G;
141c18ec02fSPetter Reinholdtsen 
142c18ec02fSPetter Reinholdtsen POWER_HEADROOM powerheadroom;
143c18ec02fSPetter Reinholdtsen 
144c18ec02fSPetter Reinholdtsen uint8_t PowercapSetable_flag=0;
145c18ec02fSPetter Reinholdtsen uint8_t PowercapstatusFlag=0;
146c18ec02fSPetter Reinholdtsen 
147c18ec02fSPetter Reinholdtsen static void usage(void);
148c18ec02fSPetter Reinholdtsen /* LCD Function prototypes */
149c18ec02fSPetter Reinholdtsen static int ipmi_delloem_lcd_main(struct ipmi_intf *intf, int argc,
150c18ec02fSPetter Reinholdtsen 		char **argv);
151c18ec02fSPetter Reinholdtsen int ipmi_lcd_get_platform_model_name(struct ipmi_intf *intf, char *lcdstring,
152c18ec02fSPetter Reinholdtsen 		uint8_t max_length, uint8_t field_type);
153c18ec02fSPetter Reinholdtsen static int ipmi_idracvalidator_command(struct ipmi_intf *intf);
154c18ec02fSPetter Reinholdtsen static int ipmi_lcd_get_configure_command_wh(struct ipmi_intf *intf);
155c18ec02fSPetter Reinholdtsen static int ipmi_lcd_get_configure_command(struct ipmi_intf *intf,
156c18ec02fSPetter Reinholdtsen 		uint8_t *command);
157c18ec02fSPetter Reinholdtsen static int ipmi_lcd_set_configure_command(struct ipmi_intf *intf, int command);
158c18ec02fSPetter Reinholdtsen static int ipmi_lcd_set_configure_command_wh(struct ipmi_intf *intf, uint32_t  mode,
159c18ec02fSPetter Reinholdtsen 		uint16_t lcdquallifier,uint8_t errordisp);
160c18ec02fSPetter Reinholdtsen static int ipmi_lcd_get_single_line_text(struct ipmi_intf *intf,
161c18ec02fSPetter Reinholdtsen 		char *lcdstring, uint8_t max_length);
162c18ec02fSPetter Reinholdtsen static int ipmi_lcd_get_info_wh(struct ipmi_intf *intf);
163c18ec02fSPetter Reinholdtsen static int ipmi_lcd_get_info(struct ipmi_intf *intf);
164c18ec02fSPetter Reinholdtsen static int ipmi_lcd_get_status_val(struct ipmi_intf *intf,
165c18ec02fSPetter Reinholdtsen 		LCD_STATUS *lcdstatus);
166c18ec02fSPetter Reinholdtsen static int IsLCDSupported();
167c18ec02fSPetter Reinholdtsen static void CheckLCDSupport(struct ipmi_intf *intf);
168c18ec02fSPetter Reinholdtsen static void ipmi_lcd_status_print(LCD_STATUS lcdstatus);
169c18ec02fSPetter Reinholdtsen static int ipmi_lcd_get_status(struct ipmi_intf *intf);
170c18ec02fSPetter Reinholdtsen static int ipmi_lcd_set_kvm(struct ipmi_intf *intf, char status);
171c18ec02fSPetter Reinholdtsen static int ipmi_lcd_set_lock(struct ipmi_intf *intf,  char lock);
172c18ec02fSPetter Reinholdtsen static int ipmi_lcd_set_single_line_text(struct ipmi_intf *intf, char *text);
173c18ec02fSPetter Reinholdtsen static int ipmi_lcd_set_text(struct ipmi_intf *intf, char *text,
174c18ec02fSPetter Reinholdtsen 		int line_number);
175c18ec02fSPetter Reinholdtsen static int ipmi_lcd_configure_wh(struct ipmi_intf *intf, uint32_t mode,
176c18ec02fSPetter Reinholdtsen 		uint16_t lcdquallifier, uint8_t errordisp, int8_t line_number, char *text);
177c18ec02fSPetter Reinholdtsen static int ipmi_lcd_configure(struct ipmi_intf *intf, int command,
178c18ec02fSPetter Reinholdtsen 		int8_t line_number, char *text);
179c18ec02fSPetter Reinholdtsen static void ipmi_lcd_usage(void);
180c18ec02fSPetter Reinholdtsen /* MAC Function prototypes */
181c18ec02fSPetter Reinholdtsen static int ipmi_delloem_mac_main(struct ipmi_intf *intf, int argc, char **argv);
182c18ec02fSPetter Reinholdtsen static void InitEmbeddedNICMacAddressValues();
183c18ec02fSPetter Reinholdtsen static int ipmi_macinfo_drac_idrac_virtual_mac(struct ipmi_intf *intf,
184c18ec02fSPetter Reinholdtsen 		uint8_t NicNum);
185c18ec02fSPetter Reinholdtsen static int ipmi_macinfo_drac_idrac_mac(struct ipmi_intf *intf,uint8_t NicNum);
186c18ec02fSPetter Reinholdtsen static int ipmi_macinfo_10g(struct ipmi_intf *intf, uint8_t NicNum);
187c18ec02fSPetter Reinholdtsen static int ipmi_macinfo_11g(struct ipmi_intf *intf, uint8_t NicNum);
188c18ec02fSPetter Reinholdtsen static int ipmi_macinfo(struct ipmi_intf *intf, uint8_t NicNum);
189c18ec02fSPetter Reinholdtsen static void ipmi_mac_usage(void);
190c18ec02fSPetter Reinholdtsen /* LAN Function prototypes */
191c18ec02fSPetter Reinholdtsen static int ipmi_delloem_lan_main(struct ipmi_intf *intf, int argc, char **argv);
192c18ec02fSPetter Reinholdtsen static int IsLANSupported();
193c18ec02fSPetter Reinholdtsen static int get_nic_selection_mode(int current_arg, char **argv);
194c18ec02fSPetter Reinholdtsen static int ipmi_lan_set_nic_selection(struct ipmi_intf *intf,
195c18ec02fSPetter Reinholdtsen 		uint8_t nic_selection);
196c18ec02fSPetter Reinholdtsen static int ipmi_lan_get_nic_selection(struct ipmi_intf *intf);
197c18ec02fSPetter Reinholdtsen static int ipmi_lan_get_active_nic(struct ipmi_intf *intf);
198c18ec02fSPetter Reinholdtsen static void ipmi_lan_usage(void);
199c18ec02fSPetter Reinholdtsen static int ipmi_lan_set_nic_selection_12g(struct ipmi_intf *intf,
200c18ec02fSPetter Reinholdtsen 		uint8_t *nic_selection);
201c18ec02fSPetter Reinholdtsen /* Power monitor Function prototypes */
202c18ec02fSPetter Reinholdtsen static int ipmi_delloem_powermonitor_main(struct ipmi_intf *intf, int argc,
203c18ec02fSPetter Reinholdtsen 		char **argv);
204c18ec02fSPetter Reinholdtsen static void ipmi_time_to_str(time_t rawTime, char *strTime);
205c18ec02fSPetter Reinholdtsen static int ipmi_get_sensor_reading(struct ipmi_intf *intf,
206c18ec02fSPetter Reinholdtsen 		unsigned char sensorNumber, SensorReadingType *pSensorReadingData);
207c18ec02fSPetter Reinholdtsen static int ipmi_get_power_capstatus_command(struct ipmi_intf *intf);
208c18ec02fSPetter Reinholdtsen static int ipmi_set_power_capstatus_command(struct ipmi_intf *intf,
209c18ec02fSPetter Reinholdtsen 		uint8_t val);
210c18ec02fSPetter Reinholdtsen static int ipmi_powermgmt(struct ipmi_intf *intf);
211c18ec02fSPetter Reinholdtsen static int ipmi_powermgmt_clear(struct ipmi_intf *intf, uint8_t clearValue);
212c18ec02fSPetter Reinholdtsen static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt);
213c18ec02fSPetter Reinholdtsen static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr);
214c18ec02fSPetter Reinholdtsen static int ipmi_get_power_headroom_command(struct ipmi_intf *intf, uint8_t unit);
215c18ec02fSPetter Reinholdtsen static int ipmi_get_power_consumption_data(struct ipmi_intf *intf, uint8_t unit);
216c18ec02fSPetter Reinholdtsen static int ipmi_get_instan_power_consmpt_data(struct ipmi_intf *intf,
217c18ec02fSPetter Reinholdtsen 		IPMI_INST_POWER_CONSUMPTION_DATA *instpowerconsumptiondata);
218c18ec02fSPetter Reinholdtsen static void ipmi_print_get_instan_power_Amps_data(
219c18ec02fSPetter Reinholdtsen 		IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata);
220c18ec02fSPetter Reinholdtsen static int ipmi_print_get_power_consmpt_data(struct ipmi_intf *intf,
221c18ec02fSPetter Reinholdtsen 		uint8_t  unit);
222c18ec02fSPetter Reinholdtsen static int ipmi_get_avgpower_consmpt_history(struct ipmi_intf *intf,
223c18ec02fSPetter Reinholdtsen 		IPMI_AVGPOWER_CONSUMP_HISTORY *pavgpower);
224c18ec02fSPetter Reinholdtsen static int ipmi_get_peakpower_consmpt_history(struct ipmi_intf *intf,
225c18ec02fSPetter Reinholdtsen 		IPMI_POWER_CONSUMP_HISTORY *pstPeakpower);
226c18ec02fSPetter Reinholdtsen static int ipmi_get_minpower_consmpt_history(struct ipmi_intf *intf,
227c18ec02fSPetter Reinholdtsen 		IPMI_POWER_CONSUMP_HISTORY *pstMinpower);
228c18ec02fSPetter Reinholdtsen static int ipmi_print_power_consmpt_history(struct ipmi_intf *intf, int unit);
229c18ec02fSPetter Reinholdtsen static int ipmi_get_power_cap(struct ipmi_intf *intf,
230c18ec02fSPetter Reinholdtsen 		IPMI_POWER_CAP *ipmipowercap);
231c18ec02fSPetter Reinholdtsen static int ipmi_print_power_cap(struct ipmi_intf *intf, uint8_t unit);
232c18ec02fSPetter Reinholdtsen static int ipmi_set_power_cap(struct ipmi_intf *intf, int unit, int val);
233c18ec02fSPetter Reinholdtsen static void ipmi_powermonitor_usage(void);
234c18ec02fSPetter Reinholdtsen /* vFlash Function prototypes */
235c18ec02fSPetter Reinholdtsen static int ipmi_delloem_vFlash_main(struct ipmi_intf *intf, int argc,
236c18ec02fSPetter Reinholdtsen 		char **argv);
237c18ec02fSPetter Reinholdtsen const char *get_vFlash_compcode_str(uint8_t vflashcompcode,
238c18ec02fSPetter Reinholdtsen 		const struct vFlashstr *vs);
239c18ec02fSPetter Reinholdtsen static int ipmi_get_sd_card_info(struct ipmi_intf *intf);
240c18ec02fSPetter Reinholdtsen static int ipmi_delloem_vFlash_process(struct ipmi_intf *intf, int current_arg,
241c18ec02fSPetter Reinholdtsen 		char **argv);
242c18ec02fSPetter Reinholdtsen static void ipmi_vFlash_usage(void);
243c18ec02fSPetter Reinholdtsen /* LED Function prototypes */
244c18ec02fSPetter Reinholdtsen static int ipmi_getsesmask(int, char **argv);
245c18ec02fSPetter Reinholdtsen static void CheckSetLEDSupport(struct ipmi_intf *intf);
246c18ec02fSPetter Reinholdtsen static int IsSetLEDSupported(void);
247c18ec02fSPetter Reinholdtsen static void ipmi_setled_usage(void);
248c18ec02fSPetter Reinholdtsen static int ipmi_delloem_setled_main(struct ipmi_intf *intf, int argc,
249c18ec02fSPetter Reinholdtsen 		char **argv);
250c18ec02fSPetter Reinholdtsen static int ipmi_setled_state(struct ipmi_intf *intf, int bayId, int slotId,
251c18ec02fSPetter Reinholdtsen 		int state);
252c18ec02fSPetter Reinholdtsen static int ipmi_getdrivemap(struct ipmi_intf *intf, int b, int d, int f,
253c18ec02fSPetter Reinholdtsen 		int *bayId, int *slotId);
254c18ec02fSPetter Reinholdtsen 
255c18ec02fSPetter Reinholdtsen /* Function Name:       ipmi_delloem_main
256c18ec02fSPetter Reinholdtsen  *
257c18ec02fSPetter Reinholdtsen  * Description:         This function processes the delloem command
258c18ec02fSPetter Reinholdtsen  * Input:               intf    - ipmi interface
259c18ec02fSPetter Reinholdtsen  *                       argc    - no of arguments
260c18ec02fSPetter Reinholdtsen  *                       argv    - argument string array
261c18ec02fSPetter Reinholdtsen  * Output:
262c18ec02fSPetter Reinholdtsen  *
263c18ec02fSPetter Reinholdtsen  * Return:              return code     0 - success
264c18ec02fSPetter Reinholdtsen  *                                      -1 - failure
265c18ec02fSPetter Reinholdtsen  */
266c18ec02fSPetter Reinholdtsen int
ipmi_delloem_main(struct ipmi_intf * intf,int argc,char ** argv)267c18ec02fSPetter Reinholdtsen ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv)
268c18ec02fSPetter Reinholdtsen {
269c18ec02fSPetter Reinholdtsen 	int rc = 0;
270c18ec02fSPetter Reinholdtsen 	current_arg = 0;
271c18ec02fSPetter Reinholdtsen 	if (argc == 0 || strncmp(argv[0], "help\0", 5) == 0) {
272c18ec02fSPetter Reinholdtsen 		usage();
273c18ec02fSPetter Reinholdtsen 		return 0;
274c18ec02fSPetter Reinholdtsen 	}
275c18ec02fSPetter Reinholdtsen 	if (0 ==strncmp(argv[current_arg], "lcd\0", 4)) {
2762f578975SPaul Zirnik 		rc = ipmi_delloem_lcd_main(intf,argc,argv);
277c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "mac\0", 4) == 0) {
278c18ec02fSPetter Reinholdtsen 		/* mac address*/
2792f578975SPaul Zirnik 		rc = ipmi_delloem_mac_main(intf,argc,argv);
280c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "lan\0", 4) == 0) {
281c18ec02fSPetter Reinholdtsen 		/* lan address*/
2822f578975SPaul Zirnik 		rc = ipmi_delloem_lan_main(intf,argc,argv);
283c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "setled\0", 7) == 0) {
284c18ec02fSPetter Reinholdtsen 		/* SetLED support */
2852f578975SPaul Zirnik 		rc = ipmi_delloem_setled_main(intf,argc,argv);
286c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "powermonitor\0", 13) == 0) {
287c18ec02fSPetter Reinholdtsen 		/*Powermanagement report processing*/
2882f578975SPaul Zirnik 		rc = ipmi_delloem_powermonitor_main(intf,argc,argv);
289c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "vFlash\0", 7) == 0) {
290c18ec02fSPetter Reinholdtsen 		/* vFlash Support */
2912f578975SPaul Zirnik 		rc = ipmi_delloem_vFlash_main(intf,argc,argv);
292c18ec02fSPetter Reinholdtsen 	} else {
293c18ec02fSPetter Reinholdtsen 		usage();
294c18ec02fSPetter Reinholdtsen 		return -1;
295c18ec02fSPetter Reinholdtsen 	}
296c18ec02fSPetter Reinholdtsen 	return rc;
297c18ec02fSPetter Reinholdtsen }
298c18ec02fSPetter Reinholdtsen /*
299c18ec02fSPetter Reinholdtsen  * Function Name:     usage
300c18ec02fSPetter Reinholdtsen  *
301c18ec02fSPetter Reinholdtsen  * Description:       This function prints help message for delloem command
302c18ec02fSPetter Reinholdtsen  * Input:
303c18ec02fSPetter Reinholdtsen  * Output:
304c18ec02fSPetter Reinholdtsen  *
305c18ec02fSPetter Reinholdtsen  * Return:
306c18ec02fSPetter Reinholdtsen  *
307c18ec02fSPetter Reinholdtsen  */
308c18ec02fSPetter Reinholdtsen static void
usage(void)309c18ec02fSPetter Reinholdtsen usage(void)
310c18ec02fSPetter Reinholdtsen {
311c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
312c18ec02fSPetter Reinholdtsen "");
313c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
314c18ec02fSPetter Reinholdtsen "usage: delloem <command> [option...]");
315c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
316c18ec02fSPetter Reinholdtsen "");
317c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
318c18ec02fSPetter Reinholdtsen "commands:");
319c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
320c18ec02fSPetter Reinholdtsen "    lcd");
321c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
322c18ec02fSPetter Reinholdtsen "    mac");
323c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
324c18ec02fSPetter Reinholdtsen "    lan");
325c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
326c18ec02fSPetter Reinholdtsen "    setled");
327c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
328c18ec02fSPetter Reinholdtsen "    powermonitor");
329c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
330c18ec02fSPetter Reinholdtsen "    vFlash");
331c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
332c18ec02fSPetter Reinholdtsen "");
333c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
334c18ec02fSPetter Reinholdtsen "For help on individual commands type:");
335c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
336c18ec02fSPetter Reinholdtsen "delloem <command> help");
337c18ec02fSPetter Reinholdtsen }
338c18ec02fSPetter Reinholdtsen /*
339c18ec02fSPetter Reinholdtsen  * Function Name:       ipmi_delloem_lcd_main
340c18ec02fSPetter Reinholdtsen  *
341c18ec02fSPetter Reinholdtsen  * Description:         This function processes the delloem lcd command
342c18ec02fSPetter Reinholdtsen  * Input:               intf    - ipmi interface
343c18ec02fSPetter Reinholdtsen  *                       argc    - no of arguments
344c18ec02fSPetter Reinholdtsen  *                       argv    - argument string array
345c18ec02fSPetter Reinholdtsen  * Output:
346c18ec02fSPetter Reinholdtsen  *
347c18ec02fSPetter Reinholdtsen  * Return:              return code     0 - success
348c18ec02fSPetter Reinholdtsen  *                         -1 - failure
349c18ec02fSPetter Reinholdtsen  *
350c18ec02fSPetter Reinholdtsen  */
351c18ec02fSPetter Reinholdtsen static int
ipmi_delloem_lcd_main(struct ipmi_intf * intf,int argc,char ** argv)352c18ec02fSPetter Reinholdtsen ipmi_delloem_lcd_main(struct ipmi_intf * intf, int argc, char ** argv)
353c18ec02fSPetter Reinholdtsen {
354c18ec02fSPetter Reinholdtsen 	int rc = 0;
355c18ec02fSPetter Reinholdtsen 	current_arg++;
356c18ec02fSPetter Reinholdtsen 	if (argc < current_arg) {
357c18ec02fSPetter Reinholdtsen 		usage();
358c18ec02fSPetter Reinholdtsen 		return -1;
359c18ec02fSPetter Reinholdtsen 	}
360c18ec02fSPetter Reinholdtsen 	/* ipmitool delloem lcd info*/
361c18ec02fSPetter Reinholdtsen 	if (argc == 1 || strcmp(argv[current_arg], "help") == 0) {
362c18ec02fSPetter Reinholdtsen 		ipmi_lcd_usage();
363c18ec02fSPetter Reinholdtsen 		return 0;
364c18ec02fSPetter Reinholdtsen 	}
365c18ec02fSPetter Reinholdtsen 	CheckLCDSupport(intf);
366c18ec02fSPetter Reinholdtsen 	ipmi_idracvalidator_command(intf);
367c18ec02fSPetter Reinholdtsen 	if (!IsLCDSupported()) {
368c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "lcd is not supported on this system.");
369c18ec02fSPetter Reinholdtsen 		return -1;
370c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "info\0", 5) == 0) {
371859e8a45SZdenek Styblik 		if (iDRAC_FLAG_ALL) {
372c18ec02fSPetter Reinholdtsen 			rc = ipmi_lcd_get_info_wh(intf);
373c18ec02fSPetter Reinholdtsen 		} else {
374c18ec02fSPetter Reinholdtsen 			rc = ipmi_lcd_get_info(intf);
375c18ec02fSPetter Reinholdtsen 		}
376c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "status\0", 7) == 0) {
377c18ec02fSPetter Reinholdtsen 		rc = ipmi_lcd_get_status(intf);
378c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "set\0", 4) == 0) {
379c18ec02fSPetter Reinholdtsen 		/* ipmitool delloem lcd set*/
380c18ec02fSPetter Reinholdtsen 		uint8_t line_number = 0;
381c18ec02fSPetter Reinholdtsen 		current_arg++;
382c18ec02fSPetter Reinholdtsen 		if (argc <= current_arg) {
383c18ec02fSPetter Reinholdtsen 			ipmi_lcd_usage();
384c18ec02fSPetter Reinholdtsen 			return -1;
385c18ec02fSPetter Reinholdtsen 		}
386c18ec02fSPetter Reinholdtsen 		if (strncmp(argv[current_arg], "line\0", 5) == 0) {
387c18ec02fSPetter Reinholdtsen 			current_arg++;
388c18ec02fSPetter Reinholdtsen 			if (argc <= current_arg) {
389c18ec02fSPetter Reinholdtsen 				usage();
390c18ec02fSPetter Reinholdtsen 				return -1;
391c18ec02fSPetter Reinholdtsen 			}
392c18ec02fSPetter Reinholdtsen 			if (str2uchar(argv[current_arg], &line_number) != 0) {
393c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR,
394c18ec02fSPetter Reinholdtsen 						"Argument '%s' is either not a number or out of range.",
395c18ec02fSPetter Reinholdtsen 						argv[current_arg]);
396c18ec02fSPetter Reinholdtsen 				return (-1);
397c18ec02fSPetter Reinholdtsen 			}
398c18ec02fSPetter Reinholdtsen 			current_arg++;
399c18ec02fSPetter Reinholdtsen 			if (argc <= current_arg) {
400c18ec02fSPetter Reinholdtsen 				usage();
401c18ec02fSPetter Reinholdtsen 				return -1;
402c18ec02fSPetter Reinholdtsen 			}
403c18ec02fSPetter Reinholdtsen 		}
404c18ec02fSPetter Reinholdtsen 		if ((strncmp(argv[current_arg], "mode\0", 5) == 0)
405859e8a45SZdenek Styblik 				&& (iDRAC_FLAG_ALL)) {
406c18ec02fSPetter Reinholdtsen 			current_arg++;
407c18ec02fSPetter Reinholdtsen 			if (argc <= current_arg) {
408c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
409c18ec02fSPetter Reinholdtsen 				return -1;
410c18ec02fSPetter Reinholdtsen 			}
411c18ec02fSPetter Reinholdtsen 			if (argv[current_arg] == NULL) {
412c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
413c18ec02fSPetter Reinholdtsen 				return -1;
414c18ec02fSPetter Reinholdtsen 			}
415c18ec02fSPetter Reinholdtsen 			if (strncmp(argv[current_arg], "none\0", 5) == 0) {
416c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_NONE, 0xFF,
417c18ec02fSPetter Reinholdtsen 						0XFF, 0, NULL);
418c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "modelname\0", 10) == 0) {
419c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0xFF,
420c18ec02fSPetter Reinholdtsen 						0XFF, 0, NULL);
421c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "userdefined\0", 12) == 0) {
422c18ec02fSPetter Reinholdtsen 				current_arg++;
423c18ec02fSPetter Reinholdtsen 				if (argc <= current_arg) {
424c18ec02fSPetter Reinholdtsen 					ipmi_lcd_usage();
425c18ec02fSPetter Reinholdtsen 					return -1;
426c18ec02fSPetter Reinholdtsen 				}
427c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED,
428c18ec02fSPetter Reinholdtsen 						0xFF, 0XFF, line_number, argv[current_arg]);
429c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "ipv4address\0", 12) == 0) {
430c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_iDRAC_IPV4ADRESS,
431c18ec02fSPetter Reinholdtsen 						0xFF, 0XFF, 0, NULL);
432c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "macaddress\0", 11) == 0) {
433c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_IDRAC_MAC_ADDRESS,
434c18ec02fSPetter Reinholdtsen 							0xFF, 0XFF, 0, NULL);
435c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "systemname\0", 11) == 0) {
436c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_OS_SYSTEM_NAME, 0xFF,
437c18ec02fSPetter Reinholdtsen 						0XFF, 0, NULL);
438c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "servicetag\0", 11) == 0) {
439c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_SERVICE_TAG, 0xFF,
440c18ec02fSPetter Reinholdtsen 						0XFF, 0, NULL);
441c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "ipv6address\0", 12) == 0) {
442c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_iDRAC_IPV6ADRESS,
443c18ec02fSPetter Reinholdtsen 						0xFF, 0XFF, 0, NULL);
444c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "ambienttemp\0", 12) == 0) {
445c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_AMBEINT_TEMP, 0xFF,
446c18ec02fSPetter Reinholdtsen 						0XFF, 0, NULL);
447c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "systemwatt\0", 11) == 0) {
448c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_SYSTEM_WATTS, 0xFF,
449c18ec02fSPetter Reinholdtsen 						0XFF, 0, NULL);
450c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "assettag\0", 9) == 0) {
451c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_ASSET_TAG, 0xFF,
452c18ec02fSPetter Reinholdtsen 						0XFF, 0, NULL);
453c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
454c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
455c18ec02fSPetter Reinholdtsen 			} else {
456*faae8fd2SZdenek Styblik 				lprintf(LOG_ERR, "Invalid DellOEM command: %s",
457*faae8fd2SZdenek Styblik 						argv[current_arg]);
458c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
459c18ec02fSPetter Reinholdtsen 			}
460c18ec02fSPetter Reinholdtsen 		} else if ((strncmp(argv[current_arg], "lcdqualifier\0", 13) == 0)
461859e8a45SZdenek Styblik 				&& (iDRAC_FLAG_ALL)) {
462c18ec02fSPetter Reinholdtsen 			current_arg++;
463c18ec02fSPetter Reinholdtsen 			if (argc <= current_arg) {
464c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
465c18ec02fSPetter Reinholdtsen 				return -1;
466c18ec02fSPetter Reinholdtsen 			}
467c18ec02fSPetter Reinholdtsen 			if (argv[current_arg] == NULL) {
468c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
469c18ec02fSPetter Reinholdtsen 				return -1;
470c18ec02fSPetter Reinholdtsen 			}
471c18ec02fSPetter Reinholdtsen 			if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
472c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, 0xFF, 0x00, 0XFF, 0, NULL);
473c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "btuphr\0",7) == 0) {
474c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, 0xFF, 0x01, 0XFF, 0, NULL);
475c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "celsius\0", 8) == 0) {
476c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, 0xFF, 0x02, 0xFF, 0, NULL);
477c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "fahrenheit", 11) == 0) {
478c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, 0xFF, 0x03, 0xFF, 0, NULL);
479c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
480c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
481c18ec02fSPetter Reinholdtsen 			} else {
482*faae8fd2SZdenek Styblik 				lprintf(LOG_ERR, "Invalid DellOEM command: %s",
483*faae8fd2SZdenek Styblik 						argv[current_arg]);
484c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
485c18ec02fSPetter Reinholdtsen 			}
486c18ec02fSPetter Reinholdtsen 		} else if ((strncmp(argv[current_arg], "errordisplay\0", 13) == 0)
487859e8a45SZdenek Styblik 				&& (iDRAC_FLAG_ALL)) {
488c18ec02fSPetter Reinholdtsen 			current_arg++;
489c18ec02fSPetter Reinholdtsen 			if (argc <= current_arg) {
490c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
491c18ec02fSPetter Reinholdtsen 				return -1;
492c18ec02fSPetter Reinholdtsen 			}
493c18ec02fSPetter Reinholdtsen 			if (argv[current_arg] == NULL) {
494c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
495c18ec02fSPetter Reinholdtsen 				return -1;
496c18ec02fSPetter Reinholdtsen 			}
497c18ec02fSPetter Reinholdtsen 			if (strncmp(argv[current_arg], "sel\0", 4) == 0) {
498c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, 0xFF, 0xFF,
499c18ec02fSPetter Reinholdtsen 						IPMI_DELL_LCD_ERROR_DISP_SEL, 0, NULL);
500c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "simple\0", 7) == 0) {
501c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_configure_wh(intf, 0xFF, 0xFF,
502c18ec02fSPetter Reinholdtsen 						IPMI_DELL_LCD_ERROR_DISP_VERBOSE, 0, NULL);
503c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
504c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
505c18ec02fSPetter Reinholdtsen 			} else {
506*faae8fd2SZdenek Styblik 				lprintf(LOG_ERR, "Invalid DellOEM command: %s",
507*faae8fd2SZdenek Styblik 						argv[current_arg]);
508c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
509c18ec02fSPetter Reinholdtsen 			}
510c18ec02fSPetter Reinholdtsen 		} else if ((strncmp(argv[current_arg], "none\0", 5) == 0)
511c18ec02fSPetter Reinholdtsen 				&& (iDRAC_FLAG==0)) {
512c18ec02fSPetter Reinholdtsen 			rc = ipmi_lcd_configure(intf, IPMI_DELL_LCD_CONFIG_NONE, 0, NULL);
513c18ec02fSPetter Reinholdtsen 		} else if ((strncmp(argv[current_arg], "default\0", 8) == 0)
514c18ec02fSPetter Reinholdtsen 				&& (iDRAC_FLAG==0)) {
515c18ec02fSPetter Reinholdtsen 			rc = ipmi_lcd_configure(intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0, NULL);
516c18ec02fSPetter Reinholdtsen 		} else if ((strncmp(argv[current_arg], "custom\0", 7) == 0)
517c18ec02fSPetter Reinholdtsen 				&& (iDRAC_FLAG==0)) {
518c18ec02fSPetter Reinholdtsen 			current_arg++;
519c18ec02fSPetter Reinholdtsen 			if (argc <= current_arg) {
520c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
521c18ec02fSPetter Reinholdtsen 				return -1;
522c18ec02fSPetter Reinholdtsen 			}
523c18ec02fSPetter Reinholdtsen 			rc = ipmi_lcd_configure(intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED,
524c18ec02fSPetter Reinholdtsen 					line_number, argv[current_arg]);
525c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "vkvm\0", 5) == 0) {
526c18ec02fSPetter Reinholdtsen 			current_arg++;
527c18ec02fSPetter Reinholdtsen 			if (argc <= current_arg) {
528c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
529c18ec02fSPetter Reinholdtsen 				return -1;
530c18ec02fSPetter Reinholdtsen 			}
531c18ec02fSPetter Reinholdtsen 			if (strncmp(argv[current_arg], "active\0", 7) == 0) {
532c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_set_kvm(intf, 1);
533c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "inactive\0", 9) == 0) {
534c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_set_kvm(intf, 0);
535c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
536c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
537c18ec02fSPetter Reinholdtsen 			} else {
538*faae8fd2SZdenek Styblik 				lprintf(LOG_ERR, "Invalid DellOEM command: %s",
539*faae8fd2SZdenek Styblik 						argv[current_arg]);
540c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
541c18ec02fSPetter Reinholdtsen 			}
542c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "frontpanelaccess\0", 17) == 0) {
543c18ec02fSPetter Reinholdtsen 			current_arg++;
544c18ec02fSPetter Reinholdtsen 			if (argc <= current_arg) {
545c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
546c18ec02fSPetter Reinholdtsen 				return -1;
547c18ec02fSPetter Reinholdtsen 			}
548c18ec02fSPetter Reinholdtsen 			if (strncmp(argv[current_arg], "viewandmodify\0", 14) == 0) {
549c18ec02fSPetter Reinholdtsen 				rc = ipmi_lcd_set_lock(intf, 0);
550c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "viewonly\0", 9)==0) {
551c18ec02fSPetter Reinholdtsen 				rc =  ipmi_lcd_set_lock(intf, 1);
552c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "disabled\0", 9)==0) {
553c18ec02fSPetter Reinholdtsen 				rc =  ipmi_lcd_set_lock(intf, 2);
554c18ec02fSPetter Reinholdtsen 			} else if (strncmp(argv[current_arg], "help\0", 5) == 0) {
555c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
556c18ec02fSPetter Reinholdtsen 			} else {
557*faae8fd2SZdenek Styblik 				lprintf(LOG_ERR, "Invalid DellOEM command: %s",
558*faae8fd2SZdenek Styblik 						argv[current_arg]);
559c18ec02fSPetter Reinholdtsen 				ipmi_lcd_usage();
560c18ec02fSPetter Reinholdtsen 			}
561c18ec02fSPetter Reinholdtsen 		} else if( (strncmp(argv[current_arg], "help\0", 5) == 0)
562c18ec02fSPetter Reinholdtsen 				&& (iDRAC_FLAG==0)) {
563c18ec02fSPetter Reinholdtsen 			ipmi_lcd_usage();
564c18ec02fSPetter Reinholdtsen 		} else {
565*faae8fd2SZdenek Styblik 			lprintf(LOG_ERR, "Invalid DellOEM command: %s",
566*faae8fd2SZdenek Styblik 					argv[current_arg]);
567c18ec02fSPetter Reinholdtsen 			ipmi_lcd_usage();
568c18ec02fSPetter Reinholdtsen 			return -1;
569c18ec02fSPetter Reinholdtsen 		}
570c18ec02fSPetter Reinholdtsen 	} else {
571*faae8fd2SZdenek Styblik 		lprintf(LOG_ERR, "Invalid DellOEM command: %s",
572*faae8fd2SZdenek Styblik 				argv[current_arg]);
573c18ec02fSPetter Reinholdtsen 		ipmi_lcd_usage();
574c18ec02fSPetter Reinholdtsen 		return -1;
575c18ec02fSPetter Reinholdtsen 	}
576c18ec02fSPetter Reinholdtsen 	return rc;
577c18ec02fSPetter Reinholdtsen }
578c18ec02fSPetter Reinholdtsen /* ipmi_lcd_get_platform_model_name - This function retrieves the platform model
579c18ec02fSPetter Reinholdtsen  * name, or any other parameter which stores data in the same format
580c18ec02fSPetter Reinholdtsen  *
581c18ec02fSPetter Reinholdtsen  * @intf:        pointer to interface
582c18ec02fSPetter Reinholdtsen  * @lcdstring:   hostname/platform model string(output)
583c18ec02fSPetter Reinholdtsen  * @max_length:  length of the platform model string
584c18ec02fSPetter Reinholdtsen  * @field_type:  either hostname/platform model
585c18ec02fSPetter Reinholdtsen  *
586c18ec02fSPetter Reinholdtsen  * returns: 0 => success, other value means error
587c18ec02fSPetter Reinholdtsen  */
588c18ec02fSPetter Reinholdtsen int
ipmi_lcd_get_platform_model_name(struct ipmi_intf * intf,char * lcdstring,uint8_t max_length,uint8_t field_type)589c18ec02fSPetter Reinholdtsen ipmi_lcd_get_platform_model_name(struct ipmi_intf * intf, char* lcdstring,
590c18ec02fSPetter Reinholdtsen 		uint8_t max_length, uint8_t field_type)
591c18ec02fSPetter Reinholdtsen {
592c18ec02fSPetter Reinholdtsen 	int bytes_copied = 0;
593c18ec02fSPetter Reinholdtsen 	int ii = 0;
594c18ec02fSPetter Reinholdtsen 	int lcdstring_len = 0;
595c18ec02fSPetter Reinholdtsen 	int rc = 0;
596c18ec02fSPetter Reinholdtsen 	IPMI_DELL_LCD_STRING lcdstringblock;
597c18ec02fSPetter Reinholdtsen 
598c18ec02fSPetter Reinholdtsen 	for (ii = 0; ii < 4; ii++) {
599c18ec02fSPetter Reinholdtsen 		int bytes_to_copy;
600c18ec02fSPetter Reinholdtsen 		rc = ipmi_mc_getsysinfo(intf, field_type, ii, 0, sizeof(lcdstringblock),
601c18ec02fSPetter Reinholdtsen 				&lcdstringblock);
602c18ec02fSPetter Reinholdtsen 		if (rc < 0) {
603c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting platform model name");
604c18ec02fSPetter Reinholdtsen 			break;
605c18ec02fSPetter Reinholdtsen 		} else if (rc > 0) {
606c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting platform model name: %s",
607c18ec02fSPetter Reinholdtsen 					val2str(rc, completion_code_vals));
608c18ec02fSPetter Reinholdtsen 			break;
609c18ec02fSPetter Reinholdtsen 		}
610c18ec02fSPetter Reinholdtsen 		/* first block is different - 14 bytes*/
611c18ec02fSPetter Reinholdtsen 		if (ii == 0) {
612c18ec02fSPetter Reinholdtsen 			lcdstring_len = lcdstringblock.lcd_string.selector_0_string.length;
613c18ec02fSPetter Reinholdtsen 			lcdstring_len = MIN(lcdstring_len,max_length);
614c18ec02fSPetter Reinholdtsen 			bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE);
615c18ec02fSPetter Reinholdtsen 			memcpy(lcdstring, lcdstringblock.lcd_string.selector_0_string.data,
616c18ec02fSPetter Reinholdtsen 					bytes_to_copy);
617c18ec02fSPetter Reinholdtsen 		} else {
618c18ec02fSPetter Reinholdtsen 			int string_offset;
619c18ec02fSPetter Reinholdtsen 			bytes_to_copy = MIN(lcdstring_len - bytes_copied,
620c18ec02fSPetter Reinholdtsen 					IPMI_DELL_LCD_STRINGN_SIZE);
621c18ec02fSPetter Reinholdtsen 			if (bytes_to_copy < 1) {
622c18ec02fSPetter Reinholdtsen 				break;
623c18ec02fSPetter Reinholdtsen 			}
624c18ec02fSPetter Reinholdtsen 			string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE
625c18ec02fSPetter Reinholdtsen 				* (ii-1);
626c18ec02fSPetter Reinholdtsen 			memcpy(lcdstring + string_offset,
627c18ec02fSPetter Reinholdtsen 					lcdstringblock.lcd_string.selector_n_data, bytes_to_copy);
628c18ec02fSPetter Reinholdtsen 		}
629c18ec02fSPetter Reinholdtsen 		bytes_copied += bytes_to_copy;
630c18ec02fSPetter Reinholdtsen 		if (bytes_copied >= lcdstring_len) {
631c18ec02fSPetter Reinholdtsen 			break;
632c18ec02fSPetter Reinholdtsen 		}
633c18ec02fSPetter Reinholdtsen 	}
634c18ec02fSPetter Reinholdtsen 	return rc;
635c18ec02fSPetter Reinholdtsen }
636c18ec02fSPetter Reinholdtsen /*
637c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_idracvalidator_command
638c18ec02fSPetter Reinholdtsen  *
639c18ec02fSPetter Reinholdtsen  * Description:      This function returns the iDRAC6 type
640c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
641c18ec02fSPetter Reinholdtsen  * Output:
642c18ec02fSPetter Reinholdtsen  *
643c18ec02fSPetter Reinholdtsen  * Return:           iDRAC6 type     1 - whoville
644c18ec02fSPetter Reinholdtsen  *                                   0 - others
645c18ec02fSPetter Reinholdtsen  */
646c18ec02fSPetter Reinholdtsen static int
ipmi_idracvalidator_command(struct ipmi_intf * intf)647c18ec02fSPetter Reinholdtsen ipmi_idracvalidator_command(struct ipmi_intf * intf)
648c18ec02fSPetter Reinholdtsen {
649c18ec02fSPetter Reinholdtsen 	int rc;
650c18ec02fSPetter Reinholdtsen 	uint8_t data[11];
651c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_IDRAC_VALIDATOR, 2, 0, sizeof(data),
652c18ec02fSPetter Reinholdtsen 			data);
653c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
654c18ec02fSPetter Reinholdtsen 		/*lprintf(LOG_ERR, " Error getting IMC type"); */
655c18ec02fSPetter Reinholdtsen 		return -1;
656c18ec02fSPetter Reinholdtsen 	} else if (rc > 0) {
657c18ec02fSPetter Reinholdtsen 		/*lprintf(LOG_ERR, " Error getting IMC type: %s",
658c18ec02fSPetter Reinholdtsen 		val2str(rsp->ccode, completion_code_vals));  */
659c18ec02fSPetter Reinholdtsen 		return -1;
660c18ec02fSPetter Reinholdtsen 	}
661859e8a45SZdenek Styblik 	/*
662859e8a45SZdenek Styblik 	 * Set the new flags to 0
663859e8a45SZdenek Styblik 	 */
664859e8a45SZdenek Styblik 	iDRAC_FLAG_ALL = 0;
665859e8a45SZdenek Styblik 	iDRAC_FLAG_12_13 = 0;
666c18ec02fSPetter Reinholdtsen 	/* Support the 11G Monolithic, modular, Maisy and Coaster */
667c18ec02fSPetter Reinholdtsen 	if ((IMC_IDRAC_11G_MONOLITHIC == data[10])
668c18ec02fSPetter Reinholdtsen 			|| (IMC_IDRAC_11G_MODULAR == data[10])
669c18ec02fSPetter Reinholdtsen 			|| (IMC_MASER_LITE_BMC == data[10])
670c18ec02fSPetter Reinholdtsen 			|| (IMC_MASER_LITE_NU == data[10])) {
671c18ec02fSPetter Reinholdtsen 		iDRAC_FLAG=IDRAC_11G;
672859e8a45SZdenek Styblik 		iDRAC_FLAG_ALL = 1;
673c18ec02fSPetter Reinholdtsen 	} else if((IMC_IDRAC_12G_MONOLITHIC == data[10])
674c18ec02fSPetter Reinholdtsen 			|| (IMC_IDRAC_12G_MODULAR == data[10])) {
675c18ec02fSPetter Reinholdtsen 		iDRAC_FLAG = IDRAC_12G;
676859e8a45SZdenek Styblik 		iDRAC_FLAG_ALL = 1;
677859e8a45SZdenek Styblik 		iDRAC_FLAG_12_13 = 1;
678859e8a45SZdenek Styblik 	} else if ((IMC_IDRAC_13G_MONOLITHIC == data[10])
679859e8a45SZdenek Styblik 			|| (IMC_IDRAC_13G_MODULAR == data[10])
680859e8a45SZdenek Styblik 			|| (IMC_IDRAC_13G_DCS == data[10])) {
681859e8a45SZdenek Styblik 		iDRAC_FLAG=IDRAC_13G;
682859e8a45SZdenek Styblik 		iDRAC_FLAG_ALL = 1;
683859e8a45SZdenek Styblik 		iDRAC_FLAG_12_13 = 1;
684c18ec02fSPetter Reinholdtsen 	} else {
685c18ec02fSPetter Reinholdtsen 		iDRAC_FLAG = 0;
686859e8a45SZdenek Styblik 		iDRAC_FLAG_ALL = 0;
687859e8a45SZdenek Styblik 		iDRAC_FLAG_12_13 = 0;
688c18ec02fSPetter Reinholdtsen 	}
689c18ec02fSPetter Reinholdtsen 	IMC_Type = data[10];
690c18ec02fSPetter Reinholdtsen 	return 0;
691c18ec02fSPetter Reinholdtsen }
692c18ec02fSPetter Reinholdtsen /*
693c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_lcd_get_configure_command_wh
694c18ec02fSPetter Reinholdtsen  *
695c18ec02fSPetter Reinholdtsen  * Description:      This function returns current lcd configuration for Dell OEM LCD command
696c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
697c18ec02fSPetter Reinholdtsen  * Global:           lcd_mode - lcd mode setting
698c18ec02fSPetter Reinholdtsen  * Output:
699c18ec02fSPetter Reinholdtsen  *
700c18ec02fSPetter Reinholdtsen  * Return:           returns the current lcd configuration
701c18ec02fSPetter Reinholdtsen  *                   0 = User defined
702c18ec02fSPetter Reinholdtsen  *                   1 = Default
703c18ec02fSPetter Reinholdtsen  *                   2 = None
704c18ec02fSPetter Reinholdtsen  */
705c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_get_configure_command_wh(struct ipmi_intf * intf)706c18ec02fSPetter Reinholdtsen ipmi_lcd_get_configure_command_wh(struct ipmi_intf * intf)
707c18ec02fSPetter Reinholdtsen {
708c18ec02fSPetter Reinholdtsen 	int rc;
709c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_CONFIG_SELECTOR, 0, 0,
710c18ec02fSPetter Reinholdtsen 			sizeof(lcd_mode), &lcd_mode);
711c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
712c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD configuration");
713c18ec02fSPetter Reinholdtsen 		return -1;
714c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1) || (rc == 0xcb)){
715c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD configuration: "
716c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
717c18ec02fSPetter Reinholdtsen 	} else if (rc > 0) {
718c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD configuration: %s",
719c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
720c18ec02fSPetter Reinholdtsen 		return -1;
721c18ec02fSPetter Reinholdtsen 	}
722c18ec02fSPetter Reinholdtsen 	return 0;
723c18ec02fSPetter Reinholdtsen }
724c18ec02fSPetter Reinholdtsen /*
725c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_lcd_get_configure_command
726c18ec02fSPetter Reinholdtsen  *
727c18ec02fSPetter Reinholdtsen  * Description:   This function returns current lcd configuration for Dell OEM
728c18ec02fSPetter Reinholdtsen  * LCD command
729c18ec02fSPetter Reinholdtsen  * Input:         intf            - ipmi interface
730c18ec02fSPetter Reinholdtsen  * Output:        command         - user defined / default / none / ipv4 / mac address /
731c18ec02fSPetter Reinholdtsen  *                 system name / service tag / ipv6 / temp / system watt / asset tag
732c18ec02fSPetter Reinholdtsen  *
733c18ec02fSPetter Reinholdtsen  * Return:
734c18ec02fSPetter Reinholdtsen  */
735c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_get_configure_command(struct ipmi_intf * intf,uint8_t * command)736c18ec02fSPetter Reinholdtsen ipmi_lcd_get_configure_command(struct ipmi_intf * intf, uint8_t *command)
737c18ec02fSPetter Reinholdtsen {
738c18ec02fSPetter Reinholdtsen 	uint8_t data[4];
739c18ec02fSPetter Reinholdtsen 	int rc;
740c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_CONFIG_SELECTOR, 0, 0,
741c18ec02fSPetter Reinholdtsen 			sizeof(data), data);
742c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
743c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD configuration");
744c18ec02fSPetter Reinholdtsen 		return -1;
745c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1)||(rc == 0xcb)) {
746c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD configuration: "
747c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
748c18ec02fSPetter Reinholdtsen 		return -1;
749c18ec02fSPetter Reinholdtsen 	} else if (rc > 0) {
750c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD configuration: %s",
751c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
752c18ec02fSPetter Reinholdtsen 		return -1;
753c18ec02fSPetter Reinholdtsen 	}
754c18ec02fSPetter Reinholdtsen 	/* rsp->data[0] is the rev */
755c18ec02fSPetter Reinholdtsen 	*command = data[1];
756c18ec02fSPetter Reinholdtsen 	return 0;
757c18ec02fSPetter Reinholdtsen }
758c18ec02fSPetter Reinholdtsen /*
759c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_lcd_set_configure_command
760c18ec02fSPetter Reinholdtsen  *
761c18ec02fSPetter Reinholdtsen  * Description:      This function updates current lcd configuration
762c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
763c18ec02fSPetter Reinholdtsen  *                   command         - user defined / default / none / ipv4 / mac address /
764c18ec02fSPetter Reinholdtsen  *                        system name / service tag / ipv6 / temp / system watt / asset tag
765c18ec02fSPetter Reinholdtsen  * Output:
766c18ec02fSPetter Reinholdtsen  * Return:
767c18ec02fSPetter Reinholdtsen  */
768c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_set_configure_command(struct ipmi_intf * intf,int command)769c18ec02fSPetter Reinholdtsen ipmi_lcd_set_configure_command(struct ipmi_intf * intf, int command)
770c18ec02fSPetter Reinholdtsen {
771c18ec02fSPetter Reinholdtsen 	#define LSCC_DATA_LEN 2
772c18ec02fSPetter Reinholdtsen 	uint8_t data[2];
773c18ec02fSPetter Reinholdtsen 	int rc;
774c18ec02fSPetter Reinholdtsen 	data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR;
775c18ec02fSPetter Reinholdtsen 	data[1] = command;                      /* command - custom, default, none */
776c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_setsysinfo(intf, 2, data);
777c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
778c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD configuration");
779c18ec02fSPetter Reinholdtsen 		return -1;
780c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1) || (rc == 0xcb)) {
781c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD configuration: "
782c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
783c18ec02fSPetter Reinholdtsen 	} else if (rc > 0) {
784c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD configuration: %s",
785c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
786c18ec02fSPetter Reinholdtsen 		return -1;
787c18ec02fSPetter Reinholdtsen 	}
788c18ec02fSPetter Reinholdtsen 	return 0;
789c18ec02fSPetter Reinholdtsen }
790c18ec02fSPetter Reinholdtsen /*
791c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_lcd_set_configure_command
792c18ec02fSPetter Reinholdtsen  *
793c18ec02fSPetter Reinholdtsen  * Description:      This function updates current lcd configuration
794c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
795c18ec02fSPetter Reinholdtsen  *                   mode            - user defined / default / none
796c18ec02fSPetter Reinholdtsen  *                   lcdquallifier   - lcd quallifier id
797c18ec02fSPetter Reinholdtsen  *                   errordisp       - error number
798c18ec02fSPetter Reinholdtsen  * Output:
799c18ec02fSPetter Reinholdtsen  * Return:
800c18ec02fSPetter Reinholdtsen  */
801c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_set_configure_command_wh(struct ipmi_intf * intf,uint32_t mode,uint16_t lcdquallifier,uint8_t errordisp)802c18ec02fSPetter Reinholdtsen ipmi_lcd_set_configure_command_wh(struct ipmi_intf * intf, uint32_t  mode,
803c18ec02fSPetter Reinholdtsen 		uint16_t lcdquallifier, uint8_t errordisp)
804c18ec02fSPetter Reinholdtsen {
805c18ec02fSPetter Reinholdtsen 	#define LSCC_DATA_LEN 2
806c18ec02fSPetter Reinholdtsen 	uint8_t data[13];
807c18ec02fSPetter Reinholdtsen 	int rc;
808c18ec02fSPetter Reinholdtsen 	ipmi_lcd_get_configure_command_wh(intf);
809c18ec02fSPetter Reinholdtsen 	data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR;
810c18ec02fSPetter Reinholdtsen 	if (mode != 0xFF) {
811c18ec02fSPetter Reinholdtsen 		data[1] = mode & 0xFF; /* command - custom, default, none*/
812c18ec02fSPetter Reinholdtsen 		data[2] = (mode & 0xFF00) >> 8;
813c18ec02fSPetter Reinholdtsen 		data[3] = (mode & 0xFF0000) >> 16;
814c18ec02fSPetter Reinholdtsen 		data[4] = (mode & 0xFF000000) >> 24;
815c18ec02fSPetter Reinholdtsen 	} else {
816c18ec02fSPetter Reinholdtsen 		data[1] = (lcd_mode.lcdmode) & 0xFF; /* command - custom, default, none*/
817c18ec02fSPetter Reinholdtsen 		data[2] = ((lcd_mode.lcdmode) & 0xFF00) >> 8;
818c18ec02fSPetter Reinholdtsen 		data[3] = ((lcd_mode.lcdmode) & 0xFF0000) >> 16;
819c18ec02fSPetter Reinholdtsen 		data[4] = ((lcd_mode.lcdmode) & 0xFF000000) >> 24;
820c18ec02fSPetter Reinholdtsen 	}
821c18ec02fSPetter Reinholdtsen 	if (lcdquallifier != 0xFF) {
822c18ec02fSPetter Reinholdtsen 		if(lcdquallifier == 0x01) {
823c18ec02fSPetter Reinholdtsen 			data[5] = (lcd_mode.lcdquallifier) | 0x01; /* command - custom, default, none*/
824c18ec02fSPetter Reinholdtsen 		} else  if (lcdquallifier == 0x00) {
825c18ec02fSPetter Reinholdtsen 			data[5] = (lcd_mode.lcdquallifier) & 0xFE; /* command - custom, default, none*/
826c18ec02fSPetter Reinholdtsen 		} else if (lcdquallifier == 0x03) {
827c18ec02fSPetter Reinholdtsen 			data[5] = (lcd_mode.lcdquallifier) | 0x02; /* command - custom, default, none*/
828c18ec02fSPetter Reinholdtsen 		} else if (lcdquallifier == 0x02) {
829c18ec02fSPetter Reinholdtsen 			data[5] = (lcd_mode.lcdquallifier) & 0xFD;
830c18ec02fSPetter Reinholdtsen 		}
831c18ec02fSPetter Reinholdtsen 	} else {
832c18ec02fSPetter Reinholdtsen 		data[5] = lcd_mode.lcdquallifier;
833c18ec02fSPetter Reinholdtsen 	}
834c18ec02fSPetter Reinholdtsen 	if (errordisp != 0xFF) {
835c18ec02fSPetter Reinholdtsen 		data[11] = errordisp;
836c18ec02fSPetter Reinholdtsen 	} else {
837c18ec02fSPetter Reinholdtsen 		data[11] = lcd_mode.error_display;
838c18ec02fSPetter Reinholdtsen 	}
839c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_setsysinfo(intf, 13, data);
840c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
841c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD configuration");
842c18ec02fSPetter Reinholdtsen 		return -1;
843c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1) || (rc == 0xcb)) {
844c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD configuration: "
845c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
846c18ec02fSPetter Reinholdtsen 	} else if (rc > 0) {
847c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD configuration: %s",
848c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
849c18ec02fSPetter Reinholdtsen 		return -1;
850c18ec02fSPetter Reinholdtsen 	}
851c18ec02fSPetter Reinholdtsen 	return 0;
852c18ec02fSPetter Reinholdtsen }
853c18ec02fSPetter Reinholdtsen /*
854c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_lcd_get_single_line_text
855c18ec02fSPetter Reinholdtsen  *
856c18ec02fSPetter Reinholdtsen  * Description:    This function updates current lcd configuration
857c18ec02fSPetter Reinholdtsen  * Input:          intf            - ipmi interface
858c18ec02fSPetter Reinholdtsen  *                 lcdstring       - new string to be updated
859c18ec02fSPetter Reinholdtsen  *                 max_length      - length of the string
860c18ec02fSPetter Reinholdtsen  * Output:
861c18ec02fSPetter Reinholdtsen  * Return:
862c18ec02fSPetter Reinholdtsen  */
863c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_get_single_line_text(struct ipmi_intf * intf,char * lcdstring,uint8_t max_length)864c18ec02fSPetter Reinholdtsen ipmi_lcd_get_single_line_text(struct ipmi_intf * intf, char* lcdstring,
865c18ec02fSPetter Reinholdtsen 		uint8_t max_length)
866c18ec02fSPetter Reinholdtsen {
867c18ec02fSPetter Reinholdtsen 	IPMI_DELL_LCD_STRING lcdstringblock;
868c18ec02fSPetter Reinholdtsen 	int lcdstring_len = 0;
869c18ec02fSPetter Reinholdtsen 	int bytes_copied = 0;
870c18ec02fSPetter Reinholdtsen 	int ii, rc;
871c18ec02fSPetter Reinholdtsen 	for (ii = 0; ii < 4; ii++) {
872c18ec02fSPetter Reinholdtsen 		int bytes_to_copy;
873c18ec02fSPetter Reinholdtsen 		rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_STRING_SELECTOR, ii, 0,
874c18ec02fSPetter Reinholdtsen 				sizeof(lcdstringblock), &lcdstringblock);
875c18ec02fSPetter Reinholdtsen 		if (rc < 0) {
876c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting text data");
877c18ec02fSPetter Reinholdtsen 			return -1;
878c18ec02fSPetter Reinholdtsen 		} else if (rc > 0) {
879c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting text data: %s",
880c18ec02fSPetter Reinholdtsen 					val2str(rc, completion_code_vals));
881c18ec02fSPetter Reinholdtsen 			return -1;
882c18ec02fSPetter Reinholdtsen 		}
883c18ec02fSPetter Reinholdtsen 		/* first block is different - 14 bytes*/
884c18ec02fSPetter Reinholdtsen 		if (0 == ii) {
885c18ec02fSPetter Reinholdtsen 			lcdstring_len = lcdstringblock.lcd_string.selector_0_string.length;
886c18ec02fSPetter Reinholdtsen 			if (lcdstring_len < 1 || lcdstring_len > max_length) {
887c18ec02fSPetter Reinholdtsen 				break;
888c18ec02fSPetter Reinholdtsen 			}
889c18ec02fSPetter Reinholdtsen 			bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE);
890c18ec02fSPetter Reinholdtsen 			memcpy(lcdstring, lcdstringblock.lcd_string.selector_0_string.data,
891c18ec02fSPetter Reinholdtsen 					bytes_to_copy);
892c18ec02fSPetter Reinholdtsen 		} else {
893c18ec02fSPetter Reinholdtsen 			int string_offset;
894c18ec02fSPetter Reinholdtsen 			bytes_to_copy = MIN(lcdstring_len - bytes_copied,
895c18ec02fSPetter Reinholdtsen 					IPMI_DELL_LCD_STRINGN_SIZE);
896c18ec02fSPetter Reinholdtsen 			if (bytes_to_copy < 1) {
897c18ec02fSPetter Reinholdtsen 				break;
898c18ec02fSPetter Reinholdtsen 			}
899c18ec02fSPetter Reinholdtsen 			string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE
900c18ec02fSPetter Reinholdtsen 				* (ii-1);
901c18ec02fSPetter Reinholdtsen 			memcpy(lcdstring+string_offset,
902c18ec02fSPetter Reinholdtsen 					lcdstringblock.lcd_string.selector_n_data, bytes_to_copy);
903c18ec02fSPetter Reinholdtsen 		}
904c18ec02fSPetter Reinholdtsen 		bytes_copied += bytes_to_copy;
905c18ec02fSPetter Reinholdtsen 		if (bytes_copied >= lcdstring_len) {
906c18ec02fSPetter Reinholdtsen 			break;
907c18ec02fSPetter Reinholdtsen 		}
908c18ec02fSPetter Reinholdtsen 	}
909c18ec02fSPetter Reinholdtsen 	return 0;
910c18ec02fSPetter Reinholdtsen }
911c18ec02fSPetter Reinholdtsen /*
912c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_lcd_get_info_wh
913c18ec02fSPetter Reinholdtsen  *
914c18ec02fSPetter Reinholdtsen  * Description:     This function prints current lcd configuration for whoville platform
915c18ec02fSPetter Reinholdtsen  * Input:           intf            - ipmi interface
916c18ec02fSPetter Reinholdtsen  * Output:
917c18ec02fSPetter Reinholdtsen  * Return:
918c18ec02fSPetter Reinholdtsen  */
919c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_get_info_wh(struct ipmi_intf * intf)920c18ec02fSPetter Reinholdtsen ipmi_lcd_get_info_wh(struct ipmi_intf * intf)
921c18ec02fSPetter Reinholdtsen {
922c18ec02fSPetter Reinholdtsen 	IPMI_DELL_LCD_CAPS lcd_caps;
923c18ec02fSPetter Reinholdtsen 	char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0};
924c18ec02fSPetter Reinholdtsen 	int rc;
925c18ec02fSPetter Reinholdtsen 	printf("LCD info\n");
926c18ec02fSPetter Reinholdtsen 	if (ipmi_lcd_get_configure_command_wh(intf) != 0) {
927c18ec02fSPetter Reinholdtsen 		return -1;
928c18ec02fSPetter Reinholdtsen 	}
929c18ec02fSPetter Reinholdtsen 	if (lcd_mode.lcdmode== IPMI_DELL_LCD_CONFIG_DEFAULT) {
930c18ec02fSPetter Reinholdtsen 		char text[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0};
931c18ec02fSPetter Reinholdtsen 		if (ipmi_lcd_get_platform_model_name(intf, text,
932c18ec02fSPetter Reinholdtsen 					IPMI_DELL_LCD_STRING_LENGTH_MAX,
933c18ec02fSPetter Reinholdtsen 					IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR) != 0) {
934c18ec02fSPetter Reinholdtsen 			return (-1);
935c18ec02fSPetter Reinholdtsen 		}
936c18ec02fSPetter Reinholdtsen 		printf("    Setting:Model name\n");
937c18ec02fSPetter Reinholdtsen 		printf("    Line 1:  %s\n", text);
938c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_NONE) {
939c18ec02fSPetter Reinholdtsen 		printf("    Setting:   none\n");
940c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_USER_DEFINED) {
941c18ec02fSPetter Reinholdtsen 		printf("    Setting: User defined\n");
942c18ec02fSPetter Reinholdtsen 		rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_GET_CAPS_SELECTOR, 0, 0,
943c18ec02fSPetter Reinholdtsen 				sizeof(lcd_caps), &lcd_caps);
944c18ec02fSPetter Reinholdtsen 		if (rc < 0) {
945c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting LCD capabilities.");
946c18ec02fSPetter Reinholdtsen 			return -1;
947c18ec02fSPetter Reinholdtsen 		} else if ((rc == 0xc1) || (rc == 0xcb)) {
948c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting LCD capabilities: "
949c18ec02fSPetter Reinholdtsen 					"Command not supported on this system.");
950c18ec02fSPetter Reinholdtsen 		} else if (rc > 0) {
951c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting LCD capabilities: %s",
952c18ec02fSPetter Reinholdtsen 					val2str(rc, completion_code_vals));
953c18ec02fSPetter Reinholdtsen 			return -1;
954c18ec02fSPetter Reinholdtsen 		}
955c18ec02fSPetter Reinholdtsen 		if (lcd_caps.number_lines > 0) {
956c18ec02fSPetter Reinholdtsen 			memset(lcdstring, 0, IPMI_DELL_LCD_STRING_LENGTH_MAX + 1);
957c18ec02fSPetter Reinholdtsen 			rc = ipmi_lcd_get_single_line_text(intf, lcdstring,
958c18ec02fSPetter Reinholdtsen 					lcd_caps.max_chars[0]);
959c18ec02fSPetter Reinholdtsen 			printf("    Text:    %s\n", lcdstring);
960c18ec02fSPetter Reinholdtsen 		} else {
961c18ec02fSPetter Reinholdtsen 			printf("    No lines to show\n");
962c18ec02fSPetter Reinholdtsen 		}
963c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV4ADRESS) {
964c18ec02fSPetter Reinholdtsen 		printf("    Setting:   IPV4 Address\n");
965c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_IDRAC_MAC_ADDRESS) {
966c18ec02fSPetter Reinholdtsen 		printf("    Setting:   MAC Address\n");
967c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_OS_SYSTEM_NAME) {
968c18ec02fSPetter Reinholdtsen 		printf("    Setting:   OS System Name\n");
969c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SERVICE_TAG) {
970c18ec02fSPetter Reinholdtsen 		printf("    Setting:   System Tag\n");
971c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV6ADRESS) {
972c18ec02fSPetter Reinholdtsen 		printf("    Setting:  IPV6 Address\n");
973c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_ASSET_TAG) {
974c18ec02fSPetter Reinholdtsen 		printf("    Setting:  Asset Tag\n");
975c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_AMBEINT_TEMP) {
976c18ec02fSPetter Reinholdtsen 		printf("    Setting:  Ambient Temp\n");
977c18ec02fSPetter Reinholdtsen 		if (lcd_mode.lcdquallifier & 0x02) {
978c18ec02fSPetter Reinholdtsen 			printf("    Unit:  F\n");
979c18ec02fSPetter Reinholdtsen 		} else {
980c18ec02fSPetter Reinholdtsen 			printf("    Unit:  C\n");
981c18ec02fSPetter Reinholdtsen 		}
982c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SYSTEM_WATTS) {
983c18ec02fSPetter Reinholdtsen 		printf("    Setting:  System Watts\n");
984c18ec02fSPetter Reinholdtsen 		if (lcd_mode.lcdquallifier & 0x01) {
985c18ec02fSPetter Reinholdtsen 			printf("    Unit:  BTU/hr\n");
986c18ec02fSPetter Reinholdtsen 		} else {
987c18ec02fSPetter Reinholdtsen 			printf("    Unit:  Watt\n");
988c18ec02fSPetter Reinholdtsen 		}
989c18ec02fSPetter Reinholdtsen 	}
990c18ec02fSPetter Reinholdtsen 	if (lcd_mode.error_display == IPMI_DELL_LCD_ERROR_DISP_SEL) {
991c18ec02fSPetter Reinholdtsen 		printf("    Error Display:  SEL\n");
992c18ec02fSPetter Reinholdtsen 	} else if (lcd_mode.error_display == IPMI_DELL_LCD_ERROR_DISP_VERBOSE) {
993c18ec02fSPetter Reinholdtsen 		printf("    Error Display:  Simple\n");
994c18ec02fSPetter Reinholdtsen 	}
995c18ec02fSPetter Reinholdtsen 	return 0;
996c18ec02fSPetter Reinholdtsen }
997c18ec02fSPetter Reinholdtsen /*
998c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_lcd_get_info
999c18ec02fSPetter Reinholdtsen  *
1000c18ec02fSPetter Reinholdtsen  * Description:      This function prints current lcd configuration for platform other than whoville
1001c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
1002c18ec02fSPetter Reinholdtsen  * Output:
1003c18ec02fSPetter Reinholdtsen  * Return:
1004c18ec02fSPetter Reinholdtsen  */
1005c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_get_info(struct ipmi_intf * intf)1006c18ec02fSPetter Reinholdtsen ipmi_lcd_get_info(struct ipmi_intf * intf)
1007c18ec02fSPetter Reinholdtsen {
1008c18ec02fSPetter Reinholdtsen 	IPMI_DELL_LCD_CAPS lcd_caps;
1009c18ec02fSPetter Reinholdtsen 	uint8_t command = 0;
1010c18ec02fSPetter Reinholdtsen 	char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0};
1011c18ec02fSPetter Reinholdtsen 	int rc;
1012c18ec02fSPetter Reinholdtsen 
1013c18ec02fSPetter Reinholdtsen 	printf("LCD info\n");
1014c18ec02fSPetter Reinholdtsen 
1015c18ec02fSPetter Reinholdtsen 	if (ipmi_lcd_get_configure_command(intf, &command) != 0) {
1016c18ec02fSPetter Reinholdtsen 		return -1;
1017c18ec02fSPetter Reinholdtsen 	}
1018c18ec02fSPetter Reinholdtsen 	if (command == IPMI_DELL_LCD_CONFIG_DEFAULT) {
1019c18ec02fSPetter Reinholdtsen 		memset(lcdstring,0,IPMI_DELL_LCD_STRING_LENGTH_MAX+1);
1020c18ec02fSPetter Reinholdtsen 		if (ipmi_lcd_get_platform_model_name(intf, lcdstring,
1021c18ec02fSPetter Reinholdtsen 					IPMI_DELL_LCD_STRING_LENGTH_MAX,
1022c18ec02fSPetter Reinholdtsen 					IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR) != 0) {
1023c18ec02fSPetter Reinholdtsen 			return (-1);
1024c18ec02fSPetter Reinholdtsen 		}
1025c18ec02fSPetter Reinholdtsen 		printf("    Setting: default\n");
1026c18ec02fSPetter Reinholdtsen 		printf("    Line 1:  %s\n", lcdstring);
1027c18ec02fSPetter Reinholdtsen 	} else if (command == IPMI_DELL_LCD_CONFIG_NONE) {
1028c18ec02fSPetter Reinholdtsen 		printf("    Setting:   none\n");
1029c18ec02fSPetter Reinholdtsen 	} else if (command == IPMI_DELL_LCD_CONFIG_USER_DEFINED) {
1030c18ec02fSPetter Reinholdtsen 		printf("    Setting: custom\n");
1031c18ec02fSPetter Reinholdtsen 		rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_GET_CAPS_SELECTOR, 0, 0,
1032c18ec02fSPetter Reinholdtsen 				sizeof(lcd_caps), &lcd_caps);
1033c18ec02fSPetter Reinholdtsen 		if (rc < 0) {
1034c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting LCD capabilities.");
1035c18ec02fSPetter Reinholdtsen 			return -1;
1036c18ec02fSPetter Reinholdtsen 		} else if ((rc == 0xc1) || (rc == 0xcb)) {
1037c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting LCD capabilities: "
1038c18ec02fSPetter Reinholdtsen 					"Command not supported on this system.");
1039c18ec02fSPetter Reinholdtsen 		} else if (rc > 0) {
1040c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error getting LCD capabilities: %s",
1041c18ec02fSPetter Reinholdtsen 					val2str(rc, completion_code_vals));
1042c18ec02fSPetter Reinholdtsen 			return -1;
1043c18ec02fSPetter Reinholdtsen 		}
1044c18ec02fSPetter Reinholdtsen 		if (lcd_caps.number_lines > 0) {
1045c18ec02fSPetter Reinholdtsen 			memset(lcdstring, 0, IPMI_DELL_LCD_STRING_LENGTH_MAX + 1);
1046c18ec02fSPetter Reinholdtsen 			rc = ipmi_lcd_get_single_line_text(intf, lcdstring,
1047c18ec02fSPetter Reinholdtsen 					lcd_caps.max_chars[0]);
1048c18ec02fSPetter Reinholdtsen 			printf("    Text:    %s\n", lcdstring);
1049c18ec02fSPetter Reinholdtsen 		} else {
1050c18ec02fSPetter Reinholdtsen 			printf("    No lines to show\n");
1051c18ec02fSPetter Reinholdtsen 		}
1052c18ec02fSPetter Reinholdtsen 	}
1053c18ec02fSPetter Reinholdtsen 	return 0;
1054c18ec02fSPetter Reinholdtsen }
1055c18ec02fSPetter Reinholdtsen /*
1056c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_lcd_get_status_val
1057c18ec02fSPetter Reinholdtsen  *
1058c18ec02fSPetter Reinholdtsen  * Description:      This function gets current lcd configuration
1059c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
1060c18ec02fSPetter Reinholdtsen  * Output:           lcdstatus       - KVM Status & Lock Status
1061c18ec02fSPetter Reinholdtsen  * Return:
1062c18ec02fSPetter Reinholdtsen  */
1063c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_get_status_val(struct ipmi_intf * intf,LCD_STATUS * lcdstatus)1064c18ec02fSPetter Reinholdtsen ipmi_lcd_get_status_val(struct ipmi_intf * intf, LCD_STATUS* lcdstatus)
1065c18ec02fSPetter Reinholdtsen {
1066c18ec02fSPetter Reinholdtsen 	int rc;
1067c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_STATUS_SELECTOR, 0, 0,
1068c18ec02fSPetter Reinholdtsen 			sizeof(*lcdstatus), lcdstatus);
1069c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
1070c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD Status");
1071c18ec02fSPetter Reinholdtsen 		return -1;
1072c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1) || (rc == 0xcb)) {
1073c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD status: "
1074c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
1075c18ec02fSPetter Reinholdtsen 		return -1;
1076c18ec02fSPetter Reinholdtsen 	} else if (rc > 0) {
1077c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD Status: %s",
1078c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
1079c18ec02fSPetter Reinholdtsen 		return -1;
1080c18ec02fSPetter Reinholdtsen 	}
1081c18ec02fSPetter Reinholdtsen 	return 0;
1082c18ec02fSPetter Reinholdtsen }
1083c18ec02fSPetter Reinholdtsen /*
1084c18ec02fSPetter Reinholdtsen  * Function Name:    IsLCDSupported
1085c18ec02fSPetter Reinholdtsen  *
1086c18ec02fSPetter Reinholdtsen  * Description:   This function returns whether lcd supported or not
1087c18ec02fSPetter Reinholdtsen  * Input:
1088c18ec02fSPetter Reinholdtsen  * Output:
1089c18ec02fSPetter Reinholdtsen  * Return:
1090c18ec02fSPetter Reinholdtsen  */
1091c18ec02fSPetter Reinholdtsen static int
IsLCDSupported()1092c18ec02fSPetter Reinholdtsen IsLCDSupported()
1093c18ec02fSPetter Reinholdtsen {
1094c18ec02fSPetter Reinholdtsen 	return LcdSupported;
1095c18ec02fSPetter Reinholdtsen }
1096c18ec02fSPetter Reinholdtsen /*
1097c18ec02fSPetter Reinholdtsen  * Function Name:         CheckLCDSupport
1098c18ec02fSPetter Reinholdtsen  *
1099c18ec02fSPetter Reinholdtsen  * Description:  This function checks whether lcd supported or not
1100c18ec02fSPetter Reinholdtsen  * Input:        intf            - ipmi interface
1101c18ec02fSPetter Reinholdtsen  * Output:
1102c18ec02fSPetter Reinholdtsen  * Return:
1103c18ec02fSPetter Reinholdtsen  */
1104c18ec02fSPetter Reinholdtsen static void
CheckLCDSupport(struct ipmi_intf * intf)1105c18ec02fSPetter Reinholdtsen CheckLCDSupport(struct ipmi_intf * intf)
1106c18ec02fSPetter Reinholdtsen {
1107c18ec02fSPetter Reinholdtsen 	int rc;
1108c18ec02fSPetter Reinholdtsen 	LcdSupported = 0;
1109c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_STATUS_SELECTOR, 0, 0, 0, NULL);
1110c18ec02fSPetter Reinholdtsen 	if (rc == 0) {
1111c18ec02fSPetter Reinholdtsen 		LcdSupported = 1;
1112c18ec02fSPetter Reinholdtsen 	}
1113c18ec02fSPetter Reinholdtsen }
1114c18ec02fSPetter Reinholdtsen /*
1115c18ec02fSPetter Reinholdtsen  * Function Name:     ipmi_lcd_status_print
1116c18ec02fSPetter Reinholdtsen  *
1117c18ec02fSPetter Reinholdtsen  * Description:    This function prints current lcd configuration KVM Status & Lock Status
1118c18ec02fSPetter Reinholdtsen  * Input:          lcdstatus - KVM Status & Lock Status
1119c18ec02fSPetter Reinholdtsen  * Output:
1120c18ec02fSPetter Reinholdtsen  * Return:
1121c18ec02fSPetter Reinholdtsen  */
1122c18ec02fSPetter Reinholdtsen static void
ipmi_lcd_status_print(LCD_STATUS lcdstatus)1123c18ec02fSPetter Reinholdtsen ipmi_lcd_status_print(LCD_STATUS lcdstatus)
1124c18ec02fSPetter Reinholdtsen {
1125c18ec02fSPetter Reinholdtsen 	switch (lcdstatus.vKVM_status) {
1126c18ec02fSPetter Reinholdtsen 		case 0x00:
1127c18ec02fSPetter Reinholdtsen 			printf("LCD KVM Status :Inactive\n");
1128c18ec02fSPetter Reinholdtsen 			break;
1129c18ec02fSPetter Reinholdtsen 		case 0x01:
1130c18ec02fSPetter Reinholdtsen 			printf("LCD KVM Status :Active\n");
1131c18ec02fSPetter Reinholdtsen 			break;
1132c18ec02fSPetter Reinholdtsen 		default:
1133c18ec02fSPetter Reinholdtsen 			printf("LCD KVM Status :Invalid Status\n");
1134c18ec02fSPetter Reinholdtsen 			break;
1135c18ec02fSPetter Reinholdtsen 	}
1136c18ec02fSPetter Reinholdtsen 	switch (lcdstatus.lock_status) {
1137c18ec02fSPetter Reinholdtsen 		case 0x00:
1138c18ec02fSPetter Reinholdtsen 			printf("LCD lock Status :View and modify\n");
1139c18ec02fSPetter Reinholdtsen 			break;
1140c18ec02fSPetter Reinholdtsen 		case 0x01:
1141c18ec02fSPetter Reinholdtsen 			printf("LCD lock Status :View only\n");
1142c18ec02fSPetter Reinholdtsen 			break;
1143c18ec02fSPetter Reinholdtsen 		case 0x02:
1144c18ec02fSPetter Reinholdtsen 			printf("LCD lock Status :disabled\n");
1145c18ec02fSPetter Reinholdtsen 			break;
1146c18ec02fSPetter Reinholdtsen 		default:
1147c18ec02fSPetter Reinholdtsen 			printf("LCD lock Status :Invalid\n");
1148c18ec02fSPetter Reinholdtsen 			break;
1149c18ec02fSPetter Reinholdtsen 	}
1150c18ec02fSPetter Reinholdtsen }
1151c18ec02fSPetter Reinholdtsen /*
1152c18ec02fSPetter Reinholdtsen  * Function Name:     ipmi_lcd_get_status
1153c18ec02fSPetter Reinholdtsen  *
1154c18ec02fSPetter Reinholdtsen  * Description:      This function gets current lcd KVM active status & lcd access mode
1155c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
1156c18ec02fSPetter Reinholdtsen  * Output:
1157c18ec02fSPetter Reinholdtsen  * Return:           -1 on error
1158c18ec02fSPetter Reinholdtsen  *                   0 if successful
1159c18ec02fSPetter Reinholdtsen  */
1160c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_get_status(struct ipmi_intf * intf)1161c18ec02fSPetter Reinholdtsen ipmi_lcd_get_status(struct ipmi_intf * intf)
1162c18ec02fSPetter Reinholdtsen {
1163c18ec02fSPetter Reinholdtsen 	int rc=0;
1164c18ec02fSPetter Reinholdtsen 	LCD_STATUS  lcdstatus;
1165c18ec02fSPetter Reinholdtsen 	rc =ipmi_lcd_get_status_val( intf, &lcdstatus);
1166c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
1167c18ec02fSPetter Reinholdtsen 		return -1;
1168c18ec02fSPetter Reinholdtsen 	}
1169c18ec02fSPetter Reinholdtsen 	ipmi_lcd_status_print(lcdstatus);
1170c18ec02fSPetter Reinholdtsen 	return rc;
1171c18ec02fSPetter Reinholdtsen }
1172c18ec02fSPetter Reinholdtsen /*
1173c18ec02fSPetter Reinholdtsen  * Function Name:     ipmi_lcd_set_kvm
1174c18ec02fSPetter Reinholdtsen  *
1175c18ec02fSPetter Reinholdtsen  * Description:       This function sets lcd KVM active status
1176c18ec02fSPetter Reinholdtsen  * Input:             intf            - ipmi interface
1177c18ec02fSPetter Reinholdtsen  *                    status  - Inactive / Active
1178c18ec02fSPetter Reinholdtsen  * Output:
1179c18ec02fSPetter Reinholdtsen  * Return:            -1 on error
1180c18ec02fSPetter Reinholdtsen  *                    0 if successful
1181c18ec02fSPetter Reinholdtsen  */
1182c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_set_kvm(struct ipmi_intf * intf,char status)1183c18ec02fSPetter Reinholdtsen ipmi_lcd_set_kvm(struct ipmi_intf * intf, char status)
1184c18ec02fSPetter Reinholdtsen {
1185c18ec02fSPetter Reinholdtsen 	#define LSCC_DATA_LEN 2
1186c18ec02fSPetter Reinholdtsen 	LCD_STATUS lcdstatus;
1187c18ec02fSPetter Reinholdtsen 	int rc=0;
1188c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = NULL;
1189c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req = {0};
1190c18ec02fSPetter Reinholdtsen 	uint8_t data[5];
1191c18ec02fSPetter Reinholdtsen 	rc = ipmi_lcd_get_status_val(intf,&lcdstatus);
1192c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
1193c18ec02fSPetter Reinholdtsen 		return -1;
1194c18ec02fSPetter Reinholdtsen 	}
1195c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
1196c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
1197c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_SET_SYS_INFO;
1198c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 5;
1199c18ec02fSPetter Reinholdtsen 	req.msg.data = data;
1200c18ec02fSPetter Reinholdtsen 	data[0] = IPMI_DELL_LCD_STATUS_SELECTOR;
1201c18ec02fSPetter Reinholdtsen 	data[1] = status; /* active- incative*/
1202c18ec02fSPetter Reinholdtsen 	data[2] = lcdstatus.lock_status; /* full-veiw-locked */
1203c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
1204c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
1205c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD status");
1206c18ec02fSPetter Reinholdtsen 		rc= -1;
1207c18ec02fSPetter Reinholdtsen 	} else if ((rsp->ccode == 0xc1) || (rsp->ccode == 0xcb)) {
1208c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD status: "
1209c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
1210c18ec02fSPetter Reinholdtsen 		return -1;
1211c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
1212c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD status: %s",
1213c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
1214c18ec02fSPetter Reinholdtsen 		rc= -1;
1215c18ec02fSPetter Reinholdtsen 	}
1216c18ec02fSPetter Reinholdtsen 	return rc;
1217c18ec02fSPetter Reinholdtsen }
1218c18ec02fSPetter Reinholdtsen /*
1219c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_lcd_set_lock
1220c18ec02fSPetter Reinholdtsen  *
1221c18ec02fSPetter Reinholdtsen  * Description:     This function sets lcd access mode
1222c18ec02fSPetter Reinholdtsen  * Input:           intf            - ipmi interface
1223c18ec02fSPetter Reinholdtsen  *                  lock    - View and modify / View only / Diabled
1224c18ec02fSPetter Reinholdtsen  * Output:
1225c18ec02fSPetter Reinholdtsen  * Return:          -1 on error
1226c18ec02fSPetter Reinholdtsen  *                  0 if successful
1227c18ec02fSPetter Reinholdtsen  */
1228c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_set_lock(struct ipmi_intf * intf,char lock)1229c18ec02fSPetter Reinholdtsen ipmi_lcd_set_lock(struct ipmi_intf * intf,  char lock)
1230c18ec02fSPetter Reinholdtsen {
1231c18ec02fSPetter Reinholdtsen 	#define LSCC_DATA_LEN 2
1232c18ec02fSPetter Reinholdtsen 	LCD_STATUS lcdstatus;
1233c18ec02fSPetter Reinholdtsen 	int rc =0;
1234c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = NULL;
1235c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req = {0};
1236c18ec02fSPetter Reinholdtsen 	uint8_t data[5];
1237c18ec02fSPetter Reinholdtsen 	rc = ipmi_lcd_get_status_val(intf,&lcdstatus);
1238c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
1239c18ec02fSPetter Reinholdtsen 		return -1;
1240c18ec02fSPetter Reinholdtsen 	}
1241c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
1242c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
1243c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_SET_SYS_INFO;
1244c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 5;
1245c18ec02fSPetter Reinholdtsen 	req.msg.data = data;
1246c18ec02fSPetter Reinholdtsen 	data[0] = IPMI_DELL_LCD_STATUS_SELECTOR;
1247c18ec02fSPetter Reinholdtsen 	data[1] = lcdstatus.vKVM_status; /* active- incative */
1248c18ec02fSPetter Reinholdtsen 	data[2] = lock; /* full- veiw-locked */
1249c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
1250c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
1251c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD status");
1252c18ec02fSPetter Reinholdtsen 		rc = -1;
1253c18ec02fSPetter Reinholdtsen 	} else if ((rsp->ccode == 0xc1) || (rsp->ccode == 0xcb)) {
1254c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD status: "
1255c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
1256c18ec02fSPetter Reinholdtsen 		rc = -1;
1257c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
1258c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting LCD status: %s",
1259c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
1260c18ec02fSPetter Reinholdtsen 		rc= -1;
1261c18ec02fSPetter Reinholdtsen 	}
1262c18ec02fSPetter Reinholdtsen 	return rc;
1263c18ec02fSPetter Reinholdtsen }
1264c18ec02fSPetter Reinholdtsen /*
1265c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_lcd_set_single_line_text
1266c18ec02fSPetter Reinholdtsen  *
1267c18ec02fSPetter Reinholdtsen  * Description:    This function sets lcd line text
1268c18ec02fSPetter Reinholdtsen  * Input:          intf            - ipmi interface
1269c18ec02fSPetter Reinholdtsen  *                 text    - lcd string
1270c18ec02fSPetter Reinholdtsen  * Output:
1271c18ec02fSPetter Reinholdtsen  * Return:         -1 on error
1272c18ec02fSPetter Reinholdtsen  *                 0 if successful
1273c18ec02fSPetter Reinholdtsen  */
1274c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_set_single_line_text(struct ipmi_intf * intf,char * text)1275c18ec02fSPetter Reinholdtsen ipmi_lcd_set_single_line_text(struct ipmi_intf * intf, char * text)
1276c18ec02fSPetter Reinholdtsen {
1277c18ec02fSPetter Reinholdtsen 	uint8_t data[18];
1278c18ec02fSPetter Reinholdtsen 	int bytes_to_store = strlen(text);
1279c18ec02fSPetter Reinholdtsen 	int bytes_stored = 0;
1280c18ec02fSPetter Reinholdtsen 	int ii;
1281c18ec02fSPetter Reinholdtsen 	int rc = 0;
1282c18ec02fSPetter Reinholdtsen 	if (bytes_to_store > IPMI_DELL_LCD_STRING_LENGTH_MAX) {
1283c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Out of range Max limit is 62 characters");
1284c18ec02fSPetter Reinholdtsen 		return (-1);
1285c18ec02fSPetter Reinholdtsen 	} else {
1286c18ec02fSPetter Reinholdtsen 		bytes_to_store = MIN(bytes_to_store, IPMI_DELL_LCD_STRING_LENGTH_MAX);
1287c18ec02fSPetter Reinholdtsen 		for (ii = 0; ii < 4; ii++) {
1288c18ec02fSPetter Reinholdtsen 			/*first block, 2 bytes parms and 14 bytes data*/
1289c18ec02fSPetter Reinholdtsen 			if (0 == ii) {
1290c18ec02fSPetter Reinholdtsen 				int size_of_copy = MIN((bytes_to_store - bytes_stored),
1291c18ec02fSPetter Reinholdtsen 						IPMI_DELL_LCD_STRING1_SIZE);
1292c18ec02fSPetter Reinholdtsen 				if (size_of_copy < 0) {
1293c18ec02fSPetter Reinholdtsen 					/* allow 0 string length*/
1294c18ec02fSPetter Reinholdtsen 					break;
1295c18ec02fSPetter Reinholdtsen 				}
1296c18ec02fSPetter Reinholdtsen 				data[0] = IPMI_DELL_LCD_STRING_SELECTOR;
1297c18ec02fSPetter Reinholdtsen 				data[1] = ii; /* block number to use (0)*/
1298c18ec02fSPetter Reinholdtsen 				data[2] = 0; /*string encoding*/
1299c18ec02fSPetter Reinholdtsen 				data[3] = bytes_to_store; /* total string length*/
1300c18ec02fSPetter Reinholdtsen 				memcpy(data + 4, text+bytes_stored, size_of_copy);
1301c18ec02fSPetter Reinholdtsen 				bytes_stored += size_of_copy;
1302c18ec02fSPetter Reinholdtsen 			} else {
1303c18ec02fSPetter Reinholdtsen 				int size_of_copy = MIN((bytes_to_store - bytes_stored),
1304c18ec02fSPetter Reinholdtsen 						IPMI_DELL_LCD_STRINGN_SIZE);
1305c18ec02fSPetter Reinholdtsen 				if (size_of_copy <= 0) {
1306c18ec02fSPetter Reinholdtsen 					break;
1307c18ec02fSPetter Reinholdtsen 				}
1308c18ec02fSPetter Reinholdtsen 				data[0] = IPMI_DELL_LCD_STRING_SELECTOR;
1309c18ec02fSPetter Reinholdtsen 				data[1] = ii; /* block number to use (1,2,3)*/
1310c18ec02fSPetter Reinholdtsen 				memcpy(data + 2, text+bytes_stored, size_of_copy);
1311c18ec02fSPetter Reinholdtsen 				bytes_stored += size_of_copy;
1312c18ec02fSPetter Reinholdtsen 			}
1313c18ec02fSPetter Reinholdtsen 			rc = ipmi_mc_setsysinfo(intf, 18, data);
1314c18ec02fSPetter Reinholdtsen 			if (rc < 0) {
1315c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Error setting text data");
1316c18ec02fSPetter Reinholdtsen 				rc = -1;
1317c18ec02fSPetter Reinholdtsen 			} else if (rc > 0) {
1318c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Error setting text data: %s",
1319c18ec02fSPetter Reinholdtsen 						val2str(rc, completion_code_vals));
1320c18ec02fSPetter Reinholdtsen 				rc = -1;
1321c18ec02fSPetter Reinholdtsen 			}
1322c18ec02fSPetter Reinholdtsen 		}
1323c18ec02fSPetter Reinholdtsen 	}
1324c18ec02fSPetter Reinholdtsen 	return rc;
1325c18ec02fSPetter Reinholdtsen }
1326c18ec02fSPetter Reinholdtsen /*
1327c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_lcd_set_text
1328c18ec02fSPetter Reinholdtsen  *
1329c18ec02fSPetter Reinholdtsen  * Description:     This function sets lcd line text
1330c18ec02fSPetter Reinholdtsen  * Input:           intf            - ipmi interface
1331c18ec02fSPetter Reinholdtsen  *                  text    - lcd string
1332c18ec02fSPetter Reinholdtsen  *                  line_number- line number
1333c18ec02fSPetter Reinholdtsen  * Output:
1334c18ec02fSPetter Reinholdtsen  * Return:          -1 on error
1335c18ec02fSPetter Reinholdtsen  *                  0 if successful
1336c18ec02fSPetter Reinholdtsen  */
1337c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_set_text(struct ipmi_intf * intf,char * text,int line_number)1338c18ec02fSPetter Reinholdtsen ipmi_lcd_set_text(struct ipmi_intf * intf, char * text, int line_number)
1339c18ec02fSPetter Reinholdtsen {
1340c18ec02fSPetter Reinholdtsen 	int rc = 0;
1341c18ec02fSPetter Reinholdtsen 	IPMI_DELL_LCD_CAPS lcd_caps;
1342c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_LCD_GET_CAPS_SELECTOR, 0, 0,
1343c18ec02fSPetter Reinholdtsen 			sizeof(lcd_caps), &lcd_caps);
1344c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
1345c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD capabilities");
1346c18ec02fSPetter Reinholdtsen 		return -1;
1347c18ec02fSPetter Reinholdtsen 	} else if (rc > 0) {
1348c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting LCD capabilities: %s",
1349c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
1350c18ec02fSPetter Reinholdtsen 		return -1;
1351c18ec02fSPetter Reinholdtsen 	}
1352c18ec02fSPetter Reinholdtsen 	if (lcd_caps.number_lines > 0) {
1353c18ec02fSPetter Reinholdtsen 		rc = ipmi_lcd_set_single_line_text(intf, text);
1354c18ec02fSPetter Reinholdtsen 	} else {
1355c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "LCD does not have any lines that can be set");
1356c18ec02fSPetter Reinholdtsen 		rc = -1;
1357c18ec02fSPetter Reinholdtsen 	}
1358c18ec02fSPetter Reinholdtsen 	return rc;
1359c18ec02fSPetter Reinholdtsen }
1360c18ec02fSPetter Reinholdtsen /*
1361c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_lcd_configure_wh
1362c18ec02fSPetter Reinholdtsen  *
1363c18ec02fSPetter Reinholdtsen  * Description:     This function updates the current lcd configuration
1364c18ec02fSPetter Reinholdtsen  * Input:           intf            - ipmi interface
1365c18ec02fSPetter Reinholdtsen  *                  lcdquallifier- lcd quallifier
1366c18ec02fSPetter Reinholdtsen  *                  errordisp       - error number
1367c18ec02fSPetter Reinholdtsen  *                  line_number-line number
1368c18ec02fSPetter Reinholdtsen  *                  text            - lcd string
1369c18ec02fSPetter Reinholdtsen  * Output:
1370c18ec02fSPetter Reinholdtsen  * Return:          -1 on error
1371c18ec02fSPetter Reinholdtsen  *                  0 if successful
1372c18ec02fSPetter Reinholdtsen  */
1373c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_configure_wh(struct ipmi_intf * intf,uint32_t mode,uint16_t lcdquallifier,uint8_t errordisp,int8_t line_number,char * text)1374c18ec02fSPetter Reinholdtsen ipmi_lcd_configure_wh(struct ipmi_intf * intf, uint32_t  mode,
1375c18ec02fSPetter Reinholdtsen 		uint16_t lcdquallifier, uint8_t errordisp, int8_t line_number, char * text)
1376c18ec02fSPetter Reinholdtsen {
1377c18ec02fSPetter Reinholdtsen 	int rc = 0;
1378c18ec02fSPetter Reinholdtsen 	if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == mode) {
1379c18ec02fSPetter Reinholdtsen 		/* Any error was reported earlier. */
1380c18ec02fSPetter Reinholdtsen 		rc = ipmi_lcd_set_text(intf, text, line_number);
1381c18ec02fSPetter Reinholdtsen 	}
1382c18ec02fSPetter Reinholdtsen 	if (rc == 0) {
1383c18ec02fSPetter Reinholdtsen 		rc = ipmi_lcd_set_configure_command_wh(intf, mode ,lcdquallifier,errordisp);
1384c18ec02fSPetter Reinholdtsen 	}
1385c18ec02fSPetter Reinholdtsen 	return rc;
1386c18ec02fSPetter Reinholdtsen }
1387c18ec02fSPetter Reinholdtsen /*
1388c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_lcd_configure
1389c18ec02fSPetter Reinholdtsen  *
1390c18ec02fSPetter Reinholdtsen  * Description:     This function updates the current lcd configuration
1391c18ec02fSPetter Reinholdtsen  * Input:           intf            - ipmi interface
1392c18ec02fSPetter Reinholdtsen  *                  command- lcd command
1393c18ec02fSPetter Reinholdtsen  *                  line_number-line number
1394c18ec02fSPetter Reinholdtsen  *                  text            - lcd string
1395c18ec02fSPetter Reinholdtsen  * Output:
1396c18ec02fSPetter Reinholdtsen  * Return:          -1 on error
1397c18ec02fSPetter Reinholdtsen  *                  0 if successful
1398c18ec02fSPetter Reinholdtsen  */
1399c18ec02fSPetter Reinholdtsen static int
ipmi_lcd_configure(struct ipmi_intf * intf,int command,int8_t line_number,char * text)1400c18ec02fSPetter Reinholdtsen ipmi_lcd_configure(struct ipmi_intf * intf, int command,
1401c18ec02fSPetter Reinholdtsen 		int8_t line_number, char * text)
1402c18ec02fSPetter Reinholdtsen {
1403c18ec02fSPetter Reinholdtsen 	int rc = 0;
1404c18ec02fSPetter Reinholdtsen 	if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == command) {
1405c18ec02fSPetter Reinholdtsen 		rc = ipmi_lcd_set_text(intf, text, line_number);
1406c18ec02fSPetter Reinholdtsen 	}
1407c18ec02fSPetter Reinholdtsen 	if (rc == 0) {
1408c18ec02fSPetter Reinholdtsen 		rc = ipmi_lcd_set_configure_command(intf, command);
1409c18ec02fSPetter Reinholdtsen 	}
1410c18ec02fSPetter Reinholdtsen 	return rc;
1411c18ec02fSPetter Reinholdtsen }
1412c18ec02fSPetter Reinholdtsen /*
1413c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_lcd_usage
1414c18ec02fSPetter Reinholdtsen  *
1415c18ec02fSPetter Reinholdtsen  * Description:   This function prints help message for lcd command
1416c18ec02fSPetter Reinholdtsen  * Input:
1417c18ec02fSPetter Reinholdtsen  * Output:
1418c18ec02fSPetter Reinholdtsen  *
1419c18ec02fSPetter Reinholdtsen  * Return:
1420c18ec02fSPetter Reinholdtsen  */
1421c18ec02fSPetter Reinholdtsen static void
ipmi_lcd_usage(void)1422c18ec02fSPetter Reinholdtsen ipmi_lcd_usage(void)
1423c18ec02fSPetter Reinholdtsen {
1424c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1425c18ec02fSPetter Reinholdtsen "");
1426c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1427c18ec02fSPetter Reinholdtsen "Generic DELL HW:");
1428c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1429c18ec02fSPetter Reinholdtsen "   lcd set {none}|{default}|{custom <text>}");
1430c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1431c18ec02fSPetter Reinholdtsen "      Set LCD text displayed during non-fault conditions");
1432c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1433c18ec02fSPetter Reinholdtsen "");
1434c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1435859e8a45SZdenek Styblik "iDRAC 11g or iDRAC 12g or  iDRAC 13g :");
1436c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1437c18ec02fSPetter Reinholdtsen "   lcd set {mode}|{lcdqualifier}|{errordisplay}");
1438c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1439c18ec02fSPetter Reinholdtsen "      Allows you to set the LCD mode and user-defined string.");
1440c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1441c18ec02fSPetter Reinholdtsen "");
1442c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1443c18ec02fSPetter Reinholdtsen "   lcd set mode {none}|{modelname}|{ipv4address}|{macaddress}|");
1444c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1445c18ec02fSPetter Reinholdtsen "   {systemname}|{servicetag}|{ipv6address}|{ambienttemp}");
1446c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1447c18ec02fSPetter Reinholdtsen "   {systemwatt }|{assettag}|{userdefined}<text>");
1448c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1449c18ec02fSPetter Reinholdtsen "	   Allows you to set the LCD display mode to any of the preceding");
1450c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1451c18ec02fSPetter Reinholdtsen "      parameters");
1452c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1453c18ec02fSPetter Reinholdtsen "");
1454c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1455c18ec02fSPetter Reinholdtsen "   lcd set lcdqualifier {watt}|{btuphr}|{celsius}|{fahrenheit}");
1456c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1457c18ec02fSPetter Reinholdtsen "      Allows you to set the unit for the system ambient temperature mode.");
1458c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1459c18ec02fSPetter Reinholdtsen "");
1460c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1461c18ec02fSPetter Reinholdtsen "   lcd set errordisplay {sel}|{simple}");
1462c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1463c18ec02fSPetter Reinholdtsen "      Allows you to set the error display.");
1464c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1465c18ec02fSPetter Reinholdtsen "");
1466c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1467c18ec02fSPetter Reinholdtsen "   lcd info");
1468c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1469c18ec02fSPetter Reinholdtsen "      Show LCD text that is displayed during non-fault conditions");
1470c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1471c18ec02fSPetter Reinholdtsen "");
1472c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1473c18ec02fSPetter Reinholdtsen "");
1474c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1475c18ec02fSPetter Reinholdtsen "   lcd set vkvm{active}|{inactive}");
1476c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1477c18ec02fSPetter Reinholdtsen "      Set vKVM active and inactive, message will be displayed on lcd");
1478c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1479c18ec02fSPetter Reinholdtsen "      when vKVM is active and vKVM session is in progress");
1480c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1481c18ec02fSPetter Reinholdtsen "");
1482c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1483c18ec02fSPetter Reinholdtsen "   lcd set frontpanelaccess {viewandmodify}|{viewonly}|{disabled}");
1484c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1485c18ec02fSPetter Reinholdtsen "      Set LCD mode to view and modify, view only or disabled ");
1486c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1487c18ec02fSPetter Reinholdtsen "");
1488c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1489c18ec02fSPetter Reinholdtsen "   lcd status");
1490c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1491c18ec02fSPetter Reinholdtsen "      Show LCD Status for vKVM display<active|inactive>");
1492c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1493c18ec02fSPetter Reinholdtsen "      and Front Panel access mode {viewandmodify}|{viewonly}|{disabled}");
1494c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1495c18ec02fSPetter Reinholdtsen "");
1496c18ec02fSPetter Reinholdtsen }
1497c18ec02fSPetter Reinholdtsen /*
1498c18ec02fSPetter Reinholdtsen  * Function Name:       ipmi_delloem_mac_main
1499c18ec02fSPetter Reinholdtsen  *
1500c18ec02fSPetter Reinholdtsen  * Description:         This function processes the delloem mac command
1501c18ec02fSPetter Reinholdtsen  * Input:               intf    - ipmi interface
1502c18ec02fSPetter Reinholdtsen  *                       argc    - no of arguments
1503c18ec02fSPetter Reinholdtsen  *                       argv    - argument string array
1504c18ec02fSPetter Reinholdtsen  * Output:
1505c18ec02fSPetter Reinholdtsen  *
1506c18ec02fSPetter Reinholdtsen  * Return:              return code     0 - success
1507c18ec02fSPetter Reinholdtsen  *                         -1 - failure
1508c18ec02fSPetter Reinholdtsen  */
1509c18ec02fSPetter Reinholdtsen static int
ipmi_delloem_mac_main(struct ipmi_intf * intf,int argc,char ** argv)1510c18ec02fSPetter Reinholdtsen ipmi_delloem_mac_main(struct ipmi_intf * intf, int argc, char ** argv)
1511c18ec02fSPetter Reinholdtsen {
1512c18ec02fSPetter Reinholdtsen 	int rc = 0;
1513c18ec02fSPetter Reinholdtsen 	int currIdInt = -1;
1514c18ec02fSPetter Reinholdtsen 	current_arg++;
1515c18ec02fSPetter Reinholdtsen 	if (argc > 1 && strcmp(argv[current_arg], "help") == 0) {
1516c18ec02fSPetter Reinholdtsen 		ipmi_mac_usage();
1517c18ec02fSPetter Reinholdtsen 		return 0;
1518c18ec02fSPetter Reinholdtsen 	}
1519c18ec02fSPetter Reinholdtsen 	ipmi_idracvalidator_command(intf);
1520c18ec02fSPetter Reinholdtsen 	if (argc == 1) {
1521c18ec02fSPetter Reinholdtsen 		rc = ipmi_macinfo(intf, 0xff);
1522c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "list\0", 5) == 0) {
1523c18ec02fSPetter Reinholdtsen 		rc = ipmi_macinfo(intf, 0xff);
1524c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "get\0", 4) == 0) {
1525c18ec02fSPetter Reinholdtsen 		current_arg++;
1526c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
1527c18ec02fSPetter Reinholdtsen 			ipmi_mac_usage();
1528c18ec02fSPetter Reinholdtsen 			return -1;
1529c18ec02fSPetter Reinholdtsen 		}
1530c18ec02fSPetter Reinholdtsen 		if (str2int(argv[current_arg],&currIdInt) != 0) {
1531c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
1532c18ec02fSPetter Reinholdtsen 					"Invalid NIC number. The NIC number should be between 0-8");
1533c18ec02fSPetter Reinholdtsen 			return -1;
1534c18ec02fSPetter Reinholdtsen 		}
1535c18ec02fSPetter Reinholdtsen 		if ((currIdInt > 8) || (currIdInt < 0)) {
1536c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
1537c18ec02fSPetter Reinholdtsen 					"Invalid NIC number. The NIC number should be between 0-8");
1538c18ec02fSPetter Reinholdtsen 			return -1;
1539c18ec02fSPetter Reinholdtsen 		}
1540c18ec02fSPetter Reinholdtsen 		rc = ipmi_macinfo(intf, currIdInt);
1541c18ec02fSPetter Reinholdtsen 	} else {
1542c18ec02fSPetter Reinholdtsen 		ipmi_mac_usage();
1543c18ec02fSPetter Reinholdtsen 	}
1544c18ec02fSPetter Reinholdtsen 	return rc;
1545c18ec02fSPetter Reinholdtsen }
1546c18ec02fSPetter Reinholdtsen 
1547c18ec02fSPetter Reinholdtsen EmbeddedNICMacAddressType EmbeddedNICMacAddress;
1548c18ec02fSPetter Reinholdtsen 
1549c18ec02fSPetter Reinholdtsen EmbeddedNICMacAddressType_10G EmbeddedNICMacAddress_10G;
1550c18ec02fSPetter Reinholdtsen 
1551c18ec02fSPetter Reinholdtsen static void
InitEmbeddedNICMacAddressValues()1552c18ec02fSPetter Reinholdtsen InitEmbeddedNICMacAddressValues()
1553c18ec02fSPetter Reinholdtsen {
1554c18ec02fSPetter Reinholdtsen 	uint8_t i;
1555c18ec02fSPetter Reinholdtsen 	uint8_t j;
1556c18ec02fSPetter Reinholdtsen 	for (i = 0; i < MAX_LOM; i++) {
1557c18ec02fSPetter Reinholdtsen 		EmbeddedNICMacAddress.LOMMacAddress[i].BladSlotNumber = 0;
1558c18ec02fSPetter Reinholdtsen 		EmbeddedNICMacAddress.LOMMacAddress[i].MacType = LOM_MACTYPE_RESERVED;
1559c18ec02fSPetter Reinholdtsen 		EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus =
1560c18ec02fSPetter Reinholdtsen 			LOM_ETHERNET_RESERVED;
1561c18ec02fSPetter Reinholdtsen 		EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber = 0;
1562c18ec02fSPetter Reinholdtsen 		EmbeddedNICMacAddress.LOMMacAddress[i].Reserved = 0;
1563c18ec02fSPetter Reinholdtsen 		for (j = 0; j < MACADDRESSLENGH; j++) {
1564c18ec02fSPetter Reinholdtsen 			EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j] = 0;
1565c18ec02fSPetter Reinholdtsen 			EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j] = 0;
1566c18ec02fSPetter Reinholdtsen 		}
1567c18ec02fSPetter Reinholdtsen 	}
1568c18ec02fSPetter Reinholdtsen }
1569c18ec02fSPetter Reinholdtsen 
1570c18ec02fSPetter Reinholdtsen uint8_t UseVirtualMacAddress = 0;
1571c18ec02fSPetter Reinholdtsen static int
ipmi_macinfo_drac_idrac_virtual_mac(struct ipmi_intf * intf,uint8_t NicNum)1572c18ec02fSPetter Reinholdtsen ipmi_macinfo_drac_idrac_virtual_mac(struct ipmi_intf* intf,uint8_t NicNum)
1573c18ec02fSPetter Reinholdtsen {
1574c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
1575c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
1576c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
1577c18ec02fSPetter Reinholdtsen 	uint8_t VirtualMacAddress [MACADDRESSLENGH];
1578c18ec02fSPetter Reinholdtsen 	uint8_t input_length=0;
1579c18ec02fSPetter Reinholdtsen 	uint8_t j;
1580c18ec02fSPetter Reinholdtsen 	uint8_t i;
1581c18ec02fSPetter Reinholdtsen 	if (NicNum != 0xff && NicNum != IDRAC_NIC_NUMBER) {
1582c18ec02fSPetter Reinholdtsen 		return 0;
1583c18ec02fSPetter Reinholdtsen 	}
1584c18ec02fSPetter Reinholdtsen 	UseVirtualMacAddress = 0;
1585c18ec02fSPetter Reinholdtsen 	input_length = 0;
1586c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 1; /*Get*/
1587c18ec02fSPetter Reinholdtsen 
1588c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
1589c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
1590c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_IDRAC_VIRTUAL_MAC;
1591c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
1592c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
1593c18ec02fSPetter Reinholdtsen 
1594c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
1595c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
1596c18ec02fSPetter Reinholdtsen 		return -1;
1597c18ec02fSPetter Reinholdtsen 	}
1598c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
1599c18ec02fSPetter Reinholdtsen 		return -1;
1600c18ec02fSPetter Reinholdtsen 	}
1601c18ec02fSPetter Reinholdtsen 	if ((IMC_IDRAC_12G_MODULAR == IMC_Type)
1602859e8a45SZdenek Styblik 			|| (IMC_IDRAC_12G_MONOLITHIC== IMC_Type)
1603859e8a45SZdenek Styblik 			|| (IMC_IDRAC_13G_MODULAR == IMC_Type)
1604859e8a45SZdenek Styblik 			|| (IMC_IDRAC_13G_MONOLITHIC== IMC_Type)) {
1605c18ec02fSPetter Reinholdtsen 		/* Get the Chasiss Assigned MAC Addresss for 12g Only */
1606c18ec02fSPetter Reinholdtsen 		memcpy(VirtualMacAddress, ((rsp->data) + 1), MACADDRESSLENGH);
1607c18ec02fSPetter Reinholdtsen 		for (i = 0; i < MACADDRESSLENGH; i++) {
1608c18ec02fSPetter Reinholdtsen 			if (VirtualMacAddress[i] != 0) {
1609c18ec02fSPetter Reinholdtsen 				UseVirtualMacAddress = 1;
1610c18ec02fSPetter Reinholdtsen 			}
1611c18ec02fSPetter Reinholdtsen 		}
1612c18ec02fSPetter Reinholdtsen 		/* Get the Server Assigned MAC Addresss for 12g Only */
1613c18ec02fSPetter Reinholdtsen 		if (!UseVirtualMacAddress) {
1614c18ec02fSPetter Reinholdtsen 			memcpy(VirtualMacAddress, ((rsp->data) + 1 + MACADDRESSLENGH),
1615c18ec02fSPetter Reinholdtsen 					MACADDRESSLENGH);
1616c18ec02fSPetter Reinholdtsen 			for (i = 0; i < MACADDRESSLENGH; i++) {
1617c18ec02fSPetter Reinholdtsen 				if (VirtualMacAddress[i] != 0) {
1618c18ec02fSPetter Reinholdtsen 					UseVirtualMacAddress = 1;
1619c18ec02fSPetter Reinholdtsen 				}
1620c18ec02fSPetter Reinholdtsen 			}
1621c18ec02fSPetter Reinholdtsen 		}
1622c18ec02fSPetter Reinholdtsen 	} else {
1623c18ec02fSPetter Reinholdtsen 		memcpy(VirtualMacAddress, ((rsp->data) + VIRTUAL_MAC_OFFSET),
1624c18ec02fSPetter Reinholdtsen 				MACADDRESSLENGH);
1625c18ec02fSPetter Reinholdtsen 		for (i = 0; i < MACADDRESSLENGH; i++) {
1626c18ec02fSPetter Reinholdtsen 			if (VirtualMacAddress[i] != 0) {
1627c18ec02fSPetter Reinholdtsen 				UseVirtualMacAddress = 1;
1628c18ec02fSPetter Reinholdtsen 			}
1629c18ec02fSPetter Reinholdtsen 		}
1630c18ec02fSPetter Reinholdtsen 	}
1631c18ec02fSPetter Reinholdtsen 	if (UseVirtualMacAddress == 0) {
1632c18ec02fSPetter Reinholdtsen 		return -1;
1633c18ec02fSPetter Reinholdtsen 	}
1634c18ec02fSPetter Reinholdtsen 	if (IMC_IDRAC_10G == IMC_Type) {
1635c18ec02fSPetter Reinholdtsen 		printf("\nDRAC MAC Address ");
1636c18ec02fSPetter Reinholdtsen 	} else if ((IMC_IDRAC_11G_MODULAR == IMC_Type)
1637c18ec02fSPetter Reinholdtsen 			|| (IMC_IDRAC_11G_MONOLITHIC== IMC_Type)) {
1638c18ec02fSPetter Reinholdtsen 		printf("\niDRAC6 MAC Address ");
1639c18ec02fSPetter Reinholdtsen 	} else if ((IMC_IDRAC_12G_MODULAR == IMC_Type)
1640c18ec02fSPetter Reinholdtsen 			|| (IMC_IDRAC_12G_MONOLITHIC== IMC_Type)) {
1641c18ec02fSPetter Reinholdtsen 		printf("\niDRAC7 MAC Address ");
1642859e8a45SZdenek Styblik 	} else if ((IMC_IDRAC_13G_MODULAR == IMC_Type)
1643859e8a45SZdenek Styblik 			|| (IMC_IDRAC_13G_MONOLITHIC== IMC_Type)) {
1644859e8a45SZdenek Styblik 			printf ("\niDRAC8 MAC Address ");
1645c18ec02fSPetter Reinholdtsen 	} else if ((IMC_MASER_LITE_BMC== IMC_Type)
1646c18ec02fSPetter Reinholdtsen 			|| (IMC_MASER_LITE_NU== IMC_Type)) {
1647c18ec02fSPetter Reinholdtsen 		printf("\nBMC MAC Address ");
1648c18ec02fSPetter Reinholdtsen 	} else {
1649c18ec02fSPetter Reinholdtsen 		printf("\niDRAC6 MAC Address ");
1650c18ec02fSPetter Reinholdtsen 	}
1651c18ec02fSPetter Reinholdtsen 
1652c18ec02fSPetter Reinholdtsen 	for (j = 0; j < 5; j++) {
1653c18ec02fSPetter Reinholdtsen 		printf("%02x:", VirtualMacAddress[j]);
1654c18ec02fSPetter Reinholdtsen 	}
1655c18ec02fSPetter Reinholdtsen 	printf("%02x", VirtualMacAddress[j]);
1656c18ec02fSPetter Reinholdtsen 	printf("\n");
1657c18ec02fSPetter Reinholdtsen 	return 0;
1658c18ec02fSPetter Reinholdtsen }
1659c18ec02fSPetter Reinholdtsen /*
1660c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_macinfo_drac_idrac_mac
1661c18ec02fSPetter Reinholdtsen  *
1662c18ec02fSPetter Reinholdtsen  * Description:      This function retrieves the mac address of DRAC or iDRAC
1663c18ec02fSPetter Reinholdtsen  * Input:            NicNum
1664c18ec02fSPetter Reinholdtsen  * Output:
1665c18ec02fSPetter Reinholdtsen  * Return:
1666c18ec02fSPetter Reinholdtsen  */
1667c18ec02fSPetter Reinholdtsen static int
ipmi_macinfo_drac_idrac_mac(struct ipmi_intf * intf,uint8_t NicNum)1668c18ec02fSPetter Reinholdtsen ipmi_macinfo_drac_idrac_mac(struct ipmi_intf* intf,uint8_t NicNum)
1669c18ec02fSPetter Reinholdtsen {
1670c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
1671c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
1672c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
1673c18ec02fSPetter Reinholdtsen 	uint8_t input_length=0;
1674c18ec02fSPetter Reinholdtsen 	uint8_t iDRAC6MacAddressByte[MACADDRESSLENGH];
1675c18ec02fSPetter Reinholdtsen 	uint8_t j;
1676c18ec02fSPetter Reinholdtsen 	ipmi_macinfo_drac_idrac_virtual_mac(intf,NicNum);
1677c18ec02fSPetter Reinholdtsen 	if ((NicNum != 0xff && NicNum != IDRAC_NIC_NUMBER)
1678c18ec02fSPetter Reinholdtsen 			|| UseVirtualMacAddress != 0) {
1679c18ec02fSPetter Reinholdtsen 		return 0;
1680c18ec02fSPetter Reinholdtsen 	}
1681c18ec02fSPetter Reinholdtsen 	input_length = 0;
1682c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = LAN_CHANNEL_NUMBER;
1683c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = MAC_ADDR_PARAM;
1684c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00;
1685c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00;
1686c18ec02fSPetter Reinholdtsen 
1687c18ec02fSPetter Reinholdtsen 	req.msg.netfn = TRANSPORT_NETFN;
1688c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
1689c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_LAN_PARAM_CMD;
1690c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
1691c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
1692c18ec02fSPetter Reinholdtsen 
1693c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
1694c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
1695c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting MAC Address");
1696c18ec02fSPetter Reinholdtsen 		return -1;
1697c18ec02fSPetter Reinholdtsen 	}
1698c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
1699c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting MAC Address (%s)",
1700c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
1701c18ec02fSPetter Reinholdtsen 		return -1;
1702c18ec02fSPetter Reinholdtsen 	}
1703c18ec02fSPetter Reinholdtsen 	memcpy(iDRAC6MacAddressByte, ((rsp->data) + PARAM_REV_OFFSET),
1704c18ec02fSPetter Reinholdtsen 			MACADDRESSLENGH);
1705c18ec02fSPetter Reinholdtsen 
1706c18ec02fSPetter Reinholdtsen 	if (IMC_IDRAC_10G == IMC_Type) {
1707c18ec02fSPetter Reinholdtsen 		printf("\nDRAC MAC Address ");
1708c18ec02fSPetter Reinholdtsen 	} else if ((IMC_IDRAC_11G_MODULAR == IMC_Type)
1709c18ec02fSPetter Reinholdtsen 			|| (IMC_IDRAC_11G_MONOLITHIC== IMC_Type)) {
1710c18ec02fSPetter Reinholdtsen 		printf("\niDRAC6 MAC Address ");
1711c18ec02fSPetter Reinholdtsen 	} else if ((IMC_IDRAC_12G_MODULAR == IMC_Type)
1712c18ec02fSPetter Reinholdtsen 			|| (IMC_IDRAC_12G_MONOLITHIC== IMC_Type)) {
1713c18ec02fSPetter Reinholdtsen 		printf("\niDRAC7 MAC Address ");
1714859e8a45SZdenek Styblik 	} else if ((IMC_IDRAC_13G_MODULAR == IMC_Type)
1715859e8a45SZdenek Styblik 			|| (IMC_IDRAC_13G_MONOLITHIC== IMC_Type)) {
1716859e8a45SZdenek Styblik 			printf ("\niDRAC8 MAC Address ");
1717c18ec02fSPetter Reinholdtsen 	} else if ((IMC_MASER_LITE_BMC== IMC_Type)
1718c18ec02fSPetter Reinholdtsen 			|| (IMC_MASER_LITE_NU== IMC_Type)) {
1719c18ec02fSPetter Reinholdtsen 		printf("\n\rBMC MAC Address ");
1720c18ec02fSPetter Reinholdtsen 	} else {
1721c18ec02fSPetter Reinholdtsen 		printf("\niDRAC6 MAC Address ");
1722c18ec02fSPetter Reinholdtsen 	}
1723c18ec02fSPetter Reinholdtsen 
1724c18ec02fSPetter Reinholdtsen 	for (j = 0; j < 5; j++) {
1725c18ec02fSPetter Reinholdtsen 		printf("%02x:", iDRAC6MacAddressByte[j]);
1726c18ec02fSPetter Reinholdtsen 	}
1727c18ec02fSPetter Reinholdtsen 	printf("%02x", iDRAC6MacAddressByte[j]);
1728c18ec02fSPetter Reinholdtsen 	printf("\n");
1729c18ec02fSPetter Reinholdtsen 	return 0;
1730c18ec02fSPetter Reinholdtsen }
1731c18ec02fSPetter Reinholdtsen /*
1732c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_macinfo_10g
1733c18ec02fSPetter Reinholdtsen  *
1734c18ec02fSPetter Reinholdtsen  * Description:      This function retrieves the mac address of LOMs
1735c18ec02fSPetter Reinholdtsen  * Input:            intf      - ipmi interface
1736c18ec02fSPetter Reinholdtsen  *                   NicNum    - NIC number
1737c18ec02fSPetter Reinholdtsen  * Output:
1738c18ec02fSPetter Reinholdtsen  * Return:
1739c18ec02fSPetter Reinholdtsen  */
1740c18ec02fSPetter Reinholdtsen static int
ipmi_macinfo_10g(struct ipmi_intf * intf,uint8_t NicNum)1741c18ec02fSPetter Reinholdtsen ipmi_macinfo_10g(struct ipmi_intf* intf, uint8_t NicNum)
1742c18ec02fSPetter Reinholdtsen {
1743c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
1744c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
1745c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
1746c18ec02fSPetter Reinholdtsen 	uint8_t input_length=0;
1747c18ec02fSPetter Reinholdtsen 	uint8_t j;
1748c18ec02fSPetter Reinholdtsen 	uint8_t i;
1749c18ec02fSPetter Reinholdtsen 	uint8_t Total_No_NICs = 0;
1750c18ec02fSPetter Reinholdtsen 	InitEmbeddedNICMacAddressValues();
1751c18ec02fSPetter Reinholdtsen 	memset(msg_data, 0, sizeof(msg_data));
1752c18ec02fSPetter Reinholdtsen 	input_length = 0;
1753c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00; /* Get Parameter Command */
1754c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_9G_10G; /* OEM Param */
1755c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00;
1756c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00;
1757c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
1758c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
1759c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
1760c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_GET_SYS_INFO;
1761c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
1762c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
1763c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
1764c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
1765c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting MAC Address");
1766c18ec02fSPetter Reinholdtsen 		return -1;
1767c18ec02fSPetter Reinholdtsen 	}
1768c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
1769c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting MAC Address (%s)",
1770c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
1771c18ec02fSPetter Reinholdtsen 		return -1;
1772c18ec02fSPetter Reinholdtsen 	}
1773c18ec02fSPetter Reinholdtsen 	Total_No_NICs = (uint8_t)rsp->data[0 + PARAM_REV_OFFSET]; /* Byte 1: Total Number of Embedded NICs */
1774c18ec02fSPetter Reinholdtsen 	if (IDRAC_NIC_NUMBER != NicNum) {
1775c18ec02fSPetter Reinholdtsen 		if (0xff == NicNum) {
1776c18ec02fSPetter Reinholdtsen 			printf("\nSystem LOMs");
1777c18ec02fSPetter Reinholdtsen 		}
1778c18ec02fSPetter Reinholdtsen 		printf("\nNIC Number\tMAC Address\n");
1779c18ec02fSPetter Reinholdtsen 		memcpy(&EmbeddedNICMacAddress_10G,
1780c18ec02fSPetter Reinholdtsen 				((rsp->data) + PARAM_REV_OFFSET+TOTAL_N0_NICS_INDEX),
1781c18ec02fSPetter Reinholdtsen 				Total_No_NICs* MACADDRESSLENGH);
1782c18ec02fSPetter Reinholdtsen 		/*Read the LOM type and Mac Addresses */
1783c18ec02fSPetter Reinholdtsen 		for (i = 0; i < Total_No_NICs; i++) {
1784c18ec02fSPetter Reinholdtsen 			if ((0xff == NicNum) || (i == NicNum)) {
1785c18ec02fSPetter Reinholdtsen 				printf("\n%d",i);
1786c18ec02fSPetter Reinholdtsen 				printf("\t\t");
1787c18ec02fSPetter Reinholdtsen 				for (j = 0 ; j < 5; j++) {
1788c18ec02fSPetter Reinholdtsen 					printf("%02x:",
1789c18ec02fSPetter Reinholdtsen 							EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j]);
1790c18ec02fSPetter Reinholdtsen 				}
1791c18ec02fSPetter Reinholdtsen 				printf("%02x",
1792c18ec02fSPetter Reinholdtsen 						EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j]);
1793c18ec02fSPetter Reinholdtsen 			}
1794c18ec02fSPetter Reinholdtsen 		}
1795c18ec02fSPetter Reinholdtsen 		printf("\n");
1796c18ec02fSPetter Reinholdtsen 	}
1797c18ec02fSPetter Reinholdtsen 	ipmi_macinfo_drac_idrac_mac(intf,NicNum);
1798c18ec02fSPetter Reinholdtsen 	return 0;
1799c18ec02fSPetter Reinholdtsen }
1800c18ec02fSPetter Reinholdtsen /*
1801c18ec02fSPetter Reinholdtsen  * Function Name:      ipmi_macinfo_11g
1802c18ec02fSPetter Reinholdtsen  *
1803c18ec02fSPetter Reinholdtsen  * Description:        This function retrieves the mac address of LOMs
1804c18ec02fSPetter Reinholdtsen  * Input:              intf - ipmi interface
1805c18ec02fSPetter Reinholdtsen  * Output:
1806c18ec02fSPetter Reinholdtsen  * Return:
1807c18ec02fSPetter Reinholdtsen  */
1808c18ec02fSPetter Reinholdtsen static int
ipmi_macinfo_11g(struct ipmi_intf * intf,uint8_t NicNum)1809c18ec02fSPetter Reinholdtsen ipmi_macinfo_11g(struct ipmi_intf* intf, uint8_t NicNum)
1810c18ec02fSPetter Reinholdtsen {
1811c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
1812c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
1813c18ec02fSPetter Reinholdtsen 	uint8_t input_length = 0;
1814c18ec02fSPetter Reinholdtsen 	uint8_t i;
1815c18ec02fSPetter Reinholdtsen 	uint8_t j;
1816c18ec02fSPetter Reinholdtsen 	uint8_t len;
1817c18ec02fSPetter Reinholdtsen 	uint8_t loop_count;
1818c18ec02fSPetter Reinholdtsen 	uint8_t maxlen;
1819c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
1820c18ec02fSPetter Reinholdtsen 	uint8_t offset;
1821c18ec02fSPetter Reinholdtsen 	offset = 0;
1822c18ec02fSPetter Reinholdtsen 	len = 8; /*eigher 8 or 16 */
1823c18ec02fSPetter Reinholdtsen 	maxlen = 64;
1824c18ec02fSPetter Reinholdtsen 	loop_count = maxlen / len;
1825c18ec02fSPetter Reinholdtsen 	InitEmbeddedNICMacAddressValues();
1826c18ec02fSPetter Reinholdtsen 	memset(msg_data, 0, sizeof(msg_data));
1827c18ec02fSPetter Reinholdtsen 	input_length = 0;
1828c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00; /* Get Parameter Command */
1829c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_11G; /* OEM Param */
1830c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00;
1831c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00;
1832c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00;
1833c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0x00;
1834c18ec02fSPetter Reinholdtsen 
1835c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
1836c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_APP;
1837c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
1838c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_GET_SYS_INFO;
1839c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
1840c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
1841c18ec02fSPetter Reinholdtsen 
1842c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
1843c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
1844c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting MAC Address");
1845c18ec02fSPetter Reinholdtsen 		return -1;
1846c18ec02fSPetter Reinholdtsen 	}
1847c18ec02fSPetter Reinholdtsen 	if (rsp->ccode > 0) {
1848c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting MAC Address (%s)",
1849c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
1850c18ec02fSPetter Reinholdtsen 		return -1;
1851c18ec02fSPetter Reinholdtsen 	}
1852c18ec02fSPetter Reinholdtsen 	len = 8; /*eigher 8 or 16 */
1853c18ec02fSPetter Reinholdtsen 	maxlen = (uint8_t)rsp->data[0 + PARAM_REV_OFFSET];
1854c18ec02fSPetter Reinholdtsen 	loop_count = maxlen / len;
1855c18ec02fSPetter Reinholdtsen 	if (IDRAC_NIC_NUMBER != NicNum) {
1856c18ec02fSPetter Reinholdtsen 		if (0xff == NicNum) {
1857c18ec02fSPetter Reinholdtsen 			printf("\nSystem LOMs");
1858c18ec02fSPetter Reinholdtsen 		}
1859c18ec02fSPetter Reinholdtsen 		printf("\nNIC Number\tMAC Address\t\tStatus\n");
1860c18ec02fSPetter Reinholdtsen 		/*Read the LOM type and Mac Addresses */
1861c18ec02fSPetter Reinholdtsen 		offset=0;
1862c18ec02fSPetter Reinholdtsen 		for (i = 0; i < loop_count; i++, offset = offset + len) {
1863c18ec02fSPetter Reinholdtsen 			input_length = 4;
1864c18ec02fSPetter Reinholdtsen 			msg_data[input_length++] = offset;
1865c18ec02fSPetter Reinholdtsen 			msg_data[input_length++] = len;
1866c18ec02fSPetter Reinholdtsen 
1867c18ec02fSPetter Reinholdtsen 			req.msg.netfn = IPMI_NETFN_APP;
1868c18ec02fSPetter Reinholdtsen 			req.msg.lun = 0;
1869c18ec02fSPetter Reinholdtsen 			req.msg.cmd = IPMI_GET_SYS_INFO;
1870c18ec02fSPetter Reinholdtsen 			req.msg.data = msg_data;
1871c18ec02fSPetter Reinholdtsen 			req.msg.data_len = input_length;
1872c18ec02fSPetter Reinholdtsen 
1873c18ec02fSPetter Reinholdtsen 			rsp = intf->sendrecv(intf, &req);
1874c18ec02fSPetter Reinholdtsen 			if (rsp == NULL) {
1875c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Error in getting MAC Address");
1876c18ec02fSPetter Reinholdtsen 				return -1;
1877c18ec02fSPetter Reinholdtsen 			}
1878c18ec02fSPetter Reinholdtsen 			if (rsp->ccode > 0) {
1879c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Error in getting MAC Address (%s)",
1880c18ec02fSPetter Reinholdtsen 						val2str(rsp->ccode, completion_code_vals));
1881c18ec02fSPetter Reinholdtsen 				return -1;
1882c18ec02fSPetter Reinholdtsen 			}
1883c18ec02fSPetter Reinholdtsen 			memcpy(&(EmbeddedNICMacAddress.LOMMacAddress[i]),
1884c18ec02fSPetter Reinholdtsen 					((rsp->data)+PARAM_REV_OFFSET), len);
1885c18ec02fSPetter Reinholdtsen 			if (LOM_MACTYPE_ETHERNET == EmbeddedNICMacAddress.LOMMacAddress[i].MacType) {
1886c18ec02fSPetter Reinholdtsen 				if ((0xff==NicNum)
1887c18ec02fSPetter Reinholdtsen 						|| (NicNum == EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber)) {
1888c18ec02fSPetter Reinholdtsen 					printf("\n%d",EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber);
1889c18ec02fSPetter Reinholdtsen 					printf("\t\t");
1890c18ec02fSPetter Reinholdtsen 					for (j = 0; j < 5; j++) {
1891c18ec02fSPetter Reinholdtsen 						printf("%02x:",
1892c18ec02fSPetter Reinholdtsen 								EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j]);
1893c18ec02fSPetter Reinholdtsen 					}
1894c18ec02fSPetter Reinholdtsen 					printf("%02x",
1895c18ec02fSPetter Reinholdtsen 							EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j]);
1896c18ec02fSPetter Reinholdtsen 
1897c18ec02fSPetter Reinholdtsen 					if (LOM_ETHERNET_ENABLED
1898c18ec02fSPetter Reinholdtsen 							== EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus) {
1899c18ec02fSPetter Reinholdtsen 						printf("\tEnabled");
1900c18ec02fSPetter Reinholdtsen 					} else {
1901c18ec02fSPetter Reinholdtsen 						printf("\tDisabled");
1902c18ec02fSPetter Reinholdtsen 					}
1903c18ec02fSPetter Reinholdtsen 				}
1904c18ec02fSPetter Reinholdtsen 			}
1905c18ec02fSPetter Reinholdtsen 		}
1906c18ec02fSPetter Reinholdtsen 		printf("\n");
1907c18ec02fSPetter Reinholdtsen 	}
1908c18ec02fSPetter Reinholdtsen 	ipmi_macinfo_drac_idrac_mac(intf,NicNum);
1909c18ec02fSPetter Reinholdtsen 	return 0;
1910c18ec02fSPetter Reinholdtsen }
1911c18ec02fSPetter Reinholdtsen /*
1912c18ec02fSPetter Reinholdtsen  * Function Name:      ipmi_macinfo
1913c18ec02fSPetter Reinholdtsen  *
1914c18ec02fSPetter Reinholdtsen  * Description:     This function retrieves the mac address of LOMs
1915c18ec02fSPetter Reinholdtsen  * Input:           intf   - ipmi interface
1916c18ec02fSPetter Reinholdtsen  * Output:
1917c18ec02fSPetter Reinholdtsen  * Return:
1918c18ec02fSPetter Reinholdtsen  */
1919c18ec02fSPetter Reinholdtsen static int
ipmi_macinfo(struct ipmi_intf * intf,uint8_t NicNum)1920c18ec02fSPetter Reinholdtsen ipmi_macinfo(struct ipmi_intf* intf, uint8_t NicNum)
1921c18ec02fSPetter Reinholdtsen {
1922c18ec02fSPetter Reinholdtsen 	if (IMC_IDRAC_10G == IMC_Type) {
1923c18ec02fSPetter Reinholdtsen 		return ipmi_macinfo_10g(intf,NicNum);
1924c18ec02fSPetter Reinholdtsen 	} else if ((IMC_IDRAC_11G_MODULAR == IMC_Type
1925c18ec02fSPetter Reinholdtsen 				|| IMC_IDRAC_11G_MONOLITHIC == IMC_Type)
1926c18ec02fSPetter Reinholdtsen 			|| (IMC_IDRAC_12G_MODULAR == IMC_Type
1927c18ec02fSPetter Reinholdtsen 				|| IMC_IDRAC_12G_MONOLITHIC == IMC_Type)
1928859e8a45SZdenek Styblik 			|| (IMC_IDRAC_13G_MODULAR == IMC_Type
1929859e8a45SZdenek Styblik 				|| IMC_IDRAC_13G_MONOLITHIC == IMC_Type)
1930c18ec02fSPetter Reinholdtsen 			|| (IMC_MASER_LITE_NU == IMC_Type || IMC_MASER_LITE_BMC== IMC_Type)) {
1931c18ec02fSPetter Reinholdtsen 		return ipmi_macinfo_11g(intf,NicNum);
1932c18ec02fSPetter Reinholdtsen 	} else {
1933c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting MAC Address : Not supported platform");
1934c18ec02fSPetter Reinholdtsen 		return (-1);
1935c18ec02fSPetter Reinholdtsen 	}
1936c18ec02fSPetter Reinholdtsen }
1937c18ec02fSPetter Reinholdtsen /*
1938c18ec02fSPetter Reinholdtsen  * Function Name:     ipmi_mac_usage
1939c18ec02fSPetter Reinholdtsen  *
1940c18ec02fSPetter Reinholdtsen  * Description:   This function prints help message for mac command
1941c18ec02fSPetter Reinholdtsen  * Input:
1942c18ec02fSPetter Reinholdtsen  * Output:
1943c18ec02fSPetter Reinholdtsen  *
1944c18ec02fSPetter Reinholdtsen  * Return:
1945c18ec02fSPetter Reinholdtsen  */
1946c18ec02fSPetter Reinholdtsen static void
ipmi_mac_usage(void)1947c18ec02fSPetter Reinholdtsen ipmi_mac_usage(void)
1948c18ec02fSPetter Reinholdtsen {
1949c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1950c18ec02fSPetter Reinholdtsen "");
1951c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1952c18ec02fSPetter Reinholdtsen "   mac list");
1953c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1954c18ec02fSPetter Reinholdtsen "      Lists the MAC address of LOMs");
1955c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1956c18ec02fSPetter Reinholdtsen "");
1957c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1958c18ec02fSPetter Reinholdtsen "   mac get <NIC number>");
1959c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1960c18ec02fSPetter Reinholdtsen "      Shows the MAC address of specified LOM. 0-7 System LOM, 8- DRAC/iDRAC.");
1961c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
1962c18ec02fSPetter Reinholdtsen "");
1963c18ec02fSPetter Reinholdtsen }
1964c18ec02fSPetter Reinholdtsen /*
1965c18ec02fSPetter Reinholdtsen  * Function Name:       ipmi_delloem_lan_main
1966c18ec02fSPetter Reinholdtsen  *
1967c18ec02fSPetter Reinholdtsen  * Description:         This function processes the delloem lan command
1968c18ec02fSPetter Reinholdtsen  * Input:               intf    - ipmi interface
1969c18ec02fSPetter Reinholdtsen  *                      argc    - no of arguments
1970c18ec02fSPetter Reinholdtsen  *                      argv    - argument string array
1971c18ec02fSPetter Reinholdtsen  * Output:
1972c18ec02fSPetter Reinholdtsen  *
1973c18ec02fSPetter Reinholdtsen  * Return:              return code     0 - success
1974c18ec02fSPetter Reinholdtsen  *                         -1 - failure
1975c18ec02fSPetter Reinholdtsen  */
1976c18ec02fSPetter Reinholdtsen static int
ipmi_delloem_lan_main(struct ipmi_intf * intf,int argc,char ** argv)1977c18ec02fSPetter Reinholdtsen ipmi_delloem_lan_main(struct ipmi_intf * intf, int argc, char ** argv)
1978c18ec02fSPetter Reinholdtsen {
1979c18ec02fSPetter Reinholdtsen 	int rc = 0;
1980c18ec02fSPetter Reinholdtsen 	int nic_selection = 0;
1981c18ec02fSPetter Reinholdtsen 	char nic_set[2] = {0};
1982c18ec02fSPetter Reinholdtsen 	current_arg++;
1983c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] == NULL || strcmp(argv[current_arg], "help") == 0) {
1984c18ec02fSPetter Reinholdtsen 		ipmi_lan_usage();
1985c18ec02fSPetter Reinholdtsen 		return 0;
1986c18ec02fSPetter Reinholdtsen 	}
1987c18ec02fSPetter Reinholdtsen 	ipmi_idracvalidator_command(intf);
1988c18ec02fSPetter Reinholdtsen 	if (!IsLANSupported()) {
1989c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "lan is not supported on this system.");
1990c18ec02fSPetter Reinholdtsen 		return -1;
1991c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "set\0", 4) == 0) {
1992c18ec02fSPetter Reinholdtsen 		current_arg++;
1993c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
1994c18ec02fSPetter Reinholdtsen 			ipmi_lan_usage();
1995c18ec02fSPetter Reinholdtsen 			return -1;
1996c18ec02fSPetter Reinholdtsen 		}
1997859e8a45SZdenek Styblik 		if (iDRAC_FLAG_12_13)  {
1998c18ec02fSPetter Reinholdtsen 			nic_selection = get_nic_selection_mode_12g(intf, current_arg, argv,
1999c18ec02fSPetter Reinholdtsen 					nic_set);
2000c18ec02fSPetter Reinholdtsen 			if (INVALID == nic_selection) {
2001c18ec02fSPetter Reinholdtsen 				ipmi_lan_usage();
2002c18ec02fSPetter Reinholdtsen 				return -1;
2003c18ec02fSPetter Reinholdtsen 			} else if (INVAILD_FAILOVER_MODE == nic_selection) {
2004c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVAILD_FAILOVER_MODE_STRING);
2005c18ec02fSPetter Reinholdtsen 				return (-1);
2006c18ec02fSPetter Reinholdtsen 			} else if (INVAILD_FAILOVER_MODE_SETTINGS == nic_selection) {
2007c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVAILD_FAILOVER_MODE_SET);
2008c18ec02fSPetter Reinholdtsen 				return (-1);
2009c18ec02fSPetter Reinholdtsen 			} else if (INVAILD_SHARED_MODE == nic_selection) {
2010c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVAILD_SHARED_MODE_SET_STRING);
2011c18ec02fSPetter Reinholdtsen 				return (-1);
2012c18ec02fSPetter Reinholdtsen 			}
2013c18ec02fSPetter Reinholdtsen 			rc = ipmi_lan_set_nic_selection_12g(intf,nic_set);
2014c18ec02fSPetter Reinholdtsen 		} else {
2015c18ec02fSPetter Reinholdtsen 			nic_selection = get_nic_selection_mode(current_arg, argv);
2016c18ec02fSPetter Reinholdtsen 			if (INVALID == nic_selection) {
2017c18ec02fSPetter Reinholdtsen 				ipmi_lan_usage();
2018c18ec02fSPetter Reinholdtsen 				return -1;
2019c18ec02fSPetter Reinholdtsen 			}
2020c18ec02fSPetter Reinholdtsen 			if (IMC_IDRAC_11G_MODULAR == IMC_Type) {
2021c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, INVAILD_SHARED_MODE_SET_STRING);
2022c18ec02fSPetter Reinholdtsen 				return (-1);
2023c18ec02fSPetter Reinholdtsen 			}
2024c18ec02fSPetter Reinholdtsen 			rc = ipmi_lan_set_nic_selection(intf,nic_selection);
2025c18ec02fSPetter Reinholdtsen 		}
2026c18ec02fSPetter Reinholdtsen 		return 0;
2027c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "get\0", 4) == 0) {
2028c18ec02fSPetter Reinholdtsen 		current_arg++;
2029c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
2030c18ec02fSPetter Reinholdtsen 			rc = ipmi_lan_get_nic_selection(intf);
2031c18ec02fSPetter Reinholdtsen 			return rc;
2032c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "active\0", 7) == 0) {
2033c18ec02fSPetter Reinholdtsen 			rc = ipmi_lan_get_active_nic(intf);
2034c18ec02fSPetter Reinholdtsen 			return rc;
2035c18ec02fSPetter Reinholdtsen 		} else {
2036c18ec02fSPetter Reinholdtsen 			ipmi_lan_usage();
2037c18ec02fSPetter Reinholdtsen 		}
2038c18ec02fSPetter Reinholdtsen 	} else {
2039c18ec02fSPetter Reinholdtsen 		ipmi_lan_usage();
2040c18ec02fSPetter Reinholdtsen 		return -1;
2041c18ec02fSPetter Reinholdtsen 	}
2042c18ec02fSPetter Reinholdtsen 	return rc;
2043c18ec02fSPetter Reinholdtsen }
2044c18ec02fSPetter Reinholdtsen 
2045c18ec02fSPetter Reinholdtsen static int
IsLANSupported()2046c18ec02fSPetter Reinholdtsen IsLANSupported()
2047c18ec02fSPetter Reinholdtsen {
2048c18ec02fSPetter Reinholdtsen 	if (IMC_IDRAC_11G_MODULAR == IMC_Type) {
2049c18ec02fSPetter Reinholdtsen 		return 0;
2050c18ec02fSPetter Reinholdtsen 	}
2051c18ec02fSPetter Reinholdtsen 	return 1;
2052c18ec02fSPetter Reinholdtsen }
2053c18ec02fSPetter Reinholdtsen 
2054c18ec02fSPetter Reinholdtsen int
get_nic_selection_mode_12g(struct ipmi_intf * intf,int current_arg,char ** argv,char * nic_set)2055c18ec02fSPetter Reinholdtsen get_nic_selection_mode_12g(struct ipmi_intf* intf,int current_arg,
2056c18ec02fSPetter Reinholdtsen 		char ** argv, char *nic_set)
2057c18ec02fSPetter Reinholdtsen {
2058c18ec02fSPetter Reinholdtsen 	/* First get the current settings. */
2059c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
2060c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2061c18ec02fSPetter Reinholdtsen 	int failover = 0;
2062c18ec02fSPetter Reinholdtsen 	uint8_t input_length = 0;
2063c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
2064c18ec02fSPetter Reinholdtsen 
2065c18ec02fSPetter Reinholdtsen 	input_length = 0;
2066c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2067c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2068c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_NIC_SELECTION_12G_CMD;
2069c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
2070c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
2071c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2072c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2073c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting nic selection");
2074c18ec02fSPetter Reinholdtsen 		return -1;
2075c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2076c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting nic selection (%s)",
2077c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2078c18ec02fSPetter Reinholdtsen 		return -1;
2079c18ec02fSPetter Reinholdtsen 	}
2080c18ec02fSPetter Reinholdtsen 	nic_set[0] = rsp->data[0];
2081c18ec02fSPetter Reinholdtsen 	nic_set[1] = rsp->data[1];
2082c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2083c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "dedicated\0", 10) == 0) {
2084c18ec02fSPetter Reinholdtsen 		nic_set[0] = 1;
2085c18ec02fSPetter Reinholdtsen 		nic_set[1] = 0;
2086c18ec02fSPetter Reinholdtsen 		return 0;
2087c18ec02fSPetter Reinholdtsen 	}
2088c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2089c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "shared\0", 7) == 0) {
2090c18ec02fSPetter Reinholdtsen 		/* placeholder */
2091c18ec02fSPetter Reinholdtsen 	} else {
2092c18ec02fSPetter Reinholdtsen 		return INVALID;
2093c18ec02fSPetter Reinholdtsen 	}
2094c18ec02fSPetter Reinholdtsen 
2095c18ec02fSPetter Reinholdtsen 	current_arg++;
2096c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2097c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "with\0", 5) == 0) {
2098c18ec02fSPetter Reinholdtsen 		/* placeholder */
2099c18ec02fSPetter Reinholdtsen 	} else {
2100c18ec02fSPetter Reinholdtsen 		return INVALID;
2101c18ec02fSPetter Reinholdtsen 	}
2102c18ec02fSPetter Reinholdtsen 
2103c18ec02fSPetter Reinholdtsen 	current_arg++;
2104c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2105c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "failover\0", 9) == 0) {
2106c18ec02fSPetter Reinholdtsen 		failover = 1;
2107c18ec02fSPetter Reinholdtsen 	}
2108c18ec02fSPetter Reinholdtsen 	if (failover) {
2109c18ec02fSPetter Reinholdtsen 		current_arg++;
2110c18ec02fSPetter Reinholdtsen 	}
2111c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2112c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "lom1\0", 5) == 0) {
2113859e8a45SZdenek Styblik 		if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
2114c18ec02fSPetter Reinholdtsen 			return INVAILD_SHARED_MODE;
2115c18ec02fSPetter Reinholdtsen 		}
2116c18ec02fSPetter Reinholdtsen 		if (failover) {
2117c18ec02fSPetter Reinholdtsen 			if (nic_set[0] == 2) {
2118c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE;
2119c18ec02fSPetter Reinholdtsen 			} else if (nic_set[0] == 1) {
2120c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE_SETTINGS;
2121c18ec02fSPetter Reinholdtsen 			}
2122c18ec02fSPetter Reinholdtsen 			nic_set[1] = 2;
2123c18ec02fSPetter Reinholdtsen 		} else {
2124c18ec02fSPetter Reinholdtsen 			nic_set[0] = 2;
2125c18ec02fSPetter Reinholdtsen 			if (nic_set[1] == 2) {
2126c18ec02fSPetter Reinholdtsen 				nic_set[1] = 0;
2127c18ec02fSPetter Reinholdtsen 			}
2128c18ec02fSPetter Reinholdtsen 		}
2129c18ec02fSPetter Reinholdtsen 		return 0;
2130c18ec02fSPetter Reinholdtsen 	} else if (argv[current_arg] != NULL
2131c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "lom2\0", 5) == 0) {
2132859e8a45SZdenek Styblik 		if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
2133c18ec02fSPetter Reinholdtsen 			return INVAILD_SHARED_MODE;
2134c18ec02fSPetter Reinholdtsen 		}
2135c18ec02fSPetter Reinholdtsen 		if (failover) {
2136c18ec02fSPetter Reinholdtsen 			if (nic_set[0] == 3) {
2137c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE;
2138c18ec02fSPetter Reinholdtsen 			} else if(nic_set[0] == 1) {
2139c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE_SETTINGS;
2140c18ec02fSPetter Reinholdtsen 			}
2141c18ec02fSPetter Reinholdtsen 			nic_set[1] = 3;
2142c18ec02fSPetter Reinholdtsen 		} else {
2143c18ec02fSPetter Reinholdtsen 			nic_set[0] = 3;
2144c18ec02fSPetter Reinholdtsen 			if (nic_set[1] == 3) {
2145c18ec02fSPetter Reinholdtsen 				nic_set[1] = 0;
2146c18ec02fSPetter Reinholdtsen 			}
2147c18ec02fSPetter Reinholdtsen 		}
2148c18ec02fSPetter Reinholdtsen 		return 0;
2149c18ec02fSPetter Reinholdtsen 	} else if (argv[current_arg] != NULL
2150c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "lom3\0", 5) == 0) {
2151859e8a45SZdenek Styblik 		if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
2152c18ec02fSPetter Reinholdtsen 			return INVAILD_SHARED_MODE;
2153c18ec02fSPetter Reinholdtsen 		}
2154c18ec02fSPetter Reinholdtsen 		if (failover) {
2155c18ec02fSPetter Reinholdtsen 			if (nic_set[0] == 4) {
2156c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE;
2157c18ec02fSPetter Reinholdtsen 			} else if(nic_set[0] == 1) {
2158c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE_SETTINGS;
2159c18ec02fSPetter Reinholdtsen 			}
2160c18ec02fSPetter Reinholdtsen 			nic_set[1] = 4;
2161c18ec02fSPetter Reinholdtsen 		} else {
2162c18ec02fSPetter Reinholdtsen 			nic_set[0] = 4;
2163c18ec02fSPetter Reinholdtsen 			if (nic_set[1] == 4) {
2164c18ec02fSPetter Reinholdtsen 				nic_set[1] = 0;
2165c18ec02fSPetter Reinholdtsen 			}
2166c18ec02fSPetter Reinholdtsen 		}
2167c18ec02fSPetter Reinholdtsen 		return 0;
2168c18ec02fSPetter Reinholdtsen 	} else if (argv[current_arg] != NULL
2169c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "lom4\0", 5) == 0) {
2170859e8a45SZdenek Styblik 		if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
2171c18ec02fSPetter Reinholdtsen 			return INVAILD_SHARED_MODE;
2172c18ec02fSPetter Reinholdtsen 		}
2173c18ec02fSPetter Reinholdtsen 		if (failover) {
2174c18ec02fSPetter Reinholdtsen 			if (nic_set[0] == 5) {
2175c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE;
2176c18ec02fSPetter Reinholdtsen 			} else if(nic_set[0] == 1) {
2177c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE_SETTINGS;
2178c18ec02fSPetter Reinholdtsen 			}
2179c18ec02fSPetter Reinholdtsen 			nic_set[1] = 5;
2180c18ec02fSPetter Reinholdtsen 		} else {
2181c18ec02fSPetter Reinholdtsen 			nic_set[0] = 5;
2182c18ec02fSPetter Reinholdtsen 			if (nic_set[1] == 5) {
2183c18ec02fSPetter Reinholdtsen 				nic_set[1] = 0;
2184c18ec02fSPetter Reinholdtsen 			}
2185c18ec02fSPetter Reinholdtsen 		}
2186c18ec02fSPetter Reinholdtsen 		return 0;
2187c18ec02fSPetter Reinholdtsen 	} else if (failover && argv[current_arg] != NULL
2188c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "none\0", 5) == 0) {
2189859e8a45SZdenek Styblik 		if ((IMC_IDRAC_12G_MODULAR == IMC_Type) ||  (IMC_IDRAC_13G_MODULAR == IMC_Type) ) {
2190c18ec02fSPetter Reinholdtsen 			return INVAILD_SHARED_MODE;
2191c18ec02fSPetter Reinholdtsen 		}
2192c18ec02fSPetter Reinholdtsen 		if (failover) {
2193c18ec02fSPetter Reinholdtsen 			if (nic_set[0] == 1) {
2194c18ec02fSPetter Reinholdtsen 				return INVAILD_FAILOVER_MODE_SETTINGS;
2195c18ec02fSPetter Reinholdtsen 			}
2196c18ec02fSPetter Reinholdtsen 			nic_set[1] = 0;
2197c18ec02fSPetter Reinholdtsen 		}
2198c18ec02fSPetter Reinholdtsen 		return 0;
2199c18ec02fSPetter Reinholdtsen 	} else if (failover && argv[current_arg] != NULL
2200c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "all\0", 4) == 0) {
2201c18ec02fSPetter Reinholdtsen 		/* placeholder */
2202c18ec02fSPetter Reinholdtsen 	} else {
2203c18ec02fSPetter Reinholdtsen 		return INVALID;
2204c18ec02fSPetter Reinholdtsen 	}
2205c18ec02fSPetter Reinholdtsen 
2206c18ec02fSPetter Reinholdtsen 	current_arg++;
2207c18ec02fSPetter Reinholdtsen 	if (failover && argv[current_arg] != NULL
2208c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "loms\0", 5) == 0) {
2209859e8a45SZdenek Styblik 		if ((IMC_IDRAC_12G_MODULAR == IMC_Type) ||  (IMC_IDRAC_13G_MODULAR == IMC_Type)) {
2210c18ec02fSPetter Reinholdtsen 			return INVAILD_SHARED_MODE;
2211c18ec02fSPetter Reinholdtsen 		}
2212c18ec02fSPetter Reinholdtsen 		if (nic_set[0] == 1) {
2213c18ec02fSPetter Reinholdtsen 			return INVAILD_FAILOVER_MODE_SETTINGS;
2214c18ec02fSPetter Reinholdtsen 		}
2215c18ec02fSPetter Reinholdtsen 		nic_set[1] = 6;
2216c18ec02fSPetter Reinholdtsen 		return 0;
2217c18ec02fSPetter Reinholdtsen 	}
2218c18ec02fSPetter Reinholdtsen 	return INVALID;
2219c18ec02fSPetter Reinholdtsen }
2220c18ec02fSPetter Reinholdtsen 
2221c18ec02fSPetter Reinholdtsen static int
get_nic_selection_mode(int current_arg,char ** argv)2222c18ec02fSPetter Reinholdtsen get_nic_selection_mode(int current_arg, char ** argv)
2223c18ec02fSPetter Reinholdtsen {
2224c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2225c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "dedicated\0", 10) == 0) {
2226c18ec02fSPetter Reinholdtsen 		return DEDICATED;
2227c18ec02fSPetter Reinholdtsen 	}
2228c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2229c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "shared\0", 7) == 0) {
2230c18ec02fSPetter Reinholdtsen 		if (argv[current_arg+1] == NULL) {
2231c18ec02fSPetter Reinholdtsen 			return SHARED;
2232c18ec02fSPetter Reinholdtsen 		}
2233c18ec02fSPetter Reinholdtsen 	}
2234c18ec02fSPetter Reinholdtsen 
2235c18ec02fSPetter Reinholdtsen 	current_arg++;
2236c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2237c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "with\0", 5) == 0) {
2238c18ec02fSPetter Reinholdtsen 		/* place holder */
2239c18ec02fSPetter Reinholdtsen 	} else {
2240c18ec02fSPetter Reinholdtsen 		return INVALID;
2241c18ec02fSPetter Reinholdtsen 	}
2242c18ec02fSPetter Reinholdtsen 
2243c18ec02fSPetter Reinholdtsen 	current_arg++;
2244c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2245c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "failover\0", 9) == 0) {
2246c18ec02fSPetter Reinholdtsen 		/* place holder */
2247c18ec02fSPetter Reinholdtsen 	} else {
2248c18ec02fSPetter Reinholdtsen 		return INVALID;
2249c18ec02fSPetter Reinholdtsen 	}
2250c18ec02fSPetter Reinholdtsen 
2251c18ec02fSPetter Reinholdtsen 	current_arg++;
2252c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2253c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "lom2\0", 5) == 0) {
2254c18ec02fSPetter Reinholdtsen 		return SHARED_WITH_FAILOVER_LOM2;
2255c18ec02fSPetter Reinholdtsen 	} else if (argv[current_arg] != NULL
2256c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "all\0", 4) == 0) {
2257c18ec02fSPetter Reinholdtsen 		/* place holder */
2258c18ec02fSPetter Reinholdtsen 	} else {
2259c18ec02fSPetter Reinholdtsen 		return INVALID;
2260c18ec02fSPetter Reinholdtsen 	}
2261c18ec02fSPetter Reinholdtsen 
2262c18ec02fSPetter Reinholdtsen 	current_arg++;
2263c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] != NULL
2264c18ec02fSPetter Reinholdtsen 			&& strncmp(argv[current_arg], "loms\0", 5) == 0) {
2265c18ec02fSPetter Reinholdtsen 		return SHARED_WITH_FAILOVER_ALL_LOMS;
2266c18ec02fSPetter Reinholdtsen 	}
2267c18ec02fSPetter Reinholdtsen 	return INVALID;
2268c18ec02fSPetter Reinholdtsen }
2269c18ec02fSPetter Reinholdtsen 
2270c18ec02fSPetter Reinholdtsen static int
ipmi_lan_set_nic_selection_12g(struct ipmi_intf * intf,uint8_t * nic_selection)2271c18ec02fSPetter Reinholdtsen ipmi_lan_set_nic_selection_12g(struct ipmi_intf * intf, uint8_t * nic_selection)
2272c18ec02fSPetter Reinholdtsen {
2273c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
2274c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2275c18ec02fSPetter Reinholdtsen 	uint8_t input_length = 0;
2276c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
2277c18ec02fSPetter Reinholdtsen 
2278c18ec02fSPetter Reinholdtsen 	input_length = 0;
2279c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = nic_selection[0];
2280c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = nic_selection[1];
2281c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2282c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2283c18ec02fSPetter Reinholdtsen 	req.msg.cmd = SET_NIC_SELECTION_12G_CMD;
2284c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
2285c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
2286c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2287c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2288c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in setting nic selection");
2289c18ec02fSPetter Reinholdtsen 		return -1;
2290c18ec02fSPetter Reinholdtsen 	} else if( (nic_selection[0] == 1)
2291859e8a45SZdenek Styblik 			&& (( iDRAC_FLAG_12_13 )
2292859e8a45SZdenek Styblik 			&& (rsp->ccode == LICENSE_NOT_SUPPORTED))) {
2293c18ec02fSPetter Reinholdtsen 		/* Check license only for setting the dedicated nic. */
2294c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
2295c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
2296c18ec02fSPetter Reinholdtsen 		return -1;
2297c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2298c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in setting nic selection (%s)",
2299c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2300c18ec02fSPetter Reinholdtsen 		return -1;
2301c18ec02fSPetter Reinholdtsen 	}
2302c18ec02fSPetter Reinholdtsen 	printf("configured successfully");
2303c18ec02fSPetter Reinholdtsen 	return 0;
2304c18ec02fSPetter Reinholdtsen }
2305c18ec02fSPetter Reinholdtsen 
2306c18ec02fSPetter Reinholdtsen static int
ipmi_lan_set_nic_selection(struct ipmi_intf * intf,uint8_t nic_selection)2307c18ec02fSPetter Reinholdtsen ipmi_lan_set_nic_selection(struct ipmi_intf * intf, uint8_t nic_selection)
2308c18ec02fSPetter Reinholdtsen {
2309c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
2310c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2311c18ec02fSPetter Reinholdtsen 	uint8_t input_length = 0;
2312c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
2313c18ec02fSPetter Reinholdtsen 
2314c18ec02fSPetter Reinholdtsen 	input_length = 0;
2315c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = nic_selection;
2316c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2317c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2318c18ec02fSPetter Reinholdtsen 	req.msg.cmd = SET_NIC_SELECTION_CMD;
2319c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
2320c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
2321c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2322c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2323c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in setting nic selection");
2324c18ec02fSPetter Reinholdtsen 		return -1;
2325c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2326c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in setting nic selection (%s)",
2327c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2328c18ec02fSPetter Reinholdtsen 		return -1;
2329c18ec02fSPetter Reinholdtsen 	}
2330c18ec02fSPetter Reinholdtsen 	printf("configured successfully");
2331c18ec02fSPetter Reinholdtsen 	return 0;
2332c18ec02fSPetter Reinholdtsen }
2333c18ec02fSPetter Reinholdtsen 
2334c18ec02fSPetter Reinholdtsen static int
ipmi_lan_get_nic_selection(struct ipmi_intf * intf)2335c18ec02fSPetter Reinholdtsen ipmi_lan_get_nic_selection(struct ipmi_intf * intf)
2336c18ec02fSPetter Reinholdtsen {
2337c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
2338c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2339c18ec02fSPetter Reinholdtsen 	uint8_t input_length=0;
2340c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
2341c18ec02fSPetter Reinholdtsen 	uint8_t nic_selection=-1;
2342c18ec02fSPetter Reinholdtsen 	uint8_t nic_selection_failover = 0;
2343c18ec02fSPetter Reinholdtsen 
2344c18ec02fSPetter Reinholdtsen 	input_length = 0;
2345c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2346c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2347859e8a45SZdenek Styblik 	if( iDRAC_FLAG_12_13 ) {
2348c18ec02fSPetter Reinholdtsen 		req.msg.cmd = GET_NIC_SELECTION_12G_CMD;
2349c18ec02fSPetter Reinholdtsen 	} else {
2350c18ec02fSPetter Reinholdtsen 		req.msg.cmd = GET_NIC_SELECTION_CMD;
2351c18ec02fSPetter Reinholdtsen 	}
2352c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
2353c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
2354c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2355c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2356c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting nic selection");
2357c18ec02fSPetter Reinholdtsen 		return -1;
2358c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2359c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting nic selection (%s)",
2360c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2361c18ec02fSPetter Reinholdtsen 		return -1;
2362c18ec02fSPetter Reinholdtsen 	}
2363c18ec02fSPetter Reinholdtsen 	nic_selection = rsp->data[0];
2364859e8a45SZdenek Styblik 	if( iDRAC_FLAG_12_13 ) {
2365c18ec02fSPetter Reinholdtsen 		nic_selection_failover = rsp->data[1];
2366c18ec02fSPetter Reinholdtsen 		if ((nic_selection < 6) && (nic_selection > 0)
2367c18ec02fSPetter Reinholdtsen 				&& (nic_selection_failover < 7)) {
2368c18ec02fSPetter Reinholdtsen 			if(nic_selection == 1) {
2369c18ec02fSPetter Reinholdtsen 				printf("%s\n",NIC_Selection_Mode_String_12g[nic_selection-1]);
2370c18ec02fSPetter Reinholdtsen 			} else if(nic_selection) {
2371c18ec02fSPetter Reinholdtsen 				printf("Shared LOM   :  %s\n",
2372c18ec02fSPetter Reinholdtsen 						NIC_Selection_Mode_String_12g[nic_selection-1]);
2373c18ec02fSPetter Reinholdtsen 				if(nic_selection_failover  == 0) {
2374c18ec02fSPetter Reinholdtsen 					printf("Failover LOM :  None\n");
2375c18ec02fSPetter Reinholdtsen 				} else if(nic_selection_failover >= 2 && nic_selection_failover <= 6) {
2376c18ec02fSPetter Reinholdtsen 					printf("Failover LOM :  %s\n",
2377c18ec02fSPetter Reinholdtsen 							NIC_Selection_Mode_String_12g[nic_selection_failover + 3]);
2378c18ec02fSPetter Reinholdtsen 				}
2379c18ec02fSPetter Reinholdtsen 			}
2380c18ec02fSPetter Reinholdtsen 		} else {
2381c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Error Outof bond Value received (%d) (%d)",
2382c18ec02fSPetter Reinholdtsen 					nic_selection,nic_selection_failover);
2383c18ec02fSPetter Reinholdtsen 			return -1;
2384c18ec02fSPetter Reinholdtsen 		}
2385c18ec02fSPetter Reinholdtsen 	} else {
2386c18ec02fSPetter Reinholdtsen 		printf("%s\n",NIC_Selection_Mode_String[nic_selection]);
2387c18ec02fSPetter Reinholdtsen 	}
2388c18ec02fSPetter Reinholdtsen 	return 0;
2389c18ec02fSPetter Reinholdtsen }
2390c18ec02fSPetter Reinholdtsen 
2391c18ec02fSPetter Reinholdtsen static int
ipmi_lan_get_active_nic(struct ipmi_intf * intf)2392c18ec02fSPetter Reinholdtsen ipmi_lan_get_active_nic(struct ipmi_intf * intf)
2393c18ec02fSPetter Reinholdtsen {
2394c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
2395c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2396c18ec02fSPetter Reinholdtsen 	uint8_t active_nic=0;
2397c18ec02fSPetter Reinholdtsen 	uint8_t current_lom =0;
2398c18ec02fSPetter Reinholdtsen 	uint8_t input_length=0;
2399c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[30];
2400c18ec02fSPetter Reinholdtsen 
2401c18ec02fSPetter Reinholdtsen 	input_length = 0;
2402c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0; /* Get Status */
2403c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0; /* Reserved */
2404c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0; /* Reserved */
2405c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2406c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2407c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_ACTIVE_NIC_CMD;
2408c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
2409c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
2410c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2411c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2412c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting Active LOM Status");
2413c18ec02fSPetter Reinholdtsen 		return -1;
2414c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2415c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting Active LOM Status (%s)",
2416c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2417c18ec02fSPetter Reinholdtsen 		return -1;
2418c18ec02fSPetter Reinholdtsen 	}
2419c18ec02fSPetter Reinholdtsen 	current_lom = rsp->data[0];
2420c18ec02fSPetter Reinholdtsen 	input_length = 0;
2421c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 1; /* Get Link status */
2422c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0; /* Reserved */
2423c18ec02fSPetter Reinholdtsen 	msg_data[input_length++] = 0; /* Reserved */
2424c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2425c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2426c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_ACTIVE_NIC_CMD;
2427c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
2428c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
2429c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2430c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2431c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting Active LOM Status");
2432c18ec02fSPetter Reinholdtsen 		return -1;
2433c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2434c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting Active LOM Status (%s)",
2435c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2436c18ec02fSPetter Reinholdtsen 		return -1;
2437c18ec02fSPetter Reinholdtsen 	}
2438c18ec02fSPetter Reinholdtsen 	active_nic = rsp->data[1];
2439c18ec02fSPetter Reinholdtsen 	if (current_lom < 6 && active_nic) {
2440c18ec02fSPetter Reinholdtsen 		printf("\n%s\n", AciveLOM_String[current_lom]);
2441c18ec02fSPetter Reinholdtsen 	} else {
2442c18ec02fSPetter Reinholdtsen 		printf("\n%s\n", AciveLOM_String[0]);
2443c18ec02fSPetter Reinholdtsen 	}
2444c18ec02fSPetter Reinholdtsen 	return 0;
2445c18ec02fSPetter Reinholdtsen }
2446c18ec02fSPetter Reinholdtsen 
2447c18ec02fSPetter Reinholdtsen static void
ipmi_lan_usage(void)2448c18ec02fSPetter Reinholdtsen ipmi_lan_usage(void)
2449c18ec02fSPetter Reinholdtsen {
2450c18ec02fSPetter Reinholdtsen 	/* TODO:
2451c18ec02fSPetter Reinholdtsen 	 *  - rewrite
2452c18ec02fSPetter Reinholdtsen 	 *  - review
2453c18ec02fSPetter Reinholdtsen 	 *  - make it fit into 80 chars per line
2454c18ec02fSPetter Reinholdtsen 	 *  - this ``shared with Failover None).'' seems like a typo
2455c18ec02fSPetter Reinholdtsen 	 */
2456c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2457c18ec02fSPetter Reinholdtsen "");
2458c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2459c18ec02fSPetter Reinholdtsen "   lan set <Mode>");
2460c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2461c18ec02fSPetter Reinholdtsen "      sets the NIC Selection Mode :");
2462c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2463859e8a45SZdenek Styblik "          on iDRAC12g OR iDRAC13g  :");
2464c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2465c18ec02fSPetter Reinholdtsen "              dedicated, shared with lom1, shared with lom2,shared with lom3,shared");
2466c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2467c18ec02fSPetter Reinholdtsen "              with lom4,shared with failover lom1,shared with failover lom2,shared");
2468c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2469c18ec02fSPetter Reinholdtsen "              with failover lom3,shared with failover lom4,shared with Failover all");
2470c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2471c18ec02fSPetter Reinholdtsen "              loms, shared with Failover None).");
2472c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2473c18ec02fSPetter Reinholdtsen "          on other systems :");
2474c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2475c18ec02fSPetter Reinholdtsen "              dedicated, shared, shared with failover lom2,");
2476c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2477c18ec02fSPetter Reinholdtsen "              shared with Failover all loms.");
2478c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2479c18ec02fSPetter Reinholdtsen "");
2480c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2481c18ec02fSPetter Reinholdtsen "   lan get ");
2482c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2483859e8a45SZdenek Styblik "          on iDRAC12g or iDRAC13g  :");
2484c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2485c18ec02fSPetter Reinholdtsen "              returns the current NIC Selection Mode (dedicated, shared with lom1, shared");
2486c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2487c18ec02fSPetter Reinholdtsen "              with lom2, shared with lom3, shared with lom4,shared with failover lom1,");
2488c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2489c18ec02fSPetter Reinholdtsen "              shared with failover lom2,shared with failover lom3,shared with failover");
2490c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2491c18ec02fSPetter Reinholdtsen "              lom4,shared with Failover all loms,shared with Failover None).");
2492c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2493c18ec02fSPetter Reinholdtsen "          on other systems :");
2494c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2495c18ec02fSPetter Reinholdtsen "              dedicated, shared, shared with failover,");
2496c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2497c18ec02fSPetter Reinholdtsen "              lom2, shared with Failover all loms.");
2498c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2499c18ec02fSPetter Reinholdtsen "");
2500c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2501c18ec02fSPetter Reinholdtsen "   lan get active");
2502c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2503c18ec02fSPetter Reinholdtsen "      returns the current active NIC (dedicated, LOM1, LOM2, LOM3, LOM4).");
2504c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
2505c18ec02fSPetter Reinholdtsen "");
2506c18ec02fSPetter Reinholdtsen }
2507c18ec02fSPetter Reinholdtsen /*
2508c18ec02fSPetter Reinholdtsen  * Function Name:       ipmi_delloem_powermonitor_main
2509c18ec02fSPetter Reinholdtsen  *
2510c18ec02fSPetter Reinholdtsen  * Description:         This function processes the delloem powermonitor command
2511c18ec02fSPetter Reinholdtsen  * Input:               intf    - ipmi interface
2512c18ec02fSPetter Reinholdtsen  *                       argc    - no of arguments
2513c18ec02fSPetter Reinholdtsen  *                      argv    - argument string array
2514c18ec02fSPetter Reinholdtsen  * Output:
2515c18ec02fSPetter Reinholdtsen  *
2516c18ec02fSPetter Reinholdtsen  * Return:              return code     0 - success
2517c18ec02fSPetter Reinholdtsen  *                         -1 - failure
2518c18ec02fSPetter Reinholdtsen  */
2519c18ec02fSPetter Reinholdtsen static int
ipmi_delloem_powermonitor_main(struct ipmi_intf * intf,int argc,char ** argv)2520c18ec02fSPetter Reinholdtsen ipmi_delloem_powermonitor_main(struct ipmi_intf * intf, int argc, char ** argv)
2521c18ec02fSPetter Reinholdtsen {
2522c18ec02fSPetter Reinholdtsen 	int rc = 0;
2523c18ec02fSPetter Reinholdtsen 	current_arg++;
2524c18ec02fSPetter Reinholdtsen 	if (argc > 1 && strcmp(argv[current_arg], "help") == 0) {
2525c18ec02fSPetter Reinholdtsen 		ipmi_powermonitor_usage();
2526c18ec02fSPetter Reinholdtsen 		return 0;
2527c18ec02fSPetter Reinholdtsen 	}
2528c18ec02fSPetter Reinholdtsen 	ipmi_idracvalidator_command(intf);
2529c18ec02fSPetter Reinholdtsen 	if (argc == 1) {
2530c18ec02fSPetter Reinholdtsen 		rc = ipmi_powermgmt(intf);
2531c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "status\0", 7) == 0) {
2532c18ec02fSPetter Reinholdtsen 		rc = ipmi_powermgmt(intf);
2533c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "clear\0", 6) == 0) {
2534c18ec02fSPetter Reinholdtsen 		current_arg++;
2535c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
2536c18ec02fSPetter Reinholdtsen 			ipmi_powermonitor_usage();
2537c18ec02fSPetter Reinholdtsen 			return -1;
2538c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "peakpower\0", 10) == 0) {
2539c18ec02fSPetter Reinholdtsen 			rc = ipmi_powermgmt_clear(intf, 1);
2540c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "cumulativepower\0", 16) == 0) {
2541c18ec02fSPetter Reinholdtsen 			rc = ipmi_powermgmt_clear(intf, 0);
2542c18ec02fSPetter Reinholdtsen 		} else {
2543c18ec02fSPetter Reinholdtsen 			ipmi_powermonitor_usage();
2544c18ec02fSPetter Reinholdtsen 			return -1;
2545c18ec02fSPetter Reinholdtsen 		}
2546c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "powerconsumption\0", 17) == 0) {
2547c18ec02fSPetter Reinholdtsen 		current_arg++;
2548c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
2549c18ec02fSPetter Reinholdtsen 			rc = ipmi_print_get_power_consmpt_data(intf,watt);
2550c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
2551c18ec02fSPetter Reinholdtsen 			rc = ipmi_print_get_power_consmpt_data(intf, watt);
2552c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) {
2553c18ec02fSPetter Reinholdtsen 			rc = ipmi_print_get_power_consmpt_data(intf, btuphr);
2554c18ec02fSPetter Reinholdtsen 		} else {
2555c18ec02fSPetter Reinholdtsen 			ipmi_powermonitor_usage();
2556c18ec02fSPetter Reinholdtsen 			return -1;
2557c18ec02fSPetter Reinholdtsen 		}
2558c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "powerconsumptionhistory\0", 23) == 0) {
2559c18ec02fSPetter Reinholdtsen 		current_arg++;
2560c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
2561c18ec02fSPetter Reinholdtsen 			rc = ipmi_print_power_consmpt_history(intf,watt);
2562c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
2563c18ec02fSPetter Reinholdtsen 			rc = ipmi_print_power_consmpt_history(intf, watt);
2564c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) {
2565c18ec02fSPetter Reinholdtsen 			rc = ipmi_print_power_consmpt_history(intf, btuphr);
2566c18ec02fSPetter Reinholdtsen 		} else {
2567c18ec02fSPetter Reinholdtsen 			ipmi_powermonitor_usage();
2568c18ec02fSPetter Reinholdtsen 			return -1;
2569c18ec02fSPetter Reinholdtsen 		}
2570c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "getpowerbudget\0", 15) == 0) {
2571c18ec02fSPetter Reinholdtsen 		current_arg++;
2572c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
2573c18ec02fSPetter Reinholdtsen 			rc=ipmi_print_power_cap(intf,watt);
2574c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
2575c18ec02fSPetter Reinholdtsen 			rc = ipmi_print_power_cap(intf, watt);
2576c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) {
2577c18ec02fSPetter Reinholdtsen 			rc = ipmi_print_power_cap(intf, btuphr);
2578c18ec02fSPetter Reinholdtsen 		} else {
2579c18ec02fSPetter Reinholdtsen 			ipmi_powermonitor_usage();
2580c18ec02fSPetter Reinholdtsen 			return -1;
2581c18ec02fSPetter Reinholdtsen 		}
2582c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "setpowerbudget\0", 15) == 0) {
2583c18ec02fSPetter Reinholdtsen 		int val;
2584c18ec02fSPetter Reinholdtsen 		current_arg++;
2585c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
2586c18ec02fSPetter Reinholdtsen 			ipmi_powermonitor_usage();
2587c18ec02fSPetter Reinholdtsen 			return -1;
2588c18ec02fSPetter Reinholdtsen 		}
2589c18ec02fSPetter Reinholdtsen 		if (strchr(argv[current_arg], '.')) {
2590c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
2591c18ec02fSPetter Reinholdtsen 					"Cap value in Watts, Btu/hr or percent should be whole number");
2592c18ec02fSPetter Reinholdtsen 			return -1;
2593c18ec02fSPetter Reinholdtsen 		}
2594c18ec02fSPetter Reinholdtsen 		if (str2int(argv[current_arg], &val) != 0) {
2595c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given capacity value '%s' is invalid.",
2596c18ec02fSPetter Reinholdtsen 					argv[current_arg]);
2597c18ec02fSPetter Reinholdtsen 			return (-1);
2598c18ec02fSPetter Reinholdtsen 		}
2599c18ec02fSPetter Reinholdtsen 		current_arg++;
2600c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
2601c18ec02fSPetter Reinholdtsen 			ipmi_powermonitor_usage();
2602c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "watt\0", 5) == 0) {
2603c18ec02fSPetter Reinholdtsen 			rc = ipmi_set_power_cap(intf,watt,val);
2604c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) {
2605c18ec02fSPetter Reinholdtsen 			rc = ipmi_set_power_cap(intf, btuphr,val);
2606c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "percent\0", 8) == 0) {
2607c18ec02fSPetter Reinholdtsen 			rc = ipmi_set_power_cap(intf,percent,val);
2608c18ec02fSPetter Reinholdtsen 		} else {
2609c18ec02fSPetter Reinholdtsen 			ipmi_powermonitor_usage();
2610c18ec02fSPetter Reinholdtsen 			return -1;
2611c18ec02fSPetter Reinholdtsen 		}
2612c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "enablepowercap\0", 15) == 0) {
2613c18ec02fSPetter Reinholdtsen 		ipmi_set_power_capstatus_command(intf,1);
2614c18ec02fSPetter Reinholdtsen 	} else if (strncmp(argv[current_arg], "disablepowercap\0", 16) == 0) {
2615c18ec02fSPetter Reinholdtsen 		ipmi_set_power_capstatus_command(intf,0);
2616c18ec02fSPetter Reinholdtsen 	} else {
2617c18ec02fSPetter Reinholdtsen 		ipmi_powermonitor_usage();
2618c18ec02fSPetter Reinholdtsen 		return -1;
2619c18ec02fSPetter Reinholdtsen 	}
2620c18ec02fSPetter Reinholdtsen 	return rc;
2621c18ec02fSPetter Reinholdtsen }
2622c18ec02fSPetter Reinholdtsen /*
2623c18ec02fSPetter Reinholdtsen  * Function Name:     ipmi_time_to_str
2624c18ec02fSPetter Reinholdtsen  *
2625c18ec02fSPetter Reinholdtsen  * Description:       This function converts ipmi time format into gmtime format
2626c18ec02fSPetter Reinholdtsen  * Input:             rawTime  - ipmi time format
2627c18ec02fSPetter Reinholdtsen  * Output:            strTime  - gmtime format
2628c18ec02fSPetter Reinholdtsen  *
2629c18ec02fSPetter Reinholdtsen  * Return:
2630c18ec02fSPetter Reinholdtsen  */
2631c18ec02fSPetter Reinholdtsen static void
ipmi_time_to_str(time_t rawTime,char * strTime)2632c18ec02fSPetter Reinholdtsen ipmi_time_to_str(time_t rawTime, char * strTime)
2633c18ec02fSPetter Reinholdtsen {
2634c18ec02fSPetter Reinholdtsen 	struct tm *tm;
2635c18ec02fSPetter Reinholdtsen 	char *temp;
2636c18ec02fSPetter Reinholdtsen 	tm = gmtime(&rawTime);
2637c18ec02fSPetter Reinholdtsen 	temp = asctime(tm);
2638c18ec02fSPetter Reinholdtsen 	strcpy(strTime,temp);
2639c18ec02fSPetter Reinholdtsen }
2640c18ec02fSPetter Reinholdtsen /*
2641c18ec02fSPetter Reinholdtsen  * Function Name:      ipmi_get_sensor_reading
2642c18ec02fSPetter Reinholdtsen  *
2643c18ec02fSPetter Reinholdtsen  * Description:        This function retrieves a raw sensor reading
2644c18ec02fSPetter Reinholdtsen  * Input:              sensorOwner       - sensor owner id
2645c18ec02fSPetter Reinholdtsen  *                     sensorNumber      - sensor id
2646c18ec02fSPetter Reinholdtsen  *                     intf              - ipmi interface
2647c18ec02fSPetter Reinholdtsen  * Output:             sensorReadingData - ipmi response structure
2648c18ec02fSPetter Reinholdtsen  * Return:             1 on error
2649c18ec02fSPetter Reinholdtsen  *                     0 if successful
2650c18ec02fSPetter Reinholdtsen  */
2651c18ec02fSPetter Reinholdtsen static int
ipmi_get_sensor_reading(struct ipmi_intf * intf,unsigned char sensorNumber,SensorReadingType * pSensorReadingData)2652c18ec02fSPetter Reinholdtsen ipmi_get_sensor_reading(struct ipmi_intf *intf, unsigned char sensorNumber,
2653c18ec02fSPetter Reinholdtsen 		SensorReadingType* pSensorReadingData)
2654c18ec02fSPetter Reinholdtsen {
2655c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2656c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
2657c18ec02fSPetter Reinholdtsen 	int rc = 0;
2658c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
2659c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
2660c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2661c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_SENSOR_READING;
2662c18ec02fSPetter Reinholdtsen 	req.msg.data = &sensorNumber;
2663c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 1;
2664c18ec02fSPetter Reinholdtsen 	if (pSensorReadingData == NULL) {
2665c18ec02fSPetter Reinholdtsen 		return -1;
2666c18ec02fSPetter Reinholdtsen 	}
2667c18ec02fSPetter Reinholdtsen 	memset(pSensorReadingData, 0, sizeof(SensorReadingType));
2668c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2669c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2670c18ec02fSPetter Reinholdtsen 		return 1;
2671c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2672c18ec02fSPetter Reinholdtsen 		return 1;
2673c18ec02fSPetter Reinholdtsen 	}
2674c18ec02fSPetter Reinholdtsen 	memcpy(pSensorReadingData, rsp->data, sizeof(SensorReadingType));
2675c18ec02fSPetter Reinholdtsen 	/* if there is an error transmitting ipmi command, return error */
2676c18ec02fSPetter Reinholdtsen 	if (rsp->ccode != 0) {
2677c18ec02fSPetter Reinholdtsen 		rc = 1;
2678c18ec02fSPetter Reinholdtsen 	}
2679c18ec02fSPetter Reinholdtsen 	/* if sensor messages are disabled, return error*/
2680c18ec02fSPetter Reinholdtsen 	if ((!(rsp->data[1]& 0xC0)) || ((rsp->data[1] & 0x20))) {
2681c18ec02fSPetter Reinholdtsen 		rc =1;
2682c18ec02fSPetter Reinholdtsen 	}
2683c18ec02fSPetter Reinholdtsen 	return rc;
2684c18ec02fSPetter Reinholdtsen }
2685c18ec02fSPetter Reinholdtsen /*
2686c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_get_power_capstatus_command
2687c18ec02fSPetter Reinholdtsen  *
2688c18ec02fSPetter Reinholdtsen  * Description:     This function gets the power cap status
2689c18ec02fSPetter Reinholdtsen  * Input:           intf                 - ipmi interface
2690c18ec02fSPetter Reinholdtsen  * Global:          PowercapSetable_flag - power cap status
2691c18ec02fSPetter Reinholdtsen  * Output:
2692c18ec02fSPetter Reinholdtsen  *
2693c18ec02fSPetter Reinholdtsen  * Return:
2694c18ec02fSPetter Reinholdtsen  */
2695c18ec02fSPetter Reinholdtsen static int
ipmi_get_power_capstatus_command(struct ipmi_intf * intf)2696c18ec02fSPetter Reinholdtsen ipmi_get_power_capstatus_command(struct ipmi_intf * intf)
2697c18ec02fSPetter Reinholdtsen {
2698c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = NULL;
2699c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req = {0};
2700c18ec02fSPetter Reinholdtsen 	uint8_t data[2];
2701c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2702c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2703c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS;
2704c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 2;
2705c18ec02fSPetter Reinholdtsen 	req.msg.data = data;
2706c18ec02fSPetter Reinholdtsen 	data[0] = 01;
2707c18ec02fSPetter Reinholdtsen 	data[1] = 0xFF;
2708c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2709c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2710c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting powercap status");
2711c18ec02fSPetter Reinholdtsen 		return -1;
2712859e8a45SZdenek Styblik 	} else if (( iDRAC_FLAG_12_13 ) && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
2713c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
2714c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
2715c18ec02fSPetter Reinholdtsen 		return -1; /* Return Error as unlicensed */
2716c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2717c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting powercap statusr: %s",
2718c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2719c18ec02fSPetter Reinholdtsen 		return -1;
2720c18ec02fSPetter Reinholdtsen 	}
2721c18ec02fSPetter Reinholdtsen 	if (rsp->data[0] & 0x02) {
2722c18ec02fSPetter Reinholdtsen 		PowercapSetable_flag=1;
2723c18ec02fSPetter Reinholdtsen 	}
2724c18ec02fSPetter Reinholdtsen 	if (rsp->data[0] & 0x01) {
2725c18ec02fSPetter Reinholdtsen 		PowercapstatusFlag=1;
2726c18ec02fSPetter Reinholdtsen 	}
2727c18ec02fSPetter Reinholdtsen 	return 0;
2728c18ec02fSPetter Reinholdtsen }
2729c18ec02fSPetter Reinholdtsen /*
2730c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_set_power_capstatus_command
2731c18ec02fSPetter Reinholdtsen  *
2732c18ec02fSPetter Reinholdtsen  * Description:      This function sets the power cap status
2733c18ec02fSPetter Reinholdtsen  * Input:            intf     - ipmi interface
2734c18ec02fSPetter Reinholdtsen  *                   val      - power cap status
2735c18ec02fSPetter Reinholdtsen  * Output:
2736c18ec02fSPetter Reinholdtsen  *
2737c18ec02fSPetter Reinholdtsen  * Return:
2738c18ec02fSPetter Reinholdtsen  */
2739c18ec02fSPetter Reinholdtsen static int
ipmi_set_power_capstatus_command(struct ipmi_intf * intf,uint8_t val)2740c18ec02fSPetter Reinholdtsen ipmi_set_power_capstatus_command(struct ipmi_intf * intf, uint8_t val)
2741c18ec02fSPetter Reinholdtsen {
2742c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = NULL;
2743c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req = {0};
2744c18ec02fSPetter Reinholdtsen 	uint8_t data[2];
2745c18ec02fSPetter Reinholdtsen 	if (ipmi_get_power_capstatus_command(intf) < 0) {
2746c18ec02fSPetter Reinholdtsen 		return -1;
2747c18ec02fSPetter Reinholdtsen 	}
2748c18ec02fSPetter Reinholdtsen 	if (PowercapSetable_flag != 1) {
2749c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Can not set powercap on this system");
2750c18ec02fSPetter Reinholdtsen 		return -1;
2751c18ec02fSPetter Reinholdtsen 	}
2752c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2753c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2754c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS;
2755c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 2;
2756c18ec02fSPetter Reinholdtsen 	req.msg.data = data;
2757c18ec02fSPetter Reinholdtsen 	data[0] = 00;
2758c18ec02fSPetter Reinholdtsen 	data[1] = val;
2759c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2760c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2761c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting powercap status");
2762c18ec02fSPetter Reinholdtsen 		return -1;
2763859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13) && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
2764c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
2765c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
2766c18ec02fSPetter Reinholdtsen 		return -1; /* return unlicensed Error code */
2767c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
2768c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting powercap statusr: %s",
2769c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2770c18ec02fSPetter Reinholdtsen 		return -1;
2771c18ec02fSPetter Reinholdtsen 	}
2772c18ec02fSPetter Reinholdtsen 	return 0;
2773c18ec02fSPetter Reinholdtsen }
2774c18ec02fSPetter Reinholdtsen /*
2775c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_powermgmt
2776c18ec02fSPetter Reinholdtsen  *
2777c18ec02fSPetter Reinholdtsen  * Description:      This function print the powermonitor details
2778c18ec02fSPetter Reinholdtsen  * Input:            intf     - ipmi interface
2779c18ec02fSPetter Reinholdtsen  * Output:
2780c18ec02fSPetter Reinholdtsen  *
2781c18ec02fSPetter Reinholdtsen  * Return:
2782c18ec02fSPetter Reinholdtsen  */
2783c18ec02fSPetter Reinholdtsen static int
ipmi_powermgmt(struct ipmi_intf * intf)2784c18ec02fSPetter Reinholdtsen ipmi_powermgmt(struct ipmi_intf * intf)
2785c18ec02fSPetter Reinholdtsen {
2786c18ec02fSPetter Reinholdtsen 	time_t now;
2787c18ec02fSPetter Reinholdtsen 	struct tm* tm;
2788c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
2789c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2790c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[2];
2791c18ec02fSPetter Reinholdtsen 	uint32_t cumStartTimeConv;
2792c18ec02fSPetter Reinholdtsen 	uint32_t cumReadingConv;
2793c18ec02fSPetter Reinholdtsen 	uint32_t maxPeakStartTimeConv;
2794c18ec02fSPetter Reinholdtsen 	uint32_t ampPeakTimeConv;
2795c18ec02fSPetter Reinholdtsen 	uint16_t ampReadingConv;
2796c18ec02fSPetter Reinholdtsen 	uint32_t wattPeakTimeConv;
2797c18ec02fSPetter Reinholdtsen 	uint32_t wattReadingConv;
2798c18ec02fSPetter Reinholdtsen 	uint32_t bmctimeconv;
2799c18ec02fSPetter Reinholdtsen 	uint32_t * bmctimeconvval;
2800c18ec02fSPetter Reinholdtsen 
2801c18ec02fSPetter Reinholdtsen 	IPMI_POWER_MONITOR * pwrMonitorInfo;
2802c18ec02fSPetter Reinholdtsen 
2803c18ec02fSPetter Reinholdtsen 	char cumStartTime[26];
2804c18ec02fSPetter Reinholdtsen 	char maxPeakStartTime[26];
2805c18ec02fSPetter Reinholdtsen 	char ampPeakTime[26];
2806c18ec02fSPetter Reinholdtsen 	char wattPeakTime[26];
2807c18ec02fSPetter Reinholdtsen 	char bmctime[26];
2808c18ec02fSPetter Reinholdtsen 
2809c18ec02fSPetter Reinholdtsen 	int ampReading;
2810c18ec02fSPetter Reinholdtsen 	int ampReadingRemainder;
2811c18ec02fSPetter Reinholdtsen 	int remainder;
2812c18ec02fSPetter Reinholdtsen 	int wattReading;
2813c18ec02fSPetter Reinholdtsen 
2814c18ec02fSPetter Reinholdtsen 	now = time(0);
2815c18ec02fSPetter Reinholdtsen 	tm = gmtime(&now);
2816c18ec02fSPetter Reinholdtsen 
2817c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
2818c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_STORAGE;
2819c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2820c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_CMD_GET_SEL_TIME;
2821c18ec02fSPetter Reinholdtsen 
2822c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2823c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2824c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting BMC time info.");
2825c18ec02fSPetter Reinholdtsen 		return -1;
2826c18ec02fSPetter Reinholdtsen 	}
2827c18ec02fSPetter Reinholdtsen 	if (rsp->ccode != 0) {
2828c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
2829c18ec02fSPetter Reinholdtsen 				"Error getting power management information, return code %x",
2830c18ec02fSPetter Reinholdtsen 				rsp->ccode);
2831c18ec02fSPetter Reinholdtsen 		return -1;
2832c18ec02fSPetter Reinholdtsen 	}
2833c18ec02fSPetter Reinholdtsen 	bmctimeconvval=(uint32_t*)rsp->data;
2834c18ec02fSPetter Reinholdtsen # if WORDS_BIGENDIAN
2835c18ec02fSPetter Reinholdtsen 	bmctimeconv=BSWAP_32(*bmctimeconvval);
2836c18ec02fSPetter Reinholdtsen # else
2837c18ec02fSPetter Reinholdtsen 	bmctimeconv=*bmctimeconvval;
2838c18ec02fSPetter Reinholdtsen # endif
2839c18ec02fSPetter Reinholdtsen 
2840c18ec02fSPetter Reinholdtsen 	/* get powermanagement info*/
2841c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2842c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0x0;
2843c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_PWRMGMT_INFO_CMD;
2844c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
2845c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 2;
2846c18ec02fSPetter Reinholdtsen 
2847c18ec02fSPetter Reinholdtsen 	memset(msg_data, 0, 2);
2848c18ec02fSPetter Reinholdtsen 	msg_data[0] = 0x07;
2849c18ec02fSPetter Reinholdtsen 	msg_data[1] = 0x01;
2850c18ec02fSPetter Reinholdtsen 
2851c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2852c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2853c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power management information.");
2854c18ec02fSPetter Reinholdtsen 		return -1;
2855c18ec02fSPetter Reinholdtsen 	}
2856c18ec02fSPetter Reinholdtsen 
2857859e8a45SZdenek Styblik 	if ((iDRAC_FLAG_12_13) && (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
2858c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
2859c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
2860c18ec02fSPetter Reinholdtsen 		return -1;
2861c18ec02fSPetter Reinholdtsen 	} else if ((rsp->ccode == 0xc1)||(rsp->ccode == 0xcb)) {
2862c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power management information: "
2863c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
2864c18ec02fSPetter Reinholdtsen 		return -1;
2865c18ec02fSPetter Reinholdtsen 	}else if (rsp->ccode != 0) {
2866c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
2867c18ec02fSPetter Reinholdtsen 				"Error getting power management information, return code %x",
2868c18ec02fSPetter Reinholdtsen 				rsp->ccode);
2869c18ec02fSPetter Reinholdtsen 		return -1;
2870c18ec02fSPetter Reinholdtsen 	}
2871c18ec02fSPetter Reinholdtsen 
2872c18ec02fSPetter Reinholdtsen 	pwrMonitorInfo = (IPMI_POWER_MONITOR*)rsp->data;
2873c18ec02fSPetter Reinholdtsen # if WORDS_BIGENDIAN
2874c18ec02fSPetter Reinholdtsen 	cumStartTimeConv = BSWAP_32(pwrMonitorInfo->cumStartTime);
2875c18ec02fSPetter Reinholdtsen 	cumReadingConv = BSWAP_32(pwrMonitorInfo->cumReading);
2876c18ec02fSPetter Reinholdtsen 	maxPeakStartTimeConv = BSWAP_32(pwrMonitorInfo->maxPeakStartTime);
2877c18ec02fSPetter Reinholdtsen 	ampPeakTimeConv = BSWAP_32(pwrMonitorInfo->ampPeakTime);
2878c18ec02fSPetter Reinholdtsen 	ampReadingConv = BSWAP_16(pwrMonitorInfo->ampReading);
2879c18ec02fSPetter Reinholdtsen 	wattPeakTimeConv = BSWAP_32(pwrMonitorInfo->wattPeakTime);
2880c18ec02fSPetter Reinholdtsen 	wattReadingConv = BSWAP_16(pwrMonitorInfo->wattReading);
2881c18ec02fSPetter Reinholdtsen # else
2882c18ec02fSPetter Reinholdtsen 	cumStartTimeConv = pwrMonitorInfo->cumStartTime;
2883c18ec02fSPetter Reinholdtsen 	cumReadingConv = pwrMonitorInfo->cumReading;
2884c18ec02fSPetter Reinholdtsen 	maxPeakStartTimeConv = pwrMonitorInfo->maxPeakStartTime;
2885c18ec02fSPetter Reinholdtsen 	ampPeakTimeConv = pwrMonitorInfo->ampPeakTime;
2886c18ec02fSPetter Reinholdtsen 	ampReadingConv = pwrMonitorInfo->ampReading;
2887c18ec02fSPetter Reinholdtsen 	wattPeakTimeConv = pwrMonitorInfo->wattPeakTime;
2888c18ec02fSPetter Reinholdtsen 	wattReadingConv = pwrMonitorInfo->wattReading;
2889c18ec02fSPetter Reinholdtsen # endif
2890c18ec02fSPetter Reinholdtsen 
2891c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(cumStartTimeConv, cumStartTime);
2892c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(maxPeakStartTimeConv, maxPeakStartTime);
2893c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(ampPeakTimeConv, ampPeakTime);
2894c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(wattPeakTimeConv, wattPeakTime);
2895c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(bmctimeconv, bmctime);
2896c18ec02fSPetter Reinholdtsen 	now = time(0);
2897c18ec02fSPetter Reinholdtsen 
2898c18ec02fSPetter Reinholdtsen 	remainder = (cumReadingConv % 1000);
2899c18ec02fSPetter Reinholdtsen 	cumReadingConv = cumReadingConv / 1000;
2900c18ec02fSPetter Reinholdtsen 	remainder = (remainder + 50) / 100;
2901c18ec02fSPetter Reinholdtsen 
2902c18ec02fSPetter Reinholdtsen 	ampReading = ampReadingConv;
2903c18ec02fSPetter Reinholdtsen 	ampReadingRemainder = ampReading%10;
2904c18ec02fSPetter Reinholdtsen 	ampReading = ampReading/10;
2905c18ec02fSPetter Reinholdtsen 
2906c18ec02fSPetter Reinholdtsen 	wattReading = wattReadingConv;
2907c18ec02fSPetter Reinholdtsen 
2908c18ec02fSPetter Reinholdtsen 	printf("Power Tracking Statistics\n");
2909c18ec02fSPetter Reinholdtsen 	printf("Statistic      : Cumulative Energy Consumption\n");
2910c18ec02fSPetter Reinholdtsen 	printf("Start Time     : %s", cumStartTime);
2911c18ec02fSPetter Reinholdtsen 	printf("Finish Time    : %s", bmctime);
2912c18ec02fSPetter Reinholdtsen 	printf("Reading        : %d.%d kWh\n\n", cumReadingConv, remainder);
2913c18ec02fSPetter Reinholdtsen 
2914c18ec02fSPetter Reinholdtsen 	printf("Statistic      : System Peak Power\n");
2915c18ec02fSPetter Reinholdtsen 	printf("Start Time     : %s", maxPeakStartTime);
2916c18ec02fSPetter Reinholdtsen 	printf("Peak Time      : %s", wattPeakTime);
2917c18ec02fSPetter Reinholdtsen 	printf("Peak Reading   : %d W\n\n", wattReading);
2918c18ec02fSPetter Reinholdtsen 
2919c18ec02fSPetter Reinholdtsen 	printf("Statistic      : System Peak Amperage\n");
2920c18ec02fSPetter Reinholdtsen 	printf("Start Time     : %s", maxPeakStartTime);
2921c18ec02fSPetter Reinholdtsen 	printf("Peak Time      : %s", ampPeakTime);
2922c18ec02fSPetter Reinholdtsen 	printf("Peak Reading   : %d.%d A\n", ampReading, ampReadingRemainder);
2923c18ec02fSPetter Reinholdtsen 	return 0;
2924c18ec02fSPetter Reinholdtsen }
2925c18ec02fSPetter Reinholdtsen /*
2926c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_powermgmt_clear
2927c18ec02fSPetter Reinholdtsen  *
2928c18ec02fSPetter Reinholdtsen  * Description:     This function clears peakpower / cumulativepower value
2929c18ec02fSPetter Reinholdtsen  * Input:           intf           - ipmi interface
2930c18ec02fSPetter Reinholdtsen  *                  clearValue     - peakpower / cumulativepower
2931c18ec02fSPetter Reinholdtsen  * Output:
2932c18ec02fSPetter Reinholdtsen  *
2933c18ec02fSPetter Reinholdtsen  * Return:
2934c18ec02fSPetter Reinholdtsen  */
2935c18ec02fSPetter Reinholdtsen static int
ipmi_powermgmt_clear(struct ipmi_intf * intf,uint8_t clearValue)2936c18ec02fSPetter Reinholdtsen ipmi_powermgmt_clear(struct ipmi_intf * intf, uint8_t clearValue)
2937c18ec02fSPetter Reinholdtsen {
2938c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
2939c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
2940c18ec02fSPetter Reinholdtsen 	uint8_t clearType = 1;
2941c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[3];
2942c18ec02fSPetter Reinholdtsen 	if (clearValue) {
2943c18ec02fSPetter Reinholdtsen 		clearType = 2;
2944c18ec02fSPetter Reinholdtsen 	}
2945c18ec02fSPetter Reinholdtsen 	/* clear powermanagement info*/
2946c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
2947c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
2948c18ec02fSPetter Reinholdtsen 	req.msg.cmd = CLEAR_PWRMGMT_INFO_CMD;
2949c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
2950c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 3;
2951c18ec02fSPetter Reinholdtsen 	memset(msg_data, 0, 3);
2952c18ec02fSPetter Reinholdtsen 	msg_data[0] = 0x07;
2953c18ec02fSPetter Reinholdtsen 	msg_data[1] = 0x01;
2954c18ec02fSPetter Reinholdtsen 	msg_data[2] = clearType;
2955c18ec02fSPetter Reinholdtsen 
2956c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
2957c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
2958c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error clearing power values.");
2959c18ec02fSPetter Reinholdtsen 		return -1;
2960859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13)
2961c18ec02fSPetter Reinholdtsen 			&& (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
2962c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
2963c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
2964c18ec02fSPetter Reinholdtsen 		return -1;
2965c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode == 0xc1) {
2966c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
2967c18ec02fSPetter Reinholdtsen 				"Error clearing power values, command not supported on this system.");
2968c18ec02fSPetter Reinholdtsen 		return -1;
2969c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode != 0) {
2970c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error clearing power values: %s",
2971c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
2972c18ec02fSPetter Reinholdtsen 		return -1;
2973c18ec02fSPetter Reinholdtsen 	}
2974c18ec02fSPetter Reinholdtsen 	return 0;
2975c18ec02fSPetter Reinholdtsen }
2976c18ec02fSPetter Reinholdtsen /*
2977c18ec02fSPetter Reinholdtsen  * Function Name:    watt_to_btuphr_conversion
2978c18ec02fSPetter Reinholdtsen  *
2979c18ec02fSPetter Reinholdtsen  * Description:      This function converts the power value in watt to btuphr
2980c18ec02fSPetter Reinholdtsen  * Input:            powerinwatt     - power in watt
2981c18ec02fSPetter Reinholdtsen  *
2982c18ec02fSPetter Reinholdtsen  * Output:           power in btuphr
2983c18ec02fSPetter Reinholdtsen  *
2984c18ec02fSPetter Reinholdtsen  * Return:
2985c18ec02fSPetter Reinholdtsen  */
2986c18ec02fSPetter Reinholdtsen static uint64_t
watt_to_btuphr_conversion(uint32_t powerinwatt)2987c18ec02fSPetter Reinholdtsen watt_to_btuphr_conversion(uint32_t powerinwatt)
2988c18ec02fSPetter Reinholdtsen {
2989c18ec02fSPetter Reinholdtsen 	uint64_t powerinbtuphr;
2990c18ec02fSPetter Reinholdtsen 	powerinbtuphr=(3.413 * powerinwatt);
2991c18ec02fSPetter Reinholdtsen 	return(powerinbtuphr);
2992c18ec02fSPetter Reinholdtsen }
2993c18ec02fSPetter Reinholdtsen /*
2994c18ec02fSPetter Reinholdtsen  * Function Name:    btuphr_to_watt_conversion
2995c18ec02fSPetter Reinholdtsen  *
2996c18ec02fSPetter Reinholdtsen  * Description:      This function converts the power value in  btuphr to watt
2997c18ec02fSPetter Reinholdtsen  * Input:            powerinbtuphr   - power in btuphr
2998c18ec02fSPetter Reinholdtsen  *
2999c18ec02fSPetter Reinholdtsen  * Output:           power in watt
3000c18ec02fSPetter Reinholdtsen  *
3001c18ec02fSPetter Reinholdtsen  * Return:
3002c18ec02fSPetter Reinholdtsen  */
3003c18ec02fSPetter Reinholdtsen static uint32_t
btuphr_to_watt_conversion(uint64_t powerinbtuphr)3004c18ec02fSPetter Reinholdtsen btuphr_to_watt_conversion(uint64_t powerinbtuphr)
3005c18ec02fSPetter Reinholdtsen {
3006c18ec02fSPetter Reinholdtsen 	uint32_t powerinwatt;
3007c18ec02fSPetter Reinholdtsen 	/*returning the floor value*/
3008c18ec02fSPetter Reinholdtsen 	powerinwatt= (powerinbtuphr / 3.413);
3009c18ec02fSPetter Reinholdtsen 	return (powerinwatt);
3010c18ec02fSPetter Reinholdtsen }
3011c18ec02fSPetter Reinholdtsen /*
3012c18ec02fSPetter Reinholdtsen  * Function Name:        ipmi_get_power_headroom_command
3013c18ec02fSPetter Reinholdtsen  *
3014c18ec02fSPetter Reinholdtsen  * Description:          This function prints the Power consumption information
3015c18ec02fSPetter Reinholdtsen  * Input:                intf    - ipmi interface
3016c18ec02fSPetter Reinholdtsen  *                       unit    - watt / btuphr
3017c18ec02fSPetter Reinholdtsen  * Output:
3018c18ec02fSPetter Reinholdtsen  *
3019c18ec02fSPetter Reinholdtsen  * Return:
3020c18ec02fSPetter Reinholdtsen  */
3021c18ec02fSPetter Reinholdtsen static int
ipmi_get_power_headroom_command(struct ipmi_intf * intf,uint8_t unit)3022c18ec02fSPetter Reinholdtsen ipmi_get_power_headroom_command(struct ipmi_intf * intf,uint8_t unit)
3023c18ec02fSPetter Reinholdtsen {
3024c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = NULL;
3025c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req = {0};
3026c18ec02fSPetter Reinholdtsen 	uint64_t peakpowerheadroombtuphr;
3027c18ec02fSPetter Reinholdtsen 	uint64_t instantpowerhearoom;
3028c18ec02fSPetter Reinholdtsen 
3029c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
3030c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
3031c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_PWR_HEADROOM_CMD;
3032c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 0;
3033c18ec02fSPetter Reinholdtsen 
3034c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
3035c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
3036c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power headroom status");
3037c18ec02fSPetter Reinholdtsen 		return -1;
3038859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13)
3039c18ec02fSPetter Reinholdtsen 			&& (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
3040c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3041c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3042c18ec02fSPetter Reinholdtsen 		return -1;
3043c18ec02fSPetter Reinholdtsen 	} else if ((rsp->ccode == 0xc1) || (rsp->ccode == 0xcb)) {
3044c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power headroom status: "
3045c18ec02fSPetter Reinholdtsen 				"Command not supported on this system ");
3046c18ec02fSPetter Reinholdtsen 		return -1;
3047c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
3048c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power headroom status: %s",
3049c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
3050c18ec02fSPetter Reinholdtsen 		return -1;
3051c18ec02fSPetter Reinholdtsen 	}
3052c18ec02fSPetter Reinholdtsen 	if (verbose > 1) {
3053c18ec02fSPetter Reinholdtsen 		/* need to look into */
3054c18ec02fSPetter Reinholdtsen 		printf("power headroom  Data               : %x %x %x %x ", rsp->data[0],
3055c18ec02fSPetter Reinholdtsen 				rsp->data[1], rsp->data[2], rsp->data[3]);
3056c18ec02fSPetter Reinholdtsen 	}
3057c18ec02fSPetter Reinholdtsen 	powerheadroom= *(( POWER_HEADROOM *)rsp->data);
3058c18ec02fSPetter Reinholdtsen # if WORDS_BIGENDIAN
3059c18ec02fSPetter Reinholdtsen 	powerheadroom.instheadroom = BSWAP_16(powerheadroom.instheadroom);
3060c18ec02fSPetter Reinholdtsen 	powerheadroom.peakheadroom = BSWAP_16(powerheadroom.peakheadroom);
3061c18ec02fSPetter Reinholdtsen # endif
3062c18ec02fSPetter Reinholdtsen 	printf("Headroom\n");
3063c18ec02fSPetter Reinholdtsen 	printf("Statistic                     Reading\n");
3064c18ec02fSPetter Reinholdtsen 	if (unit == btuphr) {
3065c18ec02fSPetter Reinholdtsen 		peakpowerheadroombtuphr = watt_to_btuphr_conversion(powerheadroom.peakheadroom);
3066c18ec02fSPetter Reinholdtsen 		instantpowerhearoom = watt_to_btuphr_conversion(powerheadroom.instheadroom);
3067c18ec02fSPetter Reinholdtsen 		printf("System Instantaneous Headroom : %lld BTU/hr\n",
3068c18ec02fSPetter Reinholdtsen 				instantpowerhearoom);
3069c18ec02fSPetter Reinholdtsen 		printf("System Peak Headroom          : %lld BTU/hr\n",
3070c18ec02fSPetter Reinholdtsen 				peakpowerheadroombtuphr);
3071c18ec02fSPetter Reinholdtsen 	} else {
3072c18ec02fSPetter Reinholdtsen 		printf("System Instantaneous Headroom : %d W\n",
3073c18ec02fSPetter Reinholdtsen 				powerheadroom.instheadroom);
3074c18ec02fSPetter Reinholdtsen 		printf("System Peak Headroom          : %d W\n",
3075c18ec02fSPetter Reinholdtsen 				powerheadroom.peakheadroom);
3076c18ec02fSPetter Reinholdtsen 	}
3077c18ec02fSPetter Reinholdtsen 	return 0;
3078c18ec02fSPetter Reinholdtsen }
3079c18ec02fSPetter Reinholdtsen /*
3080c18ec02fSPetter Reinholdtsen  * Function Name:       ipmi_get_power_consumption_data
3081c18ec02fSPetter Reinholdtsen  *
3082c18ec02fSPetter Reinholdtsen  * Description:         This function updates the instant Power consumption information
3083c18ec02fSPetter Reinholdtsen  * Input:               intf - ipmi interface
3084c18ec02fSPetter Reinholdtsen  * Output:              power consumption current reading
3085c18ec02fSPetter Reinholdtsen  *                      Assumption value will be in Watt.
3086c18ec02fSPetter Reinholdtsen  *
3087c18ec02fSPetter Reinholdtsen  * Return:
3088c18ec02fSPetter Reinholdtsen  */
3089c18ec02fSPetter Reinholdtsen static int
ipmi_get_power_consumption_data(struct ipmi_intf * intf,uint8_t unit)3090c18ec02fSPetter Reinholdtsen ipmi_get_power_consumption_data(struct ipmi_intf * intf,uint8_t unit)
3091c18ec02fSPetter Reinholdtsen {
3092c18ec02fSPetter Reinholdtsen 	SensorReadingType sensorReadingData;
3093c18ec02fSPetter Reinholdtsen 
3094c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp=NULL;
3095c18ec02fSPetter Reinholdtsen 	struct sdr_record_list *sdr;
3096c18ec02fSPetter Reinholdtsen 	int readingbtuphr = 0;
3097c18ec02fSPetter Reinholdtsen 	int warning_threshbtuphr = 0;
3098c18ec02fSPetter Reinholdtsen 	int failure_threshbtuphr = 0;
3099c18ec02fSPetter Reinholdtsen 	int status = 0;
3100c18ec02fSPetter Reinholdtsen 	int sensor_number = 0;
3101c18ec02fSPetter Reinholdtsen 	sdr = ipmi_sdr_find_sdr_byid(intf, "System Level");
3102c18ec02fSPetter Reinholdtsen 	if (sdr == NULL) {
3103c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3104c18ec02fSPetter Reinholdtsen 				"Error : Can not access the System Level sensor data");
3105c18ec02fSPetter Reinholdtsen 		return -1;
3106c18ec02fSPetter Reinholdtsen 	}
3107c18ec02fSPetter Reinholdtsen 	sensor_number = sdr->record.common->keys.sensor_num;
3108c18ec02fSPetter Reinholdtsen 	ipmi_get_sensor_reading(intf,sensor_number,&sensorReadingData);
3109c18ec02fSPetter Reinholdtsen 	rsp = ipmi_sdr_get_sensor_thresholds(intf,
3110c18ec02fSPetter Reinholdtsen 			sdr->record.common->keys.sensor_num,
3111c18ec02fSPetter Reinholdtsen 			sdr->record.common->keys.owner_id,
3112c18ec02fSPetter Reinholdtsen 			sdr->record.common->keys.lun,
3113c18ec02fSPetter Reinholdtsen 			sdr->record.common->keys.channel);
3114c18ec02fSPetter Reinholdtsen 	if (rsp == NULL || rsp->ccode != 0) {
3115c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3116c18ec02fSPetter Reinholdtsen 				"Error : Can not access the System Level sensor data");
3117c18ec02fSPetter Reinholdtsen 		return -1;
3118c18ec02fSPetter Reinholdtsen 	}
3119c18ec02fSPetter Reinholdtsen 	readingbtuphr = sdr_convert_sensor_reading(sdr->record.full,
3120c18ec02fSPetter Reinholdtsen 			sensorReadingData.sensorReading);
3121c18ec02fSPetter Reinholdtsen 	warning_threshbtuphr = sdr_convert_sensor_reading(sdr->record.full,
3122c18ec02fSPetter Reinholdtsen 			rsp->data[4]);
3123c18ec02fSPetter Reinholdtsen 	failure_threshbtuphr = sdr_convert_sensor_reading(sdr->record.full,
3124c18ec02fSPetter Reinholdtsen 			rsp->data[5]);
3125c18ec02fSPetter Reinholdtsen 
3126c18ec02fSPetter Reinholdtsen 	printf("System Board System Level\n");
3127c18ec02fSPetter Reinholdtsen 	if (unit == btuphr) {
3128c18ec02fSPetter Reinholdtsen 		readingbtuphr = watt_to_btuphr_conversion(readingbtuphr);
3129c18ec02fSPetter Reinholdtsen 		warning_threshbtuphr = watt_to_btuphr_conversion(warning_threshbtuphr);
3130c18ec02fSPetter Reinholdtsen 		failure_threshbtuphr = watt_to_btuphr_conversion( failure_threshbtuphr);
3131c18ec02fSPetter Reinholdtsen 
3132c18ec02fSPetter Reinholdtsen 		printf("Reading                        : %d BTU/hr\n", readingbtuphr);
3133c18ec02fSPetter Reinholdtsen 		printf("Warning threshold      : %d BTU/hr\n", warning_threshbtuphr);
3134c18ec02fSPetter Reinholdtsen 		printf("Failure threshold      : %d BTU/hr\n", failure_threshbtuphr);
3135c18ec02fSPetter Reinholdtsen 	} else {
3136c18ec02fSPetter Reinholdtsen 		printf("Reading                        : %d W \n",readingbtuphr);
3137c18ec02fSPetter Reinholdtsen 		printf("Warning threshold      : %d W \n",(warning_threshbtuphr));
3138c18ec02fSPetter Reinholdtsen 		printf("Failure threshold      : %d W \n",(failure_threshbtuphr));
3139c18ec02fSPetter Reinholdtsen 	}
3140c18ec02fSPetter Reinholdtsen 	return status;
3141c18ec02fSPetter Reinholdtsen }
3142c18ec02fSPetter Reinholdtsen /*
3143c18ec02fSPetter Reinholdtsen  * Function Name:      ipmi_get_instan_power_consmpt_data
3144c18ec02fSPetter Reinholdtsen  *
3145c18ec02fSPetter Reinholdtsen  * Description:        This function updates the instant Power consumption information
3146c18ec02fSPetter Reinholdtsen  * Input:              intf - ipmi interface
3147c18ec02fSPetter Reinholdtsen  * Output:             instpowerconsumptiondata - instant Power consumption information
3148c18ec02fSPetter Reinholdtsen  *
3149c18ec02fSPetter Reinholdtsen  * Return:
3150c18ec02fSPetter Reinholdtsen  */
3151c18ec02fSPetter Reinholdtsen static int
ipmi_get_instan_power_consmpt_data(struct ipmi_intf * intf,IPMI_INST_POWER_CONSUMPTION_DATA * instpowerconsumptiondata)3152c18ec02fSPetter Reinholdtsen ipmi_get_instan_power_consmpt_data(struct ipmi_intf * intf,
3153c18ec02fSPetter Reinholdtsen 		IPMI_INST_POWER_CONSUMPTION_DATA * instpowerconsumptiondata)
3154c18ec02fSPetter Reinholdtsen {
3155c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
3156c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req={0};
3157c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[2];
3158c18ec02fSPetter Reinholdtsen 	/*get instantaneous power consumption command*/
3159c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
3160c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
3161c18ec02fSPetter Reinholdtsen 	req.msg.cmd = GET_PWR_CONSUMPTION_CMD;
3162c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
3163c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 2;
3164c18ec02fSPetter Reinholdtsen 	memset(msg_data, 0, 2);
3165c18ec02fSPetter Reinholdtsen 	msg_data[0] = 0x0A;
3166c18ec02fSPetter Reinholdtsen 	msg_data[1] = 0x00;
3167c18ec02fSPetter Reinholdtsen 
3168c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
3169c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
3170c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting instantaneous power consumption data .");
3171c18ec02fSPetter Reinholdtsen 		return -1;
3172859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13)
3173c18ec02fSPetter Reinholdtsen 			&& (rsp->ccode == LICENSE_NOT_SUPPORTED)) {
3174c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3175c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3176c18ec02fSPetter Reinholdtsen 		return -1;
3177c18ec02fSPetter Reinholdtsen 	} else if ((rsp->ccode == 0xc1) || (rsp->ccode == 0xcb)) {
3178c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting instantaneous power consumption data: "
3179c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
3180c18ec02fSPetter Reinholdtsen 		return -1;
3181c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode != 0) {
3182c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting instantaneous power consumption data: %s",
3183c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
3184c18ec02fSPetter Reinholdtsen 		return -1;
3185c18ec02fSPetter Reinholdtsen 	}
3186c18ec02fSPetter Reinholdtsen 	*instpowerconsumptiondata = *((IPMI_INST_POWER_CONSUMPTION_DATA *)(rsp->data));
3187c18ec02fSPetter Reinholdtsen #if WORDS_BIGENDIAN
3188c18ec02fSPetter Reinholdtsen 	instpowerconsumptiondata->instanpowerconsumption = BSWAP_16(instpowerconsumptiondata->instanpowerconsumption);
3189c18ec02fSPetter Reinholdtsen 	instpowerconsumptiondata->instanApms = BSWAP_16(instpowerconsumptiondata->instanApms);
3190c18ec02fSPetter Reinholdtsen 	instpowerconsumptiondata->resv1 = BSWAP_16(instpowerconsumptiondata->resv1);
3191c18ec02fSPetter Reinholdtsen #endif
3192c18ec02fSPetter Reinholdtsen 	return 0;
3193c18ec02fSPetter Reinholdtsen }
3194c18ec02fSPetter Reinholdtsen /*
3195c18ec02fSPetter Reinholdtsen  * Function Name:      ipmi_print_get_instan_power_Amps_data
3196c18ec02fSPetter Reinholdtsen  *
3197c18ec02fSPetter Reinholdtsen  * Description:        This function prints the instant Power consumption information
3198c18ec02fSPetter Reinholdtsen  * Input:              instpowerconsumptiondata - instant Power consumption information
3199c18ec02fSPetter Reinholdtsen  * Output:
3200c18ec02fSPetter Reinholdtsen  *
3201c18ec02fSPetter Reinholdtsen  * Return:
3202c18ec02fSPetter Reinholdtsen  */
3203c18ec02fSPetter Reinholdtsen static void
ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata)3204c18ec02fSPetter Reinholdtsen ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata)
3205c18ec02fSPetter Reinholdtsen {
3206c18ec02fSPetter Reinholdtsen 	uint16_t intampsval=0;
3207c18ec02fSPetter Reinholdtsen 	uint16_t decimalampsval=0;
3208c18ec02fSPetter Reinholdtsen 	if (instpowerconsumptiondata.instanApms > 0) {
3209c18ec02fSPetter Reinholdtsen 		decimalampsval = (instpowerconsumptiondata.instanApms % 10);
3210c18ec02fSPetter Reinholdtsen 		intampsval = instpowerconsumptiondata.instanApms / 10;
3211c18ec02fSPetter Reinholdtsen 	}
3212c18ec02fSPetter Reinholdtsen 	printf("\nAmperage value: %d.%d A \n", intampsval, decimalampsval);
3213c18ec02fSPetter Reinholdtsen }
3214c18ec02fSPetter Reinholdtsen /*
3215c18ec02fSPetter Reinholdtsen  * Function Name:     ipmi_print_get_power_consmpt_data
3216c18ec02fSPetter Reinholdtsen  *
3217c18ec02fSPetter Reinholdtsen  * Description:       This function prints the Power consumption information
3218c18ec02fSPetter Reinholdtsen  * Input:             intf            - ipmi interface
3219c18ec02fSPetter Reinholdtsen  *                    unit            - watt / btuphr
3220c18ec02fSPetter Reinholdtsen  * Output:
3221c18ec02fSPetter Reinholdtsen  *
3222c18ec02fSPetter Reinholdtsen  * Return:
3223c18ec02fSPetter Reinholdtsen  */
3224c18ec02fSPetter Reinholdtsen static int
ipmi_print_get_power_consmpt_data(struct ipmi_intf * intf,uint8_t unit)3225c18ec02fSPetter Reinholdtsen ipmi_print_get_power_consmpt_data(struct ipmi_intf * intf, uint8_t unit)
3226c18ec02fSPetter Reinholdtsen {
3227c18ec02fSPetter Reinholdtsen 	int rc = 0;
3228c18ec02fSPetter Reinholdtsen 	IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata = {0,0,0,0};
3229c18ec02fSPetter Reinholdtsen 	printf("\nPower consumption information\n");
3230c18ec02fSPetter Reinholdtsen 	rc = ipmi_get_power_consumption_data(intf, unit);
3231c18ec02fSPetter Reinholdtsen 	if (rc == (-1)) {
3232c18ec02fSPetter Reinholdtsen 		return rc;
3233c18ec02fSPetter Reinholdtsen 	}
3234c18ec02fSPetter Reinholdtsen 	rc = ipmi_get_instan_power_consmpt_data(intf, &instpowerconsumptiondata);
3235c18ec02fSPetter Reinholdtsen 	if (rc == (-1)) {
3236c18ec02fSPetter Reinholdtsen 		return rc;
3237c18ec02fSPetter Reinholdtsen 	}
3238c18ec02fSPetter Reinholdtsen 	ipmi_print_get_instan_power_Amps_data(instpowerconsumptiondata);
3239c18ec02fSPetter Reinholdtsen 	rc = ipmi_get_power_headroom_command(intf, unit);
3240c18ec02fSPetter Reinholdtsen 	if (rc == (-1)) {
3241c18ec02fSPetter Reinholdtsen 		return rc;
3242c18ec02fSPetter Reinholdtsen 	}
3243c18ec02fSPetter Reinholdtsen 	return rc;
3244c18ec02fSPetter Reinholdtsen }
3245c18ec02fSPetter Reinholdtsen /*
3246c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_get_avgpower_consmpt_history
3247c18ec02fSPetter Reinholdtsen  *
3248c18ec02fSPetter Reinholdtsen  * Description:     This function updates the average power consumption information
3249c18ec02fSPetter Reinholdtsen  * Input:           intf            - ipmi interface
3250c18ec02fSPetter Reinholdtsen  * Output:          pavgpower- average power consumption information
3251c18ec02fSPetter Reinholdtsen  *
3252c18ec02fSPetter Reinholdtsen  * Return:
3253c18ec02fSPetter Reinholdtsen  */
3254c18ec02fSPetter Reinholdtsen static int
ipmi_get_avgpower_consmpt_history(struct ipmi_intf * intf,IPMI_AVGPOWER_CONSUMP_HISTORY * pavgpower)3255c18ec02fSPetter Reinholdtsen ipmi_get_avgpower_consmpt_history(struct ipmi_intf * intf,
3256c18ec02fSPetter Reinholdtsen 		IPMI_AVGPOWER_CONSUMP_HISTORY * pavgpower)
3257c18ec02fSPetter Reinholdtsen {
3258c18ec02fSPetter Reinholdtsen 	int rc;
3259c18ec02fSPetter Reinholdtsen 	uint8_t *rdata;
3260c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, 0xeb, 0, 0, sizeof(*pavgpower), pavgpower);
3261c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
3262c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3263c18ec02fSPetter Reinholdtsen 				"Error getting average power consumption history data.");
3264c18ec02fSPetter Reinholdtsen 		return -1;
3265859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13) &&  (rc == LICENSE_NOT_SUPPORTED)) {
3266c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3267c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3268c18ec02fSPetter Reinholdtsen 		return -1;
3269c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1) || (rc == 0xcb)) {
3270c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting average power consumption history data: "
3271c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
3272c18ec02fSPetter Reinholdtsen 		return -1;
3273c18ec02fSPetter Reinholdtsen 	} else if (rc != 0) {
3274c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3275c18ec02fSPetter Reinholdtsen 				"Error getting average power consumption history data: %s",
3276c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
3277c18ec02fSPetter Reinholdtsen 		return -1;
3278c18ec02fSPetter Reinholdtsen 	}
3279c18ec02fSPetter Reinholdtsen 	if (verbose > 1) {
3280c18ec02fSPetter Reinholdtsen 		rdata = (void *)pavgpower;
3281c18ec02fSPetter Reinholdtsen 		printf("Average power consumption history data"
3282c18ec02fSPetter Reinholdtsen 				"       :%x %x %x %x %x %x %x %x\n\n",
3283c18ec02fSPetter Reinholdtsen 				rdata[0], rdata[1], rdata[2], rdata[3],
3284c18ec02fSPetter Reinholdtsen 				rdata[4], rdata[5], rdata[6], rdata[7]);
3285c18ec02fSPetter Reinholdtsen 	}
3286c18ec02fSPetter Reinholdtsen # if WORDS_BIGENDIAN
3287c18ec02fSPetter Reinholdtsen 	pavgpower->lastminutepower = BSWAP_16(pavgpower->lastminutepower);
3288c18ec02fSPetter Reinholdtsen 	pavgpower->lasthourpower = BSWAP_16(pavgpower->lasthourpower);
3289c18ec02fSPetter Reinholdtsen 	pavgpower->lastdaypower = BSWAP_16(pavgpower->lastdaypower);
3290c18ec02fSPetter Reinholdtsen 	pavgpower->lastweakpower = BSWAP_16(pavgpower->lastweakpower);
3291c18ec02fSPetter Reinholdtsen # endif
3292c18ec02fSPetter Reinholdtsen 	return 0;
3293c18ec02fSPetter Reinholdtsen }
3294c18ec02fSPetter Reinholdtsen /*
3295c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_get_peakpower_consmpt_history
3296c18ec02fSPetter Reinholdtsen  *
3297c18ec02fSPetter Reinholdtsen  * Description:      This function updates the peak power consumption information
3298c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
3299c18ec02fSPetter Reinholdtsen  * Output:           pavgpower- peak power consumption information
3300c18ec02fSPetter Reinholdtsen  *
3301c18ec02fSPetter Reinholdtsen  * Return:
3302c18ec02fSPetter Reinholdtsen  */
3303c18ec02fSPetter Reinholdtsen static int
ipmi_get_peakpower_consmpt_history(struct ipmi_intf * intf,IPMI_POWER_CONSUMP_HISTORY * pstPeakpower)3304c18ec02fSPetter Reinholdtsen ipmi_get_peakpower_consmpt_history(struct ipmi_intf * intf,
3305c18ec02fSPetter Reinholdtsen 		IPMI_POWER_CONSUMP_HISTORY * pstPeakpower)
3306c18ec02fSPetter Reinholdtsen {
3307c18ec02fSPetter Reinholdtsen 	uint8_t *rdata;
3308c18ec02fSPetter Reinholdtsen 	int rc;
3309c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, 0xec, 0, 0, sizeof(*pstPeakpower),
3310c18ec02fSPetter Reinholdtsen 			pstPeakpower);
3311c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
3312c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting  peak power consumption history data.");
3313c18ec02fSPetter Reinholdtsen 		return -1;
3314859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
3315c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3316c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3317c18ec02fSPetter Reinholdtsen 		return -1;
3318c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1) || (rc == 0xcb)) {
3319c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting peak power consumption history data: "
3320c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
3321c18ec02fSPetter Reinholdtsen 		return -1;
3322c18ec02fSPetter Reinholdtsen 	} else if (rc != 0) {
3323c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting peak power consumption history data: %s",
3324c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
3325c18ec02fSPetter Reinholdtsen 		return -1;
3326c18ec02fSPetter Reinholdtsen 	}
3327c18ec02fSPetter Reinholdtsen 	if (verbose > 1) {
3328c18ec02fSPetter Reinholdtsen 		rdata = (void *)pstPeakpower;
3329c18ec02fSPetter Reinholdtsen 		printf("Peak power consmhistory  Data               : "
3330c18ec02fSPetter Reinholdtsen 				"%x %x %x %x %x %x %x %x %x %x\n   "
3331c18ec02fSPetter Reinholdtsen 				"%x %x %x %x %x %x %x %x %x %x %x %x %x %x\n\n",
3332c18ec02fSPetter Reinholdtsen 				rdata[0], rdata[1], rdata[2], rdata[3],
3333c18ec02fSPetter Reinholdtsen 				rdata[4], rdata[5], rdata[6], rdata[7],
3334c18ec02fSPetter Reinholdtsen 				rdata[8], rdata[9], rdata[10], rdata[11],
3335c18ec02fSPetter Reinholdtsen 				rdata[12], rdata[13], rdata[14], rdata[15],
3336c18ec02fSPetter Reinholdtsen 				rdata[16], rdata[17], rdata[18], rdata[19],
3337c18ec02fSPetter Reinholdtsen 				rdata[20], rdata[21], rdata[22], rdata[23]);
3338c18ec02fSPetter Reinholdtsen 	}
3339c18ec02fSPetter Reinholdtsen # if WORDS_BIGENDIAN
3340c18ec02fSPetter Reinholdtsen 	pstPeakpower->lastminutepower = BSWAP_16(pstPeakpower->lastminutepower);
3341c18ec02fSPetter Reinholdtsen 	pstPeakpower->lasthourpower = BSWAP_16(pstPeakpower->lasthourpower);
3342c18ec02fSPetter Reinholdtsen 	pstPeakpower->lastdaypower = BSWAP_16(pstPeakpower->lastdaypower);
3343c18ec02fSPetter Reinholdtsen 	pstPeakpower->lastweakpower = BSWAP_16(pstPeakpower->lastweakpower);
3344c18ec02fSPetter Reinholdtsen 	pstPeakpower->lastminutepowertime = BSWAP_32(pstPeakpower->lastminutepowertime);
3345c18ec02fSPetter Reinholdtsen 	pstPeakpower->lasthourpowertime = BSWAP_32(pstPeakpower->lasthourpowertime);
3346c18ec02fSPetter Reinholdtsen 	pstPeakpower->lastdaypowertime = BSWAP_32(pstPeakpower->lastdaypowertime);
3347c18ec02fSPetter Reinholdtsen 	pstPeakpower->lastweekpowertime = BSWAP_32(pstPeakpower->lastweekpowertime);
3348c18ec02fSPetter Reinholdtsen #endif
3349c18ec02fSPetter Reinholdtsen 	return 0;
3350c18ec02fSPetter Reinholdtsen }
3351c18ec02fSPetter Reinholdtsen /*
3352c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_get_minpower_consmpt_history
3353c18ec02fSPetter Reinholdtsen  *
3354c18ec02fSPetter Reinholdtsen  * Description:      This function updates the peak power consumption information
3355c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
3356c18ec02fSPetter Reinholdtsen  * Output:           pavgpower- peak power consumption information
3357c18ec02fSPetter Reinholdtsen  *
3358c18ec02fSPetter Reinholdtsen  * Return:
3359c18ec02fSPetter Reinholdtsen  */
3360c18ec02fSPetter Reinholdtsen static int
ipmi_get_minpower_consmpt_history(struct ipmi_intf * intf,IPMI_POWER_CONSUMP_HISTORY * pstMinpower)3361c18ec02fSPetter Reinholdtsen ipmi_get_minpower_consmpt_history(struct ipmi_intf * intf,
3362c18ec02fSPetter Reinholdtsen 		IPMI_POWER_CONSUMP_HISTORY * pstMinpower)
3363c18ec02fSPetter Reinholdtsen {
3364c18ec02fSPetter Reinholdtsen 	uint8_t *rdata;
3365c18ec02fSPetter Reinholdtsen 	int rc;
3366c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, 0xed, 0, 0, sizeof(*pstMinpower),
3367c18ec02fSPetter Reinholdtsen 			pstMinpower);
3368c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
3369c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting  peak power consumption history data .");
3370c18ec02fSPetter Reinholdtsen 		return -1;
3371859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13) &&  (rc == LICENSE_NOT_SUPPORTED)) {
3372c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3373c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3374c18ec02fSPetter Reinholdtsen 		return -1;
3375c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1) || (rc == 0xcb)) {
3376c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting peak power consumption history data: "
3377c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
3378c18ec02fSPetter Reinholdtsen 		return -1;
3379c18ec02fSPetter Reinholdtsen 	} else if (rc != 0) {
3380c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting peak power consumption history data: %s",
3381c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
3382c18ec02fSPetter Reinholdtsen 		return -1;
3383c18ec02fSPetter Reinholdtsen 	}
3384c18ec02fSPetter Reinholdtsen 	if (verbose > 1) {
3385c18ec02fSPetter Reinholdtsen 		rdata = (void *)pstMinpower;
3386c18ec02fSPetter Reinholdtsen 		printf("Peak power consmhistory  Data               : "
3387c18ec02fSPetter Reinholdtsen 				"%x %x %x %x %x %x %x %x %x %x\n   "
3388c18ec02fSPetter Reinholdtsen 				"%x %x %x %x %x %x %x %x %x %x %x %x %x\n\n",
3389c18ec02fSPetter Reinholdtsen 				rdata[0], rdata[1], rdata[2], rdata[3],
3390c18ec02fSPetter Reinholdtsen 				rdata[4], rdata[5], rdata[6], rdata[7],
3391c18ec02fSPetter Reinholdtsen 				rdata[8], rdata[9], rdata[10], rdata[11],
3392c18ec02fSPetter Reinholdtsen 				rdata[12], rdata[13], rdata[14], rdata[15],
3393c18ec02fSPetter Reinholdtsen 				rdata[16], rdata[17], rdata[18], rdata[19],
3394c18ec02fSPetter Reinholdtsen 				rdata[20], rdata[21], rdata[22], rdata[23]);
3395c18ec02fSPetter Reinholdtsen 	}
3396c18ec02fSPetter Reinholdtsen # if WORDS_BIGENDIAN
3397c18ec02fSPetter Reinholdtsen 	pstMinpower->lastminutepower = BSWAP_16(pstMinpower->lastminutepower);
3398c18ec02fSPetter Reinholdtsen 	pstMinpower->lasthourpower = BSWAP_16(pstMinpower->lasthourpower);
3399c18ec02fSPetter Reinholdtsen 	pstMinpower->lastdaypower = BSWAP_16(pstMinpower->lastdaypower);
3400c18ec02fSPetter Reinholdtsen 	pstMinpower->lastweakpower = BSWAP_16(pstMinpower->lastweakpower);
3401c18ec02fSPetter Reinholdtsen 	pstMinpower->lastminutepowertime = BSWAP_32(pstMinpower->lastminutepowertime);
3402c18ec02fSPetter Reinholdtsen 	pstMinpower->lasthourpowertime = BSWAP_32(pstMinpower->lasthourpowertime);
3403c18ec02fSPetter Reinholdtsen 	pstMinpower->lastdaypowertime = BSWAP_32(pstMinpower->lastdaypowertime);
3404c18ec02fSPetter Reinholdtsen 	pstMinpower->lastweekpowertime = BSWAP_32(pstMinpower->lastweekpowertime);
3405c18ec02fSPetter Reinholdtsen # endif
3406c18ec02fSPetter Reinholdtsen 	return 0;
3407c18ec02fSPetter Reinholdtsen }
3408c18ec02fSPetter Reinholdtsen /*
3409c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_print_power_consmpt_history
3410c18ec02fSPetter Reinholdtsen  *
3411c18ec02fSPetter Reinholdtsen  * Description:      This function print the average and peak power consumption information
3412c18ec02fSPetter Reinholdtsen  * Input:            intf      - ipmi interface
3413c18ec02fSPetter Reinholdtsen  *                   unit      - watt / btuphr
3414c18ec02fSPetter Reinholdtsen  * Output:
3415c18ec02fSPetter Reinholdtsen  *
3416c18ec02fSPetter Reinholdtsen  * Return:
3417c18ec02fSPetter Reinholdtsen  */
3418c18ec02fSPetter Reinholdtsen static int
ipmi_print_power_consmpt_history(struct ipmi_intf * intf,int unit)3419c18ec02fSPetter Reinholdtsen ipmi_print_power_consmpt_history(struct ipmi_intf * intf, int unit)
3420c18ec02fSPetter Reinholdtsen {
3421c18ec02fSPetter Reinholdtsen 	char timestr[30];
3422c18ec02fSPetter Reinholdtsen 	uint32_t lastminutepeakpower;
3423c18ec02fSPetter Reinholdtsen 	uint32_t lasthourpeakpower;
3424c18ec02fSPetter Reinholdtsen 	uint32_t lastdaypeakpower;
3425c18ec02fSPetter Reinholdtsen 	uint32_t lastweekpeakpower;
3426c18ec02fSPetter Reinholdtsen 	uint64_t tempbtuphrconv;
3427c18ec02fSPetter Reinholdtsen 	int rc = 0;
3428c18ec02fSPetter Reinholdtsen 
3429c18ec02fSPetter Reinholdtsen 	IPMI_AVGPOWER_CONSUMP_HISTORY avgpower;
3430c18ec02fSPetter Reinholdtsen 	IPMI_POWER_CONSUMP_HISTORY stMinpower;
3431c18ec02fSPetter Reinholdtsen 	IPMI_POWER_CONSUMP_HISTORY stPeakpower;
3432c18ec02fSPetter Reinholdtsen 
3433c18ec02fSPetter Reinholdtsen 	rc = ipmi_get_avgpower_consmpt_history(intf, &avgpower);
3434c18ec02fSPetter Reinholdtsen 	if (rc == (-1)) {
3435c18ec02fSPetter Reinholdtsen 		return rc;
3436c18ec02fSPetter Reinholdtsen 	}
3437c18ec02fSPetter Reinholdtsen 
3438c18ec02fSPetter Reinholdtsen 	rc = ipmi_get_peakpower_consmpt_history(intf, &stPeakpower);
3439c18ec02fSPetter Reinholdtsen 	if (rc == (-1)) {
3440c18ec02fSPetter Reinholdtsen 		return rc;
3441c18ec02fSPetter Reinholdtsen 	}
3442c18ec02fSPetter Reinholdtsen 
3443c18ec02fSPetter Reinholdtsen 	rc = ipmi_get_minpower_consmpt_history(intf, &stMinpower);
3444c18ec02fSPetter Reinholdtsen 	if (rc == (-1)) {
3445c18ec02fSPetter Reinholdtsen 		return rc;
3446c18ec02fSPetter Reinholdtsen 	}
3447c18ec02fSPetter Reinholdtsen 	if (rc != 0) {
3448c18ec02fSPetter Reinholdtsen 		return rc;
3449c18ec02fSPetter Reinholdtsen 	}
3450c18ec02fSPetter Reinholdtsen 	printf("Power Consumption History\n\n");
3451c18ec02fSPetter Reinholdtsen 	/* The fields are alligned manually changing the spaces will alter
3452c18ec02fSPetter Reinholdtsen 	 * the alignment*/
3453c18ec02fSPetter Reinholdtsen 	printf("Statistic                   Last Minute     Last Hour     "
3454c18ec02fSPetter Reinholdtsen 			"Last Day     Last Week\n\n");
3455c18ec02fSPetter Reinholdtsen 	if (unit == btuphr) {
3456c18ec02fSPetter Reinholdtsen 		printf("Average Power Consumption  ");
3457c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastminutepower);
3458c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr     ", tempbtuphrconv);
3459c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lasthourpower);
3460c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr   ", tempbtuphrconv);
3461c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastdaypower);
3462c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr  ", tempbtuphrconv);
3463c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastweakpower);
3464c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr\n", tempbtuphrconv);
3465c18ec02fSPetter Reinholdtsen 
3466c18ec02fSPetter Reinholdtsen 		printf("Max Power Consumption      ");
3467c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastminutepower);
3468c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr     ", tempbtuphrconv);
3469c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lasthourpower);
3470c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr   ", tempbtuphrconv);
3471c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastdaypower);
3472c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr  ", tempbtuphrconv);
3473c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastweakpower);
3474c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr\n", tempbtuphrconv);
3475c18ec02fSPetter Reinholdtsen 
3476c18ec02fSPetter Reinholdtsen 		printf("Min Power Consumption      ");
3477c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastminutepower);
3478c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr     ", tempbtuphrconv);
3479c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lasthourpower);
3480c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr   ", tempbtuphrconv);
3481c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastdaypower);
3482c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr  ", tempbtuphrconv);
3483c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastweakpower);
3484c18ec02fSPetter Reinholdtsen 		printf("%4lld BTU/hr\n\n", tempbtuphrconv);
3485c18ec02fSPetter Reinholdtsen 	} else {
3486c18ec02fSPetter Reinholdtsen 		printf("Average Power Consumption  ");
3487c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (avgpower.lastminutepower);
3488c18ec02fSPetter Reinholdtsen 		printf("%4lld W          ", tempbtuphrconv);
3489c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (avgpower.lasthourpower);
3490c18ec02fSPetter Reinholdtsen 		printf("%4lld W        ", tempbtuphrconv);
3491c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (avgpower.lastdaypower);
3492c18ec02fSPetter Reinholdtsen 		printf("%4lld W       ", tempbtuphrconv);
3493c18ec02fSPetter Reinholdtsen 		tempbtuphrconv=(avgpower.lastweakpower);
3494c18ec02fSPetter Reinholdtsen 		printf("%4lld W   \n", tempbtuphrconv);
3495c18ec02fSPetter Reinholdtsen 
3496c18ec02fSPetter Reinholdtsen 		printf("Max Power Consumption      ");
3497c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (stPeakpower.lastminutepower);
3498c18ec02fSPetter Reinholdtsen 		printf("%4lld W          ", tempbtuphrconv);
3499c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (stPeakpower.lasthourpower);
3500c18ec02fSPetter Reinholdtsen 		printf("%4lld W        ", tempbtuphrconv);
3501c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (stPeakpower.lastdaypower);
3502c18ec02fSPetter Reinholdtsen 		printf("%4lld W       ", tempbtuphrconv);
3503c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (stPeakpower.lastweakpower);
3504c18ec02fSPetter Reinholdtsen 		printf("%4lld W   \n", tempbtuphrconv);
3505c18ec02fSPetter Reinholdtsen 
3506c18ec02fSPetter Reinholdtsen 		printf("Min Power Consumption      ");
3507c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (stMinpower.lastminutepower);
3508c18ec02fSPetter Reinholdtsen 		printf("%4lld W          ", tempbtuphrconv);
3509c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (stMinpower.lasthourpower);
3510c18ec02fSPetter Reinholdtsen 		printf("%4lld W        ", tempbtuphrconv);
3511c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (stMinpower.lastdaypower);
3512c18ec02fSPetter Reinholdtsen 		printf("%4lld W       ", tempbtuphrconv);
3513c18ec02fSPetter Reinholdtsen 		tempbtuphrconv = (stMinpower.lastweakpower);
3514c18ec02fSPetter Reinholdtsen 		printf("%4lld W   \n\n", tempbtuphrconv);
3515c18ec02fSPetter Reinholdtsen 	}
3516c18ec02fSPetter Reinholdtsen 
3517c18ec02fSPetter Reinholdtsen 	lastminutepeakpower = stPeakpower.lastminutepowertime;
3518c18ec02fSPetter Reinholdtsen 	lasthourpeakpower = stPeakpower.lasthourpowertime;
3519c18ec02fSPetter Reinholdtsen 	lastdaypeakpower = stPeakpower.lastdaypowertime;
3520c18ec02fSPetter Reinholdtsen 	lastweekpeakpower = stPeakpower.lastweekpowertime;
3521c18ec02fSPetter Reinholdtsen 
3522c18ec02fSPetter Reinholdtsen 	printf("Max Power Time\n");
3523c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(lastminutepeakpower, timestr);
3524c18ec02fSPetter Reinholdtsen 	printf("Last Minute     : %s",timestr);
3525c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(lasthourpeakpower, timestr);
3526c18ec02fSPetter Reinholdtsen 	printf("Last Hour       : %s",timestr);
3527c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(lastdaypeakpower, timestr);
3528c18ec02fSPetter Reinholdtsen 	printf("Last Day        : %s",timestr);
3529c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(lastweekpeakpower, timestr);
3530c18ec02fSPetter Reinholdtsen 	printf("Last Week       : %s",timestr);
3531c18ec02fSPetter Reinholdtsen 
3532c18ec02fSPetter Reinholdtsen 	lastminutepeakpower=stMinpower.lastminutepowertime;
3533c18ec02fSPetter Reinholdtsen 	lasthourpeakpower=stMinpower.lasthourpowertime;
3534c18ec02fSPetter Reinholdtsen 	lastdaypeakpower=stMinpower.lastdaypowertime;
3535c18ec02fSPetter Reinholdtsen 	lastweekpeakpower=stMinpower.lastweekpowertime;
3536c18ec02fSPetter Reinholdtsen 
3537c18ec02fSPetter Reinholdtsen 	printf("Min Power Time\n");
3538c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(lastminutepeakpower, timestr);
3539c18ec02fSPetter Reinholdtsen 	printf("Last Minute     : %s", timestr);
3540c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(lasthourpeakpower, timestr);
3541c18ec02fSPetter Reinholdtsen 	printf("Last Hour       : %s", timestr);
3542c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(lastdaypeakpower, timestr);
3543c18ec02fSPetter Reinholdtsen 	printf("Last Day        : %s", timestr);
3544c18ec02fSPetter Reinholdtsen 	ipmi_time_to_str(lastweekpeakpower, timestr);
3545c18ec02fSPetter Reinholdtsen 	printf("Last Week       : %s", timestr);
3546c18ec02fSPetter Reinholdtsen 	return rc;
3547c18ec02fSPetter Reinholdtsen }
3548c18ec02fSPetter Reinholdtsen /*
3549c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_get_power_cap
3550c18ec02fSPetter Reinholdtsen  *
3551c18ec02fSPetter Reinholdtsen  * Description:      This function updates the power cap information
3552c18ec02fSPetter Reinholdtsen  * Input:            intf         - ipmi interface
3553c18ec02fSPetter Reinholdtsen  * Output:           ipmipowercap - power cap information
3554c18ec02fSPetter Reinholdtsen  *
3555c18ec02fSPetter Reinholdtsen  * Return:
3556c18ec02fSPetter Reinholdtsen  */
3557c18ec02fSPetter Reinholdtsen static int
ipmi_get_power_cap(struct ipmi_intf * intf,IPMI_POWER_CAP * ipmipowercap)3558c18ec02fSPetter Reinholdtsen ipmi_get_power_cap(struct ipmi_intf * intf, IPMI_POWER_CAP * ipmipowercap)
3559c18ec02fSPetter Reinholdtsen {
3560c18ec02fSPetter Reinholdtsen 	uint8_t *rdata;
3561c18ec02fSPetter Reinholdtsen 	int rc;
3562c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_POWER_CAP, 0, 0,
3563c18ec02fSPetter Reinholdtsen 			sizeof(*ipmipowercap), ipmipowercap);
3564c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
3565c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power cap.");
3566c18ec02fSPetter Reinholdtsen 		return -1;
3567859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
3568c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3569c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3570c18ec02fSPetter Reinholdtsen 		return -1;
3571c18ec02fSPetter Reinholdtsen 	} else if ((rc == 0xc1) || (rc == 0xcb)) {
3572c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power cap: "
3573c18ec02fSPetter Reinholdtsen 				"Command not supported on this system.");
3574c18ec02fSPetter Reinholdtsen 		return -1;
3575c18ec02fSPetter Reinholdtsen 	} else if (rc != 0) {
3576c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power cap: %s",
3577c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
3578c18ec02fSPetter Reinholdtsen 		return -1;
3579c18ec02fSPetter Reinholdtsen 	}
3580c18ec02fSPetter Reinholdtsen 	if (verbose > 1) {
3581c18ec02fSPetter Reinholdtsen 		rdata = (void*)ipmipowercap;
3582c18ec02fSPetter Reinholdtsen 		printf("power cap  Data               :%x %x %x %x %x %x %x %x %x %x ",
3583c18ec02fSPetter Reinholdtsen 				rdata[1], rdata[2], rdata[3],
3584c18ec02fSPetter Reinholdtsen 				rdata[4], rdata[5], rdata[6], rdata[7],
3585c18ec02fSPetter Reinholdtsen 				rdata[8], rdata[9], rdata[10],rdata[11]);
3586c18ec02fSPetter Reinholdtsen 	}
3587c18ec02fSPetter Reinholdtsen # if WORDS_BIGENDIAN
3588c18ec02fSPetter Reinholdtsen 	ipmipowercap->PowerCap = BSWAP_16(ipmipowercap->PowerCap);
3589c18ec02fSPetter Reinholdtsen 	ipmipowercap->MaximumPowerConsmp = BSWAP_16(ipmipowercap->MaximumPowerConsmp);
3590c18ec02fSPetter Reinholdtsen 	ipmipowercap->MinimumPowerConsmp = BSWAP_16(ipmipowercap->MinimumPowerConsmp);
3591c18ec02fSPetter Reinholdtsen 	ipmipowercap->totalnumpowersupp = BSWAP_16(ipmipowercap->totalnumpowersupp);
3592c18ec02fSPetter Reinholdtsen 	ipmipowercap->AvailablePower = BSWAP_16(ipmipowercap->AvailablePower);
3593c18ec02fSPetter Reinholdtsen 	ipmipowercap->SystemThrottling = BSWAP_16(ipmipowercap->SystemThrottling);
3594c18ec02fSPetter Reinholdtsen 	ipmipowercap->Resv = BSWAP_16(ipmipowercap->Resv);
3595c18ec02fSPetter Reinholdtsen # endif
3596c18ec02fSPetter Reinholdtsen 	return 0;
3597c18ec02fSPetter Reinholdtsen }
3598c18ec02fSPetter Reinholdtsen /*
3599c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_print_power_cap
3600c18ec02fSPetter Reinholdtsen  *
3601c18ec02fSPetter Reinholdtsen  * Description:      This function print the power cap information
3602c18ec02fSPetter Reinholdtsen  * Input:            intf            - ipmi interface
3603c18ec02fSPetter Reinholdtsen  *                   unit            - watt / btuphr
3604c18ec02fSPetter Reinholdtsen  * Output:
3605c18ec02fSPetter Reinholdtsen  * Return:
3606c18ec02fSPetter Reinholdtsen  */
3607c18ec02fSPetter Reinholdtsen static int
ipmi_print_power_cap(struct ipmi_intf * intf,uint8_t unit)3608c18ec02fSPetter Reinholdtsen ipmi_print_power_cap(struct ipmi_intf * intf,uint8_t unit)
3609c18ec02fSPetter Reinholdtsen {
3610c18ec02fSPetter Reinholdtsen 	uint64_t tempbtuphrconv;
3611c18ec02fSPetter Reinholdtsen 	int rc;
3612c18ec02fSPetter Reinholdtsen 	IPMI_POWER_CAP ipmipowercap;
3613c18ec02fSPetter Reinholdtsen 	memset(&ipmipowercap, 0, sizeof(ipmipowercap));
3614c18ec02fSPetter Reinholdtsen 	rc = ipmi_get_power_cap(intf, &ipmipowercap);
3615c18ec02fSPetter Reinholdtsen 	if (rc == 0) {
3616c18ec02fSPetter Reinholdtsen 		if (unit == btuphr) {
3617c18ec02fSPetter Reinholdtsen 			tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp);
3618c18ec02fSPetter Reinholdtsen 			printf("Maximum power: %lld  BTU/hr\n", tempbtuphrconv);
3619c18ec02fSPetter Reinholdtsen 			tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp);
3620c18ec02fSPetter Reinholdtsen 			printf("Minimum power: %lld  BTU/hr\n", tempbtuphrconv);
3621c18ec02fSPetter Reinholdtsen 			tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.PowerCap);
3622c18ec02fSPetter Reinholdtsen 			printf("Power cap    : %lld  BTU/hr\n", tempbtuphrconv);
3623c18ec02fSPetter Reinholdtsen 		} else {
3624c18ec02fSPetter Reinholdtsen 			printf("Maximum power: %d Watt\n", ipmipowercap.MaximumPowerConsmp);
3625c18ec02fSPetter Reinholdtsen 			printf("Minimum power: %d Watt\n", ipmipowercap.MinimumPowerConsmp);
3626c18ec02fSPetter Reinholdtsen 			printf("Power cap    : %d Watt\n", ipmipowercap.PowerCap);
3627c18ec02fSPetter Reinholdtsen 		}
3628c18ec02fSPetter Reinholdtsen 	}
3629c18ec02fSPetter Reinholdtsen 	return rc;
3630c18ec02fSPetter Reinholdtsen }
3631c18ec02fSPetter Reinholdtsen /*
3632c18ec02fSPetter Reinholdtsen  * Function Name:     ipmi_set_power_cap
3633c18ec02fSPetter Reinholdtsen  *
3634c18ec02fSPetter Reinholdtsen  * Description:       This function updates the power cap information
3635c18ec02fSPetter Reinholdtsen  * Input:             intf            - ipmi interface
3636c18ec02fSPetter Reinholdtsen  *                    unit            - watt / btuphr
3637c18ec02fSPetter Reinholdtsen  *                    val             - new power cap value
3638c18ec02fSPetter Reinholdtsen  * Output:
3639c18ec02fSPetter Reinholdtsen  * Return:
3640c18ec02fSPetter Reinholdtsen  */
3641c18ec02fSPetter Reinholdtsen static int
ipmi_set_power_cap(struct ipmi_intf * intf,int unit,int val)3642c18ec02fSPetter Reinholdtsen ipmi_set_power_cap(struct ipmi_intf * intf, int unit, int val)
3643c18ec02fSPetter Reinholdtsen {
3644c18ec02fSPetter Reinholdtsen 	int rc;
3645c18ec02fSPetter Reinholdtsen 	uint8_t data[13], *rdata;
3646c18ec02fSPetter Reinholdtsen 	uint16_t powercapval;
3647c18ec02fSPetter Reinholdtsen 	uint64_t maxpowerbtuphr;
3648c18ec02fSPetter Reinholdtsen 	uint64_t maxpowerbtuphr1;
3649c18ec02fSPetter Reinholdtsen 	uint64_t minpowerbtuphr;
3650c18ec02fSPetter Reinholdtsen 	IPMI_POWER_CAP ipmipowercap;
3651c18ec02fSPetter Reinholdtsen 
3652c18ec02fSPetter Reinholdtsen 	if (ipmi_get_power_capstatus_command(intf) < 0) {
3653c18ec02fSPetter Reinholdtsen 		return -1; /* Adding the failed condition check */
3654c18ec02fSPetter Reinholdtsen 	}
3655c18ec02fSPetter Reinholdtsen 	if (PowercapSetable_flag != 1) {
3656c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Can not set powercap on this system");
3657c18ec02fSPetter Reinholdtsen 		return -1;
3658c18ec02fSPetter Reinholdtsen 	} else if (PowercapstatusFlag != 1) {
3659c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Power cap set feature is not enabled");
3660c18ec02fSPetter Reinholdtsen 		return -1;
3661c18ec02fSPetter Reinholdtsen 	}
3662c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_getsysinfo(intf, IPMI_DELL_POWER_CAP, 0, 0,
3663c18ec02fSPetter Reinholdtsen 			sizeof(ipmipowercap), &ipmipowercap);
3664c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
3665c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power cap.");
3666c18ec02fSPetter Reinholdtsen 		return -1;
3667859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
3668c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3669c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3670c18ec02fSPetter Reinholdtsen 		return -1;
3671c18ec02fSPetter Reinholdtsen 	} else if (rc == 0xc1) {
3672c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power cap, command not supported on "
3673c18ec02fSPetter Reinholdtsen 				"this system.");
3674c18ec02fSPetter Reinholdtsen 		return -1;
3675c18ec02fSPetter Reinholdtsen 	} else if (rc != 0) {
3676c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error getting power cap: %s",
3677c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
3678c18ec02fSPetter Reinholdtsen 		return -1;
3679c18ec02fSPetter Reinholdtsen 	}
3680c18ec02fSPetter Reinholdtsen 	if (verbose > 1) {
3681c18ec02fSPetter Reinholdtsen 		rdata = (void *)&ipmipowercap;
3682c18ec02fSPetter Reinholdtsen 		printf("power cap  Data               :%x %x %x %x %x %x %x %x %x %x %x ",
3683c18ec02fSPetter Reinholdtsen 				rdata[1], rdata[2], rdata[3],
3684c18ec02fSPetter Reinholdtsen 				rdata[4], rdata[5], rdata[6], rdata[7],
3685c18ec02fSPetter Reinholdtsen 				rdata[8], rdata[9], rdata[10],rdata[11]);
3686c18ec02fSPetter Reinholdtsen 	}
3687c18ec02fSPetter Reinholdtsen # if WORDS_BIGENDIAN
3688c18ec02fSPetter Reinholdtsen 	ipmipowercap.PowerCap = BSWAP_16(ipmipowercap.PowerCap);
3689c18ec02fSPetter Reinholdtsen 	ipmipowercap.MaximumPowerConsmp = BSWAP_16(ipmipowercap.MaximumPowerConsmp);
3690c18ec02fSPetter Reinholdtsen 	ipmipowercap.MinimumPowerConsmp = BSWAP_16(ipmipowercap.MinimumPowerConsmp);
3691c18ec02fSPetter Reinholdtsen 	ipmipowercap.AvailablePower = BSWAP_16(ipmipowercap.AvailablePower);
3692c18ec02fSPetter Reinholdtsen 	ipmipowercap.totalnumpowersupp = BSWAP_16(ipmipowercap.totalnumpowersupp);
3693c18ec02fSPetter Reinholdtsen # endif
3694c18ec02fSPetter Reinholdtsen 	memset(data, 0, 13);
3695c18ec02fSPetter Reinholdtsen 	data[0] = IPMI_DELL_POWER_CAP;
3696c18ec02fSPetter Reinholdtsen 	powercapval = val;
3697c18ec02fSPetter Reinholdtsen 	data[1] = (powercapval & 0XFF);
3698c18ec02fSPetter Reinholdtsen 	data[2] = ((powercapval & 0XFF00) >> 8);
3699c18ec02fSPetter Reinholdtsen 	data[3] = unit;
3700c18ec02fSPetter Reinholdtsen 	data[4] = ((ipmipowercap.MaximumPowerConsmp & 0xFF));
3701c18ec02fSPetter Reinholdtsen 	data[5] = ((ipmipowercap.MaximumPowerConsmp & 0xFF00) >> 8);
3702c18ec02fSPetter Reinholdtsen 	data[6] = ((ipmipowercap.MinimumPowerConsmp & 0xFF));
3703c18ec02fSPetter Reinholdtsen 	data[7] = ((ipmipowercap.MinimumPowerConsmp & 0xFF00) >> 8);
3704c18ec02fSPetter Reinholdtsen 	data[8] = (ipmipowercap.totalnumpowersupp);
3705c18ec02fSPetter Reinholdtsen 	data[9] = ((ipmipowercap.AvailablePower & 0xFF));
3706c18ec02fSPetter Reinholdtsen 	data[10] = ((ipmipowercap.AvailablePower & 0xFF00) >> 8);
3707c18ec02fSPetter Reinholdtsen 	data[11] = (ipmipowercap.SystemThrottling);
3708c18ec02fSPetter Reinholdtsen 	data[12] = 0x00;
3709c18ec02fSPetter Reinholdtsen 
3710c18ec02fSPetter Reinholdtsen 	if (unit == btuphr) {
3711c18ec02fSPetter Reinholdtsen 		val = btuphr_to_watt_conversion(val);
3712c18ec02fSPetter Reinholdtsen 	} else if (unit == percent) {
3713c18ec02fSPetter Reinholdtsen 		if ((val < 0) || (val > 100)) {
3714c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Cap value is out of boundary conditon it "
3715c18ec02fSPetter Reinholdtsen 					"should be between 0  - 100");
3716c18ec02fSPetter Reinholdtsen 			return -1;
3717c18ec02fSPetter Reinholdtsen 		}
3718c18ec02fSPetter Reinholdtsen 		val = ((val*(ipmipowercap.MaximumPowerConsmp
3719c18ec02fSPetter Reinholdtsen 						- ipmipowercap.MinimumPowerConsmp)) / 100)
3720c18ec02fSPetter Reinholdtsen 						+ ipmipowercap.MinimumPowerConsmp;
3721c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Cap value in percentage is  %d ", val);
3722c18ec02fSPetter Reinholdtsen 		data[1] = (val & 0XFF);
3723c18ec02fSPetter Reinholdtsen 		data[2] = ((val & 0XFF00) >> 8);
3724c18ec02fSPetter Reinholdtsen 		data[3] = watt;
3725c18ec02fSPetter Reinholdtsen 	}
3726c18ec02fSPetter Reinholdtsen 	if (((val < ipmipowercap.MinimumPowerConsmp)
3727c18ec02fSPetter Reinholdtsen 				|| (val > ipmipowercap.MaximumPowerConsmp)) && (unit == watt)) {
3728c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3729c18ec02fSPetter Reinholdtsen 				"Cap value is out of boundary conditon it should be between %d  - %d",
3730c18ec02fSPetter Reinholdtsen 				ipmipowercap.MinimumPowerConsmp, ipmipowercap.MaximumPowerConsmp);
3731c18ec02fSPetter Reinholdtsen 		return -1;
3732c18ec02fSPetter Reinholdtsen 	} else if (((val < ipmipowercap.MinimumPowerConsmp)
3733c18ec02fSPetter Reinholdtsen 				|| (val > ipmipowercap.MaximumPowerConsmp)) && (unit == btuphr)) {
3734c18ec02fSPetter Reinholdtsen 		minpowerbtuphr = watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp);
3735c18ec02fSPetter Reinholdtsen 		maxpowerbtuphr = watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp);
3736c18ec02fSPetter Reinholdtsen 		maxpowerbtuphr1 = watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp);
3737c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3738c18ec02fSPetter Reinholdtsen 				"Cap value is out of boundary conditon it should be between %d",
3739c18ec02fSPetter Reinholdtsen 				minpowerbtuphr);
3740c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, " -%d", maxpowerbtuphr1);
3741c18ec02fSPetter Reinholdtsen 		return -1;
3742c18ec02fSPetter Reinholdtsen 	}
3743c18ec02fSPetter Reinholdtsen 	rc = ipmi_mc_setsysinfo(intf, 13, data);
3744c18ec02fSPetter Reinholdtsen 	if (rc < 0) {
3745c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting power cap");
3746c18ec02fSPetter Reinholdtsen 		return -1;
3747859e8a45SZdenek Styblik 	} else if ((iDRAC_FLAG_12_13) && (rc == LICENSE_NOT_SUPPORTED)) {
3748c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3749c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3750c18ec02fSPetter Reinholdtsen 		return -1;
3751c18ec02fSPetter Reinholdtsen 	} else if (rc > 0) {
3752c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error setting power cap: %s",
3753c18ec02fSPetter Reinholdtsen 				val2str(rc, completion_code_vals));
3754c18ec02fSPetter Reinholdtsen 		return -1;
3755c18ec02fSPetter Reinholdtsen 	}
3756c18ec02fSPetter Reinholdtsen 	if (verbose > 1) {
3757c18ec02fSPetter Reinholdtsen 		printf("CC for setpowercap :%d ", rc);
3758c18ec02fSPetter Reinholdtsen 	}
3759c18ec02fSPetter Reinholdtsen 	return 0;
3760c18ec02fSPetter Reinholdtsen }
3761c18ec02fSPetter Reinholdtsen /*
3762c18ec02fSPetter Reinholdtsen  * Function Name:   ipmi_powermonitor_usage
3763c18ec02fSPetter Reinholdtsen  *
3764c18ec02fSPetter Reinholdtsen  * Description:     This function prints help message for powermonitor command
3765c18ec02fSPetter Reinholdtsen  * Input:
3766c18ec02fSPetter Reinholdtsen  * Output:
3767c18ec02fSPetter Reinholdtsen  *
3768c18ec02fSPetter Reinholdtsen  * Return:
3769c18ec02fSPetter Reinholdtsen  */
3770c18ec02fSPetter Reinholdtsen static void
ipmi_powermonitor_usage(void)3771c18ec02fSPetter Reinholdtsen ipmi_powermonitor_usage(void)
3772c18ec02fSPetter Reinholdtsen {
3773c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3774c18ec02fSPetter Reinholdtsen "");
3775c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3776c18ec02fSPetter Reinholdtsen "   powermonitor");
3777c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3778c18ec02fSPetter Reinholdtsen "      Shows power tracking statistics ");
3779c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3780c18ec02fSPetter Reinholdtsen "");
3781c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3782c18ec02fSPetter Reinholdtsen "   powermonitor clear cumulativepower");
3783c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3784c18ec02fSPetter Reinholdtsen "      Reset cumulative power reading");
3785c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3786c18ec02fSPetter Reinholdtsen "");
3787c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3788c18ec02fSPetter Reinholdtsen "   powermonitor clear peakpower");
3789c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3790c18ec02fSPetter Reinholdtsen "      Reset peak power reading");
3791c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3792c18ec02fSPetter Reinholdtsen "");
3793c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3794c18ec02fSPetter Reinholdtsen "   powermonitor powerconsumption");
3795c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3796c18ec02fSPetter Reinholdtsen "      Displays power consumption in <watt|btuphr>");
3797c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3798c18ec02fSPetter Reinholdtsen "");
3799c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3800c18ec02fSPetter Reinholdtsen "   powermonitor powerconsumptionhistory <watt|btuphr>");
3801c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3802c18ec02fSPetter Reinholdtsen "      Displays power consumption history ");
3803c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3804c18ec02fSPetter Reinholdtsen "");
3805c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3806c18ec02fSPetter Reinholdtsen "   powermonitor getpowerbudget");
3807c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3808c18ec02fSPetter Reinholdtsen "      Displays power cap in <watt|btuphr>");
3809c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3810c18ec02fSPetter Reinholdtsen "");
3811c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3812c18ec02fSPetter Reinholdtsen "   powermonitor setpowerbudget <val><watt|btuphr|percent>");
3813c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3814c18ec02fSPetter Reinholdtsen "      Allows user to set the  power cap in <watt|BTU/hr|percentage>");
3815c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3816c18ec02fSPetter Reinholdtsen "");
3817c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3818c18ec02fSPetter Reinholdtsen "   powermonitor enablepowercap ");
3819c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3820c18ec02fSPetter Reinholdtsen "      To enable set power cap");
3821c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3822c18ec02fSPetter Reinholdtsen "");
3823c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3824c18ec02fSPetter Reinholdtsen "   powermonitor disablepowercap ");
3825c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3826c18ec02fSPetter Reinholdtsen "      To disable set power cap");
3827c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
3828c18ec02fSPetter Reinholdtsen "");
3829c18ec02fSPetter Reinholdtsen }
3830c18ec02fSPetter Reinholdtsen /*
3831c18ec02fSPetter Reinholdtsen  * Function Name:	   ipmi_delloem_vFlash_main
3832c18ec02fSPetter Reinholdtsen  *
3833c18ec02fSPetter Reinholdtsen  * Description:		   This function processes the delloem vFlash command
3834c18ec02fSPetter Reinholdtsen  * Input:			   intf    - ipmi interface
3835c18ec02fSPetter Reinholdtsen  *					   argc    - no of arguments
3836c18ec02fSPetter Reinholdtsen  *					   argv    - argument string array
3837c18ec02fSPetter Reinholdtsen  * Output:
3838c18ec02fSPetter Reinholdtsen  *
3839c18ec02fSPetter Reinholdtsen  * Return:			   return code	   0 - success
3840c18ec02fSPetter Reinholdtsen  *						  -1 - failure
3841c18ec02fSPetter Reinholdtsen  */
3842c18ec02fSPetter Reinholdtsen static int
ipmi_delloem_vFlash_main(struct ipmi_intf * intf,int argc,char ** argv)3843c18ec02fSPetter Reinholdtsen ipmi_delloem_vFlash_main(struct ipmi_intf * intf, int argc, char ** argv)
3844c18ec02fSPetter Reinholdtsen {
3845c18ec02fSPetter Reinholdtsen 	int rc = 0;
3846c18ec02fSPetter Reinholdtsen 	current_arg++;
3847c18ec02fSPetter Reinholdtsen 	rc = ipmi_delloem_vFlash_process(intf, current_arg, argv);
3848c18ec02fSPetter Reinholdtsen 	return rc;
3849c18ec02fSPetter Reinholdtsen }
3850c18ec02fSPetter Reinholdtsen /*
3851c18ec02fSPetter Reinholdtsen  * Function Name: 	get_vFlash_compcode_str
3852c18ec02fSPetter Reinholdtsen  *
3853c18ec02fSPetter Reinholdtsen  * Description: 	This function maps the vFlash completion code
3854c18ec02fSPetter Reinholdtsen  * 		to a string
3855c18ec02fSPetter Reinholdtsen  * Input : vFlash completion code and static array of codes vs strings
3856c18ec02fSPetter Reinholdtsen  * Output: -
3857c18ec02fSPetter Reinholdtsen  * Return: returns the mapped string
3858c18ec02fSPetter Reinholdtsen  */
3859c18ec02fSPetter Reinholdtsen const char *
get_vFlash_compcode_str(uint8_t vflashcompcode,const struct vFlashstr * vs)3860c18ec02fSPetter Reinholdtsen get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs)
3861c18ec02fSPetter Reinholdtsen {
3862c18ec02fSPetter Reinholdtsen 	static char un_str[32];
3863c18ec02fSPetter Reinholdtsen 	int i;
3864c18ec02fSPetter Reinholdtsen 	for (i = 0; vs[i].str != NULL; i++) {
3865c18ec02fSPetter Reinholdtsen 		if (vs[i].val == vflashcompcode)
3866c18ec02fSPetter Reinholdtsen 			return vs[i].str;
3867c18ec02fSPetter Reinholdtsen 	}
3868c18ec02fSPetter Reinholdtsen 	memset(un_str, 0, 32);
3869c18ec02fSPetter Reinholdtsen 	snprintf(un_str, 32, "Unknown (0x%02X)", vflashcompcode);
3870c18ec02fSPetter Reinholdtsen 	return un_str;
3871c18ec02fSPetter Reinholdtsen }
3872c18ec02fSPetter Reinholdtsen /*
3873c18ec02fSPetter Reinholdtsen  * Function Name: 	ipmi_get_sd_card_info
3874c18ec02fSPetter Reinholdtsen  *
3875c18ec02fSPetter Reinholdtsen  * Description: This function prints the vFlash Extended SD card info
3876c18ec02fSPetter Reinholdtsen  * Input : ipmi interface
3877c18ec02fSPetter Reinholdtsen  * Output: prints the sd card extended info
3878c18ec02fSPetter Reinholdtsen  * Return: 0 - success -1 - failure
3879c18ec02fSPetter Reinholdtsen  */
3880c18ec02fSPetter Reinholdtsen static int
ipmi_get_sd_card_info(struct ipmi_intf * intf)3881c18ec02fSPetter Reinholdtsen ipmi_get_sd_card_info(struct ipmi_intf * intf) {
3882c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
3883c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
3884c18ec02fSPetter Reinholdtsen 	uint8_t msg_data[2];
3885c18ec02fSPetter Reinholdtsen 	uint8_t input_length=0;
3886c18ec02fSPetter Reinholdtsen 	uint8_t cardstatus=0x00;
3887c18ec02fSPetter Reinholdtsen 	IPMI_DELL_SDCARD_INFO * sdcardinfoblock;
3888c18ec02fSPetter Reinholdtsen 
3889c18ec02fSPetter Reinholdtsen 	input_length = 2;
3890c18ec02fSPetter Reinholdtsen 	msg_data[0] = msg_data[1] = 0x00;
3891c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
3892c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
3893c18ec02fSPetter Reinholdtsen 	req.msg.cmd = IPMI_GET_EXT_SD_CARD_INFO;
3894c18ec02fSPetter Reinholdtsen 	req.msg.data = msg_data;
3895c18ec02fSPetter Reinholdtsen 	req.msg.data_len = input_length;
3896c18ec02fSPetter Reinholdtsen 
3897c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
3898c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
3899c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting SD Card Extended Information");
3900c18ec02fSPetter Reinholdtsen 		return -1;
3901c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode > 0) {
3902c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting SD Card Extended Information (%s)",
3903c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
3904c18ec02fSPetter Reinholdtsen 		return -1;
3905c18ec02fSPetter Reinholdtsen 	}
3906c18ec02fSPetter Reinholdtsen 
3907c18ec02fSPetter Reinholdtsen 	sdcardinfoblock = (IPMI_DELL_SDCARD_INFO *) (void *) rsp->data;
3908c18ec02fSPetter Reinholdtsen 
3909859e8a45SZdenek Styblik 	if ((iDRAC_FLAG_12_13)
3910c18ec02fSPetter Reinholdtsen 			&& (sdcardinfoblock->vflashcompcode == VFL_NOT_LICENSED)) {
3911c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3912c18ec02fSPetter Reinholdtsen 				"FM001 : A required license is missing or expired");
3913c18ec02fSPetter Reinholdtsen 		return -1;
3914c18ec02fSPetter Reinholdtsen 	} else if (sdcardinfoblock->vflashcompcode != 0x00) {
3915c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error in getting SD Card Extended Information (%s)",
3916c18ec02fSPetter Reinholdtsen 				get_vFlash_compcode_str(sdcardinfoblock->vflashcompcode,
3917c18ec02fSPetter Reinholdtsen 					vFlash_completion_code_vals));
3918c18ec02fSPetter Reinholdtsen 		return -1;
3919c18ec02fSPetter Reinholdtsen 	}
3920c18ec02fSPetter Reinholdtsen 
3921c18ec02fSPetter Reinholdtsen 	if (!(sdcardinfoblock->sdcardstatus & 0x04)) {
3922c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3923c18ec02fSPetter Reinholdtsen 				"vFlash SD card is unavailable, please insert the card of");
3924c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3925c18ec02fSPetter Reinholdtsen 				"size 256MB or greater");
3926c18ec02fSPetter Reinholdtsen 		return (-1);
3927c18ec02fSPetter Reinholdtsen 	}
3928c18ec02fSPetter Reinholdtsen 
3929c18ec02fSPetter Reinholdtsen 	printf("vFlash SD Card Properties\n");
3930c18ec02fSPetter Reinholdtsen 	printf("SD Card size       : %8dMB\n", sdcardinfoblock->sdcardsize);
3931c18ec02fSPetter Reinholdtsen 	printf("Available size     : %8dMB\n", sdcardinfoblock->sdcardavailsize);
3932c18ec02fSPetter Reinholdtsen 	printf("Initialized        : %10s\n",
3933c18ec02fSPetter Reinholdtsen 			(sdcardinfoblock->sdcardstatus & 0x80) ? "Yes" : "No");
3934c18ec02fSPetter Reinholdtsen 	printf("Licensed           : %10s\n",
3935c18ec02fSPetter Reinholdtsen 			(sdcardinfoblock->sdcardstatus & 0x40) ? "Yes" : "No");
3936c18ec02fSPetter Reinholdtsen 	printf("Attached           : %10s\n",
3937c18ec02fSPetter Reinholdtsen 			(sdcardinfoblock->sdcardstatus & 0x20) ? "Yes" : "No");
3938c18ec02fSPetter Reinholdtsen 	printf("Enabled            : %10s\n",
3939c18ec02fSPetter Reinholdtsen 			(sdcardinfoblock->sdcardstatus & 0x10) ? "Yes" : "No");
3940c18ec02fSPetter Reinholdtsen 	printf("Write Protected    : %10s\n",
3941c18ec02fSPetter Reinholdtsen 			(sdcardinfoblock->sdcardstatus & 0x08) ? "Yes" : "No");
3942c18ec02fSPetter Reinholdtsen 	cardstatus = sdcardinfoblock->sdcardstatus & 0x03;
3943c18ec02fSPetter Reinholdtsen 	printf("Health             : %10s\n",
3944c18ec02fSPetter Reinholdtsen 			((0x00 == cardstatus) ? "OK" : (
3945c18ec02fSPetter Reinholdtsen 				(cardstatus == 0x03) ? "Undefined" : (
3946c18ec02fSPetter Reinholdtsen 					(cardstatus == 0x02) ? "Critical" : "Warning"))));
3947c18ec02fSPetter Reinholdtsen 	printf("Bootable partition : %10d\n", sdcardinfoblock->bootpartion);
3948c18ec02fSPetter Reinholdtsen 	return 0;
3949c18ec02fSPetter Reinholdtsen }
3950c18ec02fSPetter Reinholdtsen /*
3951c18ec02fSPetter Reinholdtsen  * Function Name: 	ipmi_delloem_vFlash_process
3952c18ec02fSPetter Reinholdtsen  *
3953c18ec02fSPetter Reinholdtsen  * Description: 	This function processes the args for vFlash subcmd
3954c18ec02fSPetter Reinholdtsen  * Input : intf - ipmi interface, arg index, argv array
3955c18ec02fSPetter Reinholdtsen  * Output: prints help or error with help
3956c18ec02fSPetter Reinholdtsen  * Return: 0 - Success -1 - failure
3957c18ec02fSPetter Reinholdtsen  */
3958c18ec02fSPetter Reinholdtsen static int
ipmi_delloem_vFlash_process(struct ipmi_intf * intf,int current_arg,char ** argv)3959c18ec02fSPetter Reinholdtsen ipmi_delloem_vFlash_process(struct ipmi_intf * intf, int current_arg, char ** argv)
3960c18ec02fSPetter Reinholdtsen {
3961c18ec02fSPetter Reinholdtsen 	int rc;
3962c18ec02fSPetter Reinholdtsen 	if (strncmp(intf->name,"wmi\0",4) && strncmp(intf->name, "open\0",5)) {
3963c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR,
3964c18ec02fSPetter Reinholdtsen 				"vFlash support is enabled only for wmi and open interface.");
3965c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Its not enabled for lan and lanplus interface.");
3966c18ec02fSPetter Reinholdtsen 		return -1;
3967c18ec02fSPetter Reinholdtsen 	}
3968c18ec02fSPetter Reinholdtsen 
3969c18ec02fSPetter Reinholdtsen 	if (argv[current_arg] == NULL || strcmp(argv[current_arg], "help") == 0) {
3970c18ec02fSPetter Reinholdtsen 		ipmi_vFlash_usage();
3971c18ec02fSPetter Reinholdtsen 		return 0;
3972c18ec02fSPetter Reinholdtsen 	}
3973c18ec02fSPetter Reinholdtsen 	ipmi_idracvalidator_command(intf);
3974c18ec02fSPetter Reinholdtsen 	if (!strncmp(argv[current_arg], "info\0", 5)) {
3975c18ec02fSPetter Reinholdtsen 		current_arg++;
3976c18ec02fSPetter Reinholdtsen 		if (argv[current_arg] == NULL) {
3977c18ec02fSPetter Reinholdtsen 			ipmi_vFlash_usage();
3978c18ec02fSPetter Reinholdtsen 			return -1;
3979c18ec02fSPetter Reinholdtsen 		} else if (strncmp(argv[current_arg], "Card\0", 5) == 0) {
3980c18ec02fSPetter Reinholdtsen 			current_arg++;
3981c18ec02fSPetter Reinholdtsen 			if (argv[current_arg] != NULL) {
3982c18ec02fSPetter Reinholdtsen 				ipmi_vFlash_usage();
3983c18ec02fSPetter Reinholdtsen 				return -1;
3984c18ec02fSPetter Reinholdtsen 			}
3985c18ec02fSPetter Reinholdtsen 			rc = ipmi_get_sd_card_info(intf);
3986c18ec02fSPetter Reinholdtsen 			return rc;
3987c18ec02fSPetter Reinholdtsen 		} else {
3988c18ec02fSPetter Reinholdtsen 			/* TBD: many sub commands are present */
3989c18ec02fSPetter Reinholdtsen 			ipmi_vFlash_usage();
3990c18ec02fSPetter Reinholdtsen 			return -1;
3991c18ec02fSPetter Reinholdtsen 		}
3992c18ec02fSPetter Reinholdtsen 	} else {
3993c18ec02fSPetter Reinholdtsen 		/* TBD other vFlash subcommands */
3994c18ec02fSPetter Reinholdtsen 		ipmi_vFlash_usage();
3995c18ec02fSPetter Reinholdtsen 		return -1;
3996c18ec02fSPetter Reinholdtsen 	}
3997c18ec02fSPetter Reinholdtsen }
3998c18ec02fSPetter Reinholdtsen /*
3999c18ec02fSPetter Reinholdtsen  * Function Name: 	ipmi_vFlash_usage
4000c18ec02fSPetter Reinholdtsen  *
4001c18ec02fSPetter Reinholdtsen  * Description: 	This function displays the usage for using vFlash
4002c18ec02fSPetter Reinholdtsen  * Input : void
4003c18ec02fSPetter Reinholdtsen  * Output: prints help
4004c18ec02fSPetter Reinholdtsen  * Return: void
4005c18ec02fSPetter Reinholdtsen  */
4006c18ec02fSPetter Reinholdtsen static void
ipmi_vFlash_usage(void)4007c18ec02fSPetter Reinholdtsen ipmi_vFlash_usage(void)
4008c18ec02fSPetter Reinholdtsen {
4009c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4010c18ec02fSPetter Reinholdtsen "");
4011c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4012c18ec02fSPetter Reinholdtsen "   vFlash info Card");
4013c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4014c18ec02fSPetter Reinholdtsen "      Shows Extended SD Card information");
4015c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4016c18ec02fSPetter Reinholdtsen "");
4017c18ec02fSPetter Reinholdtsen }
4018c18ec02fSPetter Reinholdtsen /*
4019c18ec02fSPetter Reinholdtsen  * Function Name: ipmi_setled_usage
4020c18ec02fSPetter Reinholdtsen  *
4021c18ec02fSPetter Reinholdtsen  * Description:  This function prints help message for setled command
4022c18ec02fSPetter Reinholdtsen  * Input:
4023c18ec02fSPetter Reinholdtsen  * Output:
4024c18ec02fSPetter Reinholdtsen  *
4025c18ec02fSPetter Reinholdtsen  * Return:
4026c18ec02fSPetter Reinholdtsen  */
4027c18ec02fSPetter Reinholdtsen static void
ipmi_setled_usage(void)4028c18ec02fSPetter Reinholdtsen ipmi_setled_usage(void)
4029c18ec02fSPetter Reinholdtsen {
4030c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4031c18ec02fSPetter Reinholdtsen "");
4032c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4033c18ec02fSPetter Reinholdtsen "   setled <b:d.f> <state..>");
4034c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4035c18ec02fSPetter Reinholdtsen "      Set backplane LED state");
4036c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4037c18ec02fSPetter Reinholdtsen "      b:d.f = PCI Bus:Device.Function of drive (lspci format)");
4038c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4039c18ec02fSPetter Reinholdtsen "      state = present|online|hotspare|identify|rebuilding|");
4040c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4041c18ec02fSPetter Reinholdtsen "              fault|predict|critical|failed");
4042c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE,
4043c18ec02fSPetter Reinholdtsen "");
4044c18ec02fSPetter Reinholdtsen }
4045c18ec02fSPetter Reinholdtsen 
4046c18ec02fSPetter Reinholdtsen static int
IsSetLEDSupported(void)4047c18ec02fSPetter Reinholdtsen IsSetLEDSupported(void)
4048c18ec02fSPetter Reinholdtsen {
4049c18ec02fSPetter Reinholdtsen 	return SetLEDSupported;
4050c18ec02fSPetter Reinholdtsen }
4051c18ec02fSPetter Reinholdtsen 
4052c18ec02fSPetter Reinholdtsen static void
CheckSetLEDSupport(struct ipmi_intf * intf)4053c18ec02fSPetter Reinholdtsen CheckSetLEDSupport(struct ipmi_intf * intf)
4054c18ec02fSPetter Reinholdtsen {
4055c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = NULL;
4056c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req = {0};
4057c18ec02fSPetter Reinholdtsen 	uint8_t data[10];
4058c18ec02fSPetter Reinholdtsen 
4059c18ec02fSPetter Reinholdtsen 	SetLEDSupported = 0;
4060c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
4061c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
4062c18ec02fSPetter Reinholdtsen 	req.msg.cmd = 0xD5; /* Storage */
4063c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 10;
4064c18ec02fSPetter Reinholdtsen 	req.msg.data = data;
4065c18ec02fSPetter Reinholdtsen 
4066c18ec02fSPetter Reinholdtsen 	memset(data, 0, sizeof(data));
4067c18ec02fSPetter Reinholdtsen 	data[0] = 0x01; /* get */
4068c18ec02fSPetter Reinholdtsen 	data[1] = 0x00; /* subcmd:get firmware version */
4069c18ec02fSPetter Reinholdtsen 	data[2] = 0x08; /* length lsb */
4070c18ec02fSPetter Reinholdtsen 	data[3] = 0x00; /* length msb */
4071c18ec02fSPetter Reinholdtsen 	data[4] = 0x00; /* offset lsb */
4072c18ec02fSPetter Reinholdtsen 	data[5] = 0x00; /* offset msb */
4073c18ec02fSPetter Reinholdtsen 	data[6] = 0x00; /* bay id */
4074c18ec02fSPetter Reinholdtsen 	data[7] = 0x00;
4075c18ec02fSPetter Reinholdtsen 	data[8] = 0x00;
4076c18ec02fSPetter Reinholdtsen 	data[9] = 0x00;
4077c18ec02fSPetter Reinholdtsen 
4078c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
4079c18ec02fSPetter Reinholdtsen 	if (rsp == NULL || rsp->ccode != 0) {
4080c18ec02fSPetter Reinholdtsen 		return;
4081c18ec02fSPetter Reinholdtsen 	}
4082c18ec02fSPetter Reinholdtsen 	SetLEDSupported = 1;
4083c18ec02fSPetter Reinholdtsen }
4084c18ec02fSPetter Reinholdtsen /*
4085c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_getdrivemap
4086c18ec02fSPetter Reinholdtsen  *
4087c18ec02fSPetter Reinholdtsen  * Description:      This function returns mapping of BDF to Bay:Slot
4088c18ec02fSPetter Reinholdtsen  * Input:            intf         - ipmi interface
4089c18ec02fSPetter Reinholdtsen  *		    bdf	 	 - PCI Address of drive
4090c18ec02fSPetter Reinholdtsen  *		    *bay	 - Returns bay ID
4091c18ec02fSPetter Reinholdtsen  *		    *slot	 - Returns slot ID
4092c18ec02fSPetter Reinholdtsen  * Output:
4093c18ec02fSPetter Reinholdtsen  *
4094c18ec02fSPetter Reinholdtsen  * Return:
4095c18ec02fSPetter Reinholdtsen  */
4096c18ec02fSPetter Reinholdtsen static int
ipmi_getdrivemap(struct ipmi_intf * intf,int b,int d,int f,int * bay,int * slot)4097c18ec02fSPetter Reinholdtsen ipmi_getdrivemap(struct ipmi_intf * intf, int b, int d, int f, int *bay,
4098c18ec02fSPetter Reinholdtsen 		int *slot)
4099c18ec02fSPetter Reinholdtsen {
4100c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = NULL;
4101c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req = {0};
4102c18ec02fSPetter Reinholdtsen 	uint8_t data[8];
4103c18ec02fSPetter Reinholdtsen 	/* Get mapping of BDF to bay:slot */
4104c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
4105c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
4106c18ec02fSPetter Reinholdtsen 	req.msg.cmd = 0xD5;
4107c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 8;
4108c18ec02fSPetter Reinholdtsen 	req.msg.data = data;
4109c18ec02fSPetter Reinholdtsen 
4110c18ec02fSPetter Reinholdtsen 	memset(data, 0, sizeof(data));
4111c18ec02fSPetter Reinholdtsen 	data[0] = 0x01; /* get */
4112c18ec02fSPetter Reinholdtsen 	data[1] = 0x07; /* storage map */
4113c18ec02fSPetter Reinholdtsen 	data[2] = 0x06; /* length lsb */
4114c18ec02fSPetter Reinholdtsen 	data[3] = 0x00; /* length msb */
4115c18ec02fSPetter Reinholdtsen 	data[4] = 0x00; /* offset lsb */
4116c18ec02fSPetter Reinholdtsen 	data[5] = 0x00; /* offset msb */
4117c18ec02fSPetter Reinholdtsen 	data[6] = b; /* bus */
4118c18ec02fSPetter Reinholdtsen 	data[7] = (d << 3) + f; /* devfn */
4119c18ec02fSPetter Reinholdtsen 
4120c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
4121c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
4122c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error issuing getdrivemap command.");
4123c18ec02fSPetter Reinholdtsen 		return -1;
4124c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode != 0) {
4125c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error issuing getdrivemap command: %s",
4126c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
4127c18ec02fSPetter Reinholdtsen 		return -1;
4128c18ec02fSPetter Reinholdtsen 	}
4129c18ec02fSPetter Reinholdtsen 	*bay = rsp->data[7];
4130c18ec02fSPetter Reinholdtsen 	*slot = rsp->data[8];
4131c18ec02fSPetter Reinholdtsen 	if (*bay == 0xFF || *slot == 0xFF) {
4132c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error could not get drive bay:slot mapping");
4133c18ec02fSPetter Reinholdtsen 		return -1;
4134c18ec02fSPetter Reinholdtsen 	}
4135c18ec02fSPetter Reinholdtsen 	return 0;
4136c18ec02fSPetter Reinholdtsen }
4137c18ec02fSPetter Reinholdtsen /*
4138c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_setled_state
4139c18ec02fSPetter Reinholdtsen  *
4140c18ec02fSPetter Reinholdtsen  * Description:      This function updates the LED on the backplane
4141c18ec02fSPetter Reinholdtsen  * Input:            intf         - ipmi interface
4142c18ec02fSPetter Reinholdtsen  *		    bdf	 	 - PCI Address of drive
4143c18ec02fSPetter Reinholdtsen  *		    state	 - SES Flags state of drive
4144c18ec02fSPetter Reinholdtsen  * Output:
4145c18ec02fSPetter Reinholdtsen  *
4146c18ec02fSPetter Reinholdtsen  * Return:
4147c18ec02fSPetter Reinholdtsen  */
4148c18ec02fSPetter Reinholdtsen static int
ipmi_setled_state(struct ipmi_intf * intf,int bayId,int slotId,int state)4149c18ec02fSPetter Reinholdtsen ipmi_setled_state(struct ipmi_intf * intf, int bayId, int slotId, int state)
4150c18ec02fSPetter Reinholdtsen {
4151c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp = NULL;
4152c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req = {0};
4153c18ec02fSPetter Reinholdtsen 	uint8_t data[20];
4154c18ec02fSPetter Reinholdtsen 	/* Issue Drive Status Update to bay:slot */
4155c18ec02fSPetter Reinholdtsen 	req.msg.netfn = DELL_OEM_NETFN;
4156c18ec02fSPetter Reinholdtsen 	req.msg.lun = 0;
4157c18ec02fSPetter Reinholdtsen 	req.msg.cmd = 0xD5;
4158c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 20;
4159c18ec02fSPetter Reinholdtsen 	req.msg.data = data;
4160c18ec02fSPetter Reinholdtsen 
4161c18ec02fSPetter Reinholdtsen 	memset(data, 0, sizeof(data));
4162c18ec02fSPetter Reinholdtsen 	data[0] = 0x00; /* set */
4163c18ec02fSPetter Reinholdtsen 	data[1] = 0x04; /* set drive status */
4164c18ec02fSPetter Reinholdtsen 	data[2] = 0x0e; /* length lsb */
4165c18ec02fSPetter Reinholdtsen 	data[3] = 0x00; /* length msb */
4166c18ec02fSPetter Reinholdtsen 	data[4] = 0x00; /* offset lsb */
4167c18ec02fSPetter Reinholdtsen 	data[5] = 0x00; /* offset msb */
4168c18ec02fSPetter Reinholdtsen 	data[6] = 0x0e; /* length lsb */
4169c18ec02fSPetter Reinholdtsen 	data[7] = 0x00; /* length msb */
4170c18ec02fSPetter Reinholdtsen 	data[8] = bayId; /* bayid */
4171c18ec02fSPetter Reinholdtsen 	data[9] = slotId; /* slotid */
4172c18ec02fSPetter Reinholdtsen 	data[10] = state & 0xff; /* state LSB */
4173c18ec02fSPetter Reinholdtsen 	data[11] = state >> 8; /* state MSB; */
4174c18ec02fSPetter Reinholdtsen 
4175c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
4176c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
4177c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error issuing setled command.");
4178c18ec02fSPetter Reinholdtsen 		return -1;
4179c18ec02fSPetter Reinholdtsen 	} else if (rsp->ccode != 0) {
4180c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Error issuing setled command: %s",
4181c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
4182c18ec02fSPetter Reinholdtsen 		return -1;
4183c18ec02fSPetter Reinholdtsen 	}
4184c18ec02fSPetter Reinholdtsen 	return 0;
4185c18ec02fSPetter Reinholdtsen }
4186c18ec02fSPetter Reinholdtsen /*
4187c18ec02fSPetter Reinholdtsen  * Function Name:    ipmi_getsesmask
4188c18ec02fSPetter Reinholdtsen  *
4189c18ec02fSPetter Reinholdtsen  * Description:      This function calculates bits in SES drive update
4190c18ec02fSPetter Reinholdtsen  * Return:           Mask set with bits for SES backplane update
4191c18ec02fSPetter Reinholdtsen  */
4192c18ec02fSPetter Reinholdtsen static int
ipmi_getsesmask(int argc,char ** argv)4193c18ec02fSPetter Reinholdtsen ipmi_getsesmask(int argc, char **argv)
4194c18ec02fSPetter Reinholdtsen {
4195c18ec02fSPetter Reinholdtsen 	int mask = 0;
4196c18ec02fSPetter Reinholdtsen 	while (current_arg < argc) {
4197c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "present"))
4198c18ec02fSPetter Reinholdtsen 			mask |= (1L << 0);
4199c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "online"))
4200c18ec02fSPetter Reinholdtsen 			mask |= (1L << 1);
4201c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "hotspare"))
4202c18ec02fSPetter Reinholdtsen 			mask |= (1L << 2);
4203c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "identify"))
4204c18ec02fSPetter Reinholdtsen 			mask |= (1L << 3);
4205c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "rebuilding"))
4206c18ec02fSPetter Reinholdtsen 			mask |= (1L << 4);
4207c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "fault"))
4208c18ec02fSPetter Reinholdtsen 			mask |= (1L << 5);
4209c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "predict"))
4210c18ec02fSPetter Reinholdtsen 			mask |= (1L << 6);
4211c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "critical"))
4212c18ec02fSPetter Reinholdtsen 			mask |= (1L << 9);
4213c18ec02fSPetter Reinholdtsen 		if (!strcmp(argv[current_arg], "failed"))
4214c18ec02fSPetter Reinholdtsen 			mask |= (1L << 10);
4215c18ec02fSPetter Reinholdtsen 		current_arg++;
4216c18ec02fSPetter Reinholdtsen 	}
4217c18ec02fSPetter Reinholdtsen 	return mask;
4218c18ec02fSPetter Reinholdtsen }
4219c18ec02fSPetter Reinholdtsen /*
4220c18ec02fSPetter Reinholdtsen  * Function Name:       ipmi_delloem_setled_main
4221c18ec02fSPetter Reinholdtsen  *
4222c18ec02fSPetter Reinholdtsen  * Description:         This function processes the delloem setled command
4223c18ec02fSPetter Reinholdtsen  * Input:               intf    - ipmi interface
4224c18ec02fSPetter Reinholdtsen  *                       argc    - no of arguments
4225c18ec02fSPetter Reinholdtsen  *                       argv    - argument string array
4226c18ec02fSPetter Reinholdtsen  * Output:
4227c18ec02fSPetter Reinholdtsen  *
4228c18ec02fSPetter Reinholdtsen  * Return:              return code     0 - success
4229c18ec02fSPetter Reinholdtsen  *                         -1 - failure
4230c18ec02fSPetter Reinholdtsen  */
4231c18ec02fSPetter Reinholdtsen static int
ipmi_delloem_setled_main(struct ipmi_intf * intf,int argc,char ** argv)4232c18ec02fSPetter Reinholdtsen ipmi_delloem_setled_main(struct ipmi_intf * intf, int argc, char ** argv)
4233c18ec02fSPetter Reinholdtsen {
4234c18ec02fSPetter Reinholdtsen 	int b,d,f, mask;
4235c18ec02fSPetter Reinholdtsen 	int bayId, slotId;
4236c18ec02fSPetter Reinholdtsen 	bayId = 0xFF;
4237c18ec02fSPetter Reinholdtsen 	slotId = 0xFF;
4238c18ec02fSPetter Reinholdtsen 	current_arg++;
4239c18ec02fSPetter Reinholdtsen 	if (argc < current_arg) {
4240c18ec02fSPetter Reinholdtsen 		usage();
4241c18ec02fSPetter Reinholdtsen 		return -1;
4242c18ec02fSPetter Reinholdtsen 	}
4243c18ec02fSPetter Reinholdtsen 	/* ipmitool delloem setled info*/
4244c18ec02fSPetter Reinholdtsen 	if (argc == 1 || strcmp(argv[current_arg], "help") == 0) {
4245c18ec02fSPetter Reinholdtsen 		ipmi_setled_usage();
4246c18ec02fSPetter Reinholdtsen 		return 0;
4247c18ec02fSPetter Reinholdtsen 	}
4248c18ec02fSPetter Reinholdtsen 	CheckSetLEDSupport(intf);
4249c18ec02fSPetter Reinholdtsen 	if (!IsSetLEDSupported()) {
4250c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "'setled' is not supported on this system.");
4251c18ec02fSPetter Reinholdtsen 		return -1;
4252c18ec02fSPetter Reinholdtsen 	} else if (sscanf(argv[current_arg], "%*x:%x:%x.%x", &b,&d,&f) == 3) {
4253c18ec02fSPetter Reinholdtsen 		/* We have bus/dev/function of drive */
4254c18ec02fSPetter Reinholdtsen 		current_arg++;
4255c18ec02fSPetter Reinholdtsen 		ipmi_getdrivemap (intf, b, d, f, &bayId, &slotId);
4256c18ec02fSPetter Reinholdtsen 	} else if (sscanf(argv[current_arg], "%x:%x.%x", &b,&d,&f) == 3) {
4257c18ec02fSPetter Reinholdtsen 		/* We have bus/dev/function of drive */
4258c18ec02fSPetter Reinholdtsen 		current_arg++;
4259c18ec02fSPetter Reinholdtsen 	} else {
4260c18ec02fSPetter Reinholdtsen 		ipmi_setled_usage();
4261c18ec02fSPetter Reinholdtsen 		return -1;
4262c18ec02fSPetter Reinholdtsen 	}
4263c18ec02fSPetter Reinholdtsen 	/* Get mask of SES flags */
4264c18ec02fSPetter Reinholdtsen 	mask = ipmi_getsesmask(argc, argv);
4265c18ec02fSPetter Reinholdtsen 	/* Get drive mapping */
4266c18ec02fSPetter Reinholdtsen 	if (ipmi_getdrivemap (intf, b, d, f, &bayId, &slotId)) {
4267c18ec02fSPetter Reinholdtsen 		return -1;
4268c18ec02fSPetter Reinholdtsen 	}
4269c18ec02fSPetter Reinholdtsen 	/* Set drive LEDs */
4270c18ec02fSPetter Reinholdtsen 	return ipmi_setled_state (intf, bayId, slotId, mask);
4271c18ec02fSPetter Reinholdtsen }
4272