/* Show slot bindings */ static int cmd_slot_bindings(hypervisor_conn_t *conn,int argc,char *argv[]) { struct cisco_card *card,*sc; vm_instance_t *vm; int i,j; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); for(i=0;i<vm->nr_slots;i++) { if (!(card = vm_slot_get_card_ptr(vm,i))) continue; /* main module */ hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u/%u: %s", card->slot_id,card->subslot_id,card->dev_type); /* sub-slots */ for(j=0;j<CISCO_CARD_MAX_SUBSLOTS;j++) { if (!(sc = card->sub_slots[j])) continue; hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u/%u: %s", card->slot_id,card->subslot_id,card->dev_type); } } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }
/* Disable Network IO descriptor for the specified slot */ int vm_slot_disable_nio(vm_instance_t *vm,u_int slot_id,u_int port_id) { struct cisco_nio_binding *nb; struct cisco_card *card,*rc; u_int real_port_id; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(-1); /* Get the real card (in case this is a sub-slot) */ real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc); if (rc == NULL) return(-1); /* no nio binding for this slot/port ? */ if (!(nb = cisco_card_find_nio_binding(rc,real_port_id))) return(-1); /* check that the driver is defined and successfully initialized */ if (!rc->driver || !rc->drv_info) return(-1); return(rc->driver->card_unset_nio(vm,rc,port_id)); }
/* Return the NM status register given the detected EEPROM (3660) */ static u_int nm_get_status_2(struct c3600_iofpga_data *d,u_int pos) { u_int res = 0xFFFF; u_int start,end; int i; switch(pos) { case 0: /* word 0: slot 1 - 4 */ start = 1; end = 4; break; case 1: /* word 1: slot 5 - 6 */ start = 5; end = 6; break; default: return(res); } for(i=start;i<=end;i++) { if (vm_slot_get_card_ptr(d->router->vm,i)) res &= c3660_nm_masks[i-1]; } return(res); }
/* Show info about the specified slot (sub-slots included) */ int vm_slot_show_info(vm_instance_t *vm,u_int slot_id) { struct cisco_card *card; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(-1); cisco_card_show_info(vm,card); return(0); }
/* Return the NM status register given the detected EEPROM (3620/3640) */ static u_int nm_get_status_1(struct c3600_iofpga_data *d) { u_int res = 0xFFFF; int i; for(i=0;i<4;i++) { if (vm_slot_get_card_ptr(d->router->vm,i)) res &= ~(0x1111 << i); } return(res); }
/* Select the current NM EEPROM */ static void nm_eeprom_select(struct c3600_iofpga_data *d,u_int slot) { struct cisco_eeprom *eeprom = NULL; struct cisco_card *card; card = vm_slot_get_card_ptr(d->router->vm,slot); if (card != NULL) eeprom = &card->eeprom; d->router->nm_eeprom_group.eeprom[0] = eeprom; }
/* Check if the specified slot has a valid EEPROM defined */ int vm_slot_check_eeprom(vm_instance_t *vm,u_int slot_id,u_int port_id) { struct cisco_card *card,*rc; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(FALSE); /* Get the real card (in case this is a sub-slot) */ vm_slot_translate_port_id(vm,slot_id,port_id,&rc); if (rc == NULL) return(FALSE); return(cisco_card_check_eeprom(rc)); }
/* Add a network IO binding */ int vm_slot_add_nio_binding(vm_instance_t *vm,u_int slot_id,u_int port_id, char *nio_name) { struct cisco_nio_binding *nb; struct cisco_card *card,*rc; u_int real_port_id; netio_desc_t *nio; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(-1); /* Get the real card (in case this is a sub-slot) */ real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc); if (rc == NULL) return(-1); /* check that a NIO is not already bound to this port */ if (cisco_card_find_nio_binding(rc,real_port_id) != NULL) { vm_error(vm,"a NIO already exists for interface %u/%u.\n", slot_id,port_id); return(-1); } /* acquire a reference on the NIO object */ if (!(nio = netio_acquire(nio_name))) { vm_error(vm,"unable to find NIO '%s'.\n",nio_name); return(-1); } /* create a new binding */ if (!(nb = malloc(sizeof(*nb)))) { vm_error(vm,"unable to create NIO binding for interface %u/%u.\n", slot_id,port_id); netio_release(nio_name); return(-1); } memset(nb,0,sizeof(*nb)); nb->nio = nio; nb->port_id = real_port_id; nb->orig_port_id = port_id; nb->next = rc->nio_list; if (nb->next) nb->next->prev = nb; rc->nio_list = nb; return(0); }
/* Save config for the specified slot (sub-slots included) */ int vm_slot_save_config(vm_instance_t *vm,u_int slot_id,FILE *fd) { struct cisco_card *card; int i; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(-1); /* Main slot info */ cisco_card_save_config(vm,card,fd); /* Shutdown sub-slots */ for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) cisco_card_save_config(vm,card->sub_slots[i],fd); return(0); }
/* Disable all NIO for the specified slot (sub-slots included) */ int vm_slot_disable_all_nio(vm_instance_t *vm,u_int slot_id) { struct cisco_card *card; int i; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(-1); /* Disable slot NIOs */ cisco_card_disable_all_nio(vm,card); /* Disable NIO of sub-slots */ for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) cisco_card_disable_all_nio(vm,card->sub_slots[i]); return(0); }
/* Shutdown the specified slot (sub-slots included) */ int vm_slot_shutdown(vm_instance_t *vm,u_int slot_id) { struct cisco_card *card; int i; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(-1); /* Disable all NIO */ vm_slot_disable_all_nio(vm,slot_id); /* Shutdown sub-slots */ for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) cisco_card_shutdown(vm,card->sub_slots[i]); /* Shutdown card main module */ cisco_card_shutdown(vm,card); return(0); }
/* Initialize the specified slot (sub-slots included) */ int vm_slot_init(vm_instance_t *vm,u_int slot_id) { struct cisco_card *card; int i; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(0); /* Initialize card main module */ cisco_card_init(vm,card,slot_id); /* Initialize sub-slots */ for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) cisco_card_init(vm,card->sub_slots[i],slot_id); /* Enable all NIO */ vm_slot_enable_all_nio(vm,slot_id); return(0); }
/* Remove all NIO bindings for the specified slot (sub-slots included) */ int vm_slot_remove_all_nio_bindings(vm_instance_t *vm,u_int slot_id) { struct cisco_card *card,*sc; int i; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(-1); /* Remove NIO bindings for the main slot */ cisco_card_remove_all_nio_bindings(vm,card); /* Remove NIO bindings for all sub-slots */ for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) { if ((sc = card->sub_slots[i]) != NULL) cisco_card_remove_all_nio_bindings(vm,sc); } return(0); }
/* Remove a NIO binding */ int vm_slot_remove_nio_binding(vm_instance_t *vm,u_int slot_id,u_int port_id) { struct cisco_nio_binding *nb; struct cisco_card *card,*rc; u_int real_port_id; if (!(card = vm_slot_get_card_ptr(vm,slot_id))) return(-1); /* Get the real card (in case this is a sub-slot) */ real_port_id = vm_slot_translate_port_id(vm,slot_id,port_id,&rc); if (rc == NULL) return(-1); /* no nio binding for this slot/port ? */ if (!(nb = cisco_card_find_nio_binding(rc,real_port_id))) return(-1); /* tell the NM driver to stop using this NIO */ if (rc->driver) rc->driver->card_unset_nio(vm,rc,port_id); /* remove this entry from the double linked list */ if (nb->next) nb->next->prev = nb->prev; if (nb->prev) { nb->prev->next = nb->next; } else { rc->nio_list = nb->next; } /* unreference NIO object */ netio_release(nb->nio->name); free(nb); return(0); }
/* Show NIO bindings for the specified slot */ static int cmd_slot_nio_bindings(hypervisor_conn_t *conn,int argc,char *argv[]) { struct cisco_nio_binding *nb; struct cisco_card *card,*sc; vm_instance_t *vm; u_int i,slot; if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM))) return(-1); slot = atoi(argv[1]); if ((card = vm_slot_get_card_ptr(vm,slot))) { /* main module */ for(nb=card->nio_list;nb;nb=nb->next) { hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u: %s", nb->port_id,nb->nio->name); } /* sub-slots */ for(i=0;i<CISCO_CARD_MAX_SUBSLOTS;i++) { if (!(sc = card->sub_slots[i])) continue; for(nb=sc->nio_list;nb;nb=nb->next) { hypervisor_send_reply(conn,HSC_INFO_MSG,0,"%u: %s", nb->port_id,nb->nio->name); } } } vm_release(vm); hypervisor_send_reply(conn,HSC_INFO_OK,1,"OK"); return(0); }