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