[dpdk-dev,5/9] raw/dpaa2_cmdif: introduce DPAA2 command interface driver
Checks
Commit Message
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
MAINTAINERS | 6 +
config/common_armv8a_linuxapp | 5 +
config/common_base | 5 +
config/defconfig_arm64-dpaa2-linuxapp-gcc | 6 +
drivers/raw/Makefile | 1 +
drivers/raw/dpaa2_cmdif/Makefile | 33 +++++
drivers/raw/dpaa2_cmdif/dpaa2_cmdif.c | 139 +++++++++++++++++++++
drivers/raw/dpaa2_cmdif/dpaa2_cmdif_logs.h | 35 ++++++
.../dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map | 4 +
mk/rte.app.mk | 1 +
10 files changed, 235 insertions(+)
create mode 100644 drivers/raw/dpaa2_cmdif/Makefile
create mode 100644 drivers/raw/dpaa2_cmdif/dpaa2_cmdif.c
create mode 100644 drivers/raw/dpaa2_cmdif/dpaa2_cmdif_logs.h
create mode 100644 drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map
Comments
Hi Nipun,
Some trivial inputs:
On Thursday 22 February 2018 03:04 PM, Nipun Gupta wrote:
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
> MAINTAINERS | 6 +
> config/common_armv8a_linuxapp | 5 +
> config/common_base | 5 +
> config/defconfig_arm64-dpaa2-linuxapp-gcc | 6 +
> drivers/raw/Makefile | 1 +
> drivers/raw/dpaa2_cmdif/Makefile | 33 +++++
> drivers/raw/dpaa2_cmdif/dpaa2_cmdif.c | 139 +++++++++++++++++++++
> drivers/raw/dpaa2_cmdif/dpaa2_cmdif_logs.h | 35 ++++++
> .../dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map | 4 +
> mk/rte.app.mk | 1 +
> 10 files changed, 235 insertions(+)
> create mode 100644 drivers/raw/dpaa2_cmdif/Makefile
> create mode 100644 drivers/raw/dpaa2_cmdif/dpaa2_cmdif.c
> create mode 100644 drivers/raw/dpaa2_cmdif/dpaa2_cmdif_logs.h
> create mode 100644 drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a646ca3..e06df3b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -725,6 +725,12 @@ F: drivers/crypto/zuc/
> F: doc/guides/cryptodevs/zuc.rst
> F: doc/guides/cryptodevs/features/zuc.ini
>
> +Rawdev Drivers
> +--------------
> +
> +DPAA2 CMDIF
> +M: Nipun Gupta <nipun.gupta@nxp.com>
> +F: drivers/raw/dpaa2_cmdif/
I think you should put one more new line here. For all the sub-section
for Maintainers, there are 2 new lines before new sub-section starts.
>
> Eventdev Drivers
> ----------------
> diff --git a/config/common_armv8a_linuxapp b/config/common_armv8a_linuxapp
> index 507b28a..32e3cfe 100644
> --- a/config/common_armv8a_linuxapp
> +++ b/config/common_armv8a_linuxapp
> @@ -94,3 +94,8 @@ CONFIG_RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS=2048
> #
> CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
> CONFIG_RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS=2048
> +
> +#
> +# Compile DPAA2 Command Intefrace driver
^^^^^^^^^
Interface - spell mistake
> +#
> +CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=y
> diff --git a/config/common_base b/config/common_base
> index ad03cf4..a549b54 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -587,6 +587,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
> CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
>
> #
> +# Compile DPAA2 CMDIF support
> +#
> +CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=n
> +
> +#
> # Compile librte_ring
> #
> CONFIG_RTE_LIBRTE_RING=y
> diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> index afdbc34..ce1ffc5 100644
> --- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
> +++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> @@ -42,3 +42,9 @@ CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE=n
> CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_INIT=n
> CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_DRIVER=n
> CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_RX=n
> +
> +#
> +# Compile DPAA2 Command Intefrace driver
> +#
> +CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=y
If already added in armv8a, why is it required in arm64-dpaa2 as well?
Rawdevices are intended to be custom and I think they should be added
only to the SoC specific configuration files.
-
Shreyansh
-----Original Message-----
> Date: Thu, 22 Feb 2018 15:04:45 +0530
> From: Nipun Gupta <nipun.gupta@nxp.com>
> To: thomas@monjalon.net, hemant.agrawal@nxp.com, shreyansh.jain@nxp.com
> CC: dev@dpdk.org, Nipun Gupta <nipun.gupta@nxp.com>
> Subject: [dpdk-dev] [PATCH 5/9] raw/dpaa2_cmdif: introduce DPAA2 command
> interface driver
> X-Mailer: git-send-email 1.9.1
>
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
> MAINTAINERS | 6 +
> config/common_armv8a_linuxapp | 5 +
Please move this change to common config.
We already agreed that you guys move the changes to common config in
this release.
I would like to avoid any compilation errors specific only to arm64
such as this
https://dpdk.org/ml/archives/dev/2018-February/091336.html
> -----Original Message-----
> From: Shreyansh Jain
> Sent: Thursday, February 22, 2018 18:42
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: thomas@monjalon.net; Hemant Agrawal <hemant.agrawal@nxp.com>;
> dev@dpdk.org
> Subject: Re: [PATCH 5/9] raw/dpaa2_cmdif: introduce DPAA2 command
> interface driver
>
> Hi Nipun,
>
> Some trivial inputs:
>
> On Thursday 22 February 2018 03:04 PM, Nipun Gupta wrote:
> > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > ---
> > MAINTAINERS | 6 +
> > config/common_armv8a_linuxapp | 5 +
> > config/common_base | 5 +
> > config/defconfig_arm64-dpaa2-linuxapp-gcc | 6 +
> > drivers/raw/Makefile | 1 +
> > drivers/raw/dpaa2_cmdif/Makefile | 33 +++++
> > drivers/raw/dpaa2_cmdif/dpaa2_cmdif.c | 139
> +++++++++++++++++++++
> > drivers/raw/dpaa2_cmdif/dpaa2_cmdif_logs.h | 35 ++++++
> > .../dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map | 4 +
> > mk/rte.app.mk | 1 +
> > 10 files changed, 235 insertions(+)
> > create mode 100644 drivers/raw/dpaa2_cmdif/Makefile
> > create mode 100644 drivers/raw/dpaa2_cmdif/dpaa2_cmdif.c
> > create mode 100644 drivers/raw/dpaa2_cmdif/dpaa2_cmdif_logs.h
> > create mode 100644
> drivers/raw/dpaa2_cmdif/rte_pmd_dpaa2_cmdif_version.map
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index a646ca3..e06df3b 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -725,6 +725,12 @@ F: drivers/crypto/zuc/
> > F: doc/guides/cryptodevs/zuc.rst
> > F: doc/guides/cryptodevs/features/zuc.ini
> >
> > +Rawdev Drivers
> > +--------------
> > +
> > +DPAA2 CMDIF
> > +M: Nipun Gupta <nipun.gupta@nxp.com>
> > +F: drivers/raw/dpaa2_cmdif/
>
> I think you should put one more new line here. For all the sub-section
> for Maintainers, there are 2 new lines before new sub-section starts.
Agree.. I'll take care in the next version.
>
> >
> > Eventdev Drivers
> > ----------------
> > diff --git a/config/common_armv8a_linuxapp
> b/config/common_armv8a_linuxapp
> > index 507b28a..32e3cfe 100644
> > --- a/config/common_armv8a_linuxapp
> > +++ b/config/common_armv8a_linuxapp
> > @@ -94,3 +94,8 @@
> CONFIG_RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS=2048
> > #
> > CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
> > CONFIG_RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS=2048
> > +
> > +#
> > +# Compile DPAA2 Command Intefrace driver
> ^^^^^^^^^
> Interface - spell mistake
Agree. I will update.
>
> > +#
> > +CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=y
> > diff --git a/config/common_base b/config/common_base
> > index ad03cf4..a549b54 100644
> > --- a/config/common_base
> > +++ b/config/common_base
> > @@ -587,6 +587,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
> > CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
> >
> > #
> > +# Compile DPAA2 CMDIF support
> > +#
> > +CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=n
> > +
> > +#
> > # Compile librte_ring
> > #
> > CONFIG_RTE_LIBRTE_RING=y
> > diff --git a/config/defconfig_arm64-dpaa2-linuxapp-gcc
> b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> > index afdbc34..ce1ffc5 100644
> > --- a/config/defconfig_arm64-dpaa2-linuxapp-gcc
> > +++ b/config/defconfig_arm64-dpaa2-linuxapp-gcc
> > @@ -42,3 +42,9 @@ CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE=n
> > CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_INIT=n
> > CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_DRIVER=n
> > CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_RX=n
> > +
> > +#
> > +# Compile DPAA2 Command Intefrace driver
> > +#
> > +CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=y
>
> If already added in armv8a, why is it required in arm64-dpaa2 as well?
> Rawdevices are intended to be custom and I think they should be added
> only to the SoC specific configuration files.
As I understand you suggest this to be part of only arm64-dpaa2 and not in armv8a?
Thanks,
Nipun
>
> -
> Shreyansh
> -----Original Message-----
> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> Sent: Thursday, February 22, 2018 20:02
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: thomas@monjalon.net; Hemant Agrawal <hemant.agrawal@nxp.com>;
> Shreyansh Jain <shreyansh.jain@nxp.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 5/9] raw/dpaa2_cmdif: introduce DPAA2
> command interface driver
>
> -----Original Message-----
> > Date: Thu, 22 Feb 2018 15:04:45 +0530
> > From: Nipun Gupta <nipun.gupta@nxp.com>
> > To: thomas@monjalon.net, hemant.agrawal@nxp.com,
> shreyansh.jain@nxp.com
> > CC: dev@dpdk.org, Nipun Gupta <nipun.gupta@nxp.com>
> > Subject: [dpdk-dev] [PATCH 5/9] raw/dpaa2_cmdif: introduce DPAA2
> command
> > interface driver
> > X-Mailer: git-send-email 1.9.1
> >
> > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > ---
> > MAINTAINERS | 6 +
> > config/common_armv8a_linuxapp | 5 +
>
> Please move this change to common config.
> We already agreed that you guys move the changes to common config in
> this release.
Okay Jerin. We will look into this.
Thanks,
Nipun
>
> I would like to avoid any compilation errors specific only to arm64
> such as this
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdpdk.o
> rg%2Fml%2Farchives%2Fdev%2F2018-
> February%2F091336.html&data=02%7C01%7Cnipun.gupta%40nxp.com%7C631
> e2e423f7e4ee6d74908d57a01123c%7C686ea1d3bc2b4c6fa92cd99c5c301635%
> 7C0%7C0%7C636549067385804564&sdata=dinNVoUori7dnl2PaviflV9FeR%2Bj7
> UUpjDexGaxAA60%3D&reserved=0
>
>
@@ -725,6 +725,12 @@ F: drivers/crypto/zuc/
F: doc/guides/cryptodevs/zuc.rst
F: doc/guides/cryptodevs/features/zuc.ini
+Rawdev Drivers
+--------------
+
+DPAA2 CMDIF
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/raw/dpaa2_cmdif/
Eventdev Drivers
----------------
@@ -94,3 +94,8 @@ CONFIG_RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS=2048
#
CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC=y
CONFIG_RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS=2048
+
+#
+# Compile DPAA2 Command Intefrace driver
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=y
@@ -587,6 +587,11 @@ CONFIG_RTE_RAWDEV_MAX_DEVS=10
CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y
#
+# Compile DPAA2 CMDIF support
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=n
+
+#
# Compile librte_ring
#
CONFIG_RTE_LIBRTE_RING=y
@@ -42,3 +42,9 @@ CONFIG_RTE_LIBRTE_DPAA2_DEBUG_TX_FREE=n
CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_INIT=n
CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_DPAA2_SEC_DEBUG_RX=n
+
+#
+# Compile DPAA2 Command Intefrace driver
+#
+CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF=y
+
@@ -5,5 +5,6 @@ include $(RTE_SDK)/mk/rte.vars.mk
# DIRS-$(<configuration>) += <directory>
DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF) += dpaa2_cmdif
include $(RTE_SDK)/mk/rte.subdir.mk
new file mode 100644
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2018 NXP
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_dpaa2_cmdif.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc
+CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include
+
+LDLIBS += -lrte_bus_fslmc
+LDLIBS += -lrte_eal
+LDLIBS += -lrte_rawdev
+LDLIBS += -lrte_bus_vdev
+LDLIBS += -lrte_kvargs
+
+EXPORT_MAP := rte_pmd_dpaa2_cmdif_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF) += dpaa2_cmdif.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
new file mode 100644
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <rte_bus_vdev.h>
+#include <rte_atomic.h>
+#include <rte_interrupts.h>
+#include <rte_branch_prediction.h>
+#include <rte_lcore.h>
+
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include <portal/dpaa2_hw_pvt.h>
+#include <portal/dpaa2_hw_dpio.h>
+#include "rte_pmd_dpaa2_cmdif.h"
+#include "dpaa2_cmdif_logs.h"
+
+/* Dynamic log type identifier */
+int dpaa2_cmdif_logtype;
+
+/* CMDIF driver name */
+#define DPAA2_CMDIF_PMD_NAME dpaa2_dpci
+
+/* CMDIF driver object */
+static struct rte_vdev_driver dpaa2_cmdif_drv;
+
+static const struct rte_rawdev_ops dpaa2_cmdif_ops = {
+};
+
+static int
+dpaa2_cmdif_create(const char *name,
+ struct rte_vdev_device *vdev,
+ int socket_id)
+{
+ struct rte_rawdev *rawdev;
+ struct dpaa2_dpci_dev *cidev;
+
+ /* Allocate device structure */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct dpaa2_dpci_dev),
+ socket_id);
+ if (!rawdev) {
+ DPAA2_CMDIF_ERR("Unable to allocate rawdevice");
+ return -EINVAL;
+ }
+
+ rawdev->dev_ops = &dpaa2_cmdif_ops;
+ rawdev->device = &vdev->device;
+ rawdev->driver_name = vdev->device.driver->name;
+
+ /* For secondary processes, the primary has done all the work */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ cidev = rte_dpaa2_alloc_dpci_dev();
+ if (!cidev) {
+ DPAA2_CMDIF_ERR("Unable to allocate CI device");
+ rte_rawdev_pmd_release(rawdev);
+ return -ENODEV;
+ }
+
+ rawdev->dev_private = cidev;
+
+ return 0;
+}
+
+static int
+dpaa2_cmdif_destroy(const char *name)
+{
+ int ret;
+ struct rte_rawdev *rdev;
+
+ rdev = rte_rawdev_pmd_get_named_dev(name);
+ if (!rdev) {
+ DPAA2_CMDIF_ERR("Invalid device name (%s)", name);
+ return -EINVAL;
+ }
+
+ /* The primary process will only free the DPCI device */
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_dpaa2_free_dpci_dev(rdev->dev_private);
+
+ ret = rte_rawdev_pmd_release(rdev);
+ if (ret)
+ DPAA2_CMDIF_DEBUG("Device cleanup failed");
+
+ return 0;
+}
+
+static int
+dpaa2_cmdif_probe(struct rte_vdev_device *vdev)
+{
+ const char *name;
+ int ret = 0;
+
+ name = rte_vdev_device_name(vdev);
+
+ DPAA2_CMDIF_INFO("Init %s on NUMA node %d", name, rte_socket_id());
+
+ ret = dpaa2_cmdif_create(name, vdev, rte_socket_id());
+
+ return ret;
+}
+
+static int
+dpaa2_cmdif_remove(struct rte_vdev_device *vdev)
+{
+ const char *name;
+ int ret;
+
+ name = rte_vdev_device_name(vdev);
+
+ DPAA2_CMDIF_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
+
+ ret = dpaa2_cmdif_destroy(name);
+
+ return ret;
+}
+
+static struct rte_vdev_driver dpaa2_cmdif_drv = {
+ .probe = dpaa2_cmdif_probe,
+ .remove = dpaa2_cmdif_remove
+};
+
+RTE_PMD_REGISTER_VDEV(DPAA2_CMDIF_PMD_NAME, dpaa2_cmdif_drv);
+
+RTE_INIT(dpaa2_cmdif_init_log);
+
+static void
+dpaa2_cmdif_init_log(void)
+{
+ dpaa2_cmdif_logtype = rte_log_register("dpaa2.cmdif");
+ if (dpaa2_cmdif_logtype >= 0)
+ rte_log_set_level(dpaa2_cmdif_logtype, RTE_LOG_INFO);
+}
new file mode 100644
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2018 NXP
+ */
+
+#ifndef __DPAA2_CMDIF_LOGS_H__
+#define __DPAA2_CMDIF_LOGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_rawdev.h>
+
+extern int dpaa2_cmdif_logtype;
+
+#define DPAA2_CMDIF_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, dpaa2_cmdif_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+#define DPAA2_CMDIF_FUNC_TRACE() DPAA2_CMDIF_LOG(DEBUG, ">>")
+
+#define DPAA2_CMDIF_DEBUG(fmt, args...) \
+ DPAA2_CMDIF_LOG(DEBUG, fmt, ## args)
+#define DPAA2_CMDIF_INFO(fmt, args...) \
+ DPAA2_CMDIF_LOG(INFO, fmt, ## args)
+#define DPAA2_CMDIF_ERR(fmt, args...) \
+ DPAA2_CMDIF_LOG(ERR, fmt, ## args)
+#define DPAA2_CMDIF_WARN(fmt, args...) \
+ DPAA2_CMDIF_LOG(WARNING, fmt, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DPAA2_CMDIF_LOGS_H__ */
new file mode 100644
@@ -0,0 +1,4 @@
+DPDK_18.05 {
+
+ local: *;
+};
@@ -230,6 +230,7 @@ endif # CONFIG_RTE_LIBRTE_EVENTDEV
ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF) += -lrte_pmd_dpaa2_cmdif
endif # CONFIG_RTE_LIBRTE_RAWDEV
ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y)