void mipsnet_init (int base, qemu_irq irq, NICInfo *nd) { MIPSnetState *s; qemu_check_nic_model(nd, "mipsnet"); s = qemu_mallocz(sizeof(MIPSnetState)); register_ioport_write(base, 36, 1, mipsnet_ioport_write, s); register_ioport_read(base, 36, 1, mipsnet_ioport_read, s); register_ioport_write(base, 36, 2, mipsnet_ioport_write, s); register_ioport_read(base, 36, 2, mipsnet_ioport_read, s); register_ioport_write(base, 36, 4, mipsnet_ioport_write, s); register_ioport_read(base, 36, 4, mipsnet_ioport_read, s); s->io_base = base; s->irq = irq; if (nd && nd->vlan) { s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, mipsnet_receive, mipsnet_can_receive, mipsnet_cleanup, s); } else { s->vc = NULL; } qemu_format_nic_info_str(s->vc, nd->macaddr); mipsnet_reset(s); register_savevm("mipsnet", 0, 0, mipsnet_save, mipsnet_load, s); }
void mipsnet_init (int base, qemu_irq irq, NICInfo *nd) { MIPSnetState *s; qemu_check_nic_model(nd, "mipsnet"); s = qemu_mallocz(sizeof(MIPSnetState)); register_ioport_write(base, 36, 1, mipsnet_ioport_write, s); register_ioport_read(base, 36, 1, mipsnet_ioport_read, s); register_ioport_write(base, 36, 2, mipsnet_ioport_write, s); register_ioport_read(base, 36, 2, mipsnet_ioport_read, s); register_ioport_write(base, 36, 4, mipsnet_ioport_write, s); register_ioport_read(base, 36, 4, mipsnet_ioport_read, s); s->io_base = base; s->irq = irq; if (nd) { memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr)); s->conf.vlan = nd->vlan; s->conf.peer = nd->netdev; s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, nd->model, nd->name, s); qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); } mipsnet_reset(s); vmstate_register(NULL, 0, &vmstate_mipsnet, s); }
static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val) { MIPSnetState *s = opaque; addr &= 0x3f; #ifdef DEBUG_MIPSNET_DATA printf("mipsnet: write addr=0x%02x val=0x%02x\n", addr, val); #endif switch (addr) { case MIPSNET_TX_DATA_COUNT: s->tx_count = (val <= MAX_ETH_FRAME_SIZE) ? val : 0; s->tx_written = 0; break; case MIPSNET_INT_CTL: if (val & MIPSNET_INTCTL_TXDONE) { s->intctl &= ~MIPSNET_INTCTL_TXDONE; } else if (val & MIPSNET_INTCTL_RXDONE) { s->intctl &= ~MIPSNET_INTCTL_RXDONE; } else if (val & MIPSNET_INTCTL_TESTBIT) { mipsnet_reset(s); s->intctl |= MIPSNET_INTCTL_TESTBIT; } else if (!val) { /* ACK testbit interrupt, flag was cleared on read. */ } s->busy = !!s->intctl; mipsnet_update_irq(s); break; case MIPSNET_TX_DATA_BUFFER: s->tx_buffer[s->tx_written++] = val; if (s->tx_written == s->tx_count) { /* Send buffer. */ #ifdef DEBUG_MIPSNET_SEND printf("mipsnet: sending len=%d\n", s->tx_count); #endif qemu_send_packet(s->vc, s->tx_buffer, s->tx_count); s->tx_count = s->tx_written = 0; s->intctl |= MIPSNET_INTCTL_TXDONE; s->busy = 1; mipsnet_update_irq(s); } break; /* Read-only registers */ case MIPSNET_DEV_ID: case MIPSNET_BUSY: case MIPSNET_RX_DATA_COUNT: case MIPSNET_INTERRUPT_INFO: case MIPSNET_RX_DATA_BUFFER: default: break; } }
static void mipsnet_ioport_write(void *opaque, hwaddr addr, uint64_t val, unsigned int size) { MIPSnetState *s = opaque; addr &= 0x3f; trace_mipsnet_write(addr, val); switch (addr) { case MIPSNET_TX_DATA_COUNT: s->tx_count = (val <= MAX_ETH_FRAME_SIZE) ? val : 0; s->tx_written = 0; break; case MIPSNET_INT_CTL: if (val & MIPSNET_INTCTL_TXDONE) { s->intctl &= ~MIPSNET_INTCTL_TXDONE; } else if (val & MIPSNET_INTCTL_RXDONE) { s->intctl &= ~MIPSNET_INTCTL_RXDONE; } else if (val & MIPSNET_INTCTL_TESTBIT) { mipsnet_reset(s); s->intctl |= MIPSNET_INTCTL_TESTBIT; } else if (!val) { /* ACK testbit interrupt, flag was cleared on read. */ } s->busy = !!s->intctl; mipsnet_update_irq(s); break; case MIPSNET_TX_DATA_BUFFER: s->tx_buffer[s->tx_written++] = val; if (s->tx_written == s->tx_count) { /* Send buffer. */ trace_mipsnet_send(s->tx_count); qemu_send_packet(&s->nic->nc, s->tx_buffer, s->tx_count); s->tx_count = s->tx_written = 0; s->intctl |= MIPSNET_INTCTL_TXDONE; s->busy = 1; mipsnet_update_irq(s); } break; /* Read-only registers */ case MIPSNET_DEV_ID: case MIPSNET_BUSY: case MIPSNET_RX_DATA_COUNT: case MIPSNET_INTERRUPT_INFO: case MIPSNET_RX_DATA_BUFFER: default: break; } }
void mipsnet_init (int base, qemu_irq irq, NICInfo *nd) { MIPSnetState *s; s = qemu_mallocz(sizeof(MIPSnetState)); if (!s) return; register_ioport_write(base, 36, 1, mipsnet_ioport_write, s); register_ioport_read(base, 36, 1, mipsnet_ioport_read, s); register_ioport_write(base, 36, 2, mipsnet_ioport_write, s); register_ioport_read(base, 36, 2, mipsnet_ioport_read, s); register_ioport_write(base, 36, 4, mipsnet_ioport_write, s); register_ioport_read(base, 36, 4, mipsnet_ioport_read, s); s->irq = irq; s->nd = nd; if (nd && nd->vlan) { s->vc = qemu_new_vlan_client(nd->vlan, mipsnet_receive, mipsnet_can_receive, s); } else { s->vc = NULL; } snprintf(s->vc->info_str, sizeof(s->vc->info_str), "mipsnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x", s->nd->macaddr[0], s->nd->macaddr[1], s->nd->macaddr[2], s->nd->macaddr[3], s->nd->macaddr[4], s->nd->macaddr[5]); mipsnet_reset(s); register_savevm("mipsnet", 0, 0, mipsnet_save, mipsnet_load, s); }
static void mipsnet_sysbus_reset(DeviceState *dev) { MIPSnetState *s = DO_UPCAST(MIPSnetState, busdev.qdev, dev); mipsnet_reset(s); }
static void mipsnet_sysbus_reset(DeviceState *dev) { MIPSnetState *s = MIPS_NET(dev); mipsnet_reset(s); }
phantom_device_t * driver_isa_mipsnet_probe( int port, int irq, int stage ) { (void) stage; SHOW_FLOW( 0, "Looking for MipsNet at 0x%x", port ); if( mipsnet_probe(port) ) { SHOW_ERROR( 1, "failed for port 0x%X", port ); return 0; } phantom_device_t * dev = calloc(1, sizeof(phantom_device_t)); assert(dev != 0); dev->name = "NE2000"; dev->seq_number = seq_number++; dev->iobase = port; dev->irq = irq; dev->iomem = 0; // TODO map mem //dev->dops.stop = mipsnet_disable; dev->dops.read = mipsnet_read; dev->dops.write = mipsnet_write; dev->dops.get_address = mipsnet_get_address; dev->drv_private = calloc( 1, sizeof(struct mipsnet)); assert( dev->drv_private != 0 ); struct mipsnet *pvt = dev->drv_private; //hal_sem_init( &(pvt->reset_sem), "Ne2kReset" ); hal_sem_init( &(pvt->recv_interrupt_sem), "mipsRecv" ); hal_sem_init( &(pvt->send_interrupt_sem), "mipsSend" ); mipsnet_reset(dev); if( hal_irq_alloc( irq, &mipsnet_interrupt, dev, HAL_IRQ_SHAREABLE ) ) { SHOW_ERROR( 0, "IRQ %d is busy", irq ); //goto free2; //free2: free(dev->drv_private); free(dev); return 0; } //pvt->thread = hal_start_kernel_thread_arg( mipsnet_thread, dev ); //mipsnet_ei(dev); //pvt->active = 1; ifnet *interface; if( if_register_interface( IF_TYPE_ETHERNET, &interface, dev) ) { SHOW_ERROR( 0, "Failed to register interface for %s", dev->name ); } else if_simple_setup(interface, WIRED_ADDRESS, WIRED_NETMASK, WIRED_BROADCAST, WIRED_NET, WIRED_ROUTER, DEF_ROUTE_ROUTER ); return dev; }