aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.14/702-dpaa2-ethernet-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.14/702-dpaa2-ethernet-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.14/702-dpaa2-ethernet-support-layerscape.patch3605
1 files changed, 2329 insertions, 1276 deletions
diff --git a/target/linux/layerscape/patches-4.14/702-dpaa2-ethernet-support-layerscape.patch b/target/linux/layerscape/patches-4.14/702-dpaa2-ethernet-support-layerscape.patch
index 44cedd1237..9ccacba3ae 100644
--- a/target/linux/layerscape/patches-4.14/702-dpaa2-ethernet-support-layerscape.patch
+++ b/target/linux/layerscape/patches-4.14/702-dpaa2-ethernet-support-layerscape.patch
@@ -1,33 +1,42 @@
-From 6ec4d0cf0b0e5e41abc91012db4ebff7d415a92b Mon Sep 17 00:00:00 2001
+From 90b3f1705785f0e30de6f41abc8764aae1391245 Mon Sep 17 00:00:00 2001
From: Biwen Li <biwen.li@nxp.com>
-Date: Tue, 30 Oct 2018 18:26:13 +0800
-Subject: [PATCH 08/40] dpaa2-ethernet: support layerscape
-This is an integrated patch of dpaa2-ethernet for
- layerscape
+Date: Wed, 17 Apr 2019 18:58:28 +0800
+Subject: [PATCH] dpaa2-ethernet: support layerscape
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+This is an integrated patch of dpaa2-ethernet for layerscape
+
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Guanhua Gao <guanhua.gao@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
+Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
+Signed-off-by: Valentin Catalin Neacsu <valentin-catalin.neacsu@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
-Signed-off-by: Biwen Li <biwen.li@nxp.com>
---
drivers/staging/fsl-dpaa2/Kconfig | 7 +
- drivers/staging/fsl-dpaa2/ethernet/Makefile | 2 +
- .../fsl-dpaa2/ethernet/dpaa2-eth-ceetm.c | 1240 +++++++++
+ drivers/staging/fsl-dpaa2/ethernet/Makefile | 3 +
+ .../fsl-dpaa2/ethernet/dpaa2-eth-ceetm.c | 1187 ++++++++
.../fsl-dpaa2/ethernet/dpaa2-eth-ceetm.h | 183 ++
- .../fsl-dpaa2/ethernet/dpaa2-eth-debugfs.c | 357 +++
+ .../fsl-dpaa2/ethernet/dpaa2-eth-debugfs.c | 356 +++
.../fsl-dpaa2/ethernet/dpaa2-eth-debugfs.h | 60 +
- .../staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 2335 +++++++++++++----
- .../staging/fsl-dpaa2/ethernet/dpaa2-eth.h | 388 ++-
- .../fsl-dpaa2/ethernet/dpaa2-ethtool.c | 625 ++++-
- drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h | 192 +-
- drivers/staging/fsl-dpaa2/ethernet/dpni.c | 604 ++++-
- drivers/staging/fsl-dpaa2/ethernet/dpni.h | 344 ++-
- 12 files changed, 5723 insertions(+), 614 deletions(-)
+ .../fsl-dpaa2/ethernet/dpaa2-eth-trace.h | 29 +-
+ .../staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 2509 +++++++++++++----
+ .../staging/fsl-dpaa2/ethernet/dpaa2-eth.h | 394 ++-
+ .../fsl-dpaa2/ethernet/dpaa2-ethtool.c | 716 ++++-
+ drivers/staging/fsl-dpaa2/ethernet/dpkg.h | 380 ++-
+ drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h | 255 +-
+ drivers/staging/fsl-dpaa2/ethernet/dpni.c | 704 ++++-
+ drivers/staging/fsl-dpaa2/ethernet/dpni.h | 401 ++-
+ drivers/staging/fsl-dpaa2/ethernet/net.h | 30 +-
+ 15 files changed, 6315 insertions(+), 899 deletions(-)
create mode 100644 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth-ceetm.c
create mode 100644 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth-ceetm.h
create mode 100644 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth-debugfs.c
@@ -51,7 +60,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
bool "Enable Rx error queue"
--- a/drivers/staging/fsl-dpaa2/ethernet/Makefile
+++ b/drivers/staging/fsl-dpaa2/ethernet/Makefile
-@@ -5,6 +5,8 @@
+@@ -1,3 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0
+ #
+ # Makefile for the Freescale DPAA2 Ethernet controller
+ #
+@@ -5,6 +6,8 @@
obj-$(CONFIG_FSL_DPAA2_ETH) += fsl-dpaa2-eth.o
fsl-dpaa2-eth-objs := dpaa2-eth.o dpaa2-ethtool.o dpni.o
@@ -62,10 +76,10 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
CFLAGS_dpaa2-eth.o := -I$(src)
--- /dev/null
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth-ceetm.c
-@@ -0,0 +1,1240 @@
+@@ -0,0 +1,1187 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
-+ * Copyright 2017 NXP
++ * Copyright 2017-2019 NXP
+ *
+ */
+
@@ -197,7 +211,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ enum update_tx_prio type)
+{
+ struct dpaa2_ceetm_qdisc *sch = qdisc_priv(cl->parent);
-+ struct dpni_congestion_notification_cfg notif_cfg = {0};
+ struct dpni_tx_schedule_cfg *sched_cfg;
+ struct dpni_taildrop td = {0};
+ u8 ch_id = 0, tc_id = 0;
@@ -209,18 +222,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+ switch (type) {
+ case DPAA2_ETH_ADD_CQ:
-+ /* Disable congestion notifications */
-+ notif_cfg.threshold_entry = 0;
-+ notif_cfg.threshold_exit = 0;
-+ err = dpni_set_congestion_notification(priv->mc_io, 0,
-+ priv->mc_token,
-+ DPNI_QUEUE_TX, tc_id,
-+ &notif_cfg);
-+ if (err) {
-+ netdev_err(priv->net_dev, "Error disabling congestion notifications %d\n",
-+ err);
-+ return err;
-+ }
+ /* Enable taildrop */
+ td.enable = 1;
+ td.units = DPNI_CONGESTION_UNIT_FRAMES;
@@ -245,24 +246,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ err);
+ return err;
+ }
-+ /* Enable congestion notifications */
-+ notif_cfg.units = DPNI_CONGESTION_UNIT_BYTES;
-+ notif_cfg.threshold_entry = DPAA2_ETH_TX_CONG_ENTRY_THRESH;
-+ notif_cfg.threshold_exit = DPAA2_ETH_TX_CONG_EXIT_THRESH;
-+ notif_cfg.message_ctx = (u64)priv;
-+ notif_cfg.message_iova = priv->cscn_dma;
-+ notif_cfg.notification_mode = DPNI_CONG_OPT_WRITE_MEM_ON_ENTER |
-+ DPNI_CONG_OPT_WRITE_MEM_ON_EXIT |
-+ DPNI_CONG_OPT_COHERENT_WRITE;
-+ err = dpni_set_congestion_notification(priv->mc_io, 0,
-+ priv->mc_token,
-+ DPNI_QUEUE_TX, tc_id,
-+ &notif_cfg);
-+ if (err) {
-+ netdev_err(priv->net_dev, "Error enabling congestion notifications %d\n",
-+ err);
-+ return err;
-+ }
+ break;
+ }
+
@@ -564,15 +547,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ struct netdev_queue *dev_queue;
+ unsigned int i, parent_id;
+ struct Qdisc *qdisc;
-+ int err;
+
+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
+
+ /* Validate inputs */
+ if (sch->parent != TC_H_ROOT) {
-+ pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n");
-+ tcf_block_put(priv->block);
-+ qdisc_class_hash_destroy(&priv->clhash);
++ pr_err("CEETM: a root ceetm qdisc must be root\n");
+ return -EINVAL;
+ }
+
@@ -589,10 +569,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ priv->root.qdiscs = kcalloc(dev->num_tx_queues,
+ sizeof(priv->root.qdiscs[0]),
+ GFP_KERNEL);
-+ if (!priv->root.qdiscs) {
-+ err = -ENOMEM;
-+ goto err_init_root;
-+ }
++ if (!priv->root.qdiscs)
++ return -ENOMEM;
+
+ for (i = 0; i < dev->num_tx_queues; i++) {
+ dev_queue = netdev_get_tx_queue(dev, i);
@@ -601,10 +579,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+ qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
+ parent_id);
-+ if (!qdisc) {
-+ err = -ENOMEM;
-+ goto err_init_root;
-+ }
++ if (!qdisc)
++ return -ENOMEM;
+
+ priv->root.qdiscs[i] = qdisc;
+ qdisc->flags |= TCQ_F_ONETXQUEUE;
@@ -616,16 +592,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ if (!priv->root.qstats) {
+ pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
+ __func__);
-+ err = -ENOMEM;
-+ goto err_init_root;
++ return -ENOMEM;
+ }
+
+ dpaa2_eth_ceetm_enable(priv_eth);
+ return 0;
-+
-+err_init_root:
-+ dpaa2_ceetm_destroy(sch);
-+ return err;
+}
+
+/* Configure a prio ceetm qdisc */
@@ -636,21 +607,18 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ struct net_device *dev = qdisc_dev(sch);
+ struct dpaa2_ceetm_class *parent_cl;
+ struct Qdisc *parent_qdisc;
-+ int err;
+
+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
+
+ if (sch->parent == TC_H_ROOT) {
+ pr_err("CEETM: a prio ceetm qdisc can not be root\n");
-+ err = -EINVAL;
-+ goto err_init_prio;
++ return -EINVAL;
+ }
+
+ parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
+ if (strcmp(parent_qdisc->ops->id, dpaa2_ceetm_qdisc_ops.id)) {
+ pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
-+ err = -EINVAL;
-+ goto err_init_prio;
++ return -EINVAL;
+ }
+
+ /* Obtain the parent root ceetm_class */
@@ -658,20 +626,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+ if (!parent_cl || parent_cl->type != CEETM_ROOT) {
+ pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
-+ err = -EINVAL;
-+ goto err_init_prio;
++ return -EINVAL;
+ }
+
+ priv->prio.parent = parent_cl;
+ parent_cl->child = sch;
+
-+ err = dpaa2_ceetm_change_prio(sch, priv, qopt);
-+
-+ return 0;
-+
-+err_init_prio:
-+ dpaa2_ceetm_destroy(sch);
-+ return err;
++ return dpaa2_ceetm_change_prio(sch, priv, qopt);
+}
+
+/* Configure a generic ceetm qdisc */
@@ -741,7 +702,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ break;
+ default:
+ pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
-+ dpaa2_ceetm_destroy(sch);
++ /* Note: dpaa2_ceetm_destroy() will be called by our caller */
+ err = -EINVAL;
+ }
+
@@ -1491,7 +1452,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif
--- /dev/null
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth-debugfs.c
-@@ -0,0 +1,357 @@
+@@ -0,0 +1,356 @@
+
+/* Copyright 2015 Freescale Semiconductor Inc.
+ *
@@ -1605,9 +1566,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ int i, err;
+
+ seq_printf(file, "non-zero FQ stats for %s:\n", priv->net_dev->name);
-+ seq_printf(file, "%s%16s%16s%16s%16s%16s%16s\n",
++ seq_printf(file, "%s%16s%16s%16s%16s%16s\n",
+ "VFQID", "CPU", "Traffic Class", "Type", "Frames",
-+ "Pending frames", "Congestion");
++ "Pending frames");
+
+ for (i = 0; i < priv->num_fqs; i++) {
+ fq = &priv->fq[i];
@@ -1619,14 +1580,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ if (!fq->stats.frames && !fcnt)
+ continue;
+
-+ seq_printf(file, "%5d%16d%16d%16s%16llu%16u%16llu\n",
++ seq_printf(file, "%5d%16d%16d%16s%16llu%16u\n",
+ fq->fqid,
+ fq->target_cpu,
+ fq->tc,
+ fq_type_to_str(fq),
+ fq->stats.frames,
-+ fcnt,
-+ fq->stats.congestion_entry);
++ fcnt);
+ }
+
+ return 0;
@@ -1912,9 +1872,80 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* CONFIG_FSL_DPAA2_ETH_DEBUGFS */
+
+#endif /* DPAA2_ETH_DEBUGFS_H */
+--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth-trace.h
++++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth-trace.h
+@@ -1,32 +1,5 @@
++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+ /* Copyright 2014-2015 Freescale Semiconductor Inc.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of Freescale Semiconductor nor the
+- * names of its contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ #undef TRACE_SYSTEM
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
-@@ -38,9 +38,14 @@
+@@ -1,33 +1,6 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+ /* Copyright 2014-2016 Freescale Semiconductor Inc.
+ * Copyright 2016-2017 NXP
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of Freescale Semiconductor nor the
+- * names of its contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ #include <linux/init.h>
+ #include <linux/module.h>
+@@ -38,9 +11,14 @@
#include <linux/msi.h>
#include <linux/kthread.h>
#include <linux/iommu.h>
@@ -1930,7 +1961,16 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
* using trace events only need to #include <trace/events/sched.h>
-@@ -104,13 +109,15 @@ static void free_rx_fd(struct dpaa2_eth_
+@@ -52,8 +30,6 @@ MODULE_LICENSE("Dual BSD/GPL");
+ MODULE_AUTHOR("Freescale Semiconductor, Inc");
+ MODULE_DESCRIPTION("Freescale DPAA2 Ethernet Driver");
+
+-const char dpaa2_eth_drv_version[] = "0.1";
+-
+ static void *dpaa2_iova_to_virt(struct iommu_domain *domain,
+ dma_addr_t iova_addr)
+ {
+@@ -104,26 +80,27 @@ static void free_rx_fd(struct dpaa2_eth_
/* We don't support any other format */
return;
@@ -1943,28 +1983,47 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ for (i = 1; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) {
addr = dpaa2_sg_get_addr(&sgt[i]);
sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
- dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
+- dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
-+ DMA_BIDIRECTIONAL);
++ dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
++ DMA_BIDIRECTIONAL);
- skb_free_frag(sg_vaddr);
+- skb_free_frag(sg_vaddr);
++ free_pages((unsigned long)sg_vaddr, 0);
if (dpaa2_sg_is_final(&sgt[i]))
-@@ -133,8 +140,7 @@ static struct sk_buff *build_linear_skb(
+ break;
+ }
+
+ free_buf:
+- skb_free_frag(vaddr);
++ free_pages((unsigned long)vaddr, 0);
+ }
+
+ /* Build a linear skb based on a single-buffer frame descriptor */
+-static struct sk_buff *build_linear_skb(struct dpaa2_eth_priv *priv,
+- struct dpaa2_eth_channel *ch,
++static struct sk_buff *build_linear_skb(struct dpaa2_eth_channel *ch,
+ const struct dpaa2_fd *fd,
+ void *fd_vaddr)
+ {
+@@ -133,8 +110,7 @@ static struct sk_buff *build_linear_skb(
ch->buf_count--;
- skb = build_skb(fd_vaddr, DPAA2_ETH_RX_BUF_SIZE +
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
-+ skb = build_skb(fd_vaddr, DPAA2_ETH_SKB_SIZE);
++ skb = build_skb(fd_vaddr, DPAA2_ETH_RX_BUF_RAW_SIZE);
if (unlikely(!skb))
return NULL;
-@@ -170,15 +176,19 @@ static struct sk_buff *build_frag_skb(st
+@@ -169,16 +145,20 @@ static struct sk_buff *build_frag_skb(st
+ /* Get the address and length from the S/G entry */
sg_addr = dpaa2_sg_get_addr(sge);
sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, sg_addr);
- dma_unmap_single(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE,
+- dma_unmap_single(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
-+ DMA_BIDIRECTIONAL);
++ dma_unmap_page(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE,
++ DMA_BIDIRECTIONAL);
sg_length = dpaa2_sg_get_len(sge);
@@ -1972,17 +2031,17 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* We build the skb around the first data buffer */
- skb = build_skb(sg_vaddr, DPAA2_ETH_RX_BUF_SIZE +
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
-+ skb = build_skb(sg_vaddr, DPAA2_ETH_SKB_SIZE);
++ skb = build_skb(sg_vaddr, DPAA2_ETH_RX_BUF_RAW_SIZE);
if (unlikely(!skb)) {
+ /* Free the first SG entry now, since we already
+ * unmapped it and obtained the virtual address
+ */
-+ skb_free_frag(sg_vaddr);
++ free_pages((unsigned long)sg_vaddr, 0);
+
/* We still need to subtract the buffers used
* by this FD from our software counter
*/
-@@ -213,17 +223,173 @@ static struct sk_buff *build_frag_skb(st
+@@ -213,17 +193,172 @@ static struct sk_buff *build_frag_skb(st
break;
}
@@ -2021,9 +2080,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+ fq = &priv->fq[queue_id];
+ for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) {
-+ err = dpaa2_io_service_enqueue_qd(fq->channel->dpio,
-+ priv->tx_qdid, 0,
-+ fq->tx_qdbin, fd);
++ err = priv->enqueue(priv, fq, fd, 0);
+ if (err != -EBUSY)
+ break;
+ }
@@ -2039,6 +2096,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ return err;
+}
+
++/* Free buffers acquired from the buffer pool or which were meant to
++ * be released in the pool
++ */
+static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
+{
+ struct device *dev = priv->net_dev->dev.parent;
@@ -2046,11 +2106,10 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ int i;
+
+ for (i = 0; i < count; i++) {
-+ /* Same logic as on regular Rx path */
+ vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]);
-+ dma_unmap_single(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ skb_free_frag(vaddr);
++ dma_unmap_page(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE,
++ DMA_BIDIRECTIONAL);
++ free_pages((unsigned long)vaddr, 0);
+ }
+}
+
@@ -2152,12 +2211,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpaa2_eth_channel *ch,
const struct dpaa2_fd *fd,
- struct napi_struct *napi)
-+ struct napi_struct *napi,
-+ u16 queue_id)
++ struct dpaa2_eth_fq *fq)
{
dma_addr_t addr = dpaa2_fd_get_addr(fd);
u8 fd_format = dpaa2_fd_get_format(fd);
-@@ -235,14 +401,16 @@ static void dpaa2_eth_rx(struct dpaa2_et
+@@ -235,14 +370,16 @@ static void dpaa2_eth_rx(struct dpaa2_et
struct dpaa2_fas *fas;
void *buf_data;
u32 status = 0;
@@ -2176,23 +2234,25 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
prefetch(fas);
buf_data = vaddr + dpaa2_fd_get_offset(fd);
prefetch(buf_data);
-@@ -251,22 +419,41 @@ static void dpaa2_eth_rx(struct dpaa2_et
+@@ -251,22 +388,43 @@ static void dpaa2_eth_rx(struct dpaa2_et
percpu_extras = this_cpu_ptr(priv->percpu_extras);
if (fd_format == dpaa2_fd_single) {
+- skb = build_linear_skb(priv, ch, fd, vaddr);
+ xdp_act = dpaa2_eth_run_xdp(priv, ch, (struct dpaa2_fd *)fd,
-+ queue_id, vaddr);
++ fq->flowid, vaddr);
+ if (xdp_act != XDP_PASS)
+ return;
+
-+ dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
-+ DMA_BIDIRECTIONAL);
- skb = build_linear_skb(priv, ch, fd, vaddr);
++ dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
++ DMA_BIDIRECTIONAL);
++ skb = build_linear_skb(ch, fd, vaddr);
} else if (fd_format == dpaa2_fd_sg) {
-+ dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
++ dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
+ DMA_BIDIRECTIONAL);
skb = build_frag_skb(priv, ch, buf_data);
- skb_free_frag(vaddr);
+- skb_free_frag(vaddr);
++ free_pages((unsigned long)vaddr, 0);
percpu_extras->rx_sg_frames++;
percpu_extras->rx_sg_bytes += dpaa2_fd_get_len(fd);
} else {
@@ -2210,30 +2270,29 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ /* Get the timestamp value */
+ if (priv->ts_rx_en) {
+ struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
-+ u64 *ns = dpaa2_get_ts(vaddr, false);
++ __le64 *ts = dpaa2_get_ts(vaddr, false);
++ u64 ns;
+
-+ *ns = DPAA2_PTP_NOMINAL_FREQ_PERIOD_NS * le64_to_cpup(ns);
+ memset(shhwtstamps, 0, sizeof(*shhwtstamps));
-+ shhwtstamps->hwtstamp = ns_to_ktime(*ns);
++
++ ns = DPAA2_PTP_NOMINAL_FREQ_PERIOD_NS * le64_to_cpup(ts);
++ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+ }
+
/* Check if we need to validate the L4 csum */
if (likely(dpaa2_fd_get_frc(fd) & DPAA2_FD_FRC_FASV)) {
status = le32_to_cpu(fas->status);
-@@ -275,6 +462,12 @@ static void dpaa2_eth_rx(struct dpaa2_et
+@@ -274,30 +432,80 @@ static void dpaa2_eth_rx(struct dpaa2_et
+ }
skb->protocol = eth_type_trans(skb, priv->net_dev);
++ skb_record_rx_queue(skb, fq->flowid);
-+ /* Record Rx queue - this will be used when picking a Tx queue to
-+ * forward the frames. We're keeping flow affinity through the
-+ * network stack.
-+ */
-+ skb_record_rx_queue(skb, queue_id);
-+
percpu_stats->rx_packets++;
percpu_stats->rx_bytes += dpaa2_fd_get_len(fd);
-@@ -282,22 +475,74 @@ static void dpaa2_eth_rx(struct dpaa2_et
+- napi_gro_receive(napi, skb);
++ napi_gro_receive(&ch->napi, skb);
return;
@@ -2297,14 +2356,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* make sure we don't accidentally issue another volatile dequeue which would
* overwrite (leak) frames already in the store.
*
-+ * The number of frames is returned using the last 2 output arguments,
-+ * separately for Rx and Tx confirmations.
-+ *
* Observance of NAPI budget is not our concern, leaving that to the caller.
*/
-static int consume_frames(struct dpaa2_eth_channel *ch)
-+static bool consume_frames(struct dpaa2_eth_channel *ch, int *rx_cleaned,
-+ int *tx_conf_cleaned)
++static int consume_frames(struct dpaa2_eth_channel *ch,
++ struct dpaa2_eth_fq **src)
{
struct dpaa2_eth_priv *priv = ch->priv;
- struct dpaa2_eth_fq *fq;
@@ -2312,48 +2368,35 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpaa2_dq *dq;
const struct dpaa2_fd *fd;
int cleaned = 0;
-@@ -315,14 +560,60 @@ static int consume_frames(struct dpaa2_e
+@@ -315,16 +523,51 @@ static int consume_frames(struct dpaa2_e
}
fd = dpaa2_dq_fd(dq);
-- fq = (struct dpaa2_eth_fq *)(uintptr_t)dpaa2_dq_fqd_ctx(dq);
-- fq->stats.frames++;
+ prefetch(fd);
++
+ fq = (struct dpaa2_eth_fq *)(uintptr_t)dpaa2_dq_fqd_ctx(dq);
+- fq->stats.frames++;
- fq->consume(priv, ch, fd, &ch->napi);
-+ fq = (struct dpaa2_eth_fq *)(uintptr_t)dpaa2_dq_fqd_ctx(dq);
-+ fq->consume(priv, ch, fd, &ch->napi, fq->flowid);
++ fq->consume(priv, ch, fd, fq);
cleaned++;
} while (!is_last);
-- return cleaned;
+ if (!cleaned)
-+ return false;
-+
-+ /* All frames brought in store by a volatile dequeue
-+ * come from the same queue
-+ */
-+ if (fq->type == DPAA2_TX_CONF_FQ) {
-+ *tx_conf_cleaned += cleaned;
-+ } else {
-+ *rx_cleaned += cleaned;
-+ /* If we processed XDP_REDIRECT frames, flush them now */
-+ /* FIXME: Since we don't actually do anything inside
-+ * ndo_xdp_flush, we call it here simply for compliance
-+ * reasons
-+ */
-+ if (ch->flush) {
-+ xdp_do_flush_map();
-+ ch->flush = false;
-+ }
-+ }
++ return 0;
+
+ fq->stats.frames += cleaned;
+ ch->stats.frames += cleaned;
+
-+ return true;
-+}
++ /* A dequeue operation only pulls frames from a single queue
++ * into the store. Return the frame queue as an out param.
++ */
++ if (src)
++ *src = fq;
+
+ return cleaned;
+ }
+
+/* Configure the egress frame annotation for timestamp update */
+static void enable_tx_tstamp(struct dpaa2_fd *fd, void *buf_start)
+{
@@ -2374,10 +2417,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ ctrl = DPAA2_FAEAD_A2V | DPAA2_FAEAD_UPDV | DPAA2_FAEAD_UPD;
+ faead = dpaa2_get_faead(buf_start, true);
+ faead->ctrl = cpu_to_le32(ctrl);
- }
-
++}
++
/* Create a frame descriptor based on a fragmented skb */
-@@ -341,7 +632,6 @@ static int build_sg_fd(struct dpaa2_eth_
+ static int build_sg_fd(struct dpaa2_eth_priv *priv,
+ struct sk_buff *skb,
+@@ -341,7 +584,6 @@ static int build_sg_fd(struct dpaa2_eth_
int num_sg;
int num_dma_bufs;
struct dpaa2_eth_swa *swa;
@@ -2385,7 +2430,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Create and map scatterlist.
* We don't advertise NETIF_F_FRAGLIST, so skb_to_sgvec() will not have
-@@ -365,21 +655,14 @@ static int build_sg_fd(struct dpaa2_eth_
+@@ -365,21 +607,14 @@ static int build_sg_fd(struct dpaa2_eth_
/* Prepare the HW SGT structure */
sgt_buf_size = priv->tx_data_offset +
@@ -2410,7 +2455,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
sgt = (struct dpaa2_sg_entry *)(sgt_buf + priv->tx_data_offset);
-@@ -402,10 +685,11 @@ static int build_sg_fd(struct dpaa2_eth_
+@@ -402,10 +637,11 @@ static int build_sg_fd(struct dpaa2_eth_
* all of them on Tx Conf.
*/
swa = (struct dpaa2_eth_swa *)sgt_buf;
@@ -2426,7 +2471,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Separately map the SGT buffer */
addr = dma_map_single(dev, sgt_buf, sgt_buf_size, DMA_BIDIRECTIONAL);
-@@ -417,13 +701,15 @@ static int build_sg_fd(struct dpaa2_eth_
+@@ -417,13 +653,15 @@ static int build_sg_fd(struct dpaa2_eth_
dpaa2_fd_set_format(fd, dpaa2_fd_sg);
dpaa2_fd_set_addr(fd, addr);
dpaa2_fd_set_len(fd, skb->len);
@@ -2445,7 +2490,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
sgt_buf_alloc_failed:
dma_unmap_sg(dev, scl, num_sg, DMA_BIDIRECTIONAL);
dma_map_sg_failed:
-@@ -437,29 +723,27 @@ static int build_single_fd(struct dpaa2_
+@@ -437,29 +675,27 @@ static int build_single_fd(struct dpaa2_
struct dpaa2_fd *fd)
{
struct device *dev = priv->net_dev->dev.parent;
@@ -2488,7 +2533,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
addr = dma_map_single(dev, buffer_start,
skb_tail_pointer(skb) - buffer_start,
-@@ -471,8 +755,10 @@ static int build_single_fd(struct dpaa2_
+@@ -471,8 +707,10 @@ static int build_single_fd(struct dpaa2_
dpaa2_fd_set_offset(fd, (u16)(skb->data - buffer_start));
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_format(fd, dpaa2_fd_single);
@@ -2501,15 +2546,17 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return 0;
}
-@@ -486,92 +772,128 @@ static int build_single_fd(struct dpaa2_
- * Optionally, return the frame annotation status word (FAS), which needs
- * to be checked if we're on the confirmation path.
+@@ -483,72 +721,75 @@ static int build_single_fd(struct dpaa2_
+ * back-pointed to is also freed.
+ * This can be called either from dpaa2_eth_tx_conf() or on the error path of
+ * dpaa2_eth_tx().
+- * Optionally, return the frame annotation status word (FAS), which needs
+- * to be checked if we're on the confirmation path.
*/
--static void free_tx_fd(const struct dpaa2_eth_priv *priv,
-+static void free_tx_fd(struct dpaa2_eth_priv *priv,
- const struct dpaa2_fd *fd,
+ static void free_tx_fd(const struct dpaa2_eth_priv *priv,
+- const struct dpaa2_fd *fd,
- u32 *status)
-+ bool in_napi)
++ const struct dpaa2_fd *fd, bool in_napi)
{
struct device *dev = priv->net_dev->dev.parent;
dma_addr_t fd_addr;
@@ -2594,13 +2641,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ /* Get the timestamp value */
+ if (priv->ts_tx_en && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+ struct skb_shared_hwtstamps shhwtstamps;
-+ u64 *ns;
++ __le64 *ts = dpaa2_get_ts(buffer_start, true);
++ u64 ns;
+
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+
-+ ns = dpaa2_get_ts(buffer_start, true);
-+ *ns = DPAA2_PTP_NOMINAL_FREQ_PERIOD_NS * le64_to_cpup(ns);
-+ shhwtstamps.hwtstamp = ns_to_ktime(*ns);
++ ns = DPAA2_PTP_NOMINAL_FREQ_PERIOD_NS * le64_to_cpup(ts);
++ shhwtstamps.hwtstamp = ns_to_ktime(ns);
+ skb_tstamp_tx(skb, &shhwtstamps);
+ }
@@ -2616,46 +2663,33 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
}
static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
- {
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ struct device *dev = net_dev->dev.parent;
- struct dpaa2_fd fd;
+@@ -558,20 +799,41 @@ static netdev_tx_t dpaa2_eth_tx(struct s
struct rtnl_link_stats64 *percpu_stats;
struct dpaa2_eth_drv_stats *percpu_extras;
struct dpaa2_eth_fq *fq;
++ struct netdev_queue *nq;
u16 queue_mapping;
- int err, i;
+ unsigned int needed_headroom;
++ u32 fd_len;
+ u8 prio;
+ int err, i, ch_id = 0;
+
+ queue_mapping = skb_get_queue_mapping(skb);
+ prio = netdev_txq_to_tc(net_dev, queue_mapping);
-+
+ /* Hardware interprets priority level 0 as being the highest,
+ * so we need to do a reverse mapping to the netdev tc index
+ */
+ if (net_dev->num_tc)
+ prio = net_dev->num_tc - prio - 1;
-+
++
+ queue_mapping %= dpaa2_eth_queue_count(priv);
+ fq = &priv->fq[queue_mapping];
-+
-+ /* If we're congested, stop this tx queue; transmission of
-+ * the current skb happens regardless of congestion state
-+ */
-+ dma_sync_single_for_cpu(dev, priv->cscn_dma,
-+ DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
-+ if (unlikely(dpaa2_cscn_state_congested(priv->cscn_mem))) {
-+ netif_stop_subqueue(net_dev, queue_mapping);
-+ fq->stats.congestion_entry++;
-+ }
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
- if (unlikely(skb_headroom(skb) < DPAA2_ETH_NEEDED_HEADROOM(priv))) {
-+ /* For non-linear skb we don't need a minimum headroom */
+ needed_headroom = dpaa2_eth_needed_headroom(priv, skb);
+ if (skb_headroom(skb) < needed_headroom) {
struct sk_buff *ns;
@@ -2667,43 +2701,56 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
goto err_alloc_headroom;
}
+ percpu_extras->tx_reallocs++;
++
+ if (skb->sk)
+ skb_set_owner_w(ns, skb->sk);
++
dev_kfree_skb(skb);
skb = ns;
}
-@@ -605,13 +927,15 @@ static netdev_tx_t dpaa2_eth_tx(struct s
- /* Tracing point */
- trace_dpaa2_tx_fd(net_dev, &fd);
+@@ -602,17 +864,24 @@ static netdev_tx_t dpaa2_eth_tx(struct s
+ goto err_build_fd;
+ }
-- /* TxConf FQ selection primarily based on cpu affinity; this is
-- * non-migratable context, so it's safe to call smp_processor_id().
-- */
-- queue_mapping = smp_processor_id() % dpaa2_eth_queue_count(priv);
-- fq = &priv->fq[queue_mapping];
+ if (dpaa2_eth_ceetm_is_enabled(priv)) {
+ err = dpaa2_ceetm_classify(skb, net_dev->qdisc, &ch_id, &prio);
+ if (err)
+ goto err_ceetm_classify;
+ }
+
+ /* Tracing point */
+ trace_dpaa2_tx_fd(net_dev, &fd);
+
+- /* TxConf FQ selection primarily based on cpu affinity; this is
+- * non-migratable context, so it's safe to call smp_processor_id().
++ fd_len = dpaa2_fd_get_len(&fd);
++ nq = netdev_get_tx_queue(net_dev, queue_mapping);
++ netdev_tx_sent_queue(nq, fd_len);
++
++ /* Everything that happens after this enqueues might race with
++ * the Tx confirmation callback for this frame
+ */
+- queue_mapping = smp_processor_id() % dpaa2_eth_queue_count(priv);
+- fq = &priv->fq[queue_mapping];
for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) {
- err = dpaa2_io_service_enqueue_qd(NULL, priv->tx_qdid, 0,
-+ err = dpaa2_io_service_enqueue_qd(fq->channel->dpio,
-+ priv->tx_qdid, prio,
- fq->tx_qdbin, &fd);
+- fq->tx_qdbin, &fd);
++ err = priv->enqueue(priv, fq, &fd, 0);
if (err != -EBUSY)
break;
-@@ -620,7 +944,7 @@ static netdev_tx_t dpaa2_eth_tx(struct s
+ }
+@@ -620,14 +889,17 @@ static netdev_tx_t dpaa2_eth_tx(struct s
if (unlikely(err < 0)) {
percpu_stats->tx_errors++;
/* Clean up everything, including freeing the skb */
- free_tx_fd(priv, &fd, NULL);
+ free_tx_fd(priv, &fd, false);
++ netdev_tx_completed_queue(nq, 1, fd_len);
} else {
percpu_stats->tx_packets++;
- percpu_stats->tx_bytes += dpaa2_fd_get_len(&fd);
-@@ -628,6 +952,8 @@ static netdev_tx_t dpaa2_eth_tx(struct s
+- percpu_stats->tx_bytes += dpaa2_fd_get_len(&fd);
++ percpu_stats->tx_bytes += fd_len;
+ }
return NETDEV_TX_OK;
@@ -2712,29 +2759,36 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
err_build_fd:
err_alloc_headroom:
dev_kfree_skb(skb);
-@@ -639,13 +965,13 @@ err_alloc_headroom:
+@@ -637,48 +909,39 @@ err_alloc_headroom:
+
+ /* Tx confirmation frame processing routine */
static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv,
- struct dpaa2_eth_channel *ch,
+- struct dpaa2_eth_channel *ch,
++ struct dpaa2_eth_channel *ch __always_unused,
const struct dpaa2_fd *fd,
- struct napi_struct *napi __always_unused)
-+ struct napi_struct *napi __always_unused,
-+ u16 queue_id)
++ struct dpaa2_eth_fq *fq)
{
-+ struct device *dev = priv->net_dev->dev.parent;
struct rtnl_link_stats64 *percpu_stats;
struct dpaa2_eth_drv_stats *percpu_extras;
- u32 status = 0;
++ u32 fd_len = dpaa2_fd_get_len(fd);
u32 fd_errors;
- bool has_fas_errors = false;
/* Tracing point */
trace_dpaa2_tx_conf_fd(priv->net_dev, fd);
-@@ -654,31 +980,28 @@ static void dpaa2_eth_tx_conf(struct dpa
+
+ percpu_extras = this_cpu_ptr(priv->percpu_extras);
percpu_extras->tx_conf_frames++;
- percpu_extras->tx_conf_bytes += dpaa2_fd_get_len(fd);
+- percpu_extras->tx_conf_bytes += dpaa2_fd_get_len(fd);
++ percpu_extras->tx_conf_bytes += fd_len;
++
++ fq->dq_frames++;
++ fq->dq_bytes += fd_len;
-- /* Check frame errors in the FD field */
-- fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK;
+ /* Check frame errors in the FD field */
+ fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK;
- if (unlikely(fd_errors)) {
- /* We only check error bits in the FAS field if corresponding
- * FAERR bit is set in FD and the FAS field is marked as valid
@@ -2744,17 +2798,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- if (net_ratelimit())
- netdev_dbg(priv->net_dev, "TX frame FD error: 0x%08x\n",
- fd_errors);
-+ /* Check congestion state and wake all queues if necessary */
-+ if (unlikely(__netif_subqueue_stopped(priv->net_dev, queue_id))) {
-+ dma_sync_single_for_cpu(dev, priv->cscn_dma,
-+ DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
-+ if (!dpaa2_cscn_state_congested(priv->cscn_mem))
-+ netif_tx_wake_all_queues(priv->net_dev);
- }
-
+- }
+-
- free_tx_fd(priv, fd, has_fas_errors ? &status : NULL);
-+ /* Check frame errors in the FD field */
-+ fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK;
+ free_tx_fd(priv, fd, true);
if (likely(!fd_errors))
@@ -2774,7 +2820,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
}
static int set_rx_csum(struct dpaa2_eth_priv *priv, bool enable)
-@@ -728,26 +1051,27 @@ static int set_tx_csum(struct dpaa2_eth_
+@@ -728,26 +991,29 @@ static int set_tx_csum(struct dpaa2_eth_
/* Perform a single release command to add buffers
* to the specified buffer pool
*/
@@ -2784,7 +2830,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
{
struct device *dev = priv->net_dev->dev.parent;
u64 buf_array[DPAA2_ETH_BUFS_PER_CMD];
- void *buf;
+- void *buf;
++ struct page *page;
dma_addr_t addr;
- int i;
+ int i, err;
@@ -2794,25 +2841,30 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* alignment padding
*/
- buf = napi_alloc_frag(DPAA2_ETH_BUF_RAW_SIZE);
-+ buf = napi_alloc_frag(dpaa2_eth_buf_raw_size(priv));
- if (unlikely(!buf))
+- if (unlikely(!buf))
++ /* allocate one page for each Rx buffer. WRIOP sees
++ * the entire page except for a tailroom reserved for
++ * skb shared info
++ */
++ page = dev_alloc_pages(0);
++ if (!page)
goto err_alloc;
- buf = PTR_ALIGN(buf, DPAA2_ETH_RX_BUF_ALIGN);
-+ buf = PTR_ALIGN(buf, priv->rx_buf_align);
-
- addr = dma_map_single(dev, buf, DPAA2_ETH_RX_BUF_SIZE,
+-
+- addr = dma_map_single(dev, buf, DPAA2_ETH_RX_BUF_SIZE,
- DMA_FROM_DEVICE);
-+ DMA_BIDIRECTIONAL);
++ addr = dma_map_page(dev, page, 0, DPAA2_ETH_RX_BUF_SIZE,
++ DMA_BIDIRECTIONAL);
if (unlikely(dma_mapping_error(dev, addr)))
goto err_map;
-@@ -755,28 +1079,31 @@ static int add_bufs(struct dpaa2_eth_pri
+@@ -755,28 +1021,33 @@ static int add_bufs(struct dpaa2_eth_pri
/* tracing point */
trace_dpaa2_eth_buf_seed(priv->net_dev,
- buf, DPAA2_ETH_BUF_RAW_SIZE,
-+ buf, dpaa2_eth_buf_raw_size(priv),
++ page, DPAA2_ETH_RX_BUF_RAW_SIZE,
addr, DPAA2_ETH_RX_BUF_SIZE,
bpid);
}
@@ -2833,8 +2885,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ buf_array, i)) == -EBUSY)
cpu_relax();
+
-+ /* If release command failed, clean up and bail out; not much
-+ * else we can do about it
++ /* If release command failed, clean up and bail out;
++ * not much else we can do about it
+ */
+ if (err) {
+ free_bufs(priv, buf_array, i);
@@ -2844,13 +2896,16 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return i;
err_map:
- skb_free_frag(buf);
+- skb_free_frag(buf);
++ __free_pages(page, 0);
err_alloc:
-+ /* If we managed to allocate at least some buffers, release them */
++ /* If we managed to allocate at least some buffers,
++ * release them to hardware
++ */
if (i)
goto release_bufs;
-@@ -796,9 +1123,10 @@ static int seed_pool(struct dpaa2_eth_pr
+@@ -796,9 +1067,10 @@ static int seed_pool(struct dpaa2_eth_pr
*/
preempt_disable();
for (j = 0; j < priv->num_channels; j++) {
@@ -2863,7 +2918,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
priv->channel[j]->buf_count += new_count;
if (new_count < DPAA2_ETH_BUFS_PER_CMD) {
-@@ -818,10 +1146,8 @@ static int seed_pool(struct dpaa2_eth_pr
+@@ -818,10 +1090,8 @@ static int seed_pool(struct dpaa2_eth_pr
*/
static void drain_bufs(struct dpaa2_eth_priv *priv, int count)
{
@@ -2875,7 +2930,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
do {
ret = dpaa2_io_service_acquire(NULL, priv->bpid,
-@@ -830,27 +1156,16 @@ static void drain_bufs(struct dpaa2_eth_
+@@ -830,27 +1100,16 @@ static void drain_bufs(struct dpaa2_eth_
netdev_err(priv->net_dev, "dpaa2_io_service_acquire() failed\n");
return;
}
@@ -2906,7 +2961,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
}
/* Function is called from softirq context only, so we don't need to guard
-@@ -862,19 +1177,19 @@ static int refill_pool(struct dpaa2_eth_
+@@ -862,19 +1121,19 @@ static int refill_pool(struct dpaa2_eth_
{
int new_count;
@@ -2930,7 +2985,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return -ENOMEM;
return 0;
-@@ -887,7 +1202,8 @@ static int pull_channel(struct dpaa2_eth
+@@ -887,7 +1146,8 @@ static int pull_channel(struct dpaa2_eth
/* Retry while portal is busy */
do {
@@ -2940,22 +2995,16 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
dequeues++;
cpu_relax();
} while (err == -EBUSY);
-@@ -902,20 +1218,21 @@ static int pull_channel(struct dpaa2_eth
- /* NAPI poll routine
- *
- * Frames are dequeued from the QMan channel associated with this NAPI context.
-- * Rx, Tx confirmation and (if configured) Rx error frames all count
-- * towards the NAPI budget.
-+ * Rx and (if configured) Rx error frames count towards the NAPI budget. Tx
-+ * confirmation frames are limited by a threshold per NAPI poll cycle.
- */
+@@ -908,14 +1168,17 @@ static int pull_channel(struct dpaa2_eth
static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
{
struct dpaa2_eth_channel *ch;
- int cleaned = 0, store_cleaned;
-+ int rx_cleaned = 0, tx_conf_cleaned = 0;
-+ bool store_cleaned;
struct dpaa2_eth_priv *priv;
++ int rx_cleaned = 0, txconf_cleaned = 0;
++ struct dpaa2_eth_fq *fq, *txc_fq = NULL;
++ struct netdev_queue *nq;
++ int store_cleaned, work_done;
int err;
ch = container_of(napi, struct dpaa2_eth_channel, napi);
@@ -2966,25 +3015,45 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
err = pull_channel(ch);
if (unlikely(err))
break;
-@@ -923,29 +1240,29 @@ static int dpaa2_eth_poll(struct napi_st
+@@ -923,29 +1186,56 @@ static int dpaa2_eth_poll(struct napi_st
/* Refill pool if appropriate */
refill_pool(priv, ch, priv->bpid);
- store_cleaned = consume_frames(ch);
- cleaned += store_cleaned;
-+ store_cleaned = consume_frames(ch, &rx_cleaned,
-+ &tx_conf_cleaned);
++ store_cleaned = consume_frames(ch, &fq);
++ if (!store_cleaned)
++ break;
++ if (fq->type == DPAA2_RX_FQ) {
++ rx_cleaned += store_cleaned;
++ /* If these are XDP_REDIRECT frames, flush them now */
++ /* TODO: Do we need this? */
++ if (ch->flush) {
++ xdp_do_flush_map();
++ ch->flush = false;
++ }
++ } else {
++ txconf_cleaned += store_cleaned;
++ /* We have a single Tx conf FQ on this channel */
++ txc_fq = fq;
++ }
- /* If we have enough budget left for a full store,
- * try a new pull dequeue, otherwise we're done here
-+ /* If we've either consumed the budget with Rx frames,
-+ * or reached the Tx conf threshold, we're done.
++ /* If we either consumed the whole NAPI budget with Rx frames
++ * or we reached the Tx confirmations threshold, we're done.
*/
- if (store_cleaned == 0 ||
- cleaned > budget - DPAA2_ETH_STORE_SIZE)
- break;
- }
--
++ if (rx_cleaned >= budget ||
++ txconf_cleaned >= DPAA2_ETH_TXCONF_PER_NAPI) {
++ work_done = budget;
++ goto out;
++ }
++ } while (store_cleaned);
+
- if (cleaned < budget) {
- napi_complete_done(napi, cleaned);
- /* Re-enable data available notifications */
@@ -2993,29 +3062,69 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- cpu_relax();
- } while (err == -EBUSY);
- }
-+ if (rx_cleaned >= budget ||
-+ tx_conf_cleaned >= TX_CONF_PER_NAPI_POLL)
-+ return budget;
-+ } while (store_cleaned);
-
-- ch->stats.frames += cleaned;
-+ /* We didn't consume the entire budget, finish napi and
++ /* We didn't consume the entire budget, so finish napi and
+ * re-enable data availability notifications
+ */
-+ napi_complete(napi);
++ napi_complete_done(napi, rx_cleaned);
+ do {
+ err = dpaa2_io_service_rearm(ch->dpio, &ch->nctx);
+ cpu_relax();
+ } while (err == -EBUSY);
-+ WARN_ONCE(err, "CDAN notifications rearm failed on core %d",
-+ ch->nctx.desired_cpu);
++ WARN_ONCE(err, "CDAN notifications rearm failed on core %d",
++ ch->nctx.desired_cpu);
+
+- ch->stats.frames += cleaned;
++ work_done = max(rx_cleaned, 1);
- return cleaned;
-+ return max(rx_cleaned, 1);
++out:
++ if (txc_fq) {
++ nq = netdev_get_tx_queue(priv->net_dev, txc_fq->flowid);
++ netdev_tx_completed_queue(nq, txc_fq->dq_frames,
++ txc_fq->dq_bytes);
++ txc_fq->dq_frames = 0;
++ txc_fq->dq_bytes = 0;
++ }
++
++ return work_done;
}
static void enable_ch_napi(struct dpaa2_eth_priv *priv)
-@@ -1006,28 +1323,30 @@ static int dpaa2_eth_open(struct net_dev
+@@ -970,9 +1260,23 @@ static void disable_ch_napi(struct dpaa2
+ }
+ }
+
++static void update_tx_fqids(struct dpaa2_eth_priv *priv);
++
++static void update_pf(struct dpaa2_eth_priv *priv,
++ struct dpni_link_state *state)
++{
++ bool pause_frames;
++
++ pause_frames = !!(state->options & DPNI_LINK_OPT_PAUSE);
++ if (priv->tx_pause_frames != pause_frames) {
++ priv->tx_pause_frames = pause_frames;
++ set_rx_taildrop(priv);
++ }
++}
++
+ static int link_state_update(struct dpaa2_eth_priv *priv)
+ {
+- struct dpni_link_state state;
++ struct dpni_link_state state = {0};
+ int err;
+
+ err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, &state);
+@@ -988,6 +1292,8 @@ static int link_state_update(struct dpaa
+
+ priv->link_state = state;
+ if (state.up) {
++ update_tx_fqids(priv);
++ update_pf(priv, &state);
+ netif_carrier_on(priv->net_dev);
+ netif_tx_start_all_queues(priv->net_dev);
+ } else {
+@@ -1006,28 +1312,30 @@ static int dpaa2_eth_open(struct net_dev
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
int err;
@@ -3057,7 +3166,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
err = dpni_enable(priv->mc_io, 0, priv->mc_token);
if (err < 0) {
netdev_err(net_dev, "dpni_enable() failed\n");
-@@ -1047,48 +1366,17 @@ static int dpaa2_eth_open(struct net_dev
+@@ -1047,51 +1355,20 @@ static int dpaa2_eth_open(struct net_dev
link_state_err:
enable_err:
@@ -3072,7 +3181,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- */
-static u32 drain_channel(struct dpaa2_eth_priv *priv,
- struct dpaa2_eth_channel *ch)
--{
++static int dpaa2_eth_stop(struct net_device *net_dev)
+ {
- u32 drained = 0, total = 0;
-
- do {
@@ -3083,7 +3193,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
-
- return total;
-}
--
++ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
++ int dpni_enabled = 0;
++ int retries = 10, i;
++ int err = 0;
+
-static u32 drain_ingress_frames(struct dpaa2_eth_priv *priv)
-{
- struct dpaa2_eth_channel *ch;
@@ -3098,18 +3212,21 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- return drained;
-}
-
- static int dpaa2_eth_stop(struct net_device *net_dev)
- {
- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
- int dpni_enabled;
+-static int dpaa2_eth_stop(struct net_device *net_dev)
+-{
+- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+- int dpni_enabled;
- int retries = 10;
- u32 drained;
-+ int retries = 10, i;
-+ int err = 0;
-
- netif_tx_stop_all_queues(net_dev);
- netif_carrier_off(net_dev);
-@@ -1105,56 +1393,24 @@ static int dpaa2_eth_stop(struct net_dev
+-
+- netif_tx_stop_all_queues(net_dev);
+- netif_carrier_off(net_dev);
++ netif_tx_stop_all_queues(net_dev);
++ netif_carrier_off(net_dev);
+
+ /* Loop while dpni_disable() attempts to drain the egress FQs
+ * and confirm them back to us.
+@@ -1105,56 +1382,24 @@ static int dpaa2_eth_stop(struct net_dev
} while (dpni_enabled && --retries);
if (!retries) {
netdev_warn(net_dev, "Retry count exceeded disabling DPNI\n");
@@ -3176,7 +3293,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
}
static int dpaa2_eth_set_addr(struct net_device *net_dev, void *addr)
-@@ -1200,25 +1456,6 @@ static void dpaa2_eth_get_stats(struct n
+@@ -1200,25 +1445,6 @@ static void dpaa2_eth_get_stats(struct n
}
}
@@ -3202,7 +3319,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Copy mac unicast addresses from @net_dev to @priv.
* Its sole purpose is to make dpaa2_eth_set_rx_mode() more readable.
*/
-@@ -1380,16 +1617,363 @@ static int dpaa2_eth_set_features(struct
+@@ -1380,16 +1606,430 @@ static int dpaa2_eth_set_features(struct
return 0;
}
@@ -3249,6 +3366,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+{
+ struct device *dev = priv->net_dev->dev.parent;
+ struct dpni_buffer_layout buf_layout = {0};
++ u16 rx_buf_align;
+ int err;
+
+ /* We need to check for WRIOP version 1.0.0, but depending on the MC
@@ -3257,15 +3375,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ */
+ if (priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(0, 0, 0) ||
+ priv->dpni_attrs.wriop_version == DPAA2_WRIOP_VERSION(1, 0, 0))
-+ priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN_REV1;
++ rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN_REV1;
+ else
-+ priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN;
++ rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN;
+
+ /* tx buffer */
-+ buf_layout.pass_timestamp = true;
+ buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE;
-+ buf_layout.options = DPNI_BUF_LAYOUT_OPT_TIMESTAMP |
-+ DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
++ buf_layout.pass_timestamp = true;
++ buf_layout.options = DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
++ DPNI_BUF_LAYOUT_OPT_TIMESTAMP;
+ err = dpni_set_buffer_layout(priv->mc_io, 0, priv->mc_token,
+ DPNI_QUEUE_TX, &buf_layout);
+ if (err) {
@@ -3299,9 +3417,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ /* rx buffer */
+ buf_layout.pass_frame_status = true;
+ buf_layout.pass_parser_result = true;
-+ buf_layout.data_align = priv->rx_buf_align;
-+ buf_layout.private_data_size = 0;
++ buf_layout.data_align = rx_buf_align;
+ buf_layout.data_head_room = dpaa2_eth_rx_headroom(priv);
++ buf_layout.private_data_size = 0;
+ /* If XDP program is attached, reserve extra space for
+ * potential header expansions
+ */
@@ -3322,6 +3440,73 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ return 0;
+}
+
++#define DPNI_ENQUEUE_FQID_VER_MAJOR 7
++#define DPNI_ENQUEUE_FQID_VER_MINOR 9
++
++static inline int dpaa2_eth_enqueue_qd(struct dpaa2_eth_priv *priv,
++ struct dpaa2_eth_fq *fq,
++ struct dpaa2_fd *fd, u8 prio)
++{
++ return dpaa2_io_service_enqueue_qd(fq->channel->dpio,
++ priv->tx_qdid, prio,
++ fq->tx_qdbin, fd);
++}
++
++static inline int dpaa2_eth_enqueue_fq(struct dpaa2_eth_priv *priv,
++ struct dpaa2_eth_fq *fq,
++ struct dpaa2_fd *fd,
++ u8 prio __always_unused)
++{
++ return dpaa2_io_service_enqueue_fq(fq->channel->dpio,
++ fq->tx_fqid, fd);
++}
++
++static void set_enqueue_mode(struct dpaa2_eth_priv *priv)
++{
++ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_ENQUEUE_FQID_VER_MAJOR,
++ DPNI_ENQUEUE_FQID_VER_MINOR) < 0)
++ priv->enqueue = dpaa2_eth_enqueue_qd;
++ else
++ priv->enqueue = dpaa2_eth_enqueue_fq;
++}
++
++static void update_tx_fqids(struct dpaa2_eth_priv *priv)
++{
++ struct dpaa2_eth_fq *fq;
++ struct dpni_queue queue;
++ struct dpni_queue_id qid = {0};
++ int i, err;
++
++ /* We only use Tx FQIDs for FQID-based enqueue, so check
++ * if DPNI version supports it before updating FQIDs
++ */
++ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_ENQUEUE_FQID_VER_MAJOR,
++ DPNI_ENQUEUE_FQID_VER_MINOR) < 0)
++ return;
++
++ for (i = 0; i < priv->num_fqs; i++) {
++ fq = &priv->fq[i];
++ if (fq->type != DPAA2_TX_CONF_FQ)
++ continue;
++ err = dpni_get_queue(priv->mc_io, 0, priv->mc_token,
++ DPNI_QUEUE_TX, 0, fq->flowid,
++ &queue, &qid);
++ if (err)
++ goto out_err;
++
++ fq->tx_fqid = qid.fqid;
++ if (fq->tx_fqid == 0)
++ goto out_err;
++ }
++
++ return;
++
++out_err:
++ netdev_info(priv->net_dev,
++ "Error reading Tx FQID, fallback to QDID-based enqueue");
++ priv->enqueue = dpaa2_eth_enqueue_qd;
++}
++
+static int dpaa2_eth_set_xdp(struct net_device *net_dev, struct bpf_prog *prog)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
@@ -3471,7 +3656,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ * so we do the actual frame enqueue in ndo_xdp_xmit
+ */
+}
-+
+static int dpaa2_eth_update_xps(struct dpaa2_eth_priv *priv)
+{
+ struct net_device *net_dev = priv->net_dev;
@@ -3568,7 +3752,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
};
static void cdan_cb(struct dpaa2_io_notification_ctx *ctx)
-@@ -1422,34 +2006,32 @@ static struct fsl_mc_device *setup_dpcon
+@@ -1422,34 +2062,32 @@ static struct fsl_mc_device *setup_dpcon
err = dpcon_open(priv->mc_io, 0, dpcon->obj_desc.id, &dpcon->mc_handle);
if (err) {
dev_err(dev, "dpcon_open() failed\n");
@@ -3609,7 +3793,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
fsl_mc_object_free(dpcon);
return NULL;
-@@ -1502,7 +2084,14 @@ err_setup:
+@@ -1502,7 +2140,14 @@ err_setup:
static void free_channel(struct dpaa2_eth_priv *priv,
struct dpaa2_eth_channel *channel)
{
@@ -3624,35 +3808,51 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
kfree(channel);
}
-@@ -1546,7 +2135,8 @@ static int setup_dpio(struct dpaa2_eth_p
+@@ -1546,7 +2191,8 @@ static int setup_dpio(struct dpaa2_eth_p
nctx->desired_cpu = i;
/* Register the new context */
- err = dpaa2_io_service_register(NULL, nctx);
+ channel->dpio = dpaa2_io_service_select(i);
-+ err = dpaa2_io_service_register(channel->dpio, nctx);
++ err = dpaa2_io_service_register(channel->dpio, nctx, dev);
if (err) {
dev_dbg(dev, "No affine DPIO for cpu %d\n", i);
/* If no affine DPIO for this core, there's probably
-@@ -1586,7 +2176,7 @@ static int setup_dpio(struct dpaa2_eth_p
+@@ -1579,14 +2225,14 @@ static int setup_dpio(struct dpaa2_eth_p
+ /* Stop if we already have enough channels to accommodate all
+ * RX and TX conf queues
+ */
+- if (priv->num_channels == dpaa2_eth_queue_count(priv))
++ if (priv->num_channels == priv->dpni_attrs.num_queues)
+ break;
+ }
+
return 0;
err_set_cdan:
- dpaa2_io_service_deregister(NULL, nctx);
-+ dpaa2_io_service_deregister(channel->dpio, nctx);
++ dpaa2_io_service_deregister(channel->dpio, nctx, dev);
err_service_reg:
free_channel(priv, channel);
err_alloc_ch:
-@@ -1609,7 +2199,7 @@ static void free_dpio(struct dpaa2_eth_p
+@@ -1603,13 +2249,14 @@ err_alloc_ch:
+
+ static void free_dpio(struct dpaa2_eth_priv *priv)
+ {
+- int i;
++ struct device *dev = priv->net_dev->dev.parent;
+ struct dpaa2_eth_channel *ch;
++ int i;
+
/* deregister CDAN notifications and free channels */
for (i = 0; i < priv->num_channels; i++) {
ch = priv->channel[i];
- dpaa2_io_service_deregister(NULL, &ch->nctx);
-+ dpaa2_io_service_deregister(ch->dpio, &ch->nctx);
++ dpaa2_io_service_deregister(ch->dpio, &ch->nctx, dev);
free_channel(priv, ch);
}
}
-@@ -1636,8 +2226,7 @@ static void set_fq_affinity(struct dpaa2
+@@ -1636,8 +2283,7 @@ static void set_fq_affinity(struct dpaa2
{
struct device *dev = priv->net_dev->dev.parent;
struct dpaa2_eth_fq *fq;
@@ -3662,7 +3862,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* For each FQ, pick one channel/CPU to deliver frames to.
* This may well change at runtime, either through irqbalance or
-@@ -1649,6 +2238,7 @@ static void set_fq_affinity(struct dpaa2
+@@ -1649,6 +2295,7 @@ static void set_fq_affinity(struct dpaa2
fq = &priv->fq[i];
switch (fq->type) {
case DPAA2_RX_FQ:
@@ -3670,15 +3870,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
fq->target_cpu = rx_cpu;
rx_cpu = cpumask_next(rx_cpu, &priv->dpio_cpumask);
if (rx_cpu >= nr_cpu_ids)
-@@ -1656,6 +2246,7 @@ static void set_fq_affinity(struct dpaa2
- break;
- case DPAA2_TX_CONF_FQ:
- fq->target_cpu = txc_cpu;
-+
- txc_cpu = cpumask_next(txc_cpu, &priv->dpio_cpumask);
- if (txc_cpu >= nr_cpu_ids)
- txc_cpu = cpumask_first(&priv->dpio_cpumask);
-@@ -1665,11 +2256,13 @@ static void set_fq_affinity(struct dpaa2
+@@ -1665,11 +2312,13 @@ static void set_fq_affinity(struct dpaa2
}
fq->channel = get_affine_channel(priv, fq->target_cpu);
}
@@ -3693,7 +3885,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* We have one TxConf FQ per Tx flow.
* The number of Tx and Rx queues is the same.
-@@ -1681,11 +2274,19 @@ static void setup_fqs(struct dpaa2_eth_p
+@@ -1681,11 +2330,19 @@ static void setup_fqs(struct dpaa2_eth_p
priv->fq[priv->num_fqs++].flowid = (u16)i;
}
@@ -3718,7 +3910,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* For each FQ, decide on which core to process incoming frames */
set_fq_affinity(priv);
-@@ -1735,6 +2336,9 @@ static int setup_dpbp(struct dpaa2_eth_p
+@@ -1735,6 +2392,9 @@ static int setup_dpbp(struct dpaa2_eth_p
}
priv->bpid = dpbp_attrs.bpid;
@@ -3728,59 +3920,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return 0;
err_get_attr:
-@@ -1756,13 +2360,59 @@ static void free_dpbp(struct dpaa2_eth_p
- fsl_mc_object_free(priv->dpbp_dev);
- }
-
-+static int setup_tx_congestion(struct dpaa2_eth_priv *priv)
-+{
-+ struct dpni_congestion_notification_cfg notif_cfg = {0};
-+ struct device *dev = priv->net_dev->dev.parent;
-+ int err;
-+
-+ priv->cscn_unaligned = kzalloc(DPAA2_CSCN_SIZE + DPAA2_CSCN_ALIGN,
-+ GFP_KERNEL);
-+
-+ if (!priv->cscn_unaligned)
-+ return -ENOMEM;
-+
-+ priv->cscn_mem = PTR_ALIGN(priv->cscn_unaligned, DPAA2_CSCN_ALIGN);
-+ priv->cscn_dma = dma_map_single(dev, priv->cscn_mem, DPAA2_CSCN_SIZE,
-+ DMA_FROM_DEVICE);
-+ if (dma_mapping_error(dev, priv->cscn_dma)) {
-+ dev_err(dev, "Error mapping CSCN memory area\n");
-+ err = -ENOMEM;
-+ goto err_dma_map;
-+ }
-+
-+ notif_cfg.units = DPNI_CONGESTION_UNIT_BYTES;
-+ notif_cfg.threshold_entry = DPAA2_ETH_TX_CONG_ENTRY_THRESH;
-+ notif_cfg.threshold_exit = DPAA2_ETH_TX_CONG_EXIT_THRESH;
-+ notif_cfg.message_ctx = (u64)priv;
-+ notif_cfg.message_iova = priv->cscn_dma;
-+ notif_cfg.notification_mode = DPNI_CONG_OPT_WRITE_MEM_ON_ENTER |
-+ DPNI_CONG_OPT_WRITE_MEM_ON_EXIT |
-+ DPNI_CONG_OPT_COHERENT_WRITE;
-+ err = dpni_set_congestion_notification(priv->mc_io, 0, priv->mc_token,
-+ DPNI_QUEUE_TX, 0, &notif_cfg);
-+ if (err) {
-+ dev_err(dev, "dpni_set_congestion_notification failed\n");
-+ goto err_set_cong;
-+ }
-+
-+ return 0;
-+
-+err_set_cong:
-+ dma_unmap_single(dev, priv->cscn_dma, DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
-+err_dma_map:
-+ kfree(priv->cscn_unaligned);
-+
-+ return err;
-+}
-+
- /* Configure the DPNI object this interface is associated with */
- static int setup_dpni(struct fsl_mc_device *ls_dev)
- {
+@@ -1762,7 +2422,7 @@ static int setup_dpni(struct fsl_mc_devi
struct device *dev = &ls_dev->dev;
struct dpaa2_eth_priv *priv;
struct net_device *net_dev;
@@ -3789,7 +3929,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
int err;
net_dev = dev_get_drvdata(dev);
-@@ -1772,7 +2422,22 @@ static int setup_dpni(struct fsl_mc_devi
+@@ -1772,7 +2432,22 @@ static int setup_dpni(struct fsl_mc_devi
err = dpni_open(priv->mc_io, 0, ls_dev->obj_desc.id, &priv->mc_token);
if (err) {
dev_err(dev, "dpni_open() failed\n");
@@ -3813,7 +3953,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
}
ls_dev->mc_io = priv->mc_io;
-@@ -1781,82 +2446,53 @@ static int setup_dpni(struct fsl_mc_devi
+@@ -1781,77 +2456,41 @@ static int setup_dpni(struct fsl_mc_devi
err = dpni_reset(priv->mc_io, 0, priv->mc_token);
if (err) {
dev_err(dev, "dpni_reset() failed\n");
@@ -3858,10 +3998,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- dev_err(dev, "dpni_set_buffer_layout(TX) failed\n");
- goto err_buf_layout;
- }
-+ /* Enable congestion notifications for Tx queues */
-+ err = setup_tx_congestion(priv);
-+ if (err)
-+ goto close;
++ set_enqueue_mode(priv);
- /* tx-confirm buffer */
- buf_layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS;
@@ -3871,9 +4008,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- dev_err(dev, "dpni_set_buffer_layout(TX_CONF) failed\n");
- goto err_buf_layout;
- }
-+ /* allocate classification rule space */
-+ priv->cls_rule = kzalloc(sizeof(*priv->cls_rule) *
-+ dpaa2_eth_fs_count(priv), GFP_KERNEL);
++ priv->cls_rule = devm_kzalloc(dev, sizeof(struct dpaa2_eth_cls_rule) *
++ dpaa2_eth_fs_count(priv), GFP_KERNEL);
+ if (!priv->cls_rule)
+ goto close;
@@ -3890,7 +4026,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- dev_err(dev, "dpni_get_tx_data_offset() failed\n");
- goto err_data_offset;
+ dev_err(dev, "dpni_set_link_cfg() failed\n");
-+ goto cls_free;
++ goto close;
}
- if ((priv->tx_data_offset % 64) != 0)
@@ -3906,8 +4042,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
-err_buf_layout:
-err_get_attr:
-err_reset:
-+cls_free:
-+ kfree(priv->cls_rule);
+close:
dpni_close(priv->mc_io, 0, priv->mc_token);
-err_open:
@@ -3915,25 +4049,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return err;
}
- static void free_dpni(struct dpaa2_eth_priv *priv)
- {
-+ struct device *dev = priv->net_dev->dev.parent;
- int err;
-
- err = dpni_reset(priv->mc_io, 0, priv->mc_token);
-@@ -1865,6 +2501,11 @@ static void free_dpni(struct dpaa2_eth_p
+@@ -1865,6 +2504,7 @@ static void free_dpni(struct dpaa2_eth_p
err);
dpni_close(priv->mc_io, 0, priv->mc_token);
+
-+ kfree(priv->cls_rule);
-+
-+ dma_unmap_single(dev, priv->cscn_dma, DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
-+ kfree(priv->cscn_unaligned);
}
static int setup_rx_flow(struct dpaa2_eth_priv *priv,
-@@ -1873,11 +2514,10 @@ static int setup_rx_flow(struct dpaa2_et
+@@ -1873,11 +2513,10 @@ static int setup_rx_flow(struct dpaa2_et
struct device *dev = priv->net_dev->dev.parent;
struct dpni_queue queue;
struct dpni_queue_id qid;
@@ -3946,16 +4070,24 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
if (err) {
dev_err(dev, "dpni_get_queue(RX) failed\n");
return err;
-@@ -1890,7 +2530,7 @@ static int setup_rx_flow(struct dpaa2_et
+@@ -1889,24 +2528,136 @@ static int setup_rx_flow(struct dpaa2_et
+ queue.destination.type = DPNI_DEST_DPCON;
queue.destination.priority = 1;
queue.user_context = (u64)(uintptr_t)fq;
++ queue.flc.stash_control = 1;
++ queue.flc.value &= 0xFFFFFFFFFFFFFFC0;
++ /* 01 01 00 - data, annotation, flow context*/
++ queue.flc.value |= 0x14;
++
err = dpni_set_queue(priv->mc_io, 0, priv->mc_token,
- DPNI_QUEUE_RX, 0, fq->flowid,
+- DPNI_QUEUE_OPT_USER_CTX | DPNI_QUEUE_OPT_DEST,
+ DPNI_QUEUE_RX, fq->tc, fq->flowid,
- DPNI_QUEUE_OPT_USER_CTX | DPNI_QUEUE_OPT_DEST,
++ DPNI_QUEUE_OPT_USER_CTX | DPNI_QUEUE_OPT_DEST |
++ DPNI_QUEUE_OPT_FLC,
&queue);
if (err) {
-@@ -1898,15 +2538,121 @@ static int setup_rx_flow(struct dpaa2_et
+ dev_err(dev, "dpni_set_queue(RX) failed\n");
return err;
}
@@ -4084,7 +4216,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return 0;
}
-@@ -1953,23 +2699,88 @@ static int setup_tx_flow(struct dpaa2_et
+@@ -1926,6 +2677,7 @@ static int setup_tx_flow(struct dpaa2_et
+ }
+
+ fq->tx_qdbin = qid.qdbin;
++ fq->tx_fqid = qid.fqid;
+
+ err = dpni_get_queue(priv->mc_io, 0, priv->mc_token,
+ DPNI_QUEUE_TX_CONFIRM, 0, fq->flowid,
+@@ -1953,23 +2705,88 @@ static int setup_tx_flow(struct dpaa2_et
return 0;
}
@@ -4124,8 +4264,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
+#endif
+
-+/* default hash key fields */
-+static struct dpaa2_eth_dist_fields default_dist_fields[] = {
++/* Supported header fields for Rx hash distribution key */
++static const struct dpaa2_eth_dist_fields dist_fields[] = {
{
+ /* L2 header */
+ .rxnfc_field = RXH_L2DA,
@@ -4175,7 +4315,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
.size = 1,
}, {
/* Using UDP ports, this is functionally equivalent to raw
-@@ -1978,90 +2789,182 @@ static const struct dpaa2_eth_hash_field
+@@ -1978,41 +2795,170 @@ static const struct dpaa2_eth_hash_field
.rxnfc_field = RXH_L4_B_0_1,
.cls_prot = NET_PROT_UDP,
.cls_field = NH_FLD_UDP_PORT_SRC,
@@ -4191,161 +4331,265 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
};
-/* Set RX hash options
-- * flags is a combination of RXH_ bits
-- */
--static int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags)
-+static int legacy_config_dist_key(struct dpaa2_eth_priv *priv,
-+ dma_addr_t key_iova)
- {
-- struct device *dev = net_dev->dev.parent;
-- struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-- struct dpkg_profile_cfg cls_cfg;
++/* Configure the Rx hash key using the legacy API */
++static int config_legacy_hash_key(struct dpaa2_eth_priv *priv, dma_addr_t key)
++{
+ struct device *dev = priv->net_dev->dev.parent;
- struct dpni_rx_tc_dist_cfg dist_cfg;
-- u8 *dma_mem;
-- int i;
-- int err = 0;
-+ int i, err;
-
-- if (!dpaa2_eth_hash_enabled(priv)) {
-- dev_dbg(dev, "Hashing support is not enabled\n");
-- return 0;
-+ /* In legacy mode, we can't configure flow steering independently */
-+ if (!dpaa2_eth_hash_enabled(priv))
-+ return -EOPNOTSUPP;
++ struct dpni_rx_tc_dist_cfg dist_cfg;
++ int i, err = 0;
+
+ memset(&dist_cfg, 0, sizeof(dist_cfg));
+
-+ dist_cfg.key_cfg_iova = key_iova;
++ dist_cfg.key_cfg_iova = key;
+ dist_cfg.dist_size = dpaa2_eth_queue_count(priv);
-+ if (dpaa2_eth_fs_enabled(priv)) {
-+ dist_cfg.dist_mode = DPNI_DIST_MODE_FS;
-+ dist_cfg.fs_cfg.miss_action = DPNI_FS_MISS_HASH;
-+ } else {
-+ dist_cfg.dist_mode = DPNI_DIST_MODE_HASH;
- }
-
-- memset(&cls_cfg, 0, sizeof(cls_cfg));
++ dist_cfg.dist_mode = DPNI_DIST_MODE_HASH;
++
+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
-+ err = dpni_set_rx_tc_dist(priv->mc_io, 0, priv->mc_token, i,
-+ &dist_cfg);
++ err = dpni_set_rx_tc_dist(priv->mc_io, 0, priv->mc_token,
++ i, &dist_cfg);
+ if (err) {
+ dev_err(dev, "dpni_set_rx_tc_dist failed\n");
-+ return err;
++ break;
+ }
+ }
+
-+ return 0;
++ return err;
+}
+
-+static int config_hash_key(struct dpaa2_eth_priv *priv, dma_addr_t key_iova)
++/* Configure the Rx hash key using the new API */
++static int config_hash_key(struct dpaa2_eth_priv *priv, dma_addr_t key)
+{
+ struct device *dev = priv->net_dev->dev.parent;
+ struct dpni_rx_dist_cfg dist_cfg;
-+ int i, err;
-
-- for (i = 0; i < ARRAY_SIZE(hash_fields); i++) {
-- struct dpkg_extract *key =
-- &cls_cfg.extracts[cls_cfg.num_extracts];
-+ if (!dpaa2_eth_hash_enabled(priv))
-+ return -EOPNOTSUPP;
-
-- if (!(flags & hash_fields[i].rxnfc_field))
-- continue;
++ int i, err = 0;
++
+ memset(&dist_cfg, 0, sizeof(dist_cfg));
+
-+ dist_cfg.key_cfg_iova = key_iova;
++ dist_cfg.key_cfg_iova = key;
+ dist_cfg.dist_size = dpaa2_eth_queue_count(priv);
-+ dist_cfg.enable = true;
++ dist_cfg.enable = 1;
+
+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
+ dist_cfg.tc = i;
-+
-+ err = dpni_set_rx_hash_dist(priv->mc_io, 0,
-+ priv->mc_token, &dist_cfg);
++ err = dpni_set_rx_hash_dist(priv->mc_io, 0, priv->mc_token,
++ &dist_cfg);
+ if (err) {
+ dev_err(dev, "dpni_set_rx_hash_dist failed\n");
-+ return err;
++ break;
+ }
+ }
+
-+ return 0;
++ return err;
+}
+
-+static int config_fs_key(struct dpaa2_eth_priv *priv, dma_addr_t key_iova)
++/* Configure the Rx flow classification key */
++static int config_cls_key(struct dpaa2_eth_priv *priv, dma_addr_t key)
+{
+ struct device *dev = priv->net_dev->dev.parent;
+ struct dpni_rx_dist_cfg dist_cfg;
-+ int i, err;
-
-- if (cls_cfg.num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
-- dev_err(dev, "error adding key extraction rule, too many rules?\n");
-- return -E2BIG;
-+ if (!dpaa2_eth_fs_enabled(priv))
-+ return -EOPNOTSUPP;
++ int i, err = 0;
+
+ memset(&dist_cfg, 0, sizeof(dist_cfg));
+
-+ dist_cfg.key_cfg_iova = key_iova;
++ dist_cfg.key_cfg_iova = key;
+ dist_cfg.dist_size = dpaa2_eth_queue_count(priv);
-+ dist_cfg.enable = true;
++ dist_cfg.enable = 1;
+
+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
+ dist_cfg.tc = i;
-+
-+ err = dpni_set_rx_fs_dist(priv->mc_io, 0,
-+ priv->mc_token, &dist_cfg);
++ err = dpni_set_rx_fs_dist(priv->mc_io, 0, priv->mc_token,
++ &dist_cfg);
+ if (err) {
+ dev_err(dev, "dpni_set_rx_fs_dist failed\n");
-+ return err;
- }
++ break;
++ }
+ }
+
-+ return 0;
++ return err;
+}
-
-+int dpaa2_eth_set_dist_key(struct dpaa2_eth_priv *priv,
-+ enum dpaa2_eth_rx_dist type, u32 key_fields)
-+{
-+ struct device *dev = priv->net_dev->dev.parent;
-+ struct dpkg_profile_cfg cls_cfg;
-+ struct dpkg_extract *key;
-+ u32 hash_fields = 0;
-+ dma_addr_t key_iova;
-+ u8 *key_mem;
-+ int i, err;
+
-+ memset(&cls_cfg, 0, sizeof(cls_cfg));
++/* Size of the Rx flow classification key */
++int dpaa2_eth_cls_key_size(u64 fields)
++{
++ int i, size = 0;
+
-+ for (i = 0; i < priv->num_dist_fields; i++) {
-+ if (!(key_fields & priv->dist_fields[i].id))
++ for (i = 0; i < ARRAY_SIZE(dist_fields); i++) {
++ if (!(fields & dist_fields[i].id))
+ continue;
++ size += dist_fields[i].size;
++ }
++
++ return size;
++}
++
++/* Offset of header field in Rx classification key */
++int dpaa2_eth_cls_fld_off(int prot, int field)
++{
++ int i, off = 0;
+
-+ key = &cls_cfg.extracts[cls_cfg.num_extracts];
++ for (i = 0; i < ARRAY_SIZE(dist_fields); i++) {
++ if (dist_fields[i].cls_prot == prot &&
++ dist_fields[i].cls_field == field)
++ return off;
++ off += dist_fields[i].size;
++ }
++
++ WARN_ONCE(1, "Unsupported header field used for Rx flow cls\n");
++ return 0;
++}
++
++/* Prune unused fields from the classification rule.
++ * Used when masking is not supported
++ */
++void dpaa2_eth_cls_trim_rule(void *key_mem, u64 fields)
++{
++ int off = 0, new_off = 0;
++ int i, size;
++
++ for (i = 0; i < ARRAY_SIZE(dist_fields); i++) {
++ size = dist_fields[i].size;
++ if (dist_fields[i].id & fields) {
++ memcpy(key_mem + new_off, key_mem + off, size);
++ new_off += size;
++ }
++ off += size;
++ }
++}
++
++/* Set Rx distribution (hash or flow classification) key
+ * flags is a combination of RXH_ bits
+ */
+-static int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags)
++static int dpaa2_eth_set_dist_key(struct net_device *net_dev,
++ enum dpaa2_eth_rx_dist type, u64 flags)
+ {
+ struct device *dev = net_dev->dev.parent;
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+ struct dpkg_profile_cfg cls_cfg;
+- struct dpni_rx_tc_dist_cfg dist_cfg;
++ u32 rx_hash_fields = 0;
++ dma_addr_t key_iova;
+ u8 *dma_mem;
+ int i;
+ int err = 0;
+
+- if (!dpaa2_eth_hash_enabled(priv)) {
+- dev_dbg(dev, "Hashing support is not enabled\n");
+- return 0;
+- }
+-
+ memset(&cls_cfg, 0, sizeof(cls_cfg));
+
+- for (i = 0; i < ARRAY_SIZE(hash_fields); i++) {
++ for (i = 0; i < ARRAY_SIZE(dist_fields); i++) {
+ struct dpkg_extract *key =
+ &cls_cfg.extracts[cls_cfg.num_extracts];
+
+- if (!(flags & hash_fields[i].rxnfc_field))
++ /* For both Rx hashing and classification keys
++ * we set only the selected fields.
++ */
++ if (!(flags & dist_fields[i].id))
+ continue;
++ if (type == DPAA2_ETH_RX_DIST_HASH)
++ rx_hash_fields |= dist_fields[i].rxnfc_field;
+
+ if (cls_cfg.num_extracts >= DPKG_MAX_NUM_OF_EXTRACTS) {
+ dev_err(dev, "error adding key extraction rule, too many rules?\n");
+@@ -2020,49 +2966,107 @@ static int dpaa2_eth_set_hash(struct net
+ }
+
key->type = DPKG_EXTRACT_FROM_HDR;
- key->extract.from_hdr.prot = hash_fields[i].cls_prot;
-+ key->extract.from_hdr.prot = priv->dist_fields[i].cls_prot;
++ key->extract.from_hdr.prot = dist_fields[i].cls_prot;
key->extract.from_hdr.type = DPKG_FULL_FIELD;
- key->extract.from_hdr.field = hash_fields[i].cls_field;
-+ key->extract.from_hdr.field = priv->dist_fields[i].cls_field;
++ key->extract.from_hdr.field = dist_fields[i].cls_field;
cls_cfg.num_extracts++;
++ }
++
++ dma_mem = kzalloc(DPAA2_CLASSIFIER_DMA_SIZE, GFP_KERNEL);
++ if (!dma_mem)
++ return -ENOMEM;
++
++ err = dpni_prepare_key_cfg(&cls_cfg, dma_mem);
++ if (err) {
++ dev_err(dev, "dpni_prepare_key_cfg error %d\n", err);
++ goto free_key;
++ }
++
++ /* Prepare for setting the rx dist */
++ key_iova = dma_map_single(dev, dma_mem, DPAA2_CLASSIFIER_DMA_SIZE,
++ DMA_TO_DEVICE);
++ if (dma_mapping_error(dev, key_iova)) {
++ dev_err(dev, "DMA mapping failed\n");
++ err = -ENOMEM;
++ goto free_key;
++ }
++
++ if (type == DPAA2_ETH_RX_DIST_HASH) {
++ if (dpaa2_eth_has_legacy_dist(priv))
++ err = config_legacy_hash_key(priv, key_iova);
++ else
++ err = config_hash_key(priv, key_iova);
++ } else {
++ err = config_cls_key(priv, key_iova);
++ }
++
++ dma_unmap_single(dev, key_iova, DPAA2_CLASSIFIER_DMA_SIZE,
++ DMA_TO_DEVICE);
++ if (!err && type == DPAA2_ETH_RX_DIST_HASH)
++ priv->rx_hash_fields = rx_hash_fields;
++
++free_key:
++ kfree(dma_mem);
++ return err;
++}
++
++int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags)
++{
++ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
++ u64 key = 0;
++ int i;
++
++ if (!dpaa2_eth_hash_enabled(priv))
++ return -EOPNOTSUPP;
++
++ for (i = 0; i < ARRAY_SIZE(dist_fields); i++)
++ if (dist_fields[i].rxnfc_field & flags)
++ key |= dist_fields[i].id;
++
++ return dpaa2_eth_set_dist_key(net_dev, DPAA2_ETH_RX_DIST_HASH, key);
++}
++
++int dpaa2_eth_set_cls(struct net_device *net_dev, u64 flags)
++{
++ return dpaa2_eth_set_dist_key(net_dev, DPAA2_ETH_RX_DIST_CLS, flags);
++}
++
++static int dpaa2_eth_set_default_cls(struct dpaa2_eth_priv *priv)
++{
++ struct device *dev = priv->net_dev->dev.parent;
++ int err;
- priv->rx_hash_fields |= hash_fields[i].rxnfc_field;
-+ hash_fields |= priv->dist_fields[i].rxnfc_field;
++ /* Check if we actually support Rx flow classification */
++ if (dpaa2_eth_has_legacy_dist(priv)) {
++ dev_dbg(dev, "Rx cls not supported by current MC version\n");
++ return -EOPNOTSUPP;
}
- dma_mem = kzalloc(DPAA2_CLASSIFIER_DMA_SIZE, GFP_KERNEL);
- if (!dma_mem)
-+ key_mem = kzalloc(DPAA2_CLASSIFIER_DMA_SIZE, GFP_KERNEL);
-+ if (!key_mem)
- return -ENOMEM;
-
+- return -ENOMEM;
+-
- err = dpni_prepare_key_cfg(&cls_cfg, dma_mem);
-+ err = dpni_prepare_key_cfg(&cls_cfg, key_mem);
- if (err) {
- dev_err(dev, "dpni_prepare_key_cfg error %d\n", err);
+- if (err) {
+- dev_err(dev, "dpni_prepare_key_cfg error %d\n", err);
- goto err_prep_key;
-+ goto free_key;
++ if (!dpaa2_eth_fs_enabled(priv)) {
++ dev_dbg(dev, "Rx cls disabled in DPNI options\n");
++ return -EOPNOTSUPP;
}
- memset(&dist_cfg, 0, sizeof(dist_cfg));
@@ -4355,57 +4599,43 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- DPAA2_CLASSIFIER_DMA_SIZE,
- DMA_TO_DEVICE);
- if (dma_mapping_error(dev, dist_cfg.key_cfg_iova)) {
-+ key_iova = dma_map_single(dev, key_mem, DPAA2_CLASSIFIER_DMA_SIZE,
-+ DMA_TO_DEVICE);
-+ if (dma_mapping_error(dev, key_iova)) {
- dev_err(dev, "DMA mapping failed\n");
- err = -ENOMEM;
+- dev_err(dev, "DMA mapping failed\n");
+- err = -ENOMEM;
- goto err_dma_map;
-+ goto free_key;
++ if (!dpaa2_eth_hash_enabled(priv)) {
++ dev_dbg(dev, "Rx cls disabled for single queue DPNIs\n");
++ return -EOPNOTSUPP;
}
- dist_cfg.dist_size = dpaa2_eth_queue_count(priv);
- dist_cfg.dist_mode = DPNI_DIST_MODE_HASH;
-+ switch (type) {
-+ case DPAA2_ETH_RX_DIST_LEGACY:
-+ err = legacy_config_dist_key(priv, key_iova);
-+ break;
-+ case DPAA2_ETH_RX_DIST_HASH:
-+ err = config_hash_key(priv, key_iova);
-+ break;
-+ case DPAA2_ETH_RX_DIST_FS:
-+ err = config_fs_key(priv, key_iova);
-+ break;
-+ default:
-+ err = -EINVAL;
-+ break;
-+ }
++ /* If there is no support for masking in the classification table,
++ * we don't set a default key, as it will depend on the rules
++ * added by the user at runtime.
++ */
++ if (!dpaa2_eth_fs_mask_enabled(priv))
++ goto out;
- err = dpni_set_rx_tc_dist(priv->mc_io, 0, priv->mc_token, 0, &dist_cfg);
- dma_unmap_single(dev, dist_cfg.key_cfg_iova,
- DPAA2_CLASSIFIER_DMA_SIZE, DMA_TO_DEVICE);
-- if (err)
++ err = dpaa2_eth_set_cls(priv->net_dev, DPAA2_ETH_DIST_ALL);
+ if (err)
- dev_err(dev, "dpni_set_rx_tc_dist() error %d\n", err);
-+ dma_unmap_single(dev, key_iova, DPAA2_CLASSIFIER_DMA_SIZE,
-+ DMA_TO_DEVICE);
-+ if (err) {
-+ if (err != -EOPNOTSUPP)
-+ dev_err(dev, "Distribution key config failed\n");
-+ goto free_key;
-+ }
++ return err;
-err_dma_map:
-err_prep_key:
- kfree(dma_mem);
-+ if (type != DPAA2_ETH_RX_DIST_FS)
-+ priv->rx_hash_fields = hash_fields;
+- return err;
++out:
++ priv->rx_cls_enabled = 1;
+
-+free_key:
-+ kfree(key_mem);
- return err;
++ return 0;
}
-@@ -2080,6 +2983,7 @@ static int bind_dpni(struct dpaa2_eth_pr
+ /* Bind the DPNI to its needed objects and resources: buffer pool, DPIOs,
+@@ -2080,6 +3084,7 @@ static int bind_dpni(struct dpaa2_eth_pr
pools_params.num_dpbp = 1;
pools_params.pools[0].dpbp_id = priv->dpbp_dev->obj_desc.id;
pools_params.pools[0].backup_pool = 0;
@@ -4413,36 +4643,28 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
pools_params.pools[0].buffer_size = DPAA2_ETH_RX_BUF_SIZE;
err = dpni_set_pools(priv->mc_io, 0, priv->mc_token, &pools_params);
if (err) {
-@@ -2087,17 +2991,36 @@ static int bind_dpni(struct dpaa2_eth_pr
+@@ -2087,17 +3092,28 @@ static int bind_dpni(struct dpaa2_eth_pr
return err;
}
- /* have the interface implicitly distribute traffic based on supported
- * header fields
-+ /* Verify classification options and disable hashing and/or
-+ * flow steering support in case of invalid configuration values
++ /* have the interface implicitly distribute traffic based on
++ * the default hash key
*/
- err = dpaa2_eth_set_hash(net_dev, DPAA2_RXH_SUPPORTED);
- if (err)
- netdev_err(net_dev, "Failed to configure hashing\n");
-+ priv->dist_fields = default_dist_fields;
-+ priv->num_dist_fields = ARRAY_SIZE(default_dist_fields);
-+ check_cls_support(priv);
++ err = dpaa2_eth_set_hash(net_dev, DPAA2_RXH_DEFAULT);
++ if (err && err != -EOPNOTSUPP)
++ dev_err(dev, "Failed to configure hashing\n");
+
-+ /* have the interface implicitly distribute traffic based on
-+ * a static hash key. Also configure flow steering key, if supported.
-+ * Errors here are not blocking, so just let the called function
-+ * print its error message and move along.
++ /* Configure the flow classification key; it includes all
++ * supported header fields and cannot be modified at runtime
+ */
-+ if (dpaa2_eth_has_legacy_dist(priv)) {
-+ dpaa2_eth_set_dist_key(priv, DPAA2_ETH_RX_DIST_LEGACY,
-+ DPAA2_ETH_DIST_ALL);
-+ } else {
-+ dpaa2_eth_set_dist_key(priv, DPAA2_ETH_RX_DIST_HASH,
-+ DPAA2_ETH_DIST_DEFAULT_HASH);
-+ dpaa2_eth_set_dist_key(priv, DPAA2_ETH_RX_DIST_FS,
-+ DPAA2_ETH_DIST_ALL);
-+ }
++ err = dpaa2_eth_set_default_cls(priv);
++ if (err && err != -EOPNOTSUPP)
++ dev_err(dev, "Failed to configure Rx classification key\n");
/* Configure handling of error frames */
err_cfg.errors = DPAA2_FAS_RX_ERR_MASK;
@@ -4455,7 +4677,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
err = dpni_set_errors_behavior(priv->mc_io, 0, priv->mc_token,
&err_cfg);
if (err) {
-@@ -2114,6 +3037,11 @@ static int bind_dpni(struct dpaa2_eth_pr
+@@ -2114,6 +3130,11 @@ static int bind_dpni(struct dpaa2_eth_pr
case DPAA2_TX_CONF_FQ:
err = setup_tx_flow(priv, &priv->fq[i]);
break;
@@ -4467,7 +4689,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
default:
dev_err(dev, "Invalid FQ type %d\n", priv->fq[i].type);
return -EINVAL;
-@@ -2237,11 +3165,14 @@ static int netdev_init(struct net_device
+@@ -2237,11 +3258,14 @@ static int netdev_init(struct net_device
{
struct device *dev = net_dev->dev.parent;
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
@@ -4482,7 +4704,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
err = set_mac_addr(priv);
if (err)
-@@ -2255,14 +3186,14 @@ static int netdev_init(struct net_device
+@@ -2255,14 +3279,14 @@ static int netdev_init(struct net_device
return err;
}
@@ -4493,10 +4715,10 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
-
- /* Set MTU limits */
- net_dev->min_mtu = 68;
-+ /* Set MTU upper limit; lower limit is default (68B) */
++ /* Set MTU upper limit; lower limit is 68B (default value) */
net_dev->max_mtu = DPAA2_ETH_MAX_MTU;
+ err = dpni_set_max_frame_length(priv->mc_io, 0, priv->mc_token,
-+ (u16)DPAA2_ETH_MFL);
++ DPAA2_ETH_MFL);
+ if (err) {
+ dev_err(dev, "dpni_set_max_frame_length() failed\n");
+ return err;
@@ -4504,7 +4726,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Set actual number of queues in the net device */
num_queues = dpaa2_eth_queue_count(priv);
-@@ -2277,12 +3208,23 @@ static int netdev_init(struct net_device
+@@ -2277,12 +3301,23 @@ static int netdev_init(struct net_device
return err;
}
@@ -4534,7 +4756,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return 0;
}
-@@ -2303,14 +3245,9 @@ static int poll_link_state(void *arg)
+@@ -2303,14 +3338,9 @@ static int poll_link_state(void *arg)
return 0;
}
@@ -4550,7 +4772,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct device *dev = (struct device *)arg;
struct fsl_mc_device *dpni_dev = to_fsl_mc_device(dev);
struct net_device *net_dev = dev_get_drvdata(dev);
-@@ -2320,18 +3257,12 @@ static irqreturn_t dpni_irq0_handler_thr
+@@ -2320,18 +3350,12 @@ static irqreturn_t dpni_irq0_handler_thr
DPNI_IRQ_INDEX, &status);
if (unlikely(err)) {
netdev_err(net_dev, "Can't get irq status (err %d)\n", err);
@@ -4571,7 +4793,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return IRQ_HANDLED;
}
-@@ -2348,8 +3279,7 @@ static int setup_irqs(struct fsl_mc_devi
+@@ -2348,8 +3372,7 @@ static int setup_irqs(struct fsl_mc_devi
irq = ls_dev->irqs[0];
err = devm_request_threaded_irq(&ls_dev->dev, irq->msi_desc->irq,
@@ -4581,7 +4803,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
IRQF_NO_SUSPEND | IRQF_ONESHOT,
dev_name(&ls_dev->dev), &ls_dev->dev);
if (err < 0) {
-@@ -2405,6 +3335,393 @@ static void del_ch_napi(struct dpaa2_eth
+@@ -2405,6 +3428,393 @@ static void del_ch_napi(struct dpaa2_eth
}
}
@@ -4975,7 +5197,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
{
struct device *dev;
-@@ -2415,7 +3732,7 @@ static int dpaa2_eth_probe(struct fsl_mc
+@@ -2415,7 +3825,7 @@ static int dpaa2_eth_probe(struct fsl_mc
dev = &dpni_dev->dev;
/* Net device */
@@ -4984,7 +5206,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
if (!net_dev) {
dev_err(dev, "alloc_etherdev_mq() failed\n");
return -ENOMEM;
-@@ -2433,7 +3750,10 @@ static int dpaa2_eth_probe(struct fsl_mc
+@@ -2433,7 +3843,10 @@ static int dpaa2_eth_probe(struct fsl_mc
err = fsl_mc_portal_allocate(dpni_dev, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
&priv->mc_io);
if (err) {
@@ -4996,7 +5218,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
goto err_portal_alloc;
}
-@@ -2456,9 +3776,6 @@ static int dpaa2_eth_probe(struct fsl_mc
+@@ -2456,9 +3869,6 @@ static int dpaa2_eth_probe(struct fsl_mc
if (err)
goto err_bind;
@@ -5006,7 +5228,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Percpu statistics */
priv->percpu_stats = alloc_percpu(*priv->percpu_stats);
if (!priv->percpu_stats) {
-@@ -2491,7 +3808,14 @@ static int dpaa2_eth_probe(struct fsl_mc
+@@ -2491,7 +3901,14 @@ static int dpaa2_eth_probe(struct fsl_mc
if (err)
goto err_alloc_rings;
@@ -5022,7 +5244,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
err = setup_irqs(dpni_dev);
if (err) {
-@@ -2499,25 +3823,41 @@ static int dpaa2_eth_probe(struct fsl_mc
+@@ -2499,25 +3916,41 @@ static int dpaa2_eth_probe(struct fsl_mc
priv->poll_thread = kthread_run(poll_link_state, priv,
"%s_poll_link", net_dev->name);
if (IS_ERR(priv->poll_thread)) {
@@ -5066,7 +5288,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
del_ch_napi(priv);
err_bind:
free_dpbp(priv);
-@@ -2544,8 +3884,15 @@ static int dpaa2_eth_remove(struct fsl_m
+@@ -2544,8 +3977,15 @@ static int dpaa2_eth_remove(struct fsl_m
net_dev = dev_get_drvdata(dev);
priv = netdev_priv(net_dev);
@@ -5083,7 +5305,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
if (priv->do_link_poll)
kthread_stop(priv->poll_thread);
-@@ -2555,8 +3902,6 @@ static int dpaa2_eth_remove(struct fsl_m
+@@ -2555,17 +3995,16 @@ static int dpaa2_eth_remove(struct fsl_m
free_rings(priv);
free_percpu(priv->percpu_stats);
free_percpu(priv->percpu_extras);
@@ -5092,8 +5314,10 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
free_dpbp(priv);
free_dpio(priv);
free_dpni(priv);
-@@ -2566,6 +3911,8 @@ static int dpaa2_eth_remove(struct fsl_m
- dev_set_drvdata(dev, NULL);
+
+ fsl_mc_portal_free(priv->mc_io);
+
+- dev_set_drvdata(dev, NULL);
free_netdev(net_dev);
+ dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name);
@@ -5101,7 +5325,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
return 0;
}
-@@ -2588,4 +3935,34 @@ static struct fsl_mc_driver dpaa2_eth_dr
+@@ -2588,4 +4027,34 @@ static struct fsl_mc_driver dpaa2_eth_dr
.match_id_table = dpaa2_eth_match_id_table
};
@@ -5139,15 +5363,51 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+module_exit(dpaa2_eth_driver_exit);
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
-@@ -33,6 +33,7 @@
+@@ -1,40 +1,15 @@
++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+ /* Copyright 2014-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of Freescale Semiconductor nor the
+- * names of its contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
#ifndef __DPAA2_ETH_H
#define __DPAA2_ETH_H
+#include <linux/dcbnl.h>
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
++#include <linux/filter.h>
-@@ -44,9 +45,17 @@
+ #include "../../fsl-mc/include/dpaa2-io.h"
+ #include "../../fsl-mc/include/dpaa2-fd.h"
+@@ -44,6 +19,9 @@
#include "dpni-cmd.h"
#include "dpaa2-eth-trace.h"
@@ -5157,59 +5417,61 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
#define DPAA2_ETH_STORE_SIZE 16
-+/* We set a max threshold for how many Tx confirmations we should process
-+ * on a NAPI poll call, they take less processing time.
-+ */
-+#define TX_CONF_PER_NAPI_POLL 256
-+
- /* Maximum number of scatter-gather entries in an ingress frame,
- * considering the maximum receive frame size is 64K
- */
-@@ -60,6 +69,14 @@
+@@ -60,43 +38,59 @@
/* Convert L3 MTU to L2 MFL */
#define DPAA2_ETH_L2_MAX_FRM(mtu) ((mtu) + VLAN_ETH_HLEN)
+-/* Set the taildrop threshold (in bytes) to allow the enqueue of several jumbo
+- * frames in the Rx queues (length of the current frame is not
+- * taken into account when making the taildrop decision)
+- */
+-#define DPAA2_ETH_TAILDROP_THRESH (64 * 1024)
+-
+-/* Buffer quota per queue. Must be large enough such that for minimum sized
+- * frames taildrop kicks in before the bpool gets depleted, so we compute
+- * how many 64B frames fit inside the taildrop threshold and add a margin
+- * to accommodate the buffer refill delay.
+- */
+-#define DPAA2_ETH_MAX_FRAMES_PER_QUEUE (DPAA2_ETH_TAILDROP_THRESH / 64)
+-#define DPAA2_ETH_NUM_BUFS (DPAA2_ETH_MAX_FRAMES_PER_QUEUE + 256)
+-#define DPAA2_ETH_REFILL_THRESH DPAA2_ETH_MAX_FRAMES_PER_QUEUE
+/* Maximum burst size value for Tx shaping */
+#define DPAA2_ETH_MAX_BURST_SIZE 0xF7FF
+
+ /* Maximum number of buffers that can be acquired/released through a single
+ * QBMan command
+ */
+ #define DPAA2_ETH_BUFS_PER_CMD 7
+
+-/* Hardware requires alignment for ingress/egress buffer addresses
+- * and ingress buffer lengths.
++/* Set the taildrop threshold to 1MB to allow the enqueue of a sufficiently
++ * large number of jumbo frames in the Rx queues (length of the current frame
++ * is not taken into account when making the taildrop decision)
++ */
++#define DPAA2_ETH_TAILDROP_THRESH (1024 * 1024)
+
-+/* Maximum number of buffers that can be acquired/released through a single
-+ * QBMan command
++/* Maximum number of Tx confirmation frames to be processed
++ * in a single NAPI call
+ */
-+#define DPAA2_ETH_BUFS_PER_CMD 7
++#define DPAA2_ETH_TXCONF_PER_NAPI 256
+
- /* Set the taildrop threshold (in bytes) to allow the enqueue of several jumbo
- * frames in the Rx queues (length of the current frame is not
- * taken into account when making the taildrop decision)
-@@ -72,31 +89,32 @@
- * to accommodate the buffer refill delay.
++/* Buffer quota per channel.
++ * We want to keep in check number of ingress frames in flight: for small
++ * sized frames, buffer pool depletion will kick in first; for large sizes,
++ * Rx FQ taildrop threshold will ensure only a reasonable number of frames
++ * will be pending at any given time.
*/
- #define DPAA2_ETH_MAX_FRAMES_PER_QUEUE (DPAA2_ETH_TAILDROP_THRESH / 64)
--#define DPAA2_ETH_NUM_BUFS (DPAA2_ETH_MAX_FRAMES_PER_QUEUE + 256)
--#define DPAA2_ETH_REFILL_THRESH DPAA2_ETH_MAX_FRAMES_PER_QUEUE
-+#define DPAA2_ETH_NUM_BUFS_PER_CH (DPAA2_ETH_MAX_FRAMES_PER_QUEUE + 256)
+-#define DPAA2_ETH_RX_BUF_SIZE 2048
++#define DPAA2_ETH_NUM_BUFS_PER_CH 1024
+#define DPAA2_ETH_REFILL_THRESH(priv) \
+ ((priv)->max_bufs_per_ch - DPAA2_ETH_BUFS_PER_CMD)
-
--/* Maximum number of buffers that can be acquired/released through a single
-- * QBMan command
-- */
--#define DPAA2_ETH_BUFS_PER_CMD 7
++
+/* Global buffer quota in case flow control is enabled */
+#define DPAA2_ETH_NUM_BUFS_FC 256
+
+/* Hardware requires alignment for ingress/egress buffer addresses */
-+#define DPAA2_ETH_TX_BUF_ALIGN 64
-
--/* Hardware requires alignment for ingress/egress buffer addresses
-- * and ingress buffer lengths.
-+/* Due to a limitation in WRIOP 1.0.0, the RX buffer data must be aligned
-+ * to 256B. For newer revisions, the requirement is only for 64B alignment
- */
-+#define DPAA2_ETH_RX_BUF_ALIGN_REV1 256
-+#define DPAA2_ETH_RX_BUF_ALIGN 64
-+
- #define DPAA2_ETH_RX_BUF_SIZE 2048
--#define DPAA2_ETH_TX_BUF_ALIGN 64
+ #define DPAA2_ETH_TX_BUF_ALIGN 64
-#define DPAA2_ETH_RX_BUF_ALIGN 256
-#define DPAA2_ETH_NEEDED_HEADROOM(p_priv) \
- ((p_priv)->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN)
@@ -5222,19 +5484,29 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
- (DPAA2_ETH_RX_BUF_SIZE + \
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + \
- DPAA2_ETH_RX_BUF_ALIGN)
-+#define DPAA2_ETH_SKB_SIZE \
-+ (DPAA2_ETH_RX_BUF_SIZE + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+
-+/* PTP nominal frequency 1GHz */
-+#define DPAA2_PTP_NOMINAL_FREQ_PERIOD_NS 1
++#define DPAA2_ETH_RX_BUF_RAW_SIZE PAGE_SIZE
++#define DPAA2_ETH_RX_BUF_TAILROOM \
++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
++#define DPAA2_ETH_RX_BUF_SIZE \
++ (DPAA2_ETH_RX_BUF_RAW_SIZE - DPAA2_ETH_RX_BUF_TAILROOM)
+
+/* Hardware annotation area in RX/TX buffers */
+#define DPAA2_ETH_RX_HWA_SIZE 64
+#define DPAA2_ETH_TX_HWA_SIZE 128
++
++/* PTP nominal frequency 1GHz */
++#define DPAA2_PTP_NOMINAL_FREQ_PERIOD_NS 1
++
++/* Due to a limitation in WRIOP 1.0.0, the RX buffer data must be aligned
++ * to 256B. For newer revisions, the requirement is only for 64B alignment
++ */
++#define DPAA2_ETH_RX_BUF_ALIGN_REV1 256
++#define DPAA2_ETH_RX_BUF_ALIGN 64
/* We are accommodating a skb backpointer and some S/G info
* in the frame's software annotation. The hardware
-@@ -104,12 +122,32 @@
+@@ -104,12 +98,32 @@
*/
#define DPAA2_ETH_SWA_SIZE 64
@@ -5271,11 +5543,10 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
};
/* Annotation valid bits in FD FRC */
-@@ -120,23 +158,14 @@ struct dpaa2_eth_swa {
- #define DPAA2_FD_FRC_FASWOV 0x0800
+@@ -121,22 +135,14 @@ struct dpaa2_eth_swa {
#define DPAA2_FD_FRC_FAICFDV 0x0400
--/* Error bits in FD CTRL */
+ /* Error bits in FD CTRL */
-#define DPAA2_FD_CTRL_UFD 0x00000004
-#define DPAA2_FD_CTRL_SBE 0x00000008
-#define DPAA2_FD_CTRL_FSE 0x00000020
@@ -5294,13 +5565,14 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ FD_CTRL_FAERR)
/* Annotation bits in FD CTRL */
- #define DPAA2_FD_CTRL_ASAL 0x00020000 /* ASAL = 128 */
+-#define DPAA2_FD_CTRL_ASAL 0x00020000 /* ASAL = 128 */
-#define DPAA2_FD_CTRL_PTA 0x00800000
-#define DPAA2_FD_CTRL_PTV1 0x00400000
++#define DPAA2_FD_CTRL_ASAL 0x00020000 /* ASAL = 128B */
/* Frame annotation status */
struct dpaa2_fas {
-@@ -144,7 +173,7 @@ struct dpaa2_fas {
+@@ -144,7 +150,7 @@ struct dpaa2_fas {
u8 ppid;
__le16 ifpid;
__le32 status;
@@ -5309,7 +5581,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Frame annotation status word is located in the first 8 bytes
* of the buffer's hardware annoatation area
-@@ -152,11 +181,45 @@ struct dpaa2_fas {
+@@ -152,11 +158,45 @@ struct dpaa2_fas {
#define DPAA2_FAS_OFFSET 0
#define DPAA2_FAS_SIZE (sizeof(struct dpaa2_fas))
@@ -5347,7 +5619,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ return dpaa2_get_hwa(buf_addr, swa) + DPAA2_FAS_OFFSET;
+}
+
-+static inline u64 *dpaa2_get_ts(void *buf_addr, bool swa)
++static inline __le64 *dpaa2_get_ts(void *buf_addr, bool swa)
+{
+ return dpaa2_get_hwa(buf_addr, swa) + DPAA2_TS_OFFSET;
+}
@@ -5359,7 +5631,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Error and status bits in the frame annotation status word */
/* Debug frame, otherwise supposed to be discarded */
-@@ -203,11 +266,6 @@ struct dpaa2_fas {
+@@ -203,11 +243,6 @@ struct dpaa2_fas {
DPAA2_FAS_BLE | \
DPAA2_FAS_L3CE | \
DPAA2_FAS_L4CE)
@@ -5371,22 +5643,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Time in milliseconds between link state updates */
#define DPAA2_ETH_LINK_STATE_REFRESH 1000
-@@ -218,6 +276,14 @@ struct dpaa2_fas {
- */
- #define DPAA2_ETH_ENQUEUE_RETRIES 10
-
-+/* Tx congestion entry & exit thresholds, in number of bytes.
-+ * We allow a maximum of 512KB worth of frames pending processing on the Tx
-+ * queues of an interface
-+ */
-+#define DPAA2_ETH_TX_CONG_ENTRY_THRESH (512 * 1024)
-+#define DPAA2_ETH_TX_CONG_EXIT_THRESH \
-+ (DPAA2_ETH_TX_CONG_ENTRY_THRESH * 9 / 10)
-+
- /* Driver statistics, other than those in struct rtnl_link_stats64.
- * These are usually collected per-CPU and aggregated by ethtool.
- */
-@@ -226,6 +292,7 @@ struct dpaa2_eth_drv_stats {
+@@ -226,6 +261,7 @@ struct dpaa2_eth_drv_stats {
__u64 tx_conf_bytes;
__u64 tx_sg_frames;
__u64 tx_sg_bytes;
@@ -5394,16 +5651,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
__u64 rx_sg_frames;
__u64 rx_sg_bytes;
/* Enqueues retried due to portal busy */
-@@ -236,6 +303,8 @@ struct dpaa2_eth_drv_stats {
- struct dpaa2_eth_fq_stats {
- /* Number of frames received on this queue */
- __u64 frames;
-+ /* Number of times this queue entered congestion */
-+ __u64 congestion_entry;
- };
-
- /* Per-channel statistics */
-@@ -250,17 +319,23 @@ struct dpaa2_eth_ch_stats {
+@@ -250,17 +286,23 @@ struct dpaa2_eth_ch_stats {
__u64 pull_err;
};
@@ -5431,25 +5679,31 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
};
struct dpaa2_eth_priv;
-@@ -269,6 +344,7 @@ struct dpaa2_eth_fq {
+@@ -268,15 +310,19 @@ struct dpaa2_eth_priv;
+ struct dpaa2_eth_fq {
u32 fqid;
u32 tx_qdbin;
++ u32 tx_fqid;
u16 flowid;
+ u8 tc;
int target_cpu;
++ u32 dq_frames;
++ u32 dq_bytes;
struct dpaa2_eth_channel *channel;
enum dpaa2_eth_fq_type type;
-@@ -276,7 +352,8 @@ struct dpaa2_eth_fq {
- void (*consume)(struct dpaa2_eth_priv *,
- struct dpaa2_eth_channel *,
- const struct dpaa2_fd *,
+
+- void (*consume)(struct dpaa2_eth_priv *,
+- struct dpaa2_eth_channel *,
+- const struct dpaa2_fd *,
- struct napi_struct *);
-+ struct napi_struct *,
-+ u16 queue_id);
++ void (*consume)(struct dpaa2_eth_priv *priv,
++ struct dpaa2_eth_channel *ch,
++ const struct dpaa2_fd *fd,
++ struct dpaa2_eth_fq *fq);
struct dpaa2_eth_fq_stats stats;
};
-@@ -285,24 +362,53 @@ struct dpaa2_eth_channel {
+@@ -285,19 +331,29 @@ struct dpaa2_eth_channel {
struct fsl_mc_device *dpcon;
int dpcon_id;
int ch_id;
@@ -5464,11 +5718,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ u64 rel_buf_array[DPAA2_ETH_BUFS_PER_CMD];
+ u8 rel_buf_cnt;
+ bool flush;
-+};
-+
-+struct dpaa2_eth_cls_rule {
-+ struct ethtool_rx_flow_spec fs;
-+ bool in_use;
};
-struct dpaa2_eth_hash_fields {
@@ -5476,77 +5725,56 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
u64 rxnfc_field;
enum net_prot cls_prot;
int cls_field;
-+ int offset;
int size;
-+ u32 id;
++ u64 id;
++};
++
++struct dpaa2_eth_cls_rule {
++ struct ethtool_rx_flow_spec fs;
++ u8 in_use;
};
/* Driver private data */
- struct dpaa2_eth_priv {
- struct net_device *net_dev;
-+ /* Standard statistics */
-+ struct rtnl_link_stats64 __percpu *percpu_stats;
-+ /* Extra stats, in addition to the ones known by the kernel */
-+ struct dpaa2_eth_drv_stats __percpu *percpu_extras;
-+ bool ts_tx_en; /* Tx timestamping enabled */
-+ bool ts_rx_en; /* Rx timestamping enabled */
-+ u16 tx_data_offset;
-+ u16 bpid;
-+ u16 tx_qdid;
-+ u16 rx_buf_align;
-+ struct iommu_domain *iommu_domain;
-+ int max_bufs_per_ch;
-+ int refill_thresh;
-+ bool has_xdp_prog;
-+
-+ void *cscn_mem; /* Tx congestion notifications are written here */
-+ void *cscn_unaligned;
-+ dma_addr_t cscn_dma;
+@@ -306,17 +362,29 @@ struct dpaa2_eth_priv {
u8 num_fqs;
struct dpaa2_eth_fq fq[DPAA2_ETH_MAX_QUEUES];
-@@ -311,51 +417,193 @@ struct dpaa2_eth_priv {
++ int (*enqueue)(struct dpaa2_eth_priv *priv,
++ struct dpaa2_eth_fq *fq,
++ struct dpaa2_fd *fd, u8 prio);
+
+ u8 num_channels;
struct dpaa2_eth_channel *channel[DPAA2_ETH_MAX_DPCONS];
++ int max_bufs_per_ch;
++ int refill_thresh;
++
++ bool has_xdp_prog;
struct dpni_attr dpni_attrs;
-- u16 tx_data_offset;
--
+ u16 dpni_ver_major;
+ u16 dpni_ver_minor;
+ u16 tx_data_offset;
+
struct fsl_mc_device *dpbp_dev;
-- u16 bpid;
-- struct iommu_domain *iommu_domain;
+ u16 bpid;
+ struct iommu_domain *iommu_domain;
-- u16 tx_qdid;
++ bool ts_tx_en; /* Tx timestamping enabled */
++ bool ts_rx_en; /* Rx timestamping enabled */
++
+ u16 tx_qdid;
struct fsl_mc_io *mc_io;
/* Cores which have an affine DPIO/DPCON.
- * This is the cpu set on which Rx and Tx conf frames are processed
- */
- struct cpumask dpio_cpumask;
-
-- /* Standard statistics */
-- struct rtnl_link_stats64 __percpu *percpu_stats;
-- /* Extra stats, in addition to the ones known by the kernel */
-- struct dpaa2_eth_drv_stats __percpu *percpu_extras;
--
- u16 mc_token;
-
- struct dpni_link_state link_state;
- bool do_link_poll;
- struct task_struct *poll_thread;
+@@ -337,13 +405,30 @@ struct dpaa2_eth_priv {
-+ /* Rx distribution (hash and flow steering) header fields
-+ * supported by the driver
-+ */
-+ struct dpaa2_eth_dist_fields *dist_fields;
-+ u8 num_dist_fields;
/* enabled ethtool hashing bits */
u64 rx_hash_fields;
++ u64 rx_cls_fields;
++ struct dpaa2_eth_cls_rule *cls_rule;
++ u8 rx_cls_enabled;
+#ifdef CONFIG_FSL_DPAA2_ETH_DEBUGFS
+ struct dpaa2_debugfs dbg;
+#endif
-+ /* array of classification rules */
-+ struct dpaa2_eth_cls_rule *cls_rule;
+ struct dpni_tx_shaping_cfg shaping_cfg;
+
+ u8 dcbx_mode;
@@ -5555,55 +5783,26 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ bool tx_pause_frames;
+
+ bool ceetm_en;
-+};
-+
-+enum dpaa2_eth_rx_dist {
-+ DPAA2_ETH_RX_DIST_HASH,
-+ DPAA2_ETH_RX_DIST_FS,
-+ DPAA2_ETH_RX_DIST_LEGACY
};
-/* default Rx hash options, set during probing */
--#define DPAA2_RXH_SUPPORTED (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO \
-- | RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 \
-- | RXH_L4_B_2_3)
-+/* Supported Rx distribution field ids */
-+#define DPAA2_ETH_DIST_ETHSRC BIT(0)
-+#define DPAA2_ETH_DIST_ETHDST BIT(1)
-+#define DPAA2_ETH_DIST_ETHTYPE BIT(2)
-+#define DPAA2_ETH_DIST_VLAN BIT(3)
-+#define DPAA2_ETH_DIST_IPSRC BIT(4)
-+#define DPAA2_ETH_DIST_IPDST BIT(5)
-+#define DPAA2_ETH_DIST_IPPROTO BIT(6)
-+#define DPAA2_ETH_DIST_L4SRC BIT(7)
-+#define DPAA2_ETH_DIST_L4DST BIT(8)
-+#define DPAA2_ETH_DIST_ALL (~0U)
-+
-+/* Default Rx hash key */
-+#define DPAA2_ETH_DIST_DEFAULT_HASH \
-+ (DPAA2_ETH_DIST_IPPROTO | \
-+ DPAA2_ETH_DIST_IPSRC | DPAA2_ETH_DIST_IPDST | \
-+ DPAA2_ETH_DIST_L4SRC | DPAA2_ETH_DIST_L4DST)
+ #define DPAA2_RXH_SUPPORTED (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO \
+ | RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 \
+ | RXH_L4_B_2_3)
++/* default Rx hash options, set during probing */
++#define DPAA2_RXH_DEFAULT (RXH_L3_PROTO | RXH_IP_SRC | RXH_IP_DST | \
++ RXH_L4_B_0_1 | RXH_L4_B_2_3)
++
#define dpaa2_eth_hash_enabled(priv) \
((priv)->dpni_attrs.num_queues > 1)
-+#define dpaa2_eth_fs_enabled(priv) \
-+ (!((priv)->dpni_attrs.options & DPNI_OPT_NO_FS))
-+
-+#define dpaa2_eth_fs_mask_enabled(priv) \
-+ ((priv)->dpni_attrs.options & DPNI_OPT_HAS_KEY_MASKING)
-+
-+#define dpaa2_eth_fs_count(priv) \
-+ ((priv)->dpni_attrs.fs_entries)
-+
- /* Required by struct dpni_rx_tc_dist_cfg::key_cfg_iova */
- #define DPAA2_CLASSIFIER_DMA_SIZE 256
+@@ -352,10 +437,127 @@ struct dpaa2_eth_priv {
extern const struct ethtool_ops dpaa2_ethtool_ops;
extern const char dpaa2_eth_drv_version[];
-
--static int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv)
++extern int dpaa2_phc_index;
++
+static inline int dpaa2_eth_cmp_dpni_ver(struct dpaa2_eth_priv *priv,
+ u16 ver_major, u16 ver_minor)
+{
@@ -5612,27 +5811,51 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ return priv->dpni_ver_major - ver_major;
+}
+
-+#define DPNI_DIST_KEY_VER_MAJOR 7
-+#define DPNI_DIST_KEY_VER_MINOR 5
++/* Minimum firmware version that supports a more flexible API
++ * for configuring the Rx flow hash key
++ */
++#define DPNI_RX_DIST_KEY_VER_MAJOR 7
++#define DPNI_RX_DIST_KEY_VER_MINOR 5
+
-+static inline bool dpaa2_eth_has_legacy_dist(struct dpaa2_eth_priv *priv)
-+{
-+ return (dpaa2_eth_cmp_dpni_ver(priv, DPNI_DIST_KEY_VER_MAJOR,
-+ DPNI_DIST_KEY_VER_MINOR) < 0);
-+}
++#define dpaa2_eth_has_legacy_dist(priv) \
++ (dpaa2_eth_cmp_dpni_ver((priv), DPNI_RX_DIST_KEY_VER_MAJOR, \
++ DPNI_RX_DIST_KEY_VER_MINOR) < 0)
+
-+/* Hardware only sees DPAA2_ETH_RX_BUF_SIZE, but the skb built around
-+ * the buffer also needs space for its shared info struct, and we need
-+ * to allocate enough to accommodate hardware alignment restrictions
-+ */
-+static inline unsigned int dpaa2_eth_buf_raw_size(struct dpaa2_eth_priv *priv)
-+{
-+ return DPAA2_ETH_SKB_SIZE + priv->rx_buf_align;
-+}
++#define dpaa2_eth_fs_enabled(priv) \
++ (!((priv)->dpni_attrs.options & DPNI_OPT_NO_FS))
++
++#define dpaa2_eth_fs_mask_enabled(priv) \
++ ((priv)->dpni_attrs.options & DPNI_OPT_HAS_KEY_MASKING)
++
++#define dpaa2_eth_fs_count(priv) \
++ ((priv)->dpni_attrs.fs_entries)
++
++#define dpaa2_eth_queue_count(priv) \
++ ((priv)->num_channels)
++
++#define dpaa2_eth_tc_count(priv) \
++ ((priv)->dpni_attrs.num_tcs)
++
++enum dpaa2_eth_rx_dist {
++ DPAA2_ETH_RX_DIST_HASH,
++ DPAA2_ETH_RX_DIST_CLS
++};
++
++/* Unique IDs for the supported Rx classification header fields */
++#define DPAA2_ETH_DIST_ETHDST BIT(0)
++#define DPAA2_ETH_DIST_ETHSRC BIT(1)
++#define DPAA2_ETH_DIST_ETHTYPE BIT(2)
++#define DPAA2_ETH_DIST_VLAN BIT(3)
++#define DPAA2_ETH_DIST_IPSRC BIT(4)
++#define DPAA2_ETH_DIST_IPDST BIT(5)
++#define DPAA2_ETH_DIST_IPPROTO BIT(6)
++#define DPAA2_ETH_DIST_L4SRC BIT(7)
++#define DPAA2_ETH_DIST_L4DST BIT(8)
++#define DPAA2_ETH_DIST_ALL (~0U)
+
-+/* Total headroom needed by the hardware in Tx frame buffers */
-+static inline unsigned int
-+dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv, struct sk_buff *skb)
++static inline
++unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv,
++ struct sk_buff *skb)
+{
+ unsigned int headroom = DPAA2_ETH_SWA_SIZE;
+
@@ -5641,7 +5864,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ */
+ if (!skb)
+ return headroom;
-+
+
+-static int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv)
+ /* For non-linear skbs we have no headroom requirement, as we build a
+ * SG frame with a newly allocated SGT buffer
+ */
@@ -5656,24 +5880,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
+
+/* Extra headroom space requested to hardware, in order to make sure there's
-+ * no realloc'ing in forwarding scenarios. We need to reserve enough space
-+ * such that we can accommodate the maximum required Tx offset and alignment
-+ * in the ingress frame buffer
++ * no realloc'ing in forwarding scenarios
+ */
+static inline unsigned int dpaa2_eth_rx_headroom(struct dpaa2_eth_priv *priv)
+{
-+ return priv->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN -
-+ DPAA2_ETH_RX_HWA_SIZE;
-+}
-+
-+static inline int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv)
- {
- return priv->dpni_attrs.num_queues;
- }
-
-+static inline int dpaa2_eth_tc_count(struct dpaa2_eth_priv *priv)
-+{
-+ return priv->dpni_attrs.num_tcs;
++ return priv->tx_data_offset - DPAA2_ETH_RX_HWA_SIZE;
+}
+
+static inline bool dpaa2_eth_is_pfc_enabled(struct dpaa2_eth_priv *priv,
@@ -5702,28 +5913,74 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
+
+static inline int dpaa2_eth_ch_count(struct dpaa2_eth_priv *priv)
-+{
+ {
+- return priv->dpni_attrs.num_queues;
+ return 1;
-+}
-+
-+void check_cls_support(struct dpaa2_eth_priv *priv);
+ }
+
++int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags);
++int dpaa2_eth_set_cls(struct net_device *net_dev, u64 key);
++int dpaa2_eth_cls_key_size(u64 key);
++int dpaa2_eth_cls_fld_off(int prot, int field);
++void dpaa2_eth_cls_trim_rule(void *key_mem, u64 fields);
+
+int set_rx_taildrop(struct dpaa2_eth_priv *priv);
+
-+int dpaa2_eth_set_dist_key(struct dpaa2_eth_priv *priv,
-+ enum dpaa2_eth_rx_dist type, u32 key_fields);
-+
#endif /* __DPAA2_H */
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
-@@ -1,5 +1,5 @@
+@@ -1,35 +1,10 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/* Copyright 2014-2016 Freescale Semiconductor Inc.
- * Copyright 2016 NXP
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of Freescale Semiconductor nor the
+- * names of its contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Copyright 2016-2017 NXP
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
-@@ -62,6 +62,7 @@ static char dpaa2_ethtool_extras[][ETH_G
+ */
+
++#include <linux/net_tstamp.h>
++
+ #include "dpni.h" /* DPNI_LINK_OPT_* */
+ #include "dpaa2-eth.h"
+
+@@ -52,6 +27,10 @@ static char dpaa2_ethtool_stats[][ETH_GS
+ "[hw] rx nobuffer discards",
+ "[hw] tx discarded frames",
+ "[hw] tx confirmed frames",
++ "[hw] tx dequeued bytes",
++ "[hw] tx dequeued frames",
++ "[hw] tx rejected bytes",
++ "[hw] tx rejected frames",
+ };
+
+ #define DPAA2_ETH_NUM_STATS ARRAY_SIZE(dpaa2_ethtool_stats)
+@@ -62,6 +41,7 @@ static char dpaa2_ethtool_extras[][ETH_G
"[drv] tx conf bytes",
"[drv] tx sg frames",
"[drv] tx sg bytes",
@@ -5731,31 +5988,28 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
"[drv] rx sg frames",
"[drv] rx sg bytes",
"[drv] enqueue portal busy",
-@@ -69,6 +70,15 @@ static char dpaa2_ethtool_extras[][ETH_G
+@@ -69,6 +49,12 @@ static char dpaa2_ethtool_extras[][ETH_G
"[drv] dequeue portal busy",
"[drv] channel pull errors",
"[drv] cdan",
-+ "[drv] tx congestion state",
-+#ifdef CONFIG_FSL_QBMAN_DEBUG
+ /* FQ stats */
+ "rx pending frames",
+ "rx pending bytes",
+ "tx conf pending frames",
+ "tx conf pending bytes",
+ "buffer count"
-+#endif
};
#define DPAA2_ETH_NUM_EXTRA_STATS ARRAY_SIZE(dpaa2_ethtool_extras)
-@@ -76,10 +86,15 @@ static char dpaa2_ethtool_extras[][ETH_G
+@@ -76,14 +62,55 @@ static char dpaa2_ethtool_extras[][ETH_G
static void dpaa2_eth_get_drvinfo(struct net_device *net_dev,
struct ethtool_drvinfo *drvinfo)
{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+
strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
- strlcpy(drvinfo->version, dpaa2_eth_drv_version,
- sizeof(drvinfo->version));
+- strlcpy(drvinfo->version, dpaa2_eth_drv_version,
+- sizeof(drvinfo->version));
- strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
@@ -5764,7 +6018,86 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
strlcpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
sizeof(drvinfo->bus_info));
}
-@@ -113,25 +128,37 @@ out:
+
++#define DPNI_LINK_AUTONEG_VER_MAJOR 7
++#define DPNI_LINK_AUTONEG_VER_MINOR 8
++
++struct dpaa2_eth_link_mode_map {
++ u64 dpni_lm;
++ u64 ethtool_lm;
++};
++
++static const struct dpaa2_eth_link_mode_map dpaa2_eth_lm_map[] = {
++ {DPNI_ADVERTISED_10BASET_FULL, ETHTOOL_LINK_MODE_10baseT_Full_BIT},
++ {DPNI_ADVERTISED_100BASET_FULL, ETHTOOL_LINK_MODE_100baseT_Full_BIT},
++ {DPNI_ADVERTISED_1000BASET_FULL, ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
++ {DPNI_ADVERTISED_10000BASET_FULL, ETHTOOL_LINK_MODE_10000baseT_Full_BIT},
++ {DPNI_ADVERTISED_2500BASEX_FULL, ETHTOOL_LINK_MODE_2500baseX_Full_BIT},
++ {DPNI_ADVERTISED_AUTONEG, ETHTOOL_LINK_MODE_Autoneg_BIT},
++};
++
++static void link_mode_dpni2ethtool(u64 dpni_lm, unsigned long *ethtool_lm)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_lm_map); i++) {
++ if (dpni_lm & dpaa2_eth_lm_map[i].dpni_lm)
++ __set_bit(dpaa2_eth_lm_map[i].ethtool_lm, ethtool_lm);
++ }
++}
++
++static void link_mode_ethtool2dpni(const unsigned long *ethtool_lm,
++ u64 *dpni_lm)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_lm_map); i++) {
++ if (test_bit(dpaa2_eth_lm_map[i].ethtool_lm, ethtool_lm))
++ *dpni_lm |= dpaa2_eth_lm_map[i].dpni_lm;
++ }
++}
++
+ static int
+ dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
+ struct ethtool_link_ksettings *link_settings)
+@@ -92,17 +119,27 @@ dpaa2_eth_get_link_ksettings(struct net_
+ int err = 0;
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+
+- err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, &state);
+- if (err) {
+- netdev_err(net_dev, "ERROR %d getting link state\n", err);
+- goto out;
++ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_LINK_AUTONEG_VER_MAJOR,
++ DPNI_LINK_AUTONEG_VER_MINOR) < 0) {
++ err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token,
++ &state);
++ if (err) {
++ netdev_err(net_dev, "dpni_get_link_state failed\n");
++ goto out;
++ }
++ } else {
++ err = dpni_get_link_state_v2(priv->mc_io, 0, priv->mc_token,
++ &state);
++ if (err) {
++ netdev_err(net_dev, "dpni_get_link_state_v2 failed\n");
++ goto out;
++ }
++ link_mode_dpni2ethtool(state.supported,
++ link_settings->link_modes.supported);
++ link_mode_dpni2ethtool(state.advertising,
++ link_settings->link_modes.advertising);
+ }
+
+- /* At the moment, we have no way of interrogating the DPMAC
+- * from the DPNI side - and for that matter there may exist
+- * no DPMAC at all. So for now we just don't report anything
+- * beyond the DPNI attributes.
+- */
+ if (state.options & DPNI_LINK_OPT_AUTONEG)
+ link_settings->base.autoneg = AUTONEG_ENABLE;
+ if (!(state.options & DPNI_LINK_OPT_HALF_DUPLEX))
+@@ -113,25 +150,37 @@ out:
return err;
}
@@ -5811,10 +6144,21 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
cfg.rate = link_settings->base.speed;
if (link_settings->base.autoneg == AUTONEG_ENABLE)
cfg.options |= DPNI_LINK_OPT_AUTONEG;
-@@ -149,6 +176,81 @@ dpaa2_eth_set_link_ksettings(struct net_
- */
- netdev_dbg(net_dev, "ERROR %d setting link cfg\n", err);
+@@ -142,13 +191,92 @@ dpaa2_eth_set_link_ksettings(struct net_
+ else
+ cfg.options &= ~DPNI_LINK_OPT_HALF_DUPLEX;
++ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_LINK_AUTONEG_VER_MAJOR,
++ DPNI_LINK_AUTONEG_VER_MINOR)) {
++ err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
++ } else {
++ link_mode_ethtool2dpni(link_settings->link_modes.advertising,
++ &cfg.advertising);
++ dpni_set_link_cfg_v2(priv->mc_io, 0, priv->mc_token, &cfg);
++ }
++ if (err)
++ netdev_err(net_dev, "dpni_set_link_cfg failed");
++
+out:
+ return err;
+}
@@ -5874,7 +6218,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ else
+ cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE;
+
-+ err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
+ err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
+ if (err) {
+ netdev_dbg(net_dev, "Error setting link\n");
+ goto out;
@@ -5886,44 +6230,55 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+ priv->tx_pause_frames = pause->tx_pause;
+ err = set_rx_taildrop(priv);
-+ if (err)
+ if (err)
+- /* ethtool will be loud enough if we return an error; no point
+- * in putting our own error message on the console by default
+- */
+- netdev_dbg(net_dev, "ERROR %d setting link cfg\n", err);
+ netdev_dbg(net_dev, "Error configuring taildrop\n");
-+
+
+out:
return err;
}
-@@ -192,6 +294,13 @@ static void dpaa2_eth_get_ethtool_stats(
+@@ -192,6 +320,10 @@ static void dpaa2_eth_get_ethtool_stats(
int j, k, err;
int num_cnt;
union dpni_statistics dpni_stats;
-+
-+#ifdef CONFIG_FSL_QBMAN_DEBUG
+ u32 fcnt, bcnt;
+ u32 fcnt_rx_total = 0, fcnt_tx_total = 0;
+ u32 bcnt_rx_total = 0, bcnt_tx_total = 0;
+ u32 buf_cnt;
-+#endif
u64 cdan = 0;
u64 portal_busy = 0, pull_err = 0;
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-@@ -204,7 +313,7 @@ static void dpaa2_eth_get_ethtool_stats(
+@@ -202,9 +334,9 @@ static void dpaa2_eth_get_ethtool_stats(
+ sizeof(u64) * (DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS));
+
/* Print standard counters, from DPNI statistics */
- for (j = 0; j <= 2; j++) {
+- for (j = 0; j <= 2; j++) {
++ for (j = 0; j <= 3; j++) {
err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token,
- j, &dpni_stats);
+ j, 0, &dpni_stats);
if (err != 0)
netdev_warn(net_dev, "dpni_get_stats(%d) failed\n", j);
switch (j) {
-@@ -240,12 +349,474 @@ static void dpaa2_eth_get_ethtool_stats(
+@@ -217,6 +349,9 @@ static void dpaa2_eth_get_ethtool_stats(
+ case 2:
+ num_cnt = sizeof(dpni_stats.page_2) / sizeof(u64);
+ break;
++ case 3:
++ num_cnt = sizeof(dpni_stats.page_3) / sizeof(u64);
++ break;
+ }
+ for (k = 0; k < num_cnt; k++)
+ *(data + i++) = dpni_stats.raw.counter[k];
+@@ -240,12 +375,410 @@ static void dpaa2_eth_get_ethtool_stats(
*(data + i++) = portal_busy;
*(data + i++) = pull_err;
*(data + i++) = cdan;
+
-+ *(data + i++) = dpaa2_cscn_state_congested(priv->cscn_mem);
-+
-+#ifdef CONFIG_FSL_QBMAN_DEBUG
+ for (j = 0; j < priv->num_fqs; j++) {
+ /* Print FQ instantaneous counts */
+ err = dpaa2_io_query_fq_count(NULL, priv->fq[j].fqid,
@@ -5953,279 +6308,221 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ return;
+ }
+ *(data + i++) = buf_cnt;
-+#endif
+}
+
-+static int cls_key_off(struct dpaa2_eth_priv *priv, int prot, int field)
++static int prep_eth_rule(struct ethhdr *eth_value, struct ethhdr *eth_mask,
++ void *key, void *mask, u64 *fields)
+{
-+ int i, off = 0;
++ int off;
+
-+ for (i = 0; i < priv->num_dist_fields; i++) {
-+ if (priv->dist_fields[i].cls_prot == prot &&
-+ priv->dist_fields[i].cls_field == field)
-+ return off;
-+ off += priv->dist_fields[i].size;
++ if (eth_mask->h_proto) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_ETH, NH_FLD_ETH_TYPE);
++ *(__be16 *)(key + off) = eth_value->h_proto;
++ *(__be16 *)(mask + off) = eth_mask->h_proto;
++ *fields |= DPAA2_ETH_DIST_ETHTYPE;
+ }
+
-+ return -1;
-+}
-+
-+static u8 cls_key_size(struct dpaa2_eth_priv *priv)
-+{
-+ u8 i, size = 0;
-+
-+ for (i = 0; i < priv->num_dist_fields; i++)
-+ size += priv->dist_fields[i].size;
-+
-+ return size;
-+}
-+
-+void check_cls_support(struct dpaa2_eth_priv *priv)
-+{
-+ u8 key_size = cls_key_size(priv);
-+ struct device *dev = priv->net_dev->dev.parent;
-+
-+ if (dpaa2_eth_hash_enabled(priv)) {
-+ if (priv->dpni_attrs.fs_key_size < key_size) {
-+ dev_info(dev, "max_dist_key_size = %d, expected %d. Hashing and steering are disabled\n",
-+ priv->dpni_attrs.fs_key_size,
-+ key_size);
-+ goto disable_fs;
-+ }
-+ if (priv->num_dist_fields > DPKG_MAX_NUM_OF_EXTRACTS) {
-+ dev_info(dev, "Too many key fields (max = %d). Hashing and steering are disabled\n",
-+ DPKG_MAX_NUM_OF_EXTRACTS);
-+ goto disable_fs;
-+ }
++ if (!is_zero_ether_addr(eth_mask->h_source)) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_ETH, NH_FLD_ETH_SA);
++ ether_addr_copy(key + off, eth_value->h_source);
++ ether_addr_copy(mask + off, eth_mask->h_source);
++ *fields |= DPAA2_ETH_DIST_ETHSRC;
+ }
+
-+ if (dpaa2_eth_fs_enabled(priv)) {
-+ if (!dpaa2_eth_hash_enabled(priv)) {
-+ dev_info(dev, "Insufficient queues. Steering is disabled\n");
-+ goto disable_fs;
-+ }
-+
-+ if (!dpaa2_eth_fs_mask_enabled(priv)) {
-+ dev_info(dev, "Key masks not supported. Steering is disabled\n");
-+ goto disable_fs;
-+ }
++ if (!is_zero_ether_addr(eth_mask->h_dest)) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_ETH, NH_FLD_ETH_DA);
++ ether_addr_copy(key + off, eth_value->h_dest);
++ ether_addr_copy(mask + off, eth_mask->h_dest);
++ *fields |= DPAA2_ETH_DIST_ETHDST;
+ }
+
-+ return;
-+
-+disable_fs:
-+ priv->dpni_attrs.options |= DPNI_OPT_NO_FS;
-+ priv->dpni_attrs.options &= ~DPNI_OPT_HAS_KEY_MASKING;
++ return 0;
+}
+
-+static int prep_l4_rule(struct dpaa2_eth_priv *priv,
-+ struct ethtool_tcpip4_spec *l4_value,
-+ struct ethtool_tcpip4_spec *l4_mask,
-+ void *key, void *mask, u8 l4_proto)
++static int prep_user_ip_rule(struct ethtool_usrip4_spec *uip_value,
++ struct ethtool_usrip4_spec *uip_mask,
++ void *key, void *mask, u64 *fields)
+{
-+ int offset;
++ int off;
++ u32 tmp_value, tmp_mask;
+
-+ if (l4_mask->tos) {
-+ netdev_err(priv->net_dev, "ToS is not supported for IPv4 L4\n");
++ if (uip_mask->tos || uip_mask->ip_ver)
+ return -EOPNOTSUPP;
-+ }
+
-+ if (l4_mask->ip4src) {
-+ offset = cls_key_off(priv, NET_PROT_IP, NH_FLD_IP_SRC);
-+ *(u32 *)(key + offset) = l4_value->ip4src;
-+ *(u32 *)(mask + offset) = l4_mask->ip4src;
-+ }
-+
-+ if (l4_mask->ip4dst) {
-+ offset = cls_key_off(priv, NET_PROT_IP, NH_FLD_IP_DST);
-+ *(u32 *)(key + offset) = l4_value->ip4dst;
-+ *(u32 *)(mask + offset) = l4_mask->ip4dst;
++ if (uip_mask->ip4src) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_IP, NH_FLD_IP_SRC);
++ *(__be32 *)(key + off) = uip_value->ip4src;
++ *(__be32 *)(mask + off) = uip_mask->ip4src;
++ *fields |= DPAA2_ETH_DIST_IPSRC;
+ }
+
-+ if (l4_mask->psrc) {
-+ offset = cls_key_off(priv, NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
-+ *(u32 *)(key + offset) = l4_value->psrc;
-+ *(u32 *)(mask + offset) = l4_mask->psrc;
++ if (uip_mask->ip4dst) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_IP, NH_FLD_IP_DST);
++ *(__be32 *)(key + off) = uip_value->ip4dst;
++ *(__be32 *)(mask + off) = uip_mask->ip4dst;
++ *fields |= DPAA2_ETH_DIST_IPDST;
+ }
+
-+ if (l4_mask->pdst) {
-+ offset = cls_key_off(priv, NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
-+ *(u32 *)(key + offset) = l4_value->pdst;
-+ *(u32 *)(mask + offset) = l4_mask->pdst;
++ if (uip_mask->proto) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_IP, NH_FLD_IP_PROTO);
++ *(u8 *)(key + off) = uip_value->proto;
++ *(u8 *)(mask + off) = uip_mask->proto;
++ *fields |= DPAA2_ETH_DIST_IPPROTO;
+ }
+
-+ /* Only apply the rule for the user-specified L4 protocol
-+ * and if ethertype matches IPv4
-+ */
-+ offset = cls_key_off(priv, NET_PROT_ETH, NH_FLD_ETH_TYPE);
-+ *(u16 *)(key + offset) = htons(ETH_P_IP);
-+ *(u16 *)(mask + offset) = 0xFFFF;
-+
-+ offset = cls_key_off(priv, NET_PROT_IP, NH_FLD_IP_PROTO);
-+ *(u8 *)(key + offset) = l4_proto;
-+ *(u8 *)(mask + offset) = 0xFF;
-+
-+ /* TODO: check IP version */
-+
-+ return 0;
-+}
-+
-+static int prep_eth_rule(struct dpaa2_eth_priv *priv,
-+ struct ethhdr *eth_value, struct ethhdr *eth_mask,
-+ void *key, void *mask)
-+{
-+ int offset;
++ if (uip_mask->l4_4_bytes) {
++ tmp_value = be32_to_cpu(uip_value->l4_4_bytes);
++ tmp_mask = be32_to_cpu(uip_mask->l4_4_bytes);
+
-+ if (eth_mask->h_proto) {
-+ netdev_err(priv->net_dev, "Ethertype is not supported!\n");
-+ return -EOPNOTSUPP;
-+ }
++ off = dpaa2_eth_cls_fld_off(NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
++ *(__be16 *)(key + off) = htons(tmp_value >> 16);
++ *(__be16 *)(mask + off) = htons(tmp_mask >> 16);
++ *fields |= DPAA2_ETH_DIST_L4SRC;
+
-+ if (!is_zero_ether_addr(eth_mask->h_source)) {
-+ offset = cls_key_off(priv, NET_PROT_ETH, NH_FLD_ETH_SA);
-+ ether_addr_copy(key + offset, eth_value->h_source);
-+ ether_addr_copy(mask + offset, eth_mask->h_source);
++ off = dpaa2_eth_cls_fld_off(NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
++ *(__be16 *)(key + off) = htons(tmp_value & 0xFFFF);
++ *(__be16 *)(mask + off) = htons(tmp_mask & 0xFFFF);
++ *fields |= DPAA2_ETH_DIST_L4DST;
+ }
+
-+ if (!is_zero_ether_addr(eth_mask->h_dest)) {
-+ offset = cls_key_off(priv, NET_PROT_ETH, NH_FLD_ETH_DA);
-+ ether_addr_copy(key + offset, eth_value->h_dest);
-+ ether_addr_copy(mask + offset, eth_mask->h_dest);
-+ }
++ /* Only apply the rule for IPv4 frames */
++ off = dpaa2_eth_cls_fld_off(NET_PROT_ETH, NH_FLD_ETH_TYPE);
++ *(__be16 *)(key + off) = htons(ETH_P_IP);
++ *(__be16 *)(mask + off) = htons(0xFFFF);
++ *fields |= DPAA2_ETH_DIST_ETHTYPE;
+
+ return 0;
+}
+
-+static int prep_user_ip_rule(struct dpaa2_eth_priv *priv,
-+ struct ethtool_usrip4_spec *uip_value,
-+ struct ethtool_usrip4_spec *uip_mask,
-+ void *key, void *mask)
++static int prep_l4_rule(struct ethtool_tcpip4_spec *l4_value,
++ struct ethtool_tcpip4_spec *l4_mask,
++ void *key, void *mask, u8 l4_proto, u64 *fields)
+{
-+ int offset;
++ int off;
+
-+ if (uip_mask->tos)
++ if (l4_mask->tos)
+ return -EOPNOTSUPP;
-+
-+ if (uip_mask->ip4src) {
-+ offset = cls_key_off(priv, NET_PROT_IP, NH_FLD_IP_SRC);
-+ *(u32 *)(key + offset) = uip_value->ip4src;
-+ *(u32 *)(mask + offset) = uip_mask->ip4src;
++ if (l4_mask->ip4src) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_IP, NH_FLD_IP_SRC);
++ *(__be32 *)(key + off) = l4_value->ip4src;
++ *(__be32 *)(mask + off) = l4_mask->ip4src;
++ *fields |= DPAA2_ETH_DIST_IPSRC;
+ }
+
-+ if (uip_mask->ip4dst) {
-+ offset = cls_key_off(priv, NET_PROT_IP, NH_FLD_IP_DST);
-+ *(u32 *)(key + offset) = uip_value->ip4dst;
-+ *(u32 *)(mask + offset) = uip_mask->ip4dst;
++ if (l4_mask->ip4dst) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_IP, NH_FLD_IP_DST);
++ *(__be32 *)(key + off) = l4_value->ip4dst;
++ *(__be32 *)(mask + off) = l4_mask->ip4dst;
++ *fields |= DPAA2_ETH_DIST_IPDST;
+ }
+
-+ if (uip_mask->proto) {
-+ offset = cls_key_off(priv, NET_PROT_IP, NH_FLD_IP_PROTO);
-+ *(u32 *)(key + offset) = uip_value->proto;
-+ *(u32 *)(mask + offset) = uip_mask->proto;
++ if (l4_mask->psrc) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
++ *(__be16 *)(key + off) = l4_value->psrc;
++ *(__be16 *)(mask + off) = l4_mask->psrc;
++ *fields |= DPAA2_ETH_DIST_L4SRC;
+ }
-+ if (uip_mask->l4_4_bytes) {
-+ offset = cls_key_off(priv, NET_PROT_UDP, NH_FLD_UDP_PORT_SRC);
-+ *(u16 *)(key + offset) = uip_value->l4_4_bytes << 16;
-+ *(u16 *)(mask + offset) = uip_mask->l4_4_bytes << 16;
+
-+ offset = cls_key_off(priv, NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
-+ *(u16 *)(key + offset) = uip_value->l4_4_bytes & 0xFFFF;
-+ *(u16 *)(mask + offset) = uip_mask->l4_4_bytes & 0xFFFF;
++ if (l4_mask->pdst) {
++ off = dpaa2_eth_cls_fld_off(NET_PROT_UDP, NH_FLD_UDP_PORT_DST);
++ *(__be16 *)(key + off) = l4_value->pdst;
++ *(__be16 *)(mask + off) = l4_mask->pdst;
++ *fields |= DPAA2_ETH_DIST_L4DST;
+ }
+
-+ /* Ethertype must be IP */
-+ offset = cls_key_off(priv, NET_PROT_ETH, NH_FLD_ETH_TYPE);
-+ *(u16 *)(key + offset) = htons(ETH_P_IP);
-+ *(u16 *)(mask + offset) = 0xFFFF;
++ /* Only apply the rule for the user-specified L4 protocol
++ * and if ethertype matches IPv4
++ */
++ off = dpaa2_eth_cls_fld_off(NET_PROT_ETH, NH_FLD_ETH_TYPE);
++ *(__be16 *)(key + off) = htons(ETH_P_IP);
++ *(__be16 *)(mask + off) = htons(0xFFFF);
++ *fields |= DPAA2_ETH_DIST_ETHTYPE;
++
++ off = dpaa2_eth_cls_fld_off(NET_PROT_IP, NH_FLD_IP_PROTO);
++ *(u8 *)(key + off) = l4_proto;
++ *(u8 *)(mask + off) = 0xFF;
++ *fields |= DPAA2_ETH_DIST_IPPROTO;
+
+ return 0;
+}
+
-+static int prep_ext_rule(struct dpaa2_eth_priv *priv,
-+ struct ethtool_flow_ext *ext_value,
++static int prep_ext_rule(struct ethtool_flow_ext *ext_value,
+ struct ethtool_flow_ext *ext_mask,
-+ void *key, void *mask)
++ void *key, void *mask, u64 *fields)
+{
-+ int offset;
++ int off;
+
+ if (ext_mask->vlan_etype)
+ return -EOPNOTSUPP;
+
+ if (ext_mask->vlan_tci) {
-+ offset = cls_key_off(priv, NET_PROT_VLAN, NH_FLD_VLAN_TCI);
-+ *(u16 *)(key + offset) = ext_value->vlan_tci;
-+ *(u16 *)(mask + offset) = ext_mask->vlan_tci;
++ off = dpaa2_eth_cls_fld_off(NET_PROT_VLAN, NH_FLD_VLAN_TCI);
++ *(__be16 *)(key + off) = ext_value->vlan_tci;
++ *(__be16 *)(mask + off) = ext_mask->vlan_tci;
++ *fields |= DPAA2_ETH_DIST_VLAN;
+ }
+
+ return 0;
+}
+
-+static int prep_mac_ext_rule(struct dpaa2_eth_priv *priv,
-+ struct ethtool_flow_ext *ext_value,
++static int prep_mac_ext_rule(struct ethtool_flow_ext *ext_value,
+ struct ethtool_flow_ext *ext_mask,
-+ void *key, void *mask)
++ void *key, void *mask, u64 *fields)
+{
-+ int offset;
++ int off;
+
+ if (!is_zero_ether_addr(ext_mask->h_dest)) {
-+ offset = cls_key_off(priv, NET_PROT_ETH, NH_FLD_ETH_DA);
-+ ether_addr_copy(key + offset, ext_value->h_dest);
-+ ether_addr_copy(mask + offset, ext_mask->h_dest);
++ off = dpaa2_eth_cls_fld_off(NET_PROT_ETH, NH_FLD_ETH_DA);
++ ether_addr_copy(key + off, ext_value->h_dest);
++ ether_addr_copy(mask + off, ext_mask->h_dest);
++ *fields |= DPAA2_ETH_DIST_ETHDST;
+ }
+
+ return 0;
+}
+
-+static int prep_cls_rule(struct net_device *net_dev,
-+ struct ethtool_rx_flow_spec *fs,
-+ void *key)
++static int prep_cls_rule(struct ethtool_rx_flow_spec *fs, void *key, void *mask,
++ u64 *fields)
+{
-+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ const u8 key_size = cls_key_size(priv);
-+ void *msk = key + key_size;
+ int err;
+
-+ memset(key, 0, key_size * 2);
-+
-+ switch (fs->flow_type & 0xff) {
++ switch (fs->flow_type & 0xFF) {
++ case ETHER_FLOW:
++ err = prep_eth_rule(&fs->h_u.ether_spec, &fs->m_u.ether_spec,
++ key, mask, fields);
++ break;
++ case IP_USER_FLOW:
++ err = prep_user_ip_rule(&fs->h_u.usr_ip4_spec,
++ &fs->m_u.usr_ip4_spec, key, mask, fields);
++ break;
+ case TCP_V4_FLOW:
-+ err = prep_l4_rule(priv, &fs->h_u.tcp_ip4_spec,
-+ &fs->m_u.tcp_ip4_spec, key, msk,
-+ IPPROTO_TCP);
++ err = prep_l4_rule(&fs->h_u.tcp_ip4_spec, &fs->m_u.tcp_ip4_spec,
++ key, mask, IPPROTO_TCP, fields);
+ break;
+ case UDP_V4_FLOW:
-+ err = prep_l4_rule(priv, &fs->h_u.udp_ip4_spec,
-+ &fs->m_u.udp_ip4_spec, key, msk,
-+ IPPROTO_UDP);
++ err = prep_l4_rule(&fs->h_u.udp_ip4_spec, &fs->m_u.udp_ip4_spec,
++ key, mask, IPPROTO_UDP, fields);
+ break;
+ case SCTP_V4_FLOW:
-+ err = prep_l4_rule(priv, &fs->h_u.sctp_ip4_spec,
-+ &fs->m_u.sctp_ip4_spec, key, msk,
-+ IPPROTO_SCTP);
-+ break;
-+ case ETHER_FLOW:
-+ err = prep_eth_rule(priv, &fs->h_u.ether_spec,
-+ &fs->m_u.ether_spec, key, msk);
-+ break;
-+ case IP_USER_FLOW:
-+ err = prep_user_ip_rule(priv, &fs->h_u.usr_ip4_spec,
-+ &fs->m_u.usr_ip4_spec, key, msk);
++ err = prep_l4_rule(&fs->h_u.sctp_ip4_spec, &fs->m_u.sctp_ip4_spec,
++ key, mask, IPPROTO_SCTP, fields);
+ break;
+ default:
-+ /* TODO: AH, ESP */
+ return -EOPNOTSUPP;
+ }
++
+ if (err)
+ return err;
+
+ if (fs->flow_type & FLOW_EXT) {
-+ err = prep_ext_rule(priv, &fs->h_ext, &fs->m_ext, key, msk);
++ err = prep_ext_rule(&fs->h_ext, &fs->m_ext, key, mask, fields);
+ if (err)
+ return err;
+ }
+
+ if (fs->flow_type & FLOW_MAC_EXT) {
-+ err = prep_mac_ext_rule(priv, &fs->h_ext, &fs->m_ext, key, msk);
++ err = prep_mac_ext_rule(&fs->h_ext, &fs->m_ext, key, mask,
++ fields);
+ if (err)
+ return err;
+ }
@@ -6233,185 +6530,179 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ return 0;
+}
+
-+static int del_cls(struct net_device *net_dev, int location);
-+
-+static int do_cls(struct net_device *net_dev,
-+ struct ethtool_rx_flow_spec *fs,
-+ bool add)
++static int do_cls_rule(struct net_device *net_dev,
++ struct ethtool_rx_flow_spec *fs,
++ bool add)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+ struct device *dev = net_dev->dev.parent;
-+ const int rule_cnt = dpaa2_eth_fs_count(priv);
-+ struct dpni_rule_cfg rule_cfg;
++ struct dpni_rule_cfg rule_cfg = { 0 };
+ struct dpni_fs_action_cfg fs_act = { 0 };
-+ void *dma_mem;
-+ int err = 0, tc;
-+
-+ if (!dpaa2_eth_fs_enabled(priv)) {
-+ netdev_err(net_dev, "dev does not support steering!\n");
-+ /* dev doesn't support steering */
-+ return -EOPNOTSUPP;
-+ }
++ dma_addr_t key_iova;
++ u64 fields = 0;
++ void *key_buf;
++ int i, err = 0;
+
-+ if ((fs->ring_cookie != RX_CLS_FLOW_DISC &&
-+ fs->ring_cookie >= dpaa2_eth_queue_count(priv)) ||
-+ fs->location >= rule_cnt)
++ if (fs->ring_cookie != RX_CLS_FLOW_DISC &&
++ fs->ring_cookie >= dpaa2_eth_queue_count(priv))
+ return -EINVAL;
+
-+ /* When adding a new rule, check if location if available
-+ * and if not, free the existing table entry before inserting
-+ * the new one
-+ */
-+ if (add && (priv->cls_rule[fs->location].in_use == true))
-+ del_cls(net_dev, fs->location);
-+
-+ memset(&rule_cfg, 0, sizeof(rule_cfg));
-+ rule_cfg.key_size = cls_key_size(priv);
++ rule_cfg.key_size = dpaa2_eth_cls_key_size(DPAA2_ETH_DIST_ALL);
+
+ /* allocate twice the key size, for the actual key and for mask */
-+ dma_mem = kzalloc(rule_cfg.key_size * 2, GFP_DMA | GFP_KERNEL);
-+ if (!dma_mem)
++ key_buf = kzalloc(rule_cfg.key_size * 2, GFP_KERNEL);
++ if (!key_buf)
+ return -ENOMEM;
+
-+ err = prep_cls_rule(net_dev, fs, dma_mem);
++ /* Fill the key and mask memory areas */
++ err = prep_cls_rule(fs, key_buf, key_buf + rule_cfg.key_size, &fields);
+ if (err)
-+ goto err_free_mem;
++ goto free_mem;
++
++ if (!dpaa2_eth_fs_mask_enabled(priv)) {
++ /* Masking allows us to configure a maximal key during init and
++ * use it for all flow steering rules. Without it, we include
++ * in the key only the fields actually used, so we need to
++ * extract the others from the final key buffer.
++ *
++ * Program the FS key if needed, or return error if previously
++ * set key can't be used for the current rule. User needs to
++ * delete existing rules in this case to allow for the new one.
++ */
++ if (!priv->rx_cls_fields) {
++ err = dpaa2_eth_set_cls(net_dev, fields);
++ if (err)
++ goto free_mem;
++
++ priv->rx_cls_fields = fields;
++ } else if (priv->rx_cls_fields != fields) {
++ netdev_err(net_dev, "No support for multiple FS keys, need to delete existing rules\n");
++ err = -EOPNOTSUPP;
++ goto free_mem;
++ }
+
-+ rule_cfg.key_iova = dma_map_single(dev, dma_mem,
-+ rule_cfg.key_size * 2,
-+ DMA_TO_DEVICE);
++ dpaa2_eth_cls_trim_rule(key_buf, fields);
++ rule_cfg.key_size = dpaa2_eth_cls_key_size(fields);
++ }
+
-+ rule_cfg.mask_iova = rule_cfg.key_iova + rule_cfg.key_size;
++ key_iova = dma_map_single(dev, key_buf, rule_cfg.key_size * 2,
++ DMA_TO_DEVICE);
++ if (dma_mapping_error(dev, key_iova)) {
++ err = -ENOMEM;
++ goto free_mem;
++ }
+
-+ if (fs->ring_cookie == RX_CLS_FLOW_DISC)
-+ fs_act.options |= DPNI_FS_OPT_DISCARD;
-+ else
-+ fs_act.flow_id = fs->ring_cookie;
++ rule_cfg.key_iova = key_iova;
++ if (dpaa2_eth_fs_mask_enabled(priv))
++ rule_cfg.mask_iova = key_iova + rule_cfg.key_size;
+
-+ for (tc = 0; tc < dpaa2_eth_tc_count(priv); tc++) {
++ if (add) {
++ if (fs->ring_cookie == RX_CLS_FLOW_DISC)
++ fs_act.options |= DPNI_FS_OPT_DISCARD;
++ else
++ fs_act.flow_id = fs->ring_cookie;
++ }
++ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) {
+ if (add)
+ err = dpni_add_fs_entry(priv->mc_io, 0, priv->mc_token,
-+ tc, fs->location, &rule_cfg,
++ i, fs->location, &rule_cfg,
+ &fs_act);
+ else
+ err = dpni_remove_fs_entry(priv->mc_io, 0,
-+ priv->mc_token, tc,
++ priv->mc_token, i,
+ &rule_cfg);
-+
+ if (err)
+ break;
+ }
+
-+ dma_unmap_single(dev, rule_cfg.key_iova,
-+ rule_cfg.key_size * 2, DMA_TO_DEVICE);
-+
-+ if (err)
-+ netdev_err(net_dev, "dpaa2_add/remove_cls() error %d\n", err);
++ dma_unmap_single(dev, key_iova, rule_cfg.key_size * 2, DMA_TO_DEVICE);
+
-+err_free_mem:
-+ kfree(dma_mem);
++free_mem:
++ kfree(key_buf);
+
+ return err;
+}
+
-+static int add_cls(struct net_device *net_dev,
-+ struct ethtool_rx_flow_spec *fs)
++static int num_rules(struct dpaa2_eth_priv *priv)
+{
-+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ int err;
++ int i, rules = 0;
+
-+ err = do_cls(net_dev, fs, true);
-+ if (err)
-+ return err;
++ for (i = 0; i < dpaa2_eth_fs_count(priv); i++)
++ if (priv->cls_rule[i].in_use)
++ rules++;
+
-+ priv->cls_rule[fs->location].in_use = true;
-+ priv->cls_rule[fs->location].fs = *fs;
-+
-+ return 0;
++ return rules;
+}
+
-+static int del_cls(struct net_device *net_dev, int location)
++static int update_cls_rule(struct net_device *net_dev,
++ struct ethtool_rx_flow_spec *new_fs,
++ int location)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ int err;
++ struct dpaa2_eth_cls_rule *rule;
++ int err = -EINVAL;
+
-+ err = do_cls(net_dev, &priv->cls_rule[location].fs, false);
-+ if (err)
-+ return err;
++ if (!priv->rx_cls_enabled)
++ return -EOPNOTSUPP;
+
-+ priv->cls_rule[location].in_use = false;
++ if (location >= dpaa2_eth_fs_count(priv))
++ return -EINVAL;
+
-+ return 0;
-+}
++ rule = &priv->cls_rule[location];
+
-+static int set_hash(struct net_device *net_dev, u64 data)
-+{
-+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ u32 key = 0;
-+ int i;
++ /* If a rule is present at the specified location, delete it. */
++ if (rule->in_use) {
++ err = do_cls_rule(net_dev, &rule->fs, false);
++ if (err)
++ return err;
+
-+ if (data & RXH_DISCARD)
-+ return -EOPNOTSUPP;
++ rule->in_use = 0;
+
-+ for (i = 0; i < priv->num_dist_fields; i++)
-+ if (priv->dist_fields[i].rxnfc_field & data)
-+ key |= priv->dist_fields[i].id;
++ if (!dpaa2_eth_fs_mask_enabled(priv) && !num_rules(priv))
++ priv->rx_cls_fields = 0;
++ }
+
-+ return dpaa2_eth_set_dist_key(priv, DPAA2_ETH_RX_DIST_HASH, key);
-+}
++ /* If no new entry to add, return here */
++ if (!new_fs)
++ return err;
+
-+static int dpaa2_eth_set_rxnfc(struct net_device *net_dev,
-+ struct ethtool_rxnfc *rxnfc)
-+{
-+ int err = 0;
++ err = do_cls_rule(net_dev, new_fs, true);
++ if (err)
++ return err;
+
-+ switch (rxnfc->cmd) {
-+ case ETHTOOL_SRXCLSRLINS:
-+ err = add_cls(net_dev, &rxnfc->fs);
-+ break;
-+ case ETHTOOL_SRXCLSRLDEL:
-+ err = del_cls(net_dev, rxnfc->fs.location);
-+ break;
-+ case ETHTOOL_SRXFH:
-+ err = set_hash(net_dev, rxnfc->data);
-+ break;
-+ default:
-+ err = -EOPNOTSUPP;
-+ }
++ rule->in_use = 1;
++ rule->fs = *new_fs;
+
-+ return err;
++ return 0;
}
static int dpaa2_eth_get_rxnfc(struct net_device *net_dev,
struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
{
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-+ const int rule_cnt = dpaa2_eth_fs_count(priv);
-+ int i, j;
++ int rule_cnt = dpaa2_eth_fs_count(priv);
++ int i, j = 0;
switch (rxnfc->cmd) {
case ETHTOOL_GRXFH:
-@@ -258,6 +829,33 @@ static int dpaa2_eth_get_rxnfc(struct ne
+@@ -258,6 +791,29 @@ static int dpaa2_eth_get_rxnfc(struct ne
case ETHTOOL_GRXRINGS:
rxnfc->data = dpaa2_eth_queue_count(priv);
break;
-+
+ case ETHTOOL_GRXCLSRLCNT:
-+ for (i = 0, rxnfc->rule_cnt = 0; i < rule_cnt; i++)
-+ if (priv->cls_rule[i].in_use)
-+ rxnfc->rule_cnt++;
++ rxnfc->rule_cnt = 0;
++ rxnfc->rule_cnt = num_rules(priv);
+ rxnfc->data = rule_cnt;
+ break;
-+
+ case ETHTOOL_GRXCLSRULE:
++ if (rxnfc->fs.location >= rule_cnt)
++ return -EINVAL;
+ if (!priv->cls_rule[rxnfc->fs.location].in_use)
+ return -EINVAL;
-+
+ rxnfc->fs = priv->cls_rule[rxnfc->fs.location].fs;
+ break;
-+
+ case ETHTOOL_GRXCLSRLALL:
-+ for (i = 0, j = 0; i < rule_cnt; i++) {
++ for (i = 0; i < rule_cnt; i++) {
+ if (!priv->cls_rule[i].in_use)
+ continue;
+ if (j == rxnfc->rule_cnt)
@@ -6421,11 +6712,59 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ rxnfc->rule_cnt = j;
+ rxnfc->data = rule_cnt;
+ break;
-+
default:
return -EOPNOTSUPP;
}
-@@ -270,8 +868,11 @@ const struct ethtool_ops dpaa2_ethtool_o
+@@ -265,13 +821,61 @@ static int dpaa2_eth_get_rxnfc(struct ne
+ return 0;
+ }
+
++int dpaa2_phc_index = -1;
++EXPORT_SYMBOL(dpaa2_phc_index);
++
++static int dpaa2_eth_get_ts_info(struct net_device *dev,
++ struct ethtool_ts_info *info)
++{
++ info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
++ SOF_TIMESTAMPING_RX_HARDWARE |
++ SOF_TIMESTAMPING_RAW_HARDWARE;
++
++ info->phc_index = dpaa2_phc_index;
++
++ info->tx_types = (1 << HWTSTAMP_TX_OFF) |
++ (1 << HWTSTAMP_TX_ON);
++
++ info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
++ (1 << HWTSTAMP_FILTER_ALL);
++ return 0;
++}
++
++static int dpaa2_eth_set_rxnfc(struct net_device *net_dev,
++ struct ethtool_rxnfc *rxnfc)
++{
++ int err = 0;
++
++ switch (rxnfc->cmd) {
++ case ETHTOOL_SRXFH:
++ if ((rxnfc->data & DPAA2_RXH_SUPPORTED) != rxnfc->data)
++ return -EOPNOTSUPP;
++ err = dpaa2_eth_set_hash(net_dev, rxnfc->data);
++ break;
++ case ETHTOOL_SRXCLSRLINS:
++ err = update_cls_rule(net_dev, &rxnfc->fs, rxnfc->fs.location);
++ break;
++ case ETHTOOL_SRXCLSRLDEL:
++ err = update_cls_rule(net_dev, NULL, rxnfc->fs.location);
++ break;
++ default:
++ err = -EOPNOTSUPP;
++ }
++
++ return err;
++}
++
+ const struct ethtool_ops dpaa2_ethtool_ops = {
+ .get_drvinfo = dpaa2_eth_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_link_ksettings = dpaa2_eth_get_link_ksettings,
.set_link_ksettings = dpaa2_eth_set_link_ksettings,
@@ -6436,10 +6775,446 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
.get_strings = dpaa2_eth_get_strings,
.get_rxnfc = dpaa2_eth_get_rxnfc,
+ .set_rxnfc = dpaa2_eth_set_rxnfc,
++ .get_ts_info = dpaa2_eth_get_ts_info,
+ };
+--- a/drivers/staging/fsl-dpaa2/ethernet/dpkg.h
++++ b/drivers/staging/fsl-dpaa2/ethernet/dpkg.h
+@@ -1,39 +1,10 @@
++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+ /* Copyright 2013-2015 Freescale Semiconductor Inc.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of the above-listed copyright holders nor the
+- * names of any contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+- * POSSIBILITY OF SUCH DAMAGE.
+ */
+ #ifndef __FSL_DPKG_H_
+ #define __FSL_DPKG_H_
+
+ #include <linux/types.h>
+-#include "net.h"
+
+ /* Data Path Key Generator API
+ * Contains initialization APIs and runtime APIs for the Key Generator
+@@ -86,6 +57,355 @@ struct dpkg_mask {
+ u8 offset;
};
+
++/* Protocol fields */
++
++/* Ethernet fields */
++#define NH_FLD_ETH_DA BIT(0)
++#define NH_FLD_ETH_SA BIT(1)
++#define NH_FLD_ETH_LENGTH BIT(2)
++#define NH_FLD_ETH_TYPE BIT(3)
++#define NH_FLD_ETH_FINAL_CKSUM BIT(4)
++#define NH_FLD_ETH_PADDING BIT(5)
++#define NH_FLD_ETH_ALL_FIELDS (BIT(6) - 1)
++
++/* VLAN fields */
++#define NH_FLD_VLAN_VPRI BIT(0)
++#define NH_FLD_VLAN_CFI BIT(1)
++#define NH_FLD_VLAN_VID BIT(2)
++#define NH_FLD_VLAN_LENGTH BIT(3)
++#define NH_FLD_VLAN_TYPE BIT(4)
++#define NH_FLD_VLAN_ALL_FIELDS (BIT(5) - 1)
++
++#define NH_FLD_VLAN_TCI (NH_FLD_VLAN_VPRI | \
++ NH_FLD_VLAN_CFI | \
++ NH_FLD_VLAN_VID)
++
++/* IP (generic) fields */
++#define NH_FLD_IP_VER BIT(0)
++#define NH_FLD_IP_DSCP BIT(2)
++#define NH_FLD_IP_ECN BIT(3)
++#define NH_FLD_IP_PROTO BIT(4)
++#define NH_FLD_IP_SRC BIT(5)
++#define NH_FLD_IP_DST BIT(6)
++#define NH_FLD_IP_TOS_TC BIT(7)
++#define NH_FLD_IP_ID BIT(8)
++#define NH_FLD_IP_ALL_FIELDS (BIT(9) - 1)
++
++/* IPV4 fields */
++#define NH_FLD_IPV4_VER BIT(0)
++#define NH_FLD_IPV4_HDR_LEN BIT(1)
++#define NH_FLD_IPV4_TOS BIT(2)
++#define NH_FLD_IPV4_TOTAL_LEN BIT(3)
++#define NH_FLD_IPV4_ID BIT(4)
++#define NH_FLD_IPV4_FLAG_D BIT(5)
++#define NH_FLD_IPV4_FLAG_M BIT(6)
++#define NH_FLD_IPV4_OFFSET BIT(7)
++#define NH_FLD_IPV4_TTL BIT(8)
++#define NH_FLD_IPV4_PROTO BIT(9)
++#define NH_FLD_IPV4_CKSUM BIT(10)
++#define NH_FLD_IPV4_SRC_IP BIT(11)
++#define NH_FLD_IPV4_DST_IP BIT(12)
++#define NH_FLD_IPV4_OPTS BIT(13)
++#define NH_FLD_IPV4_OPTS_COUNT BIT(14)
++#define NH_FLD_IPV4_ALL_FIELDS (BIT(15) - 1)
++
++/* IPV6 fields */
++#define NH_FLD_IPV6_VER BIT(0)
++#define NH_FLD_IPV6_TC BIT(1)
++#define NH_FLD_IPV6_SRC_IP BIT(2)
++#define NH_FLD_IPV6_DST_IP BIT(3)
++#define NH_FLD_IPV6_NEXT_HDR BIT(4)
++#define NH_FLD_IPV6_FL BIT(5)
++#define NH_FLD_IPV6_HOP_LIMIT BIT(6)
++#define NH_FLD_IPV6_ID BIT(7)
++#define NH_FLD_IPV6_ALL_FIELDS (BIT(8) - 1)
++
++/* ICMP fields */
++#define NH_FLD_ICMP_TYPE BIT(0)
++#define NH_FLD_ICMP_CODE BIT(1)
++#define NH_FLD_ICMP_CKSUM BIT(2)
++#define NH_FLD_ICMP_ID BIT(3)
++#define NH_FLD_ICMP_SQ_NUM BIT(4)
++#define NH_FLD_ICMP_ALL_FIELDS (BIT(5) - 1)
++
++/* IGMP fields */
++#define NH_FLD_IGMP_VERSION BIT(0)
++#define NH_FLD_IGMP_TYPE BIT(1)
++#define NH_FLD_IGMP_CKSUM BIT(2)
++#define NH_FLD_IGMP_DATA BIT(3)
++#define NH_FLD_IGMP_ALL_FIELDS (BIT(4) - 1)
++
++/* TCP fields */
++#define NH_FLD_TCP_PORT_SRC BIT(0)
++#define NH_FLD_TCP_PORT_DST BIT(1)
++#define NH_FLD_TCP_SEQ BIT(2)
++#define NH_FLD_TCP_ACK BIT(3)
++#define NH_FLD_TCP_OFFSET BIT(4)
++#define NH_FLD_TCP_FLAGS BIT(5)
++#define NH_FLD_TCP_WINDOW BIT(6)
++#define NH_FLD_TCP_CKSUM BIT(7)
++#define NH_FLD_TCP_URGPTR BIT(8)
++#define NH_FLD_TCP_OPTS BIT(9)
++#define NH_FLD_TCP_OPTS_COUNT BIT(10)
++#define NH_FLD_TCP_ALL_FIELDS (BIT(11) - 1)
++
++/* UDP fields */
++#define NH_FLD_UDP_PORT_SRC BIT(0)
++#define NH_FLD_UDP_PORT_DST BIT(1)
++#define NH_FLD_UDP_LEN BIT(2)
++#define NH_FLD_UDP_CKSUM BIT(3)
++#define NH_FLD_UDP_ALL_FIELDS (BIT(4) - 1)
++
++/* UDP-lite fields */
++#define NH_FLD_UDP_LITE_PORT_SRC BIT(0)
++#define NH_FLD_UDP_LITE_PORT_DST BIT(1)
++#define NH_FLD_UDP_LITE_ALL_FIELDS (BIT(2) - 1)
++
++/* UDP-encap-ESP fields */
++#define NH_FLD_UDP_ENC_ESP_PORT_SRC BIT(0)
++#define NH_FLD_UDP_ENC_ESP_PORT_DST BIT(1)
++#define NH_FLD_UDP_ENC_ESP_LEN BIT(2)
++#define NH_FLD_UDP_ENC_ESP_CKSUM BIT(3)
++#define NH_FLD_UDP_ENC_ESP_SPI BIT(4)
++#define NH_FLD_UDP_ENC_ESP_SEQUENCE_NUM BIT(5)
++#define NH_FLD_UDP_ENC_ESP_ALL_FIELDS (BIT(6) - 1)
++
++/* SCTP fields */
++#define NH_FLD_SCTP_PORT_SRC BIT(0)
++#define NH_FLD_SCTP_PORT_DST BIT(1)
++#define NH_FLD_SCTP_VER_TAG BIT(2)
++#define NH_FLD_SCTP_CKSUM BIT(3)
++#define NH_FLD_SCTP_ALL_FIELDS (BIT(4) - 1)
++
++/* DCCP fields */
++#define NH_FLD_DCCP_PORT_SRC BIT(0)
++#define NH_FLD_DCCP_PORT_DST BIT(1)
++#define NH_FLD_DCCP_ALL_FIELDS (BIT(2) - 1)
++
++/* IPHC fields */
++#define NH_FLD_IPHC_CID BIT(0)
++#define NH_FLD_IPHC_CID_TYPE BIT(1)
++#define NH_FLD_IPHC_HCINDEX BIT(2)
++#define NH_FLD_IPHC_GEN BIT(3)
++#define NH_FLD_IPHC_D_BIT BIT(4)
++#define NH_FLD_IPHC_ALL_FIELDS (BIT(5) - 1)
++
++/* SCTP fields */
++#define NH_FLD_SCTP_CHUNK_DATA_TYPE BIT(0)
++#define NH_FLD_SCTP_CHUNK_DATA_FLAGS BIT(1)
++#define NH_FLD_SCTP_CHUNK_DATA_LENGTH BIT(2)
++#define NH_FLD_SCTP_CHUNK_DATA_TSN BIT(3)
++#define NH_FLD_SCTP_CHUNK_DATA_STREAM_ID BIT(4)
++#define NH_FLD_SCTP_CHUNK_DATA_STREAM_SQN BIT(5)
++#define NH_FLD_SCTP_CHUNK_DATA_PAYLOAD_PID BIT(6)
++#define NH_FLD_SCTP_CHUNK_DATA_UNORDERED BIT(7)
++#define NH_FLD_SCTP_CHUNK_DATA_BEGGINING BIT(8)
++#define NH_FLD_SCTP_CHUNK_DATA_END BIT(9)
++#define NH_FLD_SCTP_CHUNK_DATA_ALL_FIELDS (BIT(10) - 1)
++
++/* L2TPV2 fields */
++#define NH_FLD_L2TPV2_TYPE_BIT BIT(0)
++#define NH_FLD_L2TPV2_LENGTH_BIT BIT(1)
++#define NH_FLD_L2TPV2_SEQUENCE_BIT BIT(2)
++#define NH_FLD_L2TPV2_OFFSET_BIT BIT(3)
++#define NH_FLD_L2TPV2_PRIORITY_BIT BIT(4)
++#define NH_FLD_L2TPV2_VERSION BIT(5)
++#define NH_FLD_L2TPV2_LEN BIT(6)
++#define NH_FLD_L2TPV2_TUNNEL_ID BIT(7)
++#define NH_FLD_L2TPV2_SESSION_ID BIT(8)
++#define NH_FLD_L2TPV2_NS BIT(9)
++#define NH_FLD_L2TPV2_NR BIT(10)
++#define NH_FLD_L2TPV2_OFFSET_SIZE BIT(11)
++#define NH_FLD_L2TPV2_FIRST_BYTE BIT(12)
++#define NH_FLD_L2TPV2_ALL_FIELDS (BIT(13) - 1)
++
++/* L2TPV3 fields */
++#define NH_FLD_L2TPV3_CTRL_TYPE_BIT BIT(0)
++#define NH_FLD_L2TPV3_CTRL_LENGTH_BIT BIT(1)
++#define NH_FLD_L2TPV3_CTRL_SEQUENCE_BIT BIT(2)
++#define NH_FLD_L2TPV3_CTRL_VERSION BIT(3)
++#define NH_FLD_L2TPV3_CTRL_LENGTH BIT(4)
++#define NH_FLD_L2TPV3_CTRL_CONTROL BIT(5)
++#define NH_FLD_L2TPV3_CTRL_SENT BIT(6)
++#define NH_FLD_L2TPV3_CTRL_RECV BIT(7)
++#define NH_FLD_L2TPV3_CTRL_FIRST_BYTE BIT(8)
++#define NH_FLD_L2TPV3_CTRL_ALL_FIELDS (BIT(9) - 1)
++
++#define NH_FLD_L2TPV3_SESS_TYPE_BIT BIT(0)
++#define NH_FLD_L2TPV3_SESS_VERSION BIT(1)
++#define NH_FLD_L2TPV3_SESS_ID BIT(2)
++#define NH_FLD_L2TPV3_SESS_COOKIE BIT(3)
++#define NH_FLD_L2TPV3_SESS_ALL_FIELDS (BIT(4) - 1)
++
++/* PPP fields */
++#define NH_FLD_PPP_PID BIT(0)
++#define NH_FLD_PPP_COMPRESSED BIT(1)
++#define NH_FLD_PPP_ALL_FIELDS (BIT(2) - 1)
++
++/* PPPoE fields */
++#define NH_FLD_PPPOE_VER BIT(0)
++#define NH_FLD_PPPOE_TYPE BIT(1)
++#define NH_FLD_PPPOE_CODE BIT(2)
++#define NH_FLD_PPPOE_SID BIT(3)
++#define NH_FLD_PPPOE_LEN BIT(4)
++#define NH_FLD_PPPOE_SESSION BIT(5)
++#define NH_FLD_PPPOE_PID BIT(6)
++#define NH_FLD_PPPOE_ALL_FIELDS (BIT(7) - 1)
++
++/* PPP-Mux fields */
++#define NH_FLD_PPPMUX_PID BIT(0)
++#define NH_FLD_PPPMUX_CKSUM BIT(1)
++#define NH_FLD_PPPMUX_COMPRESSED BIT(2)
++#define NH_FLD_PPPMUX_ALL_FIELDS (BIT(3) - 1)
++
++/* PPP-Mux sub-frame fields */
++#define NH_FLD_PPPMUX_SUBFRM_PFF BIT(0)
++#define NH_FLD_PPPMUX_SUBFRM_LXT BIT(1)
++#define NH_FLD_PPPMUX_SUBFRM_LEN BIT(2)
++#define NH_FLD_PPPMUX_SUBFRM_PID BIT(3)
++#define NH_FLD_PPPMUX_SUBFRM_USE_PID BIT(4)
++#define NH_FLD_PPPMUX_SUBFRM_ALL_FIELDS (BIT(5) - 1)
++
++/* LLC fields */
++#define NH_FLD_LLC_DSAP BIT(0)
++#define NH_FLD_LLC_SSAP BIT(1)
++#define NH_FLD_LLC_CTRL BIT(2)
++#define NH_FLD_LLC_ALL_FIELDS (BIT(3) - 1)
++
++/* NLPID fields */
++#define NH_FLD_NLPID_NLPID BIT(0)
++#define NH_FLD_NLPID_ALL_FIELDS (BIT(1) - 1)
++
++/* SNAP fields */
++#define NH_FLD_SNAP_OUI BIT(0)
++#define NH_FLD_SNAP_PID BIT(1)
++#define NH_FLD_SNAP_ALL_FIELDS (BIT(2) - 1)
++
++/* LLC SNAP fields */
++#define NH_FLD_LLC_SNAP_TYPE BIT(0)
++#define NH_FLD_LLC_SNAP_ALL_FIELDS (BIT(1) - 1)
++
++/* ARP fields */
++#define NH_FLD_ARP_HTYPE BIT(0)
++#define NH_FLD_ARP_PTYPE BIT(1)
++#define NH_FLD_ARP_HLEN BIT(2)
++#define NH_FLD_ARP_PLEN BIT(3)
++#define NH_FLD_ARP_OPER BIT(4)
++#define NH_FLD_ARP_SHA BIT(5)
++#define NH_FLD_ARP_SPA BIT(6)
++#define NH_FLD_ARP_THA BIT(7)
++#define NH_FLD_ARP_TPA BIT(8)
++#define NH_FLD_ARP_ALL_FIELDS (BIT(9) - 1)
++
++/* RFC2684 fields */
++#define NH_FLD_RFC2684_LLC BIT(0)
++#define NH_FLD_RFC2684_NLPID BIT(1)
++#define NH_FLD_RFC2684_OUI BIT(2)
++#define NH_FLD_RFC2684_PID BIT(3)
++#define NH_FLD_RFC2684_VPN_OUI BIT(4)
++#define NH_FLD_RFC2684_VPN_IDX BIT(5)
++#define NH_FLD_RFC2684_ALL_FIELDS (BIT(6) - 1)
++
++/* User defined fields */
++#define NH_FLD_USER_DEFINED_SRCPORT BIT(0)
++#define NH_FLD_USER_DEFINED_PCDID BIT(1)
++#define NH_FLD_USER_DEFINED_ALL_FIELDS (BIT(2) - 1)
++
++/* Payload fields */
++#define NH_FLD_PAYLOAD_BUFFER BIT(0)
++#define NH_FLD_PAYLOAD_SIZE BIT(1)
++#define NH_FLD_MAX_FRM_SIZE BIT(2)
++#define NH_FLD_MIN_FRM_SIZE BIT(3)
++#define NH_FLD_PAYLOAD_TYPE BIT(4)
++#define NH_FLD_FRAME_SIZE BIT(5)
++#define NH_FLD_PAYLOAD_ALL_FIELDS (BIT(6) - 1)
++
++/* GRE fields */
++#define NH_FLD_GRE_TYPE BIT(0)
++#define NH_FLD_GRE_ALL_FIELDS (BIT(1) - 1)
++
++/* MINENCAP fields */
++#define NH_FLD_MINENCAP_SRC_IP BIT(0)
++#define NH_FLD_MINENCAP_DST_IP BIT(1)
++#define NH_FLD_MINENCAP_TYPE BIT(2)
++#define NH_FLD_MINENCAP_ALL_FIELDS (BIT(3) - 1)
++
++/* IPSEC AH fields */
++#define NH_FLD_IPSEC_AH_SPI BIT(0)
++#define NH_FLD_IPSEC_AH_NH BIT(1)
++#define NH_FLD_IPSEC_AH_ALL_FIELDS (BIT(2) - 1)
++
++/* IPSEC ESP fields */
++#define NH_FLD_IPSEC_ESP_SPI BIT(0)
++#define NH_FLD_IPSEC_ESP_SEQUENCE_NUM BIT(1)
++#define NH_FLD_IPSEC_ESP_ALL_FIELDS (BIT(2) - 1)
++
++/* MPLS fields */
++#define NH_FLD_MPLS_LABEL_STACK BIT(0)
++#define NH_FLD_MPLS_LABEL_STACK_ALL_FIELDS (BIT(1) - 1)
++
++/* MACSEC fields */
++#define NH_FLD_MACSEC_SECTAG BIT(0)
++#define NH_FLD_MACSEC_ALL_FIELDS (BIT(1) - 1)
++
++/* GTP fields */
++#define NH_FLD_GTP_TEID BIT(0)
++
++/* Supported protocols */
++enum net_prot {
++ NET_PROT_NONE = 0,
++ NET_PROT_PAYLOAD,
++ NET_PROT_ETH,
++ NET_PROT_VLAN,
++ NET_PROT_IPV4,
++ NET_PROT_IPV6,
++ NET_PROT_IP,
++ NET_PROT_TCP,
++ NET_PROT_UDP,
++ NET_PROT_UDP_LITE,
++ NET_PROT_IPHC,
++ NET_PROT_SCTP,
++ NET_PROT_SCTP_CHUNK_DATA,
++ NET_PROT_PPPOE,
++ NET_PROT_PPP,
++ NET_PROT_PPPMUX,
++ NET_PROT_PPPMUX_SUBFRM,
++ NET_PROT_L2TPV2,
++ NET_PROT_L2TPV3_CTRL,
++ NET_PROT_L2TPV3_SESS,
++ NET_PROT_LLC,
++ NET_PROT_LLC_SNAP,
++ NET_PROT_NLPID,
++ NET_PROT_SNAP,
++ NET_PROT_MPLS,
++ NET_PROT_IPSEC_AH,
++ NET_PROT_IPSEC_ESP,
++ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
++ NET_PROT_MACSEC,
++ NET_PROT_GRE,
++ NET_PROT_MINENCAP,
++ NET_PROT_DCCP,
++ NET_PROT_ICMP,
++ NET_PROT_IGMP,
++ NET_PROT_ARP,
++ NET_PROT_CAPWAP_DATA,
++ NET_PROT_CAPWAP_CTRL,
++ NET_PROT_RFC2684,
++ NET_PROT_ICMPV6,
++ NET_PROT_FCOE,
++ NET_PROT_FIP,
++ NET_PROT_ISCSI,
++ NET_PROT_GTP,
++ NET_PROT_USER_DEFINED_L2,
++ NET_PROT_USER_DEFINED_L3,
++ NET_PROT_USER_DEFINED_L4,
++ NET_PROT_USER_DEFINED_L5,
++ NET_PROT_USER_DEFINED_SHIM1,
++ NET_PROT_USER_DEFINED_SHIM2,
++
++ NET_PROT_DUMMY_LAST
++};
++
+ /**
+ * struct dpkg_extract - A structure for defining a single extraction
+ * @type: Determines how the union below is interpreted:
--- a/drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h
-@@ -39,9 +39,11 @@
+@@ -1,34 +1,6 @@
++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+ /* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of the above-listed copyright holders nor the
+- * names of any contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+- * POSSIBILITY OF SUCH DAMAGE.
+ */
+ #ifndef _FSL_DPNI_CMD_H
+ #define _FSL_DPNI_CMD_H
+@@ -39,9 +11,11 @@
#define DPNI_VER_MAJOR 7
#define DPNI_VER_MINOR 0
#define DPNI_CMD_BASE_VERSION 1
@@ -6451,7 +7226,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
#define DPNI_CMDID_OPEN DPNI_CMD(0x801)
#define DPNI_CMDID_CLOSE DPNI_CMD(0x800)
-@@ -64,7 +66,7 @@
+@@ -64,16 +38,18 @@
#define DPNI_CMDID_GET_IRQ_STATUS DPNI_CMD(0x016)
#define DPNI_CMDID_CLEAR_IRQ_STATUS DPNI_CMD(0x017)
@@ -6460,16 +7235,19 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
#define DPNI_CMDID_SET_ERRORS_BEHAVIOR DPNI_CMD(0x20B)
#define DPNI_CMDID_GET_QDID DPNI_CMD(0x210)
-@@ -73,7 +75,7 @@
+ #define DPNI_CMDID_GET_TX_DATA_OFFSET DPNI_CMD(0x212)
+ #define DPNI_CMDID_GET_LINK_STATE DPNI_CMD(0x215)
++#define DPNI_CMDID_GET_LINK_STATE_V2 DPNI_CMD_V2(0x215)
#define DPNI_CMDID_SET_MAX_FRAME_LENGTH DPNI_CMD(0x216)
#define DPNI_CMDID_GET_MAX_FRAME_LENGTH DPNI_CMD(0x217)
#define DPNI_CMDID_SET_LINK_CFG DPNI_CMD(0x21A)
-#define DPNI_CMDID_SET_TX_SHAPING DPNI_CMD(0x21B)
++#define DPNI_CMDID_SET_LINK_CFG_V2 DPNI_CMD_V2(0x21A)
+#define DPNI_CMDID_SET_TX_SHAPING DPNI_CMD_V2(0x21B)
#define DPNI_CMDID_SET_MCAST_PROMISC DPNI_CMD(0x220)
#define DPNI_CMDID_GET_MCAST_PROMISC DPNI_CMD(0x221)
-@@ -87,11 +89,16 @@
+@@ -87,11 +63,16 @@
#define DPNI_CMDID_SET_RX_TC_DIST DPNI_CMD(0x235)
@@ -6487,7 +7265,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
#define DPNI_CMDID_GET_QUEUE DPNI_CMD(0x25F)
#define DPNI_CMDID_SET_QUEUE DPNI_CMD(0x260)
#define DPNI_CMDID_GET_TAILDROP DPNI_CMD(0x261)
-@@ -110,6 +117,9 @@
+@@ -110,6 +91,9 @@
#define DPNI_CMDID_GET_OFFLOAD DPNI_CMD(0x26B)
#define DPNI_CMDID_SET_OFFLOAD DPNI_CMD(0x26C)
@@ -6497,7 +7275,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* Macros for accessing command fields smaller than 1byte */
#define DPNI_MASK(field) \
GENMASK(DPNI_##field##_SHIFT + DPNI_##field##_SIZE - 1, \
-@@ -126,13 +136,14 @@ struct dpni_cmd_open {
+@@ -126,13 +110,14 @@ struct dpni_cmd_open {
#define DPNI_BACKUP_POOL(val, order) (((val) & 0x1) << (order))
struct dpni_cmd_set_pools {
@@ -6516,7 +7294,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
__le16 buffer_size[DPNI_MAX_DPBP];
};
-@@ -303,6 +314,7 @@ struct dpni_rsp_get_tx_data_offset {
+@@ -303,6 +288,7 @@ struct dpni_rsp_get_tx_data_offset {
struct dpni_cmd_get_statistics {
u8 page_number;
@@ -6524,10 +7302,50 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
};
struct dpni_rsp_get_statistics {
-@@ -335,6 +347,22 @@ struct dpni_rsp_get_link_state {
+@@ -319,8 +305,22 @@ struct dpni_cmd_set_link_cfg {
__le64 options;
};
++struct dpni_cmd_set_link_cfg_v2 {
++ /* cmd word 0 */
++ __le64 pad0;
++ /* cmd word 1 */
++ __le32 rate;
++ __le32 pad1;
++ /* cmd word 2 */
++ __le64 options;
++ /* cmd word 3 */
++ __le64 advertising;
++};
++
+ #define DPNI_LINK_STATE_SHIFT 0
+ #define DPNI_LINK_STATE_SIZE 1
++#define DPNI_STATE_VALID_SHIFT 1
++#define DPNI_STATE_VALID_SIZE 1
+
+ struct dpni_rsp_get_link_state {
+ /* response word 0 */
+@@ -335,6 +335,39 @@ struct dpni_rsp_get_link_state {
+ __le64 options;
+ };
+
++struct dpni_rsp_get_link_state_v2 {
++ /* response word 0 */
++ __le32 pad0;
++ /* from LSB: up:1, valid:1 */
++ u8 flags;
++ u8 pad1[3];
++ /* response word 1 */
++ __le32 rate;
++ __le32 pad2;
++ /* response word 2 */
++ __le64 options;
++ /* cmd word 3 */
++ __le64 supported;
++ /* cmd word 4 */
++ __le64 advertising;
++};
++
+#define DPNI_COUPLED_SHIFT 0
+#define DPNI_COUPLED_SIZE 1
+
@@ -6547,7 +7365,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_max_frame_length {
__le16 max_frame_length;
};
-@@ -394,6 +422,24 @@ struct dpni_cmd_clear_mac_filters {
+@@ -394,6 +427,24 @@ struct dpni_cmd_clear_mac_filters {
u8 flags;
};
@@ -6572,7 +7390,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
#define DPNI_DIST_MODE_SHIFT 0
#define DPNI_DIST_MODE_SIZE 4
#define DPNI_MISS_ACTION_SHIFT 4
-@@ -503,6 +549,63 @@ struct dpni_cmd_set_queue {
+@@ -503,6 +554,63 @@ struct dpni_cmd_set_queue {
__le64 user_context;
};
@@ -6636,7 +7454,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_taildrop {
/* cmd word 0 */
u8 congestion_point;
-@@ -538,4 +641,79 @@ struct dpni_rsp_get_taildrop {
+@@ -538,4 +646,79 @@ struct dpni_rsp_get_taildrop {
__le32 threshold;
};
@@ -6718,7 +7536,43 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
#endif /* _FSL_DPNI_CMD_H */
--- a/drivers/staging/fsl-dpaa2/ethernet/dpni.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpni.c
-@@ -122,7 +122,7 @@ int dpni_open(struct fsl_mc_io *mc_io,
+@@ -1,34 +1,6 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+ /* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of the above-listed copyright holders nor the
+- * names of any contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+- * POSSIBILITY OF SUCH DAMAGE.
+ */
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+@@ -122,7 +94,7 @@ int dpni_open(struct fsl_mc_io *mc_io,
int dpni_id,
u16 *token)
{
@@ -6727,7 +7581,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_open *cmd_params;
int err;
-@@ -160,7 +160,7 @@ int dpni_close(struct fsl_mc_io *mc_io,
+@@ -160,7 +132,7 @@ int dpni_close(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token)
{
@@ -6736,7 +7590,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* prepare command */
cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
-@@ -188,7 +188,7 @@ int dpni_set_pools(struct fsl_mc_io *mc_
+@@ -188,7 +160,7 @@ int dpni_set_pools(struct fsl_mc_io *mc_
u16 token,
const struct dpni_pools_cfg *cfg)
{
@@ -6745,7 +7599,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_pools *cmd_params;
int i;
-@@ -199,7 +199,10 @@ int dpni_set_pools(struct fsl_mc_io *mc_
+@@ -199,7 +171,10 @@ int dpni_set_pools(struct fsl_mc_io *mc_
cmd_params = (struct dpni_cmd_set_pools *)cmd.params;
cmd_params->num_dpbp = cfg->num_dpbp;
for (i = 0; i < DPNI_MAX_DPBP; i++) {
@@ -6757,7 +7611,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
cmd_params->buffer_size[i] =
cpu_to_le16(cfg->pools[i].buffer_size);
cmd_params->backup_pool_mask |=
-@@ -222,7 +225,7 @@ int dpni_enable(struct fsl_mc_io *mc_io,
+@@ -222,7 +197,7 @@ int dpni_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token)
{
@@ -6766,7 +7620,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* prepare command */
cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
-@@ -245,7 +248,7 @@ int dpni_disable(struct fsl_mc_io *mc_io
+@@ -245,7 +220,7 @@ int dpni_disable(struct fsl_mc_io *mc_io
u32 cmd_flags,
u16 token)
{
@@ -6775,7 +7629,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* prepare command */
cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
-@@ -270,7 +273,7 @@ int dpni_is_enabled(struct fsl_mc_io *mc
+@@ -270,7 +245,7 @@ int dpni_is_enabled(struct fsl_mc_io *mc
u16 token,
int *en)
{
@@ -6784,7 +7638,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_is_enabled *rsp_params;
int err;
-@@ -303,7 +306,7 @@ int dpni_reset(struct fsl_mc_io *mc_io,
+@@ -303,7 +278,7 @@ int dpni_reset(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token)
{
@@ -6793,7 +7647,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* prepare command */
cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
-@@ -335,7 +338,7 @@ int dpni_set_irq_enable(struct fsl_mc_io
+@@ -335,7 +310,7 @@ int dpni_set_irq_enable(struct fsl_mc_io
u8 irq_index,
u8 en)
{
@@ -6802,7 +7656,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_irq_enable *cmd_params;
/* prepare command */
-@@ -366,7 +369,7 @@ int dpni_get_irq_enable(struct fsl_mc_io
+@@ -366,7 +341,7 @@ int dpni_get_irq_enable(struct fsl_mc_io
u8 irq_index,
u8 *en)
{
@@ -6811,7 +7665,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_irq_enable *cmd_params;
struct dpni_rsp_get_irq_enable *rsp_params;
-@@ -413,7 +416,7 @@ int dpni_set_irq_mask(struct fsl_mc_io *
+@@ -413,7 +388,7 @@ int dpni_set_irq_mask(struct fsl_mc_io *
u8 irq_index,
u32 mask)
{
@@ -6820,7 +7674,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_irq_mask *cmd_params;
/* prepare command */
-@@ -447,7 +450,7 @@ int dpni_get_irq_mask(struct fsl_mc_io *
+@@ -447,7 +422,7 @@ int dpni_get_irq_mask(struct fsl_mc_io *
u8 irq_index,
u32 *mask)
{
@@ -6829,7 +7683,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_irq_mask *cmd_params;
struct dpni_rsp_get_irq_mask *rsp_params;
int err;
-@@ -489,7 +492,7 @@ int dpni_get_irq_status(struct fsl_mc_io
+@@ -489,7 +464,7 @@ int dpni_get_irq_status(struct fsl_mc_io
u8 irq_index,
u32 *status)
{
@@ -6838,7 +7692,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_irq_status *cmd_params;
struct dpni_rsp_get_irq_status *rsp_params;
int err;
-@@ -532,7 +535,7 @@ int dpni_clear_irq_status(struct fsl_mc_
+@@ -532,7 +507,7 @@ int dpni_clear_irq_status(struct fsl_mc_
u8 irq_index,
u32 status)
{
@@ -6847,7 +7701,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_clear_irq_status *cmd_params;
/* prepare command */
-@@ -561,7 +564,7 @@ int dpni_get_attributes(struct fsl_mc_io
+@@ -561,7 +536,7 @@ int dpni_get_attributes(struct fsl_mc_io
u16 token,
struct dpni_attr *attr)
{
@@ -6856,7 +7710,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_get_attr *rsp_params;
int err;
-@@ -609,7 +612,7 @@ int dpni_set_errors_behavior(struct fsl_
+@@ -609,7 +584,7 @@ int dpni_set_errors_behavior(struct fsl_
u16 token,
struct dpni_error_cfg *cfg)
{
@@ -6865,7 +7719,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_errors_behavior *cmd_params;
/* prepare command */
-@@ -641,7 +644,7 @@ int dpni_get_buffer_layout(struct fsl_mc
+@@ -641,7 +616,7 @@ int dpni_get_buffer_layout(struct fsl_mc
enum dpni_queue_type qtype,
struct dpni_buffer_layout *layout)
{
@@ -6874,7 +7728,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_buffer_layout *cmd_params;
struct dpni_rsp_get_buffer_layout *rsp_params;
int err;
-@@ -689,7 +692,7 @@ int dpni_set_buffer_layout(struct fsl_mc
+@@ -689,7 +664,7 @@ int dpni_set_buffer_layout(struct fsl_mc
enum dpni_queue_type qtype,
const struct dpni_buffer_layout *layout)
{
@@ -6883,7 +7737,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_buffer_layout *cmd_params;
/* prepare command */
-@@ -731,7 +734,7 @@ int dpni_set_offload(struct fsl_mc_io *m
+@@ -731,7 +706,7 @@ int dpni_set_offload(struct fsl_mc_io *m
enum dpni_offload type,
u32 config)
{
@@ -6892,7 +7746,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_offload *cmd_params;
cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
-@@ -750,7 +753,7 @@ int dpni_get_offload(struct fsl_mc_io *m
+@@ -750,7 +725,7 @@ int dpni_get_offload(struct fsl_mc_io *m
enum dpni_offload type,
u32 *config)
{
@@ -6901,7 +7755,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_offload *cmd_params;
struct dpni_rsp_get_offload *rsp_params;
int err;
-@@ -792,7 +795,7 @@ int dpni_get_qdid(struct fsl_mc_io *mc_i
+@@ -792,7 +767,7 @@ int dpni_get_qdid(struct fsl_mc_io *mc_i
enum dpni_queue_type qtype,
u16 *qdid)
{
@@ -6910,7 +7764,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_qdid *cmd_params;
struct dpni_rsp_get_qdid *rsp_params;
int err;
-@@ -830,7 +833,7 @@ int dpni_get_tx_data_offset(struct fsl_m
+@@ -830,7 +805,7 @@ int dpni_get_tx_data_offset(struct fsl_m
u16 token,
u16 *data_offset)
{
@@ -6919,7 +7773,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_get_tx_data_offset *rsp_params;
int err;
-@@ -865,7 +868,7 @@ int dpni_set_link_cfg(struct fsl_mc_io *
+@@ -865,7 +840,7 @@ int dpni_set_link_cfg(struct fsl_mc_io *
u16 token,
const struct dpni_link_cfg *cfg)
{
@@ -6928,7 +7782,44 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_link_cfg *cmd_params;
/* prepare command */
-@@ -894,7 +897,7 @@ int dpni_get_link_state(struct fsl_mc_io
+@@ -881,6 +856,36 @@ int dpni_set_link_cfg(struct fsl_mc_io *
+ }
+
+ /**
++ * dpni_set_link_cfg_v2() - set the link configuration.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPNI object
++ * @cfg: Link configuration
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpni_set_link_cfg_v2(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ const struct dpni_link_cfg *cfg)
++{
++ struct fsl_mc_command cmd = { 0 };
++ struct dpni_cmd_set_link_cfg_v2 *cmd_params;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG_V2,
++ cmd_flags,
++ token);
++ cmd_params = (struct dpni_cmd_set_link_cfg_v2 *)cmd.params;
++ cmd_params->rate = cpu_to_le32(cfg->rate);
++ cmd_params->options = cpu_to_le64(cfg->options);
++ cmd_params->advertising = cpu_to_le64(cfg->advertising);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+@@ -894,7 +899,7 @@ int dpni_get_link_state(struct fsl_mc_io
u16 token,
struct dpni_link_state *state)
{
@@ -6937,10 +7828,50 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_get_link_state *rsp_params;
int err;
-@@ -918,6 +921,44 @@ int dpni_get_link_state(struct fsl_mc_io
+@@ -918,6 +923,84 @@ int dpni_get_link_state(struct fsl_mc_io
}
/**
++ * dpni_get_link_state_v2() - Return the link state (either up or down)
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPNI object
++ * @state: Returned link state;
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpni_get_link_state_v2(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ struct dpni_link_state *state)
++{
++ struct fsl_mc_command cmd = { 0 };
++ struct dpni_rsp_get_link_state_v2 *rsp_params;
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE_V2,
++ cmd_flags,
++ token);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ rsp_params = (struct dpni_rsp_get_link_state_v2 *)cmd.params;
++ state->up = dpni_get_field(rsp_params->flags, LINK_STATE);
++ state->state_valid = dpni_get_field(rsp_params->flags, STATE_VALID);
++ state->rate = le32_to_cpu(rsp_params->rate);
++ state->options = le64_to_cpu(rsp_params->options);
++ state->supported = le64_to_cpu(rsp_params->supported);
++ state->advertising = le64_to_cpu(rsp_params->advertising);
++
++ return 0;
++}
++
++/**
+ * dpni_set_tx_shaping() - Set the transmit shaping
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
@@ -6982,7 +7913,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* dpni_set_max_frame_length() - Set the maximum received frame length.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-@@ -933,7 +974,7 @@ int dpni_set_max_frame_length(struct fsl
+@@ -933,7 +1016,7 @@ int dpni_set_max_frame_length(struct fsl
u16 token,
u16 max_frame_length)
{
@@ -6991,7 +7922,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_max_frame_length *cmd_params;
/* prepare command */
-@@ -963,7 +1004,7 @@ int dpni_get_max_frame_length(struct fsl
+@@ -963,7 +1046,7 @@ int dpni_get_max_frame_length(struct fsl
u16 token,
u16 *max_frame_length)
{
@@ -7000,7 +7931,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_get_max_frame_length *rsp_params;
int err;
-@@ -998,7 +1039,7 @@ int dpni_set_multicast_promisc(struct fs
+@@ -998,7 +1081,7 @@ int dpni_set_multicast_promisc(struct fs
u16 token,
int en)
{
@@ -7009,7 +7940,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_multicast_promisc *cmd_params;
/* prepare command */
-@@ -1026,7 +1067,7 @@ int dpni_get_multicast_promisc(struct fs
+@@ -1026,7 +1109,7 @@ int dpni_get_multicast_promisc(struct fs
u16 token,
int *en)
{
@@ -7018,7 +7949,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_get_multicast_promisc *rsp_params;
int err;
-@@ -1061,7 +1102,7 @@ int dpni_set_unicast_promisc(struct fsl_
+@@ -1061,7 +1144,7 @@ int dpni_set_unicast_promisc(struct fsl_
u16 token,
int en)
{
@@ -7027,7 +7958,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_unicast_promisc *cmd_params;
/* prepare command */
-@@ -1089,7 +1130,7 @@ int dpni_get_unicast_promisc(struct fsl_
+@@ -1089,7 +1172,7 @@ int dpni_get_unicast_promisc(struct fsl_
u16 token,
int *en)
{
@@ -7036,7 +7967,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_get_unicast_promisc *rsp_params;
int err;
-@@ -1124,7 +1165,7 @@ int dpni_set_primary_mac_addr(struct fsl
+@@ -1124,7 +1207,7 @@ int dpni_set_primary_mac_addr(struct fsl
u16 token,
const u8 mac_addr[6])
{
@@ -7045,7 +7976,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_primary_mac_addr *cmd_params;
int i;
-@@ -1154,7 +1195,7 @@ int dpni_get_primary_mac_addr(struct fsl
+@@ -1154,7 +1237,7 @@ int dpni_get_primary_mac_addr(struct fsl
u16 token,
u8 mac_addr[6])
{
@@ -7054,7 +7985,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_get_primary_mac_addr *rsp_params;
int i, err;
-@@ -1193,7 +1234,7 @@ int dpni_get_port_mac_addr(struct fsl_mc
+@@ -1193,7 +1276,7 @@ int dpni_get_port_mac_addr(struct fsl_mc
u16 token,
u8 mac_addr[6])
{
@@ -7063,7 +7994,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_rsp_get_port_mac_addr *rsp_params;
int i, err;
-@@ -1229,7 +1270,7 @@ int dpni_add_mac_addr(struct fsl_mc_io *
+@@ -1229,7 +1312,7 @@ int dpni_add_mac_addr(struct fsl_mc_io *
u16 token,
const u8 mac_addr[6])
{
@@ -7072,7 +8003,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_add_mac_addr *cmd_params;
int i;
-@@ -1259,7 +1300,7 @@ int dpni_remove_mac_addr(struct fsl_mc_i
+@@ -1259,7 +1342,7 @@ int dpni_remove_mac_addr(struct fsl_mc_i
u16 token,
const u8 mac_addr[6])
{
@@ -7081,7 +8012,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_remove_mac_addr *cmd_params;
int i;
-@@ -1293,7 +1334,7 @@ int dpni_clear_mac_filters(struct fsl_mc
+@@ -1293,7 +1376,7 @@ int dpni_clear_mac_filters(struct fsl_mc
int unicast,
int multicast)
{
@@ -7090,7 +8021,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_clear_mac_filters *cmd_params;
/* prepare command */
-@@ -1309,6 +1350,55 @@ int dpni_clear_mac_filters(struct fsl_mc
+@@ -1309,6 +1392,55 @@ int dpni_clear_mac_filters(struct fsl_mc
}
/**
@@ -7146,7 +8077,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-@@ -1327,7 +1417,7 @@ int dpni_set_rx_tc_dist(struct fsl_mc_io
+@@ -1327,7 +1459,7 @@ int dpni_set_rx_tc_dist(struct fsl_mc_io
u8 tc_id,
const struct dpni_rx_tc_dist_cfg *cfg)
{
@@ -7155,7 +8086,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_rx_tc_dist *cmd_params;
/* prepare command */
-@@ -1346,6 +1436,293 @@ int dpni_set_rx_tc_dist(struct fsl_mc_io
+@@ -1346,6 +1478,215 @@ int dpni_set_rx_tc_dist(struct fsl_mc_io
return mc_send_command(mc_io, &cmd);
}
@@ -7266,84 +8197,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
+
+/**
-+ * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class
-+ * (to select a flow ID)
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPNI object
-+ * @tc_id: Traffic class selection (0-7)
-+ * @index: Location in the QoS table where to insert the entry.
-+ * Only relevant if MASKING is enabled for QoS
-+ * classification on this DPNI, it is ignored for exact match.
-+ * @cfg: Flow steering rule to add
-+ * @action: Action to be taken as result of a classification hit
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpni_add_fs_entry(struct fsl_mc_io *mc_io,
-+ u32 cmd_flags,
-+ u16 token,
-+ u8 tc_id,
-+ u16 index,
-+ const struct dpni_rule_cfg *cfg,
-+ const struct dpni_fs_action_cfg *action)
-+{
-+ struct dpni_cmd_add_fs_entry *cmd_params;
-+ struct fsl_mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_FS_ENT,
-+ cmd_flags,
-+ token);
-+ cmd_params = (struct dpni_cmd_add_fs_entry *)cmd.params;
-+ cmd_params->tc_id = tc_id;
-+ cmd_params->key_size = cfg->key_size;
-+ cmd_params->index = cpu_to_le16(index);
-+ cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
-+ cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
-+ cmd_params->options = cpu_to_le16(action->options);
-+ cmd_params->flow_id = cpu_to_le16(action->flow_id);
-+ cmd_params->flc = cpu_to_le64(action->flc);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific
-+ * traffic class
-+ * @mc_io: Pointer to MC portal's I/O object
-+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token: Token of DPNI object
-+ * @tc_id: Traffic class selection (0-7)
-+ * @cfg: Flow steering rule to remove
-+ *
-+ * Return: '0' on Success; Error code otherwise.
-+ */
-+int dpni_remove_fs_entry(struct fsl_mc_io *mc_io,
-+ u32 cmd_flags,
-+ u16 token,
-+ u8 tc_id,
-+ const struct dpni_rule_cfg *cfg)
-+{
-+ struct dpni_cmd_remove_fs_entry *cmd_params;
-+ struct fsl_mc_command cmd = { 0 };
-+
-+ /* prepare command */
-+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_FS_ENT,
-+ cmd_flags,
-+ token);
-+ cmd_params = (struct dpni_cmd_remove_fs_entry *)cmd.params;
-+ cmd_params->tc_id = tc_id;
-+ cmd_params->key_size = cfg->key_size;
-+ cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
-+ cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
-+
-+ /* send command to mc*/
-+ return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
+ * dpni_set_congestion_notification() - Set traffic class congestion
+ * notification configuration
+ * @mc_io: Pointer to MC portal's I/O object
@@ -7449,7 +8302,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* dpni_set_queue() - Set queue parameters
* @mc_io: Pointer to MC portal's I/O object
-@@ -1371,7 +1748,7 @@ int dpni_set_queue(struct fsl_mc_io *mc_
+@@ -1371,7 +1712,7 @@ int dpni_set_queue(struct fsl_mc_io *mc_
u8 options,
const struct dpni_queue *queue)
{
@@ -7458,7 +8311,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_queue *cmd_params;
/* prepare command */
-@@ -1419,7 +1796,7 @@ int dpni_get_queue(struct fsl_mc_io *mc_
+@@ -1419,7 +1760,7 @@ int dpni_get_queue(struct fsl_mc_io *mc_
struct dpni_queue *queue,
struct dpni_queue_id *qid)
{
@@ -7467,7 +8320,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_queue *cmd_params;
struct dpni_rsp_get_queue *rsp_params;
int err;
-@@ -1463,6 +1840,8 @@ int dpni_get_queue(struct fsl_mc_io *mc_
+@@ -1463,6 +1804,8 @@ int dpni_get_queue(struct fsl_mc_io *mc_
* @token: Token of DPNI object
* @page: Selects the statistics page to retrieve, see
* DPNI_GET_STATISTICS output. Pages are numbered 0 to 2.
@@ -7476,7 +8329,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* @stat: Structure containing the statistics
*
* Return: '0' on Success; Error code otherwise.
-@@ -1471,9 +1850,10 @@ int dpni_get_statistics(struct fsl_mc_io
+@@ -1471,9 +1814,10 @@ int dpni_get_statistics(struct fsl_mc_io
u32 cmd_flags,
u16 token,
u8 page,
@@ -7488,7 +8341,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_statistics *cmd_params;
struct dpni_rsp_get_statistics *rsp_params;
int i, err;
-@@ -1484,6 +1864,7 @@ int dpni_get_statistics(struct fsl_mc_io
+@@ -1484,6 +1828,7 @@ int dpni_get_statistics(struct fsl_mc_io
token);
cmd_params = (struct dpni_cmd_get_statistics *)cmd.params;
cmd_params->page_number = page;
@@ -7496,7 +8349,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/* send command to mc */
err = mc_send_command(mc_io, &cmd);
-@@ -1499,6 +1880,29 @@ int dpni_get_statistics(struct fsl_mc_io
+@@ -1499,6 +1844,29 @@ int dpni_get_statistics(struct fsl_mc_io
}
/**
@@ -7526,7 +8379,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* dpni_set_taildrop() - Set taildrop per queue or TC
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-@@ -1506,7 +1910,10 @@ int dpni_get_statistics(struct fsl_mc_io
+@@ -1506,7 +1874,10 @@ int dpni_get_statistics(struct fsl_mc_io
* @cg_point: Congestion point
* @q_type: Queue type on which the taildrop is configured.
* Only Rx queues are supported for now
@@ -7538,7 +8391,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* @q_index: Index of the queue if the DPNI supports multiple queues for
* traffic distribution. Ignored if CONGESTION_POINT is not 0.
* @taildrop: Taildrop structure
-@@ -1522,7 +1929,7 @@ int dpni_set_taildrop(struct fsl_mc_io *
+@@ -1522,7 +1893,7 @@ int dpni_set_taildrop(struct fsl_mc_io *
u8 index,
struct dpni_taildrop *taildrop)
{
@@ -7547,7 +8400,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_set_taildrop *cmd_params;
/* prepare command */
-@@ -1550,7 +1957,10 @@ int dpni_set_taildrop(struct fsl_mc_io *
+@@ -1550,7 +1921,10 @@ int dpni_set_taildrop(struct fsl_mc_io *
* @cg_point: Congestion point
* @q_type: Queue type on which the taildrop is configured.
* Only Rx queues are supported for now
@@ -7559,7 +8412,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* @q_index: Index of the queue if the DPNI supports multiple queues for
* traffic distribution. Ignored if CONGESTION_POINT is not 0.
* @taildrop: Taildrop structure
-@@ -1566,7 +1976,7 @@ int dpni_get_taildrop(struct fsl_mc_io *
+@@ -1566,7 +1940,7 @@ int dpni_get_taildrop(struct fsl_mc_io *
u8 index,
struct dpni_taildrop *taildrop)
{
@@ -7568,7 +8421,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
struct dpni_cmd_get_taildrop *cmd_params;
struct dpni_rsp_get_taildrop *rsp_params;
int err;
-@@ -1594,3 +2004,109 @@ int dpni_get_taildrop(struct fsl_mc_io *
+@@ -1594,3 +1968,187 @@ int dpni_get_taildrop(struct fsl_mc_io *
return 0;
}
@@ -7636,11 +8489,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ cmd_flags,
+ token);
+ cmd_params = (struct dpni_cmd_set_rx_fs_dist *)cmd.params;
-+ cmd_params->dist_size = le16_to_cpu(cfg->dist_size);
++ cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
+ dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable);
+ cmd_params->tc = cfg->tc;
-+ cmd_params->miss_flow_id = le16_to_cpu(cfg->fs_miss_flow_id);
-+ cmd_params->key_cfg_iova = le64_to_cpu(cfg->key_cfg_iova);
++ cmd_params->miss_flow_id = cpu_to_le16(cfg->fs_miss_flow_id);
++ cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
@@ -7670,17 +8523,131 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ cmd_flags,
+ token);
+ cmd_params = (struct dpni_cmd_set_rx_hash_dist *)cmd.params;
-+ cmd_params->dist_size = le16_to_cpu(cfg->dist_size);
++ cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
+ dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable);
+ cmd_params->tc = cfg->tc;
-+ cmd_params->key_cfg_iova = le64_to_cpu(cfg->key_cfg_iova);
++ cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++/**
++ * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class
++ * (to select a flow ID)
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPNI object
++ * @tc_id: Traffic class selection (0-7)
++ * @index: Location in the QoS table where to insert the entry.
++ * Only relevant if MASKING is enabled for QoS
++ * classification on this DPNI, it is ignored for exact match.
++ * @cfg: Flow steering rule to add
++ * @action: Action to be taken as result of a classification hit
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpni_add_fs_entry(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ u8 tc_id,
++ u16 index,
++ const struct dpni_rule_cfg *cfg,
++ const struct dpni_fs_action_cfg *action)
++{
++ struct dpni_cmd_add_fs_entry *cmd_params;
++ struct fsl_mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_FS_ENT,
++ cmd_flags,
++ token);
++ cmd_params = (struct dpni_cmd_add_fs_entry *)cmd.params;
++ cmd_params->tc_id = tc_id;
++ cmd_params->key_size = cfg->key_size;
++ cmd_params->index = cpu_to_le16(index);
++ cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
++ cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
++ cmd_params->options = cpu_to_le16(action->options);
++ cmd_params->flow_id = cpu_to_le16(action->flow_id);
++ cmd_params->flc = cpu_to_le64(action->flc);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++/**
++ * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific
++ * traffic class
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPNI object
++ * @tc_id: Traffic class selection (0-7)
++ * @cfg: Flow steering rule to remove
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpni_remove_fs_entry(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ u8 tc_id,
++ const struct dpni_rule_cfg *cfg)
++{
++ struct dpni_cmd_remove_fs_entry *cmd_params;
++ struct fsl_mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_FS_ENT,
++ cmd_flags,
++ token);
++ cmd_params = (struct dpni_cmd_remove_fs_entry *)cmd.params;
++ cmd_params->tc_id = tc_id;
++ cmd_params->key_size = cfg->key_size;
++ cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
++ cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
--- a/drivers/staging/fsl-dpaa2/ethernet/dpni.h
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpni.h
-@@ -52,6 +52,14 @@ struct fsl_mc_io;
+@@ -1,34 +1,6 @@
++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+ /* Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of the above-listed copyright holders nor the
+- * names of any contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+- * POSSIBILITY OF SUCH DAMAGE.
+ */
+ #ifndef __FSL_DPNI_H
+ #define __FSL_DPNI_H
+@@ -52,6 +24,14 @@ struct fsl_mc_io;
* Maximum number of buffer pools per DPNI
*/
#define DPNI_MAX_DPBP 8
@@ -7695,7 +8662,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* All traffic classes considered; see dpni_set_queue()
-@@ -123,13 +131,15 @@ struct dpni_pools_cfg {
+@@ -123,13 +103,15 @@ struct dpni_pools_cfg {
/**
* struct pools - Buffer pools parameters
* @dpbp_id: DPBP object ID
@@ -7713,7 +8680,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
} pools[DPNI_MAX_DPBP];
};
-@@ -476,6 +486,24 @@ union dpni_statistics {
+@@ -476,6 +458,24 @@ union dpni_statistics {
u64 egress_confirmed_frames;
} page_2;
/**
@@ -7738,7 +8705,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* struct raw - raw statistics structure
*/
struct {
-@@ -487,8 +515,13 @@ int dpni_get_statistics(struct fsl_mc_io
+@@ -487,8 +487,13 @@ int dpni_get_statistics(struct fsl_mc_io
u32 cmd_flags,
u16 token,
u8 page,
@@ -7752,7 +8719,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
/**
* Enable auto-negotiation
*/
-@@ -505,6 +538,10 @@ int dpni_get_statistics(struct fsl_mc_io
+@@ -505,6 +510,23 @@ int dpni_get_statistics(struct fsl_mc_io
* Enable a-symmetric pause frames
*/
#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
@@ -7760,13 +8727,62 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ * Enable priority flow control pause frames
+ */
+#define DPNI_LINK_OPT_PFC_PAUSE 0x0000000000000010ULL
++/**
++ * Advertised link speeds
++ */
++#define DPNI_ADVERTISED_10BASET_FULL 0x0000000000000001ULL
++#define DPNI_ADVERTISED_100BASET_FULL 0x0000000000000002ULL
++#define DPNI_ADVERTISED_1000BASET_FULL 0x0000000000000004ULL
++#define DPNI_ADVERTISED_10000BASET_FULL 0x0000000000000010ULL
++#define DPNI_ADVERTISED_2500BASEX_FULL 0x0000000000000020ULL
++
++/**
++ * Advertise auto-negotiation enabled
++ */
++#define DPNI_ADVERTISED_AUTONEG 0x0000000000000008ULL
/**
* struct - Structure representing DPNI link configuration
-@@ -538,6 +575,23 @@ int dpni_get_link_state(struct fsl_mc_io
+@@ -514,6 +536,7 @@ int dpni_get_statistics(struct fsl_mc_io
+ struct dpni_link_cfg {
+ u32 rate;
+ u64 options;
++ u64 advertising;
+ };
+
+ int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
+@@ -521,6 +544,11 @@ int dpni_set_link_cfg(struct fsl_mc_io
+ u16 token,
+ const struct dpni_link_cfg *cfg);
+
++int dpni_set_link_cfg_v2(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ const struct dpni_link_cfg *cfg);
++
+ /**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+@@ -530,7 +558,10 @@ int dpni_set_link_cfg(struct fsl_mc_io
+ struct dpni_link_state {
+ u32 rate;
+ u64 options;
++ u64 supported;
++ u64 advertising;
+ int up;
++ int state_valid;
+ };
+
+ int dpni_get_link_state(struct fsl_mc_io *mc_io,
+@@ -538,6 +569,28 @@ int dpni_get_link_state(struct fsl_mc_io
u16 token,
struct dpni_link_state *state);
++int dpni_get_link_state_v2(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ struct dpni_link_state *state);
++
+/**
+ * struct dpni_tx_shaping - Structure representing DPNI tx shaping configuration
+ * @rate_limit: rate in Mbps
@@ -7787,7 +8803,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
-@@ -639,6 +693,70 @@ int dpni_prepare_key_cfg(const struct dp
+@@ -639,6 +692,70 @@ int dpni_prepare_key_cfg(const struct dp
u8 *key_cfg_buf);
/**
@@ -7858,7 +8874,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration
* @dist_size: Set the distribution size;
* supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96,
-@@ -784,6 +902,108 @@ enum dpni_congestion_point {
+@@ -784,6 +901,108 @@ enum dpni_congestion_point {
};
/**
@@ -7967,7 +8983,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
* struct dpni_taildrop - Structure representing the taildrop
* @enable: Indicates whether the taildrop is active or not.
* @units: Indicates the unit of THRESHOLD. Queue taildrop only supports
-@@ -829,4 +1049,124 @@ struct dpni_rule_cfg {
+@@ -829,4 +1048,124 @@ struct dpni_rule_cfg {
u8 key_size;
};
@@ -8092,3 +9108,40 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ const struct dpni_rx_dist_cfg *cfg);
+
#endif /* __FSL_DPNI_H */
+--- a/drivers/staging/fsl-dpaa2/ethernet/net.h
++++ b/drivers/staging/fsl-dpaa2/ethernet/net.h
+@@ -1,33 +1,5 @@
++/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+ /* Copyright 2013-2015 Freescale Semiconductor Inc.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * * Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * * Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * * Neither the name of the above-listed copyright holders nor the
+- * names of any contributors may be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+- * POSSIBILITY OF SUCH DAMAGE.
+ */
+ #ifndef __FSL_NET_H
+ #define __FSL_NET_H