diff options
Diffstat (limited to 'hw/net')
-rw-r--r-- | hw/net/cadence_gem.c | 2 | ||||
-rw-r--r-- | hw/net/net_rx_pkt.c | 41 | ||||
-rw-r--r-- | hw/net/spapr_llan.c | 18 | ||||
-rw-r--r-- | hw/net/vmxnet3.c | 284 |
4 files changed, 130 insertions, 215 deletions
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index e99d4544a2..d4de8ad9f1 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -508,7 +508,7 @@ static void gem_update_int_status(CadenceGEMState *s) if ((s->num_priority_queues == 1) && s->regs[GEM_ISR]) { /* No priority queues, just trigger the interrupt */ - DB_PRINT("asserting int.\n", i); + DB_PRINT("asserting int.\n"); qemu_set_irq(s->irq[0], 1); return; } diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c index 1019b50c18..cef1c2e0d1 100644 --- a/hw/net/net_rx_pkt.c +++ b/hw/net/net_rx_pkt.c @@ -23,13 +23,13 @@ struct NetRxPkt { struct virtio_net_hdr virt_hdr; - uint8_t ehdr_buf[sizeof(struct eth_header)]; + uint8_t ehdr_buf[sizeof(struct eth_header) + sizeof(struct vlan_header)]; struct iovec *vec; uint16_t vec_len_total; uint16_t vec_len; uint32_t tot_len; uint16_t tci; - bool vlan_stripped; + size_t ehdr_buf_len; bool has_virt_hdr; eth_pkt_types_e packet_type; @@ -88,21 +88,21 @@ net_rx_pkt_pull_data(struct NetRxPkt *pkt, const struct iovec *iov, int iovcnt, size_t ploff) { - if (pkt->vlan_stripped) { + uint32_t pllen = iov_size(iov, iovcnt) - ploff; + + if (pkt->ehdr_buf_len) { net_rx_pkt_iovec_realloc(pkt, iovcnt + 1); pkt->vec[0].iov_base = pkt->ehdr_buf; - pkt->vec[0].iov_len = sizeof(pkt->ehdr_buf); - - pkt->tot_len = - iov_size(iov, iovcnt) - ploff + sizeof(struct eth_header); + pkt->vec[0].iov_len = pkt->ehdr_buf_len; + pkt->tot_len = pllen + pkt->ehdr_buf_len; pkt->vec_len = iov_copy(pkt->vec + 1, pkt->vec_len_total - 1, - iov, iovcnt, ploff, pkt->tot_len); + iov, iovcnt, ploff, pllen) + 1; } else { net_rx_pkt_iovec_realloc(pkt, iovcnt); - pkt->tot_len = iov_size(iov, iovcnt) - ploff; + pkt->tot_len = pllen; pkt->vec_len = iov_copy(pkt->vec, pkt->vec_len_total, iov, iovcnt, ploff, pkt->tot_len); } @@ -123,11 +123,12 @@ void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt, uint16_t tci = 0; uint16_t ploff = iovoff; assert(pkt); - pkt->vlan_stripped = false; if (strip_vlan) { - pkt->vlan_stripped = eth_strip_vlan(iov, iovcnt, iovoff, pkt->ehdr_buf, - &ploff, &tci); + pkt->ehdr_buf_len = eth_strip_vlan(iov, iovcnt, iovoff, pkt->ehdr_buf, + &ploff, &tci); + } else { + pkt->ehdr_buf_len = 0; } pkt->tci = tci; @@ -143,12 +144,13 @@ void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt, uint16_t tci = 0; uint16_t ploff = iovoff; assert(pkt); - pkt->vlan_stripped = false; if (strip_vlan) { - pkt->vlan_stripped = eth_strip_vlan_ex(iov, iovcnt, iovoff, vet, - pkt->ehdr_buf, - &ploff, &tci); + pkt->ehdr_buf_len = eth_strip_vlan_ex(iov, iovcnt, iovoff, vet, + pkt->ehdr_buf, + &ploff, &tci); + } else { + pkt->ehdr_buf_len = 0; } pkt->tci = tci; @@ -159,11 +161,10 @@ void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt, void net_rx_pkt_dump(struct NetRxPkt *pkt) { #ifdef NET_RX_PKT_DEBUG - NetRxPkt *pkt = (NetRxPkt *)pkt; assert(pkt); - printf("RX PKT: tot_len: %d, vlan_stripped: %d, vlan_tag: %d\n", - pkt->tot_len, pkt->vlan_stripped, pkt->tci); + printf("RX PKT: tot_len: %d, ehdr_buf_len: %lu, vlan_tag: %d\n", + pkt->tot_len, pkt->ehdr_buf_len, pkt->tci); #endif } @@ -426,7 +427,7 @@ bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt) { assert(pkt); - return pkt->vlan_stripped; + return pkt->ehdr_buf_len ? true : false; } bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt) diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c index 058908d8d7..d239e4bd7d 100644 --- a/hw/net/spapr_llan.c +++ b/hw/net/spapr_llan.c @@ -385,18 +385,24 @@ static int spapr_vlan_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off) int ret; /* Some old phyp versions give the mac address in an 8-byte - * property. The kernel driver has an insane workaround for this; + * property. The kernel driver (before 3.10) has an insane workaround; * rather than doing the obvious thing and checking the property * length, it checks whether the first byte has 0b10 in the low * bits. If a correct 6-byte property has a different first byte * the kernel will get the wrong mac address, overrunning its * buffer in the process (read only, thank goodness). * - * Here we workaround the kernel workaround by always supplying an - * 8-byte property, with the mac address in the last six bytes */ - memcpy(&padded_mac[2], &vdev->nicconf.macaddr, ETH_ALEN); - ret = fdt_setprop(fdt, node_off, "local-mac-address", - padded_mac, sizeof(padded_mac)); + * Here we return a 6-byte address unless that would break a pre-3.10 + * driver. In that case we return a padded 8-byte address to allow the old + * workaround to succeed. */ + if ((vdev->nicconf.macaddr.a[0] & 0x3) == 0x2) { + ret = fdt_setprop(fdt, node_off, "local-mac-address", + &vdev->nicconf.macaddr, ETH_ALEN); + } else { + memcpy(&padded_mac[2], &vdev->nicconf.macaddr, ETH_ALEN); + ret = fdt_setprop(fdt, node_off, "local-mac-address", + padded_mac, sizeof(padded_mac)); + } if (ret < 0) { return ret; } diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index e13a798b3b..8b1fab24fd 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -141,17 +141,17 @@ typedef struct VMXNET3Class { /* Cyclic ring abstraction */ typedef struct { hwaddr pa; - size_t size; - size_t cell_size; - size_t next; + uint32_t size; + uint32_t cell_size; + uint32_t next; uint8_t gen; } Vmxnet3Ring; static inline void vmxnet3_ring_init(PCIDevice *d, Vmxnet3Ring *ring, hwaddr pa, - size_t size, - size_t cell_size, + uint32_t size, + uint32_t cell_size, bool zero_region) { ring->pa = pa; @@ -166,7 +166,7 @@ static inline void vmxnet3_ring_init(PCIDevice *d, } #define VMXNET3_RING_DUMP(macro, ring_name, ridx, r) \ - macro("%s#%d: base %" PRIx64 " size %zu cell_size %zu gen %d next %zu", \ + macro("%s#%d: base %" PRIx64 " size %u cell_size %u gen %d next %u", \ (ring_name), (ridx), \ (r)->pa, (r)->size, (r)->cell_size, (r)->gen, (r)->next) @@ -2403,155 +2403,87 @@ static const VMStateDescription vmxstate_vmxnet3_mcast_list = { } }; -static void vmxnet3_get_ring_from_file(QEMUFile *f, Vmxnet3Ring *r) -{ - r->pa = qemu_get_be64(f); - r->size = qemu_get_be32(f); - r->cell_size = qemu_get_be32(f); - r->next = qemu_get_be32(f); - r->gen = qemu_get_byte(f); -} - -static void vmxnet3_put_ring_to_file(QEMUFile *f, Vmxnet3Ring *r) -{ - qemu_put_be64(f, r->pa); - qemu_put_be32(f, r->size); - qemu_put_be32(f, r->cell_size); - qemu_put_be32(f, r->next); - qemu_put_byte(f, r->gen); -} - -static void vmxnet3_get_tx_stats_from_file(QEMUFile *f, - struct UPT1_TxStats *tx_stat) -{ - tx_stat->TSOPktsTxOK = qemu_get_be64(f); - tx_stat->TSOBytesTxOK = qemu_get_be64(f); - tx_stat->ucastPktsTxOK = qemu_get_be64(f); - tx_stat->ucastBytesTxOK = qemu_get_be64(f); - tx_stat->mcastPktsTxOK = qemu_get_be64(f); - tx_stat->mcastBytesTxOK = qemu_get_be64(f); - tx_stat->bcastPktsTxOK = qemu_get_be64(f); - tx_stat->bcastBytesTxOK = qemu_get_be64(f); - tx_stat->pktsTxError = qemu_get_be64(f); - tx_stat->pktsTxDiscard = qemu_get_be64(f); -} - -static void vmxnet3_put_tx_stats_to_file(QEMUFile *f, - struct UPT1_TxStats *tx_stat) -{ - qemu_put_be64(f, tx_stat->TSOPktsTxOK); - qemu_put_be64(f, tx_stat->TSOBytesTxOK); - qemu_put_be64(f, tx_stat->ucastPktsTxOK); - qemu_put_be64(f, tx_stat->ucastBytesTxOK); - qemu_put_be64(f, tx_stat->mcastPktsTxOK); - qemu_put_be64(f, tx_stat->mcastBytesTxOK); - qemu_put_be64(f, tx_stat->bcastPktsTxOK); - qemu_put_be64(f, tx_stat->bcastBytesTxOK); - qemu_put_be64(f, tx_stat->pktsTxError); - qemu_put_be64(f, tx_stat->pktsTxDiscard); -} - -static int vmxnet3_get_txq_descr(QEMUFile *f, void *pv, size_t size, - VMStateField *field) -{ - Vmxnet3TxqDescr *r = pv; - - vmxnet3_get_ring_from_file(f, &r->tx_ring); - vmxnet3_get_ring_from_file(f, &r->comp_ring); - r->intr_idx = qemu_get_byte(f); - r->tx_stats_pa = qemu_get_be64(f); - - vmxnet3_get_tx_stats_from_file(f, &r->txq_stats); - - return 0; -} - -static int vmxnet3_put_txq_descr(QEMUFile *f, void *pv, size_t size, - VMStateField *field, QJSON *vmdesc) -{ - Vmxnet3TxqDescr *r = pv; - - vmxnet3_put_ring_to_file(f, &r->tx_ring); - vmxnet3_put_ring_to_file(f, &r->comp_ring); - qemu_put_byte(f, r->intr_idx); - qemu_put_be64(f, r->tx_stats_pa); - vmxnet3_put_tx_stats_to_file(f, &r->txq_stats); - - return 0; -} - -static const VMStateInfo txq_descr_info = { - .name = "txq_descr", - .get = vmxnet3_get_txq_descr, - .put = vmxnet3_put_txq_descr +static const VMStateDescription vmstate_vmxnet3_ring = { + .name = "vmxnet3-ring", + .version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT64(pa, Vmxnet3Ring), + VMSTATE_UINT32(size, Vmxnet3Ring), + VMSTATE_UINT32(cell_size, Vmxnet3Ring), + VMSTATE_UINT32(next, Vmxnet3Ring), + VMSTATE_UINT8(gen, Vmxnet3Ring), + VMSTATE_END_OF_LIST() + } }; -static void vmxnet3_get_rx_stats_from_file(QEMUFile *f, - struct UPT1_RxStats *rx_stat) -{ - rx_stat->LROPktsRxOK = qemu_get_be64(f); - rx_stat->LROBytesRxOK = qemu_get_be64(f); - rx_stat->ucastPktsRxOK = qemu_get_be64(f); - rx_stat->ucastBytesRxOK = qemu_get_be64(f); - rx_stat->mcastPktsRxOK = qemu_get_be64(f); - rx_stat->mcastBytesRxOK = qemu_get_be64(f); - rx_stat->bcastPktsRxOK = qemu_get_be64(f); - rx_stat->bcastBytesRxOK = qemu_get_be64(f); - rx_stat->pktsRxOutOfBuf = qemu_get_be64(f); - rx_stat->pktsRxError = qemu_get_be64(f); -} - -static void vmxnet3_put_rx_stats_to_file(QEMUFile *f, - struct UPT1_RxStats *rx_stat) -{ - qemu_put_be64(f, rx_stat->LROPktsRxOK); - qemu_put_be64(f, rx_stat->LROBytesRxOK); - qemu_put_be64(f, rx_stat->ucastPktsRxOK); - qemu_put_be64(f, rx_stat->ucastBytesRxOK); - qemu_put_be64(f, rx_stat->mcastPktsRxOK); - qemu_put_be64(f, rx_stat->mcastBytesRxOK); - qemu_put_be64(f, rx_stat->bcastPktsRxOK); - qemu_put_be64(f, rx_stat->bcastBytesRxOK); - qemu_put_be64(f, rx_stat->pktsRxOutOfBuf); - qemu_put_be64(f, rx_stat->pktsRxError); -} - -static int vmxnet3_get_rxq_descr(QEMUFile *f, void *pv, size_t size, - VMStateField *field) -{ - Vmxnet3RxqDescr *r = pv; - int i; - - for (i = 0; i < VMXNET3_RX_RINGS_PER_QUEUE; i++) { - vmxnet3_get_ring_from_file(f, &r->rx_ring[i]); +static const VMStateDescription vmstate_vmxnet3_tx_stats = { + .name = "vmxnet3-tx-stats", + .version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT64(TSOPktsTxOK, struct UPT1_TxStats), + VMSTATE_UINT64(TSOBytesTxOK, struct UPT1_TxStats), + VMSTATE_UINT64(ucastPktsTxOK, struct UPT1_TxStats), + VMSTATE_UINT64(ucastBytesTxOK, struct UPT1_TxStats), + VMSTATE_UINT64(mcastPktsTxOK, struct UPT1_TxStats), + VMSTATE_UINT64(mcastBytesTxOK, struct UPT1_TxStats), + VMSTATE_UINT64(bcastPktsTxOK, struct UPT1_TxStats), + VMSTATE_UINT64(bcastBytesTxOK, struct UPT1_TxStats), + VMSTATE_UINT64(pktsTxError, struct UPT1_TxStats), + VMSTATE_UINT64(pktsTxDiscard, struct UPT1_TxStats), + VMSTATE_END_OF_LIST() } +}; - vmxnet3_get_ring_from_file(f, &r->comp_ring); - r->intr_idx = qemu_get_byte(f); - r->rx_stats_pa = qemu_get_be64(f); - - vmxnet3_get_rx_stats_from_file(f, &r->rxq_stats); - - return 0; -} - -static int vmxnet3_put_rxq_descr(QEMUFile *f, void *pv, size_t size, - VMStateField *field, QJSON *vmdesc) -{ - Vmxnet3RxqDescr *r = pv; - int i; - - for (i = 0; i < VMXNET3_RX_RINGS_PER_QUEUE; i++) { - vmxnet3_put_ring_to_file(f, &r->rx_ring[i]); +static const VMStateDescription vmstate_vmxnet3_txq_descr = { + .name = "vmxnet3-txq-descr", + .version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(tx_ring, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_ring, + Vmxnet3Ring), + VMSTATE_STRUCT(comp_ring, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_ring, + Vmxnet3Ring), + VMSTATE_UINT8(intr_idx, Vmxnet3TxqDescr), + VMSTATE_UINT64(tx_stats_pa, Vmxnet3TxqDescr), + VMSTATE_STRUCT(txq_stats, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_tx_stats, + struct UPT1_TxStats), + VMSTATE_END_OF_LIST() } +}; - vmxnet3_put_ring_to_file(f, &r->comp_ring); - qemu_put_byte(f, r->intr_idx); - qemu_put_be64(f, r->rx_stats_pa); - vmxnet3_put_rx_stats_to_file(f, &r->rxq_stats); +static const VMStateDescription vmstate_vmxnet3_rx_stats = { + .name = "vmxnet3-rx-stats", + .version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT64(LROPktsRxOK, struct UPT1_RxStats), + VMSTATE_UINT64(LROBytesRxOK, struct UPT1_RxStats), + VMSTATE_UINT64(ucastPktsRxOK, struct UPT1_RxStats), + VMSTATE_UINT64(ucastBytesRxOK, struct UPT1_RxStats), + VMSTATE_UINT64(mcastPktsRxOK, struct UPT1_RxStats), + VMSTATE_UINT64(mcastBytesRxOK, struct UPT1_RxStats), + VMSTATE_UINT64(bcastPktsRxOK, struct UPT1_RxStats), + VMSTATE_UINT64(bcastBytesRxOK, struct UPT1_RxStats), + VMSTATE_UINT64(pktsRxOutOfBuf, struct UPT1_RxStats), + VMSTATE_UINT64(pktsRxError, struct UPT1_RxStats), + VMSTATE_END_OF_LIST() + } +}; - return 0; -} +static const VMStateDescription vmstate_vmxnet3_rxq_descr = { + .name = "vmxnet3-rxq-descr", + .version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(rx_ring, Vmxnet3RxqDescr, + VMXNET3_RX_RINGS_PER_QUEUE, 0, + vmstate_vmxnet3_ring, Vmxnet3Ring), + VMSTATE_STRUCT(comp_ring, Vmxnet3RxqDescr, 0, vmstate_vmxnet3_ring, + Vmxnet3Ring), + VMSTATE_UINT8(intr_idx, Vmxnet3RxqDescr), + VMSTATE_UINT64(rx_stats_pa, Vmxnet3RxqDescr), + VMSTATE_STRUCT(rxq_stats, Vmxnet3RxqDescr, 0, vmstate_vmxnet3_rx_stats, + struct UPT1_RxStats), + VMSTATE_END_OF_LIST() + } +}; static int vmxnet3_post_load(void *opaque, int version_id) { @@ -2577,40 +2509,15 @@ static int vmxnet3_post_load(void *opaque, int version_id) return 0; } -static const VMStateInfo rxq_descr_info = { - .name = "rxq_descr", - .get = vmxnet3_get_rxq_descr, - .put = vmxnet3_put_rxq_descr -}; - -static int vmxnet3_get_int_state(QEMUFile *f, void *pv, size_t size, - VMStateField *field) -{ - Vmxnet3IntState *r = pv; - - r->is_masked = qemu_get_byte(f); - r->is_pending = qemu_get_byte(f); - r->is_asserted = qemu_get_byte(f); - - return 0; -} - -static int vmxnet3_put_int_state(QEMUFile *f, void *pv, size_t size, - VMStateField *field, QJSON *vmdesc) -{ - Vmxnet3IntState *r = pv; - - qemu_put_byte(f, r->is_masked); - qemu_put_byte(f, r->is_pending); - qemu_put_byte(f, r->is_asserted); - - return 0; -} - -static const VMStateInfo int_state_info = { - .name = "int_state", - .get = vmxnet3_get_int_state, - .put = vmxnet3_put_int_state +static const VMStateDescription vmstate_vmxnet3_int_state = { + .name = "vmxnet3-int-state", + .version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_BOOL(is_masked, Vmxnet3IntState), + VMSTATE_BOOL(is_pending, Vmxnet3IntState), + VMSTATE_BOOL(is_asserted, Vmxnet3IntState), + VMSTATE_END_OF_LIST() + } }; static bool vmxnet3_vmstate_need_pcie_device(void *opaque) @@ -2667,14 +2574,15 @@ static const VMStateDescription vmstate_vmxnet3 = { VMSTATE_UINT64(drv_shmem, VMXNET3State), VMSTATE_UINT64(temp_shared_guest_driver_memory, VMXNET3State), - VMSTATE_ARRAY(txq_descr, VMXNET3State, - VMXNET3_DEVICE_MAX_TX_QUEUES, 0, txq_descr_info, + VMSTATE_STRUCT_ARRAY(txq_descr, VMXNET3State, + VMXNET3_DEVICE_MAX_TX_QUEUES, 0, vmstate_vmxnet3_txq_descr, Vmxnet3TxqDescr), - VMSTATE_ARRAY(rxq_descr, VMXNET3State, - VMXNET3_DEVICE_MAX_RX_QUEUES, 0, rxq_descr_info, + VMSTATE_STRUCT_ARRAY(rxq_descr, VMXNET3State, + VMXNET3_DEVICE_MAX_RX_QUEUES, 0, vmstate_vmxnet3_rxq_descr, Vmxnet3RxqDescr), - VMSTATE_ARRAY(interrupt_states, VMXNET3State, VMXNET3_MAX_INTRS, - 0, int_state_info, Vmxnet3IntState), + VMSTATE_STRUCT_ARRAY(interrupt_states, VMXNET3State, + VMXNET3_MAX_INTRS, 0, vmstate_vmxnet3_int_state, + Vmxnet3IntState), VMSTATE_END_OF_LIST() }, |