get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/13323/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 13323,
    "url": "http://patches.dpdk.org/api/patches/13323/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1465317632-11471-18-git-send-email-jerin.jacob@caviumnetworks.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1465317632-11471-18-git-send-email-jerin.jacob@caviumnetworks.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1465317632-11471-18-git-send-email-jerin.jacob@caviumnetworks.com",
    "date": "2016-06-07T16:40:29",
    "name": "[dpdk-dev,v3,17/20] thunderx/nicvf: add device start, stop and close support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5e7b31bc3f71b23c03554926871b4f5f68d8f8f2",
    "submitter": {
        "id": 305,
        "url": "http://patches.dpdk.org/api/people/305/?format=api",
        "name": "Jerin Jacob",
        "email": "jerin.jacob@caviumnetworks.com"
    },
    "delegate": {
        "id": 10,
        "url": "http://patches.dpdk.org/api/users/10/?format=api",
        "username": "bruce",
        "first_name": "Bruce",
        "last_name": "Richardson",
        "email": "bruce.richardson@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1465317632-11471-18-git-send-email-jerin.jacob@caviumnetworks.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/13323/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/13323/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 4A3A9AD9D;\n\tTue,  7 Jun 2016 18:42:33 +0200 (CEST)",
            "from na01-bn1-obe.outbound.protection.outlook.com\n\t(mail-bn1bon0071.outbound.protection.outlook.com [157.56.111.71])\n\tby dpdk.org (Postfix) with ESMTP id 15E07AD9D\n\tfor <dev@dpdk.org>; Tue,  7 Jun 2016 18:42:31 +0200 (CEST)",
            "from localhost.caveonetworks.com (111.93.218.67) by\n\tBN3PR0701MB1719.namprd07.prod.outlook.com (10.163.39.18) with\n\tMicrosoft SMTP\n\tServer (TLS) id 15.1.511.8; Tue, 7 Jun 2016 16:42:26 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version;\n\tbh=YNfS3jvh1XOdi+cIS6aYNNXp6p2BlBwyVzdqhlcH6uk=;\n\tb=BnaaZ+bCNXVAB+ERpAUhVgn5Yu/qlczrArhU2D8WMsE/pYQyDYNzJiSnfTfmQ6vd+AokmC0eAKqcVxrwoc+cco/7PDyX451+JxEExgEF2CGl0fpOr07aDLwCVBFgrvOAaeNiaYfks0wGTwJsjDKioYa7K2uTj/a4aYjdOdoGxgw=",
        "Authentication-Results": "spf=none (sender IP is )\n\tsmtp.mailfrom=Jerin.Jacob@cavium.com; ",
        "From": "Jerin Jacob <jerin.jacob@caviumnetworks.com>",
        "To": "<dev@dpdk.org>",
        "CC": "<thomas.monjalon@6wind.com>, <bruce.richardson@intel.com>, Jerin Jacob\n\t<jerin.jacob@caviumnetworks.com>, Maciej Czekaj\n\t<maciej.czekaj@caviumnetworks.com>, Kamil Rytarowski\n\t<Kamil.Rytarowski@caviumnetworks.com>,\n\tZyta Szpak <zyta.szpak@semihalf.com>, \n\tSlawomir Rosek <slawomir.rosek@semihalf.com>, Radoslaw Biernacki\n\t<rad@semihalf.com>",
        "Date": "Tue, 7 Jun 2016 22:10:29 +0530",
        "Message-ID": "<1465317632-11471-18-git-send-email-jerin.jacob@caviumnetworks.com>",
        "X-Mailer": "git-send-email 2.5.5",
        "In-Reply-To": "<1465317632-11471-1-git-send-email-jerin.jacob@caviumnetworks.com>",
        "References": "<1464540424-12631-1-git-send-email-jerin.jacob@caviumnetworks.com>\n\t<1465317632-11471-1-git-send-email-jerin.jacob@caviumnetworks.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[111.93.218.67]",
        "X-ClientProxiedBy": "MAXPR01CA0054.INDPRD01.PROD.OUTLOOK.COM (10.164.146.154)\n\tTo\n\tBN3PR0701MB1719.namprd07.prod.outlook.com (10.163.39.18)",
        "X-MS-Office365-Filtering-Correlation-Id": "3e1d24d4-acbb-445c-59ea-08d38ef2b723",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; BN3PR0701MB1719;\n\t2:9QoPmvESWTVvwyIl2BJKKlpOUwZP4YpkBaqnt0lKKSc9rHMyk63bW72JGvsgQQQURguq8lOiF97Ut1om4K5aHn+uGFPt/JIDzlnxvz5ZfSeoS7vo7LNB0JWyhSZtVqmnSbDHyv+PU3FtwlnJfwewcE4X3Ew22ZG+NuzPVGs+gpLpmSlSQ0ec232AIxteGLwq;\n\t3:kiJulJRBnsqw4oQNDkfWagP5wMC2biDYcC3R7GJIjRtWThjXmkagYl+UMgz4qW0dV3SeG388bL8YWywRe98MGJzLUAVdlHfdNfed2k7WfLm5CTqZViEhapnmx42YRo28;\n\t25:z3jN4UCwI9hO6MyrOCuWmoFsgCv1Gak/nCLDRV13gMSBZqDLCoc+XXpMUO6CFcVH9IE1V0NmWyKMYR52CQ7ws3C8SF4W1o2ty381l+1avZclnjRotfQEEnZxWha+JLtMV+9dSd9IP2zRIa2XWYi3c4IE+BF8CtqiQf6d2WB83HfVGUdRqcfPql6hLerkFRck4xiwKTd38BcGnqoDmEwNxO5Cb1vfMPxDhoy8ea8u7ren64r/K+0QV27hY+kFp+O9QH6ybxu9bQzL8c9wn64l5CK+2rJq3MBFNQNQeisf/JRPA6obS+xn0/pmslidorhLKviiDh/gX/KBu8lYKi7BjtyG5sPlgMQIlH7ezZqsK+lEeDSK533J9UqEQ8afX6P71z/rsXxzn0YaVL4/8xjXoYJ0vLcp2fg8FEYCO1JIf/E=",
            "1; BN3PR0701MB1719;\n\t20:8Guuyg1ds983HyAAj0AV7hnr03o2IkZHfcRWJtmDUfWYDBg2sSXO5quvmjEaVdv7Iss4Q18QAgDxMO+aLyjKCkGLEEywoJlpyy/WERfANhPvdPAOACkZ1Sjlwq7jDgXa6KG4fFKUeZ5zfF9FQVgW1NuYnNZI+g6msMDCzF+2hMWMy0hOjYywBHqWRrWaXkIlrauKHoHZGZYEUMQV6SrarAZPiPFwKG3QuLyHqdqoqWZ7kVrePK/F0/xrXV8y3aqZTehJLRvjqIvQEhCzBf+VZBlfqelhOCnYTugP+rEcTWeL7M70MONFCFKKKpkzy2/Nd1Dy1sApDiqTL3zAIb0+zYizh2EgX5shjyEYs9aZkM+cAtwgzd0q4978OS1fbqL6Wk8A4hyOQxZoWA4uy3a+a2m/nt8utMIE182LXSSKLXlITY4b0G8N5fGW/e5GSkVLM+97ngcWIosdh15V9tiwR+qdVbCM9G9KvTlU/1L047sgs31l8uPoKj+ql43cvIqCv0VXbnpuVIvzpyE3Pa9hXQD2I8EMGFyOWBKsn6SvL8Ik1LgIGeZMICcuTOFU6jTNWF2ydGMhvJDTAnMu7ucjrlTmjomHCjhWKQJ84cJbLDI=",
            "1; BN3PR0701MB1719;\n\t4:8Uqjsrph4U0tVDLmR9gYbRKGfn2Ax7zzqi6Xa0TsmNY6hNUtfmB95qah23UmNoFSgUnDmXRGHgNKT6BStB4WfKfNypZXHmrc7laRYj4xFcwuYGT6ze0Ay4+aVUJxaBGOJOelEFdL4IceiYoO3bk7+AqnCGE6XPPM/bZAymAhOQFH1/v/DeHnQBPlHdlwMOcV6NDSB+0ydt0/PUAsWH2Do5acJqyWpa01sNpaaoq1zIhlGypFJikEoCmOSuVznqcX/gyCS4q8oHEhW272Qb3nEn7R3WFNEm1fK1Pmt5/hjrTBoqO4DzUbx+oz/POkgEYMYL8JNqPvD7qYX2FyNpuOIX603Z5bQO4ePxKH1mNvY2mci+MZRUr+oaF02ddz5lqC",
            "=?us-ascii?Q?1; BN3PR0701MB1719;\n\t23:Kx2MotY33yC/Vlx1qvjqyqgOMZpNnyiWRR6O5yT?=\n\t=?us-ascii?Q?Rf9DYBAfM1QLL395ep8/tdK9L4GC7/6pGieXrkf46UqgAHTnwekvlJ9LtzDj?=\n\t=?us-ascii?Q?VXTTz3szv78mIKgc5+8K98mMpaRBfFDxLPg7i+TmctdMTEmaZ6w3a3WtwTgL?=\n\t=?us-ascii?Q?hFMM2QKYAMBSYA08kXsaoso2k5mdkzCv/bttYhW5XVZsXjOaNqBCrhy5qoSg?=\n\t=?us-ascii?Q?H05D/77MlQxK4d7f/4yLrNfF9BklfnavU8jezqANJANSIXBDR4W/XNFNmfqC?=\n\t=?us-ascii?Q?ExXmXwqQo/M+H2DEPsWpgLuDKfLwEK+QBXa3ZcgvFbgiDNqO1C7zHi+xItlF?=\n\t=?us-ascii?Q?2qPcJmGTohWuu+bHakIlJWqzLjvf9UEbFZN+5lxybdjVwaA1gIbW59PQ+00X?=\n\t=?us-ascii?Q?vQIIinb3RdToWKvCRLhvticQGT4fTp1G0zx6iLO4VEOHE/YlnQUa1z3RiR3S?=\n\t=?us-ascii?Q?b7WfYW/eoG1sY+mlLHiqo5IiNi0mGScmU1NoUvEslNm9Mf1jyS+ShI/LHv13?=\n\t=?us-ascii?Q?y4cn05VV5UGQcoLt6w/BVM4JyM8igOC3VnaF9XSjHvsCuCXhJEPGSpITDsEJ?=\n\t=?us-ascii?Q?IK9Si6pKsyIWffMEQkFMI3Ud7qRcWURaBtzW6EAOzT5NJB+XSMxY+IPbg7x2?=\n\t=?us-ascii?Q?gR3TUKEwpADG8qLPhg3tynQKnnGBOcMBlgsjrZ+pktgh3G1NQAucenZ9Ncgc?=\n\t=?us-ascii?Q?lb02zIobsURP2waSjN5ckw4GeNVwxgkEQ7nYh9bATgB3tX7tFApmnHesIOlq?=\n\t=?us-ascii?Q?8S9l2FD044eL9BGX61mH3BqNsaiWtg7H2b2Eow9SanLLkStHyX2pGJLAIEHs?=\n\t=?us-ascii?Q?3BOoBMY4FyIzUHG8xqd5LxpexmH6ZEJbhSsMAMrSYwETO4G32+7m8zxrphMJ?=\n\t=?us-ascii?Q?ndBK8OftD7jFEzmdqNB7QmfS0xb4mJvovv+A1JatJwttUyR/OCfJ9qrIuzJi?=\n\t=?us-ascii?Q?e4aSlPLtYlSo8jpMx01r9I0Hdt5LJ1d5ELkNmS5In691lBfoTMtf/zRfrXoh?=\n\t=?us-ascii?Q?3UrFkQEdYr/vuGJr7bVV8h3EAhoIFRmAZ7PH8kTYO/LW54CgcStPJHO9YSar?=\n\t=?us-ascii?Q?gaCpBzCRKBO2ftnfOuQG7ln8CkjO+hT47Pup58JyTHO9PfB7biql/EUohtso?=\n\t=?us-ascii?Q?J300NzkN2cJJegGaQkBk1TZJcqUXzvmhlYT6XbwMTrImjkSr5jx97xDGbMRK?=\n\t=?us-ascii?Q?FocHfTMiEpF4+ifEk9nAKcsFFQ4nPHyo/Kbkj?=",
            "1; BN3PR0701MB1719;\n\t5:k9e/0ncNta0oLqTFmXf1Usa64eVCdwDuddXDGZ5KXv7+Y8LwX9npvlN22LW/YE7lrFt45BfdJ02U6aR5DaN4Je+djRQh/OYwhKF6XeVpldggxL/+U23RTSPhJoKJtDuA7HGYfyPqUSykMdFzc0MROA==;\n\t24:6VkyyeIB2Q2VeJmSyaZKAJxxYiwXUEVypGcDVh4oNS0yH4MWuF2xkWpB0rfLMBV7WY121y28hlkZw47lFCcEB7eZRbY0L7oD6waXR1q4VA8=;\n\t7:WbnES9GFzXdTn5dhxnntV44IVJKJmMZSzGnBUtyovZdt4JddYHovF4KqZ80Vj0JccxIGJaEvDL3Bl++IMTmGlovSM1PrbsyRrl4zuPmE0zriMpwN1Qzh64/xRsYfdRLtYuWS1XZkWNNh/ATjRrg62TrUmIHzwR4noUaoEda2vzmunuKr9ZBC5y+FNPHNgddJ/dKeJWmvVC7QPJKyJAJni2HbHvgGK6aCMH/kxTC/OEc="
        ],
        "X-Microsoft-Antispam": "UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN3PR0701MB1719;",
        "X-Microsoft-Antispam-PRVS": "<BN3PR0701MB1719E19DA50004F5F014AC94815D0@BN3PR0701MB1719.namprd07.prod.outlook.com>",
        "X-Exchange-Antispam-Report-Test": "UriScan:;",
        "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046); \n\tSRVR:BN3PR0701MB1719; BCL:0; PCL:0; RULEID:; SRVR:BN3PR0701MB1719; ",
        "X-Forefront-PRVS": "09669DB681",
        "X-Forefront-Antispam-Report": "SFV:NSPM;\n\tSFS:(10009020)(4630300001)(6069001)(6009001)(199003)(189002)(81166006)(8676002)(81156014)(47776003)(66066001)(36756003)(92566002)(2950100001)(586003)(2351001)(48376002)(76506005)(42186005)(50466002)(4326007)(77096005)(3846002)(6116002)(5003940100001)(53416004)(5890100001)(5004730100002)(105586002)(97736004)(2906002)(5008740100001)(106356001)(189998001)(19580395003)(69596002)(101416001)(110136002)(19580405001)(68736007)(33646002)(76176999)(50986999)(229853001)(50226002)(5009440100003)(7099028)(142933001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:BN3PR0701MB1719;\n\tH:localhost.caveonetworks.com; \n\tFPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; ",
        "Received-SPF": "None (protection.outlook.com: cavium.com does not designate\n\tpermitted sender hosts)",
        "SpamDiagnosticOutput": "1:99",
        "SpamDiagnosticMetadata": "NSPM",
        "X-OriginatorOrg": "caviumnetworks.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "07 Jun 2016 16:42:26.6538\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "BN3PR0701MB1719",
        "Subject": "[dpdk-dev]  [PATCH v3 17/20] thunderx/nicvf: add device start,\n\tstop and close support",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>\nSigned-off-by: Maciej Czekaj <maciej.czekaj@caviumnetworks.com>\nSigned-off-by: Kamil Rytarowski <Kamil.Rytarowski@caviumnetworks.com>\nSigned-off-by: Zyta Szpak <zyta.szpak@semihalf.com>\nSigned-off-by: Slawomir Rosek <slawomir.rosek@semihalf.com>\nSigned-off-by: Radoslaw Biernacki <rad@semihalf.com>\n---\n drivers/net/thunderx/nicvf_ethdev.c | 468 ++++++++++++++++++++++++++++++++++++\n 1 file changed, 468 insertions(+)",
    "diff": "diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c\nindex baa2e7a..2a9ac77 100644\n--- a/drivers/net/thunderx/nicvf_ethdev.c\n+++ b/drivers/net/thunderx/nicvf_ethdev.c\n@@ -70,7 +70,10 @@\n #include \"nicvf_logs.h\"\n \n static int nicvf_dev_configure(struct rte_eth_dev *dev);\n+static int nicvf_dev_start(struct rte_eth_dev *dev);\n+static void nicvf_dev_stop(struct rte_eth_dev *dev);\n static int nicvf_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete);\n+static void nicvf_dev_close(struct rte_eth_dev *dev);\n static void nicvf_dev_stats_get(struct rte_eth_dev *dev,\n \t\t\t\tstruct rte_eth_stats *stat);\n static void nicvf_dev_stats_reset(struct rte_eth_dev *dev);\n@@ -570,6 +573,82 @@ nicvf_qset_sq_alloc(struct nicvf *nic,  struct nicvf_txq *sq, uint16_t qidx,\n \treturn 0;\n }\n \n+static int\n+nicvf_qset_rbdr_alloc(struct nicvf *nic, uint32_t desc_cnt, uint32_t buffsz)\n+{\n+\tstruct nicvf_rbdr *rbdr;\n+\tconst struct rte_memzone *rz;\n+\tuint32_t ring_size;\n+\n+\tassert(nic->rbdr == NULL);\n+\trbdr = rte_zmalloc_socket(\"rbdr\", sizeof(struct nicvf_rbdr),\n+\t\t\t\t  RTE_CACHE_LINE_SIZE, nic->node);\n+\tif (rbdr == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate mem for rbdr\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tring_size = sizeof(struct rbdr_entry_t) * desc_cnt;\n+\trz = rte_eth_dma_zone_reserve(nic->eth_dev, \"rbdr\", 0, ring_size,\n+\t\t\t\t   NICVF_RBDR_BASE_ALIGN_BYTES, nic->node);\n+\tif (rz == NULL) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate mem for rbdr desc ring\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmemset(rz->addr, 0, ring_size);\n+\n+\trbdr->phys = rz->phys_addr;\n+\trbdr->tail = 0;\n+\trbdr->next_tail = 0;\n+\trbdr->desc = rz->addr;\n+\trbdr->buffsz = buffsz;\n+\trbdr->qlen_mask = desc_cnt - 1;\n+\trbdr->rbdr_status =\n+\t\tnicvf_qset_base(nic, 0) + NIC_QSET_RBDR_0_1_STATUS0;\n+\trbdr->rbdr_door =\n+\t\tnicvf_qset_base(nic, 0) + NIC_QSET_RBDR_0_1_DOOR;\n+\n+\tnic->rbdr = rbdr;\n+\treturn 0;\n+}\n+\n+static void\n+nicvf_rbdr_release_mbuf(struct nicvf *nic, nicvf_phys_addr_t phy)\n+{\n+\tuint16_t qidx;\n+\tvoid *obj;\n+\tstruct nicvf_rxq *rxq;\n+\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_rx_queues; qidx++) {\n+\t\trxq = nic->eth_dev->data->rx_queues[qidx];\n+\t\tif (rxq->precharge_cnt) {\n+\t\t\tobj = (void *)nicvf_mbuff_phy2virt(phy,\n+\t\t\t\t\t\t\t   rxq->mbuf_phys_off);\n+\t\t\trte_mempool_put(rxq->pool, obj);\n+\t\t\trxq->precharge_cnt--;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+}\n+\n+static inline void\n+nicvf_rbdr_release_mbufs(struct nicvf *nic)\n+{\n+\tuint32_t qlen_mask, head;\n+\tstruct rbdr_entry_t *entry;\n+\tstruct nicvf_rbdr *rbdr = nic->rbdr;\n+\n+\tqlen_mask = rbdr->qlen_mask;\n+\thead = rbdr->head;\n+\twhile (head != rbdr->tail) {\n+\t\tentry = rbdr->desc + head;\n+\t\tnicvf_rbdr_release_mbuf(nic, entry->full_addr);\n+\t\thead++;\n+\t\thead = head & qlen_mask;\n+\t}\n+}\n+\n static inline void\n nicvf_tx_queue_release_mbufs(struct nicvf_txq *txq)\n {\n@@ -666,6 +745,31 @@ nicvf_configure_cpi(struct rte_eth_dev *dev)\n \treturn ret;\n }\n \n+static inline int\n+nicvf_configure_rss(struct rte_eth_dev *dev)\n+{\n+\tstruct nicvf *nic = nicvf_pmd_priv(dev);\n+\tuint64_t rsshf;\n+\tint ret = -EINVAL;\n+\n+\trsshf = nicvf_rss_ethdev_to_nic(nic,\n+\t\t\tdev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf);\n+\tPMD_DRV_LOG(INFO, \"mode=%d rx_queues=%d loopback=%d rsshf=0x%\" PRIx64,\n+\t\t    dev->data->dev_conf.rxmode.mq_mode,\n+\t\t    nic->eth_dev->data->nb_rx_queues,\n+\t\t    nic->eth_dev->data->dev_conf.lpbk_mode, rsshf);\n+\n+\tif (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_NONE)\n+\t\tret = nicvf_rss_term(nic);\n+\telse if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS)\n+\t\tret = nicvf_rss_config(nic,\n+\t\t\t\t       nic->eth_dev->data->nb_rx_queues, rsshf);\n+\tif (ret)\n+\t\tPMD_INIT_LOG(ERR, \"Failed to configure RSS %d\", ret);\n+\n+\treturn ret;\n+}\n+\n static int\n nicvf_configure_rss_reta(struct rte_eth_dev *dev)\n {\n@@ -710,6 +814,48 @@ nicvf_dev_tx_queue_release(void *sq)\n \t}\n }\n \n+static void\n+nicvf_set_tx_function(struct rte_eth_dev *dev)\n+{\n+\tstruct nicvf_txq *txq;\n+\tsize_t i;\n+\tbool multiseg = false;\n+\n+\tfor (i = 0; i < dev->data->nb_tx_queues; i++) {\n+\t\ttxq = dev->data->tx_queues[i];\n+\t\tif ((txq->txq_flags & ETH_TXQ_FLAGS_NOMULTSEGS) == 0) {\n+\t\t\tmultiseg = true;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Use a simple Tx queue (no offloads, no multi segs) if possible */\n+\tif (multiseg) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Using multi-segment tx callback\");\n+\t\tdev->tx_pkt_burst = nicvf_xmit_pkts_multiseg;\n+\t} else {\n+\t\tPMD_DRV_LOG(DEBUG, \"Using single-segment tx callback\");\n+\t\tdev->tx_pkt_burst = nicvf_xmit_pkts;\n+\t}\n+\n+\tif (txq->pool_free == nicvf_single_pool_free_xmited_buffers)\n+\t\tPMD_DRV_LOG(DEBUG, \"Using single-mempool tx free method\");\n+\telse\n+\t\tPMD_DRV_LOG(DEBUG, \"Using multi-mempool tx free method\");\n+}\n+\n+static void\n+nicvf_set_rx_function(struct rte_eth_dev *dev)\n+{\n+\tif (dev->data->scattered_rx) {\n+\t\tPMD_DRV_LOG(DEBUG, \"Using multi-segment rx callback\");\n+\t\tdev->rx_pkt_burst = nicvf_recv_pkts_multiseg;\n+\t} else {\n+\t\tPMD_DRV_LOG(DEBUG, \"Using single-segment rx callback\");\n+\t\tdev->rx_pkt_burst = nicvf_recv_pkts;\n+\t}\n+}\n+\n static int\n nicvf_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t qidx,\n \t\t\t uint16_t nb_desc, unsigned int socket_id,\n@@ -1113,6 +1259,317 @@ nicvf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)\n \t};\n }\n \n+static nicvf_phys_addr_t\n+rbdr_rte_mempool_get(void *opaque)\n+{\n+\tuint16_t qidx;\n+\tuintptr_t mbuf;\n+\tstruct nicvf_rxq *rxq;\n+\tstruct nicvf *nic = nicvf_pmd_priv((struct rte_eth_dev *)opaque);\n+\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_rx_queues; qidx++) {\n+\t\trxq = nic->eth_dev->data->rx_queues[qidx];\n+\t\t/* Maintain equal buffer count across all pools */\n+\t\tif (rxq->precharge_cnt >= rxq->qlen_mask)\n+\t\t\tcontinue;\n+\t\trxq->precharge_cnt++;\n+\t\tmbuf = (uintptr_t)rte_pktmbuf_alloc(rxq->pool);\n+\t\tif (mbuf)\n+\t\t\treturn nicvf_mbuff_virt2phy(mbuf, rxq->mbuf_phys_off);\n+\t}\n+\treturn 0;\n+}\n+\n+static int\n+nicvf_dev_start(struct rte_eth_dev *dev)\n+{\n+\tint ret;\n+\tuint16_t qidx;\n+\tuint32_t buffsz = 0, rbdrsz = 0;\n+\tuint32_t total_rxq_desc, nb_rbdr_desc, exp_buffs;\n+\tuint64_t mbuf_phys_off = 0;\n+\tstruct nicvf_rxq *rxq;\n+\tstruct rte_pktmbuf_pool_private *mbp_priv;\n+\tstruct rte_mbuf *mbuf;\n+\tstruct nicvf *nic = nicvf_pmd_priv(dev);\n+\tstruct rte_eth_rxmode *rx_conf = &dev->data->dev_conf.rxmode;\n+\tuint16_t mtu;\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\t/* Userspace process exited witout proper shutdown in last run */\n+\tif (nicvf_qset_rbdr_active(nic, 0))\n+\t\tnicvf_dev_stop(dev);\n+\n+\t/*\n+\t * Thunderx nicvf PMD can support more than one pool per port only when\n+\t * 1) Data payload size is same across all the pools in given port\n+\t * AND\n+\t * 2) All mbuffs in the pools are from the same hugepage\n+\t * AND\n+\t * 3) Mbuff metadata size is same across all the pools in given port\n+\t *\n+\t * This is to support existing application that uses multiple pool/port.\n+\t * But, the purpose of using multipool for QoS will not be addressed.\n+\t *\n+\t */\n+\n+\t/* Validate RBDR buff size */\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_rx_queues; qidx++) {\n+\t\trxq = dev->data->rx_queues[qidx];\n+\t\tmbp_priv = rte_mempool_get_priv(rxq->pool);\n+\t\tbuffsz = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;\n+\t\tif (buffsz % 128) {\n+\t\t\tPMD_INIT_LOG(ERR, \"rxbuf size must be multiply of 128\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tif (rbdrsz == 0)\n+\t\t\trbdrsz = buffsz;\n+\t\tif (rbdrsz != buffsz) {\n+\t\t\tPMD_INIT_LOG(ERR, \"buffsz not same, qid=%d (%d/%d)\",\n+\t\t\t\t     qidx, rbdrsz, buffsz);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t/* Validate mempool attributes */\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_rx_queues; qidx++) {\n+\t\trxq = dev->data->rx_queues[qidx];\n+\t\trxq->mbuf_phys_off = nicvf_mempool_phy_offset(rxq->pool);\n+\t\tmbuf = rte_pktmbuf_alloc(rxq->pool);\n+\t\tif (mbuf == NULL) {\n+\t\t\tPMD_INIT_LOG(ERR, \"Failed allocate mbuf qid=%d pool=%s\",\n+\t\t\t\t     qidx, rxq->pool->name);\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\t\trxq->mbuf_phys_off -= nicvf_mbuff_meta_length(mbuf);\n+\t\trxq->mbuf_phys_off -= RTE_PKTMBUF_HEADROOM;\n+\t\trte_pktmbuf_free(mbuf);\n+\n+\t\tif (mbuf_phys_off == 0)\n+\t\t\tmbuf_phys_off = rxq->mbuf_phys_off;\n+\t\tif (mbuf_phys_off != rxq->mbuf_phys_off) {\n+\t\t\tPMD_INIT_LOG(ERR, \"pool params not same,%s %\" PRIx64,\n+\t\t\t\t     rxq->pool->name, mbuf_phys_off);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t/* Check the level of buffers in the pool */\n+\ttotal_rxq_desc = 0;\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_rx_queues; qidx++) {\n+\t\trxq = dev->data->rx_queues[qidx];\n+\t\t/* Count total numbers of rxq descs */\n+\t\ttotal_rxq_desc += rxq->qlen_mask + 1;\n+\t\texp_buffs = RTE_MEMPOOL_CACHE_MAX_SIZE + rxq->rx_free_thresh;\n+\t\texp_buffs *= nic->eth_dev->data->nb_rx_queues;\n+\t\tif (rte_mempool_count(rxq->pool) < exp_buffs) {\n+\t\t\tPMD_INIT_LOG(ERR, \"Buff shortage in pool=%s (%d/%d)\",\n+\t\t\t\t     rxq->pool->name,\n+\t\t\t\t     rte_mempool_count(rxq->pool),\n+\t\t\t\t     exp_buffs);\n+\t\t\treturn -ENOENT;\n+\t\t}\n+\t}\n+\n+\t/* Check RBDR desc overflow */\n+\tret = nicvf_qsize_rbdr_roundup(total_rxq_desc);\n+\tif (ret == 0) {\n+\t\tPMD_INIT_LOG(ERR, \"Reached RBDR desc limit, reduce nr desc\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* Enable qset */\n+\tret = nicvf_qset_config(nic);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to enable qset %d\", ret);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Allocate RBDR and RBDR ring desc */\n+\tnb_rbdr_desc = nicvf_qsize_rbdr_roundup(total_rxq_desc);\n+\tret = nicvf_qset_rbdr_alloc(nic, nb_rbdr_desc, rbdrsz);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to allocate memory for rbdr alloc\");\n+\t\tgoto qset_reclaim;\n+\t}\n+\n+\t/* Enable and configure RBDR registers */\n+\tret = nicvf_qset_rbdr_config(nic, 0);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to configure rbdr %d\", ret);\n+\t\tgoto qset_rbdr_free;\n+\t}\n+\n+\t/* Fill rte_mempool buffers in RBDR pool and precharge it */\n+\tret = nicvf_qset_rbdr_precharge(nic, 0, rbdr_rte_mempool_get,\n+\t\t\t\t\tdev, total_rxq_desc);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to fill rbdr %d\", ret);\n+\t\tgoto qset_rbdr_reclaim;\n+\t}\n+\n+\tPMD_DRV_LOG(INFO, \"Filled %d out of %d entries in RBDR\",\n+\t\t     nic->rbdr->tail, nb_rbdr_desc);\n+\n+\t/* Configure RX queues */\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_rx_queues; qidx++) {\n+\t\tret = nicvf_start_rx_queue(dev, qidx);\n+\t\tif (ret)\n+\t\t\tgoto start_rxq_error;\n+\t}\n+\n+\t/* Configure VLAN Strip */\n+\tnicvf_vlan_hw_strip(nic, dev->data->dev_conf.rxmode.hw_vlan_strip);\n+\n+\t/* Configure TX queues */\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_tx_queues; qidx++) {\n+\t\tret = nicvf_start_tx_queue(dev, qidx);\n+\t\tif (ret)\n+\t\t\tgoto start_txq_error;\n+\t}\n+\n+\t/* Configure CPI algorithm */\n+\tret = nicvf_configure_cpi(dev);\n+\tif (ret)\n+\t\tgoto start_txq_error;\n+\n+\t/* Configure RSS */\n+\tret = nicvf_configure_rss(dev);\n+\tif (ret)\n+\t\tgoto qset_rss_error;\n+\n+\t/* Configure loopback */\n+\tret = nicvf_loopback_config(nic, dev->data->dev_conf.lpbk_mode);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to configure loopback %d\", ret);\n+\t\tgoto qset_rss_error;\n+\t}\n+\n+\t/* Reset all statistics counters attached to this port */\n+\tret = nicvf_mbox_reset_stat_counters(nic, 0x3FFF, 0x1F, 0xFFFF, 0xFFFF);\n+\tif (ret) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to reset stat counters %d\", ret);\n+\t\tgoto qset_rss_error;\n+\t}\n+\n+\t/* Setup scatter mode if needed by jumbo */\n+\tif (dev->data->dev_conf.rxmode.max_rx_pkt_len +\n+\t\t\t\t\t    2 * VLAN_TAG_SIZE > buffsz)\n+\t\tdev->data->scattered_rx = 1;\n+\tif (rx_conf->enable_scatter)\n+\t\tdev->data->scattered_rx = 1;\n+\n+\t/* Setup MTU based on max_rx_pkt_len or default */\n+\tmtu = dev->data->dev_conf.rxmode.jumbo_frame ?\n+\t\tdev->data->dev_conf.rxmode.max_rx_pkt_len\n+\t\t\t-  ETHER_HDR_LEN - ETHER_CRC_LEN\n+\t\t: ETHER_MTU;\n+\n+\tif (nicvf_dev_set_mtu(dev, mtu)) {\n+\t\tPMD_INIT_LOG(ERR, \"Failed to set default mtu size\");\n+\t\treturn -EBUSY;\n+\t}\n+\n+\t/* Configure callbacks based on scatter mode */\n+\tnicvf_set_tx_function(dev);\n+\tnicvf_set_rx_function(dev);\n+\n+\t/* Done; Let PF make the BGX's RX and TX switches to ON position */\n+\tnicvf_mbox_cfg_done(nic);\n+\treturn 0;\n+\n+qset_rss_error:\n+\tnicvf_rss_term(nic);\n+start_txq_error:\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_tx_queues; qidx++)\n+\t\tnicvf_stop_tx_queue(dev, qidx);\n+start_rxq_error:\n+\tfor (qidx = 0; qidx < nic->eth_dev->data->nb_rx_queues; qidx++)\n+\t\tnicvf_stop_rx_queue(dev, qidx);\n+qset_rbdr_reclaim:\n+\tnicvf_qset_rbdr_reclaim(nic, 0);\n+\tnicvf_rbdr_release_mbufs(nic);\n+qset_rbdr_free:\n+\tif (nic->rbdr) {\n+\t\trte_free(nic->rbdr);\n+\t\tnic->rbdr = NULL;\n+\t}\n+qset_reclaim:\n+\tnicvf_qset_reclaim(nic);\n+\treturn ret;\n+}\n+\n+static void\n+nicvf_dev_stop(struct rte_eth_dev *dev)\n+{\n+\tint ret;\n+\tuint16_t qidx;\n+\tstruct nicvf *nic = nicvf_pmd_priv(dev);\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\t/* Let PF make the BGX's RX and TX switches to OFF position */\n+\tnicvf_mbox_shutdown(nic);\n+\n+\t/* Disable loopback */\n+\tret = nicvf_loopback_config(nic, 0);\n+\tif (ret)\n+\t\tPMD_INIT_LOG(ERR, \"Failed to disable loopback %d\", ret);\n+\n+\t/* Disable VLAN Strip */\n+\tnicvf_vlan_hw_strip(nic, 0);\n+\n+\t/* Reclaim sq */\n+\tfor (qidx = 0; qidx < dev->data->nb_tx_queues; qidx++)\n+\t\tnicvf_stop_tx_queue(dev, qidx);\n+\n+\t/* Reclaim rq */\n+\tfor (qidx = 0; qidx < dev->data->nb_rx_queues; qidx++)\n+\t\tnicvf_stop_rx_queue(dev, qidx);\n+\n+\t/* Reclaim RBDR */\n+\tret = nicvf_qset_rbdr_reclaim(nic, 0);\n+\tif (ret)\n+\t\tPMD_INIT_LOG(ERR, \"Failed to reclaim RBDR %d\", ret);\n+\n+\t/* Move all charged buffers in RBDR back to pool */\n+\tif (nic->rbdr != NULL)\n+\t\tnicvf_rbdr_release_mbufs(nic);\n+\n+\t/* Reclaim CPI configuration */\n+\tif (!nic->sqs_mode) {\n+\t\tret = nicvf_mbox_config_cpi(nic, 0);\n+\t\tif (ret)\n+\t\t\tPMD_INIT_LOG(ERR, \"Failed to reclaim CPI config\");\n+\t}\n+\n+\t/* Disable qset */\n+\tret = nicvf_qset_config(nic);\n+\tif (ret)\n+\t\tPMD_INIT_LOG(ERR, \"Failed to disable qset %d\", ret);\n+\n+\t/* Disable all interrupts */\n+\tnicvf_disable_all_interrupts(nic);\n+\n+\t/* Free RBDR SW structure */\n+\tif (nic->rbdr) {\n+\t\trte_free(nic->rbdr);\n+\t\tnic->rbdr = NULL;\n+\t}\n+}\n+\n+static void\n+nicvf_dev_close(struct rte_eth_dev *dev)\n+{\n+\tstruct nicvf *nic = nicvf_pmd_priv(dev);\n+\n+\tPMD_INIT_FUNC_TRACE();\n+\n+\tnicvf_dev_stop(dev);\n+\tnicvf_periodic_alarm_stop(nic);\n+}\n+\n static int\n nicvf_dev_configure(struct rte_eth_dev *dev)\n {\n@@ -1193,7 +1650,10 @@ nicvf_dev_configure(struct rte_eth_dev *dev)\n /* Initialize and register driver with DPDK Application */\n static const struct eth_dev_ops nicvf_eth_dev_ops = {\n \t.dev_configure            = nicvf_dev_configure,\n+\t.dev_start                = nicvf_dev_start,\n+\t.dev_stop                 = nicvf_dev_stop,\n \t.link_update              = nicvf_dev_link_update,\n+\t.dev_close                = nicvf_dev_close,\n \t.stats_get                = nicvf_dev_stats_get,\n \t.stats_reset              = nicvf_dev_stats_reset,\n \t.promiscuous_enable       = nicvf_dev_promisc_enable,\n@@ -1228,6 +1688,14 @@ nicvf_eth_dev_init(struct rte_eth_dev *eth_dev)\n \n \teth_dev->dev_ops = &nicvf_eth_dev_ops;\n \n+\t/* For secondary processes, the primary has done all the work */\n+\tif (rte_eal_process_type() != RTE_PROC_PRIMARY) {\n+\t\t/* Setup callbacks for secondary process */\n+\t\tnicvf_set_tx_function(eth_dev);\n+\t\tnicvf_set_rx_function(eth_dev);\n+\t\treturn 0;\n+\t}\n+\n \tpci_dev = eth_dev->pci_dev;\n \trte_eth_copy_pci_info(eth_dev, pci_dev);\n \n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "17/20"
    ]
}