diff --git a/ipmitool/include/ipmitool/ipmi_fru.h b/ipmitool/include/ipmitool/ipmi_fru.h index e8a48f7..5a658a6 100644 --- a/ipmitool/include/ipmitool/ipmi_fru.h +++ b/ipmitool/include/ipmitool/ipmi_fru.h @@ -252,6 +252,57 @@ struct fru_picmgext_link_desc { #endif } __attribute__ ((packed)); + +#define FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED 0x00 +#define FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED1 0x01 +#define FRU_PICMGEXT_AMC_LINK_TYPE_PCI_EXPRESS 0x02 +#define FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING1 0x03 +#define FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING2 0x04 +#define FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET 0x05 +#define FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO 0x06 +#define FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE 0x07 + +/* This is used in command, not in FRU */ +struct fru_picmgext_amc_link_info { + unsigned char linkInfo[3]; +} __attribute__ ((packed)); + +struct fru_picmgext_amc_link_desc_core { +#ifndef WORDS_BIGENDIAN + unsigned int designator:12; + unsigned int type:8; + unsigned int ext:4; + unsigned int grouping:8; +#else + unsigned int grouping:8; + unsigned int ext:4; + unsigned int type:8; + unsigned int designator:12; +#endif +} __attribute__ ((packed)); + +struct fru_picmgext_amc_link_desc_extra { +#ifndef WORDS_BIGENDIAN + unsigned char asymetricMatch:2; + unsigned char reserved:6; +#else + unsigned char reserved:6; + unsigned char asymetricMatch:2; +#endif +} __attribute__ ((packed)); + + +struct fru_picmgext_amc_link_desc { +#ifndef WORDS_BIGENDIAN + struct fru_picmgext_amc_link_desc_core core;/* lsb */ + struct fru_picmgext_amc_link_desc_extra extra; +#else + struct fru_picmgext_amc_link_desc_extra extra; + struct fru_picmgext_amc_link_desc_core core;/* lsb */ +#endif +} __attribute__ ((packed)); + + struct fru_picmgext_chn_desc { #ifndef WORDS_BIGENDIAN unsigned char remote_slot:8; @@ -272,8 +323,8 @@ struct fru_picmgext_slot_desc { unsigned char chn_count; } __attribute__ ((packed)); -#define FRU_PICMGEXT_DESIGN_IF_BASE 0x00 -#define FRU_PICMGEXT_DESIGN_IF_FABRIC 0x01 +#define FRU_PICMGEXT_DESIGN_IF_BASE 0x00 +#define FRU_PICMGEXT_DESIGN_IF_FABRIC 0x01 #define FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL 0x02 #define FRU_PICMGEXT_DESIGN_IF_RESERVED 0x03 diff --git a/ipmitool/include/ipmitool/ipmi_picmg.h b/ipmitool/include/ipmitool/ipmi_picmg.h index feed332..ab234e4 100644 --- a/ipmitool/include/ipmitool/ipmi_picmg.h +++ b/ipmitool/include/ipmitool/ipmi_picmg.h @@ -13,26 +13,30 @@ #define PICMG_GET_ADDRESS_INFO_CMD 0x01 #define PICMG_GET_SHELF_ADDRESS_INFO_CMD 0x02 #define PICMG_SET_SHELF_ADDRESS_INFO_CMD 0x03 -#define PICMG_FRU_CONTROL_CMD 0x04 +#define PICMG_FRU_CONTROL_CMD 0x04 #define PICMG_GET_FRU_LED_PROPERTIES_CMD 0x05 -#define PICMG_GET_LED_COLOR_CAPABILITIES_CMD 0x06 +#define PICMG_GET_LED_COLOR_CAPABILITIES_CMD 0x06 #define PICMG_SET_FRU_LED_STATE_CMD 0x07 #define PICMG_GET_FRU_LED_STATE_CMD 0x08 -#define PICMG_SET_IPMB_CMD 0x09 -#define PICMG_SET_FRU_POLICY_CMD 0x0A -#define PICMG_GET_FRU_POLICY_CMD 0x0B -#define PICMG_FRU_ACTIVATION_CMD 0x0C -#define PICMG_GET_DEVICE_LOCATOR_RECORD_CMD 0x0D -#define PICMG_SET_PORT_STATE_CMD 0x0E -#define PICMG_GET_PORT_STATE_CMD 0x0F -#define PICMG_COMPUTE_POWER_PROPERTIES_CMD 0x10 +#define PICMG_SET_IPMB_CMD 0x09 +#define PICMG_SET_FRU_POLICY_CMD 0x0A +#define PICMG_GET_FRU_POLICY_CMD 0x0B +#define PICMG_FRU_ACTIVATION_CMD 0x0C +#define PICMG_GET_DEVICE_LOCATOR_RECORD_CMD 0x0D +#define PICMG_SET_PORT_STATE_CMD 0x0E +#define PICMG_GET_PORT_STATE_CMD 0x0F +#define PICMG_COMPUTE_POWER_PROPERTIES_CMD 0x10 #define PICMG_SET_POWER_LEVEL_CMD 0x11 #define PICMG_GET_POWER_LEVEL_CMD 0x12 #define PICMG_RENEGOTIATE_POWER_CMD 0x13 -#define PICMG_GET_FAN_SPEED_PROPERTIES_CMD 0x14 +#define PICMG_GET_FAN_SPEED_PROPERTIES_CMD 0x14 #define PICMG_SET_FAN_LEVEL_CMD 0x15 #define PICMG_GET_FAN_LEVEL_CMD 0x16 -#define PICMG_BUSED_RESOURCE_CMD 0x17 +#define PICMG_BUSED_RESOURCE_CMD 0x17 + +/* AMC.0 commands */ +#define PICMG_AMC_SET_PORT_STATE_CMD 0x19 +#define PICMG_AMC_GET_PORT_STATE_CMD 0x1A /* Site Types */ #define PICMG_ATCA_BOARD 0x00 @@ -42,9 +46,9 @@ #define PICMG_FAN_TRAY 0x04 #define PICMG_FAN_FILTER_TRAY 0x05 #define PICMG_ALARM 0x06 -#define PICMG_AMC 0x07 -#define PICMG_PMC 0x08 -#define PICMG_RTM 0x09 +#define PICMG_AMC 0x07 +#define PICMG_PMC 0x08 +#define PICMG_RTM 0x09 @@ -70,6 +74,17 @@ static const char* led_color_str[] __attribute__((unused)) = { +static const char* amc_link_type_str[] __attribute__((unused)) = { + " FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED", + " FRU_PICMGEXT_AMC_LINK_TYPE_RESERVED1", + " FRU_PICMGEXT_AMC_LINK_TYPE_PCI_EXPRESS", + " FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING1", + " FRU_PICMGEXT_AMC_LINK_TYPE_ADVANCED_SWITCHING2", + " FRU_PICMGEXT_AMC_LINK_TYPE_ETHERNET", + " FRU_PICMGEXT_AMC_LINK_TYPE_RAPIDIO", + " FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE", +}; + int ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv); #endif diff --git a/ipmitool/lib/ipmi_picmg.c b/ipmitool/lib/ipmi_picmg.c index bb2d299..0ac8eed 100644 --- a/ipmitool/lib/ipmi_picmg.c +++ b/ipmitool/lib/ipmi_picmg.c @@ -15,9 +15,13 @@ #define PICMG_EKEY_MODE_PRINT_ENABLED 2 #define PICMG_EKEY_MODE_PRINT_DISABLED 3 -#define PICMG_EKEY_MAX_CHANNEL 16 +#define PICMG_EKEY_MAX_CHANNEL 16 +#define PICMG_EKEY_MAX_FABRIC_CHANNEL 15 #define PICMG_EKEY_MAX_INTERFACE 3 +#define PICMG_EKEY_AMC_MAX_CHANNEL 16 +#define PICMG_EKEY_AMC_MAX_DEVICE 15 /* 4 bits */ + void ipmi_picmg_help (void) { @@ -33,7 +37,6 @@ 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"); @@ -217,7 +220,7 @@ int ipmi_picmg_portstate_get(struct ipmi_intf * intf, int interface,int channel, int mode) { - struct ipmi_rs * rsp; + struct ipmi_rs * rsp = NULL; struct ipmi_rq req; unsigned char msg_data[4]; @@ -235,7 +238,6 @@ ipmi_picmg_portstate_get(struct ipmi_intf * intf, int interface,int channel, msg_data[1] = (interface & 0x3)<<6; /* interface */ msg_data[1] |= (channel & 0x3F); /* channel number */ - rsp = intf->sendrecv(intf, &req); if (!rsp) { @@ -264,6 +266,8 @@ ipmi_picmg_portstate_get(struct ipmi_intf * intf, int interface,int channel, ( mode == PICMG_EKEY_MODE_PRINT_ALL || + mode == PICMG_EKEY_MODE_QUERY + || ( mode == PICMG_EKEY_MODE_PRINT_ENABLED && @@ -282,15 +286,15 @@ ipmi_picmg_portstate_get(struct ipmi_intf * intf, int interface,int channel, printf(" Link Type: "); if (d->type == 0 || d->type == 0xff) { - printf("Reserved\n"); + printf("Reserved %d\n",d->type); } else if (d->type >= 0x06 && d->type <= 0xef) { - printf("Reserved\n"); + printf("Reserved\n",d->type); } else if (d->type >= 0xf0 && d->type <= 0xfe) { - printf("OEM GUID Definition\n"); + printf("OEM GUID Definition\n",d->type); } else { @@ -395,6 +399,136 @@ 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 + +int +ipmi_picmg_amc_portstate_get(struct ipmi_intf * intf,int device,int channel, + int mode) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + + unsigned char msg_data[4]; + + struct fru_picmgext_amc_link_info* d; /* descriptor pointer for rec. data */ + + memset(&req, 0, sizeof(req)); + + req.msg.netfn = IPMI_NETFN_PICMG; + req.msg.cmd = PICMG_AMC_GET_PORT_STATE_CMD; + req.msg.data = msg_data; + + /* FIXME : add check for AMC or carrier device */ + req.msg.data_len = 3; + + msg_data[0] = 0x00; /* PICMG identifier */ + msg_data[1] = channel ; + msg_data[2] = device ; + + + rsp = intf->sendrecv(intf, &req); + + if (!rsp) { + printf("no response\n"); + return -1; + } + + if (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; + + /* 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)]); + + #ifndef WORDS_BIGENDIAN + /* I don't know what kind of frug addict defined this record */ + 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]; + + #else + #error "FIXME" + #endif + + 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"); + } + } + } + } + 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) { @@ -692,8 +826,14 @@ ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv) if(!strncmp(argv[1], "getall", 6)){ for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++){ for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++){ - rc = ipmi_picmg_portstate_get(intf,iface,channel, - PICMG_EKEY_MODE_PRINT_ALL); + if( + !(( iface == FRU_PICMGEXT_DESIGN_IF_FABRIC ) + && + ( channel > PICMG_EKEY_MAX_FABRIC_CHANNEL ) ) + ){ + rc = ipmi_picmg_portstate_get(intf,iface,channel, + PICMG_EKEY_MODE_PRINT_ALL); + } } } } @@ -758,6 +898,87 @@ ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv) return -1; } } + /* amc portstate command */ + else if (!strncmp(argv[0], "amcportstate", 12)) { + + lprintf(LOG_DEBUG,"PICMG: amcportstate API"); + + if (argc > 1) { + if (!strncmp(argv[1], "get", 3)){ + int channel ; + int device; + + lprintf(LOG_DEBUG,"PICMG: get"); + + if(!strncmp(argv[1], "getall", 6)){ + for(device=0;device<=PICMG_EKEY_AMC_MAX_DEVICE;device++){ + for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){ + rc = ipmi_picmg_amc_portstate_get(intf,device,channel, + PICMG_EKEY_MODE_PRINT_ALL); + } + } + } + else if(!strncmp(argv[1], "getgranted", 10)){ + for(device=0;device<=PICMG_EKEY_AMC_MAX_DEVICE;device++){ + for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){ + rc = ipmi_picmg_amc_portstate_get(intf,device,channel, + PICMG_EKEY_MODE_PRINT_ENABLED); + } + } + } + else if(!strncmp(argv[1], "getdenied", 9)){ + for(device=0;device<=PICMG_EKEY_AMC_MAX_DEVICE;device++){ + for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){ + rc = ipmi_picmg_amc_portstate_get(intf,device,channel, + PICMG_EKEY_MODE_PRINT_DISABLED); + } + } + } + else if (argc > 3){ + channel = atoi(argv[2]); + device = atoi(argv[3]); + lprintf(LOG_DEBUG,"PICMG: requesting device %d",device); + lprintf(LOG_DEBUG,"PICMG: requesting channel %d",channel); + + rc = ipmi_picmg_amc_portstate_get(intf,device,channel, + PICMG_EKEY_MODE_QUERY ); + } + else { + printf(" |getall|getgranted|getdenied\n"); + } + } + else if (!strncmp(argv[1], "set", 3)) { + if (argc > 5) { + int interface= atoi(argv[2]); + int channel = atoi(argv[3]); + int port = atoi(argv[4]); + int type = atoi(argv[5]); + int typeext = atoi(argv[6]); + int group = atoi(argv[7]); + int enable = atoi(argv[8]); + + lprintf(LOG_DEBUG,"PICMG: interface %d",interface); + lprintf(LOG_DEBUG,"PICMG: channel %d",channel); + lprintf(LOG_DEBUG,"PICMG: port %d",port); + lprintf(LOG_DEBUG,"PICMG: type %d",type); + lprintf(LOG_DEBUG,"PICMG: typeext %d",typeext); + lprintf(LOG_DEBUG,"PICMG: group %d",group); + lprintf(LOG_DEBUG,"PICMG: enable %d",enable); + + rc = ipmi_picmg_portstate_set(intf, interface, channel, port , + type, typeext ,group ,enable); + } + else { + printf(" <1|0>\n"); + return -1; + } + } + } + else { + printf("||||\n"); + return -1; + } + } /* ATCA led commands */ else if (!strncmp(argv[0], "led", 3)) {