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