blob: 3f2fd99c26d9593e89589d521275bfae20ea95be [file] [log] [blame]
Chris Austenac4604a2015-10-13 12:43:27 -05001#ifndef __HOST_IPMI_SEN_HANDLER_H__
2#define __HOST_IPMI_SEN_HANDLER_H__
3
Tom Joseph816e92b2017-09-06 19:23:00 +05304#include "types.hpp"
Patrick Venture0b02be92018-08-31 11:55:55 -07005
6#include <stdint.h>
7
Tom Joseph5ca50952018-02-22 00:33:38 +05308#include "host-ipmid/ipmid-api.h"
Chris Austen0012e9b2015-10-22 01:37:46 -05009
Chris Austenac4604a2015-10-13 12:43:27 -050010// IPMI commands for net functions.
11enum ipmi_netfn_sen_cmds
12{
Tom Joseph5ca50952018-02-22 00:33:38 +053013 IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20,
Patrick Venture0b02be92018-08-31 11:55:55 -070014 IPMI_CMD_GET_DEVICE_SDR = 0x21,
15 IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22,
Chris Austen10ccc0f2015-12-10 18:27:04 -060016 IPMI_CMD_GET_SENSOR_READING = 0x2D,
Patrick Venture0b02be92018-08-31 11:55:55 -070017 IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
18 IPMI_CMD_SET_SENSOR = 0x30,
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -060019 IPMI_CMD_GET_SENSOR_THRESHOLDS = 0x27,
Chris Austenac4604a2015-10-13 12:43:27 -050020};
21
Ratan Guptae0cc8552018-01-22 14:23:04 +053022/**
23 * @enum device_type
24 * IPMI FRU device types
25 */
26enum device_type
27{
28 IPMI_PHYSICAL_FRU = 0x00,
29 IPMI_LOGICAL_FRU = 0x80,
30};
31
Emily Shaffer1fabf222017-04-05 08:53:21 -070032// Discrete sensor types.
33enum ipmi_sensor_types
34{
Patrick Venture0b02be92018-08-31 11:55:55 -070035 IPMI_SENSOR_TEMP = 0x01,
Emily Shaffer1fabf222017-04-05 08:53:21 -070036 IPMI_SENSOR_VOLTAGE = 0x02,
37 IPMI_SENSOR_CURRENT = 0x03,
Patrick Venture0b02be92018-08-31 11:55:55 -070038 IPMI_SENSOR_FAN = 0x04,
39 IPMI_SENSOR_TPM = 0xCC,
Emily Shaffer1fabf222017-04-05 08:53:21 -070040};
41
Chris Austen0012e9b2015-10-22 01:37:46 -050042#define MAX_DBUS_PATH 128
Patrick Venture0b02be92018-08-31 11:55:55 -070043struct dbus_interface_t
44{
45 uint8_t sensornumber;
46 uint8_t sensortype;
Chris Austen0012e9b2015-10-22 01:37:46 -050047
Patrick Venture0b02be92018-08-31 11:55:55 -070048 char bus[MAX_DBUS_PATH];
49 char path[MAX_DBUS_PATH];
50 char interface[MAX_DBUS_PATH];
Chris Austen0012e9b2015-10-22 01:37:46 -050051};
Tomd700e762016-09-20 18:24:13 +053052
Patrick Venture0b02be92018-08-31 11:55:55 -070053int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
54int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
55int find_openbmc_path(uint8_t, dbus_interface_t*);
Tom05732372016-09-06 17:21:23 +053056
Tom Joseph5ca50952018-02-22 00:33:38 +053057ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
58 ipmi_request_t request, ipmi_response_t response,
59 ipmi_data_len_t data_len, ipmi_context_t context);
60
61ipmi_ret_t ipmi_sen_reserve_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
62 ipmi_request_t request,
63 ipmi_response_t response,
64 ipmi_data_len_t data_len,
65 ipmi_context_t context);
66
Ratan Guptae0cc8552018-01-22 14:23:04 +053067static const uint16_t FRU_RECORD_ID_START = 256;
68static const uint8_t SDR_VERSION = 0x51;
69static const uint16_t END_OF_RECORD = 0xFFFF;
70static const uint8_t LENGTH_MASK = 0x1F;
71
Tom Josephbe703f72017-03-09 12:34:35 +053072/**
Emily Shafferd06e0e72017-04-05 09:08:57 -070073 * Get SDR Info
74 */
75
76namespace get_sdr_info
77{
78namespace request
79{
80// Note: for some reason the ipmi_request_t appears to be the
81// raw value for this call.
82inline bool get_count(void* req)
83{
Patrick Venture0b02be92018-08-31 11:55:55 -070084 return (bool)((uint64_t)(req)&1);
Emily Shafferd06e0e72017-04-05 09:08:57 -070085}
86} // namespace request
87
88namespace response
89{
90#define SDR_INFO_RESP_SIZE 2
91inline void set_lun_present(int lun, uint8_t* resp)
92{
93 *resp |= 1 << lun;
94}
95inline void set_lun_not_present(int lun, uint8_t* resp)
96{
97 *resp &= ~(1 << lun);
98}
99inline void set_dynamic_population(uint8_t* resp)
100{
101 *resp |= 1 << 7;
102}
103inline void set_static_population(uint8_t* resp)
104{
105 *resp &= ~(1 << 7);
106}
107} // namespace response
108
109struct GetSdrInfoResp
110{
111 uint8_t count;
112 uint8_t luns_and_dynamic_population;
113};
114
115} // namespace get_sdr_info
Emily Shafferbbef71c2017-05-08 16:36:17 -0700116
117/**
118 * Get SDR
119 */
120namespace get_sdr
121{
122
123struct GetSdrReq
124{
125 uint8_t reservation_id_lsb;
126 uint8_t reservation_id_msb;
127 uint8_t record_id_lsb;
128 uint8_t record_id_msb;
129 uint8_t offset;
130 uint8_t bytes_to_read;
131} __attribute__((packed));
132
133namespace request
134{
135
136inline uint8_t get_reservation_id(GetSdrReq* req)
137{
138 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
139};
140
Ratan Guptae0cc8552018-01-22 14:23:04 +0530141inline uint16_t get_record_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700142{
143 return (req->record_id_lsb + (req->record_id_msb << 8));
144};
145
146} // namespace request
147
148// Response
149struct GetSdrResp
150{
151 uint8_t next_record_id_lsb;
152 uint8_t next_record_id_msb;
153 uint8_t record_data[64];
154} __attribute__((packed));
155
156namespace response
157{
158
Ratan Guptae0cc8552018-01-22 14:23:04 +0530159inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700160{
161 resp->next_record_id_lsb = next & 0xff;
162 resp->next_record_id_msb = (next >> 8) & 0xff;
163};
164
165} // namespace response
166
167// Record header
168struct SensorDataRecordHeader
169{
170 uint8_t record_id_lsb;
171 uint8_t record_id_msb;
172 uint8_t sdr_version;
173 uint8_t record_type;
174 uint8_t record_length; // Length not counting the header
175} __attribute__((packed));
176
177namespace header
178{
179
180inline void set_record_id(int id, SensorDataRecordHeader* hdr)
181{
182 hdr->record_id_lsb = (id & 0xFF);
183 hdr->record_id_msb = (id >> 8) & 0xFF;
184};
185
186} // namespace header
187
188enum SensorDataRecordType
189{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530190 SENSOR_DATA_FULL_RECORD = 0x1,
191 SENSOR_DATA_FRU_RECORD = 0x11,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700192};
193
194// Record key
195struct SensorDataRecordKey
196{
197 uint8_t owner_id;
198 uint8_t owner_lun;
199 uint8_t sensor_number;
200} __attribute__((packed));
201
Ratan Guptae0cc8552018-01-22 14:23:04 +0530202/** @struct SensorDataFruRecordKey
203 *
204 * FRU Device Locator Record(key) - SDR Type 11
205 */
206struct SensorDataFruRecordKey
207{
208 uint8_t deviceAddress;
209 uint8_t fruID;
210 uint8_t accessLun;
211 uint8_t channelNumber;
212} __attribute__((packed));
213
Emily Shafferbbef71c2017-05-08 16:36:17 -0700214namespace key
215{
216
217inline void set_owner_id_ipmb(SensorDataRecordKey* key)
218{
219 key->owner_id &= ~0x01;
220};
221
222inline void set_owner_id_system_sw(SensorDataRecordKey* key)
223{
224 key->owner_id |= 0x01;
225};
226
Tom Joseph96423912018-01-25 00:14:34 +0530227inline void set_owner_id_bmc(SensorDataRecordKey* key)
228{
229 key->owner_id |= 0x20;
230};
231
Emily Shafferbbef71c2017-05-08 16:36:17 -0700232inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
233{
234 key->owner_id &= 0x01;
Patrick Venture0b02be92018-08-31 11:55:55 -0700235 key->owner_id |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700236};
237
238inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
239{
240 key->owner_lun &= ~0x03;
Patrick Venture0b02be92018-08-31 11:55:55 -0700241 key->owner_lun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700242};
243
244inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
245{
246 key->owner_lun &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700247 key->owner_lun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700248};
249
250} // namespace key
251
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600252/** @struct GetSensorThresholdsResponse
253 *
254 * Response structure for Get Sensor Thresholds command
255 */
256struct GetSensorThresholdsResponse
257{
Patrick Venture0b02be92018-08-31 11:55:55 -0700258 uint8_t validMask; //!< valid mask
259 uint8_t lowerNonCritical; //!< lower non-critical threshold
260 uint8_t lowerCritical; //!< lower critical threshold
261 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
262 uint8_t upperNonCritical; //!< upper non-critical threshold
263 uint8_t upperCritical; //!< upper critical threshold
264 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600265} __attribute__((packed));
266
Emily Shafferbbef71c2017-05-08 16:36:17 -0700267// Body - full record
268#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530269
270static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
271
Emily Shafferbbef71c2017-05-08 16:36:17 -0700272struct SensorDataFullRecordBody
273{
274 uint8_t entity_id;
275 uint8_t entity_instance;
276 uint8_t sensor_initialization;
277 uint8_t sensor_capabilities; // no macro support
278 uint8_t sensor_type;
279 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700280 uint8_t supported_assertions[2]; // no macro support
281 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700282 uint8_t discrete_reading_setting_mask[2]; // no macro support
283 uint8_t sensor_units_1;
284 uint8_t sensor_units_2_base;
285 uint8_t sensor_units_3_modifier;
286 uint8_t linearization;
287 uint8_t m_lsb;
288 uint8_t m_msb_and_tolerance;
289 uint8_t b_lsb;
290 uint8_t b_msb_and_accuracy_lsb;
291 uint8_t accuracy_and_sensor_direction;
292 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700293 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700294 uint8_t nominal_reading;
295 uint8_t normal_max;
296 uint8_t normal_min;
297 uint8_t sensor_max;
298 uint8_t sensor_min;
299 uint8_t upper_nonrecoverable_threshold;
300 uint8_t upper_critical_threshold;
301 uint8_t upper_noncritical_threshold;
302 uint8_t lower_nonrecoverable_threshold;
303 uint8_t lower_critical_threshold;
304 uint8_t lower_noncritical_threshold;
305 uint8_t positive_threshold_hysteresis;
306 uint8_t negative_threshold_hysteresis;
307 uint16_t reserved;
308 uint8_t oem_reserved;
309 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700310 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700311} __attribute__((packed));
312
Ratan Guptae0cc8552018-01-22 14:23:04 +0530313/** @struct SensorDataFruRecordBody
314 *
315 * FRU Device Locator Record(body) - SDR Type 11
316 */
317struct SensorDataFruRecordBody
318{
319 uint8_t reserved;
320 uint8_t deviceType;
321 uint8_t deviceTypeModifier;
322 uint8_t entityID;
323 uint8_t entityInstance;
324 uint8_t oem;
325 uint8_t deviceIDLen;
326 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
327} __attribute__((packed));
328
Emily Shafferbbef71c2017-05-08 16:36:17 -0700329namespace body
330{
331
332inline void set_entity_instance_number(uint8_t n,
333 SensorDataFullRecordBody* body)
334{
Patrick Venture0b02be92018-08-31 11:55:55 -0700335 body->entity_instance &= 1 << 7;
336 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700337};
338inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
339{
Patrick Venture0b02be92018-08-31 11:55:55 -0700340 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700341};
342inline void set_entity_logical_container(SensorDataFullRecordBody* body)
343{
Patrick Venture0b02be92018-08-31 11:55:55 -0700344 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700345};
346
Patrick Venture0b02be92018-08-31 11:55:55 -0700347inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700348{
349 if (enabled)
350 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700351 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700352 }
353 else
354 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700355 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700356 };
357};
Patrick Venture0b02be92018-08-31 11:55:55 -0700358inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700359{
360 if (enabled)
361 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700362 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700363 }
364 else
365 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700366 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700367 }
368};
Patrick Venture0b02be92018-08-31 11:55:55 -0700369inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700370{
371 if (enabled)
372 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700373 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700374 }
375 else
376 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700377 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700378 }
379};
Patrick Venture0b02be92018-08-31 11:55:55 -0700380inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700381{
382 if (enabled)
383 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700384 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700385 }
386 else
387 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700388 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700389 }
390};
Patrick Venture0b02be92018-08-31 11:55:55 -0700391inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700392{
393 if (enabled)
394 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700395 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700396 }
397 else
398 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700399 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700400 }
401};
Patrick Venture0b02be92018-08-31 11:55:55 -0700402inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700403{
404 if (enabled)
405 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700406 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700407 }
408 else
409 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700410 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700411 }
412};
Patrick Venture0b02be92018-08-31 11:55:55 -0700413inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700414{
415 if (enabled)
416 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700417 body->sensor_initialization |= 1 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700418 }
419 else
420 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700421 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700422 }
423};
Patrick Venture0b02be92018-08-31 11:55:55 -0700424inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700425{
426 if (enabled)
427 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700428 body->sensor_initialization |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700429 }
430 else
431 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700432 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700433 }
434};
435
436inline void set_percentage(SensorDataFullRecordBody* body)
437{
Patrick Venture0b02be92018-08-31 11:55:55 -0700438 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700439};
440inline void unset_percentage(SensorDataFullRecordBody* body)
441{
Patrick Venture0b02be92018-08-31 11:55:55 -0700442 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700443};
444inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
445{
Patrick Venture0b02be92018-08-31 11:55:55 -0700446 body->sensor_units_1 &= ~(3 << 1);
447 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700448};
449inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
450{
Patrick Venture0b02be92018-08-31 11:55:55 -0700451 body->sensor_units_1 &= ~(7 << 3);
452 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700453};
454inline void set_analog_data_format(uint8_t format,
455 SensorDataFullRecordBody* body)
456{
Patrick Venture0b02be92018-08-31 11:55:55 -0700457 body->sensor_units_1 &= ~(3 << 6);
458 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700459};
460
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700461inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700462{
463 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700464 body->m_msb_and_tolerance &= ~(3 << 6);
465 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700466};
467inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
468{
469 body->m_msb_and_tolerance &= ~0x3f;
470 body->m_msb_and_tolerance |= tol & 0x3f;
471};
472
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700473inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700474{
475 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700476 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
477 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700478};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700479inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700480{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700481 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700482 body->b_msb_and_accuracy_lsb &= ~0x3f;
483 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700484 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700485 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700486 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700487};
488inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
489{
Patrick Venture0b02be92018-08-31 11:55:55 -0700490 body->accuracy_and_sensor_direction &= ~(3 << 2);
491 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700492};
493inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
494{
Patrick Venture0b02be92018-08-31 11:55:55 -0700495 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700496 body->accuracy_and_sensor_direction |= (dir & 3);
497};
498
499inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
500{
501 body->r_b_exponents &= 0xf0;
502 body->r_b_exponents |= exp & 0x0f;
503};
504inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
505{
506 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700507 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700508};
509
510inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
511{
512 body->id_string_info &= ~(0x1f);
513 body->id_string_info |= len & 0x1f;
514};
Patrick Venture0b02be92018-08-31 11:55:55 -0700515inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700516{
517 return body->id_string_info & 0x1f;
518};
519inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
520{
Patrick Venture0b02be92018-08-31 11:55:55 -0700521 body->id_string_info &= ~(3 << 6);
522 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700523};
524
Ratan Guptae0cc8552018-01-22 14:23:04 +0530525inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
526{
527 body->deviceIDLen &= ~(LENGTH_MASK);
528 body->deviceIDLen |= len & LENGTH_MASK;
529};
530
531inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
532{
533 return body->deviceIDLen & LENGTH_MASK;
534};
535
Tom Josephdc212b22018-02-16 09:59:57 +0530536inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
537{
538 body->discrete_reading_setting_mask[1] = mask & 0x3F;
539}
540
Emily Shafferbbef71c2017-05-08 16:36:17 -0700541} // namespace body
542
543// More types contained in section 43.17 Sensor Unit Type Codes,
544// IPMI spec v2 rev 1.1
545enum SensorUnitTypeCodes
546{
547 SENSOR_UNIT_UNSPECIFIED = 0,
548 SENSOR_UNIT_DEGREES_C = 1,
549 SENSOR_UNIT_VOLTS = 4,
550 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530551 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700552 SENSOR_UNIT_JOULES = 7,
553 SENSOR_UNIT_METERS = 34,
554 SENSOR_UNIT_REVOLUTIONS = 41,
555};
556
557struct SensorDataFullRecord
558{
559 SensorDataRecordHeader header;
560 SensorDataRecordKey key;
561 SensorDataFullRecordBody body;
562} __attribute__((packed));
563
Ratan Guptae0cc8552018-01-22 14:23:04 +0530564/** @struct SensorDataFruRecord
565 *
566 * FRU Device Locator Record - SDR Type 11
567 */
568struct SensorDataFruRecord
569{
570 SensorDataRecordHeader header;
571 SensorDataFruRecordKey key;
572 SensorDataFruRecordBody body;
573} __attribute__((packed));
574
Patrick Venture0b02be92018-08-31 11:55:55 -0700575} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530576
577namespace ipmi
578{
579
580namespace sensor
581{
582
583/**
584 * @brief Map offset to the corresponding bit in the assertion byte.
585 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500586 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530587 * byte and offsets 8-14 in the second byte.
588 *
589 * @param[in] offset - offset number.
590 * @param[in/out] resp - get sensor reading response.
591 */
592inline void setOffset(uint8_t offset, ipmi::sensor::GetReadingResponse* resp)
593{
594 if (offset > 7)
595 {
596 resp->assertOffset8_14 |= 1 << (offset - 8);
597 }
598 else
599 {
600 resp->assertOffset0_7 |= 1 << offset;
601 }
602}
603
Tom Josephe4014fc2017-09-06 23:57:36 +0530604/**
605 * @brief Set the reading field in the response.
606 *
607 * @param[in] offset - offset number.
608 * @param[in/out] resp - get sensor reading response.
609 */
610inline void setReading(uint8_t value, ipmi::sensor::GetReadingResponse* resp)
611{
612 resp->reading = value;
613}
614
Tom Joseph295f17e2017-09-07 00:09:46 +0530615/**
616 * @brief Map the value to the assertion bytes. The assertion states are stored
617 * in 2 bytes.
618 *
619 * @param[in] value - value to mapped to the assertion byte.
620 * @param[in/out] resp - get sensor reading response.
621 */
622inline void setAssertionBytes(uint16_t value,
623 ipmi::sensor::GetReadingResponse* resp)
624{
625 resp->assertOffset0_7 = static_cast<uint8_t>(value & 0x00FF);
626 resp->assertOffset8_14 = static_cast<uint8_t>(value >> 8);
627}
628
Tom Josephe05b2922017-09-07 00:43:16 +0530629/**
630 * @brief Set the scanning enabled bit in the response.
631 *
632 * @param[in/out] resp - get sensor reading response.
633 */
634inline void enableScanning(ipmi::sensor::GetReadingResponse* resp)
635{
636 resp->operation = 1 << 6;
637}
638
Tom Joseph816e92b2017-09-06 19:23:00 +0530639} // namespace sensor
640
641} // namespace ipmi
Chris Austenac4604a2015-10-13 12:43:27 -0500642#endif