Commit 4f1c942b authored by Mark McLoughlin's avatar Mark McLoughlin
Browse files

net: add return value to packet receive handler



This allows us to handle queue full conditions rather than dropping
the packet on the floor.

Signed-off-by: default avatarMark McLoughlin <markmc@redhat.com>
parent e3f5ec2b
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -725,7 +725,7 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size)
    return -1;
}

static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)
{
    uint16_t data[10];
    dp8393xState *s = vc->opaque;
@@ -742,7 +742,7 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t 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(VLANClientState *vc, const uint8_t * buf, size_t 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(VLANClientState *vc, const uint8_t * buf, size_t size)

    /* Done */
    dp8393x_update_irq(s);

    return size;
}

static void nic_reset(void *opaque)
+8 −6
Original line number Diff line number Diff line
@@ -599,7 +599,7 @@ e1000_can_receive(VLANClientState *vc)
    return (s->mac_reg[RCTL] & E1000_RCTL_EN);
}

static void
static ssize_t
e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
{
    E1000State *s = vc->opaque;
@@ -611,16 +611,16 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t 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 (%lu > %d)\n",
               (unsigned long)size, s->rxbuf_size);
        return;
        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)));
@@ -635,7 +635,7 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t 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];
@@ -659,7 +659,7 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t 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);

@@ -677,6 +677,8 @@ e1000_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
        n |= E1000_ICS_RXDMT0;

    set_ics(s, 0, n);

    return size;
}

static uint32_t
+8 −7
Original line number Diff line number Diff line
@@ -1441,7 +1441,7 @@ static int nic_can_receive(VLANClientState *vc)
    //~ return !eepro100_buffer_full(s);
}

static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t 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.
@@ -1458,18 +1458,18 @@ static void nic_receive(VLANClientState *vc, const uint8_t * buf, size_t 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(VLANClientState *vc, const uint8_t * buf, size_t 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(VLANClientState *vc, const uint8_t * buf, size_t 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(VLANClientState *vc, const uint8_t * buf, size_t 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(VLANClientState *vc, const uint8_t * buf, size_t size)
        /* S bit is set. */
        set_ru_state(s, ru_suspended);
    }
    return size;
}

static int nic_load(QEMUFile * f, void *opaque, int version_id)
+5 −3
Original line number Diff line number Diff line
@@ -501,7 +501,7 @@ static int eth_can_receive(VLANClientState *vc)
	return 1;
}

static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t 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 = vc->opaque;
@@ -510,7 +510,7 @@ static void eth_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
	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(VLANClientState *vc, const uint8_t *buf, size_t 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)
+2 −1
Original line number Diff line number Diff line
@@ -353,7 +353,7 @@ static int mcf_fec_can_receive(VLANClientState *vc)
    return s->rx_enabled;
}

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

static CPUReadMemoryFunc *mcf_fec_readfn[] = {
Loading