📄 dev_c7200.c
字号:
/* Check that a device type is defined for this bay */ if (!bay->dev_type || !bay->pa_driver) { vm_error(router->vm,"trying to init empty slot %u.\n",pa_bay); return(-1); } /* Allocate device name */ len = strlen(bay->dev_type) + 10; if (!(bay->dev_name = malloc(len))) { vm_error(router->vm,"unable to allocate device name.\n"); return(-1); } snprintf(bay->dev_name,len,"%s(%u)",bay->dev_type,pa_bay); /* Initialize PA driver */ if (bay->pa_driver->pa_init(router,bay->dev_name,pa_bay) == 1) { vm_error(router->vm,"unable to initialize PA %u.\n",pa_bay); return(-1); } /* Enable all NIO */ c7200_pa_enable_all_nio(router,pa_bay); return(0);}/* Shutdown a Port Adapter */int c7200_pa_shutdown(c7200_t *router,u_int pa_bay){ struct c7200_pa_bay *bay; if (!(bay = c7200_pa_get_info(router,pa_bay))) return(-1); /* Check that a device type is defined for this bay */ if (!bay->dev_type || !bay->pa_driver) { vm_error(router->vm,"trying to shut down an empty bay %u.\n",pa_bay); return(-1); } /* Disable all NIO */ c7200_pa_disable_all_nio(router,pa_bay); /* Shutdown the PA driver */ if (bay->drv_info && (bay->pa_driver->pa_shutdown(router,pa_bay) == -1)) { vm_error(router->vm,"unable to shutdown PA %u.\n",pa_bay); return(-1); } free(bay->dev_name); bay->dev_name = NULL; bay->drv_info = NULL; return(0);}/* Shutdown all PA of a router */int c7200_pa_shutdown_all(c7200_t *router){ int i; for(i=0;i<C7200_MAX_PA_BAYS;i++) { if (!router->pa_bay[i].dev_type) continue; c7200_pa_shutdown(router,i); } return(0);}/* Show info about all NMs */int c7200_pa_show_all_info(c7200_t *router){ struct c7200_pa_bay *bay; int i; for(i=0;i<C7200_MAX_PA_BAYS;i++) { if (!(bay = c7200_pa_get_info(router,i)) || !bay->pa_driver) continue; if (bay->pa_driver->pa_show_info != NULL) bay->pa_driver->pa_show_info(router,i); } return(0);}/* Maximum number of tokens in a PA description */#define PA_DESC_MAX_TOKENS 8/* Create a Port Adapter (command line) */int c7200_cmd_pa_create(c7200_t *router,char *str){ char *tokens[PA_DESC_MAX_TOKENS]; int i,count,res; u_int pa_bay; /* A port adapter description is like "1:PA-FE-TX" */ if ((count = m_strsplit(str,':',tokens,PA_DESC_MAX_TOKENS)) != 2) { vm_error(router->vm,"unable to parse PA description '%s'.\n",str); return(-1); } /* Parse the PA bay id */ pa_bay = atoi(tokens[0]); /* Add this new PA to the current PA list */ res = c7200_pa_add_binding(router,tokens[1],pa_bay); /* The complete array was cleaned by strsplit */ for(i=0;i<PA_DESC_MAX_TOKENS;i++) free(tokens[i]); return(res);}/* Add a Network IO descriptor binding (command line) */int c7200_cmd_add_nio(c7200_t *router,char *str){ char *tokens[PA_DESC_MAX_TOKENS]; int i,count,nio_type,res=-1; u_int pa_bay,port_id; netio_desc_t *nio; char nio_name[128]; /* A port adapter description is like "1:3:tap:tap0" */ if ((count = m_strsplit(str,':',tokens,PA_DESC_MAX_TOKENS)) < 3) { vm_error(router->vm,"unable to parse NIO description '%s'.\n",str); return(-1); } /* Parse the PA bay */ pa_bay = atoi(tokens[0]); /* Parse the PA port id */ port_id = atoi(tokens[1]); /* Autogenerate a NIO name */ snprintf(nio_name,sizeof(nio_name),"c7200-i%u/%u/%u", router->vm->instance_id,pa_bay,port_id); /* Create the Network IO descriptor */ nio = NULL; nio_type = netio_get_type(tokens[2]); switch(nio_type) { case NETIO_TYPE_UNIX: if (count != 5) { vm_error(router->vm, "invalid number of arguments for UNIX NIO '%s'\n",str); goto done; } nio = netio_desc_create_unix(nio_name,tokens[3],tokens[4]); break; case NETIO_TYPE_VDE: if (count != 5) { vm_error(router->vm, "invalid number of arguments for VDE NIO '%s'\n",str); goto done; } nio = netio_desc_create_vde(nio_name,tokens[3],tokens[4]); break; case NETIO_TYPE_TAP: if (count != 4) { vm_error(router->vm, "invalid number of arguments for TAP NIO '%s'\n",str); goto done; } nio = netio_desc_create_tap(nio_name,tokens[3]); break; case NETIO_TYPE_UDP: if (count != 6) { vm_error(router->vm, "invalid number of arguments for UDP NIO '%s'\n",str); goto done; } nio = netio_desc_create_udp(nio_name,atoi(tokens[3]), tokens[4],atoi(tokens[5])); break; case NETIO_TYPE_TCP_CLI: if (count != 5) { vm_error(router->vm, "invalid number of arguments for TCP CLI NIO '%s'\n",str); goto done; } nio = netio_desc_create_tcp_cli(nio_name,tokens[3],tokens[4]); break; case NETIO_TYPE_TCP_SER: if (count != 4) { vm_error(router->vm, "invalid number of arguments for TCP SER NIO '%s'\n",str); goto done; } nio = netio_desc_create_tcp_ser(nio_name,tokens[3]); break; case NETIO_TYPE_NULL: nio = netio_desc_create_null(nio_name); break;#ifdef LINUX_ETH case NETIO_TYPE_LINUX_ETH: if (count != 4) { vm_error(router->vm, "invalid number of arguments for Linux Eth NIO '%s'\n", str); goto done; } nio = netio_desc_create_lnxeth(nio_name,tokens[3]); break;#endif#ifdef GEN_ETH case NETIO_TYPE_GEN_ETH: if (count != 4) { vm_error(router->vm,"invalid number of " "arguments for Generic Eth NIO '%s'\n",str); goto done; } nio = netio_desc_create_geneth(nio_name,tokens[3]); break;#endif default: vm_error(router->vm,"unknown NETIO type '%s'\n",tokens[2]); goto done; } if (!nio) { fprintf(stderr,"c7200_cmd_add_nio: unable to create NETIO " "descriptor for PA bay %u\n",pa_bay); goto done; } if (c7200_pa_add_nio_binding(router,pa_bay,port_id,nio_name) == -1) { vm_error(router->vm,"unable to add NETIO binding for slot %u\n",pa_bay); netio_release(nio_name); netio_delete(nio_name); goto done; } netio_release(nio_name); res = 0; done: /* The complete array was cleaned by strsplit */ for(i=0;i<PA_DESC_MAX_TOKENS;i++) free(tokens[i]); return(res);}/* Show the list of available PA drivers */void c7200_pa_show_drivers(void){ int i; printf("Available C7200 Port Adapter drivers:\n"); for(i=0;pa_drivers[i];i++) { printf(" * %s %s\n", pa_drivers[i]->dev_type, !pa_drivers[i]->supported ? "(NOT WORKING)" : ""); } printf("\n");}/* Get an NPE driver */struct c7200_npe_driver *c7200_npe_get_driver(char *npe_type){ int i; for(i=0;npe_drivers[i].npe_type;i++) if (!strcmp(npe_drivers[i].npe_type,npe_type)) return(&npe_drivers[i]); return NULL;}/* Set the NPE type */int c7200_npe_set_type(c7200_t *router,char *npe_type){ struct c7200_npe_driver *driver; if (router->vm->status == VM_STATUS_RUNNING) { vm_error(router->vm,"unable to change NPE type when online.\n"); return(-1); } if (!(driver = c7200_npe_get_driver(npe_type))) { vm_error(router->vm,"unknown NPE type '%s'.\n",npe_type); return(-1); } router->npe_driver = driver; if (c7200_npe_set_eeprom(router) == -1) { vm_error(router->vm,"unable to find NPE '%s' EEPROM!\n", router->npe_driver->npe_type); return(-1); } return(0);}/* Show the list of available NPE drivers */void c7200_npe_show_drivers(void){ int i; printf("Available C7200 NPE drivers:\n"); for(i=0;npe_drivers[i].npe_type;i++) { printf(" * %s %s\n", npe_drivers[i].npe_type, !npe_drivers[i].supported ? "(NOT WORKING)" : ""); } printf("\n");}/* Set Midplane type */int c7200_midplane_set_type(c7200_t *router,char *midplane_type){ const struct cisco_eeprom *eeprom; m_uint8_t version; if (router->vm->status == VM_STATUS_RUNNING) { vm_error(router->vm,"unable to change Midplane type when online.\n"); return(-1); } /* Set EEPROM */ if (!(eeprom = c7200_get_midplane_eeprom(midplane_type))) { vm_error(router->vm,"unknown Midplane \"%s\"!\n",midplane_type); return(-1); } /* Copy the midplane EEPROM */ if (cisco_eeprom_copy(&router->mp_eeprom,eeprom) == -1) { vm_error(router->vm,"unable to set midplane EEPROM.\n"); return(-1); } /* Set the chassis base MAC address */ c7200_burn_mac_addr(router,&router->mac_addr); /* Get the midplane version */ cisco_eeprom_get_byte(&router->mp_eeprom,2,&version); router->midplane_version = version; router->midplane_type = eeprom->name; return(0);}/* Set chassis MAC address */int c7200_midplane_set_mac_addr(c7200_t *router,char *mac_addr){ if (parse_mac_addr(&router->mac_addr,mac_addr) == -1) { vm_error(router->vm,"unable to parse MAC address '%s'.\n",mac_addr); return(-1); } /* Set the chassis base MAC address */ c7200_burn_mac_addr(router,&router->mac_addr); return(0);}/* Create the main PCI bus for a GT64010 based system */static int c7200_init_gt64010(c7200_t *router){ vm_instance_t *vm = router->vm; if (!(vm->pci_bus[0] = pci_bus_create("MB0/MB1/MB2",0))) { vm_error(vm,"unable to create PCI data.\n"); return(-1); } return(dev_gt64010_init(vm,"gt64010",C7200_GT64K_ADDR,0x1000, C7200_GT64K_IRQ));}/* Create the two main PCI busses for a GT64120 based system */static int c7200_init_gt64120(c7200_t *router){ vm_instance_t *vm = router->vm; vm->pci_bus[0] = pci_bus_create("MB0/MB1",0); vm->pci_bus[1] = pci_bus_create("MB2",0); if (!vm->pci_bus[0] || !vm->pci_bus[1]) { vm_error(vm,"unable to create PCI data.\n"); return(-1); } return(dev_gt64120_init(vm,"gt64120",C7200_GT64K_ADDR,0x1000, C7200_GT64K_IRQ));}/* Create the two main PCI busses for a dual GT64120 system */static int c7200_init_dual_gt64120(c7200_t *router){ vm_instance_t *vm = router->vm; vm->pci_bus[0] = pci_bus_create("MB0/MB1",0); vm->pci_bus[1] = pci_bus_create("MB2",0); if (!vm->pci_bus[0] || !vm->pci_bus[1]) { vm_error(vm,"unable to create PCI data.\n",vm->name); return(-1); } /* Initialize the first GT64120 at 0x14000000 */ if (dev_gt64120_init(vm,"gt64120(1)",C7200_GT64K_ADDR,0x1000, C7200_GT64K_IRQ) == -1) return(-1); /* Initialize the second GT64120 at 0x15000000 */ if (dev_gt64120_init(vm,"gt64120(2)",C7200_GT64K_SEC_ADDR,0x1000, C7200_GT64K_IRQ) == -1) return(-1); return(0);}/* Create the PA PCI busses */static int c7200_pa_create_pci_busses(c7200_t *router){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -