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