/[dynamips]/upstream/dynamips-0.2.6-RC3/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

Annotation of /upstream/dynamips-0.2.6-RC3/cisco_eeprom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations)
Sat Oct 6 16:06:49 2007 UTC (12 years, 2 months ago) by dpavlin
File MIME type: text/plain
File size: 13472 byte(s)
dynamips-0.2.6-RC3

1 dpavlin 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 dpavlin 3 /* ====================================================================== */
19     /* NM-1E: 1 Ethernet Port Network Module EEPROM */
20     /* ====================================================================== */
21 dpavlin 4 static const m_uint16_t eeprom_nm_1e_data[] = {
22 dpavlin 3 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 dpavlin 4 static const m_uint16_t eeprom_nm_4e_data[] = {
30 dpavlin 3 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 dpavlin 4 static const m_uint16_t eeprom_nm_1fe_tx_data[] = {
38 dpavlin 3 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 dpavlin 4 static m_uint16_t eeprom_nm_4t_data[] = {
60 dpavlin 3 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 dpavlin 4 static const m_uint16_t eeprom_pa_fe_tx_data[] = {
89 dpavlin 3 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 dpavlin 4 static const m_uint16_t eeprom_pa_4e_data[] = {
97 dpavlin 3 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 dpavlin 4 static const m_uint16_t eeprom_pa_8e_data[] = {
105 dpavlin 3 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 dpavlin 4 static m_uint16_t eeprom_pa_4t_data[] = {
113 dpavlin 3 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 dpavlin 4 static m_uint16_t eeprom_pa_8t_data[] = {
121 dpavlin 3 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 dpavlin 4 static const m_uint16_t eeprom_pa_a1_data[] = {
129 dpavlin 3 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 dpavlin 4 static const m_uint16_t eeprom_pa_pos_oc3_data[] = {
137 dpavlin 3 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 dpavlin 4 static const m_uint16_t eeprom_pa_4b_data[] = {
145 dpavlin 3 0x013D, 0x0202, 0xffff, 0xffff, 0x490C, 0x7806, 0x0000, 0x0000,
146     0x5000, 0x0000, 0x0208, 0x1900, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,
147     };
148    
149     /* ====================================================================== */
150 dpavlin 4 /* 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 dpavlin 3 /* 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 dpavlin 4 { "PA-MC-8TE1", (m_uint16_t *)eeprom_pa_mc8te1_data,
179     sizeof(eeprom_pa_mc8te1_data)/2 },
180 dpavlin 3 { 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 dpavlin 1 /* Get a byte from an EEPROM */
243 dpavlin 3 int cisco_eeprom_get_byte(struct cisco_eeprom *eeprom,
244 dpavlin 1 size_t offset,m_uint8_t *val)
245     {
246     m_uint16_t tmp;
247 dpavlin 3
248     if (offset >= (eeprom->len << 1))
249 dpavlin 1 return(-1);
250    
251 dpavlin 3 tmp = eeprom->data[offset >> 1];
252 dpavlin 1
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 dpavlin 3 int cisco_eeprom_set_byte(struct cisco_eeprom *eeprom,
262 dpavlin 1 size_t offset,m_uint8_t val)
263     {
264     m_uint16_t tmp;
265    
266 dpavlin 3 if (offset >= (eeprom->len << 1))
267 dpavlin 1 return(-1);
268    
269 dpavlin 3 tmp = eeprom->data[offset >> 1];
270 dpavlin 1
271     if (offset & 1)
272     tmp = (tmp & 0xFF00) | val;
273     else
274     tmp = (tmp & 0x00FF) | (val << 8);
275    
276 dpavlin 3 eeprom->data[offset >> 1] = tmp;
277 dpavlin 1 return(0);
278     }
279    
280     /* Get an EEPROM region */
281 dpavlin 3 int cisco_eeprom_get_region(struct cisco_eeprom *eeprom,size_t offset,
282     m_uint8_t *data,size_t data_len)
283 dpavlin 1 {
284     size_t i;
285    
286     for(i=0;i<data_len;i++) {
287 dpavlin 3 if (cisco_eeprom_get_byte(eeprom,offset+i,&data[i]) == -1)
288 dpavlin 1 return(-1);
289     }
290    
291     return(0);
292     }
293    
294     /* Set an EEPROM region */
295 dpavlin 3 int cisco_eeprom_set_region(struct cisco_eeprom *eeprom,size_t offset,
296     m_uint8_t *data,size_t data_len)
297 dpavlin 1 {
298     size_t i;
299    
300     for(i=0;i<data_len;i++) {
301 dpavlin 3 if (cisco_eeprom_set_byte(eeprom,offset+i,data[i]) == -1)
302 dpavlin 1 return(-1);
303     }
304    
305     return(0);
306     }
307    
308     /* Get a field of a Cisco EEPROM v4 */
309 dpavlin 3 int cisco_eeprom_v4_get_field(struct cisco_eeprom *eeprom,m_uint8_t *type,
310     m_uint8_t *len,size_t *offset)
311 dpavlin 1 {
312     m_uint8_t tmp;
313    
314     /* Read field type */
315 dpavlin 3 if (cisco_eeprom_get_byte(eeprom,(*offset)++,type) == -1)
316 dpavlin 1 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 dpavlin 3 if (cisco_eeprom_get_byte(eeprom,(*offset)++,&tmp) == -1)
328 dpavlin 1 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 dpavlin 3 void cisco_eeprom_v4_dump(struct cisco_eeprom *eeprom)
341 dpavlin 1 {
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 dpavlin 3 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
350 dpavlin 1 break;
351    
352     printf(" Field 0x%2.2x: ",type);
353    
354     for(i=0;i<len;i++) {
355 dpavlin 3 if (cisco_eeprom_get_byte(eeprom,offset+i,&tmp) == -1)
356 dpavlin 1 break;
357    
358     printf("%2.2x ",tmp);
359     }
360    
361     printf("\n");
362    
363     offset += len;
364 dpavlin 3 }while(offset < (eeprom->len << 1));
365 dpavlin 1 }
366    
367     /* Returns the offset of the specified field */
368 dpavlin 3 int cisco_eeprom_v4_find_field(struct cisco_eeprom *eeprom,
369     m_uint8_t field_type,
370     size_t *field_offset)
371 dpavlin 1 {
372     m_uint8_t type,len;
373     size_t offset=2;
374    
375     do {
376     /* Read field */
377 dpavlin 3 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
378 dpavlin 1 break;
379    
380     if (type == field_type) {
381     *field_offset = offset;
382     return(0);
383     }
384    
385     offset += len;
386 dpavlin 3 }while(offset < (eeprom->len << 1));
387 dpavlin 1
388     return(-1);
389     }

  ViewVC Help
Powered by ViewVC 1.1.26