1 /* 2 Copyright (c) Kontron. All right reserved 3 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistribution of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistribution in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * Neither the name of Kontron, or the names of 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * This software is provided "AS IS," without a warranty of any kind. 20 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23 * DELL COMPUTERS ("DELL") AND ITS LICENSORS SHALL NOT BE LIABLE 24 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26 * DELL OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30 * EVEN IF DELL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31 */ 32 33 34 #include <ipmitool/ipmi_intf.h> 35 #include <ipmitool/ipmi_picmg.h> 36 #include <ipmitool/ipmi_fru.h> /* for access to link descriptor defines */ 37 #include <ipmitool/ipmi_strings.h> 38 #include <ipmitool/log.h> 39 40 #define PICMG_EXTENSION_ATCA_MAJOR_VERSION 2 41 #define PICMG_EXTENSION_AMC0_MAJOR_VERSION 4 42 #define PICMG_EXTENSION_UTCA_MAJOR_VERSION 5 43 44 45 #define PICMG_EKEY_MODE_QUERY 0 46 #define PICMG_EKEY_MODE_PRINT_ALL 1 47 #define PICMG_EKEY_MODE_PRINT_ENABLED 2 48 #define PICMG_EKEY_MODE_PRINT_DISABLED 3 49 50 #define PICMG_EKEY_MAX_CHANNEL 16 51 #define PICMG_EKEY_MAX_FABRIC_CHANNEL 15 52 #define PICMG_EKEY_MAX_INTERFACE 3 53 54 #define PICMG_EKEY_AMC_MAX_CHANNEL 16 55 #define PICMG_EKEY_AMC_MAX_DEVICE 15 /* 4 bits */ 56 57 58 typedef enum picmg_bused_resource_mode { 59 PICMG_BUSED_RESOURCE_SUMMARY, 60 } t_picmg_bused_resource_mode ; 61 62 63 typedef enum picmg_card_type { 64 PICMG_CARD_TYPE_CPCI, 65 PICMG_CARD_TYPE_ATCA, 66 PICMG_CARD_TYPE_AMC, 67 PICMG_CARD_TYPE_RESERVED 68 } t_picmg_card_type ; 69 70 /* This is the version of the PICMG Extenstion */ 71 static t_picmg_card_type PicmgCardType = PICMG_CARD_TYPE_RESERVED; 72 73 void 74 ipmi_picmg_help (void) 75 { 76 lprintf(LOG_NOTICE, "PICMG commands:"); 77 lprintf(LOG_NOTICE, " properties - get PICMG properties"); 78 lprintf(LOG_NOTICE, " frucontrol - FRU control"); 79 lprintf(LOG_NOTICE, " addrinfo - get address information"); 80 lprintf(LOG_NOTICE, " activate - activate a FRU"); 81 lprintf(LOG_NOTICE, " deactivate - deactivate a FRU"); 82 lprintf(LOG_NOTICE, " policy get - get the FRU activation policy"); 83 lprintf(LOG_NOTICE, " policy set - set the FRU activation policy"); 84 lprintf(LOG_NOTICE, " portstate get - get port state"); 85 lprintf(LOG_NOTICE, 86 " portstate getdenied - get all denied[disabled] port description"); 87 lprintf(LOG_NOTICE, 88 " portstate getgranted - get all granted[enabled] port description"); 89 lprintf(LOG_NOTICE, 90 " portstate getall - get all port state description"); 91 lprintf(LOG_NOTICE, " portstate set - set port state"); 92 lprintf(LOG_NOTICE, " amcportstate get - get port state"); 93 lprintf(LOG_NOTICE, " amcportstate set - set port state"); 94 lprintf(LOG_NOTICE, " led prop - get led properties"); 95 lprintf(LOG_NOTICE, " led cap - get led color capabilities"); 96 lprintf(LOG_NOTICE, " led get - get led state"); 97 lprintf(LOG_NOTICE, " led set - set led state"); 98 lprintf(LOG_NOTICE, " power get - get power level info"); 99 lprintf(LOG_NOTICE, " power set - set power level"); 100 lprintf(LOG_NOTICE, " clk get - get clk state"); 101 lprintf(LOG_NOTICE, 102 " clk getdenied - get all(up to 16) denied[disabled] clock descriptions"); 103 lprintf(LOG_NOTICE, 104 " clk getgranted - get all(up to 16) granted[enabled] clock descriptions"); 105 lprintf(LOG_NOTICE, 106 " clk getall - get all(up to 16) clock descriptions"); 107 lprintf(LOG_NOTICE, " clk set - set clk state"); 108 lprintf(LOG_NOTICE, 109 " busres summary - display brief bused resource status info"); 110 } 111 112 113 struct sAmcAddrMap { 114 unsigned char ipmbLAddr; 115 char* amcBayId; 116 unsigned char siteNum; 117 } amcAddrMap[] = { 118 {0xFF, "reserved", 0}, 119 {0x72, "A1" , 1}, 120 {0x74, "A2" , 2}, 121 {0x76, "A3" , 3}, 122 {0x78, "A4" , 4}, 123 {0x7A, "B1" , 5}, 124 {0x7C, "B2" , 6}, 125 {0x7E, "B3" , 7}, 126 {0x80, "B4" , 8}, 127 {0x82, "reserved", 0}, 128 {0x84, "reserved", 0}, 129 {0x86, "reserved", 0}, 130 {0x88, "reserved", 0}, 131 }; 132 133 /* is_amc_channel - wrapper to convert user input into integer 134 * AMC Channel range seems to be <0..255>, bits [7:0] 135 * 136 * @argv_ptr: source string to convert from; usually argv 137 * @amc_chan_ptr: pointer where to store result 138 * returns: zero on success, other values mean error 139 */ 140 int 141 is_amc_channel(const char *argv_ptr, uint8_t *amc_chan_ptr) 142 { 143 if (!argv_ptr || !amc_chan_ptr) { 144 lprintf(LOG_ERR, "is_amc_channel(): invalid argument(s)."); 145 return (-1); 146 } 147 if (str2uchar(argv_ptr, amc_chan_ptr) == 0) { 148 return 0; 149 } 150 lprintf(LOG_ERR, "Given AMC Channel '%s' is invalid.", argv_ptr); 151 return (-1); 152 } 153 /* is_amc_dev - wrapper to convert user input into integer. 154 * AMC Dev ID limits are uknown. 155 * 156 * @argv_ptr: source string to convert from; usually argv 157 * @amc_dev_ptr: pointer where to store result 158 * returns: zero on success, other values mean error 159 */ 160 int 161 is_amc_dev(const char *argv_ptr, int32_t *amc_dev_ptr) 162 { 163 if (!argv_ptr || !amc_dev_ptr) { 164 lprintf(LOG_ERR, "is_amc_dev(): invalid argument(s)."); 165 return (-1); 166 } 167 if (str2int(argv_ptr, amc_dev_ptr) == 0 && *amc_dev_ptr >= 0) { 168 return 0; 169 } 170 lprintf(LOG_ERR, "Given PICMG Device '%s' is invalid.", 171 argv_ptr); 172 return (-1); 173 } 174 /* is_amc_intf - wrapper to convert user input into integer. 175 * AMC Interface (ID) limits are uknown. 176 * 177 * @argv_ptr: source string to convert from; usually argv 178 * @amc_intf_ptr: pointer where to store result 179 * returns: zero on success, other values mean error 180 */ 181 int 182 is_amc_intf(const char *argv_ptr, int32_t *amc_intf_ptr) 183 { 184 if (!argv_ptr || !amc_intf_ptr) { 185 lprintf(LOG_ERR, "is_amc_intf(): invalid argument(s)."); 186 return (-1); 187 } 188 if (str2int(argv_ptr, amc_intf_ptr) == 0 && *amc_intf_ptr >= 0) { 189 return 0; 190 } 191 lprintf(LOG_ERR, "Given PICMG Interface '%s' is invalid.", 192 argv_ptr); 193 return (-1); 194 } 195 /* is_amc_port - wrapper to convert user input into integer. 196 * AMC Port limits are uknown. 197 * 198 * @argv_ptr: source string to convert from; usually argv 199 * @amc_port_ptr: pointer where to store result 200 * returns: zero on success, other values mean error 201 */ 202 int 203 is_amc_port(const char *argv_ptr, int32_t *amc_port_ptr) 204 { 205 if (!argv_ptr || !amc_port_ptr) { 206 lprintf(LOG_ERR, "is_amc_port(): invalid argument(s)."); 207 return (-1); 208 } 209 if (str2int(argv_ptr, amc_port_ptr) == 0 && *amc_port_ptr >= 0) { 210 return 0; 211 } 212 lprintf(LOG_ERR, "Given PICMG Port '%s' is invalid.", argv_ptr); 213 return (-1); 214 } 215 /* is_clk_acc - wrapper to convert user input into integer. 216 * Clock Accuracy limits are uknown[1byte by spec]. 217 * 218 * @argv_ptr: source string to convert from; usually argv 219 * @clk_acc_ptr: pointer where to store result 220 * returns: zero on success, other values mean error 221 */ 222 int 223 is_clk_acc(const char *argv_ptr, uint8_t *clk_acc_ptr) 224 { 225 if (!argv_ptr || !clk_acc_ptr) { 226 lprintf(LOG_ERR, "is_clk_acc(): invalid argument(s)."); 227 return (-1); 228 } 229 if (str2uchar(argv_ptr, clk_acc_ptr) == 0) { 230 return 0; 231 } 232 lprintf(LOG_ERR, "Given Clock Accuracy '%s' is invalid.", 233 argv_ptr); 234 return (-1); 235 } 236 /* is_clk_family - wrapper to convert user input into integer. 237 * Clock Family limits are uknown[1byte by spec]. 238 * 239 * @argv_ptr: source string to convert from; usually argv 240 * @clk_family_ptr: pointer where to store result 241 * returns: zero on success, other values mean error 242 */ 243 int 244 is_clk_family(const char *argv_ptr, uint8_t *clk_family_ptr) 245 { 246 if (!argv_ptr || !clk_family_ptr) { 247 lprintf(LOG_ERR, "is_clk_family(): invalid argument(s)."); 248 return (-1); 249 } 250 if (str2uchar(argv_ptr, clk_family_ptr) == 0) { 251 return 0; 252 } 253 lprintf(LOG_ERR, "Given Clock Family '%s' is invalid.", 254 argv_ptr); 255 return (-1); 256 } 257 /* is_clk_freq - wrapper to convert user input into integer. 258 * Clock Frequency limits are uknown, but specification says 259 * 3Bytes + 1B checksum 260 * 261 * @argv_ptr: source string to convert from; usually argv 262 * @clk_freq_ptr: pointer where to store result 263 * returns: zero on success, other values mean error 264 */ 265 int 266 is_clk_freq(const char *argv_ptr, uint32_t *clk_freq_ptr) 267 { 268 if (!argv_ptr || !clk_freq_ptr) { 269 lprintf(LOG_ERR, "is_clk_freq(): invalid argument(s)."); 270 return (-1); 271 } 272 if (str2uint(argv_ptr, clk_freq_ptr) == 0) { 273 return 0; 274 } 275 lprintf(LOG_ERR, "Given Clock Frequency '%s' is invalid.", 276 argv_ptr); 277 return (-1); 278 } 279 /* is_clk_id - wrapper to convert user input into integer. 280 * Clock ID limits are uknown, however it's 1B by specification and I've 281 * found two ranges: <1..5> or <0..15> 282 * 283 * @argv_ptr: source string to convert from; usually argv 284 * @clk_id_ptr: pointer where to store result 285 * returns: zero on success, other values mean error 286 */ 287 int 288 is_clk_id(const char *argv_ptr, uint8_t *clk_id_ptr) 289 { 290 if (!argv_ptr || !clk_id_ptr) { 291 lprintf(LOG_ERR, "is_clk_id(): invalid argument(s)."); 292 return (-1); 293 } 294 if (str2uchar(argv_ptr, clk_id_ptr) == 0) { 295 return 0; 296 } 297 lprintf(LOG_ERR, "Given Clock ID '%s' is invalid.", argv_ptr); 298 return (-1); 299 } 300 /* is_clk_index - wrapper to convert user input into integer. 301 * Clock Index limits are uknown[1B by spec] 302 * 303 * @argv_ptr: source string to convert from; usually argv 304 * @clk_index_ptr: pointer where to store result 305 * returns: zero on success, other values mean error 306 */ 307 int 308 is_clk_index(const char *argv_ptr, uint8_t *clk_index_ptr) 309 { 310 if (!argv_ptr || !clk_index_ptr) { 311 lprintf(LOG_ERR, "is_clk_index(): invalid argument(s)."); 312 return (-1); 313 } 314 if (str2uchar(argv_ptr, clk_index_ptr) == 0) { 315 return 0; 316 } 317 lprintf(LOG_ERR, "Given Clock Index '%s' is invalid.", argv_ptr); 318 return (-1); 319 } 320 /* is_clk_resid - wrapper to convert user input into integer. 321 * Clock Resource Index(?) limits are uknown, but maximum seems to be 15. 322 * 323 * @argv_ptr: source string to convert from; usually argv 324 * @clk_resid_ptr: pointer where to store result 325 * returns: zero on success, other values mean error 326 */ 327 int 328 is_clk_resid(const char *argv_ptr, int8_t *clk_resid_ptr) 329 { 330 if (!argv_ptr || !clk_resid_ptr) { 331 lprintf(LOG_ERR, "is_clk_resid(): invalid argument(s)."); 332 return (-1); 333 } 334 if (str2char(argv_ptr, clk_resid_ptr) == 0 335 && *clk_resid_ptr > (-1)) { 336 return 0; 337 } 338 lprintf(LOG_ERR, "Given Resource ID '%s' is invalid.", 339 clk_resid_ptr); 340 return (-1); 341 } 342 /* is_clk_setting - wrapper to convert user input into integer. 343 * Clock Setting is a 1B bitfield: 344 * x [7:4] - reserved 345 * x [3] - state - 0/1 346 * x [2] - direction - 0/1 347 * x [1:0] - PLL ctrl - 00/01/10/11[Reserved] 348 * 349 * @argv_ptr: source string to convert from; usually argv 350 * @clk_setting_ptr: pointer where to store result 351 * returns: zero on success, other values mean error 352 */ 353 int 354 is_clk_setting(const char *argv_ptr, uint8_t *clk_setting_ptr) 355 { 356 if (!argv_ptr || !clk_setting_ptr) { 357 lprintf(LOG_ERR, "is_clk_setting(): invalid argument(s)."); 358 return (-1); 359 } 360 if (str2uchar(argv_ptr, clk_setting_ptr) == 0) { 361 return 0; 362 } 363 /* FIXME - validate bits 4-7 are 0 ? */ 364 lprintf(LOG_ERR, "Given Clock Setting '%s' is invalid.", argv_ptr); 365 return (-1); 366 } 367 /* is_enable - wrapper to convert user input into integer. 368 * Valid input range for Enable is <0..1>. 369 * 370 * @argv_ptr: source string to convert from; usually argv 371 * @enable_ptr: pointer where to store result 372 * returns: zero on success, other values mean error 373 */ 374 int 375 is_enable(const char *argv_ptr, uint8_t *enable_ptr) 376 { 377 if (!argv_ptr || !enable_ptr) { 378 lprintf(LOG_ERR, "is_enable(): invalid argument(s)."); 379 return (-1); 380 } 381 if (str2uchar(argv_ptr, enable_ptr) == 0 382 && (*enable_ptr == 0 || *enable_ptr == 1)) { 383 return 0; 384 } 385 lprintf(LOG_ERR, "Given Enable '%s' is invalid.", argv_ptr); 386 return (-1); 387 } 388 /* is_enable - wrapper to convert user input into integer. 389 * LED colors: 390 * - valid <1..6>, <0xE..0xF> 391 * - reserved [0, 7] 392 * - undefined <8..D> 393 * 394 * @argv_ptr: source string to convert from; usually argv 395 * @enable_ptr: pointer where to store result 396 * returns: zero on success, other values mean error 397 */ 398 int 399 is_led_color(const char *argv_ptr, uint8_t *led_color_ptr) 400 { 401 if (!argv_ptr || !led_color_ptr) { 402 lprintf(LOG_ERR, "is_led_color(): invalid argument(s)."); 403 return (-1); 404 } 405 if (str2uchar(argv_ptr, led_color_ptr) != 0) { 406 lprintf(LOG_ERR, "Given LED Color '%s' is invalid.", 407 argv_ptr); 408 lprintf(LOG_ERR, 409 "LED Color must be from ranges: <1..6>, <0xE..0xF>"); 410 return (-1); 411 } 412 if ((*led_color_ptr >= 1 && *led_color_ptr <= 6) 413 || (*led_color_ptr >= 0xE && *led_color_ptr <= 0xF)) { 414 return 0; 415 } 416 lprintf(LOG_ERR, "Given LED Color '%s' is out of range.", argv_ptr); 417 lprintf(LOG_ERR, "LED Color must be from ranges: <1..6>, <0xE..0xF>"); 418 return (-1); 419 } 420 /* is_led_duration - wrapper to convert user input into integer. 421 * LED duration range is <1..127> 422 * 423 * @argv_ptr: source string to convert from; usually argv 424 * @enable_ptr: pointer where to store result 425 * returns: zero on success, other values mean error 426 */ 427 int 428 is_led_duration(const char *argv_ptr, uint8_t *led_duration_ptr) 429 { 430 if (!argv_ptr || !led_duration_ptr) { 431 lprintf(LOG_ERR, "is_led_duration(): invalid argument(s)."); 432 return (-1); 433 } 434 if (str2uchar(argv_ptr, led_duration_ptr) == 0 435 && *led_duration_ptr > 0 && *led_duration_ptr <= 127) { 436 return 0; 437 } 438 lprintf(LOG_ERR, "Given LED Duration '%s' is invalid", argv_ptr); 439 return (-1); 440 } 441 /* is_led_function - wrapper to convert user input into integer. 442 * LED functions, however, might differ by OEM: 443 * - 0x00 - off override 444 * - <0x01..0xFA> - blinking override 445 * - 0xFB - lamp test state 446 * - 0xFC - state restored to local ctrl state 447 * - <0xFD..0xFE> - reserved 448 * - 0xFF - on override 449 * 450 * @argv_ptr: source string to convert from; usually argv 451 * @led_fn_ptr: pointer where to store result 452 * returns: zero on success, other values mean error 453 */ 454 int 455 is_led_function(const char *argv_ptr, uint8_t *led_fn_ptr) 456 { 457 if (!argv_ptr || !led_fn_ptr) { 458 lprintf(LOG_ERR, "is_led_function(): invalid argument(s)."); 459 return (-1); 460 } 461 if (str2uchar(argv_ptr, led_fn_ptr) == 0 462 && (*led_fn_ptr < 0xFD || *led_fn_ptr > 0xFE)) { 463 return 0; 464 } 465 lprintf(LOG_ERR, "Given LED Function '%s' is invalid.", argv_ptr); 466 return (-1); 467 } 468 /* is_led_id - wrapper to convert user input into integer. 469 * LED ID range seems to be <0..255> 470 * 471 * @argv_ptr: source string to convert from; usually argv 472 * @led_id_ptr: pointer where to store result 473 * returns: zero on success, other values mean error 474 */ 475 int 476 is_led_id(const char *argv_ptr, uint8_t *led_id_ptr) 477 { 478 if (!argv_ptr || !led_id_ptr) { 479 lprintf(LOG_ERR, "is_led_id(): invalid argument(s)."); 480 return (-1); 481 } 482 if (str2uchar(argv_ptr, led_id_ptr) == 0) { 483 return 0; 484 } 485 lprintf(LOG_ERR, "Given LED ID '%s' is invalid.", argv_ptr); 486 return (-1); 487 } 488 /* is_link_group - wrapper to convert user input into integer. 489 * Link Grouping ID limis are unknown, bits [31:24] by spec. 490 * 491 * @argv_ptr: source string to convert from; usually argv 492 * @link_grp_ptr: pointer where to store result 493 * returns: zero on success, other values mean error 494 */ 495 int 496 is_link_group(const char *argv_ptr, uint8_t *link_grp_ptr) 497 { 498 if (!argv_ptr || !link_grp_ptr) { 499 lprintf(LOG_ERR, "is_link_group(): invalid argument(s)."); 500 return (-1); 501 } 502 if (str2uchar(argv_ptr, link_grp_ptr) == 0) { 503 return 0; 504 } 505 lprintf(LOG_ERR, "Given Link Group '%s' is invalid.", argv_ptr); 506 return (-1); 507 } 508 /* is_link_type - wrapper to convert user input into integer. 509 * Link Type limits are unknown, bits [19:12] 510 * 511 * @argv_ptr: source string to convert from; usually argv 512 * @link_type_ptr: pointer where to store result 513 * returns: zero on success, other values mean error 514 */ 515 int 516 is_link_type(const char *argv_ptr, uint8_t *link_type_ptr) 517 { 518 if (!argv_ptr || !link_type_ptr) { 519 lprintf(LOG_ERR, "is_link_type(): invalid argument(s)."); 520 return (-1); 521 } 522 if (str2uchar(argv_ptr, link_type_ptr) == 0) { 523 return 0; 524 } 525 lprintf(LOG_ERR, "Given Link Type '%s' is invalid.", argv_ptr); 526 return (-1); 527 } 528 /* is_link_type_ext - wrapper to convert user input into integer. 529 * Link Type Extension limits are unknown, bits [23:20] => <0..15> ? 530 * 531 * @argv_ptr: source string to convert from; usually argv 532 * @link_type_ext_ptr: pointer where to store result 533 * returns: zero on success, other values mean error 534 */ 535 int 536 is_link_type_ext(const char *argv_ptr, uint8_t *link_type_ext_ptr) 537 { 538 if (!argv_ptr || !link_type_ext_ptr) { 539 lprintf(LOG_ERR, "is_link_type_ext(): invalid argument(s)."); 540 return (-1); 541 } 542 if (str2uchar(argv_ptr, link_type_ext_ptr) != 0 543 || *link_type_ext_ptr > 15) { 544 lprintf(LOG_ERR, 545 "Given Link Type Extension '%s' is invalid.", 546 argv_ptr); 547 return (-1); 548 } 549 return 0; 550 } 551 552 int 553 ipmi_picmg_getaddr(struct ipmi_intf * intf, int argc, char ** argv) 554 { 555 struct ipmi_rs * rsp; 556 struct ipmi_rq req; 557 unsigned char msg_data[5]; 558 559 memset(&req, 0, sizeof(req)); 560 req.msg.netfn = IPMI_NETFN_PICMG; 561 req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD; 562 req.msg.data = msg_data; 563 req.msg.data_len = 2; 564 msg_data[0] = 0; /* picmg identifier */ 565 msg_data[1] = 0; /* default fru id */ 566 567 if(argc > 0) { 568 if (is_fru_id(argv[0], &msg_data[1]) != 0) { 569 return (-1); 570 } 571 } 572 573 rsp = intf->sendrecv(intf, &req); 574 if (!rsp) { 575 lprintf(LOG_ERR, "Error. No valid response received."); 576 return (-1); 577 } else if (rsp->ccode) { 578 lprintf(LOG_ERR, "Error getting address information CC: 0x%02x", 579 rsp->ccode); 580 return (-1); 581 } 582 583 printf("Hardware Address : 0x%02x\n", rsp->data[1]); 584 printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]); 585 printf("FRU ID : 0x%02x\n", rsp->data[4]); 586 printf("Site ID : 0x%02x\n", rsp->data[5]); 587 588 printf("Site Type : "); 589 switch (rsp->data[6]) { 590 case PICMG_ATCA_BOARD: 591 printf("ATCA board\n"); 592 break; 593 case PICMG_POWER_ENTRY: 594 printf("Power Entry Module\n"); 595 break; 596 case PICMG_SHELF_FRU: 597 printf("Shelf FRU\n"); 598 break; 599 case PICMG_DEDICATED_SHMC: 600 printf("Dedicated Shelf Manager\n"); 601 break; 602 case PICMG_FAN_TRAY: 603 printf("Fan Tray\n"); 604 break; 605 case PICMG_FAN_FILTER_TRAY: 606 printf("Fan Filter Tray\n"); 607 break; 608 case PICMG_ALARM: 609 printf("Alarm module\n"); 610 break; 611 case PICMG_AMC: 612 printf("AMC"); 613 printf(" -> IPMB-L Address: 0x%02x\n", amcAddrMap[rsp->data[5]].ipmbLAddr); 614 break; 615 case PICMG_PMC: 616 printf("PMC\n"); 617 break; 618 case PICMG_RTM: 619 printf("RTM\n"); 620 break; 621 default: 622 if (rsp->data[6] >= 0xc0 && rsp->data[6] <= 0xcf) { 623 printf("OEM\n"); 624 } else { 625 printf("unknown\n"); 626 } 627 } 628 629 return 0; 630 } 631 632 int 633 ipmi_picmg_properties(struct ipmi_intf * intf, int show ) 634 { 635 unsigned char PicmgExtMajorVersion; 636 struct ipmi_rs * rsp; 637 struct ipmi_rq req; 638 unsigned char msg_data; 639 640 memset(&req, 0, sizeof(req)); 641 req.msg.netfn = IPMI_NETFN_PICMG; 642 req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD; 643 req.msg.data = &msg_data; 644 req.msg.data_len = 1; 645 msg_data = 0; 646 647 rsp = intf->sendrecv(intf, &req); 648 if (!rsp || rsp->ccode) { 649 lprintf(LOG_ERR, "Error getting address information."); 650 return -1; 651 } 652 653 if( show ) 654 { 655 printf("PICMG identifier : 0x%02x\n", rsp->data[0]); 656 printf("PICMG Ext. Version : %i.%i\n", rsp->data[1]&0x0f, 657 (rsp->data[1]&0xf0) >> 4); 658 printf("Max FRU Device ID : 0x%02x\n", rsp->data[2]); 659 printf("FRU Device ID : 0x%02x\n", rsp->data[3]); 660 } 661 662 /* We cache the major extension version ... 663 to know how to format some commands */ 664 PicmgExtMajorVersion = rsp->data[1]&0x0f; 665 666 if( PicmgExtMajorVersion == PICMG_CPCI_MAJOR_VERSION ) { 667 PicmgCardType = PICMG_CARD_TYPE_CPCI; 668 } 669 else if( PicmgExtMajorVersion == PICMG_ATCA_MAJOR_VERSION) { 670 PicmgCardType = PICMG_CARD_TYPE_ATCA; 671 } 672 else if( PicmgExtMajorVersion == PICMG_AMC_MAJOR_VERSION) { 673 PicmgCardType = PICMG_CARD_TYPE_AMC; 674 } 675 676 return 0; 677 } 678 679 680 681 #define PICMG_FRU_DEACTIVATE (unsigned char) 0x00 682 #define PICMG_FRU_ACTIVATE (unsigned char) 0x01 683 684 int 685 ipmi_picmg_fru_activation(struct ipmi_intf * intf, int argc, char ** argv, unsigned char state) 686 { 687 struct ipmi_rs * rsp; 688 struct ipmi_rq req; 689 690 struct picmg_set_fru_activation_cmd cmd; 691 692 memset(&req, 0, sizeof(req)); 693 req.msg.netfn = IPMI_NETFN_PICMG; 694 req.msg.cmd = PICMG_FRU_ACTIVATION_CMD; 695 req.msg.data = (unsigned char*) &cmd; 696 req.msg.data_len = 3; 697 698 cmd.picmg_id = 0; /* PICMG identifier */ 699 if (is_fru_id(argv[0], &(cmd.fru_id)) != 0) { 700 return (-1); 701 } 702 cmd.fru_state = state; 703 704 rsp = intf->sendrecv(intf, &req); 705 706 if (!rsp || rsp->ccode) { 707 lprintf(LOG_ERR, "Error activation/deactivation of FRU."); 708 return -1; 709 } 710 if (rsp->data[0] != 0x00) { 711 lprintf(LOG_ERR, "Error activation/deactivation of FRU."); 712 } 713 714 return 0; 715 } 716 717 718 int 719 ipmi_picmg_fru_activation_policy_get(struct ipmi_intf * intf, int argc, char ** argv) 720 { 721 struct ipmi_rs * rsp; 722 struct ipmi_rq req; 723 724 unsigned char msg_data[4]; 725 726 memset(&req, 0, sizeof(req)); 727 req.msg.netfn = IPMI_NETFN_PICMG; 728 req.msg.cmd = PICMG_GET_FRU_POLICY_CMD; 729 req.msg.data = msg_data; 730 req.msg.data_len = 2; 731 732 msg_data[0] = 0; /* PICMG identifier */ 733 if (is_fru_id(argv[0], &msg_data[1]) != 0) { 734 return (-1); 735 } 736 737 rsp = intf->sendrecv(intf, &req); 738 739 if (!rsp) { 740 lprintf(LOG_ERR, "No valid response received."); 741 return -1; 742 } 743 if (rsp->ccode) { 744 lprintf(LOG_ERR, "FRU activation policy get failed with CC code 0x%02x", 745 rsp->ccode); 746 return -1; 747 } 748 749 printf(" %s\n", ((rsp->data[1] & 0x01) == 0x01) ? 750 "activation locked" : "activation not locked"); 751 printf(" %s\n", ((rsp->data[1] & 0x02) == 0x02) ? 752 "deactivation locked" : "deactivation not locked"); 753 754 return 0; 755 } 756 757 int 758 ipmi_picmg_fru_activation_policy_set(struct ipmi_intf * intf, int argc, char ** argv) 759 { 760 struct ipmi_rs * rsp; 761 struct ipmi_rq req; 762 763 unsigned char msg_data[4]; 764 765 memset(&req, 0, sizeof(req)); 766 req.msg.netfn = IPMI_NETFN_PICMG; 767 req.msg.cmd = PICMG_SET_FRU_POLICY_CMD; 768 req.msg.data = msg_data; 769 req.msg.data_len = 4; 770 771 msg_data[0] = 0; /* PICMG identifier */ 772 if (is_fru_id(argv[0], &msg_data[1]) != 0) { 773 return (-1); 774 } 775 if (str2uchar(argv[1], &msg_data[2]) != 0 || msg_data[2] > 1) { 776 /* FRU Lock Mask */ 777 lprintf(LOG_ERR, "Given FRU Lock Mask '%s' is invalid.", 778 argv[1]); 779 return (-1); 780 } 781 if (str2uchar(argv[2], &msg_data[3]) != 0 || msg_data[3] > 1) { 782 /* FRU Act Policy */ 783 lprintf(LOG_ERR, 784 "Given FRU Activation Policy '%s' is invalid.", 785 argv[2]); 786 return (-1); 787 } 788 msg_data[2]&= 0x03; 789 msg_data[3]&= 0x03; 790 791 rsp = intf->sendrecv(intf, &req); 792 793 if (!rsp) { 794 lprintf(LOG_ERR, "No valid response received."); 795 return -1; 796 } 797 798 if (rsp->ccode) { 799 lprintf(LOG_ERR, "FRU activation policy set failed with CC code 0x%02x", 800 rsp->ccode); 801 return -1; 802 } 803 804 return 0; 805 } 806 807 #define PICMG_MAX_LINK_PER_CHANNEL 4 808 809 int 810 ipmi_picmg_portstate_get(struct ipmi_intf * intf, int32_t interface, 811 uint8_t channel, int mode) 812 { 813 struct ipmi_rs * rsp = NULL; 814 struct ipmi_rq req; 815 816 unsigned char msg_data[4]; 817 818 struct fru_picmgext_link_desc* d; /* descriptor pointer for rec. data */ 819 820 memset(&req, 0, sizeof(req)); 821 822 req.msg.netfn = IPMI_NETFN_PICMG; 823 req.msg.cmd = PICMG_GET_PORT_STATE_CMD; 824 req.msg.data = msg_data; 825 req.msg.data_len = 2; 826 827 msg_data[0] = 0x00; /* PICMG identifier */ 828 msg_data[1] = (interface & 0x3)<<6; /* interface */ 829 msg_data[1] |= (channel & 0x3F); /* channel number */ 830 831 rsp = intf->sendrecv(intf, &req); 832 833 if (!rsp) { 834 lprintf(LOG_ERR, "No valid response received."); 835 return -1; 836 } 837 838 if (rsp->ccode) { 839 if( mode == PICMG_EKEY_MODE_QUERY ){ 840 lprintf(LOG_ERR, "FRU portstate get failed with CC code 0x%02x", 841 rsp->ccode); 842 } 843 return -1; 844 } 845 846 if (rsp->data_len >= 6) { 847 int index; 848 /* add support for more than one link per channel */ 849 for(index=0;index<PICMG_MAX_LINK_PER_CHANNEL;index++){ 850 if( rsp->data_len > (1+ (index*5))){ 851 d = (struct fru_picmgext_link_desc *) &(rsp->data[1 + (index*5)]); 852 853 if 854 ( 855 mode == PICMG_EKEY_MODE_PRINT_ALL 856 || 857 mode == PICMG_EKEY_MODE_QUERY 858 || 859 ( 860 mode == PICMG_EKEY_MODE_PRINT_ENABLED 861 && 862 rsp->data[5 + (index*5) ] == 0x01 863 ) 864 || 865 ( 866 mode == PICMG_EKEY_MODE_PRINT_DISABLED 867 && 868 rsp->data[5 + (index*5) ] == 0x00 869 ) 870 ) 871 { 872 printf(" Link Grouping ID: 0x%02x\n", d->grouping); 873 printf(" Link Type Extension: 0x%02x\n", d->ext); 874 printf(" Link Type: 0x%02x ", d->type); 875 if (d->type == 0 || d->type == 0xff) 876 { 877 printf("Reserved %d\n",d->type); 878 } 879 else if (d->type >= 0x06 && d->type <= 0xef) 880 { 881 printf("Reserved\n"); 882 } 883 else if (d->type >= 0xf0 && d->type <= 0xfe) 884 { 885 printf("OEM GUID Definition\n"); 886 } 887 else 888 { 889 switch (d->type) 890 { 891 case FRU_PICMGEXT_LINK_TYPE_BASE: 892 printf("PICMG 3.0 Base Interface 10/100/1000\n"); 893 break; 894 case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET: 895 printf("PICMG 3.1 Ethernet Fabric Interface\n"); 896 break; 897 case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND: 898 printf("PICMG 3.2 Infiniband Fabric Interface\n"); 899 break; 900 case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR: 901 printf("PICMG 3.3 Star Fabric Interface\n"); 902 break; 903 case FRU_PICMGEXT_LINK_TYPE_PCIE: 904 printf("PCI Express Fabric Interface\n"); 905 break; 906 default: 907 printf("Invalid\n"); 908 break; 909 } 910 } 911 printf(" Link Designator: \n"); 912 printf(" Port Flag: 0x%02x\n", d->desig_port); 913 printf(" Interface: 0x%02x - ", d->desig_if); 914 switch (d->desig_if) 915 { 916 case FRU_PICMGEXT_DESIGN_IF_BASE: 917 printf("Base Interface\n"); 918 break; 919 case FRU_PICMGEXT_DESIGN_IF_FABRIC: 920 printf("Fabric Interface\n"); 921 break; 922 case FRU_PICMGEXT_DESIGN_IF_UPDATE_CHANNEL: 923 printf("Update Channel\n"); 924 break; 925 case FRU_PICMGEXT_DESIGN_IF_RESERVED: 926 printf("Reserved\n"); 927 break; 928 default: 929 printf("Invalid"); 930 break; 931 } 932 printf(" Channel Number: 0x%02x\n", d->desig_channel); 933 printf(" STATE: %s\n", 934 ( rsp->data[5 +(index*5)] == 0x01) ?"enabled":"disabled"); 935 printf("\n"); 936 } 937 } 938 } 939 } 940 else 941 { 942 lprintf(LOG_ERR, "Unexpected answer, can't print result."); 943 } 944 945 return 0; 946 } 947 948 949 int 950 ipmi_picmg_portstate_set(struct ipmi_intf * intf, int32_t interface, 951 uint8_t channel, int32_t port, uint8_t type, 952 uint8_t typeext, uint8_t group, uint8_t enable) 953 { 954 struct ipmi_rs * rsp; 955 struct ipmi_rq req; 956 957 unsigned char msg_data[6]; 958 959 memset(&req, 0, sizeof(req)); 960 961 req.msg.netfn = IPMI_NETFN_PICMG; 962 req.msg.cmd = PICMG_SET_PORT_STATE_CMD; 963 req.msg.data = msg_data; 964 req.msg.data_len = 6; 965 966 msg_data[0] = 0x00; /* PICMG identifier */ 967 msg_data[1] = (channel & 0x3f) | ((interface & 3) << 6); 968 msg_data[2] = (port & 0xf) | ((type & 0xf) << 4); 969 msg_data[3] = ((type >> 4) & 0xf) | ((typeext & 0xf) << 4); 970 msg_data[4] = group & 0xff; 971 msg_data[5] = (enable & 0x01); /* enable/disable */ 972 973 rsp = intf->sendrecv(intf, &req); 974 975 if (!rsp) { 976 lprintf(LOG_ERR, "No valid response received."); 977 return -1; 978 } 979 980 if (rsp->ccode) { 981 lprintf(LOG_ERR, "Picmg portstate set failed with CC code 0x%02x", 982 rsp->ccode); 983 return -1; 984 } 985 986 return 0; 987 } 988 989 990 991 /* AMC.0 commands */ 992 993 #define PICMG_AMC_MAX_LINK_PER_CHANNEL 4 994 995 int 996 ipmi_picmg_amc_portstate_get(struct ipmi_intf * intf, int32_t device, 997 uint8_t channel, int mode) 998 { 999 struct ipmi_rs * rsp; 1000 struct ipmi_rq req; 1001 1002 unsigned char msg_data[4]; 1003 1004 struct fru_picmgext_amc_link_info* d; /* descriptor pointer for rec. data */ 1005 1006 memset(&req, 0, sizeof(req)); 1007 1008 req.msg.netfn = IPMI_NETFN_PICMG; 1009 req.msg.cmd = PICMG_AMC_GET_PORT_STATE_CMD; 1010 req.msg.data = msg_data; 1011 1012 /* FIXME : add check for AMC or carrier device */ 1013 if(device == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){ 1014 req.msg.data_len = 2; /* for amc only channel */ 1015 }else{ 1016 req.msg.data_len = 3; /* for carrier channel and device */ 1017 } 1018 1019 msg_data[0] = 0x00; /* PICMG identifier */ 1020 msg_data[1] = channel ; 1021 msg_data[2] = device ; 1022 1023 1024 rsp = intf->sendrecv(intf, &req); 1025 1026 if (!rsp) { 1027 lprintf(LOG_ERR, "No valid response received."); 1028 return -1; 1029 } 1030 1031 if (rsp->ccode) { 1032 if( mode == PICMG_EKEY_MODE_QUERY ){ 1033 lprintf(LOG_ERR, "Amc portstate get failed with CC code 0x%02x", 1034 rsp->ccode); 1035 } 1036 return -1; 1037 } 1038 1039 if (rsp->data_len >= 5) { 1040 int index; 1041 1042 /* add support for more than one link per channel */ 1043 for(index=0;index<PICMG_AMC_MAX_LINK_PER_CHANNEL;index++){ 1044 1045 if( rsp->data_len > (1+ (index*4))){ 1046 unsigned char type; 1047 unsigned char ext; 1048 unsigned char grouping; 1049 unsigned char port; 1050 unsigned char enabled; 1051 d = (struct fru_picmgext_amc_link_info *)&(rsp->data[1 + (index*4)]); 1052 1053 1054 /* Removed endianness check here, probably not required 1055 as we dont use bitfields */ 1056 port = d->linkInfo[0] & 0x0F; 1057 type = ((d->linkInfo[0] & 0xF0) >> 4 )|(d->linkInfo[1] & 0x0F ); 1058 ext = ((d->linkInfo[1] & 0xF0) >> 4 ); 1059 grouping = d->linkInfo[2]; 1060 1061 1062 enabled = rsp->data[4 + (index*4) ]; 1063 1064 if 1065 ( 1066 mode == PICMG_EKEY_MODE_PRINT_ALL 1067 || 1068 mode == PICMG_EKEY_MODE_QUERY 1069 || 1070 ( 1071 mode == PICMG_EKEY_MODE_PRINT_ENABLED 1072 && 1073 enabled == 0x01 1074 ) 1075 || 1076 ( 1077 mode == PICMG_EKEY_MODE_PRINT_DISABLED 1078 && 1079 enabled == 0x00 1080 ) 1081 ) 1082 { 1083 if(device == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){ 1084 printf(" Link device : AMC\n"); 1085 }else{ 1086 printf(" Link device : 0x%02x\n", device ); 1087 } 1088 1089 printf(" Link Grouping ID: 0x%02x\n", grouping); 1090 1091 if (type == 0 || type == 1 ||type == 0xff) 1092 { 1093 printf(" Link Type Extension: 0x%02x\n", ext); 1094 printf(" Link Type: Reserved\n"); 1095 } 1096 else if (type >= 0xf0 && type <= 0xfe) 1097 { 1098 printf(" Link Type Extension: 0x%02x\n", ext); 1099 printf(" Link Type: OEM GUID Definition\n"); 1100 } 1101 else 1102 { 1103 if (type <= FRU_PICMGEXT_AMC_LINK_TYPE_STORAGE ) 1104 { 1105 printf(" Link Type Extension: %s\n", 1106 amc_link_type_ext_str[type][ext]); 1107 printf(" Link Type: %s\n", 1108 amc_link_type_str[type]); 1109 } 1110 else{ 1111 printf(" Link Type Extension: 0x%02x\n", ext); 1112 printf(" Link Type: undefined\n"); 1113 } 1114 } 1115 printf(" Link Designator: \n"); 1116 printf(" Channel Number: 0x%02x\n", channel); 1117 printf(" Port Flag: 0x%02x\n", port ); 1118 printf(" STATE: %s\n", 1119 ( enabled == 0x01 )?"enabled":"disabled"); 1120 printf("\n"); 1121 } 1122 } 1123 } 1124 } 1125 else 1126 { 1127 lprintf(LOG_NOTICE,"ipmi_picmg_amc_portstate_get"\ 1128 "Unexpected answer, can't print result"); 1129 } 1130 1131 return 0; 1132 } 1133 1134 1135 int 1136 ipmi_picmg_amc_portstate_set(struct ipmi_intf * intf, uint8_t channel, 1137 int32_t port, uint8_t type, uint8_t typeext, 1138 uint8_t group, uint8_t enable, int32_t device) 1139 { 1140 struct ipmi_rs * rsp; 1141 struct ipmi_rq req; 1142 unsigned char msg_data[7]; 1143 1144 memset(&req, 0, sizeof(req)); 1145 1146 req.msg.netfn = IPMI_NETFN_PICMG; 1147 req.msg.cmd = PICMG_AMC_SET_PORT_STATE_CMD; 1148 req.msg.data = msg_data; 1149 1150 msg_data[0] = 0x00; /* PICMG identifier*/ 1151 msg_data[1] = channel; /* channel id */ 1152 msg_data[2] = port & 0xF; /* port flags */ 1153 msg_data[2] |= (type & 0x0F)<<4; /* type */ 1154 msg_data[3] = (type & 0xF0)>>4; /* type */ 1155 msg_data[3] |= (typeext & 0x0F)<<4; /* extension */ 1156 msg_data[4] = (group & 0xFF); /* group */ 1157 msg_data[5] = (enable & 0x01); /* state */ 1158 req.msg.data_len = 6; 1159 1160 /* device id - only for carrier needed */ 1161 if (device >= 0) { 1162 msg_data[6] = device; 1163 req.msg.data_len = 7; 1164 } 1165 1166 rsp = intf->sendrecv(intf, &req); 1167 1168 if (!rsp) { 1169 lprintf(LOG_ERR, "No valid response received."); 1170 return -1; 1171 } 1172 1173 if (rsp->ccode) { 1174 lprintf(LOG_ERR, "Amc portstate set failed with CC code 0x%02x", 1175 rsp->ccode); 1176 return -1; 1177 } 1178 1179 return 0; 1180 } 1181 1182 1183 int 1184 ipmi_picmg_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv) 1185 { 1186 struct ipmi_rs * rsp; 1187 struct ipmi_rq req; 1188 1189 unsigned char msg_data[6]; 1190 1191 memset(&req, 0, sizeof(req)); 1192 1193 req.msg.netfn = IPMI_NETFN_PICMG; 1194 req.msg.cmd = PICMG_GET_FRU_LED_PROPERTIES_CMD; 1195 req.msg.data = msg_data; 1196 req.msg.data_len = 2; 1197 1198 msg_data[0] = 0x00; /* PICMG identifier */ 1199 if (is_fru_id(argv[0], &msg_data[1]) != 0) { 1200 return (-1); 1201 } 1202 1203 rsp = intf->sendrecv(intf, &req); 1204 1205 if (!rsp) { 1206 lprintf(LOG_ERR, "No valid response received."); 1207 return -1; 1208 } 1209 1210 if (rsp->ccode) { 1211 lprintf(LOG_ERR, "LED get properties failed with CC code 0x%02x", 1212 rsp->ccode); 1213 return -1; 1214 } 1215 1216 printf("General Status LED Properties: 0x%2x\n", rsp->data[1] ); 1217 printf("App. Specific LED Count: 0x%2x\n", rsp->data[2] ); 1218 1219 return 0; 1220 } 1221 1222 int 1223 ipmi_picmg_get_led_capabilities(struct ipmi_intf * intf, int argc, char ** argv) 1224 { 1225 int i; 1226 struct ipmi_rs * rsp; 1227 struct ipmi_rq req; 1228 1229 unsigned char msg_data[6]; 1230 1231 memset(&req, 0, sizeof(req)); 1232 1233 req.msg.netfn = IPMI_NETFN_PICMG; 1234 req.msg.cmd = PICMG_GET_LED_COLOR_CAPABILITIES_CMD; 1235 req.msg.data = msg_data; 1236 req.msg.data_len = 3; 1237 1238 msg_data[0] = 0x00; /* PICMG identifier */ 1239 if (is_fru_id(argv[0], &msg_data[1]) != 0 1240 || is_led_id(argv[1], &msg_data[2]) != 0) { 1241 return (-1); 1242 } 1243 1244 rsp = intf->sendrecv(intf, &req); 1245 1246 if (!rsp) { 1247 lprintf(LOG_ERR, "No valid response received."); 1248 return -1; 1249 } 1250 1251 if (rsp->ccode) { 1252 lprintf(LOG_ERR, "LED get capabilities failed with CC code 0x%02x", 1253 rsp->ccode); 1254 return -1; 1255 } 1256 1257 printf("LED Color Capabilities: "); 1258 for ( i=0 ; i<8 ; i++ ) { 1259 if ( rsp->data[1] & (0x01 << i) ) { 1260 printf("%s, ", led_color_str[ i ]); 1261 } 1262 } 1263 printf("\n"); 1264 1265 printf("Default LED Color in\n"); 1266 printf(" LOCAL control: %s\n", led_color_str[ rsp->data[2] ] ); 1267 printf(" OVERRIDE state: %s\n", led_color_str[ rsp->data[3] ] ); 1268 1269 return 0; 1270 } 1271 1272 int 1273 ipmi_picmg_get_led_state(struct ipmi_intf * intf, int argc, char ** argv) 1274 { 1275 struct ipmi_rs * rsp; 1276 struct ipmi_rq req; 1277 1278 unsigned char msg_data[6]; 1279 1280 memset(&req, 0, sizeof(req)); 1281 1282 req.msg.netfn = IPMI_NETFN_PICMG; 1283 req.msg.cmd = PICMG_GET_FRU_LED_STATE_CMD; 1284 req.msg.data = msg_data; 1285 req.msg.data_len = 3; 1286 1287 msg_data[0] = 0x00; /* PICMG identifier */ 1288 if (is_fru_id(argv[0], &msg_data[1]) != 0 1289 || is_led_id(argv[1], &msg_data[2]) != 0) { 1290 return (-1); 1291 } 1292 1293 rsp = intf->sendrecv(intf, &req); 1294 1295 if (!rsp) { 1296 lprintf(LOG_ERR, "No valid response received."); 1297 return -1; 1298 } 1299 1300 if (rsp->ccode) { 1301 lprintf(LOG_ERR, "LED get state failed with CC code 0x%02x", rsp->ccode); 1302 return -1; 1303 } 1304 1305 printf("LED states: %x ", rsp->data[1] ); 1306 if (rsp->data[1] == 0x1) 1307 printf("[LOCAL CONTROL]\n"); 1308 else if (rsp->data[1] == 0x2) 1309 printf("[OVERRIDE]\n"); 1310 else if (rsp->data[1] == 0x4) 1311 printf("[LAMPTEST]\n"); 1312 else 1313 printf("\n"); 1314 1315 printf(" Local Control function: %x ", rsp->data[2] ); 1316 if (rsp->data[2] == 0x0) 1317 printf("[OFF]\n"); 1318 else if (rsp->data[2] == 0xff) 1319 printf("[ON]\n"); 1320 else 1321 printf("[BLINKING]\n"); 1322 1323 printf(" Local Control On-Duration: %x\n", rsp->data[3] ); 1324 printf(" Local Control Color: %x [%s]\n", rsp->data[4], led_color_str[ rsp->data[4] ]); 1325 1326 /* override state or lamp test */ 1327 if (rsp->data[1] == 0x02) { 1328 printf(" Override function: %x ", rsp->data[5] ); 1329 if (rsp->data[2] == 0x0) 1330 printf("[OFF]\n"); 1331 else if (rsp->data[2] == 0xff) 1332 printf("[ON]\n"); 1333 else 1334 printf("[BLINKING]\n"); 1335 1336 printf(" Override On-Duration: %x\n", rsp->data[6] ); 1337 printf(" Override Color: %x [%s]\n", rsp->data[7], led_color_str[ rsp->data[7] ]); 1338 1339 }else if (rsp->data[1] == 0x06) { 1340 printf(" Override function: %x ", rsp->data[5] ); 1341 if (rsp->data[2] == 0x0) 1342 printf("[OFF]\n"); 1343 else if (rsp->data[2] == 0xff) 1344 printf("[ON]\n"); 1345 else 1346 printf("[BLINKING]\n"); 1347 printf(" Override On-Duration: %x\n", rsp->data[6] ); 1348 printf(" Override Color: %x [%s]\n", rsp->data[7], led_color_str[ rsp->data[7] ]); 1349 printf(" Lamp test duration: %x\n", rsp->data[8] ); 1350 } 1351 1352 return 0; 1353 } 1354 1355 int 1356 ipmi_picmg_set_led_state(struct ipmi_intf * intf, int argc, char ** argv) 1357 { 1358 struct ipmi_rs * rsp; 1359 struct ipmi_rq req; 1360 1361 unsigned char msg_data[6]; 1362 1363 memset(&req, 0, sizeof(req)); 1364 1365 req.msg.netfn = IPMI_NETFN_PICMG; 1366 req.msg.cmd = PICMG_SET_FRU_LED_STATE_CMD; 1367 req.msg.data = msg_data; 1368 req.msg.data_len = 6; 1369 1370 msg_data[0] = 0x00; /* PICMG identifier */ 1371 if (is_fru_id(argv[0], &msg_data[1]) != 0 1372 || is_led_id(argv[1], &msg_data[2]) != 0 1373 || is_led_function(argv[2], &msg_data[3]) != 0 1374 || is_led_duration(argv[3], &msg_data[4]) != 0 1375 || is_led_color(argv[4], &msg_data[5]) != 0) { 1376 return (-1); 1377 } 1378 1379 rsp = intf->sendrecv(intf, &req); 1380 1381 if (!rsp) { 1382 lprintf(LOG_ERR, "No valid response received."); 1383 return -1; 1384 } 1385 1386 if (rsp->ccode) { 1387 lprintf(LOG_ERR, "LED set state failed with CC code 0x%02x", rsp->ccode); 1388 return -1; 1389 } 1390 1391 1392 return 0; 1393 } 1394 1395 int 1396 ipmi_picmg_get_power_level(struct ipmi_intf * intf, int argc, char ** argv) 1397 { 1398 int i; 1399 struct ipmi_rs * rsp; 1400 struct ipmi_rq req; 1401 1402 unsigned char msg_data[6]; 1403 1404 memset(&req, 0, sizeof(req)); 1405 1406 req.msg.netfn = IPMI_NETFN_PICMG; 1407 req.msg.cmd = PICMG_GET_POWER_LEVEL_CMD; 1408 req.msg.data = msg_data; 1409 req.msg.data_len = 3; 1410 1411 msg_data[0] = 0x00; /* PICMG identifier */ 1412 if (is_fru_id(argv[0], &msg_data[1]) != 0) { 1413 return (-1); 1414 } 1415 /* PICMG Power Type - <0..3> */ 1416 if (str2uchar(argv[1], &msg_data[2]) != 0 || msg_data[2] > 3) { 1417 lprintf(LOG_ERR, "Given Power Type '%s' is invalid", 1418 argv[1]); 1419 return (-1); 1420 } 1421 1422 rsp = intf->sendrecv(intf, &req); 1423 1424 if (!rsp) { 1425 lprintf(LOG_ERR, "No valid response received."); 1426 return -1; 1427 } 1428 1429 if (rsp->ccode) { 1430 lprintf(LOG_ERR, "Power level get failed with CC code 0x%02x", rsp->ccode); 1431 return -1; 1432 } 1433 1434 printf("Dynamic Power Configuration: %s\n", (rsp->data[1]&0x80)==0x80?"enabled":"disabled" ); 1435 printf("Actual Power Level: %i\n", (rsp->data[1] & 0xf)); 1436 printf("Delay to stable Power: %i\n", rsp->data[2]); 1437 printf("Power Multiplier: %i\n", rsp->data[3]); 1438 1439 1440 for ( i = 1; i+3 < rsp->data_len ; i++ ) { 1441 printf(" Power Draw %i: %i\n", i, (rsp->data[i+3]) * rsp->data[3] / 10); 1442 } 1443 return 0; 1444 } 1445 1446 int 1447 ipmi_picmg_set_power_level(struct ipmi_intf * intf, int argc, char ** argv) 1448 { 1449 struct ipmi_rs * rsp; 1450 struct ipmi_rq req; 1451 1452 unsigned char msg_data[6]; 1453 1454 memset(&req, 0, sizeof(req)); 1455 1456 req.msg.netfn = IPMI_NETFN_PICMG; 1457 req.msg.cmd = PICMG_SET_POWER_LEVEL_CMD; 1458 req.msg.data = msg_data; 1459 req.msg.data_len = 4; 1460 1461 msg_data[0] = 0x00; /* PICMG identifier */ 1462 if (is_fru_id(argv[0], &msg_data[1]) != 0) { 1463 return (-1); 1464 } 1465 /* PICMG Power Level - <0x00..0x14>, [0xFF] */ 1466 if (str2uchar(argv[1], &msg_data[2]) != 0 1467 || (msg_data[2] > 0x14 && msg_data[2] != 0xFF)) { 1468 lprintf(LOG_ERR, 1469 "Given PICMG Power Level '%s' is invalid.", 1470 argv[1]); 1471 return (-1); 1472 } 1473 /* PICMG Present-to-desired - <0..1> */ 1474 if (str2uchar(argv[2], &msg_data[3]) != 0 || msg_data[3] > 1) { 1475 lprintf(LOG_ERR, 1476 "Given PICMG Present-to-desired '%s' is invalid.", 1477 argv[2]); 1478 return (-1); 1479 } 1480 1481 rsp = intf->sendrecv(intf, &req); 1482 1483 if (!rsp) { 1484 lprintf(LOG_ERR, "No valid response received."); 1485 return -1; 1486 } 1487 1488 if (rsp->ccode) { 1489 lprintf(LOG_ERR, "Power level set failed with CC code 0x%02x", rsp->ccode); 1490 return -1; 1491 } 1492 1493 return 0; 1494 } 1495 1496 int 1497 ipmi_picmg_bused_resource(struct ipmi_intf * intf, t_picmg_bused_resource_mode mode) 1498 { 1499 struct ipmi_rs * rsp; 1500 struct ipmi_rq req; 1501 1502 unsigned char msg_data[6]; 1503 memset(&req, 0, sizeof(req)); 1504 1505 int status = 0; 1506 switch ( mode ) { 1507 case PICMG_BUSED_RESOURCE_SUMMARY: 1508 { 1509 t_picmg_busres_resource_id resource; 1510 t_picmg_busres_board_cmd_types cmd =PICMG_BUSRES_BOARD_CMD_QUERY; 1511 1512 req.msg.netfn = IPMI_NETFN_PICMG; 1513 req.msg.cmd = PICMG_BUSED_RESOURCE_CMD; 1514 req.msg.data = msg_data; 1515 req.msg.data_len = 3; 1516 1517 /* IF BOARD 1518 query for all resources 1519 */ 1520 for( resource=PICMG_BUSRES_METAL_TEST_BUS_1;resource<=PICMG_BUSRES_SYNC_CLOCK_GROUP_3;resource+=(t_picmg_busres_resource_id)1 ) { 1521 msg_data[0] = 0x00; /* PICMG identifier */ 1522 msg_data[1] = (unsigned char) cmd; 1523 msg_data[2] = (unsigned char) resource; 1524 rsp = intf->sendrecv(intf, &req); 1525 1526 if (!rsp) { 1527 printf("bused resource control: no response\n"); 1528 return -1; 1529 } 1530 1531 if (rsp->ccode) { 1532 printf("bused resource control: returned CC code 0x%02x\n", rsp->ccode); 1533 return -1; 1534 } else { 1535 printf("Resource 0x%02x '%-26s' : 0x%02x [%s] \n" , 1536 resource, val2str(resource,picmg_busres_id_vals), 1537 rsp->data[1], oemval2str(cmd,rsp->data[1], 1538 picmg_busres_board_status_vals)); 1539 } 1540 } 1541 } 1542 break; 1543 default : 1544 break; 1545 } 1546 1547 return status; 1548 } 1549 1550 int 1551 ipmi_picmg_fru_control(struct ipmi_intf * intf, int argc, char ** argv) 1552 { 1553 struct ipmi_rs * rsp; 1554 struct ipmi_rq req; 1555 1556 unsigned char msg_data[6]; 1557 1558 memset(&req, 0, sizeof(req)); 1559 1560 req.msg.netfn = IPMI_NETFN_PICMG; 1561 req.msg.cmd = PICMG_FRU_CONTROL_CMD; 1562 req.msg.data = msg_data; 1563 req.msg.data_len = 3; 1564 1565 msg_data[0] = 0x00; /* PICMG identifier */ 1566 if (is_fru_id(argv[0], &msg_data[1]) != 0) { 1567 return (-1); 1568 } 1569 /* FRU Control Option, valid range: <0..4> */ 1570 if (str2uchar(argv[1], &msg_data[2]) != 0 || msg_data[2] > 4) { 1571 lprintf(LOG_ERR, 1572 "Given FRU Control Option '%s' is invalid.", 1573 argv[1]); 1574 return (-1); 1575 } 1576 1577 printf("FRU Device Id: %d FRU Control Option: %s\n", msg_data[1], \ 1578 val2str( msg_data[2], picmg_frucontrol_vals)); 1579 1580 rsp = intf->sendrecv(intf, &req); 1581 1582 if (!rsp) { 1583 lprintf(LOG_ERR, "No valid response received."); 1584 return -1; 1585 } 1586 1587 if (rsp->ccode) { 1588 lprintf(LOG_ERR, "frucontrol failed with CC code 0x%02x", rsp->ccode); 1589 return -1; 1590 } else { 1591 printf("frucontrol: ok\n"); 1592 } 1593 1594 1595 1596 return 0; 1597 } 1598 1599 1600 int 1601 ipmi_picmg_clk_get(struct ipmi_intf * intf, uint8_t clk_id, int8_t clk_res, 1602 int mode) 1603 { 1604 struct ipmi_rs * rsp; 1605 struct ipmi_rq req; 1606 1607 unsigned char enabled; 1608 unsigned char direction; 1609 1610 unsigned char msg_data[6]; 1611 1612 memset(&req, 0, sizeof(req)); 1613 1614 req.msg.netfn = IPMI_NETFN_PICMG; 1615 req.msg.cmd = PICMG_AMC_GET_CLK_STATE_CMD; 1616 req.msg.data = msg_data; 1617 1618 msg_data[0] = 0x00; /* PICMG identifier */ 1619 msg_data[1] = clk_id; 1620 1621 if(clk_res == -1 || PicmgCardType != PICMG_CARD_TYPE_ATCA ){ 1622 req.msg.data_len = 2; /* for amc only channel */ 1623 }else{ 1624 req.msg.data_len = 3; /* for carrier channel and device */ 1625 msg_data[2] = clk_res; 1626 } 1627 1628 rsp = intf->sendrecv(intf, &req); 1629 1630 if (!rsp) { 1631 lprintf(LOG_ERR, "No valid response received."); 1632 return -1; 1633 } 1634 1635 if (rsp->ccode && (mode == PICMG_EKEY_MODE_QUERY) ) { 1636 lprintf(LOG_ERR, "Clk get failed with CC code 0x%02x", rsp->ccode); 1637 return -1; 1638 } 1639 1640 if (rsp->ccode == 0 ) { 1641 enabled = (rsp->data[1]&0x8)!=0; 1642 direction = (rsp->data[1]&0x4)!=0; 1643 1644 if 1645 ( 1646 mode == PICMG_EKEY_MODE_QUERY 1647 || 1648 mode == PICMG_EKEY_MODE_PRINT_ALL 1649 || 1650 ( 1651 mode == PICMG_EKEY_MODE_PRINT_DISABLED 1652 && 1653 enabled == 0 1654 ) 1655 || 1656 ( 1657 mode == PICMG_EKEY_MODE_PRINT_ENABLED 1658 && 1659 enabled == 1 1660 ) 1661 ) { 1662 if( PicmgCardType != PICMG_CARD_TYPE_AMC ) { 1663 printf("CLK resource id : %3d [ %s ]\n", clk_res , 1664 oemval2str( ((clk_res>>6)&0x03), (clk_res&0x0F), 1665 picmg_clk_resource_vals)); 1666 } else { 1667 printf("CLK resource id : N/A [ AMC Module ]\n"); 1668 clk_res = 0x40; /* Set */ 1669 } 1670 printf("CLK id : %3d [ %s ]\n", clk_id, 1671 oemval2str( ((clk_res>>6)&0x03), clk_id , 1672 picmg_clk_id_vals)); 1673 1674 1675 printf("CLK setting : 0x%02x\n", rsp->data[1]); 1676 printf(" - state: %s\n", (enabled)?"enabled":"disabled"); 1677 printf(" - direction: %s\n", (direction)?"Source":"Receiver"); 1678 printf(" - PLL ctrl: 0x%x\n", rsp->data[1]&0x3); 1679 1680 if(enabled){ 1681 unsigned long freq = 0; 1682 freq = ( rsp->data[5] << 0 1683 | rsp->data[6] << 8 1684 | rsp->data[7] << 16 1685 | rsp->data[8] << 24 ); 1686 printf(" - Index: %3d\n", rsp->data[2]); 1687 printf(" - Family: %3d [ %s ] \n", rsp->data[3], 1688 val2str( rsp->data[3], picmg_clk_family_vals)); 1689 printf(" - AccLVL: %3d [ %s ] \n", rsp->data[4], 1690 oemval2str( rsp->data[3], rsp->data[4], 1691 picmg_clk_accuracy_vals)); 1692 1693 printf(" - Freq: %ld\n", freq); 1694 } 1695 } 1696 } 1697 return 0; 1698 } 1699 1700 1701 int 1702 ipmi_picmg_clk_set(struct ipmi_intf * intf, int argc, char ** argv) 1703 { 1704 struct ipmi_rs * rsp; 1705 struct ipmi_rq req; 1706 1707 unsigned char msg_data[11] = {0}; 1708 uint32_t freq = 0; 1709 1710 memset(&req, 0, sizeof(req)); 1711 1712 req.msg.netfn = IPMI_NETFN_PICMG; 1713 req.msg.cmd = PICMG_AMC_SET_CLK_STATE_CMD; 1714 req.msg.data = msg_data; 1715 1716 msg_data[0] = 0x00; /* PICMG identifier */ 1717 if (is_clk_id(argv[0], &msg_data[1]) != 0 1718 || is_clk_index(argv[1], &msg_data[2]) != 0 1719 || is_clk_setting(argv[2], &msg_data[3]) != 0 1720 || is_clk_family(argv[3], &msg_data[4]) != 0 1721 || is_clk_acc(argv[4], &msg_data[5]) != 0 1722 || is_clk_freq(argv[5], &freq) != 0) { 1723 return (-1); 1724 } 1725 1726 msg_data[6] = (freq >> 0)& 0xFF; /* freq */ 1727 msg_data[7] = (freq >> 8)& 0xFF; /* freq */ 1728 msg_data[8] = (freq >>16)& 0xFF; /* freq */ 1729 msg_data[9] = (freq >>24)& 0xFF; /* freq */ 1730 1731 req.msg.data_len = 10; 1732 if( PicmgCardType == PICMG_CARD_TYPE_ATCA ) 1733 { 1734 if( argc > 7) 1735 { 1736 req.msg.data_len = 11; 1737 if (is_clk_resid(argv[6], &msg_data[10]) != 0) { 1738 return (-1); 1739 } 1740 } 1741 else 1742 { 1743 lprintf(LOG_ERR, "Missing resource id for atca board."); 1744 return -1; 1745 } 1746 } 1747 1748 1749 rsp = intf->sendrecv(intf, &req); 1750 if (!rsp) { 1751 lprintf(LOG_ERR, "No valid response received."); 1752 return -1; 1753 } 1754 1755 if (rsp->ccode) { 1756 lprintf(LOG_ERR, "Clk set failed with CC code 0x%02x", rsp->ccode); 1757 return -1; 1758 } 1759 1760 return 0; 1761 } 1762 1763 1764 1765 int 1766 ipmi_picmg_main (struct ipmi_intf * intf, int argc, char ** argv) 1767 { 1768 int rc = 0; 1769 int showProperties = 0; 1770 1771 if (argc == 0 || (!strncmp(argv[0], "help", 4))) { 1772 ipmi_picmg_help(); 1773 return 0; 1774 } 1775 1776 /* Get PICMG properties is called to obtain version information */ 1777 if (argc !=0 && !strncmp(argv[0], "properties", 10)) { 1778 showProperties =1; 1779 } 1780 rc = ipmi_picmg_properties(intf,showProperties); 1781 1782 /* address info command */ 1783 if (!strncmp(argv[0], "addrinfo", 8)) { 1784 rc = ipmi_picmg_getaddr(intf, argc-1, &argv[1]); 1785 } 1786 else if (!strncmp(argv[0], "busres", 6)) { 1787 if (argc > 1) { 1788 if (!strncmp(argv[1], "summary", 7)) { 1789 ipmi_picmg_bused_resource(intf, PICMG_BUSED_RESOURCE_SUMMARY ); 1790 } 1791 } else { 1792 lprintf(LOG_NOTICE, "usage: busres summary"); 1793 } 1794 } 1795 /* fru control command */ 1796 else if (!strncmp(argv[0], "frucontrol", 10)) { 1797 if (argc > 2) { 1798 rc = ipmi_picmg_fru_control(intf, argc-1, &(argv[1])); 1799 } 1800 else { 1801 lprintf(LOG_NOTICE, "usage: frucontrol <FRU-ID> <OPTION>"); 1802 lprintf(LOG_NOTICE, " OPTION:"); 1803 lprintf(LOG_NOTICE, " 0 - Cold Reset"); 1804 lprintf(LOG_NOTICE, " 1 - Warm Reset"); 1805 lprintf(LOG_NOTICE, " 2 - Graceful Reboot"); 1806 lprintf(LOG_NOTICE, " 3 - Issue Diagnostic Interrupt"); 1807 lprintf(LOG_NOTICE, " 4 - Quiesce [AMC only]"); 1808 lprintf(LOG_NOTICE, " 5-255 - Reserved"); 1809 1810 return -1; 1811 } 1812 1813 } 1814 1815 /* fru activation command */ 1816 else if (!strncmp(argv[0], "activate", 8)) { 1817 if (argc > 1) { 1818 rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_ACTIVATE); 1819 } 1820 else { 1821 lprintf(LOG_ERR, "Specify the FRU to activate."); 1822 return -1; 1823 } 1824 } 1825 1826 /* fru deactivation command */ 1827 else if (!strncmp(argv[0], "deactivate", 10)) { 1828 if (argc > 1) { 1829 rc = ipmi_picmg_fru_activation(intf, argc-1, &(argv[1]), PICMG_FRU_DEACTIVATE); 1830 }else { 1831 lprintf(LOG_ERR, "Specify the FRU to deactivate."); 1832 return -1; 1833 } 1834 } 1835 1836 /* activation policy command */ 1837 else if (!strncmp(argv[0], "policy", 6)) { 1838 if (argc > 1) { 1839 if (!strncmp(argv[1], "get", 3)) { 1840 if (argc > 2) { 1841 rc = ipmi_picmg_fru_activation_policy_get(intf, argc-1, &(argv[2])); 1842 } else { 1843 lprintf(LOG_NOTICE, "usage: get <fruid>"); 1844 } 1845 } else if (!strncmp(argv[1], "set", 3)) { 1846 if (argc > 4) { 1847 rc = ipmi_picmg_fru_activation_policy_set(intf, argc-1, &(argv[2])); 1848 } else { 1849 lprintf(LOG_NOTICE, "usage: set <fruid> <lockmask> <lock>"); 1850 lprintf(LOG_NOTICE, 1851 " lockmask: [1] affect the deactivation locked bit"); 1852 lprintf(LOG_NOTICE, 1853 " [0] affect the activation locked bit"); 1854 lprintf(LOG_NOTICE, 1855 " lock: [1] set/clear deactivation locked"); 1856 lprintf(LOG_NOTICE, " [0] set/clear locked"); 1857 } 1858 } 1859 else { 1860 lprintf(LOG_ERR, "Specify FRU."); 1861 return -1; 1862 } 1863 } else { 1864 lprintf(LOG_ERR, "Wrong parameters."); 1865 return -1; 1866 } 1867 } 1868 1869 /* portstate command */ 1870 else if (!strncmp(argv[0], "portstate", 9)) { 1871 1872 lprintf(LOG_DEBUG,"PICMG: portstate API"); 1873 1874 if (argc > 1) { 1875 if (!strncmp(argv[1], "get", 3)) { 1876 int32_t iface; 1877 uint8_t channel = 0; 1878 1879 lprintf(LOG_DEBUG,"PICMG: get"); 1880 1881 if(!strncmp(argv[1], "getall", 6)) { 1882 for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++) { 1883 for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++) { 1884 if(!(( iface == FRU_PICMGEXT_DESIGN_IF_FABRIC ) && 1885 ( channel > PICMG_EKEY_MAX_FABRIC_CHANNEL ) )) 1886 { 1887 rc = ipmi_picmg_portstate_get(intf,iface,channel, 1888 PICMG_EKEY_MODE_PRINT_ALL); 1889 } 1890 } 1891 } 1892 } 1893 else if(!strncmp(argv[1], "getgranted", 10)) { 1894 for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++) { 1895 for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++) { 1896 rc = ipmi_picmg_portstate_get(intf,iface,channel, 1897 PICMG_EKEY_MODE_PRINT_ENABLED); 1898 } 1899 } 1900 } 1901 else if(!strncmp(argv[1], "getdenied", 9)){ 1902 for(iface=0;iface<=PICMG_EKEY_MAX_INTERFACE;iface++) { 1903 for(channel=1;channel<=PICMG_EKEY_MAX_CHANNEL;channel++) { 1904 rc = ipmi_picmg_portstate_get(intf,iface,channel, 1905 PICMG_EKEY_MODE_PRINT_DISABLED); 1906 } 1907 } 1908 } 1909 else if (argc > 3){ 1910 if (is_amc_intf(argv[2], &iface) != 0 1911 || is_amc_channel(argv[3], &channel) != 0) { 1912 return (-1); 1913 } 1914 lprintf(LOG_DEBUG,"PICMG: requesting interface %d",iface); 1915 lprintf(LOG_DEBUG,"PICMG: requesting channel %d",channel); 1916 1917 rc = ipmi_picmg_portstate_get(intf,iface,channel, 1918 PICMG_EKEY_MODE_QUERY ); 1919 } 1920 else { 1921 lprintf(LOG_NOTICE, "<intf> <chn>|getall|getgranted|getdenied"); 1922 } 1923 } 1924 else if (!strncmp(argv[1], "set", 3)) { 1925 if (argc == 9) { 1926 int32_t interface = 0; 1927 int32_t port = 0; 1928 uint8_t channel = 0; 1929 uint8_t enable = 0; 1930 uint8_t group = 0; 1931 uint8_t type = 0; 1932 uint8_t typeext = 0; 1933 if (is_amc_intf(argv[2], &interface) != 0 1934 || is_amc_channel(argv[3], &channel) != 0 1935 || is_amc_port(argv[4], &port) != 0 1936 || is_link_type(argv[5], &type) != 0 1937 || is_link_type_ext(argv[6], &typeext) != 0 1938 || is_link_group(argv[7], &group) != 0 1939 || is_enable(argv[8], &enable) != 0) { 1940 return (-1); 1941 } 1942 1943 lprintf(LOG_DEBUG,"PICMG: interface %d",interface); 1944 lprintf(LOG_DEBUG,"PICMG: channel %d",channel); 1945 lprintf(LOG_DEBUG,"PICMG: port %d",port); 1946 lprintf(LOG_DEBUG,"PICMG: type %d",type); 1947 lprintf(LOG_DEBUG,"PICMG: typeext %d",typeext); 1948 lprintf(LOG_DEBUG,"PICMG: group %d",group); 1949 lprintf(LOG_DEBUG,"PICMG: enable %d",enable); 1950 1951 rc = ipmi_picmg_portstate_set(intf, interface, 1952 channel, port, type, typeext ,group ,enable); 1953 } 1954 else { 1955 lprintf(LOG_NOTICE, 1956 "<intf> <chn> <port> <type> <ext> <group> <1|0>"); 1957 return -1; 1958 } 1959 } 1960 } 1961 else { 1962 lprintf(LOG_NOTICE, "<set>|<getall>|<getgranted>|<getdenied>"); 1963 return -1; 1964 } 1965 } 1966 /* amc portstate command */ 1967 else if (!strncmp(argv[0], "amcportstate", 12)) { 1968 1969 lprintf(LOG_DEBUG,"PICMG: amcportstate API"); 1970 1971 if (argc > 1) { 1972 if (!strncmp(argv[1], "get", 3)){ 1973 int32_t device; 1974 uint8_t channel; 1975 1976 lprintf(LOG_DEBUG,"PICMG: get"); 1977 1978 if(!strncmp(argv[1], "getall", 6)){ 1979 int maxDevice = PICMG_EKEY_AMC_MAX_DEVICE; 1980 if( PicmgCardType != PICMG_CARD_TYPE_ATCA ){ 1981 maxDevice = 0; 1982 } 1983 for(device=0;device<=maxDevice;device++){ 1984 for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){ 1985 rc = ipmi_picmg_amc_portstate_get(intf,device,channel, 1986 PICMG_EKEY_MODE_PRINT_ALL); 1987 } 1988 } 1989 } 1990 else if(!strncmp(argv[1], "getgranted", 10)){ 1991 int maxDevice = PICMG_EKEY_AMC_MAX_DEVICE; 1992 if( PicmgCardType != PICMG_CARD_TYPE_ATCA ){ 1993 maxDevice = 0; 1994 } 1995 for(device=0;device<=maxDevice;device++){ 1996 for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){ 1997 rc = ipmi_picmg_amc_portstate_get(intf,device,channel, 1998 PICMG_EKEY_MODE_PRINT_ENABLED); 1999 } 2000 } 2001 } 2002 else if(!strncmp(argv[1], "getdenied", 9)){ 2003 int maxDevice = PICMG_EKEY_AMC_MAX_DEVICE; 2004 if( PicmgCardType != PICMG_CARD_TYPE_ATCA ){ 2005 maxDevice = 0; 2006 } 2007 for(device=0;device<=maxDevice;device++){ 2008 for(channel=0;channel<=PICMG_EKEY_AMC_MAX_CHANNEL;channel++){ 2009 rc = ipmi_picmg_amc_portstate_get(intf,device,channel, 2010 PICMG_EKEY_MODE_PRINT_DISABLED); 2011 } 2012 } 2013 } 2014 else if (argc > 2){ 2015 if (is_amc_channel(argv[2], &channel) != 0) { 2016 return (-1); 2017 } 2018 if (argc > 3){ 2019 if (is_amc_dev(argv[3], &device) != 0) { 2020 return (-1); 2021 } 2022 }else{ 2023 device = -1; 2024 } 2025 lprintf(LOG_DEBUG,"PICMG: requesting device %d",device); 2026 lprintf(LOG_DEBUG,"PICMG: requesting channel %d",channel); 2027 2028 rc = ipmi_picmg_amc_portstate_get(intf,device,channel, 2029 PICMG_EKEY_MODE_QUERY ); 2030 } 2031 else { 2032 lprintf(LOG_NOTICE, "<chn> <device>|getall|getgranted|getdenied"); 2033 } 2034 } 2035 else if (!strncmp(argv[1], "set", 3)) { 2036 if (argc > 7) { 2037 int32_t device = -1; 2038 int32_t port = 0; 2039 uint8_t channel = 0; 2040 uint8_t enable = 0; 2041 uint8_t group = 0; 2042 uint8_t type = 0; 2043 uint8_t typeext = 0; 2044 if (is_amc_channel(argv[2], &channel) != 0 2045 || is_amc_port(argv[3], &port) != 0 2046 || is_link_type(argv[4], &type) !=0 2047 || is_link_type_ext(argv[5], &typeext) != 0 2048 || is_link_group(argv[6], &group) != 0 2049 || is_enable(argv[7], &enable) != 0) { 2050 return (-1); 2051 } 2052 if(argc > 8){ 2053 if (is_amc_dev(argv[8], &device) != 0) { 2054 return (-1); 2055 } 2056 } 2057 2058 lprintf(LOG_DEBUG,"PICMG: channel %d",channel); 2059 lprintf(LOG_DEBUG,"PICMG: portflags %d",port); 2060 lprintf(LOG_DEBUG,"PICMG: type %d",type); 2061 lprintf(LOG_DEBUG,"PICMG: typeext %d",typeext); 2062 lprintf(LOG_DEBUG,"PICMG: group %d",group); 2063 lprintf(LOG_DEBUG,"PICMG: enable %d",enable); 2064 lprintf(LOG_DEBUG,"PICMG: device %d",device); 2065 2066 rc = ipmi_picmg_amc_portstate_set(intf, channel, port, type, 2067 typeext, group, enable, device); 2068 } 2069 else { 2070 lprintf(LOG_NOTICE, 2071 "<chn> <portflags> <type> <ext> <group> <1|0> [<device>]"); 2072 return -1; 2073 } 2074 } 2075 } 2076 else { 2077 lprintf(LOG_NOTICE, "<set>|<get>|<getall>|<getgranted>|<getdenied>"); 2078 return -1; 2079 } 2080 } 2081 /* ATCA led commands */ 2082 else if (!strncmp(argv[0], "led", 3)) { 2083 if (argc > 1) { 2084 if (!strncmp(argv[1], "prop", 4)) { 2085 if (argc > 2) { 2086 rc = ipmi_picmg_get_led_properties(intf, argc-1, &(argv[2])); 2087 } 2088 else { 2089 lprintf(LOG_NOTICE, "led prop <FRU-ID>"); 2090 } 2091 } 2092 else if (!strncmp(argv[1], "cap", 3)) { 2093 if (argc > 3) { 2094 rc = ipmi_picmg_get_led_capabilities(intf, argc-1, &(argv[2])); 2095 } 2096 else { 2097 lprintf(LOG_NOTICE, "led cap <FRU-ID> <LED-ID>"); 2098 } 2099 } 2100 else if (!strncmp(argv[1], "get", 3)) { 2101 if (argc > 3) { 2102 rc = ipmi_picmg_get_led_state(intf, argc-1, &(argv[2])); 2103 } 2104 else { 2105 lprintf(LOG_NOTICE, "led get <FRU-ID> <LED-ID>"); 2106 } 2107 } 2108 else if (!strncmp(argv[1], "set", 3)) { 2109 if (argc > 6) { 2110 rc = ipmi_picmg_set_led_state(intf, argc-1, &(argv[2])); 2111 } 2112 else { 2113 lprintf(LOG_NOTICE, 2114 "led set <FRU-ID> <LED-ID> <function> <duration> <color>"); 2115 lprintf(LOG_NOTICE, " <FRU-ID>"); 2116 lprintf(LOG_NOTICE, " <LED-ID> 0: Blue LED"); 2117 lprintf(LOG_NOTICE, " 1: LED 1"); 2118 lprintf(LOG_NOTICE, " 2: LED 2"); 2119 lprintf(LOG_NOTICE, " 3: LED 3"); 2120 lprintf(LOG_NOTICE, " 0x04-0xFE: OEM defined"); 2121 lprintf(LOG_NOTICE, 2122 " 0xFF: All LEDs under management control"); 2123 lprintf(LOG_NOTICE, " <function> 0: LED OFF override"); 2124 lprintf(LOG_NOTICE, 2125 " 1 - 250: LED blinking override (off duration)"); 2126 lprintf(LOG_NOTICE, " 251: LED Lamp Test"); 2127 lprintf(LOG_NOTICE, 2128 " 252: LED restore to local control"); 2129 lprintf(LOG_NOTICE, " 255: LED ON override"); 2130 lprintf(LOG_NOTICE, 2131 " <duration> 1 - 127: LED Lamp Test / on duration"); 2132 lprintf(LOG_NOTICE, " <color> 0: reserved"); 2133 lprintf(LOG_NOTICE, " 1: BLUE"); 2134 lprintf(LOG_NOTICE, " 2: RED"); 2135 lprintf(LOG_NOTICE, " 3: GREEN"); 2136 lprintf(LOG_NOTICE, " 4: AMBER"); 2137 lprintf(LOG_NOTICE, " 5: ORANGE"); 2138 lprintf(LOG_NOTICE, " 6: WHITE"); 2139 lprintf(LOG_NOTICE, " 7: reserved"); 2140 lprintf(LOG_NOTICE, " 0xE: do not change"); 2141 lprintf(LOG_NOTICE, " 0xF: use default color"); 2142 } 2143 } 2144 else { 2145 lprintf(LOG_NOTICE, "prop | cap | get | set"); 2146 } 2147 } 2148 } 2149 /* power commands */ 2150 else if (!strncmp(argv[0], "power", 5)) { 2151 if (argc > 1) { 2152 if (!strncmp(argv[1], "get", 3)) { 2153 if (argc > 3) { 2154 rc = ipmi_picmg_get_power_level(intf, argc-1, &(argv[2])); 2155 } 2156 else { 2157 lprintf(LOG_NOTICE, "power get <FRU-ID> <type>"); 2158 lprintf(LOG_NOTICE, " <type> 0 : steady state power draw levels"); 2159 lprintf(LOG_NOTICE, 2160 " 1 : desired steady state draw levels"); 2161 lprintf(LOG_NOTICE, " 2 : early power draw levels"); 2162 lprintf(LOG_NOTICE, " 3 : desired early levels"); 2163 2164 return -1; 2165 } 2166 } 2167 else if (!strncmp(argv[1], "set", 3)) { 2168 if (argc > 4) { 2169 rc = ipmi_picmg_set_power_level(intf, argc-1, &(argv[2])); 2170 } 2171 else { 2172 lprintf(LOG_NOTICE, "power set <FRU-ID> <level> <present-desired>"); 2173 lprintf(LOG_NOTICE, " <level> 0 : Power Off"); 2174 lprintf(LOG_NOTICE, " 0x1-0x14 : Power level"); 2175 lprintf(LOG_NOTICE, " 0xFF : do not change"); 2176 lprintf(LOG_NOTICE, 2177 "\n <present-desired> 0: do not change present levels"); 2178 lprintf(LOG_NOTICE, 2179 " 1: copy desired to present level"); 2180 2181 return -1; 2182 } 2183 } 2184 else { 2185 lprintf(LOG_NOTICE, "<set>|<get>"); 2186 return -1; 2187 } 2188 } 2189 else { 2190 lprintf(LOG_NOTICE, "<set>|<get>"); 2191 return -1; 2192 } 2193 }/* clk commands*/ 2194 else if (!strncmp(argv[0], "clk", 3)) { 2195 if (argc > 1) { 2196 if (!strncmp(argv[1], "get", 3)) { 2197 int8_t clk_res = -1; 2198 uint8_t clk_id; 2199 uint8_t max_res = 15; 2200 2201 if( PicmgCardType == PICMG_CARD_TYPE_AMC ) { 2202 max_res = 0; 2203 } 2204 2205 if(!strncmp(argv[1], "getall", 6)) { 2206 if( verbose ) { printf("Getting all clock state\n") ;} 2207 for(clk_res=0;clk_res<=max_res;clk_res++) { 2208 for(clk_id=0;clk_id<=15;clk_id++) { 2209 rc = ipmi_picmg_clk_get(intf,clk_id,clk_res, 2210 PICMG_EKEY_MODE_PRINT_ALL); 2211 } 2212 } 2213 } 2214 else if(!strncmp(argv[1], "getdenied", 6)) { 2215 if( verbose ) { printf("Getting disabled clocks\n") ;} 2216 for(clk_res=0;clk_res<=max_res;clk_res++) { 2217 for(clk_id=0;clk_id<=15;clk_id++) { 2218 rc = ipmi_picmg_clk_get(intf,clk_id,clk_res, 2219 PICMG_EKEY_MODE_PRINT_DISABLED); 2220 } 2221 } 2222 } 2223 else if(!strncmp(argv[1], "getgranted", 6)) { 2224 if( verbose ) { printf("Getting enabled clocks\n") ;} 2225 for(clk_res=0;clk_res<=max_res;clk_res++) { 2226 for(clk_id=0;clk_id<=15;clk_id++) { 2227 rc = ipmi_picmg_clk_get(intf,clk_id,clk_res, 2228 PICMG_EKEY_MODE_PRINT_ENABLED); 2229 } 2230 } 2231 } 2232 else if (argc > 2) { 2233 if (is_clk_id(argv[2], &clk_id) != 0) { 2234 return (-1); 2235 } 2236 if (argc > 3) { 2237 if (is_clk_resid(argv[3], &clk_res) != 0) { 2238 return (-1); 2239 } 2240 } 2241 2242 rc = ipmi_picmg_clk_get(intf, clk_id, clk_res, 2243 PICMG_EKEY_MODE_QUERY ); 2244 } 2245 else { 2246 lprintf(LOG_NOTICE, "clk get"); 2247 lprintf(LOG_NOTICE, 2248 "<CLK-ID> [<DEV-ID>] |getall|getgranted|getdenied"); 2249 return -1; 2250 } 2251 } 2252 else if (!strncmp(argv[1], "set", 3)) { 2253 if (argc > 7) { 2254 rc = ipmi_picmg_clk_set(intf, argc-1, &(argv[2])); 2255 } 2256 else { 2257 lprintf(LOG_NOTICE, 2258 "clk set <CLK-ID> <index> <setting> <family> <acc-lvl> <freq> [<DEV-ID>]"); 2259 2260 return -1; 2261 } 2262 } 2263 else { 2264 lprintf(LOG_NOTICE, "<set>|<get>|<getall>|<getgranted>|<getdenied>"); 2265 return -1; 2266 } 2267 } 2268 else { 2269 lprintf(LOG_NOTICE, "<set>|<get>|<getall>|<getgranted>|<getdenied>"); 2270 return -1; 2271 } 2272 } 2273 2274 else if(showProperties == 0 ){ 2275 2276 ipmi_picmg_help(); 2277 return -1; 2278 } 2279 2280 return rc; 2281 } 2282 2283 uint8_t 2284 ipmi_picmg_ipmb_address(struct ipmi_intf *intf) { 2285 struct ipmi_rq req; 2286 struct ipmi_rs *rsp; 2287 char msg_data; 2288 2289 if (!intf->picmg_avail) { 2290 return 0; 2291 } 2292 memset(&req, 0, sizeof(req)); 2293 req.msg.netfn = IPMI_NETFN_PICMG; 2294 req.msg.cmd = PICMG_GET_ADDRESS_INFO_CMD; 2295 msg_data = 0x00; 2296 req.msg.data = &msg_data; 2297 req.msg.data_len = 1; 2298 msg_data = 0; 2299 2300 rsp = intf->sendrecv(intf, &req); 2301 if (rsp && !rsp->ccode) { 2302 return rsp->data[2]; 2303 } 2304 if (rsp) { 2305 lprintf(LOG_DEBUG, "Get Address Info failed: %#x %s", 2306 rsp->ccode, val2str(rsp->ccode, completion_code_vals)); 2307 } else { 2308 lprintf(LOG_DEBUG, "Get Address Info failed: No Response"); 2309 } 2310 return 0; 2311 } 2312 2313 uint8_t 2314 picmg_discover(struct ipmi_intf *intf) { 2315 /* Check if PICMG extension is available to use the function 2316 * GetDeviceLocator to retreive i2c address PICMG hack to set 2317 * right IPMB address, If extension is not supported, should 2318 * not give any problems 2319 * PICMG Extension Version 2.0 (PICMG 3.0 Revision 1.0 ATCA) to 2320 * PICMG Extension Version 2.3 (PICMG 3.0 Revision 3.0 ATCA) 2321 * PICMG Extension Version 4.1 (PICMG 3.0 Revision 3.0 AMC) 2322 */ 2323 2324 /* First, check if PICMG extension is available and supported */ 2325 struct ipmi_rq req; 2326 struct ipmi_rs *rsp; 2327 char msg_data; 2328 uint8_t picmg_avail = 0; 2329 2330 memset(&req, 0, sizeof(req)); 2331 req.msg.netfn = IPMI_NETFN_PICMG; 2332 req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD; 2333 msg_data = 0x00; 2334 req.msg.data = &msg_data; 2335 req.msg.data_len = 1; 2336 msg_data = 0; 2337 2338 lprintf(LOG_INFO, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x", 2339 intf->my_addr, intf->transit_addr, intf->target_addr); 2340 rsp = intf->sendrecv(intf, &req); 2341 if (rsp == NULL) { 2342 lprintf(LOG_INFO,"No response from Get PICMG Properties"); 2343 } else if (rsp->ccode != 0) { 2344 lprintf(LOG_INFO,"Error response %#x from Get PICMG Properities", 2345 rsp->ccode); 2346 } else if (rsp->data_len < 4) { 2347 lprintf(LOG_INFO,"Invalid Get PICMG Properties response length %d", 2348 rsp->data_len); 2349 } else if (rsp->data[0] != 0) { 2350 lprintf(LOG_INFO,"Invalid Get PICMG Properties group extension %#x", 2351 rsp->data[0]); 2352 } else if ((rsp->data[1] & 0x0F) != PICMG_ATCA_MAJOR_VERSION 2353 && (rsp->data[1] & 0x0F) != PICMG_AMC_MAJOR_VERSION) { 2354 lprintf(LOG_INFO,"Unknown PICMG Extension Version %d.%d", 2355 (rsp->data[1] & 0x0F), (rsp->data[1] >> 4)); 2356 } else { 2357 picmg_avail = 1; 2358 lprintf(LOG_INFO, "Discovered PICMG Extension Version %d.%d", 2359 (rsp->data[1] & 0x0f), (rsp->data[1] >> 4)); 2360 } 2361 2362 return picmg_avail; 2363 } 2364