int buffed_rx;
int tx_disabled; /* stop TX pkts from guest */
- uint64_t pkt_sent, pkt_recv, pkt_drop;
+ struct nic_statistics statistics;
struct v3_dev_net_ops * net_ops;
v3_lock_t rx_lock, tx_lock;
PrintError("Virtio NIC: Failure to init locks for net_state\n");
}
- virtio->pkt_sent = virtio->pkt_recv = virtio->pkt_drop = 0;
virtio->buffed_rx = 0;
return 0;
return -ERR_VIRTIO_OTHER;
}
- return virtio->net_ops->send(buf, len, virtio->backend_data);
+ if(virtio->net_ops->send(buf, len, virtio->backend_data) >= 0){
+ virtio->statistics.tx_pkts ++;
+ virtio->statistics.tx_bytes += len;
+
+ return 0;
+ }
+
+ virtio->statistics.tx_dropped ++;
+
+ return -1;
}
if(virtio->net_ops->start_rx != NULL){
virtio->net_ops->start_rx(virtio->backend_data);
}
- //disable_cb(&virtio->rx_vq);
+ //disable_cb(&virtio->rx_vq);
v3_unlock_irqrestore(virtio->rx_lock, flags);
req_len += buf_desc->length;
desc_idx = buf_desc->next;
}
- virtio_state->pkt_sent ++;
- recved ++;
q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
q->used->ring[q->used->index % q->queue_size].length = req_len; // What do we set this to????
if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
v3_pci_raise_irq(virtio_state->virtio_dev->pci_bus, 0, virtio_state->pci_dev);
virtio_state->virtio_cfg.pci_isr = 0x1;
+
+ virtio_state->statistics.interrupts ++;
}
return 0;
flags = v3_lock_irqsave(virtio->rx_lock);
- virtio->pkt_recv ++;
if (!raw)
data_len -= hdr_len;
}
virtio->buffed_rx = 0;
}
+
+ virtio->statistics.rx_pkts ++;
+ virtio->statistics.rx_bytes += size;
} else {
- virtio->pkt_drop++;
+ virtio->statistics.rx_dropped ++;
+
/* RX queue is full, tell backend to stop RX on this device */
virtio->net_ops->stop_rx(virtio->backend_data);
enable_cb(&virtio->rx_vq);
PrintDebug("Raising IRQ %d\n", virtio->pci_dev->config_header.intr_line);
v3_pci_raise_irq(virtio->virtio_dev->pci_bus, 0, virtio->pci_dev);
virtio->virtio_cfg.pci_isr = 0x1;
+
+ virtio->statistics.interrupts ++;
}
ret_val = offset;
uint8_t mcast_addr[8];
uint8_t mac[ETH_ALEN];
+ struct nic_statistics statistics;
+
struct v3_dev_net_ops *net_ops;
void * backend_data;
};
v3_pci_raise_irq(nic_state->pci_bus, 0, nic_state->pci_dev);
}
+ nic_state->statistics.interrupts ++;
+
PrintDebug("NE2000: Raise IRQ\n");
}
return 0;
}
-static int ne2k_send_packet(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) {
+static int tx_one_pkt(struct ne2k_state * nic_state, uchar_t *pkt, uint32_t length) {
#ifdef CONFIG_DEBUG_NE2K
PrintDebug("NE2000: Send Packet:\n");
v3_hexdump(pkt, length, NULL, 0);
#endif
- return nic_state->net_ops->send(pkt, length, nic_state->backend_data);
+ if(nic_state->net_ops->send(pkt, length, nic_state->backend_data) >= 0){
+ nic_state->statistics.tx_pkts ++;
+ nic_state->statistics.tx_bytes += length;
+
+ return 0;
+ }
+
+ nic_state->statistics.tx_dropped ++;
+
+ return -1;
}
static int ne2k_rxbuf_full(struct ne2k_registers * regs) {
#endif
if(!rx_one_pkt(nic_state, buf, size)){
+ nic_state->statistics.rx_pkts ++;
+ nic_state->statistics.rx_bytes += size;
+
return 0;
}
-
+
+ nic_state->statistics.rx_dropped ++;
+
return -1;
}
}
if (offset + regs->tbcr <= NE2K_PMEM_END) {
- ne2k_send_packet(nic_state, nic_state->mem + offset, regs->tbcr);
+ tx_one_pkt(nic_state, nic_state->mem + offset, regs->tbcr);
}
regs->tsr.val = 0; /* clear the tx status reg */