From f8bc5ae591c6b6b815be96a8feba6dc77c396e7a Mon Sep 17 00:00:00 2001 From: Jean-Michel Audet Date: Thu, 26 Apr 2007 13:21:49 +0000 Subject: [PATCH] - added fru control - added amcportstate set - added clock commands - improved led command support --- ipmitool/lib/ipmi_picmg.c | 1261 +++++++++++++++++++++++++------------ 1 file changed, 847 insertions(+), 414 deletions(-) diff --git a/ipmitool/lib/ipmi_picmg.c b/ipmitool/lib/ipmi_picmg.c index 0214222..64ab09d 100644 --- a/ipmitool/lib/ipmi_picmg.c +++ b/ipmitool/lib/ipmi_picmg.c @@ -22,10 +22,12 @@ #define PICMG_EKEY_AMC_MAX_CHANNEL 16 #define PICMG_EKEY_AMC_MAX_DEVICE 15 /* 4 bits */ + void ipmi_picmg_help (void) { printf(" properties - get PICMG properties\n"); + printf(" frucontrol - FRU control\n"); printf(" addrinfo - get address information\n"); printf(" activate - activate a FRU\n"); printf(" deactivate - deactivate a FRU\n"); @@ -37,31 +39,60 @@ ipmi_picmg_help (void) printf(" portstate getall - get all port state description\n"); printf(" portstate set - set port state \n"); printf(" amcportstate get - get port state \n"); + printf(" amcportstate set - set port state \n"); printf(" led prop - get led properties\n"); printf(" led cap - get led color capabilities\n"); - printf(" led state get - get led state\n"); - printf(" led state set - set led state\n"); + printf(" led get - get led state\n"); + printf(" led set - set led state\n"); printf(" power get - get power level info\n"); printf(" power set - set power level\n"); + printf(" clk get - get clk state\n"); + printf(" clk set - set clk state\n"); } + +struct sAmcAddrMap { + unsigned char ipmbLAddr; + char* amcBayId; + unsigned char siteNum; +} amcAddrMap[] = { + {0xFF, "reserved", 0}, + {0x72, "A1" , 1}, + {0x74, "A2" , 2}, + {0x76, "A3" , 3}, + {0x78, "A4" , 4}, + {0x7A, "B1" , 5}, + {0x7C, "B2" , 6}, + {0x7E, "B3" , 7}, + {0x80, "B4" , 8}, + {0x82, "reserved", 0}, + {0x84, "reserved", 0}, + {0x86, "reserved", 0}, + {0x88, "reserved", 0}, +}; + int -ipmi_picmg_getaddr(struct ipmi_intf * intf) +ipmi_picmg_getaddr(struct ipmi_intf * intf, int argc, char ** argv) { struct ipmi_rs * rsp; struct ipmi_rq req; - unsigned char msg_data; + unsigned char msg_data[5]; memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_PICMG; req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD; - req.msg.data = &msg_data; - req.msg.data_len = 1; - msg_data = 0; + req.msg.data = msg_data; + req.msg.data_len = 2; + msg_data[0] = 0; /* picmg identifier */ + msg_data[1] = 0; /* default fru id */ + + if(argc > 0) { + msg_data[1] = strtoul(argv[0], NULL,0); /* FRU ID */ + } rsp = intf->sendrecv(intf, &req); if (!rsp || rsp->ccode) { - printf("Error getting address information\n"); + printf("Error getting address information CC: 0x%02x\n", rsp->ccode); return -1; } @@ -94,7 +125,8 @@ ipmi_picmg_getaddr(struct ipmi_intf * intf) printf("Alarm module\n"); break; case PICMG_AMC: - printf("AMC\n"); + printf("AMC"); + printf(" -> IPMB-L Address: 0x%02x\n", amcAddrMap[rsp->data[5]].ipmbLAddr); break; case PICMG_PMC: printf("PMC\n"); @@ -202,16 +234,49 @@ ipmi_picmg_fru_activation_policy_get(struct ipmi_intf * intf, int argc, char ** printf("no response\n"); return -1; } - if (rsp->ccode) { printf("returned CC code 0x%02x\n", rsp->ccode); return -1; } - printf("Activation Policy for FRU %x: ", atoi(argv[0]) ); - printf("%s, ", (rsp->data[1] & 0x01) ? "is locked" : "is not locked"); - printf("%s\n", (rsp->data[1] & 0x02) ? "deactivation locked" - : "deactivation not locked"); + printf(" %s\n", ((rsp->data[1] & 0x01) == 0x01) ? + "activation locked" : "activation not locked"); + printf(" %s\n", ((rsp->data[1] & 0x02) == 0x02) ? + "deactivation locked" : "deactivation not locked"); + + return 0; +} + +int +ipmi_picmg_fru_activation_policy_set(struct ipmi_intf * intf, int argc, char ** argv) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char msg_data[4]; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_SET_FRU_POLICY_CMD; + req.msg.data = msg_data; + req.msg.data_len = 4; + + msg_data[0] = 0; /* PICMG identifier */ + msg_data[1] = (unsigned char) atoi(argv[0]); /* FRU ID */ + msg_data[2] = (unsigned char) atoi(argv[1])& 0x03; /* FRU act policy mask */ + msg_data[3] = (unsigned char) atoi(argv[2])& 0x03; /* FRU act policy set bits */ + + rsp = intf->sendrecv(intf, &req); + + if (!rsp) { + printf("no response\n"); + return -1; + } + + if (rsp->ccode) { + printf("returned CC code 0x%02x\n", rsp->ccode); + return -1; + } return 0; } @@ -248,113 +313,117 @@ ipmi_picmg_portstate_get(struct ipmi_intf * intf, int interface,int channel, } if (rsp->ccode) { - if( mode == PICMG_EKEY_MODE_QUERY ){ - printf("returned CC code 0x%02x\n", rsp->ccode); - } + if( mode == PICMG_EKEY_MODE_QUERY ){ + printf("returned CC code 0x%02x\n", rsp->ccode); + } return -1; } if (rsp->data_len >= 6) { - int index; + int index; - /* add support for more than one link per channel */ - for(index=0;indexdata_len > (1+ (index*5))){ + if( rsp->data_len > (1+ (index*5))){ - d = (struct fru_picmgext_link_desc *) &(rsp->data[1 + (index*5)]); - - if - ( - mode == PICMG_EKEY_MODE_PRINT_ALL - || - mode == PICMG_EKEY_MODE_QUERY - || - ( - mode == PICMG_EKEY_MODE_PRINT_ENABLED - && - rsp->data[5 + (index*5) ] == 0x01 - ) - || - ( - mode == PICMG_EKEY_MODE_PRINT_DISABLED - && - rsp->data[5 + (index*5) ] == 0x00 - ) - ) - { - printf(" Link Grouping ID: 0x%02x\n", d->grouping); - printf(" Link Type Extension: 0x%02x\n", d->ext); - printf(" Link Type: "); - if (d->type == 0 || d->type == 0xff) - { - printf("Reserved %d\n",d->type); - } - else if (d->type >= 0x06 && d->type <= 0xef) - { - printf("Reserved\n",d->type); - } - else if (d->type >= 0xf0 && d->type <= 0xfe) - { - printf("OEM GUID Definition\n",d->type); - } - else - { - switch (d->type) - { - case FRU_PICMGEXT_LINK_TYPE_BASE: - printf("PICMG 3.0 Base Interface 10/100/1000\n"); - break; - case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET: - printf("PICMG 3.1 Ethernet Fabric Interface\n"); - break; - case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND: - printf("PICMG 3.2 Infiniband Fabric Interface\n"); - break; - case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR: - printf("PICMG 3.3 Star Fabric Interface\n"); - break; - case FRU_PICMGEXT_LINK_TYPE_PCIE: - printf("PCI Express Fabric Interface\n"); - default: - printf("Invalid\n"); - } - } - printf(" Link Designator: 0x%03x\n", d->designator); - printf(" Port Flag: 0x%02x\n", d->designator >> 8); - printf(" Interface: "); - switch ((d->designator & 0xff) >> 6) - { - case FRU_PICMGEXT_DESIGN_IF_BASE: - printf("Base Interface\n"); - break; - case FRU_PICMGEXT_DESIGN_IF_FABRIC: - printf("Fabric Interface\n"); - break; - case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL: - printf("Update Channel\n"); - break; - case FRU_PICMGEXT_DESIGN_IF_RESERVED: - printf("Reserved\n"); - default: - printf("Invalid"); + d = (struct fru_picmgext_link_desc *) &(rsp->data[1 + (index*5)]); + + if + ( + mode == PICMG_EKEY_MODE_PRINT_ALL + || + mode == PICMG_EKEY_MODE_QUERY + || + ( + mode == PICMG_EKEY_MODE_PRINT_ENABLED + && + rsp->data[5 + (index*5) ] == 0x01 + ) + || + ( + mode == PICMG_EKEY_MODE_PRINT_DISABLED + && + rsp->data[5 + (index*5) ] == 0x00 + ) + ) + { + printf(" Link Grouping ID: 0x%02x\n", d->grouping); + printf(" Link Type Extension: 0x%02x\n", d->ext); + printf(" Link Type: 0x%02x ", d->type); + if (d->type == 0 || d->type == 0xff) + { + printf("Reserved %d\n",d->type); + } + else if (d->type >= 0x06 && d->type <= 0xef) + { + printf("Reserved\n",d->type); + } + else if (d->type >= 0xf0 && d->type <= 0xfe) + { + printf("OEM GUID Definition\n",d->type); + } + else + { + switch (d->type) + { + case FRU_PICMGEXT_LINK_TYPE_BASE: + printf("PICMG 3.0 Base Interface 10/100/1000\n"); + break; + case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET: + printf("PICMG 3.1 Ethernet Fabric Interface\n"); + break; + case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND: + printf("PICMG 3.2 Infiniband Fabric Interface\n"); + break; + case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR: + printf("PICMG 3.3 Star Fabric Interface\n"); + break; + case FRU_PICMGEXT_LINK_TYPE_PCIE: + printf("PCI Express Fabric Interface\n"); + break; + default: + printf("Invalid\n"); + break; + } + } + printf(" Link Designator: \n"); + printf(" Port Flag: 0x%02x\n", d->desig_port); + printf(" Interface: 0x%02x - ", d->desig_if); + switch (d->desig_if) + { + case FRU_PICMGEXT_DESIGN_IF_BASE: + printf("Base Interface\n"); + break; + case FRU_PICMGEXT_DESIGN_IF_FABRIC: + printf("Fabric Interface\n"); + break; + case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL: + printf("Update Channel\n"); + break; + case FRU_PICMGEXT_DESIGN_IF_RESERVED: + printf("Reserved\n"); + break; + default: + printf("Invalid"); + break; + } + printf(" Channel Number: 0x%02x\n", d->desig_channel); + printf("\n"); + printf(" STATE: %s\n", rsp->data[5 +(index*5)] == 0x01?"enabled":"disabled"); + } } - printf(" Channel Number: 0x%02x\n", d->designator & 0x1f); - printf("\n"); - printf(" STATE: %s\n", rsp->data[5 +(index*5)] == 0x01?"enabled":"disabled"); - } - } - } + } + } + else + { + lprintf(LOG_NOTICE,"Unexpected answer, can't print result"); } - else - { - lprintf(LOG_NOTICE,"Unexpected answer, can't print result"); - } - return 0; } + int ipmi_picmg_portstate_set(struct ipmi_intf * intf, int interface, int channel, int port, int type, int typeext, int group, int enable) @@ -376,9 +445,9 @@ ipmi_picmg_portstate_set(struct ipmi_intf * intf, int interface, int channel, d = (struct fru_picmgext_link_desc*) &(msg_data[1]); - d->designator = (unsigned char) (channel & 0x1F); /* channel */ - d->designator = (unsigned char) ((interface & 0x03) << 6); /* interface */ - d->designator = (unsigned char) ((port & 0x03) << 8); /* port */ + d->desig_channel = (unsigned char) (channel & 0x1F); /* channel */ + d->desig_if = (unsigned char) ((interface & 0x03) << 6); /* interface */ + d->desig_port = (unsigned char) ((port & 0x03) << 8); /* port */ d->type = (unsigned char) (type & 0xFF); /* link type */ d->ext = (unsigned char) (typeext & 0x03); /* type ext */ @@ -401,6 +470,8 @@ ipmi_picmg_portstate_set(struct ipmi_intf * intf, int interface, int channel, return 0; } + + /* AMC.0 commands */ #define PICMG_AMC_MAX_LINK_PER_CHANNEL 4 @@ -422,7 +493,7 @@ ipmi_picmg_amc_portstate_get(struct ipmi_intf * intf,int device,int channel, req.msg.cmd = PICMG_AMC_GET_PORT_STATE_CMD; req.msg.data = msg_data; - /* FIXME : add check for AMC or carrier device */ + /* FIXME : add check for AMC or carrier device */ req.msg.data_len = 3; msg_data[0] = 0x00; /* PICMG identifier */ @@ -438,117 +509,129 @@ ipmi_picmg_amc_portstate_get(struct ipmi_intf * intf,int device,int channel, } if (rsp->ccode) { - if( mode == PICMG_EKEY_MODE_QUERY ){ - printf("returned CC code 0x%02x\n", rsp->ccode); - } + if( mode == PICMG_EKEY_MODE_QUERY ){ + printf("returned CC code 0x%02x\n", rsp->ccode); + } return -1; } if (rsp->data_len >= 5) { - int index; + int index; - /* add support for more than one link per channel */ - for(index=0;indexdata_len > (1+ (index*4))){ - unsigned char type; - unsigned char ext; - unsigned char grouping; - unsigned char port; - unsigned char enabled; - d = (struct fru_picmgext_amc_link_info *)&(rsp->data[1 + (index*4)]); + if( rsp->data_len > (1+ (index*4))){ + unsigned char type; + unsigned char ext; + unsigned char grouping; + unsigned char port; + unsigned char enabled; + d = (struct fru_picmgext_amc_link_info *)&(rsp->data[1 + (index*4)]); - /* Removed endianness check here, probably not required - as we dont use bitfields */ - port = d->linkInfo[0] & 0x0F; - type = ((d->linkInfo[0] & 0xF0) >> 4 )|(d->linkInfo[1] & 0x0F ); - ext = ((d->linkInfo[1] & 0xF0) >> 4 ); - grouping = d->linkInfo[2]; + /* Removed endianness check here, probably not required + as we dont use bitfields */ + port = d->linkInfo[0] & 0x0F; + type = ((d->linkInfo[0] & 0xF0) >> 4 )|(d->linkInfo[1] & 0x0F ); + ext = ((d->linkInfo[1] & 0xF0) >> 4 ); + grouping = d->linkInfo[2]; - enabled = rsp->data[4 + (index*4) ]; + enabled = rsp->data[4 + (index*4) ]; - if - ( - mode == PICMG_EKEY_MODE_PRINT_ALL - || - mode == PICMG_EKEY_MODE_QUERY - || - ( - mode == PICMG_EKEY_MODE_PRINT_ENABLED - && - enabled == 0x01 - ) - || - ( - mode == PICMG_EKEY_MODE_PRINT_DISABLED - && - enabled == 0x00 - ) - ) - { - printf(" Link device : 0x%02x\n", device ); - printf(" Link channel: 0x%02x\n", channel); - - printf(" Link Grouping ID: 0x%02x\n", grouping); - printf(" Link Type Extension: 0x%02x\n", ext); - printf(" Link Type: "); - if (type == 0 || type == 1 ||type == 0xff) - { - printf("Reserved\n"); - } - else if (type >= 0xf0 && type <= 0xfe) - { - printf("OEM GUID Definition\n"); - } - else - { - if (type <= FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE ) - { - printf("%s\n",amc_link_type_str[type]); - } - else{ - printf("undefined\n"); - } - } - printf(" Port Flag: 0x%02x\n", port ); - printf(" STATE: %s\n",( enabled == 0x01 )?"enabled":"disabled"); - printf("\n"); - } - } - } + if + ( + mode == PICMG_EKEY_MODE_PRINT_ALL + || + mode == PICMG_EKEY_MODE_QUERY + || + ( + mode == PICMG_EKEY_MODE_PRINT_ENABLED + && + enabled == 0x01 + ) + || + ( + mode == PICMG_EKEY_MODE_PRINT_DISABLED + && + enabled == 0x00 + ) + ) + { + printf(" Link device : 0x%02x\n", device ); + printf(" Link channel: 0x%02x\n", channel); + + printf(" Link Grouping ID: 0x%02x\n", grouping); + printf(" Link Type Extension: 0x%02x\n", ext); + printf(" Link Type: "); + if (type == 0 || type == 1 ||type == 0xff) + { + printf("Reserved\n"); + } + else if (type >= 0xf0 && type <= 0xfe) + { + printf("OEM GUID Definition\n"); + } + else + { + if (type <= FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE ) + { + printf("%s\n",amc_link_type_str[type]); + } + else{ + printf("undefined\n"); + } + } + printf(" Port Flag: 0x%02x\n", port ); + printf(" STATE: %s\n",( enabled == 0x01 )?"enabled":"disabled"); + printf("\n"); + } + } + } + } + else + { + lprintf(LOG_NOTICE,"ipmi_picmg_amc_portstate_get"\ + "Unexpected answer, can't print result"); } - else - { - lprintf(LOG_NOTICE,"ipmi_picmg_amc_portstate_get"\ - "Unexpected answer, can't print result"); - } - return 0; } + int -ipmi_picmg_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv) +ipmi_picmg_amc_portstate_set(struct ipmi_intf * intf, int channel, int port, + int type, int typeext, int group, int enable, int device) { - struct ipmi_rs * rsp; - struct ipmi_rq req; - - unsigned char msg_data[6]; - + struct ipmi_rs * rsp; + struct ipmi_rq req; + unsigned char msg_data[7]; + memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_PICMG; - req.msg.cmd = PICMG_GET_FRU_LED_PROPERTIES_CMD; - req.msg.data = msg_data; - req.msg.data_len = 2; - - msg_data[0] = 0x00; /* PICMG identifier */ - msg_data[1] = atoi(argv[0]); /* FRU-ID */ - + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_AMC_SET_PORT_STATE_CMD; + req.msg.data = msg_data; + + msg_data[0] = 0x00; /* PICMG identifier*/ + msg_data[1] = channel; /* channel id */ + msg_data[2] = port & 0xF; /* port flags */ + msg_data[2] |= (type & 0x0F)<<4; /* type */ + msg_data[3] = (type & 0xF0)>>4; /* type */ + msg_data[3] |= (typeext & 0x0F)<<4; /* extension */ + msg_data[4] = (group & 0xFF); /* group */ + msg_data[5] = (enable & 0x01); /* state */ + req.msg.data_len = 6; + + /* device id - only for carrier needed */ + if (device >= 0) { + msg_data[6] = device; + req.msg.data_len = 7; + } + rsp = intf->sendrecv(intf, &req); - + if (!rsp) { printf("no response\n"); return -1; @@ -558,10 +641,44 @@ ipmi_picmg_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv) printf("returned CC code 0x%02x\n", rsp->ccode); return -1; } - - printf("General Status LED Properties: 0x%2x\n\r", rsp->data[1] ); - printf("App. Specific LED Count: 0x%2x\n\r", rsp->data[2] ); - + + return 0; +} + + +int +ipmi_picmg_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_FRU_LED_PROPERTIES_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atoi(argv[0]); /* FRU-ID */ + + rsp = intf->sendrecv(intf, &req); + + if (!rsp) { + printf("no response\n"); + return -1; + } + + if (rsp->ccode) { + printf("returned CC code 0x%02x\n", rsp->ccode); + return -1; + } + + printf("General Status LED Properties: 0x%2x\n\r", rsp->data[1] ); + printf("App. Specific LED Count: 0x%2x\n\r", rsp->data[2] ); + return 0; } @@ -571,23 +688,23 @@ ipmi_picmg_get_led_capabilities(struct ipmi_intf * intf, int argc, char ** argv) int i; struct ipmi_rs * rsp; struct ipmi_rq req; - + unsigned char msg_data[6]; - + memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_PICMG; req.msg.cmd = PICMG_GET_LED_COLOR_CAPABILITIES_CMD; req.msg.data = msg_data; req.msg.data_len = 3; - + msg_data[0] = 0x00; /* PICMG identifier */ msg_data[1] = atoi(argv[0]); /* FRU-ID */ msg_data[2] = atoi(argv[1]); /* LED-ID */ - - + + rsp = intf->sendrecv(intf, &req); - + if (!rsp) { printf("no response\n"); return -1; @@ -597,19 +714,19 @@ ipmi_picmg_get_led_capabilities(struct ipmi_intf * intf, int argc, char ** argv) printf("returned CC code 0x%02x\n", rsp->ccode); return -1; } - - printf("LED Color Capabilities: "); + + printf("LED Color Capabilities: ", rsp->data[1] ); for ( i=0 ; i<8 ; i++ ) { if ( rsp->data[1] & (0x01 << i) ) { printf("%s, ", led_color_str[ i ]); } } printf("\n\r"); - + printf("Default LED Color in\n\r"); - printf(" LOCAL control: %s\n\r", led_color_str[ rsp->data[2] ] ); + printf(" LOCAL control: %s\n\r", led_color_str[ rsp->data[2] ] ); printf(" OVERRIDE state: %s\n\r", led_color_str[ rsp->data[3] ] ); - + return 0; } @@ -618,23 +735,23 @@ ipmi_picmg_get_led_state(struct ipmi_intf * intf, int argc, char ** argv) { struct ipmi_rs * rsp; struct ipmi_rq req; - + unsigned char msg_data[6]; - + memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_PICMG; req.msg.cmd = PICMG_GET_FRU_LED_STATE_CMD; req.msg.data = msg_data; req.msg.data_len = 3; - + msg_data[0] = 0x00; /* PICMG identifier */ msg_data[1] = atoi(argv[0]); /* FRU-ID */ msg_data[2] = atoi(argv[1]); /* LED-ID */ - - + + rsp = intf->sendrecv(intf, &req); - + if (!rsp) { printf("no response\n"); return -1; @@ -644,25 +761,54 @@ ipmi_picmg_get_led_state(struct ipmi_intf * intf, int argc, char ** argv) printf("returned CC code 0x%02x\n", rsp->ccode); return -1; } - - printf("LED states: %x\n\r", rsp->data[1] ); - printf(" Local Control function: %x\n\r", rsp->data[2] ); + + printf("LED states: %x ", rsp->data[1] ); + if (rsp->data[1] == 0x1) + printf("[LOCAL CONTROL]\n\r"); + else if (rsp->data[1] == 0x2) + printf("[OVERRIDE]\n\r"); + else if (rsp->data[1] == 0x4) + printf("[LAMPTEST]\n\r"); + else + printf("\n\r"); + + printf(" Local Control function: %x ", rsp->data[2] ); + if (rsp->data[2] == 0x0) + printf("[OFF]\n\r"); + else if (rsp->data[2] == 0xff) + printf("[ON]\n\r"); + else + printf("[BLINKING]\n\r"); + printf(" Local Control On-Duration: %x\n\r", rsp->data[3] ); - printf(" Local Control Color: %s\n\r", led_color_str[ rsp->data[4] ]); - + printf(" Local Control Color: %x [%s]\n\r", rsp->data[4], led_color_str[ rsp->data[4] ]); + /* override state or lamp test */ - if (rsp->data[1] == 0x01) { - printf(" Override function: %x\n\r", rsp->data[5] ); + if (rsp->data[1] == 0x02) { + printf(" Override function: %x ", rsp->data[5] ); + if (rsp->data[2] == 0x0) + printf("[OFF]\n\r"); + else if (rsp->data[2] == 0xff) + printf("[ON]\n\r"); + else + printf("[BLINKING]\n\r"); + printf(" Override On-Duration: %x\n\r", rsp->data[6] ); - printf(" Override Color: %s\n\r", led_color_str[ rsp->data[7] ]); - - }else if (rsp->data[1] == 0x03) { - printf(" Override function: %x\n\r", rsp->data[5] ); + printf(" Override Color: %x [%s]\n\r", rsp->data[7], led_color_str[ rsp->data[7] ]); + + }else if (rsp->data[1] == 0x06) { + printf(" Override function: %x ", rsp->data[5] ); + if (rsp->data[2] == 0x0) + printf("[OFF]\n\r"); + else if (rsp->data[2] == 0xff) + printf("[ON]\n\r"); + else + printf("[BLINKING]\n\r"); printf(" Override On-Duration: %x\n\r", rsp->data[6] ); - printf(" Override Color: %s\n\r", led_color_str[ rsp->data[7] ]); + printf(" Override Color: %x [%s]\n\r", rsp->data[7], led_color_str[ rsp->data[7] ]); printf(" Lamp test duration: %x\n\r", rsp->data[8] ); } - + return 0; } @@ -671,25 +817,25 @@ ipmi_picmg_set_led_state(struct ipmi_intf * intf, int argc, char ** argv) { struct ipmi_rs * rsp; struct ipmi_rq req; - + unsigned char msg_data[6]; - + memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_PICMG; req.msg.cmd = PICMG_SET_FRU_LED_STATE_CMD; req.msg.data = msg_data; req.msg.data_len = 6; - + msg_data[0] = 0x00; /* PICMG identifier */ msg_data[1] = atoi(argv[0]); /* FRU-ID */ msg_data[2] = atoi(argv[1]); /* LED-ID */ msg_data[3] = atoi(argv[2]); /* LED function */ msg_data[4] = atoi(argv[3]); /* LED on duration */ msg_data[5] = atoi(argv[4]); /* LED color */ - + rsp = intf->sendrecv(intf, &req); - + if (!rsp) { printf("no response\n"); return -1; @@ -699,8 +845,8 @@ ipmi_picmg_set_led_state(struct ipmi_intf * intf, int argc, char ** argv) printf("returned CC code 0x%02x\n", rsp->ccode); return -1; } - - + + return 0; } @@ -710,20 +856,65 @@ ipmi_picmg_get_power_level(struct ipmi_intf * intf, int argc, char ** argv) int i; struct ipmi_rs * rsp; struct ipmi_rq req; - + unsigned char msg_data[6]; - + memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_PICMG; req.msg.cmd = PICMG_GET_POWER_LEVEL_CMD; req.msg.data = msg_data; req.msg.data_len = 3; - + msg_data[0] = 0x00; /* PICMG identifier */ msg_data[1] = atoi(argv[0]); /* FRU-ID */ msg_data[2] = atoi(argv[1]); /* Power type */ - + + + rsp = intf->sendrecv(intf, &req); + + if (!rsp) { + printf("no response\n"); + return -1; + } + + if (rsp->ccode) { + printf("returned CC code 0x%02x\n", rsp->ccode); + return -1; + } + + printf("Dynamic Power Configuration: %s\n", (rsp->data[1]&0x80)==0x80?"enabled":"disabled" ); + printf("Actual Power Level: %i\n", (rsp->data[1] & 0xf)); + printf("Delay to stable Power: %i\n", rsp->data[2]); + printf("Power Multiplier: %i\n", rsp->data[3]); + + + for ( i = 1; i+3 < rsp->data_len ; i++ ) { + printf(" Power Draw %i: %i\n", i, (rsp->data[i+3]) * rsp->data[3] / 10); + } + return 0; +} + +int +ipmi_picmg_set_power_level(struct ipmi_intf * intf, int argc, char ** argv) +{ + int i; + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_SET_POWER_LEVEL_CMD; + req.msg.data = msg_data; + req.msg.data_len = 4; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atoi(argv[0]); /* FRU-ID */ + msg_data[2] = atoi(argv[1]); /* power level */ + msg_data[3] = atoi(argv[2]); /* present to desired */ rsp = intf->sendrecv(intf, &req); @@ -737,18 +928,170 @@ ipmi_picmg_get_power_level(struct ipmi_intf * intf, int argc, char ** argv) return -1; } - printf("Dynamic Power Configuration: %s\n", (rsp->data[1]&0x80)==0x80?"enabled":"disabled" ); - printf("Actual Power Level: %i\n", (rsp->data[1] & 0xf)); - printf("Delay to stable Power: %i\n", rsp->data[2]); - printf("Power Multiplier: %i\n", rsp->data[3]); - - - for ( i = 1; i+3 < rsp->data_len ; i++ ) { - printf(" Power Draw %i: %i\n", i, rsp->data[i+3]); - } return 0; } +int +ipmi_picmg_fru_control(struct ipmi_intf * intf, int argc, char ** argv) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_FRU_CONTROL_CMD; + req.msg.data = msg_data; + req.msg.data_len = 3; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atoi(argv[0]); /* FRU-ID */ + msg_data[2] = atoi(argv[1]); /* control option */ + + printf("0: 0x%02x 1: 0x%02x\n\r", msg_data[1], msg_data[2]); + + rsp = intf->sendrecv(intf, &req); + + if (!rsp) { + printf("frucontrol: no response\n"); + return -1; + } + + if (rsp->ccode) { + printf("frucontrol: returned CC code 0x%02x\n", rsp->ccode); + return -1; + } + + + + return 0; +} + + +int +ipmi_picmg_clk_get(struct ipmi_intf * intf, int argc, char ** argv) +{ + int i; + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char enabled; + unsigned char direction; + + unsigned char msg_data[6]; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_AMC_GET_CLK_STATE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = atoi(argv[0]); /* clk id */ + + if(argc>2){ + msg_data[2] = atoi(argv[1]); /* resource id */ + req.msg.data_len = 3; + } + + rsp = intf->sendrecv(intf, &req); + + if (!rsp) { + printf("no response\n"); + return -1; + } + + if (rsp->ccode) { + printf("returned CC code 0x%02x\n", rsp->ccode); + return -1; + } + + enabled = (rsp->data[1]&0x8)!=0; + direction = (rsp->data[1]&0x4)!=0; + + printf("CLK setting: 0x%02x\n", rsp->data[1]); + printf(" - state: %s\n", (enabled)?"enabled":"disabled"); + printf(" - direction: %s\n", (direction)?"Source":"Receiver"); + printf(" - PLL ctrl: 0x%x\n", rsp->data[1]&0x3); + + if(enabled){ + unsigned long freq = 0; + freq = ( rsp->data[5] << 0 + | rsp->data[6] << 8 + | rsp->data[7] << 16 + | rsp->data[8] << 24 ); + printf(" - Index: %d\n", rsp->data[2]); + printf(" - Family: %d\n", rsp->data[3]); + printf(" - AccLVL: %d\n", rsp->data[4]); + printf(" - Freq: %d\n", freq); + } + + return 0; +} + + +int +ipmi_picmg_clk_set(struct ipmi_intf * intf, int argc, char ** argv) +{ + int i; + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char msg_data[11]; + unsigned long freq=0; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_AMC_SET_CLK_STATE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 11; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = strtoul(argv[0], NULL,0); /* clk id */ + msg_data[2] = strtoul(argv[1], NULL,0); /* clk index */ + msg_data[3] = strtoul(argv[2], NULL,0); /* setting */ + msg_data[4] = strtoul(argv[3], NULL,0); /* family */ + msg_data[5] = strtoul(argv[4], NULL,0); /* acc */ + + freq = strtoul(argv[5], NULL,0); + msg_data[6] = (freq >> 0)& 0xFF; /* freq */ + msg_data[7] = (freq >> 8)& 0xFF; /* freq */ + msg_data[8] = (freq >>16)& 0xFF; /* freq */ + msg_data[9] = (freq >>24)& 0xFF; /* freq */ + + msg_data[10] = strtoul(argv[6 ], NULL,0); /* resource id */ + +#if 1 +printf("## ID: %d\n", msg_data[1]); +printf("## index: %d\n", msg_data[2]); +printf("## setting: 0x02x\n", msg_data[3]); +printf("## family: %d\n", msg_data[4]); +printf("## acc: %d\n", msg_data[5]); +printf("## freq: %d\n", freq ); +printf("## res: %d\n", msg_data[10]); +#endif + + rsp = intf->sendrecv(intf, &req); + + if (!rsp) { + printf("no response\n"); + return -1; + } + + if (rsp->ccode) { + printf("returned CC code 0x%02x\n", rsp->ccode); + return -1; + } + + return 0; +} + + + int ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv) { @@ -761,14 +1104,35 @@ ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv) /* address info command */ else if (!strncmp(argv[0], "addrinfo", 8)) { - rc = ipmi_picmg_getaddr(intf); + rc = ipmi_picmg_getaddr(intf, argc-1, &argv[1]); } - + /* picmg properties command */ else if (!strncmp(argv[0], "properties", 10)) { rc = ipmi_picmg_properties(intf); } + /* fru control command */ + else if (!strncmp(argv[0], "frucontrol", 10)) { + if (argc > 2) { + rc = ipmi_picmg_fru_control(intf, argc-1, &(argv[1])); + } + else { + printf("usage: frucontrol