Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/806236/?format=api
{ "id": 806236, "url": "http://patchwork.ozlabs.org/api/patches/806236/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1503839623-3906-3-git-send-email-madalin.bucur@nxp.com/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api", "name": "Linux network development", "link_name": "netdev", "list_id": "netdev.vger.kernel.org", "list_email": "netdev@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1503839623-3906-3-git-send-email-madalin.bucur@nxp.com>", "list_archive_url": null, "date": "2017-08-27T13:13:38", "name": "[v4,2/7] fsl/fman: enable FMan Keygen", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": true, "hash": "71957803e8bb2105d05c2f16aad874598bc92dd7", "submitter": { "id": 70042, "url": "http://patchwork.ozlabs.org/api/people/70042/?format=api", "name": "Madalin Bucur", "email": "madalin.bucur@nxp.com" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1503839623-3906-3-git-send-email-madalin.bucur@nxp.com/mbox/", "series": [ { "id": 20, "url": "http://patchwork.ozlabs.org/api/series/20/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=20", "date": "2017-08-27T13:13:37", "name": "Add RSS to DPAA 1.x Ethernet driver", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/20/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/806236/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/806236/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<netdev-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming@ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "spf=fail (sender IP is 192.88.168.50)\n\tsmtp.mailfrom=nxp.com; vger.kernel.org; dkim=none (message not signed)\n\theader.d=none; vger.kernel.org;\n\tdmarc=fail action=none header.from=nxp.com; " ], "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xgFkt0Ysmz9s7f\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSun, 27 Aug 2017 23:15:34 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751849AbdH0NPR (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tSun, 27 Aug 2017 09:15:17 -0400", "from mail-bn3nam01on0051.outbound.protection.outlook.com\n\t([104.47.33.51]:51968\n\t\"EHLO NAM01-BN3-obe.outbound.protection.outlook.com\"\n\trhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP\n\tid S1751411AbdH0NNw (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tSun, 27 Aug 2017 09:13:52 -0400", "from CY1PR03CA0030.namprd03.prod.outlook.com (2603:10b6:600::40) by\n\tDM2PR03MB559.namprd03.prod.outlook.com (2a01:111:e400:241d::28) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.1385.9;\n\tSun, 27 Aug 2017 13:13:49 +0000", "from BY2FFO11FD013.protection.gbl (2a01:111:f400:7c0c::170) by\n\tCY1PR03CA0030.outlook.office365.com (2603:10b6:600::40) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id\n\t15.1.1385.9 via Frontend Transport; Sun, 27 Aug 2017 13:13:49 +0000", "from tx30smr01.am.freescale.net (192.88.168.50) by\n\tBY2FFO11FD013.mail.protection.outlook.com (10.1.14.75) with Microsoft\n\tSMTP Server (version=TLS1_0,\n\tcipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1341.15\n\tvia Frontend Transport; Sun, 27 Aug 2017 13:13:49 +0000", "from fsr-fed2164-101.ea.freescale.net\n\t(fsr-fed2164-101.ea.freescale.net [10.171.73.197])\n\tby tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id\n\tv7RDDhJk028627; Sun, 27 Aug 2017 06:13:47 -0700" ], "Received-SPF": "Fail (protection.outlook.com: domain of nxp.com does not\n\tdesignate 192.88.168.50 as permitted sender)\n\treceiver=protection.outlook.com; \n\tclient-ip=192.88.168.50; helo=tx30smr01.am.freescale.net;", "From": "Madalin Bucur <madalin.bucur@nxp.com>", "To": "<netdev@vger.kernel.org>, <davem@davemloft.net>", "CC": "<linuxppc-dev@lists.ozlabs.org>, <linux-kernel@vger.kernel.org>", "Subject": "[PATCH v4 2/7] fsl/fman: enable FMan Keygen", "Date": "Sun, 27 Aug 2017 16:13:38 +0300", "Message-ID": "<1503839623-3906-3-git-send-email-madalin.bucur@nxp.com>", "X-Mailer": "git-send-email 2.1.0", "In-Reply-To": "<1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>", "References": "<1503839623-3906-1-git-send-email-madalin.bucur@nxp.com>", "Reply-To": "<madalin.bucur@nxp.com>", "X-EOPAttributedMessage": "0", "X-Matching-Connectors": "131483132291950752;\n\t(91ab9b29-cfa4-454e-5278-08d120cd25b8); ()", "X-Forefront-Antispam-Report": "CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI;\n\tSFV:NSPM;\n\tSFS:(10009020)(6009001)(336005)(39860400002)(39380400002)(2980300002)(1109001)(1110001)(339900001)(189002)(199003)(4326008)(81156014)(68736007)(97736004)(575784001)(77096006)(86362001)(36756003)(5660300001)(106466001)(105606002)(8936002)(3450700001)(81166006)(104016004)(2950100002)(50226002)(85426001)(6666003)(50466002)(8676002)(2906002)(48376002)(53936002)(47776003)(53946003)(356003)(50986999)(54906002)(76176999)(43066003)(305945005)(626005)(498600001)(5003940100001)(33646002)(189998001)(2004002);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:DM2PR03MB559;\n\tH:tx30smr01.am.freescale.net; FPR:; SPF:Fail;\n\tPTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; ", "X-Microsoft-Exchange-Diagnostics": [ "1; BY2FFO11FD013;\n\t1:b8R3bORu3sY4kjSGv/r5W5BZshziR6K5mjb3jOFSD+6VNKsX/Hm3Qenp120R8A37R5gixs4tv/Gawlp0mOSyB7UIwqfSMSl5s8obVgObEA0TzgR5JcsOJdQFDmsz6FX2", "1; DM2PR03MB559;\n\t3:t5xex6cn5+7Vkegy1kFFroF8Y7t1hwTvZjWXEeqyYsi+5dHeLtHydP40XDS1UDGpgYaenUcveFVbAbUDBvLDY+uSkWVou5WQ/gJmaZKGJSZ60eDuU6N6LMNN76m9zE/E+SKHCpgB/e9SyfltVLdVjigQ+Plr3OVIBjFWJAEFH72Tbz9k709kmlnxPSFh2eyfV6Vy3FWeggIetDAgJb31/qLXpVqPs4A9Yk3/I5gvEXgOZN3QP+lZwUKR4SUo90bc5td2Zjxz+IoLMF1dXPIDkbiltT2VIMGUJDLuPK661HNNqXEq8OMzz1ox/C8VUHBJZ4L4feMhzIMjjXb/DTfmxDFvGrdQRX46LbA860FHCPs=;\n\t25:b4g4q3KDNvM0HLmhm9pcb3LnXBeD0QtGs8D0JC8/wOY4n1HM+VJU1QESstOFXimWamixwh/eI+vdmH25KOeER0zJiNYqcQqBIF5kQsskbaFSK1ObqsiFHCaJ8ermEe4KAhFaYyPEi8dDT/j/KD1udbkBr0FXu3h+MisKjYsV6fhqAcYnOia9zHlCVyQ4lOaeU+uDK6T/QUr8i9anxb+pUf90EhjNAfZ4BskgP5qaOWdMz++OMdnVSCMMgSaBsvXFoB7/sl1cUsW2QlnROepkzVU/HeNEpM2T9W8Fiqnu0UbgUldAEFv2WmNY7Eq/GkC3DbQvtwAdMHVIiIlIBY7Y4Q==", "1; DM2PR03MB559;\n\t31:7vXd7BC/EHb+5sHcw2YRbu5GHssN8QdwvEj1wt93LrPIUcLOZ2pGFxHzqVeMXUx9zXs3Idv8G8QWHYpL9yFGBFpJo33LfWdBPAxjvr3OcfgdEtf6pP3zk/QAfu9FT6GGaXc6dP0uEOfMH3elcMRQoeYV8g4UwpYoGsJF9oF5kJeBeFc2YkRIYKc7huhFld/LH92MBuWhK8KboRLD27mXosq6Fq7LitudCH0SS01mTdE=;\n\t4:gw+g40+H1oImM9U9Dv/2MgLq/sO5xJgEf08fKNx7crCL+/QlBlWDi1EGv043rEOQjnwV9CPK9kB3MBhzdw9EagpEyT0ETpkf4s9t934G49YKWMUfW46CUT72pJYqRzXgYOR/+FB99n2c4YZO76IhAlneHfQ2mIiFnZ1OaGBFflmWu4LTSFoET3EuRmp844zboRgs9dPyR6JLDpyuv7q4ycwbZH2AV5CYIlBMxjiTw3h1hiVHVECuX8gYjr2Uqw2gSPYOSlPENLLA67eX6WHGFyUwfCCvNAU0pl3JAf9Q7oE3flWCgzXiX7ItAtvcFB6O2ibN000SXCJ8Zc9cXlICjw==", "1; DM2PR03MB559;\n\t23:LDC+vWRbUvpcQASARwQwYhBmfLXRV5Ao5fymiaGEZL2s/KYVgUPw6wckruZH7SS/SuGWyEK2DH7mvKhUSVoc9eyvXdAhUlhrh7y+8I+GuXC8bsKY8ex7tulWVENLMcso3Nxqutd68RLRG5DyARo56ZEBlSVIS5+iuwOo/WiyDpFMmGsK6iZZkwzdFrY2bWewtje5H4LJCltStQpUOKZ6m7cazL4MN68Xn+SP6LdzBIfZaNIOQLtU+CSMC3mSltqkrxHWPlLP4XYG5huM5EVFDTxbBposXZLPB+J0XK1y7aaGEfyVyif8bVxw03YxeyvBCzZ9i7AcGPxj5WXPiLwFqifVLxizvqqj7OeXMWwam6BDtdV84RP+taPa0BS2W7mu0SPVZGQJMEYeMmHGU2EmW4lnbLirTevc7zgOB+ohnxKu1NaSPcwwDZ9cYIZCiDyNgmTjIvBNkmSje2o2ur9MUWFQbCWbmuzvZNei/ujqxKC3Tw7s06e4oivxZcWdEQKpgLuJW/ML25dRazVV9rgdlvHo2vYMHl+DaBZUxHCtRHxgti21Z1ExSsxjAo/3qXDNdCfS2YQwA+0jY1f79OBg57FycxjKtjOS3BAyWNWV1/raSxhYDXb9s4st8rhlAUrV9edqox+xPZayNI8k4OHaiyIT+k7NAvhtNuubFgJUgK+9BDIwzUY8IHvOMsAayV0YRYSwQU5bpZRgUavfTpaqkC+6TxE2fpe2xpOz8wtlIJq3AdtkqwIZS5wdGNsl6n6+uIeEUwWe4S3jfbO5At3efIKGZiuxCr9QD/ivyszQL9hJ5Nw2wKn9wvNp1YEdzpMUXYv2X9sRCVnNpK9Q8/kyHLdaOBx5H1u/lzShvplY5EwFycVUH3VCdPgsMGs0hO9Yw6E9zASTf5I7IHZyl0+Qv0N7+6QgvqKUaIEQ3rOhgPbpsVIh4hCr1BNn3HOFNAx1Y7ADmPcuyJZY7PqcYK60vj0wCGkQlr/MrUhjv/emxO8l4w/uH8HVMVD0A8GFuLkw+X8wPsAkAU/BOnPE7OJhwgAnzhcUi0WHwngRkLw3WIq9IK0e1hnBC/L7pTmSO4whapTPaPL/U/DEZ9Zhq6XkMpEYaaVs5NWadO4KGQ3R8y6imHio7HmTUXduzwVbQY0DjJygH9d6S8wuYwn8+Yrhtg==", "1; DM2PR03MB559;\n\t6:cmJc4jGH1f+dYcAcfmqrQE8LQNqCmc0iYL41sEzrcUV2bJSW5H2QD1HRN75OykTDeANorrAE0173cT7FnPS0DegrluTrakGXTZnf2LIqYqXNB8ZLrhg06BXyTYtDBfb7hqkcceBf3FcrWeI6SIay6migwyNwsqQQyzzru8A2q/STyNku0yS9HXac+anq0YHq7KwQW8OtExM+/rsSE09NtKs1STieYEaXtrcrhpAXq9ertWAdD0AgdS+F8ugXzjIUEnexWn4TZAd6Y5k0cowaBslRENQxTOkTNVNmdzB2D5nikK9bqgkoa3XRiRUoLAtxJjB+yS/Kw/XJLPqADj/a6g==;\n\t5:m+nYi1jQwlMGvejSB65b8GFo4ZDZZQvpFJ2zfHE5TBAnm1xITufe5ohwaImIWt/Klvhw2FiMUuBKvHGiwV4zqYuL9UM+ynm6+21ITdLtoBMHZe9XQ6JUSJ53G23lMQxe7WA1qTkvQNMYV6PScJ+bEw==;\n\t24:KJxkekI8AQ9I6sHUaD8mkBvi1ULdldizKrDlrVhaKYy0SPojjDm/bNPMVjVVm4bZ9BmI9xsgsjD2WaszLNIaeLlLs56voQ1hmYND04hnv3I=;\n\t7:76MYX4I9SbYsYn83ADcgeupqAHoGyukuS3MoW2XyIeIIxs+dNiGRCHnjkzEkD14qNsL2x1e8NjA1J9dtRSPF7acfWp/O9pZgic+EWe+8Sm90PKQ+lpnnVNhvBsATyl4tggEPOfZhEjDRgi8rpf/nLXURXxT1fbI9ddlrCjVPI5UBwi57DG9Pylz9Sx+ZBoTMWC/wPDP9c/ARfHeysXm19LobMoV+E8hJh58nO9zN+BQ=" ], "MIME-Version": "1.0", "Content-Type": "text/plain", "X-MS-PublicTrafficType": "Email", "X-MS-Office365-Filtering-Correlation-Id": "cb995d57-006f-403a-a8a0-08d4ed4d74ae", "X-Microsoft-Antispam": "UriScan:; BCL:0; PCL:0;\n\tRULEID:(300000500095)(300135000095)(300000501095)(300135300095)(300000502095)(300135100095)(22001)(300000503095)(300135400095)(2017052603199)(201703131430075)(201703131517081)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095);\n\tSRVR:DM2PR03MB559; ", "X-MS-TrafficTypeDiagnostic": "DM2PR03MB559:", "X-Exchange-Antispam-Report-Test": "UriScan:(185117386973197)(788757137089);", "X-Microsoft-Antispam-PRVS": "<DM2PR03MB559B1E5CC5FF0472DFAB462EC990@DM2PR03MB559.namprd03.prod.outlook.com>", "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6095135)(601004)(2401047)(8121501046)(13016025)(13018025)(5005006)(100000703101)(100105400095)(93006095)(93001095)(3002001)(10201501046)(6055026)(6096035)(20161123565025)(20161123561025)(20161123556025)(20161123563025)(201703131430075)(201703131433075)(201703131448075)(201703161259150)(201703151042153)(20161123559100)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);\n\tSRVR:DM2PR03MB559; BCL:0; PCL:0;\n\tRULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(400006)(100000804101)(100110200095)(100000805101)(100110500095);\n\tSRVR:DM2PR03MB559; ", "X-Forefront-PRVS": "0412A98A59", "SpamDiagnosticOutput": "1:99", "SpamDiagnosticMetadata": "NSPM", "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "27 Aug 2017 13:13:49.0078\n\t(UTC)", "X-MS-Exchange-CrossTenant-Id": "5afe0b00-7697-4969-b663-5eab37d5f47e", "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e;\n\tIp=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net]", "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem", "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DM2PR03MB559", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "From: Iordache Florinel-R70177 <florinel.iordache@nxp.com>\n\nAdd support for the FMan Keygen with a hardcoded scheme to spread\nincoming traffic on a FQ range based on source and destination IPs\nand ports.\n\nSigned-off-by: Iordache Florinel <florinel.iordache@nxp.com>\nSigned-off-by: Madalin Bucur <madalin.bucur@nxp.com>\n---\n drivers/net/ethernet/freescale/fman/Makefile | 2 +-\n drivers/net/ethernet/freescale/fman/fman.c | 8 +\n drivers/net/ethernet/freescale/fman/fman.h | 2 +\n drivers/net/ethernet/freescale/fman/fman_keygen.c | 783 ++++++++++++++++++++++\n drivers/net/ethernet/freescale/fman/fman_keygen.h | 46 ++\n drivers/net/ethernet/freescale/fman/fman_port.c | 40 +-\n drivers/net/ethernet/freescale/fman/fman_port.h | 5 +\n 7 files changed, 884 insertions(+), 2 deletions(-)\n create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c\n create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h", "diff": "diff --git a/drivers/net/ethernet/freescale/fman/Makefile b/drivers/net/ethernet/freescale/fman/Makefile\nindex 6049177..2c38119 100644\n--- a/drivers/net/ethernet/freescale/fman/Makefile\n+++ b/drivers/net/ethernet/freescale/fman/Makefile\n@@ -4,6 +4,6 @@ obj-$(CONFIG_FSL_FMAN) += fsl_fman.o\n obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o\n obj-$(CONFIG_FSL_FMAN) += fsl_mac.o\n \n-fsl_fman-objs\t:= fman_muram.o fman.o fman_sp.o\n+fsl_fman-objs\t:= fman_muram.o fman.o fman_sp.o fman_keygen.o\n fsl_fman_port-objs := fman_port.o\n fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o\ndiff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c\nindex 8179cc1..f420dac 100644\n--- a/drivers/net/ethernet/freescale/fman/fman.c\n+++ b/drivers/net/ethernet/freescale/fman/fman.c\n@@ -45,6 +45,7 @@\n \n #include \"fman.h\"\n #include \"fman_muram.h\"\n+#include \"fman_keygen.h\"\n \n /* General defines */\n #define FMAN_LIODN_TBL\t\t\t64\t/* size of LIODN table */\n@@ -56,6 +57,7 @@\n /* Modules registers offsets */\n #define BMI_OFFSET\t\t0x00080000\n #define QMI_OFFSET\t\t0x00080400\n+#define KG_OFFSET\t\t0x000C1000\n #define DMA_OFFSET\t\t0x000C2000\n #define FPM_OFFSET\t\t0x000C3000\n #define IMEM_OFFSET\t\t0x000C4000\n@@ -1737,6 +1739,7 @@ static int fman_config(struct fman *fman)\n \tfman->qmi_regs = base_addr + QMI_OFFSET;\n \tfman->dma_regs = base_addr + DMA_OFFSET;\n \tfman->hwp_regs = base_addr + HWP_OFFSET;\n+\tfman->kg_regs = base_addr + KG_OFFSET;\n \tfman->base_addr = base_addr;\n \n \tspin_lock_init(&fman->spinlock);\n@@ -2009,6 +2012,11 @@ static int fman_init(struct fman *fman)\n \t/* Init HW Parser */\n \thwp_init(fman->hwp_regs);\n \n+\t/* Init KeyGen */\n+\tfman->keygen = keygen_init(fman->kg_regs);\n+\tif (!fman->keygen)\n+\t\treturn -EINVAL;\n+\n \terr = enable(fman, cfg);\n \tif (err != 0)\n \t\treturn err;\ndiff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h\nindex 1015dac..bfa02e0 100644\n--- a/drivers/net/ethernet/freescale/fman/fman.h\n+++ b/drivers/net/ethernet/freescale/fman/fman.h\n@@ -328,6 +328,7 @@ struct fman {\n \tstruct fman_qmi_regs __iomem *qmi_regs;\n \tstruct fman_dma_regs __iomem *dma_regs;\n \tstruct fman_hwp_regs __iomem *hwp_regs;\n+\tstruct fman_kg_regs __iomem *kg_regs;\n \tfman_exceptions_cb *exception_cb;\n \tfman_bus_error_cb *bus_error_cb;\n \t/* Spinlock for FMan use */\n@@ -336,6 +337,7 @@ struct fman {\n \n \tstruct fman_cfg *cfg;\n \tstruct muram_info *muram;\n+\tstruct fman_keygen *keygen;\n \t/* cam section in muram */\n \tunsigned long cam_offset;\n \tsize_t cam_size;\ndiff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.c b/drivers/net/ethernet/freescale/fman/fman_keygen.c\nnew file mode 100644\nindex 0000000..f54da3c\n--- /dev/null\n+++ b/drivers/net/ethernet/freescale/fman/fman_keygen.c\n@@ -0,0 +1,783 @@\n+/*\n+ * Copyright 2017 NXP\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ * * Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * * Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in the\n+ * documentation and/or other materials provided with the distribution.\n+ * * Neither the name of NXP nor the\n+ * names of its contributors may be used to endorse or promote products\n+ * derived from this software without specific prior written permission.\n+ *\n+ *\n+ * ALTERNATIVELY, this software may be distributed under the terms of the\n+ * GNU General Public License (\"GPL\") as published by the Free Software\n+ * Foundation, either version 2 of that License or (at your option) any\n+ * later version.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY NXP ``AS IS'' AND ANY\n+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n+ * DISCLAIMED. IN NO EVENT SHALL NXP BE LIABLE FOR ANY\n+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#define pr_fmt(fmt) KBUILD_MODNAME \": \" fmt\n+\n+#include <linux/slab.h>\n+\n+#include \"fman_keygen.h\"\n+\n+/* Maximum number of HW Ports */\n+#define FMAN_MAX_NUM_OF_HW_PORTS\t\t64\n+\n+/* Maximum number of KeyGen Schemes */\n+#define FM_KG_MAX_NUM_OF_SCHEMES\t\t32\n+\n+/* Number of generic KeyGen Generic Extract Command Registers */\n+#define FM_KG_NUM_OF_GENERIC_REGS\t\t8\n+\n+/* Dummy port ID */\n+#define DUMMY_PORT_ID\t\t\t\t0\n+\n+/* Select Scheme Value Register */\n+#define KG_SCH_DEF_USE_KGSE_DV_0\t\t2\n+#define KG_SCH_DEF_USE_KGSE_DV_1\t\t3\n+\n+/* Registers Shifting values */\n+#define FM_KG_KGAR_NUM_SHIFT\t\t\t16\n+#define KG_SCH_DEF_L4_PORT_SHIFT\t\t8\n+#define KG_SCH_DEF_IP_ADDR_SHIFT\t\t18\n+#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT\t\t24\n+\n+/* KeyGen Registers bit field masks: */\n+\n+/* Enable bit field mask for KeyGen General Configuration Register */\n+#define FM_KG_KGGCR_EN\t\t\t\t0x80000000\n+\n+/* KeyGen Global Registers bit field masks */\n+#define FM_KG_KGAR_GO\t\t\t\t0x80000000\n+#define FM_KG_KGAR_READ\t\t\t\t0x40000000\n+#define FM_KG_KGAR_WRITE\t\t\t0x00000000\n+#define FM_KG_KGAR_SEL_SCHEME_ENTRY\t\t0x00000000\n+#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT\t\t0x00008000\n+\n+#define FM_KG_KGAR_ERR\t\t\t\t0x20000000\n+#define FM_KG_KGAR_SEL_CLS_PLAN_ENTRY\t\t0x01000000\n+#define FM_KG_KGAR_SEL_PORT_ENTRY\t\t0x02000000\n+#define FM_KG_KGAR_SEL_PORT_WSEL_SP\t\t0x00008000\n+#define FM_KG_KGAR_SEL_PORT_WSEL_CPP\t\t0x00004000\n+\n+/* Error events exceptions */\n+#define FM_EX_KG_DOUBLE_ECC\t\t\t0x80000000\n+#define FM_EX_KG_KEYSIZE_OVERFLOW\t\t0x40000000\n+\n+/* Scheme Registers bit field masks */\n+#define KG_SCH_MODE_EN\t\t\t\t0x80000000\n+#define KG_SCH_VSP_NO_KSP_EN\t\t\t0x80000000\n+#define KG_SCH_HASH_CONFIG_SYM\t\t\t0x40000000\n+\n+/* Known Protocol field codes */\n+#define KG_SCH_KN_PORT_ID\t\t0x80000000\n+#define KG_SCH_KN_MACDST\t\t0x40000000\n+#define KG_SCH_KN_MACSRC\t\t0x20000000\n+#define KG_SCH_KN_TCI1\t\t\t0x10000000\n+#define KG_SCH_KN_TCI2\t\t\t0x08000000\n+#define KG_SCH_KN_ETYPE\t\t\t0x04000000\n+#define KG_SCH_KN_PPPSID\t\t0x02000000\n+#define KG_SCH_KN_PPPID\t\t\t0x01000000\n+#define KG_SCH_KN_MPLS1\t\t\t0x00800000\n+#define KG_SCH_KN_MPLS2\t\t\t0x00400000\n+#define KG_SCH_KN_MPLS_LAST\t\t0x00200000\n+#define KG_SCH_KN_IPSRC1\t\t0x00100000\n+#define KG_SCH_KN_IPDST1\t\t0x00080000\n+#define KG_SCH_KN_PTYPE1\t\t0x00040000\n+#define KG_SCH_KN_IPTOS_TC1\t\t0x00020000\n+#define KG_SCH_KN_IPV6FL1\t\t0x00010000\n+#define KG_SCH_KN_IPSRC2\t\t0x00008000\n+#define KG_SCH_KN_IPDST2\t\t0x00004000\n+#define KG_SCH_KN_PTYPE2\t\t0x00002000\n+#define KG_SCH_KN_IPTOS_TC2\t\t0x00001000\n+#define KG_SCH_KN_IPV6FL2\t\t0x00000800\n+#define KG_SCH_KN_GREPTYPE\t\t0x00000400\n+#define KG_SCH_KN_IPSEC_SPI\t\t0x00000200\n+#define KG_SCH_KN_IPSEC_NH\t\t0x00000100\n+#define KG_SCH_KN_IPPID\t\t\t0x00000080\n+#define KG_SCH_KN_L4PSRC\t\t0x00000004\n+#define KG_SCH_KN_L4PDST\t\t0x00000002\n+#define KG_SCH_KN_TFLG\t\t\t0x00000001\n+\n+/* NIA values */\n+#define NIA_ENG_BMI\t\t\t0x00500000\n+#define NIA_BMI_AC_ENQ_FRAME\t\t0x00000002\n+#define ENQUEUE_KG_DFLT_NIA\t\t(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)\n+\n+/* Hard-coded configuration:\n+ * These values are used as hard-coded values for KeyGen configuration\n+ * and they replace user selections for this hard-coded version\n+ */\n+\n+/* Hash distribution shift */\n+#define DEFAULT_HASH_DIST_FQID_SHIFT\t\t0\n+\n+/* Hash shift */\n+#define DEFAULT_HASH_SHIFT\t\t\t0\n+\n+/* Symmetric hash usage:\n+ * Warning:\n+ * - the value for symmetric hash usage must be in accordance with hash\n+ *\tkey defined below\n+ * - according to tests performed, spreading is not working if symmetric\n+ *\thash is set on true\n+ * So ultimately symmetric hash functionality should be always disabled:\n+ */\n+#define DEFAULT_SYMMETRIC_HASH\t\t\tfalse\n+\n+/* Hash Key extraction fields: */\n+#define DEFAULT_HASH_KEY_EXTRACT_FIELDS\t\t\\\n+\t(KG_SCH_KN_IPSRC1 | KG_SCH_KN_IPDST1 | \\\n+\t KG_SCH_KN_L4PSRC | KG_SCH_KN_L4PDST)\n+\n+/* Default values to be used as hash key in case IPv4 or L4 (TCP, UDP)\n+ * don't exist in the frame\n+ */\n+/* Default IPv4 address */\n+#define DEFAULT_HASH_KEY_IPv4_ADDR\t\t0x0A0A0A0A\n+/* Default L4 port */\n+#define DEFAULT_HASH_KEY_L4_PORT\t\t0x0B0B0B0B\n+\n+/* KeyGen Memory Mapped Registers: */\n+\n+/* Scheme Configuration RAM Registers */\n+struct fman_kg_scheme_regs {\n+\tu32 kgse_mode;\t\t/* 0x100: MODE */\n+\tu32 kgse_ekfc;\t\t/* 0x104: Extract Known Fields Command */\n+\tu32 kgse_ekdv;\t\t/* 0x108: Extract Known Default Value */\n+\tu32 kgse_bmch;\t\t/* 0x10C: Bit Mask Command High */\n+\tu32 kgse_bmcl;\t\t/* 0x110: Bit Mask Command Low */\n+\tu32 kgse_fqb;\t\t/* 0x114: Frame Queue Base */\n+\tu32 kgse_hc;\t\t/* 0x118: Hash Command */\n+\tu32 kgse_ppc;\t\t/* 0x11C: Policer Profile Command */\n+\tu32 kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];\n+\t\t\t/* 0x120: Generic Extract Command */\n+\tu32 kgse_spc;\n+\t\t/* 0x140: KeyGen Scheme Entry Statistic Packet Counter */\n+\tu32 kgse_dv0;\t/* 0x144: KeyGen Scheme Entry Default Value 0 */\n+\tu32 kgse_dv1;\t/* 0x148: KeyGen Scheme Entry Default Value 1 */\n+\tu32 kgse_ccbs;\n+\t\t/* 0x14C: KeyGen Scheme Entry Coarse Classification Bit*/\n+\tu32 kgse_mv;\t/* 0x150: KeyGen Scheme Entry Match vector */\n+\tu32 kgse_om;\t/* 0x154: KeyGen Scheme Entry Operation Mode bits */\n+\tu32 kgse_vsp;\n+\t\t/* 0x158: KeyGen Scheme Entry Virtual Storage Profile */\n+};\n+\n+/* Port Partition Configuration Registers */\n+struct fman_kg_pe_regs {\n+\tu32 fmkg_pe_sp;\t\t/* 0x100: KeyGen Port entry Scheme Partition */\n+\tu32 fmkg_pe_cpp;\n+\t\t/* 0x104: KeyGen Port Entry Classification Plan Partition */\n+};\n+\n+/* General Configuration and Status Registers\n+ * Global Statistic Counters\n+ * KeyGen Global Registers\n+ */\n+struct fman_kg_regs {\n+\tu32 fmkg_gcr;\t/* 0x000: KeyGen General Configuration Register */\n+\tu32 res004;\t/* 0x004: Reserved */\n+\tu32 res008;\t/* 0x008: Reserved */\n+\tu32 fmkg_eer;\t/* 0x00C: KeyGen Error Event Register */\n+\tu32 fmkg_eeer;\t/* 0x010: KeyGen Error Event Enable Register */\n+\tu32 res014;\t/* 0x014: Reserved */\n+\tu32 res018;\t/* 0x018: Reserved */\n+\tu32 fmkg_seer;\t/* 0x01C: KeyGen Scheme Error Event Register */\n+\tu32 fmkg_seeer;\t/* 0x020: KeyGen Scheme Error Event Enable Register */\n+\tu32 fmkg_gsr;\t/* 0x024: KeyGen Global Status Register */\n+\tu32 fmkg_tpc;\t/* 0x028: Total Packet Counter Register */\n+\tu32 fmkg_serc;\t/* 0x02C: Soft Error Capture Register */\n+\tu32 res030[4];\t/* 0x030: Reserved */\n+\tu32 fmkg_fdor;\t/* 0x034: Frame Data Offset Register */\n+\tu32 fmkg_gdv0r;\t/* 0x038: Global Default Value Register 0 */\n+\tu32 fmkg_gdv1r;\t/* 0x03C: Global Default Value Register 1 */\n+\tu32 res04c[6];\t/* 0x040: Reserved */\n+\tu32 fmkg_feer;\t/* 0x044: Force Error Event Register */\n+\tu32 res068[38];\t/* 0x048: Reserved */\n+\tunion {\n+\t\tu32 fmkg_indirect[63];\t/* 0x100: Indirect Access Registers */\n+\t\tstruct fman_kg_scheme_regs fmkg_sch; /* Scheme Registers */\n+\t\tstruct fman_kg_pe_regs fmkg_pe; /* Port Partition Registers */\n+\t};\n+\tu32 fmkg_ar;\t/* 0x1FC: KeyGen Action Register */\n+};\n+\n+/* KeyGen Scheme data */\n+struct keygen_scheme {\n+\tbool used;\t/* Specifies if this scheme is used */\n+\tu8 hw_port_id;\n+\t\t/* Hardware port ID\n+\t\t * schemes sharing between multiple ports is not\n+\t\t * currently supported\n+\t\t * so we have only one port id bound to a scheme\n+\t\t */\n+\tu32 base_fqid;\n+\t\t/* Base FQID:\n+\t\t * Must be between 1 and 2^24-1\n+\t\t * If hash is used and an even distribution is\n+\t\t * expected according to hash_fqid_count,\n+\t\t * base_fqid must be aligned to hash_fqid_count\n+\t\t */\n+\tu32 hash_fqid_count;\n+\t\t/* FQ range for hash distribution:\n+\t\t * Must be a power of 2\n+\t\t * Represents the range of queues for spreading\n+\t\t */\n+\tbool use_hashing;\t/* Usage of Hashing and spreading over FQ */\n+\tbool symmetric_hash;\t/* Symmetric Hash option usage */\n+\tu8 hashShift;\n+\t\t/* Hash result right shift.\n+\t\t * Select the 24 bits out of the 64 hash result.\n+\t\t * 0 means using the 24 LSB's, otherwise\n+\t\t * use the 24 LSB's after shifting right\n+\t\t */\n+\tu32 match_vector;\t/* Match Vector */\n+};\n+\n+/* KeyGen driver data */\n+struct fman_keygen {\n+\tstruct keygen_scheme schemes[FM_KG_MAX_NUM_OF_SCHEMES];\n+\t\t\t\t/* Array of schemes */\n+\tstruct fman_kg_regs __iomem *keygen_regs;\t/* KeyGen registers */\n+};\n+\n+/* keygen_write_ar_wait\n+ *\n+ * Write Action Register with specified value, wait for GO bit field to be\n+ * idle and then read the error\n+ *\n+ * regs: KeyGen registers\n+ * fmkg_ar: Action Register value\n+ *\n+ * Return: Zero for success or error code in case of failure\n+ */\n+static int keygen_write_ar_wait(struct fman_kg_regs __iomem *regs, u32 fmkg_ar)\n+{\n+\tiowrite32be(fmkg_ar, ®s->fmkg_ar);\n+\n+\t/* Wait for GO bit field to be idle */\n+\twhile (fmkg_ar & FM_KG_KGAR_GO)\n+\t\tfmkg_ar = ioread32be(®s->fmkg_ar);\n+\n+\tif (fmkg_ar & FM_KG_KGAR_ERR)\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n+/* build_ar_scheme\n+ *\n+ * Build Action Register value for scheme settings\n+ *\n+ * scheme_id: Scheme ID\n+ * update_counter: update scheme counter\n+ * write: true for action to write the scheme or false for read action\n+ *\n+ * Return: AR value\n+ */\n+static u32 build_ar_scheme(u8 scheme_id, bool update_counter, bool write)\n+{\n+\tu32 rw = (u32)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);\n+\n+\treturn (u32)(FM_KG_KGAR_GO |\n+\t\t\trw |\n+\t\t\tFM_KG_KGAR_SEL_SCHEME_ENTRY |\n+\t\t\tDUMMY_PORT_ID |\n+\t\t\t((u32)scheme_id << FM_KG_KGAR_NUM_SHIFT) |\n+\t\t\t(update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));\n+}\n+\n+/* build_ar_bind_scheme\n+ *\n+ * Build Action Register value for port binding to schemes\n+ *\n+ * hwport_id: HW Port ID\n+ * write: true for action to write the bind or false for read action\n+ *\n+ * Return: AR value\n+ */\n+static u32 build_ar_bind_scheme(u8 hwport_id, bool write)\n+{\n+\tu32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;\n+\n+\treturn (u32)(FM_KG_KGAR_GO |\n+\t\t\trw |\n+\t\t\tFM_KG_KGAR_SEL_PORT_ENTRY |\n+\t\t\thwport_id |\n+\t\t\tFM_KG_KGAR_SEL_PORT_WSEL_SP);\n+}\n+\n+/* keygen_write_sp\n+ *\n+ * Write Scheme Partition Register with specified value\n+ *\n+ * regs: KeyGen Registers\n+ * sp: Scheme Partition register value\n+ * add: true to add a scheme partition or false to clear\n+ *\n+ * Return: none\n+ */\n+static void keygen_write_sp(struct fman_kg_regs __iomem *regs, u32 sp, bool add)\n+{\n+\tu32 tmp;\n+\n+\ttmp = ioread32be(®s->fmkg_pe.fmkg_pe_sp);\n+\n+\tif (add)\n+\t\ttmp |= sp;\n+\telse\n+\t\ttmp &= ~sp;\n+\n+\tiowrite32be(tmp, ®s->fmkg_pe.fmkg_pe_sp);\n+}\n+\n+/* build_ar_bind_cls_plan\n+ *\n+ * Build Action Register value for Classification Plan\n+ *\n+ * hwport_id: HW Port ID\n+ * write: true for action to write the CP or false for read action\n+ *\n+ * Return: AR value\n+ */\n+static u32 build_ar_bind_cls_plan(u8 hwport_id, bool write)\n+{\n+\tu32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;\n+\n+\treturn (u32)(FM_KG_KGAR_GO |\n+\t\t\trw |\n+\t\t\tFM_KG_KGAR_SEL_PORT_ENTRY |\n+\t\t\thwport_id |\n+\t\t\tFM_KG_KGAR_SEL_PORT_WSEL_CPP);\n+}\n+\n+/* keygen_write_cpp\n+ *\n+ * Write Classification Plan Partition Register with specified value\n+ *\n+ * regs: KeyGen Registers\n+ * cpp: CPP register value\n+ *\n+ * Return: none\n+ */\n+static void keygen_write_cpp(struct fman_kg_regs __iomem *regs, u32 cpp)\n+{\n+\tiowrite32be(cpp, ®s->fmkg_pe.fmkg_pe_cpp);\n+}\n+\n+/* keygen_write_scheme\n+ *\n+ * Write all Schemes Registers with specified values\n+ *\n+ * regs: KeyGen Registers\n+ * scheme_id: Scheme ID\n+ * scheme_regs: Scheme registers values desired to be written\n+ * update_counter: update scheme counter\n+ *\n+ * Return: Zero for success or error code in case of failure\n+ */\n+static int keygen_write_scheme(struct fman_kg_regs __iomem *regs, u8 scheme_id,\n+\t\t\t struct fman_kg_scheme_regs *scheme_regs,\n+\t\t\t\tbool update_counter)\n+{\n+\tu32 ar_reg;\n+\tint err, i;\n+\n+\t/* Write indirect scheme registers */\n+\tiowrite32be(scheme_regs->kgse_mode, ®s->fmkg_sch.kgse_mode);\n+\tiowrite32be(scheme_regs->kgse_ekfc, ®s->fmkg_sch.kgse_ekfc);\n+\tiowrite32be(scheme_regs->kgse_ekdv, ®s->fmkg_sch.kgse_ekdv);\n+\tiowrite32be(scheme_regs->kgse_bmch, ®s->fmkg_sch.kgse_bmch);\n+\tiowrite32be(scheme_regs->kgse_bmcl, ®s->fmkg_sch.kgse_bmcl);\n+\tiowrite32be(scheme_regs->kgse_fqb, ®s->fmkg_sch.kgse_fqb);\n+\tiowrite32be(scheme_regs->kgse_hc, ®s->fmkg_sch.kgse_hc);\n+\tiowrite32be(scheme_regs->kgse_ppc, ®s->fmkg_sch.kgse_ppc);\n+\tiowrite32be(scheme_regs->kgse_spc, ®s->fmkg_sch.kgse_spc);\n+\tiowrite32be(scheme_regs->kgse_dv0, ®s->fmkg_sch.kgse_dv0);\n+\tiowrite32be(scheme_regs->kgse_dv1, ®s->fmkg_sch.kgse_dv1);\n+\tiowrite32be(scheme_regs->kgse_ccbs, ®s->fmkg_sch.kgse_ccbs);\n+\tiowrite32be(scheme_regs->kgse_mv, ®s->fmkg_sch.kgse_mv);\n+\tiowrite32be(scheme_regs->kgse_om, ®s->fmkg_sch.kgse_om);\n+\tiowrite32be(scheme_regs->kgse_vsp, ®s->fmkg_sch.kgse_vsp);\n+\n+\tfor (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)\n+\t\tiowrite32be(scheme_regs->kgse_gec[i],\n+\t\t\t ®s->fmkg_sch.kgse_gec[i]);\n+\n+\t/* Write AR (Action register) */\n+\tar_reg = build_ar_scheme(scheme_id, update_counter, true);\n+\terr = keygen_write_ar_wait(regs, ar_reg);\n+\tif (err != 0) {\n+\t\tpr_err(\"Writing Action Register failed\\n\");\n+\t\treturn err;\n+\t}\n+\n+\treturn err;\n+}\n+\n+/* get_free_scheme_id\n+ *\n+ * Find the first free scheme available to be used\n+ *\n+ * keygen: KeyGen handle\n+ * scheme_id: pointer to scheme id\n+ *\n+ * Return: 0 on success, -EINVAL when the are no available free schemes\n+ */\n+static int get_free_scheme_id(struct fman_keygen *keygen, u8 *scheme_id)\n+{\n+\tu8 i;\n+\n+\tfor (i = 0; i < FM_KG_MAX_NUM_OF_SCHEMES; i++)\n+\t\tif (!keygen->schemes[i].used) {\n+\t\t\t*scheme_id = i;\n+\t\t\treturn 0;\n+\t\t}\n+\n+\treturn -EINVAL;\n+}\n+\n+/* get_scheme\n+ *\n+ * Provides the scheme for specified ID\n+ *\n+ * keygen: KeyGen handle\n+ * scheme_id: Scheme ID\n+ *\n+ * Return: handle to required scheme\n+ */\n+static struct keygen_scheme *get_scheme(struct fman_keygen *keygen,\n+\t\t\t\t\tu8 scheme_id)\n+{\n+\tif (scheme_id >= FM_KG_MAX_NUM_OF_SCHEMES)\n+\t\treturn NULL;\n+\treturn &keygen->schemes[scheme_id];\n+}\n+\n+/* keygen_bind_port_to_schemes\n+ *\n+ * Bind the port to schemes\n+ *\n+ * keygen: KeyGen handle\n+ * scheme_id: id of the scheme to bind to\n+ * bind: true to bind the port or false to unbind it\n+ *\n+ * Return: Zero for success or error code in case of failure\n+ */\n+static int keygen_bind_port_to_schemes(struct fman_keygen *keygen,\n+\t\t\t\t u8 scheme_id,\n+\t\t\t\t\tbool bind)\n+{\n+\tstruct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;\n+\tstruct keygen_scheme *scheme;\n+\tu32 ar_reg;\n+\tu32 schemes_vector = 0;\n+\tint err;\n+\n+\tscheme = get_scheme(keygen, scheme_id);\n+\tif (!scheme) {\n+\t\tpr_err(\"Requested Scheme does not exist\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (!scheme->used) {\n+\t\tpr_err(\"Cannot bind port to an invalid scheme\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tschemes_vector |= 1 << (31 - scheme_id);\n+\n+\tar_reg = build_ar_bind_scheme(scheme->hw_port_id, false);\n+\terr = keygen_write_ar_wait(keygen_regs, ar_reg);\n+\tif (err != 0) {\n+\t\tpr_err(\"Reading Action Register failed\\n\");\n+\t\treturn err;\n+\t}\n+\n+\tkeygen_write_sp(keygen_regs, schemes_vector, bind);\n+\n+\tar_reg = build_ar_bind_scheme(scheme->hw_port_id, true);\n+\terr = keygen_write_ar_wait(keygen_regs, ar_reg);\n+\tif (err != 0) {\n+\t\tpr_err(\"Writing Action Register failed\\n\");\n+\t\treturn err;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* keygen_scheme_setup\n+ *\n+ * Setup the scheme according to required configuration\n+ *\n+ * keygen: KeyGen handle\n+ * scheme_id: scheme ID\n+ * enable: true to enable scheme or false to disable it\n+ *\n+ * Return: Zero for success or error code in case of failure\n+ */\n+static int keygen_scheme_setup(struct fman_keygen *keygen, u8 scheme_id,\n+\t\t\t bool enable)\n+{\n+\tstruct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;\n+\tstruct fman_kg_scheme_regs scheme_regs;\n+\tstruct keygen_scheme *scheme;\n+\tu32 tmp_reg;\n+\tint err;\n+\n+\tscheme = get_scheme(keygen, scheme_id);\n+\tif (!scheme) {\n+\t\tpr_err(\"Requested Scheme does not exist\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (enable && scheme->used) {\n+\t\tpr_err(\"The requested Scheme is already used\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Clear scheme registers */\n+\tmemset(&scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));\n+\n+\t/* Setup all scheme registers: */\n+\ttmp_reg = 0;\n+\n+\tif (enable) {\n+\t\t/* Enable Scheme */\n+\t\ttmp_reg |= KG_SCH_MODE_EN;\n+\t\t/* Enqueue frame NIA */\n+\t\ttmp_reg |= ENQUEUE_KG_DFLT_NIA;\n+\t}\n+\n+\tscheme_regs.kgse_mode = tmp_reg;\n+\n+\tscheme_regs.kgse_mv = scheme->match_vector;\n+\n+\t/* Scheme don't override StorageProfile:\n+\t * valid only for DPAA_VERSION >= 11\n+\t */\n+\tscheme_regs.kgse_vsp = KG_SCH_VSP_NO_KSP_EN;\n+\n+\t/* Configure Hard-Coded Rx Hashing: */\n+\n+\tif (scheme->use_hashing) {\n+\t\t/* configure kgse_ekfc */\n+\t\tscheme_regs.kgse_ekfc = DEFAULT_HASH_KEY_EXTRACT_FIELDS;\n+\n+\t\t/* configure kgse_ekdv */\n+\t\ttmp_reg = 0;\n+\t\ttmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_0 <<\n+\t\t\t\tKG_SCH_DEF_IP_ADDR_SHIFT);\n+\t\ttmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_1 <<\n+\t\t\t\tKG_SCH_DEF_L4_PORT_SHIFT);\n+\t\tscheme_regs.kgse_ekdv = tmp_reg;\n+\n+\t\t/* configure kgse_dv0 */\n+\t\tscheme_regs.kgse_dv0 = DEFAULT_HASH_KEY_IPv4_ADDR;\n+\t\t/* configure kgse_dv1 */\n+\t\tscheme_regs.kgse_dv1 = DEFAULT_HASH_KEY_L4_PORT;\n+\n+\t\t/* configure kgse_hc */\n+\t\ttmp_reg = 0;\n+\t\ttmp_reg |= ((scheme->hash_fqid_count - 1) <<\n+\t\t\t\tDEFAULT_HASH_DIST_FQID_SHIFT);\n+\t\ttmp_reg |= scheme->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;\n+\n+\t\tif (scheme->symmetric_hash) {\n+\t\t\t/* Normally extraction key should be verified if\n+\t\t\t * complies with symmetric hash\n+\t\t\t * But because extraction is hard-coded, we are sure\n+\t\t\t * the key is symmetric\n+\t\t\t */\n+\t\t\ttmp_reg |= KG_SCH_HASH_CONFIG_SYM;\n+\t\t}\n+\t\tscheme_regs.kgse_hc = tmp_reg;\n+\t} else {\n+\t\tscheme_regs.kgse_ekfc = 0;\n+\t\tscheme_regs.kgse_hc = 0;\n+\t\tscheme_regs.kgse_ekdv = 0;\n+\t\tscheme_regs.kgse_dv0 = 0;\n+\t\tscheme_regs.kgse_dv1 = 0;\n+\t}\n+\n+\t/* configure kgse_fqb: Scheme FQID base */\n+\ttmp_reg = 0;\n+\ttmp_reg |= scheme->base_fqid;\n+\tscheme_regs.kgse_fqb = tmp_reg;\n+\n+\t/* features not used by hard-coded configuration */\n+\tscheme_regs.kgse_bmch = 0;\n+\tscheme_regs.kgse_bmcl = 0;\n+\tscheme_regs.kgse_spc = 0;\n+\n+\t/* Write scheme registers */\n+\terr = keygen_write_scheme(keygen_regs, scheme_id, &scheme_regs, true);\n+\tif (err != 0) {\n+\t\tpr_err(\"Writing scheme registers failed\\n\");\n+\t\treturn err;\n+\t}\n+\n+\t/* Update used field for Scheme */\n+\tscheme->used = enable;\n+\n+\treturn 0;\n+}\n+\n+/* keygen_init\n+ *\n+ * KeyGen initialization:\n+ * Initializes and enables KeyGen, allocate driver memory, setup registers,\n+ * clear port bindings, invalidate all schemes\n+ *\n+ * keygen_regs: KeyGen registers base address\n+ *\n+ * Return: Handle to KeyGen driver\n+ */\n+struct fman_keygen *keygen_init(struct fman_kg_regs __iomem *keygen_regs)\n+{\n+\tstruct fman_keygen *keygen;\n+\tu32 ar;\n+\tint i;\n+\n+\t/* Allocate memory for KeyGen driver */\n+\tkeygen = kzalloc(sizeof(*keygen), GFP_KERNEL);\n+\tif (!keygen)\n+\t\treturn NULL;\n+\n+\tkeygen->keygen_regs = keygen_regs;\n+\n+\t/* KeyGen initialization (for Master partition):\n+\t * Setup KeyGen registers\n+\t */\n+\tiowrite32be(ENQUEUE_KG_DFLT_NIA, &keygen_regs->fmkg_gcr);\n+\n+\tiowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,\n+\t\t &keygen_regs->fmkg_eer);\n+\n+\tiowrite32be(0, &keygen_regs->fmkg_fdor);\n+\tiowrite32be(0, &keygen_regs->fmkg_gdv0r);\n+\tiowrite32be(0, &keygen_regs->fmkg_gdv1r);\n+\n+\t/* Clear binding between ports to schemes and classification plans\n+\t * so that all ports are not bound to any scheme/classification plan\n+\t */\n+\tfor (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {\n+\t\t/* Clear all pe sp schemes registers */\n+\t\tkeygen_write_sp(keygen_regs, 0xffffffff, false);\n+\t\tar = build_ar_bind_scheme(i, true);\n+\t\tkeygen_write_ar_wait(keygen_regs, ar);\n+\n+\t\t/* Clear all pe cpp classification plans registers */\n+\t\tkeygen_write_cpp(keygen_regs, 0);\n+\t\tar = build_ar_bind_cls_plan(i, true);\n+\t\tkeygen_write_ar_wait(keygen_regs, ar);\n+\t}\n+\n+\t/* Enable all scheme interrupts */\n+\tiowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seer);\n+\tiowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seeer);\n+\n+\t/* Enable KyeGen */\n+\tiowrite32be(ioread32be(&keygen_regs->fmkg_gcr) | FM_KG_KGGCR_EN,\n+\t\t &keygen_regs->fmkg_gcr);\n+\n+\treturn keygen;\n+}\n+EXPORT_SYMBOL(keygen_init);\n+\n+/* keygen_port_hashing_init\n+ *\n+ * Initializes a port for Rx Hashing with specified configuration parameters\n+ *\n+ * keygen: KeyGen handle\n+ * hw_port_id: HW Port ID\n+ * hash_base_fqid: Hashing Base FQID used for spreading\n+ * hash_size: Hashing size\n+ *\n+ * Return: Zero for success or error code in case of failure\n+ */\n+int keygen_port_hashing_init(struct fman_keygen *keygen, u8 hw_port_id,\n+\t\t\t u32 hash_base_fqid, u32 hash_size)\n+{\n+\tstruct keygen_scheme *scheme;\n+\tu8 scheme_id;\n+\tint err;\n+\n+\t/* Validate Scheme configuration parameters */\n+\tif (hash_base_fqid == 0 || (hash_base_fqid & ~0x00FFFFFF)) {\n+\t\tpr_err(\"Base FQID must be between 1 and 2^24-1\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (hash_size == 0 || (hash_size & (hash_size - 1)) != 0) {\n+\t\tpr_err(\"Hash size must be power of two\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Find a free scheme */\n+\terr = get_free_scheme_id(keygen, &scheme_id);\n+\tif (err) {\n+\t\tpr_err(\"The maximum number of available Schemes has been exceeded\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Create and configure Hard-Coded Scheme: */\n+\n+\tscheme = get_scheme(keygen, scheme_id);\n+\tif (!scheme) {\n+\t\tpr_err(\"Requested Scheme does not exist\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (scheme->used) {\n+\t\tpr_err(\"The requested Scheme is already used\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Clear all scheme fields because the scheme may have been\n+\t * previously used\n+\t */\n+\tmemset(scheme, 0, sizeof(struct keygen_scheme));\n+\n+\t/* Setup scheme: */\n+\tscheme->hw_port_id = hw_port_id;\n+\tscheme->use_hashing = true;\n+\tscheme->base_fqid = hash_base_fqid;\n+\tscheme->hash_fqid_count = hash_size;\n+\tscheme->symmetric_hash = DEFAULT_SYMMETRIC_HASH;\n+\tscheme->hashShift = DEFAULT_HASH_SHIFT;\n+\n+\t/* All Schemes in hard-coded configuration\n+\t * are Indirect Schemes\n+\t */\n+\tscheme->match_vector = 0;\n+\n+\terr = keygen_scheme_setup(keygen, scheme_id, true);\n+\tif (err != 0) {\n+\t\tpr_err(\"Scheme setup failed\\n\");\n+\t\treturn err;\n+\t}\n+\n+\t/* Bind Rx port to Scheme */\n+\terr = keygen_bind_port_to_schemes(keygen, scheme_id, true);\n+\tif (err != 0) {\n+\t\tpr_err(\"Binding port to schemes failed\\n\");\n+\t\treturn err;\n+\t}\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL(keygen_port_hashing_init);\ndiff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.h b/drivers/net/ethernet/freescale/fman/fman_keygen.h\nnew file mode 100644\nindex 0000000..c4640de\n--- /dev/null\n+++ b/drivers/net/ethernet/freescale/fman/fman_keygen.h\n@@ -0,0 +1,46 @@\n+/*\n+ * Copyright 2017 NXP\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ * * Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * * Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in the\n+ * documentation and/or other materials provided with the distribution.\n+ * * Neither the name of NXP nor the\n+ * names of its contributors may be used to endorse or promote products\n+ * derived from this software without specific prior written permission.\n+ *\n+ *\n+ * ALTERNATIVELY, this software may be distributed under the terms of the\n+ * GNU General Public License (\"GPL\") as published by the Free Software\n+ * Foundation, either version 2 of that License or (at your option) any\n+ * later version.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY NXP ``AS IS'' AND ANY\n+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n+ * DISCLAIMED. IN NO EVENT SHALL NXP BE LIABLE FOR ANY\n+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef __KEYGEN_H\n+#define __KEYGEN_H\n+\n+#include <linux/io.h>\n+\n+struct fman_keygen;\n+struct fman_kg_regs;\n+\n+struct fman_keygen *keygen_init(struct fman_kg_regs __iomem *keygen_regs);\n+\n+int keygen_port_hashing_init(struct fman_keygen *keygen, u8 hw_port_id,\n+\t\t\t u32 hash_base_fqid, u32 hash_size);\n+\n+#endif /* __KEYGEN_H */\ndiff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c\nindex d51e6aa..f571b3c 100644\n--- a/drivers/net/ethernet/freescale/fman/fman_port.c\n+++ b/drivers/net/ethernet/freescale/fman/fman_port.c\n@@ -44,6 +44,7 @@\n #include \"fman.h\"\n #include \"fman_port.h\"\n #include \"fman_sp.h\"\n+#include \"fman_keygen.h\"\n \n /* Queue ID */\n #define DFLT_FQ_ID\t\t0x00FFFFFF\n@@ -184,6 +185,7 @@\n #define NIA_ENG_QMI_ENQ\t\t\t\t\t0x00540000\n #define NIA_ENG_QMI_DEQ\t\t\t\t\t0x00580000\n #define NIA_ENG_HWP\t\t\t\t\t0x00440000\n+#define NIA_ENG_HWK\t\t\t\t\t0x00480000\n #define NIA_BMI_AC_ENQ_FRAME\t\t\t\t0x00000002\n #define NIA_BMI_AC_TX_RELEASE\t\t\t\t0x000002C0\n #define NIA_BMI_AC_RELEASE\t\t\t\t0x000000C0\n@@ -394,6 +396,8 @@ struct fman_port_bpools {\n struct fman_port_cfg {\n \tu32 dflt_fqid;\n \tu32 err_fqid;\n+\tu32 pcd_base_fqid;\n+\tu32 pcd_fqs_count;\n \tu8 deq_sp;\n \tbool deq_high_priority;\n \tenum fman_port_deq_type deq_type;\n@@ -1271,6 +1275,10 @@ static void set_rx_dflt_cfg(struct fman_port *port,\n \t\tport_params->specific_params.rx_params.err_fqid;\n \tport->cfg->dflt_fqid =\n \t\tport_params->specific_params.rx_params.dflt_fqid;\n+\tport->cfg->pcd_base_fqid =\n+\t\tport_params->specific_params.rx_params.pcd_base_fqid;\n+\tport->cfg->pcd_fqs_count =\n+\t\tport_params->specific_params.rx_params.pcd_fqs_count;\n }\n \n static void set_tx_dflt_cfg(struct fman_port *port,\n@@ -1398,6 +1406,24 @@ int fman_port_config(struct fman_port *port, struct fman_port_params *params)\n EXPORT_SYMBOL(fman_port_config);\n \n /**\n+ * fman_port_use_kg_hash\n+ * port: A pointer to a FM Port module.\n+ * Sets the HW KeyGen or the BMI as HW Parser next engine, enabling\n+ * or bypassing the KeyGen hashing of Rx traffic\n+ */\n+void fman_port_use_kg_hash(struct fman_port *port, bool enable)\n+{\n+\tif (enable)\n+\t\t/* After the Parser frames go to KeyGen */\n+\t\tiowrite32be(NIA_ENG_HWK, &port->bmi_regs->rx.fmbm_rfpne);\n+\telse\n+\t\t/* After the Parser frames go to BMI */\n+\t\tiowrite32be(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME,\n+\t\t\t &port->bmi_regs->rx.fmbm_rfpne);\n+}\n+EXPORT_SYMBOL(fman_port_use_kg_hash);\n+\n+/**\n * fman_port_init\n * port:\tA pointer to a FM Port module.\n * Initializes the FM PORT module by defining the software structure and\n@@ -1407,9 +1433,10 @@ EXPORT_SYMBOL(fman_port_config);\n */\n int fman_port_init(struct fman_port *port)\n {\n+\tstruct fman_port_init_params params;\n+\tstruct fman_keygen *keygen;\n \tstruct fman_port_cfg *cfg;\n \tint err;\n-\tstruct fman_port_init_params params;\n \n \tif (is_init_done(port->cfg))\n \t\treturn -EINVAL;\n@@ -1472,6 +1499,17 @@ int fman_port_init(struct fman_port *port)\n \tif (err)\n \t\treturn err;\n \n+\tif (port->cfg->pcd_fqs_count) {\n+\t\tkeygen = port->dts_params.fman->keygen;\n+\t\terr = keygen_port_hashing_init(keygen, port->port_id,\n+\t\t\t\t\t port->cfg->pcd_base_fqid,\n+\t\t\t\t\t port->cfg->pcd_fqs_count);\n+\t\tif (err)\n+\t\t\treturn err;\n+\n+\t\tfman_port_use_kg_hash(port, true);\n+\t}\n+\n \tkfree(port->cfg);\n \tport->cfg = NULL;\n \ndiff --git a/drivers/net/ethernet/freescale/fman/fman_port.h b/drivers/net/ethernet/freescale/fman/fman_port.h\nindex 8ba9017..5a99611 100644\n--- a/drivers/net/ethernet/freescale/fman/fman_port.h\n+++ b/drivers/net/ethernet/freescale/fman/fman_port.h\n@@ -100,6 +100,9 @@ struct fman_port;\n struct fman_port_rx_params {\n \tu32 err_fqid;\t\t\t/* Error Queue Id. */\n \tu32 dflt_fqid;\t\t\t/* Default Queue Id. */\n+\tu32 pcd_base_fqid;\t\t/* PCD base Queue Id. */\n+\tu32 pcd_fqs_count;\t\t/* Number of PCD FQs. */\n+\n \t/* Which external buffer pools are used\n \t * (up to FMAN_PORT_MAX_EXT_POOLS_NUM), and their sizes.\n \t */\n@@ -134,6 +137,8 @@ struct fman_port_params {\n \n int fman_port_config(struct fman_port *port, struct fman_port_params *params);\n \n+void fman_port_use_kg_hash(struct fman_port *port, bool enable);\n+\n int fman_port_init(struct fman_port *port);\n \n int fman_port_cfg_buf_prefix_content(struct fman_port *port,\n", "prefixes": [ "v4", "2/7" ] }