From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <nipun.gupta@nxp.com>
Received: from EUR02-VE1-obe.outbound.protection.outlook.com
 (mail-eopbgr20048.outbound.protection.outlook.com [40.107.2.48])
 by dpdk.org (Postfix) with ESMTP id 1E0D02BBE
 for <dev@dpdk.org>; Fri, 15 Sep 2017 08:07:37 +0200 (CEST)
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;
 bh=alSkoYEhRlswyE3ZVxWZrt+SLhwnorTZ5U67pfpKeWg=;
 b=sAwBRmLcDByHMrJoVFmjoMznZ//S9h7fet6ZjC9GfwRshTyIqnsMwY6i/zKCC0RlyMpO+dzEoCGrfjX0eeh8a5fqS3UkYZA45aG9CdZABwTw+EOzJen2Xy8BVkvrowI+IxPaC4pyIKMBlgoxurmoPrMiofSAuxIeJ4qTZjPeihw=
Received: from HE1PR0401MB2425.eurprd04.prod.outlook.com (10.168.33.22) by
 HE1PR0401MB2489.eurprd04.prod.outlook.com (10.168.147.136) with Microsoft
 SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.56.11; Fri, 15
 Sep 2017 06:07:36 +0000
Received: from HE1PR0401MB2425.eurprd04.prod.outlook.com
 ([fe80::a1f9:523b:383c:d454]) by HE1PR0401MB2425.eurprd04.prod.outlook.com
 ([fe80::a1f9:523b:383c:d454%18]) with mapi id 15.20.0056.010; Fri, 15 Sep
 2017 06:07:35 +0000
From: Nipun Gupta <nipun.gupta@nxp.com>
To: Nikhil Rao <nikhil.rao@intel.com>, "jerin.jacob@caviumnetworks.com"
 <jerin.jacob@caviumnetworks.com>, "bruce.richardson@intel.com"
 <bruce.richardson@intel.com>
CC: "gage.eads@intel.com" <gage.eads@intel.com>, "dev@dpdk.org"
 <dev@dpdk.org>, "thomas@monjalon.net" <thomas@monjalon.net>,
 "harry.van.haaren@intel.com" <harry.van.haaren@intel.com>, Hemant Agrawal
 <hemant.agrawal@nxp.com>, "narender.vangati@intel.com"
 <narender.vangati@intel.com>, "erik.g.carrillo@intel.com"
 <erik.g.carrillo@intel.com>, "abhinandan.gujjar@intel.com"
 <abhinandan.gujjar@intel.com>
Thread-Topic: [PATCH 3/4] eventdev: Add eventdev ethernet Rx adapter
Thread-Index: AQHTLHk5s4BbvriEXEOZ/buJBWEoL6K1dO+A
Date: Fri, 15 Sep 2017 06:07:35 +0000
Message-ID: <HE1PR0401MB242551FB4CD3045C0EECA092E66C0@HE1PR0401MB2425.eurprd04.prod.outlook.com>
References: <04bcb240-51fb-50dc-833c-60c33a420d6f@intel.com>
 <1505328781-23456-1-git-send-email-nikhil.rao@intel.com>
In-Reply-To: <1505328781-23456-1-git-send-email-nikhil.rao@intel.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
authentication-results: spf=none (sender IP is )
 smtp.mailfrom=nipun.gupta@nxp.com; 
x-originating-ip: [192.88.169.1]
x-ms-publictraffictype: Email
x-microsoft-exchange-diagnostics: 1; HE1PR0401MB2489;
 6:kl1eWihRVOCZpIlVVs3OAt/DDCnpWj76NOk0nrx4TK5tLdWXYB0Q9R8LafdGp4YQIb204TXFHGAWMHJ4rsPTwIn1r7Gpg56ox3z/6XPKrI0C8HgZ92kQBEg2ZcMwwgpgWV6q3p53K4/ysyqgRLJOhpvdRPIxKmqENACfDPUGVdfGPRlervSDlgik8rQhh99MzcYOyg7Hs+p0zN4lfGkgU5YCub9aLWuxgRpa2wN0/Q1UkojTW+z05E2xzEaIbiwVlKjzbzkcMYy2AfW1PGESs5BYqwFUstVkKTj7bkZFx8DdaB/EoCGMBsf6dyH2F4odAuNPB69KJuR1g2tbWClbhg==;
 5:ICLNWFYCdxf2TnCce9jwbKC8st157+wrMLPfodg+72pskp2qBVvI13yp7Mh/xrG7YPHq4ZJgmp7l/2qmnJVCuvfBLuR6a4VJRglz6e/TkOD41B3ycYRJKOaXSvvB5pBnqFlAzCu6kcoPHcKzESTHzw==;
 24:tyq87G9hiRRbOLWjzjE5Ffizg7mtdyx+rff8MoP0PHsNf7lZEzNKU4/NNG03mmXo2kLzUIALjTmBUVE63n+otijUe8Kdsw+cw42jctYaXVY=;
 7:kvKEOP5RfaqMfdmnIEXQZoDlLgoulRnkqw+DOTko/oa1yWuA9vozCOr0zsENTiueMOoUPKV+6XEneoivV/7QOoefsvjeAkaCQnL6FpDZe5u8k4pJL7fKlWfPtSGN+3nBuujHVC11pUTzUm/qCLT1LYzQtY1qi0YtNlBt8pkJjuowg4k0RFRr2J4Lc6rPWdgmaPHh0/nvkg3yUBRndnG6LVVN08XSJJvZenpEtHaDAUY=
