Commit f8e76fbf authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge branch 'net-queue'



* net-queue: (28 commits)
  virtio-net: Increase filter and control limits
  virtio-net: Add new RX filter controls
  virtio-net: MAC filter optimization
  virtio-net: Fix MAC filter overflow handling
  virtio-net: reorganize receive_filter()
  virtio-net: Use a byte to store RX mode flags
  virtio-net: Add version_id 7 placeholder for vnet header support
  virtio-net: implement rx packet queueing
  net: make use of async packet sending API in tap client
  net: add qemu_send_packet_async()
  net: split out packet queueing and flushing into separate functions
  net: return status from qemu_deliver_packet()
  net: add return value to packet receive handler
  net: pass VLANClientState* as first arg to receive handlers
  net: re-name vc->fd_read() to vc->receive()
  net: add fd_readv() handler to qemu_new_vlan_client() args
  net: only read from tapfd when we can send
  net: vlan clients with no fd_can_read() can always receive
  net: move the tap buffer into TAPState
  net: factor tap_read_packet() out of tap_send()
  ...

Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parents b319820d 4ffb17f5
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -407,9 +407,9 @@ static void do_transmit_packets(dp8393xState *s)
        if (s->regs[SONIC_RCR] & (SONIC_RCR_LB1 | SONIC_RCR_LB0)) {
            /* Loopback */
            s->regs[SONIC_TCR] |= SONIC_TCR_CRSL;
            if (s->vc->fd_can_read(s)) {
            if (s->vc->can_receive(s->vc)) {
                s->loopback_packet = 1;
                s->vc->fd_read(s, s->tx_buffer, tx_len);
                s->vc->receive(s->vc, s->tx_buffer, tx_len);
            }
        } else {
            /* Transmit packet */
@@ -676,9 +676,9 @@ static CPUWriteMemoryFunc *dp8393x_write[3] = {
    dp8393x_writel,
};

static int nic_can_receive(void *opaque)
static int nic_can_receive(VLANClientState *vc)
{
    dp8393xState *s = opaque;
    dp8393xState *s = vc->opaque;

    if (!(s->regs[SONIC_CR] & SONIC_CR_RXEN))
        return 0;
@@ -725,10 +725,10 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size)
    return -1;
}

static void nic_receive(void *opaque, const uint8_t * buf, int size)
static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
{
    uint16_t data[10];
    dp8393xState *s = opaque;
    dp8393xState *s = vc->opaque;
    int packet_type;
    uint32_t available, address;
    int width, rx_len = size;
@@ -742,7 +742,7 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
    packet_type = receive_filter(s, buf, size);
    if (packet_type < 0) {
        DPRINTF("packet not for netcard\n");
        return;
        return -1;
    }

    /* XXX: Check byte ordering */
@@ -755,7 +755,7 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
        s->memory_rw(s->mem_opaque, address, (uint8_t*)data, size, 0);
        if (data[0 * width] & 0x1) {
            /* Still EOL ; stop reception */
            return;
            return -1;
        } else {
            s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
        }
@@ -833,6 +833,8 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)

    /* Done */
    dp8393x_update_irq(s);

    return size;
}

static void nic_reset(void *opaque)
@@ -888,8 +890,8 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
    s->watchdog = qemu_new_timer(vm_clock, dp8393x_watchdog, s);
    s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */

    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
                                 nic_receive, nic_can_receive, nic_cleanup, s);
    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, nic_can_receive,
                                 nic_receive, NULL, nic_cleanup, s);

    qemu_format_nic_info_str(s->vc, nd->macaddr);
    qemu_register_reset(nic_reset, 0, s);
+16 −14
Original line number Diff line number Diff line
@@ -598,17 +598,17 @@ e1000_set_link_status(VLANClientState *vc)
}

static int
e1000_can_receive(void *opaque)
e1000_can_receive(VLANClientState *vc)
{
    E1000State *s = opaque;
    E1000State *s = vc->opaque;

    return (s->mac_reg[RCTL] & E1000_RCTL_EN);
}

