/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide 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 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     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 dpavlin 1 /* Get a byte from an EEPROM */
227 dpavlin 3 int cisco_eeprom_get_byte(struct cisco_eeprom *eeprom,
228 dpavlin 1 size_t offset,m_uint8_t *val)
229     {
230     m_uint16_t tmp;
231 dpavlin 3
232     if (offset >= (eeprom->len << 1))
233 dpavlin 1 return(-1);
234    
235 dpavlin 3 tmp = eeprom->data[offset >> 1];
236 dpavlin 1
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 dpavlin 3 int cisco_eeprom_set_byte(struct cisco_eeprom *eeprom,
246 dpavlin 1 size_t offset,m_uint8_t val)
247     {
248     m_uint16_t tmp;
249    
250 dpavlin 3 if (offset >= (eeprom->len << 1))
251 dpavlin 1 return(-1);
252    
253 dpavlin 3 tmp = eeprom->data[offset >> 1];
254 dpavlin 1
255     if (offset & 1)
256     tmp = (tmp & 0xFF00) | val;
257     else
258     tmp = (tmp & 0x00FF) | (val << 8);
259    
260 dpavlin 3 eeprom->data[offset >> 1] = tmp;
261 dpavlin 1 return(0);
262     }
263    
264     /* Get an EEPROM region */
265 dpavlin 3 int cisco_eeprom_get_region(struct cisco_eeprom *eeprom,size_t offset,
266     m_uint8_t *data,size_t data_len)
267 dpavlin 1 {
268     size_t i;
269    
270     for(i=0;i<data_len;i++) {
271 dpavlin 3 if (cisco_eeprom_get_byte(eeprom,offset+i,&data[i]) == -1)
272 dpavlin 1 return(-1);
273     }
274    
275     return(0);
276     }
277    
278     /* Set an EEPROM region */
279 dpavlin 3 int cisco_eeprom_set_region(struct cisco_eeprom *eeprom,size_t offset,
280     m_uint8_t *data,size_t data_len)
281 dpavlin 1 {
282     size_t i;
283    
284     for(i=0;i<data_len;i++) {
285 dpavlin 3 if (cisco_eeprom_set_byte(eeprom,offset+i,data[i]) == -1)
286 dpavlin 1 return(-1);
287     }
288    
289     return(0);
290     }
291    
292     /* Get a field of a Cisco EEPROM v4 */
293 dpavlin 3 int cisco_eeprom_v4_get_field(struct cisco_eeprom *eeprom,m_uint8_t *type,
294     m_uint8_t *len,size_t *offset)
295 dpavlin 1 {
296     m_uint8_t tmp;
297    
298     /* Read field type */
299 dpavlin 3 if (cisco_eeprom_get_byte(eeprom,(*offset)++,type) == -1)
300 dpavlin 1 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 dpavlin 3 if (cisco_eeprom_get_byte(eeprom,(*offset)++,&tmp) == -1)
312 dpavlin 1 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 dpavlin 3 void cisco_eeprom_v4_dump(struct cisco_eeprom *eeprom)
325 dpavlin 1 {
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 dpavlin 3 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
334 dpavlin 1 break;
335    
336     printf(" Field 0x%2.2x: ",type);
337    
338     for(i=0;i<len;i++) {
339 dpavlin 3 if (cisco_eeprom_get_byte(eeprom,offset+i,&tmp) == -1)
340 dpavlin 1 break;
341    
342     printf("%2.2x ",tmp);
343     }
344    
345     printf("\n");
346    
347     offset += len;
348 dpavlin 3 }while(offset < (eeprom->len << 1));
349 dpavlin 1 }
350    
351     /* Returns the offset of the specified field */
352 dpavlin 3 int cisco_eeprom_v4_find_field(struct cisco_eeprom *eeprom,
353     m_uint8_t field_type,
354     size_t *field_offset)
355 dpavlin 1 {
356     m_uint8_t type,len;
357     size_t offset=2;
358    
359     do {
360     /* Read field */
361 dpavlin 3 if (cisco_eeprom_v4_get_field(eeprom,&type,&len,&offset) < 1)
362 dpavlin 1 break;
363    
364     if (type == field_type) {
365     *field_offset = offset;
366     return(0);
367     }
368    
369     offset += len;
370 dpavlin 3 }while(offset < (eeprom->len << 1));
371 dpavlin 1
372     return(-1);
373     }

  ViewVC Help
Powered by ViewVC 1.1.26