x-ms-exchange-antispam-srfa-diagnostics: SSOS;SSOR;
x-forefront-antispam-report: SFV:SKI; SCL:-1; SFV:NSPM;
 SFS:(10009020)(6009001)(376002)(346002)(39860400002)(189002)(199003)(13464003)(66066001)(9686003)(229853002)(478600001)(6436002)(6506006)(76176999)(50986999)(14454004)(6116002)(6246003)(5250100002)(53936002)(55016002)(53546010)(99286003)(8936002)(33656002)(102836003)(3846002)(101416001)(86362001)(81156014)(81166006)(4326008)(2501003)(8676002)(54906002)(2900100001)(105586002)(106356001)(54356999)(68736007)(5660300001)(3660700001)(7416002)(3280700002)(97736004)(7696004)(2950100002)(305945005)(189998001)(25786009)(2906002)(316002)(74316002)(7736002)(2201001)(309714004);
 DIR:OUT; SFP:1101; SCL:1; SRVR:HE1PR0401MB2489;
 H:HE1PR0401MB2425.eurprd04.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords;
 MX:1; A:1; LANG:en; 
x-ms-office365-filtering-correlation-id: a8a51c82-dc8d-45f6-d9a3-08d4fc000f70
x-ms-office365-filtering-ht: Tenant
x-microsoft-antispam: UriScan:; BCL:0; PCL:0;
 RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(300000502095)(300135100095)(22001)(2017030254152)(48565401081)(300000503095)(300135400095)(2017052603199)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095);
 SRVR:HE1PR0401MB2489; 
x-ms-traffictypediagnostic: HE1PR0401MB2489:
x-exchange-antispam-report-test: UriScan:(185117386973197)(228905959029699);
x-microsoft-antispam-prvs: <HE1PR0401MB24894109E940352BFADF35CEE66C0@HE1PR0401MB2489.eurprd04.prod.outlook.com>
x-exchange-antispam-report-cfa-test: BCL:0; PCL:0;
 RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(93006095)(93001095)(100000703101)(100105400095)(3002001)(10201501046)(6055026)(6041248)(20161123555025)(20161123562025)(20161123560025)(20161123558100)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);
 SRVR:HE1PR0401MB2489; BCL:0; PCL:0;
 RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);
 SRVR:HE1PR0401MB2489; 
x-forefront-prvs: 0431F981D8
received-spf: None (protection.outlook.com: nxp.com does not designate
 permitted sender hosts)
spamdiagnosticoutput: 1:99
spamdiagnosticmetadata: NSPM
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: nxp.com
X-MS-Exchange-CrossTenant-originalarrivaltime: 15 Sep 2017 06:07:35.3617 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635
X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0401MB2489
Subject: Re: [dpdk-dev] [PATCH 3/4] eventdev: Add eventdev ethernet Rx
	adapter
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Fri, 15 Sep 2017 06:07:38 -0000



