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; } }
static ssize_t mipsnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size) { MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque; #ifdef DEBUG_MIPSNET_RECEIVE printf("mipsnet: receiving len=%zu\n", size); #endif if (!mipsnet_can_receive(nc)) return -1; s->busy = 1; /* Just accept everything. */ /* Write packet data. */ memcpy(s->rx_buffer, buf, size); s->rx_count = size; s->rx_read = 0; /* Now we can signal we have received something. */ s->intctl |= MIPSNET_INTCTL_RXDONE; mipsnet_update_irq(s); return size; }
static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, size_t size) { MIPSnetState *s = DO_UPCAST(NICState, nc, nc)->opaque; trace_mipsnet_receive(size); if (!mipsnet_can_receive(nc)) return -1; s->busy = 1; /* Just accept everything. */ /* Write packet data. */ memcpy(s->rx_buffer, buf, size); s->rx_count = size; s->rx_read = 0; /* Now we can signal we have received something. */ s->intctl |= MIPSNET_INTCTL_RXDONE; mipsnet_update_irq(s); return size; }
static void mipsnet_receive(void *opaque, const uint8_t *buf, int size) { MIPSnetState *s = opaque; #ifdef DEBUG_MIPSNET_RECEIVE printf("mipsnet: receiving len=%d\n", size); #endif if (!mipsnet_can_receive(opaque)) return; s->busy = 1; /* Just accept everything. */ /* Write packet data. */ memcpy(s->rx_buffer, buf, size); s->rx_count = size; s->rx_read = 0; /* Now we can signal we have received something. */ s->intctl |= MIPSNET_INTCTL_RXDONE; mipsnet_update_irq(s); }