/[dynamips]/upstream/dynamips-0.2.6-RC2/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-RC2/cisco_eeprom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Sat Oct 6 16:05:34 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 12576 byte(s)
dynamips-0.2.6-RC2

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[16] = {
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[16] = {
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[16] = {
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[64] = {
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[16] = {
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[16] = {
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[16] = {
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[64] = {
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[64] = {
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[64] = {
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[64] = {
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[64] = {
145 0x013D, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
146 0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
147 };
148
149 /* ====================================================================== */
150 /* PA EEPROMs */
151 /* ====================================================================== */
152
153 static const struct cisco_eeprom eeprom_pa_array[] = {
154 { "PA-FE-TX", (m_uint16_t *)eeprom_pa_fe_tx_data,
155 sizeof(eeprom_pa_fe_tx_data)/2 },
156 { "PA-4E", (m_uint16_t *)eeprom_pa_4e_data, sizeof(eeprom_pa_4e_data)/2 },
157 { "PA-8E", (m_uint16_t *)eeprom_pa_8e_data, sizeof(eeprom_pa_8e_data)/2 },
158 { "PA-4T+", eeprom_pa_4t_data, sizeof(eeprom_pa_4t_data)/2 },
159 { "PA-8T", eeprom_pa_8t_data, sizeof(eeprom_pa_8t_data)/2 },
160 { "PA-A1", (m_uint16_t *)eeprom_pa_a1_data, sizeof(eeprom_pa_a1_data)/2 },
161 { "PA-POS-OC3", (m_uint16_t *)eeprom_pa_pos_oc3_data,
162 sizeof(eeprom_pa_pos_oc3_data)/2 },
163 { "PA-4B", (m_uint16_t *)eeprom_pa_4b_data, sizeof(eeprom_pa_4b_data)/2 },
164 { NULL, NULL, 0 },
165 };
166
167 /* Find a PA EEPROM */
168 const struct cisco_eeprom *cisco_eeprom_find_pa(char *name)
169 {
170 return(cisco_eeprom_find(eeprom_pa_array,name));
171 }
172
173 /* ====================================================================== */
174 /* Utility functions */
175 /* ====================================================================== */
176
177 /* Find an EEPROM in the specified EEPROM array */
178 const struct cisco_eeprom *
179 cisco_eeprom_find(const struct cisco_eeprom *eeproms,char *name)
180 {
181 int i;
182
183 for(i=0;eeproms[i].name;i++)
184 if (!strcmp(eeproms[i].name,name))
185 return(&eeproms[i]);
186
187 return NULL;
188 }
189
190 /* Copy an EEPROM */
191 int cisco_eeprom_copy(struct cisco_eeprom *dst,const struct cisco_eeprom *src)
192 {
193 m_uint16_t *data;
194
195 if (!src || !src)
196 return(-1);
197
198 cisco_eeprom_free(dst);
199
200 if (!(data = malloc(src->len << 1)))
201 return(-1);
202
203 memcpy(data,src->data,src->len << 1);
204 dst->name = src->name;
205 dst->data = data;
206 dst->len = src->len;
207 return(0);
208 }
209
210 /* Free resources used by an EEPROM */
211 void cisco_eeprom_free(struct cisco_eeprom *eeprom)
212 {
213 if (eeprom && eeprom->data) {
214 free(eeprom->data);
215 eeprom->data = NULL;
216 eeprom->len = 0;
217 }
218 }
219
220 /* Return TRUE if the specified EEPROM contains usable data */
221 int cisco_eeprom_valid(struct cisco_eeprom *eeprom)
222 {
223 return((eeprom && eeprom->data) ? TRUE : FALSE);
224 }
225
226 /* Get a byte from an EEPROM */
227 int cisco_eeprom_get_byte(struct cisco_eeprom *eeprom,
228 size_t offset,m_uint8_t *val)
229 {
230 m_uint16_t tmp;
231
232 if (offset >= (eeprom->len << 1))
233 return(-1);
234
235 tmp = eeprom->data[offset >> 1];
236
237 if (!(offset & 1))
238 tmp >>= 8;
239
240 *val = tmp & 0xFF;
241 return(0);
242 }
243
244 /* Set a byte to an EEPROM */
245 int cisco_eeprom_set_byte(struct cisco_eeprom *eeprom,
246 size_t offset,m_uint8_t val)
247 {
248 m_uint16_t tmp;
249
250 if (offset >= (eeprom->len << 1))
251 return(-1);
252
253 tmp = eeprom->data[offset >> 1];
254
255 if (offset & 1)
256 tmp = (tmp & 0xFF00) | val;
257 else
258 tmp = (tmp & 0x00FF) | (val << 8);
259
260 eeprom->data[offset >> 1] = tmp;
261 return(0);
262 }
263
264 /* Get an EEPROM region */
265 int cisco_eeprom_get_region(struct cisco_eeprom *eeprom,size_t offset,
266 m_uint8_t *data,size_t data_len)
267 {
268 size_t i;
269
270 for(i=0;i<data_len;i++) {
271 if (cisco_eeprom_get_byte(eeprom,offset+i,&data[i]) == -1)
272 return(-1);
273 }
274
275 return(0);
276 }
277
278 /* Set an EEPROM region */
279 int cisco_eeprom_set_region(struct cisco_eeprom *eeprom,size_t offset,
280 m_uint8_t *data,size_t data_len)
281 {
282 size_t i;
283
284 for(i=0;i<data_len;i++) {
285 if (cisco_eeprom_set_byte(eeprom,offset+i,data[i]) == -1)
286 return(-1);
287 }
288
289 return(0);
290 }
291
292 /* Get a field of a Cisco EEPROM v4 */
293 int cisco_eeprom_v4_get_field(struct cisco_eeprom *eeprom,m_uint8_t *type,
294 m_uint8_t *len,size_t *offset)
295 {
296 m_uint8_t tmp;
297
298 /* Read field type */
299 if (cisco_eeprom_get_byte(eeprom,(*offset)++,type) == -1)
300 return(-1);
301
302 /* No more field */
303 if (*type == 0xFF)
304 return(0);
305
306 /* Get field length */
307 tmp = (*type >> 6) & 0x03;
308
309 if (tmp == 0x03) {
310 /* Variable len */
311 if (cisco_eeprom_get_byte(eeprom,(*offset)++,&tmp) == -1)
312 return(-1);
313
314 *len = tmp & 0x0F;
315 } else {
316 /* Fixed len */
317 *len = 1 << tmp;
318 }
319
320 return(1);
321 }
322
323 /* Dump a Cisco EEPROM with format version 4 */
324 void cisco_eeprom_v4_dump(struct cisco_eeprom *eeprom)
325 {
326 m_uint8_t type,len,tmp;
327 size_t i,offset=2;
328
329 printf("Dumping EEPROM contents:\n");
330
331 do {
332 /* Read field */
333 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
334 break;
335
336 printf(" Field 0x%2.2x: ",type);
337
338 for(i=0;i<len;i++) {
339 if (cisco_eeprom_get_byte(eeprom,offset+i,&tmp) == -1)
340 break;
341
342 printf("%2.2x ",tmp);
343 }
344
345 printf("\n");
346
347 offset += len;
348 }while(offset < (eeprom->len << 1));
349 }
350
351 /* Returns the offset of the specified field */
352 int cisco_eeprom_v4_find_field(struct cisco_eeprom *eeprom,
353 m_uint8_t field_type,
354 size_t *field_offset)
355 {
356 m_uint8_t type,len;
357 size_t offset=2;
358
359 do {
360 /* Read field */
361 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
362 break;
363
364 if (type == field_type) {
365 *field_offset = offset;
366 return(0);
367 }
368
369 offset += len;
370 }while(offset < (eeprom->len << 1));
371
372 return(-1);
373 }

  ViewVC Help
Powered by ViewVC 1.1.26