> -----Original Message-----
> From: Nikhil Rao [mailto:nikhil.rao@intel.com]
> Sent: Thursday, September 14, 2017 0:23
> To: jerin.jacob@caviumnetworks.com; bruce.richardson@intel.com
> Cc: gage.eads@intel.com; dev@dpdk.org; thomas@monjalon.net;
> harry.van.haaren@intel.com; Hemant Agrawal <hemant.agrawal@nxp.com>;
> Nipun Gupta <nipun.gupta@nxp.com>; narender.vangati@intel.com;
> erik.g.carrillo@intel.com; abhinandan.gujjar@intel.com
> Subject: [PATCH 3/4] eventdev: Add eventdev ethernet Rx adapter
>=20
> Add common APIs for configuring packet transfer from ethernet Rx
> queues to event devices across HW & SW packet transfer mechanisms.
> A detailed description of the adapter is contained in the header's
> comments.
>=20
> The adapter implementation uses eventdev PMDs to configure the packet
> transfer if HW support is available and if not, it uses an EAL service
> function that reads packets from ethernet Rx queues and injects these
> as events into the event device.
>=20
> Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
> Signed-off-by: Gage Eads <gage.eads@intel.com>
> Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> ---
>  lib/librte_eventdev/rte_event_eth_rx_adapter.h |  386 ++++++++
>  lib/librte_eventdev/rte_event_eth_rx_adapter.c | 1239
> ++++++++++++++++++++++++
>  lib/Makefile                                   |    2 +-
>  lib/librte_eventdev/Makefile                   |    2 +
>  lib/librte_eventdev/rte_eventdev_version.map   |   11 +-
>  5 files changed, 1638 insertions(+), 2 deletions(-)
>  create mode 100644 lib/librte_eventdev/rte_event_eth_rx_adapter.h
>  create mode 100644 lib/librte_eventdev/rte_event_eth_rx_adapter.c
>=20
> +
> +static inline void
> +fill_event_buffer(struct rte_event_eth_rx_adapter *rx_adapter,
> +	uint8_t dev_id,
> +	uint16_t rx_queue_id,
> +	struct rte_mbuf **mbufs,
> +	uint16_t num)
> +{
> +	uint32_t i;
> +	struct eth_device_info *eth_device_info =3D
> +					&rx_adapter->eth_devices[dev_id];
> +	struct eth_rx_queue_info *eth_rx_queue_info =3D
> +					&eth_device_info-
> >rx_queue[rx_queue_id];
> +
> +	int32_t qid =3D eth_rx_queue_info->event_queue_id;
> +	uint8_t sched_type =3D eth_rx_queue_info->sched_type;
> +	uint8_t priority =3D eth_rx_queue_info->priority;
> +	uint32_t flow_id;
> +	struct rte_event events[BATCH_SIZE];
> +	struct rte_mbuf *m =3D mbufs[0];
> +	uint32_t rss_mask;
> +	uint32_t rss;
> +	int do_rss;
> +
> +	/* 0xffff ffff if PKT_RX_RSS_HASH is set, otherwise 0 */
> +	rss_mask =3D ~(((m->ol_flags & PKT_RX_RSS_HASH) !=3D 0) - 1);
> +	do_rss =3D !rss_mask && !eth_rx_queue_info->flow_id_mask;
> +
> +	for (i =3D 0; i < num; i++) {
> +		m =3D mbufs[i];
> +		struct rte_event *ev =3D &events[i];
> +
> +		rss =3D do_rss ? do_softrss(m) : m->hash.rss;
> +		flow_id =3D
> +		    eth_rx_queue_info->flow_id &
> +				eth_rx_queue_info->flow_id_mask;
> +		flow_id |=3D rss & ~eth_rx_queue_info->flow_id_mask;
> +
> +		ev->flow_id =3D flow_id;
> +		ev->op =3D RTE_EVENT_OP_NEW;
> +		ev->sched_type =3D sched_type;
> +		ev->queue_id =3D qid;
> +		ev->event_type =3D RTE_EVENT_TYPE_ETHDEV;
> +		ev->sub_event_type =3D 0;
> +		ev->priority =3D priority;
> +		ev->mbuf =3D m;

How will the application get to know about the queue and eth_port from wher=
e the
packet is received by the eventdev? Is it the user responsibility to have t=
hat information
in the flow_id?

> +
> +		buf_event_enqueue(rx_adapter, ev);
> +	}
> +}
> +

<snip>

