diff --git a/ipmitool/lib/ipmi_fru.c b/ipmitool/lib/ipmi_fru.c index b7734fb..6da78dd 100644 --- a/ipmitool/lib/ipmi_fru.c +++ b/ipmitool/lib/ipmi_fru.c @@ -681,6 +681,13 @@ fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru, printf (" Maximum current load : %.3f A\n", (double) dl->max_current / 1000); break; + case FRU_RECORD_TYPE_PICMG_EXTENSION: + printf(" PICMG Extension Record\n"); + ipmi_fru_picmg_ext_print(fru_data, + i + sizeof(struct fru_multirec_header), + h->len); + + break; } i += h->len + sizeof (struct fru_multirec_header); } while (!(h->format & 0x80)); @@ -688,6 +695,267 @@ fru_area_print_multirec(struct ipmi_intf * intf, struct fru_info * fru, free(fru_data); } + +static void ipmi_fru_picmg_ext_print(unsigned char * fru_data, int off, int length) +{ + struct fru_multirec_picmgext_header *h; + int guid_count; + int offset = off; + int start_offset = off; + int i; + + h = (struct fru_multirec_picmgext_header *) &fru_data[offset]; + offset += sizeof(struct fru_multirec_picmgext_header); + + switch (h->record_id) + { + + case FRU_PICMG_BACKPLANE_P2P: + { + unsigned char index, index2; + struct fru_picmgext_slot_desc * slot_d + = (struct fru_picmgext_slot_desc*) &fru_data[offset]; + + offset += sizeof(struct fru_picmgext_slot_desc); + printf(" FRU_PICMG_BACKPLANE_P2P\n"); + + for ( ; offset <= (start_offset+length) ; ) + { + printf("\n"); + printf(" Channel Type: "); + switch ( slot_d -> chan_type ) + { + case 0x00: + case 0x07: + printf("PICMG 2.9\n"); + break; + case 0x08: + printf("Single Port Fabric IF\n"); + break; + case 0x09: + printf("Double Port Fabric IF\n"); + break; + case 0x0a: + printf("Full Channel Fabric IF\n"); + break; + case 0x0b: + printf("Base IF\n"); + break; + case 0x0c: + printf("Update Channel IF\n"); + break; + default: + printf("Unknown IF\n"); + break; + } + printf(" Slot Addr. : %02x\n", slot_d -> slot_addr ); + printf(" Channel Count: %i\n", slot_d -> chn_count); + + for ( index = 0 ; index < (slot_d -> chn_count) ; index++ ) + { + struct fru_picmgext_chn_desc * d + = (struct fru_picmgext_chn_desc *) &fru_data[offset]; + + if (verbose) + printf( " " + "Chn: %02x -> " + "Chn: %02x in " + "Slot: %02x\n", + d->local_chn, d->remote_chn, d->remote_slot); + + offset += sizeof(struct fru_picmgext_chn_desc); + } + + slot_d = (struct fru_picmgext_slot_desc*) &fru_data[offset]; + offset += sizeof(struct fru_picmgext_slot_desc); + } + } + break; + + case FRU_PICMG_ADDRESS_TABLE: + printf(" FRU_PICMG_ADDRESS_TABLE\n"); + break; + + case FRU_PICMG_SHELF_POWER_DIST: + printf(" FRU_PICMG_SHELF_POWER_DIST\n"); + break; + + case FRU_PICMG_SHELF_ACTIVATION: + printf(" FRU_PICMG_SHELF_ACTIVATION\n"); + break; + + case FRU_PICMG_SHMC_IP_CONN: + printf(" FRU_PICMG_SHMC_IP_CONN\n"); + break; + + case FRU_PICMG_BOARD_P2P: + printf(" FRU_PICMG_BOARD_P2P\n"); + + guid_count = fru_data[offset]; + printf(" GUID count: %2d\n", guid_count); + for (i = 0 ; i < guid_count; i++ ) + { + printf(" GUID %2d:\n", i); + offset += sizeof(struct fru_picmgext_guid); + } + + for ( + ++offset; + offset < off + length; + offset += sizeof(struct fru_picmgext_link_desc) + ) + { + struct fru_picmgext_link_desc * d = + (struct fru_picmgext_link_desc *) &fru_data[offset]; + + 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\n"); + } + else if (d->type >= 0x06 && d->type <= 0xef) + { + printf("Reserved\n"); + } + else if (d->type >= 0xf0 && d->type <= 0xfe) + { + printf("OEM GUID Definition\n"); + } + 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"); + } + printf(" Channel Number: 0x%02x\n", d->designator & 0x1f); + printf("\n"); + } + + break; + + case FRU_AMC_CURRENT: + printf(" FRU_AMC_CURRENT\n"); + break; + + case FRU_AMC_ACTIVATION: + printf(" FRU_AMC_ACTIVATION\n"); + { + unsigned short max_current; + + max_current = fru_data[offset]; + max_current |= fru_data[++offset]<<8; + printf(" Maximum Internal Current(@12V): %i A\n", max_current / 10); + printf(" Module Activation Rediness: %i sec.\n", fru_data[++offset]); + + printf(" Descriptor Count: %i\n", fru_data[++offset]); + printf("\n"); + + for(++offset; offset < off + length; offset += sizeof(struct fru_picmgext_activation_record)) + { + struct fru_picmgext_activation_record * a = + (struct fru_picmgext_activation_record *) &fru_data[offset]; + + printf(" IPMB-Address: 0x%x\n", a->ibmb_addr); + printf(" Max. Module Current: %i A\n", a->max_module_curr/10); + printf("\n"); + } + } + break; + + case FRU_AMC_CARRIER_P2P: + printf(" FRU_CARRIER_P2P\n"); + { + unsigned int index; + + for(offset; offset < off + length; ) + { + struct fru_picmgext_carrier_p2p_record * h = + (struct fru_picmgext_carrier_p2p_record *) &fru_data[offset]; + + printf("\n"); + printf(" Resource ID: %i", h->resource_id & 0x07); + printf(" Type: "); + if ((h->resource_id>>7) == 1) { + printf("AMC\n"); + } else { + printf("Local\n"); + } + printf(" Descriptor Count: %i\n", h->p2p_count); + + offset += sizeof(struct fru_picmgext_carrier_p2p_record); + + for (index = 0; index < h->p2p_count; index++) + { + struct fru_picmgext_carrier_p2p_descriptor * d = + (struct fru_picmgext_carrier_p2p_descriptor*)&fru_data[offset]; + + printf(" Port: %02d\t-> Remote Port: %02d\t", + d->local_port, d->remote_port); + if((d->remote_resource_id >> 7) == 1) + printf("[ AMC ID: %02d ]\n", d->remote_resource_id & 0x07); + else + printf("[ local ID: %02d ]\n", d->remote_resource_id & 0x07); + + offset += sizeof(struct fru_picmgext_carrier_p2p_descriptor); + + } + } + } + break; + + case FRU_AMC_P2P: + printf(" FRU_AMC_P2P\n"); + break; + + case FRU_AMC_CARRIER_INFO: + printf(" FRU_CARRIER_INFO\n"); + break; + + default: + printf(" Unknown PICMG Extension Record ID: %x\n", h->record_id); + break; + + } +} + + /* __ipmi_fru_print - Do actual work to print a FRU by its ID * * @intf: ipmi interface diff --git a/ipmitool/lib/ipmi_picmg.c b/ipmitool/lib/ipmi_picmg.c new file mode 100644 index 0000000..e334ffb --- /dev/null +++ b/ipmitool/lib/ipmi_picmg.c @@ -0,0 +1,747 @@ + +/* + (C) Kontron + +*/ + +#include +#include +#include /* for access to link descriptor defines */ + + +int +ipmi_picmg_help (void) +{ + printf(" properties - get PICMG properties\n"); + printf(" addrinfo - get address information\n"); + printf(" activate - activate a FRU\n"); + printf(" deactivate - deactivate a FRU\n"); + printf(" policy get - get the FRU activation policy\n"); + printf(" policy set - get the FRU activation policy\n"); + printf(" portstate get - get port state \n"); + printf(" portstate 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(" power get - get power level info\n"); + printf(" power set - set power level\n"); +} + +int +ipmi_picmg_getaddr(struct ipmi_intf * intf) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + unsigned char msg_data; + + 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; + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error getting address information\n"); + return -1; + } + + printf("Hardware Address : 0x%02x\n", rsp->data[1]); + printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]); + printf("FRU ID : 0x%02x\n", rsp->data[4]); + printf("Site ID : 0x%02x\n", rsp->data[5]); + + printf("Site Type : "); + switch (rsp->data[6]) { + case PICMG_ATCA_BOARD: + printf("ATCA board\n"); + break; + case PICMG_POWER_ENTRY: + printf("Power Entry Module\n"); + break; + case PICMG_SHELF_FRU: + printf("Shelf FRU\n"); + break; + case PICMG_DEDICATED_SHMC: + printf("Dedicated Shelf Manager\n"); + break; + case PICMG_FAN_TRAY: + printf("Fan Tray\n"); + break; + case PICMG_FAN_FILTER_TRAY: + printf("Fan Filter Tray\n"); + break; + case PICMG_ALARM: + printf("Alarm module\n"); + break; + case PICMG_AMC: + printf("AMC\n"); + break; + case PICMG_PMC: + printf("PMC\n"); + break; + case PICMG_RTM: + printf("RTM\n"); + break; + default: + if (rsp->data[6] >= 0xc0 && rsp->data[6] <= 0xcf) { + printf("OEM\n"); + } else { + printf("unknown\n"); + } + } + + return 0; +} + +int +ipmi_picmg_properties(struct ipmi_intf * intf) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + unsigned char msg_data; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD; + req.msg.data = &msg_data; + req.msg.data_len = 1; + msg_data = 0; + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error getting address information\n"); + return -1; + } + + printf("PICMG identifier : 0x%02x\n", rsp->data[0]); + printf("PICMG Ext. Version : %i.%i\n", rsp->data[1]&0x0f, (rsp->data[1]&0xf0) >> 4); + printf("Max FRU Device ID : 0x%02x\n", rsp->data[2]); + printf("FRU Device ID : 0x%02x\n", rsp->data[3]); +} + + + +#define PICMG_FRU_DEACTIVATE (unsigned char) 0x00 +#define PICMG_FRU_ACTIVATE (unsigned char) 0x01 + +int +ipmi_picmg_fru_activation(struct ipmi_intf * intf, int argc, char ** argv, unsigned char state) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + + struct picmg_set_fru_activation_cmd cmd; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_FRU_ACTIVATION_CMD; + req.msg.data = (unsigned char*) &cmd; + req.msg.data_len = 3; + + cmd.picmg_id = 0; /* PICMG identifier */ + cmd.fru_id = (unsigned char) atoi(argv[0]); /* FRU ID */ + cmd.fru_state = state; + + rsp = intf->sendrecv(intf, &req); + + if (!rsp || rsp->ccode) { + printf("Error activation/deactivation of FRU\n"); + return -1; + } + if (rsp->data[0] != 0x00) { + printf("Error\n"); + } + + return 0; +} + + +int +ipmi_picmg_fru_activation_policy_get(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_GET_FRU_POLICY_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + msg_data[0] = 0; /* PICMG identifier */ + msg_data[1] = (unsigned char) 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("Activation Policy for FRU %x: ", atoi(argv[0]) ); + printf(" %s\n",(*(rsp->data+3)&0x01 == 0x01)?"is locked":"is not locked"); + + return 0; +} + +int +ipmi_picmg_portstate_get(struct ipmi_intf * intf, int argc, char ** argv) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char msg_data[4]; + + struct fru_picmgext_link_desc* d; /* descriptor pointer for rec. data */ + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_GET_PORT_STATE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 2; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = (atoi(argv[0]) & 0x3)<<6; /* interface */ + msg_data[1] |= (atoi(argv[1]) & 0x3F); /* channel number */ + + 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; + } + + if (rsp->data_len == 6) { + d = (struct fru_picmgext_link_desc *) &(rsp->data[1]); + + 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\n"); + } + else if (d->type >= 0x06 && d->type <= 0xef) + { + printf("Reserved\n"); + } + else if (d->type >= 0xf0 && d->type <= 0xfe) + { + printf("OEM GUID Definition\n"); + } + 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"); + } + printf(" Channel Number: 0x%02x\n", d->designator & 0x1f); + printf("\n"); + printf(" STATE: %s\n", rsp->data[5] == 0x01?"enabled":"disabled"); + } + + + return 0; +} + +int +ipmi_picmg_portstate_set(struct ipmi_intf * intf, int argc, char ** argv) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char msg_data[6]; + struct fru_picmgext_link_desc* d; + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_SET_PORT_STATE_CMD; + req.msg.data = msg_data; + req.msg.data_len = 6; + + msg_data[0] = 0x00; /* PICMG identifier */ + + d = (struct fru_picmgext_link_desc*) &(msg_data[1]); + + d->designator = (unsigned char) (atoi(argv[0]) & 0x1F); /* channel */ + d->designator = (unsigned char) ((atoi(argv[1]) & 0x03) << 6); /* interface */ + d->designator = (unsigned char) ((atoi(argv[2]) & 0x03) << 8); /* port */ + + d->type = (unsigned char) (atoi(argv[3]) & 0xFF); /* link type */ + d->ext = (unsigned char) (atoi(argv[4]) & 0x03); /* type ext */ + d->grouping = (unsigned char) (atoi(argv[5]) & 0xFF); /* type ext */ + + msg_data[5] = (unsigned char) (atoi(argv[6]) & 0x01); /* en/dis */ + + 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_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; +} + +int +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; + } + + if (rsp->ccode) { + printf("returned CC code 0x%02x\n", rsp->ccode); + return -1; + } + + 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(" OVERRIDE state: %s\n\r", led_color_str[ rsp->data[3] ] ); + + return 0; +} + +int +ipmi_picmg_get_led_state(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_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; + } + + if (rsp->ccode) { + 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(" Local Control On-Duration: %x\n\r", rsp->data[3] ); + printf(" Local Control Color: %s\n\r", 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] ); + 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 On-Duration: %x\n\r", rsp->data[6] ); + printf(" Override Color: %s\n\r", led_color_str[ rsp->data[7] ]); + printf(" Lamp test duration: %x\n\r", rsp->data[8] ); + } + + return 0; +} + +int +ipmi_picmg_set_led_state(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_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; + } + + if (rsp->ccode) { + printf("returned CC code 0x%02x\n", rsp->ccode); + return -1; + } + + + return 0; +} + +int +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]); + } + return 0; +} + +int +ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv) +{ + int rc; + + if (argc == 0 || (!strncmp(argv[0], "help", 4))) { + ipmi_picmg_help(); + return 0; + } + + /* address info command */ + else if (!strncmp(argv[0], "addrinfo", 8)) { + rc = ipmi_picmg_getaddr(intf); + } + + /* picmg properties command */ + else if (!strncmp(argv[0], "properties", 10)) { + rc = ipmi_picmg_properties(intf); + } + + /* fru activation command */ + else if (!strncmp(argv[0], "activate", 8)) { + if (argc > 1) { + rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_ACTIVATE); + } + else { + printf("specify the FRU to activate\n"); + return -1; + } + } + + /* fru deactivation command */ + else if (!strncmp(argv[0], "deactivate", 10)) { + if (argc > 1) { + rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_DEACTIVATE); + }else { + printf("specify the FRU to deactivate\n"); + return -1; + } + } + + /* activation policy command */ + else if (!strncmp(argv[0], "policy", 6)) { + if (argc > 2) { + if (!strncmp(argv[1], "get", 3)) { + rc = ipmi_picmg_fru_activation_policy_get(intf, argc-1, &(argv[2])); + } + else if (!strncmp(argv[1], "set", 6)) { + printf("tbd\n"); + return -1; + } + else { + printf("specify fru\n"); + return -1; + } + }else { + printf("wrong parameters\n"); + return -1; + } + } + + /* portstate command */ + else if (!strncmp(argv[0], "portstate", 9)) { + if (argc > 2) { + if (!strncmp(argv[1], "get", 3)) { + rc = ipmi_picmg_portstate_get(intf, argc-1, &(argv[2])); + } + + else { + printf("portstate get \n"); + } + } + + else if (!strncmp(argv[1], "set", 3)) { + if (argc > 5) { + rc = ipmi_picmg_portstate_set(intf, argc-1, &(argv[2])); + } + else { + printf("portstate set \n"); + return -1; + } + } + else { + printf("|\n"); + return -1; + } + } + + /* ATCA led commands */ + else if (!strncmp(argv[0], "led", 3)) { + if (argc > 1) { + if (!strncmp(argv[1], "prop", 4)) { + if (argc > 2) { + rc = ipmi_picmg_get_led_properties(intf, argc-1, &(argv[2])); + } + else { + printf("led prop \n"); + } + } + else if (!strncmp(argv[1], "cap", 3)) { + if (argc > 3) { + rc = ipmi_picmg_get_led_capabilities(intf, argc-1, &(argv[2])); + } + else { + printf("led cap \n"); + } + } + else if (!strncmp(argv[1], "get", 3)) { + if (argc > 3) { + rc = ipmi_picmg_get_led_state(intf, argc-1, &(argv[2])); + } + else { + printf("led get \n"); + } + } + else if (!strncmp(argv[1], "set", 3)) { + if (argc > 6) { + rc = ipmi_picmg_set_led_state(intf, argc-1, &(argv[2])); + } + else { + printf("led set \n"); + printf(" \n"); + printf(" \n"); + printf(" 0: LED OFF override\n"); + printf(" 1 - 250: LED blinking override (off duration)\n"); + printf(" 251: LED Lamp Test\n"); + printf(" 252: LED restore to local control\n"); + printf(" 255: LED ON override\n"); + printf(" 1 - 127: LED Lamp Test / on duration\n"); + printf(" \n"); + } + } + else { + printf("prop | cap | get | set\n"); + } + } + } + /* power commands */ + else if (!strncmp(argv[0], "power", 5)) { + if (argc > 1) { + if (!strncmp(argv[1], "get", 3)) { + if (argc > 3) { + rc = ipmi_picmg_get_power_level(intf, argc-1, &(argv[2])); + } + else { + printf("power get \n"); + printf(" 0 : steady state powert draw levels\n"); + printf(" 1 : desired steady state draw levels\n"); + printf(" 2 : early power draw levels\n"); + printf(" 3 : desired early levels\n"); + + return -1; + } + } + else if (!strncmp(argv[1], "set", 3)) { + if (argc > 5) { + printf("not implemented yet\n"); + } + else { + return -1; + } + } + else { + printf("|\n"); + return -1; + } + } + else { + printf("|\n"); + return -1; + } + } + + else { + + ipmi_picmg_help(); + return -1; + } + + return rc; + +} diff --git a/ipmitool/src/ipmitool.c b/ipmitool/src/ipmitool.c index 4746095..26dede4 100644 --- a/ipmitool/src/ipmitool.c +++ b/ipmitool/src/ipmitool.c @@ -58,6 +58,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H # include @@ -92,6 +93,7 @@ struct ipmi_cmd ipmitool_cmd_list[] = { { ipmi_channel_main, "channel", "Configure Management Controller channels" }, { ipmi_session_main, "session", "Print session information" }, { ipmi_sunoem_main, "sunoem", "OEM Commands for Sun servers" }, + { ipmi_picmg_main, "picmg", "Run a PICMG/ATCA extended cmd"}, #ifdef HAVE_READLINE { ipmi_shell_main, "shell", "Launch interactive IPMI shell" }, #endif