get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 44801,
    "url": "https://patches.dpdk.org/api/patches/44801/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20180917103631.32304-6-shreyansh.jain@nxp.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20180917103631.32304-6-shreyansh.jain@nxp.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180917103631.32304-6-shreyansh.jain@nxp.com",
    "date": "2018-09-17T10:36:25",
    "name": "[05/11] bus/fslmc: support memory backed portals with QBMAN 5.0",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1f4c18aa21dee3b6902d60d5c0310e5fa91b31a9",
    "submitter": {
        "id": 497,
        "url": "https://patches.dpdk.org/api/people/497/?format=api",
        "name": "Shreyansh Jain",
        "email": "shreyansh.jain@nxp.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20180917103631.32304-6-shreyansh.jain@nxp.com/mbox/",
    "series": [
        {
            "id": 1352,
            "url": "https://patches.dpdk.org/api/series/1352/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=1352",
            "date": "2018-09-17T10:36:20",
            "name": "Upgrade DPAA2 FW and other feature/bug fixes",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/1352/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/44801/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/44801/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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 476A05B16;\n\tMon, 17 Sep 2018 12:38:00 +0200 (CEST)",
            "from EUR03-DB5-obe.outbound.protection.outlook.com\n\t(mail-eopbgr40054.outbound.protection.outlook.com [40.107.4.54])\n\tby dpdk.org (Postfix) with ESMTP id 33C1A532C\n\tfor <dev@dpdk.org>; Mon, 17 Sep 2018 12:37:54 +0200 (CEST)",
            "from Tophie.ap.freescale.net (14.142.187.166) by\n\tAM0PR04MB4673.eurprd04.prod.outlook.com (2603:10a6:208:75::15) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1143.18; Mon, 17 Sep 2018 10:37:51 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=+3XJIrXHjbFWCNoKtw+H+iDZFAU+5+4Kj0aTskqNYvU=;\n\tb=S0BiHXUXhqLzOVDG5T/jkKAeJPA+TaQdLkpEypdsNLTQ/CtjM7PAZwZUJHPBQu51MNM4U2CXrPzIUOaVIRV+CBllb9GpIPX+/4aDXURXhe7Sg99ICRiIQf9jffLsaN4C/VuveWwCWGVAAHTCO+TP3JrW9v5EPnmGaxp6UmQBLRg=",
        "Authentication-Results": "spf=none (sender IP is )\n\tsmtp.mailfrom=shreyansh.jain@nxp.com; ",
        "From": "Shreyansh Jain <shreyansh.jain@nxp.com>",
        "To": "dev@dpdk.org,\n\tferruh.yigit@intel.com",
        "Cc": "Nipun Gupta <nipun.gupta@nxp.com>, Youri Querry <youri.querry_1@nxp.com>,\n\tRoy Pledge <roy.pledge@nxp.com>",
        "Date": "Mon, 17 Sep 2018 16:06:25 +0530",
        "Message-Id": "<20180917103631.32304-6-shreyansh.jain@nxp.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20180917103631.32304-1-shreyansh.jain@nxp.com>",
        "References": "<20180917103631.32304-1-shreyansh.jain@nxp.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[14.142.187.166]",
        "X-ClientProxiedBy": "BM1PR01CA0092.INDPRD01.PROD.OUTLOOK.COM\n\t(2603:1096:b00:1::32) To AM0PR04MB4673.eurprd04.prod.outlook.com\n\t(2603:10a6:208:75::15)",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "5d80f905-9c24-4b21-9401-08d61c899f26",
        "X-MS-Office365-Filtering-HT": "Tenant",
        "X-Microsoft-Antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989137)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020);\n\tSRVR:AM0PR04MB4673; ",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; AM0PR04MB4673;\n\t3:hJ6mUSemgSJOFzSCzJPj/9VwiprdISl4YgX2M1z07Iuu29CDhKYwRj6p8k9IO+RyfipD2ZX2r8Mt950+DTSgNcCKbxZ8BOXvp+ibP4FuDlb1WA30rjd1izTdIK75dih+2qoEZ1YAeK3iev1cbDVO/7Z2PdH3OapRbUEoUKqpLvDsoID4cbqJlxEJVIa4WyitlVBysxjSmP6FAi8x4hS2/tbZYUuOAMhO/Rt2crAGfXXsqHLUQU0PgealKqGXURs9;\n\t25:U6+FVOIJbaabgSU+WatcqdYfvqTxzbOtru3uDWJZfL5BGIwoQy1o6CT6Q0F8eXqoRYf1PhudrdtXFq841pMciDuxPnpBQn+V74XrvK5xiV76k08mCNKUKD9Tv1CbggkmePVRW+6co3UvjXa8WxJrZzvtL+65nXo8p6KzAWAxKy1eatJo+ZoxxgYc3SiwtAq5yGwUhJoxW+FCZjcjS6UInUFIxVWTE/6AjPNWNWzcZfTJLOxFWM5ZebvfM7jlaMGY5/wCp2HpKJGQapbht0mrlyu6tr/5GGPmv4fGNRHKG5Tx7ZAaVD9VwN2v9vTDy7EzCve54jEJPipu1bLq5pCQQw==;\n\t31:sp0xkds7fRn2LAwPKP/agB0Rgfsg7UbEI+Xp5qqolwjHwHhM18VhDdLHBQKinXvmhmXA1X4WdvYAOuaBmY6JQbhf3xpwby7CWxJaL5ck0EMl1j+DFjUHIen4h43cWehiAdnUSbnWlsLwOzqubfAkycU8LKjKs+xV+w9/REexgnbwYQrCjQQH+xsw3un7k2AZUYa3OJAq7rNbjrGrazb1EQvn4PJ/cHS0pasBotw955Y=",
            "1; AM0PR04MB4673;\n\t20:TyqXWIpcLGBFvEKmygVOBZmQ4HMrOu48oKpqzH1Rf/pLvnVKfmiAszpkhbykaNjz9PtwN4lUoOUVBsDugDqH20yvI8XGuDlIt4sZlXyco+2YGAmVbqKlo8H05UK09ZnpOCqr8D78vmqxOo9uUTuuiSxw48NV6p91kqCukMy8b7DO9mPBfmsijtgcAQcQ2mhztLh2HHC1fPTaCJCRXxfvHqNt1XjXz46ZddKzKcdZ4/W/ecApMhVLuk8cj1b9fM4+qGH4FDifc17Yg/RVRaKiw2K90jUOXzNAXfEygxByvpUIBibRCaR6+cE/PUV47vMnqpbKGLpHZDuJNFFoPji15xvlryU4lXIGlX6S5Vl2d+7hXEhmkC/uZMSiFac7Yukd4Z7/KXhdXxs9JzHcAprymdCYL4/MxVdO5wpcFRrcEb8U3q4eRKfixvYjnPgNZ+4MX1O68oqiecMbdd87uHH5qEmjgcpFpjL2jUaSPtAJ22Mne6J3HHapA3kIxPo3i+99;\n\t4:LoZ2ZqHKNyMjqoK05H15D6fAXDJY/xCK6c0lXjGZOOy8E1baKqhLRXF5XK2rCC7O1AY5PTSrBIa9YyvsRxkLbSCM65YsLmDlxIFXVEez7UO30BaQh8X7vC/yTeuoGHESob7vLwfuyH1jWOaTIYfW1hjeMbwT4noQYQfkPFz/VMuoU6cdaTIeUo5OF7K+bgw39yzIbHiKttMcGGH1NqiGzdHbaffQ/riNQMes6UhZJqKk5Mo/WWOipdnnBOUYmB4k/CLaZPztC7Wpx+dLmMO1liN6ZUpD28h84HSIOSt4BpKV/iV9t0lPanmtC6sYmHu5WRL1VJuFjnwIUAUMBFacGHCEMuegCbuyEQ59WwoS7h5vw4EdZ+TN1gDkhgWFVhYW",
            "=?us-ascii?Q?1; AM0PR04MB4673;\n\t23:rnKk8Uijg6+619P7TxLTJnswB8VQiGqcPXg4u2PNE?=\n\tuq+ZDwKy+R6fWev6MpTChlIvTGCS3j6N7WMUM5qrwVs0FBbFhDxhmapNx6diEZouRPokxVCSx/I30MqQGJA/7RPjEQeT59RipmSeOKP08pJA2u0qBz08sOmpCUwuoMrgJqTpWjjG9yOzD8Xm3CHUqxCrdAXsECjOQWJgql0nz38Ru43k2JgZdjBRG0uJjm2k9+q9okTRCmzNm4pW1BscbhrJecPQXdSt7DmI/c/lzbmvEgCgYEUF90pKcM5wWdZeDaQeFz+muewNlK8Rj/o0zqiBK0OJnlRwhsQ+ANcu6pP5ALkMEjx/1pF6Zv0VQ0Dy7IN/xNJ+vDXCxwtZgoGgCD1JH9RSSnOLFj2ZTXEd4CNh0Gui4/ZugMQa0rrXd6SoCcBW3752T+jqj9XHBWldaStGatbbSSK43Srmdg48gOV3GHpR5IVxmp6Q+YRoHv4iOaVge9VaFOVYKowF5a7RC3YPtK+ue2Fnlpybh/wWBf7GUCTJ6J7Oc0ia8pn08FvpFB6zHpv3nIOGtMkG3EZ8UF4VTFtErvcwxQ5Hul4AEc6un/FuodUYNjtt99vOJCYcMnOW3+SUGCRaXuVvM9/fjUpW1LWpJY1YsaZEDjlfL6KxfdQwd/7pXx4xg4FcbZZZi24EOz0rD8HMP1ii/R6Z1kLrcYfSmOmVSGTyFfHN9UpXrSnab18Tpj5Gk3HwignzlxRas39SU/5ECZ7QFakjunnrObZ3xKOE2GlytDnuqPybamD11Kpd5swD3M3Zgs/iMvNPgUbUanx2lBHXQyQ3Rgvs7gpzFRHxLdc0FRrJ4lRDkzylLRH2kdqgWFJkjjs66XeNqEVZjpur124kB4otfJGlH9xTUgZ+PFPFQDhoUZ2TR1Pa/pqsLLz8R8L6nQX2LJ9VdH7A/S6qTROQSL6ZODPLdMeOHTlKbYxW7y+o0cMji6o4mjVR2v9CtiGy1vRYcdp23ADBsgENVH5uYPaRp1CIbHe4QSz7aB+SzNskfvRX6rGZGyCWgR6++VKpGf1Xkg+DLQ329AeJqsK8qBIxx7fxGyrWK9ygS3Y3KfE8pSNm277Y+2slYZeWaqmH42MDO2nstU9uBcYYQAFowVm9tGiKtzkk906phdRQoXInz6s7cGE2Exjk1WV/Iig+tvb1SNMpPtxZb0CxD+7uAeJgjgzDe7Vn86iMYzHDQsFTjjcTUbBnIsZaNf6IfnLDOtJXvqRjYlCZ1jOM15GqVo7UH2JCIr6NOalYhgoX/2faIxKb9ZfWeCfeKFKxKKTIXzaFsmD0c5m8b8l2Uv4WClSFpsaBFJj5FzVmbLTh5Qk/AH96O9GJhH/vHV7sTEOdXCK2qg=",
            "1; AM0PR04MB4673;\n\t6:3GqOQO0jgFtD1qRB0zccXi0sz5A+Rx2xo4l+Xv1D0fyCMT9WriYe+k4jgnN+hcWfiL4xb4GEHJw2/wzMVJev3jaiXYz64yNaE588tua2zYRpJ0FKFR1+HBl9VYfaqejY1IqcsLGGV0OgzWVqqluINkNK03enjc8VageVCcWgUrOJVt55B3SWG+61PlYrhYEBaxZ4nq1edNjsL4jCrufcz5PEgwP3pgDkN75C397u8iCduc5HlEJRINHYpWJ0rKDz4z1QYtBdYH0iaCgVx5zji/vbNZi0GvqgdL3DS5NF9A9gfUJ4lpkUpbQ7AHBsPHaf3YB9JvQ6DVIvti7brcXcO+P5bIYuIiU7CqkyuArwzd8K2jDY1ltpZpYph38OvCbySeYdTaMw1yI+2GNeEIRWMl5krKoSsPALXeYvfp7D3lYyzHaGLyF0LY3NvSlj+6SWBDLwM/FBjzbwHyGpNFWYsw==;\n\t5:zEHW+uHUrwAtmUDdinObah6PbL9NJjJQnYD73VqaSWdfYW9wZ5B68uG1ZG2uY1rzdScuHqaTq+bMFDTYGYp6/zU6VTJsWMdivq8IpCPqZ/i11syCj78GbPe6oMUFMZ8iylxTwgralLEl65ppq4PQ+h9Rd5yxLb/XBlAg3Kgk0AU=;\n\t7:vzuoBTuSp5B3kKuoZXaie7405tV4hCgy6sxt0yI9+vZ8YHTWa/M5qaNmD8gPlFW7lkfu+Tu76BBXxoDcVAsXmBvSTfAwAn5qRfq1Z0weNEVcREoY0PTb0VjZhxiU7ihtzQB4ocB/W40zGToB50fiIa/TXSSZ+xpYj4ut7W+N/0eRSJ/b3EpvBK4LWBL6c3MwD9uWcc3NWvnwtd5N6+f385mZCD+VlJTFNbVO5n3crOWjgyFM+td8A1FDhMcMxPGL"
        ],
        "X-MS-TrafficTypeDiagnostic": "AM0PR04MB4673:",
        "X-Microsoft-Antispam-PRVS": "<AM0PR04MB4673547102D05DF6A44793B5901E0@AM0PR04MB4673.eurprd04.prod.outlook.com>",
        "X-Exchange-Antispam-Report-Test": "UriScan:(185117386973197)(227817650892897)(275809806118684); ",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3231355)(944501410)(52105095)(10201501046)(3002001)(93006095)(93001095)(6055026)(149027)(150027)(6041310)(20161123564045)(20161123558120)(20161123560045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699050);\n\tSRVR:AM0PR04MB4673; BCL:0; PCL:0; RULEID:; SRVR:AM0PR04MB4673; ",
        "X-Forefront-PRVS": "0798146F16",
        "X-Forefront-Antispam-Report": "SFV:NSPM;\n\tSFS:(10009020)(136003)(396003)(346002)(366004)(376002)(39860400002)(199004)(189003)(16526019)(48376002)(186003)(1076002)(3846002)(5660300001)(486006)(54906003)(6506007)(386003)(16586007)(316002)(36756003)(14444005)(44832011)(5009440100003)(52116002)(6116002)(2616005)(76176011)(446003)(51416003)(11346002)(956004)(476003)(53946003)(6512007)(47776003)(106356001)(25786009)(50226002)(2906002)(68736007)(105586002)(81156014)(81166006)(7736002)(6666003)(305945005)(8676002)(8936002)(4326008)(575784001)(86362001)(97736004)(6486002)(478600001)(50466002)(66066001)(26005)(53936002)(16200700003)(110426005)(569006);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR04MB4673;\n\tH:Tophie.ap.freescale.net; FPR:; \n\tSPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; ",
        "Received-SPF": "None (protection.outlook.com: nxp.com does not designate\n\tpermitted sender hosts)",
        "X-Microsoft-Antispam-Message-Info": "1ZUr4xHW9F5gZzjfuPBXJaijrvqweT9gWOfEd0e9mcyxWirWjMqiinp+L9MQ6WmRoRawLHyXbkqorUqtoZlVUnYX1PBHDGKyCFj7sZnzQO2SeozNsVgaJJ2ivTqCnbshiJR6c/jDMOHrt46lzrlBA/ySTkj2NfxlvFPGSEUHh21iPpq++s84Fhi1KX9TF61IGpoCzK4SnVoIYBg41ZK7hmhWtyIQ7sjySkEC86s+Zz/4dDGDNYWJRxw29gT9KNlhIZVyC/62Ubv0v5uYQkSp3gWKRPboFh9GfuFi38PO5U50644MH+24nZpoUllwea2Eh2w333DIy4tq0SRfawdNUCvVq5yD3itHiCR5exEVRTY=",
        "SpamDiagnosticOutput": "1:99",
        "SpamDiagnosticMetadata": "NSPM",
        "X-OriginatorOrg": "nxp.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "17 Sep 2018 10:37:51.5394\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "5d80f905-9c24-4b21-9401-08d61c899f26",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "686ea1d3-bc2b-4c6f-a92c-d99c5c301635",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM0PR04MB4673",
        "Subject": "[dpdk-dev] [PATCH 05/11] bus/fslmc: support memory backed portals\n\twith QBMAN 5.0",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Nipun Gupta <nipun.gupta@nxp.com>\n\nSigned-off-by: Youri Querry <youri.querry_1@nxp.com>\nSigned-off-by: Roy Pledge <roy.pledge@nxp.com>\nSigned-off-by: Nipun Gupta <nipun.gupta@nxp.com>\n---\n drivers/bus/fslmc/portal/dpaa2_hw_dpio.c      | 180 ++---\n drivers/bus/fslmc/portal/dpaa2_hw_pvt.h       |   4 +\n drivers/bus/fslmc/qbman/include/compat.h      |   3 +-\n .../fslmc/qbman/include/fsl_qbman_portal.h    |  31 +-\n drivers/bus/fslmc/qbman/qbman_portal.c        | 764 +++++++++++++++---\n drivers/bus/fslmc/qbman/qbman_portal.h        |  30 +-\n drivers/bus/fslmc/qbman/qbman_sys.h           | 100 ++-\n drivers/bus/fslmc/qbman/qbman_sys_decl.h      |   4 +\n 8 files changed, 867 insertions(+), 249 deletions(-)",
    "diff": "diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c\nindex 99f70be1c..76f80b951 100644\n--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c\n+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c\n@@ -1,7 +1,7 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n  *\n  *   Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.\n- *   Copyright 2016 NXP\n+ *   Copyright 2016-2018 NXP\n  *\n  */\n #include <unistd.h>\n@@ -177,68 +177,6 @@ static int dpaa2_dpio_intr_init(struct dpaa2_dpio_dev *dpio_dev)\n }\n #endif\n \n-static int\n-configure_dpio_qbman_swp(struct dpaa2_dpio_dev *dpio_dev)\n-{\n-\tstruct qbman_swp_desc p_des;\n-\tstruct dpio_attr attr;\n-\n-\tdpio_dev->dpio = malloc(sizeof(struct fsl_mc_io));\n-\tif (!dpio_dev->dpio) {\n-\t\tDPAA2_BUS_ERR(\"Memory allocation failure\");\n-\t\treturn -1;\n-\t}\n-\n-\tdpio_dev->dpio->regs = dpio_dev->mc_portal;\n-\tif (dpio_open(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->hw_id,\n-\t\t      &dpio_dev->token)) {\n-\t\tDPAA2_BUS_ERR(\"Failed to allocate IO space\");\n-\t\tfree(dpio_dev->dpio);\n-\t\treturn -1;\n-\t}\n-\n-\tif (dpio_reset(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token)) {\n-\t\tDPAA2_BUS_ERR(\"Failed to reset dpio\");\n-\t\tdpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);\n-\t\tfree(dpio_dev->dpio);\n-\t\treturn -1;\n-\t}\n-\n-\tif (dpio_enable(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token)) {\n-\t\tDPAA2_BUS_ERR(\"Failed to Enable dpio\");\n-\t\tdpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);\n-\t\tfree(dpio_dev->dpio);\n-\t\treturn -1;\n-\t}\n-\n-\tif (dpio_get_attributes(dpio_dev->dpio, CMD_PRI_LOW,\n-\t\t\t\tdpio_dev->token, &attr)) {\n-\t\tDPAA2_BUS_ERR(\"DPIO Get attribute failed\");\n-\t\tdpio_disable(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);\n-\t\tdpio_close(dpio_dev->dpio, CMD_PRI_LOW,  dpio_dev->token);\n-\t\tfree(dpio_dev->dpio);\n-\t\treturn -1;\n-\t}\n-\n-\t/* Configure & setup SW portal */\n-\tp_des.block = NULL;\n-\tp_des.idx = attr.qbman_portal_id;\n-\tp_des.cena_bar = (void *)(dpio_dev->qbman_portal_ce_paddr);\n-\tp_des.cinh_bar = (void *)(dpio_dev->qbman_portal_ci_paddr);\n-\tp_des.irq = -1;\n-\tp_des.qman_version = attr.qbman_version;\n-\n-\tdpio_dev->sw_portal = qbman_swp_init(&p_des);\n-\tif (dpio_dev->sw_portal == NULL) {\n-\t\tDPAA2_BUS_ERR(\"QBMan SW Portal Init failed\");\n-\t\tdpio_close(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);\n-\t\tfree(dpio_dev->dpio);\n-\t\treturn -1;\n-\t}\n-\n-\treturn 0;\n-}\n-\n static int\n dpaa2_configure_stashing(struct dpaa2_dpio_dev *dpio_dev, int cpu_id)\n {\n@@ -402,15 +340,17 @@ dpaa2_create_dpio_device(int vdev_fd,\n \t\t\t struct vfio_device_info *obj_info,\n \t\t\t int object_id)\n {\n-\tstruct dpaa2_dpio_dev *dpio_dev;\n+\tstruct dpaa2_dpio_dev *dpio_dev = NULL;\n \tstruct vfio_region_info reg_info = { .argsz = sizeof(reg_info)};\n+\tstruct qbman_swp_desc p_des;\n+\tstruct dpio_attr attr;\n \n \tif (obj_info->num_regions < NUM_DPIO_REGIONS) {\n \t\tDPAA2_BUS_ERR(\"Not sufficient number of DPIO regions\");\n \t\treturn -1;\n \t}\n \n-\tdpio_dev = rte_malloc(NULL, sizeof(struct dpaa2_dpio_dev),\n+\tdpio_dev = rte_zmalloc(NULL, sizeof(struct dpaa2_dpio_dev),\n \t\t\t      RTE_CACHE_LINE_SIZE);\n \tif (!dpio_dev) {\n \t\tDPAA2_BUS_ERR(\"Memory allocation failed for DPIO Device\");\n@@ -423,45 +363,33 @@ dpaa2_create_dpio_device(int vdev_fd,\n \t/* Using single portal  for all devices */\n \tdpio_dev->mc_portal = rte_mcp_ptr_list[MC_PORTAL_INDEX];\n \n-\treg_info.index = 0;\n-\tif (ioctl(vdev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info)) {\n-\t\tDPAA2_BUS_ERR(\"vfio: error getting region info\");\n-\t\trte_free(dpio_dev);\n-\t\treturn -1;\n+\tdpio_dev->dpio = malloc(sizeof(struct fsl_mc_io));\n+\tif (!dpio_dev->dpio) {\n+\t\tDPAA2_BUS_ERR(\"Memory allocation failure\");\n+\t\tgoto err;\n \t}\n \n-\tdpio_dev->ce_size = reg_info.size;\n-\tdpio_dev->qbman_portal_ce_paddr = (size_t)mmap(NULL, reg_info.size,\n-\t\t\t\tPROT_WRITE | PROT_READ, MAP_SHARED,\n-\t\t\t\tvdev_fd, reg_info.offset);\n-\n-\treg_info.index = 1;\n-\tif (ioctl(vdev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info)) {\n-\t\tDPAA2_BUS_ERR(\"vfio: error getting region info\");\n-\t\trte_free(dpio_dev);\n-\t\treturn -1;\n+\tdpio_dev->dpio->regs = dpio_dev->mc_portal;\n+\tif (dpio_open(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->hw_id,\n+\t\t      &dpio_dev->token)) {\n+\t\tDPAA2_BUS_ERR(\"Failed to allocate IO space\");\n+\t\tgoto err;\n \t}\n \n-\tdpio_dev->ci_size = reg_info.size;\n-\tdpio_dev->qbman_portal_ci_paddr = (size_t)mmap(NULL, reg_info.size,\n-\t\t\t\tPROT_WRITE | PROT_READ, MAP_SHARED,\n-\t\t\t\tvdev_fd, reg_info.offset);\n-\n-\tif (configure_dpio_qbman_swp(dpio_dev)) {\n-\t\tDPAA2_BUS_ERR(\n-\t\t\t     \"Fail to configure the dpio qbman portal for %d\",\n-\t\t\t     dpio_dev->hw_id);\n-\t\trte_free(dpio_dev);\n-\t\treturn -1;\n+\tif (dpio_reset(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token)) {\n+\t\tDPAA2_BUS_ERR(\"Failed to reset dpio\");\n+\t\tgoto err;\n \t}\n \n-\tio_space_count++;\n-\tdpio_dev->index = io_space_count;\n+\tif (dpio_enable(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token)) {\n+\t\tDPAA2_BUS_ERR(\"Failed to Enable dpio\");\n+\t\tgoto err;\n+\t}\n \n-\tif (rte_dpaa2_vfio_setup_intr(&dpio_dev->intr_handle, vdev_fd, 1)) {\n-\t\tDPAA2_BUS_ERR(\"Fail to setup interrupt for %d\",\n-\t\t\t      dpio_dev->hw_id);\n-\t\trte_free(dpio_dev);\n+\tif (dpio_get_attributes(dpio_dev->dpio, CMD_PRI_LOW,\n+\t\t\t\tdpio_dev->token, &attr)) {\n+\t\tDPAA2_BUS_ERR(\"DPIO Get attribute failed\");\n+\t\tgoto err;\n \t}\n \n \t/* find the SoC type for the first time */\n@@ -483,9 +411,67 @@ dpaa2_create_dpio_device(int vdev_fd,\n \t\tdpaa2_svr_family = (mc_plat_info.svr & 0xffff0000);\n \t}\n \n+\tif (dpaa2_svr_family == SVR_LX2160A)\n+\t\treg_info.index = DPAA2_SWP_CENA_MEM_REGION;\n+\telse\n+\t\treg_info.index = DPAA2_SWP_CENA_REGION;\n+\n+\tif (ioctl(vdev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info)) {\n+\t\tDPAA2_BUS_ERR(\"vfio: error getting region info\");\n+\t\tgoto err;\n+\t}\n+\n+\tdpio_dev->ce_size = reg_info.size;\n+\tdpio_dev->qbman_portal_ce_paddr = (size_t)mmap(NULL, reg_info.size,\n+\t\t\t\tPROT_WRITE | PROT_READ, MAP_SHARED,\n+\t\t\t\tvdev_fd, reg_info.offset);\n+\n+\treg_info.index = DPAA2_SWP_CINH_REGION;\n+\tif (ioctl(vdev_fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info)) {\n+\t\tDPAA2_BUS_ERR(\"vfio: error getting region info\");\n+\t\tgoto err;\n+\t}\n+\n+\tdpio_dev->ci_size = reg_info.size;\n+\tdpio_dev->qbman_portal_ci_paddr = (size_t)mmap(NULL, reg_info.size,\n+\t\t\t\tPROT_WRITE | PROT_READ, MAP_SHARED,\n+\t\t\t\tvdev_fd, reg_info.offset);\n+\n+\t/* Configure & setup SW portal */\n+\tp_des.block = NULL;\n+\tp_des.idx = attr.qbman_portal_id;\n+\tp_des.cena_bar = (void *)(dpio_dev->qbman_portal_ce_paddr);\n+\tp_des.cinh_bar = (void *)(dpio_dev->qbman_portal_ci_paddr);\n+\tp_des.irq = -1;\n+\tp_des.qman_version = attr.qbman_version;\n+\n+\tdpio_dev->sw_portal = qbman_swp_init(&p_des);\n+\tif (dpio_dev->sw_portal == NULL) {\n+\t\tDPAA2_BUS_ERR(\"QBMan SW Portal Init failed\");\n+\t\tgoto err;\n+\t}\n+\n+\tio_space_count++;\n+\tdpio_dev->index = io_space_count;\n+\n+\tif (rte_dpaa2_vfio_setup_intr(&dpio_dev->intr_handle, vdev_fd, 1)) {\n+\t\tDPAA2_BUS_ERR(\"Fail to setup interrupt for %d\",\n+\t\t\t      dpio_dev->hw_id);\n+\t\tgoto err;\n+\t}\n+\n \tTAILQ_INSERT_TAIL(&dpio_dev_list, dpio_dev, next);\n \n \treturn 0;\n+\n+err:\n+\tif (dpio_dev->dpio) {\n+\t\tdpio_disable(dpio_dev->dpio, CMD_PRI_LOW, dpio_dev->token);\n+\t\tdpio_close(dpio_dev->dpio, CMD_PRI_LOW,  dpio_dev->token);\n+\t\tfree(dpio_dev->dpio);\n+\t}\n+\trte_free(dpio_dev);\n+\treturn -1;\n }\n \n void\ndiff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h\nindex 820759360..f2eebe65d 100644\n--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h\n+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h\n@@ -37,6 +37,10 @@\n #define DPAA2_DQRR_RING_SIZE\t16\n \t/** <Maximum number of slots available in RX ring*/\n \n+#define DPAA2_SWP_CENA_REGION\t\t0\n+#define DPAA2_SWP_CINH_REGION\t\t1\n+#define DPAA2_SWP_CENA_MEM_REGION\t2\n+\n #define MC_PORTAL_INDEX\t\t0\n #define NUM_DPIO_REGIONS\t2\n #define NUM_DQS_PER_QUEUE       2\ndiff --git a/drivers/bus/fslmc/qbman/include/compat.h b/drivers/bus/fslmc/qbman/include/compat.h\nindex 7be8f54c5..655bff4b6 100644\n--- a/drivers/bus/fslmc/qbman/include/compat.h\n+++ b/drivers/bus/fslmc/qbman/include/compat.h\n@@ -78,13 +78,14 @@ do { \\\n #define lower_32_bits(x) ((uint32_t)(x))\n #define upper_32_bits(x) ((uint32_t)(((x) >> 16) >> 16))\n \n-\n #define __iomem\n \n #define __raw_readb(p)\t(*(const volatile unsigned char *)(p))\n #define __raw_readl(p)\t(*(const volatile unsigned int *)(p))\n #define __raw_writel(v, p) {*(volatile unsigned int *)(p) = (v); }\n \n+#define dma_wmb()\t\trte_smp_mb()\n+\n #define atomic_t                rte_atomic32_t\n #define atomic_read(v)          rte_atomic32_read(v)\n #define atomic_set(v, i)        rte_atomic32_set(v, i)\ndiff --git a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h\nindex 3e63db3ab..7370e53e0 100644\n--- a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h\n+++ b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h\n@@ -42,6 +42,15 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);\n  */\n void qbman_swp_finish(struct qbman_swp *p);\n \n+/**\n+ * qbman_swp_invalidate() - Invalidate the cache enabled area of the QBMan\n+ * portal. This is required to be called if a portal moved to another core\n+ * because the QBMan portal area is non coherent\n+ * @p: the qbman_swp object to be invalidated\n+ *\n+ */\n+void qbman_swp_invalidate(struct qbman_swp *p);\n+\n /**\n  * qbman_swp_get_desc() - Get the descriptor of the given portal object.\n  * @p: the given portal object.\n@@ -172,7 +181,7 @@ void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);\n /**\n  * struct qbman_result - structure for qbman dequeue response and/or\n  * notification.\n- * @donot_manipulate_directly: the 16 32bit data to represent the whole\n+ * @dont_manipulate_directly: the 16 32bit data to represent the whole\n  * possible qbman dequeue result.\n  */\n struct qbman_result {\n@@ -262,7 +271,7 @@ void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable);\n  */\n struct qbman_pull_desc {\n \tunion {\n-\t\tuint32_t donot_manipulate_directly[16];\n+\t\tuint32_t dont_manipulate_directly[16];\n \t\tstruct pull {\n \t\t\tuint8_t verb;\n \t\t\tuint8_t numf;\n@@ -355,6 +364,14 @@ void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, uint32_t wqid,\n void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,\n \t\t\t\t enum qbman_pull_type_e dct);\n \n+/**\n+ * qbman_pull_desc_set_rad() - Decide whether reschedule the fq after dequeue\n+ *\n+ * @rad: 1 = Reschedule the FQ after dequeue.\n+ *\t 0 = Allow the FQ to remain active after dequeue.\n+ */\n+void qbman_pull_desc_set_rad(struct qbman_pull_desc *d, int rad);\n+\n /**\n  * qbman_swp_pull() - Issue the pull dequeue command\n  * @s: the software portal object.\n@@ -775,7 +792,7 @@ uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn);\n /* struct qbman_eq_desc - structure of enqueue descriptor */\n struct qbman_eq_desc {\n \tunion {\n-\t\tuint32_t donot_manipulate_directly[8];\n+\t\tuint32_t dont_manipulate_directly[8];\n \t\tstruct eq {\n \t\t\tuint8_t verb;\n \t\t\tuint8_t dca;\n@@ -796,11 +813,11 @@ struct qbman_eq_desc {\n \n /**\n  * struct qbman_eq_response - structure of enqueue response\n- * @donot_manipulate_directly: the 16 32bit data to represent the whole\n+ * @dont_manipulate_directly: the 16 32bit data to represent the whole\n  * enqueue response.\n  */\n struct qbman_eq_response {\n-\tuint32_t donot_manipulate_directly[16];\n+\tuint32_t dont_manipulate_directly[16];\n };\n \n /**\n@@ -998,12 +1015,12 @@ int qbman_swp_enqueue_thresh(struct qbman_swp *s, unsigned int thresh);\n \t/*******************/\n /**\n  * struct qbman_release_desc - The structure for buffer release descriptor\n- * @donot_manipulate_directly: the 32bit data to represent the whole\n+ * @dont_manipulate_directly: the 32bit data to represent the whole\n  * possible settings of qbman release descriptor.\n  */\n struct qbman_release_desc {\n \tunion {\n-\t\tuint32_t donot_manipulate_directly[16];\n+\t\tuint32_t dont_manipulate_directly[16];\n \t\tstruct br {\n \t\t\tuint8_t verb;\n \t\t\tuint8_t reserved;\ndiff --git a/drivers/bus/fslmc/qbman/qbman_portal.c b/drivers/bus/fslmc/qbman/qbman_portal.c\nindex 071450052..3380e54f5 100644\n--- a/drivers/bus/fslmc/qbman/qbman_portal.c\n+++ b/drivers/bus/fslmc/qbman/qbman_portal.c\n@@ -1,39 +1,17 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n  *\n  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.\n+ * Copyright 2018 NXP\n  *\n  */\n \n+#include \"qbman_sys.h\"\n #include \"qbman_portal.h\"\n \n /* QBMan portal management command codes */\n #define QBMAN_MC_ACQUIRE       0x30\n #define QBMAN_WQCHAN_CONFIGURE 0x46\n \n-/* CINH register offsets */\n-#define QBMAN_CINH_SWP_EQCR_PI 0x800\n-#define QBMAN_CINH_SWP_EQCR_CI 0x840\n-#define QBMAN_CINH_SWP_EQAR    0x8c0\n-#define QBMAN_CINH_SWP_DQPI    0xa00\n-#define QBMAN_CINH_SWP_DCAP    0xac0\n-#define QBMAN_CINH_SWP_SDQCR   0xb00\n-#define QBMAN_CINH_SWP_RAR     0xcc0\n-#define QBMAN_CINH_SWP_ISR     0xe00\n-#define QBMAN_CINH_SWP_IER     0xe40\n-#define QBMAN_CINH_SWP_ISDR    0xe80\n-#define QBMAN_CINH_SWP_IIR     0xec0\n-#define QBMAN_CINH_SWP_DQRR_ITR    0xa80\n-#define QBMAN_CINH_SWP_ITPR    0xf40\n-\n-/* CENA register offsets */\n-#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))\n-#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))\n-#define QBMAN_CENA_SWP_RCR(n)  (0x400 + ((uint32_t)(n) << 6))\n-#define QBMAN_CENA_SWP_CR      0x600\n-#define QBMAN_CENA_SWP_RR(vb)  (0x700 + ((uint32_t)(vb) >> 1))\n-#define QBMAN_CENA_SWP_VDQCR   0x780\n-#define QBMAN_CENA_SWP_EQCR_CI 0x840\n-\n /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */\n #define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)\n \n@@ -83,6 +61,102 @@ enum qbman_sdqcr_fc {\n #define MAX_QBMAN_PORTALS  64\n static struct qbman_swp *portal_idx_map[MAX_QBMAN_PORTALS];\n \n+/* Internal Function declaration */\n+static int\n+qbman_swp_enqueue_array_mode_direct(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd);\n+static int\n+qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd);\n+\n+static int\n+qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd);\n+static int\n+qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd);\n+\n+static int\n+qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd,\n+\t\tuint32_t *flags,\n+\t\tint num_frames);\n+static int\n+qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd,\n+\t\tuint32_t *flags,\n+\t\tint num_frames);\n+\n+static int\n+qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd,\n+\t\tint num_frames);\n+static int\n+qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd,\n+\t\tint num_frames);\n+\n+static int\n+qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d);\n+static int\n+qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d);\n+\n+const struct qbman_result *qbman_swp_dqrr_next_direct(struct qbman_swp *s);\n+const struct qbman_result *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s);\n+\n+static int\n+qbman_swp_release_direct(struct qbman_swp *s,\n+\t\tconst struct qbman_release_desc *d,\n+\t\tconst uint64_t *buffers, unsigned int num_buffers);\n+static int\n+qbman_swp_release_mem_back(struct qbman_swp *s,\n+\t\tconst struct qbman_release_desc *d,\n+\t\tconst uint64_t *buffers, unsigned int num_buffers);\n+\n+/* Function pointers */\n+static int (*qbman_swp_enqueue_array_mode_ptr)(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd)\n+\t= qbman_swp_enqueue_array_mode_direct;\n+\n+static int (*qbman_swp_enqueue_ring_mode_ptr)(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd)\n+\t= qbman_swp_enqueue_ring_mode_direct;\n+\n+static int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd,\n+\t\tuint32_t *flags,\n+\t\tint num_frames)\n+\t= qbman_swp_enqueue_multiple_direct;\n+\n+static int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s,\n+\t\tconst struct qbman_eq_desc *d,\n+\t\tconst struct qbman_fd *fd,\n+\t\tint num_frames)\n+\t= qbman_swp_enqueue_multiple_desc_direct;\n+\n+static int (*qbman_swp_pull_ptr)(struct qbman_swp *s,\n+\t\tstruct qbman_pull_desc *d)\n+\t= qbman_swp_pull_direct;\n+\n+const struct qbman_result *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s)\n+\t\t= qbman_swp_dqrr_next_direct;\n+\n+static int (*qbman_swp_release_ptr)(struct qbman_swp *s,\n+\t\t\tconst struct qbman_release_desc *d,\n+\t\t\tconst uint64_t *buffers, unsigned int num_buffers)\n+\t\t\t= qbman_swp_release_direct;\n+\n /*********************************/\n /* Portal constructor/destructor */\n /*********************************/\n@@ -104,25 +178,30 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)\n {\n \tint ret;\n \tuint32_t eqcr_pi;\n+\tuint32_t mask_size;\n \tstruct qbman_swp *p = malloc(sizeof(*p));\n \n \tif (!p)\n \t\treturn NULL;\n+\n+\tmemset(p, 0, sizeof(struct qbman_swp));\n+\n \tp->desc = *d;\n #ifdef QBMAN_CHECKING\n \tp->mc.check = swp_mc_can_start;\n #endif\n \tp->mc.valid_bit = QB_VALID_BIT;\n-\tp->sdq = 0;\n \tp->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT;\n \tp->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT;\n \tp->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT;\n+\tif ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)\n+\t\tp->mr.valid_bit = QB_VALID_BIT;\n \n \tatomic_set(&p->vdq.busy, 1);\n \tp->vdq.valid_bit = QB_VALID_BIT;\n-\tp->dqrr.next_idx = 0;\n \tp->dqrr.valid_bit = QB_VALID_BIT;\n-\tif ((p->desc.qman_version & 0xFFFF0000) < QMAN_REV_4100) {\n+\tqman_version = p->desc.qman_version;\n+\tif ((qman_version & 0xFFFF0000) < QMAN_REV_4100) {\n \t\tp->dqrr.dqrr_size = 4;\n \t\tp->dqrr.reset_bug = 1;\n \t} else {\n@@ -136,18 +215,54 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)\n \t\tpr_err(\"qbman_swp_sys_init() failed %d\\n\", ret);\n \t\treturn NULL;\n \t}\n+\n+\t/* Verify that the DQRRPI is 0 - if it is not the portal isn't\n+\t * in default state which is an error\n+\t */\n+\tif (qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_DQPI) & 0xF) {\n+\t\tpr_err(\"qbman DQRR PI is not zero, portal is not clean\\n\");\n+\t\tfree(p);\n+\t\treturn NULL;\n+\t}\n+\n \t/* SDQCR needs to be initialized to 0 when no channels are\n \t * being dequeued from or else the QMan HW will indicate an\n \t * error.  The values that were calculated above will be\n \t * applied when dequeues from a specific channel are enabled.\n \t */\n \tqbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, 0);\n+\n+\tp->eqcr.pi_ring_size = 8;\n+\tif ((qman_version & 0xFFFF0000) >= QMAN_REV_5000) {\n+\t\tp->eqcr.pi_ring_size = 32;\n+\t\tqbman_swp_enqueue_array_mode_ptr =\n+\t\t\t\tqbman_swp_enqueue_array_mode_mem_back;\n+\t\tqbman_swp_enqueue_ring_mode_ptr =\n+\t\t\t\tqbman_swp_enqueue_ring_mode_mem_back;\n+\t\tqbman_swp_enqueue_multiple_ptr =\n+\t\t\t\tqbman_swp_enqueue_multiple_mem_back;\n+\t\tqbman_swp_enqueue_multiple_desc_ptr =\n+\t\t\t\tqbman_swp_enqueue_multiple_desc_mem_back;\n+\t\tqbman_swp_pull_ptr = qbman_swp_pull_mem_back;\n+\t\tqbman_swp_dqrr_next_ptr = qbman_swp_dqrr_next_mem_back;\n+\t\tqbman_swp_release_ptr = qbman_swp_release_mem_back;\n+\t}\n+\n+\tfor (mask_size = p->eqcr.pi_ring_size; mask_size > 0; mask_size >>= 1)\n+\t\tp->eqcr.pi_mask = (p->eqcr.pi_mask<<1) + 1;\n \teqcr_pi = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_PI);\n-\tp->eqcr.pi = eqcr_pi & 0xF;\n+\tp->eqcr.pi = eqcr_pi & p->eqcr.pi_mask;\n \tp->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT;\n-\tp->eqcr.ci = qbman_cinh_read(&p->sys, QBMAN_CINH_SWP_EQCR_CI) & 0xF;\n-\tp->eqcr.available = QBMAN_EQCR_SIZE - qm_cyc_diff(QBMAN_EQCR_SIZE,\n-\t\t\t\t\t\tp->eqcr.ci, p->eqcr.pi);\n+\tif ((p->desc.qman_version & QMAN_REV_MASK) < QMAN_REV_5000)\n+\t\tp->eqcr.ci = qbman_cinh_read(&p->sys,\n+\t\t\t\tQBMAN_CINH_SWP_EQCR_CI) & p->eqcr.pi_mask;\n+\telse\n+\t\tp->eqcr.ci = qbman_cinh_read(&p->sys,\n+\t\t\t\tQBMAN_CINH_SWP_EQCR_PI) & p->eqcr.pi_mask;\n+\tp->eqcr.available = p->eqcr.pi_ring_size -\n+\t\t\t\tqm_cyc_diff(p->eqcr.pi_ring_size,\n+\t\t\t\tp->eqcr.ci & (p->eqcr.pi_mask<<1),\n+\t\t\t\tp->eqcr.pi & (p->eqcr.pi_mask<<1));\n \n \tportal_idx_map[p->desc.idx] = p;\n \treturn p;\n@@ -229,7 +344,8 @@ int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)\n \n void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)\n {\n-\tqbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);\n+\tqbman_cinh_write(&p->sys, QBMAN_CINH_SWP_IIR,\n+\t\t\t inhibit ? 0xffffffff : 0);\n }\n \n /***********************/\n@@ -246,7 +362,10 @@ void *qbman_swp_mc_start(struct qbman_swp *p)\n #ifdef QBMAN_CHECKING\n \tQBMAN_BUG_ON(p->mc.check != swp_mc_can_start);\n #endif\n-\tret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);\n+\tif ((p->desc.qman_version & QMAN_REV_MASK) < QMAN_REV_5000)\n+\t\tret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);\n+\telse\n+\t\tret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR_MEM);\n #ifdef QBMAN_CHECKING\n \tif (!ret)\n \t\tp->mc.check = swp_mc_can_submit;\n@@ -266,8 +385,17 @@ void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint8_t cmd_verb)\n \t * caller wants to OR but has forgotten to do so.\n \t */\n \tQBMAN_BUG_ON((*v & cmd_verb) != *v);\n-\t*v = cmd_verb | p->mc.valid_bit;\n-\tqbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);\n+\tif ((p->desc.qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {\n+\t\tdma_wmb();\n+\t\t*v = cmd_verb | p->mc.valid_bit;\n+\t\tqbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);\n+\t\tclean(cmd);\n+\t} else {\n+\t\t*v = cmd_verb | p->mr.valid_bit;\n+\t\tqbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR_MEM, cmd);\n+\t\tdma_wmb();\n+\t\tqbman_cinh_write(&p->sys, QBMAN_CINH_SWP_CR_RT, QMAN_RT_MODE);\n+\t}\n #ifdef QBMAN_CHECKING\n \tp->mc.check = swp_mc_can_poll;\n #endif\n@@ -279,17 +407,34 @@ void *qbman_swp_mc_result(struct qbman_swp *p)\n #ifdef QBMAN_CHECKING\n \tQBMAN_BUG_ON(p->mc.check != swp_mc_can_poll);\n #endif\n-\tqbman_cena_invalidate_prefetch(&p->sys,\n-\t\t\t\t       QBMAN_CENA_SWP_RR(p->mc.valid_bit));\n-\tret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit));\n-\t/* Remove the valid-bit - command completed if the rest is non-zero */\n-\tverb = ret[0] & ~QB_VALID_BIT;\n-\tif (!verb)\n-\t\treturn NULL;\n+\tif ((p->desc.qman_version & QMAN_REV_MASK) < QMAN_REV_5000) {\n+\t\tqbman_cena_invalidate_prefetch(&p->sys,\n+\t\t\t\tQBMAN_CENA_SWP_RR(p->mc.valid_bit));\n+\t\tret = qbman_cena_read(&p->sys,\n+\t\t\t\tQBMAN_CENA_SWP_RR(p->mc.valid_bit));\n+\t\t/* Remove the valid-bit -\n+\t\t * command completed iff the rest is non-zero\n+\t\t */\n+\t\tverb = ret[0] & ~QB_VALID_BIT;\n+\t\tif (!verb)\n+\t\t\treturn NULL;\n+\t\tp->mc.valid_bit ^= QB_VALID_BIT;\n+\t} else {\n+\t\tret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR_MEM);\n+\t\t/* Command completed if the valid bit is toggled */\n+\t\tif (p->mr.valid_bit != (ret[0] & QB_VALID_BIT))\n+\t\t\treturn NULL;\n+\t\t/* Remove the valid-bit -\n+\t\t * command completed iff the rest is non-zero\n+\t\t */\n+\t\tverb = ret[0] & ~QB_VALID_BIT;\n+\t\tif (!verb)\n+\t\t\treturn NULL;\n+\t\tp->mr.valid_bit ^= QB_VALID_BIT;\n+\t}\n #ifdef QBMAN_CHECKING\n \tp->mc.check = swp_mc_can_start;\n #endif\n-\tp->mc.valid_bit ^= QB_VALID_BIT;\n \treturn ret;\n }\n \n@@ -417,13 +562,26 @@ void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable,\n \t}\n }\n \n-#define EQAR_IDX(eqar)     ((eqar) & 0x7)\n+#define EQAR_IDX(eqar)     ((eqar) & 0x1f)\n #define EQAR_VB(eqar)      ((eqar) & 0x80)\n #define EQAR_SUCCESS(eqar) ((eqar) & 0x100)\n \n-static int qbman_swp_enqueue_array_mode(struct qbman_swp *s,\n-\t\t\t\t\tconst struct qbman_eq_desc *d,\n-\t\t\t\t\tconst struct qbman_fd *fd)\n+static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p,\n+\t\t\t\t\t\t   uint8_t idx)\n+{\n+\tif (idx < 16)\n+\t\tqbman_cinh_write(&p->sys, QBMAN_CINH_SWP_EQCR_AM_RT + idx * 4,\n+\t\t\t\t     QMAN_RT_MODE);\n+\telse\n+\t\tqbman_cinh_write(&p->sys, QBMAN_CINH_SWP_EQCR_AM_RT2 +\n+\t\t\t\t     (idx - 16) * 4,\n+\t\t\t\t     QMAN_RT_MODE);\n+}\n+\n+\n+static int qbman_swp_enqueue_array_mode_direct(struct qbman_swp *s,\n+\t\t\t\t\t       const struct qbman_eq_desc *d,\n+\t\t\t\t\t       const struct qbman_fd *fd)\n {\n \tuint32_t *p;\n \tconst uint32_t *cl = qb_cl(d);\n@@ -433,39 +591,69 @@ static int qbman_swp_enqueue_array_mode(struct qbman_swp *s,\n \tif (!EQAR_SUCCESS(eqar))\n \t\treturn -EBUSY;\n \tp = qbman_cena_write_start_wo_shadow(&s->sys,\n-\t\t\t\t\tQBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));\n+\t\t\tQBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));\n \tmemcpy(&p[1], &cl[1], 28);\n \tmemcpy(&p[8], fd, sizeof(*fd));\n+\n \t/* Set the verb byte, have to substitute in the valid-bit */\n-\tlwsync();\n+\tdma_wmb();\n \tp[0] = cl[0] | EQAR_VB(eqar);\n \tqbman_cena_write_complete_wo_shadow(&s->sys,\n-\t\t\t\t\tQBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));\n \treturn 0;\n }\n+static int qbman_swp_enqueue_array_mode_mem_back(struct qbman_swp *s,\n+\t\t\t\t\t\t const struct qbman_eq_desc *d,\n+\t\t\t\t\t\t const struct qbman_fd *fd)\n+{\n+\tuint32_t *p;\n+\tconst uint32_t *cl = qb_cl(d);\n+\tuint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);\n \n-static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,\n-\t\t\t\t       const struct qbman_eq_desc *d,\n-\t\t\t\t       const struct qbman_fd *fd)\n+\tpr_debug(\"EQAR=%08x\\n\", eqar);\n+\tif (!EQAR_SUCCESS(eqar))\n+\t\treturn -EBUSY;\n+\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n+\t\t\tQBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));\n+\tmemcpy(&p[1], &cl[1], 28);\n+\tmemcpy(&p[8], fd, sizeof(*fd));\n+\n+\t/* Set the verb byte, have to substitute in the valid-bit */\n+\tp[0] = cl[0] | EQAR_VB(eqar);\n+\tdma_wmb();\n+\tqbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar));\n+\treturn 0;\n+}\n+\n+static inline int qbman_swp_enqueue_array_mode(struct qbman_swp *s,\n+\t\t\t\t\t       const struct qbman_eq_desc *d,\n+\t\t\t\t\t       const struct qbman_fd *fd)\n+{\n+\treturn qbman_swp_enqueue_array_mode_ptr(s, d, fd);\n+}\n+\n+static int qbman_swp_enqueue_ring_mode_direct(struct qbman_swp *s,\n+\t\t\t\t\t      const struct qbman_eq_desc *d,\n+\t\t\t\t\t      const struct qbman_fd *fd)\n {\n \tuint32_t *p;\n \tconst uint32_t *cl = qb_cl(d);\n-\tuint32_t eqcr_ci;\n-\tuint8_t diff;\n+\tuint32_t eqcr_ci, full_mask, half_mask;\n \n+\thalf_mask = (s->eqcr.pi_mask>>1);\n+\tfull_mask = s->eqcr.pi_mask;\n \tif (!s->eqcr.available) {\n \t\teqcr_ci = s->eqcr.ci;\n \t\ts->eqcr.ci = qbman_cena_read_reg(&s->sys,\n-\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & 0xF;\n-\t\tdiff = qm_cyc_diff(QBMAN_EQCR_SIZE,\n-\t\t\t\t   eqcr_ci, s->eqcr.ci);\n-\t\ts->eqcr.available += diff;\n-\t\tif (!diff)\n+\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & full_mask;\n+\t\ts->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,\n+\t\t\t\teqcr_ci, s->eqcr.ci);\n+\t\tif (!s->eqcr.available)\n \t\t\treturn -EBUSY;\n \t}\n \n \tp = qbman_cena_write_start_wo_shadow(&s->sys,\n-\t\t\t\t\tQBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));\n+\t\t\tQBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));\n \tmemcpy(&p[1], &cl[1], 28);\n \tmemcpy(&p[8], fd, sizeof(*fd));\n \tlwsync();\n@@ -473,16 +661,61 @@ static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,\n \t/* Set the verb byte, have to substitute in the valid-bit */\n \tp[0] = cl[0] | s->eqcr.pi_vb;\n \tqbman_cena_write_complete_wo_shadow(&s->sys,\n-\t\t\t\t\tQBMAN_CENA_SWP_EQCR(s->eqcr.pi & 7));\n+\t\t\tQBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));\n \ts->eqcr.pi++;\n-\ts->eqcr.pi &= 0xF;\n+\ts->eqcr.pi &= full_mask;\n \ts->eqcr.available--;\n-\tif (!(s->eqcr.pi & 7))\n+\tif (!(s->eqcr.pi & half_mask))\n \t\ts->eqcr.pi_vb ^= QB_VALID_BIT;\n \n \treturn 0;\n }\n \n+static int qbman_swp_enqueue_ring_mode_mem_back(struct qbman_swp *s,\n+\t\t\t\t\t\tconst struct qbman_eq_desc *d,\n+\t\t\t\t\t\tconst struct qbman_fd *fd)\n+{\n+\tuint32_t *p;\n+\tconst uint32_t *cl = qb_cl(d);\n+\tuint32_t eqcr_ci, full_mask, half_mask;\n+\n+\thalf_mask = (s->eqcr.pi_mask>>1);\n+\tfull_mask = s->eqcr.pi_mask;\n+\tif (!s->eqcr.available) {\n+\t\teqcr_ci = s->eqcr.ci;\n+\t\ts->eqcr.ci = qbman_cinh_read(&s->sys,\n+\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & full_mask;\n+\t\ts->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,\n+\t\t\t\teqcr_ci, s->eqcr.ci);\n+\t\tif (!s->eqcr.available)\n+\t\t\treturn -EBUSY;\n+\t}\n+\n+\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n+\t\t\tQBMAN_CENA_SWP_EQCR(s->eqcr.pi & half_mask));\n+\tmemcpy(&p[1], &cl[1], 28);\n+\tmemcpy(&p[8], fd, sizeof(*fd));\n+\n+\t/* Set the verb byte, have to substitute in the valid-bit */\n+\tp[0] = cl[0] | s->eqcr.pi_vb;\n+\ts->eqcr.pi++;\n+\ts->eqcr.pi &= full_mask;\n+\ts->eqcr.available--;\n+\tif (!(s->eqcr.pi & half_mask))\n+\t\ts->eqcr.pi_vb ^= QB_VALID_BIT;\n+\tdma_wmb();\n+\tqbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,\n+\t\t\t\t(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);\n+\treturn 0;\n+}\n+\n+static int qbman_swp_enqueue_ring_mode(struct qbman_swp *s,\n+\t\t\t\t       const struct qbman_eq_desc *d,\n+\t\t\t\t       const struct qbman_fd *fd)\n+{\n+\treturn qbman_swp_enqueue_ring_mode_ptr(s, d, fd);\n+}\n+\n int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,\n \t\t      const struct qbman_fd *fd)\n {\n@@ -492,27 +725,27 @@ int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,\n \t\treturn qbman_swp_enqueue_ring_mode(s, d, fd);\n }\n \n-int qbman_swp_enqueue_multiple(struct qbman_swp *s,\n-\t\t\t       const struct qbman_eq_desc *d,\n-\t\t\t       const struct qbman_fd *fd,\n-\t\t\t       uint32_t *flags,\n-\t\t\t       int num_frames)\n+static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,\n+\t\t\t\t\t     const struct qbman_eq_desc *d,\n+\t\t\t\t\t     const struct qbman_fd *fd,\n+\t\t\t\t\t     uint32_t *flags,\n+\t\t\t\t\t     int num_frames)\n {\n-\tuint32_t *p;\n+\tuint32_t *p = NULL;\n \tconst uint32_t *cl = qb_cl(d);\n-\tuint32_t eqcr_ci, eqcr_pi;\n-\tuint8_t diff;\n+\tuint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;\n \tint i, num_enqueued = 0;\n \tuint64_t addr_cena;\n \n+\thalf_mask = (s->eqcr.pi_mask>>1);\n+\tfull_mask = s->eqcr.pi_mask;\n \tif (!s->eqcr.available) {\n \t\teqcr_ci = s->eqcr.ci;\n \t\ts->eqcr.ci = qbman_cena_read_reg(&s->sys,\n-\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & 0xF;\n-\t\tdiff = qm_cyc_diff(QBMAN_EQCR_SIZE,\n-\t\t\t\t   eqcr_ci, s->eqcr.ci);\n-\t\ts->eqcr.available += diff;\n-\t\tif (!diff)\n+\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & full_mask;\n+\t\ts->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,\n+\t\t\t\teqcr_ci, s->eqcr.ci);\n+\t\tif (!s->eqcr.available)\n \t\t\treturn 0;\n \t}\n \n@@ -523,11 +756,10 @@ int qbman_swp_enqueue_multiple(struct qbman_swp *s,\n \t/* Fill in the EQCR ring */\n \tfor (i = 0; i < num_enqueued; i++) {\n \t\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n-\t\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & 7));\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));\n \t\tmemcpy(&p[1], &cl[1], 28);\n \t\tmemcpy(&p[8], &fd[i], sizeof(*fd));\n \t\teqcr_pi++;\n-\t\teqcr_pi &= 0xF;\n \t}\n \n \tlwsync();\n@@ -536,7 +768,7 @@ int qbman_swp_enqueue_multiple(struct qbman_swp *s,\n \teqcr_pi = s->eqcr.pi;\n \tfor (i = 0; i < num_enqueued; i++) {\n \t\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n-\t\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & 7));\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));\n \t\tp[0] = cl[0] | s->eqcr.pi_vb;\n \t\tif (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {\n \t\t\tstruct qbman_eq_desc *d = (struct qbman_eq_desc *)p;\n@@ -545,8 +777,7 @@ int qbman_swp_enqueue_multiple(struct qbman_swp *s,\n \t\t\t\t((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);\n \t\t}\n \t\teqcr_pi++;\n-\t\teqcr_pi &= 0xF;\n-\t\tif (!(eqcr_pi & 7))\n+\t\tif (!(eqcr_pi & half_mask))\n \t\t\ts->eqcr.pi_vb ^= QB_VALID_BIT;\n \t}\n \n@@ -554,35 +785,104 @@ int qbman_swp_enqueue_multiple(struct qbman_swp *s,\n \teqcr_pi = s->eqcr.pi;\n \taddr_cena = (size_t)s->sys.addr_cena;\n \tfor (i = 0; i < num_enqueued; i++) {\n-\t\tdcbf((addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & 7)));\n+\t\tdcbf((uintptr_t)(addr_cena +\n+\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)));\n \t\teqcr_pi++;\n-\t\teqcr_pi &= 0xF;\n \t}\n-\ts->eqcr.pi = eqcr_pi;\n+\ts->eqcr.pi = eqcr_pi & full_mask;\n \n \treturn num_enqueued;\n }\n \n-int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,\n-\t\t\t\t    const struct qbman_eq_desc *d,\n-\t\t\t\t    const struct qbman_fd *fd,\n-\t\t\t\t    int num_frames)\n+static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,\n+\t\t\t\t\t       const struct qbman_eq_desc *d,\n+\t\t\t\t\t       const struct qbman_fd *fd,\n+\t\t\t\t\t       uint32_t *flags,\n+\t\t\t\t\t       int num_frames)\n+{\n+\tuint32_t *p = NULL;\n+\tconst uint32_t *cl = qb_cl(d);\n+\tuint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;\n+\tint i, num_enqueued = 0;\n+\n+\thalf_mask = (s->eqcr.pi_mask>>1);\n+\tfull_mask = s->eqcr.pi_mask;\n+\tif (!s->eqcr.available) {\n+\t\teqcr_ci = s->eqcr.ci;\n+\t\ts->eqcr.ci = qbman_cinh_read(&s->sys,\n+\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & full_mask;\n+\t\ts->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,\n+\t\t\t\t\teqcr_ci, s->eqcr.ci);\n+\t\tif (!s->eqcr.available)\n+\t\t\treturn 0;\n+\t}\n+\n+\teqcr_pi = s->eqcr.pi;\n+\tnum_enqueued = (s->eqcr.available < num_frames) ?\n+\t\t\ts->eqcr.available : num_frames;\n+\ts->eqcr.available -= num_enqueued;\n+\t/* Fill in the EQCR ring */\n+\tfor (i = 0; i < num_enqueued; i++) {\n+\t\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));\n+\t\tmemcpy(&p[1], &cl[1], 28);\n+\t\tmemcpy(&p[8], &fd[i], sizeof(*fd));\n+\t\teqcr_pi++;\n+\t}\n+\n+\t/* Set the verb byte, have to substitute in the valid-bit */\n+\teqcr_pi = s->eqcr.pi;\n+\tfor (i = 0; i < num_enqueued; i++) {\n+\t\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));\n+\t\tp[0] = cl[0] | s->eqcr.pi_vb;\n+\t\tif (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) {\n+\t\t\tstruct qbman_eq_desc *d = (struct qbman_eq_desc *)p;\n+\n+\t\t\td->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) |\n+\t\t\t\t((flags[i]) & QBMAN_EQCR_DCA_IDXMASK);\n+\t\t}\n+\t\teqcr_pi++;\n+\t\tif (!(eqcr_pi & half_mask))\n+\t\t\ts->eqcr.pi_vb ^= QB_VALID_BIT;\n+\t}\n+\ts->eqcr.pi = eqcr_pi & full_mask;\n+\n+\tdma_wmb();\n+\tqbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,\n+\t\t\t\t(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);\n+\treturn num_enqueued;\n+}\n+\n+inline int qbman_swp_enqueue_multiple(struct qbman_swp *s,\n+\t\t\t\t      const struct qbman_eq_desc *d,\n+\t\t\t\t      const struct qbman_fd *fd,\n+\t\t\t\t      uint32_t *flags,\n+\t\t\t\t      int num_frames)\n+{\n+\treturn qbman_swp_enqueue_multiple_ptr(s, d, fd, flags, num_frames);\n+}\n+\n+static int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,\n+\t\t\t\t\tconst struct qbman_eq_desc *d,\n+\t\t\t\t\tconst struct qbman_fd *fd,\n+\t\t\t\t\tint num_frames)\n {\n \tuint32_t *p;\n \tconst uint32_t *cl;\n-\tuint32_t eqcr_ci, eqcr_pi;\n-\tuint8_t diff;\n+\tuint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;\n \tint i, num_enqueued = 0;\n \tuint64_t addr_cena;\n \n+\thalf_mask = (s->eqcr.pi_mask>>1);\n+\tfull_mask = s->eqcr.pi_mask;\n \tif (!s->eqcr.available) {\n \t\teqcr_ci = s->eqcr.ci;\n \t\ts->eqcr.ci = qbman_cena_read_reg(&s->sys,\n-\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & 0xF;\n-\t\tdiff = qm_cyc_diff(QBMAN_EQCR_SIZE,\n-\t\t\t\t   eqcr_ci, s->eqcr.ci);\n-\t\ts->eqcr.available += diff;\n-\t\tif (!diff)\n+\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & full_mask;\n+\t\ts->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,\n+\t\t\t\t\teqcr_ci, s->eqcr.ci);\n+\t\tif (!s->eqcr.available)\n \t\t\treturn 0;\n \t}\n \n@@ -593,12 +893,11 @@ int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,\n \t/* Fill in the EQCR ring */\n \tfor (i = 0; i < num_enqueued; i++) {\n \t\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n-\t\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & 7));\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));\n \t\tcl = qb_cl(&d[i]);\n \t\tmemcpy(&p[1], &cl[1], 28);\n \t\tmemcpy(&p[8], &fd[i], sizeof(*fd));\n \t\teqcr_pi++;\n-\t\teqcr_pi &= 0xF;\n \t}\n \n \tlwsync();\n@@ -607,12 +906,11 @@ int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,\n \teqcr_pi = s->eqcr.pi;\n \tfor (i = 0; i < num_enqueued; i++) {\n \t\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n-\t\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & 7));\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));\n \t\tcl = qb_cl(&d[i]);\n \t\tp[0] = cl[0] | s->eqcr.pi_vb;\n \t\teqcr_pi++;\n-\t\teqcr_pi &= 0xF;\n-\t\tif (!(eqcr_pi & 7))\n+\t\tif (!(eqcr_pi & half_mask))\n \t\t\ts->eqcr.pi_vb ^= QB_VALID_BIT;\n \t}\n \n@@ -620,14 +918,78 @@ int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,\n \teqcr_pi = s->eqcr.pi;\n \taddr_cena = (size_t)s->sys.addr_cena;\n \tfor (i = 0; i < num_enqueued; i++) {\n-\t\tdcbf((addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & 7)));\n+\t\tdcbf((uintptr_t)(addr_cena +\n+\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)));\n+\t\teqcr_pi++;\n+\t}\n+\ts->eqcr.pi = eqcr_pi & full_mask;\n+\n+\treturn num_enqueued;\n+}\n+\n+static int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,\n+\t\t\t\t\tconst struct qbman_eq_desc *d,\n+\t\t\t\t\tconst struct qbman_fd *fd,\n+\t\t\t\t\tint num_frames)\n+{\n+\tuint32_t *p;\n+\tconst uint32_t *cl;\n+\tuint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;\n+\tint i, num_enqueued = 0;\n+\n+\thalf_mask = (s->eqcr.pi_mask>>1);\n+\tfull_mask = s->eqcr.pi_mask;\n+\tif (!s->eqcr.available) {\n+\t\teqcr_ci = s->eqcr.ci;\n+\t\ts->eqcr.ci = qbman_cinh_read(&s->sys,\n+\t\t\t\tQBMAN_CENA_SWP_EQCR_CI) & full_mask;\n+\t\ts->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,\n+\t\t\t\t\teqcr_ci, s->eqcr.ci);\n+\t\tif (!s->eqcr.available)\n+\t\t\treturn 0;\n+\t}\n+\n+\teqcr_pi = s->eqcr.pi;\n+\tnum_enqueued = (s->eqcr.available < num_frames) ?\n+\t\t\ts->eqcr.available : num_frames;\n+\ts->eqcr.available -= num_enqueued;\n+\t/* Fill in the EQCR ring */\n+\tfor (i = 0; i < num_enqueued; i++) {\n+\t\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));\n+\t\tcl = qb_cl(&d[i]);\n+\t\tmemcpy(&p[1], &cl[1], 28);\n+\t\tmemcpy(&p[8], &fd[i], sizeof(*fd));\n+\t\teqcr_pi++;\n+\t}\n+\n+\t/* Set the verb byte, have to substitute in the valid-bit */\n+\teqcr_pi = s->eqcr.pi;\n+\tfor (i = 0; i < num_enqueued; i++) {\n+\t\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n+\t\t\t\tQBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask));\n+\t\tcl = qb_cl(&d[i]);\n+\t\tp[0] = cl[0] | s->eqcr.pi_vb;\n \t\teqcr_pi++;\n-\t\teqcr_pi &= 0xF;\n+\t\tif (!(eqcr_pi & half_mask))\n+\t\t\ts->eqcr.pi_vb ^= QB_VALID_BIT;\n \t}\n-\ts->eqcr.pi = eqcr_pi;\n+\n+\ts->eqcr.pi = eqcr_pi & full_mask;\n+\n+\tdma_wmb();\n+\tqbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI,\n+\t\t\t\t(QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb);\n \n \treturn num_enqueued;\n }\n+inline int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s,\n+\t\t\t\t\t   const struct qbman_eq_desc *d,\n+\t\t\t\t\t   const struct qbman_fd *fd,\n+\t\t\t\t\t   int num_frames)\n+{\n+\treturn qbman_swp_enqueue_multiple_desc_ptr(s, d, fd, num_frames);\n+}\n \n /*************************/\n /* Static (push) dequeue */\n@@ -670,6 +1032,7 @@ void qbman_swp_push_set(struct qbman_swp *s, uint8_t channel_idx, int enable)\n #define QB_VDQCR_VERB_DT_SHIFT     2\n #define QB_VDQCR_VERB_RLS_SHIFT    4\n #define QB_VDQCR_VERB_WAE_SHIFT    5\n+#define QB_VDQCR_VERB_RAD_SHIFT    6\n \n enum qb_pull_dt_e {\n \tqb_pull_dt_channel,\n@@ -702,7 +1065,8 @@ void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,\n \td->pull.rsp_addr = storage_phys;\n }\n \n-void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)\n+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d,\n+\t\t\t\t   uint8_t numframes)\n {\n \td->pull.numf = numframes - 1;\n }\n@@ -735,7 +1099,20 @@ void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, uint32_t chid,\n \td->pull.dq_src = chid;\n }\n \n-int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)\n+void qbman_pull_desc_set_rad(struct qbman_pull_desc *d, int rad)\n+{\n+\tif (d->pull.verb & (1 << QB_VDQCR_VERB_RLS_SHIFT)) {\n+\t\tif (rad)\n+\t\t\td->pull.verb |= 1 << QB_VDQCR_VERB_RAD_SHIFT;\n+\t\telse\n+\t\t\td->pull.verb &= ~(1 << QB_VDQCR_VERB_RAD_SHIFT);\n+\t} else {\n+\t\tprintf(\"The RAD feature is not valid when RLS = 0\\n\");\n+\t}\n+}\n+\n+static int qbman_swp_pull_direct(struct qbman_swp *s,\n+\t\t\t\t struct qbman_pull_desc *d)\n {\n \tuint32_t *p;\n \tuint32_t *cl = qb_cl(d);\n@@ -759,6 +1136,36 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)\n \treturn 0;\n }\n \n+static int qbman_swp_pull_mem_back(struct qbman_swp *s,\n+\t\t\t\t   struct qbman_pull_desc *d)\n+{\n+\tuint32_t *p;\n+\tuint32_t *cl = qb_cl(d);\n+\n+\tif (!atomic_dec_and_test(&s->vdq.busy)) {\n+\t\tatomic_inc(&s->vdq.busy);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\td->pull.tok = s->sys.idx + 1;\n+\ts->vdq.storage = (void *)(size_t)d->pull.rsp_addr_virt;\n+\tp = qbman_cena_write_start_wo_shadow(&s->sys, QBMAN_CENA_SWP_VDQCR_MEM);\n+\tmemcpy(&p[1], &cl[1], 12);\n+\n+\t/* Set the verb byte, have to substitute in the valid-bit */\n+\tp[0] = cl[0] | s->vdq.valid_bit;\n+\ts->vdq.valid_bit ^= QB_VALID_BIT;\n+\tdma_wmb();\n+\tqbman_cinh_write(&s->sys, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE);\n+\n+\treturn 0;\n+}\n+\n+inline int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)\n+{\n+\treturn qbman_swp_pull_ptr(s, d);\n+}\n+\n /****************/\n /* Polling DQRR */\n /****************/\n@@ -791,7 +1198,12 @@ void qbman_swp_prefetch_dqrr_next(struct qbman_swp *s)\n  * only once, so repeated calls can return a sequence of DQRR entries, without\n  * requiring they be consumed immediately or in any particular order.\n  */\n-const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)\n+inline const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)\n+{\n+\treturn qbman_swp_dqrr_next_ptr(s);\n+}\n+\n+const struct qbman_result *qbman_swp_dqrr_next_direct(struct qbman_swp *s)\n {\n \tuint32_t verb;\n \tuint32_t response_verb;\n@@ -801,7 +1213,7 @@ const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)\n \t/* Before using valid-bit to detect if something is there, we have to\n \t * handle the case of the DQRR reset bug...\n \t */\n-\tif (unlikely(s->dqrr.reset_bug)) {\n+\tif (s->dqrr.reset_bug) {\n \t\t/* We pick up new entries by cache-inhibited producer index,\n \t\t * which means that a non-coherent mapping would require us to\n \t\t * invalidate and read *only* once that PI has indicated that\n@@ -833,7 +1245,8 @@ const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)\n \t\t\t\t\tQBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));\n \t}\n \tp = qbman_cena_read_wo_shadow(&s->sys,\n-\t\t\t\t      QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));\n+\t\t\tQBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));\n+\n \tverb = p->dq.verb;\n \n \t/* If the valid-bit isn't of the expected polarity, nothing there. Note,\n@@ -867,11 +1280,54 @@ const struct qbman_result *qbman_swp_dqrr_next(struct qbman_swp *s)\n \treturn p;\n }\n \n+const struct qbman_result *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s)\n+{\n+\tuint32_t verb;\n+\tuint32_t response_verb;\n+\tuint32_t flags;\n+\tconst struct qbman_result *p;\n+\n+\tp = qbman_cena_read_wo_shadow(&s->sys,\n+\t\t\tQBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx));\n+\n+\tverb = p->dq.verb;\n+\n+\t/* If the valid-bit isn't of the expected polarity, nothing there. Note,\n+\t * in the DQRR reset bug workaround, we shouldn't need to skip these\n+\t * check, because we've already determined that a new entry is available\n+\t * and we've invalidated the cacheline before reading it, so the\n+\t * valid-bit behaviour is repaired and should tell us what we already\n+\t * knew from reading PI.\n+\t */\n+\tif ((verb & QB_VALID_BIT) != s->dqrr.valid_bit)\n+\t\treturn NULL;\n+\n+\t/* There's something there. Move \"next_idx\" attention to the next ring\n+\t * entry (and prefetch it) before returning what we found.\n+\t */\n+\ts->dqrr.next_idx++;\n+\tif (s->dqrr.next_idx == s->dqrr.dqrr_size) {\n+\t\ts->dqrr.next_idx = 0;\n+\t\ts->dqrr.valid_bit ^= QB_VALID_BIT;\n+\t}\n+\t/* If this is the final response to a volatile dequeue command\n+\t * indicate that the vdq is no longer busy\n+\t */\n+\tflags = p->dq.stat;\n+\tresponse_verb = verb & QBMAN_RESPONSE_VERB_MASK;\n+\tif ((response_verb == QBMAN_RESULT_DQ) &&\n+\t    (flags & QBMAN_DQ_STAT_VOLATILE) &&\n+\t    (flags & QBMAN_DQ_STAT_EXPIRED))\n+\t\tatomic_inc(&s->vdq.busy);\n+\treturn p;\n+}\n+\n /* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */\n void qbman_swp_dqrr_consume(struct qbman_swp *s,\n \t\t\t    const struct qbman_result *dq)\n {\n-\tqbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));\n+\tqbman_cinh_write(&s->sys,\n+\t\t\tQBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));\n }\n \n /* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */\n@@ -884,6 +1340,7 @@ void qbman_swp_dqrr_idx_consume(struct qbman_swp *s,\n /*********************************/\n /* Polling user-provided storage */\n /*********************************/\n+\n int qbman_result_has_new_result(struct qbman_swp *s,\n \t\t\t\tstruct qbman_result *dq)\n {\n@@ -898,11 +1355,11 @@ int qbman_result_has_new_result(struct qbman_swp *s,\n \t((struct qbman_result *)dq)->dq.tok = 0;\n \n \t/*\n-\t * VDQCR \"no longer busy\" hook - not quite the same as DQRR, because the\n-\t * fact \"VDQCR\" shows busy doesn't mean that we hold the result that\n-\t * makes it available. Eg. we may be looking at our 10th dequeue result,\n-\t * having released VDQCR after the 1st result and it is now busy due to\n-\t * some other command!\n+\t * VDQCR \"no longer busy\" hook - not quite the same as DQRR, because\n+\t * the fact \"VDQCR\" shows busy doesn't mean that we hold the result\n+\t * that makes it available. Eg. we may be looking at our 10th dequeue\n+\t * result, having released VDQCR after the 1st result and it is now\n+\t * busy due to some other command!\n \t */\n \tif (s->vdq.storage == dq) {\n \t\ts->vdq.storage = NULL;\n@@ -936,11 +1393,11 @@ int qbman_check_command_complete(struct qbman_result *dq)\n \n \ts = portal_idx_map[dq->dq.tok - 1];\n \t/*\n-\t * VDQCR \"no longer busy\" hook - not quite the same as DQRR, because the\n-\t * fact \"VDQCR\" shows busy doesn't mean that we hold the result that\n-\t * makes it available. Eg. we may be looking at our 10th dequeue result,\n-\t * having released VDQCR after the 1st result and it is now busy due to\n-\t * some other command!\n+\t * VDQCR \"no longer busy\" hook - not quite the same as DQRR, because\n+\t * the fact \"VDQCR\" shows busy doesn't mean that we hold the result\n+\t * that makes it available. Eg. we may be looking at our 10th dequeue\n+\t * result, having released VDQCR after the 1st result and it is now\n+\t * busy due to some other command!\n \t */\n \tif (s->vdq.storage == dq) {\n \t\ts->vdq.storage = NULL;\n@@ -1142,8 +1599,10 @@ void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)\n #define RAR_VB(rar)      ((rar) & 0x80)\n #define RAR_SUCCESS(rar) ((rar) & 0x100)\n \n-int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,\n-\t\t      const uint64_t *buffers, unsigned int num_buffers)\n+static int qbman_swp_release_direct(struct qbman_swp *s,\n+\t\t\t\t    const struct qbman_release_desc *d,\n+\t\t\t\t    const uint64_t *buffers,\n+\t\t\t\t    unsigned int num_buffers)\n {\n \tuint32_t *p;\n \tconst uint32_t *cl = qb_cl(d);\n@@ -1157,22 +1616,63 @@ int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,\n \n \t/* Start the release command */\n \tp = qbman_cena_write_start_wo_shadow(&s->sys,\n-\t\t\t\t\t     QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));\n+\t\t\t\t     QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));\n \n \t/* Copy the caller's buffer pointers to the command */\n \tu64_to_le32_copy(&p[2], buffers, num_buffers);\n \n-\t/* Set the verb byte, have to substitute in the valid-bit and the number\n-\t * of buffers.\n+\t/* Set the verb byte, have to substitute in the valid-bit and the\n+\t * number of buffers.\n \t */\n \tlwsync();\n \tp[0] = cl[0] | RAR_VB(rar) | num_buffers;\n \tqbman_cena_write_complete_wo_shadow(&s->sys,\n-\t\t\t\t\t    QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));\n+\t\t\t\t    QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));\n \n \treturn 0;\n }\n \n+static int qbman_swp_release_mem_back(struct qbman_swp *s,\n+\t\t\t\t      const struct qbman_release_desc *d,\n+\t\t\t\t      const uint64_t *buffers,\n+\t\t\t\t      unsigned int num_buffers)\n+{\n+\tuint32_t *p;\n+\tconst uint32_t *cl = qb_cl(d);\n+\tuint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);\n+\n+\tpr_debug(\"RAR=%08x\\n\", rar);\n+\tif (!RAR_SUCCESS(rar))\n+\t\treturn -EBUSY;\n+\n+\tQBMAN_BUG_ON(!num_buffers || (num_buffers > 7));\n+\n+\t/* Start the release command */\n+\tp = qbman_cena_write_start_wo_shadow(&s->sys,\n+\t\tQBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar)));\n+\n+\t/* Copy the caller's buffer pointers to the command */\n+\tu64_to_le32_copy(&p[2], buffers, num_buffers);\n+\n+\t/* Set the verb byte, have to substitute in the valid-bit and the\n+\t * number of buffers.\n+\t */\n+\tp[0] = cl[0] | RAR_VB(rar) | num_buffers;\n+\tlwsync();\n+\tqbman_cinh_write(&s->sys, QBMAN_CINH_SWP_RCR_AM_RT +\n+\t\tRAR_IDX(rar) * 4, QMAN_RT_MODE);\n+\n+\treturn 0;\n+}\n+\n+inline int qbman_swp_release(struct qbman_swp *s,\n+\t\t\t     const struct qbman_release_desc *d,\n+\t\t\t     const uint64_t *buffers,\n+\t\t\t     unsigned int num_buffers)\n+{\n+\treturn qbman_swp_release_ptr(s, d, buffers, num_buffers);\n+}\n+\n /*******************/\n /* Buffer acquires */\n /*******************/\n@@ -1214,7 +1714,7 @@ int qbman_swp_acquire(struct qbman_swp *s, uint16_t bpid, uint64_t *buffers,\n \n \t/* Complete the management command */\n \tr = qbman_swp_mc_complete(s, p, QBMAN_MC_ACQUIRE);\n-\tif (unlikely(!r)) {\n+\tif (!r) {\n \t\tpr_err(\"qbman: acquire from BPID %d failed, no response\\n\",\n \t\t       bpid);\n \t\treturn -EIO;\n@@ -1224,7 +1724,7 @@ int qbman_swp_acquire(struct qbman_swp *s, uint16_t bpid, uint64_t *buffers,\n \tQBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ACQUIRE);\n \n \t/* Determine success or failure */\n-\tif (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {\n+\tif (r->rslt != QBMAN_MC_RSLT_OK) {\n \t\tpr_err(\"Acquire buffers from BPID 0x%x failed, code=0x%02x\\n\",\n \t\t       bpid, r->rslt);\n \t\treturn -EIO;\n@@ -1271,7 +1771,7 @@ static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,\n \n \t/* Complete the management command */\n \tr = qbman_swp_mc_complete(s, p, alt_fq_verb);\n-\tif (unlikely(!r)) {\n+\tif (!r) {\n \t\tpr_err(\"qbman: mgmt cmd failed, no response (verb=0x%x)\\n\",\n \t\t       alt_fq_verb);\n \t\treturn -EIO;\n@@ -1281,7 +1781,7 @@ static int qbman_swp_alt_fq_state(struct qbman_swp *s, uint32_t fqid,\n \tQBMAN_BUG_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != alt_fq_verb);\n \n \t/* Determine success or failure */\n-\tif (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {\n+\tif (r->rslt != QBMAN_MC_RSLT_OK) {\n \t\tpr_err(\"ALT FQID %d failed: verb = 0x%08x, code = 0x%02x\\n\",\n \t\t       fqid, alt_fq_verb, r->rslt);\n \t\treturn -EIO;\n@@ -1362,7 +1862,7 @@ static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,\n \n \t/* Complete the management command */\n \tr = qbman_swp_mc_complete(s, p, QBMAN_WQCHAN_CONFIGURE);\n-\tif (unlikely(!r)) {\n+\tif (!r) {\n \t\tpr_err(\"qbman: wqchan config failed, no response\\n\");\n \t\treturn -EIO;\n \t}\n@@ -1372,7 +1872,7 @@ static int qbman_swp_CDAN_set(struct qbman_swp *s, uint16_t channelid,\n \t\t     != QBMAN_WQCHAN_CONFIGURE);\n \n \t/* Determine success or failure */\n-\tif (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {\n+\tif (r->rslt != QBMAN_MC_RSLT_OK) {\n \t\tpr_err(\"CDAN cQID %d failed: code = 0x%02x\\n\",\n \t\t       channelid, r->rslt);\n \t\treturn -EIO;\ndiff --git a/drivers/bus/fslmc/qbman/qbman_portal.h b/drivers/bus/fslmc/qbman/qbman_portal.h\nindex dbea22a1b..3b0fc540b 100644\n--- a/drivers/bus/fslmc/qbman/qbman_portal.h\n+++ b/drivers/bus/fslmc/qbman/qbman_portal.h\n@@ -1,12 +1,17 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n  *\n  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.\n+ * Copyright 2018 NXP\n  *\n  */\n \n+#ifndef _QBMAN_PORTAL_H_\n+#define _QBMAN_PORTAL_H_\n+\n #include \"qbman_sys.h\"\n #include <fsl_qbman_portal.h>\n \n+uint32_t qman_version;\n #define QMAN_REV_4000   0x04000000\n #define QMAN_REV_4100   0x04010000\n #define QMAN_REV_4101   0x04010001\n@@ -14,13 +19,14 @@\n /* All QBMan command and result structures use this \"valid bit\" encoding */\n #define QB_VALID_BIT ((uint32_t)0x80)\n \n+/* All QBMan command use this \"Read trigger bit\" encoding */\n+#define QB_RT_BIT ((uint32_t)0x100)\n+\n /* Management command result codes */\n #define QBMAN_MC_RSLT_OK      0xf0\n \n /* QBMan DQRR size is set at runtime in qbman_portal.c */\n \n-#define QBMAN_EQCR_SIZE 8\n-\n static inline uint8_t qm_cyc_diff(uint8_t ringsize, uint8_t first,\n \t\t\t\t  uint8_t last)\n {\n@@ -51,6 +57,10 @@ struct qbman_swp {\n #endif\n \t\tuint32_t valid_bit; /* 0x00 or 0x80 */\n \t} mc;\n+\t/* Management response */\n+\tstruct {\n+\t\tuint32_t valid_bit; /* 0x00 or 0x80 */\n+\t} mr;\n \t/* Push dequeues */\n \tuint32_t sdq;\n \t/* Volatile dequeues */\n@@ -87,6 +97,8 @@ struct qbman_swp {\n \tstruct {\n \t\tuint32_t pi;\n \t\tuint32_t pi_vb;\n+\t\tuint32_t pi_ring_size;\n+\t\tuint32_t pi_mask;\n \t\tuint32_t ci;\n \t\tint available;\n \t} eqcr;\n@@ -141,4 +153,16 @@ static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,\n  * an inline) is necessary to work with different descriptor types and to work\n  * correctly with const and non-const inputs (and similarly-qualified outputs).\n  */\n-#define qb_cl(d) (&(d)->donot_manipulate_directly[0])\n+#define qb_cl(d) (&(d)->dont_manipulate_directly[0])\n+\n+#ifdef RTE_ARCH_ARM64\n+\t#define clean(p) \\\n+\t\t\t{ asm volatile(\"dc cvac, %0;\" : : \"r\" (p) : \"memory\"); }\n+\t#define invalidate(p) \\\n+\t\t\t{ asm volatile(\"dc ivac, %0\" : : \"r\"(p) : \"memory\"); }\n+#else\n+\t#define clean(p)\n+\t#define invalidate(p)\n+#endif\n+\n+#endif\ndiff --git a/drivers/bus/fslmc/qbman/qbman_sys.h b/drivers/bus/fslmc/qbman/qbman_sys.h\nindex 2bd33ea56..d41af8358 100644\n--- a/drivers/bus/fslmc/qbman/qbman_sys.h\n+++ b/drivers/bus/fslmc/qbman/qbman_sys.h\n@@ -18,11 +18,51 @@\n  * *not* to provide linux compatibility.\n  */\n \n+#ifndef _QBMAN_SYS_H_\n+#define _QBMAN_SYS_H_\n+\n #include \"qbman_sys_decl.h\"\n \n #define CENA_WRITE_ENABLE 0\n #define CINH_WRITE_ENABLE 1\n \n+/* CINH register offsets */\n+#define QBMAN_CINH_SWP_EQCR_PI      0x800\n+#define QBMAN_CINH_SWP_EQCR_CI      0x840\n+#define QBMAN_CINH_SWP_EQAR         0x8c0\n+#define QBMAN_CINH_SWP_CR_RT        0x900\n+#define QBMAN_CINH_SWP_VDQCR_RT     0x940\n+#define QBMAN_CINH_SWP_EQCR_AM_RT   0x980\n+#define QBMAN_CINH_SWP_RCR_AM_RT    0x9c0\n+#define QBMAN_CINH_SWP_DQPI         0xa00\n+#define QBMAN_CINH_SWP_DQRR_ITR     0xa80\n+#define QBMAN_CINH_SWP_DCAP         0xac0\n+#define QBMAN_CINH_SWP_SDQCR        0xb00\n+#define QBMAN_CINH_SWP_EQCR_AM_RT2  0xb40\n+#define QBMAN_CINH_SWP_RCR_PI       0xc00\n+#define QBMAN_CINH_SWP_RAR          0xcc0\n+#define QBMAN_CINH_SWP_ISR          0xe00\n+#define QBMAN_CINH_SWP_IER          0xe40\n+#define QBMAN_CINH_SWP_ISDR         0xe80\n+#define QBMAN_CINH_SWP_IIR          0xec0\n+#define QBMAN_CINH_SWP_ITPR         0xf40\n+\n+/* CENA register offsets */\n+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))\n+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))\n+#define QBMAN_CENA_SWP_RCR(n)  (0x400 + ((uint32_t)(n) << 6))\n+#define QBMAN_CENA_SWP_CR      0x600\n+#define QBMAN_CENA_SWP_RR(vb)  (0x700 + ((uint32_t)(vb) >> 1))\n+#define QBMAN_CENA_SWP_VDQCR   0x780\n+#define QBMAN_CENA_SWP_EQCR_CI 0x840\n+\n+/* CENA register offsets in memory-backed mode */\n+#define QBMAN_CENA_SWP_DQRR_MEM(n)  (0x800 + ((uint32_t)(n) << 6))\n+#define QBMAN_CENA_SWP_RCR_MEM(n)   (0x1400 + ((uint32_t)(n) << 6))\n+#define QBMAN_CENA_SWP_CR_MEM       0x1600\n+#define QBMAN_CENA_SWP_RR_MEM       0x1680\n+#define QBMAN_CENA_SWP_VDQCR_MEM    0x1780\n+\n /* Debugging assists */\n static inline void __hexdump(unsigned long start, unsigned long end,\n \t\t\t     unsigned long p, size_t sz, const unsigned char *c)\n@@ -125,8 +165,8 @@ struct qbman_swp_sys {\n \t * place-holder.\n \t */\n \tuint8_t *cena;\n-\tuint8_t __iomem *addr_cena;\n-\tuint8_t __iomem *addr_cinh;\n+\tuint8_t *addr_cena;\n+\tuint8_t *addr_cinh;\n \tuint32_t idx;\n \tenum qbman_eqcr_mode eqcr_mode;\n };\n@@ -292,13 +332,16 @@ static inline void qbman_cena_prefetch(struct qbman_swp_sys *s,\n  * qbman_portal.c. So use of it is declared locally here.\n  */\n #define QBMAN_CINH_SWP_CFG   0xd00\n-#define QBMAN_CINH_SWP_CFG   0xd00\n+\n #define SWP_CFG_DQRR_MF_SHIFT 20\n #define SWP_CFG_EST_SHIFT     16\n+#define SWP_CFG_CPBS_SHIFT    15\n #define SWP_CFG_WN_SHIFT      14\n #define SWP_CFG_RPM_SHIFT     12\n #define SWP_CFG_DCM_SHIFT     10\n #define SWP_CFG_EPM_SHIFT     8\n+#define SWP_CFG_VPM_SHIFT     7\n+#define SWP_CFG_CPM_SHIFT     6\n #define SWP_CFG_SD_SHIFT      5\n #define SWP_CFG_SP_SHIFT      4\n #define SWP_CFG_SE_SHIFT      3\n@@ -329,11 +372,20 @@ static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn,\n \treturn reg;\n }\n \n+#define QMAN_RT_MODE\t0x00000100\n+\n+#define QMAN_REV_4000\t0x04000000\n+#define QMAN_REV_4100\t0x04010000\n+#define QMAN_REV_4101\t0x04010001\n+#define QMAN_REV_5000\t0x05000000\n+#define QMAN_REV_MASK\t0xffff0000\n+\n static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,\n \t\t\t\t     const struct qbman_swp_desc *d,\n \t\t\t\t     uint8_t dqrr_size)\n {\n \tuint32_t reg;\n+\tint i;\n #ifdef RTE_ARCH_64\n \tuint8_t wn = CENA_WRITE_ENABLE;\n #else\n@@ -343,7 +395,7 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,\n \ts->addr_cena = d->cena_bar;\n \ts->addr_cinh = d->cinh_bar;\n \ts->idx = (uint32_t)d->idx;\n-\ts->cena = malloc(4096);\n+\ts->cena = malloc(64*1024);\n \tif (!s->cena) {\n \t\tpr_err(\"Could not allocate page for cena shadow\\n\");\n \t\treturn -1;\n@@ -358,12 +410,34 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,\n \treg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);\n \tQBMAN_BUG_ON(reg);\n #endif\n+\tif ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000)\n+\t\tmemset(s->addr_cena, 0, 64*1024);\n+\telse {\n+\t\t/* Invalidate the portal memory.\n+\t\t * This ensures no stale cache lines\n+\t\t */\n+\t\tfor (i = 0; i < 0x1000; i += 64)\n+\t\t\tdccivac(s->addr_cena + i);\n+\t}\n+\n \tif (s->eqcr_mode == qman_eqcr_vb_array)\n-\t\treg = qbman_set_swp_cfg(dqrr_size, wn, 0, 3, 2, 3, 1, 1, 1, 1,\n-\t\t\t\t\t1, 1);\n-\telse\n-\t\treg = qbman_set_swp_cfg(dqrr_size, wn, 1, 3, 2, 2, 1, 1, 1, 1,\n-\t\t\t\t\t1, 1);\n+\t\treg = qbman_set_swp_cfg(dqrr_size, wn,\n+\t\t\t\t\t0, 3, 2, 3, 1, 1, 1, 1, 1, 1);\n+\telse {\n+\t\tif ((d->qman_version & QMAN_REV_MASK) < QMAN_REV_5000)\n+\t\t\treg = qbman_set_swp_cfg(dqrr_size, wn,\n+\t\t\t\t\t\t1, 3, 2, 2, 1, 1, 1, 1, 1, 1);\n+\t\telse\n+\t\t\treg = qbman_set_swp_cfg(dqrr_size, wn,\n+\t\t\t\t\t\t1, 3, 2, 0, 1, 1, 1, 1, 1, 1);\n+\t}\n+\n+\tif ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) {\n+\t\treg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */\n+\t\t       1 << SWP_CFG_VPM_SHIFT |  /* VDQCR read triggered mode */\n+\t\t       1 << SWP_CFG_CPM_SHIFT;   /* CR read triggered mode */\n+\t}\n+\n \tqbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg);\n \treg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);\n \tif (!reg) {\n@@ -371,6 +445,12 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,\n \t\tfree(s->cena);\n \t\treturn -1;\n \t}\n+\n+\tif ((d->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) {\n+\t\tqbman_cinh_write(s, QBMAN_CINH_SWP_EQCR_PI, QMAN_RT_MODE);\n+\t\tqbman_cinh_write(s, QBMAN_CINH_SWP_RCR_PI, QMAN_RT_MODE);\n+\t}\n+\n \treturn 0;\n }\n \n@@ -378,3 +458,5 @@ static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s)\n {\n \tfree(s->cena);\n }\n+\n+#endif /* _QBMAN_SYS_H_ */\ndiff --git a/drivers/bus/fslmc/qbman/qbman_sys_decl.h b/drivers/bus/fslmc/qbman/qbman_sys_decl.h\nindex fa6977fee..a29f5b469 100644\n--- a/drivers/bus/fslmc/qbman/qbman_sys_decl.h\n+++ b/drivers/bus/fslmc/qbman/qbman_sys_decl.h\n@@ -3,6 +3,9 @@\n  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.\n  *\n  */\n+#ifndef _QBMAN_SYS_DECL_H_\n+#define _QBMAN_SYS_DECL_H_\n+\n #include <compat.h>\n #include <fsl_qbman_base.h>\n \n@@ -51,3 +54,4 @@ static inline void prefetch_for_store(void *p)\n \tRTE_SET_USED(p);\n }\n #endif\n+#endif /* _QBMAN_SYS_DECL_H_ */\n",
    "prefixes": [
        "05/11"
    ]
}