> +int
> +rte_event_eth_rx_adapter_queue_add(uint8_t id,
> +		uint8_t eth_dev_id,
> +		int32_t rx_queue_id,
> +		const struct rte_event_eth_rx_adapter_queue_conf
> *queue_conf)
> +{
> +	int ret;
> +	uint32_t rx_adapter_cap;
> +	struct rte_event_eth_rx_adapter *rx_adapter;
> +	struct rte_eventdev *dev;
> +	struct eth_device_info *dev_info;
> +	int start_service =3D 0;
> +
> +	RTE_EVENT_ETH_RX_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_dev_id, -EINVAL);
> +
> +	rx_adapter =3D id_to_rx_adapter(id);
> +	if (!rx_adapter || !queue_conf)
> +		return -EINVAL;
> +
> +	dev =3D &rte_eventdevs[rx_adapter->eventdev_id];
> +	ret =3D (*dev->dev_ops->eth_rx_adapter_caps_get)(dev, eth_dev_id,
> +						&rx_adapter_cap);
> +	if (ret) {
> +		RTE_EDEV_LOG_ERR("Failed to get adapter caps edev %" PRIu8
> +			"eth port %" PRIu8, id, eth_dev_id);
> +		return ret;
> +	}
> +
> +	if (!(rx_adapter_cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_FLOW_ID)
> &&
> +		!(queue_conf->rx_queue_flags &
> +
> 	RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID)) {
> +		RTE_EDEV_LOG_ERR("Flow ID required for configuration,"
> +				" eth port: %" PRIu8 " adapter id: %" PRIu8,
> +				eth_dev_id, id);
> +		return -EINVAL;
> +	}
> +
> +	if ((rx_adapter_cap &
> RTE_EVENT_ETH_RX_ADAPTER_CAP_SINGLE_EVENTQ) &&
> +		(rx_queue_id !=3D -1)) {
> +		RTE_EDEV_LOG_ERR("Rx queues can only be connected to
> single "
> +			"event queue id %u eth port %u", id, eth_dev_id);
> +		return -EINVAL;
> +	}
> +
> +	if (rx_queue_id !=3D -1 && (uint16_t)rx_queue_id >=3D
> +			rte_eth_devices[eth_dev_id].data->nb_rx_queues) {
> +		RTE_EDEV_LOG_ERR("Invalid rx queue_id %" PRIu16,
> +			 (uint16_t)rx_queue_id);
> +		return -EINVAL;
> +	}
> +
> +	start_service =3D 0;
> +	dev_info =3D &rx_adapter->eth_devices[eth_dev_id];
> +
> +	if (rx_adapter_cap &
> RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT) {
> +		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >eth_rx_adapter_queue_add,
> +					-ENOTSUP);
> +		if (!dev_info->rx_queue) {
> +			dev_info->rx_queue =3D
> +			    rte_zmalloc_socket(rx_adapter->mem_name,
> +					dev_info->dev->data->nb_rx_queues *
> +					sizeof(struct eth_rx_queue_info), 0,
> +					rx_adapter->socket_id);
> +			if (!dev_info->rx_queue)
> +				return -ENOMEM;
> +		}
> +
> +		ret =3D (*dev->dev_ops->eth_rx_adapter_queue_add)(dev,
> eth_dev_id,
> +				rx_queue_id, queue_conf);

IMO, Instead of eth_dev_id rte_eth_dev parameter should be passed to the un=
derlying driver.
Otherwise the underlying driver needs to use rte_eth_devices[] global varia=
ble to fetch the device.
This does not seems very right to me.

> +		if (!ret) {
> +			update_queue_info(rx_adapter,
> +					&rx_adapter-
> >eth_devices[eth_dev_id],
> +					rx_queue_id,
> +					1);
> +		}
> +	} else {
> +		rte_spinlock_lock(&rx_adapter->rx_lock);
> +		ret =3D init_service(rx_adapter, id);
> +		if (!ret)
> +			ret =3D add_rx_queue(rx_adapter, eth_dev_id,
> rx_queue_id,
> +					queue_conf);
> +		rte_spinlock_unlock(&rx_adapter->rx_lock);
> +		if (!ret)
> +			start_service =3D
> !!sw_rx_adapter_queue_count(rx_adapter);
> +	}
> +
> +	if (ret)
> +		return ret;
> +
> +	if (start_service)
> +		rte_service_component_runstate_set(rx_adapter->service_id,
> 1);
> +
> +	return 0;
> +}
> +
> +int
> +rte_event_eth_rx_adapter_queue_del(uint8_t id, uint8_t eth_dev_id,
> +				int32_t rx_queue_id)
> +{
> +	int ret =3D 0;
> +	struct rte_eventdev *dev;
> +	struct rte_event_eth_rx_adapter *rx_adapter;
> +	struct eth_device_info *dev_info;
> +	uint32_t rx_adapter_cap;
> +	uint16_t i;
> +
> +	RTE_EVENT_ETH_RX_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_dev_id, -EINVAL);
> +
> +	rx_adapter =3D id_to_rx_adapter(id);
> +	if (!rx_adapter)
> +		return -EINVAL;
> +
> +	dev =3D &rte_eventdevs[rx_adapter->eventdev_id];
> +	ret =3D dev->dev_ops->eth_rx_adapter_caps_get(dev, eth_dev_id,
> +						&rx_adapter_cap);
> +	if (ret)
> +		return ret;
> +
> +	if (rx_queue_id !=3D -1 && (uint16_t)rx_queue_id >=3D
> +		rte_eth_devices[eth_dev_id].data->nb_rx_queues) {
> +		RTE_EDEV_LOG_ERR("Invalid rx queue_id %" PRIu16,
> +			 (uint16_t)rx_queue_id);
> +		return -EINVAL;
> +	}
> +
> +	dev_info =3D &rx_adapter->eth_devices[eth_dev_id];
> +
> +	if (rx_adapter_cap &
> RTE_EVENT_ETH_RX_ADAPTER_CAP_INTERNAL_PORT) {
> +		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >eth_rx_adapter_queue_del,
> +				 -ENOTSUP);
> +		ret =3D (*dev->dev_ops->eth_rx_adapter_queue_del)(dev,
> eth_dev_id,
> +							rx_queue_id);

