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