From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1C8D8423C3; Fri, 13 Jan 2023 14:32:30 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B493F42D53; Fri, 13 Jan 2023 14:32:29 +0100 (CET) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mails.dpdk.org (Postfix) with ESMTP id 054A840E03 for ; Fri, 13 Jan 2023 14:32:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1673616748; x=1705152748; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=+yzAQP5r/Ir2i6rCRQiUszevviaUQ+JRd0bBZAO3xLs=; b=mAot5zyZivm9EfWRBQ8j8eChcxhGig1EYxpcHve4zYXMNUVC43OXjy3T HXyfrd9nkQ2nHbM7vEFLrkW8UT65HlF4yNSwOmNE0ynCqcJ/dK+FxZeFl RueE6kZo921xInaGXsD5jHYx+l1/ZBk6gEt6diefAggQLNFCkEA5w4Iic iFbFHPZFTHgFQQCxyJQArhbCaHRIGtKR3nB/pt2KYasWGqLH32tSgkIZn gnjPw7OS78DbvbPbMMlS0db36y4j3GyLy5D/oVzdVza2s3ddSqAxVUFmi MB+SKhYYjWbalXA8yh1jEqksnpwRJ7ZpyI96oaUsGwgM7KLiGBv7FrBYf Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10588"; a="322691634" X-IronPort-AV: E=Sophos;i="5.97,214,1669104000"; d="scan'208";a="322691634" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jan 2023 05:32:26 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10588"; a="608173093" X-IronPort-AV: E=Sophos;i="5.97,214,1669104000"; d="scan'208";a="608173093" Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by orsmga003.jf.intel.com with ESMTP; 13 Jan 2023 05:32:26 -0800 Received: from orsmsx601.amr.corp.intel.com (10.22.229.14) by ORSMSX603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Fri, 13 Jan 2023 05:32:25 -0800 Received: from ORSEDG601.ED.cps.intel.com (10.7.248.6) by orsmsx601.amr.corp.intel.com (10.22.229.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16 via Frontend Transport; Fri, 13 Jan 2023 05:32:25 -0800 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (104.47.59.170) by edgegateway.intel.com (134.134.137.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.16; Fri, 13 Jan 2023 05:32:24 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=DqCAQ37gb0eB3LcJ6SeMDLO3bHY/D4QAIK+vWVdpIXFevlzcuD7ZpcR+kDdNsV2uE2Xen16gukfC5pm8n28XEYNu8agpuSaBG6laoOr55znvbCITjdweCgO8C2ldO5Ez3fCipcmHej5DIHTT86St1ZwwXIZrZTuXhiNaj8nAcwz83uFsqIqzGBrIR77QX0/aD/r4LKT62M7ZdGjfpMyDWA4E1IHCxFxu2vo0FRnUnwyLnuQ7bXC1zunXxGU7R8S7s37ml2YZdWPRvqaYg95jRhKPfqfZxa559hcW47hRzOm5pU2E+AccDO0xtDSCN4HFwLoaNa0gmsg38WUGsjFxdw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ywnmrT1dWPoloqcL3fgcQh4GsWaVz08+krzgqTnGlXA=; b=FvaR4zzcCvPIRJtY2CaUYw2BeB34l1ljeL8TFKN+t0UxPaRRZOjqYnh1pHWgpZn6UxrIu4QSwPSwHwUD/nVlB/TSH7A/LgjmuWVbyecNDNvgBD3uyIQgQMZ8ztB3FXxXqhjWWGNz39eP3fJMPG8RreVRXlP+OwB2TRLKXOft41wB/T/A6y4mJnEZUX+MIdd3FY2aqyIvP/KGpMHQTnBm4NeWq2Pw06dQr6BUfdPB+QnjfqnGVfkm/ePfk1ow2yLcjnNFZSxKOvfBNnSGkngmcwoHwHYgectUiZ1W2rKzZVgrDs87XwPlpuxSQqgMwmolRjvPGu86n3MScXqPNvhvGA== 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 Received: from MN0PR11MB6087.namprd11.prod.outlook.com (2603:10b6:208:3cd::6) by MN0PR11MB6136.namprd11.prod.outlook.com (2603:10b6:208:3c8::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6002.13; Fri, 13 Jan 2023 13:32:22 +0000 Received: from MN0PR11MB6087.namprd11.prod.outlook.com ([fe80::11c8:bbb0:7d9e:775d]) by MN0PR11MB6087.namprd11.prod.outlook.com ([fe80::11c8:bbb0:7d9e:775d%7]) with mapi id 15.20.5986.018; Fri, 13 Jan 2023 13:32:22 +0000 From: "Zhang, Helin" To: "Liu, Mingxia" , "dev@dpdk.org" , "Zhang, Qi Z" , "Wu, Jingjing" , "Xing, Beilei" CC: "Wu, Wenjun1" , "Liu, Mingxia" Subject: RE: [PATCH v2 01/21] net/cpfl: support device initialization Thread-Topic: [PATCH v2 01/21] net/cpfl: support device initialization Thread-Index: AQHZJy+W47BCsFPeZka4aweExwykIa6cTSFw Date: Fri, 13 Jan 2023 13:32:21 +0000 Message-ID: References: <20221223015558.3143279-1-mingxia.liu@intel.com> <20230113081931.221576-1-mingxia.liu@intel.com> <20230113081931.221576-2-mingxia.liu@intel.com> In-Reply-To: <20230113081931.221576-2-mingxia.liu@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MN0PR11MB6087:EE_|MN0PR11MB6136:EE_ x-ms-office365-filtering-correlation-id: c2a1063c-46b3-4c3c-d3af-08daf56a99a9 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: e00FieFg4DNSX/ySA1DSLdJ+qfSDsAaBF7UEAn8/Fj01m0rV1CDoLTmrNB/uhtCpMoTcGXL5l2x862b+YGvYkgvqy8dgqLNBvtxx5SASSR6O7lrqTLXP2He2zSz8LDyDwlDz5bVYHuVtO5TuQQTYkCaozi0ICmXBiUOIQjgBu8aEep+UbghGIO3p0vZZakKtUQ1pMNd9Ao2kDs/3CA8FNOuiEEZPTZMZS2J3ReyRhKuRXPP3xoCypv17xuxLY79azJ/OucbkKPzeKZ8ClSR84arkAVjznqFrTpnfQk5nIJ9PkrP5Us5ERsaSnn9MuCFdzhdEUmzWxVPWlFNIq4TcidNsHcnecpeuLKVAQxvsTdF/9eZOV7v/Tw6/xFHH27tNHCqzQUHTDSWGdWrBkxF9bcvHwTd7BrFTq++53WWyJNtkjosvDp4AmZaWCftIP0dxrA54+JXXuNrsZjT9ub1PU12TADWkCQSA8ijHlKfenqVertWItc/lnW/2NsaLCgOGvlQbORXgj0fJWpwDElB+Crl7J33hwchDrD4vDaie6jDe0bSkOBXbltnEgYHcTAWA0rupMcWiptPxmgWNl5q0VKmZm1vmdIj6fUtadkKE2q3MKWNfVb8SfBr3VZDt77Ur7d1FD6783+76wQW9oqQfPqbcCbj/y2qzAr9Hk6VWkega+aeboh3aFifQX81B1jtG1jVIskcds524ECCq1AuGIw== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:MN0PR11MB6087.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230022)(346002)(136003)(396003)(366004)(39860400002)(376002)(451199015)(110136005)(86362001)(54906003)(107886003)(478600001)(6636002)(316002)(55016003)(33656002)(38070700005)(53546011)(38100700002)(122000001)(82960400001)(83380400001)(26005)(9686003)(186003)(6506007)(66446008)(2906002)(5660300002)(30864003)(66556008)(8676002)(66476007)(7696005)(71200400001)(41300700001)(64756008)(4326008)(76116006)(8936002)(66946007)(52536014)(559001)(579004); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?Pfd7dlAJYbOayGlezFHiL3m1B7gPlDOX/FUrZgk1EXY8uJchr+D230/7PzgK?= =?us-ascii?Q?jhzAQuVwSxfF3YX2hWgBQaHeGvET4f2FUwgWNUeWvy5pghL8j09Tix1cDTa6?= =?us-ascii?Q?6uuuRbLTcvd5nXUDawJC1h043qJn0jKc3JT2Q0s8T1fv+dAm2MHpwvIuOPxp?= =?us-ascii?Q?6A0ja5tm8RS+dSEcpZGVaiiQFbYRwPrkdSChhLmqlKn88IRRZpCfNXclF7Y9?= =?us-ascii?Q?x95LuS0vIZu2GkeEPD4+233OCKKNa3rbAa+TG5Csl0Pg06y1+eWRctVe9U2B?= =?us-ascii?Q?amGKeZtpDpPEbAn+SS2v9w+QwET8VQbtaM4jVglhxiJA71p+ZmDgJnto2hn+?= =?us-ascii?Q?WwEyyLUnbXrQGpMNiA4AJkQiXZvfkwfimK3e8yZiGMNlwgcQARAA77y0yj5O?= =?us-ascii?Q?zd6uhqbdPJsmRWEgM9VPDzTB+WH2J8VTZwB4VTbvJFW7YoLwDmJ0+ANVHKuI?= =?us-ascii?Q?mJSXtZMOwWwamNjinmtVkSGZATFXCetIjE5Tmf1v10vBA23UFsrJp3q8vgXw?= =?us-ascii?Q?VTZAMdyoa5B8vmOMEcLH5/OvrxwZoB0a8SII4UM9EJio6cGHS0+MpPcA8FCA?= =?us-ascii?Q?ktoSQh72eWWtkBGWHXkSD+4IY+OlBHYBtPktQ8MKQ6d1gPBrYDPmx+Y4M0fp?= =?us-ascii?Q?mCmcuUu6evLV0b/cl38jhhMwMGVCkiTRW6NJDJEdZ6Jb9D6VJluhVP2QxDIF?= =?us-ascii?Q?gz6eqAggRhKJqbqQ0fWrdGAvg2MPq/xprPV88+3XmP1CRrOHHFWcmaIIZHdx?= =?us-ascii?Q?HKhLdSBBDbCh2A/Nm1oc8zT7KzOA6b0N28kA0fwz90d8UHMgakt9M5htSFqp?= =?us-ascii?Q?AIeK494GyTvNhTHKzHP3bvXv5oiukpR4ZZ5FM0SKoRb05rQWMcJEWVr67N9I?= =?us-ascii?Q?KZcoNP4PcWmbO+ZSFRYL2cg1WI9bMgpP2xDZZtmfGSlpQ1Yoq2G4Setv+xkF?= =?us-ascii?Q?lF6T0OcHdnxL2nUeu0J823h8qEzVYheaMgaz/riLluz9o1vSs1lRmWAc3QhX?= =?us-ascii?Q?XF0tOT6oYP8WmfQS2ze5wP7DKXNqun2fan3sKtF8rSw+ctKuzpStXjb2YwKX?= =?us-ascii?Q?UZPsjqzcbnMfmGVA3vB3xdjEZkkvhgw2MZU+A88ZF8xZ5CEJ3Jip3e7sRbOq?= =?us-ascii?Q?ob+DhZPsFyp9n1TEkbSnvkvAOl9d6QVytjBtE4qGEjlmVSH+RDtm0OYD1pKZ?= =?us-ascii?Q?AQhyQGT11TXsUAhn4IRpFkNVWklTvMFwUGhQTPjg+E6nCmLq7MOUzQuPh6sk?= =?us-ascii?Q?tfoRrtWyYQ1piJA7OeIcgIQUWAOJJgO2+3DYgZcAoH7l7QetWIEXCNSNR0b0?= =?us-ascii?Q?ozO/2ct7BTILvUSsvGu3QMWLoma1t62VUWVH2P9v2/9g5Fr0rDVAGc5PYpnL?= =?us-ascii?Q?AwCWuj7a3HSskFHOz+OBXDKt+oz9K9dLVwHK7zBlJ0ITDQpECekkRIHUd33s?= =?us-ascii?Q?De8yGVaQ0AH0F4/fNjiA3gb4wpO1qXUoaLECUKmSG0iqvzzLQbiiMy1Wrooy?= =?us-ascii?Q?ZYGXrA5uSAx1uoDaNtO/nM2DcUtqDZBCPfItHwL22AYjbXaARx1aOnYnXihW?= =?us-ascii?Q?6tNMEU6OhHPgsDPn1n2Oy/KL/AKtEb+DBv6nOBvl?= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN0PR11MB6087.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: c2a1063c-46b3-4c3c-d3af-08daf56a99a9 X-MS-Exchange-CrossTenant-originalarrivaltime: 13 Jan 2023 13:32:21.9572 (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: Dc5WUdk7Iry0sil4IidUutPM8JKPN1F+xmjD9vjZTkeAy5m0S0/mUdBLY+Pv103PpIkFC+ybOQ7xsO5mWZ8Rmw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN0PR11MB6136 X-OriginatorOrg: intel.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org > -----Original Message----- > From: Mingxia Liu > Sent: Friday, January 13, 2023 4:19 PM > To: dev@dpdk.org; Zhang, Qi Z ; Wu, Jingjing > ; Xing, Beilei > Cc: Wu, Wenjun1 ; Liu, Mingxia > > Subject: [PATCH v2 01/21] net/cpfl: support device initialization >=20 > Support device init and add the following dev ops: > - dev_configure > - dev_close > - dev_infos_get > - link_update > - cpfl_dev_supported_ptypes_get >=20 > Signed-off-by: Mingxia Liu > --- > MAINTAINERS | 9 + > doc/guides/nics/cpfl.rst | 66 +++ > doc/guides/nics/features/cpfl.ini | 12 + > doc/guides/rel_notes/release_23_03.rst | 5 + > drivers/net/cpfl/cpfl_ethdev.c | 769 +++++++++++++++++++++++++ > drivers/net/cpfl/cpfl_ethdev.h | 78 +++ > drivers/net/cpfl/cpfl_logs.h | 32 + > drivers/net/cpfl/cpfl_rxtx.c | 244 ++++++++ > drivers/net/cpfl/cpfl_rxtx.h | 25 + > drivers/net/cpfl/meson.build | 14 + > drivers/net/meson.build | 1 + > 11 files changed, 1255 insertions(+) > create mode 100644 doc/guides/nics/cpfl.rst create mode 100644 > doc/guides/nics/features/cpfl.ini create mode 100644 > drivers/net/cpfl/cpfl_ethdev.c create mode 100644 > drivers/net/cpfl/cpfl_ethdev.h create mode 100644 > drivers/net/cpfl/cpfl_logs.h create mode 100644 drivers/net/cpfl/cpfl_rx= tx.c > create mode 100644 drivers/net/cpfl/cpfl_rxtx.h create mode 100644 > drivers/net/cpfl/meson.build >=20 > diff --git a/MAINTAINERS b/MAINTAINERS > index 22ef2ea4b9..970acc5751 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -780,6 +780,15 @@ F: drivers/common/idpf/ > F: doc/guides/nics/idpf.rst > F: doc/guides/nics/features/idpf.ini >=20 > +Intel cpfl > +M: Qi Zhang > +M: Jingjing Wu > +M: Beilei Xing > +T: git://dpdk.org/next/dpdk-next-net-intel > +F: drivers/net/cpfl/ > +F: doc/guides/nics/cpfl.rst > +F: doc/guides/nics/features/cpfl.ini > + > Intel igc > M: Junfeng Guo > M: Simei Su > diff --git a/doc/guides/nics/cpfl.rst b/doc/guides/nics/cpfl.rst new file= mode > 100644 index 0000000000..064c69ba7d > --- /dev/null > +++ b/doc/guides/nics/cpfl.rst > @@ -0,0 +1,66 @@ > +.. SPDX-License-Identifier: BSD-3-Clause > + Copyright(c) 2022 Intel Corporation. > + > +.. include:: > + > +CPFL Poll Mode Driver > +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > + > +The [*EXPERIMENTAL*] cpfl PMD (**librte_net_cpfl**) provides poll mode > +driver support for Intel\ |reg| Infrastructure Processing Unit (Intel\ |= reg| > IPU) E2100. > + > + > +Linux Prerequisites > +------------------- > + > +Follow the DPDK :doc:`../linux_gsg/index` to setup the basic DPDK > environment. > + > +To get better performance on Intel platforms, please follow the > +:doc:`../linux_gsg/nic_perf_intel_platform`. > + > + > +Pre-Installation Configuration > +------------------------------ > + > +Runtime Config Options > +~~~~~~~~~~~~~~~~~~~~~~ > + > +- ``vport`` (default ``0``) > + > + The PMD supports creation of multiple vports for one PCI device, > + each vport corresponds to a single ethdev. > + The user can specify the vports with specific ID to be created, for ex= ample:: > + > + -a ca:00.0,vport=3D[0,2,3] > + > + Then the PMD will create 3 vports (ethdevs) for device ``ca:00.0``. > + > + If the parameter is not provided, the vport 0 will be created by defau= lt. > + > +- ``rx_single`` (default ``0``) > + > + There are two queue modes supported by Intel\ |reg| IPU Ethernet > + ES2000 Series, single queue mode and split queue mode for Rx queue. What is the relationship with IPU E2100? Is IPU ethernet ES2000 a new produ= ct? Thanks, Helin > + User can choose Rx queue mode, example:: > + > + -a ca:00.0,rx_single=3D1 > + > + Then the PMD will configure Rx queue with single queue mode. > + Otherwise, split queue mode is chosen by default. > + > +- ``tx_single`` (default ``0``) > + > + There are two queue modes supported by Intel\ |reg| IPU Ethernet > + ES2000 Series, single queue mode and split queue mode for Tx queue. > + User can choose Tx queue mode, example:: > + > + -a ca:00.0,tx_single=3D1 > + > + Then the PMD will configure Tx queue with single queue mode. > + Otherwise, split queue mode is chosen by default. > + > + > +Driver compilation and testing > +------------------------------ > + > +Refer to the document :doc:`build_and_test` for details. > \ No newline at end of file > diff --git a/doc/guides/nics/features/cpfl.ini > b/doc/guides/nics/features/cpfl.ini > new file mode 100644 > index 0000000000..a2d1ca9e15 > --- /dev/null > +++ b/doc/guides/nics/features/cpfl.ini > @@ -0,0 +1,12 @@ > +; > +; Supported features of the 'cpfl' network poll mode driver. > +; > +; Refer to default.ini for the full list of available PMD features. > +; > +; A feature with "P" indicates only be supported when non-vector path ; > +is selected. > +; > +[Features] > +Linux =3D Y > +x86-32 =3D Y > +x86-64 =3D Y > diff --git a/doc/guides/rel_notes/release_23_03.rst > b/doc/guides/rel_notes/release_23_03.rst > index b8c5b68d6c..465a25e91e 100644 > --- a/doc/guides/rel_notes/release_23_03.rst > +++ b/doc/guides/rel_notes/release_23_03.rst > @@ -55,6 +55,11 @@ New Features > Also, make sure to start the actual text at the margin. > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D >=20 > +* **Added Intel cpfl driver.** > + > + Added the new ``cpfl`` net driver > + for Intel\ |reg| Infrastructure Processing Unit (Intel\ |reg| IPU) E21= 00. > + See the :doc:`../nics/cpfl` NIC guide for more details on this new dri= ver. >=20 > Removed Items > ------------- > diff --git a/drivers/net/cpfl/cpfl_ethdev.c b/drivers/net/cpfl/cpfl_ethde= v.c > new file mode 100644 index 0000000000..2d79ba2098 > --- /dev/null > +++ b/drivers/net/cpfl/cpfl_ethdev.c > @@ -0,0 +1,769 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "cpfl_ethdev.h" > + > +#define CPFL_TX_SINGLE_Q "tx_single" > +#define CPFL_RX_SINGLE_Q "rx_single" > +#define CPFL_VPORT "vport" > + > +rte_spinlock_t cpfl_adapter_lock; > +/* A list for all adapters, one adapter matches one PCI device */ > +struct cpfl_adapter_list cpfl_adapter_list; bool > +cpfl_adapter_list_init; > + > +static const char * const cpfl_valid_args[] =3D { > + CPFL_TX_SINGLE_Q, > + CPFL_RX_SINGLE_Q, > + CPFL_VPORT, > + NULL > +}; > + > +static int > +cpfl_dev_link_update(struct rte_eth_dev *dev, > + __rte_unused int wait_to_complete) { > + struct idpf_vport *vport =3D dev->data->dev_private; > + struct rte_eth_link new_link; > + > + memset(&new_link, 0, sizeof(new_link)); > + > + switch (vport->link_speed) { > + case 10: Is it better to replace '10' with a meaningful macro? Same comments to below 20 lines of code. Thanks, Helin > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_10M; > + break; > + case 100: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_100M; > + break; > + case 1000: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_1G; > + break; > + case 10000: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_10G; > + break; > + case 20000: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_20G; > + break; > + case 25000: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_25G; > + break; > + case 40000: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_40G; > + break; > + case 50000: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_50G; > + break; > + case 100000: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_100G; > + break; > + case 200000: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_200G; > + break; > + default: > + new_link.link_speed =3D RTE_ETH_SPEED_NUM_NONE; > + } > + > + new_link.link_duplex =3D RTE_ETH_LINK_FULL_DUPLEX; > + new_link.link_status =3D vport->link_up ? RTE_ETH_LINK_UP : > + RTE_ETH_LINK_DOWN; > + new_link.link_autoneg =3D !(dev->data->dev_conf.link_speeds & > + RTE_ETH_LINK_SPEED_FIXED); > + > + return rte_eth_linkstatus_set(dev, &new_link); } > + > +static int > +cpfl_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info > +*dev_info) { > + struct idpf_vport *vport =3D dev->data->dev_private; > + struct idpf_adapter *adapter =3D vport->adapter; > + > + dev_info->max_rx_queues =3D adapter->caps.max_rx_q; > + dev_info->max_tx_queues =3D adapter->caps.max_tx_q; > + dev_info->min_rx_bufsize =3D CPFL_MIN_BUF_SIZE; > + dev_info->max_rx_pktlen =3D vport->max_mtu + > CPFL_ETH_OVERHEAD; > + > + dev_info->max_mtu =3D vport->max_mtu; > + dev_info->min_mtu =3D RTE_ETHER_MIN_MTU; > + > + return 0; > +} > + > +static const uint32_t * > +cpfl_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused) { > + static const uint32_t ptypes[] =3D { > + RTE_PTYPE_L2_ETHER, > + RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, > + RTE_PTYPE_L3_IPV6_EXT_UNKNOWN, > + RTE_PTYPE_L4_FRAG, > + RTE_PTYPE_L4_UDP, > + RTE_PTYPE_L4_TCP, > + RTE_PTYPE_L4_SCTP, > + RTE_PTYPE_L4_ICMP, > + RTE_PTYPE_UNKNOWN > + }; > + > + return ptypes; > +} > + > +static int > +cpfl_dev_configure(struct rte_eth_dev *dev) { > + struct idpf_vport *vport =3D dev->data->dev_private; > + struct rte_eth_conf *conf =3D &dev->data->dev_conf; > + > + if (conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) { > + PMD_INIT_LOG(ERR, "Setting link speed is not supported"); > + return -ENOTSUP; > + } > + > + if (conf->txmode.mq_mode !=3D RTE_ETH_MQ_TX_NONE) { > + PMD_INIT_LOG(ERR, "Multi-queue TX mode %d is not > supported", > + conf->txmode.mq_mode); > + return -ENOTSUP; > + } > + > + if (conf->lpbk_mode !=3D 0) { > + PMD_INIT_LOG(ERR, "Loopback operation mode %d is not > supported", > + conf->lpbk_mode); > + return -ENOTSUP; > + } > + > + if (conf->dcb_capability_en !=3D 0) { > + PMD_INIT_LOG(ERR, "Priority Flow Control(PFC) if not > supported"); > + return -ENOTSUP; > + } > + > + if (conf->intr_conf.lsc !=3D 0) { > + PMD_INIT_LOG(ERR, "LSC interrupt is not supported"); > + return -ENOTSUP; > + } > + > + if (conf->intr_conf.rxq !=3D 0) { > + PMD_INIT_LOG(ERR, "RXQ interrupt is not supported"); > + return -ENOTSUP; > + } > + > + if (conf->intr_conf.rmv !=3D 0) { > + PMD_INIT_LOG(ERR, "RMV interrupt is not supported"); > + return -ENOTSUP; > + } > + > + return 0; > +} > + > +static int > +cpfl_dev_close(struct rte_eth_dev *dev) { > + struct idpf_vport *vport =3D dev->data->dev_private; > + struct cpfl_adapter_ext *adapter =3D > +CPFL_ADAPTER_TO_EXT(vport->adapter); > + > + idpf_vport_deinit(vport); > + > + adapter->cur_vports &=3D ~RTE_BIT32(vport->devarg_id); > + adapter->cur_vport_nb--; > + dev->data->dev_private =3D NULL; > + adapter->vports[vport->sw_idx] =3D NULL; > + rte_free(vport); > + > + return 0; > +} > + > +static int > +insert_value(struct cpfl_devargs *devargs, uint16_t id) { > + uint16_t i; > + > + /* ignore duplicate */ > + for (i =3D 0; i < devargs->req_vport_nb; i++) { > + if (devargs->req_vports[i] =3D=3D id) > + return 0; > + } > + > + if (devargs->req_vport_nb >=3D RTE_DIM(devargs->req_vports)) { > + PMD_INIT_LOG(ERR, "Total vport number can't be > %d", > + CPFL_MAX_VPORT_NUM); > + return -EINVAL; > + } > + > + devargs->req_vports[devargs->req_vport_nb] =3D id; > + devargs->req_vport_nb++; > + > + return 0; > +} > + > +static const char * > +parse_range(const char *value, struct cpfl_devargs *devargs) { > + uint16_t lo, hi, i; > + int n =3D 0; > + int result; > + const char *pos =3D value; > + > + result =3D sscanf(value, "%hu%n-%hu%n", &lo, &n, &hi, &n); > + if (result =3D=3D 1) { What does "1" mean here? I may suggest to replace it with a meaningful macro. Thanks, Helin > + if (lo >=3D CPFL_MAX_VPORT_NUM) > + return NULL; > + if (insert_value(devargs, lo) !=3D 0) > + return NULL; > + } else if (result =3D=3D 2) { > + if (lo > hi || hi >=3D CPFL_MAX_VPORT_NUM) > + return NULL; > + for (i =3D lo; i <=3D hi; i++) { > + if (insert_value(devargs, i) !=3D 0) > + return NULL; > + } > + } else { > + return NULL; > + } > + > + return pos + n; > +} > + > +static int > +parse_vport(const char *key, const char *value, void *args) { > + struct cpfl_devargs *devargs =3D args; > + const char *pos =3D value; > + > + devargs->req_vport_nb =3D 0; > + > + if (*pos =3D=3D '[') > + pos++; > + > + while (1) { > + pos =3D parse_range(pos, devargs); > + if (pos =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "invalid value:\"%s\" for > key:\"%s\", ", > + value, key); > + return -EINVAL; > + } > + if (*pos !=3D ',') > + break; > + pos++; > + } > + > + if (*value =3D=3D '[' && *pos !=3D ']') { > + PMD_INIT_LOG(ERR, "invalid value:\"%s\" for key:\"%s\", ", > + value, key); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > +parse_bool(const char *key, const char *value, void *args) { > + int *i =3D args; > + char *end; > + int num; > + > + errno =3D 0; > + > + num =3D strtoul(value, &end, 10); > + > + if (errno =3D=3D ERANGE || (num !=3D 0 && num !=3D 1)) { > + PMD_INIT_LOG(ERR, "invalid value:\"%s\" for key:\"%s\", > value must be 0 or 1", > + value, key); > + return -EINVAL; > + } > + > + *i =3D num; > + return 0; > +} > + > +static int > +cpfl_parse_devargs(struct rte_pci_device *pci_dev, struct > cpfl_adapter_ext *adapter, > + struct cpfl_devargs *cpfl_args) > +{ > + struct rte_devargs *devargs =3D pci_dev->device.devargs; > + struct rte_kvargs *kvlist; > + int i, ret; > + > + cpfl_args->req_vport_nb =3D 0; > + > + if (devargs =3D=3D NULL) Need a LOG for debugging purpose? > + return 0; > + > + kvlist =3D rte_kvargs_parse(devargs->args, cpfl_valid_args); > + if (kvlist =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "invalid kvargs key"); > + return -EINVAL; > + } > + > + /* check parsed devargs */ > + if (adapter->cur_vport_nb + cpfl_args->req_vport_nb > > + CPFL_MAX_VPORT_NUM) { > + PMD_INIT_LOG(ERR, "Total vport number can't be > %d", > + CPFL_MAX_VPORT_NUM); > + ret =3D -EINVAL; > + goto bail; > + } > + > + for (i =3D 0; i < cpfl_args->req_vport_nb; i++) { > + if (adapter->cur_vports & RTE_BIT32(cpfl_args- > >req_vports[i])) { > + PMD_INIT_LOG(ERR, "Vport %d has been created", > + cpfl_args->req_vports[i]); > + ret =3D -EINVAL; > + goto bail; > + } > + } > + > + ret =3D rte_kvargs_process(kvlist, CPFL_VPORT, &parse_vport, > + cpfl_args); > + if (ret !=3D 0) > + goto bail; > + > + ret =3D rte_kvargs_process(kvlist, CPFL_TX_SINGLE_Q, &parse_bool, > + &adapter->base.txq_model); > + if (ret !=3D 0) > + goto bail; > + > + ret =3D rte_kvargs_process(kvlist, CPFL_RX_SINGLE_Q, &parse_bool, > + &adapter->base.rxq_model); > + if (ret !=3D 0) > + goto bail; Is above line useless code? > + > +bail: > + rte_kvargs_free(kvlist); > + return ret; > +} > + > +static struct idpf_vport * > +cpfl_find_vport(struct cpfl_adapter_ext *adapter, uint32_t vport_id) { > + struct idpf_vport *vport =3D NULL; > + int i; > + > + for (i =3D 0; i < adapter->cur_vport_nb; i++) { > + vport =3D adapter->vports[i]; > + if (vport->vport_id !=3D vport_id) > + continue; > + else > + return vport; Likely you just need to check if vport->vport_id equals to vport_id, right? > + } > + > + return vport; > +} > + > +static void > +cpfl_handle_event_msg(struct idpf_vport *vport, uint8_t *msg, uint16_t > +msglen) { > + struct virtchnl2_event *vc_event =3D (struct virtchnl2_event *)msg; > + struct rte_eth_dev *dev =3D (struct rte_eth_dev *)vport->dev; > + > + if (msglen < sizeof(struct virtchnl2_event)) { > + PMD_DRV_LOG(ERR, "Error event"); > + return; > + } > + > + switch (vc_event->event) { > + case VIRTCHNL2_EVENT_LINK_CHANGE: > + PMD_DRV_LOG(DEBUG, > "VIRTCHNL2_EVENT_LINK_CHANGE"); > + vport->link_up =3D vc_event->link_status; > + vport->link_speed =3D vc_event->link_speed; > + cpfl_dev_link_update(dev, 0); > + break; > + default: > + PMD_DRV_LOG(ERR, " unknown event received %u", > vc_event->event); > + break; > + } > +} > + > +static void > +cpfl_handle_virtchnl_msg(struct cpfl_adapter_ext *adapter_ex) { > + struct idpf_adapter *adapter =3D &adapter_ex->base; > + struct idpf_dma_mem *dma_mem =3D NULL; > + struct idpf_hw *hw =3D &adapter->hw; > + struct virtchnl2_event *vc_event; > + struct idpf_ctlq_msg ctlq_msg; > + enum idpf_mbx_opc mbx_op; > + struct idpf_vport *vport; > + enum virtchnl_ops vc_op; > + uint16_t pending =3D 1; > + int ret; > + > + while (pending) { > + ret =3D idpf_ctlq_recv(hw->arq, &pending, &ctlq_msg); > + if (ret) { > + PMD_DRV_LOG(INFO, "Failed to read msg from > virtual channel, ret: %d", ret); > + return; > + } > + > + rte_memcpy(adapter->mbx_resp, > ctlq_msg.ctx.indirect.payload->va, > + IDPF_DFLT_MBX_BUF_SIZE); > + > + mbx_op =3D rte_le_to_cpu_16(ctlq_msg.opcode); > + vc_op =3D > rte_le_to_cpu_32(ctlq_msg.cookie.mbx.chnl_opcode); > + adapter->cmd_retval =3D > +rte_le_to_cpu_32(ctlq_msg.cookie.mbx.chnl_retval); > + > + switch (mbx_op) { > + case idpf_mbq_opc_send_msg_to_peer_pf: > + if (vc_op =3D=3D VIRTCHNL2_OP_EVENT) { > + if (ctlq_msg.data_len < sizeof(struct > virtchnl2_event)) { > + PMD_DRV_LOG(ERR, "Error event"); > + return; > + } > + vc_event =3D (struct virtchnl2_event > *)adapter->mbx_resp; > + vport =3D cpfl_find_vport(adapter_ex, > vc_event->vport_id); > + if (!vport) { > + PMD_DRV_LOG(ERR, "Can't find > vport."); > + return; > + } > + cpfl_handle_event_msg(vport, adapter- > >mbx_resp, > + ctlq_msg.data_len); > + } else { > + if (vc_op =3D=3D adapter->pend_cmd) > + notify_cmd(adapter, adapter- > >cmd_retval); > + else > + PMD_DRV_LOG(ERR, "command > mismatch, expect %u, get %u", > + adapter->pend_cmd, > vc_op); > + > + PMD_DRV_LOG(DEBUG, " Virtual channel > response is received," > + "opcode =3D %d", vc_op); > + } > + goto post_buf; > + default: > + PMD_DRV_LOG(DEBUG, "Request %u is not > supported yet", mbx_op); > + } > + } > + > +post_buf: > + if (ctlq_msg.data_len) > + dma_mem =3D ctlq_msg.ctx.indirect.payload; > + else > + pending =3D 0; > + > + ret =3D idpf_ctlq_post_rx_buffs(hw, hw->arq, &pending, &dma_mem); > + if (ret && dma_mem) > + idpf_free_dma_mem(hw, dma_mem); > +} > + > +static void > +cpfl_dev_alarm_handler(void *param) > +{ > + struct cpfl_adapter_ext *adapter =3D param; > + > + cpfl_handle_virtchnl_msg(adapter); > + > + rte_eal_alarm_set(CPFL_ALARM_INTERVAL, > cpfl_dev_alarm_handler, > +adapter); } > + > +static int > +cpfl_adapter_ext_init(struct rte_pci_device *pci_dev, struct > +cpfl_adapter_ext *adapter) { > + struct idpf_adapter *base =3D &adapter->base; > + struct idpf_hw *hw =3D &base->hw; > + int ret =3D 0; > + > + hw->hw_addr =3D (void *)pci_dev->mem_resource[0].addr; > + hw->hw_addr_len =3D pci_dev->mem_resource[0].len; > + hw->back =3D base; > + hw->vendor_id =3D pci_dev->id.vendor_id; > + hw->device_id =3D pci_dev->id.device_id; > + hw->subsystem_vendor_id =3D pci_dev->id.subsystem_vendor_id; > + > + strncpy(adapter->name, pci_dev->device.name, PCI_PRI_STR_SIZE); > + > + ret =3D idpf_adapter_init(base); > + if (ret !=3D 0) { > + PMD_INIT_LOG(ERR, "Failed to init adapter"); > + goto err_adapter_init; > + } > + > + rte_eal_alarm_set(CPFL_ALARM_INTERVAL, > cpfl_dev_alarm_handler, > +adapter); > + > + adapter->max_vport_nb =3D adapter->base.caps.max_vports; > + > + adapter->vports =3D rte_zmalloc("vports", > + adapter->max_vport_nb * > + sizeof(*adapter->vports), > + 0); > + if (adapter->vports =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Failed to allocate vports memory"); > + ret =3D -ENOMEM; > + goto err_get_ptype; > + } > + > + adapter->cur_vports =3D 0; > + adapter->cur_vport_nb =3D 0; > + > + adapter->used_vecs_num =3D 0; > + > + return ret; > + > +err_get_ptype: > + idpf_adapter_deinit(base); > +err_adapter_init: > + return ret; > +} > + > +static const struct eth_dev_ops cpfl_eth_dev_ops =3D { > + .dev_configure =3D cpfl_dev_configure, > + .dev_close =3D cpfl_dev_close, > + .dev_infos_get =3D cpfl_dev_info_get, > + .link_update =3D cpfl_dev_link_update, > + .dev_supported_ptypes_get =3D cpfl_dev_supported_ptypes_get, > +}; > + > +static uint16_t > +cpfl_vport_idx_alloc(struct cpfl_adapter_ext *ad) { > + uint16_t vport_idx; > + uint16_t i; > + > + for (i =3D 0; i < ad->max_vport_nb; i++) { > + if (ad->vports[i] =3D=3D NULL) > + break; > + } > + > + if (i =3D=3D ad->max_vport_nb) > + vport_idx =3D CPFL_INVALID_VPORT_IDX; Why not initialize vport_idx directly? > + else > + vport_idx =3D i; > + > + return vport_idx; > +} > + > +static int > +cpfl_dev_vport_init(struct rte_eth_dev *dev, void *init_params) { > + struct idpf_vport *vport =3D dev->data->dev_private; > + struct cpfl_vport_param *param =3D init_params; > + struct cpfl_adapter_ext *adapter =3D param->adapter; > + /* for sending create vport virtchnl msg prepare */ > + struct virtchnl2_create_vport create_vport_info; > + int ret =3D 0; > + > + dev->dev_ops =3D &cpfl_eth_dev_ops; > + vport->adapter =3D &adapter->base; > + vport->sw_idx =3D param->idx; > + vport->devarg_id =3D param->devarg_id; > + vport->dev =3D dev; > + > + memset(&create_vport_info, 0, sizeof(create_vport_info)); > + ret =3D idpf_create_vport_info_init(vport, &create_vport_info); > + if (ret !=3D 0) { > + PMD_INIT_LOG(ERR, "Failed to init vport req_info."); > + goto err; > + } > + > + ret =3D idpf_vport_init(vport, &create_vport_info, dev->data); > + if (ret !=3D 0) { > + PMD_INIT_LOG(ERR, "Failed to init vports."); > + goto err; > + } > + > + adapter->vports[param->idx] =3D vport; > + adapter->cur_vports |=3D RTE_BIT32(param->devarg_id); > + adapter->cur_vport_nb++; > + > + dev->data->mac_addrs =3D rte_zmalloc(NULL, RTE_ETHER_ADDR_LEN, > 0); > + if (dev->data->mac_addrs =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Cannot allocate mac_addr memory."); > + ret =3D -ENOMEM; > + goto err_mac_addrs; > + } > + > + rte_ether_addr_copy((struct rte_ether_addr *)vport- > >default_mac_addr, > + &dev->data->mac_addrs[0]); > + > + return 0; > + > +err_mac_addrs: > + adapter->vports[param->idx] =3D NULL; /* reset */ > + idpf_vport_deinit(vport); > +err: > + return ret; > +} > + > +static const struct rte_pci_id pci_id_cpfl_map[] =3D { > + { RTE_PCI_DEVICE(IDPF_INTEL_VENDOR_ID, IDPF_DEV_ID_CPF) }, > + { .vendor_id =3D 0, /* sentinel */ }, > +}; > + > +static struct cpfl_adapter_ext * > +cpfl_find_adapter_ext(struct rte_pci_device *pci_dev) { > + struct cpfl_adapter_ext *adapter; > + int found =3D 0; > + > + if (pci_dev =3D=3D NULL) > + return NULL; > + > + rte_spinlock_lock(&cpfl_adapter_lock); > + TAILQ_FOREACH(adapter, &cpfl_adapter_list, next) { > + if (strncmp(adapter->name, pci_dev->device.name, > PCI_PRI_STR_SIZE) =3D=3D 0) { > + found =3D 1; > + break; > + } > + } > + rte_spinlock_unlock(&cpfl_adapter_lock); > + > + if (found =3D=3D 0) > + return NULL; > + > + return adapter; > +} > + > +static void > +cpfl_adapter_ext_deinit(struct cpfl_adapter_ext *adapter) { > + rte_eal_alarm_cancel(cpfl_dev_alarm_handler, adapter); > + idpf_adapter_deinit(&adapter->base); > + > + rte_free(adapter->vports); > + adapter->vports =3D NULL; > +} > + > +static int > +cpfl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, > + struct rte_pci_device *pci_dev) { > + struct cpfl_vport_param vport_param; > + struct cpfl_adapter_ext *adapter; > + struct cpfl_devargs devargs; > + char name[RTE_ETH_NAME_MAX_LEN]; > + int i, retval; > + bool first_probe =3D false; > + > + if (!cpfl_adapter_list_init) { > + rte_spinlock_init(&cpfl_adapter_lock); > + TAILQ_INIT(&cpfl_adapter_list); > + cpfl_adapter_list_init =3D true; > + } > + > + adapter =3D cpfl_find_adapter_ext(pci_dev); > + if (adapter =3D=3D NULL) { > + first_probe =3D true; > + adapter =3D rte_zmalloc("cpfl_adapter_ext", > + sizeof(struct > cpfl_adapter_ext), 0); > + if (adapter =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Failed to allocate adapter."); > + return -ENOMEM; > + } > + > + retval =3D cpfl_adapter_ext_init(pci_dev, adapter); > + if (retval !=3D 0) { > + PMD_INIT_LOG(ERR, "Failed to init adapter."); > + return retval; > + } > + > + rte_spinlock_lock(&cpfl_adapter_lock); > + TAILQ_INSERT_TAIL(&cpfl_adapter_list, adapter, next); > + rte_spinlock_unlock(&cpfl_adapter_lock); > + } > + > + retval =3D cpfl_parse_devargs(pci_dev, adapter, &devargs); > + if (retval !=3D 0) { > + PMD_INIT_LOG(ERR, "Failed to parse private devargs"); > + goto err; > + } > + > + if (devargs.req_vport_nb =3D=3D 0) { > + /* If no vport devarg, create vport 0 by default. */ > + vport_param.adapter =3D adapter; > + vport_param.devarg_id =3D 0; > + vport_param.idx =3D cpfl_vport_idx_alloc(adapter); > + if (vport_param.idx =3D=3D CPFL_INVALID_VPORT_IDX) { > + PMD_INIT_LOG(ERR, "No space for vport %u", > vport_param.devarg_id); > + return 0; > + } > + snprintf(name, sizeof(name), "cpfl_%s_vport_0", > + pci_dev->device.name); > + retval =3D rte_eth_dev_create(&pci_dev->device, name, > + sizeof(struct idpf_vport), > + NULL, NULL, cpfl_dev_vport_init, > + &vport_param); > + if (retval !=3D 0) > + PMD_DRV_LOG(ERR, "Failed to create default vport > 0"); > + } else { > + for (i =3D 0; i < devargs.req_vport_nb; i++) { > + vport_param.adapter =3D adapter; > + vport_param.devarg_id =3D devargs.req_vports[i]; > + vport_param.idx =3D cpfl_vport_idx_alloc(adapter); > + if (vport_param.idx =3D=3D CPFL_INVALID_VPORT_IDX) { > + PMD_INIT_LOG(ERR, "No space for > vport %u", vport_param.devarg_id); > + break; > + } > + snprintf(name, sizeof(name), "cpfl_%s_vport_%d", > + pci_dev->device.name, > + devargs.req_vports[i]); > + retval =3D rte_eth_dev_create(&pci_dev->device, > name, > + sizeof(struct idpf_vport), > + NULL, NULL, > cpfl_dev_vport_init, > + &vport_param); > + if (retval !=3D 0) > + PMD_DRV_LOG(ERR, "Failed to create > vport %d", > + vport_param.devarg_id); > + } > + } > + > + return 0; > + > +err: > + if (first_probe) { > + rte_spinlock_lock(&cpfl_adapter_lock); > + TAILQ_REMOVE(&cpfl_adapter_list, adapter, next); > + rte_spinlock_unlock(&cpfl_adapter_lock); > + cpfl_adapter_ext_deinit(adapter); > + rte_free(adapter); > + } > + return retval; > +} > + > +static int > +cpfl_pci_remove(struct rte_pci_device *pci_dev) { > + struct cpfl_adapter_ext *adapter =3D cpfl_find_adapter_ext(pci_dev); > + uint16_t port_id; > + > + /* Ethdev created can be found RTE_ETH_FOREACH_DEV_OF > through rte_device */ > + RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device) { > + rte_eth_dev_close(port_id); > + } > + > + rte_spinlock_lock(&cpfl_adapter_lock); > + TAILQ_REMOVE(&cpfl_adapter_list, adapter, next); > + rte_spinlock_unlock(&cpfl_adapter_lock); > + cpfl_adapter_ext_deinit(adapter); > + rte_free(adapter); > + > + return 0; > +} > + > +static struct rte_pci_driver rte_cpfl_pmd =3D { > + .id_table =3D pci_id_cpfl_map, > + .drv_flags =3D RTE_PCI_DRV_NEED_MAPPING, > + .probe =3D cpfl_pci_probe, > + .remove =3D cpfl_pci_remove, > +}; > + > +/** > + * Driver initialization routine. > + * Invoked once at EAL init time. > + * Register itself as the [Poll Mode] Driver of PCI devices. > + */ > +RTE_PMD_REGISTER_PCI(net_cpfl, rte_cpfl_pmd); > +RTE_PMD_REGISTER_PCI_TABLE(net_cpfl, pci_id_cpfl_map); > +RTE_PMD_REGISTER_KMOD_DEP(net_cpfl, "* igb_uio | vfio-pci"); > +RTE_PMD_REGISTER_PARAM_STRING(net_cpfl, > + CPFL_TX_SINGLE_Q "=3D<0|1> " > + CPFL_RX_SINGLE_Q "=3D<0|1> " > + CPFL_VPORT "=3D[vport_set0,[vport_set1],...]"); > + > +RTE_LOG_REGISTER_SUFFIX(cpfl_logtype_init, init, NOTICE); > +RTE_LOG_REGISTER_SUFFIX(cpfl_logtype_driver, driver, NOTICE); > diff --git a/drivers/net/cpfl/cpfl_ethdev.h b/drivers/net/cpfl/cpfl_ethde= v.h > new file mode 100644 index 0000000000..83459b9c91 > --- /dev/null > +++ b/drivers/net/cpfl/cpfl_ethdev.h > @@ -0,0 +1,78 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#ifndef _CPFL_ETHDEV_H_ > +#define _CPFL_ETHDEV_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "cpfl_logs.h" > + > +#include > +#include > +#include > +#include > + > +#define CPFL_MAX_VPORT_NUM 8 > + > +#define CPFL_INVALID_VPORT_IDX 0xffff > + > +#define CPFL_MIN_BUF_SIZE 1024 > +#define CPFL_MAX_FRAME_SIZE 9728 > +#define CPFL_DEFAULT_MTU RTE_ETHER_MTU > + > +#define CPFL_NUM_MACADDR_MAX 64 > + > +#define CPFL_VLAN_TAG_SIZE 4 > +#define CPFL_ETH_OVERHEAD \ > + (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + > CPFL_VLAN_TAG_SIZE * 2) > + > +#define CPFL_ADAPTER_NAME_LEN (PCI_PRI_STR_SIZE + 1) > + > +#define CPFL_ALARM_INTERVAL 50000 /* us */ > + > +/* Device IDs */ > +#define IDPF_DEV_ID_CPF 0x1453 > + > +struct cpfl_vport_param { > + struct cpfl_adapter_ext *adapter; > + uint16_t devarg_id; /* arg id from user */ > + uint16_t idx; /* index in adapter->vports[]*/ > +}; > + > +/* Struct used when parse driver specific devargs */ struct > +cpfl_devargs { > + uint16_t req_vports[CPFL_MAX_VPORT_NUM]; > + uint16_t req_vport_nb; > +}; > + > +struct cpfl_adapter_ext { > + TAILQ_ENTRY(cpfl_adapter_ext) next; > + struct idpf_adapter base; > + > + char name[CPFL_ADAPTER_NAME_LEN]; > + > + struct idpf_vport **vports; > + uint16_t max_vport_nb; > + > + uint16_t cur_vports; /* bit mask of created vport */ > + uint16_t cur_vport_nb; > + > + uint16_t used_vecs_num; > +}; > + > +TAILQ_HEAD(cpfl_adapter_list, cpfl_adapter_ext); > + > +#define CPFL_DEV_TO_PCI(eth_dev) \ > + RTE_DEV_TO_PCI((eth_dev)->device) > +#define CPFL_ADAPTER_TO_EXT(p) \ > + container_of((p), struct cpfl_adapter_ext, base) > + > +#endif /* _CPFL_ETHDEV_H_ */ > diff --git a/drivers/net/cpfl/cpfl_logs.h b/drivers/net/cpfl/cpfl_logs.h = new > file mode 100644 index 0000000000..451bdfbd1d > --- /dev/null > +++ b/drivers/net/cpfl/cpfl_logs.h > @@ -0,0 +1,32 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#ifndef _CPFL_LOGS_H_ > +#define _CPFL_LOGS_H_ > + > +#include > + > +extern int cpfl_logtype_init; > +extern int cpfl_logtype_driver; > + > +#define PMD_INIT_LOG(level, ...) \ > + rte_log(RTE_LOG_ ## level, \ > + cpfl_logtype_init, \ > + RTE_FMT("%s(): " \ > + RTE_FMT_HEAD(__VA_ARGS__,) "\n", \ > + __func__, \ > + RTE_FMT_TAIL(__VA_ARGS__,))) > + > +#define PMD_DRV_LOG_RAW(level, ...) \ > + rte_log(RTE_LOG_ ## level, \ > + cpfl_logtype_driver, \ > + RTE_FMT("%s(): " \ > + RTE_FMT_HEAD(__VA_ARGS__,) "\n", \ > + __func__, \ > + RTE_FMT_TAIL(__VA_ARGS__,))) > + > +#define PMD_DRV_LOG(level, fmt, args...) \ > + PMD_DRV_LOG_RAW(level, fmt "\n", ## args) > + > +#endif /* _CPFL_LOGS_H_ */ > diff --git a/drivers/net/cpfl/cpfl_rxtx.c b/drivers/net/cpfl/cpfl_rxtx.c = new file > mode 100644 index 0000000000..ea4a2002bf > --- /dev/null > +++ b/drivers/net/cpfl/cpfl_rxtx.c > @@ -0,0 +1,244 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#include > +#include > +#include > + > +#include "cpfl_ethdev.h" > +#include "cpfl_rxtx.h" > + > +static uint64_t > +cpfl_tx_offload_convert(uint64_t offload) { > + uint64_t ol =3D 0; > + > + if ((offload & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) !=3D 0) > + ol |=3D IDPF_TX_OFFLOAD_IPV4_CKSUM; > + if ((offload & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) !=3D 0) > + ol |=3D IDPF_TX_OFFLOAD_UDP_CKSUM; > + if ((offload & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) !=3D 0) > + ol |=3D IDPF_TX_OFFLOAD_TCP_CKSUM; > + if ((offload & RTE_ETH_TX_OFFLOAD_SCTP_CKSUM) !=3D 0) > + ol |=3D IDPF_TX_OFFLOAD_SCTP_CKSUM; > + if ((offload & RTE_ETH_TX_OFFLOAD_MULTI_SEGS) !=3D 0) > + ol |=3D IDPF_TX_OFFLOAD_MULTI_SEGS; > + if ((offload & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) !=3D 0) > + ol |=3D IDPF_TX_OFFLOAD_MBUF_FAST_FREE; > + > + return ol; > +} > + > +static const struct rte_memzone * > +cpfl_dma_zone_reserve(struct rte_eth_dev *dev, uint16_t queue_idx, > + uint16_t len, uint16_t queue_type, > + unsigned int socket_id, bool splitq) { > + char ring_name[RTE_MEMZONE_NAMESIZE]; > + const struct rte_memzone *mz; > + uint32_t ring_size; > + > + memset(ring_name, 0, RTE_MEMZONE_NAMESIZE); > + switch (queue_type) { > + case VIRTCHNL2_QUEUE_TYPE_TX: > + if (splitq) > + ring_size =3D RTE_ALIGN(len * sizeof(struct > idpf_flex_tx_sched_desc), > + CPFL_DMA_MEM_ALIGN); > + else > + ring_size =3D RTE_ALIGN(len * sizeof(struct > idpf_flex_tx_desc), > + CPFL_DMA_MEM_ALIGN); > + rte_memcpy(ring_name, "cpfl Tx ring", sizeof("cpfl Tx ring")); > + break; > + case VIRTCHNL2_QUEUE_TYPE_RX: > + if (splitq) > + ring_size =3D RTE_ALIGN(len * sizeof(struct > virtchnl2_rx_flex_desc_adv_nic_3), > + CPFL_DMA_MEM_ALIGN); > + else > + ring_size =3D RTE_ALIGN(len * sizeof(struct > virtchnl2_singleq_rx_buf_desc), > + CPFL_DMA_MEM_ALIGN); > + rte_memcpy(ring_name, "cpfl Rx ring", sizeof("cpfl Rx ring")); > + break; > + case VIRTCHNL2_QUEUE_TYPE_TX_COMPLETION: > + ring_size =3D RTE_ALIGN(len * sizeof(struct > idpf_splitq_tx_compl_desc), > + CPFL_DMA_MEM_ALIGN); > + rte_memcpy(ring_name, "cpfl Tx compl ring", sizeof("cpfl Tx > compl ring")); > + break; > + case VIRTCHNL2_QUEUE_TYPE_RX_BUFFER: > + ring_size =3D RTE_ALIGN(len * sizeof(struct > virtchnl2_splitq_rx_buf_desc), > + CPFL_DMA_MEM_ALIGN); > + rte_memcpy(ring_name, "cpfl Rx buf ring", sizeof("cpfl Rx > buf ring")); > + break; > + default: > + PMD_INIT_LOG(ERR, "Invalid queue type"); > + return NULL; > + } > + > + mz =3D rte_eth_dma_zone_reserve(dev, ring_name, queue_idx, > + ring_size, CPFL_RING_BASE_ALIGN, > + socket_id); > + if (mz =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Failed to reserve DMA memory for > ring"); > + return NULL; > + } > + > + /* Zero all the descriptors in the ring. */ > + memset(mz->addr, 0, ring_size); > + > + return mz; > +} > + > +static void > +cpfl_dma_zone_release(const struct rte_memzone *mz) { > + rte_memzone_free(mz); > +} > + > +static int > +cpfl_tx_complq_setup(struct rte_eth_dev *dev, struct idpf_tx_queue *txq, > + uint16_t queue_idx, uint16_t nb_desc, > + unsigned int socket_id) > +{ > + struct idpf_vport *vport =3D dev->data->dev_private; > + const struct rte_memzone *mz; > + struct idpf_tx_queue *cq; > + int ret; > + > + cq =3D rte_zmalloc_socket("cpfl splitq cq", > + sizeof(struct idpf_tx_queue), > + RTE_CACHE_LINE_SIZE, > + socket_id); > + if (cq =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Failed to allocate memory for Tx compl > queue"); > + ret =3D -ENOMEM; > + goto err_cq_alloc; > + } > + > + cq->nb_tx_desc =3D nb_desc; > + cq->queue_id =3D vport->chunks_info.tx_compl_start_qid + > queue_idx; > + cq->port_id =3D dev->data->port_id; > + cq->txqs =3D dev->data->tx_queues; > + cq->tx_start_qid =3D vport->chunks_info.tx_start_qid; > + > + mz =3D cpfl_dma_zone_reserve(dev, queue_idx, nb_desc, > + > VIRTCHNL2_QUEUE_TYPE_TX_COMPLETION, > + socket_id, true); > + if (mz =3D=3D NULL) { Need an error log here? > + ret =3D -ENOMEM; > + goto err_mz_reserve; > + } > + cq->tx_ring_phys_addr =3D mz->iova; > + cq->compl_ring =3D mz->addr; > + cq->mz =3D mz; > + reset_split_tx_complq(cq); > + > + txq->complq =3D cq; > + > + return 0; > + > +err_mz_reserve: > + rte_free(cq); > +err_cq_alloc: > + return ret; > +} > + > +int > +cpfl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, > + uint16_t nb_desc, unsigned int socket_id, > + const struct rte_eth_txconf *tx_conf) { > + struct idpf_vport *vport =3D dev->data->dev_private; > + struct idpf_adapter *adapter =3D vport->adapter; > + uint16_t tx_rs_thresh, tx_free_thresh; > + struct idpf_hw *hw =3D &adapter->hw; > + const struct rte_memzone *mz; > + struct idpf_tx_queue *txq; > + uint64_t offloads; > + uint16_t len; > + bool is_splitq; > + int ret; > + > + offloads =3D tx_conf->offloads | dev->data- > >dev_conf.txmode.offloads; > + > + tx_rs_thresh =3D (uint16_t)((tx_conf->tx_rs_thresh > 0) ? > + tx_conf->tx_rs_thresh : CPFL_DEFAULT_TX_RS_THRESH); > + tx_free_thresh =3D (uint16_t)((tx_conf->tx_free_thresh > 0) ? > + tx_conf->tx_free_thresh : > CPFL_DEFAULT_TX_FREE_THRESH); > + if (check_tx_thresh(nb_desc, tx_rs_thresh, tx_free_thresh) !=3D 0) > + return -EINVAL; > + > + /* Allocate the TX queue data structure. */ > + txq =3D rte_zmalloc_socket("cpfl txq", > + sizeof(struct idpf_tx_queue), > + RTE_CACHE_LINE_SIZE, > + socket_id); > + if (txq =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Failed to allocate memory for tx queue > structure"); > + ret =3D -ENOMEM; > + goto err_txq_alloc; > + } > + > + is_splitq =3D !!(vport->txq_model =3D=3D > VIRTCHNL2_QUEUE_MODEL_SPLIT); > + > + txq->nb_tx_desc =3D nb_desc; > + txq->rs_thresh =3D tx_rs_thresh; > + txq->free_thresh =3D tx_free_thresh; > + txq->queue_id =3D vport->chunks_info.tx_start_qid + queue_idx; > + txq->port_id =3D dev->data->port_id; > + txq->offloads =3D cpfl_tx_offload_convert(offloads); > + txq->tx_deferred_start =3D tx_conf->tx_deferred_start; > + > + if (is_splitq) > + len =3D 2 * nb_desc; > + else > + len =3D nb_desc; > + txq->sw_nb_desc =3D len; > + > + /* Allocate TX hardware ring descriptors. */ > + mz =3D cpfl_dma_zone_reserve(dev, queue_idx, nb_desc, > VIRTCHNL2_QUEUE_TYPE_TX, > + socket_id, is_splitq); > + if (mz =3D=3D NULL) { > + ret =3D -ENOMEM; > + goto err_mz_reserve; > + } > + txq->tx_ring_phys_addr =3D mz->iova; > + txq->mz =3D mz; > + > + txq->sw_ring =3D rte_zmalloc_socket("cpfl tx sw ring", > + sizeof(struct idpf_tx_entry) * len, > + RTE_CACHE_LINE_SIZE, socket_id); > + if (txq->sw_ring =3D=3D NULL) { > + PMD_INIT_LOG(ERR, "Failed to allocate memory for SW TX > ring"); > + ret =3D -ENOMEM; > + goto err_sw_ring_alloc; > + } > + > + if (!is_splitq) { > + txq->tx_ring =3D mz->addr; > + reset_single_tx_queue(txq); > + } else { > + txq->desc_ring =3D mz->addr; > + reset_split_tx_descq(txq); > + > + /* Setup tx completion queue if split model */ > + ret =3D cpfl_tx_complq_setup(dev, txq, queue_idx, > + 2 * nb_desc, socket_id); > + if (ret !=3D 0) > + goto err_complq_setup; > + } > + > + txq->qtx_tail =3D hw->hw_addr + (vport->chunks_info.tx_qtail_start + > + queue_idx * vport->chunks_info.tx_qtail_spacing); > + txq->q_set =3D true; > + dev->data->tx_queues[queue_idx] =3D txq; > + > + return 0; > + > +err_complq_setup: > +err_sw_ring_alloc: > + cpfl_dma_zone_release(mz); > +err_mz_reserve: > + rte_free(txq); > +err_txq_alloc: > + return ret; > +} > diff --git a/drivers/net/cpfl/cpfl_rxtx.h b/drivers/net/cpfl/cpfl_rxtx.h = new > file mode 100644 index 0000000000..ec42478393 > --- /dev/null > +++ b/drivers/net/cpfl/cpfl_rxtx.h > @@ -0,0 +1,25 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2022 Intel Corporation > + */ > + > +#ifndef _CPFL_RXTX_H_ > +#define _CPFL_RXTX_H_ > + > +#include > +#include "cpfl_ethdev.h" > + > +/* In QLEN must be whole number of 32 descriptors. */ > +#define CPFL_ALIGN_RING_DESC 32 > +#define CPFL_MIN_RING_DESC 32 > +#define CPFL_MAX_RING_DESC 4096 > +#define CPFL_DMA_MEM_ALIGN 4096 > +/* Base address of the HW descriptor ring should be 128B aligned. */ > +#define CPFL_RING_BASE_ALIGN 128 > + > +#define CPFL_DEFAULT_TX_RS_THRESH 32 > +#define CPFL_DEFAULT_TX_FREE_THRESH 32 > + > +int cpfl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, > + uint16_t nb_desc, unsigned int socket_id, > + const struct rte_eth_txconf *tx_conf); #endif /* > _CPFL_RXTX_H_ */ > diff --git a/drivers/net/cpfl/meson.build b/drivers/net/cpfl/meson.build = new > file mode 100644 index 0000000000..106cc97e60 > --- /dev/null > +++ b/drivers/net/cpfl/meson.build > @@ -0,0 +1,14 @@ > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2022 Intel > +Corporation > + > +if is_windows > + build =3D false > + reason =3D 'not supported on Windows' > + subdir_done() > +endif > + > +deps +=3D ['common_idpf'] > + > +sources =3D files( > + 'cpfl_ethdev.c', > +) > \ No newline at end of file > diff --git a/drivers/net/meson.build b/drivers/net/meson.build index > 6470bf3636..a8ca338875 100644 > --- a/drivers/net/meson.build > +++ b/drivers/net/meson.build > @@ -13,6 +13,7 @@ drivers =3D [ > 'bnxt', > 'bonding', > 'cnxk', > + 'cpfl', > 'cxgbe', > 'dpaa', > 'dpaa2', > -- > 2.25.1