]> git.zerfleddert.de Git - rsbs2/blob - bmc/ipmb.c
023b240a785ab7271f9a387d4a7ee8917028d470
[rsbs2] / bmc / ipmb.c
1 #include <string.h>
2 #include <stdio.h>
3
4 #include "i2c.h"
5 #include "chassis.h"
6 #include "ipmb.h"
7
8 uint8_t ipmb_csum(unsigned char *buf, int len)
9 {
10 uint8_t csum = 0x00;
11 int i;
12
13 for(i = 0; i < len; i++) {
14 csum += buf[i];
15 }
16
17 return -csum;
18 }
19
20 void ipmb_send(struct ipmb_resp *resp)
21 {
22 unsigned char buf[24];
23 int len;
24 #ifdef DEBUG
25 int i;
26 #endif
27
28 buf[0] = resp->rqSA;
29 buf[1] = ((resp->netFn)<<2) | (resp->rqLUN & 0x3);
30 buf[2] = ipmb_csum(buf, 2);
31 buf[3] = resp->rsSA;
32 buf[4] = ((resp->rqSEQ)<<2) | (resp->rsLUN & 0x3);
33 buf[5] = resp->cmd;
34 memcpy(buf+6, resp->data, resp->datalen);
35 len = resp->datalen + 7;
36 buf[len-1] = ipmb_csum(buf+3, len - 4);
37
38 #ifdef DEBUG
39 printf("Sending: ");
40 for(i = 0; i < len; i++) {
41 printf("0x%02x ", buf[i]);
42 }
43 printf("\n");
44 #endif
45
46 i2c_send(buf, len);
47
48 }
49
50 #ifdef DEBUG
51 void ipmb_dump_req(struct ipmb_req *req)
52 {
53 int i;
54
55 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
56 printf("Connection Header:\n");
57 printf("\trs Slave Addr.: 0x%02x\n", req->rsSA);
58 printf("\tnetFn: 0x%02x, LUN: 0x%02x\n", req->netFn, req->rsLUN);
59 printf("Data:\n");
60 printf("\trq Slave Addr.: 0x%02x\n", req->rqSA);
61 printf("\trqSeq: 0x%02x, rqLUN: 0x%02x\n", req->rqSEQ, req->rqLUN);
62 printf("\tcmd: 0x%02x\n", req->cmd);
63 printf("\tData: ");
64 for(i = 0; i < req->datalen; i++) {
65 printf("0x%02x ", req->data[i]);
66 }
67 printf("\n");
68 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
69 }
70 #endif
71
72 void ipmb_invalid(struct ipmb_resp *resp)
73 {
74 #if 0
75 static unsigned char cmd_invalid[] = {0xc2};
76
77 resp->data = cmd_invalid;
78 resp->datalen = sizeof(cmd_invalid);
79 ipmb_send(resp);
80 #endif
81 }
82
83 void ipmb_cmd(struct ipmb_req *req)
84 {
85 struct ipmb_resp resp;
86 static unsigned char get_devid[] =
87 {IPMB_CC_NORMALLY, 0x42, 0x42, 0x01, 0x01, 0x51, 0xff /* Add. Dev. Supp */, 0x00, 0x00, 0x00, 0x00, 0x00 };
88 static unsigned char get_wd_timer[] =
89 {IPMB_CC_NORMALLY, 0x42, 0x00, 0x00, 0x04, 0xff, 0xff, 0xfe, 0xfe};
90 static unsigned char cc_normal[] =
91 {IPMB_CC_NORMALLY};
92
93 resp.rqSA = req->rqSA;
94 resp.netFn = req->netFn+1;
95 resp.rqLUN = req->rqLUN;
96 resp.rsSA = req->rsSA;
97 resp.rqSEQ = req->rqSEQ;
98 resp.rsLUN = req->rsLUN;
99 resp.cmd = req->cmd;
100
101 switch (req->netFn) {
102 case IPMB_NETFN_CHASSIS:
103 switch (req->cmd) {
104 case IPMB_CHASSIS_CONTROL:
105 chassis_control(*(req->data));
106 resp.data = cc_normal;
107 resp.datalen = sizeof(cc_normal);
108 ipmb_send(&resp);
109 break;
110 default:
111 #ifdef DEBUG
112 printf("Unknown chassis cmd 0x%02x\n", req->cmd);
113 ipmb_dump_req(req);
114 #endif
115 ipmb_invalid(&resp);
116 break;
117 }
118 break;
119
120 case IPMB_NETFN_SENSOR_EVENT:
121 switch (req->cmd) {
122 case IPMB_SE_PLATFORM_EVENT:
123 /*
124 * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
125 * Connection Header:
126 * rs Slave Addr.: 0x24
127 * netFn: 0x04, LUN: 0x00
128 * Data:
129 * rq Slave Addr.: 0x28
130 * rqSeq: 0x03, rqLUN: 0x00
131 * cmd: 0x02
132 * Data: 0x03 0xc8 0x00 0x6f 0x61 0x8f 0x03
133 * <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
134 * data[0] - EvMRev: 0x03
135 * data[1] - Sensor Type: 0xc8
136 * data[2] - Sensor #: 0x00
137 * data[3] - Event Dir(1)|Event Type(7): 0x6f: 0x0|0x6f (assert, discrete)
138 * data[4] - Event Data: 0x61
139 * data[5] - Event Data: 0x8f
140 * data[6] - Event Data: 0x03
141 */
142 resp.data = cc_normal;
143 resp.datalen = sizeof(cc_normal);
144 ipmb_send(&resp);
145 break;
146
147
148 default:
149 #ifdef DEBUG
150 printf("Unknown sensor cmd 0x%02x\n", req->cmd);
151 ipmb_dump_req(req);
152 #endif
153 ipmb_invalid(&resp);
154 break;
155 }
156 break;
157
158 case IPMB_NETFN_APP:
159 switch (req->cmd) {
160 case IPMB_APP_GET_DEVICE_ID:
161 resp.data = get_devid;
162 resp.datalen = sizeof(get_devid);
163 ipmb_send(&resp);
164 break;
165
166 case IPMB_APP_GET_WATCHDOG_TIMER:
167 resp.data = get_wd_timer;
168 resp.datalen = sizeof(get_wd_timer);
169 ipmb_send(&resp);
170 break;
171
172 default:
173 #ifdef DEBUG
174 printf("Unknown app cmd 0x%02x\n", req->cmd);
175 ipmb_dump_req(req);
176 #endif
177 ipmb_invalid(&resp);
178 break;
179 }
180 break;
181
182 case IPMB_NETFN_STORAGE:
183 switch (req->cmd) {
184 default:
185 #ifdef DEBUG
186 printf("Unknown storage cmd 0x%02x\n", req->cmd);
187 ipmb_dump_req(req);
188 #endif
189 ipmb_invalid(&resp);
190 break;
191 }
192 break;
193
194 default:
195 #ifdef DEBUG
196 printf("Unknown netFn 0x%02x\n", req->netFn);
197 ipmb_dump_req(req);
198 #endif
199 ipmb_invalid(&resp);
200 break;
201 }
202 }
203
204 void decode_ipmb_pkt(unsigned char *buf, int len)
205 {
206 struct ipmb_req req;
207
208 if ((buf[2] != ipmb_csum(buf, 2)) ||
209 (buf[len-1] != ipmb_csum(buf+3, len-4)))
210 return; /* Checksum wrong */
211
212 req.rsSA = buf[0];
213 req.netFn = (buf[1]>>2)&0x3f;
214 req.rsLUN = (buf[1] & 0x03);
215 req.rqSA = buf[3];
216 req.rqSEQ = (buf[4]>>2)&0x3f;
217 req.rqLUN = (buf[4] & 0x03);
218 req.cmd = buf[5];
219 req.data = buf+6;
220 req.datalen = len - 6 - 1;
221
222 ipmb_cmd(&req);
223 }
Impressum, Datenschutz