get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 63743,
    "url": "http://patches.dpdk.org/api/patches/63743/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1576057875-7677-4-git-send-email-xiaojun.liu@silicom.co.il/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1576057875-7677-4-git-send-email-xiaojun.liu@silicom.co.il>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1576057875-7677-4-git-send-email-xiaojun.liu@silicom.co.il",
    "date": "2019-12-11T09:52:07",
    "name": "[v2,3/7] net/fm10k: add config ffu statistics support",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "ae002508064850e9d8c95e37d5233a5dab206236",
    "submitter": {
        "id": 1512,
        "url": "http://patches.dpdk.org/api/people/1512/?format=api",
        "name": "Xiaojun Liu",
        "email": "xiaojun.liu@silicom.co.il"
    },
    "delegate": {
        "id": 31221,
        "url": "http://patches.dpdk.org/api/users/31221/?format=api",
        "username": "yexl",
        "first_name": "xiaolong",
        "last_name": "ye",
        "email": "xiaolong.ye@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1576057875-7677-4-git-send-email-xiaojun.liu@silicom.co.il/mbox/",
    "series": [
        {
            "id": 7788,
            "url": "http://patches.dpdk.org/api/series/7788/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=7788",
            "date": "2019-12-11T09:51:58",
            "name": "support switch management",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/7788/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/63743/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/63743/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B521DA04F1;\n\tWed, 11 Dec 2019 10:52:29 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id EAF011BF70;\n\tWed, 11 Dec 2019 10:52:11 +0100 (CET)",
            "from EUR01-VE1-obe.outbound.protection.outlook.com\n (mail-eopbgr140117.outbound.protection.outlook.com [40.107.14.117])\n by dpdk.org (Postfix) with ESMTP id 8365B1BEC4\n for <dev@dpdk.org>; Wed, 11 Dec 2019 10:52:10 +0100 (CET)",
            "from DB7PR04MB5196.eurprd04.prod.outlook.com (20.176.234.140) by\n DB7PR04MB4203.eurprd04.prod.outlook.com (52.135.131.12) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n 15.20.2538.14; Wed, 11 Dec 2019 09:52:07 +0000",
            "from DB7PR04MB5196.eurprd04.prod.outlook.com\n ([fe80::cdaa:fcae:322b:59ed]) by DB7PR04MB5196.eurprd04.prod.outlook.com\n ([fe80::cdaa:fcae:322b:59ed%7]) with mapi id 15.20.2516.018; Wed, 11 Dec 2019\n 09:52:07 +0000"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=bodpxItW5JGbEu1/2SDYdjWTDnmTmMd86BTr4JHqX/Oo1zQoi5ydpnCfr5Tr/+Xd537xHaZ5Gzqd3WB21JhDJZnZS+EB+tRUNNrt/HoP7nT4vrTe4i83cgufQoPCxb3OTA/0UWgjSGZgZpTInOCkQ89bcC/9r5k35zLR+7vstau/e3xL5lco3lWDd+W/GrJ3T5UMV/rA7gEhoCoDCmWSB+/dZwLuUujo41b397BGWsFMsWQBVdDxyWVhc7NfJqMn+tESEtFrz4jN43TNmyib+5/ElKl3LyQAsDPRW3jlcIEpu3x2arBWXJB0+sf83J7yDc/M/j284FC+2hyhvunqaA==",
        "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-SenderADCheck;\n bh=yezLZgyHsPMTDaJ02G9zAKRsXC3FWC7CrpBT7riDHqc=;\n b=PifOFd1HxzH8jTck4Y89ufG5yauEpSFITzVlozxMLKSCrTWPw7THii6FhjtHakQfIIwKbc0X5ruS19Xdzp9WcbOWN8q+qjh6IVQy9+CC2MG2IhTAMQKVAfFxRqMv/NBDqiylF/YeuyP8E5ANbNxdP36w8k75QafRKsss2kGumHOrgAP+wFUxcHy7mP1EP7DBdjZAassbklVfsvtEGxdchN4LxWS11DWtyB8IEhmmy0+XYHbZ0WdHdbrm6GXsp+nd7Z+cEeB0EHRVe81zERpqPfbhRlp9L8yVcpHq+2CEd3IqU4fvXswu371jH5ZE705jWIGfQU5032EYY2/c2/idGw==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=silicom.co.il; dmarc=pass action=none\n header.from=silicom.co.il; dkim=pass header.d=silicom.co.il; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=SILICOMLTD.onmicrosoft.com; s=selector2-SILICOMLTD-onmicrosoft-com;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=yezLZgyHsPMTDaJ02G9zAKRsXC3FWC7CrpBT7riDHqc=;\n b=wgzegaDH0xgDFTTnGp82G56hRmSUrszj6wLgx/WNeeSZH4XV+wl52FcLho//2s9y+NrOj9B+4ByJ4DU0EIqcyCKWtykDM2rZImdw5lq7Zw44uIg3B+/5pasaoiCQInDh6vR3ZOSu9uvW6cTYaBwUH0YJ8QkGVsp1e29RMliVPJc=",
        "From": "Xiaojun Liu <xiaojun.liu@silicom.co.il>",
        "To": "\"xiao.w.wang@intel.com\" <xiao.w.wang@intel.com>, \"qi.z.zhang@intel.com\"\n <qi.z.zhang@intel.com>, \"ngai-mint.kwan@intel.com\"\n <ngai-mint.kwan@intel.com>, \"jakub.fornal@intel.co\" <jakub.fornal@intel.co>,\n \"jacob.e.keller@intel.com\" <jacob.e.keller@intel.com>",
        "CC": "\"dev@dpdk.org\" <dev@dpdk.org>, Xiaojun Liu <xiaojun.liu@silicom.co.il>",
        "Thread-Topic": "[PATCH v2 3/7] net/fm10k: add config ffu statistics support",
        "Thread-Index": "AQHVsAimuLj90oPUBUmPd2ppt77Zzw==",
        "Date": "Wed, 11 Dec 2019 09:52:07 +0000",
        "Message-ID": "<1576057875-7677-4-git-send-email-xiaojun.liu@silicom.co.il>",
        "References": "<xiaojun.liu@silicom.co.il>\n <1576057875-7677-1-git-send-email-xiaojun.liu@silicom.co.il>",
        "In-Reply-To": "<1576057875-7677-1-git-send-email-xiaojun.liu@silicom.co.il>",
        "Accept-Language": "en-US",
        "Content-Language": "en-US",
        "X-MS-Has-Attach": "",
        "X-MS-TNEF-Correlator": "",
        "x-clientproxiedby": "HK2PR02CA0180.apcprd02.prod.outlook.com\n (2603:1096:201:21::16) To DB7PR04MB5196.eurprd04.prod.outlook.com\n (2603:10a6:10:1a::12)",
        "authentication-results": "spf=none (sender IP is )\n smtp.mailfrom=xiaojun.liu@silicom.co.il;",
        "x-ms-exchange-messagesentrepresentingtype": "1",
        "x-mailer": "git-send-email 1.8.3.1",
        "x-originating-ip": "[113.110.226.253]",
        "x-ms-publictraffictype": "Email",
        "x-ms-office365-filtering-correlation-id": "499b82db-da7e-449f-5338-08d77e1fc8c7",
        "x-ms-traffictypediagnostic": "DB7PR04MB4203:",
        "x-ms-exchange-transport-forked": "True",
        "x-microsoft-antispam-prvs": "\n <DB7PR04MB42039DFF421BF37EA8A3878EBD5A0@DB7PR04MB4203.eurprd04.prod.outlook.com>",
        "x-ms-oob-tlc-oobclassifiers": "OLM:113;",
        "x-forefront-prvs": "024847EE92",
        "x-forefront-antispam-report": "SFV:NSPM;\n SFS:(10019020)(346002)(366004)(136003)(39850400004)(376002)(396003)(199004)(189003)(51234002)(2906002)(71200400001)(81156014)(64756008)(316002)(66556008)(6506007)(44832011)(8676002)(52116002)(81166006)(26005)(66476007)(54906003)(110136005)(66946007)(186003)(36756003)(30864003)(6512007)(4326008)(86362001)(2616005)(107886003)(6486002)(66446008)(8936002)(5660300002)(478600001)(579004)(569006);\n DIR:OUT; SFP:1102; SCL:1; SRVR:DB7PR04MB4203;\n H:DB7PR04MB5196.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en;\n PTR:InfoNoRecords; A:1; MX:1;",
        "received-spf": "None (protection.outlook.com: silicom.co.il does not designate\n permitted sender hosts)",
        "x-ms-exchange-senderadcheck": "1",
        "x-microsoft-antispam": "BCL:0;",
        "x-microsoft-antispam-message-info": "\n 5D2Se+r5Khhx4T30qe9tbnqehMYR+DDLpCLyu4q5i8SV+QHoMl8bC0H/vlZ+9EaJlo2Tf6IRNAKJM5URWu/LskkK0ndF4Se1WwZoBFwULY8MAhP8hSAbowc8jwpgzZ2XG7d1o2eYLlM6mATfyR8aPJaXqI4W29LeIQzsqy3qJzHHtez8uZeffeC/dzeueqbxM9FJUJFETNSfytI1VsGT5V3KsyUdaXQI48W2C8HQP/oreeEXlC4ad6RsyyS8dN9jcV8N5cM2v2Sg1N6WN8MM0kkDixMoMMlUork8jM/yVewfNgWqsSQOsDGuE+NpkBz6abVPfpIjoxU7SqrL94xxpitILsqNB461yQqhCMf+MKlfBYB2Bf4DywNemaSCaEqPnPO36FCi5GtDeCs10eUlIaZC0QoAi9Opedi682segLIwKL8We5C3XuIORrfzqfqA0GJpI/gquRi5iSpmkTfNOfqLquROfMVpofy4rdgayT6quzD4Crn9YoluNnIybx0PtkN6KF5PCJcqGWl7S1ZEjQ==",
        "Content-Type": "text/plain; charset=\"iso-8859-1\"",
        "Content-Transfer-Encoding": "quoted-printable",
        "MIME-Version": "1.0",
        "X-OriginatorOrg": "silicom.co.il",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 499b82db-da7e-449f-5338-08d77e1fc8c7",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "11 Dec 2019 09:52:07.5715 (UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "c9e326d8-ce47-4930-8612-cc99d3c87ad1",
        "X-MS-Exchange-CrossTenant-mailboxtype": "HOSTED",
        "X-MS-Exchange-CrossTenant-userprincipalname": "\n OtMqw7L6dx0ylgcbvTE2DmCmaaVvweY5oFxkE7iL7jjBOWyMYz8Z3aarfcVRbrkj6Y/uVpgAvj4RDnkvGUfYtrSWJKE5VuIgw81Htj/pwiU=",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DB7PR04MB4203",
        "Subject": "[dpdk-dev] [PATCH v2 3/7] net/fm10k: add config ffu statistics\n\tsupport",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "To support switch management, add the following new files:\nAdd fm10k/switch/fm10k_config.h.\nAdd fm10k/switch/fm10k_config.c(support switch configuration)\nAdd fm10k/switch/fm10k_ffu.h\nAdd fm10k/switch/fm10k_ffu.c(support switch ffu rule)\nAdd fm10k/switch/fm10k_stats.h\nAdd fm10k/switch/fm10k_stats.c(support switch statistics)\nand modify fm10k/Makefile(add fm10k_config.c,\nfm10k_ffu.c, and fm10k_stats.c).\n\nTo avoid configuration for both kernel driver\nand userspace SDK outside DPDK, we add switch\nmanagement in FM10K DPDK PMD driver.\nTo enable switch management, you need add\nCONFIG_RTE_FM10K_MANAGEMENT=y in\nconfig/common_linux when building.\n\nSigned-off-by: Xiaojun Liu <xiaojun.liu@silicom.co.il>\n---\n drivers/net/fm10k/Makefile              |    3 +\n drivers/net/fm10k/switch/fm10k_config.c |  855 +++++++++++++++++++++\n drivers/net/fm10k/switch/fm10k_config.h |  171 +++++\n drivers/net/fm10k/switch/fm10k_ffu.c    | 1209 ++++++++++++++++++++++++++++++\n drivers/net/fm10k/switch/fm10k_ffu.h    |   31 +\n drivers/net/fm10k/switch/fm10k_stats.c  | 1242 +++++++++++++++++++++++++++++++\n drivers/net/fm10k/switch/fm10k_stats.h  |  257 +++++++\n 7 files changed, 3768 insertions(+)\n create mode 100644 drivers/net/fm10k/switch/fm10k_config.c\n create mode 100644 drivers/net/fm10k/switch/fm10k_config.h\n create mode 100644 drivers/net/fm10k/switch/fm10k_ffu.c\n create mode 100644 drivers/net/fm10k/switch/fm10k_ffu.h\n create mode 100644 drivers/net/fm10k/switch/fm10k_stats.c\n create mode 100644 drivers/net/fm10k/switch/fm10k_stats.h",
    "diff": "diff --git a/drivers/net/fm10k/Makefile b/drivers/net/fm10k/Makefile\nindex 4ec2a80..ed73251 100644\n--- a/drivers/net/fm10k/Makefile\n+++ b/drivers/net/fm10k/Makefile\n@@ -90,6 +90,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_sbus.c\n SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_serdes.c\n SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_sm.c\n SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_spico_code.c\n+SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_stats.c\n+SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_ffu.c\n+SRCS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k_config.c\n endif\n \n SRCS-$(CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR) += fm10k_rxtx_vec.c\ndiff --git a/drivers/net/fm10k/switch/fm10k_config.c b/drivers/net/fm10k/switch/fm10k_config.c\nnew file mode 100644\nindex 0000000..46c3fae\n--- /dev/null\n+++ b/drivers/net/fm10k/switch/fm10k_config.c\n@@ -0,0 +1,855 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2019   Silicom Ltd. Connectivity Solutions\n+ */\n+\n+#include <unistd.h>\n+\n+#include <rte_time.h>\n+#include <rte_kvargs.h>\n+#include <rte_hash.h>\n+#include <rte_flow.h>\n+#include <rte_flow_driver.h>\n+#include <rte_tm_driver.h>\n+\n+#include \"../base/fm10k_type.h\"\n+#include \"../base/fm10k_osdep.h\"\n+\n+#include \"../fm10k.h\"\n+#include \"../fm10k_logs.h\"\n+#include \"fm10k_debug.h\"\n+#include \"fm10k_regs.h\"\n+#include \"fm10k_switch.h\"\n+#include \"fm10k_config.h\"\n+\n+#define FM10K_CONFIG_WORD_MAX\t\t\t10\n+#define FM10K_CONFIG_WORD_LEN\t\t\t20\n+#define FM10K_CONFIG_STR_MAX\t\t\t100\n+\n+struct fm10k_cfg_key_item {\n+\tconst char *key_str[FM10K_CONFIG_WORD_MAX];\n+\tuint8_t type;\n+};\n+\n+static const char *fm10k_config_dpdk_conf_file = \"/etc/dpdk_fm10k.conf\";\n+static struct fm10k_dpdk_cfg fm10k_config_dpdk_cfg;\n+\n+static struct fm10k_cfg_key_item fm10k_config_key_items[] = {\n+\t\t/* debug configuration */\n+\t\t{ {\"debug\", \"print\", \"enable\"},\n+\t\t\tFM10K_CONFIG_DEBUG_ENABLE},\n+\t\t{ {\"debug\", \"print\", \"config\"},\n+\t\t\tFM10K_CONFIG_DEBUG_CONFIG},\n+\t\t{ {\"debug\", \"print\", \"ffu\", \"init\"},\n+\t\t\tFM10K_CONFIG_DEBUG_FFU_INIT},\n+\t\t{ {\"debug\", \"print\", \"ffu\", \"register\"},\n+\t\t\tFM10K_CONFIG_DEBUG_FFU_REG},\n+\t\t{ {\"debug\", \"print\", \"ffu\", \"rule\"},\n+\t\t\tFM10K_CONFIG_DEBUG_FFU_RULE},\n+\t\t{ {\"debug\", \"print\", \"stats\", \"port\"},\n+\t\t\tFM10K_CONFIG_DEBUG_STATS_PORT},\n+\t\t{ {\"debug\", \"print\", \"stats\", \"queue\"},\n+\t\t\tFM10K_CONFIG_DEBUG_STATS_QUEUE},\n+\t\t{ {\"debug\", \"print\", \"stats\", \"rule\"},\n+\t\t\tFM10K_CONFIG_DEBUG_STATS_FFU},\n+\t\t{ {\"debug\", \"print\", \"stats\", \"detail\"},\n+\t\t\tFM10K_CONFIG_DEBUG_STATS_MORE},\n+\t\t{ {\"debug\", \"print\", \"stats\", \"interval\"},\n+\t\t\tFM10K_CONFIG_DEBUG_STATS_INTERVAL},\n+\t\t/* general configuration */\n+\t\t{ {\"dpdk\", \"bind\", \"pf\", \"number\"},\n+\t\t\tFM10K_CONFIG_BIND_PF_NUMBER},\n+\t\t{ {\"extern\", \"port\", \"speed\"},\n+\t\t\tFM10K_CONFIG_EXT_PORT_SPEED},\n+\t\t/* internal redirect configuration */\n+\t\t{ {\"dpdk\", \"port\", \"*\", \"map\", \"pf\"},\n+\t\t\tFM10K_CONFIG_DPDK_PORT_MAP_PF},\n+\t\t{ {\"extern\", \"port\", \"*\", \"map\", \"pf\"},\n+\t\t\tFM10K_CONFIG_EXT_PORT_MAP_PF},\n+\t\t/* external redirect configuration */\n+\t\t{ {\"flowset\", \"start\"},\n+\t\t\tFM10K_CONFIG_FLOWSET_START},\n+\t\t{ {\"flowset\", \"stop\"},\n+\t\t\tFM10K_CONFIG_FLOWSET_STOP},\n+\t\t{ {\"flowset\", \"enable\"},\n+\t\t\tFM10K_CONFIG_FLOWSET_ENABLE},\n+\t\t{ {\"flow\", \"*\", \"condition\", \"source\", \"extern\", \"port\"},\n+\t\t\tFM10K_CONFIG_FLOW_COND_SRC_EXT_PORT},\n+\t\t{ {\"flow\", \"*\", \"condition\", \"source\", \"dpdk\", \"port\"},\n+\t\t\tFM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT},\n+\t\t{ {\"flow\", \"*\", \"condition\", \"vlan\"},\n+\t\t\tFM10K_CONFIG_FLOW_COND_VLAN},\n+\t\t{ {\"flow\", \"*\", \"action\", \"forward\", \"extern\", \"port\"},\n+\t\t\tFM10K_CONFIG_FLOW_ACT_FW_EXT_PORT},\n+\t\t{ {\"flow\", \"*\", \"action\", \"forward\", \"dpdk\", \"port\"},\n+\t\t\tFM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT},\n+\t\t{ {\"flow\", \"*\", \"action\", \"forward\", \"vlan\"},\n+\t\t\tFM10K_CONFIG_FLOW_ACT_FW_VALN},\n+};\n+\n+static char default_flowset[10] = \"default\";\n+\n+static struct fm10k_cfg_config_item fm10k_silc_nic_2ext_2pep[] = {\n+\t{   FM10K_CONFIG_BIND_PF_NUMBER, FM10K_CONFIG_VALUE_INT, 0,\n+\t\t\"# Tell how many PF ports are bound in DPDK.\\n\"\n+\t\t\"# Driver will check the number when initializes.\",\n+\t\t.val.int64 = 2\n+\t},\n+\t{   FM10K_CONFIG_EXT_PORT_SPEED, FM10K_CONFIG_VALUE_INT, 0,\n+\t\t\"# Set external port speed, 40 means 40G, 100 means 100G.\",\n+\t\t.val.int64 = 100\n+\t},\n+\t{   FM10K_CONFIG_DPDK_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 0,\n+\t\t\"# Map 1 or 2 PF ports to one DPDK port.\\n\"\n+\t\t\"# If mapped PF number is 2, traffic will be\\n\"\n+\t\t\"# load balance between the 2 PF.\\n\"\n+\t\t\"# And the DPDK port queue number will be configured\\n\"\n+\t\t\"# more than 2(each PF need at least 1 DPDK port queue).\",\n+\t\t.val.int64 = 0\n+\t},\n+\t{   FM10K_CONFIG_DPDK_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 1,\n+\t\t\"\",\n+\t\t.val.int64 = 1\n+\t},\n+\t{   FM10K_CONFIG_EXT_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 1,\n+\t\t\"# Map 1 or 2 PF to one external port. If mapped PF number is 2,\\n\"\n+\t\t\"# traffic will be load balance between the 2 PF. \",\n+\t\t.val.int64 = 0\n+\t},\n+\t{   FM10K_CONFIG_EXT_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 2,\n+\t\t\"\",\n+\t\t.val.int64 = 1\n+\t},\n+\t{   FM10K_CONFIG_FLOWSET_START, FM10K_CONFIG_VALUE_STR, 0,\n+\t\t\"# Define flow rule\",\n+\t\t.val.str = default_flowset\n+\t},\n+\t{   FM10K_CONFIG_FLOWSET_STOP, FM10K_CONFIG_VALUE_STR, 0,\n+\t\t\"\",\n+\t\t.val.str = default_flowset\n+\t},\n+\t{   FM10K_CONFIG_FLOWSET_ENABLE, FM10K_CONFIG_VALUE_STR, 0,\n+\t\t\"\",\n+\t\t.val.str = default_flowset\n+\t},\n+\t{   FM10K_CONFIG_TYPE_NULL, 0, 0,\n+\t\t\"\",\n+\t\t.val.int64 = 0\n+\t},\n+};\n+\n+static struct fm10k_cfg_config_item fm10k_silc_nic_2ext_4pep[] = {\n+\t{   FM10K_CONFIG_BIND_PF_NUMBER, FM10K_CONFIG_VALUE_INT, 0,\n+\t\t\"# Tell how many PF ports are bound in DPDK.\\n\"\n+\t\t\"# Driver will check the  number when initializes.\",\n+\t\t.val.int64 = 4\n+\t},\n+\n+\t{   FM10K_CONFIG_EXT_PORT_SPEED, FM10K_CONFIG_VALUE_INT, 0,\n+\t\t\"# Set external port speed, 40 means 40G, 100 means 100G.\",\n+\t\t.val.int64 = 100\n+\t},\n+\t{   FM10K_CONFIG_DPDK_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 0,\n+\t\t\"# Map 1 or 2 PF ports to one DPDK port.\\n\"\n+\t\t\"# If mapped PF number is 2, traffic will be\\n\"\n+\t\t\"# load balance between the 2 PFs.\\n\"\n+\t\t\"# And the DPDK port queue number will be configured\\n\"\n+\t\t\"# more than 2(each PF need at least 1 DPDK port queue).\",\n+\t\t.val.int64 = 0\n+\t},\n+\t{   FM10K_CONFIG_DPDK_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 0,\n+\t\t\"\",\n+\t\t.val.int64 = 2\n+\t},\n+\t{   FM10K_CONFIG_DPDK_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 1,\n+\t\t\"\",\n+\t\t.val.int64 = 1\n+\t},\n+\t{   FM10K_CONFIG_DPDK_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 1,\n+\t\t\"\",\n+\t\t.val.int64 = 3\n+\t},\n+\t{   FM10K_CONFIG_EXT_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 1,\n+\t\t\"# Map 1 or 2 PF to one external port. If mapped PF number is 2,\\n\"\n+\t\t\"# traffic will be load balance between the 2 PF.\",\n+\t\t.val.int64 = 0\n+\t},\n+\t{   FM10K_CONFIG_EXT_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 1,\n+\t\t\"\",\n+\t\t.val.int64 = 2\n+\t},\n+\t{   FM10K_CONFIG_EXT_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 2,\n+\t\t\"\",\n+\t\t.val.int64 = 1\n+\t},\n+\t{   FM10K_CONFIG_EXT_PORT_MAP_PF, FM10K_CONFIG_VALUE_INT, 2,\n+\t\t\"\",\n+\t\t.val.int64 = 3\n+\t},\n+\t{   FM10K_CONFIG_FLOWSET_START, FM10K_CONFIG_VALUE_STR, 0,\n+\t\t\"# Define flow rule\",\n+\t\t.val.str = default_flowset\n+\t},\n+\t{   FM10K_CONFIG_FLOWSET_STOP, FM10K_CONFIG_VALUE_STR, 0,\n+\t\t\"\",\n+\t\t.val.str = default_flowset\n+\t},\n+\t{   FM10K_CONFIG_FLOWSET_ENABLE, FM10K_CONFIG_VALUE_STR, 0,\n+\t\t\"\",\n+\t\t.val.str = default_flowset\n+\t},\n+\t{   FM10K_CONFIG_TYPE_NULL, 0, 0,\n+\t\t\"\",\n+\t\t.val.int64 = 0\n+\t},\n+};\n+\n+\n+static int\n+fm10k_config_conf_line_parser(char *buff, struct fm10k_cfg_config_item *item)\n+{\n+\tchar *p;\n+\tchar *endptr;\n+\tconst char *cfg_delims = { \" \" };\n+\tconst char *key_delims = { \".\" };\n+\tstruct fm10k_cfg_key_item *key;\n+\tchar cfgs[3][FM10K_CONFIG_STR_MAX];\n+\tchar cmp_keys[FM10K_CONFIG_WORD_MAX][FM10K_CONFIG_WORD_LEN];\n+\tlong key_param = 0;\n+\tuint16_t i, j;\n+\tuint8_t val_type = FM10K_CONFIG_VALUE_NULL;\n+\n+\tfor (i = 0; i < 3; i++)\t{\n+\t\tif (i == 0)\n+\t\t\tp = strtok(buff, cfg_delims);\n+\t\telse\n+\t\t\tp = strtok(NULL, cfg_delims);\n+\t\tif (p == NULL)\n+\t\t\treturn -1;\n+\t\tstrncpy(cfgs[i], p, FM10K_CONFIG_STR_MAX);\n+\t}\n+\n+\tp = strtok(NULL, cfg_delims);\n+\tif (p)\n+\t\treturn -1;\n+\n+\tmemset(cmp_keys, 0, sizeof(cmp_keys));\n+\tfor (i = 0; i < FM10K_CONFIG_WORD_MAX; i++)\t{\n+\t\tif (i == 0)\n+\t\t\tp = strtok(cfgs[0], key_delims);\n+\t\telse\n+\t\t\tp = strtok(NULL, key_delims);\n+\t\tif (p == NULL)\n+\t\t\tbreak;\n+\t\tstrncpy(cmp_keys[i], p, FM10K_CONFIG_WORD_LEN);\n+\t}\n+\n+\tif (strcmp(cfgs[1], \"int\") == 0)\n+\t\tval_type = FM10K_CONFIG_VALUE_INT;\n+\telse if (strcmp(cfgs[1], \"string\") == 0)\n+\t\tval_type = FM10K_CONFIG_VALUE_STR;\n+\telse\n+\t\treturn -1;\n+\n+\tfor (i = 0;\n+\t\t\ti < sizeof(fm10k_config_key_items) /\n+\t\t\t\tsizeof(fm10k_config_key_items[0]);\n+\t\t\ti++) {\n+\t\tkey = &fm10k_config_key_items[i];\n+\t\tfor (j = 0; j < FM10K_CONFIG_WORD_MAX; j++)\t{\n+\t\t\tif (key->key_str[j] &&\n+\t\t\t\t\tstrlen(cmp_keys[j]) > 0) {\n+\t\t\t\tif (strcmp(key->key_str[j], \"*\") == 0) {\n+\t\t\t\t\tkey_param =\n+\t\t\t\t\tstrtol(cmp_keys[j], &endptr, 10);\n+\t\t\t\t\tif ((key_param == 0 &&\n+\t\t\t\t\t\tendptr == cmp_keys[j]) ||\n+\t\t\t\t\t\t(endptr != cmp_keys[j] &&\n+\t\t\t\t\t\tstrlen(endptr) != 0))\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t} else if (strcmp(key->key_str[j],\n+\t\t\t\t\t\t\tcmp_keys[j]) != 0) {\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t} else if (key->key_str[j] == 0 &&\n+\t\t\t\t\tstrlen(cmp_keys[j]) == 0) {\n+\t\t\t\tif (val_type == FM10K_CONFIG_VALUE_STR) {\n+\t\t\t\t\titem->val.str =\n+\t\t\t\t\tmalloc(strlen(cfgs[2]) + 1);\n+\t\t\t\t\tif (item->val.str == NULL)\n+\t\t\t\t\t\treturn -1;\n+\t\t\t\t\tstrcpy(item->val.str, cfgs[2]);\n+\t\t\t\t} else {\n+\t\t\t\t\titem->val.int64 =\n+\t\t\t\t\tstrtol(cfgs[2], NULL, 10);\n+\t\t\t\t}\n+\t\t\t\titem->type = key->type;\n+\t\t\t\titem->key_param = key_param;\n+\t\t\t\titem->val_type = val_type;\n+\t\t\t\treturn 0;\n+\t\t\t}\n+\t\t}\n+\t}\n+\treturn -1;\n+}\n+\n+static bool\n+fm10k_config_blank_line_check(char *line)\n+{\n+\tuint16_t i;\n+\n+\tfor (i = 0; i < strlen(line); i++) {\n+\t\tif (line[i] == ' ' ||\n+\t\t\t\tline[i] == '\\n' ||\n+\t\t\t\tline[i] == '\\t' || line[i] == 0x0d) /* 0d: CR */\n+\t\t\tcontinue;\n+\t\telse\n+\t\t\treturn false;\n+\t}\n+\treturn true;\n+}\n+\n+static int\n+fm10k_config_conf_file_load(void)\n+{\n+\tint i = 0;\n+\tFILE *fp;\n+\tchar buff[255];\n+\tstruct fm10k_cfg_config_item *item;\n+\n+\tfp = fopen(fm10k_config_dpdk_conf_file, \"r\");\n+\tif (fp == NULL)\n+\t\treturn -1;\n+\n+\tfm10k_config_dpdk_cfg.config_list =\tmalloc\n+\t\t(sizeof(struct fm10k_cfg_config_item) * FM10K_SW_CONFIG_MAX);\n+\tif (fm10k_config_dpdk_cfg.config_list == NULL)\n+\t\treturn -1;\n+\tmemset(fm10k_config_dpdk_cfg.config_list, 0,\n+\t\tsizeof(struct fm10k_cfg_config_item) * FM10K_SW_CONFIG_MAX);\n+\n+\twhile (fgets(buff, sizeof(buff), fp)) {\n+\t\tif (buff[0] == '#' || buff[0] == 0)\n+\t\t\tcontinue;\n+\n+\t\tif (fm10k_config_blank_line_check(buff))\n+\t\t\tcontinue;\n+\n+\t\titem = &fm10k_config_dpdk_cfg.config_list[i++];\n+\t\tif (fm10k_config_conf_line_parser(buff, item) < 0) {\n+\t\t\tFM10K_SW_ERR(\"Unknown configuration: %s\", buff);\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+struct fm10k_hw*\n+fm10k_config_hw_get(int port_no)\n+{\n+\tint hw_port;\n+\n+\thw_port = fm10k_config_dpdk_cfg.dpdk_port_map[port_no].map_no[0];\n+\treturn fm10k_config_dpdk_cfg.pf_hw[hw_port];\n+}\n+\n+struct fm10k_cfg_flowset *\n+fm10k_config_flowset_current_get(void)\n+{\n+\treturn fm10k_config_dpdk_cfg.current;\n+}\n+\n+void\n+fm10k_config_flowset_current_set(struct fm10k_cfg_flowset *new)\n+{\n+\tfm10k_config_dpdk_cfg.current = new;\n+}\n+\n+bool\n+fm10k_config_flow_list_end(struct fm10k_cfg_flow *list,\n+\t\tstruct fm10k_cfg_flow *flow)\n+{\n+\treturn (list == flow);\n+}\n+\n+static void\n+fm10k_config_flow_list_init(struct fm10k_cfg_flow *list)\n+{\n+\tlist->next = list;\n+\tlist->prev = list;\n+}\n+\n+static void\n+fm10k_config_flow_list_add(struct fm10k_cfg_flow *new,\n+\t\tstruct fm10k_cfg_flow *list)\n+{\n+\tstruct fm10k_cfg_flow *next = list->next;\n+\tnext->prev = new;\n+\tnew->next = next;\n+\tnew->prev = list;\n+\tlist->next = new;\n+}\n+\n+void\n+fm10k_config_flow_list_add_tail(struct fm10k_cfg_flowset *flowset,\n+\t\tstruct fm10k_cfg_flow *flow)\n+{\n+\tfm10k_config_flow_list_add(flow, flowset->flow_head.prev);\n+}\n+\n+void\n+fm10k_config_flow_list_delete(struct fm10k_cfg_flow *flow)\n+{\n+\tflow->prev->next = flow->next;\n+\tflow->next->prev = flow->prev;\n+\tflow->prev = NULL;\n+\tflow->next = NULL;\n+}\n+\n+struct fm10k_cfg_flowset *\n+fm10k_config_flowset_get(const char *name)\n+{\n+\tstruct fm10k_cfg_flowset *flowset;\n+\n+\tflowset = fm10k_config_dpdk_cfg.flowset_head.next;\n+\twhile (flowset)\t{\n+\t\tif (strcmp(flowset->name, name) == 0)\n+\t\t\tbreak;\n+\t\tflowset = flowset->next;\n+\t}\n+\n+\tif (flowset == NULL) {\n+\t\tflowset = malloc(sizeof(struct fm10k_cfg_flowset));\n+\t\tif (flowset == NULL)\n+\t\t\treturn NULL;\n+\t\tstrcpy(flowset->name, name);\n+\t\tfm10k_config_flow_list_init(&flowset->flow_head);\n+\t\tflowset->next = fm10k_config_dpdk_cfg.flowset_head.next;\n+\t\tfm10k_config_dpdk_cfg.flowset_head.next = flowset;\n+\t}\n+\treturn flowset;\n+}\n+\n+\n+static int\n+fm10k_cfg_flow_item_set(struct fm10k_cfg_flowset *flowset,\n+\t\tuint8_t flow_no, uint8_t type, int64_t val)\n+{\n+\tstruct fm10k_cfg_flow *tmp;\n+\tstruct fm10k_cfg_flow *flow = NULL;\n+\n+\tif (flowset == NULL)\n+\t\treturn -1;\n+\n+\ttmp = flowset->flow_head.next;\n+\twhile (!fm10k_config_flow_list_end(&flowset->flow_head, tmp)) {\n+\t\tif (tmp->flow_no == flow_no) {\n+\t\t\tflow = tmp;\n+\t\t\tbreak;\n+\t\t}\n+\t\ttmp = tmp->next;\n+\t}\n+\tif (flow == NULL) {\n+\t\tflow = malloc(sizeof(struct fm10k_cfg_flow));\n+\t\tmemset(flow, 0, sizeof(struct fm10k_cfg_flow));\n+\t\tflow->flow_no = flow_no;\n+\t\tfm10k_config_flow_list_add_tail(flowset, flow);\n+\t}\n+\tif (flow == NULL)\n+\t\treturn -1;\n+\n+\tswitch (type) {\n+\tcase FM10K_CONFIG_FLOW_COND_SRC_EXT_PORT:\n+\t\tflow->src_port.port_type = FM10K_CONFIG_FLOW_EXT_PORT;\n+\t\tflow->src_port.port_no = val;\n+\t\tbreak;\n+\tcase FM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT:\n+\t\tflow->src_port.port_type = FM10K_CONFIG_FLOW_DPDK_PORT;\n+\t\tflow->src_port.port_no = val;\n+\t\tbreak;\n+\tcase FM10K_CONFIG_FLOW_COND_VLAN:\n+\t\tflow->src_port.vlan_id = val;\n+\t\tbreak;\n+\tcase FM10K_CONFIG_FLOW_ACT_FW_EXT_PORT:\n+\t\tif (flow->fw_port[0].port_type == FM10K_CONFIG_FLOW_NONE_PORT) {\n+\t\t\tflow->fw_port[0].port_type = FM10K_CONFIG_FLOW_EXT_PORT;\n+\t\t\tflow->fw_port[0].port_no = val;\n+\t\t} else {\n+\t\t\tflow->fw_port[1].port_type = FM10K_CONFIG_FLOW_EXT_PORT;\n+\t\t\tflow->fw_port[1].port_no = val;\n+\t\t}\n+\t\tbreak;\n+\tcase FM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT:\n+\t\tif (flow->fw_port[0].port_type == FM10K_CONFIG_FLOW_NONE_PORT) {\n+\t\t\tflow->fw_port[0].port_type =\n+\t\t\t\t\tFM10K_CONFIG_FLOW_DPDK_PORT;\n+\t\t\tflow->fw_port[0].port_no = val;\n+\t\t} else {\n+\t\t\tflow->fw_port[1].port_type =\n+\t\t\t\t\tFM10K_CONFIG_FLOW_DPDK_PORT;\n+\t\t\tflow->fw_port[1].port_no = val;\n+\t\t}\n+\t\tbreak;\n+\tcase FM10K_CONFIG_FLOW_ACT_FW_VALN:\n+\t\tif (flow->fw_port[0].vlan_id == 0)\n+\t\t\tflow->fw_port[0].vlan_id = val;\n+\t\telse\n+\t\t\tflow->fw_port[1].vlan_id = val;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+fm10k_config_conf_file_transfer(void)\n+{\n+\tint i;\n+\tint offset;\n+\tuint32_t tmp, data;\n+\tstruct fm10k_cfg_config_item *item;\n+\tstruct fm10k_cfg_flowset *flowset = NULL;\n+\tstruct fm10k_cfg_port_pf_map *map;\n+\n+\tfor (i = 0; i < FM10K_SW_CONFIG_MAX; i++) {\n+\t\titem = &fm10k_config_dpdk_cfg.config_list[i];\n+\t\tif (item->type == FM10K_CONFIG_TYPE_NULL)\n+\t\t\tbreak;\n+\n+\t\tswitch (item->type)\t{\n+\t\tcase FM10K_CONFIG_BIND_PF_NUMBER:\n+\t\t\tfm10k_config_dpdk_cfg.pf_num = item->val.int64;\n+\t\t\tbreak;\n+\t\tcase FM10K_CONFIG_EXT_PORT_SPEED:\n+\t\t\tfm10k_config_dpdk_cfg.ext_port_speed = item->val.int64;\n+\t\t\tbreak;\n+\t\tcase FM10K_CONFIG_DPDK_PORT_MAP_PF:\n+\t\t\tmap =\n+\t\t\t&fm10k_config_dpdk_cfg.dpdk_port_map[item->key_param];\n+\t\t\tif (map->type == FM10K_CONFIG_PORT_MAP_PF) {\n+\t\t\t\tmap->type = FM10K_CONFIG_PORT_MAP_PFS;\n+\t\t\t\tmap->map_no[1] = item->val.int64;\n+\t\t\t} else {\n+\t\t\t\tmap->type = FM10K_CONFIG_PORT_MAP_PF;\n+\t\t\t\tmap->map_no[0] = item->val.int64;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase FM10K_CONFIG_EXT_PORT_MAP_PF:\n+\t\t\tmap =\n+\t\t\t\t&fm10k_config_dpdk_cfg.ext_port_map\n+\t\t\t\t[item->key_param - 1];\n+\t\t\tif (map->type == FM10K_CONFIG_PORT_MAP_PF) {\n+\t\t\t\tmap->type = FM10K_CONFIG_PORT_MAP_PFS;\n+\t\t\t\tmap->map_no[1] = item->val.int64;\n+\t\t\t} else {\n+\t\t\t\tmap->type = FM10K_CONFIG_PORT_MAP_PF;\n+\t\t\t\tmap->map_no[0] = item->val.int64;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase FM10K_CONFIG_DEBUG_ENABLE:\n+\t\tcase FM10K_CONFIG_DEBUG_CONFIG:\n+\t\tcase FM10K_CONFIG_DEBUG_FFU_INIT:\n+\t\tcase FM10K_CONFIG_DEBUG_FFU_REG:\n+\t\tcase FM10K_CONFIG_DEBUG_FFU_RULE:\n+\t\tcase FM10K_CONFIG_DEBUG_STATS_PORT:\n+\t\tcase FM10K_CONFIG_DEBUG_STATS_QUEUE:\n+\t\tcase FM10K_CONFIG_DEBUG_STATS_FFU:\n+\t\tcase FM10K_CONFIG_DEBUG_STATS_MORE:\n+\t\t\toffset = item->type - FM10K_CONFIG_DEBUG_START;\n+\t\t\ttmp = fm10k_config_dpdk_cfg.debug_cfg;\n+\t\t\tdata = 1;\n+\t\t\tif (item->val.int64 != 1)\n+\t\t\t\tfm10k_config_dpdk_cfg.debug_cfg =\n+\t\t\t\t\t\ttmp & ~(data << offset);\n+\t\t\telse\n+\t\t\t\tfm10k_config_dpdk_cfg.debug_cfg |=\n+\t\t\t\t\t\t(data << offset);\n+\t\t\tbreak;\n+\t\tcase FM10K_CONFIG_DEBUG_STATS_INTERVAL:\n+\t\t\tfm10k_config_dpdk_cfg.stats_interval = item->val.int64;\n+\t\t\tbreak;\n+\n+\t\tcase FM10K_CONFIG_FLOWSET_START:\n+\t\t\t/* skip /n */\n+\t\t\titem->val.str[strlen(item->val.str) - 1] = 0;\n+\t\t\tflowset = fm10k_config_flowset_get(item->val.str);\n+\t\t\tif (flowset == NULL)\n+\t\t\t\treturn -1;\n+\t\t\tbreak;\n+\t\tcase FM10K_CONFIG_FLOWSET_STOP:\n+\t\t\tflowset = NULL;\n+\t\t\tbreak;\n+\t\tcase FM10K_CONFIG_FLOWSET_ENABLE:\n+\t\t\t/* skip /n */\n+\t\t\titem->val.str[strlen(item->val.str) - 1] = 0;\n+\t\t\tfm10k_config_dpdk_cfg.current =\n+\t\t\t\t\tfm10k_config_flowset_get(item->val.str);\n+\t\t\tbreak;\n+\t\tcase FM10K_CONFIG_FLOW_COND_SRC_EXT_PORT:\n+\t\tcase FM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT:\n+\t\tcase FM10K_CONFIG_FLOW_COND_VLAN:\n+\t\tcase FM10K_CONFIG_FLOW_ACT_FW_EXT_PORT:\n+\t\tcase FM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT:\n+\t\tcase FM10K_CONFIG_FLOW_ACT_FW_VALN:\n+\t\t\tif (flowset == NULL ||\n+\t\t\t\t\tfm10k_cfg_flow_item_set(flowset,\n+\t\t\t\t\titem->key_param, item->type,\n+\t\t\t\t\titem->val.int64) != 0)\n+\t\t\t\treturn -1;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+static bool\n+fm10k_config_conf_file_exist(void)\n+{\n+\tif (access(fm10k_config_dpdk_conf_file, 0) == 0)\n+\t\treturn true;\n+\treturn false;\n+}\n+\n+static int\n+fm10k_config_conf_file_item_create(FILE *fp, char *buff,\n+\t\tstruct fm10k_cfg_key_item *key,\n+\t\tstruct fm10k_cfg_config_item *item)\n+{\n+\tint i;\n+\n+\tif (item->type != key->type)\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < FM10K_CONFIG_WORD_MAX; i++) {\n+\t\tif (key->key_str[i] == 0)\n+\t\t\tbreak;\n+\t\tif (i == 0) {\n+\t\t\tsprintf(buff + strlen(buff),\n+\t\t\t\t\"%s\", key->key_str[i]);\n+\t\t} else {\n+\t\t\tif (strcmp(key->key_str[i], \"*\") == 0)\n+\t\t\t\tsprintf(buff + strlen(buff),\n+\t\t\t\t\t\t\".%u\", item->key_param);\n+\t\t\telse\n+\t\t\t\tsprintf(buff + strlen(buff),\n+\t\t\t\t\t\t\".%s\", key->key_str[i]);\n+\t\t}\n+\t}\n+\tif (item->val_type == FM10K_CONFIG_VALUE_INT)\n+\t\tsprintf(buff + strlen(buff),\n+\t\t\t\t\" int %lld\\n\", (long long)item->val.int64);\n+\telse if (item->val_type == FM10K_CONFIG_VALUE_STR)\n+\t\tsprintf(buff + strlen(buff), \" string %s\\n\", item->val.str);\n+\telse\n+\t\treturn -1;\n+\tfwrite(buff, strlen(buff), 1, fp);\n+\tFM10K_SW_TRACE(\"[write] %s\", buff);\n+\n+\treturn 0;\n+}\n+\n+static int\n+fm10k_config_conf_file_create(void)\n+{\n+\tuint16_t i, j;\n+\tstruct fm10k_cfg_key_item *key;\n+\tstruct fm10k_cfg_config_item *item;\n+\tFILE *fp;\n+\tchar buff[255] = \"\";\n+\n+\tfp = fopen(fm10k_config_dpdk_conf_file, \"w\");\n+\tif (fp == NULL)\n+\t\treturn -1;\n+\n+\tfor (i = 0; i < FM10K_SW_CONFIG_MAX; i++) {\n+\t\titem = &fm10k_config_dpdk_cfg.config_list[i];\n+\t\tif (item->type == FM10K_CONFIG_TYPE_NULL)\n+\t\t\tbreak;\n+\t\tbuff[0] = 0;\n+\t\tif (strlen(item->describe) > 0)\n+\t\t\tsprintf(buff, \"\\n\\n%s\\n\", item->describe);\n+\t\tfor (j = 0;\n+\t\t\t\tj < sizeof(fm10k_config_key_items) /\n+\t\t\t\t\tsizeof(fm10k_config_key_items[0]);\n+\t\t\t\tj++) {\n+\t\t\tkey = &fm10k_config_key_items[j];\n+\t\t\tif (fm10k_config_conf_file_item_create\n+\t\t\t\t\t(fp, buff, key, item) != 0) {\n+\t\t\t\tfclose(fp);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t}\n+\t}\n+\tfclose(fp);\n+\treturn 0;\n+}\n+\n+void\n+fm10k_config_cfg_flowset_show(void)\n+{\n+\tstruct fm10k_cfg_flowset *flowset;\n+\n+\tprintf(\"  FLOWSET ENABLE: %s\\n\", fm10k_config_dpdk_cfg.current->name);\n+\n+\tflowset = fm10k_config_dpdk_cfg.flowset_head.next;\n+\twhile (flowset) {\n+\t\tprintf(\"\\n  FLOWSET  : %s\\n\", flowset->name);\n+\t\tstruct fm10k_cfg_flow *flow = flowset->flow_head.next;\n+\t\twhile (!fm10k_config_flow_list_end(&flowset->flow_head, flow)) {\n+\t\t\tconst char *port_type[3] = { \"NON\", \"EXT\", \"DPDK\" };\n+\t\t\tif (flow->fw_port[1].port_type !=\n+\t\t\t\t\tFM10K_CONFIG_FLOW_NONE_PORT) {\n+\t\t\t\tprintf(\"  FLOW %d : %4s PORT %d VLAN %4d --> \"\n+\t\t\t\t\t\"%4s PORT %d VLAN %4d & %4s PORT %d VLAN %4d\\n\",\n+\t\t\t\t\tflow->flow_no,\n+\t\t\t\t\tport_type[flow->src_port.port_type],\n+\t\t\t\t\tflow->src_port.port_no,\n+\t\t\t\t\tflow->src_port.vlan_id,\n+\t\t\t\t\tport_type[flow->fw_port[0].port_type],\n+\t\t\t\t\tflow->fw_port[0].port_no,\n+\t\t\t\t\tflow->fw_port[0].vlan_id,\n+\t\t\t\t\tport_type[flow->fw_port[1].port_type],\n+\t\t\t\t\tflow->fw_port[1].port_no,\n+\t\t\t\t\tflow->fw_port[1].vlan_id);\n+\t\t\t} else {\n+\t\t\t\tprintf(\"  FLOW %d : %4s PORT %d VLAN %4d --> \"\n+\t\t\t\t\t\"%4s PORT %d VLAN %4d\\n\",\n+\t\t\t\t\tflow->flow_no,\n+\t\t\t\t\tport_type[flow->src_port.port_type],\n+\t\t\t\t\tflow->src_port.port_no,\n+\t\t\t\t\tflow->src_port.vlan_id,\n+\t\t\t\t\tport_type[flow->fw_port[0].port_type],\n+\t\t\t\t\tflow->fw_port[0].port_no,\n+\t\t\t\t\tflow->fw_port[0].vlan_id);\n+\t\t\t}\n+\t\t\tflow = flow->next;\n+\t\t}\n+\t\tflowset = flowset->next;\n+\t}\n+}\n+\n+static void\n+fm10k_config_cfg_describe(struct fm10k_switch *sw,\n+\t\tstruct fm10k_device_info *info)\n+{\n+\tuint16_t i;\n+\tstruct fm10k_cfg_flowset *flowset;\n+\n+\tif (!fm10k_config_check_debug(sw->dpdk_cfg, FM10K_CONFIG_DEBUG_CONFIG))\n+\t\treturn;\n+\n+\tprintf(\"--- FM10K STATIC CONFIG ---\\n\");\n+\tprintf(\"  Card Type: %s\\n\", info->desc);\n+\tprintf(\"  PF Max   : %d\\n\", fm10k_config_dpdk_cfg.pf_max);\n+\tprintf(\"  PF Bind  : %d\\n\", fm10k_config_dpdk_cfg.pf_num);\n+\tprintf(\"  DEBUG    : %#x\\n\", fm10k_config_dpdk_cfg.debug_cfg);\n+\tprintf(\"  STATS GAP: %d sec\\n\", fm10k_config_dpdk_cfg.stats_interval);\n+\tprintf(\"  EXT PORT speed: %d Gbps\\n\",\n+\t\t\tfm10k_config_dpdk_cfg.ext_port_speed);\n+\tprintf(\"  FLOWSET ENABLE: %s\\n\", fm10k_config_dpdk_cfg.current->name);\n+\n+\tfor (i = 0; i < fm10k_config_dpdk_cfg.ext_port_num; i++) {\n+\t\tif (fm10k_config_dpdk_cfg.ext_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_NULL)\n+\t\t\tcontinue;\n+\t\tif (fm10k_config_dpdk_cfg.ext_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_PF)\n+\t\t\tprintf(\"  EXT PORT[%d] MAP: PF%d\\n\", i + 1,\n+\t\t\tfm10k_config_dpdk_cfg.ext_port_map[i].map_no[0]);\n+\t\telse\n+\t\t\tprintf(\"  EXT PORT[%d] MAP: PF%d PF%d\\n\", i + 1,\n+\t\t\tfm10k_config_dpdk_cfg.ext_port_map[i].map_no[0],\n+\t\t\tfm10k_config_dpdk_cfg.ext_port_map[i].map_no[1]);\n+\t}\n+\n+\tfor (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {\n+\t\tif (fm10k_config_dpdk_cfg.dpdk_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_NULL)\n+\t\t\tcontinue;\n+\t\tif (fm10k_config_dpdk_cfg.ext_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_PF)\n+\t\t\tprintf(\"  DPDK PORT[%d] MAP: PF%d\\n\", i,\n+\t\t\tfm10k_config_dpdk_cfg.dpdk_port_map[i].map_no[0]);\n+\t\telse\n+\t\t\tprintf(\"  DPDK PORT[%d] MAP: PF%d PF%d\\n\", i,\n+\t\t\tfm10k_config_dpdk_cfg.dpdk_port_map[i].map_no[0],\n+\t\t\tfm10k_config_dpdk_cfg.dpdk_port_map[i].map_no[1]);\n+\t}\n+\n+\tflowset = fm10k_config_dpdk_cfg.flowset_head.next;\n+\twhile (flowset) {\n+\t\tprintf(\"\\n  FLOWSET  : %s\\n\", flowset->name);\n+\t\tstruct fm10k_cfg_flow *flow = flowset->flow_head.next;\n+\t\twhile (!fm10k_config_flow_list_end(&flowset->flow_head, flow)) {\n+\t\t\tconst char *port_type[3] = { \"NON\", \"EXT\", \"DPDK\" };\n+\t\t\tif (flow->fw_port[1].port_type !=\n+\t\t\t\t\tFM10K_CONFIG_FLOW_NONE_PORT) {\n+\t\t\t\tprintf(\"  FLOW %d : %4s PORT %d VLAN %4d --> \"\n+\t\t\t\t\t\"%4s PORT %d VLAN %4d & %4s PORT %d \"\n+\t\t\t\t\t\"VLAN %4d\\n\",\n+\t\t\t\t\tflow->flow_no,\n+\t\t\t\t\tport_type[flow->src_port.port_type],\n+\t\t\t\t\tflow->src_port.port_no,\n+\t\t\t\t\tflow->src_port.vlan_id,\n+\t\t\t\t\tport_type[flow->fw_port[0].port_type],\n+\t\t\t\t\tflow->fw_port[0].port_no,\n+\t\t\t\t\tflow->fw_port[0].vlan_id,\n+\t\t\t\t\tport_type[flow->fw_port[1].port_type],\n+\t\t\t\t\tflow->fw_port[1].port_no,\n+\t\t\t\t\tflow->fw_port[1].vlan_id);\n+\t\t\t} else {\n+\t\t\t\tprintf(\"  FLOW %d : %4s PORT %d VLAN %4d --> \"\n+\t\t\t\t\t\"%4s PORT %d VLAN %4d\\n\",\n+\t\t\t\t\tflow->flow_no,\n+\t\t\t\t\tport_type[flow->src_port.port_type],\n+\t\t\t\t\tflow->src_port.port_no,\n+\t\t\t\t\tflow->src_port.vlan_id,\n+\t\t\t\t\tport_type[flow->fw_port[0].port_type],\n+\t\t\t\t\tflow->fw_port[0].port_no,\n+\t\t\t\t\tflow->fw_port[0].vlan_id);\n+\t\t\t}\n+\t\t\tflow = flow->next;\n+\t\t}\n+\t\tflowset = flowset->next;\n+\t}\n+\tprintf(\"\\n\");\n+}\n+\n+int\n+fm10k_config_init(struct fm10k_switch *sw, struct fm10k_hw *hw)\n+{\n+\tstruct fm10k_device_info *info = fm10k_get_device_info(hw);\n+\n+\tfm10k_config_dpdk_cfg.stats_interval = 2;\n+\tfm10k_config_dpdk_cfg.pf_max = info->num_peps;\n+\tfm10k_config_dpdk_cfg.ext_port_num = info->num_ext_ports;\n+\n+\tif (!fm10k_config_conf_file_exist()) {\n+\t\tif (info->num_epls == 2 && info->num_peps == 2)\n+\t\t\tfm10k_config_dpdk_cfg.config_list =\n+\t\t\t\t\tfm10k_silc_nic_2ext_2pep;\n+\t\telse if (info->num_epls == 2 && info->num_peps == 4)\n+\t\t\tfm10k_config_dpdk_cfg.config_list =\n+\t\t\t\t\tfm10k_silc_nic_2ext_4pep;\n+\t\telse\n+\t\t\treturn -1;\n+\n+\t\tfm10k_config_conf_file_create();\n+\t} else {\n+\t\tif (fm10k_config_conf_file_load() < 0)\n+\t\t\treturn -1;\n+\t}\n+\n+\tif (fm10k_config_conf_file_transfer() < 0)\n+\t\treturn -1;\n+\tsw->dpdk_cfg = &fm10k_config_dpdk_cfg;\n+\n+\tfm10k_config_cfg_describe(sw, info);\n+\n+\treturn 0;\n+}\ndiff --git a/drivers/net/fm10k/switch/fm10k_config.h b/drivers/net/fm10k/switch/fm10k_config.h\nnew file mode 100644\nindex 0000000..f79df01\n--- /dev/null\n+++ b/drivers/net/fm10k/switch/fm10k_config.h\n@@ -0,0 +1,171 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2019   Silicom Ltd. Connectivity Solutions\n+ */\n+\n+#ifndef _FM10K_CONFIG_H_\n+#define _FM10K_CONFIG_H_\n+\n+\n+#include <stdint.h>\n+#include \"fm10k_switch.h\"\n+\n+/* General configuration */\n+#define FM10K_CONFIG_TYPE_NULL\t\t\t\t0\n+#define FM10K_CONFIG_BIND_PF_NUMBER\t\t\t1\n+#define FM10K_CONFIG_EXT_PORT_SPEED\t\t\t2\n+\n+/* Internal redirect configuration */\n+#define FM10K_CONFIG_DPDK_PORT_MAP_PF\t\t10\n+#define FM10K_CONFIG_EXT_PORT_MAP_PF\t\t11\n+\n+/* Debug configuration */\n+#define FM10K_CONFIG_DEBUG_START          50\n+#define FM10K_CONFIG_DEBUG_ENABLE         (FM10K_CONFIG_DEBUG_START + 0)\n+#define FM10K_CONFIG_DEBUG_CONFIG         (FM10K_CONFIG_DEBUG_START + 1)\n+#define FM10K_CONFIG_DEBUG_FFU_INIT       (FM10K_CONFIG_DEBUG_START + 2)\n+#define FM10K_CONFIG_DEBUG_FFU_REG        (FM10K_CONFIG_DEBUG_START + 3)\n+#define FM10K_CONFIG_DEBUG_FFU_RULE       (FM10K_CONFIG_DEBUG_START + 4)\n+#define FM10K_CONFIG_DEBUG_STATS_PORT     (FM10K_CONFIG_DEBUG_START + 5)\n+#define FM10K_CONFIG_DEBUG_STATS_QUEUE    (FM10K_CONFIG_DEBUG_START + 6)\n+#define FM10K_CONFIG_DEBUG_STATS_FFU      (FM10K_CONFIG_DEBUG_START + 7)\n+#define FM10K_CONFIG_DEBUG_STATS_MORE     (FM10K_CONFIG_DEBUG_START + 8)\n+#define FM10K_CONFIG_DEBUG_STATS_INTERVAL (FM10K_CONFIG_DEBUG_START + 9)\n+\n+/* external redirect configuration */\n+#define FM10K_CONFIG_FLOWSET_START           80\n+#define FM10K_CONFIG_FLOWSET_STOP            81\n+#define FM10K_CONFIG_FLOWSET_ENABLE          82\n+\n+#define FM10K_CONFIG_FLOW_COND_START         100\n+#define FM10K_CONFIG_FLOW_COND_SRC_EXT_PORT  (FM10K_CONFIG_FLOW_COND_START + 0)\n+#define FM10K_CONFIG_FLOW_COND_SRC_DPDK_PORT (FM10K_CONFIG_FLOW_COND_START + 1)\n+#define FM10K_CONFIG_FLOW_COND_VLAN          (FM10K_CONFIG_FLOW_COND_START + 2)\n+#define FM10K_CONFIG_FLOW_COND_END           (FM10K_CONFIG_FLOW_COND_START + 2)\n+\n+#define FM10K_CONFIG_FLOW_ACT_START          200\n+#define FM10K_CONFIG_FLOW_ACT_FW_EXT_PORT    (FM10K_CONFIG_FLOW_ACT_START + 0)\n+#define FM10K_CONFIG_FLOW_ACT_FW_DPDK_PORT   (FM10K_CONFIG_FLOW_ACT_START + 1)\n+#define FM10K_CONFIG_FLOW_ACT_FW_VALN        (FM10K_CONFIG_FLOW_ACT_START + 2)\n+#define FM10K_CONFIG_FLOW_ACT_END            (FM10K_CONFIG_FLOW_ACT_START + 2)\n+\n+#define FM10K_CONFIG_FLOW_NONE_PORT\t\t0\n+#define FM10K_CONFIG_FLOW_EXT_PORT\t\t1\n+#define FM10K_CONFIG_FLOW_DPDK_PORT\t\t2\n+\n+#define FM10K_CONFIG_VALUE_NULL\t\t\t0\n+#define FM10K_CONFIG_VALUE_INT\t\t\t1\n+#define FM10K_CONFIG_VALUE_STR\t\t\t2\n+\n+/* SWITCH config */\n+#define FM10K_CONFIG_PORT_MAP_NULL\t\t0\n+#define FM10K_CONFIG_PORT_MAP_PF\t\t1\n+#define FM10K_CONFIG_PORT_MAP_PFS\t\t2\n+#define FM10K_CONFIG_PORT_MAP_PFSS\t\t3\n+\n+/* DPDK port */\n+#define\tFM10K_CONFIG_DPDK_NULL\t\t\t0\n+#define FM10K_CONFIG_DPDK_PF\t\t\t1\n+#define FM10K_CONFIG_DPDK_VF\t\t\t2\n+#define FM10K_CONFIG_DPDK_MAX\t\t\t3\n+\n+struct fm10k_cfg_port_pf_map {\n+\tuint8_t type;\n+\tuint8_t map_no[2];\n+};\n+\n+/* Configuration read from file */\n+struct fm10k_cfg_config_item {\n+\tuint8_t  type;\n+\tuint8_t  val_type;\n+\tuint16_t key_param;\n+\tconst char *describe;\n+\tunion {\n+\t\tint64_t int64;\n+\t\tchar *str;\n+\t} val;\n+};\n+\n+struct fm10k_hw;\n+\n+struct fm10k_dpdk_port {\n+\tuint8_t type;\n+\tstruct fm10k_hw *hw;\n+\tvoid *rte_dev;\n+\tvoid *flow_list;\n+\tuint16_t pf_no;\n+\tuint8_t tx_queue_num;\n+\tuint8_t rx_queue_num;\n+};\n+\n+\n+/* Flow configuration */\n+struct fm10k_cfg_port {\n+\tuint8_t port_type;\n+\tuint8_t port_no;\n+\tuint16_t vlan_id;\n+};\n+\n+struct fm10k_cfg_flow {\n+\t/* set by configuration */\n+\tstruct fm10k_cfg_flow *prev;\n+\tstruct fm10k_cfg_flow *next;\n+\tuint8_t flow_no; /* only configured flow has this NO. */\n+\tstruct fm10k_cfg_port src_port;\n+\tstruct fm10k_cfg_port fw_port[2];\n+\t/* set by ffu rule add */\n+\tuint16_t rule_id;\n+};\n+\n+#define FM10K_CONFIG_FLOWSET_NAME_MAX\t256\n+struct fm10k_cfg_flowset {\n+\tchar name[FM10K_CONFIG_FLOWSET_NAME_MAX];\n+\tstruct fm10k_cfg_flow flow_head;\n+\tstruct fm10k_cfg_flowset *next;\n+};\n+\n+/* Configuration */\n+struct fm10k_dpdk_cfg {\n+\tuint8_t pf_num;\t\t\t/* configure by conf */\n+\tuint8_t pf_bind;\t\t/* initialize by dpdk */\n+\tuint8_t pf_max;\t\t\t/* set by card type */\n+\tuint8_t ext_port_num;\t/* configure by conf */\n+\tuint8_t ext_port_speed;\t/* configure by conf */\n+\tuint32_t debug_cfg;\t\t/* configure by conf */\n+\tuint32_t stats_interval;/* configure by conf */\n+\n+\tstruct fm10k_hw *master_hw; /* initialize by dpdk */\n+\tstruct fm10k_hw *pf_hw[FM10K_SW_PEP_PORTS_MAX]; /* initialize by dpdk */\n+\n+\t/* initialize by dpdk */\n+\tstruct fm10k_dpdk_port ports[FM10K_SW_LOGICAL_PORTS_MAX];\n+\t/* configure by conf or default*/\n+\tstruct fm10k_cfg_port_pf_map dpdk_port_map\n+\t\t\t\t\t[FM10K_SW_LOGICAL_PORTS_MAX];\n+\t/* configure by conf */\n+\tstruct fm10k_cfg_port_pf_map ext_port_map[FM10K_SW_EXT_PORTS_MAX];\n+\tstruct fm10k_cfg_config_item *config_list; /* configure by conf */\n+\tstruct fm10k_cfg_flowset flowset_head; /* transfer from conf file */\n+\tstruct fm10k_cfg_flowset *current;\n+};\n+\n+static inline bool\n+fm10k_config_check_debug(struct fm10k_dpdk_cfg *cfg, uint16_t dbg)\n+{\n+\treturn cfg->debug_cfg & 1 << (dbg - FM10K_CONFIG_DEBUG_START) &&\n+\t\t   cfg->debug_cfg & 1;\n+}\n+\n+struct fm10k_cfg_flowset *fm10k_config_flowset_get(const char *name);\n+struct fm10k_cfg_flowset *fm10k_config_flowset_current_get(void);\n+void fm10k_config_flowset_current_set(struct fm10k_cfg_flowset *new);\n+void fm10k_config_flow_list_add_tail(struct fm10k_cfg_flowset *flowset,\n+\t\t\t\tstruct fm10k_cfg_flow *flow);\n+void fm10k_config_flow_list_delete(struct fm10k_cfg_flow *flow);\n+bool fm10k_config_flow_list_end(struct fm10k_cfg_flow *list,\n+\t\t\t\tstruct fm10k_cfg_flow *flow);\n+\n+void fm10k_config_cfg_flowset_show(void);\n+struct fm10k_hw *fm10k_config_hw_get(int port_no);\n+int fm10k_config_init(struct fm10k_switch *sw, struct fm10k_hw *hw);\n+\n+#endif /* _FM10K_CONFIG_H */\ndiff --git a/drivers/net/fm10k/switch/fm10k_ffu.c b/drivers/net/fm10k/switch/fm10k_ffu.c\nnew file mode 100644\nindex 0000000..c2e8491\n--- /dev/null\n+++ b/drivers/net/fm10k/switch/fm10k_ffu.c\n@@ -0,0 +1,1209 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2019   Silicom Ltd. Connectivity Solutions\n+ */\n+\n+#include <rte_time.h>\n+#include <rte_kvargs.h>\n+#include <rte_hash.h>\n+#include <rte_flow.h>\n+#include <rte_flow_driver.h>\n+#include <rte_tm_driver.h>\n+\n+#include \"../base/fm10k_type.h\"\n+#include \"../base/fm10k_osdep.h\"\n+\n+#include \"../fm10k.h\"\n+#include \"../fm10k_logs.h\"\n+#include \"fm10k_debug.h\"\n+#include \"fm10k_regs.h\"\n+#include \"fm10k_switch.h\"\n+#include \"fm10k_config.h\"\n+#include \"fm10k_ffu.h\"\n+#include \"fm10k_stats.h\"\n+\n+/*\n+ * one SLICE for 40bits SEL\n+ * SLICE 28   FOR SEL SGLORT(16bits) and VLAN(16bits)\n+ *            FOR ACT ROUTE\n+ * SLICE 29   FOR SEL ETHER_TYPE(16bits)\n+ *\t\t\t  FOR ACT MIRROR | SET_VLAN\n+ * SLICE 30   FOR SEL MPLS_LABEL0(32bits)\n+ * SLICE 31   FOR SEL MPLS_LABEL1(32bits)\n+ */\n+#define FM10K_FFU_SLICE_START\t\t\t28\n+#define FM10K_FFU_SLICE_SGLORT_VID\t\t28\n+#define FM10K_FFU_SLICE_ETYPE_VID2\t\t29\n+#define FM10K_FFU_SLICE_MPLS_LABEL0\t\t30\n+#define FM10K_FFU_SLICE_MPLS_LABEL1\t\t31\n+\n+#define FM10K_FFU_SLICE_SGLORT_VLAN_CFG\t    \\\n+\t\t(FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_0, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_SGLORT) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_1, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_SGLORT) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_2, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_VPRI_VID) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_3, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_VPRI_VID) | \\\n+\t\tFM10K_SW_FFU_SLICE_CFG_START_ACTION | \\\n+\t\tFM10K_SW_FFU_SLICE_CFG_START_COMPARE | \\\n+\t\tFM10K_SW_FFU_SLICE_CFG_VALID_LOW)\n+\n+#define FM10K_FFU_SLICE_ETHER_TYPE_CFG\t    \\\n+\t\t(FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_0, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L2_TYPE) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_1, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L2_TYPE) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_2, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_VPRI2_VID2) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_3, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_VPRI2_VID2) | \\\n+\t\tFM10K_SW_FFU_SLICE_CFG_VALID_LOW)\n+\n+#define FM10K_FFU_SLICE_MPLS_LABEL0_CFG\t    \\\n+\t\t(FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_0, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L3_SIP_127_96) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_1, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L3_SIP_127_96) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_2, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L3_SIP_127_96) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_3, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L3_SIP_127_96) | \\\n+\t\tFM10K_SW_FFU_SLICE_CFG_START_COMPARE | \\\n+\t\tFM10K_SW_FFU_SLICE_CFG_VALID_LOW)\n+\n+#define FM10K_FFU_SLICE_MPLS_LABEL1_CFG\t    \\\n+\t\t(FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_0, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L3_SIP_95_64) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_1, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L3_SIP_95_64) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_2, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L3_SIP_95_64) | \\\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_CFG_SELECT_3, \\\n+\t\t\t\tFM10K_SW_FFU_MUX_SEL_L3_SIP_95_64) | \\\n+\t\tFM10K_SW_FFU_SLICE_CFG_START_COMPARE | \\\n+\t\tFM10K_SW_FFU_SLICE_CFG_VALID_LOW)\n+\n+static uint64_t fm10k_ffu_slice_cfgs[4] = {\n+\t\tFM10K_FFU_SLICE_SGLORT_VLAN_CFG,\n+\t\tFM10K_FFU_SLICE_ETHER_TYPE_CFG,\n+\t\tFM10K_FFU_SLICE_MPLS_LABEL0_CFG,\n+\t\tFM10K_FFU_SLICE_MPLS_LABEL1_CFG\n+};\n+\n+#define FM10K_FFU_INIT_PRINT(cfg, ...)\t\tdo { \\\n+\tif (fm10k_config_check_debug(cfg, FM10K_CONFIG_DEBUG_FFU_INIT)) \\\n+\t\tprintf(__VA_ARGS__); \\\n+} while (0)\n+\n+#define FM10K_FFU_RULE_PRINT(cfg, ...)\t\tdo { \\\n+\tif (fm10k_config_check_debug(cfg, FM10K_CONFIG_DEBUG_FFU_RULE)) \\\n+\t\tprintf(__VA_ARGS__); \\\n+} while (0)\n+\n+#define FM10K_FFU_CNT_INDEX(x)\t\t(FM10K_SW_FFU_CNT_START + (x))\n+\n+#define FM10K_FFU_FLOW_START\t\t10\n+#define FM10K_FFU_MIRROR_PROFILE\t1\n+\n+#define FM10K_FFU_SGLORT_TYPE_NULL\t0\n+#define FM10K_FFU_SGLORT_TYPE_EPL\t1\n+#define FM10K_FFU_SGLORT_TYPE_PF\t2\n+#define FM10K_FFU_SGLORT_TYPE_PFS\t3\n+#define FM10K_FFU_SGLORT_TYPE_DPDK\t4\n+\n+struct fm10k_ffu_rule_data {\n+\tuint16_t sglort_type;\n+\tuint16_t cond_sglort;\n+\tuint16_t cond_vlan;\n+\tuint16_t act_dglort;\n+\tuint16_t act_vlan;\n+\tuint16_t bypass_dglort;\n+\tuint16_t bypass_vlan;\n+};\n+\n+\n+static uint8_t fm10k_ffu_bitmap[FM10K_FFU_RULE_MAX / 8];\n+static uint8_t\n+fm10k_ffu_rule_get_bit(int id)\n+{\n+\tint num = id / 8;\n+\tint offset = id % 8;\n+\n+\treturn (fm10k_ffu_bitmap[num] >> offset) & 0x1;\n+}\n+\n+static void\n+fm10k_ffu_rule_set_bit(int id, uint8_t bit)\n+{\n+\tint num = id / 8;\n+\tint offset = id % 8;\n+\tuint8_t tmp = fm10k_ffu_bitmap[num];\n+\tuint8_t data = 1;\n+\n+\tif (bit == 0)\n+\t\tfm10k_ffu_bitmap[num] = tmp & ~(data << offset);\n+\telse\n+\t\tfm10k_ffu_bitmap[num] |= (data << offset);\n+}\n+\n+static int\n+fm10k_ffu_rule_alloc(void)\n+{\n+\tint i;\n+\n+\tfor (i = FM10K_FFU_FLOW_START; i < FM10K_FFU_RULE_MAX; i++)\t{\n+\t\tif (fm10k_ffu_rule_get_bit(i) != 0)\n+\t\t\tcontinue;\n+\t\tfm10k_ffu_rule_set_bit(i, 1);\n+\t\treturn i;\n+\t}\n+\treturn -1;\n+}\n+\n+static void\n+fm10k_ffu_rule_free(int id)\n+{\n+\tfm10k_ffu_rule_set_bit(id, 0);\n+}\n+\n+static void\n+fm10k_ffu_always_mismatch(struct fm10k_switch *sw,\n+\t\tunsigned int slice, unsigned int idx)\n+{\n+\tuint64_t temp64;\n+\n+\ttemp64 =\n+\t    FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY, ~0ULL) |\n+\t    FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY_TOP, ~0ULL);\n+\tfm10k_write_switch_reg128(sw, FM10K_SW_FFU_SLICE_TCAM(slice, idx),\n+\t    temp64, temp64);\n+}\n+\n+static void\n+fm10k_ffu_route_dglort(struct fm10k_switch *sw, unsigned int slice,\n+\t\t\tunsigned int idx, uint16_t sglort, uint16_t dglort)\n+{\n+\tuint64_t temp64, temp64_2;\n+\n+\t/*\n+\t * Set the key to exact match on the 16 SGLORT bits and\n+\t * always match everywhere else.\n+\t */\n+\ttemp64 = FM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY, sglort);\n+\ttemp64_2 =\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_TCAM_KEY, ~sglort & 0xffff);\n+\tfm10k_write_switch_reg128(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_TCAM(slice, idx),\n+\t\t\ttemp64_2, temp64);\n+\n+\t/*\n+\t * Set the corresponding SRAM entry to ROUTE_GLORT to the\n+\t * corresponding DGLORT.\n+\t */\n+\ttemp64 = 0x40;\n+\ttemp64 = temp64 << 32 |\n+\t    FM10K_SW_MAKE_REG_FIELD(FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT, dglort);\n+\ttemp64 |=\n+\t\tFM10K_SW_MAKE_REG_FIELD64(FFU_SLICE_SRAM_COMMAND,\n+\t    FM10K_SW_FFU_SLICE_SRAM_COMMAND_ROUTE_GLORT);\n+\t/*\n+\t * 11.5.4.2 FFU_SLICE_SRAM[0..31][0..1023]\n+\t */\n+\ttemp64_2 =\n+\t\tFM10K_SW_FFU_CNT_BANK << (35 - 23) |\n+\t\t(FM10K_SW_FFU_CNT_START + idx);\n+\ttemp64 |= temp64_2 << 23;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM(slice, idx), temp64);\n+}\n+\n+\n+static void\n+fm10k_ffu_set_dest_glort_mask(struct fm10k_switch *sw,\n+\t\tunsigned int idx, uint16_t dglort, uint64_t dport_mask)\n+{\n+\tuint64_t temp64;\n+\tunsigned int multiple_dports;\n+\tunsigned int num_dports;\n+\tunsigned int amplification_factor;\n+\tunsigned int hashed_entries;\n+\tunsigned int i, j;\n+\n+\tmultiple_dports = (dport_mask & (dport_mask - 1));\n+\n+\tFM10K_FFU_INIT_PRINT(sw->dpdk_cfg,\n+\t\t\t\"%s set glort %#x to port \", __func__, dglort);\n+\t/*\n+\t * Create an exact-match key for the given DGLORT in the DGLORT CAM.\n+\t */\n+\tfm10k_write_switch_reg(sw, FM10K_SW_GLORT_CAM(idx),\n+\t    FM10K_SW_MAKE_REG_FIELD(GLORT_CAM_KEY, dglort) |\n+\t    FM10K_SW_MAKE_REG_FIELD(GLORT_CAM_KEY_INVERT, ~dglort));\n+\n+\tif (multiple_dports) {\n+\t\t/*\n+\t\t * Create a pair of entries and use the hash value to select\n+\t\t * among them.\n+\t\t */\n+\t\tnum_dports = 0;\n+\t\tfor (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++)\n+\t\t\tif (dport_mask & (1ULL << i)) {\n+\t\t\t\tnum_dports++;\n+\t\t\t\tFM10K_FFU_INIT_PRINT(sw->dpdk_cfg, \" %d\", i);\n+\t\t\t}\n+\t\tFM10K_FFU_INIT_PRINT(sw->dpdk_cfg, \"\\n\");\n+\n+\t\t/*\n+\t\t * Create multiple entries for each dport to increase the\n+\t\t * hash modulus and capture more hash entropy.  The maximum\n+\t\t * number of hashed entries is 16.\n+\t\t */\n+\t\tamplification_factor = 16 / num_dports;\n+\t\thashed_entries = num_dports * amplification_factor;\n+\t\ttemp64 =\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_STRICT,\n+\t\t    FM10K_SW_GLORT_RAM_STRICT_HASHED);\n+\t\ttemp64 |=\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_INDEX,\n+\t\t\tsw->glort_dest_table_idx);\n+\t\ttemp64 |=\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_COUNT,\n+\t\t\thashed_entries);\n+\t\tfm10k_write_switch_reg64(sw, FM10K_SW_GLORT_RAM(idx), temp64);\n+\n+\t\tfor (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++)\n+\t\t\tif (dport_mask & (1ULL << i))\n+\t\t\t\tfor (j = 0; j < amplification_factor; j++) {\n+\t\t\t\t\tfm10k_write_switch_reg64(sw,\n+\t\t\t\t\t    FM10K_SW_GLORT_DEST_TABLE\n+\t\t\t\t\t\t(sw->glort_dest_table_idx),\n+\t\t\t\t\t    FM10K_SW_MAKE_REG_FIELD64\n+\t\t\t\t\t\t(GLORT_DEST_TABLE_MASK,\n+\t\t\t\t\t\t(1ULL << i)));\n+\t\t\t\t\tsw->glort_dest_table_idx++;\n+\t\t\t\t}\n+\t} else {\n+\t\t/*\n+\t\t * Set the corresponding entry in the DGLORT map RAM to use\n+\t\t * strict indexing straight into the DEST_TABLE, then write\n+\t\t * the corresponding destination port in the DEST_TABLE.\n+\t\t */\n+\n+\t\ttemp64 =\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_STRICT,\n+\t\t    FM10K_SW_GLORT_RAM_STRICT_STRICT);\n+\t\ttemp64 |=\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_INDEX,\n+\t\t\tsw->glort_dest_table_idx);\n+\t\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_GLORT_RAM(idx), temp64);\n+\n+\t\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_GLORT_DEST_TABLE(sw->glort_dest_table_idx),\n+\t\t    FM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(GLORT_DEST_TABLE_MASK,\n+\t\t\tdport_mask));\n+\t\tsw->glort_dest_table_idx++;\n+\t\tfor (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++)\n+\t\t\tif (dport_mask & (1ULL << i))\n+\t\t\t\tFM10K_FFU_INIT_PRINT(sw->dpdk_cfg, \" %d\\n\", i);\n+\t}\n+}\n+\n+\n+static uint32_t\n+fm10k_ffu_set_dest_glort_multi_cast(struct fm10k_switch *sw,\n+\t\tuint8_t lport1, uint8_t lport2,\n+\t\tuint16_t vlan1, uint16_t vlan2)\n+{\n+\tuint32_t dglort;\n+\tbool is_new;\n+\tuint32_t idx;\n+\tuint64_t temp64;\n+\n+\tdglort =\n+\t\tfm10k_switch_multi_glort_get(lport1, lport2,\n+\t\t\t\tvlan1, vlan2, &is_new);\n+\n+\tif (!is_new)\n+\t\treturn dglort;\n+\n+\tFM10K_FFU_INIT_PRINT(sw->dpdk_cfg,\n+\t\t\t\"%s set glort %#x to (%d:%d) (%d:%d)\\n\",\n+\t\t\t__func__, dglort, lport1, vlan1, lport2, vlan2);\n+\t/*\n+\t * Create an exact-match key for the given DGLORT in the DGLORT CAM.\n+\t */\n+\tidx = sw->glort_cam_ram_idx++;\n+\tfm10k_write_switch_reg(sw, FM10K_SW_GLORT_CAM(idx),\n+\t    FM10K_SW_MAKE_REG_FIELD(GLORT_CAM_KEY, dglort) |\n+\t    FM10K_SW_MAKE_REG_FIELD(GLORT_CAM_KEY_INVERT, ~dglort));\n+\n+\t/*\n+\t * Create multiple entries for each dport to increase the\n+\t * hash modulus and capture more hash entropy.  The maximum\n+\t * number of hashed entries is 16.\n+\t */\n+\ttemp64 =\n+\t\tFM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_STRICT,\n+\t    FM10K_SW_GLORT_RAM_STRICT_STRICT);\n+\ttemp64 |=\n+\t\tFM10K_SW_MAKE_REG_FIELD64(GLORT_RAM_DEST_INDEX,\n+\t\tsw->glort_dest_table_idx);\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_GLORT_RAM(idx), temp64);\n+\n+\t/* GLORT_DEST_TABLE\n+\t * Field Name\t\tBit(s)\tType\tDefault\n+\t * DestMask\t\t\t47:0\tRW\t\t0x0\n+\t * IP_MulticastIndex59:48\tRW\t\t0x0\n+\t * Reserved\t\t\t63:60\tRSV\t\t0x0\n+\t */\n+\ttemp64 = sw->mcast_dest_table_idx;\n+\ttemp64 = temp64 << 48 | 1 << lport1 | 1 << lport2;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_GLORT_DEST_TABLE\n+\t\t\t(sw->glort_dest_table_idx), temp64);\n+\tsw->glort_dest_table_idx++;\n+\n+\t/* MCAST_DEST_TABLE\n+\t * Field Name\t\tBit(s)\tType\tDefault\n+\t * PortMask\t\t\t47:0\tRW\t\t0x0\n+\t * LenTableIdx\t\t61:48\tRW\t\t0x0\n+\t * Reserved\t\t\t63:62\tRSV\t\t00b\n+\t */\n+\ttemp64 = sw->mcast_len_table_idx;\n+\ttemp64 = 1 << lport1 | 1 << lport2 | temp64 << 48;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_SCHED_MCAST_DEST_TABLE\n+\t\t\t(sw->mcast_dest_table_idx++), temp64);\n+\n+\t/* MCAST_LEN_TABLE\n+\t * Field Name\t\tBit(s)\tType\tDefault\n+\t * L3_McastIdx\t\t14:0\tRW\t\t0x0\n+\t * L3_Repcnt\t\t26:15\tRW\t\t0x0\n+\t * Reserved\t\t\t31:27\tRSV\t\t0x0\n+\t */\n+\ttemp64 =\n+\t\tsw->mcast_vlan_table_idx | 1 << 15;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_SCHED_MCAST_LEN_TABLE\n+\t\t\t(sw->mcast_len_table_idx++), temp64);\n+\n+\t/* MCAST_VLAN_TABLE\n+\t * Field Name\t\tBit(s)\tType\tDefault\n+\t * VID\t\t\t\t11:0\tRW\t\t0x0\n+\t * DGLORT\t\t\t27:12\tRW\t\t0x0\n+\t * ReplaceVID\t\t28\t\tRW\t\t0b\n+\t * ReplaceDGLORT\t29\t\tRW\t\t0b\n+\t * Reserved\t\t\t31:30\tRSV\t\t00b\n+\t */\n+\ttemp64 = vlan1 |\n+\t\t\tfm10k_switch_pf_glort_get\n+\t\t\t(lport1) << 12 | 1 << 28 | 1 << 29;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_MOD_MCAST_VLAN_TABLE\n+\t\t\t(sw->mcast_vlan_table_idx++), temp64);\n+\ttemp64 = vlan2 |\n+\t\t\tfm10k_switch_pf_glort_get\n+\t\t\t(lport2) << 12 | 1 << 28 | 1 << 29;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_MOD_MCAST_VLAN_TABLE\n+\t\t\t(sw->mcast_vlan_table_idx++), temp64);\n+\n+\treturn dglort;\n+}\n+\n+static uint64_t\n+fm10k_data64_field64_get(uint64_t data, int start, int end)\n+{\n+\tuint64_t tmp64 = data;\n+\n+\tif (start == end) {\n+\t\ttmp64 = (data >> start) & 1;\n+\t} else {\n+\t\ttmp64 = tmp64 << (64 - end);\n+\t\ttmp64 = tmp64 >> (64 - end + start);\n+\t}\n+\treturn tmp64;\n+}\n+\n+static uint32_t\n+fm10k_data64_field32_get(uint64_t data, int start, int end)\n+{\n+\tuint64_t tmp64 = data;\n+\tuint32_t tmp32;\n+\n+\tif (start == end) {\n+\t\ttmp32 = (data >> start) & 1;\n+\t} else {\n+\t\ttmp64 = tmp64 << (64 - end);\n+\t\ttmp32 = tmp64 >> (64 - end + start);\n+\t}\n+\treturn tmp32;\n+}\n+\n+static uint32_t\n+fm10k_data32_field_get(uint32_t data, int start, int end)\n+{\n+\tuint32_t tmp32 = data;\n+\n+\tif (start == end) {\n+\t\ttmp32 = (data >> start) & 1;\n+\t} else {\n+\t\ttmp32 = tmp32 << (64 - end);\n+\t\ttmp32 = tmp32 >> (64 - end + start);\n+\t}\n+\treturn tmp32;\n+}\n+\n+\n+static void\n+fm10k_glort_register_dump(struct fm10k_switch *sw)\n+{\n+\tuint32_t i;\n+\tuint64_t data64;\n+\tuint32_t data32;\n+\tuint32_t tmp32;\n+\n+\tif (!fm10k_config_check_debug\n+\t\t(sw->dpdk_cfg, FM10K_CONFIG_DEBUG_FFU_REG))\n+\t\treturn;\n+\n+\tprintf(\"----- GLORT -----\\n\");\n+\n+\tfor (i = 0; i < sw->glort_cam_ram_idx; i++)\t{\n+\t\tdata32 = fm10k_read_switch_reg(sw, FM10K_SW_GLORT_CAM(i));\n+\t\tprintf(\"[%02u]GLORT_CAM %#x Key %#x\\n\", i, data32,\n+\t\t\t\tfm10k_data32_field_get(data32, 0, 15));\n+\t\tdata64 = fm10k_read_switch_reg64(sw, FM10K_SW_GLORT_RAM(i));\n+\t\tprintf(\"    GLORT_RAM %#llx Strict %u DestIndex %u\\n\",\n+\t\t\t\t(unsigned long long)data64,\n+\t\t\t\tfm10k_data64_field32_get(data64, 0, 1),\n+\t\t\t\tfm10k_data64_field32_get(data64, 2, 13));\n+\t\ttmp32 = fm10k_data64_field32_get(data64, 2, 13);\n+\t\tdata64 =\n+\t\t\tfm10k_read_switch_reg64(sw,\n+\t\t\t\tFM10K_SW_GLORT_DEST_TABLE(tmp32));\n+\t\tprintf(\"    GLORT_DEST_TABLE[%u] %#llx IP_MulticastIndex %u\\n\",\n+\t\t\t\ttmp32, (unsigned long long)data64,\n+\t\t\t\tfm10k_data64_field32_get(data64, 48, 59));\n+\t\ttmp32 = fm10k_data64_field32_get(data64, 48, 59);\n+\t\tif (tmp32 == 0)\n+\t\t\tcontinue;\n+\t\tdata64 = fm10k_read_switch_reg64(sw,\n+\t\t\t\tFM10K_SW_SCHED_MCAST_DEST_TABLE(tmp32));\n+\t\tprintf(\"    SCHED_MCAST_DEST_TABLE[%u] %#llx PortMask %#llx\"\n+\t\t\t\t\" LenTableIdx %u\\n\", tmp32,\n+\t\t\t\t(unsigned long long)data64,\n+\t\t\t\t(unsigned long long)\n+\t\t\t\tfm10k_data64_field64_get(data64, 0, 47),\n+\t\t\t\tfm10k_data64_field32_get(data64, 48, 61));\n+\t\ttmp32 = fm10k_data64_field32_get(data64, 48, 61);\n+\t\tdata32 = fm10k_read_switch_reg(sw,\n+\t\t\t\tFM10K_SW_SCHED_MCAST_LEN_TABLE(tmp32));\n+\t\tprintf(\"    SCHED_MCAST_LEN_TABLE[%u] %#x \"\n+\t\t\t\t\"L3_McastIdx %u L3_Repcnt %u\\n\",\n+\t\t\t\ttmp32, data32,\n+\t\t\t\tfm10k_data32_field_get(data32, 0, 14),\n+\t\t\t\tfm10k_data32_field_get(data32, 15, 26));\n+\t\ttmp32 = fm10k_data32_field_get(data32, 0, 14);\n+\t\tdata32 = fm10k_read_switch_reg(sw,\n+\t\t\t\tFM10K_SW_MOD_MCAST_VLAN_TABLE(tmp32));\n+\t\tprintf(\"    MOD_MCAST_VLAN_TABLE[%u] %#x VID %u \"\n+\t\t\t\t\"DGLORT %#x ReplaceVID %u ReplaceDGLORT %u\\n\",\n+\t\t\t\ttmp32, data32,\n+\t\t\t\tfm10k_data32_field_get(data32, 0, 11),\n+\t\t\t\tfm10k_data32_field_get(data32, 12, 27),\n+\t\t\t\tfm10k_data32_field_get(data32, 28, 28),\n+\t\t\t\tfm10k_data32_field_get(data32, 29, 29));\n+\t\tdata32 = fm10k_read_switch_reg(sw,\n+\t\t\t\tFM10K_SW_MOD_MCAST_VLAN_TABLE(tmp32 + 1));\n+\t\tprintf(\"    MOD_MCAST_VLAN_TABLE[%u] %#x VID %u \"\n+\t\t\t\t\"DGLORT %#x ReplaceVID %u ReplaceDGLORT %u\\n\",\n+\t\t\t\ttmp32 + 1, data32,\n+\t\t\t\tfm10k_data32_field_get(data32, 0, 11),\n+\t\t\t\tfm10k_data32_field_get(data32, 12, 27),\n+\t\t\t\tfm10k_data32_field_get(data32, 28, 28),\n+\t\t\t\tfm10k_data32_field_get(data32, 29, 29));\n+\t}\n+}\n+\n+static void\n+fm10k_ffu_register_dump(struct fm10k_switch *sw)\n+{\n+\tint i, j;\n+\tuint32_t data[8];\n+\tuint32_t ffu_valid;\n+\n+\tif (!fm10k_config_check_debug(sw->dpdk_cfg, FM10K_CONFIG_DEBUG_FFU_REG))\n+\t\treturn;\n+\n+\tprintf(\"--------------- FFU REGISTERS DUMP ------------------\\n\");\n+\n+\tfm10k_read_switch_array(sw, FM10K_SW_FFU_MASTER_VALID, data, 2);\n+\tprintf(\"FFU_MASTER_VALID: %#x %#x\\n\", data[0], data[1]);\n+\tffu_valid = data[0];\n+\n+\tfor (i = 0; i < 32; i++) {\n+\t\tif ((ffu_valid & (1 << i)) == 0)\n+\t\t\tcontinue;\n+\n+\t\tprintf(\"------ SLICE%d ------\\n\", i);\n+\t\tfm10k_read_switch_array(sw,\n+\t\t\t\tFM10K_SW_FFU_SLICE_VALID(i), data, 2);\n+\t\tif (data[0] != 0 || data[1] != 0)\n+\t\t\tprintf(\"FFU_SLICE_VALID[%d]: %#x %#x\\n\",\n+\t\t\t\ti, data[0], data[1]);\n+\n+\t\tfm10k_read_switch_array(sw,\n+\t\t\t\tFM10K_SW_FFU_SLICE_CASCADE_ACTION(i), data, 2);\n+\t\tif (data[0] != 0 || data[1] != 0)\n+\t\t\tprintf(\"FFU_SLICE_CASCADE_ACTION[%d]: %#x %#x\\n\",\n+\t\t\t\ti, data[0], data[1]);\n+\n+\t\tfor (j = 0; j < 1; j++) {\n+\t\t\tfm10k_read_switch_array(sw,\n+\t\t\t\t\tFM10K_SW_FFU_SLICE_CFG(i, j), data, 2);\n+\t\t\tif (data[0] != 0 || data[1] != 0)\n+\t\t\t\tprintf(\"FFU_SLICE_CFG[%d][%d]: %#x %#x\\n\",\n+\t\t\t\t\t\ti, j, data[0], data[1]);\n+\t\t}\n+\t\tfor (j = 0; j < 32; j++) {\n+\t\t\tfm10k_read_switch_array(sw,\n+\t\t\t\t\tFM10K_SW_FFU_SLICE_TCAM(i, j), data, 4);\n+\t\t\tif ((data[0] != 0 || data[1] != 0 ||\n+\t\t\t\t\tdata[2] != 0 || data[3] != 0))\n+\t\t\t\tprintf(\"FFU_SLICE_TCAM[%d][%d]: %#x %#x %#x %#x\\n\",\n+\t\t\t\t\ti, j, data[0], data[1],\n+\t\t\t\t\tdata[2], data[3]);\n+\n+\t\t\tfm10k_read_switch_array(sw,\n+\t\t\t\t\tFM10K_SW_FFU_SLICE_SRAM(i, j), data, 2);\n+\t\t\tif (data[0] != 0 || data[1] != 0)\n+\t\t\t\tprintf(\"FFU_SLICE_SRAM[%d][%d]: %#x %#x\\n\",\n+\t\t\t\t\ti, j, data[0], data[1]);\n+\t\t}\n+\t}\n+}\n+\n+\n+static void\n+fm10k_ffu_mirror_set_action(struct fm10k_switch *sw,\n+\t\tuint16_t ffu_slice,\tuint16_t table_idx)\n+{\n+\tuint64_t data64;\n+\n+\t/* blank the next ffu slice */\n+\tfm10k_write_switch_reg128(sw,\n+\t\tFM10K_SW_FFU_SLICE_TCAM\n+\t\t(ffu_slice, table_idx), 0xffffffffff, 0x1);\n+\t/* SET FFU RX_MIRROR */\n+\tdata64 = 0x60; /* higher than route, not necessary */\n+\tdata64 = data64 << 32 | 0x2 << 21 | 1 << (8 + 4) | 1 << 4;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM(ffu_slice, table_idx), data64);\n+}\n+\n+static void\n+fm10k_ffu_mirror_set_forward(struct fm10k_switch *sw,\n+\t\tint profile,\n+\t\tuint16_t vlan,\n+\t\tuint16_t dest_lport,\n+\t\tuint32_t dest_sglort)\n+{\n+\tuint64_t data64;\n+\n+\t/* RX_MIRROR_CFG */\n+\tfm10k_write_switch_reg(sw, 0xd50000 + 0xd, profile);\n+\n+\t/* FH_MIRROR_PROFILE_TABLE */\n+\tfm10k_write_switch_reg(sw,\n+\t\t\t0xd50000 + 0x1 * profile + 0x40, dest_lport);\n+\n+\t/* MOD_MIRROR_PROFILE_TABLE don't work */\n+\tdata64 = vlan;\n+\tdata64 = (dest_sglort & 0xffff) | data64 << 17;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\t0xe80000 + 0x2 * profile + 0x24000, data64);\n+}\n+\n+\n+int\n+fm10k_ffu_mirror_set(struct fm10k_switch *sw,\n+\t\tuint16_t src_ext_port,\n+\t\tuint16_t dest_ext_port,\n+\t\tuint16_t vlan)\n+{\n+\tuint16_t table_idx;\n+\tuint16_t ffu_slice = FM10K_FFU_SLICE_SGLORT_VID + 1;\n+\tuint16_t mirror_profile = FM10K_FFU_MIRROR_PROFILE;\n+\n+\ttable_idx = FM10K_FFU_EXT_PORT_RULE_INGRESS(src_ext_port - 1);\n+\tfm10k_ffu_mirror_set_action(sw, ffu_slice, table_idx);\n+\n+\tfm10k_ffu_mirror_set_forward(sw, mirror_profile,\n+\t\t\tvlan, sw->epl_map[dest_ext_port - 1].logical_port,\n+\t\t\tsw->epl_map[dest_ext_port - 1].glort);\n+\treturn 0;\n+}\n+\n+int\n+fm10k_ffu_mirror_reset(struct fm10k_switch *sw, int src_ext_port)\n+{\n+\tuint16_t table_idx;\n+\tuint16_t ffu_slice = FM10K_FFU_SLICE_SGLORT_VID + 1;\n+\n+\ttable_idx = FM10K_FFU_EXT_PORT_RULE_INGRESS(src_ext_port - 1);\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM(ffu_slice, table_idx), 0);\n+\treturn 0;\n+}\n+\n+static void\n+fm10k_ffu_logical_port_vlan_set(struct fm10k_switch *sw,\n+\t\tuint16_t lport, uint16_t vlan_id)\n+{\n+\tuint64_t data;\n+\n+\t/* 11.21.3.9 INGRESS_VID_TABLE[0..4095] */\n+\tdata = fm10k_read_switch_reg64(sw,\n+\t\t\t0xE80000 + 0x2 * vlan_id + 0x20000);\n+\tdata |= 1 << lport;\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\t0xE80000 + 0x2 * vlan_id + 0x20000, data);\n+\n+\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg,\n+\t\t\t\"%s lport:%d, vlan_id:%d, reg:%#llx\\n\",\n+\t\t\t__func__, lport, vlan_id, (unsigned long long)data);\n+}\n+\n+static void\n+fm10k_ffu_glort_port_vlan_set(struct fm10k_switch *sw,\n+\t\tuint16_t glort, uint16_t vlan_id)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < FM10K_SW_PEPS_SUPPORTED; i++) {\n+\t\tif (sw->pep_map[i].glort == glort) {\n+\t\t\tfm10k_ffu_logical_port_vlan_set(sw,\n+\t\t\t\t\tsw->pep_map[i].logical_port, vlan_id);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tfor (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {\n+\t\tif (sw->epl_map[i].glort == glort) {\n+\t\t\tfm10k_ffu_logical_port_vlan_set(sw,\n+\t\t\t\t\tsw->epl_map[i].logical_port, vlan_id);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+}\n+\n+\n+static uint16_t\n+fm10k_ffu_dpdk_port_glort_get(struct fm10k_switch *sw, int port)\n+{\n+\tint pf;\n+\tuint16_t glort = 0;\n+\n+\tif (sw->dpdk_cfg->dpdk_port_map[port].type ==\n+\t\t\tFM10K_CONFIG_PORT_MAP_PFS ||\n+\t\tsw->dpdk_cfg->dpdk_port_map[port].type ==\n+\t\t\tFM10K_CONFIG_PORT_MAP_PFSS) {\n+\t\tglort = fm10k_switch_pfs_glort_get\n+\t\t\t\t(sw->dpdk_cfg->dpdk_port_map[port].map_no[0],\n+\t\t\t\tsw->dpdk_cfg->dpdk_port_map[port].map_no[1]);\n+\t} else if (sw->dpdk_cfg->dpdk_port_map[port].type ==\n+\t\t\tFM10K_CONFIG_PORT_MAP_PF) {\n+\t\tpf = sw->dpdk_cfg->dpdk_port_map[port].map_no[0];\n+\t\tglort = fm10k_switch_pf_glort_get(pf);\n+\t}\n+\treturn glort;\n+}\n+\n+static void\n+fm10k_ffu_rule_enable_single_cast(struct fm10k_switch *sw,\n+\t\tint rule_id,\n+\t\tuint16_t sglort,\n+\t\tuint16_t svlan,\n+\t\tuint16_t dglort,\n+\t\tuint16_t dvlan)\n+{\n+\tuint64_t temp64;\n+\tuint64_t sglort_vid_tcam = 0, sglort_vid_tcam_mask = 0;\n+\tuint64_t sram[4] = { 0, 0, 0, 0 };\n+\tuint16_t sram_idx = 0, tcam_slice, sram_slice, i;\n+\n+\tsglort_vid_tcam |= sglort;\n+\tsglort_vid_tcam_mask |= 0xffff;\n+\tif (svlan) {\n+\t\ttemp64 = svlan;\n+\t\tsglort_vid_tcam |= temp64 << 16;\n+\t\tsglort_vid_tcam_mask |= 0xfff0000;\n+\t\tfm10k_ffu_glort_port_vlan_set(sw, sglort, svlan);\n+\t}\n+\n+\t/* set counter */\n+\tsram[sram_idx] |=\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_COUNTER_BANK,\n+\t\t\tFM10K_SW_FFU_CNT_BANK) |\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_COUNTER_INDEX,\n+\t\t\tFM10K_FFU_CNT_INDEX(rule_id));\n+\n+\tsram[sram_idx] |=\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_PRECEDENCE, 3) |\n+\t\t    FM10K_SW_MAKE_REG_FIELD\n+\t\t\t(FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT, dglort) |\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_COMMAND,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM_COMMAND_ROUTE_GLORT);\n+\tsram_idx++;\n+\n+\tif (dvlan) {\n+\t\t/* Force updating VLAN tag if present.\n+\t\t * Add if absent. 11.5.3.4\n+\t\t */\n+\t\ttemp64 = 3;\n+\t\tsram[sram_idx] =\n+\t\t\ttemp64 << 16 | dvlan |\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_PRECEDENCE, 2) |\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_COMMAND,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM_COMMAND_FIELD_SET);\n+\t\tfm10k_ffu_glort_port_vlan_set(sw, dglort, dvlan);\n+\t\tsram_idx++;\n+\t}\n+\n+\tif (sglort_vid_tcam) {\n+\t\ttcam_slice = FM10K_FFU_SLICE_SGLORT_VID;\n+\t\ttemp64 =\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_TCAM_KEY,\n+\t\t\t~sglort_vid_tcam & sglort_vid_tcam_mask);\n+\t\tfm10k_write_switch_reg128(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_TCAM(tcam_slice, rule_id),\n+\t\t\ttemp64, sglort_vid_tcam);\n+\t\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg,\n+\t\t\t\"TCAM slice:%d, rule:%d, data0:%#llx, data1:%#llx\\n\",\n+\t\t\ttcam_slice, rule_id,\n+\t\t\t(unsigned long long)sglort_vid_tcam,\n+\t\t\t(unsigned long long)temp64);\n+\t}\n+\n+\t/* blank the next SLICE TCAM */\n+\tfm10k_ffu_always_mismatch(sw, tcam_slice + 1, rule_id);\n+\n+\tfor (i = 0; i < sram_idx; i++) {\n+\t\tsram_slice = FM10K_FFU_SLICE_START + i;\n+\t\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM(sram_slice, rule_id), sram[i]);\n+\t\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg,\n+\t\t\t\"SRAM slice:%d, rule:%d, data:%#llx\\n\",\n+\t\t\tsram_slice, rule_id, (unsigned long long)sram[i]);\n+\t}\n+\t/* disable the next SLICE SRAM */\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM(sram_slice + 1, rule_id), 0);\n+\n+\tfm10k_stats_rule_count_reg(rule_id);\n+}\n+\n+static void\n+fm10k_ffu_rule_enable_multi_cast(struct fm10k_switch *sw,\n+\t\tint rule_id,\n+\t\tuint16_t sglort,\n+\t\tuint16_t svlan,\n+\t\tuint8_t lport1,\n+\t\tuint8_t lport2,\n+\t\tuint16_t vlan1,\n+\t\tuint16_t vlan2)\n+{\n+\tuint64_t temp64;\n+\tuint32_t dglort;\n+\tuint64_t sglort_vid_tcam = 0, sglort_vid_tcam_mask = 0;\n+\tuint64_t sram[4] = { 0, 0, 0, 0 };\n+\tuint16_t sram_idx = 0, tcam_slice, sram_slice, i;\n+\n+\tdglort =\n+\t\tfm10k_ffu_set_dest_glort_multi_cast(sw,\n+\t\t\t\tlport1, lport2, vlan1, vlan2);\n+\n+\tsglort_vid_tcam |= sglort;\n+\tsglort_vid_tcam_mask |= 0xffff;\n+\tif (svlan) {\n+\t\ttemp64 = svlan;\n+\t\tsglort_vid_tcam |= temp64 << 16;\n+\t\tsglort_vid_tcam_mask |= 0xfff0000;\n+\t\tfm10k_ffu_glort_port_vlan_set(sw, sglort, svlan);\n+\t}\n+\n+\tfm10k_ffu_logical_port_vlan_set(sw, lport1, vlan1);\n+\tfm10k_ffu_logical_port_vlan_set(sw, lport2, vlan2);\n+\n+\t/* set counter */\n+\tsram[sram_idx] |=\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_COUNTER_BANK,\n+\t\t\tFM10K_SW_FFU_CNT_BANK) |\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_COUNTER_INDEX,\n+\t\t\tFM10K_FFU_CNT_INDEX(rule_id));\n+\n+\tsram[sram_idx] |=\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_PRECEDENCE, 3) |\n+\t\t    FM10K_SW_MAKE_REG_FIELD\n+\t\t\t(FFU_SLICE_SRAM_ROUTE_GLORT_DGLORT, dglort) |\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_SRAM_COMMAND,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM_COMMAND_ROUTE_GLORT);\n+\tsram_idx++;\n+\n+\tif (sglort_vid_tcam) {\n+\t\ttcam_slice = FM10K_FFU_SLICE_SGLORT_VID;\n+\t\ttemp64 =\n+\t\t\tFM10K_SW_MAKE_REG_FIELD64\n+\t\t\t(FFU_SLICE_TCAM_KEY,\n+\t\t\t~sglort_vid_tcam & sglort_vid_tcam_mask);\n+\t\tfm10k_write_switch_reg128(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_TCAM(tcam_slice, rule_id),\n+\t\t\ttemp64, sglort_vid_tcam);\n+\t\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg,\n+\t\t\t\"TCAM slice:%d, rule:%d, data0:%#llx, data1:%#llx\\n\",\n+\t\t\ttcam_slice, rule_id,\n+\t\t\t(unsigned long long)sglort_vid_tcam,\n+\t\t\t(unsigned long long)temp64);\n+\t}\n+\n+\t/* blank the next SLICE TCAM */\n+\tfm10k_ffu_always_mismatch(sw, tcam_slice + 1, rule_id);\n+\n+\tfor (i = 0; i < sram_idx; i++) {\n+\t\tsram_slice = FM10K_FFU_SLICE_START + i;\n+\t\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM(sram_slice, rule_id), sram[i]);\n+\t\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg,\n+\t\t\t\"SRAM slice:%d, rule:%d, data:%#llx\\n\",\n+\t\t\tsram_slice, rule_id, (unsigned long long)sram[i]);\n+\t}\n+\t/* disable the next SLICE SRAM */\n+\tfm10k_write_switch_reg64(sw,\n+\t\t\tFM10K_SW_FFU_SLICE_SRAM(sram_slice + 1, rule_id), 0);\n+\n+\tfm10k_stats_rule_count_reg(rule_id);\n+}\n+\n+\n+void\n+fm10k_ffu_flow_enable(struct fm10k_switch *sw, struct fm10k_cfg_flow *flow)\n+{\n+\tuint16_t sglort = 0;\n+\tuint16_t svlan = 0;\n+\tuint16_t dglort = 0;\n+\tuint16_t dvlan = 0;\n+\tuint16_t lport1 = 0, lport2 = 0;\n+\tuint16_t dvlan2 = 0;\n+\n+\tswitch (flow->src_port.port_type) {\n+\tcase FM10K_CONFIG_FLOW_EXT_PORT:\n+\t\tsglort = fm10k_switch_epl_glort_get(flow->src_port.port_no - 1);\n+\t\tbreak;\n+\tcase FM10K_CONFIG_FLOW_DPDK_PORT:\n+\t\tsglort =\n+\t\t\tfm10k_ffu_dpdk_port_glort_get(sw,\n+\t\t\tflow->src_port.port_no);\n+\t\tbreak;\n+\t}\n+\tswitch (flow->fw_port[0].port_type) {\n+\tcase FM10K_CONFIG_FLOW_EXT_PORT:\n+\t\tdglort =\n+\t\t\tfm10k_switch_epl_glort_get\n+\t\t\t(flow->fw_port[0].port_no - 1);\n+\t\tlport1 =\n+\t\t\tfm10k_switch_epl_logical_get\n+\t\t\t(flow->fw_port[0].port_no - 1);\n+\t\tbreak;\n+\tcase FM10K_CONFIG_FLOW_DPDK_PORT:\n+\t\tdglort =\n+\t\t\tfm10k_ffu_dpdk_port_glort_get\n+\t\t\t(sw, flow->fw_port[0].port_no);\n+\t\tlport1 =\n+\t\t\tfm10k_switch_pf_logical_get\n+\t\t\t(flow->fw_port[0].port_no);\n+\t\tbreak;\n+\t}\n+\tsvlan = flow->src_port.vlan_id;\n+\tdvlan = flow->fw_port[0].vlan_id;\n+\n+\tflow->rule_id = fm10k_ffu_rule_alloc();\n+\n+\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg,\n+\t\t\"Set rule cond sglort:%#x, vlan:%d ==> \"\n+\t\t\"act dglort:%#x, vlan:%d\",\n+\t\tsglort, svlan, dglort, dvlan);\n+\n+\tif (flow->fw_port[1].port_type)\t{\n+\t\tswitch (flow->fw_port[1].port_type)\t{\n+\t\tcase FM10K_CONFIG_FLOW_EXT_PORT:\n+\t\t\tdglort =\n+\t\t\t\tfm10k_switch_epl_glort_get\n+\t\t\t\t(flow->fw_port[1].port_no - 1);\n+\t\t\tlport2 =\n+\t\t\t\tfm10k_switch_epl_logical_get\n+\t\t\t\t(flow->fw_port[1].port_no - 1);\n+\t\t\tbreak;\n+\t\tcase FM10K_CONFIG_FLOW_DPDK_PORT:\n+\t\t\tdglort =\n+\t\t\t\tfm10k_ffu_dpdk_port_glort_get\n+\t\t\t\t(sw, flow->fw_port[1].port_no);\n+\t\t\tlport2 =\n+\t\t\t\tfm10k_switch_pf_logical_get\n+\t\t\t\t(flow->fw_port[1].port_no);\n+\t\t\tbreak;\n+\t\t}\n+\t\tdvlan2 = flow->fw_port[1].vlan_id;\n+\t\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg,\n+\t\t\t\" (bypass glort:%#x, vlan:%d)\\n\",\n+\t\t\tdglort, dvlan2);\n+\n+\t\tfm10k_ffu_rule_enable_multi_cast(sw,\n+\t\t\tflow->rule_id, sglort, svlan,\n+\t\t\tlport1, lport2, dvlan, dvlan2);\n+\t} else {\n+\t\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg, \"\\n\");\n+\t\tfm10k_ffu_rule_enable_single_cast(sw,\n+\t\t\tflow->rule_id, sglort, svlan, dglort, dvlan);\n+\t}\n+}\n+\n+\n+void\n+fm10k_ffu_flow_disable(struct fm10k_switch *sw, struct fm10k_cfg_flow *flow)\n+{\n+\tint i;\n+\n+\tif (flow->rule_id == 0)\n+\t\treturn;\n+\n+\tFM10K_FFU_RULE_PRINT(sw->dpdk_cfg,\n+\t\t\t\"Remove flow %d rule %d\\n\",\n+\t\t\tflow->flow_no, flow->rule_id);\n+\n+\tfor (i = FM10K_FFU_SLICE_START; i < FM10K_SW_FFU_NUM_SLICES; i++) {\n+\t\tfm10k_ffu_always_mismatch(sw, i, flow->rule_id);\n+\t\tfm10k_write_switch_reg64(sw,\n+\t\t\t\tFM10K_SW_FFU_SLICE_SRAM(i, flow->rule_id), 0);\n+\t}\n+\tfm10k_ffu_rule_free(flow->rule_id);\n+}\n+\n+\n+static int\n+fm10k_ffu_configured_flowset_enable(struct fm10k_switch *sw)\n+{\n+\tstruct fm10k_cfg_flowset *flowset;\n+\tstruct fm10k_cfg_flow *flow;\n+\n+\tflowset = fm10k_config_flowset_current_get();\n+\tflow = flowset->flow_head.next;\n+\twhile (!fm10k_config_flow_list_end(&flowset->flow_head, flow)) {\n+\t\tfm10k_ffu_flow_enable(sw, flow);\n+\t\tflow = flow->next;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+\n+void\n+fm10k_ffu_flowset_switch(struct fm10k_switch *sw, const char *new_name)\n+{\n+\tstruct fm10k_cfg_flowset *flowset;\n+\tstruct fm10k_cfg_flowset *cur_fs;\n+\tstruct fm10k_cfg_flow *flow;\n+\n+\tcur_fs = fm10k_config_flowset_current_get();\n+\tif (strcmp(cur_fs->name, new_name) == 0)\n+\t\treturn;\n+\n+\tflowset = fm10k_config_flowset_get(new_name);\n+\tif (flowset == NULL) {\n+\t\tFM10K_SW_ERR(\"Can not find flowset %s!!\\n\", new_name);\n+\t\treturn;\n+\t}\n+\n+\t/* disable current flowset */\n+\tflow = cur_fs->flow_head.next;\n+\twhile (!fm10k_config_flow_list_end(&cur_fs->flow_head, flow)) {\n+\t\tfm10k_ffu_flow_disable(sw, flow);\n+\t\tflow = flow->next;\n+\t}\n+\n+\t/* enable new flowset */\n+\tfm10k_config_flowset_current_set(flowset);\n+\tflow = flowset->flow_head.next;\n+\twhile (!fm10k_config_flow_list_end(&flowset->flow_head, flow)) {\n+\t\tfm10k_ffu_flow_enable(sw, flow);\n+\t\tflow = flow->next;\n+\t}\n+}\n+\n+\n+int\n+fm10k_ffu_init(struct fm10k_switch *sw, struct fm10k_dpdk_cfg *cfg)\n+{\n+\tint ret = 0;\n+\tuint64_t data64;\n+\tuint16_t i, j;\n+\tuint32_t sglort = 0, dglort = 0;\n+\tuint16_t table_idx = 0;\n+\tuint16_t ffu_slice = FM10K_FFU_SLICE_START;\n+\n+\tsw->mcast_dest_table_idx = 1;\n+\tsw->mcast_len_table_idx = 1;\n+\tsw->mcast_vlan_table_idx = 1;\n+\n+\tfor (i = 0;\n+\t\t i < sizeof(fm10k_ffu_slice_cfgs) / sizeof(uint64_t);\n+\t\t i++) {\n+\t\tfor (j = 0; j < FM10K_SW_FFU_NUM_SCENARIOS; j++) {\n+\t\t\tdata64 = fm10k_ffu_slice_cfgs[i];\n+\t\t\tfm10k_write_switch_reg64(sw,\n+\t\t\t\t\tFM10K_SW_FFU_SLICE_CFG\n+\t\t\t\t\t(FM10K_FFU_SLICE_START + i, j),\n+\t\t\t\t\tdata64);\n+\t\t}\n+\t\tFM10K_FFU_INIT_PRINT(cfg, \"SET slice %d cfg = %#llx\\n\",\n+\t\t\t\tFM10K_FFU_SLICE_START + i,\n+\t\t\t\t(unsigned long long)data64);\n+\t}\n+\n+\tfor (table_idx = 0;\n+\t\t table_idx < FM10K_SW_FFU_SLICE_TCAM_ENTRIES / 2;\n+\t\t table_idx++)\n+\t\tfor (i = ffu_slice; i < FM10K_SW_FFU_NUM_SLICES; i++)\n+\t\t\tfm10k_ffu_always_mismatch(sw, i, table_idx);\n+\n+\t/*\n+\t * Create a TCAM entry to match each SGLORT that might be used, and\n+\t * set the corresponding SRAM action entries to ROUTE_GLORT to the\n+\t * corresponding DGLORT (see above table).\n+\t * SGLORT ROUTE is always the first slice\n+\t */\n+\tfor (i = 0; i < FM10K_SW_EXT_PORTS_MAX; i++) {\n+\t\tif (cfg->ext_port_map[i].type == FM10K_CONFIG_PORT_MAP_NULL)\n+\t\t\tcontinue;\n+\n+\t\tif (cfg->ext_port_map[i].type == FM10K_CONFIG_PORT_MAP_PF) {\n+\t\t\tsglort = fm10k_switch_epl_glort_get(i);\n+\t\t\tdglort =\n+\t\t\t\tfm10k_switch_pf_glort_get\n+\t\t\t\t(cfg->ext_port_map[i].map_no[0]);\n+\t\t} else if (cfg->ext_port_map[i].type ==\n+\t\t\t\t   FM10K_CONFIG_PORT_MAP_PFS) {\n+\t\t\tsglort = fm10k_switch_epl_glort_get(i);\n+\t\t\tdglort =\n+\t\t\t\tfm10k_switch_pfs_glort_get\n+\t\t\t\t(cfg->ext_port_map[i].map_no[0],\n+\t\t\t\tcfg->ext_port_map[i].map_no[1]);\n+\t\t}\n+\n+\t\ttable_idx = FM10K_FFU_EXT_PORT_RULE_INGRESS(i);\n+\t\tfm10k_ffu_route_dglort(sw,\n+\t\t\t\tffu_slice, table_idx, sglort, dglort);\n+\n+\t\t/* blank the next ffu slice */\n+\t\tfm10k_write_switch_reg128(sw,\n+\t\t\t\tFM10K_SW_FFU_SLICE_TCAM\n+\t\t\t\t(ffu_slice + 1, table_idx),\n+\t\t\t    0xffffffffff, 0x1);\n+\t\ttable_idx = FM10K_FFU_EXT_PORT_RULE_EGRESS(i);\n+\t\tfm10k_ffu_route_dglort(sw,\n+\t\t\t\tffu_slice, table_idx, dglort, sglort);\n+\n+\t\t/* blank the next ffu slice */\n+\t\tfm10k_write_switch_reg128(sw,\n+\t\t\t\tFM10K_SW_FFU_SLICE_TCAM\n+\t\t\t\t(ffu_slice + 1, table_idx),\n+\t\t\t    0xffffffffff, 0x1);\n+\t}\n+\n+\tfor (i = ffu_slice; i < FM10K_SW_FFU_NUM_SLICES; i++) {\n+\t\tfm10k_write_switch_reg64(sw,\n+\t\t\t\tFM10K_SW_FFU_SLICE_CASCADE_ACTION(i),\n+\t\t\t\t0xf0f000f);\n+\t\t/* Set slice 0 to valid for all scenarios */\n+\t\tfm10k_write_switch_reg64(sw,\n+\t\t\t\tFM10K_SW_FFU_SLICE_VALID(i),\n+\t\t\t\tFM10K_SW_FFU_SLICE_VALID_ALL_SCENARIOS);\n+\t}\n+\n+\t/* Mark slice 0 as valid and all chunks as invalid */\n+\tdata64 = 0;\n+\tfor (i = ffu_slice; i < FM10K_SW_FFU_NUM_SLICES; i++)\n+\t\tdata64 |= FM10K_SW_FFU_MASTER_VALID_SLICE_VALID(i);\n+\tfm10k_write_switch_reg64(sw, FM10K_SW_FFU_MASTER_VALID, data64);\n+\n+\t/*\n+\t * Set up the DGLORT map according to the desired\n+\t * SGLORT -> { DGLORT, logical_port } map.\n+\t */\n+\tfor (i = 0; i < sw->info->num_peps; i++) {\n+\t\tif (sw->pep_map[i].glort == 0)\n+\t\t\tcontinue;\n+\t\tfm10k_ffu_set_dest_glort_mask(sw,\n+\t\t\t\tsw->glort_cam_ram_idx++,\n+\t\t\t\tsw->pep_map[i].glort,\n+\t\t\t\tFM10K_SW_DPORT_MASK\n+\t\t\t\t(sw->pep_map[i].logical_port));\n+\t}\n+\n+\tfor (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {\n+\t\tif (sw->epl_map[i].glort == 0)\n+\t\t\tcontinue;\n+\t\tfm10k_ffu_set_dest_glort_mask(sw,\n+\t\t\t\tsw->glort_cam_ram_idx++,\n+\t\t\t\tsw->epl_map[i].glort,\n+\t\t\t\tFM10K_SW_DPORT_MASK\n+\t\t\t\t(sw->epl_map[i].logical_port));\n+\t}\n+\n+\tfor (i = 0; i < FM10K_SW_EXT_PORTS_MAX; i++) {\n+\t\tuint64_t dport_mask = 0;\n+\n+\t\tif (cfg->ext_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_PFS) {\n+\t\t\tdglort =\n+\t\t\t\tfm10k_switch_pfs_glort_get\n+\t\t\t\t(cfg->ext_port_map[i].map_no[0],\n+\t\t\t\t\t\tcfg->ext_port_map[i].map_no[1]);\n+\t\t\tdport_mask =\n+\t\t\t\tFM10K_SW_DPORT_MASK\n+\t\t(sw->pep_map[cfg->ext_port_map[i].map_no[0]].logical_port) |\n+\t\t\t\tFM10K_SW_DPORT_MASK\n+\t\t(sw->pep_map[cfg->ext_port_map[i].map_no[1]].logical_port);\n+\t\t\tfm10k_ffu_set_dest_glort_mask(sw,\n+\t\t\t\tsw->glort_cam_ram_idx++, dglort, dport_mask);\n+\t\t}\n+\t}\n+\n+\t/* Ensure the rest of the DGLORT TCAM won't match */\n+\tfor (table_idx = sw->glort_cam_ram_idx;\n+\t\t table_idx < FM10K_SW_GLORT_CAM_ENTRIES;\n+\t\t table_idx++)\n+\t\tfm10k_write_switch_reg(sw,\n+\t\t\t\tFM10K_SW_GLORT_CAM(table_idx),\n+\t\t\t\tFM10K_SW_GLORT_CAM_MATCH_NONE);\n+\n+\tret = fm10k_ffu_configured_flowset_enable(sw);\n+\n+\tfm10k_ffu_register_dump(sw);\n+\tfm10k_glort_register_dump(sw);\n+\treturn ret;\n+}\ndiff --git a/drivers/net/fm10k/switch/fm10k_ffu.h b/drivers/net/fm10k/switch/fm10k_ffu.h\nnew file mode 100644\nindex 0000000..9d46007\n--- /dev/null\n+++ b/drivers/net/fm10k/switch/fm10k_ffu.h\n@@ -0,0 +1,31 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2019   Silicom Ltd. Connectivity Solutions\n+ */\n+\n+#ifndef _FM10K_FFU_H_\n+#define _FM10K_FFU_H_\n+\n+\n+#include <stdint.h>\n+\n+#define FM10K_FFU_EXT_PORT_RULE_INGRESS(i)\t((i) * 2)\n+#define FM10K_FFU_EXT_PORT_RULE_EGRESS(i)\t((i) * 2 + 1)\n+#define FM10K_FFU_RULE_MAX\t\tFM10K_SW_FFU_RULE_MAX\n+\n+struct fm10k_switch;\n+struct fm10k_dpdk_cfg;\n+struct fm10k_cfg_flow;\n+\n+int fm10k_ffu_init(struct fm10k_switch *sw, struct fm10k_dpdk_cfg *cfg);\n+\n+int fm10k_ffu_mirror_set(struct fm10k_switch *sw,\n+\t\tuint16_t src_dpdk_port, u16 dest_dpdk_port, uint16_t vlan);\n+int fm10k_ffu_mirror_reset(struct fm10k_switch *sw, int src_dpdk_port);\n+\n+void fm10k_ffu_flow_enable(struct fm10k_switch *sw,\n+\t\tstruct fm10k_cfg_flow *flow);\n+void fm10k_ffu_flow_disable(struct fm10k_switch *sw,\n+\t\tstruct fm10k_cfg_flow *flow);\n+void fm10k_ffu_flowset_switch(struct fm10k_switch *sw, const char *new_name);\n+\n+#endif /* _FM10K_FFU_H */\ndiff --git a/drivers/net/fm10k/switch/fm10k_stats.c b/drivers/net/fm10k/switch/fm10k_stats.c\nnew file mode 100644\nindex 0000000..4172b22\n--- /dev/null\n+++ b/drivers/net/fm10k/switch/fm10k_stats.c\n@@ -0,0 +1,1242 @@\n+/* spdx-license-identifier: bsd-3-clause\n+ * copyright 2019   silicom ltd. connectivity solutions\n+ */\n+\n+#include <rte_time.h>\n+#include <rte_kvargs.h>\n+#include <rte_hash.h>\n+#include <rte_flow.h>\n+#include <rte_flow_driver.h>\n+#include <rte_tm_driver.h>\n+\n+#include \"../base/fm10k_type.h\"\n+#include \"../base/fm10k_osdep.h\"\n+\n+#include \"../fm10k.h\"\n+#include \"../fm10k_logs.h\"\n+#include \"fm10k_debug.h\"\n+#include \"fm10k_regs.h\"\n+#include \"fm10k_ext_port.h\"\n+#include \"fm10k_stats.h\"\n+#include \"fm10k_switch.h\"\n+#include \"fm10k_config.h\"\n+#include \"fm10k_ffu.h\"\n+\n+\n+#define FM10K_MAX_VLAN_COUNTER\t\t\t\t63\n+#define FM10K_NB_RX_STATS_BANKS\t\t\t\t6\n+#define FM10K_BINS_PER_RX_STATS_BANK\t\t16\n+#define FM10K_WORDS_PER_RX_STATS_COUNTER\t4\n+\n+/* Max expected entries in read stats scatter gather list */\n+#define MAX_STATS_SGLIST 128\n+#define FM10K_RX_STATS_BASE\t\t\t\t\t(0xE00000)\n+#define FM10K_MOD_BASE\t\t\t\t\t\t(0xE80000)\n+#define FM10K_CM_APPLY_BASE\t\t\t\t\t(0xD40000)\n+#define FM10K_EPL_BASE\t\t\t\t\t\t(0x0E0000)\n+\n+#define FM10K_RX_STATS_BANK(index1, index0, word)\t\t\t\\\n+\t\t\t((0x001000) * ((index1) - 0) + \\\n+\t\t\t(0x000004) * ((index0) - 0) + \\\n+\t\t\t(word) + (0x000000) + \\\n+\t\t\t(FM10K_RX_STATS_BASE))\n+#define FM10K_MOD_STATS_BANK_FRAME(index1, index0, word)\t\\\n+\t\t\t((0x000800) * ((index1) - 0) + \\\n+\t\t\t(0x000002) * ((index0) - 0) + \\\n+\t\t\t(word) + (0x025000) + \\\n+\t\t\t(FM10K_MOD_BASE))\n+#define FM10K_MOD_STATS_BANK_BYTE(index1, index0, word)\t\t\\\n+\t\t\t((0x000800) * ((index1) - 0) + \\\n+\t\t\t(0x000002) * ((index0) - 0) + \\\n+\t\t\t(word) + (0x026000) + \\\n+\t\t\t(FM10K_MOD_BASE))\n+#define FM10K_CM_APPLY_DROP_COUNT(index, word)\t\t\t\t\\\n+\t\t\t((0x000002) * ((index) - 0) + \\\n+\t\t\t(word) + (0x000880) + \\\n+\t\t\t(FM10K_CM_APPLY_BASE))\n+#define FM10K_MAC_OVERSIZE_COUNTER(index1, index0)\t\t\t\\\n+\t\t\t((0x000400) * ((index1) - 0) + \\\n+\t\t\t(0x000080) * ((index0) - 0) + \\\n+\t\t\t(0x000021) + \\\n+\t\t\t(FM10K_EPL_BASE))\n+#define FM10K_MAC_JABBER_COUNTER(index1, index0)\t\t\t\\\n+\t\t\t((0x000400) * ((index1) - 0) + \\\n+\t\t\t(0x000080) * ((index0) - 0) + \\\n+\t\t\t(0x000022) + \\\n+\t\t\t(FM10K_EPL_BASE))\n+#define FM10K_MAC_UNDERSIZE_COUNTER(index1, index0)\t\t\t\\\n+\t\t\t((0x000400) * ((index1) - 0) + \\\n+\t\t\t(0x000080) * ((index0) - 0) + \\\n+\t\t\t(0x000023) + \\\n+\t\t\t(FM10K_EPL_BASE))\n+#define FM10K_MAC_RUNT_COUNTER(index1, index0)\t\t\t\t\\\n+\t\t\t((0x000400) * ((index1) - 0) + \\\n+\t\t\t(0x000080) * ((index0) - 0) + \\\n+\t\t\t(0x000024) + \\\n+\t\t\t(FM10K_EPL_BASE))\n+#define FM10K_MAC_OVERRUN_COUNTER(index1, index0)\t\t\t\\\n+\t\t\t((0x000400) * ((index1) - 0) + \\\n+\t\t\t(0x000080) * ((index0) - 0) + \\\n+\t\t\t(0x000025) + \\\n+\t\t\t(FM10K_EPL_BASE))\n+#define FM10K_MAC_UNDERRUN_COUNTER(index1, index0)\t\t\t\\\n+\t\t\t((0x000400) * ((index1) - 0) + \\\n+\t\t\t(0x000080) * ((index0) - 0) + \\\n+\t\t\t(0x000026) + \\\n+\t\t\t(FM10K_EPL_BASE))\n+#define FM10K_MAC_CODE_ERROR_COUNTER(index1, index0)\t\t\\\n+\t\t\t((0x000400) * ((index1) - 0) + \\\n+\t\t\t(0x000080) * ((index0) - 0) + \\\n+\t\t\t(0x000027) + \\\n+\t\t\t(FM10K_EPL_BASE))\n+\n+/* Rx Bank Definitions */\n+#define FM10K_RX_STAT_BANK_TYPE                       0\n+#define FM10K_RX_STAT_BANK_SIZE                       1\n+#define FM10K_RX_STAT_BANK_PRI                        2\n+#define FM10K_RX_STAT_BANK_FWD_1                      3\n+#define FM10K_RX_STAT_BANK_FWD_2                      4\n+#define FM10K_RX_STAT_BANK_VLAN                       5\n+\n+/* FM10K_RX_STAT_BANK_TYPE Bin Definitions */\n+#define FM10K_RX_STAT_NONIP_L2UCAST                   0\n+#define FM10K_RX_STAT_NONIP_L2MCAST                   1\n+#define FM10K_RX_STAT_NONIP_L2BCAST                   2\n+#define FM10K_RX_STAT_IPV4_L2UCAST                    3\n+#define FM10K_RX_STAT_IPV4_L2MCAST                    4\n+#define FM10K_RX_STAT_IPV4_L2BCAST                    5\n+#define FM10K_RX_STAT_IPV6_L2UCAST                    6\n+#define FM10K_RX_STAT_IPV6_L2MCAST                    7\n+#define FM10K_RX_STAT_IPV6_L2BCAST                    8\n+#define FM10K_RX_STAT_IEEE802_3_PAUSE                 9\n+#define FM10K_RX_STAT_CLASS_BASED_PAUSE               10\n+#define FM10K_RX_STAT_FRAMING_ERR                     11\n+#define FM10K_RX_STAT_FCS_ERR                         12\n+\n+/* FM10K_RX_STAT_BANK_SIZE Bin Definitions */\n+#define FM10K_RX_STAT_LEN_LT_64                       0\n+#define FM10K_RX_STAT_LEN_EQ_64                       1\n+#define FM10K_RX_STAT_LEN_65_127                      2\n+#define FM10K_RX_STAT_LEN_128_255                     3\n+#define FM10K_RX_STAT_LEN_256_511                     4\n+#define FM10K_RX_STAT_LEN_512_1023                    5\n+#define FM10K_RX_STAT_LEN_1024_1522                   6\n+#define FM10K_RX_STAT_LEN_1523_2047                   7\n+#define FM10K_RX_STAT_LEN_2048_4095                   8\n+#define FM10K_RX_STAT_LEN_4096_8191                   9\n+#define FM10K_RX_STAT_LEN_8192_10239                  10\n+#define FM10K_RX_STAT_LEN_GE_10240                    11\n+\n+/* FM10K_RX_STAT_BANK_PRI Bin Definitions */\n+#define FM10K_RX_STAT_PRI_0                           0\n+#define FM10K_RX_STAT_PRI_1                           1\n+#define FM10K_RX_STAT_PRI_2                           2\n+#define FM10K_RX_STAT_PRI_3                           3\n+#define FM10K_RX_STAT_PRI_4                           4\n+#define FM10K_RX_STAT_PRI_5                           5\n+#define FM10K_RX_STAT_PRI_6                           6\n+#define FM10K_RX_STAT_PRI_7                           7\n+#define FM10K_RX_STAT_PRI_8                           8\n+#define FM10K_RX_STAT_PRI_9                           9\n+#define FM10K_RX_STAT_PRI_10                          10\n+#define FM10K_RX_STAT_PRI_11                          11\n+#define FM10K_RX_STAT_PRI_12                          12\n+#define FM10K_RX_STAT_PRI_13                          13\n+#define FM10K_RX_STAT_PRI_14                          14\n+#define FM10K_RX_STAT_PRI_15                          15\n+\n+/* FM10K_RX_STAT_BANK_FWD_1 Bin Definitions */\n+#define FM10K_RX_STAT_FID_FORWARDED                   0\n+#define FM10K_RX_STAT_FLOOD_FORWARDED                 1\n+#define FM10K_RX_STAT_SPECIALLY_HANDLED               2\n+#define FM10K_RX_STAT_PARSER_ERROR_DROP               3\n+#define FM10K_RX_STAT_ECC_ERROR_DROP                  4\n+#define FM10K_RX_STAT_TRAPPED                         5\n+#define FM10K_RX_STAT_PAUSE_DROPS                     6\n+#define FM10K_RX_STAT_STP_DROPS                       7\n+#define FM10K_RX_STAT_SECURITY_VIOLATIONS             8\n+#define FM10K_RX_STAT_VLAN_TAG_DROPS                  9\n+#define FM10K_RX_STAT_VLAN_INGRESS_DROPS              10\n+#define FM10K_RX_STAT_VLAN_EGRESS_DROPS               11\n+#define FM10K_RX_STAT_GLORT_MISS_DROPS                12\n+#define FM10K_RX_STAT_FFU_DROPS                       13\n+#define FM10K_RX_STAT_TRIGGER_DROPS                   14\n+#define FM10K_RX_STAT_OVERFLOW4                       15\n+\n+/* FM10K_RX_STAT_BANK_FWD_2 Bin Definitions */\n+#define FM10K_RX_STAT_POLICER_DROPS                   0\n+#define FM10K_RX_STAT_TTL_DROPS                       1\n+#define FM10K_RX_STAT_CM_PRIV_DROPS                   2\n+#define FM10K_RX_STAT_CM_SMP0_DROPS                   3\n+#define FM10K_RX_STAT_CM_SMP1_DROPS                   4\n+#define FM10K_RX_STAT_CM_RX_HOG_0_DROPS               5\n+#define FM10K_RX_STAT_CM_RX_HOG_1_DROPS               6\n+#define FM10K_RX_STAT_CM_TX_HOG_0_DROPS               7\n+#define FM10K_RX_STAT_CM_TX_HOG_1_DROPS               8\n+/* Bin 9 reserved */\n+#define FM10K_RX_STAT_TRIGGER_REDIRECTS               10\n+#define FM10K_RX_STAT_FLOOD_CONTROL_DROPS             11\n+#define FM10K_RX_STAT_GLORT_FORWARDED                 12\n+#define FM10K_RX_STAT_LOOPBACK_SUPPRESS               13\n+#define FM10K_RX_STAT_OTHERS                          14\n+#define FM10K_RX_STAT_OVERFLOW5                       15\n+\n+/* FM10K_RX_STAT_BANK_VLAN Bin definitions */\n+#define FM10K_RX_STAT_VLAN_UCAST                      0\n+#define FM10K_RX_STAT_VLAN_MCAST                      1\n+#define FM10K_RX_STAT_VLAN_BCAST                      2\n+\n+/* Tx Bank Definitions */\n+#define FM10K_TX_STAT_BANK_TYPE                       0\n+#define FM10K_TX_STAT_BANK_SIZE                       1\n+\n+/* FM10K_TX_STAT_BANK_TYPE Bin Definitions */\n+#define FM10K_TX_STAT_L2UCAST                         0\n+#define FM10K_TX_STAT_L2MCAST                         1\n+#define FM10K_TX_STAT_L2BCAST                         2\n+#define FM10K_TX_STAT_ERR_SENT                        3\n+#define FM10K_TX_STAT_TIMEOUT_DROP                    4\n+#define FM10K_TX_STAT_ERR_DROP                        5\n+#define FM10K_TX_STAT_ECC_DROP                        6\n+#define FM10K_TX_STAT_LOOPBACK_DROP                   7\n+#define FM10K_TX_STAT_TTL1_DROP                       8\n+#define FM10K_TX_STAT_IEEE802_3_PAUSE                 9\n+#define FM10K_TX_STAT_CLASS_BASED_PAUSE               10\n+\n+/* FM10K_TX_STAT_BANK_SIZE Bin Definitions */\n+#define FM10K_TX_STAT_LEN_LT_64                       0\n+#define FM10K_TX_STAT_LEN_EQ_64                       1\n+#define FM10K_TX_STAT_LEN_65_127                      2\n+#define FM10K_TX_STAT_LEN_128_255                     3\n+#define FM10K_TX_STAT_LEN_256_511                     4\n+#define FM10K_TX_STAT_LEN_512_1023                    5\n+#define FM10K_TX_STAT_LEN_1024_1522                   6\n+#define FM10K_TX_STAT_LEN_1523_2047                   7\n+#define FM10K_TX_STAT_LEN_2048_4095                   8\n+#define FM10K_TX_STAT_LEN_4096_8191                   9\n+#define FM10K_TX_STAT_LEN_8192_10239                  10\n+#define FM10K_TX_STAT_LEN_GE_10240                    11\n+\n+\n+/* This structure is used to build a table of all rx / tx counters */\n+struct fm10k_port_count_mapping {\n+\t/* Bank in which the counter is located */\n+\tuint32_t bank;\n+\n+\t/* Bin  in which the counter is located */\n+\tuint32_t bin;\n+\n+\t/*\n+\t * Offset (in bytes) of a the frame counter in\n+\t * the fm10k_counters structure\n+\t */\n+\tuint32_t frame_offset;\n+\n+\t/*\n+\t * Offset (in bytes) of a the byte counter in\n+\t * the fm10k_counters structure\n+\t */\n+\tuint32_t byte_offset;\n+};\n+\n+\n+/*\n+ * Table of all RX port counters in the RX banks\n+ * This table is used for retrieving counters as\n+ * well as resetting them\n+ */\n+static struct fm10k_port_count_mapping rx_port_cnt_map_table[] = {\n+    /* Bank                        Bin\n+     * --------------------------  ------------------------------\n+     * frame_offset\n+     * ---------------------------------------------\n+     * byte_offset\n+     * ---------------------------------------------------\n+     */\n+    /* Type Bank */\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_NONIP_L2UCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_ucst_pkts_nonip),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_ucst_octets_nonip)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_NONIP_L2MCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_mcst_pkts_nonip),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_mcst_octets_nonip)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_NONIP_L2BCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_bcst_pkts_nonip),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_bcst_octets_nonip)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV4_L2UCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_ucst_pkts_ipv4),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_ucst_octets_ipv4)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV4_L2MCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_mcst_pkts_ipv4),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_mcst_octets_ipv4)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV4_L2BCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_bcst_pkts_ipv4),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_bcst_octets_ipv4)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV6_L2UCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_ucst_pkts_ipv6),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_ucst_octets_ipv6)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV6_L2MCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_mcst_pkts_ipv6),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_mcst_octets_ipv6)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IPV6_L2BCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_bcst_pkts_ipv6),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_bcst_octets_ipv6)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_IEEE802_3_PAUSE,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_pause_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_pause_octets)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_CLASS_BASED_PAUSE,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_cbpause_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_cbpause_octets)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_FRAMING_ERR,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_framing_error_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_framing_error_octets)},\n+{\tFM10K_RX_STAT_BANK_TYPE,  FM10K_RX_STAT_FCS_ERR,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_fcs_errors),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_fcs_errors_octets)},\n+\n+    /* Size Bank */\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_LT_64,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_minto63_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_minto63_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_EQ_64,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_64_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_64_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_65_127,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_65to127_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_65to127_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_128_255,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_128to255_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_128to255_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_256_511,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_256to511_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_256to511_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_512_1023,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_512to1023_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_512to1023_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_1024_1522,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_1024to1522_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_1024to1522_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_1523_2047,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_1523to2047_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_1523to2047_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_2048_4095,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_2048to4095_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_2048to4095_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_4096_8191,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_4096to8191_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_4096to8191_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_8192_10239,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_8192to10239_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_8192to10239_octets)},\n+{\tFM10K_RX_STAT_BANK_SIZE,  FM10K_RX_STAT_LEN_GE_10240,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_10240tomax_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_10240tomax_octets)},\n+\n+    /* priority Bank */\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_0,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[0]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[0])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_1,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[1]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[1])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_2,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[2]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[2])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_3,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[3]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[3])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_4,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[4]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[4])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_5,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[5]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[5])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_6,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[6]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[6])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_7,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[7]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[7])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_8,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[8]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[8])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_9,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[9]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[9])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_10,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[10]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[10])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_11,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[11]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[11])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_12,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[12]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[12])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_13,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[13]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[13])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_14,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[14]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[14])},\n+{\tFM10K_RX_STAT_BANK_PRI,   FM10K_RX_STAT_PRI_15,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_pkts[15]),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_priority_octets[15])},\n+\n+    /* Forwarding Bank */\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_FID_FORWARDED,\n+\toffsetof(struct fm10k_port_counters, cnt_fid_forwarded_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_fid_forwarded_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_FLOOD_FORWARDED,\n+\toffsetof(struct fm10k_port_counters, cnt_flood_forwarded_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_flood_forwarded_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_SPECIALLY_HANDLED,\n+\toffsetof(struct fm10k_port_counters, cnt_specially_handled_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_specially_handled_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_PARSER_ERROR_DROP,\n+\toffsetof(struct fm10k_port_counters, cnt_parse_err_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_parse_err_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_ECC_ERROR_DROP,\n+\toffsetof(struct fm10k_port_counters, cnt_parity_error_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_parity_error_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_TRAPPED,\n+\toffsetof(struct fm10k_port_counters, cnt_trapped_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_trapped_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_PAUSE_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_pause_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_pause_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_STP_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_stp_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_stp_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_SECURITY_VIOLATIONS,\n+\toffsetof(struct fm10k_port_counters, cnt_security_violation_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_security_violation_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_VLAN_TAG_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_vlan_tag_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_vlan_tag_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_VLAN_INGRESS_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_vlan_ingressbv_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_vlan_ingressbv_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_VLAN_EGRESS_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_vlan_egressbv_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_vlan_egressbv_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_GLORT_MISS_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_glort_miss_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_glort_miss_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_FFU_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_ffu_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_ffu_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_1, FM10K_RX_STAT_TRIGGER_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_trigger_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_trigger_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_POLICER_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_policer_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_policer_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_TTL_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_ttl_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_ttl_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_PRIV_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_cmpriv_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_cmpriv_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_SMP0_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_smp0_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_smp0_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_SMP1_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_smp1_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_smp1_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_RX_HOG_0_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_hog0_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_hog0_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_RX_HOG_1_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_rx_hog1_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_rx_hog1_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_TX_HOG_0_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_hog0_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_hog0_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_CM_TX_HOG_1_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_hog1_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_hog1_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_TRIGGER_REDIRECTS,\n+\toffsetof(struct fm10k_port_counters, cnt_trigger_redir_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_trigger_redir_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_FLOOD_CONTROL_DROPS,\n+\toffsetof(struct fm10k_port_counters, cnt_flood_control_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_flood_control_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_GLORT_FORWARDED,\n+\toffsetof(struct fm10k_port_counters, cnt_glort_forwarded_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_glort_forwarded_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_LOOPBACK_SUPPRESS,\n+\toffsetof(struct fm10k_port_counters, cnt_loopback_drops_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_loopback_drop_octets)},\n+{\tFM10K_RX_STAT_BANK_FWD_2, FM10K_RX_STAT_OTHERS,\n+\toffsetof(struct fm10k_port_counters, cnt_other_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_other_octets)},\n+\n+}; /* end rxPortCntMapTable */\n+\n+\n+/*\n+ * Table of all TX port counters in the TX banks\n+ * This table is used for retrieving counters as\n+ * well as resetting them\n+ */\n+static struct fm10k_port_count_mapping tx_port_cnt_map_table[] = {\n+    /* Bank                        Bin\n+     * --------------------------  ------------------------------\n+     * frame_offset\n+     * ---------------------------------------------\n+     * byte_offset\n+     * ---------------------------------------------------\n+     */\n+    /* Type Bank */\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_L2UCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_ucst_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_ucst_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_L2MCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_mcst_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_mcst_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_L2BCAST,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_bcst_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_bcst_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_ERR_SENT,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_error_sent_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_error_sent_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_TIMEOUT_DROP,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_timeout_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_timeout_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_ERR_DROP,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_error_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_error_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_ECC_DROP,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_unrepair_ecc_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_unrepair_ecc_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_LOOPBACK_DROP,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_loopback_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_loopback_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_TTL1_DROP,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_ttl_drop_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_ttl_drop_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_IEEE802_3_PAUSE,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_pause_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_pause_octets)},\n+{\tFM10K_TX_STAT_BANK_TYPE, FM10K_TX_STAT_CLASS_BASED_PAUSE,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_cbpause_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_cbpause_octets)},\n+\n+    /* Size Bank */\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_LT_64,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_minto63_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_minto63_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_EQ_64,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_64_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_64_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_65_127,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_65to127_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_65to127_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_128_255,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_128to255_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_128to255_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_256_511,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_256to511_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_256to511_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_512_1023,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_512to1023_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_512to1023_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_1024_1522,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_1024to1522_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_1024to1522_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_1523_2047,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_1523to2047_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_1523to2047_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_2048_4095,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_2048to4095_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_2048to4095_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_4096_8191,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_4096to8191_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_4096to8191_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_8192_10239,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_8192to10239_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_8192to10239_octets)},\n+{\tFM10K_TX_STAT_BANK_SIZE, FM10K_TX_STAT_LEN_GE_10240,\n+\toffsetof(struct fm10k_port_counters, cnt_tx_10240tomax_pkts),\n+\toffsetof(struct fm10k_port_counters, cnt_tx_10240tomax_octets)},\n+\n+};  /* end tx_port_cnt_map_table */\n+\n+\n+/*\n+ * Get a 32bit EPL counter by adding it to the scatter gather\n+ * list.\n+ * Depends on the existence of the variables:\n+ * sgList [out] - scatter gather array to hold the reads\n+ * sgListCnt [out] - number of entry in the sgList\n+ */\n+static inline void\n+fm10k_get_epl_port_stat32(struct fm10k_scatter_gather_entry *sg_list,\n+\t\tstruct fm10k_port_counters *counters,\n+\t\tint *sg_list_cnt, int epl, int lane)\n+{\n+\tsg_list[*sg_list_cnt].addr = FM10K_MAC_OVERSIZE_COUNTER(epl, lane);\n+\tsg_list[*sg_list_cnt].data =\n+\t\t\t(uint32_t *)&counters->cnt_rx_oversized_pkts;\n+\tsg_list[*sg_list_cnt].count = 1;\n+\t(*sg_list_cnt)++;\n+\n+\tsg_list[*sg_list_cnt].addr = FM10K_MAC_JABBER_COUNTER(epl, lane);\n+\tsg_list[*sg_list_cnt].data =\n+\t\t\t(uint32_t *)&counters->cnt_rx_jabber_pkts;\n+\tsg_list[*sg_list_cnt].count = 1;\n+\t(*sg_list_cnt)++;\n+\n+\tsg_list[*sg_list_cnt].addr = FM10K_MAC_UNDERSIZE_COUNTER(epl, lane);\n+\tsg_list[*sg_list_cnt].data =\n+\t\t\t(uint32_t *)&counters->cnt_rx_undersized_pkts;\n+\tsg_list[*sg_list_cnt].count = 1;\n+\t(*sg_list_cnt)++;\n+\n+\tsg_list[*sg_list_cnt].addr = FM10K_MAC_RUNT_COUNTER(epl, lane);\n+\tsg_list[*sg_list_cnt].data =\n+\t\t\t(uint32_t *)&counters->cnt_rx_fragment_pkts;\n+\tsg_list[*sg_list_cnt].count = 1;\n+\t(*sg_list_cnt)++;\n+\n+\tsg_list[*sg_list_cnt].addr = FM10K_MAC_OVERRUN_COUNTER(epl, lane);\n+\tsg_list[*sg_list_cnt].data =\n+\t\t\t(uint32_t *)&counters->cnt_over_run_pkts;\n+\tsg_list[*sg_list_cnt].count = 1;\n+\t(*sg_list_cnt)++;\n+\n+\tsg_list[*sg_list_cnt].addr = FM10K_MAC_CODE_ERROR_COUNTER(epl, lane);\n+\tsg_list[*sg_list_cnt].data =\n+\t\t\t(uint32_t *)&counters->cnt_code_errors;\n+\tsg_list[*sg_list_cnt].count = 1;\n+\t(*sg_list_cnt)++;\n+}\n+\n+\n+static void\n+fm10k_read_scatter_gather(struct fm10k_switch *sw,\n+\t\tint n_entries,\n+\t\tstruct fm10k_scatter_gather_entry *sg_list)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < n_entries; i++) {\n+\t\tuint32_t addr  = sg_list[i].addr;\n+\t\tuint32_t count = sg_list[i].count;\n+\t\tuint32_t *data = sg_list[i].data;\n+\n+\t\tfm10k_read_switch_array(sw, addr, data, count);\n+\t}\n+}\n+\n+\n+static int\n+fm10k_get_port_counters(struct fm10k_switch *sw,\n+\t\tstruct fm10k_ext_port *ext_port,\n+\t\tstruct fm10k_port_counters *counters)\n+{\n+\tint phys_port;\n+\tint epl;\n+\tint lane;\n+\tstruct timeval ts;\n+\tbool valid_ip_stats = true;\n+\tuint32_t i;\n+\tstruct fm10k_scatter_gather_entry sg_list[MAX_STATS_SGLIST];\n+\tint sg_list_cnt = 0;\n+\t/* Temporary bin array to retrieve 128bit\n+\t * port counters (frame + bytes).\n+\t */\n+\tuint32_t cnt_rx_port_stats_bank\n+\t\t\t\t\t[FM10K_NB_RX_STATS_BANKS]\n+\t\t\t\t\t[FM10K_BINS_PER_RX_STATS_BANK]\n+\t\t\t\t\t[FM10K_WORDS_PER_RX_STATS_COUNTER];\n+\t/*\n+\t * Fill the counters structure with 0 to assure\n+\t * all fields not explicitly set below, which will\n+\t * be the fields not supported by the FM10000,\n+\t * will be 0 on return.\n+\t */\n+\tmemset(counters, 0, sizeof(*counters));\n+\n+\tphys_port = ext_port->portno;\n+\tepl = ext_port->eplno;\n+\tlane = ext_port->first_lane;\n+\n+\tcounters->cnt_version = FM10K_STATS_VERSION;\n+\n+\t/*\n+\t * Reading counters for each RX bank\n+\t *\n+\t * Because the RX_STATS_BANK register contains\n+\t * both, frame count and byte count in a 128bit\n+\t * register, we first store the data in a temporary\n+\t * array.\n+\t * 1. Fill Scatter Gather to retrieve each bin\n+\t *    counter from the rx bank and store in a temp\n+\t *    array.\n+\t */\n+\tfor (i = 0;\n+\t\t\ti < sizeof(rx_port_cnt_map_table) /\n+\t\t\t\tsizeof(rx_port_cnt_map_table[0]);\n+\t\t\ti++) {\n+\t\t/*\n+\t\t * Add a 128bit read of an rx counter to the scatter gather\n+\t\t * list.\n+\t\t * NOTE: Read values will be stored in the temporary\n+\t\t *       array switchExt->cnt_rx_port_stats_bank;\n+\t\t * Depends on the existence of the variables:\n+\t\t * switchExt->cnt_rx_PortStatsBank [out] - Array to store the\n+\t\t * 128bit values sgList\n+\t\t * [out] - scatter gather array to hold the reads sgListCnt\n+\t\t * [out] - number of entry in the sgList\n+\t\t */\n+\t\tuint32_t bank = rx_port_cnt_map_table[i].bank;\n+\t\tuint32_t bin = rx_port_cnt_map_table[i].bin;\n+\n+\t\tsg_list[sg_list_cnt].addr =\n+\t\t\tFM10K_RX_STATS_BANK(bank, (phys_port << 4 | (bin)), 0);\n+\t\tsg_list[sg_list_cnt].data = cnt_rx_port_stats_bank[bank][bin];\n+\t\tsg_list[sg_list_cnt].count = 4;\n+\t\tsg_list_cnt++;\n+}\n+\n+\t/*\n+\t * 2. Fill in the scatter gather for tx bank\n+\t *    counters. They will directly be stored\n+\t *    in the fm10k_counters structure upon\n+\t *    scatter gather read.\n+\t */\n+\tfor (i = 0;\n+\t\t\ti < sizeof(tx_port_cnt_map_table) /\n+\t\t\t\tsizeof(tx_port_cnt_map_table[0]);\n+\t\t\ti++) {\n+\t\t/*\n+\t\t * Add a 64bit read of a tx counter to the scatter gather list.\n+\t\t * Depends on the existence of the variables:\n+\t\t * sgList [out] - scatter gather array to hold the reads\n+\t\t * sgListCnt [out] - number of entry in the sgList\n+\t\t */\n+\t\tuint32_t bank = tx_port_cnt_map_table[i].bank;\n+\t\tuint32_t bin = tx_port_cnt_map_table[i].bin;\n+\t\tuint32_t frame_offset = tx_port_cnt_map_table[i].frame_offset;\n+\n+\t\tsg_list[sg_list_cnt].addr =\n+\t\t\tFM10K_MOD_STATS_BANK_FRAME(bank,\n+\t\t\t\t\t(phys_port << 4 | (bin)), 0);\n+\t\tsg_list[sg_list_cnt].data =\n+\t\t\t(uint32_t *)(((uint8_t *)counters) + (frame_offset));\n+\t\tsg_list[sg_list_cnt].count = 2;\n+\t\tsg_list_cnt++;\n+\t}\n+\n+\t/*\n+\t * 3. Fill in the scatter gather for TX CM DROP\n+\t *    and for EPL counters. They will directly be\n+\t *    stored in the fm10k_counters structure upon\n+\t *    scatter gather read.\n+\t */\n+\tsg_list[sg_list_cnt].addr =\n+\t\t\tFM10K_CM_APPLY_DROP_COUNT(phys_port, 0);\n+\tsg_list[sg_list_cnt].data =\n+\t\t\t(uint32_t *)&counters->cnt_rx_cm_drop_pkts;\n+\tsg_list[sg_list_cnt].count = 2;\n+\tsg_list_cnt++;\n+\t/* EPL Counters */\n+\tfm10k_get_epl_port_stat32(sg_list, counters, &sg_list_cnt, epl, lane);\n+\n+\t/*\n+\t * 4. Execute scatter gather read.\n+\t */\n+\tif (sg_list_cnt >= MAX_STATS_SGLIST) {\n+\t\t/*\n+\t\t * Pretty static. Mainly to warn if something new added,\n+\t\t * but the array size is not adjust accordingly\n+\t\t */\n+\t\tFM10K_SW_ERR(\"Scatter list array %d for port %d overflow.\\n\",\n+\t\t\t\tsg_list_cnt, phys_port);\n+\t\treturn -1;\n+\t}\n+\n+\t/*\n+\t * Taking lock to protect temporary structures used to\n+\t * store 128b counters\n+\t */\n+\tFM10K_SW_SWITCH_LOCK(sw);\n+\n+\t/* now get the stats in one shot, optimized for fibm */\n+\tfm10k_read_scatter_gather(sw, sg_list_cnt, sg_list);\n+\tFM10K_SW_SWITCH_UNLOCK(sw);\n+\n+\tcounters->timestamp = ts.tv_sec * 1000000 + ts.tv_usec;\n+\n+\t/*\n+\t * 5. Retrieve the frame/byte counts from 128bit\n+\t *    registers stored in temporary array and set\n+\t *    the proper fm_portCounter structure members.\n+\t */\n+\tfor (i = 0;\n+\t\t\ti < sizeof(rx_port_cnt_map_table) /\n+\t\t\t\tsizeof(rx_port_cnt_map_table[0]);\n+\t\t\ti++) {\n+\t\t/*\n+\t\t * Update the counter variable related to a 128bit HW counter\n+\t\t * NOTE: Read values will be retrieved from the temporary\n+\t\t *       array switchExt->cnt_rx_PortStatsBank;\n+\t\t * Depends on the existence of the variables:\n+\t\t * switchExt->cnt_rx_PortStatsBank [in] - Array to read the\n+\t\t * 128bit values from\n+\t\t */\n+\t\tuint32_t bank = rx_port_cnt_map_table[i].bank;\n+\t\tuint32_t bin = rx_port_cnt_map_table[i].bin;\n+\t\tuint32_t frame_offset = rx_port_cnt_map_table[i].frame_offset;\n+\t\tuint32_t byte_offset = rx_port_cnt_map_table[i].byte_offset;\n+\n+\t\t*((uint64_t *)(((uint8_t *)counters) + frame_offset)) =\n+\t\t(((uint64_t)(cnt_rx_port_stats_bank[bank][bin][1]) << 32) |\n+\t\t((uint64_t)(cnt_rx_port_stats_bank[bank][bin][0])));\n+\n+\t\t*((uint64_t *)(((uint8_t *)counters) + byte_offset)) =\n+\t\t(((uint64_t)(cnt_rx_port_stats_bank[bank][bin][3]) << 32) |\n+\t\t((uint64_t)(cnt_rx_port_stats_bank[bank][bin][2])));\n+\t}\n+\n+\t/*\n+\t * 6. Set some counters that are not available\n+\t *    in HW but can be computed from two or more\n+\t *    HW counters.\n+\t */\n+\t/*\n+\t * If IP parsing is enabled then the IP stats will be read and will be\n+\t * valid. Else all traffic, whether IP or not, is counted as _nonip.\n+\t */\n+\tif (valid_ip_stats) {\n+\t\t/*\n+\t\t * RX counters.\n+\t\t */\n+\t\tcounters->cnt_rx_ucst_pkts =\n+\t\t\t\tcounters->cnt_rx_ucst_pkts_nonip +\n+\t\t\t\tcounters->cnt_rx_ucst_pkts_ipv4 +\n+\t\t\t\tcounters->cnt_rx_ucst_pkts_ipv6;\n+\n+\t\tcounters->cnt_rx_mcst_pkts =\n+\t\t\t\tcounters->cnt_rx_mcst_pkts_nonip +\n+\t\t\t\tcounters->cnt_rx_mcst_pkts_ipv4 +\n+\t\t\t\tcounters->cnt_rx_mcst_pkts_ipv6;\n+\n+\t\tcounters->cnt_rx_bcst_pkts =\n+\t\t\t\tcounters->cnt_rx_bcst_pkts_nonip +\n+\t\t\t\tcounters->cnt_rx_bcst_pkts_ipv4 +\n+\t\t\t\tcounters->cnt_rx_bcst_pkts_ipv6;\n+\n+\t\t/*\n+\t\t * Misc. counters.\n+\t\t */\n+\t\tcounters->cnt_rx_octets_nonip  =\n+\t\t\t\tcounters->cnt_rx_ucst_octets_nonip +\n+\t\t\t\tcounters->cnt_rx_mcst_octets_nonip +\n+\t\t\t\tcounters->cnt_rx_bcst_octets_nonip;\n+\n+\t\tcounters->cnt_rx_octets_ipv4  =\n+\t\t\t\tcounters->cnt_rx_ucst_octets_ipv4 +\n+\t\t\t\tcounters->cnt_rx_mcst_octets_ipv4 +\n+\t\t\t\tcounters->cnt_rx_bcst_octets_ipv4;\n+\n+\t\tcounters->cnt_rx_octets_ipv6  =\n+\t\t\t\tcounters->cnt_rx_ucst_octets_ipv6 +\n+\t\t\t\tcounters->cnt_rx_mcst_octets_ipv6 +\n+\t\t\t\tcounters->cnt_rx_bcst_octets_ipv6;\n+\n+\t\tcounters->cnt_rx_good_octets =\n+\t\t\t\tcounters->cnt_rx_octets_nonip +\n+\t\t\t\tcounters->cnt_rx_octets_ipv4 +\n+\t\t\t\tcounters->cnt_rx_octets_ipv6;\n+\t} else {\n+\t\t/*\n+\t\t * RX counters.\n+\t\t */\n+\t\tcounters->cnt_rx_ucst_pkts =\n+\t\t\t\tcounters->cnt_rx_ucst_pkts_nonip;\n+\t\tcounters->cnt_rx_mcst_pkts =\n+\t\t\t\tcounters->cnt_rx_mcst_pkts_nonip;\n+\t\tcounters->cnt_rx_bcst_pkts =\n+\t\t\t\tcounters->cnt_rx_bcst_pkts_nonip;\n+\n+\t\t/*\n+\t\t * Misc. counters.\n+\t\t */\n+\t\tcounters->cnt_rx_octets_nonip  =\n+\t\t\t\tcounters->cnt_rx_ucst_octets_nonip +\n+\t\t\t\tcounters->cnt_rx_mcst_octets_nonip +\n+\t\t\t\tcounters->cnt_rx_bcst_octets_nonip;\n+\n+\t\tcounters->cnt_rx_good_octets =\n+\t\t\t\tcounters->cnt_rx_octets_nonip;\n+\t}\n+\n+\tcounters->cnt_trigger_drop_redir_pkts =\n+\t\t\tcounters->cnt_trigger_redir_pkts +\n+\t\t\tcounters->cnt_trigger_drop_pkts;\n+\n+\t/* Emulate Tx _octets counter using the sum of all size bins. */\n+\tcounters->cnt_tx_octets += counters->cnt_tx_minto63_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_64_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_65to127_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_128to255_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_256to511_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_512to1023_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_1024to1522_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_1523to2047_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_2048to4095_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_4096to8191_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_8192to10239_octets;\n+\tcounters->cnt_tx_octets += counters->cnt_tx_10240tomax_octets;\n+\n+\treturn 0;\n+}   /* end fm10k_get_port_counters */\n+\n+\n+struct fm10k_stats_data {\n+\tuint64_t rx_pkts;\n+\tuint64_t tx_pkts;\n+\tuint64_t rx_drop;\n+};\n+\n+\n+static uint64_t\n+fm10k_stats_ffu_count_get(struct fm10k_switch *sw, int table_id)\n+{\n+\tuint64_t data;\n+\n+\tif (FM10K_SW_FFU_CNT_BANK < 2) {\n+\t\tdata = fm10k_read_switch_reg64(sw,\n+\t\t\t\t0xE40000 + 0x4000 * FM10K_SW_FFU_CNT_BANK +\n+\t\t\t\t0x4 * (table_id + FM10K_SW_FFU_CNT_START) +\n+\t\t\t\t0x8000);\n+\t} else {\n+\t\tdata = fm10k_read_switch_reg64(sw,\n+\t\t\t\t0xE40000 + 0x800 * (FM10K_SW_FFU_CNT_BANK - 2) +\n+\t\t\t\t0x4 * (table_id + FM10K_SW_FFU_CNT_START) +\n+\t\t\t\t0x10000);\n+\t}\n+\treturn data;\n+}\n+\n+static void\n+fm10k_stats_epl_ffu_print(struct fm10k_switch *sw, int epl)\n+{\n+\tint table_id;\n+\tuint64_t data;\n+\n+\ttable_id = FM10K_FFU_EXT_PORT_RULE_INGRESS(epl);\n+\tdata = fm10k_stats_ffu_count_get(sw, table_id);\n+\tprintf(\"             FFU[%d] ingress        %-12llu\\n\",\n+\t\t\ttable_id, (unsigned long long)(data));\n+\n+\ttable_id = FM10K_FFU_EXT_PORT_RULE_EGRESS(epl);\n+\tdata = fm10k_stats_ffu_count_get(sw, table_id);\n+\tprintf(\"             FFU[%d]  egress        %-12llu\\n\",\n+\t\t\ttable_id, (unsigned long long)(data));\n+}\n+\n+#define FM10K_STATS_RULE_NUM_MAX\t100\n+static uint16_t fm10k_stats_rule_list[FM10K_STATS_RULE_NUM_MAX];\n+void\n+fm10k_stats_rule_count_reg(uint16_t rule_id)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < FM10K_STATS_RULE_NUM_MAX; i++) {\n+\t\tif (fm10k_stats_rule_list[i] == 0) {\n+\t\t\tfm10k_stats_rule_list[i] = rule_id;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+}\n+\n+void\n+fm10k_stats_ffu_count_print(struct fm10k_switch *sw)\n+{\n+\tint i, rule_id;\n+\tuint64_t data;\n+\tstatic uint64_t ffu_count[FM10K_STATS_RULE_NUM_MAX];\n+\n+\tfor (i = 0; i < FM10K_STATS_RULE_NUM_MAX; i++) {\n+\t\tif (fm10k_stats_rule_list[i] == 0)\n+\t\t\tcontinue;\n+\n+\t\trule_id = fm10k_stats_rule_list[i];\n+\t\tdata = fm10k_stats_ffu_count_get(sw, rule_id);\n+\t\tprintf(\"FFU[%d] count         %-12llu\\n\",\n+\t\t\t\trule_id,\n+\t\t\t\t(unsigned long long)\n+\t\t\t\t(data - ffu_count[rule_id]));\n+\t\tffu_count[rule_id] = data;\n+\t}\n+}\n+\n+void\n+fm10k_stats_epl_port_print(struct fm10k_switch *sw)\n+{\n+\tint i, lport;\n+\tstruct fm10k_port_counters counters;\n+\tstruct fm10k_ext_port ext_port;\n+\tstatic struct fm10k_stats_data last_data[FM10K_SW_EXT_PORTS_MAX];\n+\tstruct fm10k_stats_data data;\n+\n+\tfor (i = 0; i < FM10K_SW_EPLS_SUPPORTED; i++) {\n+\t\tlport = sw->epl_map[i].logical_port;\n+\t\text_port.portno = lport;\n+\t\tfm10k_get_port_counters(sw, &ext_port, &counters);\n+\n+\t\tdata.rx_pkts =\n+\t\t\tcounters.cnt_rx_bcst_pkts +\n+\t\t\tcounters.cnt_rx_ucst_pkts;\n+\t\tdata.tx_pkts =\n+\t\t\tcounters.cnt_tx_bcst_pkts +\n+\t\t\tcounters.cnt_tx_ucst_pkts;\n+\t\tdata.rx_drop = counters.cnt_cmpriv_drop_pkts;\n+\t\tprintf(\"EPL  port %-2d lport %-5d tx_pkt %-12llu rx_pkt %-12llu drop_pkt %-12llu\\n\",\n+\t\t\t\ti, lport,\n+\t\t\t\t(unsigned long long)\n+\t\t\t\t(data.tx_pkts - last_data[i].tx_pkts),\n+\t\t\t\t(unsigned long long)\n+\t\t\t\t(data.rx_pkts - last_data[i].rx_pkts),\n+\t\t\t\t(unsigned long long)\n+\t\t\t\t(data.rx_drop - last_data[i].rx_drop));\n+\t\tlast_data[i] = data;\n+\n+\t\tif (fm10k_config_check_debug(sw->dpdk_cfg,\n+\t\t\t\tFM10K_CONFIG_DEBUG_STATS_FFU))\n+\t\t\tfm10k_stats_epl_ffu_print(sw, i);\n+\t}\n+}\n+\n+\n+void\n+fm10k_stats_dpdk_port_print(struct fm10k_switch *sw)\n+{\n+\tint i, j, lport, pf_no;\n+\tstruct fm10k_port_counters counters;\n+\tstruct fm10k_ext_port ext_port;\n+\tstatic struct fm10k_stats_data last_data[FM10K_SW_PEPS_MAX];\n+\tstatic struct fm10k_stats_data last_queue_data[FM10K_SW_PEPS_MAX][4];\n+\tstruct fm10k_stats_data data, mydata;\n+\tchar pf_ports[10];\n+\n+\tfor (i = 0; i < FM10K_SW_LOGICAL_PORTS_MAX; i++) {\n+\t\tif (sw->dpdk_cfg->ports[i].hw == NULL)\n+\t\t\tcontinue;\n+\t\tif (sw->dpdk_cfg->ports[i].type != FM10K_CONFIG_DPDK_PF)\n+\t\t\tcontinue;\n+\t\tif (sw->dpdk_cfg->dpdk_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_NULL)\n+\t\t\tcontinue;\n+\n+\t\tmemset(&mydata, 0, sizeof(mydata));\n+\t\tif (sw->dpdk_cfg->dpdk_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_PFS) {\n+\t\t\tfor (j = 0; j < 2; j++) {\n+\t\t\t\tpf_no =\n+\t\t\t\tsw->dpdk_cfg->dpdk_port_map[i].map_no[j];\n+\t\t\t\tlport = sw->pep_map[pf_no].logical_port;\n+\t\t\t\tmemset(&ext_port, 0, sizeof(ext_port));\n+\t\t\t\text_port.portno = lport;\n+\t\t\t\tfm10k_get_port_counters\n+\t\t\t\t(sw, &ext_port, &counters);\n+\t\t\t\tdata.rx_pkts = counters.cnt_rx_bcst_pkts +\n+\t\t\t\t\t\tcounters.cnt_rx_ucst_pkts;\n+\t\t\t\tdata.tx_pkts = counters.cnt_tx_bcst_pkts +\n+\t\t\t\t\t\tcounters.cnt_tx_ucst_pkts;\n+\t\t\t\tdata.rx_drop = counters.cnt_cmpriv_drop_pkts;\n+\t\t\t\tmydata.rx_pkts += data.rx_pkts -\n+\t\t\t\t\t\tlast_data[pf_no].rx_pkts;\n+\t\t\t\tmydata.tx_pkts += data.tx_pkts -\n+\t\t\t\t\t\tlast_data[pf_no].tx_pkts;\n+\t\t\t\tmydata.rx_drop += data.rx_drop -\n+\t\t\t\t\t\tlast_data[pf_no].rx_drop;\n+\t\t\t\tlast_data[pf_no] = data;\n+\t\t\t}\n+\t\t} else if (sw->dpdk_cfg->dpdk_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_PF) {\n+\t\t\tpf_no = sw->dpdk_cfg->dpdk_port_map[i].map_no[0];\n+\t\t\tlport = sw->pep_map[pf_no].logical_port;\n+\t\t\tmemset(&ext_port, 0, sizeof(ext_port));\n+\t\t\text_port.portno = lport;\n+\t\t\tfm10k_get_port_counters(sw, &ext_port, &counters);\n+\t\t\tdata.rx_pkts = counters.cnt_rx_bcst_pkts +\n+\t\t\t\t\tcounters.cnt_rx_ucst_pkts;\n+\t\t\tdata.tx_pkts = counters.cnt_tx_bcst_pkts +\n+\t\t\t\t\tcounters.cnt_tx_ucst_pkts;\n+\t\t\tdata.rx_drop = counters.cnt_cmpriv_drop_pkts;\n+\t\t\tmydata.rx_pkts += data.rx_pkts -\n+\t\t\t\t\tlast_data[pf_no].rx_pkts;\n+\t\t\tmydata.tx_pkts += data.tx_pkts -\n+\t\t\t\t\tlast_data[pf_no].tx_pkts;\n+\t\t\tmydata.rx_drop += data.rx_drop -\n+\t\t\t\t\tlast_data[pf_no].rx_drop;\n+\t\t\tlast_data[pf_no] = data;\n+\t\t} else {\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (sw->dpdk_cfg->dpdk_port_map[i].type ==\n+\t\t\t\tFM10K_CONFIG_PORT_MAP_PF)\n+\t\t\tsprintf(pf_ports, \"%d\",\n+\t\t\t\tsw->dpdk_cfg->dpdk_port_map[i].map_no[0]);\n+\t\telse\n+\t\t\tsprintf(pf_ports, \"%d/%d\",\n+\t\t\t\tsw->dpdk_cfg->dpdk_port_map[i].map_no[0],\n+\t\t\t\tsw->dpdk_cfg->dpdk_port_map[i].map_no[1]);\n+\n+\t\tprintf(\"DPDK port %-2d  pf %-5s   tx_pkt %-12llu \"\n+\t\t\t\t\"rx_pkt %-12llu drop_pkt %-12llu\\n\",\n+\t\t\t\ti, pf_ports,\n+\t\t\t\t(unsigned long long)mydata.tx_pkts,\n+\t\t\t\t(unsigned long long)mydata.rx_pkts,\n+\t\t\t\t(unsigned long long)mydata.rx_drop);\n+\n+\t\tif (!fm10k_config_check_debug(sw->dpdk_cfg,\n+\t\t\t\tFM10K_CONFIG_DEBUG_STATS_QUEUE))\n+\t\t\tcontinue;\n+\t\tmemset(&mydata, 0, sizeof(mydata));\n+\t\tfor (j = 0;\n+\t\t\t j < sw->dpdk_cfg->ports[i].tx_queue_num;\n+\t\t\t j++) {\n+\t\t\tstruct fm10k_hw *hw = sw->dpdk_cfg->ports[i].hw;\n+\t\t\tuint16_t queue_id = j, pf_no;\n+\n+\t\t\tfm10k_switch_dpdk_hw_queue_map(hw, queue_id,\n+\t\t\t\t\tsw->dpdk_cfg->ports[i].tx_queue_num,\n+\t\t\t\t\t&hw, &queue_id);\n+\t\t\tpf_no = fm10k_switch_dpdk_pf_no_get(hw);\n+\t\t\tdata.tx_pkts =\n+\t\t\t\tFM10K_READ_REG(hw, FM10K_QPTC(queue_id));\n+\t\t\tdata.rx_pkts =\n+\t\t\t\tFM10K_READ_REG(hw, FM10K_QPRC(queue_id));\n+\t\t\tdata.rx_drop =\n+\t\t\t\tFM10K_READ_REG(hw, FM10K_QPRDC(queue_id));\n+\t\t\tmydata.tx_pkts += data.tx_pkts -\n+\t\t\t\tlast_queue_data[pf_no][queue_id].tx_pkts;\n+\t\t\tmydata.rx_pkts += data.rx_pkts -\n+\t\t\t\tlast_queue_data[pf_no][queue_id].rx_pkts;\n+\t\t\tmydata.rx_drop += data.rx_drop -\n+\t\t\t\tlast_queue_data[pf_no][queue_id].rx_drop;\n+\t\t\tprintf(\"            queue %d(%d:%d) tx_pkt %-12llu \"\n+\t\t\t\t\"rx_pkt %-12llu drop_pkt %-12llu\\n\", j,\n+\t\t\t\tpf_no, queue_id,\n+\t\t\t\t(unsigned long long)(data.tx_pkts -\n+\t\t\t\tlast_queue_data[pf_no][queue_id].tx_pkts),\n+\t\t\t\t(unsigned long long)(data.rx_pkts -\n+\t\t\t\tlast_queue_data[pf_no][queue_id].rx_pkts),\n+\t\t\t\t(unsigned long long)(data.rx_drop -\n+\t\t\t\tlast_queue_data[pf_no][queue_id].rx_drop));\n+\t\t\tlast_queue_data[pf_no][queue_id] = data;\n+\t\t}\n+\t\tprintf(\"                   total tx_pkt %-12llu \"\n+\t\t\t\t\"rx_pkt %-12llu drop_pkt %-12llu\\n\",\n+\t\t\t\t(unsigned long long)mydata.tx_pkts,\n+\t\t\t\t(unsigned long long)mydata.rx_pkts,\n+\t\t\t\t(unsigned long long)mydata.rx_drop);\n+\t}\n+}\n+\n+\n+static void\n+fm10k_stats_port_counter_print(struct fm10k_switch *sw, int lport)\n+{\n+\tunsigned int i;\n+\tstruct fm10k_port_counters counters;\n+\tstruct fm10k_ext_port ext_port;\n+\tuint64_t *pdata;\n+\n+\tmemset(&ext_port, 0, sizeof(ext_port));\n+\text_port.portno = lport;\n+\tfm10k_get_port_counters(sw, &ext_port, &counters);\n+\n+\tfor (i = 0;\n+\t\t\ti < sizeof(rx_port_cnt_map_table) /\n+\t\t\t\tsizeof(rx_port_cnt_map_table[0]);\n+\t\t\ti++) {\n+\t\tpdata =\n+\t\t\t(uint64_t *)((uint8_t *)(&counters) +\n+\t\t\trx_port_cnt_map_table[i].frame_offset);\n+\t\tif (*pdata != 0) {\n+\t\t\tprintf(\"port %d rx bank %d idx %d pkt %llu\\n\", lport,\n+\t\t\t\t\trx_port_cnt_map_table[i].bank,\n+\t\t\t\t\trx_port_cnt_map_table[i].bin,\n+\t\t\t\t\t(unsigned long long)*pdata);\n+\t\t}\n+\t}\n+\tfor (i = 0;\n+\t\t\ti < sizeof(tx_port_cnt_map_table) /\n+\t\t\t\tsizeof(tx_port_cnt_map_table[0]);\n+\t\t\ti++) {\n+\t\tpdata =\n+\t\t\t(uint64_t *)((uint8_t *)(&counters) +\n+\t\t\ttx_port_cnt_map_table[i].frame_offset);\n+\t\tif (*pdata != 0) {\n+\t\t\tprintf(\"port %d tx bank %d idx %d pkt %llu\\n\",\n+\t\t\t\t\tlport,\n+\t\t\t\t\ttx_port_cnt_map_table[i].bank,\n+\t\t\t\t\ttx_port_cnt_map_table[i].bin,\n+\t\t\t\t\t(unsigned long long)*pdata);\n+\t\t}\n+\t}\n+}\n+\n+void\n+fm10k_stats_port_bank_print(struct fm10k_switch *sw)\n+{\n+\tint i;\n+\n+\tfor (i = 0;\n+\t\t i < FM10K_SW_EPLS_SUPPORTED;\n+\t\t i++) {\n+\t\tfm10k_stats_port_counter_print(sw,\n+\t\t\t\tsw->epl_map[i].logical_port);\n+\t}\n+\tfor (i = 0;\n+\t\t i < FM10K_SW_PEPS_SUPPORTED;\n+\t\t i++) {\n+\t\tfm10k_stats_port_counter_print(sw,\n+\t\t\t\tsw->pep_map[i].logical_port);\n+\t}\n+}\n+\n+\n+void *\n+fm10k_switch_process_stats(void *ctx)\n+{\n+\tstruct fm10k_switch *sw = ctx;\n+\n+\tusec_delay(5000000);\n+\n+\tif (!fm10k_config_check_debug(sw->dpdk_cfg,\n+\t\t\tFM10K_CONFIG_DEBUG_ENABLE))\n+\t\treturn NULL;\n+\n+\tif (!sw->dpdk_cfg->stats_interval)\n+\t\treturn NULL;\n+\n+\twhile (1) {\n+\t\tif (fm10k_config_check_debug(sw->dpdk_cfg,\n+\t\t\t\tFM10K_CONFIG_DEBUG_STATS_PORT)) {\n+\t\t\tprintf(\"--- port statistic ---\\n\");\n+\t\t\tfm10k_stats_epl_port_print(sw);\n+\t\t\tfm10k_stats_dpdk_port_print(sw);\n+\t\t}\n+\t\tif (fm10k_config_check_debug(sw->dpdk_cfg,\n+\t\t\t\tFM10K_CONFIG_DEBUG_STATS_FFU)) {\n+\t\t\tprintf(\"--- ffu statistic ---\\n\");\n+\t\t\tfm10k_stats_ffu_count_print(sw);\n+\t\t}\n+\t\tif (fm10k_config_check_debug(sw->dpdk_cfg,\n+\t\t\t\tFM10K_CONFIG_DEBUG_STATS_MORE)) {\n+\t\t\tprintf(\"--- detail statistic ---\\n\");\n+\t\t\tfm10k_stats_port_bank_print(sw);\n+\t\t}\n+\t\tusec_delay(1000000 * sw->dpdk_cfg->stats_interval);\n+\t}\n+\treturn NULL;\n+}\n+\ndiff --git a/drivers/net/fm10k/switch/fm10k_stats.h b/drivers/net/fm10k/switch/fm10k_stats.h\nnew file mode 100644\nindex 0000000..5180312\n--- /dev/null\n+++ b/drivers/net/fm10k/switch/fm10k_stats.h\n@@ -0,0 +1,257 @@\n+/* spdx-license-identifier: bsd-3-clause\n+ * copyright 2019   silicom ltd. connectivity solutions\n+ */\n+\n+#ifndef _fm10k_stats_h_\n+#define _fm10k_stats_h_\n+\n+\n+#include <stdint.h>\n+\n+\n+#define FM10K_STATS_VERSION\t  (1 << 4)\n+\n+\n+struct fm10k_scatter_gather_entry {\n+\tuint32_t  addr;\n+\tuint32_t  count;\n+\tuint32_t *data;\n+\n+};\n+\n+\n+struct fm10k_port_counters {\n+\tuint64_t cnt_version;\n+\tuint64_t cnt_rx_ucst_pkts;\n+\tuint64_t cnt_rx_ucst_pkts_nonip;\n+\tuint64_t cnt_rx_ucst_pkts_ipv4;\n+\tuint64_t cnt_rx_ucst_pkts_ipv6;\n+\tuint64_t cnt_rx_bcst_pkts;\n+\tuint64_t cnt_rx_bcst_pkts_nonip;\n+\tuint64_t cnt_rx_bcst_pkts_ipv4;\n+\tuint64_t cnt_rx_bcst_pkts_ipv6;\n+\tuint64_t cnt_rx_mcst_pkts;\n+\tuint64_t cnt_rx_mcst_pkts_nonip;\n+\tuint64_t cnt_rx_mcst_pkts_ipv4;\n+\tuint64_t cnt_rx_mcst_pkts_ipv6;\n+\tuint64_t cnt_rx_pause_pkts;\n+\tuint64_t cnt_rx_cbpause_pkts;\n+\tuint64_t cnt_rx_fcs_errors;\n+\tuint64_t cnt_rx_symbol_errors;\n+\tuint64_t cnt_rx_framesize_errors;\n+\tuint64_t cnt_rx_framing_error_pkts;\n+\tuint64_t cnt_rx_minto63_pkts;\n+\tuint64_t cnt_rx_64_pkts;\n+\tuint64_t cnt_rx_65to127_pkts;\n+\tuint64_t cnt_rx_128to255_pkts;\n+\tuint64_t cnt_rx_256to511_pkts;\n+\tuint64_t cnt_rx_512to1023_pkts;\n+\tuint64_t cnt_rx_1024to1522_pkts;\n+\tuint64_t cnt_rx_1523to2047_pkts;\n+\tuint64_t cnt_rx_2048to4095_pkts;\n+\tuint64_t cnt_rx_4096to8191_pkts;\n+\tuint64_t cnt_rx_8192to10239_pkts;\n+\tuint64_t cnt_rx_10240tomax_pkts;\n+\tuint64_t cnt_rx_minto63_octets;\n+\tuint64_t cnt_rx_64_octets;\n+\tuint64_t cnt_rx_65to127_octets;\n+\tuint64_t cnt_rx_128to255_octets;\n+\tuint64_t cnt_rx_256to511_octets;\n+\tuint64_t cnt_rx_512to1023_octets;\n+\tuint64_t cnt_rx_1024to1522_octets;\n+\tuint64_t cnt_rx_1523to2047_octets;\n+\tuint64_t cnt_rx_2048to4095_octets;\n+\tuint64_t cnt_rx_4096to8191_octets;\n+\tuint64_t cnt_rx_8192to10239_octets;\n+\tuint64_t cnt_rx_10240tomax_octets;\n+\tuint64_t cnt_rx_octets_nonip;\n+\tuint64_t cnt_rx_octets_ipv4;\n+\tuint64_t cnt_rx_octets_ipv6;\n+\tuint64_t cnt_rx_ucst_octets_nonip;\n+\tuint64_t cnt_rx_ucst_octets_ipv4;\n+\tuint64_t cnt_rx_ucst_octets_ipv6;\n+\tuint64_t cnt_rx_bcst_octets_nonip;\n+\tuint64_t cnt_rx_bcst_octets_ipv4;\n+\tuint64_t cnt_rx_bcst_octets_ipv6;\n+\tuint64_t cnt_rx_mcst_octets_nonip;\n+\tuint64_t cnt_rx_mcst_octets_ipv4;\n+\tuint64_t cnt_rx_mcst_octets_ipv6;\n+\tuint64_t cnt_rx_pause_octets;\n+\tuint64_t cnt_rx_cbpause_octets;\n+\tuint64_t cnt_rx_fcs_errors_octets;\n+\tuint64_t cnt_rx_framing_error_octets;\n+\tuint64_t cnt_rx_good_octets;\n+\tuint64_t cnt_rx_bad_octets;\n+\tuint64_t cnt_rx_priority_pkts[16];\n+\tuint64_t cnt_rx_invalid_priority_pkts;\n+\tuint64_t cnt_rx_priority_octets[16];\n+\tuint64_t cnt_rx_invalid_priority_octets;\n+\tuint64_t cnt_fid_forwarded_pkts;\n+\tuint64_t cnt_flood_forwarded_pkts;\n+\tuint64_t cnt_glort_switched_pkts;\n+\tuint64_t cnt_glort_routed_pkts;\n+\tuint64_t cnt_specially_handled_pkts;\n+\tuint64_t cnt_parse_err_drop_pkts;\n+\tuint64_t cnt_parity_error_pkts;\n+\tuint64_t cnt_trapped_pkts;\n+\tuint64_t cnt_pause_drop_pkts;\n+\tuint64_t cnt_stp_drop_pkts;\n+\tuint64_t cnt_stp_ingress_drops_pkts;\n+\tuint64_t cnt_stp_egress_drops_pkts;\n+\tuint64_t cnt_reserved_trap_pkts;\n+\tuint64_t cnt_security_violation_pkts;\n+\tuint64_t cnt_vlan_tag_drop_pkts;\n+\tuint64_t cnt_vlan_ingressbv_pkts;\n+\tuint64_t cnt_vlan_egressbv_pkts;\n+\tuint64_t cnt_loopback_drops_pkts;\n+\tuint64_t cnt_glort_miss_drop_pkts;\n+\tuint64_t cnt_ffu_drop_pkts;\n+\tuint64_t cnt_invalid_drop_pkts;\n+\tuint64_t cnt_policer_drop_pkts;\n+\tuint64_t cnt_ttl_drop_pkts;\n+\tuint64_t cnt_global_wmdrop_pkts;\n+\tuint64_t cnt_rx_mpdrop_pkts;\n+\tuint64_t cnt_rx_hogdrop_pkts;\n+\tuint64_t cnt_tx_hogdrop_pkts;\n+\tuint64_t cnt_other_pkts;\n+\tuint64_t cnt_flood_control_drop_pkts;\n+\tuint64_t cnt_cmpriv_drop_pkts;\n+\tuint64_t cnt_smp0_drop_pkts;\n+\tuint64_t cnt_smp1_drop_pkts;\n+\tuint64_t cnt_rx_hog0_drop_pkts;\n+\tuint64_t cnt_rx_hog1_drop_pkts;\n+\tuint64_t cnt_tx_hog0_drop_pkts;\n+\tuint64_t cnt_tx_hog1_drop_pkts;\n+\tuint64_t cnt_rate_limit0_drop_pkts;\n+\tuint64_t cnt_rate_limit1_drop_pkts;\n+\tuint64_t cnt_bad_smp_drop_pkts;\n+\tuint64_t cnt_trigger_drop_redir_pkts;\n+\tuint64_t cnt_trigger_drop_pkts;\n+\tuint64_t cnt_trigger_redir_pkts;\n+\tuint64_t cnt_glort_forwarded_pkts;\n+\tuint64_t cnt_trigger_mirrored_pkts;\n+\tuint64_t cnt_broadcast_drop_pkts;\n+\tuint64_t cnt_dlf_drop_pkts;\n+\tuint64_t cnt_rx_cm_drop_pkts;\n+\tuint64_t cnt_fid_forwarded_octets;\n+\tuint64_t cnt_flood_forwarded_octets;\n+\tuint64_t cnt_specially_handled_octets;\n+\tuint64_t cnt_parse_err_drop_octets;\n+\tuint64_t cnt_parity_error_octets;\n+\tuint64_t cnt_trapped_octets;\n+\tuint64_t cnt_pause_drop_octets;\n+\tuint64_t cnt_stp_drop_octets;\n+\tuint64_t cnt_security_violation_octets;\n+\tuint64_t cnt_vlan_tag_drop_octets;\n+\tuint64_t cnt_vlan_ingressbv_octets;\n+\tuint64_t cnt_vlan_egressbv_octets;\n+\tuint64_t cnt_loopback_drop_octets;\n+\tuint64_t cnt_glort_miss_drop_octets;\n+\tuint64_t cnt_ffu_drop_octets;\n+\tuint64_t cnt_policer_drop_octets;\n+\tuint64_t cnt_ttl_drop_octets;\n+\tuint64_t cnt_other_octets;\n+\tuint64_t cnt_flood_control_drop_octets;\n+\tuint64_t cnt_cmpriv_drop_octets;\n+\tuint64_t cnt_smp0_drop_octets;\n+\tuint64_t cnt_smp1_drop_octets;\n+\tuint64_t cnt_rx_hog0_drop_octets;\n+\tuint64_t cnt_rx_hog1_drop_octets;\n+\tuint64_t cnt_tx_hog0_drop_octets;\n+\tuint64_t cnt_tx_hog1_drop_octets;\n+\tuint64_t cnt_trigger_drop_octets;\n+\tuint64_t cnt_trigger_redir_octets;\n+\tuint64_t cnt_glort_forwarded_octets;\n+\tuint64_t cnt_tx_ucst_pkts;\n+\tuint64_t cnt_tx_bcst_pkts;\n+\tuint64_t cnt_tx_mcst_pkts;\n+\tuint64_t cnt_tx_ucst_pkts_nonip;\n+\tuint64_t cnt_tx_bcst_pkts_nonip;\n+\tuint64_t cnt_tx_mcst_pkts_nonip;\n+\tuint64_t cnt_tx_ucst_pkts_ip;\n+\tuint64_t cnt_tx_bcst_pkts_ip;\n+\tuint64_t cnt_tx_mcst_pkts_ip;\n+\tuint64_t cnt_tx_pause_pkts;\n+\tuint64_t cnt_tx_cbpause_pkts;\n+\tuint64_t cnt_tx_fcs_err_drop_pkts;\n+\tuint64_t cnt_tx_framing_error_pkts;\n+\tuint64_t cnt_tx_error_sent_pkts;\n+\tuint64_t cnt_tx_error_drop_pkts;\n+\tuint64_t cnt_tx_timeout_pkts;\n+\tuint64_t cnt_tx_outofmem_err_pkts;\n+\tuint64_t cnt_tx_unrepair_ecc_pkts;\n+\tuint64_t cnt_tx_loopback_pkts;\n+\tuint64_t cnt_tx_ttl_drop_pkts;\n+\tuint64_t cnt_tx_minto63_pkts;\n+\tuint64_t cnt_tx_64_pkts;\n+\tuint64_t cnt_tx_65to127_pkts;\n+\tuint64_t cnt_tx_128to255_pkts;\n+\tuint64_t cnt_tx_256to511_pkts;\n+\tuint64_t cnt_tx_512to1023_pkts;\n+\tuint64_t cnt_tx_1024to1522_pkts;\n+\tuint64_t cnt_tx_1523to2047_pkts;\n+\tuint64_t cnt_tx_2048to4095_pkts;\n+\tuint64_t cnt_tx_4096to8191_pkts;\n+\tuint64_t cnt_tx_8192to10239_pkts;\n+\tuint64_t cnt_tx_10240tomax_pkts;\n+\tuint64_t cnt_tx_minto63_octets;\n+\tuint64_t cnt_tx_64_octets;\n+\tuint64_t cnt_tx_65to127_octets;\n+\tuint64_t cnt_tx_128to255_octets;\n+\tuint64_t cnt_tx_256to511_octets;\n+\tuint64_t cnt_tx_512to1023_octets;\n+\tuint64_t cnt_tx_1024to1522_octets;\n+\tuint64_t cnt_tx_1523to2047_octets;\n+\tuint64_t cnt_tx_2048to4095_octets;\n+\tuint64_t cnt_tx_4096to8191_octets;\n+\tuint64_t cnt_tx_8192to10239_octets;\n+\tuint64_t cnt_tx_10240tomax_octets;\n+\tuint64_t cnt_tx_ucst_octets_nonip;\n+\tuint64_t cnt_tx_bcst_octets_nonip;\n+\tuint64_t cnt_tx_mcst_octets_nonip;\n+\tuint64_t cnt_tx_ucst_octets_ip;\n+\tuint64_t cnt_tx_bcst_octets_ip;\n+\tuint64_t cnt_tx_mcst_octets_ip;\n+\tuint64_t cnt_tx_ucst_octets;\n+\tuint64_t cnt_tx_mcst_octets;\n+\tuint64_t cnt_tx_bcst_octets;\n+\tuint64_t cnt_tx_fcs_err_drop_octets;\n+\tuint64_t cnt_tx_octets;\n+\tuint64_t cnt_tx_error_octets;\n+\tuint64_t cnt_tx_framing_error_octets;\n+\tuint64_t cnt_tx_pause_octets;\n+\tuint64_t cnt_tx_cbpause_octets;\n+\tuint64_t cnt_tx_fcs_errored_octets;\n+\tuint64_t cnt_tx_error_sent_octets;\n+\tuint64_t cnt_tx_timeout_octets;\n+\tuint64_t cnt_tx_outofmem_err_octets;\n+\tuint64_t cnt_tx_unrepair_ecc_octets;\n+\tuint64_t cnt_tx_loopback_octets;\n+\tuint64_t cnt_tx_ttl_drop_octets;\n+\tuint64_t cnt_tx_priority_octets[16];\n+\tuint64_t cnt_under_run_pkts;\n+\tuint64_t cnt_over_run_pkts;\n+\tuint64_t cnt_rx_fragment_pkts;\n+\tuint64_t cnt_rx_undersized_pkts;\n+\tuint64_t cnt_rx_jabber_pkts;\n+\tuint64_t cnt_corrupted_pkts;\n+\tuint64_t cnt_code_errors;\n+\tuint64_t cnt_rx_oversized_pkts;\n+\tuint64_t cnt_tx_fcs_errored_pkts;\n+\tuint64_t cnt_stats_drop_count_tx;\n+\tuint64_t cnt_stats_drop_count_rx;\n+\tuint64_t cnt_tx_mirror_pkts;\n+\tuint64_t cnt_tx_mirror_octets;\n+\tuint64_t cnt_tx_cmdrop_pkts;\n+\tuint64_t timestamp;\n+};\n+\n+void fm10k_stats_rule_count_reg(uint16_t rule_id);\n+void *fm10k_switch_process_stats(void *ctx_);\n+\n+void fm10k_stats_epl_port_print(struct fm10k_switch *sw);\n+void fm10k_stats_dpdk_port_print(struct fm10k_switch *sw);\n+void fm10k_stats_ffu_count_print(struct fm10k_switch *sw);\n+void fm10k_stats_port_bank_print(struct fm10k_switch *sw);\n+\n+#endif /* _fm10k_stats_h */\n",
    "prefixes": [
        "v2",
        "3/7"
    ]
}