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
ipmi_picmg_help(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
is_amc_channel(const char * argv_ptr,uint8_t * amc_chan_ptr)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
is_amc_dev(const char * argv_ptr,int32_t * amc_dev_ptr)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
is_amc_intf(const char * argv_ptr,int32_t * amc_intf_ptr)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
is_amc_port(const char * argv_ptr,int32_t * amc_port_ptr)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
is_clk_acc(const char * argv_ptr,uint8_t * clk_acc_ptr)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
is_clk_family(const char * argv_ptr,uint8_t * clk_family_ptr)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
is_clk_freq(const char * argv_ptr,uint32_t * clk_freq_ptr)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
is_clk_id(const char * argv_ptr,uint8_t * clk_id_ptr)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
is_clk_index(const char * argv_ptr,uint8_t * clk_index_ptr)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
is_clk_resid(const char * argv_ptr,int8_t * clk_resid_ptr)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
is_clk_setting(const char * argv_ptr,uint8_t * clk_setting_ptr)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
is_enable(const char * argv_ptr,uint8_t * enable_ptr)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
is_led_color(const char * argv_ptr,uint8_t * led_color_ptr)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
is_led_duration(const char * argv_ptr,uint8_t * led_duration_ptr)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
is_led_function(const char * argv_ptr,uint8_t * led_fn_ptr)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
is_led_id(const char * argv_ptr,uint8_t * led_id_ptr)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
is_link_group(const char * argv_ptr,uint8_t * link_grp_ptr)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
is_link_type(const char * argv_ptr,uint8_t * link_type_ptr)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
is_link_type_ext(const char * argv_ptr,uint8_t * link_type_ext_ptr)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
ipmi_picmg_getaddr(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_properties(struct ipmi_intf * intf,int show)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
ipmi_picmg_fru_activation(struct ipmi_intf * intf,int argc,char ** argv,unsigned char state)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
ipmi_picmg_fru_activation_policy_get(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_fru_activation_policy_set(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_portstate_get(struct ipmi_intf * intf,int32_t interface,uint8_t channel,int mode)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
ipmi_picmg_portstate_set(struct ipmi_intf * intf,int32_t interface,uint8_t channel,int32_t port,uint8_t type,uint8_t typeext,uint8_t group,uint8_t enable)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
ipmi_picmg_amc_portstate_get(struct ipmi_intf * intf,int32_t device,uint8_t channel,int mode)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
ipmi_picmg_amc_portstate_set(struct ipmi_intf * intf,uint8_t channel,int32_t port,uint8_t type,uint8_t typeext,uint8_t group,uint8_t enable,int32_t device)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
ipmi_picmg_get_led_properties(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_get_led_capabilities(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_get_led_state(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_set_led_state(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_get_power_level(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_set_power_level(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_bused_resource(struct ipmi_intf * intf,t_picmg_bused_resource_mode mode)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
ipmi_picmg_fru_control(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_clk_get(struct ipmi_intf * intf,uint8_t clk_id,int8_t clk_res,int mode)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
ipmi_picmg_clk_set(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_main(struct ipmi_intf * intf,int argc,char ** argv)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
ipmi_picmg_ipmb_address(struct ipmi_intf * intf)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
picmg_discover(struct ipmi_intf * intf)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