From patchwork Fri Feb 22 11:15:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hemant Agrawal X-Patchwork-Id: 50442 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E48912BF4; Fri, 22 Feb 2019 12:16:00 +0100 (CET) Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50040.outbound.protection.outlook.com [40.107.5.40]) by dpdk.org (Postfix) with ESMTP id A53AF1E34 for ; Fri, 22 Feb 2019 12:15:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IIZCRlbjWQWa1r2Zo+9Z9h3dWRD+Rv4Gm3FfeId03BA=; b=whfIh/Aq4HRZ3ZU0GPYrsUMMr98pt0am1rA97kJ4HgtMGSxbyEhWBNwTEe+JkdXuBS/IVES4w5ArAN20LqsOQW7TDF7aMvuuEacWW7IFSUPPoTcylGhxodU3d3A088kcTiqhZn60lllkk0XYX4vQvIchy2zzb6zlrqyo6XnH97Q= Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com (10.168.65.19) by VI1PR0401MB2431.eurprd04.prod.outlook.com (10.169.134.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1643.14; Fri, 22 Feb 2019 11:15:58 +0000 Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84]) by VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84%9]) with mapi id 15.20.1643.016; Fri, 22 Feb 2019 11:15:58 +0000 From: Hemant Agrawal To: "dev@dpdk.org" CC: "ferruh.yigit@intel.com" , Shreyansh Jain Thread-Topic: [PATCH 1/6] net/dpaa2: add support for VLAN tpid config Thread-Index: AQHUyp/81xWmFcOo60GlJhRracTplA== Date: Fri, 22 Feb 2019 11:15:58 +0000 Message-ID: <20190222111440.30530-1-hemant.agrawal@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [92.120.1.72] x-mailer: git-send-email 2.17.1 x-clientproxiedby: BM1PR01CA0084.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:1::24) To VI1PR0401MB2541.eurprd04.prod.outlook.com (2603:10a6:800:56::19) authentication-results: spf=none (sender IP is ) smtp.mailfrom=hemant.agrawal@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: c40bdb05-6ece-4352-4e51-08d698b71e89 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600110)(711020)(4605104)(4618075)(2017052603328)(7153060)(7193020); SRVR:VI1PR0401MB2431; x-ms-traffictypediagnostic: VI1PR0401MB2431: x-microsoft-exchange-diagnostics: =?iso-8859-1?Q?1; VI1PR0401MB2431; 23:iT6VY+dzuezg6ec4dHysjiS4FCsxhgS5bM4HN?= =?iso-8859-1?q?a+ifjexLRDNf2ZLL2SOcwTulv?= =?iso-8859-1?q?gr9LTPYTeRxn353lrolKG01B2g8YU7LSHNMWGajTtONpONGmOqE?= =?iso-8859-1?q?lIHSdGKIu3047itABDL9/+yz6CNRcCFH+3M2TNaGjtKbYzGu9tH?= =?iso-8859-1?q?V3OZG+cXBHvZwnok6h1M8ZUDewWJ0IsKSbbN5XRbS7jyUayOApr?= =?iso-8859-1?q?wrmHrtr8ks89im4r2aF6a3w80Xh6xq0YQv4l5xxdCB0gKE8h5RF?= =?iso-8859-1?q?yKQnR/4q59+1BJwpdoThuXrDgmXaqxtlhQw32CsgQ0kjHKfibDG?= =?iso-8859-1?q?ScdxMxiBEl/ZjHZNE/AJiKzffGjzlEoorLMmrioFxo52M9+lo7b?= =?iso-8859-1?q?s37mbJk03vyk2SlojzRUMWGJaRul2TocnlIMlEQOFnP1N7d70Bz?= =?iso-8859-1?q?HQOu+yruusWwdceTmYthui0mL5fCkOrxtPEiwgCcBdp+BgGCaFc?= =?iso-8859-1?q?EZ7o//Y0WNkgNe3Ga1UZQdeJaL1kha0nxqS+pH28G3FMlmVgY8K?= =?iso-8859-1?q?v8EIr6LnJVeq7EclSCOBQadq7z/f9PudqL/XaIQggkwxc58Vmyl?= =?iso-8859-1?q?jmJjcfM72m3kC+TLml4iKWkbjL2H/xxzlbkiFe3DAkDoILGTZmX?= =?iso-8859-1?q?XAusKZex6eAzD6K3Q+srhdkcfmvBAKu4wHQ0ZARXba20DF6eYxJ?= =?iso-8859-1?q?FqEEyveIiOzy/D2iHBaHGfuTgmJOgZ//Vxm7qFuw3oCY5/JO24F?= =?iso-8859-1?q?Vb7NkJieWtq/KLybe2K3WE/+pAU1+SNjTn8j4RsEJpl86rYjcSt?= =?iso-8859-1?q?1tLM+wYbsjWnTZi1gdIwvAZzKEc8M2r6qq8bNESh7efjdUfDpO0?= =?iso-8859-1?q?pOx4H+q+Enrx4w2B9vRxV82dBr41lq7ZjT8pyE16vPVoKygHRRX?= =?iso-8859-1?q?+d7kBRX6FLEHUV/jgpqbgjthaThZ0YDQFklLiynxXo4i/VaaLEV?= =?iso-8859-1?q?vizK3Unb+QgSbxWdBcapddo9j3JYU5kOs2ZlqbPjd2oJbQAJeUO?= =?iso-8859-1?q?toCxyUuPciEVhrt0ZNqPcVPfRykh8jFD787pRphpniJBEPAZb9S?= =?iso-8859-1?q?s8HGHEhv+bwqFqIcIi1iGKHKVOzL6z34ez63GIJCSAPBMKvv6to?= =?iso-8859-1?q?LLNakA8YK2zD6Sas31lFOCw/dZvG1aPACTrkIvhSr267e889kPg?= =?iso-8859-1?q?WOXZ5MstJjDoH5KluLGwsMlaqEGgPETpmV1R04ST+K8IFYHSHAC?= =?iso-8859-1?q?ytJJtMceqObgKhaEr3IewTa5hzJwDiC2szMaf/lw7wGyJkV8/uD?= =?iso-8859-1?q?BCq6sOxMOCXymG/pjkAbpob+XjbaLPjJZ9mupR/Hh/frP?= x-microsoft-antispam-prvs: x-forefront-prvs: 09565527D6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(376002)(396003)(136003)(366004)(189003)(199004)(2906002)(99286004)(8936002)(105586002)(26005)(54906003)(3846002)(6116002)(106356001)(71190400001)(8676002)(97736004)(316002)(6506007)(6512007)(1730700003)(5640700003)(81156014)(71200400001)(102836004)(36756003)(14444005)(256004)(386003)(6486002)(50226002)(81166006)(6436002)(6916009)(86362001)(1076003)(305945005)(478600001)(5660300002)(68736007)(44832011)(2616005)(486006)(2501003)(53936002)(2351001)(66066001)(7736002)(4326008)(186003)(14454004)(25786009)(52116002)(476003); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0401MB2431; H:VI1PR0401MB2541.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: d4uGTR96uSbixOdTzdK3uQ7qgqdnyRJp2jW4lx4cWVCFCNBnj0pYNrVqiX83k3/4CmbxaWzQMijABqYYT4ouofVHfRmqt1HMEcFB36D6svg0oeL6MjX6w/R/enBU3wS3j9SHAD/2yl7G93zovKnL9dB80YaxWJYEXCseJzVBOpDADy53aP37U9M9s9/lsaQYLO3iL0SCMHcuzkuH+5QsjGvNfUDL4yVWcaMjAkyKuc9R1UR2+EaXAfFG6Soeq2oNk9HOyKMN/nz7t7Z50r9b/MOj1i8v9xIjKH+GIMCoJ8+mYMkz8EU+lR1qfaKkpnKuLFqjzk3CLDXHUb1AktELG6q7ir5AZWmpGY17kA0dgynRctATCx2CZwsGUG4ayEiaXenqfIJyx9L5/MD6GShDCwOgU2pyTx+DG/tBZgTxi2Y= MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: c40bdb05-6ece-4352-4e51-08d698b71e89 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Feb 2019 11:15:57.0139 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2431 Subject: [dpdk-dev] [PATCH 1/6] net/dpaa2: add support for VLAN tpid config X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add support to config custom tpid in dpni. i.e. value other than 0x8100 and 0x88A8 Signed-off-by: Hemant Agrawal --- drivers/net/dpaa2/dpaa2_ethdev.c | 39 ++++++++++++ drivers/net/dpaa2/mc/dpni.c | 98 +++++++++++++++++++++++++++++ drivers/net/dpaa2/mc/fsl_dpni.h | 20 ++++++ drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 18 ++++++ 4 files changed, 175 insertions(+) diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index 2b90f4021..bc3faa8a3 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -161,6 +161,44 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask) return 0; } +static int +dpaa2_vlan_tpid_set(struct rte_eth_dev *dev, + enum rte_vlan_type vlan_type __rte_unused, + uint16_t tpid) +{ + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct fsl_mc_io *dpni = priv->hw; + int ret = -ENOTSUP; + + PMD_INIT_FUNC_TRACE(); + + /* nothing to be done for standard vlan tpids */ + if (tpid == 0x8100 || tpid == 0x88A8) + return 0; + + ret = dpni_add_custom_tpid(dpni, CMD_PRI_LOW, + priv->token, tpid); + if (ret < 0) + DPAA2_PMD_INFO("Unable to set vlan tpid = %d", ret); + /* if already configured tpids, remove them first */ + if (ret == -EBUSY) { + struct dpni_custom_tpid_cfg tpid_list = {0}; + + ret = dpni_get_custom_tpid(dpni, CMD_PRI_LOW, + priv->token, &tpid_list); + if (ret < 0) + goto fail; + ret = dpni_remove_custom_tpid(dpni, CMD_PRI_LOW, + priv->token, tpid_list.tpid1); + if (ret < 0) + goto fail; + ret = dpni_add_custom_tpid(dpni, CMD_PRI_LOW, + priv->token, tpid); + } +fail: + return ret; +} + static int dpaa2_fw_version_get(struct rte_eth_dev *dev, char *fw_version, @@ -1832,6 +1870,7 @@ static struct eth_dev_ops dpaa2_ethdev_ops = { .mtu_set = dpaa2_dev_mtu_set, .vlan_filter_set = dpaa2_vlan_filter_set, .vlan_offload_set = dpaa2_vlan_offload_set, + .vlan_tpid_set = dpaa2_vlan_tpid_set, .rx_queue_setup = dpaa2_dev_rx_queue_setup, .rx_queue_release = dpaa2_dev_rx_queue_release, .tx_queue_setup = dpaa2_dev_tx_queue_setup, diff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c index 44b5604d3..0907a3699 100644 --- a/drivers/net/dpaa2/mc/dpni.c +++ b/drivers/net/dpaa2/mc/dpni.c @@ -2063,3 +2063,101 @@ int dpni_get_opr(struct fsl_mc_io *mc_io, return 0; } + +/** + * dpni_add_custom_tpid() - Configures a distinct Ethertype value + * (or TPID value) to indicate VLAN tag in addition to the common + * TPID values 0x8100 and 0x88A8 + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tpid: New value for TPID + * + * Only two custom values are accepted. If the function is called for the third + * time it will return error. + * To replace an existing value use dpni_remove_custom_tpid() to remove + * a previous TPID and after that use again the function. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, uint16_t tpid) +{ + struct dpni_cmd_add_custom_tpid *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_CUSTOM_TPID, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_add_custom_tpid *)cmd.params; + cmd_params->tpid = cpu_to_le16(tpid); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_remove_custom_tpid() - Removes a distinct Ethertype value added + * previously with dpni_add_custom_tpid() + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tpid: New value for TPID + * + * Use this function when a TPID value added with dpni_add_custom_tpid() needs + * to be replaced. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_remove_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, uint16_t tpid) +{ + struct dpni_cmd_remove_custom_tpid *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_CUSTOM_TPID, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_remove_custom_tpid *)cmd.params; + cmd_params->tpid = cpu_to_le16(tpid); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_get_custom_tpid() - Returns custom TPID (vlan tags) values configured + * to detect 802.1q frames + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tpid: TPID values. Only nonzero members of the structure are valid. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, struct dpni_custom_tpid_cfg *tpid) +{ + struct dpni_rsp_get_custom_tpid *rsp_params; + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_CUSTOM_TPID, + cmd_flags, + token); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* read command response */ + rsp_params = (struct dpni_rsp_get_custom_tpid *)cmd.params; + tpid->tpid1 = le16_to_cpu(rsp_params->tpid1); + tpid->tpid2 = le16_to_cpu(rsp_params->tpid2); + + return err; +} diff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h index de1bcb5bf..0359a2bc7 100644 --- a/drivers/net/dpaa2/mc/fsl_dpni.h +++ b/drivers/net/dpaa2/mc/fsl_dpni.h @@ -1202,4 +1202,24 @@ int dpni_get_opr(struct fsl_mc_io *mc_io, struct opr_cfg *cfg, struct opr_qry *qry); +int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, uint16_t tpid); + +int dpni_remove_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, uint16_t tpid); + +/** + * struct dpni_custom_tpid_cfg - custom TPID configuration. Contains custom TPID + * values used in current dpni object to detect 802.1q frames. + * @tpid1: first tag. Not used if zero. + * @tpid2: second tag. Not used if zero. + */ +struct dpni_custom_tpid_cfg { + uint16_t tpid1; + uint16_t tpid2; +}; + +int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, struct dpni_custom_tpid_cfg *tpid); + #endif /* __FSL_DPNI_H */ diff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h index 3df5bcf1f..81830ed85 100644 --- a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h +++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h @@ -91,6 +91,9 @@ #define DPNI_CMDID_GET_TX_CONFIRMATION_MODE DPNI_CMD(0x26D) #define DPNI_CMDID_SET_OPR DPNI_CMD(0x26e) #define DPNI_CMDID_GET_OPR DPNI_CMD(0x26f) +#define DPNI_CMDID_ADD_CUSTOM_TPID DPNI_CMD(0x275) +#define DPNI_CMDID_REMOVE_CUSTOM_TPID DPNI_CMD(0x276) +#define DPNI_CMDID_GET_CUSTOM_TPID DPNI_CMD(0x277) /* Macros for accessing command fields smaller than 1byte */ #define DPNI_MASK(field) \ @@ -674,5 +677,20 @@ struct dpni_rsp_get_opr { uint16_t opr_id; }; +struct dpni_cmd_add_custom_tpid { + uint16_t pad; + uint16_t tpid; +}; + +struct dpni_cmd_remove_custom_tpid { + uint16_t pad; + uint16_t tpid; +}; + +struct dpni_rsp_get_custom_tpid { + uint16_t tpid1; + uint16_t tpid2; +}; + #pragma pack(pop) #endif /* _FSL_DPNI_CMD_H */ From patchwork Fri Feb 22 11:15:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hemant Agrawal X-Patchwork-Id: 50443 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 70A8D2C39; Fri, 22 Feb 2019 12:16:04 +0100 (CET) Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50061.outbound.protection.outlook.com [40.107.5.61]) by dpdk.org (Postfix) with ESMTP id 8D2751E34; Fri, 22 Feb 2019 12:16:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6Ypyw5ieGgkIRjYNRIsU+3ImKi2TK60mHMipuS3fhEM=; b=YPxE/sSYKRkw97aHbM6s5IOhj/N55cbclqIFxHCEOGh3+1XGUwVrhO1M0hN1+PX3G5AI4S92blbZumm0Vi6HpNmPU5aCX+aVGVNd8cqt5WTPiz+PulQRuJVewDUluvYOzZUAcMy6F74DmN6TAMw7MiBlgaMGqc3STrJ4EpSsPHA= Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com (10.168.65.19) by VI1PR0401MB2431.eurprd04.prod.outlook.com (10.169.134.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1643.14; Fri, 22 Feb 2019 11:15:59 +0000 Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84]) by VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84%9]) with mapi id 15.20.1643.016; Fri, 22 Feb 2019 11:15:59 +0000 From: Hemant Agrawal To: "dev@dpdk.org" CC: "ferruh.yigit@intel.com" , Shreyansh Jain , "stable@dpdk.org" Thread-Topic: [PATCH 2/6] mempool/dpaa2: fix to reduce continuous print on empty pool Thread-Index: AQHUyp/9/yB64hl2XUSpnb6ESM5/ng== Date: Fri, 22 Feb 2019 11:15:59 +0000 Message-ID: <20190222111440.30530-2-hemant.agrawal@nxp.com> References: <20190222111440.30530-1-hemant.agrawal@nxp.com> In-Reply-To: <20190222111440.30530-1-hemant.agrawal@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [92.120.1.72] x-mailer: git-send-email 2.17.1 x-clientproxiedby: BM1PR01CA0084.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:1::24) To VI1PR0401MB2541.eurprd04.prod.outlook.com (2603:10a6:800:56::19) authentication-results: spf=none (sender IP is ) smtp.mailfrom=hemant.agrawal@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 27b87814-ac60-4062-d408-08d698b71f65 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600110)(711020)(4605104)(4618075)(2017052603328)(7153060)(7193020); SRVR:VI1PR0401MB2431; x-ms-traffictypediagnostic: VI1PR0401MB2431: x-microsoft-exchange-diagnostics: =?iso-8859-1?Q?1; VI1PR0401MB2431; 23:u1SvD+z3cwXFRfcbd8yaaQIidNiXYszFOYKzL?= =?iso-8859-1?q?TxRrzji8XUGr5NzflyKplftQN?= =?iso-8859-1?q?Qi/v8+2koQUM8zx1N2zHmi3DQ0QeQ1tLfSILxxeKyFk+AHWcrWk?= =?iso-8859-1?q?eml6tDxpzmqM6Iz0kGNucbuc7qi2v+Sd0m+NBy7rO47HK4K8NO8?= =?iso-8859-1?q?63BfKrTfvgNzM3Rpr5OWsHyzWRZ2qA8KGkdP27EoiZnn90weBz7?= =?iso-8859-1?q?mvj2Duz+UQ67u2extskxX1x06L3zLhO6q6+UwBLVCdYBGfoNEUI?= =?iso-8859-1?q?Odcf8OyT/4tbCKSmdZakqnrvViR2xttfhFZ51L3OhLN7mWLQWhE?= =?iso-8859-1?q?bewqzTOCKNn+ic7YFBYgSCyT+3NGlWsuYZbs3lavbW0SkhEgTUN?= =?iso-8859-1?q?oZz+c74JssQNKdmwrghEPMgH4XkVE48kcIpaDbmYq1+k60kuDCO?= =?iso-8859-1?q?ccoThwRUVR8gINOjtjdCcij3kvI2AfetvyDESHY2Xe7yteArsvP?= =?iso-8859-1?q?IcB0Hj0egVQzHPJejFpg79SuEPIYNXzRi9y3DXOc9B6bYUGxGS8?= =?iso-8859-1?q?PkH8qupiZHuY0QPrLStFKbBw4sURcTmFoh4fe1UxHbRrIeStf0+?= =?iso-8859-1?q?di0ib30OzDi/kVE23YDQqSKeTqhnnpYYPVisTbR51ou+aL6bsrA?= =?iso-8859-1?q?xJvbImeg2EFx/ce2Se+gYl98huIoRqSY2kkI/7UK2i0t4zvBpaU?= =?iso-8859-1?q?tj9ztInr1tCq33/k48vwL2u+/u7KHT9uH0UOq3O45uTA+HHdki8?= =?iso-8859-1?q?YHmkyt0t3iidBGyjjOIeDrgrEcPZpGh0xY/c0ILYjCQuntk7MY9?= =?iso-8859-1?q?S6bAt+G58SSak4E+gFzpv2W+UqCKpVeUpL2nV5LBd2Zj4SzbXh5?= =?iso-8859-1?q?6CvG49ebWznqNz5i7nA4y52cTzNdQtJ7sIjrcBB+Lzds1fVc+iE?= =?iso-8859-1?q?eFBOGsWtiwF0qA7PEu/SohQFtMMQdU6KNtjubg7fBRweZR/TMbb?= =?iso-8859-1?q?X+9lb8GDlTB/vM84lvxn9zIm+EejTm2+7VcMu9HFX6dQPoqWmGl?= =?iso-8859-1?q?I11pODF5UmVATfHhm+43cP/YxUWFN3WuksLQjSkkEDMZAipQWgJ?= =?iso-8859-1?q?N/2pL92aBHTmE5Y9fryB4Ci8CK33j/oLt4CsNxTjzISKjQ6MlIe?= =?iso-8859-1?q?/ApTNVNrli9nSUV3qpIOvSeJkZ96wrXEB6qDPTNzlimMDS124hp?= =?iso-8859-1?q?LvWd5M1ehaGLnibO5xqokNnxlC7hIjTvcCE+wHM487CyyNHWWAc?= =?iso-8859-1?q?dxIbwX/gBJ3RwxTmWR0h2uJw9Ztto4bTwbBp6ymBr8FiKHQS/Xb?= =?iso-8859-1?q?H/xMyNl8+tdoK2kxukBa/9eCOWkig9R1k0v10wfLVBjgXyPrB7K?= =?iso-8859-1?q?uF0S4BQ9/OZEX93wI1acdZbKjsEziktZsHFFkKuHTNph/VgK+0A?= =?iso-8859-1?q?dsN4Q2H?= x-microsoft-antispam-prvs: x-forefront-prvs: 09565527D6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(376002)(396003)(136003)(366004)(189003)(199004)(2906002)(99286004)(8936002)(105586002)(26005)(54906003)(3846002)(6116002)(106356001)(71190400001)(8676002)(97736004)(316002)(6506007)(6512007)(1730700003)(5640700003)(81156014)(71200400001)(102836004)(36756003)(256004)(386003)(6486002)(50226002)(81166006)(6436002)(6916009)(86362001)(1076003)(305945005)(478600001)(5660300002)(68736007)(44832011)(2616005)(486006)(11346002)(2501003)(53936002)(2351001)(66066001)(4744005)(7736002)(4326008)(186003)(446003)(14454004)(76176011)(25786009)(52116002)(476003); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0401MB2431; H:VI1PR0401MB2541.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: GkUBkAGLjsHSVGGkGqcgHpFVbv9DW3mymwuHrBDYjZDVh4jlYaf5jGp7Gy74fybefnIlvs1ASGPcMAmc0moA9O+KDBbeP754Ksp6Qg26xz3FXVW5PO5UJxb1IAI7zd+q1gv+7B74b2XFno84Dl9O4oq2mFy7vwFfBEuRLXP48NbIa2Z8NUOiwNduk9L3IVBIqIm08Ty6t/Ns3MWI7bB52rNaH4loy9PKjdO1X23I+gY+/5ZaYyw/4EAxfMlkwXY2Uy8CnRFgcDE/P5ELy29oTgUObeab0F91Dv6tNKlpS1/NRK5/2RDNPAwZiDv0yBzkkh1I2fmgWw3W7NX40oBic6/2+ajjwJZmGfaFZ8Eo9qHwRvnUCoLuY8FmCftDGdQ/YpiwGs10aIlv6ifJKs48+uDPuWHIKXNvyJQG9OI9a3M= MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 27b87814-ac60-4062-d408-08d698b71f65 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Feb 2019 11:15:58.2979 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2431 Subject: [dpdk-dev] [PATCH 2/6] mempool/dpaa2: fix to reduce continuous print on empty pool X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Changing the print to DP_DEBUG to avoid continuous prints when buffer pools runs out of buffers Fixes: 3646ccf0b036 ("mempool/dpaa2: support dynamic logging") Cc: stable@dpdk.org Signed-off-by: Hemant Agrawal --- drivers/mempool/dpaa2/dpaa2_hw_mempool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c index 335eae40e..da66577cc 100644 --- a/drivers/mempool/dpaa2/dpaa2_hw_mempool.c +++ b/drivers/mempool/dpaa2/dpaa2_hw_mempool.c @@ -326,8 +326,8 @@ rte_dpaa2_mbuf_alloc_bulk(struct rte_mempool *pool, * in pool, qbman_swp_acquire returns 0 */ if (ret <= 0) { - DPAA2_MEMPOOL_ERR("Buffer acquire failed with" - " err code: %d", ret); + DPAA2_MEMPOOL_DP_DEBUG( + "Buffer acquire failed with err code: %d", ret); /* The API expect the exact number of requested bufs */ /* Releasing all buffers allocated */ rte_dpaa2_mbuf_release(pool, obj_table, bpid, From patchwork Fri Feb 22 11:16:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hemant Agrawal X-Patchwork-Id: 50444 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 249032F4F; Fri, 22 Feb 2019 12:16:06 +0100 (CET) Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50078.outbound.protection.outlook.com [40.107.5.78]) by dpdk.org (Postfix) with ESMTP id 8AB0A2C30 for ; Fri, 22 Feb 2019 12:16:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=z18ZkxCbNfhFvtoogYLp4+mApHakOlvQkeXqZCKwYNI=; b=iI3TcIarSrXMWlLD40KIjuTNyOw+pn02KbePixtuK2hWWSQ9CgcT+kcMGYoNV+fsdAuuO9II4CXxFJUPlbbVOPeL3hlF18MTG03s6CFBdZAROBJUTN63/ftUfpFYJPtvmiPy6uKVQtJEUmi4NBn7UYG/1Blbr78r8Jl6o4Ni4aE= Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com (10.168.65.19) by VI1PR0401MB2431.eurprd04.prod.outlook.com (10.169.134.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1643.14; Fri, 22 Feb 2019 11:16:01 +0000 Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84]) by VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84%9]) with mapi id 15.20.1643.016; Fri, 22 Feb 2019 11:16:01 +0000 From: Hemant Agrawal To: "dev@dpdk.org" CC: "ferruh.yigit@intel.com" , Shreyansh Jain , Nipun Gupta Thread-Topic: [PATCH 3/6] bus/fslmc: add enqueue response read routines in qbman Thread-Index: AQHUyp/+uyOYWW+ao0WwttU4gJ5aig== Date: Fri, 22 Feb 2019 11:16:01 +0000 Message-ID: <20190222111440.30530-3-hemant.agrawal@nxp.com> References: <20190222111440.30530-1-hemant.agrawal@nxp.com> In-Reply-To: <20190222111440.30530-1-hemant.agrawal@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [92.120.1.72] x-mailer: git-send-email 2.17.1 x-clientproxiedby: BM1PR01CA0084.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:1::24) To VI1PR0401MB2541.eurprd04.prod.outlook.com (2603:10a6:800:56::19) authentication-results: spf=none (sender IP is ) smtp.mailfrom=hemant.agrawal@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 04989335-0e57-4ed2-369d-08d698b7205f x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600110)(711020)(4605104)(4618075)(2017052603328)(7153060)(7193020); SRVR:VI1PR0401MB2431; x-ms-traffictypediagnostic: VI1PR0401MB2431: x-microsoft-exchange-diagnostics: =?iso-8859-1?Q?1; VI1PR0401MB2431; 23:ptKhWMoX+o9YWD1AEn20cF0uyX7s2Kgv1Kb3w?= =?iso-8859-1?q?7a6F0ZWB3ipF7LWvOBes92df6?= =?iso-8859-1?q?vD1GPHWHhLudpSjSGcWfx67eS/ajXo36sYT0SmLzw1QelUxhVhi?= =?iso-8859-1?q?UDPJJZBxn22wpckfZ94oFCkj81RHjvC6AYVw+vHjNbUGb+bcsdb?= =?iso-8859-1?q?p1xULoxsbdlqOIOMTyu/HWQhzSMN9UWdlFbIAR4zg6bYRNaEIMq?= =?iso-8859-1?q?YiOTHfSiJOTwXrcNHoCOurUkj5jIMw/Y1X0OIfbbZIikuB1Nihr?= =?iso-8859-1?q?yVSudVyPDeHGwA5dGc86BlucbLkhucTjI3hmApf1KyPsXEROD+n?= =?iso-8859-1?q?7hB12K7d5V21Ay4hxo/brnYcGG07hAm6eBnfUEgv6PsG9XjRKxV?= =?iso-8859-1?q?C9YP+1K+0SUiYa5vii+QwgynhcAqcN2P22/txNDlD/k6BUuH/fD?= =?iso-8859-1?q?13WVnshW6sq88bza0BCM1pfY/T5wq8Lvpm74gPl0r3dFbKGRWtp?= =?iso-8859-1?q?VuoV2SoFyL6CV+8jK0WjuE+VNxY0wJEIKz+SuUDKiYakIOGoAe3?= =?iso-8859-1?q?7lJrmxN7V5pupw6nPjCgmDTwY1MvQcsQMY9Vreja3osqLAGDDNa?= =?iso-8859-1?q?4VKYSUXtol9Ym2TM/yfBzzpekVrHf2nnp0qzElJms2a6pg8aXh0?= =?iso-8859-1?q?aQMfjYhrPeTXDVegU79SrcUmknmezZZwKe0/xXGyA+J+Y/BqziR?= =?iso-8859-1?q?kSbtG98BMLWwre4JaFTDxOn01gB2eGXEJnVQMlF9ptfkBWZh8R6?= =?iso-8859-1?q?hoelH5vsEmrjwCvQnFbvoGnt3EF47Th33DXg/WQUhlevLf3gwvc?= =?iso-8859-1?q?7Axy8C0+izq4wh01gjf/onh7b+lTv519GBKP9ekF2OQxOQwnkUx?= =?iso-8859-1?q?Q2P9D31deKa4/LNJ5G1uBBwFHg6Y++awi7u867loclYCrUTpfIb?= =?iso-8859-1?q?zbvkXZN71HdkXbP200/J9W778/2HC3YTpLfze4brTFzUBOGUkGx?= =?iso-8859-1?q?gQrTq7KqoynPPNRxtfru6aD2nBigT1HvmLDyXyiNcEd9BP3Xfjw?= =?iso-8859-1?q?Ka8MDURYAHugJcR6FZ+ZjNX6DNMu+WyrePLqAI0djwmGSHogJDn?= =?iso-8859-1?q?qyDo7q07dd0dFUxipIDu5FobArFlQ3zN57DgsCoD8hvAOMZasuC?= =?iso-8859-1?q?tptYgV/W9GJMX9h3p584iuSdU7S0yPziw+8terDxaInwXKWuZlr?= =?iso-8859-1?q?CqYztIg0wGS3cWOi8qyyc2wBurpU0qLt8mCptpRCHskppB4utfg?= =?iso-8859-1?q?ZqwX1pUQiDbVh9UaU4ns+tOYRyU6etnID9kHwLTu4BclqT9Gaq/?= =?iso-8859-1?q?SGQrIPD3EZSy+YYOnlakLWQtbguse7r0h9iXsNPNezPc9U9tFH+?= =?iso-8859-1?q?wPkCrvT98E24ghHVAbtfD770xHl7S1R36n7hR50mxfi6f5PCuMF?= =?iso-8859-1?q?gjhgoL4oek4JiXQ0ZGrL7XeJvoJO/9zNlTIAeLo9H2NwY69rtzR?= =?iso-8859-1?q?N+l12r/cDnpG5XGn8tbawJjtguNops38k7/O3U15Xq/Z8UlE8w2?= =?iso-8859-1?q?rFzQSQROhq+WqNflGhi2Wol6L0A45fPyJoDJzVpBK28/uEZLWzn?= =?iso-8859-1?q?R7zjOvs0uPzJDEUSqz7OrkW+8=3D?= x-microsoft-antispam-prvs: x-forefront-prvs: 09565527D6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(979002)(346002)(39860400002)(376002)(396003)(136003)(366004)(189003)(199004)(2906002)(99286004)(8936002)(105586002)(26005)(54906003)(3846002)(6116002)(106356001)(53946003)(71190400001)(8676002)(97736004)(316002)(6506007)(6512007)(1730700003)(5640700003)(81156014)(71200400001)(102836004)(36756003)(14444005)(5024004)(256004)(386003)(6486002)(50226002)(81166006)(6436002)(6916009)(86362001)(1076003)(305945005)(478600001)(5660300002)(68736007)(44832011)(2616005)(486006)(11346002)(2501003)(53936002)(2351001)(66066001)(30864003)(7736002)(4326008)(186003)(446003)(14454004)(76176011)(25786009)(52116002)(476003)(579004)(969003)(989001)(999001)(1009001)(1019001); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0401MB2431; H:VI1PR0401MB2541.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: 8FGe2rKLt6C4+Gwda8BkZhR3sVwQYXVL8y6ZUcKrm0ESRWs+tYsDol4ZEFL3fxUtHZj8JM82wF+013YtJvWQS7C4MVNAorVJMmTsL6HYtlCVcxw4UUYSCVDuE+1srX8Nh5G1KhAPhNjbU7OsJ9kEHKv0N3XBdOBOFrrMnHPf8j5pQiVJQkb0W0cLqVinXJX/ra1zBbUc73aiOHoe5TW2hQ6vYYpKPgMFe9ih0bbxwRXdVbaG36IVhmUXR7DEkPSc9HT1iypgIDvCN12NL8N74rwjBAcXSLGWG3M6S0wd3dTbE3oJK5Q3pEsq62VEVNRU/zXoctM+SljwYzbZ+kWXe6/jKfIWBdyg3uGB9p3roWbBtFsTBH5c/7dYemYLap2PLvUqjkbwGk/7rf2gO6c/DoW0hgy1XZP4b5pfkRpbXRw= MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 04989335-0e57-4ed2-369d-08d698b7205f X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Feb 2019 11:15:59.9293 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2431 Subject: [dpdk-dev] [PATCH 3/6] bus/fslmc: add enqueue response read routines in qbman X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Nipun Gupta Signed-off-by: Nipun Gupta --- drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 47 ++++ drivers/bus/fslmc/portal/dpaa2_hw_dpio.h | 4 + drivers/bus/fslmc/portal/dpaa2_hw_pvt.h | 24 ++ .../fslmc/qbman/include/fsl_qbman_portal.h | 56 +++- drivers/bus/fslmc/qbman/qbman_portal.c | 26 ++ drivers/bus/fslmc/rte_bus_fslmc_version.map | 16 +- drivers/net/dpaa2/dpaa2_ethdev.c | 42 +++ drivers/net/dpaa2/dpaa2_ethdev.h | 13 +- drivers/net/dpaa2/dpaa2_rxtx.c | 255 ++++++++++++++++++ 9 files changed, 480 insertions(+), 3 deletions(-) diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c index f377f24ae..7bcbde840 100644 --- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c +++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c @@ -526,6 +526,18 @@ dpaa2_create_dpio_device(int vdev_fd, goto err; } + dpio_dev->eqresp = rte_zmalloc(NULL, MAX_EQ_RESP_ENTRIES * + (sizeof(struct qbman_result) + + sizeof(struct eqresp_metadata)), + RTE_CACHE_LINE_SIZE); + if (!dpio_dev->eqresp) { + DPAA2_BUS_ERR("Memory allocation failed for eqresp"); + goto err; + } + dpio_dev->eqresp_meta = (struct eqresp_metadata *)(dpio_dev->eqresp + + MAX_EQ_RESP_ENTRIES); + + TAILQ_INSERT_TAIL(&dpio_dev_list, dpio_dev, next); return 0; @@ -588,6 +600,41 @@ dpaa2_alloc_dq_storage(struct queue_storage_info_t *q_storage) return -1; } +uint32_t +dpaa2_free_eq_descriptors(void) +{ + struct dpaa2_dpio_dev *dpio_dev = DPAA2_PER_LCORE_DPIO; + struct qbman_result *eqresp; + struct eqresp_metadata *eqresp_meta; + struct dpaa2_queue *txq; + + while (dpio_dev->eqresp_ci != dpio_dev->eqresp_pi) { + eqresp = &dpio_dev->eqresp[dpio_dev->eqresp_ci]; + eqresp_meta = &dpio_dev->eqresp_meta[dpio_dev->eqresp_ci]; + + if (!qbman_result_eqresp_rspid(eqresp)) + break; + + if (qbman_result_eqresp_rc(eqresp)) { + txq = eqresp_meta->dpaa2_q; + txq->cb_eqresp_free(dpio_dev->eqresp_ci); + } + qbman_result_eqresp_set_rspid(eqresp, 0); + + dpio_dev->eqresp_ci + 1 < MAX_EQ_RESP_ENTRIES ? + dpio_dev->eqresp_ci++ : (dpio_dev->eqresp_ci = 0); + } + + /* Return 1 less entry so that PI and CI are never same in a + * case there all the EQ responses are in use. + */ + if (dpio_dev->eqresp_ci > dpio_dev->eqresp_pi) + return dpio_dev->eqresp_ci - dpio_dev->eqresp_pi - 1; + else + return dpio_dev->eqresp_ci - dpio_dev->eqresp_pi + + MAX_EQ_RESP_ENTRIES - 1; +} + static struct rte_dpaa2_object rte_dpaa2_dpio_obj = { .dev_type = DPAA2_IO, .create = dpaa2_create_dpio_device, diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h index 4354c76de..17e7e4fad 100644 --- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h +++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.h @@ -51,4 +51,8 @@ dpaa2_alloc_dq_storage(struct queue_storage_info_t *q_storage); void dpaa2_free_dq_storage(struct queue_storage_info_t *q_storage); +/* free the enqueue response descriptors */ +uint32_t +dpaa2_free_eq_descriptors(void); + #endif /* _DPAA2_HW_DPIO_H_ */ diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h index 626fcbbca..4679e9340 100644 --- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h +++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h @@ -34,6 +34,7 @@ /* Maximum number of slots available in TX ring */ #define MAX_TX_RING_SLOTS 32 +#define MAX_EQ_RESP_ENTRIES (MAX_TX_RING_SLOTS + 1) /* Maximum number of slots available in RX ring */ #define DPAA2_EQCR_RING_SIZE 8 @@ -50,6 +51,15 @@ /* EQCR shift to get EQCR size for LX2 (2 >> 5) = 32 for LX2 */ #define DPAA2_LX2_EQCR_SHIFT 5 +/* Flag to determine an ordered queue mbuf */ +#define DPAA2_ENQUEUE_FLAG_ORP (1ULL << 30) +/* ORP ID shift and mask */ +#define DPAA2_EQCR_OPRID_SHIFT 16 +#define DPAA2_EQCR_OPRID_MASK 0x3FFF0000 +/* Sequence number shift and mask */ +#define DPAA2_EQCR_SEQNUM_SHIFT 0 +#define DPAA2_EQCR_SEQNUM_MASK 0x0000FFFF + #define DPAA2_SWP_CENA_REGION 0 #define DPAA2_SWP_CINH_REGION 1 #define DPAA2_SWP_CENA_MEM_REGION 2 @@ -77,12 +87,23 @@ #define DPAA2_DPCI_MAX_QUEUES 2 +struct dpaa2_queue; + +struct eqresp_metadata { + struct dpaa2_queue *dpaa2_q; + struct rte_mempool *mp; +}; + struct dpaa2_dpio_dev { TAILQ_ENTRY(dpaa2_dpio_dev) next; /**< Pointer to Next device instance */ uint16_t index; /**< Index of a instance in the list */ rte_atomic16_t ref_count; /**< How many thread contexts are sharing this.*/ + uint16_t eqresp_ci; + uint16_t eqresp_pi; + struct qbman_result *eqresp; + struct eqresp_metadata *eqresp_meta; struct fsl_mc_io *dpio; /** handle to DPIO portal object */ uint16_t token; struct qbman_swp *sw_portal; /** SW portal object */ @@ -125,6 +146,8 @@ typedef void (dpaa2_queue_cb_dqrr_t)(struct qbman_swp *swp, struct dpaa2_queue *rxq, struct rte_event *ev); +typedef void (dpaa2_queue_cb_eqresp_free_t)(uint16_t eqresp_ci); + struct dpaa2_queue { struct rte_mempool *mb_pool; /**< mbuf pool to populate RX ring. */ union { @@ -144,6 +167,7 @@ struct dpaa2_queue { }; struct rte_event ev; dpaa2_queue_cb_dqrr_t *cb; + dpaa2_queue_cb_eqresp_free_t *cb_eqresp_free; struct dpaa2_bp_info *bp_array; }; diff --git a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h index 10c72e048..a9192d3cb 100644 --- a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h +++ b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h @@ -212,6 +212,23 @@ struct qbman_result { __le32 rid_tok; __le64 ctx; } scn; + struct eq_resp { + uint8_t verb; + uint8_t dca; + __le16 seqnum; + __le16 oprid; + uint8_t reserved; + uint8_t rc; + __le32 tgtid; + __le32 tag; + uint16_t qdbin; + uint8_t qpri; + uint8_t reserved1; + __le32 fqid:24; + __le32 rspid:8; + __le64 rsp_addr; + uint8_t fd[32]; + } eq_resp; }; }; @@ -788,7 +805,6 @@ uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn); /************/ /* Enqueues */ /************/ - /* struct qbman_eq_desc - structure of enqueue descriptor */ struct qbman_eq_desc { union { @@ -956,6 +972,44 @@ void qbman_eq_desc_set_eqdi(struct qbman_eq_desc *d, int enable); void qbman_eq_desc_set_dca(struct qbman_eq_desc *d, int enable, uint8_t dqrr_idx, int park); +/** + * qbman_result_eqresp_fd() - Get fd from enqueue response. + * @eqresp: enqueue response. + * + * Return the fd pointer. + */ +struct qbman_fd *qbman_result_eqresp_fd(struct qbman_result *eqresp); + +/** + * qbman_result_eqresp_set_rspid() - Set the response id in enqueue response. + * @eqresp: enqueue response. + * @val: values to set into the response id. + * + * This value is set into the response id before the enqueue command, which, + * get overwritten by qbman once the enqueue command is complete. + */ +void qbman_result_eqresp_set_rspid(struct qbman_result *eqresp, uint8_t val); + +/** + * qbman_result_eqresp_rspid() - Get the response id. + * @eqresp: enqueue response. + * + * Return the response id. + * + * At the time of enqueue user provides the response id. Response id gets + * copied into the enqueue response to determine if the command has been + * completed, and response has been updated. + */ +uint8_t qbman_result_eqresp_rspid(struct qbman_result *eqresp); + +/** + * qbman_result_eqresp_rc() - determines if enqueue command is sucessful. + * @eqresp: enqueue response. + * + * Return 0 when command is sucessful. + */ +uint8_t qbman_result_eqresp_rc(struct qbman_result *eqresp); + /** * qbman_swp_enqueue() - Issue an enqueue command. * @s: the software portal used for enqueue. diff --git a/drivers/bus/fslmc/qbman/qbman_portal.c b/drivers/bus/fslmc/qbman/qbman_portal.c index 14f4b0344..f49b18097 100644 --- a/drivers/bus/fslmc/qbman/qbman_portal.c +++ b/drivers/bus/fslmc/qbman/qbman_portal.c @@ -1569,6 +1569,32 @@ uint64_t qbman_result_cgcu_icnt(const struct qbman_result *scn) return qbman_result_SCN_ctx(scn); } +/********************/ +/* Parsing EQ RESP */ +/********************/ +struct qbman_fd *qbman_result_eqresp_fd(struct qbman_result *eqresp) +{ + return (struct qbman_fd *)&eqresp->eq_resp.fd[0]; +} + +void qbman_result_eqresp_set_rspid(struct qbman_result *eqresp, uint8_t val) +{ + eqresp->eq_resp.rspid = val; +} + +uint8_t qbman_result_eqresp_rspid(struct qbman_result *eqresp) +{ + return eqresp->eq_resp.rspid; +} + +uint8_t qbman_result_eqresp_rc(struct qbman_result *eqresp) +{ + if (eqresp->eq_resp.rc == 0xE) + return 0; + else + return -1; +} + /******************/ /* Buffer release */ /******************/ diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map index dcc4e082e..811a2e7b9 100644 --- a/drivers/bus/fslmc/rte_bus_fslmc_version.map +++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map @@ -120,7 +120,6 @@ DPDK_18.05 { DPDK_18.11 { global: - dpaa2_dqrr_size; dpaa2_eqcr_size; dpci_get_link_state; @@ -129,3 +128,18 @@ DPDK_18.11 { dpci_set_opr; } DPDK_18.05; + +DPDK_19.05 { + global: + dpaa2_free_eq_descriptors; + + qbman_eq_desc_set_orp; + qbman_eq_desc_set_token; + qbman_result_DQ_odpid; + qbman_result_DQ_seqnum; + qbman_result_eqresp_fd; + qbman_result_eqresp_rc; + qbman_result_eqresp_rspid; + qbman_result_eqresp_set_rspid; +} DPDK_18.11; + diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index bc3faa8a3..0ab43cadf 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -665,6 +665,7 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, return -ret; } } + dpaa2_q->cb_eqresp_free = dpaa2_dev_free_eqresp_buf; dev->data->tx_queues[tx_queue_id] = dpaa2_q; return 0; } @@ -894,6 +895,10 @@ dpaa2_dev_start(struct rte_eth_dev *dev) dpaa2_eth_setup_irqs(dev, 1); } + /* Change the tx burst function if ordered queues are used */ + if (priv->en_ordered) + dev->tx_pkt_burst = dpaa2_dev_tx_ordered; + return 0; } @@ -1793,6 +1798,8 @@ int dpaa2_eth_eventq_attach(const struct rte_eth_dev *dev, dpaa2_ethq->cb = dpaa2_dev_process_parallel_event; else if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ATOMIC) dpaa2_ethq->cb = dpaa2_dev_process_atomic_event; + else if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ORDERED) + dpaa2_ethq->cb = dpaa2_dev_process_ordered_event; else return -EINVAL; @@ -1807,6 +1814,41 @@ int dpaa2_eth_eventq_attach(const struct rte_eth_dev *dev, cfg.destination.hold_active = 1; } + if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ORDERED && + !eth_priv->en_ordered) { + struct opr_cfg ocfg; + + /* Restoration window size = 256 frames */ + ocfg.oprrws = 3; + /* Restoration window size = 512 frames for LX2 */ + if (dpaa2_svr_family == SVR_LX2160A) + ocfg.oprrws = 4; + /* Auto advance NESN window enabled */ + ocfg.oa = 1; + /* Late arrival window size disabled */ + ocfg.olws = 0; + /* ORL resource exhaustaion advance NESN disabled */ + ocfg.oeane = 0; + /* Loose ordering enabled */ + ocfg.oloe = 1; + eth_priv->en_loose_ordered = 1; + /* Strict ordering enabled if explicitly set */ + if (getenv("DPAA2_STRICT_ORDERING_ENABLE")) { + ocfg.oloe = 0; + eth_priv->en_loose_ordered = 0; + } + + ret = dpni_set_opr(dpni, CMD_PRI_LOW, eth_priv->token, + dpaa2_ethq->tc_index, flow_id, + OPR_OPT_CREATE, &ocfg); + if (ret) { + DPAA2_PMD_ERR("Error setting opr: ret: %d\n", ret); + return ret; + } + + eth_priv->en_ordered = 1; + } + options |= DPNI_QUEUE_OPT_USER_CTX; cfg.user_context = (size_t)(dpaa2_ethq); diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h index 420ad6446..313cbe4bf 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.h +++ b/drivers/net/dpaa2/dpaa2_ethdev.h @@ -96,15 +96,17 @@ struct dpaa2_dev_priv { uint16_t token; uint8_t nb_tx_queues; uint8_t nb_rx_queues; + uint32_t options; void *rx_vq[MAX_RX_QUEUES]; void *tx_vq[MAX_TX_QUEUES]; struct dpaa2_bp_list *bp_list; /**mbuf; } +void __attribute__((hot)) +dpaa2_dev_process_ordered_event(struct qbman_swp *swp, + const struct qbman_fd *fd, + const struct qbman_result *dq, + struct dpaa2_queue *rxq, + struct rte_event *ev) +{ + rte_prefetch0((void *)(size_t)(DPAA2_GET_FD_ADDR(fd) + + DPAA2_FD_PTA_SIZE + 16)); + + ev->flow_id = rxq->ev.flow_id; + ev->sub_event_type = rxq->ev.sub_event_type; + ev->event_type = RTE_EVENT_TYPE_ETHDEV; + ev->op = RTE_EVENT_OP_NEW; + ev->sched_type = rxq->ev.sched_type; + ev->queue_id = rxq->ev.queue_id; + ev->priority = rxq->ev.priority; + + ev->mbuf = eth_fd_to_mbuf(fd); + + ev->mbuf->seqn = DPAA2_ENQUEUE_FLAG_ORP; + ev->mbuf->seqn |= qbman_result_DQ_odpid(dq) << DPAA2_EQCR_OPRID_SHIFT; + ev->mbuf->seqn |= qbman_result_DQ_seqnum(dq) << DPAA2_EQCR_SEQNUM_SHIFT; + + qbman_swp_dqrr_consume(swp, dq); +} + /* * Callback to handle sending packets through WRIOP based interface */ @@ -864,6 +891,234 @@ dpaa2_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) return num_tx; } +void +dpaa2_dev_free_eqresp_buf(uint16_t eqresp_ci) +{ + struct dpaa2_dpio_dev *dpio_dev = DPAA2_PER_LCORE_DPIO; + struct qbman_fd *fd; + struct rte_mbuf *m; + + fd = qbman_result_eqresp_fd(&dpio_dev->eqresp[eqresp_ci]); + m = eth_fd_to_mbuf(fd); + rte_pktmbuf_free(m); +} + +static void +dpaa2_set_enqueue_descriptor(struct dpaa2_queue *dpaa2_q, + struct rte_mbuf *m, + struct qbman_eq_desc *eqdesc) +{ + struct rte_eth_dev_data *eth_data = dpaa2_q->eth_data; + struct dpaa2_dev_priv *priv = eth_data->dev_private; + struct dpaa2_dpio_dev *dpio_dev = DPAA2_PER_LCORE_DPIO; + struct eqresp_metadata *eqresp_meta; + uint16_t orpid, seqnum; + uint8_t dq_idx; + + qbman_eq_desc_set_qd(eqdesc, priv->qdid, dpaa2_q->flow_id, + dpaa2_q->tc_index); + + if (m->seqn & DPAA2_ENQUEUE_FLAG_ORP) { + orpid = (m->seqn & DPAA2_EQCR_OPRID_MASK) >> + DPAA2_EQCR_OPRID_SHIFT; + seqnum = (m->seqn & DPAA2_EQCR_SEQNUM_MASK) >> + DPAA2_EQCR_SEQNUM_SHIFT; + + if (!priv->en_loose_ordered) { + qbman_eq_desc_set_orp(eqdesc, 1, orpid, seqnum, 0); + qbman_eq_desc_set_response(eqdesc, (uint64_t) + DPAA2_VADDR_TO_IOVA(&dpio_dev->eqresp[ + dpio_dev->eqresp_pi]), 1); + qbman_eq_desc_set_token(eqdesc, 1); + + eqresp_meta = &dpio_dev->eqresp_meta[ + dpio_dev->eqresp_pi]; + eqresp_meta->dpaa2_q = dpaa2_q; + eqresp_meta->mp = m->pool; + + dpio_dev->eqresp_pi + 1 < MAX_EQ_RESP_ENTRIES ? + dpio_dev->eqresp_pi++ : + (dpio_dev->eqresp_pi = 0); + } else { + qbman_eq_desc_set_orp(eqdesc, 0, orpid, seqnum, 0); + } + } else { + dq_idx = m->seqn - 1; + qbman_eq_desc_set_dca(eqdesc, 1, dq_idx, 0); + DPAA2_PER_LCORE_DQRR_SIZE--; + DPAA2_PER_LCORE_DQRR_HELD &= ~(1 << dq_idx); + } + m->seqn = DPAA2_INVALID_MBUF_SEQN; +} + +/* Callback to handle sending ordered packets through WRIOP based interface */ +uint16_t +dpaa2_dev_tx_ordered(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) +{ + /* Function to transmit the frames to given device and VQ*/ + struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)queue; + struct rte_eth_dev_data *eth_data = dpaa2_q->eth_data; + struct dpaa2_dev_priv *priv = eth_data->dev_private; + struct dpaa2_queue *order_sendq = (struct dpaa2_queue *)priv->tx_vq[0]; + struct qbman_fd fd_arr[MAX_TX_RING_SLOTS]; + struct rte_mbuf *mi; + struct rte_mempool *mp; + struct qbman_eq_desc eqdesc[MAX_TX_RING_SLOTS]; + struct qbman_swp *swp; + uint32_t frames_to_send, num_free_eq_desc; + uint32_t loop, retry_count; + int32_t ret; + uint16_t num_tx = 0; + uint16_t bpid; + + if (unlikely(!DPAA2_PER_LCORE_DPIO)) { + ret = dpaa2_affine_qbman_swp(); + if (ret) { + DPAA2_PMD_ERR("Failure in affining portal"); + return 0; + } + } + swp = DPAA2_PER_LCORE_PORTAL; + + DPAA2_PMD_DP_DEBUG("===> eth_data =%p, fqid =%d\n", + eth_data, dpaa2_q->fqid); + + /* This would also handle normal and atomic queues as any type + * of packet can be enqueued when ordered queues are being used. + */ + while (nb_pkts) { + /*Check if the queue is congested*/ + retry_count = 0; + while (qbman_result_SCN_state(dpaa2_q->cscn)) { + retry_count++; + /* Retry for some time before giving up */ + if (retry_count > CONG_RETRY_COUNT) + goto skip_tx; + } + + frames_to_send = (nb_pkts > dpaa2_eqcr_size) ? + dpaa2_eqcr_size : nb_pkts; + + if (!priv->en_loose_ordered) { + if ((*bufs)->seqn & DPAA2_ENQUEUE_FLAG_ORP) { + num_free_eq_desc = dpaa2_free_eq_descriptors(); + if (num_free_eq_desc < frames_to_send) + frames_to_send = num_free_eq_desc; + } + } + + for (loop = 0; loop < frames_to_send; loop++) { + /*Prepare enqueue descriptor*/ + qbman_eq_desc_clear(&eqdesc[loop]); + + if ((*bufs)->seqn) { + /* Use only queue 0 for Tx in case of atomic/ + * ordered packets as packets can get unordered + * when being tranmitted out from the interface + */ + dpaa2_set_enqueue_descriptor(order_sendq, + (*bufs), + &eqdesc[loop]); + } else { + qbman_eq_desc_set_no_orp(&eqdesc[loop], + DPAA2_EQ_RESP_ERR_FQ); + qbman_eq_desc_set_qd(&eqdesc[loop], priv->qdid, + dpaa2_q->flow_id, + dpaa2_q->tc_index); + } + + if (likely(RTE_MBUF_DIRECT(*bufs))) { + mp = (*bufs)->pool; + /* Check the basic scenario and set + * the FD appropriately here itself. + */ + if (likely(mp && mp->ops_index == + priv->bp_list->dpaa2_ops_index && + (*bufs)->nb_segs == 1 && + rte_mbuf_refcnt_read((*bufs)) == 1)) { + if (unlikely((*bufs)->ol_flags + & PKT_TX_VLAN_PKT)) { + ret = rte_vlan_insert(bufs); + if (ret) + goto send_n_return; + } + DPAA2_MBUF_TO_CONTIG_FD((*bufs), + &fd_arr[loop], + mempool_to_bpid(mp)); + bufs++; + continue; + } + } else { + mi = rte_mbuf_from_indirect(*bufs); + mp = mi->pool; + } + /* Not a hw_pkt pool allocated frame */ + if (unlikely(!mp || !priv->bp_list)) { + DPAA2_PMD_ERR("Err: No buffer pool attached"); + goto send_n_return; + } + + if (mp->ops_index != priv->bp_list->dpaa2_ops_index) { + DPAA2_PMD_WARN("Non DPAA2 buffer pool"); + /* alloc should be from the default buffer pool + * attached to this interface + */ + bpid = priv->bp_list->buf_pool.bpid; + + if (unlikely((*bufs)->nb_segs > 1)) { + DPAA2_PMD_ERR( + "S/G not supp for non hw offload buffer"); + goto send_n_return; + } + if (eth_copy_mbuf_to_fd(*bufs, + &fd_arr[loop], bpid)) { + goto send_n_return; + } + /* free the original packet */ + rte_pktmbuf_free(*bufs); + } else { + bpid = mempool_to_bpid(mp); + if (unlikely((*bufs)->nb_segs > 1)) { + if (eth_mbuf_to_sg_fd(*bufs, + &fd_arr[loop], + bpid)) + goto send_n_return; + } else { + eth_mbuf_to_fd(*bufs, + &fd_arr[loop], bpid); + } + } + bufs++; + } + loop = 0; + while (loop < frames_to_send) { + loop += qbman_swp_enqueue_multiple_desc(swp, + &eqdesc[loop], &fd_arr[loop], + frames_to_send - loop); + } + + num_tx += frames_to_send; + nb_pkts -= frames_to_send; + } + dpaa2_q->tx_pkts += num_tx; + return num_tx; + +send_n_return: + /* send any already prepared fd */ + if (loop) { + unsigned int i = 0; + + while (i < loop) { + i += qbman_swp_enqueue_multiple_desc(swp, &eqdesc[loop], + &fd_arr[i], loop - i); + } + num_tx += loop; + } +skip_tx: + dpaa2_q->tx_pkts += num_tx; + return num_tx; +} + /** * Dummy DPDK callback for TX. * From patchwork Fri Feb 22 11:16:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hemant Agrawal X-Patchwork-Id: 50445 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 99B3B3576; Fri, 22 Feb 2019 12:16:07 +0100 (CET) Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50064.outbound.protection.outlook.com [40.107.5.64]) by dpdk.org (Postfix) with ESMTP id D69892C30 for ; Fri, 22 Feb 2019 12:16:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mKvbXxkw+voZiLdpyh9oZQS+aZNW4jp6Px3LJXWJ2Q4=; b=ZKgX+FpcL3Pp8BLsCwjNya7NvKpBkbxUXPFkcDh0TLbyfQUd4CH8xVS+uSR7Ub8oL9NJpeOhi6PkCp8Q2oEhTRZQHxfOiVpqP9ofdzyJmhJ4PEJeRX9LOnHgVwVBcenwsUkSSF701lDo3kFz3VGSGvoR9DdbvfbsYvP7mPrHeTY= Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com (10.168.65.19) by VI1PR0401MB2431.eurprd04.prod.outlook.com (10.169.134.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1643.14; Fri, 22 Feb 2019 11:16:03 +0000 Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84]) by VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84%9]) with mapi id 15.20.1643.016; Fri, 22 Feb 2019 11:16:03 +0000 From: Hemant Agrawal To: "dev@dpdk.org" CC: "ferruh.yigit@intel.com" , Shreyansh Jain , Ashish Jain Thread-Topic: [PATCH 4/6] net/dpaa2: add support for 16 Rx Queues per traffic class Thread-Index: AQHUyp//SYgKOxysLkKCc1tn8V+jJQ== Date: Fri, 22 Feb 2019 11:16:02 +0000 Message-ID: <20190222111440.30530-4-hemant.agrawal@nxp.com> References: <20190222111440.30530-1-hemant.agrawal@nxp.com> In-Reply-To: <20190222111440.30530-1-hemant.agrawal@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [92.120.1.72] x-mailer: git-send-email 2.17.1 x-clientproxiedby: BM1PR01CA0084.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:1::24) To VI1PR0401MB2541.eurprd04.prod.outlook.com (2603:10a6:800:56::19) authentication-results: spf=none (sender IP is ) smtp.mailfrom=hemant.agrawal@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 38919ddd-a2f7-48b1-88c5-08d698b7214c x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600110)(711020)(4605104)(4618075)(2017052603328)(7153060)(7193020); SRVR:VI1PR0401MB2431; x-ms-traffictypediagnostic: VI1PR0401MB2431: x-microsoft-exchange-diagnostics: =?iso-8859-1?Q?1; VI1PR0401MB2431; 23:8oM2qbgG+u83Zjp7AskCETBE7mDkjoa29AXeI?= =?iso-8859-1?q?oQNEY2/cerwQ4IT8VyVcoGNpr?= =?iso-8859-1?q?15oWFdGhFrmxK1CbFmMFkPQBkKki5knYqlIvXn9Vf1oZ3agczAU?= =?iso-8859-1?q?E3IPigWULgYHKvhOF/d88HJFTNpUr9D2QS2JrRh3lfD1JNh/XhN?= =?iso-8859-1?q?mRHyvTfckV/NGJsW3UTiOUrnx1Z6blyfI1yVDnhrsDeys1D4MvJ?= =?iso-8859-1?q?KVFwV20M9wBqDgRWLqvQJFoIC/m+7puCXWjvg7xAqhnINzkFMVg?= =?iso-8859-1?q?Q19S2cp4u/mCToPtnJe3BQ/oOyRoNrh20qOWa03e/yQmhM2ph8D?= =?iso-8859-1?q?1ZlvHkV/NdEK5N9YlomUy5azEuzYCET53CCAZ0Eh4/2P4rigBjx?= =?iso-8859-1?q?gzrTRJ4zkQoRfDjiOOfm9UCa2ZxzkrDksL1IO5DfwAoGn41A/J1?= =?iso-8859-1?q?qSxK5Z3W4Vaa8U6DVQb3CAyQ3n0r07IDQk7mOy4SJlrD574Ar+5?= =?iso-8859-1?q?2kSQjzBqMHBRWN7AGolUp8zkJEjGRcEwrr/rImMdcu28LuH+K/J?= =?iso-8859-1?q?gGVYKQMYfP4TDL0ekp0DX7IIJKy0Y9MHiJLAi4yGEByXgSwMJXY?= =?iso-8859-1?q?TWCJSFMCF246GlJ8B6tMGJpKHEdZ0xrXqKYW2BZ774geJ5oGzzD?= =?iso-8859-1?q?9M5fcUKtXNRxHwhVsczk6gddmtUGnh+bp61hmN60k1Sjoq2hdHs?= =?iso-8859-1?q?zbwzuz4y5zCrBh2K8QW28W/6YrbC+TLd0IPEprwRAwcUWTZCuyB?= =?iso-8859-1?q?oZbZ8pGPZ6/EaPFP3BCaMqxlhaRIzf6oZkiQ8EBYAKlXeooGlCX?= =?iso-8859-1?q?xea4B5dZitBPmpduNd0mexw0C6UEB3sd1lnCvu697CbS6aNN/yG?= =?iso-8859-1?q?Tnmb+AtRLyyV+uDH9wQ9sXVRbN2eH+v5olFCEF2YZk05K/GLCCG?= =?iso-8859-1?q?O4o4jCIo2bvp6hojjJGn7xegTQZNAynWSyeWruEDs6mGDpuEovM?= =?iso-8859-1?q?8HVH3SltSvwTQMpbck79MyNw/frsacq3HYtsdJ3RCMT226pGrhL?= =?iso-8859-1?q?PcTB0nTaJk+5PlrfNoM+JV6kDSym2CzFhjrFU1183dX7nK6GOAB?= =?iso-8859-1?q?G3OIwHHF1hJc1WF6/XStFxsdIcvQ3D7Sa4MTxxZZqZbAHe0pscR?= =?iso-8859-1?q?UNY0D//4SohqZJzBZCgR5AE4TsyX9N41YOlBBPidSTr0eev5H/M?= =?iso-8859-1?q?ijO9sgU3R+jYvz36BvFKFsyJ6wIYVPvaOkX2E6H2T5ctxfYanL8?= =?iso-8859-1?q?8QGDwTxWCY8fu++EKlkBCHdhJcD0UGzIUwn88tXONO9SwFeC2EQ?= =?iso-8859-1?q?bfOKv+6hC6bYxAi2xFMr+Ccxfw3od0kfhBKOmEase9VPaiefBiJ?= =?iso-8859-1?q?OQguc4tBDdQG8xXYtT2xbRx+PoX5lGGVkXpFI=3D?= x-microsoft-antispam-prvs: x-forefront-prvs: 09565527D6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(376002)(396003)(136003)(366004)(189003)(199004)(2906002)(99286004)(8936002)(105586002)(26005)(54906003)(3846002)(6116002)(106356001)(71190400001)(8676002)(97736004)(316002)(6506007)(6512007)(1730700003)(5640700003)(81156014)(71200400001)(102836004)(36756003)(256004)(386003)(6486002)(50226002)(81166006)(6436002)(6916009)(86362001)(1076003)(305945005)(478600001)(5660300002)(68736007)(44832011)(2616005)(486006)(11346002)(2501003)(53936002)(2351001)(66066001)(7736002)(4326008)(186003)(446003)(14454004)(76176011)(25786009)(52116002)(476003); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0401MB2431; H:VI1PR0401MB2541.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: /jM41XnytGkCHkwUBinNf2TVQEow1TmsoHXLtghh6EI9hU3ttzSvKt/lRmR2Gy5xyISJLb/we/q9sgnxS6U/oTYhSce0KUjg0W3Wb6eb+2CUyEQlSnF7WOKNI+bTI+b+OSr0sZDGBxELf3jAUdce4Dmq5cHNfCxUZf8L7h4K6qH/P1HdUAgSWkHdReBfM35W447F8bmdhDSMDAJRbWSMhXNONA/m+srFhnFxRJhXgspX0zUa1Ml5lbt1A6IKTiDcIKkGRWztTOCqmiJd7FuLmKNaqB/osOcfgYBdtVBb7ZV9xsIfMMNIS8s8G/7dcpSuVQgzC5EBEbCzlOHzWZbzvX1s/BCeLHPgOo2QrL/cXCMLthfegfZfYDeQuA72lemv1MWXj/VKy4HrmkJv2fGMQOf49MB60camHNQpeC6PPpY= MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 38919ddd-a2f7-48b1-88c5-08d698b7214c X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Feb 2019 11:16:01.4506 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2431 Subject: [dpdk-dev] [PATCH 4/6] net/dpaa2: add support for 16 Rx Queues per traffic class X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Ashish Jain Adding support for 16 queues per TC per DPNI port which is required for LX2 platform. Signed-off-by: Ashish Jain --- drivers/net/dpaa2/dpaa2_ethdev.c | 6 ++++-- drivers/net/dpaa2/dpaa2_ethdev.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index 0ab43cadf..f8c2983b9 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -266,6 +266,7 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev) struct dpaa2_dev_priv *priv = dev->data->dev_private; uint16_t dist_idx; uint32_t vq_id; + uint8_t num_rxqueue_per_tc; struct dpaa2_queue *mc_q, *mcq; uint32_t tot_queues; int i; @@ -273,6 +274,7 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); + num_rxqueue_per_tc = (priv->nb_rx_queues / priv->num_rx_tc); tot_queues = priv->nb_rx_queues + priv->nb_tx_queues; mc_q = rte_malloc(NULL, sizeof(struct dpaa2_queue) * tot_queues, RTE_CACHE_LINE_SIZE); @@ -311,8 +313,8 @@ dpaa2_alloc_rx_tx_queues(struct rte_eth_dev *dev) vq_id = 0; for (dist_idx = 0; dist_idx < priv->nb_rx_queues; dist_idx++) { mcq = (struct dpaa2_queue *)priv->rx_vq[vq_id]; - mcq->tc_index = DPAA2_DEF_TC; - mcq->flow_id = dist_idx; + mcq->tc_index = dist_idx / num_rxqueue_per_tc; + mcq->flow_id = dist_idx % num_rxqueue_per_tc; vq_id++; } diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h index 313cbe4bf..13259be7d 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.h +++ b/drivers/net/dpaa2/dpaa2_ethdev.h @@ -20,7 +20,7 @@ #define DPAA2_MAX_RX_PKT_LEN 10240 /*WRIOP support*/ #define MAX_TCS DPNI_MAX_TC -#define MAX_RX_QUEUES 16 +#define MAX_RX_QUEUES 128 #define MAX_TX_QUEUES 16 /*default tc to be used for ,congestion, distribution etc configuration. */ From patchwork Fri Feb 22 11:16:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hemant Agrawal X-Patchwork-Id: 50446 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E4F91378E; Fri, 22 Feb 2019 12:16:08 +0100 (CET) Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50040.outbound.protection.outlook.com [40.107.5.40]) by dpdk.org (Postfix) with ESMTP id 7FDA82C5E for ; Fri, 22 Feb 2019 12:16:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=prk2jgsTAAjFqb93jedDUcdRl7GJXlcMmhx8AFcS8yo=; b=o/pMBXSKXDPqoxay7W2xpA+mRX0Lcz07MY7d8y8ne0ppgrRI779tfMF2aKjKrkUyHs2dJFLy01XQSp/T5Ox2qAuJsURXtBDMBdbW+tLEVIbzWOedrR4fOx/PF/tcN1nQ+MZwCAHUL2GVB9nkxxpD2t+Fdn9UU/8Wfb2z4TOQlUY= Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com (10.168.65.19) by VI1PR0401MB2431.eurprd04.prod.outlook.com (10.169.134.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1643.14; Fri, 22 Feb 2019 11:16:04 +0000 Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84]) by VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84%9]) with mapi id 15.20.1643.016; Fri, 22 Feb 2019 11:16:04 +0000 From: Hemant Agrawal To: "dev@dpdk.org" CC: "ferruh.yigit@intel.com" , Shreyansh Jain Thread-Topic: [PATCH 5/6] net/dpaa2: support low level loopback tester Thread-Index: AQHUyp//zQb2ODFb4keenXOTyB6HCg== Date: Fri, 22 Feb 2019 11:16:04 +0000 Message-ID: <20190222111440.30530-5-hemant.agrawal@nxp.com> References: <20190222111440.30530-1-hemant.agrawal@nxp.com> In-Reply-To: <20190222111440.30530-1-hemant.agrawal@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [92.120.1.72] x-mailer: git-send-email 2.17.1 x-clientproxiedby: BM1PR01CA0084.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:1::24) To VI1PR0401MB2541.eurprd04.prod.outlook.com (2603:10a6:800:56::19) authentication-results: spf=none (sender IP is ) smtp.mailfrom=hemant.agrawal@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 8f693601-88ae-46c7-58bd-08d698b7222b x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600110)(711020)(4605104)(4618075)(2017052603328)(7153060)(7193020); SRVR:VI1PR0401MB2431; x-ms-traffictypediagnostic: VI1PR0401MB2431: x-microsoft-exchange-diagnostics: =?iso-8859-1?Q?1; VI1PR0401MB2431; 23:ZYMtVIIe4TNjqqTkMzEyz7VzE0s0o0QrVN+Vl?= =?iso-8859-1?q?z30F7IpUMta5waAqz/4aatZpH?= =?iso-8859-1?q?6+PjrjwmvW+hSJr78M40V8w3dmpXu1LsRjNcQNY0DcpdjOS1QwQ?= =?iso-8859-1?q?zorgWMz1Phq/r/rsKqkkJpplZrqloFvZu0TL/At0p4Jg6/s+cud?= =?iso-8859-1?q?QLR4iktX0WdxX83U2+O+PjBBZ/kMMRvzcZ3B+pRbwiXms7ZjGvD?= =?iso-8859-1?q?88YlUf1vGrn1h49q5CrSzCshaKZakpKjPAXWjxwgRpBS6szWx0g?= =?iso-8859-1?q?cscuSDms4ULIbx8TjZZShMR3HI2V/H7MSfQvH5BbPcbjw/zRdBR?= =?iso-8859-1?q?EiHenk4tGAwZuIG4w9icWS4Iz+DAUttA0FxIGnwRGbB6jRXFhyH?= =?iso-8859-1?q?w6ePRwlQErCEdx0Bu2bLUPEg3iey1l9uotNY6np5276oZxOjyJR?= =?iso-8859-1?q?F2ztD03ru8JYnV2tbLNuJpAwFMgnQMaiZm/4rnjiJv4auOh2P9f?= =?iso-8859-1?q?ghHH6uS8gbLapQF1mYofPBLkVvSXZ5TEBAoSe7li1VMD8J1EmHE?= =?iso-8859-1?q?aMkCwLPCHcqdJ9XwzOFNfFdDQBv70dE67RniNb9uSdaQLT6hbgS?= =?iso-8859-1?q?Dva2T1xtntUgrz64UwAPqBTC6qj1tkfQQmb9sbIX4On2Z0/Rb2H?= =?iso-8859-1?q?c9qDQFUuO9rQBF0EbBiJS5hVxEzxCBecgB7vSmITWyjV92pPG7m?= =?iso-8859-1?q?FRsc6I9kgY0jKY2qfbyQwDKloevA4Pa5noUk/i0G0eluPvFl8kT?= =?iso-8859-1?q?IbeBltqbKpp3qwK9m7w4929K1WyfyQk7nIwUj6dfI+HTRSzlKZs?= =?iso-8859-1?q?B0vhS0fKxWrrCO1PQ282inQH9PJP1QvkAuk/UG+4xo6xEkKg56p?= =?iso-8859-1?q?6LEStTFPH1x5TpXeEshXZT3VeWizL9rRJe/o6+meNrx5UujX1wS?= =?iso-8859-1?q?syJ89djp3O82IF3MLPEgaWrN2jcwj7tSCnsOtggbltAddM0fC+9?= =?iso-8859-1?q?6Wm9XW7oSLAtQVwKhuCS1qm1e0sWjTnl6OIqCkWx2ro5t9g9rey?= =?iso-8859-1?q?xa097S7s1aExI5E4Q+KdN6bPGK2s/KvuvQSHaJ19fJWyttQTXzd?= =?iso-8859-1?q?OjyLp5zrAkZVVky14Jt+Gkp8HmDzv5RcvrEayM+bVT/+oncM5rz?= =?iso-8859-1?q?e/6h5VwIhrGwPOpyqghu0T08vYQ8gv+Uu6m6g4rhoqB0Y/03fyK?= =?iso-8859-1?q?3QaAAg0gs/Z7I3Mlmti0/s5vU1THV/IVVwMULjcsX2Ni5Wv7imV?= =?iso-8859-1?q?GkQ9OpYZbODjsnDY33FSei9SDkIQiGFZtQShrJsmyGVs3TQMnZA?= =?iso-8859-1?q?yeIi3ScArPlUKRr+rLO7X7Oq+fTzVai2QhSPAiSa/yzeca8VIUB?= =?iso-8859-1?q?dk3ftu7KyeX0PIPOp1sjMAWEKc69Q1/KTFlNId3Lb6jsHTj5C2d?= =?iso-8859-1?q?+/yYqCpXoohsoydjLrESezlp+avXEHwvHBXTQ72W/JcFKuUiiQb?= =?iso-8859-1?q?R/okmkz4PaYzz50WXKzW?= x-microsoft-antispam-prvs: x-forefront-prvs: 09565527D6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(376002)(396003)(136003)(366004)(189003)(199004)(2906002)(99286004)(8936002)(105586002)(26005)(54906003)(3846002)(6116002)(106356001)(53946003)(71190400001)(8676002)(97736004)(316002)(6506007)(6512007)(1730700003)(5640700003)(81156014)(71200400001)(102836004)(36756003)(14444005)(5024004)(256004)(386003)(6486002)(50226002)(81166006)(6436002)(6916009)(86362001)(1076003)(305945005)(478600001)(5660300002)(68736007)(44832011)(2616005)(486006)(11346002)(2501003)(53936002)(2351001)(66066001)(30864003)(7736002)(4326008)(186003)(446003)(14454004)(76176011)(25786009)(52116002)(476003); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0401MB2431; H:VI1PR0401MB2541.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: oGwBm/90B+6JMDxmbJBXp8bAQeQHk/fzW+ACX2O4br0l1HmPoYIBxwjBDgrLtIE9untCPH8mz/yGyXEWcjABvSc0JW1zXnPiUNreTTizOV6tseb/d8iBpraxShkQZNsI2zpODwPKEhXIogqcRNlwaSj5lMT1AB4/BDU9R5PQPcxIpJhTc5K9/X9CfNNCgSLbOmiS1u8XKmgwteD9C8fL8xiLrMGzhRN+tEf4L9Nqn8GWzbEo6BJCYX1Out5WcoVDzoT+qKwrFTifIcwTfCmtD9oHO5fS2UcAL0onclX3aSWCmiOaT6WBK5D+j+MOIYoyW7jR7vqfP/XwgpfipeIuHxaOBbgJW4ZByOYOICU9p/0ZspyA3DKrtJap5ChQ8d+nCO0FR94wtvEgUHRPI/pg+AAjg719av2oprZn3hcte0E= MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8f693601-88ae-46c7-58bd-08d698b7222b X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Feb 2019 11:16:03.1060 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2431 Subject: [dpdk-dev] [PATCH 5/6] net/dpaa2: support low level loopback tester X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Signed-off-by: Hemant Agrawal --- doc/guides/nics/dpaa2.rst | 5 + .../fslmc/qbman/include/fsl_qbman_portal.h | 18 ++ drivers/bus/fslmc/qbman/qbman_portal.c | 161 ++++++++++++++++++ drivers/bus/fslmc/rte_bus_fslmc_version.map | 1 + drivers/net/dpaa2/dpaa2_ethdev.c | 57 ++++++- drivers/net/dpaa2/dpaa2_ethdev.h | 3 + drivers/net/dpaa2/dpaa2_rxtx.c | 161 ++++++++++++++++++ 7 files changed, 402 insertions(+), 4 deletions(-) diff --git a/doc/guides/nics/dpaa2.rst b/doc/guides/nics/dpaa2.rst index 769dc4e12..392ab0580 100644 --- a/doc/guides/nics/dpaa2.rst +++ b/doc/guides/nics/dpaa2.rst @@ -499,6 +499,11 @@ for details. Done testpmd> + +* Use dev arg option ``drv_loopback=1`` to loopback packets at + driver level. Any packet received will be reflected back by the + driver on same port. + Enabling logs ------------- diff --git a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h index a9192d3cb..07b8a4372 100644 --- a/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h +++ b/drivers/bus/fslmc/qbman/include/fsl_qbman_portal.h @@ -1039,6 +1039,24 @@ int qbman_swp_enqueue_multiple(struct qbman_swp *s, const struct qbman_fd *fd, uint32_t *flags, int num_frames); + +/** + * qbman_swp_enqueue_multiple_fd() - Enqueue multiple frames with same + eq descriptor + * @s: the software portal used for enqueue. + * @d: the enqueue descriptor. + * @fd: the frame descriptor to be enqueued. + * @flags: bit-mask of QBMAN_ENQUEUE_FLAG_*** options + * @num_frames: the number of the frames to be enqueued. + * + * Return the number of enqueued frames, -EBUSY if the EQCR is not ready. + */ +int qbman_swp_enqueue_multiple_fd(struct qbman_swp *s, + const struct qbman_eq_desc *d, + struct qbman_fd **fd, + uint32_t *flags, + int num_frames); + /** * qbman_swp_enqueue_multiple_desc() - Enqueue multiple frames with * individual eq descriptor. diff --git a/drivers/bus/fslmc/qbman/qbman_portal.c b/drivers/bus/fslmc/qbman/qbman_portal.c index f49b18097..20da8b921 100644 --- a/drivers/bus/fslmc/qbman/qbman_portal.c +++ b/drivers/bus/fslmc/qbman/qbman_portal.c @@ -93,6 +93,20 @@ qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, uint32_t *flags, int num_frames); +static int +qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp *s, + const struct qbman_eq_desc *d, + struct qbman_fd **fd, + uint32_t *flags, + int num_frames); + +static int +qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp *s, + const struct qbman_eq_desc *d, + struct qbman_fd **fd, + uint32_t *flags, + int num_frames); + static int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, @@ -139,6 +153,13 @@ static int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s, int num_frames) = qbman_swp_enqueue_multiple_direct; +static int (*qbman_swp_enqueue_multiple_fd_ptr)(struct qbman_swp *s, + const struct qbman_eq_desc *d, + struct qbman_fd **fd, + uint32_t *flags, + int num_frames) + = qbman_swp_enqueue_multiple_fd_direct; + static int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct qbman_fd *fd, @@ -243,6 +264,8 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) qbman_swp_enqueue_ring_mode_mem_back; qbman_swp_enqueue_multiple_ptr = qbman_swp_enqueue_multiple_mem_back; + qbman_swp_enqueue_multiple_fd_ptr = + qbman_swp_enqueue_multiple_fd_mem_back; qbman_swp_enqueue_multiple_desc_ptr = qbman_swp_enqueue_multiple_desc_mem_back; qbman_swp_pull_ptr = qbman_swp_pull_mem_back; @@ -862,6 +885,144 @@ inline int qbman_swp_enqueue_multiple(struct qbman_swp *s, return qbman_swp_enqueue_multiple_ptr(s, d, fd, flags, num_frames); } +static int qbman_swp_enqueue_multiple_fd_direct(struct qbman_swp *s, + const struct qbman_eq_desc *d, + struct qbman_fd **fd, + uint32_t *flags, + int num_frames) +{ + uint32_t *p = NULL; + const uint32_t *cl = qb_cl(d); + uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; + int i, num_enqueued = 0; + uint64_t addr_cena; + + half_mask = (s->eqcr.pi_ci_mask>>1); + full_mask = s->eqcr.pi_ci_mask; + if (!s->eqcr.available) { + eqcr_ci = s->eqcr.ci; + s->eqcr.ci = qbman_cena_read_reg(&s->sys, + QBMAN_CENA_SWP_EQCR_CI) & full_mask; + s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, + eqcr_ci, s->eqcr.ci); + if (!s->eqcr.available) + return 0; + } + + eqcr_pi = s->eqcr.pi; + num_enqueued = (s->eqcr.available < num_frames) ? + s->eqcr.available : num_frames; + s->eqcr.available -= num_enqueued; + /* Fill in the EQCR ring */ + for (i = 0; i < num_enqueued; i++) { + p = qbman_cena_write_start_wo_shadow(&s->sys, + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); + memcpy(&p[1], &cl[1], 28); + memcpy(&p[8], fd[i], sizeof(struct qbman_fd)); + eqcr_pi++; + } + + lwsync(); + + /* Set the verb byte, have to substitute in the valid-bit */ + eqcr_pi = s->eqcr.pi; + for (i = 0; i < num_enqueued; i++) { + p = qbman_cena_write_start_wo_shadow(&s->sys, + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); + p[0] = cl[0] | s->eqcr.pi_vb; + if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { + struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; + + d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | + ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); + } + eqcr_pi++; + if (!(eqcr_pi & half_mask)) + s->eqcr.pi_vb ^= QB_VALID_BIT; + } + + /* Flush all the cacheline without load/store in between */ + eqcr_pi = s->eqcr.pi; + addr_cena = (size_t)s->sys.addr_cena; + for (i = 0; i < num_enqueued; i++) { + dcbf(addr_cena + + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); + eqcr_pi++; + } + s->eqcr.pi = eqcr_pi & full_mask; + + return num_enqueued; +} + +static int qbman_swp_enqueue_multiple_fd_mem_back(struct qbman_swp *s, + const struct qbman_eq_desc *d, + struct qbman_fd **fd, + uint32_t *flags, + int num_frames) +{ + uint32_t *p = NULL; + const uint32_t *cl = qb_cl(d); + uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; + int i, num_enqueued = 0; + + half_mask = (s->eqcr.pi_ci_mask>>1); + full_mask = s->eqcr.pi_ci_mask; + if (!s->eqcr.available) { + eqcr_ci = s->eqcr.ci; + s->eqcr.ci = qbman_cena_read_reg(&s->sys, + QBMAN_CENA_SWP_EQCR_CI_MEMBACK) & full_mask; + s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, + eqcr_ci, s->eqcr.ci); + if (!s->eqcr.available) + return 0; + } + + eqcr_pi = s->eqcr.pi; + num_enqueued = (s->eqcr.available < num_frames) ? + s->eqcr.available : num_frames; + s->eqcr.available -= num_enqueued; + /* Fill in the EQCR ring */ + for (i = 0; i < num_enqueued; i++) { + p = qbman_cena_write_start_wo_shadow(&s->sys, + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); + memcpy(&p[1], &cl[1], 28); + memcpy(&p[8], fd[i], sizeof(struct qbman_fd)); + eqcr_pi++; + } + + /* Set the verb byte, have to substitute in the valid-bit */ + eqcr_pi = s->eqcr.pi; + for (i = 0; i < num_enqueued; i++) { + p = qbman_cena_write_start_wo_shadow(&s->sys, + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); + p[0] = cl[0] | s->eqcr.pi_vb; + if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { + struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; + + d->eq.dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | + ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); + } + eqcr_pi++; + if (!(eqcr_pi & half_mask)) + s->eqcr.pi_vb ^= QB_VALID_BIT; + } + s->eqcr.pi = eqcr_pi & full_mask; + + dma_wmb(); + qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_EQCR_PI, + (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); + return num_enqueued; +} + +inline int qbman_swp_enqueue_multiple_fd(struct qbman_swp *s, + const struct qbman_eq_desc *d, + struct qbman_fd **fd, + uint32_t *flags, + int num_frames) +{ + return qbman_swp_enqueue_multiple_fd_ptr(s, d, fd, flags, num_frames); +} + static int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, const struct qbman_fd *fd, diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map index 811a2e7b9..aa844dd80 100644 --- a/drivers/bus/fslmc/rte_bus_fslmc_version.map +++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map @@ -141,5 +141,6 @@ DPDK_19.05 { qbman_result_eqresp_rc; qbman_result_eqresp_rspid; qbman_result_eqresp_set_rspid; + qbman_swp_enqueue_multiple_fd; } DPDK_18.11; diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index f8c2983b9..08a95a14a 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -27,6 +27,8 @@ #include "dpaa2_ethdev.h" #include +#define DRIVER_LOOPBACK_MODE "drv_looback" + /* Supported Rx offloads */ static uint64_t dev_rx_offloads_sup = DEV_RX_OFFLOAD_VLAN_STRIP | @@ -732,7 +734,8 @@ dpaa2_supported_ptypes_get(struct rte_eth_dev *dev) RTE_PTYPE_UNKNOWN }; - if (dev->rx_pkt_burst == dpaa2_dev_prefetch_rx) + if (dev->rx_pkt_burst == dpaa2_dev_prefetch_rx || + dev->rx_pkt_burst == dpaa2_dev_loopback_rx) return ptypes; return NULL; } @@ -1997,6 +2000,43 @@ populate_mac_addr(struct fsl_mc_io *dpni_dev, struct dpaa2_dev_priv *priv, return -1; } +static int +check_devargs_handler(__rte_unused const char *key, const char *value, + __rte_unused void *opaque) +{ + if (strcmp(value, "1")) + return -1; + + return 0; +} + +static int +dpaa2_get_devargs(struct rte_devargs *devargs, const char *key) +{ + struct rte_kvargs *kvlist; + + if (!devargs) + return 0; + + kvlist = rte_kvargs_parse(devargs->args, NULL); + if (!kvlist) + return 0; + + if (!rte_kvargs_count(kvlist, key)) { + rte_kvargs_free(kvlist); + return 0; + } + + if (rte_kvargs_process(kvlist, key, + check_devargs_handler, NULL) < 0) { + rte_kvargs_free(kvlist); + return 0; + } + rte_kvargs_free(kvlist); + + return 1; +} + static int dpaa2_dev_init(struct rte_eth_dev *eth_dev) { @@ -2016,7 +2056,10 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) * plugged. */ eth_dev->dev_ops = &dpaa2_ethdev_ops; - eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; + if (dpaa2_get_devargs(dev->devargs, DRIVER_LOOPBACK_MODE)) + eth_dev->rx_pkt_burst = dpaa2_dev_loopback_rx; + else + eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; eth_dev->tx_pkt_burst = dpaa2_dev_tx; return 0; } @@ -2133,7 +2176,12 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) eth_dev->dev_ops = &dpaa2_ethdev_ops; - eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; + if (dpaa2_get_devargs(dev->devargs, DRIVER_LOOPBACK_MODE)) { + eth_dev->rx_pkt_burst = dpaa2_dev_loopback_rx; + DPAA2_PMD_INFO("Loopback mode"); + } else { + eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; + } eth_dev->tx_pkt_burst = dpaa2_dev_tx; RTE_LOG(INFO, PMD, "%s: netdev created\n", eth_dev->data->name); @@ -2251,7 +2299,8 @@ static struct rte_dpaa2_driver rte_dpaa2_pmd = { }; RTE_PMD_REGISTER_DPAA2(net_dpaa2, rte_dpaa2_pmd); - +RTE_PMD_REGISTER_PARAM_STRING(net_dpaa2, + DRIVER_LOOPBACK_MODE "="); RTE_INIT(dpaa2_pmd_init_log) { dpaa2_logtype_pmd = rte_log_register("pmd.net.dpaa2"); diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h index 13259be7d..7148104ec 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.h +++ b/drivers/net/dpaa2/dpaa2_ethdev.h @@ -125,6 +125,9 @@ int dpaa2_eth_eventq_attach(const struct rte_eth_dev *dev, int dpaa2_eth_eventq_detach(const struct rte_eth_dev *dev, int eth_rx_queue_id); +uint16_t dpaa2_dev_loopback_rx(void *queue, struct rte_mbuf **bufs, + uint16_t nb_pkts); + uint16_t dpaa2_dev_prefetch_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts); void dpaa2_dev_process_parallel_event(struct qbman_swp *swp, diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c index 1aa184730..c6e50123c 100644 --- a/drivers/net/dpaa2/dpaa2_rxtx.c +++ b/drivers/net/dpaa2/dpaa2_rxtx.c @@ -1143,3 +1143,164 @@ dummy_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) (void)nb_pkts; return 0; } + +#if defined(RTE_TOOLCHAIN_GCC) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#elif defined(RTE_TOOLCHAIN_CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcast-qual" +#endif + +/* This function loopbacks all the received packets.*/ +uint16_t +dpaa2_dev_loopback_rx(void *queue, + struct rte_mbuf **bufs __rte_unused, + uint16_t nb_pkts) +{ + /* Function receive frames for a given device and VQ*/ + struct dpaa2_queue *dpaa2_q = (struct dpaa2_queue *)queue; + struct qbman_result *dq_storage, *dq_storage1 = NULL; + uint32_t fqid = dpaa2_q->fqid; + int ret, num_rx = 0, num_tx = 0, pull_size; + uint8_t pending, status; + struct qbman_swp *swp; + struct qbman_fd *fd[DPAA2_LX2_DQRR_RING_SIZE]; + struct qbman_pull_desc pulldesc; + struct qbman_eq_desc eqdesc; + struct queue_storage_info_t *q_storage = dpaa2_q->q_storage; + struct rte_eth_dev_data *eth_data = dpaa2_q->eth_data; + struct dpaa2_dev_priv *priv = eth_data->dev_private; + struct dpaa2_queue *tx_q = priv->tx_vq[0]; + /* todo - currently we are using 1st TX queue only for loopback*/ + + if (unlikely(!DPAA2_PER_LCORE_ETHRX_DPIO)) { + ret = dpaa2_affine_qbman_ethrx_swp(); + if (ret) { + DPAA2_PMD_ERR("Failure in affining portal"); + return 0; + } + } + swp = DPAA2_PER_LCORE_ETHRX_PORTAL; + pull_size = (nb_pkts > dpaa2_dqrr_size) ? dpaa2_dqrr_size : nb_pkts; + if (unlikely(!q_storage->active_dqs)) { + q_storage->toggle = 0; + dq_storage = q_storage->dq_storage[q_storage->toggle]; + q_storage->last_num_pkts = pull_size; + qbman_pull_desc_clear(&pulldesc); + qbman_pull_desc_set_numframes(&pulldesc, + q_storage->last_num_pkts); + qbman_pull_desc_set_fq(&pulldesc, fqid); + qbman_pull_desc_set_storage(&pulldesc, dq_storage, + (size_t)(DPAA2_VADDR_TO_IOVA(dq_storage)), 1); + if (check_swp_active_dqs(DPAA2_PER_LCORE_ETHRX_DPIO->index)) { + while (!qbman_check_command_complete( + get_swp_active_dqs( + DPAA2_PER_LCORE_ETHRX_DPIO->index))) + ; + clear_swp_active_dqs(DPAA2_PER_LCORE_ETHRX_DPIO->index); + } + while (1) { + if (qbman_swp_pull(swp, &pulldesc)) { + DPAA2_PMD_DP_DEBUG( + "VDQ command not issued.QBMAN busy\n"); + /* Portal was busy, try again */ + continue; + } + break; + } + q_storage->active_dqs = dq_storage; + q_storage->active_dpio_id = DPAA2_PER_LCORE_ETHRX_DPIO->index; + set_swp_active_dqs(DPAA2_PER_LCORE_ETHRX_DPIO->index, + dq_storage); + } + + dq_storage = q_storage->active_dqs; + rte_prefetch0((void *)(size_t)(dq_storage)); + rte_prefetch0((void *)(size_t)(dq_storage + 1)); + + /* Prepare next pull descriptor. This will give space for the + * prefething done on DQRR entries + */ + q_storage->toggle ^= 1; + dq_storage1 = q_storage->dq_storage[q_storage->toggle]; + qbman_pull_desc_clear(&pulldesc); + qbman_pull_desc_set_numframes(&pulldesc, pull_size); + qbman_pull_desc_set_fq(&pulldesc, fqid); + qbman_pull_desc_set_storage(&pulldesc, dq_storage1, + (size_t)(DPAA2_VADDR_TO_IOVA(dq_storage1)), 1); + + /*Prepare enqueue descriptor*/ + qbman_eq_desc_clear(&eqdesc); + qbman_eq_desc_set_no_orp(&eqdesc, DPAA2_EQ_RESP_ERR_FQ); + qbman_eq_desc_set_response(&eqdesc, 0, 0); + qbman_eq_desc_set_fq(&eqdesc, tx_q->fqid); + + /* Check if the previous issued command is completed. + * Also seems like the SWP is shared between the Ethernet Driver + * and the SEC driver. + */ + while (!qbman_check_command_complete(dq_storage)) + ; + if (dq_storage == get_swp_active_dqs(q_storage->active_dpio_id)) + clear_swp_active_dqs(q_storage->active_dpio_id); + + pending = 1; + + do { + /* Loop until the dq_storage is updated with + * new token by QBMAN + */ + while (!qbman_check_new_result(dq_storage)) + ; + rte_prefetch0((void *)((size_t)(dq_storage + 2))); + /* Check whether Last Pull command is Expired and + * setting Condition for Loop termination + */ + if (qbman_result_DQ_is_pull_complete(dq_storage)) { + pending = 0; + /* Check for valid frame. */ + status = qbman_result_DQ_flags(dq_storage); + if (unlikely((status & QBMAN_DQ_STAT_VALIDFRAME) == 0)) + continue; + } + fd[num_rx] = (struct qbman_fd *)qbman_result_DQ_fd(dq_storage); + + dq_storage++; + num_rx++; + } while (pending); + + while (num_tx < num_rx) { + num_tx += qbman_swp_enqueue_multiple_fd(swp, &eqdesc, + &fd[num_tx], 0, num_rx - num_tx); + } + + if (check_swp_active_dqs(DPAA2_PER_LCORE_ETHRX_DPIO->index)) { + while (!qbman_check_command_complete( + get_swp_active_dqs(DPAA2_PER_LCORE_ETHRX_DPIO->index))) + ; + clear_swp_active_dqs(DPAA2_PER_LCORE_ETHRX_DPIO->index); + } + /* issue a volatile dequeue command for next pull */ + while (1) { + if (qbman_swp_pull(swp, &pulldesc)) { + DPAA2_PMD_DP_DEBUG("VDQ command is not issued." + "QBMAN is busy (2)\n"); + continue; + } + break; + } + q_storage->active_dqs = dq_storage1; + q_storage->active_dpio_id = DPAA2_PER_LCORE_ETHRX_DPIO->index; + set_swp_active_dqs(DPAA2_PER_LCORE_ETHRX_DPIO->index, dq_storage1); + + dpaa2_q->rx_pkts += num_rx; + dpaa2_q->tx_pkts += num_tx; + + return 0; +} +#if defined(RTE_TOOLCHAIN_GCC) +#pragma GCC diagnostic pop +#elif defined(RTE_TOOLCHAIN_CLANG) +#pragma clang diagnostic pop +#endif From patchwork Fri Feb 22 11:16:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hemant Agrawal X-Patchwork-Id: 50447 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7C55D4C8B; Fri, 22 Feb 2019 12:16:10 +0100 (CET) Received: from EUR03-VE1-obe.outbound.protection.outlook.com (mail-eopbgr50061.outbound.protection.outlook.com [40.107.5.61]) by dpdk.org (Postfix) with ESMTP id 5D05E378B for ; Fri, 22 Feb 2019 12:16:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ZiXLkIY6KxuMiy1rsYrvK+5OWtFnQn30WSPY+LMEWb4=; b=jkrimaI/sa71fzziBO8aonPabQS8UAQJK95iWcGSd59fIi4tHgmCXm+wFOww4wmG/NcgXwk5WlHzoYukYHO+AxgOQ0vZESN6/UzE9FlBI78H9pE8apeVF/pjE1sjBNo347ZN8z0OulZlfIOkfEvV/nIluY7IGLWeYe/Y9pXni0Y= Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com (10.168.65.19) by VI1PR0401MB2431.eurprd04.prod.outlook.com (10.169.134.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1643.14; Fri, 22 Feb 2019 11:16:06 +0000 Received: from VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84]) by VI1PR0401MB2541.eurprd04.prod.outlook.com ([fe80::1cad:15be:6f7e:cb84%9]) with mapi id 15.20.1643.016; Fri, 22 Feb 2019 11:16:05 +0000 From: Hemant Agrawal To: "dev@dpdk.org" CC: "ferruh.yigit@intel.com" , Shreyansh Jain , Sunil Kumar Kori Thread-Topic: [PATCH 6/6] net/dpaa2: add basic support for generic flow Thread-Index: AQHUyqAAbMtzRktU50y4cs/6kD7Dvg== Date: Fri, 22 Feb 2019 11:16:05 +0000 Message-ID: <20190222111440.30530-6-hemant.agrawal@nxp.com> References: <20190222111440.30530-1-hemant.agrawal@nxp.com> In-Reply-To: <20190222111440.30530-1-hemant.agrawal@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [92.120.1.72] x-mailer: git-send-email 2.17.1 x-clientproxiedby: BM1PR01CA0084.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:1::24) To VI1PR0401MB2541.eurprd04.prod.outlook.com (2603:10a6:800:56::19) authentication-results: spf=none (sender IP is ) smtp.mailfrom=hemant.agrawal@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: b96751ae-3ac1-4a71-7345-08d698b7230c x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600110)(711020)(4605104)(4618075)(2017052603328)(7153060)(7193020); SRVR:VI1PR0401MB2431; x-ms-traffictypediagnostic: VI1PR0401MB2431: x-microsoft-exchange-diagnostics: =?iso-8859-1?Q?1; VI1PR0401MB2431; 23:zh1xw0MDIDRBHqMPSuEvN5ofTneDnhJhM8dZw?= =?iso-8859-1?q?GdwLuu7gQGMQPiQ5y0dktfCVL?= =?iso-8859-1?q?DPAp9TjrFFGK56s6HLPYrOGW3M8UQSZVGRocObRZgRXqBHQEDki?= =?iso-8859-1?q?SIGm7obQB3gKdTB9YFu4BOBzJq7IgfJnf6AwAyOSPcse8kVbGP/?= =?iso-8859-1?q?vtHTZ0uOtr3VUoZQq7rpTA1t3g6xvo60s43z4vOcG2KbeYBpHrY?= =?iso-8859-1?q?9Dvz8A6OBliiY0uxG4sjqsYuUXpdUXq6rG+oTfENc17W7CIGVjW?= =?iso-8859-1?q?uHU1KuFPojsCOrljgzTYfCr89yuJlScRObOZNcSNefuuuynCBWq?= =?iso-8859-1?q?6dl9erSkaFadYYrAR6ly2WtnDhtkC1hHCoNDUVXSEYmkY4orhCQ?= =?iso-8859-1?q?+v/dIZ+PJUoUti5nA+1N2NwIIYrFV8D9P5lech8RMRHZhP/N+Ux?= =?iso-8859-1?q?cS0n7+97lUFoWv6NdRyZgNwAvKKnKLJvTRnCMO5KUGPnaqeSZY0?= =?iso-8859-1?q?XB1VeAJ/RA9tgBzbn9DXpsemUpzZyNPnYL1EzxIvIrZuuDNJmN6?= =?iso-8859-1?q?CVfCkaFwr2OHWpvXHtxFVq3J4Ge37l/cQSeken0JQu8Zwxxe6n8?= =?iso-8859-1?q?qDAlrV5odBQXN89aT7hijus68TUliJPy+9m7WZHK9HojhB1bL8q?= =?iso-8859-1?q?WraK/+RP6miPeiHv8ZV2yEDV0Rn9JAUPNybwXrf9WYwGRUJ7St/?= =?iso-8859-1?q?MvYBJfydTggF8e/ADcEfLyzI43OHQNHAq1Z+dsjhmv9osQsXHKZ?= =?iso-8859-1?q?j5koknrnxWoeZlIQhbW0CZJiscKNnymGSyPvsYy2WtA6u70h1lD?= =?iso-8859-1?q?0AEC6P5yfRAFpDxoIn7vSeE2O3Yn9ibHSvW/EK8p4FhxryEB4/D?= =?iso-8859-1?q?WKqaL7qQjSmoz5fwyuekdswpx4rPaL/6dyC7LrtZxTG0Vi69L1X?= =?iso-8859-1?q?UK+FBD5GNenNVkmS2RC6KHF0g76LpoXuUfor70ZzwWHhEMqZnj1?= =?iso-8859-1?q?LHjL/76OXtEDoqedwq+1G4qpRKTSDcofxa6ViWHaMS2oNElaJFx?= =?iso-8859-1?q?1vQFUyIPXCtH1C9uRamftshO3o88QHvEADsouqIGYnkgzVY85gm?= =?iso-8859-1?q?JG+AKGZf0It1myI+deX7iHwhlQpjcE3RcG5YV9PXFlgmcYi/Rvj?= =?iso-8859-1?q?duMBjWFL4V6a6JSnZM1kZgIq/7GeeciKKR8AhAtpvst9RIiOo3v?= =?iso-8859-1?q?JtKtnbv+tKtS24D+H7uU/CuG1FLbZCZ4kAj7TEJ36p/ov1pYJRA?= =?iso-8859-1?q?5+3eZKyH4JEDmdVnGCl8r+b7ttCWKFDNxAaMl/jzegRbgzPlVqG?= =?iso-8859-1?q?cTPyBLbaKib9jBjeHK5yjDxzKwlvLiB2qfCwp+NMzXzKsnMtVsp?= =?iso-8859-1?q?u5qSJOTds1aTKTkrRTZ03NeQP4TIVgsTl+U8GmA0BKWWpSssZj3?= =?iso-8859-1?q?SVK9c3qe6FqKa8o9pNDfIS1HL1bKCDjdS2Mys+i5YxbtTDsaeAN?= =?iso-8859-1?q?YlrJF65NEWlbP4A1hJsR40XXcJbhBDM5NZe58/DmB7uhnM/SfdN?= =?iso-8859-1?q?J7UF7loOfCwQ=3D?= x-microsoft-antispam-prvs: x-forefront-prvs: 09565527D6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(376002)(396003)(136003)(366004)(189003)(199004)(51234002)(2906002)(99286004)(8936002)(105586002)(26005)(54906003)(3846002)(6116002)(106356001)(53946003)(71190400001)(8676002)(97736004)(316002)(6506007)(6512007)(1730700003)(5640700003)(81156014)(71200400001)(102836004)(36756003)(14444005)(256004)(386003)(6486002)(50226002)(81166006)(6436002)(6916009)(86362001)(1076003)(305945005)(478600001)(5660300002)(68736007)(44832011)(2616005)(486006)(11346002)(2501003)(53936002)(2351001)(66066001)(30864003)(7736002)(4326008)(186003)(446003)(14454004)(76176011)(25786009)(52116002)(476003)(41533002)(569006); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0401MB2431; H:VI1PR0401MB2541.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: 5SVLkUYWtAsqbkZHqtTPGYrPeg2h1VVSecbBAgjUpowdV1L7TimIK1utT8JMlOZ0SjEDWtB+MQJNHYNpi1jGk4v7xbfQcbXP6m0jsKPQLLuA4BPF0OOtDAGvZnhXBTzo9APJCli7idk4/gc1x0xV3ULhwYPehXgqdL4f0SlwcN1keA114z902O+ThLOvS+8Y7yYWHY7pKOprxbGgwTlOyF5/lgXmTSiv7r589QBDtfZ4jjVZf3HL3pcxdRt2CFfdpZLc/Z338dInIJ5RyDzJuufj61r5jYYnvpBnSuJgCxuVM+WkV1D339uP8+cL4eyu159B3fCPW82YCkaSoKV1iJyRMfUjHVVHOOYdx4qRpZY0WyXWdRZ842ddqx4bUMWUrhBjPJ/Do4v72q81N5hFLP/uFxyyVR6rOitdDwP2vq8= MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: b96751ae-3ac1-4a71-7345-08d698b7230c X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Feb 2019 11:16:04.4181 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2431 Subject: [dpdk-dev] [PATCH 6/6] net/dpaa2: add basic support for generic flow X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Sunil Kumar Kori Signed-off-by: Sunil Kumar Kori Signed-off-by: Hemant Agrawal --- drivers/net/dpaa2/Makefile | 1 + drivers/net/dpaa2/base/dpaa2_hw_dpni.c | 4 +- drivers/net/dpaa2/dpaa2_ethdev.c | 90 +- drivers/net/dpaa2/dpaa2_ethdev.h | 22 + drivers/net/dpaa2/dpaa2_flow.c | 1972 ++++++++++++++++++++++++ drivers/net/dpaa2/mc/dpni.c | 312 ++++ drivers/net/dpaa2/mc/fsl_dpni.h | 154 ++ drivers/net/dpaa2/mc/fsl_dpni_cmd.h | 88 ++ drivers/net/dpaa2/meson.build | 1 + 9 files changed, 2635 insertions(+), 9 deletions(-) create mode 100644 drivers/net/dpaa2/dpaa2_flow.c diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile index 562551175..8bd269bfa 100644 --- a/drivers/net/dpaa2/Makefile +++ b/drivers/net/dpaa2/Makefile @@ -33,6 +33,7 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += base/dpaa2_hw_dpni.c SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_rxtx.c SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_ethdev.c +SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_flow.c SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += dpaa2_mux.c SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpni.c SRCS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += mc/dpkg.c diff --git a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c index 11f14931e..56e2e56a3 100644 --- a/drivers/net/dpaa2/base/dpaa2_hw_dpni.c +++ b/drivers/net/dpaa2/base/dpaa2_hw_dpni.c @@ -23,7 +23,7 @@ #include "../dpaa2_ethdev.h" -static int +int dpaa2_distset_to_dpkg_profile_cfg( uint64_t req_dist_set, struct dpkg_profile_cfg *kg_cfg); @@ -170,7 +170,7 @@ int dpaa2_remove_flow_dist( return ret; } -static int +int dpaa2_distset_to_dpkg_profile_cfg( uint64_t req_dist_set, struct dpkg_profile_cfg *kg_cfg) diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index 08a95a14a..a8f0e3002 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "dpaa2_pmd_logs.h" #include @@ -83,6 +84,14 @@ static const struct rte_dpaa2_xstats_name_off dpaa2_xstats_strings[] = { {"egress_confirmed_frames", 2, 4}, }; +static const enum rte_filter_op dpaa2_supported_filter_ops[] = { + RTE_ETH_FILTER_ADD, + RTE_ETH_FILTER_DELETE, + RTE_ETH_FILTER_UPDATE, + RTE_ETH_FILTER_FLUSH, + RTE_ETH_FILTER_GET +}; + static struct rte_dpaa2_driver rte_dpaa2_pmd; static int dpaa2_dev_uninit(struct rte_eth_dev *eth_dev); static int dpaa2_dev_link_update(struct rte_eth_dev *dev, @@ -1892,6 +1901,47 @@ int dpaa2_eth_eventq_detach(const struct rte_eth_dev *dev, return ret; } +static inline int +dpaa2_dev_verify_filter_ops(enum rte_filter_op filter_op) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(dpaa2_supported_filter_ops); i++) { + if (dpaa2_supported_filter_ops[i] == filter_op) + return 0; + } + return -ENOTSUP; +} + +static int +dpaa2_dev_flow_ctrl(struct rte_eth_dev *dev, + enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg) +{ + int ret = 0; + + if (!dev) + return -ENODEV; + + switch (filter_type) { + case RTE_ETH_FILTER_GENERIC: + if (dpaa2_dev_verify_filter_ops(filter_op) < 0) { + ret = -ENOTSUP; + break; + } + *(const void **)arg = &dpaa2_flow_ops; + dpaa2_filter_type |= filter_type; + break; + default: + RTE_LOG(ERR, PMD, "Filter type (%d) not supported", + filter_type); + ret = -ENOTSUP; + break; + } + return ret; +} + static struct eth_dev_ops dpaa2_ethdev_ops = { .dev_configure = dpaa2_eth_dev_configure, .dev_start = dpaa2_dev_start, @@ -1930,6 +1980,7 @@ static struct eth_dev_ops dpaa2_ethdev_ops = { .mac_addr_set = dpaa2_dev_set_mac_addr, .rss_hash_update = dpaa2_dev_rss_hash_update, .rss_hash_conf_get = dpaa2_dev_rss_hash_conf_get, + .filter_ctrl = dpaa2_dev_flow_ctrl, }; /* Populate the mac address from physically available (u-boot/firmware) and/or @@ -2046,7 +2097,7 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) struct dpni_attr attr; struct dpaa2_dev_priv *priv = eth_dev->data->dev_private; struct dpni_buffer_layout layout; - int ret, hw_id; + int ret, hw_id, i; PMD_INIT_FUNC_TRACE(); @@ -2102,11 +2153,8 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) priv->num_rx_tc = attr.num_rx_tcs; - /* Resetting the "num_rx_queues" to equal number of queues in first TC - * as only one TC is supported on Rx Side. Once Multiple TCs will be - * in use for Rx processing then this will be changed or removed. - */ - priv->nb_rx_queues = attr.num_queues; + for (i = 0; i < attr.num_rx_tcs; i++) + priv->nb_rx_queues += attr.num_queues; /* Using number of TX queues as number of TX TCs */ priv->nb_tx_queues = attr.num_tx_tcs; @@ -2184,6 +2232,26 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) } eth_dev->tx_pkt_burst = dpaa2_dev_tx; + /*Init fields w.r.t. classficaition*/ + memset(&priv->extract.qos_key_cfg, 0, sizeof(struct dpkg_profile_cfg)); + priv->extract.qos_extract_param = (size_t)rte_malloc(NULL, 256, 64); + if (!priv->extract.qos_extract_param) { + DPAA2_PMD_ERR(" Error(%d) in allocation resources for flow " + " classificaiton ", ret); + goto init_err; + } + for (i = 0; i < MAX_TCS; i++) { + memset(&priv->extract.fs_key_cfg[i], 0, + sizeof(struct dpkg_profile_cfg)); + priv->extract.fs_extract_param[i] = + (size_t)rte_malloc(NULL, 256, 64); + if (!priv->extract.fs_extract_param[i]) { + DPAA2_PMD_ERR(" Error(%d) in allocation resources for flow classificaiton", + ret); + goto init_err; + } + } + RTE_LOG(INFO, PMD, "%s: netdev created\n", eth_dev->data->name); return 0; init_err: @@ -2196,7 +2264,7 @@ dpaa2_dev_uninit(struct rte_eth_dev *eth_dev) { struct dpaa2_dev_priv *priv = eth_dev->data->dev_private; struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; - int ret; + int i, ret; PMD_INIT_FUNC_TRACE(); @@ -2224,6 +2292,14 @@ dpaa2_dev_uninit(struct rte_eth_dev *eth_dev) priv->hw = NULL; rte_free(dpni); + for (i = 0; i < MAX_TCS; i++) { + if (priv->extract.fs_extract_param[i]) + rte_free((void *)(size_t)priv->extract.fs_extract_param[i]); + } + + if (priv->extract.qos_extract_param) + rte_free((void *)(size_t)priv->extract.qos_extract_param); + eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; eth_dev->tx_pkt_burst = NULL; diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_ethdev.h index 7148104ec..0ef1bf368 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.h +++ b/drivers/net/dpaa2/dpaa2_ethdev.h @@ -89,6 +89,13 @@ /* enable timestamp in mbuf*/ extern enum pmd_dpaa2_ts dpaa2_enable_ts; +#define DPAA2_QOS_TABLE_RECONFIGURE 1 +#define DPAA2_FS_TABLE_RECONFIGURE 2 + +/*Externaly defined*/ +extern const struct rte_flow_ops dpaa2_flow_ops; +extern enum rte_filter_type dpaa2_filter_type; + struct dpaa2_dev_priv { void *hw; int32_t hw_id; @@ -107,8 +114,23 @@ struct dpaa2_dev_priv { uint8_t flags; /*dpaa2 config flags */ uint8_t en_ordered; uint8_t en_loose_ordered; + + struct pattern_s { + uint8_t item_count; + uint8_t pattern_type[DPKG_MAX_NUM_OF_EXTRACTS]; + } pattern[MAX_TCS + 1]; + + struct extract_s { + struct dpkg_profile_cfg qos_key_cfg; + struct dpkg_profile_cfg fs_key_cfg[MAX_TCS]; + uint64_t qos_extract_param; + uint64_t fs_extract_param[MAX_TCS]; + } extract; }; +int dpaa2_distset_to_dpkg_profile_cfg(uint64_t req_dist_set, + struct dpkg_profile_cfg *kg_cfg); + int dpaa2_setup_flow_dist(struct rte_eth_dev *eth_dev, uint64_t req_dist_set); diff --git a/drivers/net/dpaa2/dpaa2_flow.c b/drivers/net/dpaa2/dpaa2_flow.c new file mode 100644 index 000000000..20de3da53 --- /dev/null +++ b/drivers/net/dpaa2/dpaa2_flow.c @@ -0,0 +1,1972 @@ +/* * SPDX-License-Identifier: BSD-3-Clause + * Copyright 2018 NXP + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +struct rte_flow { + struct dpni_rule_cfg rule; + uint8_t key_size; + uint8_t tc_id; + uint8_t flow_type; + uint8_t index; + enum rte_flow_action_type action; + uint16_t flow_id; +}; + +/* Layout for rule compositions for supported patterns */ +/* TODO: Current design only supports Ethernet + IPv4 based classification. */ +/* So corresponding offset macros are valid only. Rest are placeholder for */ +/* now. Once support for other netwrok headers will be added then */ +/* corresponding macros will be updated with correct values*/ +#define DPAA2_CLS_RULE_OFFSET_ETH 0 /*Start of buffer*/ +#define DPAA2_CLS_RULE_OFFSET_VLAN 14 /* DPAA2_CLS_RULE_OFFSET_ETH */ + /* + Sizeof Eth fields */ +#define DPAA2_CLS_RULE_OFFSET_IPV4 14 /* DPAA2_CLS_RULE_OFFSET_VLAN */ + /* + Sizeof VLAN fields */ +#define DPAA2_CLS_RULE_OFFSET_IPV6 25 /* DPAA2_CLS_RULE_OFFSET_IPV4 */ + /* + Sizeof IPV4 fields */ +#define DPAA2_CLS_RULE_OFFSET_ICMP 58 /* DPAA2_CLS_RULE_OFFSET_IPV6 */ + /* + Sizeof IPV6 fields */ +#define DPAA2_CLS_RULE_OFFSET_UDP 60 /* DPAA2_CLS_RULE_OFFSET_ICMP */ + /* + Sizeof ICMP fields */ +#define DPAA2_CLS_RULE_OFFSET_TCP 64 /* DPAA2_CLS_RULE_OFFSET_UDP */ + /* + Sizeof UDP fields */ +#define DPAA2_CLS_RULE_OFFSET_SCTP 68 /* DPAA2_CLS_RULE_OFFSET_TCP */ + /* + Sizeof TCP fields */ +#define DPAA2_CLS_RULE_OFFSET_GRE 72 /* DPAA2_CLS_RULE_OFFSET_SCTP */ + /* + Sizeof SCTP fields */ + +static const +enum rte_flow_item_type dpaa2_supported_pattern_type[] = { + RTE_FLOW_ITEM_TYPE_END, + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_VLAN, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_ICMP, + RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_TCP, + RTE_FLOW_ITEM_TYPE_SCTP, + RTE_FLOW_ITEM_TYPE_GRE, +}; + +static const +enum rte_flow_action_type dpaa2_supported_action_type[] = { + RTE_FLOW_ACTION_TYPE_END, + RTE_FLOW_ACTION_TYPE_QUEUE, + RTE_FLOW_ACTION_TYPE_RSS +}; + +enum rte_filter_type dpaa2_filter_type = RTE_ETH_FILTER_NONE; +static const void *default_mask; + +static int +dpaa2_configure_flow_eth(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_eth *spec, *mask; + + /* TODO: Currently upper bound of range parameter is not implemented */ + const struct rte_flow_item_eth *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ + /* TODO: pattern is an array of 9 elements where 9th pattern element */ + /* is for QoS table and 1-8th pattern element is for FS tables. */ + /* It can be changed to macro. */ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_SA; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_DA; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_TYPE; + index++; + + priv->extract.qos_key_cfg.num_extracts = index; + } + + if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_SA; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_DA; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_TYPE; + index++; + + priv->extract.fs_key_cfg[group].num_extracts = index; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_eth *)pattern->spec; + last = (const struct rte_flow_item_eth *)pattern->last; + mask = (const struct rte_flow_item_eth *) + (pattern->mask ? pattern->mask : default_mask); + + /* Key rule */ + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_ETH; + memcpy((void *)key_iova, (const void *)(spec->src.addr_bytes), + sizeof(struct ether_addr)); + key_iova += sizeof(struct ether_addr); + memcpy((void *)key_iova, (const void *)(spec->dst.addr_bytes), + sizeof(struct ether_addr)); + key_iova += sizeof(struct ether_addr); + memcpy((void *)key_iova, (const void *)(&spec->type), + sizeof(rte_be16_t)); + + /* Key mask */ + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_ETH; + memcpy((void *)mask_iova, (const void *)(mask->src.addr_bytes), + sizeof(struct ether_addr)); + mask_iova += sizeof(struct ether_addr); + memcpy((void *)mask_iova, (const void *)(mask->dst.addr_bytes), + sizeof(struct ether_addr)); + mask_iova += sizeof(struct ether_addr); + memcpy((void *)mask_iova, (const void *)(&mask->type), + sizeof(rte_be16_t)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_ETH + + ((2 * sizeof(struct ether_addr)) + + sizeof(rte_be16_t))); + return device_configured; +} + +static int +dpaa2_configure_flow_vlan(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_vlan *spec, *mask; + + const struct rte_flow_item_vlan *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_VLAN; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_VLAN_TCI; + priv->extract.qos_key_cfg.num_extracts++; + } + + if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_VLAN; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_VLAN_TCI; + priv->extract.fs_key_cfg[group].num_extracts++; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_vlan *)pattern->spec; + last = (const struct rte_flow_item_vlan *)pattern->last; + mask = (const struct rte_flow_item_vlan *) + (pattern->mask ? pattern->mask : default_mask); + + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_VLAN; + memcpy((void *)key_iova, (const void *)(&spec->tci), + sizeof(rte_be16_t)); + + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_VLAN; + memcpy((void *)mask_iova, (const void *)(&mask->tci), + sizeof(rte_be16_t)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_VLAN + sizeof(rte_be16_t)); + return device_configured; +} + +static int +dpaa2_configure_flow_ipv4(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_ipv4 *spec, *mask; + + const struct rte_flow_item_ipv4 *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_DST; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; + index++; + + priv->extract.qos_key_cfg.num_extracts = index; + } + + if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_DST; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; + index++; + + priv->extract.fs_key_cfg[group].num_extracts = index; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_ipv4 *)pattern->spec; + last = (const struct rte_flow_item_ipv4 *)pattern->last; + mask = (const struct rte_flow_item_ipv4 *) + (pattern->mask ? pattern->mask : default_mask); + + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4; + memcpy((void *)key_iova, (const void *)&spec->hdr.src_addr, + sizeof(uint32_t)); + key_iova += sizeof(uint32_t); + memcpy((void *)key_iova, (const void *)&spec->hdr.dst_addr, + sizeof(uint32_t)); + key_iova += sizeof(uint32_t); + memcpy((void *)key_iova, (const void *)&spec->hdr.next_proto_id, + sizeof(uint8_t)); + + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_IPV4; + memcpy((void *)mask_iova, (const void *)&mask->hdr.src_addr, + sizeof(uint32_t)); + mask_iova += sizeof(uint32_t); + memcpy((void *)mask_iova, (const void *)&mask->hdr.dst_addr, + sizeof(uint32_t)); + mask_iova += sizeof(uint32_t); + memcpy((void *)mask_iova, (const void *)&mask->hdr.next_proto_id, + sizeof(uint8_t)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_IPV4 + + (2 * sizeof(uint32_t)) + sizeof(uint8_t)); + + return device_configured; +} + +static int +dpaa2_configure_flow_ipv6(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_ipv6 *spec, *mask; + + const struct rte_flow_item_ipv6 *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_DST; + index++; + + priv->extract.qos_key_cfg.num_extracts = index; + } + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_DST; + index++; + + priv->extract.fs_key_cfg[group].num_extracts = index; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_ipv6 *)pattern->spec; + last = (const struct rte_flow_item_ipv6 *)pattern->last; + mask = (const struct rte_flow_item_ipv6 *) + (pattern->mask ? pattern->mask : default_mask); + + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV6; + memcpy((void *)key_iova, (const void *)(spec->hdr.src_addr), + sizeof(spec->hdr.src_addr)); + key_iova += sizeof(spec->hdr.src_addr); + memcpy((void *)key_iova, (const void *)(spec->hdr.dst_addr), + sizeof(spec->hdr.dst_addr)); + + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_IPV6; + memcpy((void *)mask_iova, (const void *)(mask->hdr.src_addr), + sizeof(mask->hdr.src_addr)); + mask_iova += sizeof(mask->hdr.src_addr); + memcpy((void *)mask_iova, (const void *)(mask->hdr.dst_addr), + sizeof(mask->hdr.dst_addr)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_IPV6 + + sizeof(spec->hdr.src_addr) + + sizeof(mask->hdr.dst_addr)); + return device_configured; +} + +static int +dpaa2_configure_flow_icmp(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_icmp *spec, *mask; + + const struct rte_flow_item_icmp *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ICMP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ICMP_TYPE; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ICMP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ICMP_CODE; + index++; + + priv->extract.qos_key_cfg.num_extracts = index; + } + + if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ICMP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ICMP_TYPE; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ICMP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ICMP_CODE; + index++; + + priv->extract.fs_key_cfg[group].num_extracts = index; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_icmp *)pattern->spec; + last = (const struct rte_flow_item_icmp *)pattern->last; + mask = (const struct rte_flow_item_icmp *) + (pattern->mask ? pattern->mask : default_mask); + + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_ICMP; + memcpy((void *)key_iova, (const void *)&spec->hdr.icmp_type, + sizeof(uint8_t)); + key_iova += sizeof(uint8_t); + memcpy((void *)key_iova, (const void *)&spec->hdr.icmp_code, + sizeof(uint8_t)); + + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_ICMP; + memcpy((void *)mask_iova, (const void *)&mask->hdr.icmp_type, + sizeof(uint8_t)); + key_iova += sizeof(uint8_t); + memcpy((void *)mask_iova, (const void *)&mask->hdr.icmp_code, + sizeof(uint8_t)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_ICMP + + (2 * sizeof(uint8_t))); + + return device_configured; +} + +static int +dpaa2_configure_flow_udp(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_udp *spec, *mask; + + const struct rte_flow_item_udp *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_UDP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_SRC; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_UDP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_DST; + index++; + + priv->extract.qos_key_cfg.num_extracts = index; + } + + if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_UDP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_SRC; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_UDP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_DST; + index++; + + priv->extract.fs_key_cfg[group].num_extracts = index; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_udp *)pattern->spec; + last = (const struct rte_flow_item_udp *)pattern->last; + mask = (const struct rte_flow_item_udp *) + (pattern->mask ? pattern->mask : default_mask); + + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 + + (2 * sizeof(uint32_t)); + memset((void *)key_iova, 0x11, sizeof(uint8_t)); + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_UDP; + memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port), + sizeof(uint16_t)); + key_iova += sizeof(uint16_t); + memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port), + sizeof(uint16_t)); + + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_UDP; + memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port), + sizeof(uint16_t)); + mask_iova += sizeof(uint16_t); + memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port), + sizeof(uint16_t)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_UDP + + (2 * sizeof(uint16_t))); + + return device_configured; +} + +static int +dpaa2_configure_flow_tcp(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_tcp *spec, *mask; + + const struct rte_flow_item_tcp *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_TCP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_SRC; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_TCP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_DST; + index++; + + priv->extract.qos_key_cfg.num_extracts = index; + } + + if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_TCP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_SRC; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_TCP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_DST; + index++; + + priv->extract.fs_key_cfg[group].num_extracts = index; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_tcp *)pattern->spec; + last = (const struct rte_flow_item_tcp *)pattern->last; + mask = (const struct rte_flow_item_tcp *) + (pattern->mask ? pattern->mask : default_mask); + + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 + + (2 * sizeof(uint32_t)); + memset((void *)key_iova, 0x06, sizeof(uint8_t)); + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_TCP; + memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port), + sizeof(uint16_t)); + key_iova += sizeof(uint16_t); + memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port), + sizeof(uint16_t)); + + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_TCP; + memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port), + sizeof(uint16_t)); + mask_iova += sizeof(uint16_t); + memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port), + sizeof(uint16_t)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_TCP + + (2 * sizeof(uint16_t))); + + return device_configured; +} + +static int +dpaa2_configure_flow_sctp(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_sctp *spec, *mask; + + const struct rte_flow_item_sctp *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_SCTP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_SRC; + index++; + + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_SCTP; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_DST; + index++; + + priv->extract.qos_key_cfg.num_extracts = index; + } + + if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_SCTP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_SRC; + index++; + + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_SCTP; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_DST; + index++; + + priv->extract.fs_key_cfg[group].num_extracts = index; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_sctp *)pattern->spec; + last = (const struct rte_flow_item_sctp *)pattern->last; + mask = (const struct rte_flow_item_sctp *) + (pattern->mask ? pattern->mask : default_mask); + + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 + + (2 * sizeof(uint32_t)); + memset((void *)key_iova, 0x84, sizeof(uint8_t)); + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_SCTP; + memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port), + sizeof(uint16_t)); + key_iova += sizeof(uint16_t); + memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port), + sizeof(uint16_t)); + + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_SCTP; + memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port), + sizeof(uint16_t)); + mask_iova += sizeof(uint16_t); + memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port), + sizeof(uint16_t)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_SCTP + + (2 * sizeof(uint16_t))); + return device_configured; +} + +static int +dpaa2_configure_flow_gre(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item *pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + int index, j = 0; + size_t key_iova; + size_t mask_iova; + int device_configured = 0, entry_found = 0; + uint32_t group; + const struct rte_flow_item_gre *spec, *mask; + + const struct rte_flow_item_gre *last __rte_unused; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + + group = attr->group; + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */ + if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { + DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", + DPKG_MAX_NUM_OF_EXTRACTS); + return -ENOTSUP; + } + + for (j = 0; j < priv->pattern[8].item_count; j++) { + if (priv->pattern[8].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[8].pattern_type[j] = pattern->type; + priv->pattern[8].item_count++; + device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; + } + + entry_found = 0; + for (j = 0; j < priv->pattern[group].item_count; j++) { + if (priv->pattern[group].pattern_type[j] != pattern->type) { + continue; + } else { + entry_found = 1; + break; + } + } + + if (!entry_found) { + priv->pattern[group].pattern_type[j] = pattern->type; + priv->pattern[group].item_count++; + device_configured |= DPAA2_FS_TABLE_RECONFIGURE; + } + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->index = attr->priority; + + if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + index = priv->extract.qos_key_cfg.num_extracts; + priv->extract.qos_key_cfg.extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_GRE; + priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_GRE_TYPE; + index++; + + priv->extract.qos_key_cfg.num_extracts = index; + } + + if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { + index = priv->extract.fs_key_cfg[group].num_extracts; + priv->extract.fs_key_cfg[group].extracts[index].type = + DPKG_EXTRACT_FROM_HDR; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_GRE; + priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_GRE_TYPE; + index++; + + priv->extract.fs_key_cfg[group].num_extracts = index; + } + + /* Parse pattern list to get the matching parameters */ + spec = (const struct rte_flow_item_gre *)pattern->spec; + last = (const struct rte_flow_item_gre *)pattern->last; + mask = (const struct rte_flow_item_gre *) + (pattern->mask ? pattern->mask : default_mask); + + key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_GRE; + memcpy((void *)key_iova, (const void *)(&spec->protocol), + sizeof(rte_be16_t)); + + mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_GRE; + memcpy((void *)mask_iova, (const void *)(&mask->protocol), + sizeof(rte_be16_t)); + + flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_GRE + sizeof(rte_be16_t)); + + return device_configured; +} + +static int +dpaa2_generic_flow_set(struct rte_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + const struct rte_flow_action_queue *dest_queue; + const struct rte_flow_action_rss *rss_conf; + uint16_t index; + int is_keycfg_configured = 0, end_of_list = 0; + int ret = 0, i = 0, j = 0; + struct dpni_attr nic_attr; + struct dpni_rx_tc_dist_cfg tc_cfg; + struct dpni_qos_tbl_cfg qos_cfg; + struct dpkg_profile_cfg key_cfg; + struct dpni_fs_action_cfg action; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + size_t param; + + /* Parse pattern list to get the matching parameters */ + while (!end_of_list) { + switch (pattern[i].type) { + case RTE_FLOW_ITEM_TYPE_ETH: + is_keycfg_configured = dpaa2_configure_flow_eth(flow, + dev, + attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + is_keycfg_configured = dpaa2_configure_flow_vlan(flow, + dev, + attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_IPV4: + is_keycfg_configured = dpaa2_configure_flow_ipv4(flow, + dev, + attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + is_keycfg_configured = dpaa2_configure_flow_ipv6(flow, + dev, + attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_ICMP: + is_keycfg_configured = dpaa2_configure_flow_icmp(flow, + dev, + attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_UDP: + is_keycfg_configured = dpaa2_configure_flow_udp(flow, + dev, + attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_TCP: + is_keycfg_configured = dpaa2_configure_flow_tcp(flow, + dev, + attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_SCTP: + is_keycfg_configured = dpaa2_configure_flow_sctp(flow, + dev, attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_GRE: + is_keycfg_configured = dpaa2_configure_flow_gre(flow, + dev, + attr, + &pattern[i], + actions, + error); + break; + case RTE_FLOW_ITEM_TYPE_END: + end_of_list = 1; + break; /*End of List*/ + default: + DPAA2_PMD_ERR("Invalid action type"); + ret = -ENOTSUP; + break; + } + i++; + } + + /* Let's parse action on matching traffic */ + end_of_list = 0; + while (!end_of_list) { + switch (actions[j].type) { + case RTE_FLOW_ACTION_TYPE_QUEUE: + dest_queue = (const struct rte_flow_action_queue *)(actions[j].conf); + flow->flow_id = dest_queue->index; + flow->action = RTE_FLOW_ACTION_TYPE_QUEUE; + memset(&action, 0, sizeof(struct dpni_fs_action_cfg)); + action.flow_id = flow->flow_id; + if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) { + if (dpkg_prepare_key_cfg(&priv->extract.qos_key_cfg, + (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) { + DPAA2_PMD_ERR( + "Unable to prepare extract parameters"); + return -1; + } + + memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg)); + qos_cfg.discard_on_miss = true; + qos_cfg.keep_entries = true; + qos_cfg.key_cfg_iova = (size_t)priv->extract.qos_extract_param; + ret = dpni_set_qos_table(dpni, CMD_PRI_LOW, + priv->token, &qos_cfg); + if (ret < 0) { + DPAA2_PMD_ERR( + "Distribution cannot be configured.(%d)" + , ret); + return -1; + } + } + if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) { + if (dpkg_prepare_key_cfg(&priv->extract.fs_key_cfg[flow->tc_id], + (uint8_t *)(size_t)priv->extract.fs_extract_param[flow->tc_id]) < 0) { + DPAA2_PMD_ERR( + "Unable to prepare extract parameters"); + return -1; + } + + memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg)); + tc_cfg.dist_size = priv->nb_rx_queues / priv->num_rx_tc; + tc_cfg.dist_mode = DPNI_DIST_MODE_FS; + tc_cfg.key_cfg_iova = + (uint64_t)priv->extract.fs_extract_param[flow->tc_id]; + tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP; + tc_cfg.fs_cfg.keep_entries = true; + ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, + priv->token, + flow->tc_id, &tc_cfg); + if (ret < 0) { + DPAA2_PMD_ERR( + "Distribution cannot be configured.(%d)" + , ret); + return -1; + } + } + /* Configure QoS table first */ + memset(&nic_attr, 0, sizeof(struct dpni_attr)); + ret = dpni_get_attributes(dpni, CMD_PRI_LOW, + priv->token, &nic_attr); + if (ret < 0) { + DPAA2_PMD_ERR( + "Failure to get attribute. dpni@%p err code(%d)\n", + dpni, ret); + return ret; + } + + action.flow_id = action.flow_id % nic_attr.num_rx_tcs; + index = flow->index + (flow->tc_id * nic_attr.fs_entries); + ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, + priv->token, &flow->rule, + flow->tc_id, index); + if (ret < 0) { + DPAA2_PMD_ERR( + "Error in addnig entry to QoS table(%d)", ret); + return ret; + } + + /* Then Configure FS table */ + ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW, priv->token, + flow->tc_id, flow->index, + &flow->rule, &action); + if (ret < 0) { + DPAA2_PMD_ERR( + "Error in adding entry to FS table(%d)", ret); + return ret; + } + break; + case RTE_FLOW_ACTION_TYPE_RSS: + ret = dpni_get_attributes(dpni, CMD_PRI_LOW, + priv->token, &nic_attr); + if (ret < 0) { + DPAA2_PMD_ERR( + "Failure to get attribute. dpni@%p err code(%d)\n", + dpni, ret); + return ret; + } + rss_conf = (const struct rte_flow_action_rss *)(actions[j].conf); + for (i = 0; i < (int)rss_conf->queue_num; i++) { + if (rss_conf->queue[i] < (attr->group * nic_attr.num_queues) || + rss_conf->queue[i] >= ((attr->group + 1) * nic_attr.num_queues)) { + DPAA2_PMD_ERR( + "Queue/Group combination are not supported\n"); + return -ENOTSUP; + } + } + + flow->action = RTE_FLOW_ACTION_TYPE_RSS; + ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types, + &key_cfg); + if (ret < 0) { + DPAA2_PMD_ERR( + "unable to set flow distribution.please check queue config\n"); + return ret; + } + + /* Allocate DMA'ble memory to write the rules */ + param = (size_t)rte_malloc(NULL, 256, 64); + if (!param) { + DPAA2_PMD_ERR("Memory allocation failure\n"); + return -1; + } + + if (dpkg_prepare_key_cfg(&key_cfg, (uint8_t *)param) < 0) { + DPAA2_PMD_ERR( + "Unable to prepare extract parameters"); + rte_free((void *)param); + return -1; + } + + memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg)); + tc_cfg.dist_size = rss_conf->queue_num; + tc_cfg.dist_mode = DPNI_DIST_MODE_HASH; + tc_cfg.key_cfg_iova = (size_t)param; + tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP; + + ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, + priv->token, flow->tc_id, + &tc_cfg); + if (ret < 0) { + DPAA2_PMD_ERR( + "Distribution cannot be configured: %d\n", ret); + rte_free((void *)param); + return -1; + } + + rte_free((void *)param); + if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) { + if (dpkg_prepare_key_cfg(&priv->extract.qos_key_cfg, + (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) { + DPAA2_PMD_ERR( + "Unable to prepare extract parameters"); + return -1; + } + memset(&qos_cfg, 0, + sizeof(struct dpni_qos_tbl_cfg)); + qos_cfg.discard_on_miss = true; + qos_cfg.keep_entries = true; + qos_cfg.key_cfg_iova = (size_t)priv->extract.qos_extract_param; + ret = dpni_set_qos_table(dpni, CMD_PRI_LOW, + priv->token, &qos_cfg); + if (ret < 0) { + DPAA2_PMD_ERR( + "Distribution can not be configured(%d)\n", + ret); + return -1; + } + } + + /* Add Rule into QoS table */ + index = flow->index + (flow->tc_id * nic_attr.fs_entries); + ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, priv->token, + &flow->rule, flow->tc_id, + index); + if (ret < 0) { + DPAA2_PMD_ERR( + "Error in entry addition in QoS table(%d)", + ret); + return ret; + } + break; + case RTE_FLOW_ACTION_TYPE_END: + end_of_list = 1; + break; + default: + DPAA2_PMD_ERR("Invalid action type"); + ret = -ENOTSUP; + break; + } + j++; + } + + return ret; +} + +static inline int +dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr, + const struct rte_flow_attr *attr) +{ + int ret = 0; + + if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) { + DPAA2_PMD_ERR("Priority group is out of range\n"); + ret = -ENOTSUP; + } + if (unlikely(attr->priority >= dpni_attr->fs_entries)) { + DPAA2_PMD_ERR("Priority within the group is out of range\n"); + ret = -ENOTSUP; + } + if (unlikely(attr->egress)) { + DPAA2_PMD_ERR( + "Flow configuration is not supported on egress side\n"); + ret = -ENOTSUP; + } + if (unlikely(!attr->ingress)) { + DPAA2_PMD_ERR("Ingress flag must be configured\n"); + ret = -EINVAL; + } + return ret; +} + +static inline void +dpaa2_dev_update_default_mask(const struct rte_flow_item *pattern) +{ + switch (pattern->type) { + case RTE_FLOW_ITEM_TYPE_ETH: + default_mask = (const void *)&rte_flow_item_eth_mask; + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + default_mask = (const void *)&rte_flow_item_vlan_mask; + break; + case RTE_FLOW_ITEM_TYPE_IPV4: + default_mask = (const void *)&rte_flow_item_ipv4_mask; + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + default_mask = (const void *)&rte_flow_item_ipv6_mask; + break; + case RTE_FLOW_ITEM_TYPE_ICMP: + default_mask = (const void *)&rte_flow_item_icmp_mask; + break; + case RTE_FLOW_ITEM_TYPE_UDP: + default_mask = (const void *)&rte_flow_item_udp_mask; + break; + case RTE_FLOW_ITEM_TYPE_TCP: + default_mask = (const void *)&rte_flow_item_tcp_mask; + break; + case RTE_FLOW_ITEM_TYPE_SCTP: + default_mask = (const void *)&rte_flow_item_sctp_mask; + break; + case RTE_FLOW_ITEM_TYPE_GRE: + default_mask = (const void *)&rte_flow_item_gre_mask; + break; + default: + DPAA2_PMD_ERR("Invalid pattern type"); + } +} + +static inline int +dpaa2_dev_verify_patterns(struct dpaa2_dev_priv *dev_priv, + const struct rte_flow_item pattern[]) +{ + unsigned int i, j, k, is_found = 0; + int ret = 0; + + for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) { + for (i = 0; i < RTE_DIM(dpaa2_supported_pattern_type); i++) { + if (dpaa2_supported_pattern_type[i] == pattern[j].type) { + is_found = 1; + break; + } + } + if (!is_found) { + ret = -ENOTSUP; + break; + } + } + /* Lets verify other combinations of given pattern rules */ + for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) { + if (!pattern[j].spec) { + ret = -EINVAL; + break; + } + if ((pattern[j].last) && (!pattern[j].mask)) + dpaa2_dev_update_default_mask(&pattern[j]); + } + + /* DPAA2 platform has a limitation that extract parameter can not be */ + /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */ + for (i = 0; pattern[i].type != RTE_FLOW_ITEM_TYPE_END; i++) { + for (j = 0; j < MAX_TCS + 1; j++) { + for (k = 0; k < DPKG_MAX_NUM_OF_EXTRACTS; j++) { + if (dev_priv->pattern[j].pattern_type[k] == pattern[i].type) + break; + } + if (dev_priv->pattern[j].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) + ret = -ENOTSUP; + } + } + return ret; +} + +static inline int +dpaa2_dev_verify_actions(const struct rte_flow_action actions[]) +{ + unsigned int i, j, is_found = 0; + int ret = 0; + + for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) { + for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) { + if (dpaa2_supported_action_type[i] == actions[j].type) { + is_found = 1; + break; + } + } + if (!is_found) { + ret = -ENOTSUP; + break; + } + } + for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) { + if ((actions[j].type != RTE_FLOW_ACTION_TYPE_DROP) && (!actions[j].conf)) + ret = -EINVAL; + } + return ret; +} + +static +int dpaa2_flow_validate(struct rte_eth_dev *dev, + const struct rte_flow_attr *flow_attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow_error *error __rte_unused) +{ + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct dpni_attr dpni_attr; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + uint16_t token = priv->token; + int ret = 0; + + memset(&dpni_attr, 0, sizeof(struct dpni_attr)); + ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr); + if (ret < 0) { + DPAA2_PMD_ERR( + "Failure to get dpni@%p attribute, err code %d\n", + dpni, ret); + return ret; + } + + /* Verify input attributes */ + ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr); + if (ret < 0) { + DPAA2_PMD_ERR( + "Invalid attributes are given\n"); + goto not_valid_params; + } + /* Verify input pattern list */ + ret = dpaa2_dev_verify_patterns(priv, pattern); + if (ret < 0) { + DPAA2_PMD_ERR( + "Invalid pattern list is given\n"); + goto not_valid_params; + } + /* Verify input action list */ + ret = dpaa2_dev_verify_actions(actions); + if (ret < 0) { + DPAA2_PMD_ERR( + "Invalid action list is given\n"); + goto not_valid_params; + } +not_valid_params: + return ret; +} + +static +struct rte_flow *dpaa2_flow_create(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + struct rte_flow *flow = NULL; + size_t key_iova = 0, mask_iova = 0; + int ret; + + flow = rte_malloc(NULL, sizeof(struct rte_flow), RTE_CACHE_LINE_SIZE); + if (!flow) { + DPAA2_PMD_ERR("Failure to allocate memory for flow"); + return NULL; + } + /* Allocate DMA'ble memory to write the rules */ + key_iova = (size_t)rte_malloc(NULL, 256, 64); + if (!key_iova) { + DPAA2_PMD_ERR( + "Memory allocation failure for rule configration\n"); + goto creation_error; + } + mask_iova = (size_t)rte_malloc(NULL, 256, 64); + if (!mask_iova) { + DPAA2_PMD_ERR( + "Memory allocation failure for rule configration\n"); + goto creation_error; + } + + flow->rule.key_iova = key_iova; + flow->rule.mask_iova = mask_iova; + flow->rule.key_size = 0; + + switch (dpaa2_filter_type) { + case RTE_ETH_FILTER_GENERIC: + ret = dpaa2_generic_flow_set(flow, dev, attr, pattern, + actions, error); + if (ret < 0) { + DPAA2_PMD_ERR( + "Failure to create flow, return code (%d)", ret); + goto creation_error; + } + break; + default: + DPAA2_PMD_ERR("Filter type (%d) not supported", + dpaa2_filter_type); + break; + } + + return flow; + +creation_error: + if (flow) + rte_free((void *)flow); + if (key_iova) + rte_free((void *)key_iova); + if (mask_iova) + rte_free((void *)mask_iova); + return NULL; +} + +static +int dpaa2_flow_destroy(struct rte_eth_dev *dev, + struct rte_flow *flow, + struct rte_flow_error *error __rte_unused) +{ + int ret = 0; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + + switch (flow->action) { + case RTE_FLOW_ACTION_TYPE_QUEUE: + /* Remove entry from QoS table first */ + ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token, + &flow->rule); + if (ret < 0) { + DPAA2_PMD_ERR( + "Error in adding entry to QoS table(%d)", ret); + goto error; + } + + /* Then remove entry from FS table */ + ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token, + flow->tc_id, &flow->rule); + if (ret < 0) { + DPAA2_PMD_ERR( + "Error in entry addition in FS table(%d)", ret); + goto error; + } + break; + case RTE_FLOW_ACTION_TYPE_RSS: + ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token, + &flow->rule); + if (ret < 0) { + DPAA2_PMD_ERR( + "Error in entry addition in QoS table(%d)", ret); + goto error; + } + break; + default: + DPAA2_PMD_ERR( + "Action type (%d) is not supported", flow->action); + ret = -ENOTSUP; + break; + } + + /* Now free the flow */ + rte_free(flow); + +error: + return ret; +} + +static int +dpaa2_flow_flush(struct rte_eth_dev *dev, + struct rte_flow_error *error __rte_unused) +{ + int ret = 0, tc_id; + struct dpni_rx_tc_dist_cfg tc_cfg; + struct dpni_qos_tbl_cfg qos_cfg; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + + /* Reset QoS table */ + qos_cfg.default_tc = 0; + qos_cfg.discard_on_miss = false; + qos_cfg.keep_entries = false; + qos_cfg.key_cfg_iova = priv->extract.qos_extract_param; + ret = dpni_set_qos_table(dpni, CMD_PRI_LOW, priv->token, &qos_cfg); + if (ret < 0) + DPAA2_PMD_ERR( + "QoS table is not reset to default: %d\n", ret); + + for (tc_id = 0; tc_id < priv->num_rx_tc; tc_id++) { + /* Reset FS table */ + memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg)); + ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, priv->token, + tc_id, &tc_cfg); + if (ret < 0) + DPAA2_PMD_ERR( + "Error (%d) in flushing entries for TC (%d)", + ret, tc_id); + } + return ret; +} + +static int +dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused, + struct rte_flow *flow __rte_unused, + const struct rte_flow_action *actions __rte_unused, + void *data __rte_unused, + struct rte_flow_error *error __rte_unused) +{ + return 0; +} + +const struct rte_flow_ops dpaa2_flow_ops = { + .create = dpaa2_flow_create, + .validate = dpaa2_flow_validate, + .destroy = dpaa2_flow_destroy, + .flush = dpaa2_flow_flush, + .query = dpaa2_flow_query, +}; diff --git a/drivers/net/dpaa2/mc/dpni.c b/drivers/net/dpaa2/mc/dpni.c index 0907a3699..6c12a0ae1 100644 --- a/drivers/net/dpaa2/mc/dpni.c +++ b/drivers/net/dpaa2/mc/dpni.c @@ -1528,6 +1528,248 @@ int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dpni_set_qos_table() - Set QoS mapping table + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @cfg: QoS table configuration + * + * This function and all QoS-related functions require that + *'max_tcs > 1' was set at DPNI creation. + * + * warning: Before calling this function, call dpkg_prepare_key_cfg() to + * prepare the key_cfg_iova parameter + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_set_qos_table(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + const struct dpni_qos_tbl_cfg *cfg) +{ + struct dpni_cmd_set_qos_table *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QOS_TBL, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_set_qos_table *)cmd.params; + cmd_params->default_tc = cfg->default_tc; + cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); + dpni_set_field(cmd_params->discard_on_miss, + ENABLE, + cfg->discard_on_miss); + dpni_set_field(cmd_params->discard_on_miss, + KEEP_QOS_ENTRIES, + cfg->keep_entries); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_add_qos_entry() - Add QoS mapping entry (to select a traffic class) + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @cfg: QoS rule to add + * @tc_id: Traffic class selection (0-7) + * @index: Location in the QoS table where to insert the entry. + * Only relevant if MASKING is enabled for QoS classification on + * this DPNI, it is ignored for exact match. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_add_qos_entry(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + const struct dpni_rule_cfg *cfg, + uint8_t tc_id, + uint16_t index) +{ + struct dpni_cmd_add_qos_entry *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_QOS_ENT, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_add_qos_entry *)cmd.params; + cmd_params->tc_id = tc_id; + cmd_params->key_size = cfg->key_size; + cmd_params->index = cpu_to_le16(index); + cmd_params->key_iova = cpu_to_le64(cfg->key_iova); + cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_remove_qos_entry() - Remove QoS mapping entry + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @cfg: QoS rule to remove + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_remove_qos_entry(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + const struct dpni_rule_cfg *cfg) +{ + struct dpni_cmd_remove_qos_entry *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_QOS_ENT, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_remove_qos_entry *)cmd.params; + cmd_params->key_size = cfg->key_size; + cmd_params->key_iova = cpu_to_le64(cfg->key_iova); + cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_clear_qos_table() - Clear all QoS mapping entries + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * + * Following this function call, all frames are directed to + * the default traffic class (0) + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_clear_qos_table(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_QOS_TBL, + cmd_flags, + token); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class + * (to select a flow ID) + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tc_id: Traffic class selection (0-7) + * @index: Location in the QoS table where to insert the entry. + * Only relevant if MASKING is enabled for QoS classification + * on this DPNI, it is ignored for exact match. + * @cfg: Flow steering rule to add + * @action: Action to be taken as result of a classification hit + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_add_fs_entry(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + uint8_t tc_id, + uint16_t index, + const struct dpni_rule_cfg *cfg, + const struct dpni_fs_action_cfg *action) +{ + struct dpni_cmd_add_fs_entry *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_FS_ENT, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_add_fs_entry *)cmd.params; + cmd_params->tc_id = tc_id; + cmd_params->key_size = cfg->key_size; + cmd_params->index = cpu_to_le16(index); + cmd_params->key_iova = cpu_to_le64(cfg->key_iova); + cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); + cmd_params->options = cpu_to_le16(action->options); + cmd_params->flow_id = cpu_to_le16(action->flow_id); + cmd_params->flc = cpu_to_le64(action->flc); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific + * traffic class + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tc_id: Traffic class selection (0-7) + * @cfg: Flow steering rule to remove + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_remove_fs_entry(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + uint8_t tc_id, + const struct dpni_rule_cfg *cfg) +{ + struct dpni_cmd_remove_fs_entry *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_FS_ENT, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_remove_fs_entry *)cmd.params; + cmd_params->tc_id = tc_id; + cmd_params->key_size = cfg->key_size; + cmd_params->key_iova = cpu_to_le64(cfg->key_iova); + cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_clear_fs_entries() - Clear all Flow Steering entries of a specific + * traffic class + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @tc_id: Traffic class selection (0-7) + * + * Return: '0' on Success; Error code otherwise. + */ +int dpni_clear_fs_entries(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + uint8_t tc_id) +{ + struct dpni_cmd_clear_fs_entries *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_FS_ENT, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_clear_fs_entries *)cmd.params; + cmd_params->tc_id = tc_id; + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + /** * dpni_set_congestion_notification() - Set traffic class congestion * notification configuration @@ -2064,6 +2306,76 @@ int dpni_get_opr(struct fsl_mc_io *mc_io, return 0; } +/** + * dpni_set_rx_fs_dist() - Set Rx traffic class FS distribution + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @cfg: Distribution configuration + * If the FS is already enabled with a previous call the classification + * key will be changed but all the table rules are kept. If the + * existing rules do not match the key the results will not be + * predictable. It is the user responsibility to keep key integrity + * If cfg.enable is set to 1 the command will create a flow steering table + * and will classify packets according to this table. The packets + * that miss all the table rules will be classified according to + * settings made in dpni_set_rx_hash_dist() + * If cfg.enable is set to 0 the command will clear flow steering table. The + * packets will be classified according to settings made in + * dpni_set_rx_hash_dist() + */ +int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, const struct dpni_rx_dist_cfg *cfg) +{ + struct dpni_cmd_set_rx_fs_dist *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FS_DIST, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_set_rx_fs_dist *)cmd.params; + cmd_params->dist_size = cpu_to_le16(cfg->dist_size); + dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable); + cmd_params->tc = cfg->tc; + cmd_params->miss_flow_id = cpu_to_le16(cfg->fs_miss_flow_id); + cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +/** + * dpni_set_rx_hash_dist() - Set Rx traffic class HASH distribution + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPNI object + * @cfg: Distribution configuration + * If cfg.enable is set to 1 the packets will be classified using a hash + * function based on the key received in cfg.key_cfg_iova parameter + * If cfg.enable is set to 0 the packets will be sent to the queue configured in + * dpni_set_rx_dist_default_queue() call + */ +int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, const struct dpni_rx_dist_cfg *cfg) +{ + struct dpni_cmd_set_rx_hash_dist *cmd_params; + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_HASH_DIST, + cmd_flags, + token); + cmd_params = (struct dpni_cmd_set_rx_hash_dist *)cmd.params; + cmd_params->dist_size = cpu_to_le16(cfg->dist_size); + dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable); + cmd_params->tc_id = cfg->tc; + cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + /** * dpni_add_custom_tpid() - Configures a distinct Ethertype value * (or TPID value) to indicate VLAN tag in addition to the common diff --git a/drivers/net/dpaa2/mc/fsl_dpni.h b/drivers/net/dpaa2/mc/fsl_dpni.h index 0359a2bc7..aecdc8d1f 100644 --- a/drivers/net/dpaa2/mc/fsl_dpni.h +++ b/drivers/net/dpaa2/mc/fsl_dpni.h @@ -1071,6 +1071,123 @@ int dpni_get_tx_confirmation_mode(struct fsl_mc_io *mc_io, uint16_t token, enum dpni_confirmation_mode *mode); +/** + * struct dpni_qos_tbl_cfg - Structure representing QOS table configuration + * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with + * key extractions to be used as the QoS criteria by calling + * dpkg_prepare_key_cfg() + * @discard_on_miss: Set to '1' to discard frames in case of no match (miss); + * '0' to use the 'default_tc' in such cases + * @keep_entries: if set to one will not delele existing table entries. This + * option will work properly only for dpni objects created with + * DPNI_OPT_HAS_KEY_MASKING option. All previous QoS entries must + * be compatible with new key composition rule. + * It is the caller's job to delete incompatible entries before + * executing this function. + * @default_tc: Used in case of no-match and 'discard_on_miss'= 0 + */ +struct dpni_qos_tbl_cfg { + uint64_t key_cfg_iova; + int discard_on_miss; + int keep_entries; + uint8_t default_tc; +}; + +int dpni_set_qos_table(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + const struct dpni_qos_tbl_cfg *cfg); + +/** + * struct dpni_rule_cfg - Rule configuration for table lookup + * @key_iova: I/O virtual address of the key (must be in DMA-able memory) + * @mask_iova: I/O virtual address of the mask (must be in DMA-able memory) + * @key_size: key and mask size (in bytes) + */ +struct dpni_rule_cfg { + uint64_t key_iova; + uint64_t mask_iova; + uint8_t key_size; +}; + +int dpni_add_qos_entry(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + const struct dpni_rule_cfg *cfg, + uint8_t tc_id, + uint16_t index); + +int dpni_remove_qos_entry(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + const struct dpni_rule_cfg *cfg); + +int dpni_clear_qos_table(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token); + +/** + * Discard matching traffic. If set, this takes precedence over any other + * configuration and matching traffic is always discarded. + */ + #define DPNI_FS_OPT_DISCARD 0x1 + +/** + * Set FLC value. If set, flc member of truct dpni_fs_action_cfg is used to + * override the FLC value set per queue. + * For more details check the Frame Descriptor section in the hardware + * documentation. + */ +#define DPNI_FS_OPT_SET_FLC 0x2 + +/* + * Indicates whether the 6 lowest significant bits of FLC are used for stash + * control. If set, the 6 least significant bits in value are interpreted as + * follows: + * - bits 0-1: indicates the number of 64 byte units of context that are + * stashed. FLC value is interpreted as a memory address in this case, + * excluding the 6 LS bits. + * - bits 2-3: indicates the number of 64 byte units of frame annotation + * to be stashed. Annotation is placed at FD[ADDR]. + * - bits 4-5: indicates the number of 64 byte units of frame data to be + * stashed. Frame data is placed at FD[ADDR] + FD[OFFSET]. + * This flag is ignored if DPNI_FS_OPT_SET_FLC is not specified. + */ +#define DPNI_FS_OPT_SET_STASH_CONTROL 0x4 + +/** + * struct dpni_fs_action_cfg - Action configuration for table look-up + * @flc: FLC value for traffic matching this rule. Please check the Frame + * Descriptor section in the hardware documentation for more information. + * @flow_id: Identifies the Rx queue used for matching traffic. Supported + * values are in range 0 to num_queue-1. + * @options: Any combination of DPNI_FS_OPT_ values. + */ +struct dpni_fs_action_cfg { + uint64_t flc; + uint16_t flow_id; + uint16_t options; +}; + +int dpni_add_fs_entry(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + uint8_t tc_id, + uint16_t index, + const struct dpni_rule_cfg *cfg, + const struct dpni_fs_action_cfg *action); + +int dpni_remove_fs_entry(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + uint8_t tc_id, + const struct dpni_rule_cfg *cfg); + +int dpni_clear_fs_entries(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + uint8_t tc_id); + int dpni_get_api_version(struct fsl_mc_io *mc_io, uint32_t cmd_flags, uint16_t *major_ver, @@ -1202,6 +1319,43 @@ int dpni_get_opr(struct fsl_mc_io *mc_io, struct opr_cfg *cfg, struct opr_qry *qry); +/** + * When used for queue_idx in function dpni_set_rx_dist_default_queue will + * signal to dpni to drop all unclassified frames + */ +#define DPNI_FS_MISS_DROP ((uint16_t)-1) + +/** + * struct dpni_rx_dist_cfg - distribution configuration + * @dist_size: distribution size; supported values: 1,2,3,4,6,7,8, + * 12,14,16,24,28,32,48,56,64,96,112,128,192,224,256,384,448, + * 512,768,896,1024 + * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with + * the extractions to be used for the distribution key by calling + * dpkg_prepare_key_cfg() relevant only when enable!=0 otherwise + * it can be '0' + * @enable: enable/disable the distribution. + * @tc: TC id for which distribution is set + * @fs_miss_flow_id: when packet misses all rules from flow steering table and + * hash is disabled it will be put into this queue id; use + * DPNI_FS_MISS_DROP to drop frames. The value of this field is + * used only when flow steering distribution is enabled and hash + * distribution is disabled + */ +struct dpni_rx_dist_cfg { + uint16_t dist_size; + uint64_t key_cfg_iova; + uint8_t enable; + uint8_t tc; + uint16_t fs_miss_flow_id; +}; + +int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, const struct dpni_rx_dist_cfg *cfg); + +int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags, + uint16_t token, const struct dpni_rx_dist_cfg *cfg); + int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags, uint16_t token, uint16_t tpid); diff --git a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h index 81830ed85..9116e417e 100644 --- a/drivers/net/dpaa2/mc/fsl_dpni_cmd.h +++ b/drivers/net/dpaa2/mc/fsl_dpni_cmd.h @@ -69,6 +69,14 @@ #define DPNI_CMDID_SET_RX_TC_DIST DPNI_CMD_V3(0x235) +#define DPNI_CMDID_SET_QOS_TBL DPNI_CMD_V2(0x240) +#define DPNI_CMDID_ADD_QOS_ENT DPNI_CMD(0x241) +#define DPNI_CMDID_REMOVE_QOS_ENT DPNI_CMD(0x242) +#define DPNI_CMDID_CLR_QOS_TBL DPNI_CMD(0x243) +#define DPNI_CMDID_ADD_FS_ENT DPNI_CMD(0x244) +#define DPNI_CMDID_REMOVE_FS_ENT DPNI_CMD(0x245) +#define DPNI_CMDID_CLR_FS_ENT DPNI_CMD(0x246) + #define DPNI_CMDID_GET_STATISTICS DPNI_CMD_V2(0x25D) #define DPNI_CMDID_RESET_STATISTICS DPNI_CMD(0x25E) #define DPNI_CMDID_GET_QUEUE DPNI_CMD(0x25F) @@ -91,6 +99,8 @@ #define DPNI_CMDID_GET_TX_CONFIRMATION_MODE DPNI_CMD(0x26D) #define DPNI_CMDID_SET_OPR DPNI_CMD(0x26e) #define DPNI_CMDID_GET_OPR DPNI_CMD(0x26f) +#define DPNI_CMDID_SET_RX_FS_DIST DPNI_CMD(0x273) +#define DPNI_CMDID_SET_RX_HASH_DIST DPNI_CMD(0x274) #define DPNI_CMDID_ADD_CUSTOM_TPID DPNI_CMD(0x275) #define DPNI_CMDID_REMOVE_CUSTOM_TPID DPNI_CMD(0x276) #define DPNI_CMDID_GET_CUSTOM_TPID DPNI_CMD(0x277) @@ -495,6 +505,63 @@ struct dpni_cmd_set_queue { uint64_t user_context; }; +#define DPNI_DISCARD_ON_MISS_SHIFT 0 +#define DPNI_DISCARD_ON_MISS_SIZE 1 +#define DPNI_KEEP_QOS_ENTRIES_SHIFT 1 +#define DPNI_KEEP_QOS_ENTRIES_SIZE 1 + +struct dpni_cmd_set_qos_table { + uint32_t pad; + uint8_t default_tc; + /* only the LSB */ + uint8_t discard_on_miss; + uint16_t pad1[21]; + uint64_t key_cfg_iova; +}; + +struct dpni_cmd_add_qos_entry { + uint16_t pad; + uint8_t tc_id; + uint8_t key_size; + uint16_t index; + uint16_t pad2; + uint64_t key_iova; + uint64_t mask_iova; +}; + +struct dpni_cmd_remove_qos_entry { + uint8_t pad1[3]; + uint8_t key_size; + uint32_t pad2; + uint64_t key_iova; + uint64_t mask_iova; +}; + +struct dpni_cmd_add_fs_entry { + uint16_t options; + uint8_t tc_id; + uint8_t key_size; + uint16_t index; + uint16_t flow_id; + uint64_t key_iova; + uint64_t mask_iova; + uint64_t flc; +}; + +struct dpni_cmd_remove_fs_entry { + uint16_t pad1; + uint8_t tc_id; + uint8_t key_size; + uint32_t pad2; + uint64_t key_iova; + uint64_t mask_iova; +}; + +struct dpni_cmd_clear_fs_entries { + uint16_t pad; + uint8_t tc_id; +}; + #define DPNI_DROP_ENABLE_SHIFT 0 #define DPNI_DROP_ENABLE_SIZE 1 #define DPNI_DROP_UNITS_SHIFT 2 @@ -692,5 +759,26 @@ struct dpni_rsp_get_custom_tpid { uint16_t tpid2; }; +#define DPNI_RX_FS_DIST_ENABLE_SHIFT 0 +#define DPNI_RX_FS_DIST_ENABLE_SIZE 1 +struct dpni_cmd_set_rx_fs_dist { + uint16_t dist_size; + uint8_t enable; + uint8_t tc; + uint16_t miss_flow_id; + uint16_t pad1; + uint64_t key_cfg_iova; +}; + +#define DPNI_RX_HASH_DIST_ENABLE_SHIFT 0 +#define DPNI_RX_HASH_DIST_ENABLE_SIZE 1 +struct dpni_cmd_set_rx_hash_dist { + uint16_t dist_size; + uint8_t enable; + uint8_t tc_id; + uint32_t pad; + uint64_t key_cfg_iova; +}; + #pragma pack(pop) #endif /* _FSL_DPNI_CMD_H */ diff --git a/drivers/net/dpaa2/meson.build b/drivers/net/dpaa2/meson.build index 801cbf5d7..53e1d8189 100644 --- a/drivers/net/dpaa2/meson.build +++ b/drivers/net/dpaa2/meson.build @@ -11,6 +11,7 @@ deps += ['mempool_dpaa2'] sources = files('base/dpaa2_hw_dpni.c', 'dpaa2_mux.c', 'dpaa2_ethdev.c', + 'dpaa2_flow.c', 'dpaa2_rxtx.c', 'mc/dpkg.c', 'mc/dpdmux.c',