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