static void
e1000_receive(void *opaque, const uint8_t *buf, int size)
static ssize_t
e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
{
    E1000State *s = opaque;
    E1000State *s = vc->opaque;
    struct e1000_rx_desc desc;
    target_phys_addr_t base;
    unsigned int n, rdt;
@@ -617,16 +617,16 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
    uint8_t vlan_status = 0, vlan_offset = 0;

    if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
        return;
        return -1;

    if (size > s->rxbuf_size) {
        DBGOUT(RX, "packet too large for buffers (%d > %d)\n", size,
               s->rxbuf_size);
        return;
        DBGOUT(RX, "packet too large for buffers (%lu > %d)\n",
               (unsigned long)size, s->rxbuf_size);
        return -1;
    }

    if (!receive_filter(s, buf, size))
        return;
        return size;

    if (vlan_enabled(s) && is_vlan_packet(s, buf)) {
        vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));
@@ -641,7 +641,7 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
    do {
        if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
            set_ics(s, 0, E1000_ICS_RXO);
            return;
            return -1;
        }
        base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
               sizeof(desc) * s->mac_reg[RDH];
@@ -665,7 +665,7 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
            DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
                   rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
            set_ics(s, 0, E1000_ICS_RXO);
            return;
            return -1;
        }
    } while (desc.buffer_addr == 0);

@@ -683,6 +683,8 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
        n |= E1000_ICS_RXDMT0;

    set_ics(s, 0, n);

    return size;
}

static uint32_t
@@ -1119,8 +1121,8 @@ static void pci_e1000_init(PCIDevice *pci_dev)
    d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;

    d->vc = qdev_get_vlan_client(&d->dev.qdev,
                                 e1000_receive, e1000_can_receive,
                                 e1000_cleanup, d);
                                 e1000_can_receive, e1000_receive,
                                 NULL, e1000_cleanup, d);
    d->vc->link_status_changed = e1000_set_link_status;

    qemu_format_nic_info_str(d->vc, macaddr);
+12 −11
Original line number Diff line number Diff line
@@ -1433,21 +1433,21 @@ static void pci_mmio_map(PCIDevice * pci_dev, int region_num,
    }
}

static int nic_can_receive(void *opaque)
static int nic_can_receive(VLANClientState *vc)
{
    EEPRO100State *s = opaque;
    EEPRO100State *s = vc->opaque;
    logout("%p\n", s);
    return get_ru_state(s) == ru_ready;
    //~ return !eepro100_buffer_full(s);
}

static void nic_receive(void *opaque, const uint8_t * buf, int size)
static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
{
    /* TODO:
     * - Magic packets should set bit 30 in power management driver register.
     * - Interesting packets should set bit 29 in power management driver register.
     */
    EEPRO100State *s = opaque;
    EEPRO100State *s = vc->opaque;
    uint16_t rfd_status = 0xa000;
    static const uint8_t broadcast_macaddr[6] =
        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -1458,18 +1458,18 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
    if (s->configuration[8] & 0x80) {
        /* CSMA is disabled. */
        logout("%p received while CSMA is disabled\n", s);
        return;
        return -1;
    } else if (size < 64 && (s->configuration[7] & 1)) {
        /* Short frame and configuration byte 7/0 (discard short receive) set:
         * Short frame is discarded */
        logout("%p received short frame (%d byte)\n", s, size);
        s->statistics.rx_short_frame_errors++;
        //~ return;
        //~ return -1;
    } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) {
        /* Long frame and configuration byte 18/3 (long receive ok) not set:
         * Long frames are discarded. */
        logout("%p received long frame (%d byte), ignored\n", s, size);
        return;
        return -1;
    } else if (memcmp(buf, s->macaddr, 6) == 0) {       // !!!
        /* Frame matches individual address. */
        /* TODO: check configuration byte 15/4 (ignore U/L). */
@@ -1485,7 +1485,7 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
        assert(!(s->configuration[21] & BIT(3)));
        int mcast_idx = compute_mcast_idx(buf);
        if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
            return;
            return size;
        }
        rfd_status |= 0x0002;
    } else if (s->configuration[15] & 1) {
@@ -1495,7 +1495,7 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
    } else {
        logout("%p received frame, ignored, len=%d,%s\n", s, size,
               nic_dump(buf, size));
        return;
        return size;
    }

    if (get_ru_state(s) != ru_ready) {
@@ -1503,7 +1503,7 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
        logout("no ressources, state=%u\n", get_ru_state(s));
        s->statistics.rx_resource_errors++;
        //~ assert(!"no ressources");
        return;
        return -1;
    }
    //~ !!!
