[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH v2 12/12] plat/xen/drivers/net: Add receive operation


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Mon, 1 Apr 2019 16:42:52 +0300
  • Cc: felipe.huici@xxxxxxxxx, Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx>, Florian.Schmidt@xxxxxxxxx, sharan.santhanam@xxxxxxxxx, simon.kuenzer@xxxxxxxxx, yuri.volchkov@xxxxxxxxx
  • Delivery-date: Mon, 01 Apr 2019 13:43:08 +0000
  • Ironport-phdr: 9a23:7i48+xWuZ7adVBj2sDJX3TteAIfV8LGtZVwlr6E/grcLSJyIuqrYZRWPv6dThVPEFb/W9+hDw7KP9fy5ASpRvd3f7DgrS99lb1c9k8IYnggtUoauKHbQC7rUVRE8B9lIT1R//nu2YgB/Ecf6YEDO8DXptWZBUhrwOhBoKevrB4Xck9q41/yo+53Ufg5EmCexbal9IRmrsQndrM0bjIRtJqswxRbCv2dFdflRyW50P1yYggzy5t23/J5t8iRQv+wu+stdWqjkfKo2UKJVAi0+P286+MPkux/DTRCS5nQHSWUZjgBIAwne4x7kWJr6rzb3ufB82CmeOs32UKw0VDG/5KplVBPklCEKPCMi/WrJlsJ/kr5UoBO5pxx+3YHUZp2VNOFjda/ZZN8WWHZNUtpUWyFHH4iybZYAD/AZMOhYsYfzulUAoxi5CwauCuPi0SNEimPs0KEmyektDR3K0Qo9FNwOqnTUq9D1Ob8MXOCy16nI0TTDb/VL0jn79YjIag0hquyLUL1sdsrR0lUvFwLDjlmKrYzlIiuV1vkWvmeH9OpsT/qvi3M8pA1ruDivwd4hh4/UjYwW0lDJ7Th1zYkoKdGiS0N2YcSoHIVOuyyYLYd7TNsuT3xntSon0LELup62cDIUxJkpyRPTceGLfoeW7h/lSe2fOy13hGh/d7K6nxuy9E+gxfDiWcSsy1ZKqzZFksHLtnAQyxzf8siHReV5/kemwTuPyQXT5ftFIUAwj6bUN4UhzqQolpoOqkvPBDX2mELugK+XcEUr5PSo5vz6brjpu5OQLYx5hwHkPqgwhMCyA/40PwYWU2ie4+u81bnj/UPjQLVNi/07irXWsJfBJcQHp665BRVZ0oI+6xanEjery8gXnWIdIFJdZRKIlJLlO0vJIPzgF/ewn0yskCt3x/DBJrDhGI/CL3ndkLj7e7Zx8VJTyA0xzdBY+51bEKsBIO/3V0L/r9HYARo5PBa1w+bjEtlyyoQeWWeXCK+DLKzSqUOI5v4oI+SUYY8VuTD9K/ki5/71lHM2hEESfbe30psTc324GvVmI16FYXr3mNsAHnkFvgwkQOztkl2CXiZZZ2yuUKIk+jE7FIWmAJ/DSICph7yBxia7EYdQZmxcF16DDXfod4CFW/gRdCKfOclhnSIYWrilUYAuzguiuxHny7B/NOrb5jUYtY7/1Nhy/+DTmw899Th1D8SFzW6BVWF0nn4JRzAq3aByukp9xUmf3qh8mfNXDsZf6O1UUg0iL57T0/R6C8zuWgLGZtqJU1amTc+8AT4rSNI92cQObFx7G9W+jhDMxSyqDKUQl7GQApw77L7T33zrKMlm0XrJyrQhhUE8QsRTLW2mmrJ/9w/LCo7SkkWZkqGqdaIG0C7O6WeM02yOvUBGXw5qSqjFW24QaVfSrdvj/UzOVaGhCak/OAtb1cGCMrdKasHujVheRPbjJc7eY2Orl2euAhaIwq+DbIrpe2UawiXQE04EnB4P8naCLwcxHT2trHzDDG8mKVW6ZkLq8O5l7X+2UEIw5wWLdFF6kaq4/FgSn/PPZekU2+cvvzw9qjM8OEulwpqCAN2buwtnOqFBec4V60wBzX/T8RZ6aM/zZ5t+j0ITJlwk93jl0A96X8AZyZAn
  • Ironport-sdr: 2nTAUGjPeiPztH1WC9tsiCa70ucjK9magxZkZLUtZQKE1OCaj301qe/q0V2CzV8KgBw6YgzwYC i33Xg8sE+ROw==
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

This patch adds support for receive operation

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
Signed-off-by: Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx>
---
 plat/xen/drivers/net/netfront.c | 100 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/plat/xen/drivers/net/netfront.c b/plat/xen/drivers/net/netfront.c
