* [dpdk-dev] [RFC 01/10] virtio: rearrange resource initialization
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 7:14 ` Ouyang, Changchun
2014-08-26 2:07 ` [dpdk-dev] [RFC 02/10] virtio: use weak barriers Stephen Hemminger
` (8 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev
[-- Attachment #1: virtio-linux-portio.patch --]
[-- Type: text/plain, Size: 3086 bytes --]
For clarity make the setup of PCI resources for Linux
into a function rather than block of code #ifdef'd in middle
of dev_init.
---
lib/librte_pmd_virtio/virtio_ethdev.c | 76 +++++++++++++++++++---------------
1 file changed, 43 insertions(+), 33 deletions(-)
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:03.622515574 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:03.622515574 -0700
@@ -706,6 +706,41 @@ virtio_has_msix(const struct rte_pci_add
return (d != NULL);
}
+
+/* Extract I/O port numbers from sysfs */
+static int virtio_resource_init(struct rte_pci_device *pci_dev)
+{
+ char dirname[PATH_MAX];
+ char filename[PATH_MAX];
+ unsigned long start, size;
+
+ if (get_uio_dev(&pci_dev->addr, dirname, sizeof(dirname)) < 0)
+ return -1;
+
+ /* get portio size */
+ snprintf(filename, sizeof(filename),
+ "%s/portio/port0/size", dirname);
+ if (parse_sysfs_value(filename, &size) < 0) {
+ PMD_INIT_LOG(ERR, "%s(): cannot parse size",
+ __func__);
+ return -1;
+ }
+
+ /* get portio start */
+ snprintf(filename, sizeof(filename),
+ "%s/portio/port0/start", dirname);
+ if (parse_sysfs_value(filename, &start) < 0) {
+ PMD_INIT_LOG(ERR, "%s(): cannot parse portio start",
+ __func__);
+ return -1;
+ }
+ pci_dev->mem_resource[0].addr = (void *)(uintptr_t)start;
+ pci_dev->mem_resource[0].len = (uint64_t)size;
+ PMD_INIT_LOG(DEBUG,
+ "PCI Port IO found start=0x%lx with size=0x%lx",
+ start, size);
+ return 0;
+}
#else
static int
virtio_has_msix(const struct rte_pci_addr *loc __rte_unused)
@@ -713,6 +748,12 @@ virtio_has_msix(const struct rte_pci_add
/* nic_uio does not enable interrupts, return 0 (false). */
return 0;
}
+
+static int virtio_resource_init(struct rte_pci_device *pci_dev __rte_unused)
+{
+ /* no setup required */
+ return 0;
+}
#endif
/*
@@ -749,40 +790,9 @@ eth_virtio_dev_init(__rte_unused struct
return 0;
pci_dev = eth_dev->pci_dev;
+ if (virtio_resource_init(pci_dev) < 0)
+ return -1;
-#ifdef RTE_EXEC_ENV_LINUXAPP
- {
- char dirname[PATH_MAX];
- char filename[PATH_MAX];
- unsigned long start, size;
-
- if (get_uio_dev(&pci_dev->addr, dirname, sizeof(dirname)) < 0)
- return -1;
-
- /* get portio size */
- snprintf(filename, sizeof(filename),
- "%s/portio/port0/size", dirname);
- if (parse_sysfs_value(filename, &size) < 0) {
- PMD_INIT_LOG(ERR, "%s(): cannot parse size",
- __func__);
- return -1;
- }
-
- /* get portio start */
- snprintf(filename, sizeof(filename),
- "%s/portio/port0/start", dirname);
- if (parse_sysfs_value(filename, &start) < 0) {
- PMD_INIT_LOG(ERR, "%s(): cannot parse portio start",
- __func__);
- return -1;
- }
- pci_dev->mem_resource[0].addr = (void *)(uintptr_t)start;
- pci_dev->mem_resource[0].len = (uint64_t)size;
- PMD_INIT_LOG(DEBUG,
- "PCI Port IO found start=0x%lx with size=0x%lx",
- start, size);
- }
-#endif
hw->use_msix = virtio_has_msix(&pci_dev->addr);
hw->io_base = (uint32_t)(uintptr_t)pci_dev->mem_resource[0].addr;
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [dpdk-dev] [RFC 01/10] virtio: rearrange resource initialization
2014-08-26 2:07 ` [dpdk-dev] [RFC 01/10] virtio: rearrange resource initialization Stephen Hemminger
@ 2014-08-26 7:14 ` Ouyang, Changchun
0 siblings, 0 replies; 19+ messages in thread
From: Ouyang, Changchun @ 2014-08-26 7:14 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
Acked-by: Changchun Ouyang <Changchun.ouyang@intel.com>
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, August 26, 2014 10:08 AM
> To: Ouyang, Changchun
> Cc: dev@dpdk.org
> Subject: [RFC 01/10] virtio: rearrange resource initialization
>
> For clarity make the setup of PCI resources for Linux into a function rather
> than block of code #ifdef'd in middle of dev_init.
>
> ---
> lib/librte_pmd_virtio/virtio_ethdev.c | 76 +++++++++++++++++++----------
> -----
> 1 file changed, 43 insertions(+), 33 deletions(-)
>
> --- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25
> 19:00:03.622515574 -0700
> +++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25
> 19:00:03.622515574 -0700
> @@ -706,6 +706,41 @@ virtio_has_msix(const struct rte_pci_add
>
> return (d != NULL);
> }
> +
> +/* Extract I/O port numbers from sysfs */ static int
> +virtio_resource_init(struct rte_pci_device *pci_dev) {
> + char dirname[PATH_MAX];
> + char filename[PATH_MAX];
> + unsigned long start, size;
> +
> + if (get_uio_dev(&pci_dev->addr, dirname, sizeof(dirname)) < 0)
> + return -1;
> +
> + /* get portio size */
> + snprintf(filename, sizeof(filename),
> + "%s/portio/port0/size", dirname);
> + if (parse_sysfs_value(filename, &size) < 0) {
> + PMD_INIT_LOG(ERR, "%s(): cannot parse size",
> + __func__);
> + return -1;
> + }
> +
> + /* get portio start */
> + snprintf(filename, sizeof(filename),
> + "%s/portio/port0/start", dirname);
> + if (parse_sysfs_value(filename, &start) < 0) {
> + PMD_INIT_LOG(ERR, "%s(): cannot parse portio start",
> + __func__);
> + return -1;
> + }
> + pci_dev->mem_resource[0].addr = (void *)(uintptr_t)start;
> + pci_dev->mem_resource[0].len = (uint64_t)size;
> + PMD_INIT_LOG(DEBUG,
> + "PCI Port IO found start=0x%lx with size=0x%lx",
> + start, size);
> + return 0;
> +}
> #else
> static int
> virtio_has_msix(const struct rte_pci_addr *loc __rte_unused) @@ -713,6
> +748,12 @@ virtio_has_msix(const struct rte_pci_add
> /* nic_uio does not enable interrupts, return 0 (false). */
> return 0;
> }
> +
> +static int virtio_resource_init(struct rte_pci_device *pci_dev
> +__rte_unused) {
> + /* no setup required */
> + return 0;
> +}
> #endif
>
> /*
> @@ -749,40 +790,9 @@ eth_virtio_dev_init(__rte_unused struct
> return 0;
>
> pci_dev = eth_dev->pci_dev;
> + if (virtio_resource_init(pci_dev) < 0)
> + return -1;
>
> -#ifdef RTE_EXEC_ENV_LINUXAPP
> - {
> - char dirname[PATH_MAX];
> - char filename[PATH_MAX];
> - unsigned long start, size;
> -
> - if (get_uio_dev(&pci_dev->addr, dirname, sizeof(dirname))
> < 0)
> - return -1;
> -
> - /* get portio size */
> - snprintf(filename, sizeof(filename),
> - "%s/portio/port0/size", dirname);
> - if (parse_sysfs_value(filename, &size) < 0) {
> - PMD_INIT_LOG(ERR, "%s(): cannot parse size",
> - __func__);
> - return -1;
> - }
> -
> - /* get portio start */
> - snprintf(filename, sizeof(filename),
> - "%s/portio/port0/start", dirname);
> - if (parse_sysfs_value(filename, &start) < 0) {
> - PMD_INIT_LOG(ERR, "%s(): cannot parse portio
> start",
> - __func__);
> - return -1;
> - }
> - pci_dev->mem_resource[0].addr = (void *)(uintptr_t)start;
> - pci_dev->mem_resource[0].len = (uint64_t)size;
> - PMD_INIT_LOG(DEBUG,
> - "PCI Port IO found start=0x%lx with size=0x%lx",
> - start, size);
> - }
> -#endif
> hw->use_msix = virtio_has_msix(&pci_dev->addr);
> hw->io_base = (uint32_t)(uintptr_t)pci_dev-
> >mem_resource[0].addr;
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 02/10] virtio: use weak barriers
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 01/10] virtio: rearrange resource initialization Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 03/10] virtio: allow starting with link down Stephen Hemminger
` (7 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev
[-- Attachment #1: virtio-barrier.patch --]
[-- Type: text/plain, Size: 3756 bytes --]
The DPDK driver only has to deal with the case of running on PCI
and with SMP. In this case, the code can use the weaker barriers
instead of using hard (fence) barriers. This will help performance.
The rationale is explained in Linux kernel virtio_ring.h.
To make it clearer that this is a virtio thing and not some generic
barrier, prefix the barrier calls with virtio_.
Add missing (and needed) barrier between updating ring data
structure and notifying host.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_virtio/virtio_ethdev.c | 2 +-
lib/librte_pmd_virtio/virtio_rxtx.c | 8 +++++---
lib/librte_pmd_virtio/virtqueue.h | 19 ++++++++++++++-----
3 files changed, 20 insertions(+), 9 deletions(-)
--- a/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:04.146518448 -0700
+++ b/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:04.142518425 -0700
@@ -454,7 +454,7 @@ virtio_recv_pkts(void *rx_queue, struct
nb_used = VIRTQUEUE_NUSED(rxvq);
- rmb();
+ virtio_rmb();
num = (uint16_t)(likely(nb_used <= nb_pkts) ? nb_used : nb_pkts);
num = (uint16_t)(likely(num <= VIRTIO_MBUF_BURST_SZ) ? num : VIRTIO_MBUF_BURST_SZ);
@@ -514,6 +514,7 @@ virtio_recv_pkts(void *rx_queue, struct
}
if (likely(nb_enqueued)) {
+ virtio_wmb();
if (unlikely(virtqueue_kick_prepare(rxvq))) {
virtqueue_notify(rxvq);
PMD_RX_LOG(DEBUG, "Notified\n");
@@ -545,7 +546,7 @@ virtio_recv_mergeable_pkts(void *rx_queu
nb_used = VIRTQUEUE_NUSED(rxvq);
- rmb();
+ virtio_rmb();
if (nb_used == 0)
return 0;
@@ -694,7 +695,7 @@ virtio_xmit_pkts(void *tx_queue, struct
PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts);
nb_used = VIRTQUEUE_NUSED(txvq);
- rmb();
+ virtio_rmb();
num = (uint16_t)(likely(nb_used < VIRTIO_MBUF_BURST_SZ) ? nb_used : VIRTIO_MBUF_BURST_SZ);
@@ -729,6 +730,7 @@ virtio_xmit_pkts(void *tx_queue, struct
}
}
vq_update_avail_idx(txvq);
+ virtio_wmb();
txvq->packets += nb_tx;
--- a/lib/librte_pmd_virtio/virtqueue.h 2014-08-25 19:00:04.146518448 -0700
+++ b/lib/librte_pmd_virtio/virtqueue.h 2014-08-25 19:00:04.142518425 -0700
@@ -46,9 +46,18 @@
#include "virtio_ring.h"
#include "virtio_logs.h"
-#define mb() rte_mb()
-#define wmb() rte_wmb()
-#define rmb() rte_rmb()
+/*
+ * Per virtio_config.h in Linux.
+ * For virtio_pci on SMP, we don't need to order with respect to MMIO
+ * accesses through relaxed memory I/O windows, so smp_mb() et al are
+ * sufficient.
+ *
+ * This driver is for virtio_pci on SMP and therefore can assume
+ * weaker (compiler barriers)
+ */
+#define virtio_mb() rte_mb()
+#define virtio_rmb() rte_compiler_barrier()
+#define virtio_wmb() rte_compiler_barrier()
#ifdef RTE_PMD_PACKET_PREFETCH
#define rte_packet_prefetch(p) rte_prefetch1(p)
@@ -226,7 +235,7 @@ virtqueue_full(const struct virtqueue *v
static inline void
vq_update_avail_idx(struct virtqueue *vq)
{
- rte_compiler_barrier();
+ virtio_rmb();
vq->vq_ring.avail->idx = vq->vq_avail_idx;
}
@@ -256,7 +265,7 @@ static inline void
virtqueue_notify(struct virtqueue *vq)
{
/*
- * Ensure updated avail->idx is visible to host. mb() necessary?
+ * Ensure updated avail->idx is visible to host.
* For virtio on IA, the notificaiton is through io port operation
* which is a serialization instruction itself.
*/
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:04.146518448 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:04.142518425 -0700
@@ -171,7 +171,7 @@ virtio_send_command(struct virtqueue *vq
uint32_t idx, desc_idx, used_idx;
struct vring_used_elem *uep;
- rmb();
+ virtio_rmb();
used_idx = (uint32_t)(vq->vq_used_cons_idx
& (vq->vq_nentries - 1));
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 03/10] virtio: allow starting with link down
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 01/10] virtio: rearrange resource initialization Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 02/10] virtio: use weak barriers Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 04/10] virtio: add support for Link State interrupt Stephen Hemminger
` (6 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev
[-- Attachment #1: virtio-link-down-ok.patch --]
[-- Type: text/plain, Size: 922 bytes --]
Starting driver with link down should be ok, it is with every
other driver. So just allow it.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_virtio/virtio_ethdev.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:05.498525861 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:05.494525839 -0700
@@ -969,14 +969,12 @@ virtio_dev_start(struct rte_eth_dev *dev
vtpci_read_dev_config(hw,
offsetof(struct virtio_net_config, status),
&status, sizeof(status));
- if ((status & VIRTIO_NET_S_LINK_UP) == 0) {
+ if ((status & VIRTIO_NET_S_LINK_UP) == 0)
PMD_INIT_LOG(ERR, "Port: %d Link is DOWN",
dev->data->port_id);
- return -EIO;
- } else {
+ else
PMD_INIT_LOG(DEBUG, "Port: %d Link is UP",
dev->data->port_id);
- }
}
vtpci_reinit_complete(hw);
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 04/10] virtio: add support for Link State interrupt
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
` (2 preceding siblings ...)
2014-08-26 2:07 ` [dpdk-dev] [RFC 03/10] virtio: allow starting with link down Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 05/10] ether: add soft vlan encap/decap functions Stephen Hemminger
` (5 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev, Stephen Hemminger
[-- Attachment #1: virtio-lsc.patch --]
[-- Type: text/plain, Size: 5846 bytes --]
Virtio has link state interrupt which can be used.
Signed-off-by: Stephen Hemminger <shemming@brocade.com>
---
lib/librte_pmd_virtio/virtio_ethdev.c | 78 ++++++++++++++++++++++++++--------
lib/librte_pmd_virtio/virtio_pci.c | 22 +++++++++
lib/librte_pmd_virtio/virtio_pci.h | 4 +
3 files changed, 86 insertions(+), 18 deletions(-)
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:06.342530488 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:06.342530488 -0700
@@ -757,6 +757,34 @@ static int virtio_resource_init(struct r
#endif
/*
+ * Process Virtio Config changed interrupt and call the callback
+ * if link state changed.
+ */
+static void
+virtio_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+ void *param)
+{
+ struct rte_eth_dev *dev = param;
+ struct virtio_hw *hw =
+ VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint8_t isr;
+
+ /* Read interrupt status which clears interrupt */
+ isr = vtpci_isr(hw);
+ PMD_DRV_LOG(INFO, "interrupt status = %#x", isr);
+
+ if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0)
+ PMD_DRV_LOG(ERR, "interrupt enable failed");
+
+ if (isr & VIRTIO_PCI_ISR_CONFIG) {
+ if (virtio_dev_link_update(dev, 0) == 0)
+ _rte_eth_dev_callback_process(dev,
+ RTE_ETH_EVENT_INTR_LSC);
+ }
+
+}
+
+/*
* This function is based on probe() function in virtio_pci.c
* It returns 0 on success.
*/
@@ -886,6 +914,10 @@ eth_virtio_dev_init(__rte_unused struct
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);
+
+ /* Setup interrupt callback */
+ rte_intr_callback_register(&pci_dev->intr_handle,
+ virtio_interrupt_handler, eth_dev);
return 0;
}
@@ -893,7 +925,7 @@ static struct eth_driver rte_virtio_pmd
{
.name = "rte_virtio_pmd",
.id_table = pci_id_virtio_map,
- .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
},
.eth_dev_init = eth_virtio_dev_init,
.dev_private_size = sizeof(struct virtio_adapter),
@@ -933,6 +965,9 @@ static int
virtio_dev_configure(struct rte_eth_dev *dev)
{
const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+ struct virtio_hw *hw =
+ VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ int ret;
PMD_INIT_LOG(DEBUG, "configure");
@@ -941,7 +976,11 @@ virtio_dev_configure(struct rte_eth_dev
return (-EINVAL);
}
- return 0;
+ ret = vtpci_irq_config(hw, 0);
+ if (ret != 0)
+ PMD_DRV_LOG(ERR, "failed to set config vector");
+
+ return ret;
}
@@ -949,7 +988,6 @@ static int
virtio_dev_start(struct rte_eth_dev *dev)
{
uint16_t nb_queues, i;
- uint16_t status;
struct virtio_hw *hw =
VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -964,18 +1002,22 @@ virtio_dev_start(struct rte_eth_dev *dev
/* Do final configuration before rx/tx engine starts */
virtio_dev_rxtx_start(dev);
- /* Check VIRTIO_NET_F_STATUS for link status*/
- if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
- vtpci_read_dev_config(hw,
- offsetof(struct virtio_net_config, status),
- &status, sizeof(status));
- if ((status & VIRTIO_NET_S_LINK_UP) == 0)
- PMD_INIT_LOG(ERR, "Port: %d Link is DOWN",
- dev->data->port_id);
- else
- PMD_INIT_LOG(DEBUG, "Port: %d Link is UP",
- dev->data->port_id);
+ /* check if lsc interrupt feature is enabled */
+ if (dev->data->dev_conf.intr_conf.lsc) {
+ if (!vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
+ PMD_DRV_LOG(ERR, "link status not supported by host");
+ return -ENOTSUP;
+ }
+
+ if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0) {
+ PMD_DRV_LOG(ERR, "interrupt enable failed");
+ return -EIO;
+ }
}
+
+ /* Initialize Link state */
+ virtio_dev_link_update(dev, 0);
+
vtpci_reinit_complete(hw);
/*Notify the backend
@@ -1057,6 +1099,7 @@ virtio_dev_stop(struct rte_eth_dev *dev)
VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
/* reset the NIC */
+ vtpci_irq_config(hw, 0);
vtpci_reset(hw);
virtio_dev_free_mbufs(dev);
}
@@ -1073,6 +1116,7 @@ virtio_dev_link_update(struct rte_eth_de
old = link;
link.link_duplex = FULL_DUPLEX;
link.link_speed = SPEED_10G;
+
if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
PMD_INIT_LOG(DEBUG, "Get link status from hw");
vtpci_read_dev_config(hw,
@@ -1091,10 +1135,8 @@ virtio_dev_link_update(struct rte_eth_de
link.link_status = 1; /* Link up */
}
virtio_dev_atomic_write_link_status(dev, &link);
- if (old.link_status == link.link_status)
- return -1;
- /*changed*/
- return 0;
+
+ return (old.link_status == link.link_status) ? -1 : 0;
}
static void
--- a/lib/librte_pmd_virtio/virtio_pci.c 2014-08-25 19:00:06.342530488 -0700
+++ b/lib/librte_pmd_virtio/virtio_pci.c 2014-08-25 19:00:06.342530488 -0700
@@ -127,3 +127,25 @@ vtpci_set_status(struct virtio_hw *hw, u
VIRTIO_WRITE_REG_1(hw, VIRTIO_PCI_STATUS, status);
}
+
+uint8_t
+vtpci_isr(struct virtio_hw *hw)
+{
+
+ return VIRTIO_READ_REG_1(hw, VIRTIO_PCI_ISR);
+}
+
+
+/* Enable one vector (0) for Link State Intrerrupt */
+int
+vtpci_irq_config(struct virtio_hw *hw, uint16_t vec)
+{
+ VIRTIO_WRITE_REG_2(hw, VIRTIO_MSI_CONFIG_VECTOR, vec);
+ vec = VIRTIO_READ_REG_2(hw, VIRTIO_MSI_CONFIG_VECTOR);
+ if (vec == VIRTIO_MSI_NO_VECTOR) {
+ PMD_DRV_LOG(ERR, "failed to set config vector");
+ return -EBUSY;
+ }
+
+ return 0;
+}
--- a/lib/librte_pmd_virtio/virtio_pci.h 2014-08-25 19:00:06.342530488 -0700
+++ b/lib/librte_pmd_virtio/virtio_pci.h 2014-08-25 19:00:06.342530488 -0700
@@ -263,4 +263,8 @@ void vtpci_write_dev_config(struct virti
void vtpci_read_dev_config(struct virtio_hw *, uint64_t, void *, int);
+uint8_t vtpci_isr(struct virtio_hw *);
+
+int vtpci_irq_config(struct virtio_hw *, uint16_t);
+
#endif /* _VIRTIO_PCI_H_ */
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 05/10] ether: add soft vlan encap/decap functions
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
` (3 preceding siblings ...)
2014-08-26 2:07 ` [dpdk-dev] [RFC 04/10] virtio: add support for Link State interrupt Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 06/10] virtio: use software vlan stripping Stephen Hemminger
` (4 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev
[-- Attachment #1: vlan-encap-decap.patch --]
[-- Type: text/plain, Size: 2502 bytes --]
It is helpful to allow device drivers that don't support hardware
VLAN stripping to emulate this in software.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_ether/rte_ether.h | 69 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
--- a/lib/librte_ether/rte_ether.h 2014-08-25 19:00:06.978533976 -0700
+++ b/lib/librte_ether/rte_ether.h 2014-08-25 19:00:06.978533976 -0700
@@ -48,6 +48,8 @@ extern "C" {
#include <rte_memcpy.h>
#include <rte_random.h>
+#include <rte_mbuf.h>
+#include <rte_byteorder.h>
#define ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */
#define ETHER_TYPE_LEN 2 /**< Length of Ethernet type field. */
@@ -294,6 +296,73 @@ struct vlan_hdr {
#define ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */
#define ETHER_TYPE_1588 0x88F7 /**< IEEE 802.1AS 1588 Precise Time Protocol. */
+/**
+ * Extract VLAN tag information into mbuf
+ *
+ * Software version of VLAN stripping
+ *
+ * @param m
+ * The packet mbuf.
+ * @return
+ * - 0: Success
+ * - 1: not a vlan packet
+ */
+static inline int rte_vlan_strip(struct rte_mbuf *m)
+{
+ struct ether_hdr *eh
+ = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+ if (eh->ether_type != ETHER_TYPE_VLAN)
+ return -1;
+
+ struct vlan_hdr *vh = (struct vlan_hdr *)(eh + 1);
+ m->ol_flags |= PKT_RX_VLAN_PKT;
+ m->pkt.vlan_macip.f.vlan_tci = rte_be_to_cpu_16(vh->vlan_tci);
+
+ /* Copy ether header over rather than moving whole packet */
+ memmove(rte_pktmbuf_adj(m, sizeof(struct vlan_hdr)),
+ eh, 2 * ETHER_ADDR_LEN);
+
+ return 0;
+}
+
+/**
+ * Insert VLAN tag into mbuf.
+ *
+ * Software version of VLAN unstripping
+ *
+ * @param m
+ * The packet mbuf.
+ * @return
+ * - 0: On success
+ * -EPERM: mbuf is is shared overwriting would be unsafe
+ * -ENOSPC: not enough headroom in mbuf
+ */
+static inline int rte_vlan_insert(struct rte_mbuf *m)
+{
+ struct ether_hdr *oh, *nh;
+ struct vlan_hdr *vh;
+
+#ifdef RTE_MBUF_SCATTER_GATHER
+ /* Can't insert header if mbuf is shared */
+ if (rte_mbuf_refcnt_read(m) > 1)
+ return -EINVAL;
+#endif
+ oh = rte_pktmbuf_mtod(m, struct ether_hdr *);
+ nh = (struct ether_hdr *)
+ rte_pktmbuf_prepend(m, sizeof(struct vlan_hdr));
+ if (nh == NULL)
+ return -ENOSPC;
+
+ memmove(nh, oh, 2 * ETHER_ADDR_LEN);
+ nh->ether_type = ETHER_TYPE_VLAN;
+
+ vh = (struct vlan_hdr *) (nh + 1);
+ vh->vlan_tci = rte_cpu_to_be_16(m->pkt.vlan_macip.f.vlan_tci);
+
+ return 0;
+}
+
#ifdef __cplusplus
}
#endif
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 06/10] virtio: use software vlan stripping
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
` (4 preceding siblings ...)
2014-08-26 2:07 ` [dpdk-dev] [RFC 05/10] ether: add soft vlan encap/decap functions Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 8:37 ` Ouyang, Changchun
2014-08-26 2:07 ` [dpdk-dev] [RFC 07/10] virtio: remove unnecessary adapter structure Stephen Hemminger
` (3 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev
[-- Attachment #1: virtio-vlan-tag.patch --]
[-- Type: text/plain, Size: 2885 bytes --]
Implement VLAN stripping in software. This allows application
to be device independent.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_virtio/virtio_ethdev.c | 2 ++
lib/librte_pmd_virtio/virtio_pci.h | 1 +
lib/librte_pmd_virtio/virtio_rxtx.c | 20 ++++++++++++++++++--
3 files changed, 21 insertions(+), 2 deletions(-)
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:07.574537243 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:07.574537243 -0700
@@ -976,6 +976,8 @@ virtio_dev_configure(struct rte_eth_dev
return (-EINVAL);
}
+ hw->vlan_strip = rxmode->hw_vlan_strip;
+
ret = vtpci_irq_config(hw, 0);
if (ret != 0)
PMD_DRV_LOG(ERR, "failed to set config vector");
--- a/lib/librte_pmd_virtio/virtio_pci.h 2014-08-25 19:00:07.574537243 -0700
+++ b/lib/librte_pmd_virtio/virtio_pci.h 2014-08-25 19:00:07.574537243 -0700
@@ -168,6 +168,7 @@ struct virtio_hw {
uint32_t max_tx_queues;
uint32_t max_rx_queues;
uint16_t vtnet_hdr_size;
+ uint8_t vlan_strip;
uint8_t use_msix;
uint8_t mac_addr[ETHER_ADDR_LEN];
};
--- a/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:07.574537243 -0700
+++ b/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:07.574537243 -0700
@@ -49,6 +49,7 @@
#include <rte_prefetch.h>
#include <rte_string_fns.h>
#include <rte_errno.h>
+#include <rte_byteorder.h>
#include "virtio_logs.h"
#include "virtio_ethdev.h"
@@ -406,8 +407,8 @@ virtio_dev_tx_queue_setup(struct rte_eth
PMD_INIT_FUNC_TRACE();
- if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOOFFLOADS)
- != ETH_TXQ_FLAGS_NOOFFLOADS) {
+ if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMS)
+ != ETH_TXQ_FLAGS_NOXSUMS) {
PMD_INIT_LOG(ERR, "TX checksum offload not supported\n");
return -EINVAL;
}
@@ -444,6 +445,7 @@ uint16_t
virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
struct virtqueue *rxvq = rx_queue;
+ struct virtio_hw *hw = rxvq->hw;
struct rte_mbuf *rxm, *new_mbuf;
uint16_t nb_used, num, nb_rx = 0;
uint32_t len[VIRTIO_MBUF_BURST_SZ];
@@ -487,6 +489,9 @@ virtio_recv_pkts(void *rx_queue, struct
rxm->pkt.pkt_len = (uint32_t)(len[i] - hdr_size);
rxm->pkt.data_len = (uint16_t)(len[i] - hdr_size);
+ if (hw->vlan_strip)
+ rte_vlan_strip(rxm);
+
VIRTIO_DUMP_PACKET(rxm, rxm->pkt.data_len);
rx_pkts[nb_rx++] = rxm;
@@ -711,6 +716,17 @@ virtio_xmit_pkts(void *tx_queue, struct
if (tx_pkts[nb_tx]->pkt.nb_segs <= txvq->vq_free_cnt) {
txm = tx_pkts[nb_tx];
+
+ /* Do VLAN tag insertion */
+ if (txm->ol_flags & PKT_TX_VLAN_PKT) {
+ error = rte_vlan_insert(txm);
+ if (unlikely(error)) {
+ rte_pktmbuf_free(txm);
+ ++nb_tx;
+ continue;
+ }
+ }
+
/* Enqueue Packet buffers */
error = virtqueue_enqueue_xmit(txvq, txm);
if (unlikely(error)) {
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [dpdk-dev] [RFC 06/10] virtio: use software vlan stripping
2014-08-26 2:07 ` [dpdk-dev] [RFC 06/10] virtio: use software vlan stripping Stephen Hemminger
@ 2014-08-26 8:37 ` Ouyang, Changchun
2014-08-26 16:24 ` Stephen Hemminger
0 siblings, 1 reply; 19+ messages in thread
From: Ouyang, Changchun @ 2014-08-26 8:37 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
Hi Stephen,
Would you please describe the use scenario for the front end rx vlan strip and tx vlan insertion?
In our current implementation, backend will strip vlan tag for RX, and insert vlan tag for TX.
Thanks
Changchun
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, August 26, 2014 10:08 AM
> To: Ouyang, Changchun
> Cc: dev@dpdk.org; Stephen Hemminger
> Subject: [RFC 06/10] virtio: use software vlan stripping
>
> Implement VLAN stripping in software. This allows application to be device
> independent.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
>
> ---
> lib/librte_pmd_virtio/virtio_ethdev.c | 2 ++
> lib/librte_pmd_virtio/virtio_pci.h | 1 +
> lib/librte_pmd_virtio/virtio_rxtx.c | 20 ++++++++++++++++++--
> 3 files changed, 21 insertions(+), 2 deletions(-)
>
> --- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25
> 19:00:07.574537243 -0700
> +++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25
> 19:00:07.574537243 -0700
> @@ -976,6 +976,8 @@ virtio_dev_configure(struct rte_eth_dev
> return (-EINVAL);
> }
>
> + hw->vlan_strip = rxmode->hw_vlan_strip;
> +
> ret = vtpci_irq_config(hw, 0);
> if (ret != 0)
> PMD_DRV_LOG(ERR, "failed to set config vector");
> --- a/lib/librte_pmd_virtio/virtio_pci.h 2014-08-25 19:00:07.574537243 -0700
> +++ b/lib/librte_pmd_virtio/virtio_pci.h 2014-08-25
> 19:00:07.574537243 -0700
> @@ -168,6 +168,7 @@ struct virtio_hw {
> uint32_t max_tx_queues;
> uint32_t max_rx_queues;
> uint16_t vtnet_hdr_size;
> + uint8_t vlan_strip;
> uint8_t use_msix;
> uint8_t mac_addr[ETHER_ADDR_LEN];
> };
> --- a/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:07.574537243 -0700
> +++ b/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25
> 19:00:07.574537243 -0700
> @@ -49,6 +49,7 @@
> #include <rte_prefetch.h>
> #include <rte_string_fns.h>
> #include <rte_errno.h>
> +#include <rte_byteorder.h>
>
> #include "virtio_logs.h"
> #include "virtio_ethdev.h"
> @@ -406,8 +407,8 @@ virtio_dev_tx_queue_setup(struct rte_eth
>
> PMD_INIT_FUNC_TRACE();
>
> - if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOOFFLOADS)
> - != ETH_TXQ_FLAGS_NOOFFLOADS) {
> + if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMS)
> + != ETH_TXQ_FLAGS_NOXSUMS) {
> PMD_INIT_LOG(ERR, "TX checksum offload not
> supported\n");
> return -EINVAL;
> }
> @@ -444,6 +445,7 @@ uint16_t
> virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t
> nb_pkts) {
> struct virtqueue *rxvq = rx_queue;
> + struct virtio_hw *hw = rxvq->hw;
> struct rte_mbuf *rxm, *new_mbuf;
> uint16_t nb_used, num, nb_rx = 0;
> uint32_t len[VIRTIO_MBUF_BURST_SZ];
> @@ -487,6 +489,9 @@ virtio_recv_pkts(void *rx_queue, struct
> rxm->pkt.pkt_len = (uint32_t)(len[i] - hdr_size);
> rxm->pkt.data_len = (uint16_t)(len[i] - hdr_size);
>
> + if (hw->vlan_strip)
> + rte_vlan_strip(rxm);
> +
> VIRTIO_DUMP_PACKET(rxm, rxm->pkt.data_len);
>
> rx_pkts[nb_rx++] = rxm;
> @@ -711,6 +716,17 @@ virtio_xmit_pkts(void *tx_queue, struct
>
> if (tx_pkts[nb_tx]->pkt.nb_segs <= txvq->vq_free_cnt) {
> txm = tx_pkts[nb_tx];
> +
> + /* Do VLAN tag insertion */
> + if (txm->ol_flags & PKT_TX_VLAN_PKT) {
> + error = rte_vlan_insert(txm);
> + if (unlikely(error)) {
> + rte_pktmbuf_free(txm);
> + ++nb_tx;
> + continue;
> + }
> + }
> +
> /* Enqueue Packet buffers */
> error = virtqueue_enqueue_xmit(txvq, txm);
> if (unlikely(error)) {
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [dpdk-dev] [RFC 06/10] virtio: use software vlan stripping
2014-08-26 8:37 ` Ouyang, Changchun
@ 2014-08-26 16:24 ` Stephen Hemminger
2014-08-27 5:42 ` Ouyang, Changchun
0 siblings, 1 reply; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 16:24 UTC (permalink / raw)
To: Ouyang, Changchun; +Cc: dev
On Tue, 26 Aug 2014 08:37:11 +0000
"Ouyang, Changchun" <changchun.ouyang@intel.com> wrote:
> Hi Stephen,
>
> Would you please describe the use scenario for the front end rx vlan strip and tx vlan insertion?
> In our current implementation, backend will strip vlan tag for RX, and insert vlan tag for TX.
>
> Thanks
> Changchun
First, we don't have to do software VLAN strip on our backend if we do this.
And this way we can always use VLAN insert on transmit. Otherwise you have to
introduce special case because there is no DPDK API to determine if device does or does not
do VLAN handling.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [dpdk-dev] [RFC 06/10] virtio: use software vlan stripping
2014-08-26 16:24 ` Stephen Hemminger
@ 2014-08-27 5:42 ` Ouyang, Changchun
2014-08-27 18:04 ` Stephen Hemminger
0 siblings, 1 reply; 19+ messages in thread
From: Ouyang, Changchun @ 2014-08-27 5:42 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Wednesday, August 27, 2014 12:24 AM
> To: Ouyang, Changchun
> Cc: dev@dpdk.org
> Subject: Re: [RFC 06/10] virtio: use software vlan stripping
>
> On Tue, 26 Aug 2014 08:37:11 +0000
> "Ouyang, Changchun" <changchun.ouyang@intel.com> wrote:
>
> > Hi Stephen,
> >
> > Would you please describe the use scenario for the front end rx vlan strip
> and tx vlan insertion?
> > In our current implementation, backend will strip vlan tag for RX, and insert
> vlan tag for TX.
> >
> > Thanks
> > Changchun
>
> First, we don't have to do software VLAN strip on our backend if we do this.
> And this way we can always use VLAN insert on transmit. Otherwise you
> have to introduce special case because there is no DPDK API to determine if
> device does or does not do VLAN handling.
>
How the virtio frontend tell backend whether it has software VLAN strip feature or not?
It seems no feature bit to negotiate it.
Thanks
Changchun
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [dpdk-dev] [RFC 06/10] virtio: use software vlan stripping
2014-08-27 5:42 ` Ouyang, Changchun
@ 2014-08-27 18:04 ` Stephen Hemminger
0 siblings, 0 replies; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-27 18:04 UTC (permalink / raw)
To: Ouyang, Changchun; +Cc: dev
On Wed, 27 Aug 2014 05:42:09 +0000
"Ouyang, Changchun" <changchun.ouyang@intel.com> wrote:
>
> > -----Original Message-----
> > From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > Sent: Wednesday, August 27, 2014 12:24 AM
> > To: Ouyang, Changchun
> > Cc: dev@dpdk.org
> > Subject: Re: [RFC 06/10] virtio: use software vlan stripping
> >
> > On Tue, 26 Aug 2014 08:37:11 +0000
> > "Ouyang, Changchun" <changchun.ouyang@intel.com> wrote:
> >
> > > Hi Stephen,
> > >
> > > Would you please describe the use scenario for the front end rx vlan strip
> > and tx vlan insertion?
> > > In our current implementation, backend will strip vlan tag for RX, and insert
> > vlan tag for TX.
> > >
> > > Thanks
> > > Changchun
> >
> > First, we don't have to do software VLAN strip on our backend if we do this.
> > And this way we can always use VLAN insert on transmit. Otherwise you
> > have to introduce special case because there is no DPDK API to determine if
> > device does or does not do VLAN handling.
> >
>
> How the virtio frontend tell backend whether it has software VLAN strip feature or not?
> It seems no feature bit to negotiate it.
>
> Thanks
> Changchun
>
All other drivers have VLAN stripping as option under rte_eth_rxmode / hw_vlan_strip.
There is negotiation in DPDK, it is strictly ask for feature and either get it or an error.
Therefore we went ahead and emulated the feature in software.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 07/10] virtio: remove unnecessary adapter structure
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
` (5 preceding siblings ...)
2014-08-26 2:07 ` [dpdk-dev] [RFC 06/10] virtio: use software vlan stripping Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 6:43 ` Ouyang, Changchun
2014-08-26 2:07 ` [dpdk-dev] [RFC 08/10] virtio: remove redundant vq_alignment Stephen Hemminger
` (2 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev
[-- Attachment #1: virtio-adapter-cleanout.patch --]
[-- Type: text/plain, Size: 5501 bytes --]
Cleanup virtio code by eliminating unnecessary nesting of
virtio hardware structure inside adapter structure.
Also allows removing unneeded macro, making code clearer.
---
lib/librte_pmd_virtio/virtio_ethdev.c | 31 +++++++++++--------------------
lib/librte_pmd_virtio/virtio_ethdev.h | 9 ---------
lib/librte_pmd_virtio/virtio_rxtx.c | 3 +--
3 files changed, 12 insertions(+), 31 deletions(-)
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:08.310541279 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:08.310541279 -0700
@@ -203,8 +203,7 @@ virtio_send_command(struct virtqueue *vq
static int
virtio_set_multiple_queues(struct rte_eth_dev *dev, uint16_t nb_queues)
{
- struct virtio_hw *hw
- = VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
struct virtio_pmd_ctrl ctrl;
int dlen[1];
int ret;
@@ -238,8 +237,7 @@ int virtio_dev_queue_setup(struct rte_et
const struct rte_memzone *mz;
uint16_t vq_size;
int size;
- struct virtio_hw *hw =
- VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
struct virtqueue *vq = NULL;
/* Write the virtqueue index to the Queue Select Field */
@@ -379,8 +377,7 @@ virtio_dev_cq_queue_setup(struct rte_eth
struct virtqueue *vq;
uint16_t nb_desc = 0;
int ret;
- struct virtio_hw *hw =
- VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
PMD_INIT_FUNC_TRACE();
ret = virtio_dev_queue_setup(dev, VTNET_CQ, VTNET_SQ_CQ_QUEUE_IDX,
@@ -765,8 +762,7 @@ virtio_interrupt_handler(__rte_unused st
void *param)
{
struct rte_eth_dev *dev = param;
- struct virtio_hw *hw =
- VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
uint8_t isr;
/* Read interrupt status which clears interrupt */
@@ -792,12 +788,11 @@ static int
eth_virtio_dev_init(__rte_unused struct eth_driver *eth_drv,
struct rte_eth_dev *eth_dev)
{
+ struct virtio_hw *hw = eth_dev->data->dev_private;
struct virtio_net_config *config;
struct virtio_net_config local_config;
uint32_t offset_conf = sizeof(config->mac);
struct rte_pci_device *pci_dev;
- struct virtio_hw *hw =
- VIRTIO_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
if (RTE_PKTMBUF_HEADROOM < sizeof(struct virtio_net_hdr)) {
PMD_INIT_LOG(ERR,
@@ -928,7 +923,7 @@ static struct eth_driver rte_virtio_pmd
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
},
.eth_dev_init = eth_virtio_dev_init,
- .dev_private_size = sizeof(struct virtio_adapter),
+ .dev_private_size = sizeof(struct virtio_hw),
};
/*
@@ -965,8 +960,7 @@ static int
virtio_dev_configure(struct rte_eth_dev *dev)
{
const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
- struct virtio_hw *hw =
- VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
int ret;
PMD_INIT_LOG(DEBUG, "configure");
@@ -990,8 +984,7 @@ static int
virtio_dev_start(struct rte_eth_dev *dev)
{
uint16_t nb_queues, i;
- struct virtio_hw *hw =
- VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
/* Tell the host we've noticed this device. */
vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
@@ -1097,8 +1090,7 @@ static void virtio_dev_free_mbufs(struct
static void
virtio_dev_stop(struct rte_eth_dev *dev)
{
- struct virtio_hw *hw =
- VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
/* reset the NIC */
vtpci_irq_config(hw, 0);
@@ -1111,8 +1103,7 @@ virtio_dev_link_update(struct rte_eth_de
{
struct rte_eth_link link, old;
uint16_t status;
- struct virtio_hw *hw =
- VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
memset(&link, 0, sizeof(link));
virtio_dev_atomic_read_link_status(dev, &link);
old = link;
@@ -1144,7 +1135,7 @@ virtio_dev_link_update(struct rte_eth_de
static void
virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
- struct virtio_hw *hw = VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
dev_info->driver_name = dev->driver->pci_drv.name;
dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
--- a/lib/librte_pmd_virtio/virtio_ethdev.h 2014-08-25 19:00:08.310541279 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.h 2014-08-25 19:00:08.310541279 -0700
@@ -110,15 +110,6 @@ uint16_t virtio_recv_mergeable_pkts(void
uint16_t virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
-/*
- * Structure to store private data for each driver instance (for each port).
- */
-struct virtio_adapter {
- struct virtio_hw hw;
-};
-
-#define VIRTIO_DEV_PRIVATE_TO_HW(adapter)\
- (&((struct virtio_adapter *)adapter)->hw)
/*
* The VIRTIO_NET_F_GUEST_TSO[46] features permit the host to send us
--- a/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:08.310541279 -0700
+++ b/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:08.310541279 -0700
@@ -326,8 +326,7 @@ virtio_dev_vring_start(struct virtqueue
void
virtio_dev_cq_start(struct rte_eth_dev *dev)
{
- struct virtio_hw *hw
- = VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct virtio_hw *hw = dev->data->dev_private;
virtio_dev_vring_start(hw->cvq, VTNET_CQ);
VIRTQUEUE_DUMP((struct virtqueue *)hw->cvq);
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [dpdk-dev] [RFC 07/10] virtio: remove unnecessary adapter structure
2014-08-26 2:07 ` [dpdk-dev] [RFC 07/10] virtio: remove unnecessary adapter structure Stephen Hemminger
@ 2014-08-26 6:43 ` Ouyang, Changchun
0 siblings, 0 replies; 19+ messages in thread
From: Ouyang, Changchun @ 2014-08-26 6:43 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
Acked-by: Changchun Ouyang <changchun.ouyang@intel.com>
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, August 26, 2014 10:08 AM
> To: Ouyang, Changchun
> Cc: dev@dpdk.org
> Subject: [RFC 07/10] virtio: remove unnecessary adapter structure
>
> Cleanup virtio code by eliminating unnecessary nesting of virtio hardware
> structure inside adapter structure.
> Also allows removing unneeded macro, making code clearer.
>
> ---
> lib/librte_pmd_virtio/virtio_ethdev.c | 31 +++++++++++--------------------
> lib/librte_pmd_virtio/virtio_ethdev.h | 9 ---------
> lib/librte_pmd_virtio/virtio_rxtx.c | 3 +--
> 3 files changed, 12 insertions(+), 31 deletions(-)
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 08/10] virtio: remove redundant vq_alignment
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
` (6 preceding siblings ...)
2014-08-26 2:07 ` [dpdk-dev] [RFC 07/10] virtio: remove unnecessary adapter structure Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 8:41 ` Ouyang, Changchun
2014-08-26 2:07 ` [dpdk-dev] [RFC 09/10] virtio: fix how states are handled during initialization Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 10/10] virtio: add support for promiscious and multicast Stephen Hemminger
9 siblings, 1 reply; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev
[-- Attachment #1: virtio-no-align.patch --]
[-- Type: text/plain, Size: 1883 bytes --]
Since vq_alignment is constant (always 4K), it does not
need to be part of the vring struct.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_virtio/virtio_ethdev.c | 1 -
lib/librte_pmd_virtio/virtio_rxtx.c | 2 +-
lib/librte_pmd_virtio/virtqueue.h | 3 +--
3 files changed, 2 insertions(+), 4 deletions(-)
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:09.918550097 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:09.918550097 -0700
@@ -290,7 +290,6 @@ int virtio_dev_queue_setup(struct rte_et
vq->port_id = dev->data->port_id;
vq->queue_id = queue_idx;
vq->vq_queue_index = vtpci_queue_idx;
- vq->vq_alignment = VIRTIO_PCI_VRING_ALIGN;
vq->vq_nentries = vq_size;
vq->vq_free_cnt = vq_size;
--- a/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:09.918550097 -0700
+++ b/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:09.918550097 -0700
@@ -258,7 +258,7 @@ virtio_dev_vring_start(struct virtqueue
* Reinitialise since virtio port might have been stopped and restarted
*/
memset(vq->vq_ring_virt_mem, 0, vq->vq_ring_size);
- vring_init(vr, size, ring_mem, vq->vq_alignment);
+ vring_init(vr, size, ring_mem, VIRTIO_PCI_VRING_ALIGN);
vq->vq_used_cons_idx = 0;
vq->vq_desc_head_idx = 0;
vq->vq_avail_idx = 0;
--- a/lib/librte_pmd_virtio/virtqueue.h 2014-08-25 19:00:09.918550097 -0700
+++ b/lib/librte_pmd_virtio/virtqueue.h 2014-08-25 19:00:09.918550097 -0700
@@ -139,8 +139,7 @@ struct virtqueue {
uint8_t port_id; /**< Device port identifier. */
void *vq_ring_virt_mem; /**< linear address of vring*/
- int vq_alignment;
- int vq_ring_size;
+ unsigned int vq_ring_size;
phys_addr_t vq_ring_mem; /**< physical address of vring */
struct vring vq_ring; /**< vring keeping desc, used and avail */
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [dpdk-dev] [RFC 08/10] virtio: remove redundant vq_alignment
2014-08-26 2:07 ` [dpdk-dev] [RFC 08/10] virtio: remove redundant vq_alignment Stephen Hemminger
@ 2014-08-26 8:41 ` Ouyang, Changchun
0 siblings, 0 replies; 19+ messages in thread
From: Ouyang, Changchun @ 2014-08-26 8:41 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
Acked by: Changchun Ouyang <Changchun.ouyang@intel.com>
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, August 26, 2014 10:08 AM
> To: Ouyang, Changchun
> Cc: dev@dpdk.org; Stephen Hemminger
> Subject: [RFC 08/10] virtio: remove redundant vq_alignment
>
> Since vq_alignment is constant (always 4K), it does not need to be part of the
> vring struct.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
> ---
> lib/librte_pmd_virtio/virtio_ethdev.c | 1 -
> lib/librte_pmd_virtio/virtio_rxtx.c | 2 +-
> lib/librte_pmd_virtio/virtqueue.h | 3 +--
> 3 files changed, 2 insertions(+), 4 deletions(-)
>
> --- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25
> 19:00:09.918550097 -0700
> +++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25
> 19:00:09.918550097 -0700
> @@ -290,7 +290,6 @@ int virtio_dev_queue_setup(struct rte_et
> vq->port_id = dev->data->port_id;
> vq->queue_id = queue_idx;
> vq->vq_queue_index = vtpci_queue_idx;
> - vq->vq_alignment = VIRTIO_PCI_VRING_ALIGN;
> vq->vq_nentries = vq_size;
> vq->vq_free_cnt = vq_size;
>
> --- a/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:09.918550097 -0700
> +++ b/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25
> 19:00:09.918550097 -0700
> @@ -258,7 +258,7 @@ virtio_dev_vring_start(struct virtqueue
> * Reinitialise since virtio port might have been stopped and restarted
> */
> memset(vq->vq_ring_virt_mem, 0, vq->vq_ring_size);
> - vring_init(vr, size, ring_mem, vq->vq_alignment);
> + vring_init(vr, size, ring_mem, VIRTIO_PCI_VRING_ALIGN);
> vq->vq_used_cons_idx = 0;
> vq->vq_desc_head_idx = 0;
> vq->vq_avail_idx = 0;
> --- a/lib/librte_pmd_virtio/virtqueue.h 2014-08-25 19:00:09.918550097 -0700
> +++ b/lib/librte_pmd_virtio/virtqueue.h 2014-08-25
> 19:00:09.918550097 -0700
> @@ -139,8 +139,7 @@ struct virtqueue {
> uint8_t port_id; /**< Device port identifier. */
>
> void *vq_ring_virt_mem; /**< linear address of vring*/
> - int vq_alignment;
> - int vq_ring_size;
> + unsigned int vq_ring_size;
> phys_addr_t vq_ring_mem; /**< physical address of vring */
>
> struct vring vq_ring; /**< vring keeping desc, used and avail */
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 09/10] virtio: fix how states are handled during initialization
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
` (7 preceding siblings ...)
2014-08-26 2:07 ` [dpdk-dev] [RFC 08/10] virtio: remove redundant vq_alignment Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 2:07 ` [dpdk-dev] [RFC 10/10] virtio: add support for promiscious and multicast Stephen Hemminger
9 siblings, 0 replies; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev
[-- Attachment #1: virtio-state.patch --]
[-- Type: text/plain, Size: 3987 bytes --]
Change order of initialiazation to match Linux kernel.
Don't blow away control queue by doing reset when stopped.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_pmd_virtio/virtio_ethdev.c | 50 ++++++++++------------------------
lib/librte_pmd_virtio/virtio_rxtx.c | 2 +
2 files changed, 18 insertions(+), 34 deletions(-)
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:11.062556360 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:12.122562032 -0700
@@ -394,9 +394,11 @@ virtio_dev_cq_queue_setup(struct rte_eth
static void
virtio_dev_close(struct rte_eth_dev *dev)
{
- PMD_INIT_LOG(DEBUG, "virtio_dev_close");
+ struct virtio_hw *hw = dev->data->dev_private;
- virtio_dev_stop(dev);
+ vtpci_irq_config(hw, VIRTIO_MSI_NO_VECTOR);
+ vtpci_reset(hw);
+ virtio_dev_free_mbufs(dev);
}
/*
@@ -811,6 +813,9 @@ eth_virtio_dev_init(__rte_unused struct
if (rte_eal_process_type() == RTE_PROC_SECONDARY)
return 0;
+ /* Tell the host we've noticed this device. */
+ vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
+
pci_dev = eth_dev->pci_dev;
if (virtio_resource_init(pci_dev) < 0)
return -1;
@@ -821,9 +826,6 @@ eth_virtio_dev_init(__rte_unused struct
/* Reset the device although not necessary at startup */
vtpci_reset(hw);
- /* Tell the host we've noticed this device. */
- vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
-
/* Tell the host we've known how to drive the device. */
vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
virtio_negotiate_features(hw);
@@ -912,6 +914,9 @@ eth_virtio_dev_init(__rte_unused struct
/* Setup interrupt callback */
rte_intr_callback_register(&pci_dev->intr_handle,
virtio_interrupt_handler, eth_dev);
+
+ virtio_dev_cq_start(eth_dev);
+
return 0;
}
@@ -982,19 +987,8 @@ virtio_dev_configure(struct rte_eth_dev
static int
virtio_dev_start(struct rte_eth_dev *dev)
{
- uint16_t nb_queues, i;
struct virtio_hw *hw = dev->data->dev_private;
-
- /* Tell the host we've noticed this device. */
- vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
-
- /* Tell the host we've known how to drive the device. */
- vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
-
- virtio_dev_cq_start(dev);
-
- /* Do final configuration before rx/tx engine starts */
- virtio_dev_rxtx_start(dev);
+ uint16_t nb_queues;
/* check if lsc interrupt feature is enabled */
if (dev->data->dev_conf.intr_conf.lsc) {
@@ -1024,18 +1018,8 @@ virtio_dev_start(struct rte_eth_dev *dev
return -EINVAL;
}
- PMD_INIT_LOG(DEBUG, "nb_queues=%d", nb_queues);
-
- for (i = 0; i < nb_queues; i++)
- virtqueue_notify(dev->data->rx_queues[i]);
-
- PMD_INIT_LOG(DEBUG, "Notified backend at initialization");
-
- for (i = 0; i < dev->data->nb_rx_queues; i++)
- VIRTQUEUE_DUMP((struct virtqueue *)dev->data->rx_queues[i]);
-
- for (i = 0; i < dev->data->nb_tx_queues; i++)
- VIRTQUEUE_DUMP((struct virtqueue *)dev->data->tx_queues[i]);
+ /* Do final configuration before rx/tx engine starts */
+ virtio_dev_rxtx_start(dev);
return 0;
}
@@ -1089,12 +1073,10 @@ static void virtio_dev_free_mbufs(struct
static void
virtio_dev_stop(struct rte_eth_dev *dev)
{
- struct virtio_hw *hw = dev->data->dev_private;
+ if (dev->data->dev_conf.intr_conf.lsc)
+ rte_intr_disable(&dev->pci_dev->intr_handle);
- /* reset the NIC */
- vtpci_irq_config(hw, 0);
- vtpci_reset(hw);
- virtio_dev_free_mbufs(dev);
+ memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link));
}
static int
--- a/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:11.062556360 -0700
+++ b/lib/librte_pmd_virtio/virtio_rxtx.c 2014-08-25 19:00:11.062556360 -0700
@@ -350,6 +350,8 @@ virtio_dev_rxtx_start(struct rte_eth_dev
for (i = 0; i < dev->data->nb_rx_queues; i++) {
virtio_dev_vring_start(dev->data->rx_queues[i], VTNET_RQ);
VIRTQUEUE_DUMP((struct virtqueue *)dev->data->rx_queues[i]);
+
+ virtqueue_notify(dev->data->rx_queues[i]);
}
/* Start tx vring. */
^ permalink raw reply [flat|nested] 19+ messages in thread
* [dpdk-dev] [RFC 10/10] virtio: add support for promiscious and multicast
2014-08-26 2:07 [dpdk-dev] [RFC 00/10] virtio patches Stephen Hemminger
` (8 preceding siblings ...)
2014-08-26 2:07 ` [dpdk-dev] [RFC 09/10] virtio: fix how states are handled during initialization Stephen Hemminger
@ 2014-08-26 2:07 ` Stephen Hemminger
2014-08-26 6:55 ` Ouyang, Changchun
9 siblings, 1 reply; 19+ messages in thread
From: Stephen Hemminger @ 2014-08-26 2:07 UTC (permalink / raw)
To: Ouyang Changchun; +Cc: dev, Stephen Hemminger
[-- Attachment #1: virtio-ctrl-rx.patch --]
[-- Type: text/plain, Size: 4770 bytes --]
Implement standard virtio controls for enabling and disabling
promiscious and multicast.
Signed-off-by: Stephen Hemminger <shemming@brocade.com>
--- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:00:16.754586819 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25 19:02:48.019397658 -0700
@@ -77,6 +77,11 @@ static void virtio_get_hwaddr(struct vir
static void virtio_dev_rx_queue_release(__rte_unused void *rxq);
static void virtio_dev_tx_queue_release(__rte_unused void *txq);
+static void virtio_promiscuous_enable(struct rte_eth_dev *dev);
+static void virtio_promiscuous_disable(struct rte_eth_dev *dev);
+static void virtio_allmulticast_enable(struct rte_eth_dev *dev);
+static void virtio_allmulticast_disable(struct rte_eth_dev *dev);
+
static void virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
static void virtio_dev_stats_reset(struct rte_eth_dev *dev);
static void virtio_dev_free_mbufs(struct rte_eth_dev *dev);
@@ -405,23 +410,27 @@ virtio_dev_close(struct rte_eth_dev *dev
* dev_ops for virtio, bare necessities for basic operation
*/
static struct eth_dev_ops virtio_eth_dev_ops = {
- .dev_configure = virtio_dev_configure,
- .dev_start = virtio_dev_start,
- .dev_stop = virtio_dev_stop,
- .dev_close = virtio_dev_close,
-
- .dev_infos_get = virtio_dev_info_get,
- .stats_get = virtio_dev_stats_get,
- .stats_reset = virtio_dev_stats_reset,
- .link_update = virtio_dev_link_update,
- .mac_addr_add = NULL,
- .mac_addr_remove = NULL,
- .rx_queue_setup = virtio_dev_rx_queue_setup,
+ .dev_configure = virtio_dev_configure,
+ .dev_start = virtio_dev_start,
+ .dev_stop = virtio_dev_stop,
+ .dev_close = virtio_dev_close,
+
+ .dev_infos_get = virtio_dev_info_get,
+ .stats_get = virtio_dev_stats_get,
+ .stats_reset = virtio_dev_stats_reset,
+ .link_update = virtio_dev_link_update,
+ .promiscuous_enable = virtio_promiscuous_enable,
+ .promiscuous_disable = virtio_promiscuous_disable,
+ .allmulticast_enable = virtio_allmulticast_enable,
+ .allmulticast_disable = virtio_allmulticast_disable,
+ .mac_addr_add = NULL,
+ .mac_addr_remove = NULL,
+ .rx_queue_setup = virtio_dev_rx_queue_setup,
/* meaningfull only to multiple queue */
- .rx_queue_release = virtio_dev_rx_queue_release,
- .tx_queue_setup = virtio_dev_tx_queue_setup,
+ .rx_queue_release = virtio_dev_rx_queue_release,
+ .tx_queue_setup = virtio_dev_tx_queue_setup,
/* meaningfull only to multiple queue */
- .tx_queue_release = virtio_dev_tx_queue_release,
+ .tx_queue_release = virtio_dev_tx_queue_release,
/* collect stats per queue */
.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,
};
@@ -466,6 +475,63 @@ virtio_dev_atomic_write_link_status(stru
return 0;
}
+/* Control receive processing (ie multicast, promiscious, mac address). */
+static int virtio_ctrl_rx(struct virtio_hw *hw, uint8_t cmd, uint8_t onoff)
+{
+ struct virtio_pmd_ctrl ctrl;
+ int len, ret;
+
+ if (!vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_RX))
+ return -ENOTSUP;
+
+ ctrl.hdr.class = VIRTIO_NET_CTRL_RX;
+ ctrl.hdr.cmd = cmd;
+ memcpy(ctrl.data, &onoff, sizeof(uint8_t));
+
+ len = sizeof(uint8_t);
+ ret = virtio_send_command(hw->cvq, &ctrl, &len, 1);
+ if (ret != 0)
+ PMD_DRV_LOG(NOTICE, "ctrl_rx %u failed: %d\n", cmd, ret);
+
+ return ret;
+}
+
+static void
+virtio_promiscuous_enable(struct rte_eth_dev *dev)
+{
+ struct virtio_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_LOG(DEBUG, "promiscious enable");
+ virtio_ctrl_rx(hw, VIRTIO_NET_CTRL_RX_PROMISC, 1);
+}
+
+static void
+virtio_promiscuous_disable(struct rte_eth_dev *dev)
+{
+ struct virtio_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_LOG(DEBUG, "promiscious disable");
+ virtio_ctrl_rx(hw, VIRTIO_NET_CTRL_RX_PROMISC, 0);
+}
+
+static void
+virtio_allmulticast_enable(struct rte_eth_dev *dev)
+{
+ struct virtio_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_LOG(DEBUG, "allmulticast enable");
+ virtio_ctrl_rx(hw, VIRTIO_NET_CTRL_RX_ALLMULTI, 1);
+}
+
+static void
+virtio_allmulticast_disable(struct rte_eth_dev *dev)
+{
+ struct virtio_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_LOG(DEBUG, "allmulticast disable");
+ virtio_ctrl_rx(hw, VIRTIO_NET_CTRL_RX_ALLMULTI, 0);
+}
+
static void
virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
@@ -559,7 +625,7 @@ virtio_negotiate_features(struct virtio_
{
uint32_t host_features, mask;
- mask = VIRTIO_NET_F_CTRL_RX | VIRTIO_NET_F_CTRL_VLAN;
+ mask = VIRTIO_NET_F_CTRL_VLAN;
mask |= VIRTIO_NET_F_CSUM | VIRTIO_NET_F_GUEST_CSUM;
/* TSO and LRO are only available when their corresponding
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [dpdk-dev] [RFC 10/10] virtio: add support for promiscious and multicast
2014-08-26 2:07 ` [dpdk-dev] [RFC 10/10] virtio: add support for promiscious and multicast Stephen Hemminger
@ 2014-08-26 6:55 ` Ouyang, Changchun
0 siblings, 0 replies; 19+ messages in thread
From: Ouyang, Changchun @ 2014-08-26 6:55 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
This patch is very similar with my previous patch:
[PATCH 4/5] virtio: New API to enable/disable multicast and promisc mode
So suggest applying only one of both.
Thanks
Changchun
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Tuesday, August 26, 2014 10:08 AM
> To: Ouyang, Changchun
> Cc: dev@dpdk.org; Stephen Hemminger
> Subject: [RFC 10/10] virtio: add support for promiscious and multicast
>
> Implement standard virtio controls for enabling and disabling promiscious
> and multicast.
>
> Signed-off-by: Stephen Hemminger <shemming@brocade.com>
>
> --- a/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25
> 19:00:16.754586819 -0700
> +++ b/lib/librte_pmd_virtio/virtio_ethdev.c 2014-08-25
> 19:02:48.019397658 -0700
^ permalink raw reply [flat|nested] 19+ messages in thread