[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v3 09/12] plat/xen/drivers/net: Enable/disable interrupts for rx queues
The user can enable/disable interrupts for devices according with the operation mode he or she chooses for the device. This patch follows closely the logic implemented in the virtio net driver. Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx> Signed-off-by: Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx> --- plat/xen/drivers/net/netfront.c | 67 +++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/plat/xen/drivers/net/netfront.c b/plat/xen/drivers/net/netfront.c index f1b073fd..9d299049 100644 --- a/plat/xen/drivers/net/netfront.c +++ b/plat/xen/drivers/net/netfront.c @@ -46,6 +46,12 @@ #define DRIVER_NAME "xen-netfront" +/* TODO Same interrupt macros we use in virtio-net */ +#define NETFRONT_INTR_EN (1 << 0) +#define NETFRONT_INTR_EN_MASK (1) +#define NETFRONT_INTR_USR_EN (1 << 1) +#define NETFRONT_INTR_USR_EN_MASK (2) + #define to_netfront_dev(dev) \ __containerof(dev, struct netfront_dev, netdev) @@ -148,6 +154,22 @@ out: return status; } +/* Returns 1 if more packets available */ +static int netfront_rxq_intr_enable(struct uk_netdev_rx_queue *rxq) +{ + int more; + + /* Check if there are no more packets enabled */ + RING_FINAL_CHECK_FOR_RESPONSES(&rxq->ring, more); + if (!more) { + /* No more packets, we can enable interrupts */ + rxq->intr_enabled |= NETFRONT_INTR_EN; + unmask_evtchn(rxq->evtchn); + } + + return (more > 0); +} + static struct uk_netdev_tx_queue *netfront_txq_setup(struct uk_netdev *n, uint16_t queue_id, uint16_t nb_desc __unused, @@ -218,6 +240,10 @@ static void netfront_handler(evtchn_port_t port __unused, { struct uk_netdev_rx_queue *rxq = arg; + /* Disable the interrupt for the ring */ + rxq->intr_enabled &= ~(NETFRONT_INTR_EN); + mask_evtchn(rxq->evtchn); + /* Indicate to the network stack about an event */ uk_netdev_drv_rx_event(&rxq->netfront_dev->netdev, rxq->lqueue_id); } @@ -334,6 +360,45 @@ err_free_txrx: return rc; } +static int netfront_rx_intr_enable(struct uk_netdev *n, + struct uk_netdev_rx_queue *rxq) +{ + int rc; + + UK_ASSERT(n != NULL); + UK_ASSERT(rxq != NULL); + UK_ASSERT(&rxq->netfront_dev->netdev == n); + + /* If the interrupt is enabled */ + if (rxq->intr_enabled & NETFRONT_INTR_EN) + return 0; + + /** + * Enable the user configuration bit. This would cause the interrupt to + * be enabled automatically if the interrupt could not be enabled now + * due to data in the queue. + */ + rxq->intr_enabled = NETFRONT_INTR_USR_EN; + rc = netfront_rxq_intr_enable(rxq); + if (!rc) + rxq->intr_enabled |= NETFRONT_INTR_EN; + + return rc; +} + +static int netfront_rx_intr_disable(struct uk_netdev *n, + struct uk_netdev_rx_queue *rxq) +{ + UK_ASSERT(n != NULL); + UK_ASSERT(rxq != NULL); + UK_ASSERT(&rxq->netfront_dev->netdev == n); + + rxq->intr_enabled &= ~(NETFRONT_INTR_USR_EN | NETFRONT_INTR_EN); + mask_evtchn(rxq->evtchn); + + return 0; +} + static int netfront_txq_info_get(struct uk_netdev *n, uint16_t queue_id, struct uk_netdev_queue_info *qinfo) @@ -478,6 +543,8 @@ static const struct uk_netdev_ops netfront_ops = { .configure = netfront_configure, .txq_configure = netfront_txq_setup, .rxq_configure = netfront_rxq_setup, + .rxq_intr_enable = netfront_rx_intr_enable, + .rxq_intr_disable = netfront_rx_intr_disable, .txq_info_get = netfront_txq_info_get, .rxq_info_get = netfront_rxq_info_get, .info_get = netfront_info_get, -- 2.20.1 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |