ethdev: return diagnostic when setting MAC address
[dpdk.git] / drivers / net / virtio / virtio_ethdev.c
index 2ef213d..41042cb 100644 (file)
@@ -67,7 +67,7 @@ static int virtio_mac_addr_add(struct rte_eth_dev *dev,
                                struct ether_addr *mac_addr,
                                uint32_t index, uint32_t vmdq);
 static void virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
-static void virtio_mac_addr_set(struct rte_eth_dev *dev,
+static int virtio_mac_addr_set(struct rte_eth_dev *dev,
                                struct ether_addr *mac_addr);
 
 static int virtio_intr_enable(struct rte_eth_dev *dev);
@@ -391,8 +391,8 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
                     size, vq->vq_ring_size);
 
        mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
-                                        SOCKET_ID_ANY,
-                                        0, VIRTIO_PCI_VRING_ALIGN);
+                       SOCKET_ID_ANY, RTE_MEMZONE_IOVA_CONTIG,
+                       VIRTIO_PCI_VRING_ALIGN);
        if (mz == NULL) {
                if (rte_errno == EEXIST)
                        mz = rte_memzone_lookup(vq_name);
@@ -417,8 +417,8 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
                snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
                         dev->data->port_id, vtpci_queue_idx);
                hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
-                                                    SOCKET_ID_ANY, 0,
-                                                    RTE_CACHE_LINE_SIZE);
+                               SOCKET_ID_ANY, RTE_MEMZONE_IOVA_CONTIG,
+                               RTE_CACHE_LINE_SIZE);
                if (hdr_mz == NULL) {
                        if (rte_errno == EEXIST)
                                hdr_mz = rte_memzone_lookup(vq_hdr_name);
@@ -1056,7 +1056,7 @@ virtio_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
        virtio_mac_table_set(hw, uc, mc);
 }
 
-static void
+static int
 virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
        struct virtio_hw *hw = dev->data->dev_private;
@@ -1072,9 +1072,14 @@ virtio_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
                ctrl.hdr.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET;
 
                memcpy(ctrl.data, mac_addr, ETHER_ADDR_LEN);
-               virtio_send_command(hw->cvq, &ctrl, &len, 1);
-       } else if (vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
-               virtio_set_hwaddr(hw);
+               return virtio_send_command(hw->cvq, &ctrl, &len, 1);
+       }
+
+       if (!vtpci_with_feature(hw, VIRTIO_NET_F_MAC))
+               return -ENOTSUP;
+
+       virtio_set_hwaddr(hw);
+       return 0;
 }
 
 static int
@@ -1751,6 +1756,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 {
        const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
        struct virtio_hw *hw = dev->data->dev_private;
+       uint64_t rx_offloads = rxmode->offloads;
        uint64_t req_features;
        int ret;
 
@@ -1763,14 +1769,11 @@ virtio_dev_configure(struct rte_eth_dev *dev)
                        return ret;
        }
 
-       /* The name hw_ip_checksum is a bit confusing since it can be
-        * set by the application to request L3 and/or L4 checksums. In
-        * case of virtio, only L4 checksum is supported.
-        */
-       if (rxmode->hw_ip_checksum)
+       if (rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM |
+                          DEV_RX_OFFLOAD_TCP_CKSUM))
                req_features |= (1ULL << VIRTIO_NET_F_GUEST_CSUM);
 
-       if (rxmode->enable_lro)
+       if (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO)
                req_features |=
                        (1ULL << VIRTIO_NET_F_GUEST_TSO4) |
                        (1ULL << VIRTIO_NET_F_GUEST_TSO6);
@@ -1782,14 +1785,15 @@ virtio_dev_configure(struct rte_eth_dev *dev)
                        return ret;
        }
 
-       if (rxmode->hw_ip_checksum &&
+       if ((rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM |
+                           DEV_RX_OFFLOAD_TCP_CKSUM)) &&
                !vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_CSUM)) {
                PMD_DRV_LOG(ERR,
                        "rx checksum not available on this host");
                return -ENOTSUP;
        }
 
-       if (rxmode->enable_lro &&
+       if ((rx_offloads & DEV_RX_OFFLOAD_TCP_LRO) &&
                (!vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO4) ||
                 !vtpci_with_feature(hw, VIRTIO_NET_F_GUEST_TSO6))) {
                PMD_DRV_LOG(ERR,
@@ -1801,9 +1805,10 @@ virtio_dev_configure(struct rte_eth_dev *dev)
        if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ))
                virtio_dev_cq_start(dev);
 
-       hw->vlan_strip = rxmode->hw_vlan_strip;
+       if (rx_offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
+               hw->vlan_strip = 1;
 
-       if (rxmode->hw_vlan_filter
+       if ((rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
            && !vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
                PMD_DRV_LOG(ERR,
                            "vlan filtering not available on this host");
@@ -1834,7 +1839,8 @@ virtio_dev_configure(struct rte_eth_dev *dev)
                hw->use_simple_tx = 0;
        }
 
-       if (rxmode->hw_ip_checksum)
+       if (rx_offloads & (DEV_RX_OFFLOAD_UDP_CKSUM |
+                          DEV_RX_OFFLOAD_TCP_CKSUM))
                hw->use_simple_rx = 0;
 
        return 0;
@@ -2036,9 +2042,10 @@ virtio_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
        const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
        struct virtio_hw *hw = dev->data->dev_private;
+       uint64_t offloads = rxmode->offloads;
 
        if (mask & ETH_VLAN_FILTER_MASK) {
-               if (rxmode->hw_vlan_filter &&
+               if ((offloads & DEV_RX_OFFLOAD_VLAN_FILTER) &&
                                !vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
 
                        PMD_DRV_LOG(NOTICE,
@@ -2049,7 +2056,7 @@ virtio_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
        }
 
        if (mask & ETH_VLAN_STRIP_MASK)
-               hw->vlan_strip = rxmode->hw_vlan_strip;
+               hw->vlan_strip = !!(offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
 
        return 0;
 }
@@ -2062,7 +2069,6 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
        dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */
 
-       dev_info->pci_dev = dev->device ? RTE_ETH_DEV_TO_PCI(dev) : NULL;
        dev_info->max_rx_queues =
                RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
        dev_info->max_tx_queues =
@@ -2075,18 +2081,21 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        };
 
        host_features = VTPCI_OPS(hw)->get_features(hw);
-       dev_info->rx_offload_capa = 0;
+       dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP;
        if (host_features & (1ULL << VIRTIO_NET_F_GUEST_CSUM)) {
                dev_info->rx_offload_capa |=
                        DEV_RX_OFFLOAD_TCP_CKSUM |
                        DEV_RX_OFFLOAD_UDP_CKSUM;
        }
+       if (host_features & (1ULL << VIRTIO_NET_F_CTRL_VLAN))
+               dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_VLAN_FILTER;
        tso_mask = (1ULL << VIRTIO_NET_F_GUEST_TSO4) |
                (1ULL << VIRTIO_NET_F_GUEST_TSO6);
        if ((host_features & tso_mask) == tso_mask)
                dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TCP_LRO;
 
-       dev_info->tx_offload_capa = 0;
+       dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MULTI_SEGS |
+                                   DEV_TX_OFFLOAD_VLAN_INSERT;
        if (hw->guest_features & (1ULL << VIRTIO_NET_F_CSUM)) {
                dev_info->tx_offload_capa |=
                        DEV_TX_OFFLOAD_UDP_CKSUM |