1 #include <avr/pgmspace.h>
9 uint8_t ipmb_csum(unsigned char *buf
, int len
)
14 for(i
= 0; i
< len
; i
++) {
21 void ipmb_send(struct ipmb_resp
*resp
, const unsigned char *data
, uint8_t datalen
)
23 unsigned char buf
[24];
30 buf
[1] = ((resp
->netFn
)<<2) | (resp
->rqLUN
& 0x3);
31 buf
[2] = ipmb_csum(buf
, 2);
33 buf
[4] = ((resp
->rqSEQ
)<<2) | (resp
->rsLUN
& 0x3);
35 memcpy(buf
+6, data
, datalen
);
37 buf
[len
-1] = ipmb_csum(buf
+3, len
- 4);
41 for(i
= 0; i
< len
; i
++) {
42 printf("0x%02x ", buf
[i
]);
52 void ipmb_dump_req(struct ipmb_req
*req
)
56 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
57 printf("Connection Header:\n");
58 printf("\trs Slave Addr.: 0x%02x\n", req
->rsSA
);
59 printf("\tnetFn: 0x%02x, LUN: 0x%02x\n", req
->netFn
, req
->rsLUN
);
61 printf("\trq Slave Addr.: 0x%02x\n", req
->rqSA
);
62 printf("\trqSeq: 0x%02x, rqLUN: 0x%02x\n", req
->rqSEQ
, req
->rqLUN
);
63 printf("\tcmd: 0x%02x\n", req
->cmd
);
65 for(i
= 0; i
< req
->datalen
; i
++) {
66 printf("0x%02x ", req
->data
[i
]);
69 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
73 void ipmb_invalid(struct ipmb_resp
*resp
)
76 const unsigned char cmd_invalid
[] = {IPMB_CC_INVALID
};
78 ipmb_send(resp
, cmd_invalid
, sizeof(cmd_invalid
));
82 void ipmb_cmd(struct ipmb_req
*req
)
84 struct ipmb_resp resp
;
85 const unsigned char get_devid
[] =
86 {IPMB_CC_NORMALLY
, 0x42, 0x42, 0x01, 0x01, 0x51, 0xff /* Add. Dev. Supp */, 0x00, 0x00, 0x00, 0x00, 0x00 };
87 const unsigned char get_wd_timer
[] =
88 {IPMB_CC_NORMALLY
, 0x42, 0x00, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xfe};
89 const unsigned char cc_normal
[] =
91 const unsigned char sel_info
[] =
92 {IPMB_CC_NORMALLY
, 0x51, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
93 const unsigned char sel_alloc_info
[] =
94 {IPMB_CC_NORMALLY
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
95 const unsigned char sel_entry
[] =
97 const unsigned char sel_timestamp
[] =
98 {IPMB_CC_NORMALLY
, 0x00, 0x00, 0x00, 0x00};
99 const unsigned char chassis_status
[] =
100 {IPMB_CC_NORMALLY
, 0x60, 0x10, 0x00, 0x00};
101 const unsigned char reserve_sdr
[] =
102 {IPMB_CC_NORMALLY
, 0x00, 0x00};
103 const unsigned char get_sdr
[] =
104 {IPMB_CC_NORMALLY
, 0xff, 0xff};
106 resp
.rqSA
= req
->rqSA
;
107 resp
.netFn
= req
->netFn
+1;
108 resp
.rqLUN
= req
->rqLUN
;
109 resp
.rsSA
= req
->rsSA
;
110 resp
.rqSEQ
= req
->rqSEQ
;
111 resp
.rsLUN
= req
->rsLUN
;
114 switch (req
->netFn
) {
115 case IPMB_NETFN_CHASSIS
:
117 case IPMB_CHASSIS_GET_STATUS
:
118 ipmb_send(&resp
, chassis_status
, sizeof(chassis_status
));
120 case IPMB_CHASSIS_CONTROL
:
121 chassis_control(*(req
->data
));
122 ipmb_send(&resp
, cc_normal
, sizeof(cc_normal
));
126 printf("Unknown chassis cmd 0x%02x\n", req
->cmd
);
134 case IPMB_NETFN_SENSOR_EVENT
:
136 case IPMB_SE_PLATFORM_EVENT
:
138 * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
140 * rs Slave Addr.: 0x24
141 * netFn: 0x04, LUN: 0x00
143 * rq Slave Addr.: 0x28
144 * rqSeq: 0x03, rqLUN: 0x00
146 * Data: 0x03 0xc8 0x00 0x6f 0x61 0x8f 0x03
147 * <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
148 * data[0] - EvMRev: 0x03
149 * data[1] - Sensor Type: 0xc8
150 * data[2] - Sensor #: 0x00
151 * data[3] - Event Dir(1)|Event Type(7): 0x6f: 0x0|0x6f (assert, discrete)
152 * data[4] - Event Data: 0x61
153 * data[5] - Event Data: 0x8f
154 * data[6] - Event Data: 0x03
156 ipmb_send(&resp
, cc_normal
, sizeof(cc_normal
));
162 printf("Unknown sensor cmd 0x%02x\n", req
->cmd
);
172 case IPMB_APP_GET_DEVICE_ID
:
173 ipmb_send(&resp
, get_devid
, sizeof(get_devid
));
176 case IPMB_APP_GET_WATCHDOG_TIMER
:
177 ipmb_send(&resp
, get_wd_timer
, sizeof(get_wd_timer
));
182 printf("Unknown app cmd 0x%02x\n", req
->cmd
);
190 case IPMB_NETFN_STORAGE
:
192 case IPMB_STORAGE_RESERVE_SDR
:
193 ipmb_send(&resp
, reserve_sdr
, sizeof(reserve_sdr
));
195 case IPMB_STORAGE_GET_SDR
:
196 ipmb_send(&resp
, get_sdr
, sizeof(get_sdr
));
198 case IPMB_STORAGE_GET_SEL_INFO
:
199 ipmb_send(&resp
, sel_info
, sizeof(sel_info
));
201 case IPMB_STORAGE_GET_SEL_ALLOCATION
:
202 ipmb_send(&resp
, sel_alloc_info
, sizeof(sel_alloc_info
));
204 case IPMB_STORAGE_GET_SEL_ENTRY
:
205 ipmb_send(&resp
, sel_entry
, sizeof(sel_entry
));
207 case IPMB_STORAGE_GET_SEL_TIME
:
208 ipmb_send(&resp
, sel_timestamp
, sizeof(sel_timestamp
));
212 printf("Unknown storage cmd 0x%02x\n", req
->cmd
);
222 printf("Unknown netFn 0x%02x\n", req
->netFn
);
230 void decode_ipmb_pkt(unsigned char *buf
, int len
)
234 if ((buf
[2] != ipmb_csum(buf
, 2)) ||
235 (buf
[len
-1] != ipmb_csum(buf
+3, len
-4)))
236 return; /* Checksum wrong */
239 req
.netFn
= (buf
[1]>>2)&0x3f;
240 req
.rsLUN
= (buf
[1] & 0x03);
242 req
.rqSEQ
= (buf
[4]>>2)&0x3f;
243 req
.rqLUN
= (buf
[4] & 0x03);
246 req
.datalen
= len
- 6 - 1;