1 /* 2 * Copyright (c) 2008, Dell Inc 3 * All rights reserved. 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * - Redistributions of source code must retain the above copyright notice, 7 * this list of conditions and the following disclaimer. 8 * 9 * - Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * - Neither the name of Dell Inc nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 /* 28 * Thursday Oct 7 17:30:12 2009 29 * <deepaganesh_paulraj@dell.com> 30 * 31 * This code implements a dell OEM proprietary commands. 32 * This Code is edited and Implemented the License feature for Delloem 33 * Author Harsha S <Harsha_S1@dell.com> 34 */ 35 #include <stdlib.h> 36 #include <stdio.h> 37 #include <string.h> 38 #include <sys/types.h> 39 #include <sys/socket.h> 40 #include <netinet/in.h> 41 #include <arpa/inet.h> 42 #include <errno.h> 43 #include <unistd.h> 44 #include <signal.h> 45 #include <ctype.h> 46 #include <limits.h> 47 #include <time.h> 48 49 #include <ipmitool/ipmi.h> 50 #include <ipmitool/ipmi_intf.h> 51 #include <ipmitool/helper.h> 52 #include <ipmitool/log.h> 53 #include <ipmitool/ipmi_sel.h> 54 #include <ipmitool/ipmi_delloem.h> 55 #include <ipmitool/ipmi_fru.h> 56 #include <ipmitool/ipmi_sdr.h> 57 #include <ipmitool/ipmi_mc.h> 58 #include <ipmitool/ipmi_sensor.h> 59 #include <ipmitool/ipmi_sel.h> 60 #include <ipmitool/bswap.h> 61 #include <ipmitool/ipmi_sdr.h> 62 #include <ipmitool/ipmi_entity.h> 63 #include <ipmitool/ipmi_fru.h> 64 #include <ipmitool/ipmi_sensor.h> 65 66 #define DELL_OEM_NETFN (uint8_t)(0x30) 67 #define GET_IDRAC_VIRTUAL_MAC (uint8_t)(0xC9) 68 /* 11g Support Macros */ 69 #define INVALID (-1) 70 #define SHARED 0 71 #define SHARED_WITH_FAILOVER_LOM2 1 72 #define DEDICATED 2 73 #define SHARED_WITH_FAILOVER_ALL_LOMS 3 74 /* 11g Support Macros */ 75 #define SHARED 0 76 #define SHARED_WITH_FAILOVER_LOM2 1 77 #define DEDICATED 2 78 #define SHARED_WITH_FAILOVER_ALL_LOMS 3 79 /* 12g Support Strings for nic selection */ 80 #define INVAILD_FAILOVER_MODE -2 81 #define INVAILD_FAILOVER_MODE_SETTINGS -3 82 #define INVAILD_SHARED_MODE -4 83 84 #define INVAILD_FAILOVER_MODE_STRING "ERROR: Cannot set shared with failover lom same as current shared lom." 85 #define INVAILD_FAILOVER_MODE_SET "ERROR: Cannot set shared with failover loms when NIC is set to dedicated Mode." 86 #define INVAILD_SHARED_MODE_SET_STRING "ERROR: Cannot set shared Mode for Blades." 87 88 char AciveLOM_String [6] [10] = { 89 "None", 90 "LOM1", 91 "LOM2", 92 "LOM3", 93 "LOM4", 94 "dedicated" 95 }; 96 /* 11g Support Strings for nic selection */ 97 char NIC_Selection_Mode_String [4] [50] = { 98 "shared", 99 "shared with failover lom2", 100 "dedicated", 101 "shared with Failover all loms" 102 }; 103 104 char NIC_Selection_Mode_String_12g[] [50] = { 105 "dedicated", 106 "shared with lom1", 107 "shared with lom2", 108 "shared with lom3", 109 "shared with lom4", 110 "shared with failover lom1", 111 "shared with failover lom2", 112 "shared with failover lom3", 113 "shared with failover lom4", 114 "shared with failover all loms" 115 }; 116 117 const struct vFlashstr vFlash_completion_code_vals[] = { 118 {0x00, "SUCCESS"}, 119 {0x01, "NO_SD_CARD"}, 120 {0x63, "UNKNOWN_ERROR"}, 121 {0x00, NULL} 122 }; 123 124 static int current_arg =0; 125 uint8_t iDRAC_FLAG=0; 126 127 /* 128 * new flags for 129 * 11G || 12G || 13G -> _ALL 130 * 12G || 13G -> _12_13 131 * 132 */ 133 uint8_t iDRAC_FLAG_ALL=0; 134 uint8_t iDRAC_FLAG_12_13=0; 135 136 LCD_MODE lcd_mode; 137 static uint8_t LcdSupported=0; 138 static uint8_t SetLEDSupported=0; 139 140 volatile uint8_t IMC_Type = IMC_IDRAC_10G; 141 142 POWER_HEADROOM powerheadroom; 143 144 uint8_t PowercapSetable_flag=0; 145 uint8_t PowercapstatusFlag=0; 146 147 static void usage(void); 148 /* LCD Function prototypes */ 149 static int ipmi_delloem_lcd_main(struct ipmi_intf *intf, int argc, 150 char **argv); 151 int ipmi_lcd_get_platform_model_name(struct ipmi_intf *intf, char *lcdstring, 152 uint8_t max_length, uint8_t field_type); 153 static int ipmi_idracvalidator_command(struct ipmi_intf *intf); 154 static int ipmi_lcd_get_configure_command_wh(struct ipmi_intf *intf); 155 static int ipmi_lcd_get_configure_command(struct ipmi_intf *intf, 156 uint8_t *command); 157 static int ipmi_lcd_set_configure_command(struct ipmi_intf *intf, int command); 158 static int ipmi_lcd_set_configure_command_wh(struct ipmi_intf *intf, uint32_t mode, 159 uint16_t lcdquallifier,uint8_t errordisp); 160 static int ipmi_lcd_get_single_line_text(struct ipmi_intf *intf, 161 char *lcdstring, uint8_t max_length); 162 static int ipmi_lcd_get_info_wh(struct ipmi_intf *intf); 163 static int ipmi_lcd_get_info(struct ipmi_intf *intf); 164 static int ipmi_lcd_get_status_val(struct ipmi_intf *intf, 165 LCD_STATUS *lcdstatus); 166 static int IsLCDSupported(); 167 static void CheckLCDSupport(struct ipmi_intf *intf); 168 static void ipmi_lcd_status_print(LCD_STATUS lcdstatus); 169 static int ipmi_lcd_get_status(struct ipmi_intf *intf); 170 static int ipmi_lcd_set_kvm(struct ipmi_intf *intf, char status); 171 static int ipmi_lcd_set_lock(struct ipmi_intf *intf, char lock); 172 static int ipmi_lcd_set_single_line_text(struct ipmi_intf *intf, char *text); 173 static int ipmi_lcd_set_text(struct ipmi_intf *intf, char *text, 174 int line_number); 175 static int ipmi_lcd_configure_wh(struct ipmi_intf *intf, uint32_t mode, 176 uint16_t lcdquallifier, uint8_t errordisp, int8_t line_number, char *text); 177 static int ipmi_lcd_configure(struct ipmi_intf *intf, int command, 178 int8_t line_number, char *text); 179 static void ipmi_lcd_usage(void); 180 /* MAC Function prototypes */ 181 static int ipmi_delloem_mac_main(struct ipmi_intf *intf, int argc, char **argv); 182 static void InitEmbeddedNICMacAddressValues(); 183 static int ipmi_macinfo_drac_idrac_virtual_mac(struct ipmi_intf *intf, 184 uint8_t NicNum); 185 static int ipmi_macinfo_drac_idrac_mac(struct ipmi_intf *intf,uint8_t NicNum); 186 static int ipmi_macinfo_10g(struct ipmi_intf *intf, uint8_t NicNum); 187 static int ipmi_macinfo_11g(struct ipmi_intf *intf, uint8_t NicNum); 188 static int ipmi_macinfo(struct ipmi_intf *intf, uint8_t NicNum); 189 static void ipmi_mac_usage(void); 190 /* LAN Function prototypes */ 191 static int ipmi_delloem_lan_main(struct ipmi_intf *intf, int argc, char **argv); 192 static int IsLANSupported(); 193 static int get_nic_selection_mode(int current_arg, char **argv); 194 static int ipmi_lan_set_nic_selection(struct ipmi_intf *intf, 195 uint8_t nic_selection); 196 static int ipmi_lan_get_nic_selection(struct ipmi_intf *intf); 197 static int ipmi_lan_get_active_nic(struct ipmi_intf *intf); 198 static void ipmi_lan_usage(void); 199 static int ipmi_lan_set_nic_selection_12g(struct ipmi_intf *intf, 200 uint8_t *nic_selection); 201 /* Power monitor Function prototypes */ 202 static int ipmi_delloem_powermonitor_main(struct ipmi_intf *intf, int argc, 203 char **argv); 204 static void ipmi_time_to_str(time_t rawTime, char *strTime); 205 static int ipmi_get_sensor_reading(struct ipmi_intf *intf, 206 unsigned char sensorNumber, SensorReadingType *pSensorReadingData); 207 static int ipmi_get_power_capstatus_command(struct ipmi_intf *intf); 208 static int ipmi_set_power_capstatus_command(struct ipmi_intf *intf, 209 uint8_t val); 210 static int ipmi_powermgmt(struct ipmi_intf *intf); 211 static int ipmi_powermgmt_clear(struct ipmi_intf *intf, uint8_t clearValue); 212 static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt); 213 static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr); 214 static int ipmi_get_power_headroom_command(struct ipmi_intf *intf, uint8_t unit); 215 static int ipmi_get_power_consumption_data(struct ipmi_intf *intf, uint8_t unit); 216 static int ipmi_get_instan_power_consmpt_data(struct ipmi_intf *intf, 217 IPMI_INST_POWER_CONSUMPTION_DATA *instpowerconsumptiondata); 218 static void ipmi_print_get_instan_power_Amps_data( 219 IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata); 220 static int ipmi_print_get_power_consmpt_data(struct ipmi_intf *intf, 221 uint8_t unit); 222 static int ipmi_get_avgpower_consmpt_history(struct ipmi_intf *intf, 223 IPMI_AVGPOWER_CONSUMP_HISTORY *pavgpower); 224 static int ipmi_get_peakpower_consmpt_history(struct ipmi_intf *intf, 225 IPMI_POWER_CONSUMP_HISTORY *pstPeakpower); 226 static int ipmi_get_minpower_consmpt_history(struct ipmi_intf *intf, 227 IPMI_POWER_CONSUMP_HISTORY *pstMinpower); 228 static int ipmi_print_power_consmpt_history(struct ipmi_intf *intf, int unit); 229 static int ipmi_get_power_cap(struct ipmi_intf *intf, 230 IPMI_POWER_CAP *ipmipowercap); 231 static int ipmi_print_power_cap(struct ipmi_intf *intf, uint8_t unit); 232 static int ipmi_set_power_cap(struct ipmi_intf *intf, int unit, int val); 233 static void ipmi_powermonitor_usage(void); 234 /* vFlash Function prototypes */ 235 static int ipmi_delloem_vFlash_main(struct ipmi_intf *intf, int argc, 236 char **argv); 237 const char *get_vFlash_compcode_str(uint8_t vflashcompcode, 238 const struct vFlashstr *vs); 239 static int ipmi_get_sd_card_info(struct ipmi_intf *intf); 240 static int ipmi_delloem_vFlash_process(struct ipmi_intf *intf, int current_arg, 241 char **argv); 242 static void ipmi_vFlash_usage(void); 243 /* LED Function prototypes */ 244 static int ipmi_getsesmask(int, char **argv); 245 static void CheckSetLEDSupport(struct ipmi_intf *intf); 246 static int IsSetLEDSupported(void); 247 static void ipmi_setled_usage(void); 248 static int ipmi_delloem_setled_main(struct ipmi_intf *intf, int argc, 249 char **argv); 250 static int ipmi_setled_state(struct ipmi_intf *intf, int bayId, int slotId, 251 int state); 252 static int ipmi_getdrivemap(struct ipmi_intf *intf, int b, int d, int f, 253 int *bayId, int *slotId); 254 255 /* Function Name: ipmi_delloem_main 256 * 257 * Description: This function processes the delloem command 258 * Input: intf - ipmi interface 259 * argc - no of arguments 260 * argv - argument string array 261 * Output: 262 * 263 * Return: return code 0 - success 264 * -1 - failure 265 */ 266 int 267 ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv) 268 { 269 int rc = 0; 270 current_arg = 0; 271 if (argc == 0 || strncmp(argv[0], "help\0", 5) == 0) { 272 usage(); 273 return 0; 274 } 275 if (0 ==strncmp(argv[current_arg], "lcd\0", 4)) { 276 ipmi_delloem_lcd_main(intf,argc,argv); 277 } else if (strncmp(argv[current_arg], "mac\0", 4) == 0) { 278 /* mac address*/ 279 ipmi_delloem_mac_main(intf,argc,argv); 280 } else if (strncmp(argv[current_arg], "lan\0", 4) == 0) { 281 /* lan address*/ 282 ipmi_delloem_lan_main(intf,argc,argv); 283 } else if (strncmp(argv[current_arg], "setled\0", 7) == 0) { 284 /* SetLED support */ 285 ipmi_delloem_setled_main(intf,argc,argv); 286 } else if (strncmp(argv[current_arg], "powermonitor\0", 13) == 0) { 287 /*Powermanagement report processing*/ 288 ipmi_delloem_powermonitor_main(intf,argc,argv); 289 } else if (strncmp(argv[current_arg], "vFlash\0", 7) == 0) { 290 /* vFlash Support */ 291 ipmi_delloem_vFlash_main(intf,argc,argv); 292 } else { 293 usage(); 294 return -1; 295 } 296 return rc; 297 } 298 /* 299 * Function Name: usage 300 * 301 * Description: This function prints help message for delloem command 302 * Input: 303 * Output: 304 * 305 * Return: 306 * 307 */ 308 static void 309 usage(void) 310 { 311 lprintf(LOG_NOTICE, 312 ""); 313 lprintf(LOG_NOTICE, 314 "usage: delloem <command> [option...]"); 315 lprintf(LOG_NOTICE, 316 ""); 317 lprintf(LOG_NOTICE, 318 "commands:"); 319 lprintf(LOG_NOTICE, 320 " lcd"); 321 lprintf(LOG_NOTICE, 322 " mac"); 323 lprintf(LOG_NOTICE, 324 " lan"); 325 lprintf(LOG_NOTICE, 326 " setled"); 327 lprintf(LOG_NOTICE, 328 " powermonitor"); 329 lprintf(LOG_NOTICE, 330 " vFlash"); 331 lprintf(LOG_NOTICE, 332 ""); 333 lprintf(LOG_NOTICE, 334 "For help on individual commands type:"); 335 lprintf(LOG_NOTICE, 336 "delloem <command> help"); 337 } 338 /* 339 * Function Name: ipmi_delloem_lcd_main 340 * 341 * Description: This function processes the delloem lcd command 342 * Input: intf - ipmi interface 343 * argc - no of arguments 344 * argv - argument string array 345 * Output: 346 * 347 * Return: return code 0 - success 348 * -1 - failure 349 * 350 */ 351 static int 352 ipmi_delloem_lcd_main(struct ipmi_intf * intf, int argc, char ** argv) 353 { 354 int rc = 0; 355 current_arg++; 356 if (argc < current_arg) { 357 usage(); 358 return -1; 359 } 360 /* ipmitool delloem lcd info*/ 361 if (argc == 1 || strcmp(argv[current_arg], "help") == 0) { 362 ipmi_lcd_usage(); 363 return 0; 364 } 365 CheckLCDSupport(intf); 366 ipmi_idracvalidator_command(intf); 367 if (!IsLCDSupported()) { 368 lprintf(LOG_ERR, "lcd is not supported on this system."); 369 return -1; 370 } else if (strncmp(argv[current_arg], "info\0", 5) == 0) { 371 if (iDRAC_FLAG_ALL) { 372 rc = ipmi_lcd_get_info_wh(intf); 373 } else { 374 rc = ipmi_lcd_get_info(intf); 375 } 376 } else if (strncmp(argv[current_arg], "status\0", 7) == 0) { 377 rc = ipmi_lcd_get_status(intf); 378 } else if (strncmp(argv[current_arg], "set\0", 4) == 0) { 379 /* ipmitool delloem lcd set*/ 380 uint8_t line_number = 0; 381 current_arg++; 382 if (argc <= current_arg) { 383 ipmi_lcd_usage(); 384 return -1; 385 } 386 if (strncmp(argv[current_arg], "line\0", 5) == 0) { 387 current_arg++; 388 if (argc <= current_arg) { 389 usage(); 390 return -1; 391 } 392 if (str2uchar(argv[current_arg], &line_number) != 0) { 393 lprintf(LOG_ERR, 394 "Argument '%s' is either not a number or out of range.", 395 argv[current_arg]); 396 return (-1); 397 } 398 current_arg++; 399 if (argc <= current_arg) { 400 usage(); 401 return -1; 402 } 403 } 404 if ((strncmp(argv[current_arg], "mode\0", 5) == 0) 405 && (iDRAC_FLAG_ALL)) { 406 current_arg++; 407 if (argc <= current_arg) { 408 ipmi_lcd_usage(); 409 return -1; 410 } 411 if (argv[current_arg] == NULL) { 412 ipmi_lcd_usage(); 413 return -1; 414 } 415 if (strncmp(argv[current_arg], "none\0", 5) == 0) { 416 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_NONE, 0xFF, 417 0XFF, 0, NULL); 418 } else if (strncmp(argv[current_arg], "modelname\0", 10) == 0) { 419 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0xFF, 420 0XFF, 0, NULL); 421 } else if (strncmp(argv[current_arg], "userdefined\0", 12) == 0) { 422 current_arg++; 423 if (argc <= current_arg) { 424 ipmi_lcd_usage(); 425 return -1; 426 } 427 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED, 428 0xFF, 0XFF, line_number, argv[current_arg]); 429 } else if (strncmp(argv[current_arg], "ipv4address\0", 12) == 0) { 430 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_iDRAC_IPV4ADRESS, 431 0xFF, 0XFF, 0, NULL); 432 } else if (strncmp(argv[current_arg], "macaddress\0", 11) == 0) { 433 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_IDRAC_MAC_ADDRESS, 434 0xFF, 0XFF, 0, NULL); 435 } else if (strncmp(argv[current_arg], "systemname\0", 11) == 0) { 436 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_OS_SYSTEM_NAME, 0xFF, 437 0XFF, 0, NULL); 438 } else if (strncmp(argv[current_arg], "servicetag\0", 11) == 0) { 439 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_SERVICE_TAG, 0xFF, 440 0XFF, 0, NULL); 441 } else if (strncmp(argv[current_arg], "ipv6address\0", 12) == 0) { 442 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_iDRAC_IPV6ADRESS, 443 0xFF, 0XFF, 0, NULL); 444 } else if (strncmp(argv[current_arg], "ambienttemp\0", 12) == 0) { 445 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_AMBEINT_TEMP, 0xFF, 446 0XFF, 0, NULL); 447 } else if (strncmp(argv[current_arg], "systemwatt\0", 11) == 0) { 448 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_SYSTEM_WATTS, 0xFF, 449 0XFF, 0, NULL); 450 } else if (strncmp(argv[current_arg], "assettag\0", 9) == 0) { 451 rc = ipmi_lcd_configure_wh(intf, IPMI_DELL_LCD_ASSET_TAG, 0xFF, 452 0XFF, 0, NULL); 453 } else if (strncmp(argv[current_arg], "help\0", 5) == 0) { 454 ipmi_lcd_usage(); 455 } else { 456 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 2046 IsLANSupported() 2047 { 2048 if (IMC_IDRAC_11G_MODULAR == IMC_Type) { 2049 return 0; 2050 } 2051 return 1; 2052 } 2053 2054 int 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 4047 IsSetLEDSupported(void) 4048 { 4049 return SetLEDSupported; 4050 } 4051 4052 static void 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 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 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 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 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