Here too rte_eth_device shall be passed.

> +		if (!ret) {
> +			update_queue_info(rx_adapter,
> +					&rx_adapter-
> >eth_devices[eth_dev_id],
> +					rx_queue_id,
> +					0);
> +			if (!dev_info->nb_dev_queues) {
> +				rte_free(dev_info->rx_queue);
> +				dev_info->rx_queue =3D NULL;
> +			}
> +		}
> +	} else {
> +		int rc;
> +		rte_spinlock_lock(&rx_adapter->rx_lock);
> +		if (rx_queue_id =3D=3D -1) {
> +			for (i =3D 0; i < dev_info->dev->data->nb_rx_queues; i++)
> +
> 	_rte_event_eth_rx_adapter_queue_del(rx_adapter,
> +								dev_info,
> +								i);
> +		} else {
> +			_rte_event_eth_rx_adapter_queue_del(rx_adapter,
> +							dev_info,
> +
> 	(uint16_t)rx_queue_id);
> +		}
> +
> +		rc =3D eth_poll_wrr_calc(rx_adapter);
> +		if (rc)
> +			RTE_EDEV_LOG_ERR("WRR recalculation failed %"
> PRId32,
> +					rc);
> +
> +		if (!dev_info->nb_dev_queues) {
> +			rte_free(dev_info->rx_queue);
> +			dev_info->rx_queue =3D NULL;
> +		}
> +
> +		rte_spinlock_unlock(&rx_adapter->rx_lock);
> +		rte_service_component_runstate_set(rx_adapter->service_id,
> +				sw_rx_adapter_queue_count(rx_adapter));
> +	}
> +
> +	return ret;
> +}
> +
> +
> +int
> +rte_event_eth_rx_adapter_start(uint8_t id)
> +{
> +	return rx_adapter_ctrl(id, 1);
> +}
> +
> +int
> +rte_event_eth_rx_adapter_stop(uint8_t id)
> +{
> +	return rx_adapter_ctrl(id, 0);
> +}
> +
> +int
> +rte_event_eth_rx_adapter_stats_get(uint8_t id,
> +			       struct rte_event_eth_rx_adapter_stats *stats)
> +{
> +	struct rte_event_eth_rx_adapter *rx_adapter;
> +	struct rte_event_eth_rx_adapter_stats dev_stats_sum =3D { 0 };
> +	struct rte_event_eth_rx_adapter_stats dev_stats;
> +	struct rte_eventdev *dev;
> +	struct eth_device_info *dev_info;
> +	uint32_t i;
> +	int ret;
> +
> +	RTE_EVENT_ETH_RX_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
> +
> +	rx_adapter =3D id_to_rx_adapter(id);
> +	if (!rx_adapter || !stats)
> +		return -EINVAL;
> +
> +	dev =3D &rte_eventdevs[rx_adapter->eventdev_id];
> +	memset(stats, 0, sizeof(*stats));
> +	for (i =3D 0; i < rte_eth_dev_count(); i++) {
> +		dev_info =3D &rx_adapter->eth_devices[i];
> +		if (!dev_info->internal_event_port)
> +			continue;
> +		ret =3D (*dev->dev_ops->eth_rx_adapter_stats_get)(dev, i,
> +						&dev_stats);

Preferable to check if the adapter stats get and stats set API are register=
ed from the driver.

Regards,
Nipun