//~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 <repeats 1518 times>}}
@@ -1540,6 +1540,7 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
        /* S bit is set. */
        set_ru_state(s, ru_suspended);
    }
    return size;
}

static int nic_load(QEMUFile * f, void *opaque, int version_id)
@@ -1766,7 +1767,7 @@ static void nic_init(PCIDevice *pci_dev, uint32_t device)
    nic_reset(s);

    s->vc = qdev_get_vlan_client(&d->dev.qdev,
                                 nic_receive, nic_can_receive,
                                 nic_can_receive, nic_receive, NULL,
                                 nic_cleanup, s);

    qemu_format_nic_info_str(s->vc, s->macaddr);
+8 −6
Original line number Diff line number Diff line
@@ -496,21 +496,21 @@ static int eth_match_groupaddr(struct fs_eth *eth, const unsigned char *sa)
	return match;
}

static int eth_can_receive(void *opaque)
static int eth_can_receive(VLANClientState *vc)
{
	return 1;
}

static void eth_receive(void *opaque, const uint8_t *buf, int size)
static ssize_t eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
{
	unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	struct fs_eth *eth = opaque;
	struct fs_eth *eth = vc->opaque;
	int use_ma0 = eth->regs[RW_REC_CTRL] & 1;
	int use_ma1 = eth->regs[RW_REC_CTRL] & 2;
	int r_bcast = eth->regs[RW_REC_CTRL] & 8;

	if (size < 12)
		return;
		return -1;

	D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n",
		 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
@@ -521,10 +521,12 @@ static void eth_receive(void *opaque, const uint8_t *buf, int size)
	    && (!use_ma1 || memcmp(buf, eth->macaddr[1], 6))
	    && (!r_bcast || memcmp(buf, sa_bcast, 6))
	    && !eth_match_groupaddr(eth, buf))
		return;
		return size;

	/* FIXME: Find another way to pass on the fake csum.  */
	etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1);

        return size;
}

static int eth_tx_push(void *opaque, unsigned char *buf, int len)
@@ -593,7 +595,7 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
	cpu_register_physical_memory (base, 0x5c, eth->ethregs);

	eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
				       eth_receive, eth_can_receive,
				       eth_can_receive, eth_receive, NULL,
				       eth_cleanup, eth);
	eth->vc->opaque = eth;
	eth->vc->link_status_changed = eth_set_link;
+6 −5
Original line number Diff line number Diff line
@@ -347,15 +347,15 @@ static void mcf_fec_write(void *opaque, target_phys_addr_t addr, uint32_t value)
    mcf_fec_update(s);
}

static int mcf_fec_can_receive(void *opaque)
static int mcf_fec_can_receive(VLANClientState *vc)
{
    mcf_fec_state *s = (mcf_fec_state *)opaque;
    mcf_fec_state *s = vc->opaque;
    return s->rx_enabled;
}

static void mcf_fec_receive(void *opaque, const uint8_t *buf, int size)
static ssize_t mcf_fec_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
{
    mcf_fec_state *s = (mcf_fec_state *)opaque;
    mcf_fec_state *s = vc->opaque;
    mcf_fec_bd bd;
    uint32_t flags = 0;
    uint32_t addr;
@@ -426,6 +426,7 @@ static void mcf_fec_receive(void *opaque, const uint8_t *buf, int size)
    s->rx_descriptor = addr;
    mcf_fec_enable_rx(s);
    mcf_fec_update(s);
    return size;
}

static CPUReadMemoryFunc *mcf_fec_readfn[] = {
@@ -462,7 +463,7 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
    cpu_register_physical_memory(base, 0x400, s->mmio_index);

    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
                                 mcf_fec_receive, mcf_fec_can_receive,
                                 mcf_fec_can_receive, mcf_fec_receive, NULL,
                                 mcf_fec_cleanup, s);
    memcpy(s->macaddr, nd->macaddr, 6);
    qemu_format_nic_info_str(s->vc, s->macaddr);
Loading