diff options
Diffstat (limited to 'drivers/net/virtio')
-rw-r--r-- | drivers/net/virtio/virtio_ethdev.c | 27 | ||||
-rw-r--r-- | drivers/net/virtio/virtio_pci.c | 6 | ||||
-rw-r--r-- | drivers/net/virtio/virtio_pci.h | 4 | ||||
-rw-r--r-- | drivers/net/virtio/virtio_user/virtio_user_dev.c | 2 | ||||
-rw-r--r-- | drivers/net/virtio/virtio_user/virtio_user_dev.h | 6 | ||||
-rw-r--r-- | drivers/net/virtio/virtio_user_ethdev.c | 7 | ||||
-rw-r--r-- | drivers/net/virtio/virtqueue.h | 8 |
7 files changed, 45 insertions, 15 deletions
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index f5961ab7..452ad2a5 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -545,6 +545,9 @@ virtio_free_queues(struct virtio_hw *hw) int queue_type; uint16_t i; + if (hw->vqs == NULL) + return; + for (i = 0; i < nr_vq; i++) { vq = hw->vqs[i]; if (!vq) @@ -563,9 +566,11 @@ virtio_free_queues(struct virtio_hw *hw) } rte_free(vq); + hw->vqs[i] = NULL; } rte_free(hw->vqs); + hw->vqs = NULL; } static int @@ -1210,11 +1215,11 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features) rte_eth_copy_pci_info(eth_dev, pci_dev); - /* If host does not support status then disable LSC */ - if (!vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) - eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC; - else + /* If host does not support both status and MSI-X then disable LSC */ + if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS) && hw->use_msix) eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC; + else + eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC; rx_func_get(eth_dev); @@ -1550,9 +1555,6 @@ virtio_dev_start(struct rte_eth_dev *dev) } } - /* Initialize Link state */ - virtio_dev_link_update(dev, 0); - /*Notify the backend *Otherwise the tap backend might already stop its queue due to fullness. *vhost backend will have no chance to be waked up @@ -1582,6 +1584,11 @@ virtio_dev_start(struct rte_eth_dev *dev) VIRTQUEUE_DUMP(txvq->vq); } + hw->started = 1; + + /* Initialize Link state */ + virtio_dev_link_update(dev, 0); + return 0; } @@ -1636,6 +1643,7 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev) static void virtio_dev_stop(struct rte_eth_dev *dev) { + struct virtio_hw *hw = dev->data->dev_private; struct rte_eth_link link; PMD_INIT_LOG(DEBUG, "stop"); @@ -1643,6 +1651,7 @@ virtio_dev_stop(struct rte_eth_dev *dev) if (dev->data->dev_conf.intr_conf.lsc) rte_intr_disable(&dev->pci_dev->intr_handle); + hw->started = 0; memset(&link, 0, sizeof(link)); virtio_dev_atomic_write_link_status(dev, &link); } @@ -1659,7 +1668,9 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet link.link_duplex = ETH_LINK_FULL_DUPLEX; link.link_speed = SPEED_10G; - if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) { + if (hw->started == 0) { + link.link_status = ETH_LINK_DOWN; + } else if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) { PMD_INIT_LOG(DEBUG, "Get link status from hw"); vtpci_read_dev_config(hw, offsetof(struct virtio_net_config, status), diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c index 8d5355c7..f6d697f3 100644 --- a/drivers/net/virtio/virtio_pci.c +++ b/drivers/net/virtio/virtio_pci.c @@ -48,6 +48,7 @@ */ #define PCI_CAPABILITY_LIST 0x34 #define PCI_CAP_ID_VNDR 0x09 +#define PCI_CAP_ID_MSIX 0x11 /* * The remaining space is defined by each driver as the per-driver @@ -517,7 +518,7 @@ modern_del_queue(struct virtio_hw *hw, struct virtqueue *vq) static void modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue *vq) { - io_write16(1, vq->notify_addr); + io_write16(vq->vq_queue_index, vq->notify_addr); } const struct virtio_pci_ops modern_ops = { @@ -670,6 +671,9 @@ virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw) break; } + if (cap.cap_vndr == PCI_CAP_ID_MSIX) + hw->use_msix = 1; + if (cap.cap_vndr != PCI_CAP_ID_VNDR) { PMD_INIT_LOG(DEBUG, "[%2x] skipping non VNDR cap id: %02x", diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h index 511a1c87..40f7e424 100644 --- a/drivers/net/virtio/virtio_pci.h +++ b/drivers/net/virtio/virtio_pci.h @@ -160,7 +160,8 @@ struct virtnet_ctl; /* * Maximum number of virtqueues per device. */ -#define VIRTIO_MAX_VIRTQUEUES 8 +#define VIRTIO_MAX_VIRTQUEUE_PAIRS 8 +#define VIRTIO_MAX_VIRTQUEUES (VIRTIO_MAX_VIRTQUEUE_PAIRS * 2 + 1) /* Common configuration */ #define VIRTIO_PCI_CAP_COMMON_CFG 1 @@ -248,6 +249,7 @@ struct virtio_hw { uint64_t req_guest_features; uint64_t guest_features; uint32_t max_queue_pairs; + uint16_t started; uint16_t vtnet_hdr_size; uint8_t vlan_strip; uint8_t use_msix; diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index a38398b8..91f6a59a 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -230,7 +230,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, parse_mac(dev, mac); dev->vhostfd = -1; - for (i = 0; i < VIRTIO_MAX_VIRTQUEUES * 2 + 1; ++i) { + for (i = 0; i < VIRTIO_MAX_VIRTQUEUES; ++i) { dev->kickfds[i] = -1; dev->callfds[i] = -1; } diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h index 28fc788e..1326b912 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.h +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h @@ -40,8 +40,8 @@ struct virtio_user_dev { int vhostfd; - int callfds[VIRTIO_MAX_VIRTQUEUES * 2 + 1]; - int kickfds[VIRTIO_MAX_VIRTQUEUES * 2 + 1]; + int callfds[VIRTIO_MAX_VIRTQUEUES]; + int kickfds[VIRTIO_MAX_VIRTQUEUES]; int mac_specified; uint32_t max_queue_pairs; uint32_t queue_pairs; @@ -53,7 +53,7 @@ struct virtio_user_dev { uint8_t status; uint8_t mac_addr[ETHER_ADDR_LEN]; char path[PATH_MAX]; - struct vring vrings[VIRTIO_MAX_VIRTQUEUES * 2 + 1]; + struct vring vrings[VIRTIO_MAX_VIRTQUEUES]; }; int virtio_user_start_device(struct virtio_user_dev *dev); diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c index 013600e4..f018724f 100644 --- a/drivers/net/virtio/virtio_user_ethdev.c +++ b/drivers/net/virtio/virtio_user_ethdev.c @@ -416,6 +416,13 @@ virtio_user_pmd_probe(const char *name, const char *params) goto end; } + if (queues > VIRTIO_MAX_VIRTQUEUE_PAIRS) { + PMD_INIT_LOG(ERR, "arg %s %" PRIu64 " exceeds the limit %u", + VIRTIO_USER_ARG_QUEUES_NUM, queues, + VIRTIO_MAX_VIRTQUEUE_PAIRS); + goto end; + } + eth_dev = virtio_user_eth_dev_alloc(name); if (!eth_dev) { PMD_INIT_LOG(ERR, "virtio_user fails to alloc device"); diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h index b1070e05..569c251c 100644 --- a/drivers/net/virtio/virtqueue.h +++ b/drivers/net/virtio/virtqueue.h @@ -71,8 +71,14 @@ struct rte_mbuf; /** * Return the physical address (or virtual address in case of * virtio-user) of mbuf data buffer. + * + * The address is firstly casted to the word size (sizeof(uintptr_t)) + * before casting it to uint64_t. This is to make it work with different + * combination of word size (64 bit and 32 bit) and virtio device + * (virtio-pci and virtio-user). */ -#define VIRTIO_MBUF_ADDR(mb, vq) (*(uint64_t *)((uintptr_t)(mb) + (vq)->offset)) +#define VIRTIO_MBUF_ADDR(mb, vq) \ + ((uint64_t)(*(uintptr_t *)((uintptr_t)(mb) + (vq)->offset))) #else #define VIRTIO_MBUF_ADDR(mb, vq) ((mb)->buf_physaddr) #endif |