X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_user%2Fvirtio_user_dev.c;h=6a6145583b77044fddcfd9b227045b69c375061f;hb=6c31a8c20a5af8f8b7929d7637a6a9d414ccfb31;hp=ed55cd7524d5333bb2b03447891fcc3418cf24fa;hpb=f078c2f04d2badd432402b4e495ebee4e41cf8ef;p=dpdk.git diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index ed55cd7524..6a6145583b 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -44,7 +44,7 @@ virtio_user_create_queue(struct virtio_user_dev *dev, uint32_t queue_sel) file.fd = dev->callfds[queue_sel]; ret = dev->ops->set_vring_call(dev, &file); if (ret < 0) { - PMD_INIT_LOG(ERR, "(%s) Failed to create queue %u\n", dev->path, queue_sel); + PMD_INIT_LOG(ERR, "(%s) Failed to create queue %u", dev->path, queue_sel); return -1; } @@ -108,7 +108,7 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel) return 0; err: - PMD_INIT_LOG(ERR, "(%s) Failed to kick queue %u\n", dev->path, queue_sel); + PMD_INIT_LOG(ERR, "(%s) Failed to kick queue %u", dev->path, queue_sel); return -1; } @@ -214,7 +214,7 @@ error: pthread_mutex_unlock(&dev->mutex); rte_mcfg_mem_read_unlock(); - PMD_INIT_LOG(ERR, "(%s) Failed to start device\n", dev->path); + PMD_INIT_LOG(ERR, "(%s) Failed to start device", dev->path); /* TODO: free resource here or caller to check */ return -1; @@ -255,26 +255,89 @@ out: err: pthread_mutex_unlock(&dev->mutex); - PMD_INIT_LOG(ERR, "(%s) Failed to stop device\n", dev->path); + PMD_INIT_LOG(ERR, "(%s) Failed to stop device", dev->path); return -1; } -static inline void -parse_mac(struct virtio_user_dev *dev, const char *mac) +int +virtio_user_dev_set_mac(struct virtio_user_dev *dev) { - struct rte_ether_addr tmp; + int ret = 0; - if (!mac) - return; + if (!(dev->device_features & (1ULL << VIRTIO_NET_F_MAC))) + return -ENOTSUP; + + if (!dev->ops->set_config) + return -ENOTSUP; + + ret = dev->ops->set_config(dev, dev->mac_addr, + offsetof(struct virtio_net_config, mac), + RTE_ETHER_ADDR_LEN); + if (ret) + PMD_DRV_LOG(ERR, "(%s) Failed to set MAC address in device", dev->path); + + return ret; +} + +int +virtio_user_dev_get_mac(struct virtio_user_dev *dev) +{ + int ret = 0; + + if (!(dev->device_features & (1ULL << VIRTIO_NET_F_MAC))) + return -ENOTSUP; + + if (!dev->ops->get_config) + return -ENOTSUP; + + ret = dev->ops->get_config(dev, dev->mac_addr, + offsetof(struct virtio_net_config, mac), + RTE_ETHER_ADDR_LEN); + if (ret) + PMD_DRV_LOG(ERR, "(%s) Failed to get MAC address from device", dev->path); + + return ret; +} + +static void +virtio_user_dev_init_mac(struct virtio_user_dev *dev, const char *mac) +{ + struct rte_ether_addr cmdline_mac; + char buf[RTE_ETHER_ADDR_FMT_SIZE]; + int ret; - if (rte_ether_unformat_addr(mac, &tmp) == 0) { - memcpy(dev->mac_addr, &tmp, RTE_ETHER_ADDR_LEN); + if (mac && rte_ether_unformat_addr(mac, &cmdline_mac) == 0) { + /* + * MAC address was passed from command-line, try to store + * it in the device if it supports it. Otherwise try to use + * the device one. + */ + memcpy(dev->mac_addr, &cmdline_mac, RTE_ETHER_ADDR_LEN); dev->mac_specified = 1; + + /* Setting MAC may fail, continue to get the device one in this case */ + virtio_user_dev_set_mac(dev); + ret = virtio_user_dev_get_mac(dev); + if (ret == -ENOTSUP) + goto out; + + if (memcmp(&cmdline_mac, dev->mac_addr, RTE_ETHER_ADDR_LEN)) + PMD_DRV_LOG(INFO, "(%s) Device MAC update failed", dev->path); } else { - /* ignore the wrong mac, use random mac */ - PMD_DRV_LOG(ERR, "wrong format of mac: %s", mac); + ret = virtio_user_dev_get_mac(dev); + if (ret) { + PMD_DRV_LOG(ERR, "(%s) No valid MAC in devargs or device, use random", + dev->path); + return; + } + + dev->mac_specified = 1; } +out: + rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, + (struct rte_ether_addr *)dev->mac_addr); + PMD_DRV_LOG(INFO, "(%s) MAC %s specified", dev->path, buf); } static int @@ -353,7 +416,7 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev) } for (i = 0; i < dev->max_queue_pairs; ++i) - eth_dev->intr_handle->efds[i] = dev->callfds[i]; + eth_dev->intr_handle->efds[i] = dev->callfds[2 * i]; eth_dev->intr_handle->nb_efd = dev->max_queue_pairs; eth_dev->intr_handle->max_intr = dev->max_queue_pairs + 1; eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV; @@ -408,7 +471,7 @@ exit: pthread_mutex_unlock(&dev->mutex); if (ret < 0) - PMD_DRV_LOG(ERR, "(%s) Failed to update memory table\n", dev->path); + PMD_DRV_LOG(ERR, "(%s) Failed to update memory table", dev->path); } static int @@ -437,17 +500,17 @@ virtio_user_dev_setup(struct virtio_user_dev *dev) } if (dev->ops->setup(dev) < 0) { - PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path); + PMD_INIT_LOG(ERR, "(%s) Failed to setup backend", dev->path); return -1; } if (virtio_user_dev_init_notify(dev) < 0) { - PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers\n", dev->path); + PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers", dev->path); goto destroy; } if (virtio_user_fill_intr_handle(dev) < 0) { - PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler\n", dev->path); + PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler", dev->path); goto uninit; } @@ -509,8 +572,6 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, dev->unsupported_features = 0; dev->backend_type = backend_type; - parse_mac(dev, mac); - if (*ifname) { dev->ifname = *ifname; *ifname = NULL; @@ -538,6 +599,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, return -1; } + virtio_user_dev_init_mac(dev, mac); + if (!mrg_rxbuf) dev->unsupported_features |= (1ull << VIRTIO_NET_F_MRG_RXBUF); @@ -579,7 +642,7 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, if (rte_mem_event_callback_register(VIRTIO_USER_MEM_EVENT_CLB_NAME, virtio_user_mem_event_cb, dev)) { if (rte_errno != ENOTSUP) { - PMD_INIT_LOG(ERR, "(%s) Failed to register mem event callback\n", + PMD_INIT_LOG(ERR, "(%s) Failed to register mem event callback", dev->path); return -1; } @@ -591,6 +654,13 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, void virtio_user_dev_uninit(struct virtio_user_dev *dev) { + struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id]; + + if (eth_dev->intr_handle) { + free(eth_dev->intr_handle); + eth_dev->intr_handle = NULL; + } + virtio_user_stop_device(dev); rte_mem_event_callback_unregister(VIRTIO_USER_MEM_EVENT_CLB_NAME, dev); @@ -796,7 +866,7 @@ virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status) dev->status = status; ret = dev->ops->set_status(dev, status); if (ret && ret != -ENOTSUP) - PMD_INIT_LOG(ERR, "(%s) Failed to set backend status\n", dev->path); + PMD_INIT_LOG(ERR, "(%s) Failed to set backend status", dev->path); pthread_mutex_unlock(&dev->mutex); return ret; @@ -820,7 +890,7 @@ virtio_user_dev_update_status(struct virtio_user_dev *dev) "\t-DRIVER_OK: %u\n" "\t-FEATURES_OK: %u\n" "\t-DEVICE_NEED_RESET: %u\n" - "\t-FAILED: %u\n", + "\t-FAILED: %u", dev->status, (dev->status == VIRTIO_CONFIG_STATUS_RESET), !!(dev->status & VIRTIO_CONFIG_STATUS_ACK), @@ -830,7 +900,7 @@ virtio_user_dev_update_status(struct virtio_user_dev *dev) !!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET), !!(dev->status & VIRTIO_CONFIG_STATUS_FAILED)); } else if (ret != -ENOTSUP) { - PMD_INIT_LOG(ERR, "(%s) Failed to get backend status\n", dev->path); + PMD_INIT_LOG(ERR, "(%s) Failed to get backend status", dev->path); } pthread_mutex_unlock(&dev->mutex);