diff options
Diffstat (limited to 'util/oem_dell.c')
-rw-r--r-- | util/oem_dell.c | 6095 |
1 files changed, 6095 insertions, 0 deletions
diff --git a/util/oem_dell.c b/util/oem_dell.c new file mode 100644 index 0000000..1911d96 --- /dev/null +++ b/util/oem_dell.c @@ -0,0 +1,6095 @@ +/* + * oem_dell.c + * Handle Dell OEM command functions + * + * Change history: + * 08/17/2011 ARCress - included in ipmiutil source tree + * + */ +/****************************************************************** +Copyright (c) 2008, Dell Inc +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +- Neither the name of Dell Inc nor the names of its contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +******************************************************************/ +/* +* Thursday Oct 7 17:30:12 2009 +* <deepaganesh_paulraj@dell.com> +* +* This code implements a dell OEM proprietary commands. +* This Code is edited and Implemented the License feature for Delloem +* Author Harsha S <Harsha_S1@dell.com> +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifdef WIN32 +#include <windows.h> +#define int8_t char +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned int +#define uint64_t unsigned long +#include "getopt.h" +#else +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <unistd.h> +#include <signal.h> +#include <ctype.h> +#include <limits.h> +#if defined(HPUX) +/* getopt is defined in stdio.h */ +#elif defined(MACOS) +/* getopt is defined in unistd.h */ +#include <unistd.h> +#include <stdint.h> +#else +#include <getopt.h> +#endif +#endif + +#include <time.h> +#include "ipmicmd.h" +#include "isensor.h" +#include "ievents.h" +#include "oem_dell.h" + +// #ifdef METACOMMAND is assumed +extern int i_sol(int argc, char **argv); /*isol.c*/ +extern void lprintf(int level, const char * format, ...); /*ipmilanplus.c*/ +extern void set_loglevel(int level); +extern void printbuf(const uint8_t * buf, int len, const char * desc); + +#define IPMI_DELL_OEM_NETFN (uint8_t)(0x30) +#define GET_CHASSIS_LED_STATE (uint8_t)(0x32) +#define GET_IDRAC_VIRTUAL_MAC (uint8_t)(0xC9) +// 11g Support Macros +#define INVALID -1 +#define SHARED 0 +#define SHARED_WITH_FAILOVER_LOM2 1 +#define DEDICATED 2 +#define SHARED_WITH_FAILOVER_ALL_LOMS 3 +char ActiveLOM_String[6][10] = {"None","LOM1","LOM2","LOM3","LOM4","dedicated"}; +#define INVAILD_FAILOVER_MODE -2 +#define INVAILD_FAILOVER_MODE_SETTINGS -3 +#define INVAILD_SHARED_MODE -4 + +#define INVAILD_FAILOVER_MODE_STRING "ERROR: Cannot set shared with failover lom same as current shared lom.\n" +#define INVAILD_FAILOVER_MODE_SET "ERROR: Cannot set shared with failover loms when NIC is set to dedicated Mode.\n" +#define INVAILD_SHARED_MODE_SET_STRING "ERROR: Cannot set shared Mode for Blades.\n" + +// 11g Support Strings for nic selection +char NIC_Selection_Mode_String [4] [50] = { "shared", + "shared with failover lom2", + "dedicated", + "shared with Failover all loms" + }; + +// 11g Support Macros (dups) +//#define SHARED 0 +//#define SHARED_WITH_FAILOVER_LOM2 1 +//#define DEDICATED 2 +//#define SHARED_WITH_FAILOVER_ALL_LOMS 3 + +// 12g Support Strings for nic selection +char NIC_Selection_Mode_String_12g[] [50] = { + "dedicated", + "shared with lom1", + "shared with lom2", + "shared with lom3", + "shared with lom4", + "shared with failover lom1", + "shared with failover lom2", + "shared with failover lom3", + "shared with failover lom4", + "shared with failover all loms" + }; + +static char * progver = "2.93"; +static char * progname = "idelloem"; +static int verbose = 0; +static char fdebug = 0; +static uchar g_bus = PUBLIC_BUS; +static uchar g_sa = BMC_SA; +static uchar g_lun = BMC_LUN; +static uchar g_addrtype = ADDR_SMI; +static uchar *sdrcache = NULL; +static char *sdrfile = NULL; +static int argc_sav; +static char **argv_sav; +static int current_arg =0; +uint8_t iDRAC_FLAG=0; +LCD_MODE lcd_mode; +static uint8_t LcdSupported=0; +static uint8_t SetLEDSupported=0; + +volatile uint8_t IMC_Type = IMC_IDRAC_10G; + + +const struct vFlashstr vFlash_completion_code_vals[] = { + {0x00, "SUCCESS"}, + {0x01, "NO_SD_CARD"}, + {0x63, "UNKNOWN_ERROR"}, + {0x00, NULL} +}; + + +POWER_HEADROOM powerheadroom; + +uint8_t PowercapSetable_flag=0; +uint8_t PowercapstatusFlag=0; + +static void usage(void); + +/* LCD Function prototypes */ +static int ipmi_delloem_lcd_main (void * intf, int argc, char ** argv); +static int ipmi_lcd_get_platform_model_name (void * intf,char* lcdstring, + uint8_t max_length,uint8_t field_type); +static int ipmi_idracvalidator_command (void * intf); +static int ipmi_lcd_get_configure_command_wh (void * intf); +static int ipmi_lcd_get_configure_command (void * intf,uint8_t *command); +static int ipmi_lcd_set_configure_command (void * intf, int command); +static int ipmi_lcd_set_configure_command_wh (void * intf, uint32_t mode, + uint16_t lcdqualifier,uint8_t errordisp); +static int ipmi_lcd_get_single_line_text (void * intf, char* lcdstring, uint8_t max_length); +static int ipmi_lcd_get_info_wh(void * intf); +static int ipmi_lcd_get_info(void * intf); +static int ipmi_lcd_get_status_val(void * intf, LCD_STATUS* lcdstatus); +static int IsLCDSupported (); +static void CheckLCDSupport(void * intf); +static void ipmi_lcd_status_print( LCD_STATUS lcdstatus); +static int ipmi_lcd_get_status(void * intf ); +static int ipmi_lcd_set_kvm(void * intf, char status); +static int ipmi_lcd_set_lock(void * intf, char lock); +static int ipmi_lcd_set_single_line_text (void * intf, char * text); +static int ipmi_lcd_set_text(void * intf, char * text, int line_number); +static int ipmi_lcd_configure_wh (void * intf, uint32_t mode , + uint16_t lcdqualifier, uint8_t errordisp, + int8_t line_number, char * text); +static int ipmi_lcd_configure (void * intf, int command, + int8_t line_number, char * text); +static void ipmi_lcd_usage(void); + +/* MAC Function prototypes */ +static int ipmi_delloem_mac_main (void * intf, int argc, char ** argv); +static int make_int(const char *str, int *value); +static void InitEmbeddedNICMacAddressValues (); +static int ipmi_macinfo_drac_idrac_virtual_mac(void* intf,uint8_t NicNum); +static int ipmi_macinfo_drac_idrac_mac(void* intf,uint8_t NicNum); +static int ipmi_macinfo_10g (void* intf, uint8_t NicNum); +static int ipmi_macinfo_11g (void* intf, uint8_t NicNum); +static int ipmi_macinfo (void* intf, uint8_t NicNum); +static void ipmi_mac_usage(void); + +/* LAN Function prototypes */ +static int ipmi_delloem_lan_main (void * intf, int argc, char ** argv); +static int IsLANSupported (); +static int get_nic_selection_mode (int current_arg, char ** argv); +static int ipmi_lan_set_nic_selection (void* intf, uint8_t nic_selection); +static int ipmi_lan_get_nic_selection (void* intf); +static int get_nic_selection_mode_12g (void* intf,int iarg, char **argv, char *nic_set); +static int ipmi_lan_get_active_nic (void* intf); +static void ipmi_lan_usage(void); +static int ipmi_lan_set_nic_selection_12g (void* intf, uint8_t* nic_selection); + +/* POwer monitor Function prototypes */ +static int ipmi_delloem_powermonitor_main (void * intf, int argc, char **argv); +static void ipmi_time_to_str(time_t rawTime, char* strTime); +static int ipmi_get_power_capstatus_command (void * intf); +static int ipmi_set_power_capstatus_command (void * intf,uint8_t val); +static int ipmi_powermgmt(void* intf); +static int ipmi_powermgmt_clear(void* intf,uint8_t clearValue); +static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt); +static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr); +static int ipmi_get_power_headroom_command (void * intf,uint8_t unit); +static int ipmi_get_power_consumption_data(void* intf,uint8_t unit); +static int ipmi_get_instan_power_consmpt_data(void* intf, + IPMI_INST_POWER_CONSUMPTION_DATA* instpowerconsumptiondata); +static void ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata); +static int ipmi_print_get_power_consmpt_data(void* intf,uint8_t unit); +static int ipmi_get_avgpower_consmpt_history(void* intf,IPMI_AVGPOWER_CONSUMP_HISTORY* pavgpower ); +static int ipmi_get_peakpower_consmpt_history(void* intf,IPMI_POWER_CONSUMP_HISTORY * pstPeakpower); +static int ipmi_get_minpower_consmpt_history(void* intf,IPMI_POWER_CONSUMP_HISTORY * pstMinpower); +static int ipmi_print_power_consmpt_history(void* intf,int unit ); +static int ipmi_get_power_cap(void* intf,IPMI_POWER_CAP* ipmipowercap ); +static int ipmi_print_power_cap(void* intf,uint8_t unit ); +static int ipmi_set_power_cap(void* intf,int unit,int val ); +static void ipmi_powermonitor_usage(void); + +/* vFlash Function prototypes */ +static int ipmi_delloem_vFlash_main(void * intf, int argc, char ** argv); +const char * get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs); +static int ipmi_get_sd_card_info(void* intf); +static int ipmi_delloem_vFlash_process(void* intf, int current_arg, char ** argv); +static void ipmi_vFlash_usage(void); + + +/* windbg Function prototypes */ +volatile uint8_t windbgsession = 0; +static int ipmi_delloem_windbg_main (void * intf, int argc, char ** argv); +static int ipmi_windbg_start (void * intf); +static int ipmi_windbg_end (void * intf); +static void ipmi_windbg_usage (void); + + + +/* LED Function prototypes */ + +static int ipmi_getsesmask(int, char **); +static int CheckSetLEDSupport(void * intf); +static int IsSetLEDSupported(void); +static void ipmi_setled_usage(void); +static int ipmi_delloem_setled_main(void *intf, int argc, char ** argv); +static int ipmi_delloem_getled_main(void *intf, int argc, char ** argv); +static int ipmi_setled_state (void * intf, int bayId, int slotId, int state); +static int ipmi_getdrivemap (void * intf, int b, int d, int f, int *bayId, int *slotId); +//extern int optind; /*from getopt*/ + +static int ipmi_sol_activate(void *intf, int j, int k) +{ + char **args; + int rv, i, n; + int x = 0; + n = argc_sav; + args = argv_sav; + /* use the user-specified args, but switch to sol */ + for (i = 0; i < n; i++) { + if (strcmp(args[i],"ipmiutil") == 0) { x = 1; } + else if (strcmp(args[i],"delloem") == 0) args[i] = "sol"; + else if (strcmp(args[i],"windbg") == 0) args[i] = "-a"; + else if (strcmp(args[i],"start") == 0) args[i] = "-a"; + } + ipmi_close_(); + if (x == 1) { args++; n--; } + optind = 0; + rv = i_sol(n, args); + return rv; +} + +static int ipmi_sol_deactivate(void *intf) +{ + char **args; + int rv, i, n; + int x = 0; + n = argc_sav; + args = argv_sav; + /* use the user-specified args, but switch to sol */ + for (i = 0; i < n; i++) { + if (strcmp(args[i],"ipmiutil") == 0) { x = 1; } + else if (strcmp(args[i],"delloem") == 0) args[i] = "sol"; + else if (strcmp(args[i],"windbg") == 0) args[i] = "-d"; + else if (strcmp(args[i],"end") == 0) args[i] = "-d"; + } + ipmi_close_(); + if (x == 1) { args++; n--; } + optind = 0; + rv = i_sol(n, args); + return rv; +} + +static int sysinfo_param(const char *str) { + // SysInfo Parameters + // 1 = system firmware version + // 2 = system hostname + // 3 = primary operating system name (non-volatile) + // 4 = operating system name (volatile) + // 0xe3 = dell: os version + // 0xde = dell: url + if (!strcmp(str, "system_name")) return 0x02; + if (!strcmp(str, "primary_os_name")) return 0x03; + if (!strcmp(str, "os_name")) return 0x04; + if (!strcmp(str, "dell_os_version")) return 0xe4; + if (!strcmp(str, "dell_url")) return 0xde; + return strtoul(str, 0, 16); +} + +static void ipmi_sysinfo_usage() +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " getsysinfo (os_name|primary_os_name|dell_os_version|dell_url)"); + lprintf(LOG_NOTICE, " Retrieves system info from bmc for given argument"); + lprintf(LOG_NOTICE, " setsysinfo (os_name|primary_os_name|dell_os_version|dell_url)"); + lprintf(LOG_NOTICE, " Stores system Info for given argument to bmc"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " primary_os_name = primary operating system name"); + lprintf(LOG_NOTICE, " os_name = secondary operating system name"); + lprintf(LOG_NOTICE, " system_name = system hostname of server"); + lprintf(LOG_NOTICE, " dell_os_version = running version of operating system (Dell)"); + lprintf(LOG_NOTICE, " dell_url = url of bmc webserver (Dell)"); + + lprintf(LOG_NOTICE, ""); +} + +static int +ipmi_delloem_sysinfo_main(void * intf, int argc, char ** argv) +{ + int param, isset; + char *str; + unsigned char infostr[256], *pos; + int j, ret; + + /* Is this a setsysinfo or getsysinfo */ + isset = !strncmp(argv[current_arg], "setsysinfo\0",10); + + current_arg++; + if (argc < current_arg) { + usage(); + return -1; + } + if (argc == 1 || strcmp(argv[current_arg], "help") == 0 || + argc < (isset ? current_arg+2 : current_arg+1)) { + ipmi_sysinfo_usage(); + return 0; + } + memset(infostr, 0, sizeof(infostr)); + + param = sysinfo_param(argv[current_arg++]); + + if (isset) { + str = argv[current_arg]; + j = strlen_(str); + ret = set_system_info(param,str,j); + } else { + pos = infostr; + j = sizeof(infostr); + ret = get_system_info(param,infostr,&j); + printf("%s\n", infostr); + } + return ret; +} + +static void ipmi_password_policy_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " passwordpolicy <on | off>"); + lprintf(LOG_NOTICE, " Set the OEM Password Policy Check on or off"); + lprintf(LOG_NOTICE, " This parameter is write-only"); + lprintf(LOG_NOTICE, ""); +} + +static int +ipmi_delloem_password_policy(void * intf, int argc, char ** argv) +{ + int rv = 0; + int rsp_len; + struct ipmi_rq req = {0}; + uint8_t data[4]; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + uint8_t bval; + + + current_arg++; + if (argc < current_arg) { + usage(); + return -1; + } + + if (strcmp(argv[current_arg], "on") == 0) { + bval = 0x01; + } else if (strcmp(argv[current_arg], "off") == 0) { + bval = 0x00; + } else { /* other or "help" */ + ipmi_password_policy_usage(); + return 0; + } + + printf("Setting OEM Password Policy Check to %s ...\n", argv[current_arg]); + req.msg.netfn = 0x30; /*Dell OEM netfn*/ + req.msg.lun = 0; + req.msg.cmd = 0x51; + req.msg.data_len = 1; + req.msg.data = data; + data[0] = bval; + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting OEM password policy: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + } + if (rv == 0) printf("successful\n"); + /* This works for DELL C6220 with firmware >= 1.23 */ + + return(rv); +} + +/***************************************************************** +* Function Name: ipmi_delloem_main +* +* Description: This function processes the delloem command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +int +ipmi_delloem_main(void * intf, int argc, char ** argv) +{ + int rc = 0; + + // ipmi_idracvalidator_command(intf); + // CheckLCDSupport (intf); + // CheckSetLEDSupport (intf); + + if (argc == 0 || strncmp(argv[0], "help\0", 5) == 0) + { + usage(); + return 0; + } + + if (0 ==strncmp(argv[current_arg], "lcd\0", 4) ) + { + rc = ipmi_delloem_lcd_main (intf,argc,argv); + } + /* mac address*/ + else if (strncmp(argv[current_arg], "mac\0", 4) == 0) + { + rc = ipmi_delloem_mac_main (intf,argc,argv); + } + /* lan address*/ + else if (strncmp(argv[current_arg], "lan\0", 4) == 0) + { + rc = ipmi_delloem_lan_main (intf,argc,argv); + } + /* SetLED support */ + else if (strncmp(argv[current_arg], "setled\0", 7) == 0) + { + rc = ipmi_delloem_setled_main (intf,argc,argv); + } + else if (strncmp(argv[current_arg], "getled\0", 13) == 0) + { + rc = ipmi_delloem_getled_main (intf,argc,argv); + } + else if (strncmp(argv[current_arg], "passwordpolicy\0", 14) == 0) + { + rc = ipmi_delloem_password_policy (intf,argc,argv); + } + /*Powermanagement report processing*/ + else if (strncmp(argv[current_arg], "powermonitor\0", 13) == 0) + { + rc = ipmi_delloem_powermonitor_main (intf,argc,argv); + } + /* vFlash Support */ + else if (strncmp(argv[current_arg], "vFlash\0", 7) == 0) + { + rc = ipmi_delloem_vFlash_main (intf,argc,argv); + } + else if (strncmp(argv[current_arg], "windbg\0", 7) == 0) + { + rc = ipmi_delloem_windbg_main (intf,argc,argv); + } + else if ((strncmp(argv[current_arg], "getsysinfo\0", 10) == 0) || + (strncmp(argv[current_arg], "setsysinfo\0", 10) == 0)) + { + rc = ipmi_delloem_sysinfo_main (intf,argc,argv); + } + else + { + usage(); + return ERR_USAGE; + } + return rc; +} + +/***************************************************************** +* Function Name: usage +* +* Description: This function prints help message for delloem command +* Input: +* Output: +* +* Return: +* +******************************************************************/ + +static void usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "usage: delloem <command> [option...]"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "commands:"); + lprintf(LOG_NOTICE, " lcd"); + lprintf(LOG_NOTICE, " mac"); + lprintf(LOG_NOTICE, " lan"); + lprintf(LOG_NOTICE, " setled"); + lprintf(LOG_NOTICE, " getled"); + lprintf(LOG_NOTICE, " powermonitor"); + lprintf(LOG_NOTICE, " windbg"); + lprintf(LOG_NOTICE, " vFlash"); + lprintf(LOG_NOTICE, " getsysinfo"); + lprintf(LOG_NOTICE, " setsysinfo"); + lprintf(LOG_NOTICE, " passwordpolicy"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "For help on individual commands type:"); + lprintf(LOG_NOTICE, "delloem <command> help"); + +} + +/***************************************************************** +* Function Name: ipmi_delloem_lcd_main +* +* Description: This function processes the delloem lcd command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_lcd_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + if (argc < current_arg) + { + usage(); + return -1; + } + + + /* ipmitool delloem lcd info*/ + if (argc == 1 || strcmp(argv[current_arg], "help") == 0) + { + ipmi_lcd_usage(); + return 0; + } + CheckLCDSupport (intf); + ipmi_idracvalidator_command(intf); + if (!IsLCDSupported()) { + printf("lcd is not supported on this system.\n"); + return -1; + } + else if (strncmp(argv[current_arg], "info\0", 5) == 0) + { + if((iDRAC_FLAG==IDRAC_11G) || (iDRAC_FLAG==IDRAC_12G) ) + rc = ipmi_lcd_get_info_wh(intf); + else + rc = ipmi_lcd_get_info(intf); + } + else if (strncmp(argv[current_arg], "status\0", 7) == 0) + { + rc = ipmi_lcd_get_status(intf); + } + /* ipmitool delloem lcd set*/ + else if (strncmp(argv[current_arg], "set\0", 4) == 0) + { + uint8_t line_number = 0; + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (strncmp(argv[current_arg], "line\0", 5) == 0) + { + current_arg++; + if (argc <= current_arg) {usage();return -1;} + line_number = (uint8_t)strtoul(argv[current_arg], NULL, 0); + current_arg++; + if (argc <= current_arg) {usage();return -1;} + } + + + if ((strncmp(argv[current_arg], "mode\0", 5) == 0)&&((iDRAC_FLAG==IDRAC_11G) || (iDRAC_FLAG==IDRAC_12G) )) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (argv[current_arg] == NULL) + { + ipmi_lcd_usage(); + return -1; + } + if (strncmp(argv[current_arg], "none\0", 5) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_NONE,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "modelname\0", 10) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_DEFAULT,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "userdefined\0", 12) == 0) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage();return -1; + } + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED,0xFF,0XFF, line_number, argv[current_arg]); + } + else if (strncmp(argv[current_arg], "ipv4address\0", 12) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_iDRAC_IPV4ADRESS ,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "macaddress\0", 11) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_IDRAC_MAC_ADDRESS,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "systemname\0", 11) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_OS_SYSTEM_NAME,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "servicetag\0", 11) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_SERVICE_TAG, 0xFF,0XFF,0, NULL); + } + else if (strncmp(argv[current_arg], "ipv6address\0", 12) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_iDRAC_IPV6ADRESS ,0xFF,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "ambienttemp\0", 12) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_AMBEINT_TEMP, 0xFF,0XFF,0, NULL); + + } + else if (strncmp(argv[current_arg], "systemwatt\0", 11) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_SYSTEM_WATTS , 0xFF,0XFF,0, NULL); + + } + else if (strncmp(argv[current_arg], "assettag\0", 9) == 0) + { + rc = ipmi_lcd_configure_wh (intf, IPMI_DELL_LCD_ASSET_TAG , 0xFF,0XFF,0, NULL); + + } + else if (strncmp(argv[current_arg], "help\0", 5) == 0) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + } + } + else if ((strncmp(argv[current_arg], "lcdqualifier\0", 13)== 0) &&((iDRAC_FLAG==IDRAC_11G) || (iDRAC_FLAG==IDRAC_12G) ) ) + { + + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (argv[current_arg] == NULL) + { + ipmi_lcd_usage(); + return -1; + } + + if (strncmp(argv[current_arg], "watt\0", 5) == 0) { + + + rc = ipmi_lcd_configure_wh (intf, 0xFF,0x00,0XFF, 0, NULL); + } + else if (strncmp(argv[current_arg], "btuphr\0",7) == 0) { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0x01,0XFF, 0, NULL); + + } else if (strncmp(argv[current_arg], "celsius\0", 8) == 0) { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0x02,0xFF, 0, NULL); + } else if (strncmp(argv[current_arg], "fahrenheit", 11) == 0) { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0x03,0xFF, 0, NULL); + + }else if (strncmp(argv[current_arg], "help\0", 5) == 0) { + ipmi_lcd_usage(); + } + else { + ipmi_lcd_usage(); + } + } + else if( (strncmp(argv[current_arg], "errordisplay\0", 13) == 0)&&((iDRAC_FLAG==IDRAC_11G) || (iDRAC_FLAG==IDRAC_12G) )) + { + + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (argv[current_arg] == NULL) + { + ipmi_lcd_usage(); + return -1; + } + + if (strncmp(argv[current_arg], "sel\0", 4) == 0) + { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0xFF,IPMI_DELL_LCD_ERROR_DISP_SEL , 0, NULL); + } + else if (strncmp(argv[current_arg], "simple\0", 7) == 0) + { + rc = ipmi_lcd_configure_wh (intf, 0xFF,0xFF,IPMI_DELL_LCD_ERROR_DISP_VERBOSE , 0, NULL); + + } + else if (strncmp(argv[current_arg], "help\0", 5) == 0) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + } + } + + else if ((strncmp(argv[current_arg], "none\0", 5) == 0)&&(iDRAC_FLAG==0)) + { + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_NONE, 0, NULL); + } + else if ((strncmp(argv[current_arg], "default\0", 8) == 0)&&(iDRAC_FLAG==0)) + { + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0, NULL); + + } + else if ((strncmp(argv[current_arg], "custom\0", 7) == 0)&&(iDRAC_FLAG==0)) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED, line_number, argv[current_arg]); + } + + else if (strncmp(argv[current_arg], "vkvm\0", 5) == 0) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + + if (strncmp(argv[current_arg], "active\0", 7) == 0) + { + rc = ipmi_lcd_set_kvm (intf, 1); + } + else if (strncmp(argv[current_arg], "inactive\0", 9)==0) + { + rc = ipmi_lcd_set_kvm (intf, 0); + + } + else if (strncmp(argv[current_arg], "help\0", 5) == 0) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + } + + } + else if (strncmp(argv[current_arg], "frontpanelaccess\0", 17) == 0) + { + current_arg++; + if (argc <= current_arg) + { + ipmi_lcd_usage(); + return -1; + } + if (strncmp(argv[current_arg], "viewandmodify\0", 14) == 0) + { + rc = ipmi_lcd_set_lock (intf, 0); + } + else if (strncmp(argv[current_arg], "viewonly\0", 9)==0) + { + rc = ipmi_lcd_set_lock (intf, 1); + + } + else if (strncmp(argv[current_arg], "disabled\0", 9)==0) + { + rc = ipmi_lcd_set_lock (intf, 2); + + } + else if (strncmp(argv[current_arg], "help\0", 5) == 0) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + } + + } + else if( (strncmp(argv[current_arg], "help\0", 5) == 0)&&(iDRAC_FLAG==0)) + { + ipmi_lcd_usage(); + } + else + { + ipmi_lcd_usage(); + return -1; + } + } + else + { + ipmi_lcd_usage(); + return -1; + } + return(rc); +} + + + +/***************************************************************** +* Function Name: ipmi_lcd_get_platform_model_name +* +* Description: This function retrieves the platform model name, or any other parameter +* which stores data in the same format +* Input: intf - pointer to interface +* max_length - length of the platform model string +* field_type - either hostname / platform model +* Output: lcdstring - hostname / platform model string +* +* Return: +* +******************************************************************/ +static int +ipmi_lcd_get_platform_model_name (void * intf, + char* lcdstring, + uint8_t max_length, + uint8_t field_type) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_LCD_STRING * lcdstringblock; + int lcdstring_len = 0; + int bytes_copied = 0; + + int ii; + + for (ii = 0; ii < 4; ii++) + { + int bytes_to_copy; + memset (&req,0,sizeof(req)); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = field_type; + data[2] = ii; + data[3] = 0; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting platform model name: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + lcdstringblock = (IPMI_DELL_LCD_STRING *) (void *) rsp; + + /* first block is different - 14 bytes*/ + if (0 == ii) { + lcdstring_len = lcdstringblock->lcd_string.selector_0_string.length; + + lcdstring_len = MIN (lcdstring_len,max_length); + + bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE); + memcpy (lcdstring, lcdstringblock->lcd_string.selector_0_string.data, bytes_to_copy); + } else { + int string_offset; + + bytes_to_copy = MIN(lcdstring_len - bytes_copied, IPMI_DELL_LCD_STRINGN_SIZE); + if (bytes_to_copy < 1) + break; + string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE * (ii-1); + memcpy (lcdstring+string_offset, lcdstringblock->lcd_string.selector_n_data, bytes_to_copy); + } + + + bytes_copied += bytes_to_copy; + + if (bytes_copied >= lcdstring_len) + + break; + } + return rv; +} + +/***************************************************************** +* Function Name: ipmi_idracvalidator_command +* +* Description: This function returns the iDRAC6 type +* Input: intf - ipmi interface +* Output: +* +* Return: iDRAC6 type 1 - whoville +* 0 - others +* +******************************************************************/ + +static int +ipmi_idracvalidator_command (void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + memset (&req,0,sizeof(req)); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = IPMI_DELL_IDRAC_VALIDATOR; + data[2] = 2; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv && fdebug) { + printf(" Error getting IMC type"); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + IMC_Type = rsp[10]; + if( (IMC_Type == IMC_IDRAC_11G_MONOLITHIC) || (IMC_Type == IMC_IDRAC_11G_MODULAR) ) + { + iDRAC_FLAG=IDRAC_11G; + } + else if( (IMC_Type == IMC_IDRAC_12G_MONOLITHIC) || (IMC_Type == IMC_IDRAC_12G_MODULAR) ) + { + iDRAC_FLAG=IDRAC_12G; + } + else + { + iDRAC_FLAG=0; + } + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_configure_command_wh +* +* Description: This function returns current lcd configuration for Dell OEM LCD command +* Input: intf - ipmi interface +* Global: lcd_mode - lcd mode setting +* Output: +* +* Return: returns the current lcd configuration +* 0 = User defined +* 1 = Default +* 2 = None +* +******************************************************************/ +static int +ipmi_lcd_get_configure_command_wh (void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = IPMI_DELL_LCD_CONFIG_SELECTOR; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD configuration: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcd_mode= *((LCD_MODE*)(&rsp[0])); + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_lcd_get_configure_command +* +* Description: This function returns current lcd configuration for Dell OEM LCD command +* Input: intf - ipmi interface +* Output: command - user defined / default / none / ipv4 / mac address / + system name / service tag / ipv6 / temp / system watt / asset tag +* +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_get_configure_command (void * intf, + uint8_t *command) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = IPMI_DELL_LCD_CONFIG_SELECTOR; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD configuration: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + /* rsp->data[0] is the rev */ + *command = rsp[1]; + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_configure_command +* +* Description: This function updates current lcd configuration +* Input: intf - ipmi interface +* command - user defined / default / none / ipv4 / mac address / +* system name / service tag / ipv6 / temp / system watt / asset tag +* Output: +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_set_configure_command (void * intf, int command) +{ +#define LSCC_DATA_LEN 2 + + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[2]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 2; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR; + data[1] = command; /* command - custom, default, none */ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting LCD configuration: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_lcd_set_configure_command +* +* Description: This function updates current lcd configuration +* Input: intf - ipmi interface +* mode - user defined / default / none +* lcdqualifier - lcd quallifier id +* errordisp - error number +* Output: +* Return: +* +******************************************************************/ +static int +ipmi_lcd_set_configure_command_wh (void * intf, + uint32_t mode, + uint16_t lcdqualifier, + uint8_t errordisp) +{ +#define LSCC_DATA_LEN 2 + + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[13]; + + ipmi_lcd_get_configure_command_wh(intf); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 13; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR; + + if(mode!=0xFF) + { + + data[1] = mode&0xFF; /* command - custom, default, none*/ + data[2]=(mode&0xFF00)>>8; + data[3]=(mode&0xFF0000)>>16; + data[4]=(mode&0xFF000000)>>24; + } + else + { + data[1] = (lcd_mode.lcdmode)&0xFF; /* command - custom, default, none*/ + data[2]=((lcd_mode.lcdmode)&0xFF00)>>8; + data[3]=((lcd_mode.lcdmode)&0xFF0000)>>16; + data[4]=((lcd_mode.lcdmode)&0xFF000000)>>24; + } + + if(lcdqualifier!=0xFF) + { + if(lcdqualifier==0x01) + { + data[5] =(lcd_mode.lcdqualifier)|0x01; /* command - custom, default, none*/ + + } + else if(lcdqualifier==0x00) + { + data[5] =(lcd_mode.lcdqualifier)&0xFE; /* command - custom, default, none*/ + } + else if (lcdqualifier==0x03) + { + data[5] =(lcd_mode.lcdqualifier)|0x02; /* command - custom, default, none*/ + } + else if (lcdqualifier==0x02) + { + data[5] =(lcd_mode.lcdqualifier)&0xFD; + } + } + else + { + data[5]=(uchar)lcd_mode.lcdqualifier; + } + if(errordisp!=0xFF) + { + data[11]=errordisp; + } + else + { + data[11]=lcd_mode.error_display; + } + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting LCD configuration: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + return 0; +} + + + +/***************************************************************** +* Function Name: ipmi_lcd_get_single_line_text +* +* Description: This function updates current lcd configuration +* Input: intf - ipmi interface +* lcdstring - new string to be updated +* max_length - length of the string +* Output: +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_get_single_line_text (void * intf, char* lcdstring, uint8_t max_length) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; + int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_LCD_STRING * lcdstringblock; + int lcdstring_len = 0; + int bytes_copied = 0; + int ii; + + for (ii = 0; ii < 4; ii++) { + int bytes_to_copy; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = IPMI_DELL_LCD_STRING_SELECTOR; + data[2] = ii; /* block selector*/ + data[3] = 0; /* set selector (n/a)*/ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting text data: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcdstringblock = (IPMI_DELL_LCD_STRING *) (void *) rsp; + + /* first block is different - 14 bytes*/ + if (0 == ii) + { + lcdstring_len = lcdstringblock->lcd_string.selector_0_string.length; + + if (lcdstring_len < 1 || lcdstring_len > max_length) + break; + + bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE); + memcpy (lcdstring, lcdstringblock->lcd_string.selector_0_string.data, bytes_to_copy); + } + else + { + int string_offset; + + bytes_to_copy = MIN(lcdstring_len - bytes_copied, IPMI_DELL_LCD_STRINGN_SIZE); + if (bytes_to_copy < 1) + break; + string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE * (ii-1); + memcpy (lcdstring+string_offset, lcdstringblock->lcd_string.selector_n_data, bytes_to_copy); + } + + bytes_copied += bytes_to_copy; + if (bytes_copied >= lcdstring_len) + break; + } + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_info_wh +* +* Description: This function prints current lcd configuration for whoville platform +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_get_info_wh(void * intf) + +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + uint8_t command = 0; + IPMI_DELL_LCD_CAPS* lcd_caps; + char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + int rc; + + + printf("LCD info\n"); + + if (ipmi_lcd_get_configure_command_wh (intf) != 0) + { + return -1; + } + else + { + if (lcd_mode.lcdmode== IPMI_DELL_LCD_CONFIG_DEFAULT) + { + char text[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + + ipmi_lcd_get_platform_model_name(intf, text, + IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR); + + if (text == NULL) + return -1; + printf(" Setting:Model name\n"); + printf(" Line 1: %s\n", text); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_NONE) + { + printf(" Setting: none\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_CONFIG_USER_DEFINED) + { + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; + data[2] = 0; /* set selector (n/a)*/ + data[3] = 0; /* block selector (n/a)*/ + + printf(" Setting: User defined\n"); + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD capabilities: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcd_caps = (IPMI_DELL_LCD_CAPS *)rsp; + if (lcd_caps->number_lines > 0) + { + memset(lcdstring, 0, IPMI_DELL_LCD_STRING_LENGTH_MAX+1); + + rc = ipmi_lcd_get_single_line_text (intf, lcdstring, lcd_caps->max_chars[0]); + printf(" Text: %s\n", lcdstring); + } + else + { + printf(" No lines to show\n"); + } + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV4ADRESS) + { + printf(" Setting: IPV4 Address\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_IDRAC_MAC_ADDRESS) + { + printf(" Setting: MAC Address\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_OS_SYSTEM_NAME) + { + printf(" Setting: OS System Name\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SERVICE_TAG) + { + printf(" Setting: System Tag\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_iDRAC_IPV6ADRESS) + { + printf(" Setting: IPV6 Address\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_AMBEINT_TEMP) + { + printf(" Setting: Ambient Temp\n"); + if(lcd_mode.lcdqualifier&0x02) + printf(" Unit: F\n"); + else + printf(" Unit: C\n"); + } + else if (lcd_mode.lcdmode == IPMI_DELL_LCD_SYSTEM_WATTS) + { + printf(" Setting: System Watts\n"); + + if(lcd_mode.lcdqualifier&0x01) + printf(" Unit: BTU/hr\n"); + else + printf(" Unit: Watt\n"); + + } + if(lcd_mode.error_display==IPMI_DELL_LCD_ERROR_DISP_SEL) + printf(" Error Display: SEL\n"); + else if(lcd_mode.error_display==IPMI_DELL_LCD_ERROR_DISP_VERBOSE) + printf(" Error Display: Simple\n"); + } + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_info +* +* Description: This function prints current lcd configuration for platform other than whoville +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ +static int ipmi_lcd_get_info(void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_LCD_CAPS * lcd_caps; + uint8_t command = 0; + char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + int rc; + + printf("LCD info\n"); + + if (ipmi_lcd_get_configure_command (intf, &command) != 0) + { + return -1; + } + else + { + if (command == IPMI_DELL_LCD_CONFIG_DEFAULT) + { + memset (lcdstring,0,IPMI_DELL_LCD_STRING_LENGTH_MAX+1); + + ipmi_lcd_get_platform_model_name(intf, lcdstring, IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR); + + printf(" Setting: default\n"); + printf(" Line 1: %s\n", lcdstring); + } + else if (command == IPMI_DELL_LCD_CONFIG_NONE) + { + printf(" Setting: none\n"); + } + else if (command == IPMI_DELL_LCD_CONFIG_USER_DEFINED) + { + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter */ + data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; + data[2] = 0; /* set selector (n/a) */ + data[3] = 0; /* block selector (n/a) */ + + printf(" Setting: custom\n"); + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD capabilities: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcd_caps = (IPMI_DELL_LCD_CAPS *)(void *)rsp; + if (lcd_caps->number_lines > 0) + { + memset (lcdstring,0,IPMI_DELL_LCD_STRING_LENGTH_MAX+1); + rc = ipmi_lcd_get_single_line_text (intf, lcdstring, lcd_caps->max_chars[0]); + printf(" Text: %s\n", lcdstring); + } + else + { + printf(" No lines to show\n"); + } + } + } + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_status_val +* +* Description: This function gets current lcd configuration +* Input: intf - ipmi interface +* Output: lcdstatus - KVM Status & Lock Status +* Return: +* +******************************************************************/ + +static int +ipmi_lcd_get_status_val(void * intf, LCD_STATUS* lcdstatus) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter */ + data[1] = IPMI_DELL_LCD_STATUS_SELECTOR; + data[2] = 0; /* block selector */ + data[3] = 0; + /* set selector (n/a) */ + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + /*lcdstatus= (LCD_STATUS* ) rsp->data; */ + + lcdstatus->vKVM_status=rsp[1]; + lcdstatus->lock_status=rsp[2]; + + return 0; +} + + +/***************************************************************** +* Function Name: IsLCDSupported +* +* Description: This function returns whether lcd supported or not +* Input: +* Output: +* Return: +* +******************************************************************/ +static int IsLCDSupported () +{ + return LcdSupported; +} + +/***************************************************************** +* Function Name: CheckLCDSupport +* +* Description: This function checks whether lcd supported or not +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ +static void CheckLCDSupport(void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + LcdSupported = 0; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter */ + data[1] = IPMI_DELL_LCD_STATUS_SELECTOR; + data[2] = 0; /* block selector */ + data[3] = 0; + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { return; } + LcdSupported = 1; + +} + +/***************************************************************** +* Function Name: ipmi_lcd_status_print +* +* Description: This function prints current lcd configuration KVM Status & Lock Status +* Input: lcdstatus - KVM Status & Lock Status +* Output: +* Return: +* +******************************************************************/ + +static void ipmi_lcd_status_print( LCD_STATUS lcdstatus) +{ + switch (lcdstatus.vKVM_status) + { + case 0x00: + printf("LCD KVM Status :Inactive\n"); + break; + case 0x01: + printf("LCD KVM Status :Active\n"); + break; + default: + printf("LCD KVM Status :Invalid Status\n"); + + break; + } + + switch (lcdstatus.lock_status) + { + case 0x00: + printf("LCD lock Status :View and modify\n"); + break; + case 0x01: + printf("LCD lock Status :View only\n"); + break; + case 0x02: + printf("LCD lock Status :disabled\n"); + break; + default: + printf("LCD lock Status :Invalid\n"); + break; + } + +} + +/***************************************************************** +* Function Name: ipmi_lcd_get_status +* +* Description: This function gets current lcd KVM active status & lcd access mode +* Input: intf - ipmi interface +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ +static int +ipmi_lcd_get_status(void * intf ) +{ + int rc=0; + LCD_STATUS lcdstatus; + + rc =ipmi_lcd_get_status_val( intf, &lcdstatus); + if (rc <0) + return -1; + ipmi_lcd_status_print(lcdstatus); + + return rc; + +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_kvm +* +* Description: This function sets lcd KVM active status +* Input: intf - ipmi interface +* status - Inactive / Active +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ +static int +ipmi_lcd_set_kvm(void * intf, char status) +{ +#define LSCC_DATA_LEN 2 + LCD_STATUS lcdstatus; + int rc=0; + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[5]; + rc=ipmi_lcd_get_status_val(intf,&lcdstatus); + if (rc < 0) + return -1; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 5; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STATUS_SELECTOR; + data[1] = status; /* active- incative*/ + data[2] = lcdstatus.lock_status; /* full-veiw-locked */ + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting LCD status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + return rc; +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_lock +* +* Description: This function sets lcd access mode +* Input: intf - ipmi interface +* lock - View and modify / View only / Diabled +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ +static int +ipmi_lcd_set_lock(void * intf, char lock) +{ +#define LSCC_DATA_LEN 2 + LCD_STATUS lcdstatus; + int rc =0; + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[5]; + rc=ipmi_lcd_get_status_val(intf,&lcdstatus); + if (rc < 0) + return -1; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 5; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STATUS_SELECTOR; + data[1] = lcdstatus.vKVM_status; /* active- incative */ + data[2] = lock; /* full- veiw-locked */ + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting LCD status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + return rc; +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_single_line_text +* +* Description: This function sets lcd line text +* Input: intf - ipmi interface +* text - lcd string +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ + +static int +ipmi_lcd_set_single_line_text (void * intf, char * text) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[18]; + int bytes_to_store = strlen_(text); + int bytes_stored = 0; + int ii; + int rc = 0; + if (bytes_to_store>IPMI_DELL_LCD_STRING_LENGTH_MAX) + { + lprintf(LOG_ERR, " Out of range Max limit is 62 characters"); + return 1; + + } + else + { + bytes_to_store = MIN(bytes_to_store, IPMI_DELL_LCD_STRING_LENGTH_MAX); + for (ii = 0; ii < 4; ii++) { + /*first block, 2 bytes parms and 14 bytes data*/ + if (0 == ii) { + int size_of_copy = + MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRING1_SIZE); + if (size_of_copy < 0) /* allow 0 string length*/ + break; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = size_of_copy + 4; /* chars, selectors and sizes*/ + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STRING_SELECTOR; + data[1] = ii; /* block number to use (0)*/ + data[2] = 0; /*string encoding*/ + data[3] = bytes_to_store; /* total string length*/ + memcpy (data+4, text+bytes_stored, size_of_copy); + bytes_stored += size_of_copy; + } else { + int size_of_copy = + MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRINGN_SIZE); + if (size_of_copy <= 0) + break; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = size_of_copy + 2; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STRING_SELECTOR; + data[1] = ii; /* block number to use (1,2,3)*/ + memcpy (data+2, text+bytes_stored, size_of_copy); + bytes_stored += size_of_copy; + } + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error setting text data: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + } + } + return rc; +} + +/***************************************************************** +* Function Name: ipmi_lcd_set_text +* +* Description: This function sets lcd line text +* Input: intf - ipmi interface +* text - lcd string +* line_number- line number + +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ + +static int +ipmi_lcd_set_text(void * intf, char * text, int line_number) +{ + int rc = 0; + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_LCD_CAPS * lcd_caps; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; + data[2] = 0; /* set selector (n/a)*/ + data[3] = 0; /* block selector (n/a)*/ + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf("Error getting LCD capabilities: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + lcd_caps = (IPMI_DELL_LCD_CAPS *)(void *)rsp; + + if (lcd_caps->number_lines > 0) { + rc = ipmi_lcd_set_single_line_text (intf, text); + } else { + lprintf(LOG_ERR, "LCD does not have any lines that can be set"); + rc = -1; + } + + + return rc; +} + +/***************************************************************** +* Function Name: ipmi_lcd_configure_wh +* +* Description: This function updates the current lcd configuration +* Input: intf - ipmi interface +* lcdqualifier- lcd quallifier +* errordisp - error number +* line_number-line number +* text - lcd string +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ + +static int +ipmi_lcd_configure_wh (void * intf, uint32_t mode , + uint16_t lcdqualifier, uint8_t errordisp, + int8_t line_number, char * text) +{ + int rc = 0; + + + if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == mode) + /* Any error was reported earlier. */ + rc = ipmi_lcd_set_text(intf, text, line_number); + + + if (rc == 0) + + rc = ipmi_lcd_set_configure_command_wh (intf, mode ,lcdqualifier,errordisp); + + return rc; +} + + +/***************************************************************** +* Function Name: ipmi_lcd_configure +* +* Description: This function updates the current lcd configuration +* Input: intf - ipmi interface +* command- lcd command +* line_number-line number +* text - lcd string +* Output: +* Return: -1 on error +* 0 if successful +* +******************************************************************/ + +static int +ipmi_lcd_configure (void * intf, int command, + int8_t line_number, char * text) +{ + int rc = 0; + + if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == command) + rc = ipmi_lcd_set_text(intf, text, line_number); + + if (rc == 0) + rc = ipmi_lcd_set_configure_command (intf, command); + + return rc; +} + + +/***************************************************************** +* Function Name: ipmi_lcd_usage +* +* Description: This function prints help message for lcd command +* Input: +* Output: +* +* Return: +* +******************************************************************/ + +static void +ipmi_lcd_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "Generic DELL HW:"); + lprintf(LOG_NOTICE, " lcd set {none}|{default}|{custom <text>}"); + lprintf(LOG_NOTICE, " Set LCD text displayed during non-fault conditions"); + + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "iDRAC 11g or iDRAC 12g:"); + lprintf(LOG_NOTICE, " lcd set {mode}|{lcdqualifier}|{errordisplay}"); + lprintf(LOG_NOTICE, " Allows you to set the LCD mode and user-definedstring."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set mode {none}|{modelname}|{ipv4address}|{macaddress}|"); + lprintf(LOG_NOTICE, " {systemname}|{servicetag}|{ipv6address}|{ambienttemp}"); + lprintf(LOG_NOTICE, " {systemwatt }|{assettag}|{userdefined}<text>"); + lprintf(LOG_NOTICE, " Allows you to set the LCD display mode to any of the preceding parameters"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set lcdqualifier {watt}|{btuphr}|{celsius}|{fahrenheit}"); + lprintf(LOG_NOTICE, " Allows you to set the unit for the system ambient temperature mode."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set errordisplay {sel}|{simple}"); + lprintf(LOG_NOTICE, " Allows you to set the error display."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd info"); + lprintf(LOG_NOTICE, " Show LCD text that is displayed during non-fault conditions"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set vkvm{active}|{inactive}"); + lprintf(LOG_NOTICE, " Set vKVM active and inactive, message will be displayed on lcd"); + lprintf(LOG_NOTICE, " when vKVM is active and vKVM session is in progress"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set frontpanelaccess {viewandmodify}|{viewonly}|{disabled}"); + lprintf(LOG_NOTICE, " Set LCD mode to view and modify, view only or disabled "); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd status"); + lprintf(LOG_NOTICE, " Show LCD Status for vKVM display<active|inactive>"); + lprintf(LOG_NOTICE, " and Front Panel access mode {viewandmodify}|{viewonly}|{disabled} "); + lprintf(LOG_NOTICE, ""); +} + +/***************************************************************** +* Function Name: ipmi_delloem_mac_main +* +* Description: This function processes the delloem mac command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + + +static int ipmi_delloem_mac_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + if (argc > 1 && strcmp(argv[current_arg], "help") == 0) + { + ipmi_mac_usage(); + return 0; + } + ipmi_idracvalidator_command(intf); + if (argc == 1) /*( || (strncmp(argv[current_arg], "list\0", 5) == 0) )*/ + { + rc = ipmi_macinfo(intf, 0xff); + } + else if (strncmp(argv[current_arg], "get\0", 4) == 0) + { + int currIdInt; + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_mac_usage(); + return -1; + } + if(make_int(argv[current_arg],&currIdInt) < 0) { + lprintf(LOG_ERR, "Invalid NIC number. The NIC number should be between 0-8\n"); + return -1; + } + if( (currIdInt > 8) || (currIdInt < 0) ) + { + lprintf(LOG_ERR, "Invalid NIC number. The NIC number should be between 0-8\n"); + return -1; + } + rc = ipmi_macinfo(intf, currIdInt); + } + else + { + ipmi_mac_usage(); + } + return(rc); +} + + +/***************************************************************** +* Function Name: make_int +* +* Description: This function convert string into integer +* Input: str - decimal number string +* Output: value - integer value +* Return: +* +******************************************************************/ +static int make_int(const char *str, int *value) +{ + char *tmp=NULL; + *value = (int)strtol(str,&tmp,0); + if ( tmp-str != strlen(str) ) + { + return -1; + } + return 0; +} + + + + + +EmbeddedNICMacAddressType EmbeddedNICMacAddress; + +EmbeddedNICMacAddressType_10G EmbeddedNICMacAddress_10G; + +static void InitEmbeddedNICMacAddressValues () +{ + uint8_t i; + uint8_t j; + + + for (i=0;i<MAX_LOM;i++) + { +#ifdef LOM_OLD + EmbeddedNICMacAddress.LOMMacAddress[i].BladSlotNumber = 0; + EmbeddedNICMacAddress.LOMMacAddress[i].MacType = LOM_MACTYPE_RESERVED; + EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus = LOM_ETHERNET_RESERVED; + EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber = 0; + EmbeddedNICMacAddress.LOMMacAddress[i].Reserved = 0; +#else + EmbeddedNICMacAddress.LOMMacAddress[i].b0 = 0xF0; + EmbeddedNICMacAddress.LOMMacAddress[i].b1 = 0x00; +#endif + for (j=0;j<MACADDRESSLENGH;j++) + { + EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j] = 0; + EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j] = 0; + } + } +} + +uint8_t UseVirtualMacAddress = 0; +#define VIRTUAL_MAC_OFFSET (2) +static int ipmi_macinfo_drac_idrac_virtual_mac(void* intf,uint8_t NicNum) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t VirtualMacAddress [MACADDRESSLENGH]; + uint8_t input_length=0; + uint8_t j; + //uint8_t length; + uint8_t i; + + + if (0xff==NicNum || IDRAC_NIC_NUMBER==NicNum ) + { + UseVirtualMacAddress = 0; + + input_length = 0; + msg_data[input_length++] = 1; /*Get*/ + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_IDRAC_VIRTUAL_MAC; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { return rv; } + + if( (IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type) ) { + // Get the Chasiss Assigned MAC Addresss for 12g Only + memcpy(VirtualMacAddress,&rsp[1],MACADDRESSLENGH); + + for (i=0;i<MACADDRESSLENGH;i++) + { + if (0 != VirtualMacAddress [i]) + { + UseVirtualMacAddress = 1; + } + } + // Get the Server Assigned MAC Addresss for 12g Only + if(!UseVirtualMacAddress) { + memcpy(VirtualMacAddress,&rsp[1+MACADDRESSLENGH],MACADDRESSLENGH); + + for (i=0;i<MACADDRESSLENGH;i++) + { + if (0 != VirtualMacAddress [i]) + { + UseVirtualMacAddress = 1; + } + } + } + } else { + memcpy(VirtualMacAddress,&rsp[VIRTUAL_MAC_OFFSET],MACADDRESSLENGH); + + for (i=0;i<MACADDRESSLENGH;i++) + { + if (0 != VirtualMacAddress [i]) + { + UseVirtualMacAddress = 1; + } + } + } + if (0 == UseVirtualMacAddress) + return -1; + if (IMC_IDRAC_10G == IMC_Type) + printf ("\nDRAC MAC Address "); + else if ( (IMC_IDRAC_11G_MODULAR == IMC_Type) || (IMC_IDRAC_11G_MONOLITHIC== IMC_Type) ) + printf ("\niDRAC6 MAC Address "); + else if ( (IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type) ) + printf ("\niDRAC7 MAC Address "); + + for (j=0;j<5;j++) + printf("%02x:",VirtualMacAddress[j]); + printf("%02x",VirtualMacAddress[j]); /*5*/ + + printf ("\n\r"); + + } + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_macinfo_drac_idrac_mac +* +* Description: This function retrieves the mac address of DRAC or iDRAC +* Input: NicNum +* Output: +* Return: +* +******************************************************************/ + +static int ipmi_macinfo_drac_idrac_mac(void* intf,uint8_t NicNum) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + uint8_t iDRAC6MacAddressByte[MACADDRESSLENGH]; + uint8_t j; + + ipmi_macinfo_drac_idrac_virtual_mac (intf,NicNum); + + + if ((0xff==NicNum || IDRAC_NIC_NUMBER==NicNum) && 0 == UseVirtualMacAddress) + { + + input_length = 0; + + msg_data[input_length++] = LAN_CHANNEL_NUMBER; + msg_data[input_length++] = MAC_ADDR_PARAM; + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + + req.msg.netfn = TRANSPORT_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_LAN_PARAM_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting MAC Address: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + memcpy(iDRAC6MacAddressByte,&rsp[PARAM_REV_OFFSET],MACADDRESSLENGH); + + if (IMC_IDRAC_10G == IMC_Type) + printf ("\n\rDRAC MAC Address "); + else if ((IMC_IDRAC_11G_MODULAR == IMC_Type) || (IMC_IDRAC_11G_MONOLITHIC== IMC_Type)) + printf ("\n\riDRAC6 MAC Address "); + else if ((IMC_IDRAC_12G_MODULAR == IMC_Type) || (IMC_IDRAC_12G_MONOLITHIC== IMC_Type)) + printf ("\n\riDRAC7 MAC Address "); + else + printf ("\n\riDRAC6 MAC Address "); + + for (j=0;j<5;j++) + printf("%02x:",iDRAC6MacAddressByte[j]); + printf("%02x",iDRAC6MacAddressByte[j]); + + printf ("\n\r"); + } + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_macinfo_10g +* +* Description: This function retrieves the mac address of LOMs +* Input: intf - ipmi interface + NicNum - NIC number +* Output: +* Return: +* +******************************************************************/ + +static int ipmi_macinfo_10g (void* intf, uint8_t NicNum) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + + uint8_t j; + uint8_t i; + + uint8_t Total_No_NICs = 0; + + + InitEmbeddedNICMacAddressValues (); + + memset(msg_data, 0, sizeof(msg_data)); + input_length = 0; + msg_data[input_length++] = 0x00; /* Get Parameter Command */ + msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_9G_10G; /* OEM Param */ + + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = APP_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_SYSTEM_INFO_CMD; + req.msg.data = msg_data; + + + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting MAC Address: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + if (fdebug) dump_buf("GetMacResp_10G",rsp,rsp_len,0); + + Total_No_NICs = (uint8_t) rsp[PARAM_REV_OFFSET]; /* Byte 1: Total Number of Embedded NICs */ + + if (IDRAC_NIC_NUMBER != NicNum) + { + if (0xff == NicNum) + { + printf ("\n\rSystem LOMs"); + } + printf("\n\rNIC Number\tMAC Address\n\r"); + + memcpy(&EmbeddedNICMacAddress_10G,&rsp[PARAM_REV_OFFSET+TOTAL_N0_NICS_INDEX],Total_No_NICs* MACADDRESSLENGH); + + + /*Read the LOM type and Mac Addresses */ + + for (i=0;i<Total_No_NICs;i++) + { + if ((0xff==NicNum) || (i == NicNum) ) + { + printf ("\n\r%d",i); + printf ("\t\t"); + for (j=0;j<5;j++) + { + printf("%02x:",EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j]); + } + printf("%02x",EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j]); + } + } + printf ("\n\r"); + + } + + ipmi_macinfo_drac_idrac_mac(intf,NicNum); + + + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_macinfo_11g +* +* Description: This function retrieves the mac address of LOMs +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ + +static int ipmi_macinfo_11g (void* intf, uint8_t NicNum) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t msg_data[30]; + uint8_t input_length=0; + uint8_t len; + uint8_t j; + uint8_t offset; + uint8_t maxlen; + uint8_t loop_count; + uint8_t i; + uint8_t lom_mactype; + uint8_t lom_nicnum; + uint8_t lom_ethstat; + uint8_t *lom_mac; + // uint8_t LOMStatus = 0; + // uint8_t PlayingDead = 0; + + offset = 0; + len = 8; /*eigher 8 or 16 */ + maxlen = 64; + loop_count = maxlen / len; + + InitEmbeddedNICMacAddressValues (); + + memset(msg_data, 0, sizeof(msg_data)); + input_length = 0; + msg_data[input_length++] = 0x00; /* Get Parameter Command */ + msg_data[input_length++] = EMB_NIC_MAC_ADDRESS_11G; /* OEM Param */ + + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + msg_data[input_length++] = 0x00; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = APP_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_SYSTEM_INFO_CMD; + req.msg.data = msg_data; + + + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting MAC Address: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + + len = 8; /*eigher 8 or 16 */ + maxlen = (uint8_t) rsp[0+PARAM_REV_OFFSET]; + loop_count = maxlen / len; + + if (IDRAC_NIC_NUMBER != NicNum) + { + if (0xff == NicNum) + { + printf ("\n\rSystem LOMs"); + } + printf("\n\rNIC Number\tMAC Address\t\tStatus\n\r"); + + + /*Read the LOM type and Mac Addresses */ + offset=0; + for (i=0;i<loop_count;i++,offset=offset+len) + { + input_length = 4; + msg_data[input_length++] = offset; + msg_data[input_length++] = len; + + req.msg.netfn = APP_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_SYSTEM_INFO_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting MAC Address: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x\n", rv); + return rv; + } + if (fdebug) { + printf("ipmi_macinfo_11g(%d) i=%d offset=%d\n",NicNum,i,offset); + dump_buf("GetMacResp",rsp,rsp_len,0); + } + + memcpy(&(EmbeddedNICMacAddress.LOMMacAddress[i]),&rsp[PARAM_REV_OFFSET],len); + +#ifdef LOM_OLD + lom_ethstat = EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus; + lom_mactype = EmbeddedNICMacAddress.LOMMacAddress[i].MacType; + lom_nicnum = EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber; + lom_mac = &EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[0]; +#else + lom_ethstat = ((EmbeddedNICMacAddress.LOMMacAddress[i].b0 & 0xc0) >> 6); + lom_mactype = ((EmbeddedNICMacAddress.LOMMacAddress[i].b0 & 0x30) >> 4); + /* lom_bladslot = (b0 & 0x0f); */ + lom_nicnum = (EmbeddedNICMacAddress.LOMMacAddress[i].b1 & 0x1f); + lom_mac = &EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[0]; + if (fdebug) { + printf("\n\rlom_ethstat=%x lom_mactype=%x lom_nicnum=%x\n", + lom_ethstat,lom_mactype,lom_nicnum); + printf("MacAdrB=%02x:%02x:%02x:%02x:%02x:%02x\n", + lom_mac[0], lom_mac[1], lom_mac[2], + lom_mac[3], lom_mac[4], lom_mac[5]); + printf("\n\rrsp_mac=%02x:%02x:%02x:%02x:%02x:%02x\n", + rsp[3], rsp[4], rsp[5], rsp[6], rsp[7], rsp[8]); + } + lom_mac = &rsp[3]; +#endif + + if (LOM_MACTYPE_ETHERNET == lom_mactype) + { + + if ( (0xff==NicNum) || (NicNum == lom_nicnum) ) + { + printf ("\n\r%d",lom_nicnum); + printf ("\t\t"); + for (j=0;j<5;j++) + printf("%02x:",lom_mac[j]); + printf("%02x",lom_mac[j]); + + if (LOM_ETHERNET_ENABLED == lom_ethstat) + printf ("\tEnabled"); + else + printf ("\tDisabled"); + } + } + + } + printf ("\n\r"); + + } + + ipmi_macinfo_drac_idrac_mac(intf,NicNum); + + return 0; + +} + + + +/***************************************************************** +* Function Name: ipmi_macinfo +* +* Description: This function retrieves the mac address of LOMs +* Input: intf - ipmi interface +* Output: +* Return: +* +******************************************************************/ + +static int ipmi_macinfo (void* intf, uint8_t NicNum) +{ + if (IMC_IDRAC_10G == IMC_Type) + { + return ipmi_macinfo_10g (intf,NicNum); + } + else if ((IMC_IDRAC_11G_MODULAR == IMC_Type || IMC_IDRAC_11G_MONOLITHIC== IMC_Type ) || + (IMC_IDRAC_12G_MODULAR == IMC_Type || IMC_IDRAC_12G_MONOLITHIC== IMC_Type ) ) + { + return ipmi_macinfo_11g (intf,NicNum); + } + else + { + lprintf(LOG_ERR, " Error in getting MAC Address : Not supported platform"); + return 0; + } +} + + +/***************************************************************** +* Function Name: ipmi_mac_usage +* +* Description: This function prints help message for mac command +* Input: +* Output: +* +* Return: +* +******************************************************************/ + +static void +ipmi_mac_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " mac list"); + lprintf(LOG_NOTICE, " Lists the MAC address of LOMs"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " mac get <NIC number>"); + lprintf(LOG_NOTICE, " Shows the MAC address of specified LOM. 0-7 System LOM, 8- DRAC/iDRAC."); + lprintf(LOG_NOTICE, ""); +} + +/***************************************************************** +* Function Name: ipmi_delloem_lan_main +* +* Description: This function processes the delloem lan command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_lan_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + int nic_selection = 0; + char nic_set[2] = {0}; + current_arg++; + if (argv[current_arg] == NULL || strcmp(argv[current_arg], "help") == 0) + { + ipmi_lan_usage(); + return 0; + } + ipmi_idracvalidator_command(intf); + if (!IsLANSupported()) + { + printf("lan is not supported on this system.\n"); + return -1; + } + else if (strncmp(argv[current_arg], "set\0", 4) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_lan_usage(); + return -1; + } + if(iDRAC_FLAG == IDRAC_12G) { + nic_selection = get_nic_selection_mode_12g(intf,current_arg,argv,nic_set); + if (INVALID == nic_selection) + { + ipmi_lan_usage(); + return -1; + } else if(INVAILD_FAILOVER_MODE == nic_selection) { + printf(INVAILD_FAILOVER_MODE_STRING); + return 0; + } else if(INVAILD_FAILOVER_MODE_SETTINGS == nic_selection){ + printf(INVAILD_FAILOVER_MODE_SET); + return 0; + } else if(INVAILD_SHARED_MODE == nic_selection){ + printf(INVAILD_SHARED_MODE_SET_STRING); + return 0; + } + + rc = ipmi_lan_set_nic_selection_12g(intf,nic_set); + } + else + { + nic_selection = get_nic_selection_mode(current_arg,argv); + + if (INVALID == nic_selection) + { + ipmi_lan_usage(); + return -1; + } + if(IMC_IDRAC_11G_MODULAR == IMC_Type) { + printf(INVAILD_SHARED_MODE_SET_STRING); + return 0; + } + rc = ipmi_lan_set_nic_selection(intf,nic_selection); + } + return 0; + } + else if (strncmp(argv[current_arg], "get\0", 4) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + rc = ipmi_lan_get_nic_selection(intf); + return rc; + } + else if (strncmp(argv[current_arg], "active\0", 7) == 0) + { + rc = ipmi_lan_get_active_nic(intf); + return rc; + } + else + { + ipmi_lan_usage(); + } + + } + else + { + ipmi_lan_usage(); + return -1; + } + return(rc); +} + + +static int IsLANSupported () +{ + if (IMC_IDRAC_11G_MODULAR == IMC_Type) + return 0; + return 1; +} + + +int get_nic_selection_mode_12g (void* intf,int current_arg, char ** argv, char *nic_set) +{ + int failover = 0; + + // First get the current settings. + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + + input_length = 0; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + + req.msg.cmd = GET_NIC_SELECTION_12G_CMD; + + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting NIC selection: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + + nic_set[0] = rsp[0]; + nic_set[1] = rsp[1]; + + + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "dedicated\0", 10)) + { + nic_set[0] = 1; + nic_set[1] = 0; + return 0; + } + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "shared\0", 7)) + { + + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "with\0", 5)) + { + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "failover\0", 9)) + { + failover = 1; + } + if(failover) + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom1\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 2) + { + return INVAILD_FAILOVER_MODE; + } else if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 2; + } + else { + nic_set[0] = 2; + if(nic_set[1] == 2) + nic_set[1] = 0; + } + return 0; + } + else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom2\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 3) + { + return INVAILD_FAILOVER_MODE; + } else if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 3; + } + else { + nic_set[0] = 3; + if(nic_set[1] == 3) + nic_set[1] = 0; + + } + return 0; + } + else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom3\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 4) + { + return INVAILD_FAILOVER_MODE; + } else if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 4; + } + else { + nic_set[0] = 4; + if(nic_set[1] == 4) + nic_set[1] = 0; + } + return 0; + } + else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom4\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 5) + { + return INVAILD_FAILOVER_MODE; + } else if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 5; + } + else { + nic_set[0] = 5; + if(nic_set[1] == 5) + nic_set[1] = 0; + } + return 0; + } + else if (failover && NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "none\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(failover) { + if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 0; + } + return 0; + } + else if (failover && NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "all\0", 4)) + { + } + else + return INVALID; + + current_arg++; + if (failover && NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "loms\0", 5)) + { + if(IMC_IDRAC_12G_MODULAR == IMC_Type) + { + return INVAILD_SHARED_MODE; + } + if(nic_set[0] == 1) { + return INVAILD_FAILOVER_MODE_SETTINGS; + } + nic_set[1] = 6; + return 0; + } + + return INVALID; + +} + + +static int get_nic_selection_mode (int current_arg, char ** argv) +{ + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "dedicated\0", 10)) + { + return DEDICATED; + } + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "shared\0", 7)) + { + if (NULL == argv[current_arg+1] ) + return SHARED; + } + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "with\0", 5)) + { + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "failover\0", 9)) + { + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "lom2\0", 5)) + { + return SHARED_WITH_FAILOVER_LOM2; + } + else if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "all\0", 4)) + { + } + else + return INVALID; + + current_arg++; + if (NULL!= argv[current_arg] && 0 == strncmp(argv[current_arg], "loms\0", 5)) + { + return SHARED_WITH_FAILOVER_ALL_LOMS; + } + + return INVALID; + +} + + +static int ipmi_lan_set_nic_selection_12g (void* intf, uint8_t* nic_selection) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + + input_length = 0; + + msg_data[input_length++] = nic_selection[0]; + msg_data[input_length++] = nic_selection[1]; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = SET_NIC_SELECTION_12G_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in setting NIC selection: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + printf("configured successfully"); + + return 0; +} + + +static int ipmi_lan_set_nic_selection (void* intf, uint8_t nic_selection) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + //uint8_t j; + + input_length = 0; + + msg_data[input_length++] = nic_selection; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = SET_NIC_SELECTION_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in setting NIC selection: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + printf("configured successfully"); + + return 0; +} + +static int ipmi_lan_get_nic_selection (void* intf) +{ + uint8_t nic_selection=-1; + uint8_t nic_selection_failover = 0; + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + //uint8_t j; + + input_length = 0; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + if(iDRAC_FLAG == IDRAC_12G) + req.msg.cmd = GET_NIC_SELECTION_12G_CMD; + else + req.msg.cmd = GET_NIC_SELECTION_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting NIC selection: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + nic_selection = rsp[0]; + + if(iDRAC_FLAG == IDRAC_12G) + { + + nic_selection_failover = rsp[1]; + if ((nic_selection < 6) && (nic_selection > 0) && (nic_selection_failover < 7)) + { + if(nic_selection == 1) { + printf ("%s\n",NIC_Selection_Mode_String_12g[nic_selection-1]); + } else if(nic_selection) { + printf ("Shared LOM : %s\n",NIC_Selection_Mode_String_12g[nic_selection-1]); + if(nic_selection_failover == 0) + printf ("Failover LOM : None\n"); + else if(nic_selection_failover >= 2 && nic_selection_failover <= 6) + printf ("Failover LOM : %s\n",NIC_Selection_Mode_String_12g[nic_selection_failover + 3]); + } + + } + else + { + lprintf(LOG_ERR, " Error Outof bond Value received (%d) (%d) \n",nic_selection,nic_selection_failover); + return -1; + } + } + else + { + printf ("%s\n",NIC_Selection_Mode_String[nic_selection]); + } + + return 0; +} + +static int ipmi_lan_get_active_nic (void* intf) +{ + uint8_t active_nic=0; + uint8_t current_lom =0; + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[30]; + uint8_t input_length=0; + + input_length = 0; + + msg_data[input_length++] = 0; /*Get current LOM*/ + msg_data[input_length++] = 0; /*Reserved*/ + msg_data[input_length++] = 0; /*Reserved*/ + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_ACTIVE_NIC_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting Current LOM: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + current_lom = rsp[0]; + + input_length = 0; + + msg_data[input_length++] = 1; //Get Link status + msg_data[input_length++] = 0; //Reserved + msg_data[input_length++] = 0; //Reserved + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_ACTIVE_NIC_CMD; + req.msg.data = msg_data; + req.msg.data_len = input_length; + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error in getting Active LOM Status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + + active_nic = rsp[1]; + if (current_lom < 5 && active_nic) + printf ("\n%s\n",ActiveLOM_String[current_lom]); + else + printf ("\n%s\n",ActiveLOM_String[5]); + + return 0; +} + + +static void +ipmi_lan_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lan set <Mode> "); + lprintf(LOG_NOTICE, " sets the NIC Selection Mode :"); + lprintf(LOG_NOTICE, " on iDRAC12g :"); + + lprintf(LOG_NOTICE, " dedicated, shared with lom1, shared with lom2,shared with lom3,shared "); + lprintf(LOG_NOTICE, " with lom4,shared with failover lom1,shared with failover lom2,shared "); + lprintf(LOG_NOTICE, " with failover lom3,shared with failoverlom4,shared with Failover all "); + lprintf(LOG_NOTICE, " loms, shared with Failover None)."); + lprintf(LOG_NOTICE, " on other systems :"); + lprintf(LOG_NOTICE, " dedicated, shared, shared with failoverlom2,"); + lprintf(LOG_NOTICE, " shared with Failover all loms."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lan get "); + lprintf(LOG_NOTICE, " on iDRAC12g :"); + lprintf(LOG_NOTICE, " returns the current NIC Selection Mode (dedicated, shared with lom1, shared "); + lprintf(LOG_NOTICE, " with lom2, shared with lom3, shared with lom4,shared with failover lom1,"); + lprintf(LOG_NOTICE, " shared with failover lom2,shared with failover lom3,shared with failover "); + lprintf(LOG_NOTICE, " lom4,shared with Failover all loms,shared with Failover None)."); + lprintf(LOG_NOTICE, " on other systems :"); + lprintf(LOG_NOTICE, " dedicated, shared, shared with failover,"); + lprintf(LOG_NOTICE, " lom2, shared with Failover all loms."); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lan get active"); + lprintf(LOG_NOTICE, " Get the current active LOMs (LOM1, LOM2, LOM3, LOM4, NONE)."); + lprintf(LOG_NOTICE, ""); + +} + +/***************************************************************** +* Function Name: ipmi_delloem_powermonitor_main +* +* Description: This function processes the delloem powermonitor command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_powermonitor_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + if (argc > 1 && strcmp(argv[current_arg], "help") == 0) + { + ipmi_powermonitor_usage(); + return 0; + } + ipmi_idracvalidator_command(intf); + if (argc == 1) + { + rc = ipmi_powermgmt(intf); + } + else if (strncmp(argv[current_arg], "status\0", 7) == 0) + { + rc = ipmi_powermgmt(intf); + } + + else if (strncmp(argv[current_arg], "clear\0", 6) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_powermonitor_usage(); + return -1; + } + else if (strncmp(argv[current_arg], "peakpower\0", 10) == 0) + { + rc = ipmi_powermgmt_clear(intf, 1); + } + else if (strncmp(argv[current_arg], "cumulativepower\0", 16) == 0) + { + rc = ipmi_powermgmt_clear(intf, 0); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + + } + + + else if (strncmp(argv[current_arg], "powerconsumption\0", 17) == 0) + { + current_arg++; + + if (argv[current_arg] == NULL) + { + + rc=ipmi_print_get_power_consmpt_data(intf,watt); + + } + else if (strncmp(argv[current_arg], "watt\0", 5) == 0) + { + + rc = ipmi_print_get_power_consmpt_data(intf, watt); + } + else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) + { + rc = ipmi_print_get_power_consmpt_data(intf, btuphr); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + } + else if (strncmp(argv[current_arg], "powerconsumptionhistory\0", 23) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + rc=ipmi_print_power_consmpt_history(intf,watt); + + } + else if (strncmp(argv[current_arg], "watt\0", 5) == 0) + { + rc = ipmi_print_power_consmpt_history(intf, watt); + } + else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) + { + rc = ipmi_print_power_consmpt_history(intf, btuphr); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + + } + + else if (strncmp(argv[current_arg], "getpowerbudget\0", 15) == 0) + { + current_arg++; + if (argv[current_arg] == NULL) + { + rc=ipmi_print_power_cap(intf,watt); + + } + else if (strncmp(argv[current_arg], "watt\0", 5) == 0) + { + rc = ipmi_print_power_cap(intf, watt); + } + else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) + { + rc = ipmi_print_power_cap(intf, btuphr); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + + } + + else if (strncmp(argv[current_arg], "setpowerbudget\0", 15) == 0) + { + int val; + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_powermonitor_usage(); + return -1; + } + if (strchr(argv[current_arg], '.')) + { + lprintf(LOG_ERR, " Cap value in Watts, Btu/hr or percent should be whole number"); + return -1; + } + make_int(argv[current_arg],&val); + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_powermonitor_usage(); + } + else if (strncmp(argv[current_arg], "watt\0", 5) == 0) + { + rc=ipmi_set_power_cap(intf,watt,val); + } + else if (strncmp(argv[current_arg], "btuphr\0", 7) == 0) + { + rc=ipmi_set_power_cap(intf, btuphr,val); + } + else if (strncmp(argv[current_arg], "percent\0", 8) == 0) + { + rc=ipmi_set_power_cap(intf,percent,val); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + + } + + else if (strncmp(argv[current_arg], "enablepowercap\0", 15) == 0) + { + rc = ipmi_set_power_capstatus_command(intf,1); + } + + else if (strncmp(argv[current_arg], "disablepowercap\0", 16) == 0) + { + rc = ipmi_set_power_capstatus_command(intf,0); + } + else + { + ipmi_powermonitor_usage(); + return -1; + } + if (sdrcache != NULL) free_sdr_cache(sdrcache); + return(rc); +} + + +/***************************************************************** +* Function Name: ipmi_time_to_str +* +* Description: This function converts ipmi time format into gmtime format +* Input: rawTime - ipmi time format +* Output: strTime - gmtime format +* +* Return: +* +******************************************************************/ + +static void +ipmi_time_to_str(time_t rawTime, char* strTime) +{ + struct tm * tm; + char *temp; + tm = gmtime(&rawTime); + + temp = asctime(tm); + + strcpy(strTime,temp); +} + +#ifdef NOT_USED +static int ipmi_get_sensor_reading(void *intf , + unsigned char sensorNumber, + SensorReadingType* pSensorReadingData); +/***************************************************************** +* Function Name: ipmi_get_sensor_reading +* +* Description: This function retrieves a raw sensor reading +* Input: sensorOwner - sensor owner id +* sensorNumber - sensor id +* intf - ipmi interface +* Output: sensorReadingData - ipmi response structure +* Return: 1 on error +* 0 if successful +* +******************************************************************/ +static int +ipmi_get_sensor_reading(void *intf , + unsigned char sensorNumber, + SensorReadingType* pSensorReadingData) +{ + struct ipmi_rq req; + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len; + int rc = 0; + // uint8_t save_addr; + + memset(&req, 0, sizeof (req)); + req.msg.netfn = IPMI_NETFN_SE; + req.msg.lun = 0; + req.msg.cmd = (uint8_t)(GET_SENSOR_READING | 0x0ff); + req.msg.data = &sensorNumber; + req.msg.data_len = 1; + + if (NULL == pSensorReadingData) + return -1; + memset(pSensorReadingData,0, sizeof(SensorReadingType)); + + rc = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rc) return 1; + + memcpy(pSensorReadingData, rsp, sizeof(SensorReadingType)); + + /* if sensor messages are disabled, return error*/ + if ((!(rsp[1]& 0xC0)) || ((rsp[1] & 0x20))) { + rc =1; + } + return rc; +} +#endif + + +/***************************************************************** +* Function Name: ipmi_get_power_capstatus_command +* +* Description: This function gets the power cap status +* Input: intf - ipmi interface +* Global: PowercapSetable_flag - power cap status +* Output: +* +* Return: +* +******************************************************************/ +static int +ipmi_get_power_capstatus_command (void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[2]; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS; + req.msg.data_len = 2; + req.msg.data = data; + data[0] = 01; + data[1] = 0xFF; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting powercap status: "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", + rv,decode_cc(0,rv)); + return rv; + } + if (rsp[0]&0x02) + PowercapSetable_flag=1; + if(rsp[0]&0x01) + PowercapstatusFlag=1; + return 0; +} + +/***************************************************************** +* Function Name: ipmi_set_power_capstatus_command +* +* Description: This function sets the power cap status +* Input: intf - ipmi interface +* val - power cap status +* Output: +* +* Return: +* +******************************************************************/ + +static int +ipmi_set_power_capstatus_command (void * intf,uint8_t val) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[2]; + if(ipmi_get_power_capstatus_command(intf) < 0) + return -1; + + if (PowercapSetable_flag!=1) + { + lprintf(LOG_ERR, " Can not set powercap on this system"); + return -1; + } + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = IPMI_DELL_POWER_CAP_STATUS; + req.msg.data_len = 2; + req.msg.data = data; + + data[0] = 00; + data[1] = val; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error setting powercap status: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; //return unlicensed Error code + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + return 0; +} + + + +/***************************************************************** +* Function Name: ipmi_powermgmt +* +* Description: This function print the powermonitor details +* Input: intf - ipmi interface +* Output: +* +* Return: +* +******************************************************************/ +static int ipmi_powermgmt(void* intf) +{ + time_t now; + struct tm* tm; + char* dte; + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t msg_data[2]; + uint32_t cumStartTimeConv; + uint32_t cumReadingConv; + uint32_t maxPeakStartTimeConv; + uint32_t ampPeakTimeConv; + uint16_t ampReadingConv; + uint32_t wattPeakTimeConv; + uint32_t wattReadingConv; + uint32_t bmctimeconv; + uint32_t * bmctimeconvval; + + IPMI_POWER_MONITOR* pwrMonitorInfo; + + + char cumStartTime[26]; + char maxPeakStartTime[26]; + char ampPeakTime[26]; + char wattPeakTime[26]; + char bmctime[26]; + + // float cumReading; + int ampReading; + int wattReading; + int ampReadingRemainder; + // int round; + // int round2; + int remainder; + + now = time(0); + tm = gmtime(&now); + dte = asctime(tm); + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.lun = 0; + req.msg.cmd = IPMI_CMD_GET_SEL_TIME; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting BMC time info "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + bmctimeconvval=(uint32_t*)rsp; +#if WORDS_BIGENDIAN + bmctimeconv=BSWAP_32(*bmctimeconvval); +#else + bmctimeconv=*bmctimeconvval; +#endif + + /* get powermanagement info*/ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0x0; + req.msg.cmd = GET_PWRMGMT_INFO_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + memset(msg_data, 0, 2); + msg_data[0] = 0x07; + msg_data[1] = 0x01; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power management info "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + pwrMonitorInfo = (IPMI_POWER_MONITOR*)rsp; + +#if WORDS_BIGENDIAN + cumStartTimeConv = BSWAP_32(pwrMonitorInfo->cumStartTime); + cumReadingConv = BSWAP_32(pwrMonitorInfo->cumReading); + maxPeakStartTimeConv = BSWAP_32(pwrMonitorInfo->maxPeakStartTime); + ampPeakTimeConv = BSWAP_32(pwrMonitorInfo->ampPeakTime); + ampReadingConv = BSWAP_16(pwrMonitorInfo->ampReading); + wattPeakTimeConv = BSWAP_32(pwrMonitorInfo->wattPeakTime); + wattReadingConv = BSWAP_16(pwrMonitorInfo->wattReading); +#else + cumStartTimeConv = pwrMonitorInfo->cumStartTime; + cumReadingConv = pwrMonitorInfo->cumReading; + maxPeakStartTimeConv = pwrMonitorInfo->maxPeakStartTime; + ampPeakTimeConv = pwrMonitorInfo->ampPeakTime; + ampReadingConv = pwrMonitorInfo->ampReading; + wattPeakTimeConv = pwrMonitorInfo->wattPeakTime; + wattReadingConv = pwrMonitorInfo->wattReading; +#endif + + ipmi_time_to_str(cumStartTimeConv, cumStartTime); + + ipmi_time_to_str(maxPeakStartTimeConv, maxPeakStartTime); + ipmi_time_to_str(ampPeakTimeConv, ampPeakTime); + ipmi_time_to_str(wattPeakTimeConv, wattPeakTime); + ipmi_time_to_str(bmctimeconv, bmctime); + + now = time(0); + + + remainder = (cumReadingConv % 1000); + cumReadingConv = cumReadingConv / 1000; + remainder = (remainder + 50) / 100; + + ampReading = ampReadingConv; + ampReadingRemainder = ampReading%10; + ampReading = ampReading/10; + + wattReading = wattReadingConv; + + printf("Power Tracking Statistics\n"); + printf("Statistic : Cumulative Energy Consumption\n"); + printf("Start Time : %s", cumStartTime); + printf("Finish Time : %s", bmctime); + printf("Reading : %d.%d kWh\n\n", cumReadingConv, remainder); + + printf("Statistic : System Peak Power\n"); + printf("Start Time : %s", maxPeakStartTime); + printf("Peak Time : %s", wattPeakTime); + printf("Peak Reading : %d W\n\n", wattReading); + + printf("Statistic : System Peak Amperage\n"); + printf("Start Time : %s", maxPeakStartTime); + printf("Peak Time : %s", ampPeakTime); + printf("Peak Reading : %d.%d A\n", ampReading, ampReadingRemainder); + + + return 0; + +} +/***************************************************************** +* Function Name: ipmi_powermgmt_clear +* +* Description: This function clears peakpower / cumulativepower value +* Input: intf - ipmi interface +* clearValue - peakpower / cumulativepower +* Output: +* +* Return: +* +******************************************************************/ +static int +ipmi_powermgmt_clear(void* intf,uint8_t clearValue) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + uint8_t clearType; + uint8_t msg_data[3]; + + if (clearValue) { + clearType = 2; + } else { + clearType = 1; + } + + /* clear powermanagement info*/ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = CLEAR_PWRMGMT_INFO_CMD; + req.msg.data = msg_data; + req.msg.data_len = 3; + + + memset(msg_data, 0, 3); + msg_data[0] = 0x07; + msg_data[1] = 0x01; + msg_data[2] = clearType; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error clearing power values: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + return 0; + +} + +/***************************************************************** +* Function Name: watt_to_btuphr_conversion +* +* Description: This function converts the power value in watt to btuphr +* Input: powerinwatt - power in watt +* +* Output: power in btuphr +* +* Return: +* +******************************************************************/ +static uint64_t watt_to_btuphr_conversion(uint32_t powerinwatt) +{ + uint64_t powerinbtuphr; + powerinbtuphr=(uint64_t)(3.413*powerinwatt); + + return(powerinbtuphr); +} + +/***************************************************************** +* Function Name: btuphr_to_watt_conversion +* +* Description: This function converts the power value in btuphr to watt +* Input: powerinbtuphr - power in btuphr +* +* Output: power in watt +* +* Return: +* +******************************************************************/ +static uint32_t btuphr_to_watt_conversion(uint64_t powerinbtuphr) +{ + uint32_t powerinwatt; + /*returning the floor value*/ + powerinwatt= (uint32_t)(powerinbtuphr/3.413); + return (powerinwatt); +} + +/***************************************************************** +* Function Name: ipmi_get_power_headroom_command +* +* Description: This function prints the Power consumption information +* Input: intf - ipmi interface +* unit - watt / btuphr +* Output: +* +* Return: +* +******************************************************************/ +static int ipmi_get_power_headroom_command (void * intf,uint8_t unit) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint64_t peakpowerheadroombtuphr; + uint64_t instantpowerhearoom; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_PWR_HEADROOM_CMD; + req.msg.data_len = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power headroom status: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + if(verbose>1) + printf("power headroom Data : %x %x %x %x ", + /*need to look into */ rsp[0], rsp[1], rsp[2], rsp[3]); + powerheadroom= *(( POWER_HEADROOM *)rsp); +#if WORDS_BIGENDIAN + powerheadroom.instheadroom = BSWAP_16(powerheadroom.instheadroom); + powerheadroom.peakheadroom = BSWAP_16(powerheadroom.peakheadroom); +#endif + + printf ("Headroom\n\r"); + printf ("Statistic Reading\n\r"); + + if(unit == btuphr) + { + peakpowerheadroombtuphr=watt_to_btuphr_conversion(powerheadroom.peakheadroom); + instantpowerhearoom= watt_to_btuphr_conversion(powerheadroom.instheadroom); + + printf ("System Instantaneous Headroom : %ld BTU/hr\n",instantpowerhearoom); + printf ("System Peak Headroom : %ld BTU/hr\n",peakpowerheadroombtuphr); + } + else + { + printf ("System Instantaneous Headroom : %ld W\n",powerheadroom.instheadroom); + printf ("System Peak Headroom : %ld W\n",powerheadroom.peakheadroom); + } + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_get_power_consumption_data +* +* Description: This function updates the instant Power consumption information +* Input: intf - ipmi interface +* Output: power consumption current reading +* Assumption value will be in Watt. +* +* Return: +* +******************************************************************/ +static int ipmi_get_power_consumption_data(void* intf,uint8_t unit) +{ + int rc = 0; + SensorReadingType sensorReadingData; + uint8_t rsp[IPMI_RSPBUF_SIZE]; + struct sdr_record_list *sdr = NULL; + uchar sdrbuf[SDR_SZ]; + double readingf, warningf, failuref; + int readingbtuphr=0; + int warning_threshbtuphr=0; + int failure_thresbtuphr=0; + int status=0; + int sensor_number = 0; + + if (sdrfile != NULL) { + rc = get_sdr_file(sdrfile,&sdrcache); + if (rc) printf ("Error 0x%02x: Cannot get SDRs from %s\n",rc,sdrfile); + } else if (sdrcache == NULL) { + rc = get_sdr_cache(&sdrcache); + if (rc) printf ("Error 0x%02x: Cannot get SDRs\n",rc); + } + + rc = find_sdr_by_tag(sdrbuf, sdrcache, "System Level", fdebug); + if (rc != 0) + { + printf ("Error %d: Cannot access the System Level sensor data\n",rc); + return rc; + } + sdr = (struct sdr_record_list *)sdrbuf; + + sensor_number = sdrbuf[7]; // sdr->record.full->keys.sensor_num; + if (fdebug) printf("calling GetSensorReading(%x)\n",sensor_number); + rc = GetSensorReading(sensor_number, sdrbuf, + (uchar *)&sensorReadingData.sensorReading); + if (rc != 0) + printf("Error %d getting sensor %x reading\n",rc,sensor_number); + + rc = GetSensorThresholds( sensor_number, rsp); + if (fdebug) printf("GetSensorThresholds(%x) rc = %d\n",sensor_number,rc); + if (rc == 0) + { + readingf = RawToFloat(sensorReadingData.sensorReading,sdrbuf); + warningf = RawToFloat(rsp[4], sdrbuf); + failuref = RawToFloat(rsp[5], sdrbuf); + readingbtuphr = (int)readingf; + warning_threshbtuphr = (int)warningf; + failure_thresbtuphr = (int)failuref; + + if (fdebug) { + printf("Reading 0x%02x = %.2f, Warning 0x%02x = %.2f, Failure 0x%02x = %.2f\n", + sensorReadingData.sensorReading, readingf, + rsp[4], warningf, rsp[5], failuref); + } + + printf ("System Board System Level\n\r"); + if (unit==btuphr) + { + readingbtuphr= watt_to_btuphr_conversion(readingbtuphr); + warning_threshbtuphr= watt_to_btuphr_conversion(warning_threshbtuphr); + failure_thresbtuphr= watt_to_btuphr_conversion( failure_thresbtuphr); + + printf ("Reading : %d BTU/hr\n",readingbtuphr); + printf ("Warning threshold : %d BTU/hr\n",warning_threshbtuphr); + printf ("Failure threshold : %d BTU/hr\n",failure_thresbtuphr); + } + else + { + printf ("Reading : %d W \n",readingbtuphr); + printf ("Warning threshold : %d W \n",(warning_threshbtuphr)); + printf ("Failure threshold : %d W \n",(failure_thresbtuphr)); + } + } + else + { + printf ("Error %d: Cannot access the System Level threshold data\n",rc); + return -1; + } + return status; +} + + + + +/***************************************************************** +* Function Name: ipmi_get_instan_power_consmpt_data +* +* Description: This function updates the instant Power consumption information +* Input: intf - ipmi interface +* Output: instpowerconsumptiondata - instant Power consumption information +* +* Return: +* +******************************************************************/ + +static int ipmi_get_instan_power_consmpt_data(void* intf, + IPMI_INST_POWER_CONSUMPTION_DATA* instpowerconsumptiondata) +{ + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req={0}; + + uint8_t msg_data[2]; + + + /*get instantaneous power consumption command*/ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_PWR_CONSUMPTION_CMD; + + req.msg.data = msg_data; + req.msg.data_len = 2; + + + + memset(msg_data, 0, 2); + + msg_data[0] = 0x0A; + msg_data[1] = 0x00; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power consumption data: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + * instpowerconsumptiondata = * ( (IPMI_INST_POWER_CONSUMPTION_DATA*) (rsp)); +#if WORDS_BIGENDIAN + instpowerconsumptiondata->instanpowerconsumption = BSWAP_16(instpowerconsumptiondata->instanpowerconsumption); + instpowerconsumptiondata->instanApms = BSWAP_16(instpowerconsumptiondata->instanApms); + instpowerconsumptiondata->resv1 = BSWAP_16(instpowerconsumptiondata->resv1); +#endif + + return 0; + + +} + + +/***************************************************************** +* Function Name: ipmi_print_get_instan_power_Amps_data +* +* Description: This function prints the instant Power consumption information +* Input: instpowerconsumptiondata - instant Power consumption information +* Output: +* +* Return: +* +******************************************************************/ +static void ipmi_print_get_instan_power_Amps_data(IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata) +{ + uint16_t intampsval=0; + uint16_t decimalampsval=0; + + + if (instpowerconsumptiondata.instanApms>0) + { + decimalampsval=(instpowerconsumptiondata.instanApms%10); + intampsval=instpowerconsumptiondata.instanApms/10; + } + printf("\nAmperage value: %d.%d A \n",intampsval,decimalampsval); +} +/***************************************************************** +* Function Name: ipmi_print_get_power_consmpt_data +* +* Description: This function prints the Power consumption information +* Input: intf - ipmi interface +* unit - watt / btuphr +* Output: +* +* Return: +* +******************************************************************/ +static int ipmi_print_get_power_consmpt_data(void* intf,uint8_t unit) +{ + + int rc = 0; + IPMI_INST_POWER_CONSUMPTION_DATA instpowerconsumptiondata = {0,0,0,0}; + // int i; + //uint16_t inputwattageL=0; + //int sensorIndex = 0; + //uint32_t readingbtuphr; + //uint32_t warning_threshbtuphr; + //uint32_t failure_thresbtuphr; + + printf ("\nPower consumption information\n"); + + + rc=ipmi_get_power_consumption_data(intf,unit); + if (-1 == rc) + return rc; + + rc=ipmi_get_instan_power_consmpt_data(intf,&instpowerconsumptiondata); + if (-1 == rc) + return rc; + + ipmi_print_get_instan_power_Amps_data(instpowerconsumptiondata); + + + rc=ipmi_get_power_headroom_command(intf,unit); + + if (-1 == rc) + return rc; + + return rc; + + +} + + +/***************************************************************** +* Function Name: ipmi_get_avgpower_consmpt_history +* +* Description: This function updates the average power consumption information +* Input: intf - ipmi interface +* Output: pavgpower- average power consumption information +* +* Return: +* +******************************************************************/ +static int ipmi_get_avgpower_consmpt_history(void* intf,IPMI_AVGPOWER_CONSUMP_HISTORY* pavgpower ) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = 0xeb; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting average power consumption data: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + if (verbose > 1) + { + printf("Average power consumption history Data :%x %x %x %x %x %x %x %x\n\n", + rsp[0], rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7]); + + } + + *pavgpower = *( (IPMI_AVGPOWER_CONSUMP_HISTORY*) rsp); +#if WORDS_BIGENDIAN + pavgpower->lastminutepower = BSWAP_16(pavgpower->lastminutepower); + pavgpower->lasthourpower = BSWAP_16(pavgpower->lasthourpower); + pavgpower->lastdaypower = BSWAP_16(pavgpower->lastdaypower); + pavgpower->lastweakpower = BSWAP_16(pavgpower->lastweakpower); +#endif + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_get_peakpower_consmpt_history +* +* Description: This function updates the peak power consumption information +* Input: intf - ipmi interface +* Output: pavgpower- peak power consumption information +* +* Return: +* +******************************************************************/ +static int ipmi_get_peakpower_consmpt_history(void* intf,IPMI_POWER_CONSUMP_HISTORY * pstPeakpower) +{ + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = 0xec; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting peak power consumption history: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + if (verbose > 1) + { + printf("Peak power consmhistory Data : %x %x %x %x %x %x %x %x %x %x\n %x %x %x %x %x %x %x %x %x %x %x %x %x\n\n", + rsp[0], rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7], + rsp[8], rsp[9], rsp[10], rsp[11], + rsp[12], rsp[13], rsp[14], rsp[15], + rsp[16], rsp[17], rsp[18], rsp[19], + rsp[20], rsp[21], rsp[22], rsp[23] + ); + + } + *pstPeakpower =* ((IPMI_POWER_CONSUMP_HISTORY*)rsp); +#if WORDS_BIGENDIAN + pstPeakpower->lastminutepower = BSWAP_16(pstPeakpower->lastminutepower); + pstPeakpower->lasthourpower = BSWAP_16(pstPeakpower->lasthourpower); + pstPeakpower->lastdaypower = BSWAP_16(pstPeakpower->lastdaypower); + pstPeakpower->lastweakpower = BSWAP_16(pstPeakpower->lastweakpower); + pstPeakpower->lastminutepowertime = BSWAP_32(pstPeakpower->lastminutepowertime); + pstPeakpower->lasthourpowertime = BSWAP_32(pstPeakpower->lasthourpowertime); + pstPeakpower->lastdaypowertime = BSWAP_32(pstPeakpower->lastdaypowertime); + pstPeakpower->lastweekpowertime = BSWAP_32(pstPeakpower->lastweekpowertime); +#endif + return 0; +} + + +/***************************************************************** +* Function Name: ipmi_get_minpower_consmpt_history +* +* Description: This function updates the peak power consumption information +* Input: intf - ipmi interface +* Output: pavgpower- peak power consumption information +* +* Return: +* +******************************************************************/ +static int ipmi_get_minpower_consmpt_history(void* intf,IPMI_POWER_CONSUMP_HISTORY * pstMinpower) +{ + + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; + data[1] = 0xed; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting min power consumption history: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + if (verbose > 1) + { + printf("Peak power consmhistory Data : %x %x %x %x %x %x %x %x %x %x\n %x %x %x %x %x %x %x %x %x %x %x %x %x\n\n", + rsp[0], rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7], + rsp[8], rsp[9], rsp[10], rsp[11], + rsp[12], rsp[13], rsp[14], rsp[15], + rsp[16], rsp[17], rsp[18], rsp[19], + rsp[20], rsp[21], rsp[22], rsp[23] + ); + + } + *pstMinpower =* ((IPMI_POWER_CONSUMP_HISTORY*)rsp); +#if WORDS_BIGENDIAN + pstMinpower->lastminutepower = BSWAP_16(pstMinpower->lastminutepower); + pstMinpower->lasthourpower = BSWAP_16(pstMinpower->lasthourpower); + pstMinpower->lastdaypower = BSWAP_16(pstMinpower->lastdaypower); + pstMinpower->lastweakpower = BSWAP_16(pstMinpower->lastweakpower); + pstMinpower->lastminutepowertime = BSWAP_32(pstMinpower->lastminutepowertime); + pstMinpower->lasthourpowertime = BSWAP_32(pstMinpower->lasthourpowertime); + pstMinpower->lastdaypowertime = BSWAP_32(pstMinpower->lastdaypowertime); + pstMinpower->lastweekpowertime = BSWAP_32(pstMinpower->lastweekpowertime); +#endif + return 0; +} + + + +/***************************************************************** +* Function Name: ipmi_print_power_consmpt_history +* +* Description: This function print the average and peak power consumption information +* Input: intf - ipmi interface +* unit - watt / btuphr +* Output: +* +* Return: +* +******************************************************************/ +static int ipmi_print_power_consmpt_history(void* intf,int unit ) +{ + + char timestr[30]; + + uint32_t lastminutepeakpower; + uint32_t lasthourpeakpower; + uint32_t lastdaypeakpower; + uint32_t lastweekpeakpower; + + IPMI_AVGPOWER_CONSUMP_HISTORY avgpower; + IPMI_POWER_CONSUMP_HISTORY stMinpower; + IPMI_POWER_CONSUMP_HISTORY stPeakpower; + int rc=0; + + uint64_t tempbtuphrconv; + //uint16_t temp; + + + rc= ipmi_get_avgpower_consmpt_history(intf,&avgpower); + if (-1 == rc) + return rc; + + rc= ipmi_get_peakpower_consmpt_history(intf,&stPeakpower); + if (-1 == rc) + return rc; + + rc= ipmi_get_minpower_consmpt_history(intf,&stMinpower); + if (-1 == rc) + return rc; + + + if(rc==0) + { + printf ("Power Consumption History\n\r\n\r"); + /* The fields are alligned manually changing the spaces will alter the alignment*/ + printf ("Statistic Last Minute Last Hour Last Day Last Week\n\r\n\r"); + + if (unit ==btuphr) + { + printf ("Average Power Consumption "); + tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastminutepower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lasthourpower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastdaypower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(avgpower.lastweakpower); + printf ("%4d BTU/hr\n\r",tempbtuphrconv); + + printf ("Max Power Consumption "); + tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastminutepower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lasthourpower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastdaypower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stPeakpower.lastweakpower); + printf ("%4d BTU/hr\n\r",tempbtuphrconv); + + printf ("Min Power Consumption "); + tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastminutepower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lasthourpower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastdaypower); + printf ("%4d BTU/hr ",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(stMinpower.lastweakpower); + printf ("%4d BTU/hr\n\r\n\r",tempbtuphrconv); + + } + else + { + + printf ("Average Power Consumption "); + tempbtuphrconv=(avgpower.lastminutepower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(avgpower.lasthourpower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(avgpower.lastdaypower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(avgpower.lastweakpower); + printf ("%4ld W \n\r",tempbtuphrconv); + + printf ("Max Power Consumption "); + tempbtuphrconv=(stPeakpower.lastminutepower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stPeakpower.lasthourpower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stPeakpower.lastdaypower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stPeakpower.lastweakpower); + printf ("%4ld W \n\r",tempbtuphrconv); + + printf ("Min Power Consumption "); + tempbtuphrconv=(stMinpower.lastminutepower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stMinpower.lasthourpower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stMinpower.lastdaypower); + printf ("%4ld W ",tempbtuphrconv); + tempbtuphrconv=(stMinpower.lastweakpower); + printf ("%4ld W \n\r\n\r",tempbtuphrconv); + } + + lastminutepeakpower=stPeakpower.lastminutepowertime; + lasthourpeakpower=stPeakpower.lasthourpowertime; + lastdaypeakpower=stPeakpower.lastdaypowertime; + lastweekpeakpower=stPeakpower.lastweekpowertime; + + printf ("Max Power Time\n\r"); + ipmi_time_to_str(lastminutepeakpower, timestr); + printf ("Last Minute : %s",timestr); + ipmi_time_to_str(lasthourpeakpower, timestr); + printf ("Last Hour : %s",timestr); + ipmi_time_to_str(lastdaypeakpower, timestr); + printf ("Last Day : %s",timestr); + ipmi_time_to_str(lastweekpeakpower, timestr); + printf ("Last Week : %s",timestr); + + + lastminutepeakpower=stMinpower.lastminutepowertime; + lasthourpeakpower=stMinpower.lasthourpowertime; + lastdaypeakpower=stMinpower.lastdaypowertime; + lastweekpeakpower=stMinpower.lastweekpowertime; + + printf ("Min Power Time\n\r"); + ipmi_time_to_str(lastminutepeakpower, timestr); + printf ("Last Minute : %s",timestr); + ipmi_time_to_str(lasthourpeakpower, timestr); + printf ("Last Hour : %s",timestr); + ipmi_time_to_str(lastdaypeakpower, timestr); + printf ("Last Day : %s",timestr); + ipmi_time_to_str(lastweekpeakpower, timestr); + printf ("Last Week : %s",timestr); + + } + return rc; + +} + + + +/***************************************************************** +* Function Name: ipmi_get_power_cap +* +* Description: This function updates the power cap information +* Input: intf - ipmi interface +* Output: ipmipowercap - power cap information +* +* Return: +* +******************************************************************/ + +static int ipmi_get_power_cap(void* intf,IPMI_POWER_CAP* ipmipowercap ) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req={0}; + //uint64_t tempbtuphrconv; + uint8_t data[4]; + + /* power supply rating command*/ + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + + data[0] = 0; + data[1] = IPMI_DELL_POWER_CAP; + data[2] = 0; + data[3] = 0; + + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power cap: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + if (verbose > 1){ + printf("power cap Data :%x %x %x %x %x %x %x %x %x %x %x", + rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7], + rsp[8], rsp[9], rsp[10],rsp[11]); + + } + + * ipmipowercap = *((IPMI_POWER_CAP*)(rsp)); +#if WORDS_BIGENDIAN + ipmipowercap->PowerCap = BSWAP_16(ipmipowercap->PowerCap); + ipmipowercap->MaximumPowerConsmp = BSWAP_16(ipmipowercap->MaximumPowerConsmp); + ipmipowercap->MinimumPowerConsmp = BSWAP_16(ipmipowercap->MinimumPowerConsmp); + ipmipowercap->totalnumpowersupp = BSWAP_16(ipmipowercap->totalnumpowersupp); + ipmipowercap->AvailablePower = BSWAP_16(ipmipowercap->AvailablePower); + ipmipowercap->SystemThrottling = BSWAP_16(ipmipowercap->SystemThrottling); + ipmipowercap->Resv = BSWAP_16(ipmipowercap->Resv); +#endif + + return 0; +} + +/***************************************************************** +* Function Name: ipmi_print_power_cap +* +* Description: This function print the power cap information +* Input: intf - ipmi interface +* unit - watt / btuphr +* Output: +* Return: +* +******************************************************************/ +static int ipmi_print_power_cap(void* intf,uint8_t unit ) +{ + uint64_t tempbtuphrconv; + int rc; + IPMI_POWER_CAP ipmipowercap; + + memset(&ipmipowercap,0,sizeof(ipmipowercap)); + rc=ipmi_get_power_cap(intf,&ipmipowercap); + + + if (rc==0) + { + if (unit ==btuphr){ + tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); + printf ("Maximum power: %ld BTU/hr\n",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp); + printf ("Minimum power: %ld BTU/hr\n",tempbtuphrconv); + tempbtuphrconv=watt_to_btuphr_conversion(ipmipowercap.PowerCap); + printf ("Power cap : %ld BTU/hr\n",tempbtuphrconv); + }else{ + + printf ("Maximum power: %ld Watt\n",ipmipowercap.MaximumPowerConsmp); + printf ("Minimum power: %ld Watt\n",ipmipowercap.MinimumPowerConsmp); + printf ("Power cap : %ld Watt\n",ipmipowercap.PowerCap); + } + } + return rc; + +} + +/***************************************************************** +* Function Name: ipmi_set_power_cap +* +* Description: This function updates the power cap information +* Input: intf - ipmi interface +* unit - watt / btuphr +* val - new power cap value +* Output: +* Return: +* +******************************************************************/ +static int ipmi_set_power_cap(void* intf,int unit,int val ) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req={0}; + uint8_t data[13]; + uint16_t powercapval; + uint64_t maxpowerbtuphr; + uint64_t maxpowerbtuphr1; + uint64_t minpowerbtuphr; + IPMI_POWER_CAP ipmipowercap; + + if(ipmi_get_power_capstatus_command(intf) < 0) + return -1; // Adding the failed condition check + + if (PowercapSetable_flag!=1) + { + lprintf(LOG_ERR, " Can not set powercap on this system"); + return -1; + } + else if(PowercapstatusFlag!=1) + { + lprintf(LOG_ERR, " Power cap set feature is not enabled"); + return -1; + } + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + memset(data, 0, 4); + req.msg.data = data; + + data[0] = 0; + data[1] = IPMI_DELL_POWER_CAP; + data[2] = 0; + data[3] = 0; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting power cap: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + if (verbose > 1) + { + printf("power cap Data :%x %x %x %x %x %x %x %x %x %x ", + rsp[1], rsp[2], rsp[3], + rsp[4], rsp[5], rsp[6], rsp[7], + rsp[8], rsp[9], rsp[10],rsp[11]); + + } + + ipmipowercap.PowerCap=((rsp[1]<<8)+rsp[2]); + ipmipowercap.unit=rsp[3]; + ipmipowercap.MaximumPowerConsmp=((rsp[4]<<8)+rsp[5]); + ipmipowercap.MinimumPowerConsmp=((rsp[6]<<8)+rsp[7]); + /* ARC: need Dell to verify these 3 values */ + ipmipowercap.totalnumpowersupp = rsp[8]; + ipmipowercap.AvailablePower = ((rsp[9]<<8)+rsp[10]); + ipmipowercap.SystemThrottling = rsp[11]; + + memset(data, 0, 13); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.lun = 0; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 13; + req.msg.data = data; + data[0] = IPMI_DELL_POWER_CAP; + powercapval=val; + + + data[1] = (powercapval&0XFF); + data[2] = ((powercapval&0XFF00)>>8); + data[3] = unit; + + data[4]=((ipmipowercap.MaximumPowerConsmp&0xFF)); + data[5]=((ipmipowercap.MaximumPowerConsmp&0xFF00)>>8); + data[6]=((ipmipowercap.MinimumPowerConsmp&0xFF)); + data[7]=((ipmipowercap.MinimumPowerConsmp&0xFF00)>>8); + data[8]=(uint8_t)(ipmipowercap.totalnumpowersupp); + data[9]=((ipmipowercap.AvailablePower&0xFF)); + data[10]=((ipmipowercap.AvailablePower&0xFF00)>>8); + data[11]=(uint8_t)(ipmipowercap.SystemThrottling); + data[12]=0x00; + + ipmipowercap.MaximumPowerConsmp = BSWAP_16(ipmipowercap.MaximumPowerConsmp); + ipmipowercap.MinimumPowerConsmp = BSWAP_16(ipmipowercap.MinimumPowerConsmp); + ipmipowercap.PowerCap = BSWAP_16(ipmipowercap.PowerCap); + if(unit==btuphr) + { + val = btuphr_to_watt_conversion(val); + + } + else if(unit ==percent) + { + if((val <0)||(val>100)) + { + lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between 0 - 100"); + return -1; + } + val =( (val*(ipmipowercap.MaximumPowerConsmp -ipmipowercap.MinimumPowerConsmp))/100)+ipmipowercap.MinimumPowerConsmp; + lprintf(LOG_ERR, " Cap value in percentage is %d ",val); + data[1] = (val&0XFF); + data[2] = ((val&0XFF00)>>8); + data[3] = watt; + } + if(((val<ipmipowercap.MinimumPowerConsmp)||(val>ipmipowercap.MaximumPowerConsmp))&&(unit==watt)) + { + lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between %d - %d", + ipmipowercap.MinimumPowerConsmp,ipmipowercap.MaximumPowerConsmp); + return -1; + } + else if(((val<ipmipowercap.MinimumPowerConsmp)||(val>ipmipowercap.MaximumPowerConsmp))&&(unit==btuphr)) + { + minpowerbtuphr= watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp); + maxpowerbtuphr=watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); + maxpowerbtuphr1= watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp); + lprintf(LOG_ERR, " Cap value is out of boundary conditon it should be between %d", + minpowerbtuphr); + lprintf(LOG_ERR, " -%d", + maxpowerbtuphr1); + + return -1; + } + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error setting power cap: "); + if (rv < 0) printf("no response\n"); + else if((iDRAC_FLAG == IDRAC_12G) && (rv == LICENSE_NOT_SUPPORTED)) { + printf("FM001 : A required license is missing or expired\n"); + return rv; + } + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + if (verbose > 1) + { + printf("CC for setpowercap :%d ",rv); + } + return 0; +} + +#ifdef NOT_USED +static int getpowersupplyfruinfo(void *intf, uint8_t id, + struct fru_header header, struct fru_info fru); +/***************************************************************** +* Function Name: getpowersupplyfruinfo +* +* Description: This function retrieves the FRU header +* Input: intf - ipmi interface +* header - watt / btuphr +* fru - FRU information +* Output: header - FRU header +* Return: +* +******************************************************************/ +static int getpowersupplyfruinfo(void *intf, uint8_t id, + struct fru_header header, struct fru_info fru) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[4]; + + memset(&fru, 0, sizeof(struct fru_info)); + memset(&header, 0, sizeof(struct fru_header)); + + /* + * get info about this FRU + */ + memset(msg_data, 0, 4); + msg_data[0] = id; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.lun = 0; + req.msg.cmd = GET_FRU_INFO; + req.msg.data = msg_data; + req.msg.data_len = 1; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Device not present, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + fru.size = (rsp[1] << 8) | rsp[0]; + fru.access = rsp[2] & 0x1; + + lprintf(LOG_DEBUG, "fru.size = %d bytes (accessed by %s)", + fru.size, fru.access ? "words" : "bytes"); + + if (fru.size < 1) { + printf(" Invalid FRU size %d", fru.size); + return -1; + } + + /* + * retrieve the FRU header + */ + msg_data[0] = id; + msg_data[1] = 0; + msg_data[2] = 0; + msg_data[3] = 8; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.lun = 0; + req.msg.cmd = GET_FRU_DATA; + req.msg.data = msg_data; + req.msg.data_len = 4; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Device not present, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + if (verbose > 1) + printbuf(rsp, rsp_len, "FRU DATA"); + + memcpy(&header, &rsp[1], 8); + + return 0; + + +} +#endif + +/***************************************************************** +* Function Name: ipmi_powermonitor_usage +* +* Description: This function prints help message for powermonitor command +* Input: +* Output: +* +* Return: +* +******************************************************************/ +static void +ipmi_powermonitor_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor"); + lprintf(LOG_NOTICE, " Shows power tracking statistics "); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor clear cumulativepower"); + lprintf(LOG_NOTICE, " Reset cumulative power reading"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor clear peakpower"); + lprintf(LOG_NOTICE, " Reset peak power reading"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor powerconsumption"); + lprintf(LOG_NOTICE, " Displays power consumption in <watt|btuphr>"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor powerconsumptionhistory <watt|btuphr>"); + lprintf(LOG_NOTICE, " Displays power consumption history "); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor getpowerbudget"); + lprintf(LOG_NOTICE, " Displays power cap in <watt|btuphr>"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor setpowerbudget <val><watt|btuphr|percent>"); + lprintf(LOG_NOTICE, " Allows user to set the power cap in <watt|BTU/hr|percentage>"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor enablepowercap "); + lprintf(LOG_NOTICE, " To enable set power cap"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " powermonitor disablepowercap "); + lprintf(LOG_NOTICE, " To disable set power cap"); + lprintf(LOG_NOTICE, ""); + +} +/***************************************************************** +* Function Name: ipmi_delloem_vFlash_main +* +* Description: This function processes the delloem vFlash command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_vFlash_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + rc = ipmi_delloem_vFlash_process(intf, current_arg, argv); + return(rc); +} + + + +/***************************************************************** +* Function Name: get_vFlash_compcode_str +* +* Description: This function maps the vFlash completion code +* to a string +* Input : vFlash completion code and static array of codes vs strings +* Output: - +* Return: returns the mapped string +* +******************************************************************/ +const char * +get_vFlash_compcode_str(uint8_t vflashcompcode, const struct vFlashstr *vs) +{ + static char un_str[32]; + int i; + + for (i = 0; vs[i].str != NULL; i++) { + if (vs[i].val == vflashcompcode) + return vs[i].str; + } + + memset(un_str, 0, 32); + snprintf(un_str, 32, "Unknown (0x%02X)", vflashcompcode); + + return un_str; +} + +/***************************************************************** +* Function Name: ipmi_get_sd_card_info +* +* Description: This function prints the vFlash Extended SD card info +* Input : ipmi interface +* Output: prints the sd card extended info +* Return: 0 - success -1 - failure +* +******************************************************************/ +static int +ipmi_get_sd_card_info(void* intf) { + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req; + + uint8_t msg_data[2]; + uint8_t input_length=0; + uint8_t cardstatus=0x00; + + IPMI_DELL_SDCARD_INFO * sdcardinfoblock; + + input_length = 2; + msg_data[0] = msg_data[1] = 0x00; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = IPMI_GET_EXT_SD_CARD_INFO; + req.msg.data = msg_data; + req.msg.data_len = input_length; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error getting SD Card Extended info, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n",rv,decode_cc(0,rv)); + return rv; + } + + sdcardinfoblock = (IPMI_DELL_SDCARD_INFO *) (void *) rsp; + + if( (iDRAC_FLAG == IDRAC_12G) && (sdcardinfoblock->vflashcompcode == VFL_NOT_LICENSED)) + { + printf("FM001 : A required license is missing or expired\n"); + return -1; + } + else if (sdcardinfoblock->vflashcompcode != 0x00) + { + lprintf(LOG_ERR, " Error in getting SD Card Extended Information (%s) \n", get_vFlash_compcode_str(sdcardinfoblock->vflashcompcode, + vFlash_completion_code_vals)); + return -1; + } + + if (!(sdcardinfoblock->sdcardstatus & 0x04)) + { + lprintf(LOG_ERR, " vFlash SD card is unavailable, please insert the card\n of size 256MB or greater\n"); + return 0; + } + + printf("vFlash SD Card Properties\n"); + printf("SD Card size : %8dMB\n",sdcardinfoblock->sdcardsize); + printf("Available size : %8dMB\n",sdcardinfoblock->sdcardavailsize); + printf("Initialized : %10s\n", (sdcardinfoblock->sdcardstatus & 0x80) ? + "Yes" : "No"); + printf("Licensed : %10s\n", (sdcardinfoblock->sdcardstatus & 0x40) ? + "Yes" : "No"); + printf("Attached : %10s\n", (sdcardinfoblock->sdcardstatus & 0x20) ? + "Yes" : "No"); + printf("Enabled : %10s\n", (sdcardinfoblock->sdcardstatus & 0x10) ? + "Yes" : "No"); + printf("Write Protected : %10s\n", (sdcardinfoblock->sdcardstatus & 0x08) ? + "Yes" : "No"); + cardstatus = sdcardinfoblock->sdcardstatus & 0x03; + printf("Health : %10s\n", ((0x00 == cardstatus + ) ? "OK" : ((cardstatus == 0x03) ? + "Undefined" : ((cardstatus == 0x02) ? + "Critical" : "Warning")))); + printf("Bootable partition : %10d\n",sdcardinfoblock->bootpartion); + return 0; +} + +/***************************************************************** +* Function Name: ipmi_delloem_vFlash_process +* +* Description: This function processes the args for vFlash subcmd +* Input : intf - ipmi interface, arg index, argv array +* Output: prints help or error with help +* Return: 0 - Success -1 - failure +* +******************************************************************/ +static int +ipmi_delloem_vFlash_process(void* intf, int current_arg, char ** argv) +{ + int rc = 0; + int drv; + + drv = get_driver_type(); + if (drv != DRV_MV) /* MV open driver */ + { + lprintf(LOG_ERR, " vFlash support is enabled only for wmi and open interface.\n Its not enabled for lan and lanplus interface."); + return -1; + } + + if (argv[current_arg] == NULL || strcmp(argv[current_arg], "help") == 0) + { + ipmi_vFlash_usage(); + return 0; + } + ipmi_idracvalidator_command(intf); + if (!strncmp(argv[current_arg], "info\0", 5)) + { + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_vFlash_usage(); + return -1; + } + else if (strncmp(argv[current_arg], "Card\0", 5) == 0) + { + current_arg++; + if (argv[current_arg] != NULL) + { + ipmi_vFlash_usage(); + return -1; + } + rc = ipmi_get_sd_card_info(intf); + return rc; + } + else /* TBD: many sub commands are present */ + { + ipmi_vFlash_usage(); + return -1; + } + } + /* TBD other vFlash subcommands */ + else + { + ipmi_vFlash_usage(); + return -1; + } + return(rc); +} + +/***************************************************************** +* Function Name: ipmi_vFlash_usage +* +* Description: This function displays the usage for using vFlash +* Input : void +* Output: prints help +* Return: void +* +******************************************************************/ +static void +ipmi_vFlash_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " vFlash info Card"); + lprintf(LOG_NOTICE, " Shows Extended SD Card information"); + lprintf(LOG_NOTICE, ""); +} +/***************************************************************** +* Function Name: ipmi_delloem_windbg_main +* +* Description: This function processes the delloem windbg command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ + +static int ipmi_delloem_windbg_main (void * intf, int argc, char ** argv) +{ + int rc = 0; + + current_arg++; + if (argv[current_arg] == NULL) + { + ipmi_windbg_usage(); + return -1; + } + if (strncmp(argv[current_arg], "start\0", 6) == 0) + { + rc = ipmi_windbg_start(intf); + } + else if (strncmp(argv[current_arg], "end\0", 4) == 0) + { + rc = ipmi_windbg_end(intf); + } + else + { + ipmi_windbg_usage(); + } + return(rc); +} + +/***************************************************************** +* Function Name: ipmi_windbg_start +* +* Description: This function Starts the windbg +* Input : void +* Output: Start the debug +* Return: void +* +******************************************************************/ +static int +ipmi_windbg_start (void * intf) +{ + int rc; + lprintf(LOG_NOTICE, "Issuing sol activate"); + lprintf(LOG_NOTICE, ""); + + rc = ipmi_sol_activate(intf,0,0); + if (rc) lprintf(LOG_NOTICE, "Can not issue sol activate"); + else windbgsession = 1; + return(rc); +} + +/***************************************************************** +* Function Name: ipmi_windbg_end +* +* Description: This function ends the windbg +* Input : void +* Output: End the debug +* Return: void +* +******************************************************************/ + +static int +ipmi_windbg_end(void * intf) +{ + int rc; + lprintf(LOG_NOTICE, "Issuing sol deactivate"); + lprintf(LOG_NOTICE, ""); + rc = ipmi_sol_deactivate(intf); + if (rc) lprintf(LOG_NOTICE, "Can not issue sol deactivate"); + else windbgsession = 0; + return(rc); +} + + +/***************************************************************** +* Function Name: ipmi_windbg_usage +* +* Description: This function displays the usage for using windbg +* Input : void +* Output: prints help +* Return: void +* +******************************************************************/ + +static void +ipmi_windbg_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " windbg start"); + lprintf(LOG_NOTICE, " Starts the windbg session (Cold Reset & SOL Activation)"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " windbg end"); + lprintf(LOG_NOTICE, " Ends the windbg session (SOL Deactivation"); + lprintf(LOG_NOTICE, ""); +} + + + +/********************************************************************** +* Function Name: ipmi_setled_usage +* +* Description: This function prints help message for setled command +* Input: +* Output: +* +* Return: +* +***********************************************************************/ +static void +ipmi_setled_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " setled <b:d.f> <state..>"); + lprintf(LOG_NOTICE, " Set backplane LED state"); + lprintf(LOG_NOTICE, " b:d.f = PCI Bus:Device.Function of drive (lspci format)"); + lprintf(LOG_NOTICE, " state = present|online|hotspare|identify|rebuilding|"); + lprintf(LOG_NOTICE, " fault|predict|critical|failed"); + lprintf(LOG_NOTICE, ""); +} + +static void +ipmi_delloem_getled_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " getled "); + lprintf(LOG_NOTICE, " Get Chassis ID LED state"); + lprintf(LOG_NOTICE, ""); +} + +static int +IsSetLEDSupported(void) +{ + return SetLEDSupported; +} + +static int +CheckSetLEDSupport(void * intf) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[10]; + + SetLEDSupported = 0; + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = 0xD5; /* Storage */ + req.msg.data_len = sizeof(data); /*10*/ + req.msg.data = data; + + memset(data, 0, sizeof(data)); + data[0] = 0x01; // get + data[1] = 0x00; // subcmd:get firmware version + data[2] = 0x08; // length lsb + data[3] = 0x00; // length msb + data[4] = 0x00; // offset lsb + data[5] = 0x00; // offset msb + data[6] = 0x00; // bay id + data[7] = 0x00; + data[8] = 0x00; + data[9] = 0x00; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv == 0) SetLEDSupported = 1; + return(rv); +} + +/***************************************************************** +* Function Name: ipmi_getdrivemap +* +* Description: This function returns mapping of BDF to Bay:Slot +* Input: intf - ipmi interface +* bdf - PCI Address of drive +* *bay - Returns bay ID + *slot - Returns slot ID +* Output: +* +* Return: +* +******************************************************************/ +static int +ipmi_getdrivemap(void * intf, int b, int d, int f, int *bay, int *slot) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[8]; + + /* Get mapping of BDF to bay:slot */ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = 0xD5; + req.msg.data_len = 8; + req.msg.data = data; + + memset(data, 0, sizeof(data)); + data[0] = 0x01; // get + data[1] = 0x07; // storage map + data[2] = 0x06; // length lsb + data[3] = 0x00; // length msb + data[4] = 0x00; // offset lsb + data[5] = 0x00; // offset msb + data[6] = b; // bus + data[7] = (d << 3) + f; // devfn + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error issuing getdrivemap command, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", rv, decode_cc(0,rv)); + return rv; + } + + *bay = rsp[7]; + *slot = rsp[8]; + if (*bay == 0xFF || *slot == 0xFF) + { + lprintf(LOG_ERR, "Error could not get drive bay:slot mapping"); + return -1; + } + return 0; +} + +/***************************************************************** +* Function Name: ipmi_setled_state +* +* Description: This function updates the LED on the backplane +* Input: intf - ipmi interface +* bdf - PCI Address of drive +* state - SES Flags state of drive +* Output: +* +* Return: +* +******************************************************************/ +static int +ipmi_setled_state (void * intf, int bayId, int slotId, int state) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[20]; + + /* Issue Drive Status Update to bay:slot */ + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = 0xD5; + req.msg.data_len = 20; + req.msg.data = data; + + memset(data, 0, sizeof(data)); + data[0] = 0x00; // set + data[1] = 0x04; // set drive status + data[2] = 0x0e; // length lsb + data[3] = 0x00; // length msb + data[4] = 0x00; // offset lsb + data[5] = 0x00; // offset msb + data[6] = 0x0e; // length lsb + data[7] = 0x00; // length msb + data[8] = bayId; // bayid + data[9] = slotId; // slotid + data[10] = state & 0xff; // state LSB + data[11] = state >> 8; // state MSB; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error issuing setled command, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", rv, decode_cc(0,rv)); + return rv; + } + + return 0; +} + +int ipmi_delloem_getled_state (void * intf, uint8_t *state) +{ + uint8_t rsp[IPMI_RSPBUF_SIZE]; int rsp_len, rv; + struct ipmi_rq req = {0}; + uint8_t data[2]; + uint8_t led_state = 0; + + req.msg.netfn = IPMI_DELL_OEM_NETFN; + req.msg.lun = 0; + req.msg.cmd = GET_CHASSIS_LED_STATE; + req.msg.data_len = 0; + req.msg.data = data; + + rv = ipmi_sendrecv(&req, &rsp[0], &rsp_len); + if (rv) { + printf(" Error issuing getled command, "); + if (rv < 0) printf("no response\n"); + else printf("Completion Code 0x%02x %s\n", rv, decode_cc(0,rv)); + } else { + led_state = rsp[0]; + } + *state = led_state; + return rv; +} + +/***************************************************************** +* Function Name: ipmi_getsesmask +* +* Description: This function calculates bits in SES drive update +* Return: Mask set with bits for SES backplane update +* +******************************************************************/ +static int ipmi_getsesmask(int argc, char **argv) +{ + int mask = 0; + //int idx; + + while (current_arg < argc) { + if (!strcmp(argv[current_arg], "present")) + mask |= (1L << 0); + if (!strcmp(argv[current_arg], "online")) + mask |= (1L << 1); + if (!strcmp(argv[current_arg], "hotspare")) + mask |= (1L << 2); + if (!strcmp(argv[current_arg], "identify")) + mask |= (1L << 3); + if (!strcmp(argv[current_arg], "rebuilding")) + mask |= (1L << 4); + if (!strcmp(argv[current_arg], "fault")) + mask |= (1L << 5); + if (!strcmp(argv[current_arg], "predict")) + mask |= (1L << 6); + if (!strcmp(argv[current_arg], "critical")) + mask |= (1L << 9); + if (!strcmp(argv[current_arg], "failed")) + mask |= (1L << 10); + current_arg++; + } + return mask; +} + +/***************************************************************** +* Function Name: ipmi_delloem_setled_main +* +* Description: This function processes the delloem setled command +* Input: intf - ipmi interface + argc - no of arguments + argv - argument string array +* Output: +* +* Return: return code 0 - success +* -1 - failure +* +******************************************************************/ +static int +ipmi_delloem_setled_main(void * intf, int argc, char ** argv) +{ + int rc = -1; + int b,d,f, mask; + int bayId, slotId; + + bayId = 0xFF; + slotId = 0xFF; + + current_arg++; + if (argc < current_arg) + { + usage(); + return rc; + } + + /* ipmitool delloem setled info*/ + if (argc == 1 || strcmp(argv[current_arg], "help") == 0) + { + ipmi_setled_usage(); + return 0; + } + CheckSetLEDSupport (intf); + if (!IsSetLEDSupported()) + { + printf("'setled' is not supported on this system.\n"); + return rc; + } + else if (sscanf(argv[current_arg], "%*x:%x:%x.%x", &b,&d,&f) == 3) { + /* We have bus/dev/function of drive */ + current_arg++; + ipmi_getdrivemap (intf, b, d, f, &bayId, &slotId); + } + else if (sscanf(argv[current_arg], "%x:%x.%x", &b,&d,&f) == 3) { + /* We have bus/dev/function of drive */ + current_arg++; + } + else { + ipmi_setled_usage(); + return -1; + } + /* Get mask of SES flags */ + mask = ipmi_getsesmask(argc, argv); + + /* Get drive mapping */ + if (ipmi_getdrivemap (intf, b, d, f, &bayId, &slotId)) + return -1; + + /* Set drive LEDs */ + return ipmi_setled_state (intf, bayId, slotId, mask); +} + +static int +ipmi_delloem_getled_main(void * intf, int argc, char ** argv) +{ + int rc = 0; + uint8_t state; + + if (argc == 1 || strncmp(argv[0], "help\0", 5) == 0) + { + ipmi_delloem_getled_usage(); + return(0); + } else { + rc = ipmi_delloem_getled_state (intf, &state); + if (rc != 0) printf("getled_state error %d\n",rc); + else { + if (state == 0x01) + printf("Chassis ID LED Status = ON\n"); + else printf("Chassis ID LED Status = off\n"); + } + } + return (rc); +} + +/* + * decode_sensor_dell + * inputs: + * sdr = the SDR buffer + * reading = the 3 or 4 bytes of data from GetSensorReading + * pstring = points to the output string buffer + * slen = size of the output buffer + * outputs: + * rv = 0 if this sensor was successfully interpreted here, + * non-zero otherwise, to use default interpretations. + * pstring = contains the sensor reading interpretation string (if rv==0) + */ +int decode_sensor_dell(uchar *sdr,uchar *reading,char *pstring, int slen) +{ + int rv = -1; + uchar stype, evtype; + + if (sdr == NULL || reading == NULL) return(rv); + if (pstring == NULL || slen == 0) return(rv); + /* sdr[3] is SDR type: 1=full, 2=compact, 0xC0=oem */ + if (sdr[3] != 0x02) return(rv); /*return if not compact SDR */ + stype = sdr[12]; /*sensor type*/ + evtype = sdr[13]; /*event type */ + if (stype == 0x02) { /* Discrete Voltage */ + /* Dell Discrete Voltage is opposite from normal */ + if (evtype == 0x03) { /*oem interpretation */ + if (reading[2] & 0x01) strncpy(pstring,"OK",slen); + else strncpy(pstring,"Exceeded",slen); /*LimitExceeded*/ + rv = 0; + } + } + return(rv); +} + +#define BIT(x) (1 << x) +#define SIZE_OF_DESC 128 + +char * get_dell_evt_desc(uchar *sel_rec) +{ + struct sel_event_record * rec = (struct sel_event_record *)sel_rec; + int data1, data2, data3; + int code; + char *desc = NULL; + + unsigned char count; + unsigned char node; + //unsigned char num; + unsigned char dimmNum; + unsigned char dimmsPerNode; + char dimmStr[32]; + //char cardStr[32]; + //char numStr[32]; + char tmpdesc[SIZE_OF_DESC]; + static char rgdesc[SIZE_OF_DESC]; + char* str; + unsigned char incr = 0; + unsigned char i = 0; + //unsigned char postCode; + // struct ipmi_rs *rsp; + // struct ipmi_rq req; + char tmpData; + int version; + // uint8_t devid[20]; /*usually 16 bytes*/ + uint8_t iver; + // int rv; + + data1 = rec->sel_type.standard_type.event_data[0]; + data2 = rec->sel_type.standard_type.event_data[1]; + data3 = rec->sel_type.standard_type.event_data[2]; + if ( (rec->sel_type.standard_type.event_type == 0x0B) || + (rec->sel_type.standard_type.event_type == 0x6F) || + (rec->sel_type.standard_type.event_type == 0x07)) + { + code = rec->sel_type.standard_type.sensor_type; + /* BDF or Slot */ + desc = rgdesc; + memset(desc,0,SIZE_OF_DESC); + switch (code) { + case 0x07: + if( ((data1 & DATA_BYTE2_SPECIFIED_MASK) == 0x80)) + { + if((data1 & 0x0f) == 0x00) + snprintf(desc,SIZE_OF_DESC,"CPU Internal Err | "); + if((data1 & 0x0f) == 0x06) + { + snprintf(desc,SIZE_OF_DESC,"CPU Protocol Err | "); + } + /* change bit location to a number */ + for (count= 0; count < 8; count++) + { + if (BIT(count)& data2) + { + count++; + if( ((data1 & 0x0f) == 0x06) && (rec->sel_type.standard_type.sensor_num == 0x0A)) + snprintf(desc,SIZE_OF_DESC,"FSB %d ",count); + else + snprintf(desc,SIZE_OF_DESC,"CPU %d | APIC ID %d ",count,data3); + break; + } + } + } + break; + case 0x0C: + if ( (rec->sel_type.standard_type.event_type == 0x0B) && + !(data1 & 0x03) ) + { + if(data2 & 0x04) + strcpy(desc,"Memory is in Spare Mode"); + else if(data2 & 0x02) + strcpy(desc,"Memory is in Raid Mode "); + else if(data2 & 0x01) + strcpy(desc,"Memory is in Mirror Mode "); + break; + } + case 0x10: + get_devid_ver(NULL,NULL,&iver); + // rv = ipmi_getdeviceid(devid,sizeof(devid),fdbg); + // if (rv != 0) return NULL; + version = iver; + /* Memory DIMMS */ + if( (data1 & 0x80) || (data1 & 0x20 ) ) + { + if( (code == 0x0c) && (rec->sel_type.standard_type.event_type == 0x0B) ) + { + if((data1 & 0x0f) == 0x00) + { + snprintf(desc,SIZE_OF_DESC," Redundancy Regained | "); + } + else if((data1 & 0x0f) == 0x01) + { + snprintf(desc,SIZE_OF_DESC,"Redundancy Lost | "); + } + } + else if(code == 0x0c) + { + if((data1 & 0x0f) == 0x00) + { + if(rec->sel_type.standard_type.sensor_num == 0x1C) + { + if((data1 & 0x80) && (data1 & 0x20 )) + { + count = 0; + snprintf(desc,SIZE_OF_DESC,"CRC Error on:"); + for(i=0;i<4;i++) + { + if((BIT(i))&(data2)) + { + if(count) + { + str = desc+strlen(desc); + *str++ = ','; + str = '\0'; + count = 0; + } + switch(i) + { + case 0: snprintf(tmpdesc,SIZE_OF_DESC,"South Bound Memory"); + strcat(desc,tmpdesc); + count++; + break; + case 1: snprintf(tmpdesc,SIZE_OF_DESC,"South Bound Config"); + strcat(desc,tmpdesc); + count++; + break; + case 2: snprintf(tmpdesc,SIZE_OF_DESC,"North Bound memory"); + strcat(desc,tmpdesc); + count++; + break; + case 3: snprintf(tmpdesc,SIZE_OF_DESC,"North Bound memory-corr"); + strcat(desc,tmpdesc); + count++; + break; + default: + break; + } + } + } + if(data3>=0x00 && data3<0xFF) + { + snprintf(tmpdesc,SIZE_OF_DESC,"|Failing_Channel:%d",data3); + strcat(desc,tmpdesc); + } + } + break; + } + snprintf(desc,SIZE_OF_DESC,"Correctable ECC | "); + } + else if((data1 & 0x0f) == 0x01) + { + snprintf(desc,SIZE_OF_DESC,"UnCorrectable ECC | "); + } + } + else if(code == 0x10) + { + if((data1 & 0x0f) == 0x00) + snprintf(desc,SIZE_OF_DESC,"Corr Memory Log Dissabled | "); + } + } + else + { + if(code == 0x12) + { + if((data1 & 0x0f) == 0x02) + snprintf(desc,SIZE_OF_DESC,"Unknown System Hardware Failure "); + } + if(code == 0x10) + { + if((data1 & 0x0f) == 0x03) + snprintf(desc,SIZE_OF_DESC,"All Even Logging Dissabled"); + } + } + if(data1 & 0x80 ) + { + if(((data2 >> 4) != 0x0f) && ((data2 >> 4) < 0x08)) + { + tmpData = ('A'+ (data2 >> 4)); + if( (code == 0x0c) && (rec->sel_type.standard_type.event_type == 0x0B) ) + { + snprintf(tmpdesc, SIZE_OF_DESC, "Bad Card %c", tmpData); + } + else + { + snprintf(tmpdesc, SIZE_OF_DESC, "Card %c", tmpData); + } + strcat(desc, tmpdesc); + } + if (0x0F != (data2 & 0x0f)) + { + if(0x51 == version) + { + snprintf(tmpdesc, SIZE_OF_DESC, "Bank %d", ((data2 & 0x0f)+1)); + strcat(desc, tmpdesc); + } + else + { + incr = (data2 & 0x0f) << 3; + } + } + + } + if(data1 & 0x20 ) + { + if(0x51 == version) + { + snprintf(tmpdesc, SIZE_OF_DESC, "DIMM %s", ('A'+ data3)); + strcat(desc, tmpdesc); + } + else if( ((data2 >> 4) > 0x07) && ((data2 >> 4) != 0x0F)) + { + strcpy(dimmStr, " DIMM_"); + str = desc+strlen(desc); + dimmsPerNode = 4; + if( (data2 >> 4) == 0x09) dimmsPerNode = 6; + else if( (data2 >> 4) == 0x0A) dimmsPerNode = 8; + else if( (data2 >> 4) == 0x0B) dimmsPerNode = 9; + else if( (data2 >> 4) == 0x0C) dimmsPerNode = 12; + else if( (data2 >> 4) == 0x0D) dimmsPerNode = 24; + else if( (data2 >> 4) == 0x0E) dimmsPerNode = 3; + count = 0; + for (i = 0; i < 8; i++) + { + if (BIT(i) & data3) + { + if (count) + { + *str++ = ','; + count = 0; + } + node = (incr + i)/dimmsPerNode; + dimmNum = ((incr + i)%dimmsPerNode)+1; + dimmStr[5] = node + 'A'; + sprintf(tmpdesc,"%d",dimmNum); + dimmStr[6] = tmpdesc[0]; + dimmStr[7] = '\0'; + strcat(str,dimmStr); + count++; + } + } + } + else + { + strcpy(dimmStr, " DIMM"); + str = desc+strlen(desc); + count = 0; + for (i = 0; i < 8; i++) + { + if (BIT(i) & data3) + { + // check if more than one DIMM, if so add a comma to the string. + if (count) + { + *str++ = ','; + count = 0; + } + sprintf(tmpdesc,"%d",(i + incr + 1)); + dimmStr[4] = tmpdesc[0]; + dimmStr[5] = '\0'; + strcat(str, dimmStr); + count++; + } + } + } + } + break; + case 0x20: + if(((data1 & 0x0f)== 0x00)&&((data1 & 0x80) && (data1 & 0x20))) + { + if((data2 > 0x00)&&(data2<0xFF)) + { + //Add the code to display 194 entries.This sensor present only in ORCA + + } + switch(data3) + { + case 0x01: + snprintf(desc,SIZE_OF_DESC,"BIOS TXT Error"); + break; + case 0x02: + snprintf(desc,SIZE_OF_DESC,"Processor/FIT TXT"); + break; + case 0x03: + snprintf(desc,SIZE_OF_DESC,"BIOS ACM TXT Error"); + break; + case 0x04: + snprintf(desc,SIZE_OF_DESC,"SINIT ACM TXT Error"); + break; + case 0xff: + snprintf(desc,SIZE_OF_DESC,"Unrecognized TT Error12"); + break; + default: + break; + } + } + break; + case 0x23: + + if(data1 == 0xC1) + { + if(data2 == 0x04) + { + snprintf(desc,SIZE_OF_DESC,"Hard Reset|Interrupt type None,SMS/OS Timer used at expiration"); + } + } + + break; + case 0x2B: + if(((data1 & 0x0f)== 0x02)&&((data1 & 0x80) && (data1 & 0x20))) + { + if(data2 == 0x02) + { + if(data3 == 0x00) + { + snprintf(desc, SIZE_OF_DESC, "between BMC/iDRAC Firmware and other hardware"); + } + else if(data3 == 0x01) + { + snprintf(desc, SIZE_OF_DESC, "between BMC/iDRAC Firmware and CPU"); + } + } + } + break; + + case 0xC1: + if(rec->sel_type.standard_type.sensor_num == 0x25) + { + if((data1 & 0x0f) == 0x01) + { + snprintf(desc, SIZE_OF_DESC, "Failed to program Virtual Mac Address"); + if((data1 & 0x80)&&(data1 & 0x20)) + { + snprintf(tmpdesc, SIZE_OF_DESC, "PCI %.2x:%.2x.%x", + data3 &0x7f, (data2 >> 3) & 0x1F, + data2 & 0x7); + } + } + else if((data1 & 0x0f) == 0x02) + { + snprintf(desc, SIZE_OF_DESC, "Device option ROM failed to support link tuning or flex address"); + if((data1 & 0x80)&&(data1 & 0x20)) + { + //Add Mezzanine code here.DELLOEM SEL displayed unknown event + } + } + else if((data1 & 0x0f) == 0x03) + { + snprintf(desc, SIZE_OF_DESC, "Failed to get link tuning or flex address data from BMC/iDRAC"); + } + strcat(desc,tmpdesc); + } + break; + case 0x13: + case 0xC2: + case 0xC3: + if(rec->sel_type.standard_type.sensor_num == 0x29) + { + if(((data1 & 0x0f)== 0x02)&&((data1 & 0x80) && (data1 & 0x20))) + { + #if 1 /*This sensor is not implemented in iDRAC code*/ + snprintf(tmpdesc, SIZE_OF_DESC, "Partner-(LinkId:%d,AgentId:%d)|",(data2 & 0xC0),(data2 & 0x30)); + strcat(desc,tmpdesc); + snprintf(tmpdesc, SIZE_OF_DESC, "ReportingAgent(LinkId:%d,AgentId:%d)|",(data2 & 0x0C),(data2 & 0x03)); + strcat(desc,tmpdesc); + if((data3 & 0xFC) == 0x00) + { + snprintf(tmpdesc, SIZE_OF_DESC, "LinkWidthDegraded|"); + strcat(desc,tmpdesc); + } + if(BIT(1)& data3) + { + snprintf(tmpdesc,SIZE_OF_DESC,"PA_Type:IOH|"); + } + else + { + snprintf(tmpdesc,SIZE_OF_DESC,"PA-Type:CPU|"); + } + strcat(desc,tmpdesc); + if(BIT(0)& data3) + { + snprintf(tmpdesc,SIZE_OF_DESC,"RA-Type:IOH"); + } + else + { + snprintf(tmpdesc,SIZE_OF_DESC,"RA-Type:CPU"); + } + strcat(desc,tmpdesc); + #endif + } + } + else + { + + if((data1 & 0x0f) == 0x02) + { + sprintf(desc,"%s","IO channel Check NMI"); + } + else + { + if((data1 & 0x0f) == 0x00) + { + snprintf(desc, SIZE_OF_DESC, "%s","PCIe Error |"); + } + else if((data1 & 0x0f) == 0x01) + { + snprintf(desc, SIZE_OF_DESC, "%s","I/O Error |"); + } + else if((data1 & 0x0f) == 0x04) + { + snprintf(desc, SIZE_OF_DESC, "%s","PCI PERR |"); + } + else if((data1 & 0x0f) == 0x05) + { + snprintf(desc, SIZE_OF_DESC, "%s","PCI SERR |"); + } + else + { + snprintf(desc, SIZE_OF_DESC, "%s"," "); + } + if (data3 & 0x80) + snprintf(tmpdesc, SIZE_OF_DESC, "Slot %d", data3 & 0x7f); + else + snprintf(tmpdesc, SIZE_OF_DESC, "PCI %.2x:%.2x.%x", + data3 &0x7f, (data2 >> 3) & 0x1F, + data2 & 0x7); + strcat(desc,tmpdesc); + } + } + break; + case 0x0F: + if(((data1 & 0x0f)== 0x0F)&&(data1 & 0x80)) + { + switch(data2) + { + case 0x80: + snprintf(desc, SIZE_OF_DESC, "No memory is detected.");break; + case 0x81: + snprintf(desc,SIZE_OF_DESC, "Memory is detected but is not configurable.");break; + case 0x82: + snprintf(desc, SIZE_OF_DESC, "Memory is configured but not usable.");break; + case 0x83: + snprintf(desc, SIZE_OF_DESC, "System BIOS shadow failed.");break; + case 0x84: + snprintf(desc, SIZE_OF_DESC, "CMOS failed.");break; + case 0x85: + snprintf(desc, SIZE_OF_DESC, "DMA controller failed.");break; + case 0x86: + snprintf(desc, SIZE_OF_DESC, "Interrupt controller failed.");break; + case 0x87: + snprintf(desc, SIZE_OF_DESC, "Timer refresh failed.");break; + case 0x88: + snprintf(desc, SIZE_OF_DESC, "Programmable interval timer error.");break; + case 0x89: + snprintf(desc, SIZE_OF_DESC, "Parity error.");break; + case 0x8A: + snprintf(desc, SIZE_OF_DESC, "SIO failed.");break; + case 0x8B: + snprintf(desc, SIZE_OF_DESC, "Keyboard controller failed.");break; + case 0x8C: + snprintf(desc, SIZE_OF_DESC, "System management interrupt initialization failed.");break; + case 0x8D: + snprintf(desc, SIZE_OF_DESC, "TXT-SX Error.");break; + case 0xC0: + snprintf(desc, SIZE_OF_DESC, "Shutdown test failed.");break; + case 0xC1: + snprintf(desc, SIZE_OF_DESC, "BIOS POST memory test failed.");break; + case 0xC2: + snprintf(desc, SIZE_OF_DESC, "RAC configuration failed.");break; + case 0xC3: + snprintf(desc, SIZE_OF_DESC, "CPU configuration failed.");break; + case 0xC4: + snprintf(desc, SIZE_OF_DESC, "Incorrect memory configuration.");break; + case 0xFE: + snprintf(desc, SIZE_OF_DESC, "General failure after video."); + break; + } + } + break; + + default: + break; + } + } + else + { + code = rec->sel_type.standard_type.event_type; + } + return desc; +} + +/* + * decode_sel_dell + * inputs: + * evt = the 16-byte IPMI SEL event + * outbuf = points to the output string buffer + * outsz = size of the output buffer + * outputs: + * rv = 0 if this event was successfully interpreted here, + * non-zero otherwise, to use default interpretations. + * outbuf = will contain the interpreted event text string (if rv==0) + */ +int decode_sel_dell(uint8_t *evt, char *outbuf, int outsz, char fdesc, + char fdbg) +{ + int rv = -1; + uint16_t id, genid; + uint8_t rectype; + uint32_t timestamp; + char *type_str = NULL; + char *gstr = NULL; + char *pstr = NULL; + int sevid; + uchar stype, snum; + + fdebug = fdbg; + sevid = SEV_INFO; + id = evt[0] + (evt[1] << 8); + rectype = evt[2]; + timestamp = evt[3] + (evt[4] << 8) + (evt[5] << 16) + (evt[6] << 24); + genid = evt[7] | (evt[8] << 8); + stype = evt[10]; + snum = evt[11]; + gstr = "BMC "; + if (genid == 0x0033) gstr = "Bios"; + type_str = ""; + if (rectype == 0x02) type_str = get_sensor_type_desc(stype); + +#ifdef OTHER + /* evt[13] is data1/offset*/ + if ( ((evt[13] & DATA_BYTE2_SPECIFIED_MASK) == 0x80) || + ((evt[13] & DATA_BYTE3_SPECIFIED_MASK) == 0x20) ) { + // if (evt[13] & DATA_BYTE2_SPECIFIED_MASK) + // evt->data = rec->sel_type.standard_type.event_data[1]; + pstr = get_dell_evt_desc(evt); + } else if (evt[13] == 0xC1) { + if (snum == 0x23) { + // evt->data = rec->sel_type.standard_type.event_data[1]; + pstr = get_dell_evt_desc(evt); + } + } +#endif + pstr = get_dell_evt_desc(evt); + if (pstr != NULL) rv = 0; + + if (rv == 0) { + format_event(id,timestamp, sevid, genid, type_str, + snum,NULL,pstr,NULL,outbuf,outsz); + } + return rv; +} + +#ifdef METACOMMAND +int i_delloem(int argc, char **argv) +#else +#ifdef WIN32 +int __cdecl +#else +int +#endif +main(int argc, char **argv) +#endif +{ + int rv = 0; + uchar devrec[16]; + int c, i; + char *s1; + + printf("%s ver %s\n", progname,progver); + set_loglevel(LOG_NOTICE); + argc_sav = argc; + argv_sav = argv; + parse_lan_options('V',"4",0); /*default to admin priv*/ + + while ( (c = getopt( argc, argv,"m:s:xzEF:J:N:P:R:T:U:V:YZ:?")) != EOF ) + switch(c) { + case 'm': /* specific IPMB MC, 3-byte address, e.g. "409600" */ + g_bus = htoi(&optarg[0]); /*bus/channel*/ + g_sa = htoi(&optarg[2]); /*device slave address*/ + g_lun = htoi(&optarg[4]); /*LUN*/ + g_addrtype = ADDR_IPMB; + if (optarg[6] == 's') { + g_addrtype = ADDR_SMI; s1 = "SMI"; + } else { g_addrtype = ADDR_IPMB; s1 = "IPMB"; } + ipmi_set_mc(g_bus,g_sa,g_lun,g_addrtype); + printf("Use MC at %s bus=%x sa=%x lun=%x\n", + s1,g_bus,g_sa,g_lun); + break; + case 's': sdrfile = optarg; break; + case 'x': fdebug = 2; /* normal (dbglog if isol) */ + verbose = 1; + break; + case 'z': fdebug = 3; /*full debug (for isol)*/ + verbose = 1; + break; + case 'N': /* nodename */ + case 'U': /* remote username */ + case 'P': /* remote password */ + case 'R': /* remote password */ + case 'E': /* get password from IPMI_PASSWORD environment var */ + case 'F': /* force driver type */ + case 'T': /* auth type */ + case 'J': /* cipher suite */ + case 'V': /* priv level */ + case 'Y': /* prompt for remote password */ + case 'Z': /* set local MC address */ + parse_lan_options(c,optarg,fdebug); + break; + default: + usage(); + rv = ERR_USAGE; + goto do_exit; + break; + } + rv = ipmi_getdeviceid(devrec,16,fdebug); + if (rv == 0) { + char ipmi_maj, ipmi_min; + ipmi_maj = devrec[4] & 0x0f; + ipmi_min = devrec[4] >> 4; + // vend_id = devrec[6] + (devrec[7] << 8) + (devrec[8] << 16); + // prod_id = devrec[9] + (devrec[10] << 8); + show_devid( devrec[2], devrec[3], ipmi_maj, ipmi_min); + } + for (i = 0; i < optind; i++) { argv++; argc--; } + + rv = ipmi_delloem_main(NULL, argc, argv); + +do_exit: + ipmi_close_(); + return(rv); +} +/* end oem_dell.c */ |