/[dynamips]/trunk/cisco_card.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 /trunk/cisco_card.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 25302 byte(s)
make working copy

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2007 Christophe Fillot (cf@utc.fr)
4 *
5 * Generic Cisco card routines and definitions.
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 <assert.h>
14
15 #include "cpu.h"
16 #include "vm.h"
17 #include "dynamips.h"
18 #include "memory.h"
19 #include "device.h"
20 #include "cisco_card.h"
21
22 /* Get cisco card type description */
23 char *cisco_card_get_type_desc(int dev_type)
24 {
25 switch(dev_type) {
26 case CISCO_CARD_TYPE_PA:
27 return("Port Adapter (PA)");
28 case CISCO_CARD_TYPE_NM:
29 return("Network Module (NM)");
30 case CISCO_CARD_TYPE_WIC:
31 return("WAN Interface Card (WIC)");
32 default:
33 return("Unknown");
34 }
35 }
36
37 /* Set EEPROM definition for the specified Cisco card */
38 int cisco_card_set_eeprom(vm_instance_t *vm,struct cisco_card *card,
39 const struct cisco_eeprom *eeprom)
40 {
41 if (!eeprom)
42 return(0);
43
44 if (cisco_eeprom_copy(&card->eeprom,eeprom) == -1) {
45 vm_error(vm,"cisco_card_set_eeprom: no memory (eeprom=%p).\n",eeprom);
46 return(-1);
47 }
48
49 return(0);
50 }
51
52 /* Unset EEPROM definition */
53 int cisco_card_unset_eeprom(struct cisco_card *card)
54 {
55 cisco_eeprom_free(&card->eeprom);
56 return(0);
57 }
58
59 /* Check if a card has a valid EEPROM defined */
60 int cisco_card_check_eeprom(struct cisco_card *card)
61 {
62 return(cisco_eeprom_valid(&card->eeprom));
63 }
64
65 /* Create a card structure */
66 static inline struct cisco_card *cisco_card_create(u_int card_type)
67 {
68 struct cisco_card *card;
69
70 if ((card = malloc(sizeof(*card))) != NULL) {
71 memset(card,0,sizeof(*card));
72 card->card_type = card_type;
73 }
74
75 return card;
76 }
77
78 /* Find a NIO binding */
79 static struct cisco_nio_binding *
80 cisco_card_find_nio_binding(struct cisco_card *card,u_int port_id)
81 {
82 struct cisco_nio_binding *nb;
83
84 if (!card)
85 return NULL;
86
87 for(nb=card->nio_list;nb;nb=nb->next)
88 if (nb->port_id == port_id)
89 return nb;
90
91 return NULL;
92 }
93
94 /* Remove all NIO bindings */
95 static void
96 cisco_card_remove_all_nio_bindings(vm_instance_t *vm,struct cisco_card *card)
97 {
98 struct cisco_nio_binding *nb,*next;
99
100 for(nb=card->nio_list;nb;nb=next) {
101 next = nb->next;
102
103 /* tell the slot driver to stop using this NIO */
104 if (card->driver)
105 card->driver->card_unset_nio(vm,card,nb->port_id);
106
107 /* unreference NIO object */
108 netio_release(nb->nio->name);
109 free(nb);
110 }
111
112 card->nio_list = NULL;
113 }
114
115 /* Enable all NIO for the specified card */
116 static inline
117 void cisco_card_enable_all_nio(vm_instance_t *vm,struct cisco_card *card)
118 {
119 struct cisco_nio_binding *nb;
120
121 if (card && card->driver && card->drv_info)
122 for(nb=card->nio_list;nb;nb=nb->next)
123 card->driver->card_set_nio(vm,card,nb->port_id,nb->nio);
124 }
125
126 /* Disable all NIO for the specified card */
127 static inline
128 void cisco_card_disable_all_nio(vm_instance_t *vm,struct cisco_card *card)
129 {
130 struct cisco_nio_binding *nb;
131
132 if (card && card->driver && card->drv_info)
133 for(nb=card->nio_list;nb;nb=nb->next)
134 card->driver->card_unset_nio(vm,card,nb->port_id);
135 }
136
137 /* Initialize a card */
138 static inline
139 int cisco_card_init(vm_instance_t *vm,struct cisco_card *card,u_int id)
140 {
141 size_t len;
142
143 /* Check that a device type is defined for this card */
144 if (!card || !card->dev_type || !card->driver)
145 return(-1);
146
147 /* Allocate device name */
148 len = strlen(card->dev_type) + 10;
149 if (!(card->dev_name = malloc(len))) {
150 vm_error(vm,"unable to allocate device name.\n");
151 return(-1);
152 }
153
154 snprintf(card->dev_name,len,"%s(%u)",card->dev_type,id);
155
156 /* Initialize card driver */
157 if (card->driver->card_init(vm,card) == -1) {
158 vm_error(vm,"unable to initialize card type '%s' (id %u)\n",
159 card->dev_type,id);
160 return(-1);
161 }
162
163 return(0);
164 }
165
166 /* Shutdown card */
167 static int cisco_card_shutdown(vm_instance_t *vm,struct cisco_card *card)
168 {
169 /* Check that a device type is defined for this card */
170 if (!card || !card->dev_type || !card->driver)
171 return(-1);
172
173 /* Shutdown the NM driver */
174 if (card->drv_info && (card->driver->card_shutdown(vm,card) == -1)) {
175 vm_error(vm,"unable to shutdown card type '%s' (slot %u/%u)\n",
176 card->dev_type,card->slot_id,card->subslot_id);
177 return(-1);
178 }
179
180 free(card->dev_name);
181 card->dev_name = NULL;
182 card->drv_info = NULL;
183 return(0);
184 }
185
186 /* Show info for the specified card */
187 static int cisco_card_show_info(vm_instance_t *vm,struct cisco_card *card)
188 {
189 /* Check that a device type is defined for this card */
190 if (!card || !card->driver || !card->driver->card_show_info)
191 return(-1);
192
193 card->driver->card_show_info(vm,card);
194 return(0);
195 }
196
197 /* Save config for the specified card */
198 static int cisco_card_save_config(vm_instance_t *vm,struct cisco_card *card,
199 FILE *fd)
200 {
201 struct cisco_nio_binding *nb;
202
203 fprintf(fd,"vm add_slot_binding %s %u %u %s\n",
204 vm->name,card->slot_id,card->subslot_id,card->dev_type);
205
206 for(nb=card->nio_list;nb;nb=nb->next) {
207 fprintf(fd,"vm add_nio_binding %s %u %u %s\n",
208 vm->name,card->slot_id,nb->orig_port_id,nb->nio->name);
209 }
210
211 return(0);
212 }
213
214 /* Find a driver in a driver array */
215 static struct cisco_card_driver *
216 cisco_card_find_driver(struct cisco_card_driver **array,char *dev_type)
217 {
218 int i;
219
220 for(i=0;array[i]!=NULL;i++)
221 if (!strcmp(array[i]->dev_type,dev_type))
222 return array[i];
223
224 return NULL;
225 }
226
227 /* ======================================================================== */
228 /* High level routines for managing VM slots. */
229 /* ======================================================================== */
230
231 /* Get slot info */
232 struct cisco_card *vm_slot_get_card_ptr(vm_instance_t *vm,u_int slot_id)
233 {
234 if (slot_id >= vm->nr_slots)
235 return NULL;
236
237 return(vm->slots[slot_id]);
238 }
239
240 /* Get info for a slot/port (with sub-cards) */
241 static int vm_slot_get_info(vm_instance_t *vm,u_int slot_id,u_int port_id,
242 struct cisco_card ***rc,u_int *real_port_id)
243 {
244 struct cisco_card *card;
245 u_int wic_id,card_type;
246
247 if (slot_id >= VM_MAX_SLOTS) {
248 *rc = NULL;
249 return(-1);
250 }
251
252 *rc = &vm->slots[slot_id];
253 card = vm->slots[slot_id];
254
255 card_type = (card != NULL) ? card->card_type : CISCO_CARD_TYPE_UNDEF;
256
257 switch(card_type) {
258 /*
259 * Handle WICs which are sub-slots for Network Modules (NM).
260 * Numbering: wic #0 => port_id = 0x10
261 * wic #1 => port_id = 0x20
262 */
263 case CISCO_CARD_TYPE_NM:
264 wic_id = port_id >> 4;
265
266 if (wic_id >= (CISCO_CARD_MAX_WIC+1)) {
267 vm_error(vm,"Invalid wic_id %u (slot %u)\n",wic_id,slot_id);
268 return(-1);
269 }
270
271 if (wic_id >= 0x01) {
272 /* wic card */
273 *rc = &card->sub_slots[wic_id - 1];
274 *real_port_id = port_id & 0x0F;
275 } else {
276 /* main card */
277 *real_port_id = port_id;
278 }
279 return(0);
280
281 /* No translation for Cisco 7200 Port Adapters and WICs */
282 case CISCO_CARD_TYPE_PA:
283 case CISCO_CARD_TYPE_WIC:
284 *real_port_id = port_id;
285 return(0);
286
287 /* Not initialized yet */
288 default:
289 *real_port_id = port_id;
290 return(0);
291 }
292 }
293
294 /* Translate a port ID (for sub-cards) */
295 static u_int
296 vm_slot_translate_port_id(vm_instance_t *vm,u_int slot_id,u_int port_id,
297 struct cisco_card **rc)
298 {
299 struct cisco_card **tmp;
300 u_int real_port_id = 0;
301
302 vm_slot_get_info(vm,slot_id,port_id,&tmp,&real_port_id);
303 *rc = *tmp;
304 return(real_port_id);
305 }
306
307 /* Check if a slot has an active card */
308 int vm_slot_active(vm_instance_t *vm,u_int slot_id,u_int port_id)
309 {
310 struct cisco_card **rc;
311 u_int real_port_id;
312
313 if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)
314 return(FALSE);
315
316 if ((*rc == NULL) || ((*rc)->dev_type == NULL))
317 return(FALSE);
318
319 return(TRUE);
320 }
321
322 /* Set a flag for a card */
323 int vm_slot_set_flag(vm_instance_t *vm,u_int slot_id,u_int port_id,u_int flag)
324 {
325 struct cisco_card **rc;
326 u_int real_port_id;
327
328 if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)
329 return(FALSE);
330
331 if (*rc == NULL)
332 return(FALSE);
333
334 (*rc)->card_flags |= flag;
335 return(TRUE);
336 }
337
338 /* Add a slot binding */
339 int vm_slot_add_binding(vm_instance_t *vm,char *dev_type,
340 u_int slot_id,u_int port_id)
341 {
342 struct cisco_card_driver *driver,**drv_array;
343 struct cisco_card **rc,*card,*nc,*parent;
344 u_int real_port_id,card_type,card_id;
345
346 if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)
347 return(-1);
348
349 /* check that this bay is empty */
350 if (*rc != NULL) {
351 if ((*rc)->card_flags & CISCO_CARD_FLAG_OVERRIDE) {
352 vm_slot_remove_binding(vm,slot_id,port_id);
353 } else {
354 vm_error(vm,"a card already exists in slot %u/%u (%s)\n",
355 slot_id,port_id,(*rc)->dev_type);
356 return(-1);
357 }
358 }
359
360 card = vm->slots[slot_id];
361
362 if (!card || (card == *rc)) {
363 /* Main slot */
364 drv_array = vm->slots_drivers;
365 card_type = vm->slots_type;
366 card_id = slot_id;
367 parent = NULL;
368 } else {
369 /* Subslot */
370 if (!card->driver->card_get_sub_info) {
371 vm_error(vm,"no sub-slot possible for slot %u/%u.\n",slot_id,port_id);
372 return(-1);
373 }
374
375 if (card->driver->card_get_sub_info(vm,card,port_id,
376 &drv_array,&card_type) == -1)
377 {
378 vm_error(vm,"no sub-slot info for slot %u/%u.\n",slot_id,port_id);
379 return(-1);
380 }
381
382 card_id = port_id;
383 parent = card;
384 }
385
386 assert(drv_array != NULL);
387
388 /* Find the card driver */
389 if (!(driver = cisco_card_find_driver(drv_array,dev_type))) {
390 vm_error(vm,"unknown card type '%s' for slot %u/%u.\n",
391 dev_type,slot_id,port_id);
392 return(-1);
393 }
394
395 /* Allocate new card info */
396 if (!(nc = cisco_card_create(card_type)))
397 return(-1);
398
399 nc->slot_id = slot_id;
400 nc->subslot_id = port_id;
401 nc->card_id = card_id;
402 nc->dev_type = driver->dev_type;
403 nc->driver = driver;
404 nc->parent = parent;
405 *rc = nc;
406 return(0);
407 }
408
409 /* Remove a slot binding */
410 int vm_slot_remove_binding(vm_instance_t *vm,u_int slot_id,u_int port_id)
411 {
412 struct cisco_card **rc,*sc;
413 u_int i,real_port_id;
414
415 if (vm_slot_get_info(vm,slot_id,port_id,&rc,&real_port_id) == -1)
416 return(-1);
417
418 if (*rc == NULL)
419 return(-1);
420
421 if ((*rc)->drv_info != NULL) {
422 vm_error(vm,"slot %u/%u is still active\n",slot_id,port_id);
423 return(-1);
424 }
425
426 for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) {
427 if ((sc = (*rc)->sub_slots[i]) != NULL) {
428 vm_error(vm,"sub-slot %u/%u is still active\n",
429 slot_id,sc->subslot_id);
430 return(-1);
431 }
432 }
433
434 /* Remove all NIOs bindings */
435 vm_slot_remove_all_nio_bindings(vm,slot_id);
436
437 /* Free the card info structure */
438 free(*rc);
439 *rc = NULL;
440 return(0);
441 }
442
443 /* Add a network IO binding */
444 int vm_slot_add_nio_binding(vm_instance_t *vm,u_int slot_id,u_int port_id,
445 char *nio_name)
446 {
447 struct cisco_nio_binding *nb;
448 struct cisco_card *card,*rc;
449 u_int real_port_id;
450 netio_desc_t *nio;
451
452 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
453 return(-1);
454
455 /* Get the real card (in case this is a sub-slot) */
456 real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
457
458 if (rc == NULL)
459 return(-1);
460
461 /* check that a NIO is not already bound to this port */
462 if (cisco_card_find_nio_binding(rc,real_port_id) != NULL) {
463 vm_error(vm,"a NIO already exists for interface %u/%u.\n",
464 slot_id,port_id);
465 return(-1);
466 }
467
468 /* acquire a reference on the NIO object */
469 if (!(nio = netio_acquire(nio_name))) {
470 vm_error(vm,"unable to find NIO '%s'.\n",nio_name);
471 return(-1);
472 }
473
474 /* create a new binding */
475 if (!(nb = malloc(sizeof(*nb)))) {
476 vm_error(vm,"unable to create NIO binding for interface %u/%u.\n",
477 slot_id,port_id);
478 netio_release(nio_name);
479 return(-1);
480 }
481
482 memset(nb,0,sizeof(*nb));
483 nb->nio = nio;
484 nb->port_id = real_port_id;
485 nb->orig_port_id = port_id;
486
487 nb->next = rc->nio_list;
488 if (nb->next) nb->next->prev = nb;
489 rc->nio_list = nb;
490 return(0);
491 }
492
493 /* Remove a NIO binding */
494 int vm_slot_remove_nio_binding(vm_instance_t *vm,u_int slot_id,u_int port_id)
495 {
496 struct cisco_nio_binding *nb;
497 struct cisco_card *card,*rc;
498 u_int real_port_id;
499
500 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
501 return(-1);
502
503 /* Get the real card (in case this is a sub-slot) */
504 real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
505
506 if (rc == NULL)
507 return(-1);
508
509 /* no nio binding for this slot/port ? */
510 if (!(nb = cisco_card_find_nio_binding(rc,real_port_id)))
511 return(-1);
512
513 /* tell the NM driver to stop using this NIO */
514 if (rc->driver)
515 rc->driver->card_unset_nio(vm,rc,port_id);
516
517 /* remove this entry from the double linked list */
518 if (nb->next)
519 nb->next->prev = nb->prev;
520
521 if (nb->prev) {
522 nb->prev->next = nb->next;
523 } else {
524 rc->nio_list = nb->next;
525 }
526
527 /* unreference NIO object */
528 netio_release(nb->nio->name);
529 free(nb);
530 return(0);
531 }
532
533 /* Remove all NIO bindings for the specified slot (sub-slots included) */
534 int vm_slot_remove_all_nio_bindings(vm_instance_t *vm,u_int slot_id)
535 {
536 struct cisco_card *card,*sc;
537 int i;
538
539 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
540 return(-1);
541
542 /* Remove NIO bindings for the main slot */
543 cisco_card_remove_all_nio_bindings(vm,card);
544
545 /* Remove NIO bindings for all sub-slots */
546 for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) {
547 if ((sc = card->sub_slots[i]) != NULL)
548 cisco_card_remove_all_nio_bindings(vm,sc);
549 }
550
551 return(0);
552 }
553
554 /* Enable a Network IO descriptor for the specified slot */
555 int vm_slot_enable_nio(vm_instance_t *vm,u_int slot_id,u_int port_id)
556 {
557 struct cisco_nio_binding *nb;
558 struct cisco_card *card,*rc;
559 u_int real_port_id;
560
561 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
562 return(-1);
563
564 /* Get the real card (in case this is a sub-slot) */
565 real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
566
567 if (rc == NULL)
568 return(-1);
569
570 /* no nio binding for this slot/port ? */
571 if (!(nb = cisco_card_find_nio_binding(rc,real_port_id)))
572 return(-1);
573
574 /* check that the driver is defined and successfully initialized */
575 if (!rc->driver || !rc->drv_info)
576 return(-1);
577
578 return(rc->driver->card_set_nio(vm,rc,port_id,nb->nio));
579 }
580
581 /* Disable Network IO descriptor for the specified slot */
582 int vm_slot_disable_nio(vm_instance_t *vm,u_int slot_id,u_int port_id)
583 {
584 struct cisco_nio_binding *nb;
585 struct cisco_card *card,*rc;
586 u_int real_port_id;
587
588 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
589 return(-1);
590
591 /* Get the real card (in case this is a sub-slot) */
592 real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
593
594 if (rc == NULL)
595 return(-1);
596
597 /* no nio binding for this slot/port ? */
598 if (!(nb = cisco_card_find_nio_binding(rc,real_port_id)))
599 return(-1);
600
601 /* check that the driver is defined and successfully initialized */
602 if (!rc->driver || !rc->drv_info)
603 return(-1);
604
605 return(rc->driver->card_unset_nio(vm,rc,port_id));
606 }
607
608 /* Enable all NIO for the specified slot (sub-slots included) */
609 int vm_slot_enable_all_nio(vm_instance_t *vm,u_int slot_id)
610 {
611 struct cisco_card *card;
612 int i;
613
614 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
615 return(-1);
616
617 /* Enable slot NIOs */
618 cisco_card_enable_all_nio(vm,card);
619
620 /* Enable NIO of sub-slots */
621 for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
622 cisco_card_enable_all_nio(vm,card->sub_slots[i]);
623
624 return(0);
625 }
626
627 /* Disable all NIO for the specified slot (sub-slots included) */
628 int vm_slot_disable_all_nio(vm_instance_t *vm,u_int slot_id)
629 {
630 struct cisco_card *card;
631 int i;
632
633 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
634 return(-1);
635
636 /* Disable slot NIOs */
637 cisco_card_disable_all_nio(vm,card);
638
639 /* Disable NIO of sub-slots */
640 for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
641 cisco_card_disable_all_nio(vm,card->sub_slots[i]);
642
643 return(0);
644 }
645
646 /* Initialize the specified slot (sub-slots included) */
647 int vm_slot_init(vm_instance_t *vm,u_int slot_id)
648 {
649 struct cisco_card *card;
650 int i;
651
652 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
653 return(0);
654
655 /* Initialize card main module */
656 cisco_card_init(vm,card,slot_id);
657
658 /* Initialize sub-slots */
659 for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
660 cisco_card_init(vm,card->sub_slots[i],slot_id);
661
662 /* Enable all NIO */
663 vm_slot_enable_all_nio(vm,slot_id);
664 return(0);
665 }
666
667 /* Initialize all slots of a VM */
668 int vm_slot_init_all(vm_instance_t *vm)
669 {
670 int i;
671
672 for(i=0;i<vm->nr_slots;i++) {
673 if (vm_slot_init(vm,i) == -1) {
674 vm_error(vm,"unable to initialize slot %u\n",i);
675 return(-1);
676 }
677 }
678
679 return(0);
680 }
681
682 /* Shutdown the specified slot (sub-slots included) */
683 int vm_slot_shutdown(vm_instance_t *vm,u_int slot_id)
684 {
685 struct cisco_card *card;
686 int i;
687
688 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
689 return(-1);
690
691 /* Disable all NIO */
692 vm_slot_disable_all_nio(vm,slot_id);
693
694 /* Shutdown sub-slots */
695 for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
696 cisco_card_shutdown(vm,card->sub_slots[i]);
697
698 /* Shutdown card main module */
699 cisco_card_shutdown(vm,card);
700 return(0);
701 }
702
703 /* Shutdown all slots of a VM */
704 int vm_slot_shutdown_all(vm_instance_t *vm)
705 {
706 int i;
707
708 for(i=0;i<vm->nr_slots;i++)
709 vm_slot_shutdown(vm,i);
710
711 return(0);
712 }
713
714 /* Show info about the specified slot (sub-slots included) */
715 int vm_slot_show_info(vm_instance_t *vm,u_int slot_id)
716 {
717 struct cisco_card *card;
718
719 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
720 return(-1);
721
722 cisco_card_show_info(vm,card);
723 return(0);
724 }
725
726 /* Show info about all slots */
727 int vm_slot_show_all_info(vm_instance_t *vm)
728 {
729 int i;
730
731 for(i=0;i<vm->nr_slots;i++)
732 vm_slot_show_info(vm,i);
733
734 return(0);
735 }
736
737 /* Check if the specified slot has a valid EEPROM defined */
738 int vm_slot_check_eeprom(vm_instance_t *vm,u_int slot_id,u_int port_id)
739 {
740 struct cisco_card *card,*rc;
741
742 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
743 return(FALSE);
744
745 /* Get the real card (in case this is a sub-slot) */
746 vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
747
748 if (rc == NULL)
749 return(FALSE);
750
751 return(cisco_card_check_eeprom(rc));
752 }
753
754 /* Returns the EEPROM data of the specified slot */
755 struct cisco_eeprom *
756 vm_slot_get_eeprom(vm_instance_t *vm,u_int slot_id,u_int port_id)
757 {
758 struct cisco_card *card,*rc;
759
760 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
761 return NULL;
762
763 /* Get the real card (in case this is a sub-slot) */
764 vm_slot_translate_port_id(vm,slot_id,port_id,&rc);
765
766 if (rc == NULL)
767 return NULL;
768
769 return(&rc->eeprom);
770 }
771
772 /* Save config for the specified slot (sub-slots included) */
773 int vm_slot_save_config(vm_instance_t *vm,u_int slot_id,FILE *fd)
774 {
775 struct cisco_card *card;
776 int i;
777
778 if (!(card = vm_slot_get_card_ptr(vm,slot_id)))
779 return(-1);
780
781 /* Main slot info */
782 cisco_card_save_config(vm,card,fd);
783
784 /* Shutdown sub-slots */
785 for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++)
786 cisco_card_save_config(vm,card->sub_slots[i],fd);
787
788 return(0);
789 }
790
791 /* Save config for all slots */
792 int vm_slot_save_all_config(vm_instance_t *vm,FILE *fd)
793 {
794 int i;
795
796 for(i=0;i<vm->nr_slots;i++)
797 vm_slot_save_config(vm,i,fd);
798
799 return(0);
800 }
801
802 /* Show slot drivers */
803 int vm_slot_show_drivers(vm_instance_t *vm)
804 {
805 char *slot_type;
806 int i;
807
808 if (!vm->slots_drivers)
809 return(-1);
810
811 slot_type = cisco_card_get_type_desc(vm->slots_type);
812
813 printf("Available %s %s drivers:\n",vm->platform->log_name,slot_type);
814
815 for(i=0;vm->slots_drivers[i];i++) {
816 printf(" * %s %s\n",
817 vm->slots_drivers[i]->dev_type,
818 !vm->slots_drivers[i]->supported ? "(NOT WORKING)" : "");
819 }
820
821 printf("\n");
822 return(0);
823 }
824
825 /* Maximum number of tokens in a slot description */
826 #define SLOT_DESC_MAX_TOKENS 8
827
828 /* Create a Network Module (command line) */
829 int vm_slot_cmd_create(vm_instance_t *vm,char *str)
830 {
831 char *tokens[SLOT_DESC_MAX_TOKENS];
832 int i,count,res;
833 u_int slot_id,port_id;
834
835 /* A port adapter description is like "1:0:NM-1FE" */
836 count = m_strsplit(str,':',tokens,SLOT_DESC_MAX_TOKENS);
837
838 if ((count < 2) || (count > 3)) {
839 vm_error(vm,"unable to parse slot description '%s'.\n",str);
840 return(-1);
841 }
842
843 /* Parse the slot id */
844 slot_id = atoi(tokens[0]);
845
846 /* Parse the sub-slot id */
847 if (count == 3)
848 port_id = atoi(tokens[1]);
849 else
850 port_id = 0;
851
852 /* Add this new slot to the current slot list */
853 res = vm_slot_add_binding(vm,tokens[count-1],slot_id,port_id);
854
855 /* The complete array was cleaned by strsplit */
856 for(i=0;i<SLOT_DESC_MAX_TOKENS;i++)
857 free(tokens[i]);
858
859 return(res);
860 }
861
862 /* Add a Network IO descriptor binding (command line) */
863 int vm_slot_cmd_add_nio(vm_instance_t *vm,char *str)
864 {
865 char *tokens[SLOT_DESC_MAX_TOKENS];
866 int i,count,nio_type,res=-1;
867 u_int slot_id,port_id;
868 netio_desc_t *nio;
869 char nio_name[128];
870
871 /* A NIO binding description is like "1:3:tap:tap0" */
872 if ((count = m_strsplit(str,':',tokens,SLOT_DESC_MAX_TOKENS)) < 3) {
873 vm_error(vm,"unable to parse NIO description '%s'.\n",str);
874 return(-1);
875 }
876
877 /* Parse the slot id */
878 slot_id = atoi(tokens[0]);
879
880 /* Parse the port id */
881 port_id = atoi(tokens[1]);
882
883 /* Autogenerate a NIO name */
884 snprintf(nio_name,sizeof(nio_name),"%s-i%u/%u/%u",
885 vm_get_type(vm),vm->instance_id,slot_id,port_id);
886
887 /* Create the Network IO descriptor */
888 nio = NULL;
889 nio_type = netio_get_type(tokens[2]);
890
891 switch(nio_type) {
892 case NETIO_TYPE_UNIX:
893 if (count != 5) {
894 vm_error(vm,"invalid number of arguments for UNIX NIO '%s'\n",str);
895 goto done;
896 }
897
898 nio = netio_desc_create_unix(nio_name,tokens[3],tokens[4]);
899 break;
900
901 case NETIO_TYPE_VDE:
902 if (count != 5) {
903 vm_error(vm,"invalid number of arguments for VDE NIO '%s'\n",str);
904 goto done;
905 }
906
907 nio = netio_desc_create_vde(nio_name,tokens[3],tokens[4]);
908 break;
909
910 case NETIO_TYPE_TAP:
911 if (count != 4) {
912 vm_error(vm,"invalid number of arguments for TAP NIO '%s'\n",str);
913 goto done;
914 }
915
916 nio = netio_desc_create_tap(nio_name,tokens[3]);
917 break;
918
919 case NETIO_TYPE_UDP:
920 if (count != 6) {
921 vm_error(vm,"invalid number of arguments for UDP NIO '%s'\n",str);
922 goto done;
923 }
924
925 nio = netio_desc_create_udp(nio_name,atoi(tokens[3]),
926 tokens[4],atoi(tokens[5]));
927 break;
928
929 case NETIO_TYPE_TCP_CLI:
930 if (count != 5) {
931 vm_error(vm,"invalid number of arguments for TCP CLI NIO '%s'\n",
932 str);
933 goto done;
934 }
935
936 nio = netio_desc_create_tcp_cli(nio_name,tokens[3],tokens[4]);
937 break;
938
939 case NETIO_TYPE_TCP_SER:
940 if (count != 4) {
941 vm_error(vm,"invalid number of arguments for TCP SER NIO '%s'\n",
942 str);
943 goto done;
944 }
945
946 nio = netio_desc_create_tcp_ser(nio_name,tokens[3]);
947 break;
948
949 case NETIO_TYPE_NULL:
950 nio = netio_desc_create_null(nio_name);
951 break;
952
953 #ifdef LINUX_ETH
954 case NETIO_TYPE_LINUX_ETH:
955 if (count != 4) {
956 vm_error(vm,"invalid number of arguments for Linux Eth NIO '%s'\n",
957 str);
958 goto done;
959 }
960
961 nio = netio_desc_create_lnxeth(nio_name,tokens[3]);
962 break;
963 #endif
964
965 #ifdef GEN_ETH
966 case NETIO_TYPE_GEN_ETH:
967 if (count != 4) {
968 vm_error(vm,
969 "invalid number of arguments for Generic Eth NIO '%s'\n",
970 str);
971 goto done;
972 }
973
974 nio = netio_desc_create_geneth(nio_name,tokens[3]);
975 break;
976 #endif
977
978 default:
979 vm_error(vm,"unknown NETIO type '%s'\n",tokens[2]);
980 goto done;
981 }
982
983 if (!nio) {
984 vm_error(vm,"unable to create NETIO descriptor for slot %u\n",slot_id);
985 goto done;
986 }
987
988 if (vm_slot_add_nio_binding(vm,slot_id,port_id,nio_name) == -1) {
989 vm_error(vm,"unable to add NETIO binding for slot %u\n",slot_id);
990 netio_release(nio_name);
991 netio_delete(nio_name);
992 goto done;
993 }
994
995 netio_release(nio_name);
996 res = 0;
997
998 done:
999 /* The complete array was cleaned by strsplit */
1000 for(i=0;i<SLOT_DESC_MAX_TOKENS;i++)
1001 free(tokens[i]);
1002
1003 return(res);
1004 }

  ViewVC Help
Powered by ViewVC 1.1.26