index be338791..6f1f6636 100644
--- a/plat/xen/drivers/net/netfront.c
+++ b/plat/xen/drivers/net/netfront.c
@@ -221,6 +221,49 @@ static int netfront_rxq_enqueue(struct uk_netdev_rx_queue 
*rxq,
        return 0;
 }
 
+static int netfront_rxq_dequeue(struct uk_netdev_rx_queue *rxq,
+               struct uk_netbuf **netbuf)
+{
+       RING_IDX prod, cons;
+       netif_rx_response_t *rx_rsp;
+       uint16_t len, id;
+       struct uk_netbuf *buf = NULL;
+       int count = 0;
+
+       UK_ASSERT(rxq != NULL);
+       UK_ASSERT(netbuf != NULL);
+
+       prod = rxq->ring.sring->rsp_prod;
+       rmb(); /* Ensure we see queued responses up to 'rp'. */
+       cons = rxq->ring.rsp_cons;
+       /* No new descriptor since last dequeue operation */
+       if (cons == prod)
+               goto out;
+
+       /* get response */
+       rx_rsp = RING_GET_RESPONSE(&rxq->ring, cons);
+       UK_ASSERT(rx_rsp->status > NETIF_RSP_NULL);
+       id = rx_rsp->id;
+       UK_ASSERT(id < NET_RX_RING_SIZE);
+
+       /* remove grant for buffer data */
+       gnttab_end_access(rxq->gref[id]);
+
+       buf = rxq->netbuf[id];
+       len = (uint16_t) rx_rsp->status;
+       if (len > ETH_PKT_LEN)
+               len = ETH_PKT_LEN;
+       buf->len = len;
+
+       *netbuf = buf;
+
+       rxq->ring.rsp_cons++;
+       count = 1;
+
+out:
+       return count;
+}
+
 static int netfront_rx_fillup(struct uk_netdev_rx_queue *rxq, uint16_t nb_desc)
 {
        struct uk_netbuf *netbuf[nb_desc];
@@ -271,6 +314,62 @@ static int netfront_rxq_intr_enable(struct 
uk_netdev_rx_queue *rxq)
        return (more > 0);
 }
 
+static int netfront_recv(struct uk_netdev *n,
+               struct uk_netdev_rx_queue *rxq,
+               struct uk_netbuf **pkt)
+{
+       int rc, status = 0;
+
+       UK_ASSERT(n != NULL);
+       UK_ASSERT(rxq != NULL);
+       UK_ASSERT(pkt != NULL);
+
+       /* Queue interrupts have to be off when calling receive */
+       UK_ASSERT(!(rxq->intr_enabled & NETFRONT_INTR_EN));
+
+       rc = netfront_rxq_dequeue(rxq, pkt);
+       UK_ASSERT(rc >= 0);
+
+       status |= (*pkt) ? UK_NETDEV_STATUS_SUCCESS : 0x0;
+       status |= netfront_rx_fillup(rxq, rc);
+
+       /* Enable interrupt only when user had previously enabled it */
+       if (rxq->intr_enabled & NETFRONT_INTR_USR_EN_MASK) {
+               /* Need to enable the interrupt on the last packet */
+               rc = netfront_rxq_intr_enable(rxq);
+               if (rc == 1 && !(*pkt)) {
+                       /**
+                        * Packet arrive after reading the queue and before
+                        * enabling the interrupt
+                        */
+                       rc = netfront_rxq_dequeue(rxq, pkt);
+                       UK_ASSERT(rc >= 0);
+                       status |= UK_NETDEV_STATUS_SUCCESS;
+
+                       /*
+                        * Since we received something, we need to fillup
+                        * and notify
+                        */
+                       status |= netfront_rx_fillup(rxq, rc);
+
+                       /* Need to enable the interrupt on the last packet */
+                       rc = netfront_rxq_intr_enable(rxq);
+                       status |= (rc == 1) ? UK_NETDEV_STATUS_MORE : 0x0;
+               } else if (*pkt) {
+                       /* When we originally got a packet and there is more */
+                       status |= (rc == 1) ? UK_NETDEV_STATUS_MORE : 0x0;
+               }
+       } else if (*pkt) {
+               /**
+                * For polling case, we report always there are further
+                * packets unless the queue is empty.
+                */
+               status |= UK_NETDEV_STATUS_MORE;
+       }
+
+       return status;
+}
+
 static struct uk_netdev_tx_queue *netfront_txq_setup(struct uk_netdev *n,
                uint16_t queue_id,
                uint16_t nb_desc __unused,
@@ -701,6 +800,7 @@ static int netfront_add_dev(struct xenbus_device *xendev)
 
        /* register netdev */
        nfdev->netdev.tx_one = netfront_xmit;
+       nfdev->netdev.rx_one = netfront_recv;
        nfdev->netdev.ops = &netfront_ops;
        rc = uk_netdev_drv_register(&nfdev->netdev, drv_allocator, DRIVER_NAME);
        if (rc < 0) {
-- 
2.11.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.