get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 130417,
    "url": "http://patchwork.dpdk.org/api/patches/130417/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20230816132552.2483752-4-mko-plv@napatech.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20230816132552.2483752-4-mko-plv@napatech.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230816132552.2483752-4-mko-plv@napatech.com",
    "date": "2023-08-16T13:25:48",
    "name": "[4/8] net/ntnic: adds flow related FPGA functionality",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1b27fea1b567d274fd6c7fb9c0e725e6bf64a891",
    "submitter": {
        "id": 3153,
        "url": "http://patchwork.dpdk.org/api/people/3153/?format=api",
        "name": "Mykola Kostenok",
        "email": "mko-plv@napatech.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20230816132552.2483752-4-mko-plv@napatech.com/mbox/",
    "series": [
        {
            "id": 29251,
            "url": "http://patchwork.dpdk.org/api/series/29251/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=29251",
            "date": "2023-08-16T13:25:51",
            "name": "[1/8] net/ntnic: initial commit which adds register defines",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/29251/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/130417/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/130417/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 2B2A743081;\n\tWed, 16 Aug 2023 16:00:33 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 788FA43278;\n\tWed, 16 Aug 2023 16:00:24 +0200 (CEST)",
            "from egress-ip4a.ess.de.barracuda.com\n (egress-ip4a.ess.de.barracuda.com [18.184.203.227])\n by mails.dpdk.org (Postfix) with ESMTP id 078514326A\n for <dev@dpdk.org>; Wed, 16 Aug 2023 16:00:22 +0200 (CEST)",
            "from EUR04-HE1-obe.outbound.protection.outlook.com\n (mail-he1eur04lp2054.outbound.protection.outlook.com [104.47.13.54]) by\n mx-outbound11-46.eu-central-1a.ess.aws.cudaops.com (version=TLSv1.2\n cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO);\n Wed, 16 Aug 2023 14:00:21 +0000",
            "from DUZPR01CA0135.eurprd01.prod.exchangelabs.com\n (2603:10a6:10:4bc::6) by AM8P190MB0994.EURP190.PROD.OUTLOOK.COM\n (2603:10a6:20b:1de::20) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6678.29; Wed, 16 Aug\n 2023 13:25:53 +0000",
            "from DB1PEPF00039234.eurprd03.prod.outlook.com\n (2603:10a6:10:4bc:cafe::d4) by DUZPR01CA0135.outlook.office365.com\n (2603:10a6:10:4bc::6) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6652.33 via Frontend\n Transport; Wed, 16 Aug 2023 13:25:53 +0000",
            "from localhost.localdomain.com (178.72.21.4) by\n DB1PEPF00039234.mail.protection.outlook.com (10.167.8.107) with Microsoft\n SMTP Server id 15.20.6699.15 via Frontend Transport; Wed, 16 Aug 2023\n 13:25:53 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=G7qqzx0hL40JHwbX35gw8Jo8Cp3jJxEGGuYCZBEYBbwXHFFv5zKrYoJn3+0P8jR5fb0EJS6WAcd2UBVWSN1fSeCL3nSC2KZCTcNQE6uREMBIfU1SBTFPuMpFvQQlOACbEr/nX1ZmKRU6GzJhM0dG3q8MdVRuhpJZ+F/CzunOIMywigV5TduDa63NNrHgscK4skFZf/Fi6wvFctGpJW3D/p1o9ZFUElgcb6Vl78xWyA64GbC0ktsnvFl5IoEyF5Ydx9FdJ93Fr7GSge5o3zSW2OHfZhLo1ZFfQl2VLo+3SWsoDGehLvNSpKxenkUJ0VZt9mad3wQgmI8poOv5kDpPDA==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=PApX8u6zPSyf0Nuv8d5OwsFYIlqCRrL1MpW6zuiJZds=;\n b=H0qgIxeOjAj1p17MNSmq4i9TIcsbiySpmLFwCa49ASHzmk5kesmBGqLe4i2jIuZGTr60qCvlml6HGiu89emJ5aT60zcNzxIALIQWwJy3POL9VVTD7FoAcEoxJ9ZjentZ2jpz1gQ4toZqf/wKTFtpP2KEXAyzT87GIMYlw8B6EY7ugOGoKgXYG1VbZpdRgCHb0y2Mu56Y0JmZP7iJz+p8CjjDXmFl2F8P3GApzg3DeSILd7p9QeBaxtS8KkE6+1cfW+xd6aK0p0+D3CqURgqvXYNcHSBfbCskBsIOSQ7tcFly9B0ObPK47rHr4pqs0WE5R4H8GUggHiIB1SI6WWjEtQ==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=fail (sender ip is\n 178.72.21.4) smtp.rcpttodomain=dpdk.org smtp.mailfrom=napatech.com;\n dmarc=fail (p=none sp=none pct=100) action=none header.from=napatech.com;\n dkim=none (message not signed); arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=napatech.com;\n s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=PApX8u6zPSyf0Nuv8d5OwsFYIlqCRrL1MpW6zuiJZds=;\n b=MEHbGUugwvv1R8zZRrh24W5mLbfFrKjdxqgOENIOIVRUf2ScCYxoCyZvw84wPCV6rsNXrBu2lh4n/yWC23U04U7gMRjyEbWEvAS5j9pXXxqjKVp5Lr9mIDgCdXUdAOwpZAvuBnViE2kCHCspyY8f8572mL7Ho90Eu1bBJ9CfKAg=",
        "X-MS-Exchange-Authentication-Results": "spf=fail (sender IP is 178.72.21.4)\n smtp.mailfrom=napatech.com; dkim=none (message not signed)\n header.d=none;dmarc=fail action=none header.from=napatech.com;",
        "Received-SPF": "Fail (protection.outlook.com: domain of napatech.com does not\n designate 178.72.21.4 as permitted sender) receiver=protection.outlook.com;\n client-ip=178.72.21.4; helo=localhost.localdomain.com;",
        "From": "Mykola Kostenok <mko-plv@napatech.com>",
        "To": "dev@dpdk.org",
        "Cc": "Christian Koue Muf <ckm@napatech.com>",
        "Subject": "[PATCH 4/8] net/ntnic: adds flow related FPGA functionality",
        "Date": "Wed, 16 Aug 2023 15:25:48 +0200",
        "Message-Id": "<20230816132552.2483752-4-mko-plv@napatech.com>",
        "X-Mailer": "git-send-email 2.39.3",
        "In-Reply-To": "<20230816132552.2483752-1-mko-plv@napatech.com>",
        "References": "<20230816132552.2483752-1-mko-plv@napatech.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "DB1PEPF00039234:EE_|AM8P190MB0994:EE_",
        "Content-Type": "text/plain",
        "X-MS-Office365-Filtering-Correlation-Id": "7f22ffa6-b5cc-4570-e300-08db9e5c50df",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n +Mjk3m9Zi+4NCP9gsWR4oNcy/G7e37Oyam3w9wSK6BKCKfEPFSSfGMKTASta4oAlYpCbHbzXktEHPn2Vy8pyDQJ7Kry++l7eFm8kNDDDt4xVwDk3n39BmusZ3tHbB+sr/GyxN2tujCdNU/SpvCgZaUmjEHmD/6nBA+Ge7GECjAiC9crarOIdS7OewYd5yr7GBshu5fwiBtZq39Hvm+VzPyt68j7LMUZdiX7pCAh/34pzvrJ+hleLa6QH2klnyZIjIq/1kgLt+m6N5zbGpUyYr9nTZBOYSnwlB0vNsogTENsNooHSCGW1/j4fV1UQST0F4DlaUoMRygcN1OagSlLR22eDANbZiG8XamJ+X2beVZD48Bz4aHFDTbWAYOGhiibV9WYzLT4n4cY6t59PAVtSr+BccV5qbzZb1+Qd9EvVTjR+GzGl1iyKYBI0BmCjueMjh0spK22sBJtViIEik9G4pvpNAciWIjBABVILper7DXL6Qaya0nATBDHj5azpJVhzSm3vNurt9FHRKyR3LstWk3c7/LdUEvDARbbEUliOEQIKujO6waRdU8J85mcGOTU6JAzFk1FZXVWKQSkvQA0yXaxf8fap+loQkcA0f8fZN/eNlD/yH5vRGC9NjM2LfFHWUcoBMObF4zbGFRfhVUFkQl1exFoo5l/BUl4rIH56Y9bc1OCnQbQRaDDUnsSXKVGahDzkWvzXa2QGwRcWo+AK+mqNtGrG0TUqMUPnD4bopWjnkf5czE75MQCnnc4DgZTlTBSTF4+CwYT3sFE8+Vrt0w==",
        "X-Forefront-Antispam-Report": "CIP:178.72.21.4; CTRY:DK; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:localhost.localdomain.com; PTR:InfoDomainNonexistent;\n CAT:NONE;\n SFS:(13230031)(6069001)(396003)(39840400004)(346002)(376002)(136003)(1800799009)(451199024)(186009)(82310400011)(46966006)(36840700001)(316002)(356005)(6916009)(81166007)(70586007)(70206006)(36736006)(36860700001)(41300700001)(5660300002)(47076005)(34020700004)(8676002)(4326008)(8936002)(30864003)(2906002)(118246002)(83380400001)(26005)(40480700001)(478600001)(336012)(86362001)(6512007)(9316004)(107886003)(6506007)(36756003)(6666004)(1076003)(2616005)(956004)(6486002)(36900700001)(559001)(579004);\n DIR:OUT; SFP:1101;",
        "X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0": "\n ckGhmC++XPZztYwihsWsf+CTs1xvgadMA8y9LgsVNmISwlTxt/M9Qf2ITcjthDPKiCS6MOz8SgJWoncs5p3uKuKRf133zpxYnuOTXhXExImooo7zk0fnzvJ5QxHU7HpXellA+3jnZJEd4504crms0jkoQ21pubGsQp+16hMvExQXnS8zsKddk1pJpm6+GL21lr3Xu4XmH/q3pSQNMQyHQdMKRMaHLbkeDLILAXf6OpDpVn0vujoRVGG3WRyjZb1RgomKPdz97idA66QG8kf8udin8IvSDnrAToczbDAEM3DwWXbzihT0g1B4UOq90ULuDOfs0BveaRPfG6ydxTcntnSFb8jQxbUwp57/C/wx4A3Lm/un1zK9AKf54vkslmUVlAh9u/7ObJMvKRTBj0h1bsG/SzQIv50ZWM45VbZBe8hBa8kreS0xS3N0jTxNI/xew9BKD+o1YCYSpYUOuAG9ILuZHZRp/XyzjGjKV4KtyhOsvXbgkyZWIIHWwsdYG9ZlMT5AaQAYGM8qg2e2uL3UQ8Z4R48DDbtsDxM2IKh+mcWvWFoN6G+0ai7BArvnW1h1FpN8H90AkusAnbTGTo6OdJrNEgrfGCO6NJhxEIvc6C9JtaXH5KEUJ0I8KGOD4CwQk1Z7bt8Nw1rQP8vt6mqbZv7nnmDPXnpGzH7cw0x2v3ZZyx4nd1nCn33a+V2bhuUDVk8Yn8Ey7fn4BEFm6P0JkW6iJg6XUNxo9aG2zBFYRgxkco4DaO2csvW52I8Y0B2HIgPtmlWDFxWo5AnIGUGxsnzEe5VTfuZqmTYdl7u9LdU=",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "16 Aug 2023 13:25:53.2680 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 7f22ffa6-b5cc-4570-e300-08db9e5c50df",
        "X-MS-Exchange-CrossTenant-Id": "c4540d0b-728a-4233-9da5-9ea30c7ec3ed",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=c4540d0b-728a-4233-9da5-9ea30c7ec3ed; Ip=[178.72.21.4];\n Helo=[localhost.localdomain.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n DB1PEPF00039234.eurprd03.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM8P190MB0994",
        "X-OriginatorOrg": "napatech.com",
        "X-BESS-ID": "1692194421-302862-12320-30147-1",
        "X-BESS-VER": "2019.1_20230807.1901",
        "X-BESS-Apparent-Source-IP": "104.47.13.54",
        "X-BESS-Parts": "H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVkaWlgamRkB2BlDYIMnYwtLcOM\n XQIjkpOTHVwCDR3MTQJM0y0djIzNzMLE2pNhYAKblOxkMAAAA=",
        "X-BESS-Outbound-Spam-Score": "0.00",
        "X-BESS-Outbound-Spam-Report": "Code version 3.2,\n rules version 3.2.2.250184 [from\n cloudscan15-117.eu-central-1a.ess.aws.cudaops.com]\n Rule breakdown below\n pts rule name              description\n ---- ---------------------- --------------------------------\n 0.00 LARGE_BODY_SHORTCUT    META:  ",
        "X-BESS-Outbound-Spam-Status": "SCORE=0.00 using account:ESS113687 scores of\n KILL_LEVEL=7.0 tests=LARGE_BODY_SHORTCUT",
        "X-BESS-BRTS-Status": "1",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Christian Koue Muf <ckm@napatech.com>\n\nThe PMD will control the registers used for flow programming,\nand this commit adds support for this.\n\nSigned-off-by: Christian Koue Muf <ckm@napatech.com>\nReviewed-by: Mykola Kostenok <mko-plv@napatech.com>\n---\n drivers/net/ntnic/meson.build                 |   21 +\n .../ntnic/nthw/flow_filter/flow_nthw_cat.c    | 1107 ++++++++++++++++\n .../ntnic/nthw/flow_filter/flow_nthw_cat.h    |  372 ++++++\n .../ntnic/nthw/flow_filter/flow_nthw_csu.c    |  146 +++\n .../ntnic/nthw/flow_filter/flow_nthw_csu.h    |   42 +\n .../ntnic/nthw/flow_filter/flow_nthw_flm.c    | 1140 +++++++++++++++++\n .../ntnic/nthw/flow_filter/flow_nthw_flm.h    |  422 ++++++\n .../ntnic/nthw/flow_filter/flow_nthw_hfu.c    |  293 +++++\n .../ntnic/nthw/flow_filter/flow_nthw_hfu.h    |  100 ++\n .../ntnic/nthw/flow_filter/flow_nthw_hsh.c    |  254 ++++\n .../ntnic/nthw/flow_filter/flow_nthw_hsh.h    |   81 ++\n .../ntnic/nthw/flow_filter/flow_nthw_hst.c    |  202 +++\n .../ntnic/nthw/flow_filter/flow_nthw_hst.h    |   72 ++\n .../ntnic/nthw/flow_filter/flow_nthw_ifr.c    |   93 ++\n .../ntnic/nthw/flow_filter/flow_nthw_ifr.h    |   39 +\n .../ntnic/nthw/flow_filter/flow_nthw_info.c   |  341 +++++\n .../ntnic/nthw/flow_filter/flow_nthw_info.h   |  104 ++\n .../ntnic/nthw/flow_filter/flow_nthw_ioa.c    |  234 ++++\n .../ntnic/nthw/flow_filter/flow_nthw_ioa.h    |   80 ++\n .../net/ntnic/nthw/flow_filter/flow_nthw_km.c |  686 ++++++++++\n .../net/ntnic/nthw/flow_filter/flow_nthw_km.h |  224 ++++\n .../ntnic/nthw/flow_filter/flow_nthw_pdb.c    |  230 ++++\n .../ntnic/nthw/flow_filter/flow_nthw_pdb.h    |   84 ++\n .../ntnic/nthw/flow_filter/flow_nthw_qsl.c    |  355 +++++\n .../ntnic/nthw/flow_filter/flow_nthw_qsl.h    |  121 ++\n .../ntnic/nthw/flow_filter/flow_nthw_rmc.c    |  112 ++\n .../ntnic/nthw/flow_filter/flow_nthw_rmc.h    |   40 +\n .../ntnic/nthw/flow_filter/flow_nthw_roa.c    |  294 +++++\n .../ntnic/nthw/flow_filter/flow_nthw_roa.h    |  109 ++\n .../ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c |  132 ++\n .../ntnic/nthw/flow_filter/flow_nthw_rpp_lr.h |   53 +\n .../ntnic/nthw/flow_filter/flow_nthw_slc.c    |  109 ++\n .../ntnic/nthw/flow_filter/flow_nthw_slc.h    |   46 +\n .../ntnic/nthw/flow_filter/flow_nthw_slc_lr.c |  109 ++\n .../ntnic/nthw/flow_filter/flow_nthw_slc_lr.h |   46 +\n .../ntnic/nthw/flow_filter/flow_nthw_tx_cpy.c |  394 ++++++\n .../ntnic/nthw/flow_filter/flow_nthw_tx_cpy.h |   72 ++\n .../ntnic/nthw/flow_filter/flow_nthw_tx_ins.c |   96 ++\n .../ntnic/nthw/flow_filter/flow_nthw_tx_ins.h |   42 +\n .../ntnic/nthw/flow_filter/flow_nthw_tx_rpl.c |  165 +++\n .../ntnic/nthw/flow_filter/flow_nthw_tx_rpl.h |   70 +\n 41 files changed, 8732 insertions(+)\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_cat.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_cat.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_csu.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_csu.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_flm.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_flm.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_hfu.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_hfu.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_hsh.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_hsh.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_hst.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_hst.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_info.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_info.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_ioa.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_ioa.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_km.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_km.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_pdb.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_pdb.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_qsl.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_qsl.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_rmc.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_rmc.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_roa.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_roa.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc_lr.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc_lr.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_cpy.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_cpy.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_ins.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_ins.h\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_rpl.c\n create mode 100644 drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_rpl.h",
    "diff": "diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build\nindex 383ff15390..c184d5d4b5 100644\n--- a/drivers/net/ntnic/meson.build\n+++ b/drivers/net/ntnic/meson.build\n@@ -17,6 +17,7 @@ includes = [\n     include_directories('nthw'),\n     include_directories('nthw/core'),\n     include_directories('nthw/supported'),\n+    include_directories('nthw/flow_filter'),\n     include_directories('sensors'),\n     include_directories('sensors/avr_sensors'),\n     include_directories('sensors/board_sensors'),\n@@ -58,6 +59,26 @@ sources = files(\n     'nthw/core/nthw_spim.c',\n     'nthw/core/nthw_spis.c',\n     'nthw/core/nthw_tsm.c',\n+    'nthw/flow_filter/flow_nthw_cat.c',\n+    'nthw/flow_filter/flow_nthw_csu.c',\n+    'nthw/flow_filter/flow_nthw_flm.c',\n+    'nthw/flow_filter/flow_nthw_hfu.c',\n+    'nthw/flow_filter/flow_nthw_hsh.c',\n+    'nthw/flow_filter/flow_nthw_hst.c',\n+    'nthw/flow_filter/flow_nthw_ifr.c',\n+    'nthw/flow_filter/flow_nthw_info.c',\n+    'nthw/flow_filter/flow_nthw_ioa.c',\n+    'nthw/flow_filter/flow_nthw_km.c',\n+    'nthw/flow_filter/flow_nthw_pdb.c',\n+    'nthw/flow_filter/flow_nthw_qsl.c',\n+    'nthw/flow_filter/flow_nthw_rmc.c',\n+    'nthw/flow_filter/flow_nthw_roa.c',\n+    'nthw/flow_filter/flow_nthw_rpp_lr.c',\n+    'nthw/flow_filter/flow_nthw_slc.c',\n+    'nthw/flow_filter/flow_nthw_slc_lr.c',\n+    'nthw/flow_filter/flow_nthw_tx_cpy.c',\n+    'nthw/flow_filter/flow_nthw_tx_ins.c',\n+    'nthw/flow_filter/flow_nthw_tx_rpl.c',\n     'nthw/nthw_fpga_model.c',\n     'nthw/nthw_dbs.c',\n     'nthw/nthw_epp.c',\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_cat.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_cat.c\nnew file mode 100644\nindex 0000000000..91376363c1\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_cat.c\n@@ -0,0 +1,1107 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_cat.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+struct cat_nthw *cat_nthw_new(void)\n+{\n+\tstruct cat_nthw *p = malloc(sizeof(struct cat_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void cat_nthw_delete(struct cat_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+void cat_nthw_set_debug_mode(struct cat_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_cat, n_debug_mode);\n+}\n+\n+int cat_nthw_init(struct cat_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_CAT, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Cat %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_cat = p_mod;\n+\n+\tp->m_km_if_cnt = fpga_get_product_param(p->mp_fpga, NT_CAT_KM_IF_CNT, -1);\n+\n+\t/* CFN */\n+\tp->mp_cfn_ctrl = module_get_register(p->m_cat, CAT_CFN_CTRL);\n+\tp->mp_cfn_addr = register_get_field(p->mp_cfn_ctrl, CAT_CFN_CTRL_ADR);\n+\tp->mp_cfn_cnt = register_get_field(p->mp_cfn_ctrl, CAT_CFN_CTRL_CNT);\n+\tp->mp_cfn_data = module_get_register(p->m_cat, CAT_CFN_DATA);\n+\tp->mp_cfn_data_enable =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_ENABLE);\n+\tp->mp_cfn_data_inv = register_get_field(p->mp_cfn_data, CAT_CFN_DATA_INV);\n+\tp->mp_cfn_data_ptc_inv =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_INV);\n+\tp->mp_cfn_data_ptc_isl =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_ISL);\n+\tp->mp_cfn_data_ptc_mac =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_MAC);\n+\tp->mp_cfn_data_ptc_l2 =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_L2);\n+\tp->mp_cfn_data_ptc_vn_tag =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_VNTAG);\n+\tp->mp_cfn_data_ptc_vlan =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_VLAN);\n+\tp->mp_cfn_data_ptc_mpls =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_MPLS);\n+\tp->mp_cfn_data_ptc_l3 =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_L3);\n+\tp->mp_cfn_data_ptc_frag =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_FRAG);\n+\tp->mp_cfn_data_ptc_ip_prot =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_IP_PROT);\n+\tp->mp_cfn_data_ptc_l4 =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_L4);\n+\tp->mp_cfn_data_ptc_tunnel =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_TUNNEL);\n+\tp->mp_cfn_data_ptc_tnl_l2 =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_TNL_L2);\n+\tp->mp_cfn_data_ptc_tnl_vlan =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_TNL_VLAN);\n+\tp->mp_cfn_data_ptc_tnl_mpls =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_TNL_MPLS);\n+\tp->mp_cfn_data_ptc_tnl_l3 =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_TNL_L3);\n+\tp->mp_cfn_data_ptc_tnl_frag =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_TNL_FRAG);\n+\tp->mp_cfn_data_ptc_tnl_ip_prot =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_TNL_IP_PROT);\n+\tp->mp_cfn_data_ptc_tnl_l4 =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_TNL_L4);\n+\tp->mp_cfn_data_err_inv =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_INV);\n+\tp->mp_cfn_data_err_cv =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_CV);\n+\tp->mp_cfn_data_err_fcs =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_FCS);\n+\tp->mp_cfn_data_err_trunc =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_TRUNC);\n+\tp->mp_cfn_data_mac_port =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_MAC_PORT);\n+\tp->mp_cfn_data_pm_cmp =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PM_CMP);\n+\tp->mp_cfn_data_pm_dct =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PM_DCT);\n+\tp->mp_cfn_data_pm_ext_inv =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PM_EXT_INV);\n+\tp->mp_cfn_data_pm_cmb =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PM_CMB);\n+\tp->mp_cfn_data_pm_and_inv =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PM_AND_INV);\n+\tp->mp_cfn_data_pm_or_inv =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PM_OR_INV);\n+\tp->mp_cfn_data_pm_inv =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_PM_INV);\n+\tp->mp_cfn_data_lc = register_get_field(p->mp_cfn_data, CAT_CFN_DATA_LC);\n+\tp->mp_cfn_data_lc_inv =\n+\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_LC_INV);\n+\n+\tif (p->m_km_if_cnt == -1) {\n+\t\tp->mp_cfn_data_km0_or =\n+\t\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_KM_OR);\n+\t} else {\n+\t\tp->mp_cfn_data_km0_or =\n+\t\t\tregister_get_field(p->mp_cfn_data, CAT_CFN_DATA_KM0_OR);\n+\t\tp->mp_cfn_data_km1_or =\n+\t\t\tregister_query_field(p->mp_cfn_data, CAT_CFN_DATA_KM1_OR);\n+\t}\n+\n+\tif (p->m_km_if_cnt < 0) {\n+\t\t/* KCE */\n+\t\tp->mp_kce_ctrl[0] = module_get_register(p->m_cat, CAT_KCE_CTRL);\n+\t\tp->mp_kce_addr[0] =\n+\t\t\tregister_get_field(p->mp_kce_ctrl[0], CAT_KCE_CTRL_ADR);\n+\t\tp->mp_kce_cnt[0] =\n+\t\t\tregister_get_field(p->mp_kce_ctrl[0], CAT_KCE_CTRL_CNT);\n+\t\tp->mp_kce_data[0] = module_get_register(p->m_cat, CAT_KCE_DATA);\n+\t\tp->mp_kce_data_enable[0] =\n+\t\t\tregister_get_field(p->mp_kce_data[0], CAT_KCE_DATA_ENABLE);\n+\t\t/* KCS */\n+\t\tp->mp_kcs_ctrl[0] = module_get_register(p->m_cat, CAT_KCS_CTRL);\n+\t\tp->mp_kcs_addr[0] =\n+\t\t\tregister_get_field(p->mp_kcs_ctrl[0], CAT_KCS_CTRL_ADR);\n+\t\tp->mp_kcs_cnt[0] =\n+\t\t\tregister_get_field(p->mp_kcs_ctrl[0], CAT_KCS_CTRL_CNT);\n+\t\tp->mp_kcs_data[0] = module_get_register(p->m_cat, CAT_KCS_DATA);\n+\t\tp->mp_kcs_data_category[0] =\n+\t\t\tregister_get_field(p->mp_kcs_data[0], CAT_KCS_DATA_CATEGORY);\n+\t\t/* FTE */\n+\t\tp->mp_fte_ctrl[0] = module_get_register(p->m_cat, CAT_FTE_CTRL);\n+\t\tp->mp_fte_addr[0] =\n+\t\t\tregister_get_field(p->mp_fte_ctrl[0], CAT_FTE_CTRL_ADR);\n+\t\tp->mp_fte_cnt[0] =\n+\t\t\tregister_get_field(p->mp_fte_ctrl[0], CAT_FTE_CTRL_CNT);\n+\t\tp->mp_fte_data[0] = module_get_register(p->m_cat, CAT_FTE_DATA);\n+\t\tp->mp_fte_data_enable[0] =\n+\t\t\tregister_get_field(p->mp_fte_data[0], CAT_FTE_DATA_ENABLE);\n+\t} else {\n+\t\t/* KCE 0 */\n+\t\tp->mp_kce_ctrl[0] = module_get_register(p->m_cat, CAT_KCE0_CTRL);\n+\t\tp->mp_kce_addr[0] =\n+\t\t\tregister_get_field(p->mp_kce_ctrl[0], CAT_KCE0_CTRL_ADR);\n+\t\tp->mp_kce_cnt[0] =\n+\t\t\tregister_get_field(p->mp_kce_ctrl[0], CAT_KCE0_CTRL_CNT);\n+\t\tp->mp_kce_data[0] = module_get_register(p->m_cat, CAT_KCE0_DATA);\n+\t\tp->mp_kce_data_enable[0] = register_get_field(p->mp_kce_data[0],\n+\t\t\t\t\tCAT_KCE0_DATA_ENABLE);\n+\t\t/* KCS 0 */\n+\t\tp->mp_kcs_ctrl[0] = module_get_register(p->m_cat, CAT_KCS0_CTRL);\n+\t\tp->mp_kcs_addr[0] =\n+\t\t\tregister_get_field(p->mp_kcs_ctrl[0], CAT_KCS0_CTRL_ADR);\n+\t\tp->mp_kcs_cnt[0] =\n+\t\t\tregister_get_field(p->mp_kcs_ctrl[0], CAT_KCS0_CTRL_CNT);\n+\t\tp->mp_kcs_data[0] = module_get_register(p->m_cat, CAT_KCS0_DATA);\n+\t\tp->mp_kcs_data_category[0] =\n+\t\t\tregister_get_field(p->mp_kcs_data[0], CAT_KCS0_DATA_CATEGORY);\n+\t\t/* FTE 0 */\n+\t\tp->mp_fte_ctrl[0] = module_get_register(p->m_cat, CAT_FTE0_CTRL);\n+\t\tp->mp_fte_addr[0] =\n+\t\t\tregister_get_field(p->mp_fte_ctrl[0], CAT_FTE0_CTRL_ADR);\n+\t\tp->mp_fte_cnt[0] =\n+\t\t\tregister_get_field(p->mp_fte_ctrl[0], CAT_FTE0_CTRL_CNT);\n+\t\tp->mp_fte_data[0] = module_get_register(p->m_cat, CAT_FTE0_DATA);\n+\t\tp->mp_fte_data_enable[0] = register_get_field(p->mp_fte_data[0],\n+\t\t\t\t\tCAT_FTE0_DATA_ENABLE);\n+\t\t/* KCE 1 */\n+\t\tp->mp_kce_ctrl[1] = module_get_register(p->m_cat, CAT_KCE1_CTRL);\n+\t\tp->mp_kce_addr[1] =\n+\t\t\tregister_get_field(p->mp_kce_ctrl[1], CAT_KCE1_CTRL_ADR);\n+\t\tp->mp_kce_cnt[1] =\n+\t\t\tregister_get_field(p->mp_kce_ctrl[1], CAT_KCE1_CTRL_CNT);\n+\t\tp->mp_kce_data[1] = module_get_register(p->m_cat, CAT_KCE1_DATA);\n+\t\tp->mp_kce_data_enable[1] = register_get_field(p->mp_kce_data[1],\n+\t\t\t\t\tCAT_KCE1_DATA_ENABLE);\n+\t\t/* KCS 1 */\n+\t\tp->mp_kcs_ctrl[1] = module_get_register(p->m_cat, CAT_KCS1_CTRL);\n+\t\tp->mp_kcs_addr[1] =\n+\t\t\tregister_get_field(p->mp_kcs_ctrl[1], CAT_KCS1_CTRL_ADR);\n+\t\tp->mp_kcs_cnt[1] =\n+\t\t\tregister_get_field(p->mp_kcs_ctrl[1], CAT_KCS1_CTRL_CNT);\n+\t\tp->mp_kcs_data[1] = module_get_register(p->m_cat, CAT_KCS1_DATA);\n+\t\tp->mp_kcs_data_category[1] =\n+\t\t\tregister_get_field(p->mp_kcs_data[1], CAT_KCS1_DATA_CATEGORY);\n+\t\t/* FTE 1 */\n+\t\tp->mp_fte_ctrl[1] = module_get_register(p->m_cat, CAT_FTE1_CTRL);\n+\t\tp->mp_fte_addr[1] =\n+\t\t\tregister_get_field(p->mp_fte_ctrl[1], CAT_FTE1_CTRL_ADR);\n+\t\tp->mp_fte_cnt[1] =\n+\t\t\tregister_get_field(p->mp_fte_ctrl[1], CAT_FTE1_CTRL_CNT);\n+\t\tp->mp_fte_data[1] = module_get_register(p->m_cat, CAT_FTE1_DATA);\n+\t\tp->mp_fte_data_enable[1] = register_get_field(p->mp_fte_data[1],\n+\t\t\t\t\tCAT_FTE1_DATA_ENABLE);\n+\t}\n+\n+\t/* CTE */\n+\tp->mp_cte_ctrl = module_get_register(p->m_cat, CAT_CTE_CTRL);\n+\tp->mp_cte_addr = register_get_field(p->mp_cte_ctrl, CAT_CTE_CTRL_ADR);\n+\tp->mp_cte_cnt = register_get_field(p->mp_cte_ctrl, CAT_CTE_CTRL_CNT);\n+\tp->mp_cte_data = module_get_register(p->m_cat, CAT_CTE_DATA);\n+\tp->mp_cte_data_col =\n+\t\tregister_get_field(p->mp_cte_data, CAT_CTE_DATA_COL_ENABLE);\n+\tp->mp_cte_data_cor =\n+\t\tregister_get_field(p->mp_cte_data, CAT_CTE_DATA_COR_ENABLE);\n+\tp->mp_cte_data_hsh =\n+\t\tregister_get_field(p->mp_cte_data, CAT_CTE_DATA_HSH_ENABLE);\n+\tp->mp_cte_data_qsl =\n+\t\tregister_get_field(p->mp_cte_data, CAT_CTE_DATA_QSL_ENABLE);\n+\tp->mp_cte_data_ipf =\n+\t\tregister_get_field(p->mp_cte_data, CAT_CTE_DATA_IPF_ENABLE);\n+\tp->mp_cte_data_slc =\n+\t\tregister_get_field(p->mp_cte_data, CAT_CTE_DATA_SLC_ENABLE);\n+\tp->mp_cte_data_pdb =\n+\t\tregister_get_field(p->mp_cte_data, CAT_CTE_DATA_PDB_ENABLE);\n+\tp->mp_cte_data_msk =\n+\t\tregister_query_field(p->mp_cte_data, CAT_CTE_DATA_MSK_ENABLE);\n+\tp->mp_cte_data_hst =\n+\t\tregister_query_field(p->mp_cte_data, CAT_CTE_DATA_HST_ENABLE);\n+\tp->mp_cte_data_epp =\n+\t\tregister_query_field(p->mp_cte_data, CAT_CTE_DATA_EPP_ENABLE);\n+\tp->mp_cte_data_tpe =\n+\t\tregister_query_field(p->mp_cte_data, CAT_CTE_DATA_TPE_ENABLE);\n+\tp->mp_cte_data_rrb =\n+\t\tregister_query_field(p->mp_cte_data, CAT_CTE_DATA_RRB_ENABLE);\n+\t/* CTS */\n+\tp->mp_cts_ctrl = module_get_register(p->m_cat, CAT_CTS_CTRL);\n+\tp->mp_cts_addr = register_get_field(p->mp_cts_ctrl, CAT_CTS_CTRL_ADR);\n+\tp->mp_cts_cnt = register_get_field(p->mp_cts_ctrl, CAT_CTS_CTRL_CNT);\n+\tp->mp_cts_data = module_get_register(p->m_cat, CAT_CTS_DATA);\n+\tp->mp_cts_data_cat_a = register_get_field(p->mp_cts_data, CAT_CTS_DATA_CAT_A);\n+\tp->mp_cts_data_cat_b = register_get_field(p->mp_cts_data, CAT_CTS_DATA_CAT_B);\n+\t/* COT */\n+\tp->mp_cot_ctrl = module_get_register(p->m_cat, CAT_COT_CTRL);\n+\tp->mp_cot_addr = register_get_field(p->mp_cot_ctrl, CAT_COT_CTRL_ADR);\n+\tp->mp_cot_cnt = register_get_field(p->mp_cot_ctrl, CAT_COT_CTRL_CNT);\n+\tp->mp_cot_data = module_get_register(p->m_cat, CAT_COT_DATA);\n+\tp->mp_cot_data_color = register_get_field(p->mp_cot_data, CAT_COT_DATA_COLOR);\n+\tp->mp_cot_data_km = register_get_field(p->mp_cot_data, CAT_COT_DATA_KM);\n+\tp->mp_cot_data_nfv_sb =\n+\t\tregister_query_field(p->mp_cot_data, CAT_COT_DATA_NFV_SB);\n+\t/* CCT */\n+\tp->mp_cct_ctrl = module_get_register(p->m_cat, CAT_CCT_CTRL);\n+\tp->mp_cct_addr = register_get_field(p->mp_cct_ctrl, CAT_CCT_CTRL_ADR);\n+\tp->mp_cct_cnt = register_get_field(p->mp_cct_ctrl, CAT_CCT_CTRL_CNT);\n+\tp->mp_cct_data = module_get_register(p->m_cat, CAT_CCT_DATA);\n+\tp->mp_cct_data_color = register_get_field(p->mp_cct_data, CAT_CCT_DATA_COLOR);\n+\tp->mp_cct_data_km = register_get_field(p->mp_cct_data, CAT_CCT_DATA_KM);\n+\t/* EXO */\n+\tp->mp_exo_ctrl = module_get_register(p->m_cat, CAT_EXO_CTRL);\n+\tp->mp_exo_addr = register_get_field(p->mp_exo_ctrl, CAT_EXO_CTRL_ADR);\n+\tp->mp_exo_cnt = register_get_field(p->mp_exo_ctrl, CAT_EXO_CTRL_CNT);\n+\tp->mp_exo_data = module_get_register(p->m_cat, CAT_EXO_DATA);\n+\tp->mp_exo_data_dyn = register_get_field(p->mp_exo_data, CAT_EXO_DATA_DYN);\n+\tp->mp_exo_data_ofs = register_get_field(p->mp_exo_data, CAT_EXO_DATA_OFS);\n+\t/* RCK */\n+\tp->mp_rck_ctrl = module_get_register(p->m_cat, CAT_RCK_CTRL);\n+\tp->mp_rck_addr = register_get_field(p->mp_rck_ctrl, CAT_RCK_CTRL_ADR);\n+\tp->mp_rck_cnt = register_get_field(p->mp_rck_ctrl, CAT_RCK_CTRL_CNT);\n+\tp->mp_rck_data = module_get_register(p->m_cat, CAT_RCK_DATA);\n+\t/* LEN */\n+\tp->mp_len_ctrl = module_get_register(p->m_cat, CAT_LEN_CTRL);\n+\tp->mp_len_addr = register_get_field(p->mp_len_ctrl, CAT_LEN_CTRL_ADR);\n+\tp->mp_len_cnt = register_get_field(p->mp_len_ctrl, CAT_LEN_CTRL_CNT);\n+\tp->mp_len_data = module_get_register(p->m_cat, CAT_LEN_DATA);\n+\tp->mp_len_data_lower = register_get_field(p->mp_len_data, CAT_LEN_DATA_LOWER);\n+\tp->mp_len_data_upper = register_get_field(p->mp_len_data, CAT_LEN_DATA_UPPER);\n+\tp->mp_len_data_dyn1 = register_get_field(p->mp_len_data, CAT_LEN_DATA_DYN1);\n+\tp->mp_len_data_dyn2 = register_get_field(p->mp_len_data, CAT_LEN_DATA_DYN2);\n+\tp->mp_len_data_inv = register_get_field(p->mp_len_data, CAT_LEN_DATA_INV);\n+\n+\tp->mp_cfn_data_ptc_cfp =\n+\t\tregister_query_field(p->mp_cfn_data, CAT_CFN_DATA_PTC_CFP);\n+\tp->mp_cfn_data_err_l3_cs =\n+\t\tregister_query_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_L3_CS);\n+\tp->mp_cfn_data_err_l4_cs =\n+\t\tregister_query_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_L4_CS);\n+\tp->mp_cfn_data_err_tnl_l3_cs =\n+\t\tregister_query_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_TNL_L3_CS);\n+\tp->mp_cfn_data_err_tnl_l4_cs =\n+\t\tregister_query_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_TNL_L4_CS);\n+\tp->mp_cfn_data_err_ttl_exp =\n+\t\tregister_query_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_TTL_EXP);\n+\tp->mp_cfn_data_err_tnl_ttl_exp =\n+\t\tregister_query_field(p->mp_cfn_data, CAT_CFN_DATA_ERR_TNL_TTL_EXP);\n+\n+\tp->mp_kcc_ctrl = module_query_register(p->m_cat, CAT_KCC_CTRL);\n+\tif (p->mp_kcc_ctrl != NULL) {\n+\t\tp->mp_kcc_addr =\n+\t\t\tregister_query_field(p->mp_kcc_ctrl, CAT_KCC_CTRL_ADR);\n+\t\tp->mp_kcc_cnt =\n+\t\t\tregister_query_field(p->mp_kcc_ctrl, CAT_KCC_CTRL_CNT);\n+\t}\n+\tp->mp_kcc_data = module_query_register(p->m_cat, CAT_KCC_DATA);\n+\tif (p->mp_kcc_data != NULL) {\n+\t\tp->mp_kcc_data_key =\n+\t\t\tregister_query_field(p->mp_kcc_data, CAT_KCC_DATA_KEY);\n+\t\tp->mp_kcc_data_category =\n+\t\t\tregister_query_field(p->mp_kcc_data, CAT_KCC_DATA_CATEGORY);\n+\t\tp->mp_kcc_data_id =\n+\t\t\tregister_query_field(p->mp_kcc_data, CAT_KCC_DATA_ID);\n+\t}\n+\n+\tp->mp_cce_ctrl = module_query_register(p->m_cat, CAT_CCE_CTRL);\n+\tif (p->mp_cce_ctrl != NULL) {\n+\t\tp->mp_cce_addr =\n+\t\t\tregister_query_field(p->mp_cce_ctrl, CAT_CCE_CTRL_ADR);\n+\t\tp->mp_cce_cnt =\n+\t\t\tregister_query_field(p->mp_cce_ctrl, CAT_CCE_CTRL_CNT);\n+\t}\n+\tp->mp_cce_data = module_query_register(p->m_cat, CAT_CCE_DATA);\n+\tif (p->mp_cce_data != NULL) {\n+\t\tp->mp_cce_data_imm =\n+\t\t\tregister_query_field(p->mp_cce_data, CAT_CCE_DATA_IMM);\n+\t\tp->mp_cce_data_ind =\n+\t\t\tregister_query_field(p->mp_cce_data, CAT_CCE_DATA_IND);\n+\t}\n+\n+\tp->mp_ccs_ctrl = module_query_register(p->m_cat, CAT_CCS_CTRL);\n+\tif (p->mp_ccs_ctrl != NULL) {\n+\t\tp->mp_ccs_addr =\n+\t\t\tregister_query_field(p->mp_ccs_ctrl, CAT_CCS_CTRL_ADR);\n+\t\tp->mp_ccs_cnt =\n+\t\t\tregister_query_field(p->mp_ccs_ctrl, CAT_CCS_CTRL_CNT);\n+\t}\n+\tp->mp_ccs_data = module_query_register(p->m_cat, CAT_CCS_DATA);\n+\tif (p->mp_ccs_data != NULL) {\n+\t\tp->mp_ccs_data_cor_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_COR_EN);\n+\t\tp->mp_ccs_data_cor =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_COR);\n+\t\tp->mp_ccs_data_hsh_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_HSH_EN);\n+\t\tp->mp_ccs_data_hsh =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_HSH);\n+\t\tp->mp_ccs_data_qsl_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_QSL_EN);\n+\t\tp->mp_ccs_data_qsl =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_QSL);\n+\t\tp->mp_ccs_data_ipf_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_IPF_EN);\n+\t\tp->mp_ccs_data_ipf =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_IPF);\n+\t\tp->mp_ccs_data_slc_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_SLC_EN);\n+\t\tp->mp_ccs_data_slc =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_SLC);\n+\t\tp->mp_ccs_data_pdb_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_PDB_EN);\n+\t\tp->mp_ccs_data_pdb =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_PDB);\n+\t\tp->mp_ccs_data_msk_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_MSK_EN);\n+\t\tp->mp_ccs_data_msk =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_MSK);\n+\t\tp->mp_ccs_data_hst_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_HST_EN);\n+\t\tp->mp_ccs_data_hst =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_HST);\n+\t\tp->mp_ccs_data_epp_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_EPP_EN);\n+\t\tp->mp_ccs_data_epp =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_EPP);\n+\t\tp->mp_ccs_data_tpe_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_TPE_EN);\n+\t\tp->mp_ccs_data_tpe =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_TPE);\n+\t\tp->mp_ccs_data_rrb_en =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_RRB_EN);\n+\t\tp->mp_ccs_data_rrb =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_RRB);\n+\t\tp->mp_ccs_data_sb0_type =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_SB0_TYPE);\n+\t\tp->mp_ccs_data_sb0_data =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_SB0_DATA);\n+\t\tp->mp_ccs_data_sb1_type =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_SB1_TYPE);\n+\t\tp->mp_ccs_data_sb1_data =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_SB1_DATA);\n+\t\tp->mp_ccs_data_sb2_type =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_SB2_TYPE);\n+\t\tp->mp_ccs_data_sb2_data =\n+\t\t\tregister_query_field(p->mp_ccs_data, CAT_CCS_DATA_SB2_DATA);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* CFN */\n+void cat_nthw_cfn_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_addr, val);\n+}\n+\n+void r(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_cnt, val);\n+}\n+\n+void cat_nthw_cfn_enable(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_enable, val);\n+}\n+\n+void cat_nthw_cfn_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_inv, val);\n+}\n+\n+void cat_nthw_cfn_ptc_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_inv, val);\n+}\n+\n+void cat_nthw_cfn_ptc_isl(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_isl, val);\n+}\n+\n+void cat_nthw_cfn_ptc_mac(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_mac, val);\n+}\n+\n+void cat_nthw_cfn_ptc_l2(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_l2, val);\n+}\n+\n+void cat_nthw_cfn_ptc_vn_tag(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_vn_tag, val);\n+}\n+\n+void cat_nthw_cfn_ptc_vlan(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_vlan, val);\n+}\n+\n+void cat_nthw_cfn_ptc_mpls(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_mpls, val);\n+}\n+\n+void cat_nthw_cfn_ptc_l3(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_l3, val);\n+}\n+\n+void cat_nthw_cfn_ptc_frag(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_frag, val);\n+}\n+\n+void cat_nthw_cfn_ptc_ip_prot(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_ip_prot, val);\n+}\n+\n+void cat_nthw_cfn_ptc_l4(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_l4, val);\n+}\n+\n+void cat_nthw_cfn_ptc_tunnel(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_tunnel, val);\n+}\n+\n+void cat_nthw_cfn_ptc_tnl_l2(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_tnl_l2, val);\n+}\n+\n+void cat_nthw_cfn_ptc_tnl_vlan(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_tnl_vlan, val);\n+}\n+\n+void cat_nthw_cfn_ptc_tnl_mpls(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_tnl_mpls, val);\n+}\n+\n+void cat_nthw_cfn_ptc_tnl_l3(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_tnl_l3, val);\n+}\n+\n+void cat_nthw_cfn_ptc_tnl_frag(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_tnl_frag, val);\n+}\n+\n+void cat_nthw_cfn_ptc_tnl_ip_prot(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_tnl_ip_prot, val);\n+}\n+\n+void cat_nthw_cfn_ptc_tnl_l4(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_ptc_tnl_l4, val);\n+}\n+\n+void cat_nthw_cfn_ptc_cfp(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cfn_data_ptc_cfp);\n+\tfield_set_val32(p->mp_cfn_data_ptc_cfp, val);\n+}\n+\n+void cat_nthw_cfn_err_l3_cs(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cfn_data_err_l3_cs);\n+\tfield_set_val32(p->mp_cfn_data_err_l3_cs, val);\n+}\n+\n+void cat_nthw_cfn_err_l4_cs(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cfn_data_err_l4_cs);\n+\tfield_set_val32(p->mp_cfn_data_err_l4_cs, val);\n+}\n+\n+void cat_nthw_cfn_err_tnl_l3_cs(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cfn_data_err_tnl_l3_cs);\n+\tfield_set_val32(p->mp_cfn_data_err_tnl_l3_cs, val);\n+}\n+\n+void cat_nthw_cfn_err_tnl_l4_cs(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cfn_data_err_tnl_l4_cs);\n+\tfield_set_val32(p->mp_cfn_data_err_tnl_l4_cs, val);\n+}\n+\n+void cat_nthw_cfn_err_ttl_exp(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cfn_data_err_ttl_exp);\n+\tfield_set_val32(p->mp_cfn_data_err_ttl_exp, val);\n+}\n+\n+void cat_nthw_cfn_err_tnl_ttl_exp(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cfn_data_err_tnl_ttl_exp);\n+\tfield_set_val32(p->mp_cfn_data_err_tnl_ttl_exp, val);\n+}\n+\n+void cat_nthw_cfn_err_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_err_inv, val);\n+}\n+\n+void cat_nthw_cfn_err_cv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_err_cv, val);\n+}\n+\n+void cat_nthw_cfn_err_fcs(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_err_fcs, val);\n+}\n+\n+void cat_nthw_cfn_err_trunc(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_err_trunc, val);\n+}\n+\n+void cat_nthw_cfn_mac_port(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_mac_port, val);\n+}\n+\n+void cat_nthw_cfn_pm_cmp(const struct cat_nthw *p, const uint32_t *val)\n+{\n+\tfield_set_val(p->mp_cfn_data_pm_cmp, val, p->mp_cfn_data_pm_cmp->mn_words);\n+}\n+\n+void cat_nthw_cfn_pm_dct(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_pm_dct, val);\n+}\n+\n+void cat_nthw_cfn_pm_ext_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_pm_ext_inv, val);\n+}\n+\n+void cat_nthw_cfn_pm_cmb(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_pm_cmb, val);\n+}\n+\n+void cat_nthw_cfn_pm_and_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_pm_and_inv, val);\n+}\n+\n+void cat_nthw_cfn_pm_or_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_pm_or_inv, val);\n+}\n+\n+void cat_nthw_cfn_pm_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_pm_inv, val);\n+}\n+\n+void cat_nthw_cfn_lc(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_lc, val);\n+}\n+\n+void cat_nthw_cfn_lc_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_lc_inv, val);\n+}\n+\n+void cat_nthw_cfn_km0_or(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cfn_data_km0_or, val);\n+}\n+\n+void cat_nthw_cfn_km1_or(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cfn_data_km1_or);\n+\tfield_set_val32(p->mp_cfn_data_km1_or, val);\n+}\n+\n+void cat_nthw_cfn_flush(const struct cat_nthw *p)\n+{\n+\tregister_flush(p->mp_cfn_ctrl, 1);\n+\tregister_flush(p->mp_cfn_data, 1);\n+}\n+\n+void cat_nthw_kce_select(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_kce_addr[index], val);\n+}\n+\n+void cat_nthw_kce_cnt(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_kce_cnt[index], val);\n+}\n+\n+void cat_nthw_kce_enable(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_kce_data_enable[index], val);\n+}\n+\n+void cat_nthw_kce_flush(const struct cat_nthw *p, int index)\n+{\n+\tregister_flush(p->mp_kce_ctrl[index], 1);\n+\tregister_flush(p->mp_kce_data[index], 1);\n+}\n+\n+void cat_nthw_kcs_select(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_kcs_addr[index], val);\n+}\n+\n+void cat_nthw_kcs_cnt(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_kcs_cnt[index], val);\n+}\n+\n+void cat_nthw_kcs_category(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_kcs_data_category[index], val);\n+}\n+\n+void cat_nthw_kcs_flush(const struct cat_nthw *p, int index)\n+{\n+\tregister_flush(p->mp_kcs_ctrl[index], 1);\n+\tregister_flush(p->mp_kcs_data[index], 1);\n+}\n+\n+void cat_nthw_fte_select(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_fte_addr[index], val);\n+}\n+\n+void cat_nthw_fte_cnt(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_fte_cnt[index], val);\n+}\n+\n+void cat_nthw_fte_enable(const struct cat_nthw *p, int index, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_fte_data_enable[index], val);\n+}\n+\n+void cat_nthw_fte_flush(const struct cat_nthw *p, int index)\n+{\n+\tregister_flush(p->mp_fte_ctrl[index], 1);\n+\tregister_flush(p->mp_fte_data[index], 1);\n+}\n+\n+void cat_nthw_cte_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_addr, val);\n+}\n+\n+void cat_nthw_cte_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_cnt, val);\n+}\n+\n+void cat_nthw_cte_enable_col(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_data_col, val);\n+}\n+\n+void cat_nthw_cte_enable_cor(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_data_cor, val);\n+}\n+\n+void cat_nthw_cte_enable_hsh(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_data_hsh, val);\n+}\n+\n+void cat_nthw_cte_enable_qsl(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_data_qsl, val);\n+}\n+\n+void cat_nthw_cte_enable_ipf(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_data_ipf, val);\n+}\n+\n+void cat_nthw_cte_enable_slc(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_data_slc, val);\n+}\n+\n+void cat_nthw_cte_enable_pdb(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cte_data_pdb, val);\n+}\n+\n+void cat_nthw_cte_enable_msk(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cte_data_msk);\n+\tfield_set_val32(p->mp_cte_data_msk, val);\n+}\n+\n+void cat_nthw_cte_enable_hst(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cte_data_hst);\n+\tfield_set_val32(p->mp_cte_data_hst, val);\n+}\n+\n+void cat_nthw_cte_enable_epp(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cte_data_epp);\n+\tfield_set_val32(p->mp_cte_data_epp, val);\n+}\n+\n+void cat_nthw_cte_enable_tpe(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cte_data_tpe);\n+\tfield_set_val32(p->mp_cte_data_tpe, val);\n+}\n+\n+void cat_nthw_cte_enable_rrb(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cte_data_rrb);\n+\tfield_set_val32(p->mp_cte_data_rrb, val);\n+}\n+\n+void cat_nthw_cte_flush(const struct cat_nthw *p)\n+{\n+\tregister_flush(p->mp_cte_ctrl, 1);\n+\tregister_flush(p->mp_cte_data, 1);\n+}\n+\n+void cat_nthw_cts_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cts_addr, val);\n+}\n+\n+void cat_nthw_cts_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cts_cnt, val);\n+}\n+\n+void cat_nthw_cts_cat_a(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cts_data_cat_a, val);\n+}\n+\n+void cat_nthw_cts_cat_b(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cts_data_cat_b, val);\n+}\n+\n+void cat_nthw_cts_flush(const struct cat_nthw *p)\n+{\n+\tregister_flush(p->mp_cts_ctrl, 1);\n+\tregister_flush(p->mp_cts_data, 1);\n+}\n+\n+void cat_nthw_cot_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cot_addr, val);\n+}\n+\n+void cat_nthw_cot_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cot_cnt, val);\n+}\n+\n+void cat_nthw_cot_color(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cot_data_color, val);\n+}\n+\n+void cat_nthw_cot_km(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cot_data_km, val);\n+}\n+\n+void cat_nthw_cot_nfv_sb(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cot_data_nfv_sb);\n+\tfield_set_val32(p->mp_cot_data_nfv_sb, val);\n+}\n+\n+void cat_nthw_cot_flush(const struct cat_nthw *p)\n+{\n+\tregister_flush(p->mp_cot_ctrl, 1);\n+\tregister_flush(p->mp_cot_data, 1);\n+}\n+\n+void cat_nthw_cct_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cct_addr, val);\n+}\n+\n+void cat_nthw_cct_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cct_cnt, val);\n+}\n+\n+void cat_nthw_cct_color(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cct_data_color, val);\n+}\n+\n+void cat_nthw_cct_km(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cct_data_km, val);\n+}\n+\n+void cat_nthw_cct_flush(const struct cat_nthw *p)\n+{\n+\tregister_flush(p->mp_cct_ctrl, 1);\n+\tregister_flush(p->mp_cct_data, 1);\n+}\n+\n+void cat_nthw_exo_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_exo_addr, val);\n+}\n+\n+void cat_nthw_exo_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_exo_cnt, val);\n+}\n+\n+void cat_nthw_exo_dyn(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_exo_data_dyn, val);\n+}\n+\n+void cat_nthw_exo_ofs(const struct cat_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_exo_data_ofs, val);\n+}\n+\n+void cat_nthw_exo_flush(const struct cat_nthw *p)\n+{\n+\tregister_flush(p->mp_exo_ctrl, 1);\n+\tregister_flush(p->mp_exo_data, 1);\n+}\n+\n+void cat_nthw_rck_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rck_addr, val);\n+}\n+\n+void cat_nthw_rck_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rck_cnt, val);\n+}\n+\n+void cat_nthw_rck_data(const struct cat_nthw *p, uint32_t val)\n+{\n+\tregister_set_val(p->mp_rck_data, &val, 1);\n+\tregister_make_dirty(p->mp_rck_data);\n+}\n+\n+void cat_nthw_rck_flush(const struct cat_nthw *p)\n+{\n+\tregister_flush(p->mp_rck_ctrl, 1);\n+\tregister_flush(p->mp_rck_data, 1);\n+}\n+\n+void cat_nthw_len_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_len_addr, val);\n+}\n+\n+void cat_nthw_len_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_len_cnt, val);\n+}\n+\n+void cat_nthw_len_lower(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_len_data_lower, val);\n+}\n+\n+void cat_nthw_len_upper(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_len_data_upper, val);\n+}\n+\n+void cat_nthw_len_dyn1(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_len_data_dyn1, val);\n+}\n+\n+void cat_nthw_len_dyn2(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_len_data_dyn2, val);\n+}\n+\n+void cat_nthw_len_inv(const struct cat_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_len_data_inv, val);\n+}\n+\n+void cat_nthw_len_flush(const struct cat_nthw *p)\n+{\n+\tregister_flush(p->mp_len_ctrl, 1);\n+\tregister_flush(p->mp_len_data, 1);\n+}\n+\n+void cat_nthw_kcc_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_kcc_addr);\n+\tfield_set_val32(p->mp_kcc_addr, val);\n+}\n+\n+void cat_nthw_kcc_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_kcc_cnt);\n+\tfield_set_val32(p->mp_kcc_cnt, val);\n+}\n+\n+void cat_nthw_kcc_key(const struct cat_nthw *p, uint32_t *val)\n+{\n+\tassert(p->mp_kcc_data_key);\n+\tfield_set_val(p->mp_kcc_data_key, val, 2);\n+}\n+\n+void cat_nthw_kcc_category(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_kcc_data_category);\n+\tfield_set_val32(p->mp_kcc_data_category, val);\n+}\n+\n+void cat_nthw_kcc_id(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_kcc_data_id);\n+\tfield_set_val32(p->mp_kcc_data_id, val);\n+}\n+\n+void cat_nthw_kcc_flush(const struct cat_nthw *p)\n+{\n+\tassert(p->mp_kcc_ctrl);\n+\tassert(p->mp_kcc_data);\n+\tregister_flush(p->mp_kcc_ctrl, 1);\n+\tregister_flush(p->mp_kcc_data, 1);\n+}\n+\n+void cat_nthw_cce_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cce_addr);\n+\tfield_set_val32(p->mp_cce_addr, val);\n+}\n+\n+void cat_nthw_cce_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cce_cnt);\n+\tfield_set_val32(p->mp_cce_cnt, val);\n+}\n+\n+void cat_nthw_cce_data_imm(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cce_data_imm);\n+\tfield_set_val32(p->mp_cce_data_imm, val);\n+}\n+\n+void cat_nthw_cce_data_ind(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_cce_data_ind);\n+\tfield_set_val32(p->mp_cce_data_ind, val);\n+}\n+\n+void cat_nthw_cce_flush(const struct cat_nthw *p)\n+{\n+\tassert(p->mp_cce_ctrl);\n+\tassert(p->mp_cce_data);\n+\tregister_flush(p->mp_cce_ctrl, 1);\n+\tregister_flush(p->mp_cce_data, 1);\n+}\n+\n+void cat_nthw_ccs_select(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_ccs_addr);\n+\tfield_set_val32(p->mp_ccs_addr, val);\n+}\n+\n+void cat_nthw_ccs_cnt(const struct cat_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_ccs_cnt);\n+\tfield_set_val32(p->mp_ccs_cnt, val);\n+}\n+\n+#define CATNTHW_CCS_SET(name)                                             \\\n+\tvoid cat_nthw_ccs_data_##name(const struct cat_nthw *p, uint32_t val) \\\n+\t{                                                                 \\\n+\t\tassert(p->mp_ccs_data_##name);                               \\\n+\t\tfield_set_val32(p->mp_ccs_data_##name, val);                  \\\n+\t}\n+\n+CATNTHW_CCS_SET(cor_en);\n+CATNTHW_CCS_SET(cor);\n+CATNTHW_CCS_SET(hsh_en);\n+CATNTHW_CCS_SET(hsh);\n+CATNTHW_CCS_SET(qsl_en);\n+CATNTHW_CCS_SET(qsl);\n+CATNTHW_CCS_SET(ipf_en);\n+CATNTHW_CCS_SET(ipf);\n+CATNTHW_CCS_SET(slc_en);\n+CATNTHW_CCS_SET(slc);\n+CATNTHW_CCS_SET(pdb_en);\n+CATNTHW_CCS_SET(pdb);\n+CATNTHW_CCS_SET(msk_en);\n+CATNTHW_CCS_SET(msk);\n+CATNTHW_CCS_SET(hst_en);\n+CATNTHW_CCS_SET(hst);\n+CATNTHW_CCS_SET(epp_en);\n+CATNTHW_CCS_SET(epp);\n+CATNTHW_CCS_SET(tpe_en);\n+CATNTHW_CCS_SET(tpe);\n+CATNTHW_CCS_SET(rrb_en);\n+CATNTHW_CCS_SET(rrb);\n+CATNTHW_CCS_SET(sb0_type);\n+CATNTHW_CCS_SET(sb0_data);\n+CATNTHW_CCS_SET(sb1_type);\n+CATNTHW_CCS_SET(sb1_data);\n+CATNTHW_CCS_SET(sb2_type);\n+CATNTHW_CCS_SET(sb2_data);\n+\n+void cat_nthw_ccs_flush(const struct cat_nthw *p)\n+{\n+\tassert(p->mp_ccs_ctrl);\n+\tassert(p->mp_ccs_data);\n+\tregister_flush(p->mp_ccs_ctrl, 1);\n+\tregister_flush(p->mp_ccs_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_cat.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_cat.h\nnew file mode 100644\nindex 0000000000..41ac891a93\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_cat.h\n@@ -0,0 +1,372 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_CAT_H__\n+#define __FLOW_NTHW_CAT_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct cat_nthw;\n+\n+typedef struct cat_nthw cat_nthw_t;\n+\n+struct cat_nthw *cat_nthw_new(void);\n+void cat_nthw_delete(struct cat_nthw *p);\n+int cat_nthw_init(struct cat_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int cat_nthw_setup(struct cat_nthw *p, int n_idx, int n_idx_cnt);\n+void cat_nthw_set_debug_mode(struct cat_nthw *p, unsigned int n_debug_mode);\n+\n+/* CFN */\n+void cat_nthw_cfn_select(const struct cat_nthw *p, uint32_t val);\n+void r(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_enable(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_isl(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_cfp(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_mac(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_l2(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_vn_tag(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_vlan(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_mpls(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_l3(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_frag(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_ip_prot(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_l4(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_tunnel(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_tnl_l2(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_tnl_vlan(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_tnl_mpls(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_tnl_l3(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_tnl_frag(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_tnl_ip_prot(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_ptc_tnl_l4(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_cv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_fcs(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_trunc(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_l3_cs(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_l4_cs(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_tnl_l3_cs(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_tnl_l4_cs(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_ttl_exp(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_err_tnl_ttl_exp(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_mac_port(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_pm_cmp(const struct cat_nthw *p, const uint32_t *val);\n+void cat_nthw_cfn_pm_dct(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_pm_ext_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_pm_cmb(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_pm_and_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_pm_or_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_pm_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_lc(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_lc_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_km0_or(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_km1_or(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cfn_flush(const struct cat_nthw *p);\n+/* KCE 0/1 */\n+void cat_nthw_kce_select(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_kce_cnt(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_kce_enable(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_kce_flush(const struct cat_nthw *p, int index);\n+/* KCS 0/1 */\n+void cat_nthw_kcs_select(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_kcs_cnt(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_kcs_category(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_kcs_flush(const struct cat_nthw *p, int index);\n+/* FTE 0/1 */\n+void cat_nthw_fte_select(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_fte_cnt(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_fte_enable(const struct cat_nthw *p, int index, uint32_t val);\n+void cat_nthw_fte_flush(const struct cat_nthw *p, int index);\n+/* CTE */\n+void cat_nthw_cte_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_col(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_cor(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_hsh(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_qsl(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_ipf(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_slc(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_pdb(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_msk(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_hst(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_epp(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_tpe(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_enable_rrb(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cte_flush(const struct cat_nthw *p);\n+/* CTS */\n+void cat_nthw_cts_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cts_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cts_flush(const struct cat_nthw *p);\n+void cat_nthw_cts_cat_a(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cts_cat_b(const struct cat_nthw *p, uint32_t val);\n+/* COT */\n+void cat_nthw_cot_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cot_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cot_color(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cot_km(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cot_nfv_sb(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cot_flush(const struct cat_nthw *p);\n+/* CCT */\n+void cat_nthw_cct_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cct_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cct_color(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cct_km(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cct_flush(const struct cat_nthw *p);\n+/* EXO */\n+void cat_nthw_exo_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_exo_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_exo_dyn(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_exo_ofs(const struct cat_nthw *p, int32_t val);\n+void cat_nthw_exo_flush(const struct cat_nthw *p);\n+/* RCK */\n+void cat_nthw_rck_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_rck_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_rck_data(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_rck_flush(const struct cat_nthw *p);\n+/* LEN */\n+void cat_nthw_len_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_len_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_len_lower(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_len_upper(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_len_dyn1(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_len_dyn2(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_len_inv(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_len_flush(const struct cat_nthw *p);\n+/* KCC */\n+void cat_nthw_kcc_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_kcc_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_kcc_key(const struct cat_nthw *p, uint32_t *val);\n+void cat_nthw_kcc_category(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_kcc_id(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_kcc_flush(const struct cat_nthw *p);\n+/* CCE */\n+void cat_nthw_cce_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cce_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cce_data_imm(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cce_data_ind(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_cce_flush(const struct cat_nthw *p);\n+/* CCS */\n+void cat_nthw_ccs_select(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_cnt(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_cor_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_cor(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_hsh_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_hsh(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_qsl_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_qsl(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_ipf_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_ipf(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_slc_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_slc(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_pdb_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_pdb(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_msk_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_msk(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_hst_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_hst(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_epp_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_epp(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_tpe_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_tpe(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_rrb_en(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_rrb(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_sb0_type(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_sb0_data(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_sb1_type(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_sb1_data(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_sb2_type(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_data_sb2_data(const struct cat_nthw *p, uint32_t val);\n+void cat_nthw_ccs_flush(const struct cat_nthw *p);\n+\n+struct cat_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\tnt_module_t *m_cat;\n+\tint m_km_if_cnt;\n+\n+\tnt_register_t *mp_cfn_ctrl;\n+\tnt_field_t *mp_cfn_addr;\n+\tnt_field_t *mp_cfn_cnt;\n+\tnt_register_t *mp_cfn_data;\n+\tnt_field_t *mp_cfn_data_enable;\n+\tnt_field_t *mp_cfn_data_inv;\n+\tnt_field_t *mp_cfn_data_ptc_inv;\n+\tnt_field_t *mp_cfn_data_ptc_isl;\n+\tnt_field_t *mp_cfn_data_ptc_cfp;\n+\tnt_field_t *mp_cfn_data_ptc_mac;\n+\tnt_field_t *mp_cfn_data_ptc_l2;\n+\tnt_field_t *mp_cfn_data_ptc_vn_tag;\n+\tnt_field_t *mp_cfn_data_ptc_vlan;\n+\tnt_field_t *mp_cfn_data_ptc_mpls;\n+\tnt_field_t *mp_cfn_data_ptc_l3;\n+\tnt_field_t *mp_cfn_data_ptc_frag;\n+\tnt_field_t *mp_cfn_data_ptc_ip_prot;\n+\tnt_field_t *mp_cfn_data_ptc_l4;\n+\tnt_field_t *mp_cfn_data_ptc_tunnel;\n+\tnt_field_t *mp_cfn_data_ptc_tnl_l2;\n+\tnt_field_t *mp_cfn_data_ptc_tnl_vlan;\n+\tnt_field_t *mp_cfn_data_ptc_tnl_mpls;\n+\tnt_field_t *mp_cfn_data_ptc_tnl_l3;\n+\tnt_field_t *mp_cfn_data_ptc_tnl_frag;\n+\tnt_field_t *mp_cfn_data_ptc_tnl_ip_prot;\n+\tnt_field_t *mp_cfn_data_ptc_tnl_l4;\n+\tnt_field_t *mp_cfn_data_err_inv;\n+\tnt_field_t *mp_cfn_data_err_cv;\n+\tnt_field_t *mp_cfn_data_err_fcs;\n+\tnt_field_t *mp_cfn_data_err_trunc;\n+\tnt_field_t *mp_cfn_data_err_l3_cs;\n+\tnt_field_t *mp_cfn_data_err_l4_cs;\n+\tnt_field_t *mp_cfn_data_err_tnl_l3_cs;\n+\tnt_field_t *mp_cfn_data_err_tnl_l4_cs;\n+\tnt_field_t *mp_cfn_data_err_ttl_exp;\n+\tnt_field_t *mp_cfn_data_err_tnl_ttl_exp;\n+\tnt_field_t *mp_cfn_data_mac_port;\n+\tnt_field_t *mp_cfn_data_pm_cmp;\n+\tnt_field_t *mp_cfn_data_pm_dct;\n+\tnt_field_t *mp_cfn_data_pm_ext_inv;\n+\tnt_field_t *mp_cfn_data_pm_cmb;\n+\tnt_field_t *mp_cfn_data_pm_and_inv;\n+\tnt_field_t *mp_cfn_data_pm_or_inv;\n+\tnt_field_t *mp_cfn_data_pm_inv;\n+\tnt_field_t *mp_cfn_data_lc;\n+\tnt_field_t *mp_cfn_data_lc_inv;\n+\tnt_field_t *mp_cfn_data_km0_or;\n+\tnt_field_t *mp_cfn_data_km1_or;\n+\n+\tnt_register_t *mp_kce_ctrl[2];\n+\tnt_field_t *mp_kce_addr[2];\n+\tnt_field_t *mp_kce_cnt[2];\n+\tnt_register_t *mp_kce_data[2];\n+\tnt_field_t *mp_kce_data_enable[2];\n+\n+\tnt_register_t *mp_kcs_ctrl[2];\n+\tnt_field_t *mp_kcs_addr[2];\n+\tnt_field_t *mp_kcs_cnt[2];\n+\tnt_register_t *mp_kcs_data[2];\n+\tnt_field_t *mp_kcs_data_category[2];\n+\n+\tnt_register_t *mp_fte_ctrl[2];\n+\tnt_field_t *mp_fte_addr[2];\n+\tnt_field_t *mp_fte_cnt[2];\n+\tnt_register_t *mp_fte_data[2];\n+\tnt_field_t *mp_fte_data_enable[2];\n+\n+\tnt_register_t *mp_cte_ctrl;\n+\tnt_field_t *mp_cte_addr;\n+\tnt_field_t *mp_cte_cnt;\n+\tnt_register_t *mp_cte_data;\n+\tnt_field_t *mp_cte_data_col;\n+\tnt_field_t *mp_cte_data_cor;\n+\tnt_field_t *mp_cte_data_hsh;\n+\tnt_field_t *mp_cte_data_qsl;\n+\tnt_field_t *mp_cte_data_ipf;\n+\tnt_field_t *mp_cte_data_slc;\n+\tnt_field_t *mp_cte_data_pdb;\n+\tnt_field_t *mp_cte_data_msk;\n+\tnt_field_t *mp_cte_data_hst;\n+\tnt_field_t *mp_cte_data_epp;\n+\tnt_field_t *mp_cte_data_tpe;\n+\tnt_field_t *mp_cte_data_rrb;\n+\n+\tnt_register_t *mp_cts_ctrl;\n+\tnt_field_t *mp_cts_addr;\n+\tnt_field_t *mp_cts_cnt;\n+\tnt_register_t *mp_cts_data;\n+\tnt_field_t *mp_cts_data_cat_a;\n+\tnt_field_t *mp_cts_data_cat_b;\n+\n+\tnt_register_t *mp_cot_ctrl;\n+\tnt_field_t *mp_cot_addr;\n+\tnt_field_t *mp_cot_cnt;\n+\tnt_register_t *mp_cot_data;\n+\tnt_field_t *mp_cot_data_color;\n+\tnt_field_t *mp_cot_data_km;\n+\tnt_field_t *mp_cot_data_nfv_sb;\n+\n+\tnt_register_t *mp_cct_ctrl;\n+\tnt_field_t *mp_cct_addr;\n+\tnt_field_t *mp_cct_cnt;\n+\tnt_register_t *mp_cct_data;\n+\tnt_field_t *mp_cct_data_color;\n+\tnt_field_t *mp_cct_data_km;\n+\n+\tnt_register_t *mp_exo_ctrl;\n+\tnt_field_t *mp_exo_addr;\n+\tnt_field_t *mp_exo_cnt;\n+\tnt_register_t *mp_exo_data;\n+\tnt_field_t *mp_exo_data_dyn;\n+\tnt_field_t *mp_exo_data_ofs;\n+\n+\tnt_register_t *mp_rck_ctrl;\n+\tnt_field_t *mp_rck_addr;\n+\tnt_field_t *mp_rck_cnt;\n+\tnt_register_t *mp_rck_data;\n+\n+\tnt_register_t *mp_len_ctrl;\n+\tnt_field_t *mp_len_addr;\n+\tnt_field_t *mp_len_cnt;\n+\tnt_register_t *mp_len_data;\n+\tnt_field_t *mp_len_data_lower;\n+\tnt_field_t *mp_len_data_upper;\n+\tnt_field_t *mp_len_data_dyn1;\n+\tnt_field_t *mp_len_data_dyn2;\n+\tnt_field_t *mp_len_data_inv;\n+\tnt_register_t *mp_kcc_ctrl;\n+\tnt_field_t *mp_kcc_addr;\n+\tnt_field_t *mp_kcc_cnt;\n+\n+\tnt_register_t *mp_kcc_data;\n+\tnt_field_t *mp_kcc_data_key;\n+\tnt_field_t *mp_kcc_data_category;\n+\tnt_field_t *mp_kcc_data_id;\n+\n+\tnt_register_t *mp_cce_ctrl;\n+\tnt_field_t *mp_cce_addr;\n+\tnt_field_t *mp_cce_cnt;\n+\n+\tnt_register_t *mp_cce_data;\n+\tnt_field_t *mp_cce_data_imm;\n+\tnt_field_t *mp_cce_data_ind;\n+\n+\tnt_register_t *mp_ccs_ctrl;\n+\tnt_field_t *mp_ccs_addr;\n+\tnt_field_t *mp_ccs_cnt;\n+\n+\tnt_register_t *mp_ccs_data;\n+\tnt_field_t *mp_ccs_data_cor_en;\n+\tnt_field_t *mp_ccs_data_cor;\n+\n+\tnt_field_t *mp_ccs_data_hsh_en;\n+\tnt_field_t *mp_ccs_data_hsh;\n+\tnt_field_t *mp_ccs_data_qsl_en;\n+\tnt_field_t *mp_ccs_data_qsl;\n+\tnt_field_t *mp_ccs_data_ipf_en;\n+\tnt_field_t *mp_ccs_data_ipf;\n+\tnt_field_t *mp_ccs_data_slc_en;\n+\tnt_field_t *mp_ccs_data_slc;\n+\tnt_field_t *mp_ccs_data_pdb_en;\n+\tnt_field_t *mp_ccs_data_pdb;\n+\tnt_field_t *mp_ccs_data_msk_en;\n+\tnt_field_t *mp_ccs_data_msk;\n+\tnt_field_t *mp_ccs_data_hst_en;\n+\tnt_field_t *mp_ccs_data_hst;\n+\tnt_field_t *mp_ccs_data_epp_en;\n+\tnt_field_t *mp_ccs_data_epp;\n+\tnt_field_t *mp_ccs_data_tpe_en;\n+\tnt_field_t *mp_ccs_data_tpe;\n+\tnt_field_t *mp_ccs_data_rrb_en;\n+\tnt_field_t *mp_ccs_data_rrb;\n+\tnt_field_t *mp_ccs_data_sb0_type;\n+\tnt_field_t *mp_ccs_data_sb0_data;\n+\tnt_field_t *mp_ccs_data_sb1_type;\n+\tnt_field_t *mp_ccs_data_sb1_data;\n+\tnt_field_t *mp_ccs_data_sb2_type;\n+\tnt_field_t *mp_ccs_data_sb2_data;\n+};\n+\n+#endif /* __FLOW_NTHW_CAT_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_csu.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_csu.c\nnew file mode 100644\nindex 0000000000..5a7f90ad69\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_csu.c\n@@ -0,0 +1,146 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_csu.h\"\n+\n+#include <stdlib.h>\n+#include <string.h>\n+\n+void csu_nthw_set_debug_mode(struct csu_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_csu, n_debug_mode);\n+}\n+\n+struct csu_nthw *csu_nthw_new(void)\n+{\n+\tstruct csu_nthw *p = malloc(sizeof(struct csu_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\treturn p;\n+}\n+\n+void csu_nthw_delete(struct csu_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int csu_nthw_init(struct csu_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_CSU, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Csu %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_csu = p_mod;\n+\n+\tp->mp_rcp_ctrl = module_get_register(p->m_csu, CSU_RCP_CTRL);\n+\tp->mp_rcp_ctrl_adr = register_get_field(p->mp_rcp_ctrl, CSU_RCP_CTRL_ADR);\n+\tp->mp_rcp_ctrl_cnt = register_get_field(p->mp_rcp_ctrl, CSU_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_csu, CSU_RCP_DATA);\n+\tp->mp_rcp_data_ol3_cmd =\n+\t\tregister_get_field(p->mp_rcp_data, CSU_RCP_DATA_OL3_CMD);\n+\tp->mp_rcp_data_ol4_cmd =\n+\t\tregister_get_field(p->mp_rcp_data, CSU_RCP_DATA_OL4_CMD);\n+\tp->mp_rcp_data_il3_cmd =\n+\t\tregister_get_field(p->mp_rcp_data, CSU_RCP_DATA_IL3_CMD);\n+\tp->mp_rcp_data_il4_cmd =\n+\t\tregister_get_field(p->mp_rcp_data, CSU_RCP_DATA_IL4_CMD);\n+\n+\treturn 0;\n+}\n+\n+void csu_nthw_rcp_select(const struct csu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_ctrl_adr, val);\n+}\n+\n+void csu_nthw_rcp_cnt(const struct csu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_ctrl_cnt, val);\n+}\n+\n+void csu_nthw_rcp_outer_l3_cmd(const struct csu_nthw *p, uint32_t val)\n+{\n+\t/*\n+\t * Select L3 calc method for outer layer3.\n+\t * 0: Do not touch checksum field.\n+\t * 1: Check, but do not touch checksum field.\n+\t * 2: Insert checksum header value for BAD checksum.\n+\t * 3: Insert checksum header value for GOOD checksum.\n+\t */\n+\tfield_set_val32(p->mp_rcp_data_ol3_cmd, val);\n+}\n+\n+void csu_nthw_rcp_outer_l4_cmd(const struct csu_nthw *p, uint32_t val)\n+{\n+\t/*\n+\t * Select L4 calc method for outer layer4.\n+\t * 0: Do not touch checksum field.\n+\t * 1: Check, but do not touch checksum field.\n+\t * 2: Insert checksum header value for BAD checksum.\n+\t * 3: Insert checksum header value for GOOD checksum.\n+\t * 4: Set UDP checksum value of ZERO for both IPv4/IPv6, set good checksum for TCP.\n+\t * 5: Set UDP checksum value of ZERO for IPv4, set good checksum for TCP.\n+\t * 6: Set UDP checksum value of ZERO for outer tunnel when tunnel is IPv4/IPv6 and UDP,\n+\t *    otherwise GOOD checksum.\n+\t * 7: Set UDP checksum value of ZERO for outer tunnel when tunnel is IPv4 and UDP, otherwise\n+\t *    GOOD checksum.\n+\t */\n+\tfield_set_val32(p->mp_rcp_data_ol4_cmd, val);\n+}\n+\n+void csu_nthw_rcp_inner_l3_cmd(const struct csu_nthw *p, uint32_t val)\n+{\n+\t/*\n+\t * Select L3 calc method for inner layer3 (tunneled).\n+\t * 0: Do not touch checksum field.\n+\t * 1: Check, but do not touch checksum field.\n+\t * 2: Insert checksum header value for BAD checksum.\n+\t * 3: Insert checksum header value for GOOD checksum.\n+\t */\n+\tfield_set_val32(p->mp_rcp_data_il3_cmd, val);\n+}\n+\n+void csu_nthw_rcp_inner_l4_cmd(const struct csu_nthw *p, uint32_t val)\n+{\n+\t/*\n+\t * Select L4 calc method for inner layer4 (tunneled).\n+\t * 0: Do not touch checksum field.\n+\t * 1: Check, but do not touch checksum field.\n+\t * 2: Insert checksum header value for BAD checksum.\n+\t * 3: Insert checksum header value for GOOD checksum.\n+\t * 4: Set UDP checksum value of ZERO for both IPv4/IPv6, set good checksum for TCP.\n+\t * 5: Set UDP checksum value of ZERO for IPv4, set good checksum for TCP.\n+\t * 6: Set UDP checksum value of ZERO for outer tunnel when tunnel is IPv4/IPv6 and UDP,\n+\t *    otherwise GOOD checksum.\n+\t * 7: Set UDP checksum value of ZERO for outer tunnel when tunnel is IPv4 and UDP, otherwise\n+\t *    GOOD checksum.\n+\t */\n+\tfield_set_val32(p->mp_rcp_data_il4_cmd, val);\n+}\n+\n+void csu_nthw_rcp_flush(const struct csu_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_csu.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_csu.h\nnew file mode 100644\nindex 0000000000..6cb0e1f781\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_csu.h\n@@ -0,0 +1,42 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef _FLOW_NTHW_CSU_H_\n+#define _FLOW_NTHW_CSU_H_\n+\n+#include <stdint.h>\n+#include \"nthw_fpga_model.h\"\n+\n+struct csu_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_csu;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_ctrl_adr;\n+\tnt_field_t *mp_rcp_ctrl_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_ol3_cmd;\n+\tnt_field_t *mp_rcp_data_ol4_cmd;\n+\tnt_field_t *mp_rcp_data_il3_cmd;\n+\tnt_field_t *mp_rcp_data_il4_cmd;\n+};\n+\n+struct csu_nthw *csu_nthw_new(void);\n+void csu_nthw_delete(struct csu_nthw *p);\n+int csu_nthw_init(struct csu_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int csu_nthw_setup(struct csu_nthw *p, int n_idx, int n_idx_cnt);\n+void csu_nthw_set_debug_mode(struct csu_nthw *p, unsigned int n_debug_mode);\n+\n+void csu_nthw_rcp_select(const struct csu_nthw *p, uint32_t val);\n+void csu_nthw_rcp_cnt(const struct csu_nthw *p, uint32_t val);\n+void csu_nthw_rcp_outer_l3_cmd(const struct csu_nthw *p, uint32_t val);\n+void csu_nthw_rcp_outer_l4_cmd(const struct csu_nthw *p, uint32_t val);\n+void csu_nthw_rcp_inner_l3_cmd(const struct csu_nthw *p, uint32_t val);\n+void csu_nthw_rcp_inner_l4_cmd(const struct csu_nthw *p, uint32_t val);\n+void csu_nthw_rcp_flush(const struct csu_nthw *p);\n+\n+#endif /* _FLOW_NTHW_CSU_H_ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_flm.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_flm.c\nnew file mode 100644\nindex 0000000000..4549898cc1\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_flm.c\n@@ -0,0 +1,1140 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+#include \"nthw_rac.h\"\n+\n+#include \"flow_nthw_flm.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+struct flm_nthw *flm_nthw_new(void)\n+{\n+\tstruct flm_nthw *p = malloc(sizeof(struct flm_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void flm_nthw_delete(struct flm_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+void flm_nthw_set_debug_mode(struct flm_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_flm, n_debug_mode);\n+}\n+\n+int flm_nthw_init(struct flm_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_FLM, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Flm %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_rac = p_fpga->p_fpga_info->mp_nthw_rac;\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_flm = p_mod;\n+\n+\tp->mp_control = module_get_register(p->m_flm, FLM_CONTROL);\n+\tp->mp_control_enable =\n+\t\tregister_get_field(p->mp_control, FLM_CONTROL_ENABLE);\n+\tp->mp_control_init = register_get_field(p->mp_control, FLM_CONTROL_INIT);\n+\tp->mp_control_lds = register_get_field(p->mp_control, FLM_CONTROL_LDS);\n+\tp->mp_control_lfs = register_get_field(p->mp_control, FLM_CONTROL_LFS);\n+\tp->mp_control_lis = register_get_field(p->mp_control, FLM_CONTROL_LIS);\n+\tp->mp_control_uds = register_get_field(p->mp_control, FLM_CONTROL_UDS);\n+\tp->mp_control_uis = register_get_field(p->mp_control, FLM_CONTROL_UIS);\n+\tp->mp_control_rds = register_get_field(p->mp_control, FLM_CONTROL_RDS);\n+\tp->mp_control_ris = register_get_field(p->mp_control, FLM_CONTROL_RIS);\n+\tp->mp_control_pds = register_query_field(p->mp_control, FLM_CONTROL_PDS);\n+\tp->mp_control_pis = register_query_field(p->mp_control, FLM_CONTROL_PIS);\n+\tp->mp_control_crcwr = register_get_field(p->mp_control, FLM_CONTROL_CRCWR);\n+\tp->mp_control_crcrd = register_get_field(p->mp_control, FLM_CONTROL_CRCRD);\n+\tp->mp_control_rbl = register_get_field(p->mp_control, FLM_CONTROL_RBL);\n+\tp->mp_control_eab = register_get_field(p->mp_control, FLM_CONTROL_EAB);\n+\tp->mp_control_split_sdram_usage =\n+\t\tregister_get_field(p->mp_control, FLM_CONTROL_SPLIT_SDRAM_USAGE);\n+\n+\tp->mp_status = module_get_register(p->m_flm, FLM_STATUS);\n+\tp->mp_status_calibdone =\n+\t\tregister_get_field(p->mp_status, FLM_STATUS_CALIBDONE);\n+\tp->mp_status_initdone =\n+\t\tregister_get_field(p->mp_status, FLM_STATUS_INITDONE);\n+\tp->mp_status_idle = register_get_field(p->mp_status, FLM_STATUS_IDLE);\n+\tp->mp_status_critical =\n+\t\tregister_get_field(p->mp_status, FLM_STATUS_CRITICAL);\n+\tp->mp_status_panic = register_get_field(p->mp_status, FLM_STATUS_PANIC);\n+\tp->mp_status_crcerr = register_get_field(p->mp_status, FLM_STATUS_CRCERR);\n+\tp->mp_status_eft_bp = register_get_field(p->mp_status, FLM_STATUS_EFT_BP);\n+\n+\tp->mp_timeout = module_get_register(p->m_flm, FLM_TIMEOUT);\n+\tp->mp_timeout_t = register_get_field(p->mp_timeout, FLM_TIMEOUT_T);\n+\n+\tp->mp_scrub = module_get_register(p->m_flm, FLM_SCRUB);\n+\tp->mp_scrub_i = register_get_field(p->mp_scrub, FLM_SCRUB_I);\n+\n+\tp->mp_load_bin = module_get_register(p->m_flm, FLM_LOAD_BIN);\n+\tp->mp_load_bin_bin = register_get_field(p->mp_load_bin, FLM_LOAD_BIN_BIN);\n+\n+\tp->mp_load_pps = module_get_register(p->m_flm, FLM_LOAD_PPS);\n+\tp->mp_load_pps_pps = register_get_field(p->mp_load_pps, FLM_LOAD_PPS_PPS);\n+\n+\tp->mp_load_lps = module_get_register(p->m_flm, FLM_LOAD_LPS);\n+\tp->mp_load_lps_lps = register_get_field(p->mp_load_lps, FLM_LOAD_LPS_LPS);\n+\n+\tp->mp_load_aps = module_get_register(p->m_flm, FLM_LOAD_APS);\n+\tp->mp_load_aps_aps = register_get_field(p->mp_load_aps, FLM_LOAD_APS_APS);\n+\n+\tp->mp_prio = module_get_register(p->m_flm, FLM_PRIO);\n+\tp->mp_prio_limit0 = register_get_field(p->mp_prio, FLM_PRIO_LIMIT0);\n+\tp->mp_prio_ft0 = register_get_field(p->mp_prio, FLM_PRIO_FT0);\n+\tp->mp_prio_limit1 = register_get_field(p->mp_prio, FLM_PRIO_LIMIT1);\n+\tp->mp_prio_ft1 = register_get_field(p->mp_prio, FLM_PRIO_FT1);\n+\tp->mp_prio_limit2 = register_get_field(p->mp_prio, FLM_PRIO_LIMIT2);\n+\tp->mp_prio_ft2 = register_get_field(p->mp_prio, FLM_PRIO_FT2);\n+\tp->mp_prio_limit3 = register_get_field(p->mp_prio, FLM_PRIO_LIMIT3);\n+\tp->mp_prio_ft3 = register_get_field(p->mp_prio, FLM_PRIO_FT3);\n+\n+\tp->mp_pst_ctrl = module_get_register(p->m_flm, FLM_PST_CTRL);\n+\tp->mp_pst_ctrl_adr = register_get_field(p->mp_pst_ctrl, FLM_PST_CTRL_ADR);\n+\tp->mp_pst_ctrl_cnt = register_get_field(p->mp_pst_ctrl, FLM_PST_CTRL_CNT);\n+\tp->mp_pst_data = module_get_register(p->m_flm, FLM_PST_DATA);\n+\tp->mp_pst_data_bp = register_get_field(p->mp_pst_data, FLM_PST_DATA_BP);\n+\tp->mp_pst_data_pp = register_get_field(p->mp_pst_data, FLM_PST_DATA_PP);\n+\tp->mp_pst_data_tp = register_get_field(p->mp_pst_data, FLM_PST_DATA_TP);\n+\n+\tp->mp_rcp_ctrl = module_get_register(p->m_flm, FLM_RCP_CTRL);\n+\tp->mp_rcp_ctrl_adr = register_get_field(p->mp_rcp_ctrl, FLM_RCP_CTRL_ADR);\n+\tp->mp_rcp_ctrl_cnt = register_get_field(p->mp_rcp_ctrl, FLM_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_flm, FLM_RCP_DATA);\n+\tp->mp_rcp_data_lookup =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_LOOKUP);\n+\tp->mp_rcp_data_qw0_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_QW0_DYN);\n+\tp->mp_rcp_data_qw0_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_QW0_OFS);\n+\tp->mp_rcp_data_qw0_sel =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_QW0_SEL);\n+\tp->mp_rcp_data_qw4_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_QW4_DYN);\n+\tp->mp_rcp_data_qw4_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_QW4_OFS);\n+\tp->mp_rcp_data_sw8_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_SW8_DYN);\n+\tp->mp_rcp_data_sw8_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_SW8_OFS);\n+\tp->mp_rcp_data_sw8_sel =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_SW8_SEL);\n+\tp->mp_rcp_data_sw9_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_SW9_DYN);\n+\tp->mp_rcp_data_sw9_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_SW9_OFS);\n+\tp->mp_rcp_data_mask = register_get_field(p->mp_rcp_data, FLM_RCP_DATA_MASK);\n+\tp->mp_rcp_data_kid = register_get_field(p->mp_rcp_data, FLM_RCP_DATA_KID);\n+\tp->mp_rcp_data_opn = register_get_field(p->mp_rcp_data, FLM_RCP_DATA_OPN);\n+\tp->mp_rcp_data_ipn = register_get_field(p->mp_rcp_data, FLM_RCP_DATA_IPN);\n+\tp->mp_rcp_data_byt_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_BYT_DYN);\n+\tp->mp_rcp_data_byt_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_BYT_OFS);\n+\tp->mp_rcp_data_txplm = register_get_field(p->mp_rcp_data, FLM_RCP_DATA_TXPLM);\n+\tp->mp_rcp_data_auto_ipv4_mask =\n+\t\tregister_get_field(p->mp_rcp_data, FLM_RCP_DATA_AUTO_IPV4_MASK);\n+\n+\tp->mp_buf_ctrl = module_get_register(p->m_flm, FLM_BUF_CTRL);\n+\n+\tp->mp_lrn_data = module_get_register(p->m_flm, FLM_LRN_DATA);\n+\tp->mp_inf_data = module_get_register(p->m_flm, FLM_INF_DATA);\n+\tp->mp_sta_data = module_get_register(p->m_flm, FLM_STA_DATA);\n+\n+\tp->mp_stat_lrn_done = module_get_register(p->m_flm, FLM_STAT_LRN_DONE);\n+\tp->mp_stat_lrn_done_cnt =\n+\t\tregister_get_field(p->mp_stat_lrn_done, FLM_STAT_LRN_DONE_CNT);\n+\n+\tp->mp_stat_lrn_ignore = module_get_register(p->m_flm, FLM_STAT_LRN_IGNORE);\n+\tp->mp_stat_lrn_ignore_cnt =\n+\t\tregister_get_field(p->mp_stat_lrn_ignore, FLM_STAT_LRN_IGNORE_CNT);\n+\n+\tp->mp_stat_lrn_fail = module_get_register(p->m_flm, FLM_STAT_LRN_FAIL);\n+\tp->mp_stat_lrn_fail_cnt =\n+\t\tregister_get_field(p->mp_stat_lrn_fail, FLM_STAT_LRN_FAIL_CNT);\n+\n+\tp->mp_stat_unl_done = module_get_register(p->m_flm, FLM_STAT_UNL_DONE);\n+\tp->mp_stat_unl_done_cnt =\n+\t\tregister_get_field(p->mp_stat_unl_done, FLM_STAT_UNL_DONE_CNT);\n+\n+\tp->mp_stat_unl_ignore = module_get_register(p->m_flm, FLM_STAT_UNL_IGNORE);\n+\tp->mp_stat_unl_ignore_cnt =\n+\t\tregister_get_field(p->mp_stat_unl_ignore, FLM_STAT_UNL_IGNORE_CNT);\n+\n+\tp->mp_stat_prb_done = module_query_register(p->m_flm, FLM_STAT_PRB_DONE);\n+\tp->mp_stat_prb_done_cnt =\n+\t\tregister_query_field(p->mp_stat_prb_done, FLM_STAT_PRB_DONE_CNT);\n+\n+\tp->mp_stat_prb_ignore = module_query_register(p->m_flm, FLM_STAT_PRB_IGNORE);\n+\tp->mp_stat_prb_ignore_cnt = register_query_field(p->mp_stat_prb_ignore,\n+\t\t\t\tFLM_STAT_PRB_IGNORE_CNT);\n+\n+\tp->mp_stat_rel_done = module_get_register(p->m_flm, FLM_STAT_REL_DONE);\n+\tp->mp_stat_rel_done_cnt =\n+\t\tregister_get_field(p->mp_stat_rel_done, FLM_STAT_REL_DONE_CNT);\n+\n+\tp->mp_stat_rel_ignore = module_get_register(p->m_flm, FLM_STAT_REL_IGNORE);\n+\tp->mp_stat_rel_ignore_cnt =\n+\t\tregister_get_field(p->mp_stat_rel_ignore, FLM_STAT_REL_IGNORE_CNT);\n+\n+\tp->mp_stat_aul_done = module_get_register(p->m_flm, FLM_STAT_AUL_DONE);\n+\tp->mp_stat_aul_done_cnt =\n+\t\tregister_get_field(p->mp_stat_aul_done, FLM_STAT_AUL_DONE_CNT);\n+\n+\tp->mp_stat_aul_ignore = module_get_register(p->m_flm, FLM_STAT_AUL_IGNORE);\n+\tp->mp_stat_aul_ignore_cnt =\n+\t\tregister_get_field(p->mp_stat_aul_ignore, FLM_STAT_AUL_IGNORE_CNT);\n+\n+\tp->mp_stat_aul_fail = module_get_register(p->m_flm, FLM_STAT_AUL_FAIL);\n+\tp->mp_stat_aul_fail_cnt =\n+\t\tregister_get_field(p->mp_stat_aul_fail, FLM_STAT_AUL_FAIL_CNT);\n+\n+\tp->mp_stat_tul_done = module_get_register(p->m_flm, FLM_STAT_TUL_DONE);\n+\tp->mp_stat_tul_done_cnt =\n+\t\tregister_get_field(p->mp_stat_tul_done, FLM_STAT_TUL_DONE_CNT);\n+\n+\tp->mp_stat_flows = module_get_register(p->m_flm, FLM_STAT_FLOWS);\n+\tp->mp_stat_flows_cnt =\n+\t\tregister_get_field(p->mp_stat_flows, FLM_STAT_FLOWS_CNT);\n+\n+\tp->mp_stat_sta_done = module_query_register(p->m_flm, FLM_STAT_STA_DONE);\n+\tp->mp_stat_sta_done_cnt =\n+\t\tregister_query_field(p->mp_stat_sta_done, FLM_STAT_STA_DONE_CNT);\n+\n+\tp->mp_stat_inf_done = module_query_register(p->m_flm, FLM_STAT_INF_DONE);\n+\tp->mp_stat_inf_done_cnt =\n+\t\tregister_query_field(p->mp_stat_inf_done, FLM_STAT_INF_DONE_CNT);\n+\n+\tp->mp_stat_inf_skip = module_query_register(p->m_flm, FLM_STAT_INF_SKIP);\n+\tp->mp_stat_inf_skip_cnt =\n+\t\tregister_query_field(p->mp_stat_inf_skip, FLM_STAT_INF_SKIP_CNT);\n+\n+\tp->mp_stat_pck_hit = module_query_register(p->m_flm, FLM_STAT_PCK_HIT);\n+\tp->mp_stat_pck_hit_cnt =\n+\t\tregister_query_field(p->mp_stat_pck_hit, FLM_STAT_PCK_HIT_CNT);\n+\n+\tp->mp_stat_pck_miss = module_query_register(p->m_flm, FLM_STAT_PCK_MISS);\n+\tp->mp_stat_pck_miss_cnt =\n+\t\tregister_query_field(p->mp_stat_pck_miss, FLM_STAT_PCK_MISS_CNT);\n+\n+\tp->mp_stat_pck_unh = module_query_register(p->m_flm, FLM_STAT_PCK_UNH);\n+\tp->mp_stat_pck_unh_cnt =\n+\t\tregister_query_field(p->mp_stat_pck_unh, FLM_STAT_PCK_UNH_CNT);\n+\n+\tp->mp_stat_pck_dis = module_query_register(p->m_flm, FLM_STAT_PCK_DIS);\n+\tp->mp_stat_pck_dis_cnt =\n+\t\tregister_query_field(p->mp_stat_pck_dis, FLM_STAT_PCK_DIS_CNT);\n+\n+\tp->mp_stat_csh_hit = module_query_register(p->m_flm, FLM_STAT_CSH_HIT);\n+\tp->mp_stat_csh_hit_cnt =\n+\t\tregister_query_field(p->mp_stat_csh_hit, FLM_STAT_CSH_HIT_CNT);\n+\n+\tp->mp_stat_csh_miss = module_query_register(p->m_flm, FLM_STAT_CSH_MISS);\n+\tp->mp_stat_csh_miss_cnt =\n+\t\tregister_query_field(p->mp_stat_csh_miss, FLM_STAT_CSH_MISS_CNT);\n+\n+\tp->mp_stat_csh_unh = module_query_register(p->m_flm, FLM_STAT_CSH_UNH);\n+\tp->mp_stat_csh_unh_cnt =\n+\t\tregister_query_field(p->mp_stat_csh_unh, FLM_STAT_CSH_UNH_CNT);\n+\n+\tp->mp_stat_cuc_start = module_query_register(p->m_flm, FLM_STAT_CUC_START);\n+\tp->mp_stat_cuc_start_cnt =\n+\t\tregister_query_field(p->mp_stat_cuc_start, FLM_STAT_CUC_START_CNT);\n+\n+\tp->mp_stat_cuc_move = module_query_register(p->m_flm, FLM_STAT_CUC_MOVE);\n+\tp->mp_stat_cuc_move_cnt =\n+\t\tregister_query_field(p->mp_stat_cuc_move, FLM_STAT_CUC_MOVE_CNT);\n+\n+\treturn 0;\n+}\n+\n+void flm_nthw_control_enable(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_enable, val);\n+}\n+\n+void flm_nthw_control_init(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_init, val);\n+}\n+\n+void flm_nthw_control_lds(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_lds, val);\n+}\n+\n+void flm_nthw_control_lfs(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_lfs, val);\n+}\n+\n+void flm_nthw_control_lis(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_lis, val);\n+}\n+\n+void flm_nthw_control_uds(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_uds, val);\n+}\n+\n+void flm_nthw_control_uis(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_uis, val);\n+}\n+\n+void flm_nthw_control_rds(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_rds, val);\n+}\n+\n+void flm_nthw_control_ris(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_ris, val);\n+}\n+\n+void flm_nthw_control_pds(const struct flm_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_control_pds);\n+\tfield_set_val32(p->mp_control_pds, val);\n+}\n+\n+void flm_nthw_control_pis(const struct flm_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_control_pis);\n+\tfield_set_val32(p->mp_control_pis, val);\n+}\n+\n+void flm_nthw_control_crcwr(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_crcwr, val);\n+}\n+\n+void flm_nthw_control_crcrd(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_crcrd, val);\n+}\n+\n+void flm_nthw_control_rbl(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_rbl, val);\n+}\n+\n+void flm_nthw_control_eab(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_eab, val);\n+}\n+\n+void flm_nthw_control_split_sdram_usage(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_control_split_sdram_usage, val);\n+}\n+\n+void flm_nthw_control_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_control, 1);\n+}\n+\n+void flm_nthw_status_calibdone(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_status_calibdone);\n+}\n+\n+void flm_nthw_status_initdone(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_status_initdone);\n+}\n+\n+void flm_nthw_status_idle(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_status_idle);\n+}\n+\n+void flm_nthw_status_critical(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_status_critical);\n+\n+\telse\n+\t\tfield_set_val32(p->mp_status_critical, *val);\n+}\n+\n+void flm_nthw_status_panic(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_status_panic);\n+\n+\telse\n+\t\tfield_set_val32(p->mp_status_panic, *val);\n+}\n+\n+void flm_nthw_status_crcerr(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_status_crcerr);\n+\n+\telse\n+\t\tfield_set_val32(p->mp_status_crcerr, *val);\n+}\n+\n+void flm_nthw_status_eft_bp(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_status_eft_bp);\n+}\n+\n+void flm_nthw_status_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_status, 1);\n+}\n+\n+void flm_nthw_status_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_status);\n+}\n+\n+void flm_nthw_timeout_t(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_timeout_t, val);\n+}\n+\n+void flm_nthw_timeout_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_timeout, 1);\n+}\n+\n+void flm_nthw_scrub_i(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_scrub_i, val);\n+}\n+\n+void flm_nthw_scrub_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_scrub, 1);\n+}\n+\n+void flm_nthw_load_bin(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_load_bin_bin, val);\n+}\n+\n+void flm_nthw_load_bin_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_load_bin, 1);\n+}\n+\n+void flm_nthw_load_pps(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_load_pps_pps, val);\n+}\n+\n+void flm_nthw_load_pps_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_load_pps, 1);\n+}\n+\n+void flm_nthw_load_lps(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_load_lps_lps, val);\n+}\n+\n+void flm_nthw_load_lps_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_load_lps, 1);\n+}\n+\n+void flm_nthw_load_aps(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_load_aps_aps, val);\n+}\n+\n+void flm_nthw_load_aps_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_load_aps, 1);\n+}\n+\n+void flm_nthw_prio_limit0(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_prio_limit0, val);\n+}\n+\n+void flm_nthw_prio_ft0(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_prio_ft0, val);\n+}\n+\n+void flm_nthw_prio_limit1(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_prio_limit1, val);\n+}\n+\n+void flm_nthw_prio_ft1(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_prio_ft1, val);\n+}\n+\n+void flm_nthw_prio_limit2(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_prio_limit2, val);\n+}\n+\n+void flm_nthw_prio_ft2(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_prio_ft2, val);\n+}\n+\n+void flm_nthw_prio_limit3(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_prio_limit3, val);\n+}\n+\n+void flm_nthw_prio_ft3(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_prio_ft3, val);\n+}\n+\n+void flm_nthw_prio_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_prio, 1);\n+}\n+\n+void flm_nthw_pst_select(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_pst_ctrl_adr, val);\n+}\n+\n+void flm_nthw_pst_cnt(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_pst_ctrl_cnt, val);\n+}\n+\n+void flm_nthw_pst_bp(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_pst_data_bp, val);\n+}\n+\n+void flm_nthw_pst_pp(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_pst_data_pp, val);\n+}\n+\n+void flm_nthw_pst_tp(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_pst_data_tp, val);\n+}\n+\n+void flm_nthw_pst_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_pst_ctrl, 1);\n+\tregister_flush(p->mp_pst_data, 1);\n+}\n+\n+void flm_nthw_rcp_select(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_ctrl_adr, val);\n+}\n+\n+void flm_nthw_rcp_cnt(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_ctrl_cnt, val);\n+}\n+\n+void flm_nthw_rcp_lookup(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_lookup, val);\n+}\n+\n+void flm_nthw_rcp_qw0_dyn(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_dyn, val);\n+}\n+\n+void flm_nthw_rcp_qw0_ofs(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_ofs, val);\n+}\n+\n+void flm_nthw_rcp_qw0_sel(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_sel, val);\n+}\n+\n+void flm_nthw_rcp_qw4_dyn(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw4_dyn, val);\n+}\n+\n+void flm_nthw_rcp_qw4_ofs(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw4_ofs, val);\n+}\n+\n+void flm_nthw_rcp_sw8_dyn(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw8_dyn, val);\n+}\n+\n+void flm_nthw_rcp_sw8_ofs(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw8_ofs, val);\n+}\n+\n+void flm_nthw_rcp_sw8_sel(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw8_sel, val);\n+}\n+\n+void flm_nthw_rcp_sw9_dyn(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw9_dyn, val);\n+}\n+\n+void flm_nthw_rcp_sw9_ofs(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw9_ofs, val);\n+}\n+\n+void flm_nthw_rcp_mask(const struct flm_nthw *p, const uint32_t *val)\n+{\n+\tfield_set_val(p->mp_rcp_data_mask, val, 10);\n+}\n+\n+void flm_nthw_rcp_kid(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_kid, val);\n+}\n+\n+void flm_nthw_rcp_opn(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_opn, val);\n+}\n+\n+void flm_nthw_rcp_ipn(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ipn, val);\n+}\n+\n+void flm_nthw_rcp_byt_dyn(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_byt_dyn, val);\n+}\n+\n+void flm_nthw_rcp_byt_ofs(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_byt_ofs, val);\n+}\n+\n+void flm_nthw_rcp_txplm(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_txplm, val);\n+}\n+\n+void flm_nthw_rcp_auto_ipv4_mask(const struct flm_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_auto_ipv4_mask, val);\n+}\n+\n+void flm_nthw_rcp_flush(const struct flm_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\n+\n+int flm_nthw_buf_ctrl_update(const struct flm_nthw *p, uint32_t *lrn_free,\n+\t\t\t  uint32_t *inf_avail, uint32_t *sta_avail)\n+{\n+\tint ret = -1;\n+\n+\tstruct nthw_rac *rac = (struct nthw_rac *)p->mp_rac;\n+\tuint32_t address_bufctrl = register_get_address(p->mp_buf_ctrl);\n+\trab_bus_id_t bus_id = 1;\n+\tstruct dma_buf_ptr bc_buf;\n+\n+\tret = nthw_rac_rab_dma_begin(rac);\n+\tif (ret == 0) {\n+\t\tnthw_rac_rab_read32_dma(rac, address_bufctrl, bus_id, 2, &bc_buf);\n+\t\tret = nthw_rac_rab_dma_commit(rac);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tuint32_t bc_mask = bc_buf.size - 1;\n+\t\tuint32_t bc_index = bc_buf.index;\n+\t\t*lrn_free = bc_buf.base[bc_index & bc_mask] & 0xffff;\n+\t\t*inf_avail = (bc_buf.base[bc_index & bc_mask] >> 16) & 0xffff;\n+\t\t*sta_avail = bc_buf.base[(bc_index + 1) & bc_mask] & 0xffff;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+int flm_nthw_lrn_data_flush(const struct flm_nthw *p, const uint32_t *data,\n+\t\t\t uint32_t word_count, uint32_t *lrn_free,\n+\t\t\t uint32_t *inf_avail, uint32_t *sta_avail)\n+{\n+\tint ret = -1;\n+\n+\tstruct nthw_rac *rac = (struct nthw_rac *)p->mp_rac;\n+\tuint32_t address = register_get_address(p->mp_lrn_data);\n+\tuint32_t address_bufctrl = register_get_address(p->mp_buf_ctrl);\n+\trab_bus_id_t bus_id = 1;\n+\tstruct dma_buf_ptr bc_buf;\n+\n+\tif (nthw_rac_rab_dma_begin(rac) == 0) {\n+\t\t/* Announce the number of words to write to LRN_DATA */\n+\t\tuint32_t bufctrl_data[2];\n+\n+\t\tbufctrl_data[0] = word_count;\n+\t\tbufctrl_data[1] = 0;\n+\t\tnthw_rac_rab_write32_dma(rac, address_bufctrl, bus_id, 2,\n+\t\t\t\t\tbufctrl_data);\n+\t\tnthw_rac_rab_write32_dma(rac, address, bus_id, word_count, data);\n+\t\tnthw_rac_rab_read32_dma(rac, address_bufctrl, bus_id, 2, &bc_buf);\n+\t\tret = nthw_rac_rab_dma_commit(rac);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tuint32_t bc_mask = bc_buf.size - 1;\n+\t\tuint32_t bc_index = bc_buf.index;\n+\t\t*lrn_free = bc_buf.base[bc_index & bc_mask] & 0xffff;\n+\t\t*inf_avail = (bc_buf.base[bc_index & bc_mask] >> 16) & 0xffff;\n+\t\t*sta_avail = bc_buf.base[(bc_index + 1) & bc_mask] & 0xffff;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+int flm_nthw_inf_data_update(const struct flm_nthw *p, uint32_t *data,\n+\t\t\t  uint32_t word_count, uint32_t *lrn_free,\n+\t\t\t  uint32_t *inf_avail, uint32_t *sta_avail)\n+{\n+\tint ret = -1;\n+\n+\tstruct nthw_rac *rac = (struct nthw_rac *)p->mp_rac;\n+\tuint32_t address_infdata = register_get_address(p->mp_inf_data);\n+\tuint32_t address_bufctrl = register_get_address(p->mp_buf_ctrl);\n+\trab_bus_id_t bus_id = 1;\n+\tstruct dma_buf_ptr buf;\n+\tstruct dma_buf_ptr bc_buf;\n+\n+\tret = nthw_rac_rab_dma_begin(rac);\n+\tif (ret == 0) {\n+\t\t/* Announce the number of words to read from INF_DATA */\n+\t\tuint32_t bufctrl_data[2];\n+\n+\t\tbufctrl_data[0] = word_count << 16;\n+\t\tbufctrl_data[1] = 0;\n+\t\tnthw_rac_rab_write32_dma(rac, address_bufctrl, bus_id, 2,\n+\t\t\t\t\tbufctrl_data);\n+\t\tnthw_rac_rab_read32_dma(rac, address_infdata, bus_id, word_count,\n+\t\t\t\t       &buf);\n+\t\tnthw_rac_rab_read32_dma(rac, address_bufctrl, bus_id, 2, &bc_buf);\n+\t\tret = nthw_rac_rab_dma_commit(rac);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tuint32_t mask = buf.size - 1;\n+\t\tuint32_t index = buf.index;\n+\n+\t\tfor (uint32_t i = 0; i < word_count; ++index, ++i)\n+\t\t\tdata[i] = buf.base[index & mask];\n+\n+\t\tuint32_t bc_mask = bc_buf.size - 1;\n+\t\tuint32_t bc_index = bc_buf.index;\n+\t\t*lrn_free = bc_buf.base[bc_index & bc_mask] & 0xffff;\n+\t\t*inf_avail = (bc_buf.base[bc_index & bc_mask] >> 16) & 0xffff;\n+\t\t*sta_avail = bc_buf.base[(bc_index + 1) & bc_mask] & 0xffff;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+int flm_nthw_sta_data_update(const struct flm_nthw *p, uint32_t *data,\n+\t\t\t  uint32_t word_count, uint32_t *lrn_free,\n+\t\t\t  uint32_t *inf_avail, uint32_t *sta_avail)\n+{\n+\tint ret = -1;\n+\n+\tstruct nthw_rac *rac = (struct nthw_rac *)p->mp_rac;\n+\tuint32_t address_stadata = register_get_address(p->mp_sta_data);\n+\tuint32_t address_bufctrl = register_get_address(p->mp_buf_ctrl);\n+\trab_bus_id_t bus_id = 1;\n+\tstruct dma_buf_ptr buf;\n+\tstruct dma_buf_ptr bc_buf;\n+\n+\tret = nthw_rac_rab_dma_begin(rac);\n+\tif (ret == 0) {\n+\t\t/* Announce the number of words to read from STA_DATA */\n+\t\tuint32_t bufctrl_data[2];\n+\n+\t\tbufctrl_data[0] = 0;\n+\t\tbufctrl_data[1] = word_count;\n+\t\tnthw_rac_rab_write32_dma(rac, address_bufctrl, bus_id, 2,\n+\t\t\t\t\tbufctrl_data);\n+\t\tnthw_rac_rab_read32_dma(rac, address_stadata, bus_id, word_count,\n+\t\t\t\t       &buf);\n+\t\tnthw_rac_rab_read32_dma(rac, address_bufctrl, bus_id, 2, &bc_buf);\n+\t\tret = nthw_rac_rab_dma_commit(rac);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\n+\t\tuint32_t mask = buf.size - 1;\n+\t\tuint32_t index = buf.index;\n+\n+\t\tfor (uint32_t i = 0; i < word_count; ++index, ++i)\n+\t\t\tdata[i] = buf.base[index & mask];\n+\n+\t\tuint32_t bc_mask = bc_buf.size - 1;\n+\t\tuint32_t bc_index = bc_buf.index;\n+\t\t*lrn_free = bc_buf.base[bc_index & bc_mask] & 0xffff;\n+\t\t*inf_avail = (bc_buf.base[bc_index & bc_mask] >> 16) & 0xffff;\n+\t\t*sta_avail = bc_buf.base[(bc_index + 1) & bc_mask] & 0xffff;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+void flm_nthw_stat_lrn_done_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_lrn_done_cnt);\n+}\n+\n+void flm_nthw_stat_lrn_done_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_lrn_done);\n+}\n+\n+void flm_nthw_stat_lrn_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_lrn_ignore_cnt);\n+}\n+\n+void flm_nthw_stat_lrn_ignore_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_lrn_ignore);\n+}\n+\n+void flm_nthw_stat_lrn_fail_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_lrn_fail_cnt);\n+}\n+\n+void flm_nthw_stat_lrn_fail_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_lrn_fail);\n+}\n+\n+void flm_nthw_stat_unl_done_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_unl_done_cnt);\n+}\n+\n+void flm_nthw_stat_unl_done_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_unl_done);\n+}\n+\n+void flm_nthw_stat_unl_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_unl_ignore_cnt);\n+}\n+\n+void flm_nthw_stat_unl_ignore_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_unl_ignore);\n+}\n+\n+void flm_nthw_stat_prb_done_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_prb_done_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_prb_done_cnt);\n+}\n+\n+void flm_nthw_stat_prb_done_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_prb_done);\n+\tregister_update(p->mp_stat_prb_done);\n+}\n+\n+void flm_nthw_stat_prb_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_prb_ignore_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_prb_ignore_cnt);\n+}\n+\n+void flm_nthw_stat_prb_ignore_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_prb_ignore);\n+\tregister_update(p->mp_stat_prb_ignore);\n+}\n+\n+void flm_nthw_stat_rel_done_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_rel_done_cnt);\n+}\n+\n+void flm_nthw_stat_rel_done_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_rel_done);\n+}\n+\n+void flm_nthw_stat_rel_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_rel_ignore_cnt);\n+}\n+\n+void flm_nthw_stat_rel_ignore_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_rel_ignore);\n+}\n+\n+void flm_nthw_stat_aul_done_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_aul_done_cnt);\n+}\n+\n+void flm_nthw_stat_aul_done_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_aul_done);\n+}\n+\n+void flm_nthw_stat_aul_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_aul_ignore_cnt);\n+}\n+\n+void flm_nthw_stat_aul_ignore_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_aul_ignore);\n+}\n+\n+void flm_nthw_stat_aul_fail_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_aul_fail_cnt);\n+}\n+\n+void flm_nthw_stat_aul_fail_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_aul_fail);\n+}\n+\n+void flm_nthw_stat_tul_done_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_tul_done_cnt);\n+}\n+\n+void flm_nthw_stat_tul_done_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_tul_done);\n+}\n+\n+void flm_nthw_stat_flows_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_flows_cnt);\n+}\n+\n+void flm_nthw_stat_flows_update(const struct flm_nthw *p)\n+{\n+\tregister_update(p->mp_stat_flows);\n+}\n+\n+void flm_nthw_stat_sta_done_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_sta_done_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_sta_done_cnt);\n+}\n+\n+void flm_nthw_stat_sta_done_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_sta_done);\n+\tregister_update(p->mp_stat_sta_done);\n+}\n+\n+void flm_nthw_stat_inf_done_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_inf_done_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_inf_done_cnt);\n+}\n+\n+void flm_nthw_stat_inf_done_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_inf_done);\n+\tregister_update(p->mp_stat_inf_done);\n+}\n+\n+void flm_nthw_stat_inf_skip_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_inf_skip_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_inf_skip_cnt);\n+}\n+\n+void flm_nthw_stat_inf_skip_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_inf_skip);\n+\tregister_update(p->mp_stat_inf_skip);\n+}\n+\n+void flm_nthw_stat_pck_hit_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_pck_hit_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_pck_hit_cnt);\n+}\n+\n+void flm_nthw_stat_pck_hit_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_pck_hit);\n+\tregister_update(p->mp_stat_pck_hit);\n+}\n+\n+void flm_nthw_stat_pck_miss_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_pck_miss_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_pck_miss_cnt);\n+}\n+\n+void flm_nthw_stat_pck_miss_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_pck_miss);\n+\tregister_update(p->mp_stat_pck_miss);\n+}\n+\n+void flm_nthw_stat_pck_unh_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_pck_unh_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_pck_unh_cnt);\n+}\n+\n+void flm_nthw_stat_pck_unh_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_pck_unh);\n+\tregister_update(p->mp_stat_pck_unh);\n+}\n+\n+void flm_nthw_stat_pck_dis_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_pck_dis_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_pck_dis_cnt);\n+}\n+\n+void flm_nthw_stat_pck_dis_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_pck_dis);\n+\tregister_update(p->mp_stat_pck_dis);\n+}\n+\n+void flm_nthw_stat_csh_hit_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_csh_hit_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_csh_hit_cnt);\n+}\n+\n+void flm_nthw_stat_csh_hit_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_csh_hit);\n+\tregister_update(p->mp_stat_csh_hit);\n+}\n+\n+void flm_nthw_stat_csh_miss_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_csh_miss_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_csh_miss_cnt);\n+}\n+\n+void flm_nthw_stat_csh_miss_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_csh_miss);\n+\tregister_update(p->mp_stat_csh_miss);\n+}\n+\n+void flm_nthw_stat_csh_unh_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_csh_unh_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_csh_unh_cnt);\n+}\n+\n+void flm_nthw_stat_csh_unh_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_csh_unh);\n+\tregister_update(p->mp_stat_csh_unh);\n+}\n+\n+void flm_nthw_stat_cuc_start_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_cuc_start_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_cuc_start_cnt);\n+}\n+\n+void flm_nthw_stat_cuc_start_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_cuc_start);\n+\tregister_update(p->mp_stat_cuc_start);\n+}\n+\n+void flm_nthw_stat_cuc_move_cnt(const struct flm_nthw *p, uint32_t *val, int get)\n+{\n+\tassert(p->mp_stat_cuc_move_cnt);\n+\tif (get)\n+\t\t*val = field_get_val32(p->mp_stat_cuc_move_cnt);\n+}\n+\n+void flm_nthw_stat_cuc_move_update(const struct flm_nthw *p)\n+{\n+\tassert(p->mp_stat_cuc_move);\n+\tregister_update(p->mp_stat_cuc_move);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_flm.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_flm.h\nnew file mode 100644\nindex 0000000000..4796d43940\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_flm.h\n@@ -0,0 +1,422 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_FLM_H__\n+#define __FLOW_NTHW_FLM_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct flm_nthw;\n+\n+typedef struct flm_nthw flm_nthw_t;\n+\n+struct flm_nthw *flm_nthw_new(void);\n+void flm_nthw_delete(struct flm_nthw *p);\n+int flm_nthw_init(struct flm_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+void flm_nthw_set_debug_mode(struct flm_nthw *p, unsigned int n_debug_mode);\n+\n+/* Control */\n+void flm_nthw_control_enable(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_init(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_lds(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_lfs(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_lis(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_uds(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_uis(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_rds(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_ris(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_pds(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_pis(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_crcwr(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_crcrd(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_rbl(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_eab(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_split_sdram_usage(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_control_flush(const struct flm_nthw *p);\n+\n+/* Status */\n+void flm_nthw_status_calibdone(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_status_initdone(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_status_idle(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_status_critical(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_status_panic(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_status_crcerr(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_status_eft_bp(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_status_flush(const struct flm_nthw *p);\n+void flm_nthw_status_update(const struct flm_nthw *p);\n+\n+/* Timeout */\n+void flm_nthw_timeout_t(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_timeout_flush(const struct flm_nthw *p);\n+\n+/* Scrub */\n+void flm_nthw_scrub_i(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_scrub_flush(const struct flm_nthw *p);\n+\n+/* Load BIN */\n+void flm_nthw_load_bin(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_load_bin_flush(const struct flm_nthw *p);\n+\n+/* Load PPS */\n+void flm_nthw_load_pps(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_load_pps_flush(const struct flm_nthw *p);\n+\n+/* Load LPS */\n+void flm_nthw_load_lps(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_load_lps_flush(const struct flm_nthw *p);\n+\n+/* Load APS */\n+void flm_nthw_load_aps(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_load_aps_flush(const struct flm_nthw *p);\n+\n+/* Prio */\n+void flm_nthw_prio_limit0(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_prio_ft0(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_prio_limit1(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_prio_ft1(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_prio_limit2(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_prio_ft2(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_prio_limit3(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_prio_ft3(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_prio_flush(const struct flm_nthw *p);\n+\n+/* PST */\n+void flm_nthw_pst_select(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_pst_cnt(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_pst_bp(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_pst_pp(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_pst_tp(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_pst_flush(const struct flm_nthw *p);\n+\n+/* RCP */\n+void flm_nthw_rcp_select(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_cnt(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_lookup(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_qw0_dyn(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_qw0_ofs(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_qw0_sel(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_qw4_dyn(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_qw4_ofs(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_sw8_dyn(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_sw8_ofs(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_sw8_sel(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_sw9_dyn(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_sw9_ofs(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_mask(const struct flm_nthw *p, const uint32_t *val);\n+void flm_nthw_rcp_kid(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_opn(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_ipn(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_byt_dyn(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_byt_ofs(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_txplm(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_auto_ipv4_mask(const struct flm_nthw *p, uint32_t val);\n+void flm_nthw_rcp_flush(const struct flm_nthw *p);\n+\n+/* Buf Ctrl */\n+int flm_nthw_buf_ctrl_update(const struct flm_nthw *p, uint32_t *lrn_free,\n+\t\t\t  uint32_t *inf_avail, uint32_t *sta_avail);\n+\n+/* Lrn Data */\n+int flm_nthw_lrn_data_flush(const struct flm_nthw *p, const uint32_t *data,\n+\t\t\t uint32_t word_count, uint32_t *lrn_free,\n+\t\t\t uint32_t *inf_avail, uint32_t *sta_avail);\n+\n+/* Inf Data */\n+int flm_nthw_inf_data_update(const struct flm_nthw *p, uint32_t *data,\n+\t\t\t  uint32_t word_count, uint32_t *lrn_free,\n+\t\t\t  uint32_t *inf_avail, uint32_t *sta_avail);\n+\n+/* Sta Data */\n+int flm_nthw_sta_data_update(const struct flm_nthw *p, uint32_t *data,\n+\t\t\t  uint32_t word_count, uint32_t *lrn_free,\n+\t\t\t  uint32_t *inf_avail, uint32_t *sta_avail);\n+\n+/* Stat Lrn _done */\n+void flm_nthw_stat_lrn_done_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_lrn_done_update(const struct flm_nthw *p);\n+\n+/* Stat Lrn Ignore */\n+void flm_nthw_stat_lrn_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_lrn_ignore_update(const struct flm_nthw *p);\n+\n+/* Stat Lrn Fail */\n+void flm_nthw_stat_lrn_fail_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_lrn_fail_update(const struct flm_nthw *p);\n+\n+/* Stat Unl _done */\n+void flm_nthw_stat_unl_done_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_unl_done_update(const struct flm_nthw *p);\n+\n+/* Stat Unl Ignore */\n+void flm_nthw_stat_unl_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_unl_ignore_update(const struct flm_nthw *p);\n+\n+/* Stat Prb _done */\n+void flm_nthw_stat_prb_done_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_prb_done_update(const struct flm_nthw *p);\n+\n+/* Stat Prb Ignore */\n+void flm_nthw_stat_prb_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_prb_ignore_update(const struct flm_nthw *p);\n+\n+/* Stat Rel _done */\n+void flm_nthw_stat_rel_done_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_rel_done_update(const struct flm_nthw *p);\n+\n+/* Stat Rel Ignore */\n+void flm_nthw_stat_rel_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_rel_ignore_update(const struct flm_nthw *p);\n+\n+/* Stat Aul _done */\n+void flm_nthw_stat_aul_done_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_aul_done_update(const struct flm_nthw *p);\n+\n+/* Stat Aul Ignore */\n+void flm_nthw_stat_aul_ignore_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_aul_ignore_update(const struct flm_nthw *p);\n+\n+/* Stat Aul Fail */\n+void flm_nthw_stat_aul_fail_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_aul_fail_update(const struct flm_nthw *p);\n+\n+/* Stat Tul _done */\n+void flm_nthw_stat_tul_done_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_tul_done_update(const struct flm_nthw *p);\n+\n+/* Stat Flows */\n+void flm_nthw_stat_flows_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_flows_update(const struct flm_nthw *p);\n+\n+/* Stat Sta _done */\n+void flm_nthw_stat_sta_done_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_sta_done_update(const struct flm_nthw *p);\n+\n+/* Stat Inf _done */\n+void flm_nthw_stat_inf_done_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_inf_done_update(const struct flm_nthw *p);\n+\n+/* Stat Inf Skip */\n+void flm_nthw_stat_inf_skip_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_inf_skip_update(const struct flm_nthw *p);\n+\n+/* Stat Pck Hit */\n+void flm_nthw_stat_pck_hit_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_pck_hit_update(const struct flm_nthw *p);\n+\n+/* Stat Pck Miss */\n+void flm_nthw_stat_pck_miss_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_pck_miss_update(const struct flm_nthw *p);\n+\n+/* Stat Pck Unh */\n+void flm_nthw_stat_pck_unh_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_pck_unh_update(const struct flm_nthw *p);\n+\n+/* Stat Pck Dis */\n+void flm_nthw_stat_pck_dis_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_pck_dis_update(const struct flm_nthw *p);\n+\n+/* Stat Csh Hit */\n+void flm_nthw_stat_csh_hit_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_csh_hit_update(const struct flm_nthw *p);\n+\n+/* Stat Csh Miss */\n+void flm_nthw_stat_csh_miss_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_csh_miss_update(const struct flm_nthw *p);\n+\n+/* Stat Csh Unh */\n+void flm_nthw_stat_csh_unh_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_csh_unh_update(const struct flm_nthw *p);\n+\n+/* Stat Cuc Start */\n+void flm_nthw_stat_cuc_start_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_cuc_start_update(const struct flm_nthw *p);\n+\n+/* Stat Cuc Move */\n+void flm_nthw_stat_cuc_move_cnt(const struct flm_nthw *p, uint32_t *val, int get);\n+void flm_nthw_stat_cuc_move_update(const struct flm_nthw *p);\n+\n+struct flm_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\tvoid *mp_rac;\n+\n+\tnt_module_t *m_flm;\n+\n+\tnt_register_t *mp_control;\n+\tnt_field_t *mp_control_enable;\n+\tnt_field_t *mp_control_init;\n+\tnt_field_t *mp_control_lds;\n+\tnt_field_t *mp_control_lfs;\n+\tnt_field_t *mp_control_lis;\n+\tnt_field_t *mp_control_uds;\n+\tnt_field_t *mp_control_uis;\n+\tnt_field_t *mp_control_rds;\n+\tnt_field_t *mp_control_ris;\n+\tnt_field_t *mp_control_pds;\n+\tnt_field_t *mp_control_pis;\n+\tnt_field_t *mp_control_crcwr;\n+\tnt_field_t *mp_control_crcrd;\n+\tnt_field_t *mp_control_rbl;\n+\tnt_field_t *mp_control_eab;\n+\tnt_field_t *mp_control_split_sdram_usage;\n+\n+\tnt_register_t *mp_status;\n+\tnt_field_t *mp_status_calibdone;\n+\tnt_field_t *mp_status_initdone;\n+\tnt_field_t *mp_status_idle;\n+\tnt_field_t *mp_status_critical;\n+\tnt_field_t *mp_status_panic;\n+\tnt_field_t *mp_status_crcerr;\n+\tnt_field_t *mp_status_eft_bp;\n+\n+\tnt_register_t *mp_timeout;\n+\tnt_field_t *mp_timeout_t;\n+\n+\tnt_register_t *mp_scrub;\n+\tnt_field_t *mp_scrub_i;\n+\n+\tnt_register_t *mp_load_bin;\n+\tnt_field_t *mp_load_bin_bin;\n+\n+\tnt_register_t *mp_load_pps;\n+\tnt_field_t *mp_load_pps_pps;\n+\n+\tnt_register_t *mp_load_lps;\n+\tnt_field_t *mp_load_lps_lps;\n+\n+\tnt_register_t *mp_load_aps;\n+\tnt_field_t *mp_load_aps_aps;\n+\n+\tnt_register_t *mp_prio;\n+\tnt_field_t *mp_prio_limit0;\n+\tnt_field_t *mp_prio_ft0;\n+\tnt_field_t *mp_prio_limit1;\n+\tnt_field_t *mp_prio_ft1;\n+\tnt_field_t *mp_prio_limit2;\n+\tnt_field_t *mp_prio_ft2;\n+\tnt_field_t *mp_prio_limit3;\n+\tnt_field_t *mp_prio_ft3;\n+\n+\tnt_register_t *mp_pst_ctrl;\n+\tnt_field_t *mp_pst_ctrl_adr;\n+\tnt_field_t *mp_pst_ctrl_cnt;\n+\tnt_register_t *mp_pst_data;\n+\tnt_field_t *mp_pst_data_bp;\n+\tnt_field_t *mp_pst_data_pp;\n+\tnt_field_t *mp_pst_data_tp;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_ctrl_adr;\n+\tnt_field_t *mp_rcp_ctrl_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_lookup;\n+\tnt_field_t *mp_rcp_data_qw0_dyn;\n+\tnt_field_t *mp_rcp_data_qw0_ofs;\n+\tnt_field_t *mp_rcp_data_qw0_sel;\n+\tnt_field_t *mp_rcp_data_qw4_dyn;\n+\tnt_field_t *mp_rcp_data_qw4_ofs;\n+\tnt_field_t *mp_rcp_data_sw8_dyn;\n+\tnt_field_t *mp_rcp_data_sw8_ofs;\n+\tnt_field_t *mp_rcp_data_sw8_sel;\n+\tnt_field_t *mp_rcp_data_sw9_dyn;\n+\tnt_field_t *mp_rcp_data_sw9_ofs;\n+\tnt_field_t *mp_rcp_data_mask;\n+\tnt_field_t *mp_rcp_data_kid;\n+\tnt_field_t *mp_rcp_data_opn;\n+\tnt_field_t *mp_rcp_data_ipn;\n+\tnt_field_t *mp_rcp_data_byt_dyn;\n+\tnt_field_t *mp_rcp_data_byt_ofs;\n+\tnt_field_t *mp_rcp_data_txplm;\n+\tnt_field_t *mp_rcp_data_auto_ipv4_mask;\n+\n+\tnt_register_t *mp_buf_ctrl;\n+\tnt_field_t *mp_buf_ctrl_lrn_free;\n+\tnt_field_t *mp_buf_ctrl_inf_avail;\n+\tnt_field_t *mp_buf_ctrl_sta_avail;\n+\n+\tnt_register_t *mp_lrn_data;\n+\tnt_register_t *mp_inf_data;\n+\tnt_register_t *mp_sta_data;\n+\n+\tnt_register_t *mp_stat_lrn_done;\n+\tnt_field_t *mp_stat_lrn_done_cnt;\n+\n+\tnt_register_t *mp_stat_lrn_ignore;\n+\tnt_field_t *mp_stat_lrn_ignore_cnt;\n+\n+\tnt_register_t *mp_stat_lrn_fail;\n+\tnt_field_t *mp_stat_lrn_fail_cnt;\n+\n+\tnt_register_t *mp_stat_unl_done;\n+\tnt_field_t *mp_stat_unl_done_cnt;\n+\n+\tnt_register_t *mp_stat_unl_ignore;\n+\tnt_field_t *mp_stat_unl_ignore_cnt;\n+\n+\tnt_register_t *mp_stat_prb_done;\n+\tnt_field_t *mp_stat_prb_done_cnt;\n+\n+\tnt_register_t *mp_stat_prb_ignore;\n+\tnt_field_t *mp_stat_prb_ignore_cnt;\n+\n+\tnt_register_t *mp_stat_rel_done;\n+\tnt_field_t *mp_stat_rel_done_cnt;\n+\n+\tnt_register_t *mp_stat_rel_ignore;\n+\tnt_field_t *mp_stat_rel_ignore_cnt;\n+\n+\tnt_register_t *mp_stat_aul_done;\n+\tnt_field_t *mp_stat_aul_done_cnt;\n+\n+\tnt_register_t *mp_stat_aul_ignore;\n+\tnt_field_t *mp_stat_aul_ignore_cnt;\n+\n+\tnt_register_t *mp_stat_aul_fail;\n+\tnt_field_t *mp_stat_aul_fail_cnt;\n+\n+\tnt_register_t *mp_stat_tul_done;\n+\tnt_field_t *mp_stat_tul_done_cnt;\n+\n+\tnt_register_t *mp_stat_flows;\n+\tnt_field_t *mp_stat_flows_cnt;\n+\n+\tnt_register_t *mp_stat_sta_done;\n+\tnt_field_t *mp_stat_sta_done_cnt;\n+\n+\tnt_register_t *mp_stat_inf_done;\n+\tnt_field_t *mp_stat_inf_done_cnt;\n+\n+\tnt_register_t *mp_stat_inf_skip;\n+\tnt_field_t *mp_stat_inf_skip_cnt;\n+\n+\tnt_register_t *mp_stat_pck_hit;\n+\tnt_field_t *mp_stat_pck_hit_cnt;\n+\n+\tnt_register_t *mp_stat_pck_miss;\n+\tnt_field_t *mp_stat_pck_miss_cnt;\n+\n+\tnt_register_t *mp_stat_pck_unh;\n+\tnt_field_t *mp_stat_pck_unh_cnt;\n+\n+\tnt_register_t *mp_stat_pck_dis;\n+\tnt_field_t *mp_stat_pck_dis_cnt;\n+\n+\tnt_register_t *mp_stat_csh_hit;\n+\tnt_field_t *mp_stat_csh_hit_cnt;\n+\n+\tnt_register_t *mp_stat_csh_miss;\n+\tnt_field_t *mp_stat_csh_miss_cnt;\n+\n+\tnt_register_t *mp_stat_csh_unh;\n+\tnt_field_t *mp_stat_csh_unh_cnt;\n+\n+\tnt_register_t *mp_stat_cuc_start;\n+\tnt_field_t *mp_stat_cuc_start_cnt;\n+\n+\tnt_register_t *mp_stat_cuc_move;\n+\tnt_field_t *mp_stat_cuc_move_cnt;\n+};\n+\n+#endif /* __FLOW_NTHW_FLM_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hfu.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hfu.c\nnew file mode 100644\nindex 0000000000..b7fe7c5863\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hfu.c\n@@ -0,0 +1,293 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_hfu.h\"\n+\n+#include <stdlib.h>\n+#include <string.h>\n+\n+void hfu_nthw_set_debug_mode(struct hfu_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_hfu, n_debug_mode);\n+}\n+\n+struct hfu_nthw *hfu_nthw_new(void)\n+{\n+\tstruct hfu_nthw *p = malloc(sizeof(struct hfu_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\treturn p;\n+}\n+\n+void hfu_nthw_delete(struct hfu_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int hfu_nthw_init(struct hfu_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_HFU, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Hfu %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_hfu = fpga_query_module(p_fpga, MOD_HFU, n_instance);\n+\n+\tp->mp_rcp_ctrl = module_get_register(p->m_hfu, HFU_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, HFU_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, HFU_RCP_CTRL_CNT);\n+\n+\tp->mp_rcp_data = module_get_register(p->m_hfu, HFU_RCP_DATA);\n+\tp->mp_rcp_data_len_a_wr =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_A_WR);\n+\tp->mp_rcp_data_len_a_ol4len =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_A_OL4LEN);\n+\tp->mp_rcp_data_len_a_pos_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_A_POS_DYN);\n+\tp->mp_rcp_data_len_a_pos_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_A_POS_OFS);\n+\tp->mp_rcp_data_len_a_add_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_A_ADD_DYN);\n+\tp->mp_rcp_data_len_a_add_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_A_ADD_OFS);\n+\tp->mp_rcp_data_len_a_sub_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_A_SUB_DYN);\n+\tp->mp_rcp_data_len_b_wr =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_B_WR);\n+\tp->mp_rcp_data_len_b_pos_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_B_POS_DYN);\n+\tp->mp_rcp_data_len_b_pos_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_B_POS_OFS);\n+\tp->mp_rcp_data_len_b_add_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_B_ADD_DYN);\n+\tp->mp_rcp_data_len_b_add_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_B_ADD_OFS);\n+\tp->mp_rcp_data_len_b_sub_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_B_SUB_DYN);\n+\tp->mp_rcp_data_len_c_wr =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_C_WR);\n+\tp->mp_rcp_data_len_c_pos_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_C_POS_DYN);\n+\tp->mp_rcp_data_len_c_pos_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_C_POS_OFS);\n+\tp->mp_rcp_data_len_c_add_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_C_ADD_DYN);\n+\tp->mp_rcp_data_len_c_add_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_C_ADD_OFS);\n+\tp->mp_rcp_data_len_c_sub_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_LEN_C_SUB_DYN);\n+\tp->mp_rcp_data_ttl_wr =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_TTL_WR);\n+\tp->mp_rcp_data_ttl_pos_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_TTL_POS_DYN);\n+\tp->mp_rcp_data_ttl_pos_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_TTL_POS_OFS);\n+\tp->mp_rcp_data_csinf = register_get_field(p->mp_rcp_data, HFU_RCP_DATA_CSINF);\n+\tp->mp_rcp_data_l3prt = register_get_field(p->mp_rcp_data, HFU_RCP_DATA_L3PRT);\n+\tp->mp_rcp_data_l3frag =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_L3FRAG);\n+\tp->mp_rcp_data_tunnel =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_TUNNEL);\n+\tp->mp_rcp_data_l4prt = register_get_field(p->mp_rcp_data, HFU_RCP_DATA_L4PRT);\n+\tp->mp_rcp_data_ol3ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_OL3OFS);\n+\tp->mp_rcp_data_ol4ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_OL4OFS);\n+\tp->mp_rcp_data_il3ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_IL3OFS);\n+\tp->mp_rcp_data_il4ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HFU_RCP_DATA_IL4OFS);\n+\n+\treturn 0;\n+}\n+\n+void hfu_nthw_rcp_select(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void hfu_nthw_rcp_cnt(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void hfu_nthw_rcp_len_a_wr(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_a_wr, val);\n+}\n+\n+void hfu_nthw_rcp_len_a_ol4len(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_a_ol4len, val);\n+}\n+\n+void hfu_nthw_rcp_len_a_pos_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_a_pos_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_len_a_pos_ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_a_pos_ofs, val);\n+}\n+\n+void hfu_nthw_rcp_len_a_add_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_a_add_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_len_a_add_ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_a_add_ofs, val);\n+}\n+\n+void hfu_nthw_rcp_len_a_sub_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_a_sub_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_len_b_wr(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_b_wr, val);\n+}\n+\n+void hfu_nthw_rcp_len_b_pos_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_b_pos_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_len_b_pos_ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_b_pos_ofs, val);\n+}\n+\n+void hfu_nthw_rcp_len_b_add_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_b_add_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_len_b_add_ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_b_add_ofs, val);\n+}\n+\n+void hfu_nthw_rcp_len_b_sub_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_b_sub_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_len_c_wr(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_c_wr, val);\n+}\n+\n+void hfu_nthw_rcp_len_c_pos_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_c_pos_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_len_c_pos_ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_c_pos_ofs, val);\n+}\n+\n+void hfu_nthw_rcp_len_c_add_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_c_add_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_len_c_add_ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_c_add_ofs, val);\n+}\n+\n+void hfu_nthw_rcp_len_c_sub_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len_c_sub_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_ttl_wr(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ttl_wr, val);\n+}\n+\n+void hfu_nthw_rcp_ttl_pos_dyn(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ttl_pos_dyn, val);\n+}\n+\n+void hfu_nthw_rcp_ttl_pos_ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ttl_pos_ofs, val);\n+}\n+\n+void hfu_nthw_rcp_csinf(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_csinf, val);\n+}\n+\n+void hfu_nthw_rcp_l3prt(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_l3prt, val);\n+}\n+\n+void hfu_nthw_rcp_l3frag(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_l3frag, val);\n+}\n+\n+void hfu_nthw_rcp_tunnel(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tunnel, val);\n+}\n+\n+void hfu_nthw_rcp_l4prt(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_l4prt, val);\n+}\n+\n+void hfu_nthw_rcp_ol3ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ol3ofs, val);\n+}\n+\n+void hfu_nthw_rcp_ol4ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ol4ofs, val);\n+}\n+\n+void hfu_nthw_rcp_il3ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_il3ofs, val);\n+}\n+\n+void hfu_nthw_rcp_il4ofs(const struct hfu_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_il4ofs, val);\n+}\n+\n+void hfu_nthw_rcp_flush(const struct hfu_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hfu.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hfu.h\nnew file mode 100644\nindex 0000000000..ecba1a8822\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hfu.h\n@@ -0,0 +1,100 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_HFU_H__\n+#define __FLOW_NTHW_HFU_H__\n+\n+#include <stdint.h>\n+#include \"nthw_fpga_model.h\"\n+\n+struct hfu_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_hfu;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_len_a_wr;\n+\tnt_field_t *mp_rcp_data_len_a_ol4len;\n+\tnt_field_t *mp_rcp_data_len_a_pos_dyn;\n+\tnt_field_t *mp_rcp_data_len_a_pos_ofs;\n+\tnt_field_t *mp_rcp_data_len_a_add_dyn;\n+\tnt_field_t *mp_rcp_data_len_a_add_ofs;\n+\tnt_field_t *mp_rcp_data_len_a_sub_dyn;\n+\tnt_field_t *mp_rcp_data_len_b_wr;\n+\tnt_field_t *mp_rcp_data_len_b_pos_dyn;\n+\tnt_field_t *mp_rcp_data_len_b_pos_ofs;\n+\tnt_field_t *mp_rcp_data_len_b_add_dyn;\n+\tnt_field_t *mp_rcp_data_len_b_add_ofs;\n+\tnt_field_t *mp_rcp_data_len_b_sub_dyn;\n+\tnt_field_t *mp_rcp_data_len_c_wr;\n+\tnt_field_t *mp_rcp_data_len_c_pos_dyn;\n+\tnt_field_t *mp_rcp_data_len_c_pos_ofs;\n+\tnt_field_t *mp_rcp_data_len_c_add_dyn;\n+\tnt_field_t *mp_rcp_data_len_c_add_ofs;\n+\tnt_field_t *mp_rcp_data_len_c_sub_dyn;\n+\tnt_field_t *mp_rcp_data_ttl_wr;\n+\tnt_field_t *mp_rcp_data_ttl_pos_dyn;\n+\tnt_field_t *mp_rcp_data_ttl_pos_ofs;\n+\tnt_field_t *mp_rcp_data_csinf;\n+\tnt_field_t *mp_rcp_data_l3prt;\n+\tnt_field_t *mp_rcp_data_l3frag;\n+\tnt_field_t *mp_rcp_data_tunnel;\n+\tnt_field_t *mp_rcp_data_l4prt;\n+\tnt_field_t *mp_rcp_data_ol3ofs;\n+\tnt_field_t *mp_rcp_data_ol4ofs;\n+\tnt_field_t *mp_rcp_data_il3ofs;\n+\tnt_field_t *mp_rcp_data_il4ofs;\n+};\n+\n+struct hfu_nthw *hfu_nthw_new(void);\n+void hfu_nthw_delete(struct hfu_nthw *p);\n+int hfu_nthw_init(struct hfu_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int hfu_nthw_setup(struct hfu_nthw *p, int n_idx, int n_idx_cnt);\n+void hfu_nthw_set_debug_mode(struct hfu_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void hfu_nthw_rcp_select(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_cnt(const struct hfu_nthw *p, uint32_t val);\n+\n+void hfu_nthw_rcp_len_a_wr(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_a_ol4len(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_a_pos_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_a_pos_ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_a_add_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_a_add_ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_a_sub_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_b_wr(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_b_pos_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_b_pos_ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_b_add_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_b_add_ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_b_sub_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_c_wr(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_c_pos_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_c_pos_ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_c_add_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_c_add_ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_len_c_sub_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_ttl_wr(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_ttl_pos_dyn(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_ttl_pos_ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_csinf(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_l3prt(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_l3frag(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_tunnel(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_l4prt(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_ol3ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_ol4ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_il3ofs(const struct hfu_nthw *p, uint32_t val);\n+void hfu_nthw_rcp_il4ofs(const struct hfu_nthw *p, uint32_t val);\n+\n+void hfu_nthw_rcp_flush(const struct hfu_nthw *p);\n+\n+#endif /* __FLOW_NTHW_HFU_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hsh.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hsh.c\nnew file mode 100644\nindex 0000000000..0dc6434e88\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hsh.c\n@@ -0,0 +1,254 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_hsh.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void hsh_nthw_set_debug_mode(struct hsh_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_hsh, n_debug_mode);\n+}\n+\n+struct hsh_nthw *hsh_nthw_new(void)\n+{\n+\tstruct hsh_nthw *p = malloc(sizeof(struct hsh_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void hsh_nthw_delete(struct hsh_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int hsh_nthw_init(struct hsh_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_HSH, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Hsh %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_hsh = p_mod;\n+\n+\t/* RCP */\n+\tp->mp_rcp_ctrl = module_get_register(p->m_hsh, HSH_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, HSH_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, HSH_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_hsh, HSH_RCP_DATA);\n+\tp->mp_rcp_data_load_dist_type =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_LOAD_DIST_TYPE);\n+\tp->mp_rcp_data_mac_port_mask =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_MAC_PORT_MASK);\n+\tp->mp_rcp_data_sort = register_get_field(p->mp_rcp_data, HSH_RCP_DATA_SORT);\n+\tp->mp_rcp_data_qw0_pe =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_QW0_PE);\n+\tp->mp_rcp_data_qw0_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_QW0_OFS);\n+\tp->mp_rcp_data_qw4_pe =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_QW4_PE);\n+\tp->mp_rcp_data_qw4_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_QW4_OFS);\n+\tp->mp_rcp_data_w8_pe = register_get_field(p->mp_rcp_data, HSH_RCP_DATA_W8_PE);\n+\tp->mp_rcp_data_w8_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_W8_OFS);\n+\tp->mp_rcp_data_w8_sort =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_W8_SORT);\n+\tp->mp_rcp_data_w9_pe = register_get_field(p->mp_rcp_data, HSH_RCP_DATA_W9_PE);\n+\tp->mp_rcp_data_w9_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_W9_OFS);\n+\tp->mp_rcp_data_w9_sort =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_W9_SORT);\n+\tp->mp_rcp_data_w9_p = register_get_field(p->mp_rcp_data, HSH_RCP_DATA_W9_P);\n+\tp->mp_rcp_data_p_mask =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_P_MASK);\n+\tp->mp_rcp_data_word_mask =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_WORD_MASK);\n+\tp->mp_rcp_data_seed = register_get_field(p->mp_rcp_data, HSH_RCP_DATA_SEED);\n+\tp->mp_rcp_data_tnl_p = register_get_field(p->mp_rcp_data, HSH_RCP_DATA_TNL_P);\n+\tp->mp_rcp_data_hsh_valid =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_HSH_VALID);\n+\tp->mp_rcp_data_hsh_type =\n+\t\tregister_get_field(p->mp_rcp_data, HSH_RCP_DATA_HSH_TYPE);\n+\tp->mp_rcp_data_auto_ipv4_mask =\n+\t\tregister_query_field(p->mp_rcp_data, HSH_RCP_DATA_AUTO_IPV4_MASK);\n+\n+\t/* Init */\n+\tuint32_t val[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\n+\n+\tfield_set_val32(p->mp_rcp_addr, 0);\n+\tfield_set_val32(p->mp_rcp_cnt, 1);\n+\n+\tfield_set_val32(p->mp_rcp_data_load_dist_type, 0);\n+\tfield_set_val(p->mp_rcp_data_mac_port_mask, val,\n+\t\t     p->mp_rcp_data_mac_port_mask->mn_words);\n+\tfield_set_val32(p->mp_rcp_data_sort, 0);\n+\tfield_set_val32(p->mp_rcp_data_qw0_pe, 0);\n+\tfield_set_val32(p->mp_rcp_data_qw0_ofs, 0);\n+\tfield_set_val32(p->mp_rcp_data_qw4_pe, 0);\n+\tfield_set_val32(p->mp_rcp_data_qw4_ofs, 0);\n+\tfield_set_val32(p->mp_rcp_data_w8_pe, 0);\n+\tfield_set_val32(p->mp_rcp_data_w8_ofs, 0);\n+\tfield_set_val32(p->mp_rcp_data_w8_sort, 0);\n+\tfield_set_val32(p->mp_rcp_data_w9_pe, 0);\n+\tfield_set_val32(p->mp_rcp_data_w9_ofs, 0);\n+\tfield_set_val32(p->mp_rcp_data_w9_sort, 0);\n+\tfield_set_val32(p->mp_rcp_data_w9_p, 0);\n+\tfield_set_val(p->mp_rcp_data_word_mask, val, 10);\n+\tfield_set_val32(p->mp_rcp_data_seed, 0);\n+\tfield_set_val32(p->mp_rcp_data_tnl_p, 0);\n+\tfield_set_val32(p->mp_rcp_data_hsh_valid, 0);\n+\tfield_set_val32(p->mp_rcp_data_hsh_type, 31);\n+\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+\n+\treturn 0;\n+}\n+\n+void hsh_nthw_rcp_select(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void hsh_nthw_rcp_cnt(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void hsh_nthw_rcp_load_dist_type(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_load_dist_type, val);\n+}\n+\n+void hsh_nthw_rcp_mac_port_mask(const struct hsh_nthw *p, uint32_t *val)\n+{\n+\tfield_set_val(p->mp_rcp_data_mac_port_mask, val,\n+\t\t     p->mp_rcp_data_mac_port_mask->mn_words);\n+}\n+\n+void hsh_nthw_rcp_sort(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sort, val);\n+}\n+\n+void hsh_nthw_rcp_qw0_pe(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_pe, val);\n+}\n+\n+void hsh_nthw_rcp_qw0_ofs(const struct hsh_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_ofs, val);\n+}\n+\n+void hsh_nthw_rcp_qw4_pe(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw4_pe, val);\n+}\n+\n+void hsh_nthw_rcp_qw4_ofs(const struct hsh_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw4_ofs, val);\n+}\n+\n+void hsh_nthw_rcp_w8_pe(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_w8_pe, val);\n+}\n+\n+void hsh_nthw_rcp_w8_ofs(const struct hsh_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_w8_ofs, val);\n+}\n+\n+void hsh_nthw_rcp_w8_sort(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_w8_sort, val);\n+}\n+\n+void hsh_nthw_rcp_w9_pe(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_w9_pe, val);\n+}\n+\n+void hsh_nthw_rcp_w9_ofs(const struct hsh_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_w9_ofs, val);\n+}\n+\n+void hsh_nthw_rcp_w9_sort(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_w9_sort, val);\n+}\n+\n+void hsh_nthw_rcp_w9_p(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_w9_p, val);\n+}\n+\n+void hsh_nthw_rcp_p_mask(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_p_mask, val);\n+}\n+\n+void hsh_nthw_rcp_word_mask(const struct hsh_nthw *p, uint32_t *val)\n+{\n+\tfield_set_val(p->mp_rcp_data_word_mask, val, 10);\n+}\n+\n+void hsh_nthw_rcp_seed(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_seed, val);\n+}\n+\n+void hsh_nthw_rcp_tnl_p(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tnl_p, val);\n+}\n+\n+void hsh_nthw_rcp_hsh_valid(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_hsh_valid, val);\n+}\n+\n+void hsh_nthw_rcp_hsh_type(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_hsh_type, val);\n+}\n+\n+void hsh_nthw_rcp_auto_ipv4_mask(const struct hsh_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_rcp_data_auto_ipv4_mask)\n+\t\tfield_set_val32(p->mp_rcp_data_auto_ipv4_mask, val);\n+}\n+\n+void hsh_nthw_rcp_flush(const struct hsh_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hsh.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hsh.h\nnew file mode 100644\nindex 0000000000..7cb7dbb743\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hsh.h\n@@ -0,0 +1,81 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_HSH_H__\n+#define __FLOW_NTHW_HSH_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct hsh_nthw;\n+\n+typedef struct hsh_nthw hsh_nthw_t;\n+\n+struct hsh_nthw *hsh_nthw_new(void);\n+void hsh_nthw_delete(struct hsh_nthw *p);\n+int hsh_nthw_init(struct hsh_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int hsh_nthw_setup(struct hsh_nthw *p, int n_idx, int n_idx_cnt);\n+void hsh_nthw_set_debug_mode(struct hsh_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void hsh_nthw_rcp_select(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_cnt(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_load_dist_type(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_mac_port_mask(const struct hsh_nthw *p, uint32_t *val);\n+void hsh_nthw_rcp_sort(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_qw0_pe(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_qw0_ofs(const struct hsh_nthw *p, int32_t val);\n+void hsh_nthw_rcp_qw4_pe(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_qw4_ofs(const struct hsh_nthw *p, int32_t val);\n+void hsh_nthw_rcp_w8_pe(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_w8_ofs(const struct hsh_nthw *p, int32_t val);\n+void hsh_nthw_rcp_w8_sort(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_w9_pe(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_w9_ofs(const struct hsh_nthw *p, int32_t val);\n+void hsh_nthw_rcp_w9_sort(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_w9_p(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_p_mask(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_word_mask(const struct hsh_nthw *p, uint32_t *val);\n+void hsh_nthw_rcp_seed(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_tnl_p(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_hsh_valid(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_hsh_type(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_auto_ipv4_mask(const struct hsh_nthw *p, uint32_t val);\n+void hsh_nthw_rcp_flush(const struct hsh_nthw *p);\n+\n+struct hsh_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_hsh;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_load_dist_type;\n+\tnt_field_t *mp_rcp_data_mac_port_mask;\n+\tnt_field_t *mp_rcp_data_sort;\n+\tnt_field_t *mp_rcp_data_qw0_pe;\n+\tnt_field_t *mp_rcp_data_qw0_ofs;\n+\tnt_field_t *mp_rcp_data_qw4_pe;\n+\tnt_field_t *mp_rcp_data_qw4_ofs;\n+\tnt_field_t *mp_rcp_data_w8_pe;\n+\tnt_field_t *mp_rcp_data_w8_ofs;\n+\tnt_field_t *mp_rcp_data_w8_sort;\n+\tnt_field_t *mp_rcp_data_w9_pe;\n+\tnt_field_t *mp_rcp_data_w9_ofs;\n+\tnt_field_t *mp_rcp_data_w9_sort;\n+\tnt_field_t *mp_rcp_data_w9_p;\n+\tnt_field_t *mp_rcp_data_p_mask;\n+\tnt_field_t *mp_rcp_data_word_mask;\n+\tnt_field_t *mp_rcp_data_seed;\n+\tnt_field_t *mp_rcp_data_tnl_p;\n+\tnt_field_t *mp_rcp_data_hsh_valid;\n+\tnt_field_t *mp_rcp_data_hsh_type;\n+\tnt_field_t *mp_rcp_data_auto_ipv4_mask;\n+};\n+\n+#endif /* __FLOW_NTHW_HSH_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hst.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hst.c\nnew file mode 100644\nindex 0000000000..fc3dc443a2\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hst.c\n@@ -0,0 +1,202 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_hst.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void hst_nthw_set_debug_mode(struct hst_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_hst, n_debug_mode);\n+}\n+\n+struct hst_nthw *hst_nthw_new(void)\n+{\n+\tstruct hst_nthw *p = malloc(sizeof(struct hst_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void hst_nthw_delete(struct hst_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int hst_nthw_init(struct hst_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_HST, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Hst %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_hst = p_mod;\n+\n+\t/* RCP */\n+\tp->mp_rcp_ctrl = module_get_register(p->m_hst, HST_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, HST_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, HST_RCP_CTRL_CNT);\n+\n+\tp->mp_rcp_data = module_get_register(p->m_hst, HST_RCP_DATA);\n+\tp->mp_rcp_data_strip_mode =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_STRIP_MODE);\n+\tp->mp_rcp_data_start_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_START_DYN);\n+\tp->mp_rcp_data_start_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_START_OFS);\n+\tp->mp_rcp_data_end_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_END_DYN);\n+\tp->mp_rcp_data_end_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_END_OFS);\n+\tp->mp_rcp_data_modif0_cmd =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF0_CMD);\n+\tp->mp_rcp_data_modif0_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF0_DYN);\n+\tp->mp_rcp_data_modif0_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF0_OFS);\n+\tp->mp_rcp_data_modif0_value =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF0_VALUE);\n+\tp->mp_rcp_data_modif1_cmd =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF1_CMD);\n+\tp->mp_rcp_data_modif1_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF1_DYN);\n+\tp->mp_rcp_data_modif1_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF1_OFS);\n+\tp->mp_rcp_data_modif1_value =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF1_VALUE);\n+\tp->mp_rcp_data_modif2_cmd =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF2_CMD);\n+\tp->mp_rcp_data_modif2_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF2_DYN);\n+\tp->mp_rcp_data_modif2_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF2_OFS);\n+\tp->mp_rcp_data_modif2_value =\n+\t\tregister_get_field(p->mp_rcp_data, HST_RCP_DATA_MODIF2_VALUE);\n+\n+\treturn 0;\n+}\n+\n+/* RCP */\n+void hst_nthw_rcp_select(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void hst_nthw_rcp_cnt(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void hst_nthw_rcp_strip_mode(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_strip_mode, val);\n+}\n+\n+void hst_nthw_rcp_start_dyn(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_start_dyn, val);\n+}\n+\n+void hst_nthw_rcp_start_ofs(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_start_ofs, val);\n+}\n+\n+void hst_nthw_rcp_end_dyn(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_end_dyn, val);\n+}\n+\n+void hst_nthw_rcp_end_ofs(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_end_ofs, val);\n+}\n+\n+void hst_nthw_rcp_modif0_cmd(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif0_cmd, val);\n+}\n+\n+void hst_nthw_rcp_modif0_dyn(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif0_dyn, val);\n+}\n+\n+void hst_nthw_rcp_modif0_ofs(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif0_ofs, val);\n+}\n+\n+void hst_nthw_rcp_modif0_value(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif0_value, val);\n+}\n+\n+void hst_nthw_rcp_modif1_cmd(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif1_cmd, val);\n+}\n+\n+void hst_nthw_rcp_modif1_dyn(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif1_dyn, val);\n+}\n+\n+void hst_nthw_rcp_modif1_ofs(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif1_ofs, val);\n+}\n+\n+void hst_nthw_rcp_modif1_value(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif1_value, val);\n+}\n+\n+void hst_nthw_rcp_modif2_cmd(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif2_cmd, val);\n+}\n+\n+void hst_nthw_rcp_modif2_dyn(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif2_dyn, val);\n+}\n+\n+void hst_nthw_rcp_modif2_ofs(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif2_ofs, val);\n+}\n+\n+void hst_nthw_rcp_modif2_value(const struct hst_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_modif2_value, val);\n+}\n+\n+void hst_nthw_rcp_flush(const struct hst_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hst.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hst.h\nnew file mode 100644\nindex 0000000000..5bc7eb6e55\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_hst.h\n@@ -0,0 +1,72 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_HST_H__\n+#define __FLOW_NTHW_HST_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct hst_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_hst;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_strip_mode;\n+\tnt_field_t *mp_rcp_data_start_dyn;\n+\tnt_field_t *mp_rcp_data_start_ofs;\n+\tnt_field_t *mp_rcp_data_end_dyn;\n+\tnt_field_t *mp_rcp_data_end_ofs;\n+\tnt_field_t *mp_rcp_data_modif0_cmd;\n+\tnt_field_t *mp_rcp_data_modif0_dyn;\n+\tnt_field_t *mp_rcp_data_modif0_ofs;\n+\tnt_field_t *mp_rcp_data_modif0_value;\n+\tnt_field_t *mp_rcp_data_modif1_cmd;\n+\tnt_field_t *mp_rcp_data_modif1_dyn;\n+\tnt_field_t *mp_rcp_data_modif1_ofs;\n+\tnt_field_t *mp_rcp_data_modif1_value;\n+\tnt_field_t *mp_rcp_data_modif2_cmd;\n+\tnt_field_t *mp_rcp_data_modif2_dyn;\n+\tnt_field_t *mp_rcp_data_modif2_ofs;\n+\tnt_field_t *mp_rcp_data_modif2_value;\n+};\n+\n+typedef struct hst_nthw hst_nthw_t;\n+\n+struct hst_nthw *hst_nthw_new(void);\n+void hst_nthw_delete(struct hst_nthw *p);\n+int hst_nthw_init(struct hst_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int hst_nthw_setup(struct hst_nthw *p, int n_idx, int n_idx_cnt);\n+void hst_nthw_set_debug_mode(struct hst_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void hst_nthw_rcp_select(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_cnt(const struct hst_nthw *p, uint32_t val);\n+\n+void hst_nthw_rcp_strip_mode(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_start_dyn(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_start_ofs(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_end_dyn(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_end_ofs(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif0_cmd(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif0_dyn(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif0_ofs(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif0_value(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif1_cmd(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif1_dyn(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif1_ofs(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif1_value(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif2_cmd(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif2_dyn(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif2_ofs(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_modif2_value(const struct hst_nthw *p, uint32_t val);\n+void hst_nthw_rcp_flush(const struct hst_nthw *p);\n+\n+#endif /* __FLOW_NTHW_HST_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.c\nnew file mode 100644\nindex 0000000000..0f51a36e57\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.c\n@@ -0,0 +1,93 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_ifr.h\"\n+\n+void ifr_nthw_set_debug_mode(struct ifr_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_ifr, n_debug_mode);\n+}\n+\n+struct ifr_nthw *ifr_nthw_new(void)\n+{\n+\tstruct ifr_nthw *p = malloc(sizeof(struct ifr_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\treturn p;\n+}\n+\n+void ifr_nthw_delete(struct ifr_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int ifr_nthw_init(struct ifr_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_IFR, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Ifr %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_ifr = fpga_query_module(p_fpga, MOD_IFR, n_instance);\n+\n+\tp->mp_rcp_ctrl = module_get_register(p->m_ifr, IFR_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, IFR_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, IFR_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_ifr, IFR_RCP_DATA);\n+\tp->mp_rcp_data_en = register_get_field(p->mp_rcp_data, IFR_RCP_DATA_EN);\n+\tp->mp_rcp_data_mtu = register_get_field(p->mp_rcp_data, IFR_RCP_DATA_MTU);\n+\n+\treturn 0;\n+}\n+\n+void ifr_nthw_rcp_select(const struct ifr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_rcp_addr);\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void ifr_nthw_rcp_cnt(const struct ifr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_rcp_cnt);\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void ifr_nthw_rcp_en(const struct ifr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_rcp_data_en);\n+\tfield_set_val32(p->mp_rcp_data_en, val);\n+}\n+\n+void ifr_nthw_rcp_mtu(const struct ifr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_rcp_data_en);\n+\tfield_set_val32(p->mp_rcp_data_mtu, val);\n+}\n+\n+void ifr_nthw_rcp_flush(const struct ifr_nthw *p)\n+{\n+\tassert(p->mp_rcp_ctrl);\n+\tassert(p->mp_rcp_data);\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.h\nnew file mode 100644\nindex 0000000000..626ca3d193\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ifr.h\n@@ -0,0 +1,39 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_IFR_H__\n+#define __FLOW_NTHW_IFR_H__\n+\n+#include \"nthw_fpga_model.h\"\n+\n+struct ifr_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_ifr;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_en;\n+\tnt_field_t *mp_rcp_data_mtu;\n+};\n+\n+struct ifr_nthw *ifr_nthw_new(void);\n+void ifr_nthw_delete(struct ifr_nthw *p);\n+int ifr_nthw_init(struct ifr_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int ifr_nthw_setup(struct ifr_nthw *p, int n_idx, int n_idx_cnt);\n+void ifr_nthw_set_debug_mode(struct ifr_nthw *p, unsigned int n_debug_mode);\n+\n+/* IFR */\n+void ifr_nthw_rcp_select(const struct ifr_nthw *p, uint32_t val);\n+void ifr_nthw_rcp_cnt(const struct ifr_nthw *p, uint32_t val);\n+void ifr_nthw_rcp_en(const struct ifr_nthw *p, uint32_t val);\n+void ifr_nthw_rcp_mtu(const struct ifr_nthw *p, uint32_t val);\n+void ifr_nthw_rcp_flush(const struct ifr_nthw *p);\n+\n+#endif /* __FLOW_NTHW_IFR_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_info.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_info.c\nnew file mode 100644\nindex 0000000000..27b55e3b7c\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_info.c\n@@ -0,0 +1,341 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"nt_util.h\"\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+#include \"nthw_fpga_model.h\"\n+\n+#include \"flow_nthw_info.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+static inline unsigned int clamp_one(unsigned int val)\n+{\n+\treturn val > 1 ? 1 : val;\n+}\n+\n+struct info_nthw *info_nthw_new(void)\n+{\n+\tstruct info_nthw *p = malloc(sizeof(struct info_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void info_nthw_delete(struct info_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int info_nthw_init(struct info_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\n+\tunsigned int km_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_KM_PRESENT, 0));\n+\tunsigned int kcc_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_CAT_KCC_PRESENT, 0));\n+\tunsigned int ioa_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_IOA_PRESENT, 0));\n+\tunsigned int roa_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_ROA_PRESENT, 0));\n+\tunsigned int dbs_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_DBS_PRESENT, 0));\n+\tunsigned int flm_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_FLM_PRESENT, 0));\n+\tunsigned int hst_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_HST_PRESENT, 0));\n+\n+\t/* Modules for Tx Packet Edit function */\n+\tunsigned int hfu_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_HFU_PRESENT, 0));\n+\tunsigned int tx_cpy_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_TX_CPY_PRESENT, 0));\n+\tunsigned int tx_ins_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_TX_INS_PRESENT, 0));\n+\tunsigned int tx_rpl_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_TX_RPL_PRESENT, 0));\n+\tunsigned int csu_present =\n+\t\tclamp_one(fpga_get_product_param(p_fpga, NT_CSU_PRESENT, 0));\n+\tunsigned int tpe_present = (hfu_present && tx_cpy_present && tx_ins_present &&\n+\t\t\t\t   tx_rpl_present && csu_present) ?\n+\t\t\t\t  1 :\n+\t\t\t\t  0;\n+\n+\tp->n_phy_ports = fpga_get_product_param(p_fpga, NT_PHY_PORTS, 0);\n+\tp->n_rx_ports = fpga_get_product_param(p_fpga, NT_RX_PORTS, 0);\n+\tp->n_ltx_avail = fpga_get_product_param(p_fpga, NT_LR_PRESENT, 0);\n+\tp->nb_cat_func = fpga_get_product_param(p_fpga, NT_CAT_FUNCS, 0);\n+\tp->nb_categories = fpga_get_product_param(p_fpga, NT_CATEGORIES, 0);\n+\tp->nb_queues = fpga_get_product_param(p_fpga, NT_QUEUES, 0);\n+\tp->nb_flow_types = fpga_get_product_param(p_fpga, NT_KM_FLOW_TYPES, 0) *\n+\t\t\t clamp_one(km_present + flm_present);\n+\tp->nb_pm_ext = fpga_get_product_param(p_fpga, NT_CAT_N_EXT, 0);\n+\tp->nb_len = fpga_get_product_param(p_fpga, NT_CAT_N_LEN, 0);\n+\tp->nb_kcc_size =\n+\t\tfpga_get_product_param(p_fpga, NT_CAT_KCC_SIZE, 0) * kcc_present;\n+\tp->nb_kcc_banks =\n+\t\tfpga_get_product_param(p_fpga, NT_CAT_KCC_BANKS, 0) * kcc_present;\n+\tp->nb_km_categories =\n+\t\tfpga_get_product_param(p_fpga, NT_KM_CATEGORIES, 0) * km_present;\n+\tp->nb_km_cam_banks =\n+\t\tfpga_get_product_param(p_fpga, NT_KM_CAM_BANKS, 0) * km_present;\n+\tp->nb_km_cam_record_words =\n+\t\tfpga_get_product_param(p_fpga, NT_KM_CAM_REC_WORDS, 0) * km_present;\n+\tp->nb_km_cam_records =\n+\t\tfpga_get_product_param(p_fpga, NT_KM_CAM_RECORDS, 0) * km_present;\n+\tp->nb_km_tcam_banks =\n+\t\tfpga_get_product_param(p_fpga, NT_KM_TCAM_BANKS, 0) * km_present;\n+\tp->nb_km_tcam_bank_width =\n+\t\tfpga_get_product_param(p_fpga, NT_KM_TCAM_BANK_WIDTH, 0) *\n+\t\tkm_present;\n+\tp->nb_flm_categories =\n+\t\tfpga_get_product_param(p_fpga, NT_FLM_CATEGORIES, 0) * flm_present;\n+\tp->nb_flm_size_mb = fpga_get_product_param(p_fpga, NT_FLM_SIZE_MB, 0);\n+\tp->nb_flm_entry_size = fpga_get_product_param(p_fpga, NT_FLM_ENTRY_SIZE, 0);\n+\tp->nb_flm_variant = fpga_get_product_param(p_fpga, NT_FLM_VARIANT, 0);\n+\tp->nb_flm_prios =\n+\t\tfpga_get_product_param(p_fpga, NT_FLM_PRIOS, 0) * flm_present;\n+\tp->nb_flm_pst_profiles =\n+\t\tfpga_get_product_param(p_fpga, NT_FLM_PST_PROFILES, 0) *\n+\t\tflm_present;\n+\tp->nb_hst_categories =\n+\t\tfpga_get_product_param(p_fpga, NT_HST_CATEGORIES, 0) * hst_present;\n+\tp->nb_qsl_categories = fpga_get_product_param(p_fpga, NT_QSL_CATEGORIES, 0);\n+\tp->nb_qsl_qst_entries = fpga_get_product_param(p_fpga, NT_QSL_QST_SIZE, 0);\n+\tp->nb_pdb_categories = fpga_get_product_param(p_fpga, NT_PDB_CATEGORIES, 0);\n+\tp->nb_ioa_categories =\n+\t\tfpga_get_product_param(p_fpga, NT_IOA_CATEGORIES, 0) * ioa_present;\n+\tp->nb_roa_categories =\n+\t\tfpga_get_product_param(p_fpga, NT_ROA_CATEGORIES, 0) * roa_present;\n+\tp->nb_dbs_categories =\n+\t\tRTE_MIN(fpga_get_product_param(p_fpga, NT_DBS_RX_QUEUES, 0),\n+\t\t    fpga_get_product_param(p_fpga, NT_DBS_TX_QUEUES, 0)) *\n+\t\tdbs_present;\n+\tp->nb_cat_km_if_cnt = fpga_get_product_param(p_fpga, NT_CAT_KM_IF_CNT,\n+\t\t\t\t\t       km_present + flm_present);\n+\tp->m_cat_km_if_m0 = fpga_get_product_param(p_fpga, NT_CAT_KM_IF_M0, -1);\n+\tp->m_cat_km_if_m1 = fpga_get_product_param(p_fpga, NT_CAT_KM_IF_M1, -1);\n+\tp->nb_tpe_categories =\n+\t\tfpga_get_product_param(p_fpga, NT_TPE_CATEGORIES, 0) * tpe_present;\n+\tp->nb_tx_cpy_writers =\n+\t\tfpga_get_product_param(p_fpga, NT_TX_CPY_WRITERS, 0) * tpe_present;\n+\tp->nb_tx_cpy_mask_mem =\n+\t\tfpga_get_product_param(p_fpga, NT_CPY_MASK_MEM, 0) * tpe_present;\n+\tp->nb_tx_rpl_depth =\n+\t\tfpga_get_product_param(p_fpga, NT_TX_RPL_DEPTH, 0) * tpe_present;\n+\tp->nb_tx_rpl_ext_categories =\n+\t\tfpga_get_product_param(p_fpga, NT_TX_RPL_EXT_CATEGORIES, 0) *\n+\t\ttpe_present;\n+\tp->nb_tpe_ifr_categories =\n+\t\tfpga_get_product_param(p_fpga, NT_TX_MTU_PROFILE_IFR, 0);\n+\treturn 0;\n+}\n+\n+unsigned int info_nthw_get_nb_phy_ports(const struct info_nthw *p)\n+{\n+\treturn p->n_phy_ports;\n+}\n+\n+unsigned int info_nthw_get_nb_rx_ports(const struct info_nthw *p)\n+{\n+\treturn p->n_rx_ports;\n+}\n+\n+unsigned int info_nthw_get_ltx_avail(const struct info_nthw *p)\n+{\n+\treturn p->n_ltx_avail;\n+}\n+\n+unsigned int info_nthw_get_nb_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_categories;\n+}\n+\n+unsigned int info_nthw_get_kcc_size(const struct info_nthw *p)\n+{\n+\treturn p->nb_kcc_size;\n+}\n+\n+unsigned int info_nthw_get_kcc_banks(const struct info_nthw *p)\n+{\n+\treturn p->nb_kcc_banks;\n+}\n+\n+unsigned int info_nthw_get_nb_queues(const struct info_nthw *p)\n+{\n+\treturn p->nb_queues;\n+}\n+\n+unsigned int info_nthw_get_nb_cat_funcs(const struct info_nthw *p)\n+{\n+\treturn p->nb_cat_func;\n+}\n+\n+unsigned int info_nthw_get_nb_km_flow_types(const struct info_nthw *p)\n+{\n+\treturn p->nb_flow_types;\n+}\n+\n+unsigned int info_nthw_get_nb_pm_ext(const struct info_nthw *p)\n+{\n+\treturn p->nb_pm_ext;\n+}\n+\n+unsigned int info_nthw_get_nb_len(const struct info_nthw *p)\n+{\n+\treturn p->nb_len;\n+}\n+\n+unsigned int info_nthw_get_nb_km_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_km_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_km_cam_banks(const struct info_nthw *p)\n+{\n+\treturn p->nb_km_cam_banks;\n+}\n+\n+unsigned int info_nthw_get_nb_km_cam_record_words(const struct info_nthw *p)\n+{\n+\treturn p->nb_km_cam_record_words;\n+}\n+\n+unsigned int info_nthw_get_nb_km_cam_records(const struct info_nthw *p)\n+{\n+\treturn p->nb_km_cam_records;\n+}\n+\n+unsigned int info_nthw_get_nb_km_tcam_banks(const struct info_nthw *p)\n+{\n+\treturn p->nb_km_tcam_banks;\n+}\n+\n+unsigned int info_nthw_get_nb_km_tcam_bank_width(const struct info_nthw *p)\n+{\n+\treturn p->nb_km_tcam_bank_width;\n+}\n+\n+unsigned int info_nthw_get_nb_flm_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_flm_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_flm_size_mb(const struct info_nthw *p)\n+{\n+\treturn p->nb_flm_size_mb;\n+}\n+\n+unsigned int info_nthw_get_nb_flm_entry_size(const struct info_nthw *p)\n+{\n+\treturn p->nb_flm_entry_size;\n+}\n+\n+unsigned int info_nthw_get_nb_flm_variant(const struct info_nthw *p)\n+{\n+\treturn p->nb_flm_variant;\n+}\n+\n+unsigned int info_nthw_get_nb_flm_prios(const struct info_nthw *p)\n+{\n+\treturn p->nb_flm_prios;\n+}\n+\n+unsigned int info_nthw_get_nb_flm_pst_profiles(const struct info_nthw *p)\n+{\n+\treturn p->nb_flm_pst_profiles;\n+}\n+\n+unsigned int info_nthw_get_nb_hst_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_hst_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_qsl_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_qsl_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_qsl_qst_entries(const struct info_nthw *p)\n+{\n+\treturn p->nb_qsl_qst_entries;\n+}\n+\n+unsigned int info_nthw_get_nb_pdb_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_pdb_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_ioa_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_ioa_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_roa_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_roa_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_dbs_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_dbs_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_cat_km_if_cnt(const struct info_nthw *p)\n+{\n+\treturn p->nb_cat_km_if_cnt;\n+}\n+\n+unsigned int info_nthw_get_nb_cat_km_if_m0(const struct info_nthw *p)\n+{\n+\treturn p->m_cat_km_if_m0;\n+}\n+\n+unsigned int info_nthw_get_nb_cat_km_if_m1(const struct info_nthw *p)\n+{\n+\treturn p->m_cat_km_if_m1;\n+}\n+\n+unsigned int info_nthw_get_nb_tpe_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_tpe_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_tx_cpy_writers(const struct info_nthw *p)\n+{\n+\treturn p->nb_tx_cpy_writers;\n+}\n+\n+unsigned int info_nthw_get_nb_tx_cpy_mask_mem(const struct info_nthw *p)\n+{\n+\treturn p->nb_tx_cpy_mask_mem;\n+}\n+\n+unsigned int info_nthw_get_nb_tx_rpl_depth(const struct info_nthw *p)\n+{\n+\treturn p->nb_tx_rpl_depth;\n+}\n+\n+unsigned int info_nthw_get_nb_tx_rpl_ext_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_tx_rpl_ext_categories;\n+}\n+\n+unsigned int info_nthw_get_nb_tpe_ifr_categories(const struct info_nthw *p)\n+{\n+\treturn p->nb_tpe_ifr_categories;\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_info.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_info.h\nnew file mode 100644\nindex 0000000000..c697ba84e9\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_info.h\n@@ -0,0 +1,104 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_INFO_H__\n+#define __FLOW_NTHW_INFO_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct info_nthw;\n+\n+struct info_nthw *info_nthw_new(void);\n+void info_nthw_delete(struct info_nthw *p);\n+int info_nthw_init(struct info_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int info_nthw_setup(struct info_nthw *p, int n_idx, int n_idx_cnt);\n+\n+unsigned int info_nthw_get_nb_phy_ports(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_rx_ports(const struct info_nthw *p);\n+unsigned int info_nthw_get_ltx_avail(const struct info_nthw *p);\n+\n+unsigned int info_nthw_get_nb_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_queues(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_cat_funcs(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_km_flow_types(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_pm_ext(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_len(const struct info_nthw *p);\n+unsigned int info_nthw_get_kcc_size(const struct info_nthw *p);\n+unsigned int info_nthw_get_kcc_banks(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_km_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_km_cam_banks(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_km_cam_record_words(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_km_cam_records(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_km_tcam_banks(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_km_tcam_bank_width(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_flm_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_flm_size_mb(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_flm_entry_size(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_flm_variant(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_flm_prios(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_flm_pst_profiles(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_hst_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_qsl_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_qsl_qst_entries(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_pdb_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_ioa_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_roa_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_dbs_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_cat_km_if_cnt(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_cat_km_if_m0(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_cat_km_if_m1(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_tpe_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_tx_cpy_writers(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_tx_cpy_mask_mem(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_tx_rpl_depth(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_tx_rpl_ext_categories(const struct info_nthw *p);\n+unsigned int info_nthw_get_nb_tpe_ifr_categories(const struct info_nthw *p);\n+\n+struct info_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\tunsigned int n_phy_ports;\n+\tunsigned int n_rx_ports;\n+\tunsigned int n_ltx_avail;\n+\tunsigned int nb_cat_func;\n+\tunsigned int nb_categories;\n+\tunsigned int nb_queues;\n+\tunsigned int nb_flow_types;\n+\tunsigned int nb_pm_ext;\n+\tunsigned int nb_len;\n+\tunsigned int nb_kcc_size;\n+\tunsigned int nb_kcc_banks;\n+\tunsigned int nb_km_categories;\n+\tunsigned int nb_km_cam_banks;\n+\tunsigned int nb_km_cam_record_words;\n+\tunsigned int nb_km_cam_records;\n+\tunsigned int nb_km_tcam_banks;\n+\tunsigned int nb_km_tcam_bank_width;\n+\tunsigned int nb_flm_categories;\n+\tunsigned int nb_flm_size_mb;\n+\tunsigned int nb_flm_entry_size;\n+\tunsigned int nb_flm_variant;\n+\tunsigned int nb_flm_prios;\n+\tunsigned int nb_flm_pst_profiles;\n+\tunsigned int nb_hst_categories;\n+\tunsigned int nb_qsl_categories;\n+\tunsigned int nb_qsl_qst_entries;\n+\tunsigned int nb_pdb_categories;\n+\tunsigned int nb_ioa_categories;\n+\tunsigned int nb_roa_categories;\n+\tunsigned int nb_dbs_categories;\n+\tunsigned int nb_cat_km_if_cnt;\n+\tunsigned int m_cat_km_if_m0;\n+\tunsigned int m_cat_km_if_m1;\n+\tunsigned int nb_tpe_categories;\n+\tunsigned int nb_tx_cpy_writers;\n+\tunsigned int nb_tx_cpy_mask_mem;\n+\tunsigned int nb_tx_rpl_depth;\n+\tunsigned int nb_tx_rpl_ext_categories;\n+\tunsigned int nb_tpe_ifr_categories;\n+};\n+\n+#endif /* __FLOW_NTHW_INFO_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ioa.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ioa.c\nnew file mode 100644\nindex 0000000000..a83d443f6f\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ioa.c\n@@ -0,0 +1,234 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_ioa.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void ioa_nthw_set_debug_mode(struct ioa_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_ioa, n_debug_mode);\n+}\n+\n+struct ioa_nthw *ioa_nthw_new(void)\n+{\n+\tstruct ioa_nthw *p = malloc(sizeof(struct ioa_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void ioa_nthw_delete(struct ioa_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int ioa_nthw_init(struct ioa_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_IOA, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Ioa %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_ioa = p_mod;\n+\n+\t/* RCP */\n+\tp->mp_rcp_ctrl = module_get_register(p->m_ioa, IOA_RECIPE_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, IOA_RECIPE_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, IOA_RECIPE_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_ioa, IOA_RECIPE_DATA);\n+\tp->mp_rcp_data_tunnel_pop =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_TUNNEL_POP);\n+\tp->mp_rcp_data_vlan_pop =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_VLAN_POP);\n+\tp->mp_rcp_data_vlan_push =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_VLAN_PUSH);\n+\tp->mp_rcp_data_vlan_vid =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_VLAN_VID);\n+\tp->mp_rcp_data_vlan_dei =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_VLAN_DEI);\n+\tp->mp_rcp_data_vlan_pcp =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_VLAN_PCP);\n+\tp->mp_rcp_data_vlan_tpid_sel =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_VLAN_TPID_SEL);\n+\tp->mp_rcp_data_queue_override_en =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_QUEUE_OVERRIDE_EN);\n+\tp->mp_rcp_data_queue_id =\n+\t\tregister_get_field(p->mp_rcp_data, IOA_RECIPE_DATA_QUEUE_ID);\n+\n+\t/* Special Vlan Tpid */\n+\tp->mp_special = module_get_register(p->m_ioa, IOA_VLAN_TPID_SPECIAL);\n+\tp->mp_special_vlan_tpid_cust_tpid0 =\n+\t\tregister_get_field(p->mp_special, IOA_VLAN_TPID_SPECIAL_CUSTTPID0);\n+\tp->mp_special_vlan_tpid_cust_tpid1 =\n+\t\tregister_get_field(p->mp_special, IOA_VLAN_TPID_SPECIAL_CUSTTPID1);\n+\t{\n+\t\t/*\n+\t\t * This extension in IOA is a messy way FPGA have chosen to\n+\t\t * put control bits for EPP module in IOA. It is accepted as\n+\t\t * we are going towards exchange IOA and ROA modules later\n+\t\t * to get higher scalability in future.\n+\t\t */\n+\t\tp->mp_roa_epp_ctrl =\n+\t\t\tmodule_query_register(p->m_ioa, IOA_ROA_EPP_CTRL);\n+\t\tif (p->mp_roa_epp_ctrl) {\n+\t\t\tp->mp_roa_epp_addr =\n+\t\t\t\tregister_get_field(p->mp_roa_epp_ctrl,\n+\t\t\t\t\t\t   IOA_ROA_EPP_CTRL_ADR);\n+\t\t\tp->mp_roa_epp_cnt =\n+\t\t\t\tregister_get_field(p->mp_roa_epp_ctrl,\n+\t\t\t\t\t\t   IOA_ROA_EPP_CTRL_CNT);\n+\t\t} else {\n+\t\t\tp->mp_roa_epp_addr = NULL;\n+\t\t\tp->mp_roa_epp_cnt = NULL;\n+\t\t}\n+\n+\t\tp->mp_roa_epp_data =\n+\t\t\tmodule_query_register(p->m_ioa, IOA_ROA_EPP_DATA);\n+\t\tif (p->mp_roa_epp_data) {\n+\t\t\tp->mp_roa_epp_data_push_tunnel =\n+\t\t\t\tregister_get_field(p->mp_roa_epp_data,\n+\t\t\t\t\t\t   IOA_ROA_EPP_DATA_PUSH_TUNNEL);\n+\t\t\tp->mp_roa_epp_data_tx_port =\n+\t\t\t\tregister_get_field(p->mp_roa_epp_data,\n+\t\t\t\t\t\t   IOA_ROA_EPP_DATA_TX_PORT);\n+\t\t} else {\n+\t\t\tp->mp_roa_epp_data_push_tunnel = NULL;\n+\t\t\tp->mp_roa_epp_data_tx_port = NULL;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+/* RCP */\n+void ioa_nthw_rcp_select(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void ioa_nthw_rcp_cnt(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void ioa_nthw_rcp_tunnel_pop(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tunnel_pop, val);\n+}\n+\n+void ioa_nthw_rcp_vlan_pop(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_vlan_pop, val);\n+}\n+\n+void ioa_nthw_rcp_vlan_push(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_vlan_push, val);\n+}\n+\n+void ioa_nthw_rcp_vlan_vid(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_vlan_vid, val);\n+}\n+\n+void ioa_nthw_rcp_vlan_dei(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_vlan_dei, val);\n+}\n+\n+void ioa_nthw_rcp_vlan_pcp(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_vlan_pcp, val);\n+}\n+\n+void ioa_nthw_rcp_vlan_tpid_sel(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_vlan_tpid_sel, val);\n+}\n+\n+void ioa_nthw_rcp_queue_override_en(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_queue_override_en, val);\n+}\n+\n+void ioa_nthw_rcp_queue_id(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_queue_id, val);\n+}\n+\n+void ioa_nthw_rcp_flush(const struct ioa_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\n+\n+/* Vlan Tpid Special */\n+void ioa_nthw_special_vlan_tpid_cust_tpid0(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_special_vlan_tpid_cust_tpid0, val);\n+}\n+\n+void ioa_nthw_special_vlan_tpid_cust_tpid1(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_special_vlan_tpid_cust_tpid1, val);\n+}\n+\n+void ioa_nthw_special_vlan_tpid_flush(const struct ioa_nthw *p)\n+{\n+\tregister_flush(p->mp_special, 1);\n+}\n+\n+void ioa_nthw_roa_epp_select(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_roa_epp_addr)\n+\t\tfield_set_val32(p->mp_roa_epp_addr, val);\n+}\n+\n+void ioa_nthw_roa_epp_cnt(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_roa_epp_cnt)\n+\t\tfield_set_val32(p->mp_roa_epp_cnt, val);\n+}\n+\n+void ioa_nthw_roa_epp_push_tunnel(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_roa_epp_data_push_tunnel)\n+\t\tfield_set_val32(p->mp_roa_epp_data_push_tunnel, val);\n+}\n+\n+void ioa_nthw_roa_epp_tx_port(const struct ioa_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_roa_epp_data_tx_port)\n+\t\tfield_set_val32(p->mp_roa_epp_data_tx_port, val);\n+}\n+\n+void ioa_nthw_roa_epp_flush(const struct ioa_nthw *p)\n+{\n+\tif (p->mp_roa_epp_ctrl)\n+\t\tregister_flush(p->mp_roa_epp_ctrl, 1);\n+\tif (p->mp_roa_epp_data)\n+\t\tregister_flush(p->mp_roa_epp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ioa.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ioa.h\nnew file mode 100644\nindex 0000000000..8ab30d2d28\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_ioa.h\n@@ -0,0 +1,80 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_IOA_H__\n+#define __FLOW_NTHW_IOA_H__\n+\n+#include \"nthw_fpga_model.h\"\n+\n+#include <stdint.h> /* uint32_t */\n+\n+struct ioa_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_ioa;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\n+\tnt_field_t *mp_rcp_data_tunnel_pop;\n+\tnt_field_t *mp_rcp_data_vlan_pop;\n+\tnt_field_t *mp_rcp_data_vlan_push;\n+\tnt_field_t *mp_rcp_data_vlan_vid;\n+\tnt_field_t *mp_rcp_data_vlan_dei;\n+\tnt_field_t *mp_rcp_data_vlan_pcp;\n+\tnt_field_t *mp_rcp_data_vlan_tpid_sel;\n+\tnt_field_t *mp_rcp_data_queue_override_en;\n+\tnt_field_t *mp_rcp_data_queue_id;\n+\n+\tnt_register_t *mp_special;\n+\tnt_field_t *mp_special_vlan_tpid_cust_tpid0;\n+\tnt_field_t *mp_special_vlan_tpid_cust_tpid1;\n+\n+\tnt_register_t *mp_roa_epp_ctrl;\n+\tnt_field_t *mp_roa_epp_addr;\n+\tnt_field_t *mp_roa_epp_cnt;\n+\tnt_register_t *mp_roa_epp_data;\n+\tnt_field_t *mp_roa_epp_data_push_tunnel;\n+\tnt_field_t *mp_roa_epp_data_tx_port;\n+};\n+\n+typedef struct ioa_nthw ioa_nthw_t;\n+\n+struct ioa_nthw *ioa_nthw_new(void);\n+void ioa_nthw_delete(struct ioa_nthw *p);\n+int ioa_nthw_init(struct ioa_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int ioa_nthw_setup(struct ioa_nthw *p, int n_idx, int n_idx_cnt);\n+void ioa_nthw_set_debug_mode(struct ioa_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void ioa_nthw_rcp_select(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_cnt(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_tunnel_pop(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_vlan_pop(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_vlan_push(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_vlan_vid(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_vlan_dei(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_vlan_pcp(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_vlan_tpid_sel(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_queue_override_en(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_queue_id(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_rcp_flush(const struct ioa_nthw *p);\n+\n+/* Vlan Tpid Special */\n+void ioa_nthw_special_vlan_tpid_cust_tpid0(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_special_vlan_tpid_cust_tpid1(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_special_vlan_tpid_flush(const struct ioa_nthw *p);\n+\n+/* EPP module */\n+void ioa_nthw_roa_epp_select(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_roa_epp_cnt(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_roa_epp_push_tunnel(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_roa_epp_tx_port(const struct ioa_nthw *p, uint32_t val);\n+void ioa_nthw_roa_epp_flush(const struct ioa_nthw *p);\n+\n+#endif /* __FLOW_NTHW_IOA_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_km.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_km.c\nnew file mode 100644\nindex 0000000000..6477debd46\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_km.c\n@@ -0,0 +1,686 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_km.h\"\n+\n+#include <stdint.h>\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+#define CHECK_AND_SET_VALUE(_a, _val)             \\\n+\tdo {                                    \\\n+\t\t__typeof__(_a) (a) = (_a); \\\n+\t\t__typeof__(_val) (val) = (_val); \\\n+\t\tif (a) {                        \\\n+\t\t\tfield_set_val32(a, val); \\\n+\t\t}                               \\\n+\t} while (0)\n+\n+void km_nthw_set_debug_mode(struct km_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_km, n_debug_mode);\n+}\n+\n+struct km_nthw *km_nthw_new(void)\n+{\n+\tstruct km_nthw *p = malloc(sizeof(struct km_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void km_nthw_delete(struct km_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int km_nthw_init(struct km_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_KM, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Km %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_km = p_mod;\n+\n+\t/* RCP */\n+\tp->mp_rcp_ctrl = module_get_register(p->m_km, KM_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, KM_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, KM_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_km, KM_RCP_DATA);\n+\tp->mp_rcp_data_qw0_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_QW0_DYN);\n+\tp->mp_rcp_data_qw0_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_QW0_OFS);\n+\tp->mp_rcp_data_qw0_sel_a =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_QW0_SEL_A);\n+\tp->mp_rcp_data_qw0_sel_b =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_QW0_SEL_B);\n+\tp->mp_rcp_data_qw4_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_QW4_DYN);\n+\tp->mp_rcp_data_qw4_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_QW4_OFS);\n+\tp->mp_rcp_data_qw4_sel_a =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_QW4_SEL_A);\n+\tp->mp_rcp_data_qw4_sel_b =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_QW4_SEL_B);\n+\n+\tp->mp_rcp_data_sw8_dyn =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW8_DYN);\n+\tp->mp_rcp_data_dw8_dyn =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW8_DYN);\n+\n+\tp->mp_rcp_data_swx_ovs_sb =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SWX_OVS_SB);\n+\tp->mp_rcp_data_swx_cch =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SWX_CCH);\n+\tp->mp_rcp_data_swx_sel_a =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_SWX_SEL_A);\n+\tp->mp_rcp_data_swx_sel_b =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_SWX_SEL_B);\n+\tp->mp_rcp_data_mask_a = register_get_field(p->mp_rcp_data, KM_RCP_DATA_MASK_A);\n+\tp->mp_rcp_data_mask_b = register_get_field(p->mp_rcp_data, KM_RCP_DATA_MASK_B);\n+\tp->mp_rcp_data_dual = register_get_field(p->mp_rcp_data, KM_RCP_DATA_DUAL);\n+\tp->mp_rcp_data_paired =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_PAIRED);\n+\tp->mp_rcp_data_el_a = register_get_field(p->mp_rcp_data, KM_RCP_DATA_EL_A);\n+\tp->mp_rcp_data_el_b = register_get_field(p->mp_rcp_data, KM_RCP_DATA_EL_B);\n+\tp->mp_rcp_data_info_a = register_get_field(p->mp_rcp_data, KM_RCP_DATA_INFO_A);\n+\tp->mp_rcp_data_info_b = register_get_field(p->mp_rcp_data, KM_RCP_DATA_INFO_B);\n+\tp->mp_rcp_data_ftm_a = register_get_field(p->mp_rcp_data, KM_RCP_DATA_FTM_A);\n+\tp->mp_rcp_data_ftm_b = register_get_field(p->mp_rcp_data, KM_RCP_DATA_FTM_B);\n+\tp->mp_rcp_data_bank_a = register_get_field(p->mp_rcp_data, KM_RCP_DATA_BANK_A);\n+\tp->mp_rcp_data_bank_b = register_get_field(p->mp_rcp_data, KM_RCP_DATA_BANK_B);\n+\tp->mp_rcp_data_kl_a = register_get_field(p->mp_rcp_data, KM_RCP_DATA_KL_A);\n+\tp->mp_rcp_data_kl_b = register_get_field(p->mp_rcp_data, KM_RCP_DATA_KL_B);\n+\tp->mp_rcp_data_flow_set =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_FLOW_SET);\n+\tp->mp_rcp_data_keyway_a =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_KEYWAY_A);\n+\tp->mp_rcp_data_keyway_b =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_KEYWAY_B);\n+\tp->mp_rcp_data_synergy_mode =\n+\t\tregister_get_field(p->mp_rcp_data, KM_RCP_DATA_SYNERGY_MODE);\n+\n+\t/* CAM */\n+\tp->mp_cam_ctrl = module_get_register(p->m_km, KM_CAM_CTRL);\n+\tp->mp_cam_addr = register_get_field(p->mp_cam_ctrl, KM_CAM_CTRL_ADR);\n+\tp->mp_cam_cnt = register_get_field(p->mp_cam_ctrl, KM_CAM_CTRL_CNT);\n+\tp->mp_cam_data = module_get_register(p->m_km, KM_CAM_DATA);\n+\tp->mp_cam_data_w0 = register_get_field(p->mp_cam_data, KM_CAM_DATA_W0);\n+\tp->mp_cam_data_w1 = register_get_field(p->mp_cam_data, KM_CAM_DATA_W1);\n+\tp->mp_cam_data_w2 = register_get_field(p->mp_cam_data, KM_CAM_DATA_W2);\n+\tp->mp_cam_data_w3 = register_get_field(p->mp_cam_data, KM_CAM_DATA_W3);\n+\tp->mp_cam_data_w4 = register_get_field(p->mp_cam_data, KM_CAM_DATA_W4);\n+\tp->mp_cam_data_w5 = register_get_field(p->mp_cam_data, KM_CAM_DATA_W5);\n+\tp->mp_cam_data_ft0 = register_get_field(p->mp_cam_data, KM_CAM_DATA_FT0);\n+\tp->mp_cam_data_ft1 = register_get_field(p->mp_cam_data, KM_CAM_DATA_FT1);\n+\tp->mp_cam_data_ft2 = register_get_field(p->mp_cam_data, KM_CAM_DATA_FT2);\n+\tp->mp_cam_data_ft3 = register_get_field(p->mp_cam_data, KM_CAM_DATA_FT3);\n+\tp->mp_cam_data_ft4 = register_get_field(p->mp_cam_data, KM_CAM_DATA_FT4);\n+\tp->mp_cam_data_ft5 = register_get_field(p->mp_cam_data, KM_CAM_DATA_FT5);\n+\t/* TCAM */\n+\tp->mp_tcam_ctrl = module_get_register(p->m_km, KM_TCAM_CTRL);\n+\tp->mp_tcam_addr = register_get_field(p->mp_tcam_ctrl, KM_TCAM_CTRL_ADR);\n+\tp->mp_tcam_cnt = register_get_field(p->mp_tcam_ctrl, KM_TCAM_CTRL_CNT);\n+\tp->mp_tcam_data = module_get_register(p->m_km, KM_TCAM_DATA);\n+\tp->mp_tcam_data_t = register_get_field(p->mp_tcam_data, KM_TCAM_DATA_T);\n+\t/* TCI */\n+\tp->mp_tci_ctrl = module_get_register(p->m_km, KM_TCI_CTRL);\n+\tp->mp_tci_addr = register_get_field(p->mp_tci_ctrl, KM_TCI_CTRL_ADR);\n+\tp->mp_tci_cnt = register_get_field(p->mp_tci_ctrl, KM_TCI_CTRL_CNT);\n+\tp->mp_tci_data = module_get_register(p->m_km, KM_TCI_DATA);\n+\tp->mp_tci_data_color = register_get_field(p->mp_tci_data, KM_TCI_DATA_COLOR);\n+\tp->mp_tci_data_ft = register_get_field(p->mp_tci_data, KM_TCI_DATA_FT);\n+\t/* TCQ */\n+\tp->mp_tcq_ctrl = module_get_register(p->m_km, KM_TCQ_CTRL);\n+\tp->mp_tcq_addr = register_get_field(p->mp_tcq_ctrl, KM_TCQ_CTRL_ADR);\n+\tp->mp_tcq_cnt = register_get_field(p->mp_tcq_ctrl, KM_TCQ_CTRL_CNT);\n+\tp->mp_tcq_data = module_get_register(p->m_km, KM_TCQ_DATA);\n+\tp->mp_tcq_data_bank_mask =\n+\t\tregister_query_field(p->mp_tcq_data, KM_TCQ_DATA_BANK_MASK);\n+\tp->mp_tcq_data_qual = register_get_field(p->mp_tcq_data, KM_TCQ_DATA_QUAL);\n+\n+\tp->mp_rcp_data_dw0_b_dyn =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW0_B_DYN);\n+\tp->mp_rcp_data_dw0_b_ofs =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW0_B_OFS);\n+\tp->mp_rcp_data_dw2_b_dyn =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW2_B_DYN);\n+\tp->mp_rcp_data_dw2_b_ofs =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW2_B_OFS);\n+\tp->mp_rcp_data_sw4_b_dyn =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW4_B_DYN);\n+\tp->mp_rcp_data_sw4_b_ofs =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW4_B_OFS);\n+\tp->mp_rcp_data_sw5_b_dyn =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW5_B_DYN);\n+\tp->mp_rcp_data_sw5_b_ofs =\n+\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW5_B_OFS);\n+\tif (!p->mp_rcp_data_dw0_b_dyn) {\n+\t\t/* old field defines */\n+\t\tp->mp_rcp_data_dw0_b_dyn =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_QW0_B_DYN);\n+\t\tp->mp_rcp_data_dw0_b_ofs =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_QW0_B_OFS);\n+\t\tp->mp_rcp_data_dw2_b_dyn =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_QW4_B_DYN);\n+\t\tp->mp_rcp_data_dw2_b_ofs =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_QW4_B_OFS);\n+\t\tp->mp_rcp_data_sw4_b_dyn =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW8_B_DYN);\n+\t\tp->mp_rcp_data_sw4_b_ofs =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW8_B_OFS);\n+\t\tp->mp_rcp_data_sw5_b_dyn =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW9_B_DYN);\n+\t\tp->mp_rcp_data_sw5_b_ofs =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW9_B_OFS);\n+\t}\n+\n+\t/* v0.6+ */\n+\tif (p->mp_rcp_data_dw8_dyn) {\n+\t\tp->mp_rcp_data_dw8_ofs =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW8_OFS);\n+\t\tp->mp_rcp_data_dw8_sel_a =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW8_SEL_A);\n+\t\tp->mp_rcp_data_dw8_sel_b =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW8_SEL_B);\n+\t\tp->mp_rcp_data_dw10_dyn =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW10_DYN);\n+\t\tp->mp_rcp_data_dw10_ofs =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW10_OFS);\n+\t\tp->mp_rcp_data_dw10_sel_a =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW10_SEL_A);\n+\t\tp->mp_rcp_data_dw10_sel_b =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_DW10_SEL_B);\n+\t} else if (p->mp_rcp_data_sw8_dyn) {\n+\t\tp->mp_rcp_data_sw8_ofs =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW8_OFS);\n+\t\tp->mp_rcp_data_sw8_sel_a =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW8_SEL_A);\n+\t\tp->mp_rcp_data_sw8_sel_b =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW8_SEL_B);\n+\t\tp->mp_rcp_data_sw9_dyn =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW9_DYN);\n+\t\tp->mp_rcp_data_sw9_ofs =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW9_OFS);\n+\t\tp->mp_rcp_data_sw9_sel_a =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW9_SEL_A);\n+\t\tp->mp_rcp_data_sw9_sel_b =\n+\t\t\tregister_query_field(p->mp_rcp_data, KM_RCP_DATA_SW9_SEL_B);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* RCP */\n+void km_nthw_rcp_select(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+};\n+\n+void km_nthw_rcp_cnt(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+};\n+\n+void km_nthw_rcp_qw0_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_dyn, val);\n+};\n+\n+void km_nthw_rcp_qw0_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_ofs, val);\n+};\n+\n+void km_nthw_rcp_qw0_sel_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_sel_a, val);\n+};\n+\n+void km_nthw_rcp_qw0_sel_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw0_sel_b, val);\n+};\n+\n+void km_nthw_rcp_qw4_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw4_dyn, val);\n+};\n+\n+void km_nthw_rcp_qw4_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw4_ofs, val);\n+};\n+\n+void km_nthw_rcp_qw4_sel_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw4_sel_a, val);\n+};\n+\n+void km_nthw_rcp_qw4_sel_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_qw4_sel_b, val);\n+};\n+\n+void km_nthw_rcp_dw8_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_dw8_dyn, val);\n+};\n+\n+void km_nthw_rcp_sw8_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_sw8_dyn, val);\n+};\n+\n+void km_nthw_rcp_sw8_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_sw8_ofs, val);\n+};\n+\n+void km_nthw_rcp_sw8_sel_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_sw8_sel_a, val);\n+};\n+\n+void km_nthw_rcp_sw8_sel_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_sw8_sel_b, val);\n+};\n+\n+void km_nthw_rcp_sw9_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_sw9_dyn, val);\n+};\n+\n+void km_nthw_rcp_sw9_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_sw9_ofs, val);\n+};\n+\n+void km_nthw_rcp_sw9_sel_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_sw9_sel_a, val);\n+};\n+\n+void km_nthw_rcp_sw9_sel_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_sw9_sel_b, val);\n+};\n+\n+void km_nthw_rcp_swx_ovs_sb(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_swx_ovs_sb, val);\n+};\n+\n+void km_nthw_rcp_swx_cch(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_swx_cch, val);\n+};\n+\n+void km_nthw_rcp_dw8_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_dw8_ofs, val);\n+};\n+\n+void km_nthw_rcp_dw8_sel_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_dw8_sel_a, val);\n+};\n+\n+void km_nthw_rcp_dw8_sel_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_dw8_sel_b, val);\n+};\n+\n+void km_nthw_rcp_dw10_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_dw10_dyn, val);\n+};\n+\n+void km_nthw_rcp_dw10_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_dw10_ofs, val);\n+};\n+\n+void km_nthw_rcp_dw10_sel_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_dw10_sel_a, val);\n+};\n+\n+void km_nthw_rcp_dw10_sel_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_dw10_sel_b, val);\n+};\n+\n+void km_nthw_rcp_swx_sel_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_swx_sel_a, val);\n+};\n+\n+void km_nthw_rcp_swx_sel_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_swx_sel_b, val);\n+};\n+\n+void km_nthw_rcp_mask_a(const struct km_nthw *p, const uint32_t *val)\n+{\n+\tfield_set_val(p->mp_rcp_data_mask_a, val, p->mp_rcp_data_mask_a->mn_words);\n+};\n+\n+void km_nthw_rcp_mask_b(const struct km_nthw *p, const uint32_t *val)\n+{\n+\tfield_set_val(p->mp_rcp_data_mask_b, val, p->mp_rcp_data_mask_b->mn_words);\n+};\n+\n+void km_nthw_rcp_mask_d_a(const struct km_nthw *p, const uint32_t *val)\n+{\n+\tfield_set_val(p->mp_rcp_data_mask_a, val, p->mp_rcp_data_mask_a->mn_words);\n+}; /* for DW8/DW10 from v6+ */\n+\n+void km_nthw_rcp_dual(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_dual, val);\n+};\n+\n+void km_nthw_rcp_paired(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_paired, val);\n+};\n+\n+void km_nthw_rcp_el_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_el_a, val);\n+};\n+\n+void km_nthw_rcp_el_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_el_b, val);\n+};\n+\n+void km_nthw_rcp_info_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_info_a, val);\n+};\n+\n+void km_nthw_rcp_info_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_info_b, val);\n+};\n+\n+void km_nthw_rcp_ftm_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ftm_a, val);\n+};\n+\n+void km_nthw_rcp_ftm_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ftm_b, val);\n+};\n+\n+void km_nthw_rcp_bank_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_bank_a, val);\n+};\n+\n+void km_nthw_rcp_bank_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_bank_b, val);\n+};\n+\n+void km_nthw_rcp_kl_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_kl_a, val);\n+};\n+\n+void km_nthw_rcp_kl_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_kl_b, val);\n+};\n+\n+void km_nthw_rcp_flow_set(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_flow_set, val);\n+};\n+\n+void km_nthw_rcp_keyway_a(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_keyway_a, val);\n+};\n+\n+void km_nthw_rcp_keyway_b(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_rcp_data_keyway_b, val);\n+};\n+\n+void km_nthw_rcp_synergy_mode(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_synergy_mode, val);\n+};\n+\n+void km_nthw_rcp_dw0_b_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_dw0_b_dyn, val);\n+};\n+\n+void km_nthw_rcp_dw0_b_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_dw0_b_ofs, val);\n+};\n+\n+void km_nthw_rcp_dw2_b_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_dw2_b_dyn, val);\n+};\n+\n+void km_nthw_rcp_dw2_b_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_dw2_b_ofs, val);\n+};\n+\n+void km_nthw_rcp_sw4_b_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw4_b_dyn, val);\n+};\n+\n+void km_nthw_rcp_sw4_b_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw4_b_ofs, val);\n+};\n+\n+void km_nthw_rcp_sw5_b_dyn(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw5_b_dyn, val);\n+};\n+\n+void km_nthw_rcp_sw5_b_ofs(const struct km_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_sw5_b_ofs, val);\n+};\n+\n+void km_nthw_rcp_flush(const struct km_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+};\n+\n+/* CAM */\n+void km_nthw_cam_select(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_addr, val);\n+};\n+\n+void km_nthw_cam_cnt(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_cnt, val);\n+};\n+\n+void km_nthw_cam_w0(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_w0, val);\n+};\n+\n+void km_nthw_cam_w1(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_w1, val);\n+};\n+\n+void km_nthw_cam_w2(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_w2, val);\n+};\n+\n+void km_nthw_cam_w3(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_w3, val);\n+};\n+\n+void km_nthw_cam_w4(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_w4, val);\n+};\n+\n+void km_nthw_cam_w5(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_w5, val);\n+};\n+\n+void km_nthw_cam_ft0(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_ft0, val);\n+};\n+\n+void km_nthw_cam_ft1(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_ft1, val);\n+};\n+\n+void km_nthw_cam_ft2(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_ft2, val);\n+};\n+\n+void km_nthw_cam_ft3(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_ft3, val);\n+};\n+\n+void km_nthw_cam_ft4(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_ft4, val);\n+};\n+\n+void km_nthw_cam_ft5(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_cam_data_ft5, val);\n+};\n+\n+void km_nthw_cam_flush(const struct km_nthw *p)\n+{\n+\tregister_flush(p->mp_cam_ctrl, 1);\n+\tregister_flush(p->mp_cam_data, 1);\n+};\n+\n+/* TCAM */\n+void km_nthw_tcam_select(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tcam_addr, val);\n+};\n+\n+void km_nthw_tcam_cnt(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tcam_cnt, val);\n+};\n+\n+void km_nthw_tcam_t(const struct km_nthw *p, uint32_t *val)\n+{\n+\tfield_set_val(p->mp_tcam_data_t, val, 3);\n+};\n+\n+void km_nthw_tcam_flush(const struct km_nthw *p)\n+{\n+\tregister_flush(p->mp_tcam_ctrl, 1);\n+\tregister_flush(p->mp_tcam_data, 1);\n+};\n+\n+/* TCI */\n+void km_nthw_tci_select(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tci_addr, val);\n+};\n+\n+void km_nthw_tci_cnt(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tci_cnt, val);\n+};\n+\n+void km_nthw_tci_color(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tci_data_color, val);\n+};\n+\n+void km_nthw_tci_ft(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tci_data_ft, val);\n+};\n+\n+void km_nthw_tci_flush(const struct km_nthw *p)\n+{\n+\tregister_flush(p->mp_tci_ctrl, 1);\n+\tregister_flush(p->mp_tci_data, 1);\n+};\n+\n+/* TCQ */\n+void km_nthw_tcq_select(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tcq_addr, val);\n+};\n+\n+void km_nthw_tcq_cnt(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tcq_cnt, val);\n+};\n+\n+void km_nthw_tcq_bank_mask(const struct km_nthw *p, uint32_t val)\n+{\n+\tCHECK_AND_SET_VALUE(p->mp_tcq_data_bank_mask, val);\n+};\n+\n+void km_nthw_tcq_qual(const struct km_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tcq_data_qual, val);\n+};\n+\n+void km_nthw_tcq_qual72(const struct km_nthw *p, uint32_t *val)\n+{\n+\tfield_set_val(p->mp_tcq_data_qual, val, 3);\n+}; /* to use in v4 */\n+\n+void km_nthw_tcq_flush(const struct km_nthw *p)\n+{\n+\tregister_flush(p->mp_tcq_ctrl, 1);\n+\tregister_flush(p->mp_tcq_data, 1);\n+};\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_km.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_km.h\nnew file mode 100644\nindex 0000000000..61f9ed2ae4\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_km.h\n@@ -0,0 +1,224 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_KM_H__\n+#define __FLOW_NTHW_KM_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct km_nthw;\n+\n+typedef struct km_nthw km_nthw_t;\n+\n+struct km_nthw *km_nthw_new(void);\n+void km_nthw_delete(struct km_nthw *p);\n+int km_nthw_init(struct km_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int km_nthw_setup(struct km_nthw *p, int n_idx, int n_idx_cnt);\n+void km_nthw_set_debug_mode(struct km_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP initial v3 */\n+void km_nthw_rcp_select(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_cnt(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_qw0_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_qw0_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_qw0_sel_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_qw0_sel_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_qw4_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_qw4_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_qw4_sel_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_qw4_sel_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_sw8_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_sw8_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_sw8_sel_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_sw8_sel_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_sw9_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_sw9_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_sw9_sel_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_sw9_sel_b(const struct km_nthw *p, uint32_t val);\n+/* subst in v6 */\n+void km_nthw_rcp_dw8_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_dw8_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_dw8_sel_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_dw8_sel_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_dw10_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_dw10_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_dw10_sel_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_dw10_sel_b(const struct km_nthw *p, uint32_t val);\n+\n+void km_nthw_rcp_swx_ovs_sb(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_swx_cch(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_swx_sel_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_swx_sel_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_mask_a(const struct km_nthw *p, const uint32_t *val);\n+void km_nthw_rcp_mask_d_a(const struct km_nthw *p, const uint32_t *val);\n+void km_nthw_rcp_mask_b(const struct km_nthw *p, const uint32_t *val);\n+void km_nthw_rcp_dual(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_paired(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_el_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_el_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_info_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_info_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_ftm_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_ftm_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_bank_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_bank_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_kl_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_kl_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_flow_set(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_keyway_a(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_keyway_b(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_synergy_mode(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_dw0_b_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_dw0_b_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_dw2_b_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_dw2_b_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_sw4_b_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_sw4_b_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_sw5_b_dyn(const struct km_nthw *p, uint32_t val);\n+void km_nthw_rcp_sw5_b_ofs(const struct km_nthw *p, int32_t val);\n+void km_nthw_rcp_flush(const struct km_nthw *p);\n+/* CAM */\n+void km_nthw_cam_select(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_cnt(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_w0(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_w1(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_w2(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_w3(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_w4(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_w5(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_ft0(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_ft1(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_ft2(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_ft3(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_ft4(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_ft5(const struct km_nthw *p, uint32_t val);\n+void km_nthw_cam_flush(const struct km_nthw *p);\n+/* TCAM */\n+void km_nthw_tcam_select(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tcam_cnt(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tcam_t(const struct km_nthw *p, uint32_t *val);\n+void km_nthw_tcam_flush(const struct km_nthw *p);\n+/* TCI */\n+void km_nthw_tci_select(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tci_cnt(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tci_color(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tci_ft(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tci_flush(const struct km_nthw *p);\n+/* TCQ */\n+void km_nthw_tcq_select(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tcq_cnt(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tcq_bank_mask(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tcq_qual(const struct km_nthw *p, uint32_t val);\n+void km_nthw_tcq_qual72(const struct km_nthw *p, uint32_t *val);\n+\n+void km_nthw_tcq_flush(const struct km_nthw *p);\n+\n+struct km_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_km;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_qw0_dyn;\n+\tnt_field_t *mp_rcp_data_qw0_ofs;\n+\tnt_field_t *mp_rcp_data_qw0_sel_a;\n+\tnt_field_t *mp_rcp_data_qw0_sel_b;\n+\tnt_field_t *mp_rcp_data_qw4_dyn;\n+\tnt_field_t *mp_rcp_data_qw4_ofs;\n+\tnt_field_t *mp_rcp_data_qw4_sel_a;\n+\tnt_field_t *mp_rcp_data_qw4_sel_b;\n+\tnt_field_t *mp_rcp_data_sw8_dyn;\n+\tnt_field_t *mp_rcp_data_sw8_ofs;\n+\tnt_field_t *mp_rcp_data_sw8_sel_a;\n+\tnt_field_t *mp_rcp_data_sw8_sel_b;\n+\tnt_field_t *mp_rcp_data_sw9_dyn;\n+\tnt_field_t *mp_rcp_data_sw9_ofs;\n+\tnt_field_t *mp_rcp_data_sw9_sel_a;\n+\tnt_field_t *mp_rcp_data_sw9_sel_b;\n+\n+\tnt_field_t *mp_rcp_data_dw8_dyn; /* substituted Sw<x> from v6+ */\n+\tnt_field_t *mp_rcp_data_dw8_ofs; /* substituted Sw<x> from v6+ */\n+\tnt_field_t *mp_rcp_data_dw8_sel_a; /* substituted Sw<x> from v6+ */\n+\tnt_field_t *mp_rcp_data_dw8_sel_b; /* substituted Sw<x> from v6+ */\n+\tnt_field_t *mp_rcp_data_dw10_dyn; /* substituted Sw<x> from v6+ */\n+\tnt_field_t *mp_rcp_data_dw10_ofs; /* substituted Sw<x> from v6+ */\n+\tnt_field_t *mp_rcp_data_dw10_sel_a; /* substituted Sw<x> from v6+ */\n+\tnt_field_t *mp_rcp_data_dw10_sel_b; /* substituted Sw<x> from v6+ */\n+\n+\tnt_field_t *mp_rcp_data_swx_ovs_sb;\n+\tnt_field_t *mp_rcp_data_swx_cch;\n+\tnt_field_t *mp_rcp_data_swx_sel_a;\n+\tnt_field_t *mp_rcp_data_swx_sel_b;\n+\tnt_field_t *mp_rcp_data_mask_a;\n+\tnt_field_t *mp_rcp_data_mask_b;\n+\tnt_field_t *mp_rcp_data_dual;\n+\tnt_field_t *mp_rcp_data_paired;\n+\tnt_field_t *mp_rcp_data_el_a;\n+\tnt_field_t *mp_rcp_data_el_b;\n+\tnt_field_t *mp_rcp_data_info_a;\n+\tnt_field_t *mp_rcp_data_info_b;\n+\tnt_field_t *mp_rcp_data_ftm_a;\n+\tnt_field_t *mp_rcp_data_ftm_b;\n+\tnt_field_t *mp_rcp_data_bank_a;\n+\tnt_field_t *mp_rcp_data_bank_b;\n+\tnt_field_t *mp_rcp_data_kl_a;\n+\tnt_field_t *mp_rcp_data_kl_b;\n+\tnt_field_t *mp_rcp_data_flow_set;\n+\tnt_field_t *mp_rcp_data_keyway_a;\n+\tnt_field_t *mp_rcp_data_keyway_b;\n+\tnt_field_t *mp_rcp_data_synergy_mode;\n+\tnt_field_t *mp_rcp_data_dw0_b_dyn;\n+\tnt_field_t *mp_rcp_data_dw0_b_ofs;\n+\tnt_field_t *mp_rcp_data_dw2_b_dyn;\n+\tnt_field_t *mp_rcp_data_dw2_b_ofs;\n+\tnt_field_t *mp_rcp_data_sw4_b_dyn;\n+\tnt_field_t *mp_rcp_data_sw4_b_ofs;\n+\tnt_field_t *mp_rcp_data_sw5_b_dyn;\n+\tnt_field_t *mp_rcp_data_sw5_b_ofs;\n+\n+\tnt_register_t *mp_cam_ctrl;\n+\tnt_field_t *mp_cam_addr;\n+\tnt_field_t *mp_cam_cnt;\n+\tnt_register_t *mp_cam_data;\n+\tnt_field_t *mp_cam_data_w0;\n+\tnt_field_t *mp_cam_data_w1;\n+\tnt_field_t *mp_cam_data_w2;\n+\tnt_field_t *mp_cam_data_w3;\n+\tnt_field_t *mp_cam_data_w4;\n+\tnt_field_t *mp_cam_data_w5;\n+\tnt_field_t *mp_cam_data_ft0;\n+\tnt_field_t *mp_cam_data_ft1;\n+\tnt_field_t *mp_cam_data_ft2;\n+\tnt_field_t *mp_cam_data_ft3;\n+\tnt_field_t *mp_cam_data_ft4;\n+\tnt_field_t *mp_cam_data_ft5;\n+\n+\tnt_register_t *mp_tcam_ctrl;\n+\tnt_field_t *mp_tcam_addr;\n+\tnt_field_t *mp_tcam_cnt;\n+\tnt_register_t *mp_tcam_data;\n+\tnt_field_t *mp_tcam_data_t;\n+\n+\tnt_register_t *mp_tci_ctrl;\n+\tnt_field_t *mp_tci_addr;\n+\tnt_field_t *mp_tci_cnt;\n+\tnt_register_t *mp_tci_data;\n+\tnt_field_t *mp_tci_data_color;\n+\tnt_field_t *mp_tci_data_ft;\n+\n+\tnt_register_t *mp_tcq_ctrl;\n+\tnt_field_t *mp_tcq_addr;\n+\tnt_field_t *mp_tcq_cnt;\n+\tnt_register_t *mp_tcq_data;\n+\tnt_field_t *mp_tcq_data_bank_mask;\n+\tnt_field_t *mp_tcq_data_qual;\n+};\n+\n+#endif /* __FLOW_NTHW_KM_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_pdb.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_pdb.c\nnew file mode 100644\nindex 0000000000..e823a527bb\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_pdb.c\n@@ -0,0 +1,230 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_pdb.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void pdb_nthw_set_debug_mode(struct pdb_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_pdb, n_debug_mode);\n+}\n+\n+struct pdb_nthw *pdb_nthw_new(void)\n+{\n+\tstruct pdb_nthw *p = malloc(sizeof(struct pdb_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void pdb_nthw_delete(struct pdb_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int pdb_nthw_init(struct pdb_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_PDB, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Pdb %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_pdb = p_mod;\n+\n+\t/* RCP */\n+\tp->mp_rcp_ctrl = module_get_register(p->m_pdb, PDB_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, PDB_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, PDB_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_pdb, PDB_RCP_DATA);\n+\tp->mp_rcp_data_descriptor =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_DESCRIPTOR);\n+\tp->mp_rcp_data_desc_len =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_DESC_LEN);\n+\tp->mp_rcp_data_tx_port =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_TX_PORT);\n+\tp->mp_rcp_data_tx_ignore =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_TX_IGNORE);\n+\tp->mp_rcp_data_tx_now =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_TX_NOW);\n+\tp->mp_rcp_data_crc_overwrite =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_CRC_OVERWRITE);\n+\tp->mp_rcp_data_align = register_get_field(p->mp_rcp_data, PDB_RCP_DATA_ALIGN);\n+\tp->mp_rcp_data_ofs0_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_OFS0_DYN);\n+\tp->mp_rcp_data_ofs0_rel =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_OFS0_REL);\n+\tp->mp_rcp_data_ofs1_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_OFS1_DYN);\n+\tp->mp_rcp_data_ofs1_rel =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_OFS1_REL);\n+\tp->mp_rcp_data_ofs2_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_OFS2_DYN);\n+\tp->mp_rcp_data_ofs2_rel =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_OFS2_REL);\n+\tp->mp_rcp_data_ip_prot_tnl =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_IP_PROT_TNL);\n+\tp->mp_rcp_data_ppc_hsh =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_PPC_HSH);\n+\tp->mp_rcp_data_duplicate_en =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_DUPLICATE_EN);\n+\tp->mp_rcp_data_duplicate_bit =\n+\t\tregister_get_field(p->mp_rcp_data, PDB_RCP_DATA_DUPLICATE_BIT);\n+\tp->mp_rcp_data_pcap_keep_fcs =\n+\t\tregister_query_field(p->mp_rcp_data, PDB_RCP_DATA_PCAP_KEEP_FCS);\n+\t/* CONFIG */\n+\tp->mp_config = module_get_register(p->m_pdb, PDB_CONFIG);\n+\tp->mp_config_ts_format =\n+\t\tregister_get_field(p->mp_config, PDB_CONFIG_TS_FORMAT);\n+\tp->mp_config_port_ofs =\n+\t\tregister_get_field(p->mp_config, PDB_CONFIG_PORT_OFS);\n+\n+\treturn 0;\n+}\n+\n+/* RCP */\n+void pdb_nthw_rcp_select(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void pdb_nthw_rcp_cnt(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void pdb_nthw_rcp_descriptor(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_descriptor, val);\n+}\n+\n+void pdb_nthw_rcp_desc_len(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_desc_len, val);\n+}\n+\n+void pdb_nthw_rcp_tx_port(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tx_port, val);\n+}\n+\n+void pdb_nthw_rcp_tx_ignore(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tx_ignore, val);\n+}\n+\n+void pdb_nthw_rcp_tx_now(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tx_now, val);\n+}\n+\n+void pdb_nthw_rcp_crc_overwrite(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_crc_overwrite, val);\n+}\n+\n+void pdb_nthw_rcp_align(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_align, val);\n+}\n+\n+void pdb_nthw_rcp_ofs0_dyn(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ofs0_dyn, val);\n+}\n+\n+void pdb_nthw_rcp_ofs0_rel(const struct pdb_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ofs0_rel, val);\n+}\n+\n+void pdb_nthw_rcp_ofs1_dyn(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ofs1_dyn, val);\n+}\n+\n+void pdb_nthw_rcp_ofs1_rel(const struct pdb_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ofs1_rel, val);\n+}\n+\n+void pdb_nthw_rcp_ofs2_dyn(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ofs2_dyn, val);\n+}\n+\n+void pdb_nthw_rcp_ofs2_rel(const struct pdb_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ofs2_rel, val);\n+}\n+\n+void pdb_nthw_rcp_ip_prot_tnl(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ip_prot_tnl, val);\n+}\n+\n+void pdb_nthw_rcp_ppc_hsh(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ppc_hsh, val);\n+}\n+\n+void pdb_nthw_rcp_duplicate_en(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_duplicate_en, val);\n+}\n+\n+void pdb_nthw_rcp_duplicate_bit(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_duplicate_bit, val);\n+}\n+\n+void pdb_nthw_rcp_data_pcap_keep_fcs(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_rcp_data_pcap_keep_fcs)\n+\t\tfield_set_val32(p->mp_rcp_data_pcap_keep_fcs, val);\n+}\n+\n+void pdb_nthw_rcp_flush(const struct pdb_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\n+\n+/* CONFIG */\n+void pdb_nthw_config_ts_format(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_config_ts_format, val);\n+}\n+\n+void pdb_nthw_config_port_ofs(const struct pdb_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_config_port_ofs, val);\n+}\n+\n+void pdb_nthw_config_flush(const struct pdb_nthw *p)\n+{\n+\tregister_flush(p->mp_config, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_pdb.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_pdb.h\nnew file mode 100644\nindex 0000000000..aed050eca5\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_pdb.h\n@@ -0,0 +1,84 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_PDB_H__\n+#define __FLOW_NTHW_PDB_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct pdb_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_pdb;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_descriptor;\n+\tnt_field_t *mp_rcp_data_desc_len;\n+\tnt_field_t *mp_rcp_data_tx_port;\n+\tnt_field_t *mp_rcp_data_tx_ignore;\n+\tnt_field_t *mp_rcp_data_tx_now;\n+\tnt_field_t *mp_rcp_data_crc_overwrite;\n+\tnt_field_t *mp_rcp_data_align;\n+\tnt_field_t *mp_rcp_data_ofs0_dyn;\n+\tnt_field_t *mp_rcp_data_ofs0_rel;\n+\tnt_field_t *mp_rcp_data_ofs1_dyn;\n+\tnt_field_t *mp_rcp_data_ofs1_rel;\n+\tnt_field_t *mp_rcp_data_ofs2_dyn;\n+\tnt_field_t *mp_rcp_data_ofs2_rel;\n+\tnt_field_t *mp_rcp_data_ip_prot_tnl;\n+\tnt_field_t *mp_rcp_data_ppc_hsh;\n+\tnt_field_t *mp_rcp_data_duplicate_en;\n+\tnt_field_t *mp_rcp_data_duplicate_bit;\n+\tnt_field_t *mp_rcp_data_pcap_keep_fcs;\n+\n+\tnt_register_t *mp_config;\n+\tnt_field_t *mp_config_ts_format;\n+\tnt_field_t *mp_config_port_ofs;\n+};\n+\n+typedef struct pdb_nthw pdb_nthw_t;\n+\n+struct pdb_nthw *pdb_nthw_new(void);\n+void pdb_nthw_delete(struct pdb_nthw *p);\n+int pdb_nthw_init(struct pdb_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int pdb_nthw_setup(struct pdb_nthw *p, int n_idx, int n_idx_cnt);\n+void pdb_nthw_set_debug_mode(struct pdb_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void pdb_nthw_rcp_select(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_cnt(const struct pdb_nthw *p, uint32_t val);\n+\n+void pdb_nthw_rcp_descriptor(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_desc_len(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_tx_port(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_tx_ignore(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_tx_now(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_crc_overwrite(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_align(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_ofs0_dyn(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_ofs0_rel(const struct pdb_nthw *p, int32_t val);\n+void pdb_nthw_rcp_ofs1_dyn(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_ofs1_rel(const struct pdb_nthw *p, int32_t val);\n+void pdb_nthw_rcp_ofs2_dyn(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_ofs2_rel(const struct pdb_nthw *p, int32_t val);\n+void pdb_nthw_rcp_ip_prot_tnl(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_ppc_hsh(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_duplicate_en(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_duplicate_bit(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_data_pcap_keep_fcs(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_rcp_flush(const struct pdb_nthw *p);\n+\n+/* CONFIG */\n+void pdb_nthw_config_ts_format(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_config_port_ofs(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_config_port_ofs(const struct pdb_nthw *p, uint32_t val);\n+void pdb_nthw_config_flush(const struct pdb_nthw *p);\n+\n+#endif /* __FLOW_NTHW_PDB_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_qsl.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_qsl.c\nnew file mode 100644\nindex 0000000000..6c13824df6\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_qsl.c\n@@ -0,0 +1,355 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_qsl.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void qsl_nthw_set_debug_mode(struct qsl_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_qsl, n_debug_mode);\n+}\n+\n+struct qsl_nthw *qsl_nthw_new(void)\n+{\n+\tstruct qsl_nthw *p = malloc(sizeof(struct qsl_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void qsl_nthw_delete(struct qsl_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int qsl_nthw_init(struct qsl_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_QSL, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: QSL %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_qsl = p_mod;\n+\n+\t/* RCP */\n+\tp->mp_rcp_ctrl = module_get_register(p->m_qsl, QSL_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, QSL_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, QSL_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_qsl, QSL_RCP_DATA);\n+\tp->mp_rcp_data_discard =\n+\t\tregister_get_field(p->mp_rcp_data, QSL_RCP_DATA_DISCARD);\n+\tp->mp_rcp_data_drop = register_get_field(p->mp_rcp_data, QSL_RCP_DATA_DROP);\n+\tp->mp_rcp_data_tbl_lo =\n+\t\tregister_get_field(p->mp_rcp_data, QSL_RCP_DATA_TBL_LO);\n+\tp->mp_rcp_data_tbl_hi =\n+\t\tregister_get_field(p->mp_rcp_data, QSL_RCP_DATA_TBL_HI);\n+\tp->mp_rcp_data_tbl_idx =\n+\t\tregister_get_field(p->mp_rcp_data, QSL_RCP_DATA_TBL_IDX);\n+\tp->mp_rcp_data_tbl_msk =\n+\t\tregister_get_field(p->mp_rcp_data, QSL_RCP_DATA_TBL_MSK);\n+\tp->mp_rcp_data_cao = register_query_field(p->mp_rcp_data, QSL_RCP_DATA_CAO);\n+\tp->mp_rcp_data_lr = register_query_field(p->mp_rcp_data, QSL_RCP_DATA_LR);\n+\tp->mp_rcp_data_tsa = register_query_field(p->mp_rcp_data, QSL_RCP_DATA_TSA);\n+\tp->mp_rcp_data_vli = register_query_field(p->mp_rcp_data, QSL_RCP_DATA_VLI);\n+\n+\t/* QST */\n+\tp->mp_qst_ctrl = module_get_register(p->m_qsl, QSL_QST_CTRL);\n+\tp->mp_qst_addr = register_get_field(p->mp_qst_ctrl, QSL_QST_CTRL_ADR);\n+\tp->mp_qst_cnt = register_get_field(p->mp_qst_ctrl, QSL_QST_CTRL_CNT);\n+\tp->mp_qst_data = module_get_register(p->m_qsl, QSL_QST_DATA);\n+\tp->mp_qst_data_queue = register_get_field(p->mp_qst_data, QSL_QST_DATA_QUEUE);\n+\tp->mp_qst_data_en = register_query_field(p->mp_qst_data, QSL_QST_DATA_EN);\n+\tp->mp_qst_data_tx_port =\n+\t\tregister_query_field(p->mp_qst_data, QSL_QST_DATA_TX_PORT);\n+\tp->mp_qst_data_lre = register_query_field(p->mp_qst_data, QSL_QST_DATA_LRE);\n+\tp->mp_qst_data_tci = register_query_field(p->mp_qst_data, QSL_QST_DATA_TCI);\n+\tp->mp_qst_data_ven = register_query_field(p->mp_qst_data, QSL_QST_DATA_VEN);\n+\t/* QEN */\n+\tp->mp_qen_ctrl = module_get_register(p->m_qsl, QSL_QEN_CTRL);\n+\tp->mp_qen_addr = register_get_field(p->mp_qen_ctrl, QSL_QEN_CTRL_ADR);\n+\tp->mp_qen_cnt = register_get_field(p->mp_qen_ctrl, QSL_QEN_CTRL_CNT);\n+\tp->mp_qen_data = module_get_register(p->m_qsl, QSL_QEN_DATA);\n+\tp->mp_qen_data_en = register_get_field(p->mp_qen_data, QSL_QEN_DATA_EN);\n+\t/* UNMQ */\n+\tp->mp_unmq_ctrl = module_get_register(p->m_qsl, QSL_UNMQ_CTRL);\n+\tp->mp_unmq_addr = register_get_field(p->mp_unmq_ctrl, QSL_UNMQ_CTRL_ADR);\n+\tp->mp_unmq_cnt = register_get_field(p->mp_unmq_ctrl, QSL_UNMQ_CTRL_CNT);\n+\tp->mp_unmq_data = module_get_register(p->m_qsl, QSL_UNMQ_DATA);\n+\tp->mp_unmq_data_dest_queue =\n+\t\tregister_get_field(p->mp_unmq_data, QSL_UNMQ_DATA_DEST_QUEUE);\n+\tp->mp_unmq_data_en = register_get_field(p->mp_unmq_data, QSL_UNMQ_DATA_EN);\n+\n+\tif (!p->mp_qst_data_en) {\n+\t\t/* changed name from EN to QEN in v0.7 */\n+\t\tp->mp_qst_data_en =\n+\t\t\tregister_get_field(p->mp_qst_data, QSL_QST_DATA_QEN);\n+\t}\n+\n+\t/* LTX - not there anymore from v0.7+ */\n+\tp->mp_ltx_ctrl = module_query_register(p->m_qsl, QSL_LTX_CTRL);\n+\tif (p->mp_ltx_ctrl) {\n+\t\tp->mp_ltx_addr =\n+\t\t\tregister_get_field(p->mp_ltx_ctrl, QSL_LTX_CTRL_ADR);\n+\t\tp->mp_ltx_cnt = register_get_field(p->mp_ltx_ctrl, QSL_LTX_CTRL_CNT);\n+\t} else {\n+\t\tp->mp_ltx_addr = NULL;\n+\t\tp->mp_ltx_cnt = NULL;\n+\t}\n+\tp->mp_ltx_data = module_query_register(p->m_qsl, QSL_LTX_DATA);\n+\tif (p->mp_ltx_data) {\n+\t\tp->mp_ltx_data_lr =\n+\t\t\tregister_get_field(p->mp_ltx_data, QSL_LTX_DATA_LR);\n+\t\tp->mp_ltx_data_tx_port =\n+\t\t\tregister_get_field(p->mp_ltx_data, QSL_LTX_DATA_TX_PORT);\n+\t\tp->mp_ltx_data_tsa =\n+\t\t\tregister_get_field(p->mp_ltx_data, QSL_LTX_DATA_TSA);\n+\t} else {\n+\t\tp->mp_ltx_data_lr = NULL;\n+\t\tp->mp_ltx_data_tx_port = NULL;\n+\t\tp->mp_ltx_data_tsa = NULL;\n+\t}\n+\treturn 0;\n+}\n+\n+int qsl_nthw_setup(struct qsl_nthw *p, int n_idx, int n_idx_cnt)\n+{\n+\t(void)p;\n+\t(void)n_idx;\n+\t(void)n_idx_cnt;\n+\n+\treturn 0;\n+}\n+\n+/* RCP */\n+void qsl_nthw_rcp_select(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+};\n+\n+void qsl_nthw_rcp_cnt(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void qsl_nthw_rcp_discard(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_discard, val);\n+}\n+\n+void qsl_nthw_rcp_drop(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_drop, val);\n+}\n+\n+void qsl_nthw_rcp_tbl_lo(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tbl_lo, val);\n+}\n+\n+void qsl_nthw_rcp_tbl_hi(const struct qsl_nthw *p, uint32_t val)\n+\n+{\n+\tfield_set_val32(p->mp_rcp_data_tbl_hi, val);\n+}\n+\n+void qsl_nthw_rcp_tbl_idx(const struct qsl_nthw *p, uint32_t val)\n+\n+{\n+\tfield_set_val32(p->mp_rcp_data_tbl_idx, val);\n+}\n+\n+void qsl_nthw_rcp_tbl_msk(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tbl_msk, val);\n+}\n+\n+void qsl_nthw_rcp_cao(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_rcp_data_cao)\n+\t\tfield_set_val32(p->mp_rcp_data_cao, val);\n+}\n+\n+void qsl_nthw_rcp_lr(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_rcp_data_lr)\n+\t\tfield_set_val32(p->mp_rcp_data_lr, val);\n+}\n+\n+void qsl_nthw_rcp_tsa(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_rcp_data_tsa)\n+\t\tfield_set_val32(p->mp_rcp_data_tsa, val);\n+}\n+\n+void qsl_nthw_rcp_vli(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_rcp_data_vli)\n+\t\tfield_set_val32(p->mp_rcp_data_vli, val);\n+}\n+\n+void qsl_nthw_rcp_flush(const struct qsl_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\n+\n+/* LTX */\n+void qsl_nthw_ltx_select(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_ltx_addr)\n+\t\tfield_set_val32(p->mp_ltx_addr, val);\n+}\n+\n+void qsl_nthw_ltx_cnt(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_ltx_addr)\n+\t\tfield_set_val32(p->mp_ltx_cnt, val);\n+}\n+\n+void qsl_nthw_ltx_lr(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_ltx_data_lr)\n+\t\tfield_set_val32(p->mp_ltx_data_lr, val);\n+}\n+\n+void qsl_nthw_ltx_tx_port(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_ltx_data_tx_port)\n+\t\tfield_set_val32(p->mp_ltx_data_tx_port, val);\n+}\n+\n+void qsl_nthw_ltx_tsa(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_ltx_data_tsa)\n+\t\tfield_set_val32(p->mp_ltx_data_tsa, val);\n+};\n+\n+void qsl_nthw_ltx_flush(const struct qsl_nthw *p)\n+{\n+\tregister_flush(p->mp_ltx_ctrl, 1);\n+\tregister_flush(p->mp_ltx_data, 1);\n+}\n+\n+/* QST */\n+void qsl_nthw_qst_select(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_qst_addr, val);\n+}\n+\n+void qsl_nthw_qst_cnt(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_qst_cnt, val);\n+}\n+\n+void qsl_nthw_qst_queue(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_qst_data_queue, val);\n+}\n+\n+void qsl_nthw_qst_en(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_qst_data_en, val);\n+}\n+\n+void qsl_nthw_qst_tx_port(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_qst_data_tx_port)\n+\t\tfield_set_val32(p->mp_qst_data_tx_port, val);\n+}\n+\n+void qsl_nthw_qst_lre(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_qst_data_lre)\n+\t\tfield_set_val32(p->mp_qst_data_lre, val);\n+}\n+\n+void qsl_nthw_qst_tci(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_qst_data_tci)\n+\t\tfield_set_val32(p->mp_qst_data_tci, val);\n+}\n+\n+void qsl_nthw_qst_ven(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_qst_data_ven)\n+\t\tfield_set_val32(p->mp_qst_data_ven, val);\n+}\n+\n+void qsl_nthw_qst_flush(const struct qsl_nthw *p)\n+{\n+\tregister_flush(p->mp_qst_ctrl, 1);\n+\tregister_flush(p->mp_qst_data, 1);\n+}\n+\n+/* QEN */\n+void qsl_nthw_qen_select(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_qen_addr, val);\n+}\n+\n+void qsl_nthw_qen_cnt(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_qen_cnt, val);\n+}\n+\n+void qsl_nthw_qen_en(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_qen_data_en, val);\n+}\n+\n+void qsl_nthw_qen_flush(const struct qsl_nthw *p)\n+{\n+\tregister_flush(p->mp_qen_ctrl, 1);\n+\tregister_flush(p->mp_qen_data, 1);\n+}\n+\n+/* UNMQ */\n+void qsl_nthw_unmq_select(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_unmq_addr, val);\n+}\n+\n+void qsl_nthw_unmq_cnt(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_unmq_cnt, val);\n+}\n+\n+void qsl_nthw_unmq_dest_queue(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_unmq_data_dest_queue, val);\n+}\n+\n+void qsl_nthw_unmq_en(const struct qsl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_unmq_data_en, val);\n+}\n+\n+void qsl_nthw_unmq_flush(const struct qsl_nthw *p)\n+{\n+\tregister_flush(p->mp_unmq_ctrl, 1);\n+\tregister_flush(p->mp_unmq_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_qsl.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_qsl.h\nnew file mode 100644\nindex 0000000000..eeebbcf1c4\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_qsl.h\n@@ -0,0 +1,121 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_QSL_H__\n+#define __FLOW_NTHW_QSL_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct qsl_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_qsl;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_discard;\n+\tnt_field_t *mp_rcp_data_drop;\n+\tnt_field_t *mp_rcp_data_tbl_lo;\n+\tnt_field_t *mp_rcp_data_tbl_hi;\n+\tnt_field_t *mp_rcp_data_tbl_idx;\n+\tnt_field_t *mp_rcp_data_tbl_msk;\n+\tnt_field_t *mp_rcp_data_cao;\n+\tnt_field_t *mp_rcp_data_lr;\n+\tnt_field_t *mp_rcp_data_tsa;\n+\tnt_field_t *mp_rcp_data_vli;\n+\n+\tnt_register_t *mp_ltx_ctrl;\n+\tnt_field_t *mp_ltx_addr;\n+\tnt_field_t *mp_ltx_cnt;\n+\tnt_register_t *mp_ltx_data;\n+\tnt_field_t *mp_ltx_data_lr;\n+\tnt_field_t *mp_ltx_data_tx_port;\n+\tnt_field_t *mp_ltx_data_tsa;\n+\n+\tnt_register_t *mp_qst_ctrl;\n+\tnt_field_t *mp_qst_addr;\n+\tnt_field_t *mp_qst_cnt;\n+\tnt_register_t *mp_qst_data;\n+\tnt_field_t *mp_qst_data_queue;\n+\tnt_field_t *mp_qst_data_en;\n+\tnt_field_t *mp_qst_data_tx_port;\n+\tnt_field_t *mp_qst_data_lre;\n+\tnt_field_t *mp_qst_data_tci;\n+\tnt_field_t *mp_qst_data_ven;\n+\n+\tnt_register_t *mp_qen_ctrl;\n+\tnt_field_t *mp_qen_addr;\n+\tnt_field_t *mp_qen_cnt;\n+\tnt_register_t *mp_qen_data;\n+\tnt_field_t *mp_qen_data_en;\n+\n+\tnt_register_t *mp_unmq_ctrl;\n+\tnt_field_t *mp_unmq_addr;\n+\tnt_field_t *mp_unmq_cnt;\n+\tnt_register_t *mp_unmq_data;\n+\tnt_field_t *mp_unmq_data_dest_queue;\n+\tnt_field_t *mp_unmq_data_en;\n+};\n+\n+typedef struct qsl_nthw qsl_nthw_t;\n+\n+struct qsl_nthw *qsl_nthw_new(void);\n+void qsl_nthw_delete(struct qsl_nthw *p);\n+int qsl_nthw_init(struct qsl_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int qsl_nthw_setup(struct qsl_nthw *p, int n_idx, int n_idx_cnt);\n+void qsl_nthw_set_debug_mode(struct qsl_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void qsl_nthw_rcp_select(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_cnt(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_discard(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_drop(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_tbl_lo(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_tbl_hi(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_tbl_idx(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_tbl_msk(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_cao(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_lr(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_tsa(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_vli(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_rcp_flush(const struct qsl_nthw *p);\n+\n+/* LTX */\n+void qsl_nthw_ltx_select(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_ltx_cnt(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_ltx_lr(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_ltx_tx_port(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_ltx_tsa(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_ltx_flush(const struct qsl_nthw *p);\n+\n+/* QST */\n+void qsl_nthw_qst_select(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qst_cnt(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qst_queue(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qst_en(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qst_tx_port(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qst_lre(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qst_tci(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qst_ven(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qst_flush(const struct qsl_nthw *p);\n+\n+/* QEN */\n+void qsl_nthw_qen_select(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qen_cnt(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qen_en(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_qen_flush(const struct qsl_nthw *p);\n+\n+/* UNMQ */\n+void qsl_nthw_unmq_select(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_unmq_cnt(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_unmq_dest_queue(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_unmq_en(const struct qsl_nthw *p, uint32_t val);\n+void qsl_nthw_unmq_flush(const struct qsl_nthw *p);\n+\n+#endif /* __FLOW_NTHW_QSL_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rmc.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rmc.c\nnew file mode 100644\nindex 0000000000..8f519b7728\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rmc.c\n@@ -0,0 +1,112 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_rmc.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void rmc_nthw_set_debug_mode(struct rmc_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_rmc, n_debug_mode);\n+}\n+\n+struct rmc_nthw *rmc_nthw_new(void)\n+{\n+\tstruct rmc_nthw *p = malloc(sizeof(struct rmc_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void rmc_nthw_delete(struct rmc_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int rmc_nthw_init(struct rmc_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_RMC, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: RMC %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_rmc = p_mod;\n+\n+\t/* CTRL */\n+\tp->mp_ctrl = module_get_register(p->m_rmc, RMC_CTRL);\n+\tp->mp_ctrl_block_statt =\n+\t\tregister_get_field(p->mp_ctrl, RMC_CTRL_BLOCK_STATT);\n+\tp->mp_ctrl_block_keep_a =\n+\t\tregister_get_field(p->mp_ctrl, RMC_CTRL_BLOCK_KEEPA);\n+\tp->mp_ctrl_block_rpp_slice =\n+\t\tregister_query_field(p->mp_ctrl, RMC_CTRL_BLOCK_RPP_SLICE);\n+\tp->mp_ctrl_block_mac_port =\n+\t\tregister_get_field(p->mp_ctrl, RMC_CTRL_BLOCK_MAC_PORT);\n+\tp->mp_ctrl_lag_phy_odd_even =\n+\t\tregister_get_field(p->mp_ctrl, RMC_CTRL_LAG_PHY_ODD_EVEN);\n+\treturn 0;\n+}\n+\n+int rmc_nthw_setup(struct rmc_nthw *p, int n_idx, int n_idx_cnt)\n+{\n+\t(void)p;\n+\t(void)n_idx;\n+\t(void)n_idx_cnt;\n+\n+\treturn 0;\n+}\n+\n+/* CTRL */\n+void rmc_nthw_ctrl_block_statt(const struct rmc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_ctrl_block_statt, val);\n+}\n+\n+void rmc_nthw_ctrl_block_keep_a(const struct rmc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_ctrl_block_keep_a, val);\n+}\n+\n+void rmc_nthw_ctrl_block_rpp_slice(const struct rmc_nthw *p, uint32_t val)\n+{\n+\tif (p->mp_ctrl_block_rpp_slice)\n+\t\tfield_set_val32(p->mp_ctrl_block_rpp_slice, val);\n+}\n+\n+void rmc_nthw_ctrl_block_mac_port(const struct rmc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_ctrl_block_mac_port, val);\n+}\n+\n+void rmc_nthw_ctrl_lag_phy_odd_even(const struct rmc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_ctrl_lag_phy_odd_even, val);\n+}\n+\n+void rmc_nthw_ctrl_flush(const struct rmc_nthw *p)\n+{\n+\tregister_flush(p->mp_ctrl, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rmc.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rmc.h\nnew file mode 100644\nindex 0000000000..57d5776002\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rmc.h\n@@ -0,0 +1,40 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_RMC_H__\n+#define __FLOW_NTHW_RMC_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct rmc_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_rmc;\n+\n+\tnt_register_t *mp_ctrl;\n+\tnt_field_t *mp_ctrl_block_statt;\n+\tnt_field_t *mp_ctrl_block_keep_a;\n+\tnt_field_t *mp_ctrl_block_rpp_slice;\n+\tnt_field_t *mp_ctrl_block_mac_port;\n+\tnt_field_t *mp_ctrl_lag_phy_odd_even;\n+};\n+\n+struct rmc_nthw *rmc_nthw_new(void);\n+void rmc_nthw_delete(struct rmc_nthw *p);\n+int rmc_nthw_init(struct rmc_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int rmc_nthw_setup(struct rmc_nthw *p, int n_idx, int n_idx_cnt);\n+void rmc_nthw_set_debug_mode(struct rmc_nthw *p, unsigned int n_debug_mode);\n+\n+/* CTRL */\n+void rmc_nthw_ctrl_block_statt(const struct rmc_nthw *p, uint32_t val);\n+void rmc_nthw_ctrl_block_keep_a(const struct rmc_nthw *p, uint32_t val);\n+void rmc_nthw_ctrl_block_rpp_slice(const struct rmc_nthw *p, uint32_t val);\n+void rmc_nthw_ctrl_block_mac_port(const struct rmc_nthw *p, uint32_t val);\n+void rmc_nthw_ctrl_lag_phy_odd_even(const struct rmc_nthw *p, uint32_t val);\n+void rmc_nthw_ctrl_flush(const struct rmc_nthw *p);\n+\n+#endif /* __FLOW_NTHW_RMC_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_roa.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_roa.c\nnew file mode 100644\nindex 0000000000..934778f426\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_roa.c\n@@ -0,0 +1,294 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_roa.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void roa_nthw_set_debug_mode(struct roa_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_roa, n_debug_mode);\n+}\n+\n+struct roa_nthw *roa_nthw_new(void)\n+{\n+\tstruct roa_nthw *p = malloc(sizeof(struct roa_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void roa_nthw_delete(struct roa_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int roa_nthw_init(struct roa_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_ROA, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: ROA %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_roa = p_mod;\n+\n+\t/* TUN HDR */\n+\tp->mp_tun_hdr_ctrl = module_get_register(p->m_roa, ROA_TUNHDR_CTRL);\n+\tp->mp_tun_hdr_addr =\n+\t\tregister_get_field(p->mp_tun_hdr_ctrl, ROA_TUNHDR_CTRL_ADR);\n+\tp->mp_tun_hdr_cnt =\n+\t\tregister_get_field(p->mp_tun_hdr_ctrl, ROA_TUNHDR_CTRL_CNT);\n+\tp->mp_tun_hdr_data = module_get_register(p->m_roa, ROA_TUNHDR_DATA);\n+\tp->mp_tun_hdr_data_tunnel_hdr =\n+\t\tregister_get_field(p->mp_tun_hdr_data, ROA_TUNHDR_DATA_TUNNEL_HDR);\n+\t/* TUN CFG */\n+\tp->mp_tun_cfg_ctrl = module_get_register(p->m_roa, ROA_TUNCFG_CTRL);\n+\tp->mp_tun_cfg_addr =\n+\t\tregister_get_field(p->mp_tun_cfg_ctrl, ROA_TUNCFG_CTRL_ADR);\n+\tp->mp_tun_cfg_cnt =\n+\t\tregister_get_field(p->mp_tun_cfg_ctrl, ROA_TUNCFG_CTRL_CNT);\n+\tp->mp_tun_cfg_data = module_get_register(p->m_roa, ROA_TUNCFG_DATA);\n+\tp->mp_tun_cfg_data_tun_len =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_LEN);\n+\tp->mp_tun_cfg_data_tun_type =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_TYPE);\n+\tp->mp_tun_cfg_data_tun_vlan =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_VLAN);\n+\tp->mp_tun_cfg_data_ip_type =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_IP_TYPE);\n+\tp->mp_tun_cfg_data_ipcs_upd =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_IPCS_UPD);\n+\tp->mp_tun_cfg_data_ipcs_precalc =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_IPCS_PRECALC);\n+\tp->mp_tun_cfg_data_iptl_upd =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_IPTL_UPD);\n+\tp->mp_tun_cfg_data_iptl_precalc =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_IPTL_PRECALC);\n+\tp->mp_tun_cfg_data_vxlan_udp_len_upd =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TUN_VXLAN_UDP_LEN_UPD);\n+\tp->mp_tun_cfg_data_tx_lag_ix =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_TX_LAG_IX);\n+\tp->mp_tun_cfg_data_recirculate =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_RECIRCULATE);\n+\tp->mp_tun_cfg_data_push_tunnel =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_PUSH_TUNNEL);\n+\tp->mp_tun_cfg_data_recirc_port =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_RECIRC_PORT);\n+\tp->mp_tun_cfg_data_recirc_bypass =\n+\t\tregister_get_field(p->mp_tun_cfg_data, ROA_TUNCFG_DATA_RECIRC_BYPASS);\n+\t/* CONFIG */\n+\tp->mp_config = module_get_register(p->m_roa, ROA_CONFIG);\n+\tp->mp_config_fwd_recirculate =\n+\t\tregister_get_field(p->mp_config, ROA_CONFIG_FWD_RECIRCULATE);\n+\tp->mp_config_fwd_normal_pcks =\n+\t\tregister_get_field(p->mp_config, ROA_CONFIG_FWD_NORMAL_PCKS);\n+\tp->mp_config_fwd_tx_port0 =\n+\t\tregister_get_field(p->mp_config, ROA_CONFIG_FWD_TXPORT0);\n+\tp->mp_config_fwd_tx_port1 =\n+\t\tregister_get_field(p->mp_config, ROA_CONFIG_FWD_TXPORT1);\n+\tp->mp_config_fwd_cell_builder_pcks =\n+\t\tregister_get_field(p->mp_config, ROA_CONFIG_FWD_CELLBUILDER_PCKS);\n+\tp->mp_config_fwd_non_normal_pcks =\n+\t\tregister_get_field(p->mp_config, ROA_CONFIG_FWD_NON_NORMAL_PCKS);\n+\t/* LAG */\n+\tp->mp_lag_cfg_ctrl = module_get_register(p->m_roa, ROA_LAGCFG_CTRL);\n+\tp->mp_lag_cfg_addr =\n+\t\tregister_get_field(p->mp_lag_cfg_ctrl, ROA_LAGCFG_CTRL_ADR);\n+\tp->mp_lag_cfg_cnt =\n+\t\tregister_get_field(p->mp_lag_cfg_ctrl, ROA_LAGCFG_CTRL_CNT);\n+\tp->mp_lag_cfg_data = module_get_register(p->m_roa, ROA_LAGCFG_DATA);\n+\tp->mp_lag_cfg_data_tx_phy_port =\n+\t\tregister_get_field(p->mp_lag_cfg_data, ROA_LAGCFG_DATA_TXPHY_PORT);\n+\n+\treturn 0;\n+}\n+\n+/* TUN HDR */\n+void roa_nthw_tun_hdr_select(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_hdr_addr, val);\n+}\n+\n+void roa_nthw_tun_hdr_cnt(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_hdr_cnt, val);\n+}\n+\n+void roa_nthw_tun_hdr_tunnel_hdr(const struct roa_nthw *p, uint32_t *val)\n+{\n+\tfield_set_val(p->mp_tun_hdr_data_tunnel_hdr, val, 4);\n+}\n+\n+void roa_nthw_tun_hdr_flush(const struct roa_nthw *p)\n+{\n+\tregister_flush(p->mp_tun_hdr_ctrl, 1);\n+\tregister_flush(p->mp_tun_hdr_data, 1);\n+}\n+\n+/* TUN CFG */\n+void roa_nthw_tun_cfg_select(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_addr, val);\n+}\n+\n+void roa_nthw_tun_cfg_cnt(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_cnt, val);\n+}\n+\n+void roa_nthw_tun_cfg_tun_len(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_tun_len, val);\n+}\n+\n+void roa_nthw_tun_cfg_tun_type(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_tun_type, val);\n+}\n+\n+void roa_nthw_tun_cfg_tun_vlan(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_tun_vlan, val);\n+}\n+\n+void roa_nthw_tun_cfg_ip_type(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_ip_type, val);\n+}\n+\n+void roa_nthw_tun_cfg_ipcs_upd(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_ipcs_upd, val);\n+}\n+\n+void roa_nthw_tun_cfg_ipcs_precalc(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_ipcs_precalc, val);\n+}\n+\n+void roa_nthw_tun_cfg_iptl_upd(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_iptl_upd, val);\n+}\n+\n+void roa_nthw_tun_cfg_iptl_precalc(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_iptl_precalc, val);\n+}\n+\n+void roa_nthw_tun_cfg_vxlan_udp_len_upd(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_vxlan_udp_len_upd, val);\n+}\n+\n+void roa_nthw_tun_cfg_tx_lag_ix(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_tx_lag_ix, val);\n+};\n+\n+void roa_nthw_tun_cfg_recirculate(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_recirculate, val);\n+}\n+\n+void roa_nthw_tun_cfg_push_tunnel(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_push_tunnel, val);\n+}\n+\n+void roa_nthw_tun_cfg_recirc_port(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_recirc_port, val);\n+}\n+\n+void roa_nthw_tun_cfg_recirc_bypass(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_tun_cfg_data_recirc_bypass, val);\n+}\n+\n+void roa_nthw_tun_cfg_flush(const struct roa_nthw *p)\n+{\n+\tregister_flush(p->mp_tun_cfg_ctrl, 1);\n+\tregister_flush(p->mp_tun_cfg_data, 1);\n+}\n+\n+/* ROA CONFIG */\n+void roa_nthw_config_fwd_recirculate(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_config_fwd_recirculate, val);\n+}\n+\n+void roa_nthw_config_fwd_normal_pcks(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_config_fwd_normal_pcks, val);\n+}\n+\n+void roa_nthw_config_fwd_tx_port0(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_config_fwd_tx_port0, val);\n+}\n+\n+void roa_nthw_config_fwd_tx_port1(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_config_fwd_tx_port1, val);\n+}\n+\n+void roa_nthw_config_fwd_cell_builder_pcks(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_config_fwd_cell_builder_pcks, val);\n+}\n+\n+void roa_nthw_config_fwd_non_normal_pcks(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_config_fwd_non_normal_pcks, val);\n+}\n+\n+void roa_nthw_config_flush(const struct roa_nthw *p)\n+{\n+\tregister_flush(p->mp_config, 1);\n+}\n+\n+/* LAG */\n+void roa_nthw_lag_cfg_select(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_lag_cfg_addr, val);\n+}\n+\n+void roa_nthw_lag_cfg_cnt(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_lag_cfg_cnt, val);\n+}\n+\n+void roa_nthw_lag_cfg_tx_phy_port(const struct roa_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_lag_cfg_data_tx_phy_port, val);\n+}\n+\n+void roa_nthw_lag_cfg_flush(const struct roa_nthw *p)\n+{\n+\tregister_flush(p->mp_lag_cfg_ctrl, 1);\n+\tregister_flush(p->mp_lag_cfg_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_roa.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_roa.h\nnew file mode 100644\nindex 0000000000..9398ef5ae9\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_roa.h\n@@ -0,0 +1,109 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_ROA_H__\n+#define __FLOW_NTHW_ROA_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct roa_nthw;\n+\n+typedef struct roa_nthw roa_nthw_t;\n+\n+struct roa_nthw *roa_nthw_new(void);\n+void roa_nthw_delete(struct roa_nthw *p);\n+int roa_nthw_init(struct roa_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int roa_nthw_setup(struct roa_nthw *p, int n_idx, int n_idx_cnt);\n+void roa_nthw_set_debug_mode(struct roa_nthw *p, unsigned int n_debug_mode);\n+\n+/* TUN HDR */\n+void roa_nthw_tun_hdr_select(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_hdr_cnt(const struct roa_nthw *p, uint32_t val);\n+\n+void roa_nthw_tun_hdr_tunnel_hdr(const struct roa_nthw *p, uint32_t *val);\n+void roa_nthw_tun_hdr_flush(const struct roa_nthw *p);\n+\n+/* TUN CFG */\n+void roa_nthw_tun_cfg_select(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_cnt(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_tun_len(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_tun_type(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_tun_vlan(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_ip_type(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_ipcs_upd(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_ipcs_precalc(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_iptl_upd(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_iptl_precalc(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_vxlan_udp_len_upd(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_tx_lag_ix(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_recirculate(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_push_tunnel(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_recirc_port(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_recirc_bypass(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_tun_cfg_flush(const struct roa_nthw *p);\n+\n+/* ROA CONFIG */\n+void roa_nthw_config_fwd_recirculate(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_config_fwd_normal_pcks(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_config_fwd_tx_port0(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_config_fwd_tx_port1(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_config_fwd_cell_builder_pcks(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_config_fwd_non_normal_pcks(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_config_flush(const struct roa_nthw *p);\n+\n+/* LAG */\n+void roa_nthw_lag_cfg_select(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_lag_cfg_cnt(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_lag_cfg_tx_phy_port(const struct roa_nthw *p, uint32_t val);\n+void roa_nthw_lag_cfg_flush(const struct roa_nthw *p);\n+\n+struct roa_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_roa;\n+\n+\tnt_register_t *mp_tun_hdr_ctrl;\n+\tnt_field_t *mp_tun_hdr_addr;\n+\tnt_field_t *mp_tun_hdr_cnt;\n+\tnt_register_t *mp_tun_hdr_data;\n+\tnt_field_t *mp_tun_hdr_data_tunnel_hdr;\n+\n+\tnt_register_t *mp_tun_cfg_ctrl;\n+\tnt_field_t *mp_tun_cfg_addr;\n+\tnt_field_t *mp_tun_cfg_cnt;\n+\tnt_register_t *mp_tun_cfg_data;\n+\tnt_field_t *mp_tun_cfg_data_tun_len;\n+\tnt_field_t *mp_tun_cfg_data_tun_type;\n+\tnt_field_t *mp_tun_cfg_data_tun_vlan;\n+\tnt_field_t *mp_tun_cfg_data_ip_type;\n+\tnt_field_t *mp_tun_cfg_data_ipcs_upd;\n+\tnt_field_t *mp_tun_cfg_data_ipcs_precalc;\n+\tnt_field_t *mp_tun_cfg_data_iptl_upd;\n+\tnt_field_t *mp_tun_cfg_data_iptl_precalc;\n+\tnt_field_t *mp_tun_cfg_data_vxlan_udp_len_upd;\n+\tnt_field_t *mp_tun_cfg_data_tx_lag_ix;\n+\tnt_field_t *mp_tun_cfg_data_recirculate;\n+\tnt_field_t *mp_tun_cfg_data_push_tunnel;\n+\tnt_field_t *mp_tun_cfg_data_recirc_port;\n+\tnt_field_t *mp_tun_cfg_data_recirc_bypass;\n+\n+\tnt_register_t *mp_config;\n+\tnt_field_t *mp_config_fwd_recirculate;\n+\tnt_field_t *mp_config_fwd_normal_pcks;\n+\tnt_field_t *mp_config_fwd_tx_port0;\n+\tnt_field_t *mp_config_fwd_tx_port1;\n+\tnt_field_t *mp_config_fwd_cell_builder_pcks;\n+\tnt_field_t *mp_config_fwd_non_normal_pcks;\n+\n+\tnt_register_t *mp_lag_cfg_ctrl;\n+\tnt_field_t *mp_lag_cfg_addr;\n+\tnt_field_t *mp_lag_cfg_cnt;\n+\tnt_register_t *mp_lag_cfg_data;\n+\tnt_field_t *mp_lag_cfg_data_tx_phy_port;\n+};\n+\n+#endif /* __FLOW_NTHW_ROA_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c\nnew file mode 100644\nindex 0000000000..2ce3ce6cf8\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.c\n@@ -0,0 +1,132 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_rpp_lr.h\"\n+\n+#include <stdlib.h>\n+#include <string.h>\n+\n+void rpp_lr_nthw_set_debug_mode(struct rpp_lr_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_rpp_lr, n_debug_mode);\n+}\n+\n+struct rpp_lr_nthw *rpp_lr_nthw_new(void)\n+{\n+\tstruct rpp_lr_nthw *p = malloc(sizeof(struct rpp_lr_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\treturn p;\n+}\n+\n+void rpp_lr_nthw_delete(struct rpp_lr_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int rpp_lr_nthw_init(struct rpp_lr_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_RPP_LR, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: RppLr %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_rpp_lr = fpga_query_module(p_fpga, MOD_RPP_LR, n_instance);\n+\n+\tp->mp_rcp_ctrl = module_get_register(p->m_rpp_lr, RPP_LR_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, RPP_LR_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, RPP_LR_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_rpp_lr, RPP_LR_RCP_DATA);\n+\tp->mp_rcp_data_exp = register_get_field(p->mp_rcp_data, RPP_LR_RCP_DATA_EXP);\n+\n+\tp->mp_ifr_rcp_ctrl = module_query_register(p->m_rpp_lr, RPP_LR_IFR_RCP_CTRL);\n+\tp->mp_ifr_rcp_addr =\n+\t\tregister_query_field(p->mp_ifr_rcp_ctrl, RPP_LR_IFR_RCP_CTRL_ADR);\n+\tp->mp_ifr_rcp_cnt =\n+\t\tregister_query_field(p->mp_ifr_rcp_ctrl, RPP_LR_IFR_RCP_CTRL_CNT);\n+\tp->mp_ifr_rcp_data = module_query_register(p->m_rpp_lr, RPP_LR_IFR_RCP_DATA);\n+\tp->mp_ifr_rcp_data_en =\n+\t\tregister_query_field(p->mp_ifr_rcp_data, RPP_LR_IFR_RCP_DATA_EN);\n+\tp->mp_ifr_rcp_data_mtu =\n+\t\tregister_query_field(p->mp_ifr_rcp_data, RPP_LR_IFR_RCP_DATA_MTU);\n+\n+\treturn 0;\n+}\n+\n+void rpp_lr_nthw_rcp_select(const struct rpp_lr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_rcp_addr);\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void rpp_lr_nthw_rcp_cnt(const struct rpp_lr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_rcp_cnt);\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void rpp_lr_nthw_rcp_exp(const struct rpp_lr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_rcp_data_exp);\n+\tfield_set_val32(p->mp_rcp_data_exp, val);\n+}\n+\n+void rpp_lr_nthw_rcp_flush(const struct rpp_lr_nthw *p)\n+{\n+\tassert(p->mp_rcp_ctrl);\n+\tassert(p->mp_rcp_data);\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\n+\n+void rpp_lr_nthw_ifr_rcp_select(const struct rpp_lr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_ifr_rcp_addr);\n+\tfield_set_val32(p->mp_ifr_rcp_addr, val);\n+}\n+\n+void rpp_lr_nthw_ifr_rcp_cnt(const struct rpp_lr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_ifr_rcp_cnt);\n+\tfield_set_val32(p->mp_ifr_rcp_cnt, val);\n+}\n+\n+void rpp_lr_nthw_ifr_rcp_en(const struct rpp_lr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_ifr_rcp_data_en);\n+\tfield_set_val32(p->mp_ifr_rcp_data_en, val);\n+}\n+\n+void rpp_lr_nthw_ifr_rcp_mtu(const struct rpp_lr_nthw *p, uint32_t val)\n+{\n+\tassert(p->mp_ifr_rcp_data_mtu);\n+\tfield_set_val32(p->mp_ifr_rcp_data_mtu, val);\n+}\n+\n+void rpp_lr_nthw_ifr_rcp_flush(const struct rpp_lr_nthw *p)\n+{\n+\tassert(p->mp_ifr_rcp_ctrl);\n+\tassert(p->mp_ifr_rcp_data);\n+\tregister_flush(p->mp_ifr_rcp_ctrl, 1);\n+\tregister_flush(p->mp_ifr_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.h\nnew file mode 100644\nindex 0000000000..e442c9d8d2\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_rpp_lr.h\n@@ -0,0 +1,53 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_RPP_LR_H__\n+#define __FLOW_NTHW_RPP_LR_H__\n+\n+#include <stdint.h>\n+#include \"nthw_fpga_model.h\"\n+\n+struct rpp_lr_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_rpp_lr;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_exp;\n+\n+\tnt_register_t *mp_ifr_rcp_ctrl;\n+\tnt_field_t *mp_ifr_rcp_addr;\n+\tnt_field_t *mp_ifr_rcp_cnt;\n+\n+\tnt_register_t *mp_ifr_rcp_data;\n+\tnt_field_t *mp_ifr_rcp_data_en;\n+\tnt_field_t *mp_ifr_rcp_data_mtu;\n+};\n+\n+struct rpp_lr_nthw *rpp_lr_nthw_new(void);\n+void rpp_lr_nthw_delete(struct rpp_lr_nthw *p);\n+int rpp_lr_nthw_init(struct rpp_lr_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int rpp_lr_nthw_setup(struct rpp_lr_nthw *p, int n_idx, int n_idx_cnt);\n+void rpp_lr_nthw_set_debug_mode(struct rpp_lr_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void rpp_lr_nthw_rcp_select(const struct rpp_lr_nthw *p, uint32_t val);\n+void rpp_lr_nthw_rcp_cnt(const struct rpp_lr_nthw *p, uint32_t val);\n+void rpp_lr_nthw_rcp_exp(const struct rpp_lr_nthw *p, uint32_t val);\n+void rpp_lr_nthw_rcp_flush(const struct rpp_lr_nthw *p);\n+\n+/* RCP IFR */\n+void rpp_lr_nthw_ifr_rcp_select(const struct rpp_lr_nthw *p, uint32_t val);\n+void rpp_lr_nthw_ifr_rcp_cnt(const struct rpp_lr_nthw *p, uint32_t val);\n+void rpp_lr_nthw_ifr_rcp_en(const struct rpp_lr_nthw *p, uint32_t val);\n+void rpp_lr_nthw_ifr_rcp_mtu(const struct rpp_lr_nthw *p, uint32_t val);\n+void rpp_lr_nthw_ifr_rcp_flush(const struct rpp_lr_nthw *p);\n+\n+#endif /* __FLOW_NTHW_RPP_LR_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc.c\nnew file mode 100644\nindex 0000000000..a409e68869\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc.c\n@@ -0,0 +1,109 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_slc.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void slc_nthw_set_debug_mode(struct slc_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_slc, n_debug_mode);\n+}\n+\n+struct slc_nthw *slc_nthw_new(void)\n+{\n+\tstruct slc_nthw *p = malloc(sizeof(struct slc_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void slc_nthw_delete(struct slc_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int slc_nthw_init(struct slc_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_SLC, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Slc %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_slc = fpga_query_module(p_fpga, MOD_SLC, n_instance);\n+\n+\t/* RCP */\n+\tp->mp_rcp_ctrl = module_get_register(p->m_slc, SLC_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, SLC_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, SLC_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_slc, SLC_RCP_DATA);\n+\tp->mp_rcp_data_tail_slc_en =\n+\t\tregister_get_field(p->mp_rcp_data, SLC_RCP_DATA_TAIL_SLC_EN);\n+\tp->mp_rcp_data_tail_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, SLC_RCP_DATA_TAIL_DYN);\n+\tp->mp_rcp_data_tail_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, SLC_RCP_DATA_TAIL_OFS);\n+\tp->mp_rcp_data_pcap = register_get_field(p->mp_rcp_data, SLC_RCP_DATA_PCAP);\n+\n+\treturn 0;\n+}\n+\n+/* RCP */\n+void slc_nthw_rcp_select(const struct slc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void slc_nthw_rcp_cnt(const struct slc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void slc_nthw_rcp_tail_slc_en(const struct slc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tail_slc_en, val);\n+}\n+\n+void slc_nthw_rcp_tail_dyn(const struct slc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tail_dyn, val);\n+}\n+\n+void slc_nthw_rcp_tail_ofs(const struct slc_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tail_ofs, val);\n+}\n+\n+void slc_nthw_rcp_pcap(const struct slc_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_pcap, val);\n+}\n+\n+void slc_nthw_rcp_flush(const struct slc_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc.h\nnew file mode 100644\nindex 0000000000..e0f58e27e4\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc.h\n@@ -0,0 +1,46 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_SLC_H__\n+#define __FLOW_NTHW_SLC_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct slc_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_slc;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\n+\tnt_field_t *mp_rcp_data_tail_slc_en;\n+\tnt_field_t *mp_rcp_data_tail_dyn;\n+\tnt_field_t *mp_rcp_data_tail_ofs;\n+\tnt_field_t *mp_rcp_data_pcap;\n+};\n+\n+typedef struct slc_nthw slc_nthw_t;\n+\n+struct slc_nthw *slc_nthw_new(void);\n+void slc_nthw_delete(struct slc_nthw *p);\n+int slc_nthw_init(struct slc_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int slc_nthw_setup(struct slc_nthw *p, int n_idx, int n_idx_cnt);\n+void slc_nthw_set_debug_mode(struct slc_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void slc_nthw_rcp_select(const struct slc_nthw *p, uint32_t val);\n+void slc_nthw_rcp_cnt(const struct slc_nthw *p, uint32_t val);\n+void slc_nthw_rcp_tail_slc_en(const struct slc_nthw *p, uint32_t val);\n+void slc_nthw_rcp_tail_dyn(const struct slc_nthw *p, uint32_t val);\n+void slc_nthw_rcp_tail_ofs(const struct slc_nthw *p, int32_t val);\n+void slc_nthw_rcp_pcap(const struct slc_nthw *p, uint32_t val);\n+void slc_nthw_rcp_flush(const struct slc_nthw *p);\n+\n+#endif /* __FLOW_NTHW_SLC_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc_lr.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc_lr.c\nnew file mode 100644\nindex 0000000000..f106974bdd\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc_lr.c\n@@ -0,0 +1,109 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_slc_lr.h\"\n+\n+#include <stdlib.h> /* malloc */\n+#include <string.h> /* memset */\n+\n+void slc_lr_nthw_set_debug_mode(struct slc_lr_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_slc_lr, n_debug_mode);\n+}\n+\n+struct slc_lr_nthw *slc_lr_nthw_new(void)\n+{\n+\tstruct slc_lr_nthw *p = malloc(sizeof(struct slc_lr_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\n+\treturn p;\n+}\n+\n+void slc_lr_nthw_delete(struct slc_lr_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int slc_lr_nthw_init(struct slc_lr_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_SLC_LR, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: Slc %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_slc_lr = fpga_query_module(p_fpga, MOD_SLC_LR, n_instance);\n+\n+\t/* RCP */\n+\tp->mp_rcp_ctrl = module_get_register(p->m_slc_lr, SLC_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, SLC_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, SLC_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_slc_lr, SLC_RCP_DATA);\n+\tp->mp_rcp_data_tail_slc_en =\n+\t\tregister_get_field(p->mp_rcp_data, SLC_RCP_DATA_TAIL_SLC_EN);\n+\tp->mp_rcp_data_tail_dyn =\n+\t\tregister_get_field(p->mp_rcp_data, SLC_RCP_DATA_TAIL_DYN);\n+\tp->mp_rcp_data_tail_ofs =\n+\t\tregister_get_field(p->mp_rcp_data, SLC_RCP_DATA_TAIL_OFS);\n+\tp->mp_rcp_data_pcap = register_get_field(p->mp_rcp_data, SLC_RCP_DATA_PCAP);\n+\n+\treturn 0;\n+}\n+\n+/* RCP */\n+void slc_lr_nthw_rcp_select(const struct slc_lr_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void slc_lr_nthw_rcp_cnt(const struct slc_lr_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void slc_lr_nthw_rcp_tail_slc_en(const struct slc_lr_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tail_slc_en, val);\n+}\n+\n+void slc_lr_nthw_rcp_tail_dyn(const struct slc_lr_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tail_dyn, val);\n+}\n+\n+void slc_lr_nthw_rcp_tail_ofs(const struct slc_lr_nthw *p, int32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_tail_ofs, val);\n+}\n+\n+void slc_lr_nthw_rcp_pcap(const struct slc_lr_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_pcap, val);\n+}\n+\n+void slc_lr_nthw_rcp_flush(const struct slc_lr_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc_lr.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc_lr.h\nnew file mode 100644\nindex 0000000000..533f2efbeb\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_slc_lr.h\n@@ -0,0 +1,46 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_SLC_LR_H__\n+#define __FLOW_NTHW_SLC_LR_H__\n+\n+#include <stdint.h> /* uint32_t */\n+#include \"nthw_fpga_model.h\"\n+\n+struct slc_lr_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_slc_lr;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\tnt_register_t *mp_rcp_data;\n+\n+\tnt_field_t *mp_rcp_data_tail_slc_en;\n+\tnt_field_t *mp_rcp_data_tail_dyn;\n+\tnt_field_t *mp_rcp_data_tail_ofs;\n+\tnt_field_t *mp_rcp_data_pcap;\n+};\n+\n+typedef struct slc_lr_nthw slc_lr_nthw_t;\n+\n+struct slc_lr_nthw *slc_lr_nthw_new(void);\n+void slc_lr_nthw_delete(struct slc_lr_nthw *p);\n+int slc_lr_nthw_init(struct slc_lr_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int slc_lr_nthw_setup(struct slc_lr_nthw *p, int n_idx, int n_idx_cnt);\n+void slc_lr_nthw_set_debug_mode(struct slc_lr_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void slc_lr_nthw_rcp_select(const struct slc_lr_nthw *p, uint32_t val);\n+void slc_lr_nthw_rcp_cnt(const struct slc_lr_nthw *p, uint32_t val);\n+void slc_lr_nthw_rcp_tail_slc_en(const struct slc_lr_nthw *p, uint32_t val);\n+void slc_lr_nthw_rcp_tail_dyn(const struct slc_lr_nthw *p, uint32_t val);\n+void slc_lr_nthw_rcp_tail_ofs(const struct slc_lr_nthw *p, int32_t val);\n+void slc_lr_nthw_rcp_pcap(const struct slc_lr_nthw *p, uint32_t val);\n+void slc_lr_nthw_rcp_flush(const struct slc_lr_nthw *p);\n+\n+#endif /* __FLOW_NTHW_SLC_LR_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_cpy.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_cpy.c\nnew file mode 100644\nindex 0000000000..4d28d8cc3d\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_cpy.c\n@@ -0,0 +1,394 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_tx_cpy.h\"\n+\n+#include <stdlib.h>\n+#include <string.h>\n+\n+void tx_cpy_nthw_set_debug_mode(struct tx_cpy_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_tx_cpy, n_debug_mode);\n+}\n+\n+struct tx_cpy_nthw *tx_cpy_nthw_new(void)\n+{\n+\tstruct tx_cpy_nthw *p = malloc(sizeof(struct tx_cpy_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\treturn p;\n+}\n+\n+void tx_cpy_nthw_delete(struct tx_cpy_nthw *p)\n+{\n+\tif (p) {\n+\t\tfree(p->m_writers);\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int tx_cpy_nthw_init(struct tx_cpy_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_TX_CPY, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: TxCpy %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_tx_cpy = fpga_query_module(p_fpga, MOD_TX_CPY, n_instance);\n+\n+\tconst int writers_cnt =\n+\t\tfpga_get_product_param(p->mp_fpga, NT_TX_CPY_WRITERS, 0);\n+\tif (writers_cnt < 1)\n+\t\treturn -1;\n+\n+\tp->m_writers_cnt = (unsigned int)writers_cnt;\n+\tp->m_writers = calloc(p->m_writers_cnt, sizeof(struct tx_cpy_writers_s));\n+\tif (p->m_writers == NULL)\n+\t\treturn -1;\n+\n+\tconst int variant =\n+\t\tfpga_get_product_param(p->mp_fpga, NT_TX_CPY_VARIANT, 0);\n+\n+\tswitch (p->m_writers_cnt) {\n+\tdefault:\n+\tcase 6:\n+\t\tp->m_writers[5].mp_writer_ctrl =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER5_CTRL);\n+\t\tp->m_writers[5].mp_writer_ctrl_addr =\n+\t\t\tregister_get_field(p->m_writers[5].mp_writer_ctrl,\n+\t\t\t\t\t   CPY_WRITER5_CTRL_ADR);\n+\t\tp->m_writers[5].mp_writer_ctrl_cnt =\n+\t\t\tregister_get_field(p->m_writers[5].mp_writer_ctrl,\n+\t\t\t\t\t   CPY_WRITER5_CTRL_CNT);\n+\t\tp->m_writers[5].mp_writer_data =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER5_DATA);\n+\t\tp->m_writers[5].mp_writer_data_reader_select =\n+\t\t\tregister_get_field(p->m_writers[5].mp_writer_data,\n+\t\t\t\t\t  CPY_WRITER5_DATA_READER_SELECT);\n+\t\tp->m_writers[5].mp_writer_data_dyn =\n+\t\t\tregister_get_field(p->m_writers[5].mp_writer_data,\n+\t\t\t\t\t   CPY_WRITER5_DATA_DYN);\n+\t\tp->m_writers[5].mp_writer_data_ofs =\n+\t\t\tregister_get_field(p->m_writers[5].mp_writer_data,\n+\t\t\t\t\t   CPY_WRITER5_DATA_OFS);\n+\t\tp->m_writers[5].mp_writer_data_len =\n+\t\t\tregister_get_field(p->m_writers[5].mp_writer_data,\n+\t\t\t\t\t   CPY_WRITER5_DATA_LEN);\n+\t\tif (variant != 0) {\n+\t\t\tp->m_writers[5].mp_writer_data_mask_pointer =\n+\t\t\t\tregister_get_field(p->m_writers[5].mp_writer_data,\n+\t\t\t\t\t\t   CPY_WRITER5_DATA_MASK_POINTER);\n+\t\t\tp->m_writers[5].mp_writer_mask_ctrl =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER5_MASK_CTRL);\n+\t\t\tp->m_writers[5].mp_writer_mask_ctrl_addr =\n+\t\t\t\tregister_get_field(p->m_writers[5].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER5_MASK_CTRL_ADR);\n+\t\t\tp->m_writers[5].mp_writer_mask_ctrl_cnt =\n+\t\t\t\tregister_get_field(p->m_writers[5].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER5_MASK_CTRL_CNT);\n+\t\t\tp->m_writers[5].mp_writer_mask_data =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER5_MASK_DATA);\n+\t\t\tp->m_writers[5].mp_writer_mask_data_byte_mask =\n+\t\t\t\tregister_get_field(p->m_writers[5].mp_writer_mask_data,\n+\t\t\t\t\t\t   CPY_WRITER5_MASK_DATA_BYTE_MASK);\n+\t\t}\n+\t/* Fallthrough */\n+\tcase 5:\n+\t\tp->m_writers[4].mp_writer_ctrl =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER4_CTRL);\n+\t\tp->m_writers[4].mp_writer_ctrl_addr =\n+\t\t\tregister_get_field(p->m_writers[4].mp_writer_ctrl, CPY_WRITER4_CTRL_ADR);\n+\t\tp->m_writers[4].mp_writer_ctrl_cnt =\n+\t\t\tregister_get_field(p->m_writers[4].mp_writer_ctrl, CPY_WRITER4_CTRL_CNT);\n+\t\tp->m_writers[4].mp_writer_data =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER4_DATA);\n+\t\tp->m_writers[4].mp_writer_data_reader_select =\n+\t\t\tregister_get_field(p->m_writers[4].mp_writer_data,\n+\t\t\t\t\t   CPY_WRITER4_DATA_READER_SELECT);\n+\t\tp->m_writers[4].mp_writer_data_dyn =\n+\t\t\tregister_get_field(p->m_writers[4].mp_writer_data, CPY_WRITER4_DATA_DYN);\n+\t\tp->m_writers[4].mp_writer_data_ofs =\n+\t\t\tregister_get_field(p->m_writers[4].mp_writer_data, CPY_WRITER4_DATA_OFS);\n+\t\tp->m_writers[4].mp_writer_data_len =\n+\t\t\tregister_get_field(p->m_writers[4].mp_writer_data, CPY_WRITER4_DATA_LEN);\n+\t\tif (variant != 0) {\n+\t\t\tp->m_writers[4].mp_writer_data_mask_pointer =\n+\t\t\t\tregister_get_field(p->m_writers[4].mp_writer_data,\n+\t\t\t\t\t\t   CPY_WRITER4_DATA_MASK_POINTER);\n+\t\t\tp->m_writers[4].mp_writer_mask_ctrl =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER4_MASK_CTRL);\n+\t\t\tp->m_writers[4].mp_writer_mask_ctrl_addr =\n+\t\t\t\tregister_get_field(p->m_writers[4].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER4_MASK_CTRL_ADR);\n+\t\t\tp->m_writers[4].mp_writer_mask_ctrl_cnt =\n+\t\t\t\tregister_get_field(p->m_writers[4].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER4_MASK_CTRL_CNT);\n+\t\t\tp->m_writers[4].mp_writer_mask_data =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER4_MASK_DATA);\n+\t\t\tp->m_writers[4].mp_writer_mask_data_byte_mask =\n+\t\t\t\tregister_get_field(p->m_writers[4].mp_writer_mask_data,\n+\t\t\t\t\t\t   CPY_WRITER4_MASK_DATA_BYTE_MASK);\n+\t\t}\n+\t/* Fallthrough */\n+\tcase 4:\n+\t\tp->m_writers[3].mp_writer_ctrl =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER3_CTRL);\n+\t\tp->m_writers[3].mp_writer_ctrl_addr =\n+\t\t\tregister_get_field(p->m_writers[3].mp_writer_ctrl, CPY_WRITER3_CTRL_ADR);\n+\t\tp->m_writers[3].mp_writer_ctrl_cnt =\n+\t\t\tregister_get_field(p->m_writers[3].mp_writer_ctrl, CPY_WRITER3_CTRL_CNT);\n+\t\tp->m_writers[3].mp_writer_data =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER3_DATA);\n+\t\tp->m_writers[3].mp_writer_data_reader_select =\n+\t\t\tregister_get_field(p->m_writers[3].mp_writer_data,\n+\t\t\t\t\t   CPY_WRITER3_DATA_READER_SELECT);\n+\t\tp->m_writers[3].mp_writer_data_dyn =\n+\t\t\tregister_get_field(p->m_writers[3].mp_writer_data, CPY_WRITER3_DATA_DYN);\n+\t\tp->m_writers[3].mp_writer_data_ofs =\n+\t\t\tregister_get_field(p->m_writers[3].mp_writer_data, CPY_WRITER3_DATA_OFS);\n+\t\tp->m_writers[3].mp_writer_data_len =\n+\t\t\tregister_get_field(p->m_writers[3].mp_writer_data, CPY_WRITER3_DATA_LEN);\n+\t\tif (variant != 0) {\n+\t\t\tp->m_writers[3].mp_writer_data_mask_pointer =\n+\t\t\t\tregister_get_field(p->m_writers[3].mp_writer_data,\n+\t\t\t\t\t\t   CPY_WRITER3_DATA_MASK_POINTER);\n+\t\t\tp->m_writers[3].mp_writer_mask_ctrl =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER3_MASK_CTRL);\n+\t\t\tp->m_writers[3].mp_writer_mask_ctrl_addr =\n+\t\t\t\tregister_get_field(p->m_writers[3].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER3_MASK_CTRL_ADR);\n+\t\t\tp->m_writers[3].mp_writer_mask_ctrl_cnt =\n+\t\t\t\tregister_get_field(p->m_writers[3].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER3_MASK_CTRL_CNT);\n+\t\t\tp->m_writers[3].mp_writer_mask_data =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER3_MASK_DATA);\n+\t\t\tp->m_writers[3].mp_writer_mask_data_byte_mask =\n+\t\t\t\tregister_get_field(p->m_writers[3].mp_writer_mask_data,\n+\t\t\t\t\t\t   CPY_WRITER3_MASK_DATA_BYTE_MASK);\n+\t\t}\n+\t/* Fallthrough */\n+\tcase 3:\n+\t\tp->m_writers[2].mp_writer_ctrl =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER2_CTRL);\n+\t\tp->m_writers[2].mp_writer_ctrl_addr =\n+\t\t\tregister_get_field(p->m_writers[2].mp_writer_ctrl, CPY_WRITER2_CTRL_ADR);\n+\t\tp->m_writers[2].mp_writer_ctrl_cnt =\n+\t\t\tregister_get_field(p->m_writers[2].mp_writer_ctrl, CPY_WRITER2_CTRL_CNT);\n+\t\tp->m_writers[2].mp_writer_data =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER2_DATA);\n+\t\tp->m_writers[2].mp_writer_data_reader_select =\n+\t\t\tregister_get_field(p->m_writers[2].mp_writer_data,\n+\t\t\t\t\t   CPY_WRITER2_DATA_READER_SELECT);\n+\t\tp->m_writers[2].mp_writer_data_dyn =\n+\t\t\tregister_get_field(p->m_writers[2].mp_writer_data, CPY_WRITER2_DATA_DYN);\n+\t\tp->m_writers[2].mp_writer_data_ofs =\n+\t\t\tregister_get_field(p->m_writers[2].mp_writer_data, CPY_WRITER2_DATA_OFS);\n+\t\tp->m_writers[2].mp_writer_data_len =\n+\t\t\tregister_get_field(p->m_writers[2].mp_writer_data, CPY_WRITER2_DATA_LEN);\n+\t\tif (variant != 0) {\n+\t\t\tp->m_writers[2].mp_writer_data_mask_pointer =\n+\t\t\t\tregister_get_field(p->m_writers[2].mp_writer_data,\n+\t\t\t\t\t\t   CPY_WRITER2_DATA_MASK_POINTER);\n+\t\t\tp->m_writers[2].mp_writer_mask_ctrl =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER2_MASK_CTRL);\n+\t\t\tp->m_writers[2].mp_writer_mask_ctrl_addr =\n+\t\t\t\tregister_get_field(p->m_writers[2].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER2_MASK_CTRL_ADR);\n+\t\t\tp->m_writers[2].mp_writer_mask_ctrl_cnt =\n+\t\t\t\tregister_get_field(p->m_writers[2].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER2_MASK_CTRL_CNT);\n+\t\t\tp->m_writers[2].mp_writer_mask_data =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER2_MASK_DATA);\n+\t\t\tp->m_writers[2].mp_writer_mask_data_byte_mask =\n+\t\t\t\tregister_get_field(p->m_writers[2].mp_writer_mask_data,\n+\t\t\t\t\t\t   CPY_WRITER2_MASK_DATA_BYTE_MASK);\n+\t\t}\n+\t/* Fallthrough */\n+\tcase 2:\n+\t\tp->m_writers[1].mp_writer_ctrl =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER1_CTRL);\n+\t\tp->m_writers[1].mp_writer_ctrl_addr =\n+\t\t\tregister_get_field(p->m_writers[1].mp_writer_ctrl, CPY_WRITER1_CTRL_ADR);\n+\t\tp->m_writers[1].mp_writer_ctrl_cnt =\n+\t\t\tregister_get_field(p->m_writers[1].mp_writer_ctrl, CPY_WRITER1_CTRL_CNT);\n+\t\tp->m_writers[1].mp_writer_data =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER1_DATA);\n+\t\tp->m_writers[1].mp_writer_data_reader_select =\n+\t\t\tregister_get_field(p->m_writers[1].mp_writer_data,\n+\t\t\t\t\t   CPY_WRITER1_DATA_READER_SELECT);\n+\t\tp->m_writers[1].mp_writer_data_dyn =\n+\t\t\tregister_get_field(p->m_writers[1].mp_writer_data, CPY_WRITER1_DATA_DYN);\n+\t\tp->m_writers[1].mp_writer_data_ofs =\n+\t\t\tregister_get_field(p->m_writers[1].mp_writer_data, CPY_WRITER1_DATA_OFS);\n+\t\tp->m_writers[1].mp_writer_data_len =\n+\t\t\tregister_get_field(p->m_writers[1].mp_writer_data, CPY_WRITER1_DATA_LEN);\n+\t\tif (variant != 0) {\n+\t\t\tp->m_writers[1].mp_writer_data_mask_pointer =\n+\t\t\t\tregister_get_field(p->m_writers[1].mp_writer_data,\n+\t\t\t\t\t\t   CPY_WRITER1_DATA_MASK_POINTER);\n+\t\t\tp->m_writers[1].mp_writer_mask_ctrl =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER1_MASK_CTRL);\n+\t\t\tp->m_writers[1].mp_writer_mask_ctrl_addr =\n+\t\t\t\tregister_get_field(p->m_writers[1].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER1_MASK_CTRL_ADR);\n+\t\t\tp->m_writers[1].mp_writer_mask_ctrl_cnt =\n+\t\t\t\tregister_get_field(p->m_writers[1].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER1_MASK_CTRL_CNT);\n+\t\t\tp->m_writers[1].mp_writer_mask_data =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER1_MASK_DATA);\n+\t\t\tp->m_writers[1].mp_writer_mask_data_byte_mask =\n+\t\t\t\tregister_get_field(p->m_writers[1].mp_writer_mask_data,\n+\t\t\t\t\t\t   CPY_WRITER1_MASK_DATA_BYTE_MASK);\n+\t\t}\n+\t/* Fallthrough */\n+\tcase 1:\n+\t\tp->m_writers[0].mp_writer_ctrl =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER0_CTRL);\n+\t\tp->m_writers[0].mp_writer_ctrl_addr =\n+\t\t\tregister_get_field(p->m_writers[0].mp_writer_ctrl, CPY_WRITER0_CTRL_ADR);\n+\t\tp->m_writers[0].mp_writer_ctrl_cnt =\n+\t\t\tregister_get_field(p->m_writers[0].mp_writer_ctrl, CPY_WRITER0_CTRL_CNT);\n+\t\tp->m_writers[0].mp_writer_data =\n+\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER0_DATA);\n+\t\tp->m_writers[0].mp_writer_data_reader_select =\n+\t\t\tregister_get_field(p->m_writers[0].mp_writer_data,\n+\t\t\t\t\t   CPY_WRITER0_DATA_READER_SELECT);\n+\t\tp->m_writers[0].mp_writer_data_dyn =\n+\t\t\tregister_get_field(p->m_writers[0].mp_writer_data, CPY_WRITER0_DATA_DYN);\n+\t\tp->m_writers[0].mp_writer_data_ofs =\n+\t\t\tregister_get_field(p->m_writers[0].mp_writer_data, CPY_WRITER0_DATA_OFS);\n+\t\tp->m_writers[0].mp_writer_data_len =\n+\t\t\tregister_get_field(p->m_writers[0].mp_writer_data, CPY_WRITER0_DATA_LEN);\n+\t\tif (variant != 0) {\n+\t\t\tp->m_writers[0].mp_writer_data_mask_pointer =\n+\t\t\t\tregister_get_field(p->m_writers[0].mp_writer_data,\n+\t\t\t\t\t\t   CPY_WRITER0_DATA_MASK_POINTER);\n+\t\t\tp->m_writers[0].mp_writer_mask_ctrl =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER0_MASK_CTRL);\n+\t\t\tp->m_writers[0].mp_writer_mask_ctrl_addr =\n+\t\t\t register_get_field(p->m_writers[0].mp_writer_mask_ctrl,\n+\t\t\t\t\t    CPY_WRITER0_MASK_CTRL_ADR);\n+\t\t\tp->m_writers[0].mp_writer_mask_ctrl_cnt =\n+\t\t\t\tregister_get_field(p->m_writers[0].mp_writer_mask_ctrl,\n+\t\t\t\t\t\t   CPY_WRITER0_MASK_CTRL_CNT);\n+\t\t\tp->m_writers[0].mp_writer_mask_data =\n+\t\t\t\tmodule_get_register(p->m_tx_cpy, CPY_WRITER0_MASK_DATA);\n+\t\t\tp->m_writers[0].mp_writer_mask_data_byte_mask =\n+\t\t\t\tregister_get_field(p->m_writers[0].mp_writer_mask_data,\n+\t\t\t\t\t\t   CPY_WRITER0_MASK_DATA_BYTE_MASK);\n+\t\t}\n+\t\tbreak;\n+\tcase 0:\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void tx_cpy_nthw_writer_select(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t    uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tfield_set_val32(p->m_writers[index].mp_writer_ctrl_addr, val);\n+}\n+\n+void tx_cpy_nthw_writer_cnt(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tfield_set_val32(p->m_writers[index].mp_writer_ctrl_cnt, val);\n+}\n+\n+void tx_cpy_nthw_writer_reader_select(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t\t  uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tfield_set_val32(p->m_writers[index].mp_writer_data_reader_select, val);\n+}\n+\n+void tx_cpy_nthw_writer_dyn(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tfield_set_val32(p->m_writers[index].mp_writer_data_dyn, val);\n+}\n+\n+void tx_cpy_nthw_writer_ofs(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tfield_set_val32(p->m_writers[index].mp_writer_data_ofs, val);\n+}\n+\n+void tx_cpy_nthw_writer_len(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tfield_set_val32(p->m_writers[index].mp_writer_data_len, val);\n+}\n+\n+void tx_cpy_nthw_writer_mask_pointer(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t\t uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tassert(p->m_writers[index].mp_writer_data_mask_pointer);\n+\tfield_set_val32(p->m_writers[index].mp_writer_data_mask_pointer, val);\n+}\n+\n+void tx_cpy_nthw_writer_flush(const struct tx_cpy_nthw *p, unsigned int index)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tregister_flush(p->m_writers[index].mp_writer_ctrl, 1);\n+\tregister_flush(p->m_writers[index].mp_writer_data, 1);\n+}\n+\n+void tx_cpy_nthw_writer_mask_select(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t\tuint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tassert(p->m_writers[index].mp_writer_mask_ctrl_addr);\n+\tfield_set_val32(p->m_writers[index].mp_writer_mask_ctrl_addr, val);\n+}\n+\n+void tx_cpy_nthw_writer_mask_cnt(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t     uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tassert(p->m_writers[index].mp_writer_mask_ctrl_cnt);\n+\tfield_set_val32(p->m_writers[index].mp_writer_mask_ctrl_cnt, val);\n+}\n+\n+void tx_cpy_nthw_writer_mask(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t  uint32_t val)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tassert(p->m_writers[index].mp_writer_mask_data_byte_mask);\n+\tfield_set_val32(p->m_writers[index].mp_writer_mask_data_byte_mask, val);\n+}\n+\n+void tx_cpy_nthw_writer_mask_flush(const struct tx_cpy_nthw *p, unsigned int index)\n+{\n+\tassert(index < p->m_writers_cnt);\n+\tassert(p->m_writers[index].mp_writer_mask_ctrl);\n+\tassert(p->m_writers[index].mp_writer_mask_data);\n+\tregister_flush(p->m_writers[index].mp_writer_mask_ctrl, 1);\n+\tregister_flush(p->m_writers[index].mp_writer_mask_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_cpy.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_cpy.h\nnew file mode 100644\nindex 0000000000..f97983b29a\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_cpy.h\n@@ -0,0 +1,72 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_TX_CPY_H__\n+#define __FLOW_NTHW_TX_CPY_H__\n+\n+#include <stdint.h>\n+#include \"nthw_fpga_model.h\"\n+\n+struct tx_cpy_writers_s {\n+\tnt_register_t *mp_writer_ctrl;\n+\tnt_field_t *mp_writer_ctrl_addr;\n+\tnt_field_t *mp_writer_ctrl_cnt;\n+\n+\tnt_register_t *mp_writer_data;\n+\tnt_field_t *mp_writer_data_reader_select;\n+\tnt_field_t *mp_writer_data_dyn;\n+\tnt_field_t *mp_writer_data_ofs;\n+\tnt_field_t *mp_writer_data_len;\n+\tnt_field_t *mp_writer_data_mask_pointer;\n+\n+\tnt_register_t *mp_writer_mask_ctrl;\n+\tnt_field_t *mp_writer_mask_ctrl_addr;\n+\tnt_field_t *mp_writer_mask_ctrl_cnt;\n+\n+\tnt_register_t *mp_writer_mask_data;\n+\tnt_field_t *mp_writer_mask_data_byte_mask;\n+};\n+\n+struct tx_cpy_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_tx_cpy;\n+\n+\tunsigned int m_writers_cnt;\n+\tstruct tx_cpy_writers_s *m_writers;\n+};\n+\n+struct tx_cpy_nthw *tx_cpy_nthw_new(void);\n+void tx_cpy_nthw_delete(struct tx_cpy_nthw *p);\n+int tx_cpy_nthw_init(struct tx_cpy_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int tx_cpy_nthw_setup(struct tx_cpy_nthw *p, int n_idx, int n_idx_cnt);\n+void tx_cpy_nthw_set_debug_mode(struct tx_cpy_nthw *p, unsigned int n_debug_mode);\n+\n+void tx_cpy_nthw_writer_select(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t    uint32_t val);\n+void tx_cpy_nthw_writer_cnt(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t uint32_t val);\n+void tx_cpy_nthw_writer_reader_select(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t\t  uint32_t val);\n+void tx_cpy_nthw_writer_dyn(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t uint32_t val);\n+void tx_cpy_nthw_writer_ofs(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t uint32_t val);\n+void tx_cpy_nthw_writer_len(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t uint32_t val);\n+void tx_cpy_nthw_writer_mask_pointer(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t\t uint32_t val);\n+void tx_cpy_nthw_writer_flush(const struct tx_cpy_nthw *p, unsigned int index);\n+\n+void tx_cpy_nthw_writer_mask_select(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t\tuint32_t val);\n+void tx_cpy_nthw_writer_mask_cnt(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t     uint32_t val);\n+void tx_cpy_nthw_writer_mask(const struct tx_cpy_nthw *p, unsigned int index,\n+\t\t\t  uint32_t val);\n+void tx_cpy_nthw_writer_mask_flush(const struct tx_cpy_nthw *p, unsigned int index);\n+\n+#endif /* __FLOW_NTHW_TX_CPY_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_ins.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_ins.c\nnew file mode 100644\nindex 0000000000..998c3613ee\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_ins.c\n@@ -0,0 +1,96 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_tx_ins.h\"\n+\n+#include <stdlib.h>\n+#include <string.h>\n+\n+void tx_ins_nthw_set_debug_mode(struct tx_ins_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_tx_ins, n_debug_mode);\n+}\n+\n+struct tx_ins_nthw *tx_ins_nthw_new(void)\n+{\n+\tstruct tx_ins_nthw *p = malloc(sizeof(struct tx_ins_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\treturn p;\n+}\n+\n+void tx_ins_nthw_delete(struct tx_ins_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int tx_ins_nthw_init(struct tx_ins_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_TX_INS, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: TxIns %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_tx_ins = fpga_query_module(p_fpga, MOD_TX_INS, n_instance);\n+\n+\tp->mp_rcp_ctrl = module_get_register(p->m_tx_ins, INS_RCP_CTRL);\n+\tp->mp_rcp_addr = register_get_field(p->mp_rcp_ctrl, INS_RCP_CTRL_ADR);\n+\tp->mp_rcp_cnt = register_get_field(p->mp_rcp_ctrl, INS_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_tx_ins, INS_RCP_DATA);\n+\tp->mp_rcp_data_dyn = register_get_field(p->mp_rcp_data, INS_RCP_DATA_DYN);\n+\tp->mp_rcp_data_ofs = register_get_field(p->mp_rcp_data, INS_RCP_DATA_OFS);\n+\tp->mp_rcp_data_len = register_get_field(p->mp_rcp_data, INS_RCP_DATA_LEN);\n+\n+\treturn 0;\n+}\n+\n+void tx_ins_nthw_rcp_select(const struct tx_ins_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_addr, val);\n+}\n+\n+void tx_ins_nthw_rcp_cnt(const struct tx_ins_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_cnt, val);\n+}\n+\n+void tx_ins_nthw_rcp_dyn(const struct tx_ins_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_dyn, val);\n+}\n+\n+void tx_ins_nthw_rcp_ofs(const struct tx_ins_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ofs, val);\n+}\n+\n+void tx_ins_nthw_rcp_len(const struct tx_ins_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len, val);\n+}\n+\n+void tx_ins_nthw_rcp_flush(const struct tx_ins_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_ins.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_ins.h\nnew file mode 100644\nindex 0000000000..813bd30c62\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_ins.h\n@@ -0,0 +1,42 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_TX_INS_H__\n+#define __FLOW_NTHW_TX_INS_H__\n+\n+#include <stdint.h>\n+#include \"nthw_fpga_model.h\"\n+\n+struct tx_ins_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_tx_ins;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_addr;\n+\tnt_field_t *mp_rcp_cnt;\n+\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_dyn;\n+\tnt_field_t *mp_rcp_data_ofs;\n+\tnt_field_t *mp_rcp_data_len;\n+};\n+\n+struct tx_ins_nthw *tx_ins_nthw_new(void);\n+void tx_ins_nthw_delete(struct tx_ins_nthw *p);\n+int tx_ins_nthw_init(struct tx_ins_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int tx_ins_nthw_setup(struct tx_ins_nthw *p, int n_idx, int n_idx_cnt);\n+void tx_ins_nthw_set_debug_mode(struct tx_ins_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void tx_ins_nthw_rcp_select(const struct tx_ins_nthw *p, uint32_t val);\n+void tx_ins_nthw_rcp_cnt(const struct tx_ins_nthw *p, uint32_t val);\n+void tx_ins_nthw_rcp_dyn(const struct tx_ins_nthw *p, uint32_t val);\n+void tx_ins_nthw_rcp_ofs(const struct tx_ins_nthw *p, uint32_t val);\n+void tx_ins_nthw_rcp_len(const struct tx_ins_nthw *p, uint32_t val);\n+void tx_ins_nthw_rcp_flush(const struct tx_ins_nthw *p);\n+\n+#endif /* __FLOW_NTHW_TX_INS_H__ */\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_rpl.c b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_rpl.c\nnew file mode 100644\nindex 0000000000..5e7e26f74d\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_rpl.c\n@@ -0,0 +1,165 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#include \"ntlog.h\"\n+#include \"nthw_drv.h\"\n+#include \"nthw_register.h\"\n+\n+#include \"flow_nthw_tx_rpl.h\"\n+\n+#include <stdlib.h>\n+#include <string.h>\n+\n+void tx_rpl_nthw_set_debug_mode(struct tx_rpl_nthw *p, unsigned int n_debug_mode)\n+{\n+\tmodule_set_debug_mode(p->m_tx_rpl, n_debug_mode);\n+}\n+\n+struct tx_rpl_nthw *tx_rpl_nthw_new(void)\n+{\n+\tstruct tx_rpl_nthw *p = malloc(sizeof(struct tx_rpl_nthw));\n+\n+\tif (p)\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\treturn p;\n+}\n+\n+void tx_rpl_nthw_delete(struct tx_rpl_nthw *p)\n+{\n+\tif (p) {\n+\t\t(void)memset(p, 0, sizeof(*p));\n+\t\tfree(p);\n+\t}\n+}\n+\n+int tx_rpl_nthw_init(struct tx_rpl_nthw *p, nt_fpga_t *p_fpga, int n_instance)\n+{\n+\tconst char *const p_adapter_id_str = p_fpga->p_fpga_info->mp_adapter_id_str;\n+\tnt_module_t *p_mod = fpga_query_module(p_fpga, MOD_TX_RPL, n_instance);\n+\n+\tassert(n_instance >= 0 && n_instance < 256);\n+\n+\tif (p == NULL)\n+\t\treturn p_mod == NULL ? -1 : 0;\n+\n+\tif (p_mod == NULL) {\n+\t\tNT_LOG(ERR, NTHW, \"%s: TxRpl %d: no such instance\\n\",\n+\t\t       p_adapter_id_str, n_instance);\n+\t\treturn -1;\n+\t}\n+\n+\tp->mp_fpga = p_fpga;\n+\tp->m_physical_adapter_no = (uint8_t)n_instance;\n+\tp->m_tx_rpl = fpga_query_module(p_fpga, MOD_TX_RPL, n_instance);\n+\n+\tp->mp_rcp_ctrl = module_get_register(p->m_tx_rpl, RPL_RCP_CTRL);\n+\tp->mp_rcp_ctrl_addr = register_get_field(p->mp_rcp_ctrl, RPL_RCP_CTRL_ADR);\n+\tp->mp_rcp_ctrl_cnt = register_get_field(p->mp_rcp_ctrl, RPL_RCP_CTRL_CNT);\n+\tp->mp_rcp_data = module_get_register(p->m_tx_rpl, RPL_RCP_DATA);\n+\tp->mp_rcp_data_dyn = register_get_field(p->mp_rcp_data, RPL_RCP_DATA_DYN);\n+\tp->mp_rcp_data_ofs = register_get_field(p->mp_rcp_data, RPL_RCP_DATA_OFS);\n+\tp->mp_rcp_data_len = register_get_field(p->mp_rcp_data, RPL_RCP_DATA_LEN);\n+\tp->mp_rcp_data_rpl_ptr =\n+\t\tregister_get_field(p->mp_rcp_data, RPL_RCP_DATA_RPL_PTR);\n+\tp->mp_rcp_data_ext_prio =\n+\t\tregister_get_field(p->mp_rcp_data, RPL_RCP_DATA_EXT_PRIO);\n+\n+\tp->mp_ext_ctrl = module_get_register(p->m_tx_rpl, RPL_EXT_CTRL);\n+\tp->mp_ext_ctrl_addr = register_get_field(p->mp_ext_ctrl, RPL_EXT_CTRL_ADR);\n+\tp->mp_ext_ctrl_cnt = register_get_field(p->mp_ext_ctrl, RPL_EXT_CTRL_CNT);\n+\tp->mp_ext_data = module_get_register(p->m_tx_rpl, RPL_EXT_DATA);\n+\tp->mp_ext_data_rpl_ptr =\n+\t\tregister_get_field(p->mp_ext_data, RPL_EXT_DATA_RPL_PTR);\n+\n+\tp->mp_rpl_ctrl = module_get_register(p->m_tx_rpl, RPL_RPL_CTRL);\n+\tp->mp_rpl_ctrl_addr = register_get_field(p->mp_rpl_ctrl, RPL_RPL_CTRL_ADR);\n+\tp->mp_rpl_ctrl_cnt = register_get_field(p->mp_rpl_ctrl, RPL_RPL_CTRL_CNT);\n+\tp->mp_rpl_data = module_get_register(p->m_tx_rpl, RPL_RPL_DATA);\n+\tp->mp_rpl_data_value = register_get_field(p->mp_rpl_data, RPL_RPL_DATA_VALUE);\n+\n+\treturn 0;\n+}\n+\n+void tx_rpl_nthw_rcp_select(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_ctrl_addr, val);\n+}\n+\n+void tx_rpl_nthw_rcp_cnt(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_ctrl_cnt, val);\n+}\n+\n+void tx_rpl_nthw_rcp_dyn(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_dyn, val);\n+}\n+\n+void tx_rpl_nthw_rcp_ofs(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ofs, val);\n+}\n+\n+void tx_rpl_nthw_rcp_len(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_len, val);\n+}\n+\n+void tx_rpl_nthw_rcp_rpl_ptr(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_rpl_ptr, val);\n+}\n+\n+void tx_rpl_nthw_rcp_ext_prio(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rcp_data_ext_prio, val);\n+}\n+\n+void tx_rpl_nthw_rcp_flush(const struct tx_rpl_nthw *p)\n+{\n+\tregister_flush(p->mp_rcp_ctrl, 1);\n+\tregister_flush(p->mp_rcp_data, 1);\n+}\n+\n+void tx_rpl_nthw_ext_select(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_ext_ctrl_addr, val);\n+}\n+\n+void tx_rpl_nthw_ext_cnt(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_ext_ctrl_cnt, val);\n+}\n+\n+void tx_rpl_nthw_ext_rpl_ptr(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_ext_data_rpl_ptr, val);\n+}\n+\n+void tx_rpl_nthw_ext_flush(const struct tx_rpl_nthw *p)\n+{\n+\tregister_flush(p->mp_ext_ctrl, 1);\n+\tregister_flush(p->mp_ext_data, 1);\n+}\n+\n+void tx_rpl_nthw_rpl_select(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rpl_ctrl_addr, val);\n+}\n+\n+void tx_rpl_nthw_rpl_cnt(const struct tx_rpl_nthw *p, uint32_t val)\n+{\n+\tfield_set_val32(p->mp_rpl_ctrl_cnt, val);\n+}\n+\n+void tx_rpl_nthw_rpl_value(const struct tx_rpl_nthw *p, const uint32_t *val)\n+{\n+\tfield_set_val(p->mp_rpl_data_value, val, 4);\n+}\n+\n+void tx_rpl_nthw_rpl_flush(const struct tx_rpl_nthw *p)\n+{\n+\tregister_flush(p->mp_rpl_ctrl, 1);\n+\tregister_flush(p->mp_rpl_data, 1);\n+}\ndiff --git a/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_rpl.h b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_rpl.h\nnew file mode 100644\nindex 0000000000..e5f724361b\n--- /dev/null\n+++ b/drivers/net/ntnic/nthw/flow_filter/flow_nthw_tx_rpl.h\n@@ -0,0 +1,70 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Napatech A/S\n+ */\n+\n+#ifndef __FLOW_NTHW_TX_RPL_H__\n+#define __FLOW_NTHW_TX_RPL_H__\n+\n+#include <stdint.h>\n+#include \"nthw_fpga_model.h\"\n+\n+struct tx_rpl_nthw {\n+\tuint8_t m_physical_adapter_no;\n+\tnt_fpga_t *mp_fpga;\n+\n+\tnt_module_t *m_tx_rpl;\n+\n+\tnt_register_t *mp_rcp_ctrl;\n+\tnt_field_t *mp_rcp_ctrl_addr;\n+\tnt_field_t *mp_rcp_ctrl_cnt;\n+\n+\tnt_register_t *mp_rcp_data;\n+\tnt_field_t *mp_rcp_data_dyn;\n+\tnt_field_t *mp_rcp_data_ofs;\n+\tnt_field_t *mp_rcp_data_len;\n+\tnt_field_t *mp_rcp_data_rpl_ptr;\n+\tnt_field_t *mp_rcp_data_ext_prio;\n+\n+\tnt_register_t *mp_ext_ctrl;\n+\tnt_field_t *mp_ext_ctrl_addr;\n+\tnt_field_t *mp_ext_ctrl_cnt;\n+\n+\tnt_register_t *mp_ext_data;\n+\tnt_field_t *mp_ext_data_rpl_ptr;\n+\n+\tnt_register_t *mp_rpl_ctrl;\n+\tnt_field_t *mp_rpl_ctrl_addr;\n+\tnt_field_t *mp_rpl_ctrl_cnt;\n+\n+\tnt_register_t *mp_rpl_data;\n+\tnt_field_t *mp_rpl_data_value;\n+};\n+\n+struct tx_rpl_nthw *tx_rpl_nthw_new(void);\n+void tx_rpl_nthw_delete(struct tx_rpl_nthw *p);\n+int tx_rpl_nthw_init(struct tx_rpl_nthw *p, nt_fpga_t *p_fpga, int n_instance);\n+\n+int tx_rpl_nthw_setup(struct tx_rpl_nthw *p, int n_idx, int n_idx_cnt);\n+void tx_rpl_nthw_set_debug_mode(struct tx_rpl_nthw *p, unsigned int n_debug_mode);\n+\n+/* RCP */\n+void tx_rpl_nthw_rcp_select(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rcp_cnt(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rcp_dyn(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rcp_ofs(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rcp_len(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rcp_rpl_ptr(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rcp_ext_prio(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rcp_flush(const struct tx_rpl_nthw *p);\n+\n+void tx_rpl_nthw_ext_select(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_ext_cnt(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_ext_rpl_ptr(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_ext_flush(const struct tx_rpl_nthw *p);\n+\n+void tx_rpl_nthw_rpl_select(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rpl_cnt(const struct tx_rpl_nthw *p, uint32_t val);\n+void tx_rpl_nthw_rpl_value(const struct tx_rpl_nthw *p, const uint32_t *val);\n+void tx_rpl_nthw_rpl_flush(const struct tx_rpl_nthw *p);\n+\n+#endif /* __FLOW_NTHW_TX_RPL_H__ */\n",
    "prefixes": [
        "4/8"
    ]
}