#include "virtqueue.h"
#include "virtio_rxtx.h"
-static int eth_virtio_dev_init(struct rte_eth_dev *eth_dev);
static int eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev);
static int virtio_dev_configure(struct rte_eth_dev *dev);
static int virtio_dev_start(struct rte_eth_dev *dev);
* One RX packet for ACK.
*/
vq->vq_ring.desc[head].flags = VRING_DESC_F_NEXT;
- vq->vq_ring.desc[head].addr = cvq->virtio_net_hdr_mz->phys_addr;
+ vq->vq_ring.desc[head].addr = cvq->virtio_net_hdr_mem;
vq->vq_ring.desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
vq->vq_free_cnt--;
i = vq->vq_ring.desc[head].next;
for (k = 0; k < pkt_num; k++) {
vq->vq_ring.desc[i].flags = VRING_DESC_F_NEXT;
- vq->vq_ring.desc[i].addr = cvq->virtio_net_hdr_mz->phys_addr
+ vq->vq_ring.desc[i].addr = cvq->virtio_net_hdr_mem
+ sizeof(struct virtio_net_ctrl_hdr)
+ sizeof(ctrl->status) + sizeof(uint8_t)*sum;
vq->vq_ring.desc[i].len = dlen[k];
}
vq->vq_ring.desc[i].flags = VRING_DESC_F_WRITE;
- vq->vq_ring.desc[i].addr = cvq->virtio_net_hdr_mz->phys_addr
+ vq->vq_ring.desc[i].addr = cvq->virtio_net_hdr_mem
+ sizeof(struct virtio_net_ctrl_hdr);
vq->vq_ring.desc[i].len = sizeof(ctrl->status);
vq->vq_free_cnt--;
virtqueue_notify(vq);
rte_rmb();
- while (vq->vq_used_cons_idx == vq->vq_ring.used->idx) {
+ while (VIRTQUEUE_NUSED(vq) == 0) {
rte_rmb();
usleep(100);
}
- while (vq->vq_used_cons_idx != vq->vq_ring.used->idx) {
+ while (VIRTQUEUE_NUSED(vq)) {
uint32_t idx, desc_idx, used_idx;
struct vring_used_elem *uep;
const struct rte_memzone *mz = NULL, *hdr_mz = NULL;
unsigned int vq_size, size;
struct virtio_hw *hw = dev->data->dev_private;
- struct virtnet_rx *rxvq;
- struct virtnet_tx *txvq;
- struct virtnet_ctl *cvq;
+ struct virtnet_rx *rxvq = NULL;
+ struct virtnet_tx *txvq = NULL;
+ struct virtnet_ctl *cvq = NULL;
struct virtqueue *vq;
const char *queue_names[] = {"rvq", "txq", "cvq"};
size_t sz_vq, sz_q = 0, sz_hdr_mz = 0;
}
}
- /*
- * Virtio PCI device VIRTIO_PCI_QUEUE_PF register is 32bit,
- * and only accepts 32 bit page frame number.
- * Check if the allocated physical memory exceeds 16TB.
- */
- if ((mz->phys_addr + vq->vq_ring_size - 1) >> (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) {
- PMD_INIT_LOG(ERR, "vring address shouldn't be above 16TB!");
- ret = -ENOMEM;
- goto fail_q_alloc;
- }
memset(mz->addr, 0, sizeof(mz->len));
vq->vq_ring_mem = mz->phys_addr;
rxvq->mz = mz;
*pvq = rxvq;
} else if (queue_type == VTNET_TQ) {
- struct virtio_tx_region *txr;
- unsigned int i;
-
txvq = (struct virtnet_tx *)RTE_PTR_ADD(vq, sz_vq);
txvq->vq = vq;
txvq->port_id = dev->data->port_id;
txvq->virtio_net_hdr_mz = hdr_mz;
txvq->virtio_net_hdr_mem = hdr_mz->phys_addr;
+ *pvq = txvq;
+ } else if (queue_type == VTNET_CQ) {
+ cvq = (struct virtnet_ctl *)RTE_PTR_ADD(vq, sz_vq);
+ cvq->vq = vq;
+ cvq->mz = mz;
+ cvq->virtio_net_hdr_mz = hdr_mz;
+ cvq->virtio_net_hdr_mem = hdr_mz->phys_addr;
+ memset(cvq->virtio_net_hdr_mz->addr, 0, PAGE_SIZE);
+ *pvq = cvq;
+ }
+
+ /* For virtio-user case (that is when dev->pci_dev is NULL), we use
+ * virtual address. And we need properly set _offset_, please see
+ * MBUF_DATA_DMA_ADDR in virtqueue.h for more information.
+ */
+ if (dev->pci_dev)
+ vq->offset = offsetof(struct rte_mbuf, buf_physaddr);
+ else {
+ vq->vq_ring_mem = (uintptr_t)mz->addr;
+ vq->offset = offsetof(struct rte_mbuf, buf_addr);
+ if (queue_type == VTNET_TQ)
+ txvq->virtio_net_hdr_mem = (uintptr_t)hdr_mz->addr;
+ else if (queue_type == VTNET_CQ)
+ cvq->virtio_net_hdr_mem = (uintptr_t)hdr_mz->addr;
+ }
+
+ if (queue_type == VTNET_TQ) {
+ struct virtio_tx_region *txr;
+ unsigned int i;
+
txr = hdr_mz->addr;
memset(txr, 0, vq_size * sizeof(*txr));
for (i = 0; i < vq_size; i++) {
start_dp->len = hw->vtnet_hdr_size;
start_dp->flags = VRING_DESC_F_NEXT;
}
+ }
- *pvq = txvq;
- } else if (queue_type == VTNET_CQ) {
- cvq = (struct virtnet_ctl *)RTE_PTR_ADD(vq, sz_vq);
- cvq->vq = vq;
- cvq->mz = mz;
- cvq->virtio_net_hdr_mz = hdr_mz;
- cvq->virtio_net_hdr_mem = hdr_mz->phys_addr;
- memset(cvq->virtio_net_hdr_mz->addr, 0, PAGE_SIZE);
- *pvq = cvq;
+ if (hw->vtpci_ops->setup_queue(hw, vq) < 0) {
+ PMD_INIT_LOG(ERR, "setup_queue failed");
+ virtio_dev_queue_release(vq);
+ return -EINVAL;
}
- hw->vtpci_ops->setup_queue(hw, vq);
vq->configured = 1;
return 0;
unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_TXQ_XSTATS +
dev->data->nb_rx_queues * VIRTIO_NB_RXQ_XSTATS;
- if (xstats_names == NULL) {
+ if (xstats_names != NULL) {
/* Note: limit checked in rte_eth_xstats_names() */
for (i = 0; i < dev->data->nb_rx_queues; i++) {
sizeof(xstats_names[count].name),
"rx_q%u_%s", i,
rte_virtio_rxq_stat_strings[t].name);
- xstats_names[count].id = count;
count++;
}
}
sizeof(xstats_names[count].name),
"tx_q%u_%s", i,
rte_virtio_txq_stat_strings[t].name);
- xstats_names[count].id = count;
count++;
}
}
unsigned t;
for (t = 0; t < VIRTIO_NB_RXQ_XSTATS; t++) {
- xstats[count].id = count;
xstats[count].value = *(uint64_t *)(((char *)rxvq) +
rte_virtio_rxq_stat_strings[t].offset);
count++;
unsigned t;
for (t = 0; t < VIRTIO_NB_TXQ_XSTATS; t++) {
- xstats[count].id = count;
xstats[count].value = *(uint64_t *)(((char *)txvq) +
rte_virtio_txq_stat_strings[t].offset);
count++;
* This function is based on probe() function in virtio_pci.c
* It returns 0 on success.
*/
-static int
+int
eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
{
struct virtio_hw *hw = eth_dev->data->dev_private;
pci_dev = eth_dev->pci_dev;
- ret = vtpci_init(pci_dev, hw, &dev_flags);
- if (ret)
- return ret;
+ if (pci_dev) {
+ ret = vtpci_init(pci_dev, hw, &dev_flags);
+ if (ret)
+ return ret;
+ }
/* Reset the device although not necessary at startup */
vtpci_reset(hw);
PMD_INIT_LOG(DEBUG, "hw->max_rx_queues=%d hw->max_tx_queues=%d",
hw->max_rx_queues, hw->max_tx_queues);
- PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
+ if (pci_dev)
+ PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
eth_dev->data->port_id, pci_dev->id.vendor_id,
pci_dev->id.device_id);
{
struct virtio_hw *hw = dev->data->dev_private;
- dev_info->driver_name = dev->driver->pci_drv.name;
+ if (dev->pci_dev)
+ dev_info->driver_name = dev->driver->pci_drv.name;
+ else
+ dev_info->driver_name = "virtio-user PMD";
dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
dev_info->min_rx_bufsize = VIRTIO_MIN_RX_BUFSIZE;
.init = rte_virtio_pmd_init,
};
-PMD_REGISTER_DRIVER(rte_virtio_driver);
+PMD_REGISTER_DRIVER(rte_virtio_driver, virtio_net);
+DRIVER_REGISTER_PCI_TABLE(virtio_net, pci_id_virtio_map);