/[dynamips]/upstream/dynamips-0.2.6-RC5/cisco_eeprom.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.6-RC5/cisco_eeprom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations)
Sat Oct 6 16:08:03 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC4/cisco_eeprom.c
File MIME type: text/plain
File size: 13472 byte(s)
dynamips-0.2.6-RC4

1 /*
2 * Cisco C7200 (Predator) simulation platform.
3 * Copyright (c) 2006 Christophe Fillot. All rights reserved.
4 *
5 * Cisco EEPROM manipulation functions.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <sys/types.h>
13 #include <sys/socket.h>
14
15 #include "utils.h"
16 #include "cisco_eeprom.h"
17
18 /* ====================================================================== */
19 /* NM-1E: 1 Ethernet Port Network Module EEPROM */
20 /* ====================================================================== */
21 static const m_uint16_t eeprom_nm_1e_data[] = {
22 0x0143, 0x0100, 0x0075, 0xCD81, 0x500D, 0xA201, 0x0000, 0x0000,
23 0x5800, 0x0000, 0x9803, 0x2000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
24 };
25
26 /* ====================================================================== */
27 /* NM-4E: 4 Ethernet Port Network Module EEPROM */
28 /* ====================================================================== */
29 static const m_uint16_t eeprom_nm_4e_data[] = {
30 0x0142, 0x0100, 0x0075, 0xCD81, 0x500D, 0xA201, 0x0000, 0x0000,
31 0x5800, 0x0000, 0x9803, 0x2000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
32 };
33
34 /* ====================================================================== */
35 /* NM-1FE-TX: 1 FastEthernet Port Network Module EEPROM */
36 /* ====================================================================== */
37 static const m_uint16_t eeprom_nm_1fe_tx_data[] = {
38 0x0144, 0x0100, 0x0075, 0xCD81, 0x500D, 0xA201, 0x0000, 0x0000,
39 0x5800, 0x0000, 0x9803, 0x2000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
40 };
41
42 /* ====================================================================== */
43 /* NM-16ESW: 16 FastEthernet Port Switch Network Module EEPROM */
44 /* ====================================================================== */
45 static m_uint16_t eeprom_nm_16esw_data[] = {
46 0x04FF, 0x4002, 0xA941, 0x0100, 0xC046, 0x0320, 0x003B, 0x3401,
47 0x4245, 0x3080, 0x0000, 0x0000, 0x0203, 0xC18B, 0x3030, 0x3030,
48 0x3030, 0x3030, 0x3030, 0x3003, 0x0081, 0x0000, 0x0000, 0x0400,
49 0xCF06, 0x0013, 0x1A1D, 0x0BD1, 0x4300, 0x11FF, 0xFFFF, 0xFFFF,
50 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
51 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
52 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
53 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
54 };
55
56 /* ====================================================================== */
57 /* NM-4T: 4 Serial Network Module EEPROM */
58 /* ====================================================================== */
59 static m_uint16_t eeprom_nm_4t_data[] = {
60 0x0154, 0x0101, 0x009D, 0x2D64, 0x5009, 0x0A02, 0x0000, 0x0000,
61 0x5800, 0x0000, 0x9811, 0x0300, 0x0005, 0xFFFF, 0xFFFF, 0xFFFF,
62 };
63
64 /* ====================================================================== */
65 /* NM EEPROMs */
66 /* ====================================================================== */
67
68 static const struct cisco_eeprom eeprom_nm_array[] = {
69 { "NM-1E", (m_uint16_t *)eeprom_nm_1e_data, sizeof(eeprom_nm_1e_data)/2 },
70 { "NM-4E", (m_uint16_t *)eeprom_nm_4e_data, sizeof(eeprom_nm_4e_data)/2 },
71 { "NM-1FE-TX", (m_uint16_t *)eeprom_nm_1fe_tx_data,
72 sizeof(eeprom_nm_1fe_tx_data)/2 },
73 { "NM-16ESW", (m_uint16_t *)eeprom_nm_16esw_data,
74 sizeof(eeprom_nm_16esw_data)/2 },
75 { "NM-4T", eeprom_nm_4t_data, sizeof(eeprom_nm_4t_data)/2 },
76 { NULL, NULL, 0 },
77 };
78
79 /* Find a NM EEPROM */
80 const struct cisco_eeprom *cisco_eeprom_find_nm(char *name)
81 {
82 return(cisco_eeprom_find(eeprom_nm_array,name));
83 }
84
85 /* ====================================================================== */
86 /* PA-FE-TX: 1 FastEthernet Port Adapter EEPROM */
87 /* ====================================================================== */
88 static const m_uint16_t eeprom_pa_fe_tx_data[] = {
89 0x0111, 0x0102, 0xffff, 0xffff, 0x4906, 0x9804, 0x0000, 0x0000,
90 0x6000, 0x0000, 0x9812, 0x1700, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
91 };
92
93 /* ====================================================================== */
94 /* PA-4E: 4 Ethernet Port Adapter EEPROM */
95 /* ====================================================================== */
96 static const m_uint16_t eeprom_pa_4e_data[] = {
97 0x0102, 0x010E, 0xFFFF, 0xFFFF, 0x4906, 0x1404, 0x0000, 0x0000,
98 0x5000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
99 };
100
101 /* ====================================================================== */
102 /* PA-8E: 8 Ethernet Port Adapter EEPROM */
103 /* ====================================================================== */
104 static const m_uint16_t eeprom_pa_8e_data[] = {
105 0x0101, 0x010E, 0xFFFF, 0xFFFF, 0x4906, 0x1404, 0x0000, 0x0000,
106 0x5000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
107 };
108
109 /* ====================================================================== */
110 /* PA-4T+: 4 Serial Port Adapter EEPROM */
111 /* ====================================================================== */
112 static m_uint16_t eeprom_pa_4t_data[] = {
113 0x010C, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
114 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
115 };
116
117 /* ====================================================================== */
118 /* PA-8T: 8 Serial Port Adapter EEPROM */
119 /* ====================================================================== */
120 static m_uint16_t eeprom_pa_8t_data[] = {
121 0x010E, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
122 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
123 };
124
125 /* ====================================================================== */
126 /* PA-A1: 1 ATM Port Adapter EEPROM */
127 /* ====================================================================== */
128 static const m_uint16_t eeprom_pa_a1_data[] = {
129 0x0117, 0x010F, 0xffff, 0xffff, 0x4906, 0x2E07, 0x0000, 0x0000,
130 0x5000, 0x0000, 0x0010, 0x2400, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
131 };
132
133 /* ====================================================================== */
134 /* PA-POS-OC3: 1 POS Port Adapter EEPROM */
135 /* ====================================================================== */
136 static const m_uint16_t eeprom_pa_pos_oc3_data[] = {
137 0x0196, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
138 0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
139 };
140
141 /* ====================================================================== */
142 /* PA-4B: 4 BRI Port Adapter EEPROM */
143 /* ====================================================================== */
144 static const m_uint16_t eeprom_pa_4b_data[] = {
145 0x013D, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
146 0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
147 };
148
149 /* ====================================================================== */
150 /* PA-MC-8TE1 */
151 /* ====================================================================== */
152 static const m_uint16_t eeprom_pa_mc8te1_data[] = {
153 0x04FF, 0x4003, 0x4E41, 0x0200, 0xC18B, 0x4A41, 0x4530, 0x3834,
154 0x3159, 0x3251, 0x3082, 0x491D, 0x7D02, 0x4241, 0x3003, 0x0081,
155 0x0000, 0x0000, 0x0400, 0x8000, 0x0127, 0x9BCB, 0x9450, 0x412D,
156 0x4D43, 0x2D38, 0x5445, 0x312B, 0x2020, 0x2020, 0x2020, 0x2020,
157 0x20C0, 0x4603, 0x2000, 0x4BBB, 0x02FF, 0xFFFF, 0xFFFF, 0xFFFF,
158 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
159 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
160 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
161 };
162
163 /* ====================================================================== */
164 /* PA EEPROMs */
165 /* ====================================================================== */
166
167 static const struct cisco_eeprom eeprom_pa_array[] = {
168 { "PA-FE-TX", (m_uint16_t *)eeprom_pa_fe_tx_data,
169 sizeof(eeprom_pa_fe_tx_data)/2 },
170 { "PA-4E", (m_uint16_t *)eeprom_pa_4e_data, sizeof(eeprom_pa_4e_data)/2 },
171 { "PA-8E", (m_uint16_t *)eeprom_pa_8e_data, sizeof(eeprom_pa_8e_data)/2 },
172 { "PA-4T+", eeprom_pa_4t_data, sizeof(eeprom_pa_4t_data)/2 },
173 { "PA-8T", eeprom_pa_8t_data, sizeof(eeprom_pa_8t_data)/2 },
174 { "PA-A1", (m_uint16_t *)eeprom_pa_a1_data, sizeof(eeprom_pa_a1_data)/2 },
175 { "PA-POS-OC3", (m_uint16_t *)eeprom_pa_pos_oc3_data,
176 sizeof(eeprom_pa_pos_oc3_data)/2 },
177 { "PA-4B", (m_uint16_t *)eeprom_pa_4b_data, sizeof(eeprom_pa_4b_data)/2 },
178 { "PA-MC-8TE1", (m_uint16_t *)eeprom_pa_mc8te1_data,
179 sizeof(eeprom_pa_mc8te1_data)/2 },
180 { NULL, NULL, 0 },
181 };
182
183 /* Find a PA EEPROM */
184 const struct cisco_eeprom *cisco_eeprom_find_pa(char *name)
185 {
186 return(cisco_eeprom_find(eeprom_pa_array,name));
187 }
188
189 /* ====================================================================== */
190 /* Utility functions */
191 /* ====================================================================== */
192
193 /* Find an EEPROM in the specified EEPROM array */
194 const struct cisco_eeprom *
195 cisco_eeprom_find(const struct cisco_eeprom *eeproms,char *name)
196 {
197 int i;
198
199 for(i=0;eeproms[i].name;i++)
200 if (!strcmp(eeproms[i].name,name))
201 return(&eeproms[i]);
202
203 return NULL;
204 }
205
206 /* Copy an EEPROM */
207 int cisco_eeprom_copy(struct cisco_eeprom *dst,const struct cisco_eeprom *src)
208 {
209 m_uint16_t *data;
210
211 if (!src || !src)
212 return(-1);
213
214 cisco_eeprom_free(dst);
215
216 if (!(data = malloc(src->len << 1)))
217 return(-1);
218
219 memcpy(data,src->data,src->len << 1);
220 dst->name = src->name;
221 dst->data = data;
222 dst->len = src->len;
223 return(0);
224 }
225
226 /* Free resources used by an EEPROM */
227 void cisco_eeprom_free(struct cisco_eeprom *eeprom)
228 {
229 if (eeprom && eeprom->data) {
230 free(eeprom->data);
231 eeprom->data = NULL;
232 eeprom->len = 0;
233 }
234 }
235
236 /* Return TRUE if the specified EEPROM contains usable data */
237 int cisco_eeprom_valid(struct cisco_eeprom *eeprom)
238 {
239 return((eeprom && eeprom->data) ? TRUE : FALSE);
240 }
241
242 /* Get a byte from an EEPROM */
243 int cisco_eeprom_get_byte(struct cisco_eeprom *eeprom,
244 size_t offset,m_uint8_t *val)
245 {
246 m_uint16_t tmp;
247
248 if (offset >= (eeprom->len << 1))
249 return(-1);
250
251 tmp = eeprom->data[offset >> 1];
252
253 if (!(offset & 1))
254 tmp >>= 8;
255
256 *val = tmp & 0xFF;
257 return(0);
258 }
259
260 /* Set a byte to an EEPROM */
261 int cisco_eeprom_set_byte(struct cisco_eeprom *eeprom,
262 size_t offset,m_uint8_t val)
263 {
264 m_uint16_t tmp;
265
266 if (offset >= (eeprom->len << 1))
267 return(-1);
268
269 tmp = eeprom->data[offset >> 1];
270
271 if (offset & 1)
272 tmp = (tmp & 0xFF00) | val;
273 else
274 tmp = (tmp & 0x00FF) | (val << 8);
275
276 eeprom->data[offset >> 1] = tmp;
277 return(0);
278 }
279
280 /* Get an EEPROM region */
281 int cisco_eeprom_get_region(struct cisco_eeprom *eeprom,size_t offset,
282 m_uint8_t *data,size_t data_len)
283 {
284 size_t i;
285
286 for(i=0;i<data_len;i++) {
287 if (cisco_eeprom_get_byte(eeprom,offset+i,&data[i]) == -1)
288 return(-1);
289 }
290
291 return(0);
292 }
293
294 /* Set an EEPROM region */
295 int cisco_eeprom_set_region(struct cisco_eeprom *eeprom,size_t offset,
296 m_uint8_t *data,size_t data_len)
297 {
298 size_t i;
299
300 for(i=0;i<data_len;i++) {
301 if (cisco_eeprom_set_byte(eeprom,offset+i,data[i]) == -1)
302 return(-1);
303 }
304
305 return(0);
306 }
307
308 /* Get a field of a Cisco EEPROM v4 */
309 int cisco_eeprom_v4_get_field(struct cisco_eeprom *eeprom,m_uint8_t *type,
310 m_uint8_t *len,size_t *offset)
311 {
312 m_uint8_t tmp;
313
314 /* Read field type */
315 if (cisco_eeprom_get_byte(eeprom,(*offset)++,type) == -1)
316 return(-1);
317
318 /* No more field */
319 if (*type == 0xFF)
320 return(0);
321
322 /* Get field length */
323 tmp = (*type >> 6) & 0x03;
324
325 if (tmp == 0x03) {
326 /* Variable len */
327 if (cisco_eeprom_get_byte(eeprom,(*offset)++,&tmp) == -1)
328 return(-1);
329
330 *len = tmp & 0x0F;
331 } else {
332 /* Fixed len */
333 *len = 1 << tmp;
334 }
335
336 return(1);
337 }
338
339 /* Dump a Cisco EEPROM with format version 4 */
340 void cisco_eeprom_v4_dump(struct cisco_eeprom *eeprom)
341 {
342 m_uint8_t type,len,tmp;
343 size_t i,offset=2;
344
345 printf("Dumping EEPROM contents:\n");
346
347 do {
348 /* Read field */
349 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
350 break;
351
352 printf(" Field 0x%2.2x: ",type);
353
354 for(i=0;i<len;i++) {
355 if (cisco_eeprom_get_byte(eeprom,offset+i,&tmp) == -1)
356 break;
357
358 printf("%2.2x ",tmp);
359 }
360
361 printf("\n");
362
363 offset += len;
364 }while(offset < (eeprom->len << 1));
365 }
366
367 /* Returns the offset of the specified field */
368 int cisco_eeprom_v4_find_field(struct cisco_eeprom *eeprom,
369 m_uint8_t field_type,
370 size_t *field_offset)
371 {
372 m_uint8_t type,len;
373 size_t offset=2;
374
375 do {
376 /* Read field */
377 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
378 break;
379
380 if (type == field_type) {
381 *field_offset = offset;
382 return(0);
383 }
384
385 offset += len;
386 }while(offset < (eeprom->len << 1));
387
388 return(-1);
389 }

  ViewVC Help
Powered by ViewVC 1.1.26