From: Ouyang Changchun <changchun.ouyang@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [RFC PATCH 04/17] virtio: Add support for Link State interrupt
Date: Mon, 8 Dec 2014 14:21:43 +0800 [thread overview]
Message-ID: <1418019716-4962-5-git-send-email-changchun.ouyang@intel.com> (raw)
In-Reply-To: <1418019716-4962-1-git-send-email-changchun.ouyang@intel.com>
Virtio has link state interrupt which can be used.
Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
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(-)
diff --git a/lib/librte_pmd_virtio/virtio_ethdev.c b/lib/librte_pmd_virtio/virtio_ethdev.c
index 4bff0fe..d37f2e9 100644
--- a/lib/librte_pmd_virtio/virtio_ethdev.c
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c
@@ -845,6 +845,34 @@ static int virtio_resource_init(struct rte_pci_device *pci_dev __rte_unused)
#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.
*/
@@ -968,6 +996,10 @@ eth_virtio_dev_init(__rte_unused struct eth_driver *eth_drv,
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;
}
@@ -975,7 +1007,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),
@@ -1021,6 +1053,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");
@@ -1029,7 +1064,11 @@ virtio_dev_configure(struct rte_eth_dev *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;
}
@@ -1037,7 +1076,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);
@@ -1052,18 +1090,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
@@ -1145,6 +1187,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);
}
@@ -1161,6 +1204,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
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,
@@ -1179,10 +1223,8 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
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
diff --git a/lib/librte_pmd_virtio/virtio_pci.c b/lib/librte_pmd_virtio/virtio_pci.c
index ca9c748..6d51032 100644
--- a/lib/librte_pmd_virtio/virtio_pci.c
+++ b/lib/librte_pmd_virtio/virtio_pci.c
@@ -127,3 +127,25 @@ vtpci_set_status(struct virtio_hw *hw, uint8_t status)
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;
+}
diff --git a/lib/librte_pmd_virtio/virtio_pci.h b/lib/librte_pmd_virtio/virtio_pci.h
index 373f9dc..6998737 100644
--- a/lib/librte_pmd_virtio/virtio_pci.h
+++ b/lib/librte_pmd_virtio/virtio_pci.h
@@ -263,4 +263,8 @@ void vtpci_write_dev_config(struct virtio_hw *, uint64_t, void *, int);
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_ */
--
1.8.4.2
next prev parent reply other threads:[~2014-12-08 6:22 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-08 6:21 [dpdk-dev] [RFC PATCH 00/17] Single virtio implementation Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 01/17] virtio: Rearrange resource initialization Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 02/17] virtio: Use weaker barriers Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 03/17] virtio: Allow starting with link down Ouyang Changchun
2014-12-08 6:21 ` Ouyang Changchun [this message]
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 05/17] ether: Add soft vlan encap/decap functions Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 06/17] virtio: Use software vlan stripping Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 07/17] virtio: Remove unnecessary adapter structure Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 08/17] virtio: Remove redundant vq_alignment Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 09/17] virtio: Fix how states are handled during initialization Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 10/17] virtio: Make vtpci_get_status local Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 11/17] virtio: Check for packet headroom at compile time Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 12/17] virtio: Move allocation before initialization Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 13/17] virtio: Add support for vlan filtering Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 14/17] virtio: Add suport for multiple mac addresses Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 15/17] virtio: Add ability to set MAC address Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 16/17] virtio: Free mbuf's with threshold Ouyang Changchun
2014-12-08 6:21 ` [dpdk-dev] [RFC PATCH 17/17] virtio: Use port IO to get PCI resource Ouyang Changchun
2014-12-08 9:30 ` [dpdk-dev] [RFC PATCH 00/17] Single virtio implementation Thomas Monjalon
2014-12-09 1:08 ` Ouyang, Changchun
2014-12-09 3:23 ` Qiu, Michael
2014-12-09 5:24 ` Stephen Hemminger
2014-12-09 5:41 ` Ouyang, Changchun
2014-12-09 6:11 ` Thomas Monjalon
2014-12-09 6:40 ` Ouyang, Changchun
2014-12-09 8:53 ` Thomas Monjalon
2014-12-09 9:46 ` Bruce Richardson
2014-12-09 14:08 ` Ouyang, Changchun
2014-12-09 16:03 ` Qiu, Michael
2014-12-10 0:29 ` Ouyang, Changchun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1418019716-4962-5-git-send-email-changchun.ouyang@intel.com \
--to=changchun.ouyang@intel.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).