From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id BCAE6A0577; Tue, 14 Apr 2020 16:56:29 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 1327E1C2E1; Tue, 14 Apr 2020 16:56:29 +0200 (CEST) Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by dpdk.org (Postfix) with ESMTP id 462451C11E for ; Tue, 14 Apr 2020 16:56:27 +0200 (CEST) IronPort-SDR: 7BYdWnYbw10HFW/lNps14Rtl0f1J0D0il77shzq6tNec5I4ySXFUjjE/bNS6n+QFlolYRKHCNg rmM23xkOcxLw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2020 07:56:26 -0700 IronPort-SDR: CNRW5qaCfmQVQE+EVM6dZNRL9uml5Tz89J99wml8AMOwRBYcYyqfrvG02+IGPG9gr983zqSkOR RRn9wOx+cetA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.72,382,1580803200"; d="scan'208";a="453565308" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by fmsmga005.fm.intel.com with ESMTP; 14 Apr 2020 07:56:26 -0700 Received: from fmsmsx605.amr.corp.intel.com (10.18.126.85) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 14 Apr 2020 07:56:26 -0700 Received: from fmsmsx605.amr.corp.intel.com (10.18.126.85) by fmsmsx605.amr.corp.intel.com (10.18.126.85) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 14 Apr 2020 07:56:25 -0700 Received: from FMSEDG002.ED.cps.intel.com (10.1.192.134) by fmsmsx605.amr.corp.intel.com (10.18.126.85) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1713.5 via Frontend Transport; Tue, 14 Apr 2020 07:56:25 -0700 Received: from NAM04-SN1-obe.outbound.protection.outlook.com (104.47.44.57) by edgegateway.intel.com (192.55.55.69) with Microsoft SMTP Server (TLS) id 14.3.439.0; Tue, 14 Apr 2020 07:56:12 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RUpzrLwsKrYFj/sJgE0DvPU7RQ2i4sE2joFH9VStUWKVyEgf2Mx/AN+7hdcYVzYfu62Zpdi35d0rMTv/Ca8SNCzPDcY93LCShxwX7/ExboD8qYBhvgNiivmYW61Rj5zFNIWyUrssND39daq8zy8KToNhJEhQChgO6POyz+Z66G12hRqsMRT6NQHUlG6X1dU+aGdU3zDRTRQBbeH1UEGRCLEzob8gd7GX4WoD9j6iK2frHQ2Mcsp05oZU8Wp+D56MkHESyhWNY4kKWI4s1q3Hl0Ul9tW5OLzi8Rsx3sgyfGefyLsbMKqfeSGAuAp1Uq/9oYfe1JeQcM4058paJLTtBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=X9n8FLC1FQhXrxNlTzGbLf8qprA6Zik25TlZOGz3Ck0=; b=VtmN8NKrX9RsGRje34z36q9Clm5boa0qMMfGieU7YH1LeNLdVXNtJWW/KdubpLFhI7cMb1Twcpfjk0DpNofdK1KlQQ5x4YbscpCv7o6vIs93TuQPZVbtw46TE/sFkrbwQGgA39m6tYVj19FwidQJi5DYn40XfriWzPYrjO9K5GEwxM2GPfdGTMKjrjMtT5td/bMAul+MGvO7kI/+dy/OxlzGgeqg70SxVGVMAe1ZTaATKPM3VMuLLExcRm9vQ3RoHTA1WDEWhibAqypm00hewPBqluNpUH4BibCs7qduWA939PMlLx/Ed75COFzJ+lbV+86D6yPSsnfzwAgoGRYUyA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=X9n8FLC1FQhXrxNlTzGbLf8qprA6Zik25TlZOGz3Ck0=; b=koDT5vUt+sE5dsAkUhbjlBKvO5h3UVbHWfA1cnbzmJ9A70XL3k9iM5kYKp4p1vkre8QKdu2jOYp4gIqVmTLYt1YMLFqSPaB8owYXiYTOOxucGDoSJsSmloAitz7kLLpMA7nyzyUx2jSEVbHV2v2D0+G1Dfk00bWrjtePhVfFf0c= Received: from DM6PR11MB2537.namprd11.prod.outlook.com (2603:10b6:5:cd::16) by DM6PR11MB4220.namprd11.prod.outlook.com (2603:10b6:5:204::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.26; Tue, 14 Apr 2020 14:55:55 +0000 Received: from DM6PR11MB2537.namprd11.prod.outlook.com ([fe80::7c08:b4ae:e9c2:a4fa]) by DM6PR11MB2537.namprd11.prod.outlook.com ([fe80::7c08:b4ae:e9c2:a4fa%6]) with mapi id 15.20.2900.028; Tue, 14 Apr 2020 14:55:55 +0000 From: "Iremonger, Bernard" To: "Di, ChenxuX" , "dev@dpdk.org" CC: "Xing, Beilei" , "Di, ChenxuX" Thread-Topic: [dpdk-dev] [PATCH v8] net/i40e: enable advanced RSS Thread-Index: AQHWEigu5KAVtWfpj0etbvNIee70A6h4tHeQ Date: Tue, 14 Apr 2020 14:55:54 +0000 Message-ID: References: <20200318014710.13577-1-chenxux.di@intel.com> <20200414063648.86590-1-chenxux.di@intel.com> In-Reply-To: <20200414063648.86590-1-chenxux.di@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-reaction: no-action dlp-version: 11.2.0.6 authentication-results: spf=none (sender IP is ) smtp.mailfrom=bernard.iremonger@intel.com; x-originating-ip: [192.198.151.190] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 39d906ad-9320-4f58-188f-08d7e083eef7 x-ms-traffictypediagnostic: DM6PR11MB4220: x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:6790; x-forefront-prvs: 0373D94D15 x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM6PR11MB2537.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(10019020)(366004)(376002)(396003)(39860400002)(136003)(346002)(2906002)(33656002)(8936002)(71200400001)(30864003)(7696005)(9686003)(4326008)(55016002)(52536014)(26005)(66556008)(64756008)(66446008)(186003)(5660300002)(66946007)(316002)(110136005)(478600001)(81156014)(86362001)(76116006)(6506007)(53546011)(54906003)(8676002)(107886003)(66476007)(559001)(579004); DIR:OUT; SFP:1102; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 9k3iSDvJ2fVMurVeZJOqiIuNDka/xv5pIkjQavyviAqtB4E8BNpBznJRYOM45U2CW6aL1mHWY4yC8vQON6gfAJqXS+W+4+lnDGcr/+boYgbvAChZ0c5vxTUgkY0Sl8ueoeQYThWzYvwX1SE0pv/0IKsptham6T2mxeyKvtzwQu/usCxvGW4qXc/mgdzFxWIyaxAG0OCkn+IkURaccqe7Z+DpdzMgyDp4l22+R3KR5WRRobt6T7NCwmFerEVoU29SrKgV22STTT/DTvMkanI9mz2XEskzsqdUlkBTbZyfFGn0U3XBvcno3QHGMB+4FoalD75SHkWULyWb3sOs4tieGeO94rrymdujQ+a0VJWWyGFjRZ8HEQjNmVPyMD4lGLdON/qiEg76fVZttJjVdAk4+5Jy+TXOUiLMkjfOcG5MWdoMAiePImwZVLdHQ3+xeKdH x-ms-exchange-antispam-messagedata: lw5+4nt5AyhpWC+ZDAjU3aL6qKPJOZCwNoeOsxOapVOjzNX63qoJnF8psjgLWGKNHQ9ybDvSCdX0opWb2wOEXFSF7qWkxSEEzgxMZqYARuKHuiSGmf6dkq7OYOw9fC5v9gXc3krUsPr1U94gLNIUOg== Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-Network-Message-Id: 39d906ad-9320-4f58-188f-08d7e083eef7 X-MS-Exchange-CrossTenant-originalarrivaltime: 14 Apr 2020 14:55:54.8724 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: fWe5RWXb/27VIHDi1mVAzcAhV+x9GKeBaEv1ZwSmt0yvbZ5RY5P+rLdxQB3kc2qzA48VPYqXClaIp8Ru9n7WzHBoWNgB1aZrqVj612tdntY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR11MB4220 X-OriginatorOrg: intel.com Subject: Re: [dpdk-dev] [PATCH v8] net/i40e: enable advanced RSS 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" Hi Chenxu, > -----Original Message----- > From: dev On Behalf Of Chenxu Di > Sent: Tuesday, April 14, 2020 7:37 AM > To: dev@dpdk.org > Cc: Xing, Beilei ; Di, ChenxuX > > Subject: [dpdk-dev] [PATCH v8] net/i40e: enable advanced RSS >=20 > This patch supports: >=20 > - symmetric hash configuration > - Input set configuration >=20 > Signed-off-by: Chenxu Di > --- > doc/guides/nics/i40e.rst | 35 ++ > doc/guides/rel_notes/release_20_05.rst | 7 + > drivers/net/i40e/i40e_ethdev.c | 509 ++++++++++++++++++++++--- > drivers/net/i40e/i40e_ethdev.h | 22 +- > drivers/net/i40e/i40e_flow.c | 199 ++++++++-- > 5 files changed, 683 insertions(+), 89 deletions(-) >=20 > diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst index > d6e578eda..1f8fca285 100644 > --- a/doc/guides/nics/i40e.rst > +++ b/doc/guides/nics/i40e.rst > @@ -569,6 +569,41 @@ details please refer to > :doc:`../testpmd_app_ug/index`. > testpmd> set port (port_id) queue-region flush (on|off) > testpmd> show port (port_id) queue-region >=20 > +Generic flow API > +~~~~~~~~~~~~~~~~~~~ > + > +- ``RSS Flow`` > + > + RSS Flow supports to set hash input set, hash function, enable hash > + and configure queue region. > + For example: > + Configure queue region as queue 0, 1, 2, 3. > + > + .. code-block:: console > + > + testpmd> flow create 0 ingress pattern end actions rss types end \ > + queues 0 1 2 3 end / end > + > + Enable hash and set input set for ipv4-tcp. > + > + .. code-block:: console > + > + testpmd> flow create 0 ingress pattern eth / ipv4 / tcp / end \ > + actions rss types ipv4-tcp l3-src-only end queues end / end > + /dpdk# make doc-guides-html sphinx processing guides-html... /root/dpdk_ipsec_gitlab_1/doc/guides/nics/i40e.rst:603: ERROR: Error in "co= de-block" directive: maximum 1 argument(s) allowed, 19 supplied. .. code-block:: console testpmd> flow create 0 ingress pattern end actions rss types end \ queues end func simple_xor / end > + Set symmetric hash enable for flow type ipv4-tcp. > + > + .. code-block:: console > + > + testpmd> flow create 0 ingress pattern eth / ipv4 / tcp / end \ > + actions rss types ipv4-tcp end queues end func symmetric_toeplitz > + / end > + > + Set hash function as simple xor. > + > + .. code-block:: console > + testpmd> flow create 0 ingress pattern end actions rss types end \ > + queues end func simple_xor / end > + > Limitations or Known issues > --------------------------- >=20 > diff --git a/doc/guides/rel_notes/release_20_05.rst > b/doc/guides/rel_notes/release_20_05.rst > index 000bbf501..bf5f399fe 100644 > --- a/doc/guides/rel_notes/release_20_05.rst > +++ b/doc/guides/rel_notes/release_20_05.rst > @@ -62,6 +62,13 @@ New Features >=20 > * Added support for matching on IPv4 Time To Live and IPv6 Hop Limit. >=20 > +* **Updated Intel i40e driver.** > + > + Updated i40e PMD with new features and improvements, including: > + > + * Added support for RSS using L3/L4 source/destination only. > + * Added support for setting hash function in rte flow. > + >=20 > Removed Items > ------------- > diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethde= v.c > index 9539b0470..efc113842 100644 > --- a/drivers/net/i40e/i40e_ethdev.c > +++ b/drivers/net/i40e/i40e_ethdev.c > @@ -1656,6 +1656,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void > *init_params __rte_unused) > /* initialize mirror rule list */ > TAILQ_INIT(&pf->mirror_list); >=20 > + /* initialize RSS rule list */ > + TAILQ_INIT(&pf->rss_config_list); > + > /* initialize Traffic Manager configuration */ > i40e_tm_conf_init(dev); >=20 > @@ -12325,14 +12328,16 @@ i40e_tunnel_filter_restore(struct i40e_pf *pf) > } > } >=20 > -/* Restore rss filter */ > +/* Restore RSS filter */ > static inline void > i40e_rss_filter_restore(struct i40e_pf *pf) { > - struct i40e_rte_flow_rss_conf *conf =3D > - &pf->rss_info; > - if (conf->conf.queue_num) > - i40e_config_rss_filter(pf, conf, TRUE); > + struct i40e_rss_conf_list *list =3D &pf->rss_config_list; > + struct i40e_rss_filter *filter; > + > + TAILQ_FOREACH(filter, list, next) { > + i40e_config_rss_filter(pf, &filter->rss_filter_info, TRUE); > + } > } >=20 > static void > @@ -12942,45 +12947,274 @@ i40e_rss_conf_init(struct > i40e_rte_flow_rss_conf *out, > return 0; > } >=20 > -int > -i40e_action_rss_same(const struct rte_flow_action_rss *comp, > - const struct rte_flow_action_rss *with) > +/* Configure hash input set */ > +static int > +i40e_rss_conf_hash_inset(struct i40e_pf *pf, uint64_t types) > { > - return (comp->func =3D=3D with->func && > - comp->level =3D=3D with->level && > - comp->types =3D=3D with->types && > - comp->key_len =3D=3D with->key_len && > - comp->queue_num =3D=3D with->queue_num && > - !memcmp(comp->key, with->key, with->key_len) && > - !memcmp(comp->queue, with->queue, > - sizeof(*with->queue) * with->queue_num)); > + struct i40e_hw *hw =3D I40E_PF_TO_HW(pf); > + struct rte_eth_input_set_conf conf; > + int i, ret; > + uint32_t j; > + static const struct { > + uint64_t type; > + enum rte_eth_input_set_field field; > + } inset_match_table[] =3D { > + {ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP4}, > + {ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP4}, > + {ETH_RSS_FRAG_IPV4 | ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_UNKNOWN}, > + {ETH_RSS_FRAG_IPV4 | ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_UNKNOWN}, > + > + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP4}, > + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP4}, > + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT}, > + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_L4_TCP_DST_PORT}, > + > + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP4}, > + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP4}, > + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT}, > + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_L4_UDP_DST_PORT}, > + > + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP4}, > + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP4}, > + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT}, > + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT}, > + > + {ETH_RSS_NONFRAG_IPV4_OTHER | > ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP4}, > + {ETH_RSS_NONFRAG_IPV4_OTHER | > ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP4}, > + {ETH_RSS_NONFRAG_IPV4_OTHER | > ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_UNKNOWN}, > + {ETH_RSS_NONFRAG_IPV4_OTHER | > ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_UNKNOWN}, > + > + {ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP6}, > + {ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP6}, > + {ETH_RSS_FRAG_IPV6 | ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_UNKNOWN}, > + {ETH_RSS_FRAG_IPV6 | ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_UNKNOWN}, > + > + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP6}, > + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP6}, > + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT}, > + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_L4_TCP_DST_PORT}, > + > + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP6}, > + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP6}, > + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT}, > + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_L4_UDP_DST_PORT}, > + > + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP6}, > + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP6}, > + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT}, > + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT}, > + > + {ETH_RSS_NONFRAG_IPV6_OTHER | > ETH_RSS_L3_SRC_ONLY, > + RTE_ETH_INPUT_SET_L3_SRC_IP6}, > + {ETH_RSS_NONFRAG_IPV6_OTHER | > ETH_RSS_L3_DST_ONLY, > + RTE_ETH_INPUT_SET_L3_DST_IP6}, > + {ETH_RSS_NONFRAG_IPV6_OTHER | > ETH_RSS_L4_SRC_ONLY, > + RTE_ETH_INPUT_SET_UNKNOWN}, > + {ETH_RSS_NONFRAG_IPV6_OTHER | > ETH_RSS_L4_DST_ONLY, > + RTE_ETH_INPUT_SET_UNKNOWN}, > + }; > + > + ret =3D 0; > + > + for (i =3D RTE_ETH_FLOW_UNKNOWN + 1; i < RTE_ETH_FLOW_MAX; > i++) { > + if (!(pf->adapter->flow_types_mask & (1ULL << i)) || > + !(types & (1ULL << i))) > + continue; > + > + conf.op =3D RTE_ETH_INPUT_SET_SELECT; > + conf.flow_type =3D i; > + conf.inset_size =3D 0; > + for (j =3D 0; j < RTE_DIM(inset_match_table); j++) { > + if ((types & inset_match_table[j].type) =3D=3D > + inset_match_table[j].type) { > + if (inset_match_table[j].field =3D=3D > + RTE_ETH_INPUT_SET_UNKNOWN) { > + return -EINVAL; > + } > + conf.field[conf.inset_size] =3D > + inset_match_table[j].field; > + conf.inset_size++; > + } > + } > + > + if (conf.inset_size) { > + ret =3D i40e_hash_filter_inset_select(hw, &conf); > + if (ret) > + return ret; > + } > + } > + > + return ret; > } >=20 > -int > -i40e_config_rss_filter(struct i40e_pf *pf, > - struct i40e_rte_flow_rss_conf *conf, bool add) > +/* Look up the conflicted rule then mark it as invalid */ static void > +i40e_rss_mark_invalid_rule(struct i40e_pf *pf, > + struct i40e_rte_flow_rss_conf *conf) > +{ > + struct i40e_rss_filter *rss_item; > + uint64_t rss_inset; > + > + /* Clear input set bits before comparing the pctype */ > + rss_inset =3D ~(ETH_RSS_L3_SRC_ONLY | ETH_RSS_L3_DST_ONLY | > + ETH_RSS_L4_SRC_ONLY | ETH_RSS_L4_DST_ONLY); > + > + TAILQ_FOREACH(rss_item, &pf->rss_config_list, next) { > + if (!rss_item->rss_filter_info.valid) > + continue; > + > + /* Rule for queue region */ > + if (conf->conf.queue_num && > + rss_item->rss_filter_info.conf.queue_num) > + rss_item->rss_filter_info.valid =3D false; > + > + /* Rule for hash input set */ > + if (conf->conf.types && > + (rss_item->rss_filter_info.conf.types & > + rss_inset) =3D=3D > + (conf->conf.types & rss_inset)) > + rss_item->rss_filter_info.valid =3D false; > + > + /* Rule for hash function */ > + if (conf->conf.func =3D=3D > + RTE_ETH_HASH_FUNCTION_SIMPLE_XOR && > + rss_item->rss_filter_info.conf.func =3D=3D > + RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) > + rss_item->rss_filter_info.valid =3D false; > + } > +} > + > +/* Configure RSS hash function */ > +static int > +i40e_rss_config_hash_function(struct i40e_pf *pf, > + struct i40e_rte_flow_rss_conf *conf) > { > struct i40e_hw *hw =3D I40E_PF_TO_HW(pf); > - uint32_t i, lut =3D 0; > - uint16_t j, num; > - struct rte_eth_rss_conf rss_conf =3D { > - .rss_key =3D conf->conf.key_len ? > - (void *)(uintptr_t)conf->conf.key : NULL, > - .rss_key_len =3D conf->conf.key_len, > - .rss_hf =3D conf->conf.types, > - }; > - struct i40e_rte_flow_rss_conf *rss_info =3D &pf->rss_info; > + uint64_t mask0 =3D conf->conf.types & pf->adapter- > >flow_types_mask; > + uint32_t reg, i; > + uint16_t j; >=20 > - if (!add) { > - if (i40e_action_rss_same(&rss_info->conf, &conf->conf)) { > - i40e_pf_disable_rss(pf); > - memset(rss_info, 0, > - sizeof(struct i40e_rte_flow_rss_conf)); > - return 0; > + if (conf->conf.func =3D=3D > RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) { > + i40e_set_symmetric_hash_enable_per_port(hw, 1); > + for (i =3D RTE_ETH_FLOW_UNKNOWN + 1; > + mask0 && i < UINT64_BIT; i++) { > + if (!(mask0 & (1UL << i))) > + continue; > + for (j =3D I40E_FILTER_PCTYPE_INVALID + 1; > + j < I40E_FILTER_PCTYPE_MAX; j++) { > + if (pf->adapter->pctypes_tbl[i] & (1ULL << j)) > + i40e_write_global_rx_ctl(hw, > + I40E_GLQF_HSYM(j), > + > I40E_GLQF_HSYM_SYMH_ENA_MASK); > + } > } > + > + return 0; > + } > + > + /* Simple XOR */ > + reg =3D i40e_read_rx_ctl(hw, I40E_GLQF_CTL); > + if (!(reg & I40E_GLQF_CTL_HTOEP_MASK)) { > + PMD_DRV_LOG(DEBUG, "Hash function already set to Simple > XOR"); > + goto out; > + } > + reg &=3D ~I40E_GLQF_CTL_HTOEP_MASK; > + > + i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg); > + > +out: > + I40E_WRITE_FLUSH(hw); > + i40e_rss_mark_invalid_rule(pf, conf); > + > + return 0; > +} > + > +/* Enable RSS according to the configuration */ static int > +i40e_rss_enable_hash(struct i40e_pf *pf, > + struct i40e_rte_flow_rss_conf *conf, > + struct rte_eth_rss_conf *rss_conf) > +{ > + struct i40e_rte_flow_rss_conf *rss_info =3D &pf->rss_info; > + > + if (!(rss_conf->rss_hf & pf->adapter->flow_types_mask)) > + return -ENOTSUP; > + > + /* Configure hash input set */ > + if (i40e_rss_conf_hash_inset(pf, rss_conf->rss_hf)) > return -EINVAL; > + > + if (rss_conf->rss_key =3D=3D NULL || rss_conf->rss_key_len < > + (I40E_PFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t)) { > + /* Random default keys */ > + static uint32_t rss_key_default[] =3D {0x6b793944, > + 0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8, > + 0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605, > + 0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581}; > + > + rss_conf->rss_key =3D (uint8_t *)rss_key_default; > + rss_conf->rss_key_len =3D (I40E_PFQF_HKEY_MAX_INDEX + 1) > * > + sizeof(uint32_t); > + PMD_DRV_LOG(INFO, > + "No valid RSS key config for i40e, using default\n"); > } >=20 > + rss_conf->rss_hf |=3D rss_info->conf.types; > + i40e_hw_rss_hash_set(pf, rss_conf); > + > + if (conf->conf.func =3D=3D > RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) > + i40e_rss_config_hash_function(pf, conf); > + > + i40e_rss_mark_invalid_rule(pf, conf); > + > + return 0; > +} > + > +/* Configure RSS queue region */ > +static int > +i40e_rss_config_queue_region(struct i40e_pf *pf, > + struct i40e_rte_flow_rss_conf *conf) > +{ > + struct i40e_hw *hw =3D I40E_PF_TO_HW(pf); > + uint32_t i, lut; > + uint16_t j, num; > + > /* If both VMDQ and RSS enabled, not all of PF queues are > configured. > * It's necessary to calculate the actual PF queues that are configured= . > */ > @@ -13000,6 +13234,7 @@ i40e_config_rss_filter(struct i40e_pf *pf, > return -ENOTSUP; > } >=20 > + lut =3D 0; > /* Fill in redirection table */ > for (i =3D 0, j =3D 0; i < hw->func_caps.rss_table_size; i++, j++) { > if (j =3D=3D num) > @@ -13010,29 +13245,203 @@ i40e_config_rss_filter(struct i40e_pf *pf, > I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut); > } >=20 > - if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) =3D=3D 0) { > - i40e_pf_disable_rss(pf); > + i40e_rss_mark_invalid_rule(pf, conf); > + > + return 0; > +} > + > +/* Configure RSS hash function to default */ static int > +i40e_rss_clear_hash_function(struct i40e_pf *pf, > + struct i40e_rte_flow_rss_conf *conf) > +{ > + struct i40e_hw *hw =3D I40E_PF_TO_HW(pf); > + uint64_t mask0 =3D conf->conf.types & pf->adapter- > >flow_types_mask; > + uint32_t i, reg; > + uint16_t j; > + > + if (conf->conf.func !=3D RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) { > + for (i =3D RTE_ETH_FLOW_UNKNOWN + 1; > + mask0 && i < UINT64_BIT; i++) { > + if (mask0 & (1UL << i)) { > + for (j =3D I40E_FILTER_PCTYPE_INVALID + 1; > + j < I40E_FILTER_PCTYPE_MAX; j++) { > + if (pf->adapter->pctypes_tbl[i] & > + (1ULL << j)) > + i40e_write_global_rx_ctl(hw, > + I40E_GLQF_HSYM(j), > + 0); > + } > + } > + } > + > return 0; > } > - if (rss_conf.rss_key =3D=3D NULL || rss_conf.rss_key_len < > - (I40E_PFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t)) { > - /* Random default keys */ > - static uint32_t rss_key_default[] =3D {0x6b793944, > - 0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8, > - 0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605, > - 0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581}; >=20 > - rss_conf.rss_key =3D (uint8_t *)rss_key_default; > - rss_conf.rss_key_len =3D (I40E_PFQF_HKEY_MAX_INDEX + 1) * > - sizeof(uint32_t); > - PMD_DRV_LOG(INFO, > - "No valid RSS key config for i40e, using default\n"); > + /* Simple XOR */ > + reg =3D i40e_read_rx_ctl(hw, I40E_GLQF_CTL); > + if (reg & I40E_GLQF_CTL_HTOEP_MASK) { > + PMD_DRV_LOG(DEBUG, > + "Hash function already set to Toeplitz"); > + goto out; > } > + reg |=3D I40E_GLQF_CTL_HTOEP_MASK; > + > + i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg); > + > +out: > + I40E_WRITE_FLUSH(hw); > + > + return 0; > +} >=20 > +/* Disable RSS hash and configure default input set */ static int > +i40e_rss_disable_hash(struct i40e_pf *pf, > + struct i40e_rte_flow_rss_conf *conf) > +{ > + struct i40e_hw *hw =3D I40E_PF_TO_HW(pf); > + struct i40e_rte_flow_rss_conf *rss_info =3D &pf->rss_info; > + struct rte_eth_rss_conf rss_conf =3D { > + .rss_key =3D pf->rss_info.conf.key_len ? > + (void *)(uintptr_t)conf->conf.key : NULL, > + .rss_key_len =3D pf->rss_info.conf.key_len, > + }; > + uint32_t i; > + > + /* Disable RSS hash */ > + rss_conf.rss_hf =3D rss_info->conf.types & ~(conf->conf.types); > i40e_hw_rss_hash_set(pf, &rss_conf); >=20 > - if (i40e_rss_conf_init(rss_info, &conf->conf)) > - return -EINVAL; > + for (i =3D RTE_ETH_FLOW_IPV4; i <=3D RTE_ETH_FLOW_L2_PAYLOAD; > i++) { > + if (!(pf->adapter->flow_types_mask & (1ULL << i)) || > + !(conf->conf.types & (1ULL << i))) > + continue; > + > + /* Configure default input set */ > + struct rte_eth_input_set_conf input_conf =3D { > + .op =3D RTE_ETH_INPUT_SET_SELECT, > + .flow_type =3D i, > + .inset_size =3D 1, > + }; > + input_conf.field[0] =3D RTE_ETH_INPUT_SET_DEFAULT; > + i40e_hash_filter_inset_select(hw, &input_conf); > + } > + > + rss_info->conf.types =3D rss_conf.rss_hf; > + > + i40e_rss_clear_hash_function(pf, conf); > + > + return 0; > +} > + > +/* Configure RSS queue region to default */ static int > +i40e_rss_clear_queue_region(struct i40e_pf *pf) { > + struct i40e_hw *hw =3D I40E_PF_TO_HW(pf); > + struct i40e_rte_flow_rss_conf *rss_info =3D &pf->rss_info; > + uint16_t queue[I40E_MAX_Q_PER_TC]; > + uint32_t num_rxq, i, lut; > + uint16_t j, num; > + > + num_rxq =3D RTE_MIN(pf->dev_data->nb_rx_queues, > I40E_MAX_Q_PER_TC); > + > + for (j =3D 0; j < num_rxq; j++) > + queue[j] =3D j; > + > + /* If both VMDQ and RSS enabled, not all of PF queues are > configured. > + * It's necessary to calculate the actual PF queues that are configured= . > + */ > + if (pf->dev_data->dev_conf.rxmode.mq_mode & > ETH_MQ_RX_VMDQ_FLAG) > + num =3D i40e_pf_calc_configured_queues_num(pf); > + else > + num =3D pf->dev_data->nb_rx_queues; > + > + num =3D RTE_MIN(num, num_rxq); > + PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are > configured", > + num); > + > + if (num =3D=3D 0) { > + PMD_DRV_LOG(ERR, > + "No PF queues are configured to enable RSS for port > %u", > + pf->dev_data->port_id); > + return -ENOTSUP; > + } > + > + lut =3D 0; > + /* Fill in redirection table */ > + for (i =3D 0, j =3D 0; i < hw->func_caps.rss_table_size; i++, j++) { > + if (j =3D=3D num) > + j =3D 0; > + lut =3D (lut << 8) | (queue[j] & ((0x1 << > + hw->func_caps.rss_table_entry_width) - 1)); > + if ((i & 3) =3D=3D 3) > + I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut); > + } > + > + rss_info->conf.queue_num =3D 0; > + memset(&rss_info->conf.queue, 0, sizeof(uint16_t)); > + > + return 0; > +} > + > +int > +i40e_config_rss_filter(struct i40e_pf *pf, > + struct i40e_rte_flow_rss_conf *conf, bool add) { > + struct i40e_rte_flow_rss_conf *rss_info =3D &pf->rss_info; > + struct rte_flow_action_rss update_conf =3D rss_info->conf; > + struct rte_eth_rss_conf rss_conf =3D { > + .rss_key =3D conf->conf.key_len ? > + (void *)(uintptr_t)conf->conf.key : NULL, > + .rss_key_len =3D conf->conf.key_len, > + .rss_hf =3D conf->conf.types, > + }; > + int ret =3D 0; > + > + if (add) { > + if (conf->conf.queue_num) { > + /* Configure RSS queue region */ > + ret =3D i40e_rss_config_queue_region(pf, conf); > + if (ret) > + return ret; > + > + update_conf.queue_num =3D conf->conf.queue_num; > + update_conf.queue =3D conf->conf.queue; > + } else if (conf->conf.func =3D=3D > + RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) { > + /* Configure hash function */ > + ret =3D i40e_rss_config_hash_function(pf, conf); > + if (ret) > + return ret; > + > + update_conf.func =3D conf->conf.func; > + } else { > + /* Configure hash enable and input set */ > + ret =3D i40e_rss_enable_hash(pf, conf, &rss_conf); > + if (ret) > + return ret; > + > + update_conf.types =3D rss_conf.rss_hf; > + update_conf.key =3D rss_conf.rss_key; > + update_conf.key_len =3D rss_conf.rss_key_len; > + } > + > + /* Update RSS info in pf */ > + if (i40e_rss_conf_init(rss_info, &update_conf)) > + return -EINVAL; > + } else { > + if (!conf->valid) > + return 0; > + > + if (conf->conf.queue_num) > + i40e_rss_clear_queue_region(pf); > + else if (conf->conf.func =3D=3D > RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) > + i40e_rss_clear_hash_function(pf, conf); > + else > + i40e_rss_disable_hash(pf, conf); > + } >=20 > return 0; > } > diff --git a/drivers/net/i40e/i40e_ethdev.h > b/drivers/net/i40e/i40e_ethdev.h index aac89de91..e9d90fa35 100644 > --- a/drivers/net/i40e/i40e_ethdev.h > +++ b/drivers/net/i40e/i40e_ethdev.h > @@ -194,6 +194,9 @@ enum i40e_flxpld_layer_idx { #define > I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK \ > I40E_MASK(0xFFFF, I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT) >=20 > +#define I40E_RSS_TYPE_NONE 0ULL > +#define I40E_RSS_TYPE_INVALID 1ULL > + > #define I40E_INSET_NONE 0x00000000000000000ULL >=20 > /* bit0 ~ bit 7 */ > @@ -749,6 +752,11 @@ struct i40e_queue_regions { > struct i40e_queue_region_info region[I40E_REGION_MAX_INDEX + > 1]; }; >=20 > +struct i40e_rss_pattern_info { > + uint8_t action_flag; > + uint64_t types; > +}; > + > /* Tunnel filter number HW supports */ > #define I40E_MAX_TUNNEL_FILTER_NUM 400 >=20 > @@ -968,6 +976,15 @@ struct i40e_rte_flow_rss_conf { > I40E_VFQF_HKEY_MAX_INDEX : > I40E_PFQF_HKEY_MAX_INDEX + 1) * > sizeof(uint32_t)]; /* Hash key. */ > uint16_t queue[I40E_MAX_Q_PER_TC]; /**< Queues indices to use. > */ > + bool valid; /* Check if it's valid */ > +}; > + > +TAILQ_HEAD(i40e_rss_conf_list, i40e_rss_filter); > + > +/* RSS filter list structure */ > +struct i40e_rss_filter { > + TAILQ_ENTRY(i40e_rss_filter) next; > + struct i40e_rte_flow_rss_conf rss_filter_info; > }; >=20 > struct i40e_vf_msg_cfg { > @@ -1038,7 +1055,8 @@ struct i40e_pf { > struct i40e_fdir_info fdir; /* flow director info */ > struct i40e_ethertype_rule ethertype; /* Ethertype filter rule */ > struct i40e_tunnel_rule tunnel; /* Tunnel filter rule */ > - struct i40e_rte_flow_rss_conf rss_info; /* rss info */ > + struct i40e_rte_flow_rss_conf rss_info; /* RSS info */ > + struct i40e_rss_conf_list rss_config_list; /* RSS rule list */ > struct i40e_queue_regions queue_region; /* queue region info */ > struct i40e_fc_conf fc_conf; /* Flow control conf */ > struct i40e_mirror_rule_list mirror_list; @@ -1338,8 +1356,6 @@ int > i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len); i= nt > i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size); = int > i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out, > const struct rte_flow_action_rss *in); -int > i40e_action_rss_same(const struct rte_flow_action_rss *comp, > - const struct rte_flow_action_rss *with); > int i40e_config_rss_filter(struct i40e_pf *pf, > struct i40e_rte_flow_rss_conf *conf, bool add); int > i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params); > diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c > index d877ac250..f4f3c3abd 100644 > --- a/drivers/net/i40e/i40e_flow.c > +++ b/drivers/net/i40e/i40e_flow.c > @@ -4424,29 +4424,80 @@ i40e_flow_parse_qinq_filter(struct rte_eth_dev > *dev, > * function for RSS, or flowtype for queue region configuration. > * For example: > * pattern: > - * Case 1: only ETH, indicate flowtype for queue region will be parsed. > - * Case 2: only VLAN, indicate user_priority for queue region will be pa= rsed. > - * Case 3: none, indicate RSS related will be parsed in action. > - * Any pattern other the ETH or VLAN will be treated as invalid except E= ND. > + * Case 1: try to transform patterns to pctype. valid pctype will be > + * used in parse action. > + * Case 2: only ETH, indicate flowtype for queue region will be parsed. > + * Case 3: only VLAN, indicate user_priority for queue region will be pa= rsed. > * So, pattern choice is depened on the purpose of configuration of > * that flow. > * action: > - * action RSS will be uaed to transmit valid parameter with > + * action RSS will be used to transmit valid parameter with > * struct rte_flow_action_rss for all the 3 case. > */ > static int > i40e_flow_parse_rss_pattern(__rte_unused struct rte_eth_dev *dev, > const struct rte_flow_item *pattern, > struct rte_flow_error *error, > - uint8_t *action_flag, > + struct i40e_rss_pattern_info *p_info, > struct i40e_queue_regions *info) { > const struct rte_flow_item_vlan *vlan_spec, *vlan_mask; > const struct rte_flow_item *item =3D pattern; > enum rte_flow_item_type item_type; > - > - if (item->type =3D=3D RTE_FLOW_ITEM_TYPE_END) > + struct rte_flow_item *items; > + uint32_t item_num =3D 0; /* non-void item number of pattern*/ > + uint32_t i =3D 0; > + static const struct { > + enum rte_flow_item_type *item_array; > + uint64_t type; > + } i40e_rss_pctype_patterns[] =3D { > + { pattern_fdir_ipv4, > + ETH_RSS_FRAG_IPV4 | > ETH_RSS_NONFRAG_IPV4_OTHER }, > + { pattern_fdir_ipv4_tcp, ETH_RSS_NONFRAG_IPV4_TCP }, > + { pattern_fdir_ipv4_udp, ETH_RSS_NONFRAG_IPV4_UDP }, > + { pattern_fdir_ipv4_sctp, ETH_RSS_NONFRAG_IPV4_SCTP }, > + { pattern_fdir_ipv6, > + ETH_RSS_FRAG_IPV6 | > ETH_RSS_NONFRAG_IPV6_OTHER }, > + { pattern_fdir_ipv6_tcp, ETH_RSS_NONFRAG_IPV6_TCP }, > + { pattern_fdir_ipv6_udp, ETH_RSS_NONFRAG_IPV6_UDP }, > + { pattern_fdir_ipv6_sctp, ETH_RSS_NONFRAG_IPV6_SCTP }, > + }; > + > + p_info->types =3D I40E_RSS_TYPE_INVALID; > + > + if (item->type =3D=3D RTE_FLOW_ITEM_TYPE_END) { > + p_info->types =3D I40E_RSS_TYPE_NONE; > return 0; > + } > + > + /* convert flow to pctype */ > + while ((pattern + i)->type !=3D RTE_FLOW_ITEM_TYPE_END) { > + if ((pattern + i)->type !=3D RTE_FLOW_ITEM_TYPE_VOID) > + item_num++; > + i++; > + } > + item_num++; > + > + items =3D rte_zmalloc("i40e_pattern", > + item_num * sizeof(struct rte_flow_item), 0); > + if (!items) { > + rte_flow_error_set(error, ENOMEM, > RTE_FLOW_ERROR_TYPE_ITEM_NUM, > + NULL, "No memory for PMD internal > items."); > + return -ENOMEM; > + } > + > + i40e_pattern_skip_void_item(items, pattern); > + > + for (i =3D 0; i < RTE_DIM(i40e_rss_pctype_patterns); i++) { > + if > (i40e_match_pattern(i40e_rss_pctype_patterns[i].item_array, > + items)) { > + p_info->types =3D i40e_rss_pctype_patterns[i].type; > + rte_free(items); > + return 0; > + } > + } > + > + rte_free(items); >=20 > for (; item->type !=3D RTE_FLOW_ITEM_TYPE_END; item++) { > if (item->last) { > @@ -4459,7 +4510,7 @@ i40e_flow_parse_rss_pattern(__rte_unused struct > rte_eth_dev *dev, > item_type =3D item->type; > switch (item_type) { > case RTE_FLOW_ITEM_TYPE_ETH: > - *action_flag =3D 1; > + p_info->action_flag =3D 1; > break; > case RTE_FLOW_ITEM_TYPE_VLAN: > vlan_spec =3D item->spec; > @@ -4472,7 +4523,7 @@ i40e_flow_parse_rss_pattern(__rte_unused struct > rte_eth_dev *dev, > vlan_spec->tci) >> 13) & 0x7; > info->region[0].user_priority_num =3D > 1; > info->queue_region_number =3D 1; > - *action_flag =3D 0; > + p_info->action_flag =3D 0; > } > } > break; > @@ -4500,12 +4551,14 @@ i40e_flow_parse_rss_pattern(__rte_unused > struct rte_eth_dev *dev, > * max index should be 7, and so on. And also, queue index should be > * continuous sequence and queue region index should be part of rss > * queue index for this port. > + * For hash params, the pctype in action and pattern must be same. > + * Set queue index must be with non-types. > */ > static int > i40e_flow_parse_rss_action(struct rte_eth_dev *dev, > const struct rte_flow_action *actions, > struct rte_flow_error *error, > - uint8_t action_flag, > + struct i40e_rss_pattern_info p_info, > struct i40e_queue_regions *conf_info, > union i40e_filter_t *filter) > { > @@ -4516,7 +4569,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev > *dev, > struct i40e_rte_flow_rss_conf *rss_config =3D > &filter->rss_conf; > struct i40e_rte_flow_rss_conf *rss_info =3D &pf->rss_info; > - uint16_t i, j, n, tmp; > + uint16_t i, j, n, tmp, nb_types; > uint32_t index =3D 0; > uint64_t hf_bit =3D 1; >=20 > @@ -4535,7 +4588,7 @@ i40e_flow_parse_rss_action(struct rte_eth_dev > *dev, > return -rte_errno; > } >=20 > - if (action_flag) { > + if (p_info.action_flag) { > for (n =3D 0; n < 64; n++) { > if (rss->types & (hf_bit << n)) { > conf_info->region[0].hw_flowtype[0] =3D n; > @@ -4674,11 +4727,11 @@ i40e_flow_parse_rss_action(struct rte_eth_dev > *dev, > if (rss_config->queue_region_conf) > return 0; >=20 > - if (!rss || !rss->queue_num) { > + if (!rss) { > rte_flow_error_set(error, EINVAL, > RTE_FLOW_ERROR_TYPE_ACTION, > act, > - "no valid queues"); > + "invalid rule"); > return -rte_errno; > } >=20 > @@ -4692,19 +4745,48 @@ i40e_flow_parse_rss_action(struct rte_eth_dev > *dev, > } > } >=20 > - if (rss_info->conf.queue_num) { > - rte_flow_error_set(error, EINVAL, > - RTE_FLOW_ERROR_TYPE_ACTION, > - act, > - "rss only allow one valid rule"); > - return -rte_errno; > + if (rss->queue_num && (p_info.types || rss->types)) > + return rte_flow_error_set > + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, > act, > + "rss types must be empty while configuring queue > region"); > + > + /* validate pattern and pctype */ > + if (!(rss->types & p_info.types) && > + (rss->types || p_info.types) && !rss->queue_num) > + return rte_flow_error_set > + (error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, > + act, "invaild pctype"); > + > + nb_types =3D 0; > + for (n =3D 0; n < RTE_ETH_FLOW_MAX; n++) { > + if (rss->types & (hf_bit << n)) > + nb_types++; > + if (nb_types > 1) > + return rte_flow_error_set > + (error, ENOTSUP, > RTE_FLOW_ERROR_TYPE_ACTION, > + act, "multi pctype is not supported"); > } >=20 > + if (rss->func =3D=3D RTE_ETH_HASH_FUNCTION_SIMPLE_XOR && > + (p_info.types || rss->types || rss->queue_num)) > + return rte_flow_error_set > + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, > act, > + "pattern, type and queues must be empty while" > + " setting hash function as simple_xor"); > + > + if (rss->func =3D=3D RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ > && > + !(p_info.types && rss->types)) > + return rte_flow_error_set > + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, > act, > + "pctype and queues can not be empty while" > + " setting hash function as symmetric toeplitz"); > + > /* Parse RSS related parameters from configuration */ > - if (rss->func !=3D RTE_ETH_HASH_FUNCTION_DEFAULT) > + if (rss->func >=3D RTE_ETH_HASH_FUNCTION_MAX || > + rss->func =3D=3D RTE_ETH_HASH_FUNCTION_TOEPLITZ) > return rte_flow_error_set > (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, > act, > - "non-default RSS hash functions are not > supported"); > + "RSS hash functions are not supported"); > if (rss->level) > return rte_flow_error_set > (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, > act, @@ -4746,19 +4828,20 @@ i40e_parse_rss_filter(struct rte_eth_dev > *dev, > union i40e_filter_t *filter, > struct rte_flow_error *error) > { > - int ret; > + struct i40e_rss_pattern_info p_info; > struct i40e_queue_regions info; > - uint8_t action_flag =3D 0; > + int ret; >=20 > memset(&info, 0, sizeof(struct i40e_queue_regions)); > + memset(&p_info, 0, sizeof(struct i40e_rss_pattern_info)); >=20 > ret =3D i40e_flow_parse_rss_pattern(dev, pattern, > - error, &action_flag, &info); > + error, &p_info, &info); > if (ret) > return ret; >=20 > ret =3D i40e_flow_parse_rss_action(dev, actions, error, > - action_flag, &info, filter); > + p_info, &info, filter); > if (ret) > return ret; >=20 > @@ -4777,15 +4860,33 @@ i40e_config_rss_filter_set(struct rte_eth_dev > *dev, { > struct i40e_pf *pf =3D I40E_DEV_PRIVATE_TO_PF(dev->data- > >dev_private); > struct i40e_hw *hw =3D I40E_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > + struct i40e_rss_filter *rss_filter; > int ret; >=20 > if (conf->queue_region_conf) { > ret =3D i40e_flush_queue_region_all_conf(dev, hw, pf, 1); > - conf->queue_region_conf =3D 0; > } else { > ret =3D i40e_config_rss_filter(pf, conf, 1); > } > - return ret; > + > + if (ret) > + return ret; > + > + rss_filter =3D rte_zmalloc("i40e_rss_filter", > + sizeof(*rss_filter), 0); > + if (rss_filter =3D=3D NULL) { > + PMD_DRV_LOG(ERR, "Failed to alloc memory."); > + return -ENOMEM; > + } > + rss_filter->rss_filter_info =3D *conf; > + /* the rule new created is always valid > + * the existing rule covered by new rule will be set invalid > + */ > + rss_filter->rss_filter_info.valid =3D true; > + > + TAILQ_INSERT_TAIL(&pf->rss_config_list, rss_filter, next); > + > + return 0; > } >=20 > static int > @@ -4794,10 +4895,21 @@ i40e_config_rss_filter_del(struct rte_eth_dev > *dev, { > struct i40e_pf *pf =3D I40E_DEV_PRIVATE_TO_PF(dev->data- > >dev_private); > struct i40e_hw *hw =3D I40E_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > + struct i40e_rss_filter *rss_filter; > + void *temp; >=20 > - i40e_flush_queue_region_all_conf(dev, hw, pf, 0); > + if (conf->queue_region_conf) > + i40e_flush_queue_region_all_conf(dev, hw, pf, 0); > + else > + i40e_config_rss_filter(pf, conf, 0); >=20 > - i40e_config_rss_filter(pf, conf, 0); > + TAILQ_FOREACH_SAFE(rss_filter, &pf->rss_config_list, next, temp) { > + if (!memcmp(&rss_filter->rss_filter_info, conf, > + sizeof(struct rte_flow_action_rss))) { > + TAILQ_REMOVE(&pf->rss_config_list, rss_filter, > next); > + rte_free(rss_filter); > + } > + } > return 0; > } >=20 > @@ -4940,7 +5052,8 @@ i40e_flow_create(struct rte_eth_dev *dev, > &cons_filter.rss_conf); > if (ret) > goto free_flow; > - flow->rule =3D &pf->rss_info; > + flow->rule =3D TAILQ_LAST(&pf->rss_config_list, > + i40e_rss_conf_list); > break; > default: > goto free_flow; > @@ -4990,7 +5103,7 @@ i40e_flow_destroy(struct rte_eth_dev *dev, > break; > case RTE_ETH_FILTER_HASH: > ret =3D i40e_config_rss_filter_del(dev, > - (struct i40e_rte_flow_rss_conf *)flow->rule); > + &((struct i40e_rss_filter *)flow->rule)- > >rss_filter_info); > break; > default: > PMD_DRV_LOG(WARNING, "Filter type (%d) not > supported", @@ -5248,13 +5361,27 @@ static int > i40e_flow_flush_rss_filter(struct rte_eth_dev *dev) { > struct i40e_pf *pf =3D I40E_DEV_PRIVATE_TO_PF(dev->data- > >dev_private); > - struct i40e_rte_flow_rss_conf *rss_info =3D &pf->rss_info; > struct i40e_hw *hw =3D I40E_DEV_PRIVATE_TO_HW(dev->data- > >dev_private); > + struct rte_flow *flow; > + void *temp; > int32_t ret =3D -EINVAL; >=20 > ret =3D i40e_flush_queue_region_all_conf(dev, hw, pf, 0); >=20 > - if (rss_info->conf.queue_num) > - ret =3D i40e_config_rss_filter(pf, rss_info, FALSE); > + /* Delete rss flows in flow list. */ > + TAILQ_FOREACH_SAFE(flow, &pf->flow_list, node, temp) { > + if (flow->filter_type !=3D RTE_ETH_FILTER_HASH) > + continue; > + > + if (flow->rule) { > + ret =3D i40e_config_rss_filter_del(dev, > + &((struct i40e_rss_filter *)flow->rule)- > >rss_filter_info); > + if (ret) > + return ret; > + } > + TAILQ_REMOVE(&pf->flow_list, flow, node); > + rte_free(flow); > + } > + > return ret; > } > -- > 2.17.1 Regards, Bernard.