aboutsummaryrefslogtreecommitdiff
path: root/include/spcn.h
blob: 0df916348762d78beddb3073cb26a641df7ec6ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 */


#ifndef __SPCN_H
#define __SPCN_H


/* SPCN commands */
#define SPCN_CMD_PRS			0x42 /* Power Resource Status */
#define SPCN_CMD_SET			0x66 /* Set Environmental Thresholds */

/* SPCN command address modes */
#define SPCN_ADDR_MODE_CEC_NODE		0x0000d000 /* CEC node single destination */
#define SPCN_ADDR_MODE_ALL_SLAVES	0x0000f000 /* Address all slaves in all racks */
#define SPCN_ADDR_MODE_RACK_NODES	0x00000000 /* Address rack node in all racks */

/* SPCN PRS command modifiers */
#define SPCN_MOD_PRS_STATUS_FIRST	0x01 /* Power Resource Status (First 1KB) */
#define SPCN_MOD_PRS_STATUS_SUBS	0x02 /* Subsequent set of 1KB PRS entries */
#define SPCN_MOD_PRS_LED_DATA_FIRST	0x51 /* LED data entry (First 1KB) */
#define SPCN_MOD_PRS_LED_DATA_SUB	0x52 /* Subsequent LED data entries */

/* SPCN SET command modifiers */
#define SPCN_MOD_SET_LED_CTL_LOC_CODE	0x07 /* Control LED with location code */
#define SPCN_MOD_SET_IDENTIFY_OFF_ENC	0x08 /* Turn off identify LEDs in CEC */
#define SPCN_MOD_SET_IDENTIFY_OFF_NODE	0x0B /* Turn off identify LEDs in Node */

/* SPCN SENSOR command modifiers */
#define SPCN_MOD_SENSOR_PARAM_FIRST	0x10 /* First 1K sensor parameters */
#define SPCN_MOD_SENSOR_PARAM_SUBS	0x11 /* Subsequent sensor parameters */
#define SPCN_MOD_SENSOR_DATA_FIRST	0x12 /* First 1K sensor data */
#define SPCN_MOD_SENSOR_DATA_SUBS	0x13 /* Subsequent sensor data blocks */
#define SPCN_MOD_PROC_JUNC_TEMP		0x14 /* Process junction temperatures */
#define SPCN_MOD_SENSOR_POWER		0x1c /* System power consumption */
#define SPCN_MOD_LAST			0xff

/*
 * Modifiers 0x53 and 0x54 are used by LEDS at standby. So HV does not come into
 * the picture here. Do we need those?
 */

/* Supported SPCN response codes */
#define LOGICAL_IND_STATE_MASK		0x10 /* If set, control fault state */
#define ACTIVE_LED_STATE_MASK		0x01 /* If set, switch on the LED */
#define SPCN_LED_IDENTIFY_MASK		0x80 /* Set identify indicator */
#define SPCN_LED_FAULT_MASK		0x40 /* Set fault indicator */
#define SPCN_LED_TRANS_MASK		0x20 /* LED is in transition */
#define SPCN_CLR_LED_STATE		0x00 /* Reset identify indicator */

/* SPCN command response status codes */
enum spcn_rsp_status {
	SPCN_RSP_STATUS_SUCCESS		= 0x01, /* Command successful */
	SPCN_RSP_STATUS_COND_SUCCESS	= 0x02, /* Command successful, but additional entries exist */
	SPCN_RSP_STATUS_INVALID_RACK	= 0x15, /* Invalid rack command */
	SPCN_RSP_STATUS_INVALID_SLAVE	= 0x16, /* Invalid slave command */
	SPCN_RSP_STATUS_INVALID_MOD	= 0x18, /* Invalid modifier */
	SPCN_RSP_STATUS_STATE_PROHIBIT	= 0x21, /* Present state prohibits */
	SPCN_RSP_STATUS_UNKNOWN		= 0xff, /* Default state */
};

/* Sensor FRCs (Frame resource class) */
enum {
	SENSOR_FRC_POWER_CTRL = 0x02,
	SENSOR_FRC_POWER_SUPPLY,
	SENSOR_FRC_REGULATOR,
	SENSOR_FRC_COOLING_FAN,
	SENSOR_FRC_COOLING_CTRL,
	SENSOR_FRC_BATTERY_CHRG,
	SENSOR_FRC_BATTERY_PACK,
	SENSOR_FRC_AMB_TEMP,
	SENSOR_FRC_TEMP,
	SENSOR_FRC_VRM,
	SENSOR_FRC_RISER_CARD,
	SENSOR_FRC_IO_BP,
};

/*
 * Common to all PRS modifiers (subcommands)
 */
struct sensor_header {
	uint16_t frc;	/* Frame resource class */
	uint16_t rid;	/* Resource ID */
} __packed;

/*
 * Data layout for PRS modifier PRS_STATUS 0x01, 0x02
 */
struct sensor_prs {
	struct sensor_header header;
	uint16_t src;	/* unused */
	uint16_t status;
} __packed;

#define PRS_STATUS_ON_SUPPORTED	0x0010
#define PRS_STATUS_ON		0x0008
#define PRS_STATUS_AC_FAULTED	0x0004
#define PRS_STATUS_FAULTED	0x0002
#define PRS_STATUS_PRESENT	0x0001

/*
 * Data layout for PRS modifier SENSOR_PARAM 0x10, 0x11
 */
struct sensor_param {
	struct sensor_header header;
	char location[4];
	char __reserved[4];
	uint16_t threshold;
	uint16_t status;
} __packed;

/*
 * Data layout for PRS modifier SENSOR_DATA 0x12, 0x13
 */
struct sensor_data {
	struct sensor_header header;
	uint16_t data;
	uint16_t status;
} __packed;

#define SENSOR_STATUS_EM_ALERT	0x0004
#define SENSOR_STATUS_FAULTED	0x0002
#define SENSOR_STATUS_PRESENT	0x0001

/* Power sensor is retrieved through a new PRS modifier 0x1C, data
 * response is as follows:
 *
 * Byte 0:
 *
 *	Bit 7: Data valid
 *	Bit 4-6: reserved
 *	Bit 0-3: Number of power supply or data records
 *
 * Each data record is 5 Bytes following above byte 0:
 *
 * Data Record: Byte 0: Power supply ID {00, 01, 02, 03, ...}
 *	     Byte 1-4: Power sensor value in milli-watts
 *
 * Example Power Sensor data: (Tuleta)
 * 84 00 00 00 00 00
 *    01 00 00 00 00
 *    02 00 02 5d 78
 *    03 00 02 0f 58
 *    00 00 00 00 00
 *
 * 0x84: Bit 7 is valid bit and there are 4 power supplies
 * 0x00 00 00 00 00
 *   |  ^^^^^^^^^^^ Power in milli-watts
 *   \-- Power supply ID
 *
 * Ox03 00 02 0f 58
 *   |  ^^^^^^^^^^^ Power in milli-watts (135000 mW)
 *   \-- Power supply ID
 */

#define POWER_SUPPLY_MAX 8

struct sensor_power_supply {
	uint8_t	rid;		/* Power supply ID */
	uint32_t milliwatts;
} __packed;

struct sensor_power {
	uint8_t status;
	struct sensor_power_supply supplies[POWER_SUPPLY_MAX];
} __packed;

#define sensor_power_is_valid(s)	((s)->status & 0x80)
#define sensor_power_count(s)		((s)->status & 0x0f)


#endif /* __SPCN_H */