From: Wei Fang <wei.fang@nxp.com>
To: claudiu.manoil@nxp.com, vladimir.oltean@nxp.com,
xiaoning.wang@nxp.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, christophe.leroy@csgroup.eu
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev
Subject: [PATCH net-next 02/13] net: enetc: add command BD ring support for i.MX95 ENETC
Date: Fri, 3 Jan 2025 14:05:58 +0800 [thread overview]
Message-ID: <20250103060610.2233908-3-wei.fang@nxp.com> (raw)
In-Reply-To: <20250103060610.2233908-1-wei.fang@nxp.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 11934 bytes --]
The command BD ring is used to configure functionality where the
underlying resources may be shared between different entities or being
too large to configure using direct registers (such as lookup tables).
Because the command BD and table formats of i.MX95 and LS1028A are very
different, the software processing logic is also different. In order to
ensure driver compatibility, struct enetc_si_ops is introduced. This
structure defines some hooks shared by VSI and PSI. Different hardware
driver will register different hooks, For example, setup_cbdr() is used
to initialize the command BD ring, and teardown_cbdr() is used to free
the command BD ring.
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
drivers/net/ethernet/freescale/enetc/enetc.h | 27 ++++++++--
.../net/ethernet/freescale/enetc/enetc4_pf.c | 47 ++++++++++++++++-
.../net/ethernet/freescale/enetc/enetc_cbdr.c | 51 ++++++++++++++++---
.../net/ethernet/freescale/enetc/enetc_pf.c | 13 +++--
.../net/ethernet/freescale/enetc/enetc_vf.c | 13 +++--
5 files changed, 132 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
index 4ad4eb5c5a74..4ff0957e69be 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -8,6 +8,7 @@
#include <linux/dma-mapping.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
+#include <linux/fsl/ntmp.h>
#include <linux/if_vlan.h>
#include <linux/phylink.h>
#include <linux/dim.h>
@@ -266,6 +267,19 @@ struct enetc_platform_info {
const struct enetc_drvdata *data;
};
+struct enetc_si;
+
+/*
+ * This structure defines the some common hooks for ENETC PSI and VSI.
+ * In addition, since VSI only uses the struct enetc_si as its private
+ * driver data, so this structure also define some hooks specifically
+ * for VSI. For VSI-specific hooks, the format is ‘vf_*()’.
+ */
+struct enetc_si_ops {
+ int (*setup_cbdr)(struct enetc_si *si);
+ void (*teardown_cbdr)(struct enetc_si *si);
+};
+
/* PCI IEP device data */
struct enetc_si {
struct pci_dev *pdev;
@@ -274,7 +288,10 @@ struct enetc_si {
struct net_device *ndev; /* back ref. */
- struct enetc_cbdr cbd_ring;
+ union {
+ struct enetc_cbdr cbd_ring; /* Only ENETC 1.0 */
+ struct ntmp_priv ntmp; /* ENETC 4.1 and later */
+ };
int num_rx_rings; /* how many rings are available in the SI */
int num_tx_rings;
@@ -284,6 +301,7 @@ struct enetc_si {
u16 revision;
int hw_features;
const struct enetc_drvdata *drvdata;
+ const struct enetc_si_ops *ops;
};
#define ENETC_SI_ALIGN 32
@@ -490,9 +508,10 @@ void enetc_mm_link_state_update(struct enetc_ndev_priv *priv, bool link);
void enetc_mm_commit_preemptible_tcs(struct enetc_ndev_priv *priv);
/* control buffer descriptor ring (CBDR) */
-int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
- struct enetc_cbdr *cbdr);
-void enetc_teardown_cbdr(struct enetc_cbdr *cbdr);
+int enetc_setup_cbdr(struct enetc_si *si);
+void enetc_teardown_cbdr(struct enetc_si *si);
+int enetc4_setup_cbdr(struct enetc_si *si);
+void enetc4_teardown_cbdr(struct enetc_si *si);
int enetc_set_mac_flt_entry(struct enetc_si *si, int index,
char *mac_addr, int si_map);
int enetc_clear_mac_flt_entry(struct enetc_si *si, int index);
diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
index fc41078c4f5d..b957e92e3a00 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
@@ -260,6 +260,23 @@ static void enetc4_configure_port(struct enetc_pf *pf)
enetc4_enable_trx(pf);
}
+static int enetc4_init_ntmp_priv(struct enetc_si *si)
+{
+ struct ntmp_priv *ntmp = &si->ntmp;
+
+ ntmp->dev_type = NETC_DEV_ENETC;
+
+ /* For ENETC 4.1, all table versions are 0 */
+ memset(&ntmp->cbdrs.tbl, 0, sizeof(ntmp->cbdrs.tbl));
+
+ return si->ops->setup_cbdr(si);
+}
+
+static void enetc4_free_ntmp_priv(struct enetc_si *si)
+{
+ si->ops->teardown_cbdr(si);
+}
+
static int enetc4_pf_init(struct enetc_pf *pf)
{
struct device *dev = &pf->si->pdev->dev;
@@ -272,11 +289,22 @@ static int enetc4_pf_init(struct enetc_pf *pf)
return err;
}
+ err = enetc4_init_ntmp_priv(pf->si);
+ if (err) {
+ dev_err(dev, "Failed to init CBDR\n");
+ return err;
+ }
+
enetc4_configure_port(pf);
return 0;
}
+static void enetc4_pf_free(struct enetc_pf *pf)
+{
+ enetc4_free_ntmp_priv(pf->si);
+}
+
static const struct net_device_ops enetc4_ndev_ops = {
.ndo_open = enetc_open,
.ndo_stop = enetc_close,
@@ -688,6 +716,11 @@ static void enetc4_pf_netdev_destroy(struct enetc_si *si)
free_netdev(ndev);
}
+static const struct enetc_si_ops enetc4_psi_ops = {
+ .setup_cbdr = enetc4_setup_cbdr,
+ .teardown_cbdr = enetc4_teardown_cbdr,
+};
+
static int enetc4_pf_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -712,6 +745,7 @@ static int enetc4_pf_probe(struct pci_dev *pdev,
"Couldn't map PF only space\n");
si->revision = enetc_get_ip_revision(&si->hw);
+ si->ops = &enetc4_psi_ops;
err = enetc_get_driver_data(si);
if (err)
return dev_err_probe(dev, err,
@@ -728,14 +762,25 @@ static int enetc4_pf_probe(struct pci_dev *pdev,
enetc_get_si_caps(si);
- return enetc4_pf_netdev_create(si);
+ err = enetc4_pf_netdev_create(si);
+ if (err)
+ goto err_netdev_create;
+
+ return 0;
+
+err_netdev_create:
+ enetc4_pf_free(pf);
+
+ return err;
}
static void enetc4_pf_remove(struct pci_dev *pdev)
{
struct enetc_si *si = pci_get_drvdata(pdev);
+ struct enetc_pf *pf = enetc_si_priv(si);
enetc4_pf_netdev_destroy(si);
+ enetc4_pf_free(pf);
}
static const struct pci_device_id enetc4_pf_id_table[] = {
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c b/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c
index 20bfdf7fb4b4..31bb82ee512d 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c
@@ -3,10 +3,12 @@
#include "enetc.h"
-int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
- struct enetc_cbdr *cbdr)
+int enetc_setup_cbdr(struct enetc_si *si)
{
- int size = bd_count * sizeof(struct enetc_cbd);
+ int size = ENETC_CBDR_DEFAULT_SIZE * sizeof(struct enetc_cbd);
+ struct enetc_cbdr *cbdr = &si->cbd_ring;
+ struct device *dev = &si->pdev->dev;
+ struct enetc_hw *hw = &si->hw;
cbdr->bd_base = dma_alloc_coherent(dev, size, &cbdr->bd_dma_base,
GFP_KERNEL);
@@ -23,7 +25,7 @@ int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
cbdr->next_to_clean = 0;
cbdr->next_to_use = 0;
cbdr->dma_dev = dev;
- cbdr->bd_count = bd_count;
+ cbdr->bd_count = ENETC_CBDR_DEFAULT_SIZE;
cbdr->pir = hw->reg + ENETC_SICBDRPIR;
cbdr->cir = hw->reg + ENETC_SICBDRCIR;
@@ -46,13 +48,41 @@ int enetc_setup_cbdr(struct device *dev, struct enetc_hw *hw, int bd_count,
}
EXPORT_SYMBOL_GPL(enetc_setup_cbdr);
-void enetc_teardown_cbdr(struct enetc_cbdr *cbdr)
+int enetc4_setup_cbdr(struct enetc_si *si)
{
- int size = cbdr->bd_count * sizeof(struct enetc_cbd);
+ struct netc_cbdrs *cbdrs = &si->ntmp.cbdrs;
+ struct device *dev = &si->pdev->dev;
+ struct enetc_hw *hw = &si->hw;
+ struct netc_cbdr_regs regs;
+
+ cbdrs->cbdr_num = 1;
+ cbdrs->cbdr_size = NETC_CBDR_BD_NUM;
+ cbdrs->dma_dev = dev;
+ cbdrs->ring = devm_kcalloc(dev, cbdrs->cbdr_num,
+ sizeof(struct netc_cbdr), GFP_KERNEL);
+ if (!cbdrs->ring)
+ return -ENOMEM;
+
+ regs.pir = hw->reg + ENETC_SICBDRPIR;
+ regs.cir = hw->reg + ENETC_SICBDRCIR;
+ regs.mr = hw->reg + ENETC_SICBDRMR;
+ regs.bar0 = hw->reg + ENETC_SICBDRBAR0;
+ regs.bar1 = hw->reg + ENETC_SICBDRBAR1;
+ regs.lenr = hw->reg + ENETC_SICBDRLENR;
+
+ return netc_setup_cbdr(dev, cbdrs->cbdr_size, ®s, cbdrs->ring);
+}
+EXPORT_SYMBOL_GPL(enetc4_setup_cbdr);
+
+void enetc_teardown_cbdr(struct enetc_si *si)
+{
+ struct enetc_cbdr *cbdr = &si->cbd_ring;
+ int size;
/* disable ring */
enetc_wr_reg(cbdr->mr, 0);
+ size = cbdr->bd_count * sizeof(struct enetc_cbd);
dma_free_coherent(cbdr->dma_dev, size, cbdr->bd_base,
cbdr->bd_dma_base);
cbdr->bd_base = NULL;
@@ -60,6 +90,15 @@ void enetc_teardown_cbdr(struct enetc_cbdr *cbdr)
}
EXPORT_SYMBOL_GPL(enetc_teardown_cbdr);
+void enetc4_teardown_cbdr(struct enetc_si *si)
+{
+ struct netc_cbdrs *cbdrs = &si->ntmp.cbdrs;
+
+ netc_teardown_cbdr(cbdrs->dma_dev, cbdrs->ring);
+ cbdrs->dma_dev = NULL;
+}
+EXPORT_SYMBOL_GPL(enetc4_teardown_cbdr);
+
static void enetc_clean_cbdr(struct enetc_cbdr *ring)
{
struct enetc_cbd *dest_cbd;
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 203862ec1114..a214749a4af6 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -939,6 +939,11 @@ static int enetc_pf_register_with_ierb(struct pci_dev *pdev)
return enetc_ierb_register_pf(ierb_pdev, pdev);
}
+static const struct enetc_si_ops enetc_psi_ops = {
+ .setup_cbdr = enetc_setup_cbdr,
+ .teardown_cbdr = enetc_teardown_cbdr,
+};
+
static struct enetc_si *enetc_psi_create(struct pci_dev *pdev)
{
struct enetc_si *si;
@@ -957,6 +962,7 @@ static struct enetc_si *enetc_psi_create(struct pci_dev *pdev)
goto out_pci_remove;
}
+ si->ops = &enetc_psi_ops;
si->revision = enetc_get_ip_revision(&si->hw);
err = enetc_get_driver_data(si);
if (err) {
@@ -964,8 +970,7 @@ static struct enetc_si *enetc_psi_create(struct pci_dev *pdev)
goto out_pci_remove;
}
- err = enetc_setup_cbdr(&pdev->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE,
- &si->cbd_ring);
+ err = si->ops->setup_cbdr(si);
if (err)
goto out_pci_remove;
@@ -984,7 +989,7 @@ static struct enetc_si *enetc_psi_create(struct pci_dev *pdev)
return si;
out_teardown_cbdr:
- enetc_teardown_cbdr(&si->cbd_ring);
+ si->ops->teardown_cbdr(si);
out_pci_remove:
enetc_pci_remove(pdev);
out:
@@ -995,7 +1000,7 @@ static void enetc_psi_destroy(struct pci_dev *pdev)
{
struct enetc_si *si = pci_get_drvdata(pdev);
- enetc_teardown_cbdr(&si->cbd_ring);
+ si->ops->teardown_cbdr(si);
enetc_pci_remove(pdev);
}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_vf.c b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
index 3768752b6008..d7d9a720069b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -162,6 +162,11 @@ static void enetc_vf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
enetc_load_primary_mac_addr(&si->hw, ndev);
}
+static const struct enetc_si_ops enetc_vsi_ops = {
+ .setup_cbdr = enetc_setup_cbdr,
+ .teardown_cbdr = enetc_teardown_cbdr,
+};
+
static int enetc_vf_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -176,6 +181,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
si = pci_get_drvdata(pdev);
si->revision = ENETC_REV_1_0;
+ si->ops = &enetc_vsi_ops;
err = enetc_get_driver_data(si);
if (err) {
dev_err_probe(&pdev->dev, err,
@@ -198,8 +204,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
enetc_init_si_rings_params(priv);
- err = enetc_setup_cbdr(priv->dev, &si->hw, ENETC_CBDR_DEFAULT_SIZE,
- &si->cbd_ring);
+ err = si->ops->setup_cbdr(si);
if (err)
goto err_setup_cbdr;
@@ -235,7 +240,7 @@ static int enetc_vf_probe(struct pci_dev *pdev,
err_alloc_msix:
enetc_free_si_resources(priv);
err_alloc_si_res:
- enetc_teardown_cbdr(&si->cbd_ring);
+ si->ops->teardown_cbdr(si);
err_setup_cbdr:
si->ndev = NULL;
free_netdev(ndev);
@@ -256,7 +261,7 @@ static void enetc_vf_remove(struct pci_dev *pdev)
enetc_free_msix(priv);
enetc_free_si_resources(priv);
- enetc_teardown_cbdr(&si->cbd_ring);
+ si->ops->teardown_cbdr(si);
free_netdev(si->ndev);
--
2.34.1
next prev parent reply other threads:[~2025-01-03 6:23 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-03 6:05 [PATCH net-next 00/13] Add more feautues for ENETC v4 - round 2 Wei Fang
2025-01-03 6:05 ` [PATCH net-next 01/13] net: enetc: add initial netc-lib driver to support NTMP Wei Fang
2025-01-03 16:20 ` Andrew Lunn
2025-01-06 2:45 ` Wei Fang
2025-01-03 6:05 ` Wei Fang [this message]
2025-01-03 6:05 ` [PATCH net-next 03/13] net: enetc: move generic MAC filterng interfaces to enetc-core Wei Fang
2025-01-03 6:06 ` [PATCH net-next 04/13] net: enetc: add MAC filter for i.MX95 ENETC PF Wei Fang
2025-01-05 1:45 ` Jakub Kicinski
2025-01-03 6:06 ` [PATCH net-next 05/13] net: enetc: add debugfs interface to dump MAC filter Wei Fang
2025-01-03 16:25 ` Andrew Lunn
2025-01-06 2:19 ` Wei Fang
2025-01-03 6:06 ` [PATCH net-next 06/13] net: enetc: make enetc_set_rxfh() and enetc_get_rxfh() reusable Wei Fang
2025-01-03 6:06 ` [PATCH net-next 07/13] net: enetc: add RSS support for i.MX95 ENETC PF Wei Fang
2025-01-03 6:06 ` [PATCH net-next 08/13] net: enetc: enable RSS feature by default Wei Fang
2025-01-03 6:06 ` [PATCH net-next 09/13] net: enetc: move generic VLAN filter interfaces to enetc-core Wei Fang
2025-01-03 6:06 ` [PATCH net-next 10/13] net: enetc: move generic VLAN hash filter functions to enetc_pf_common.c Wei Fang
2025-01-03 6:06 ` [PATCH net-next 11/13] net: enetc: add VLAN filtering support for i.MX95 ENETC PF Wei Fang
2025-01-03 6:06 ` [PATCH net-next 12/13] net: enetc: add loopback " Wei Fang
2025-01-03 6:06 ` [PATCH net-next 13/13] MAINTAINERS: add new file ntmp.h to ENETC driver Wei Fang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250103060610.2233908-3-wei.fang@nxp.com \
--to=wei.fang@nxp.com \
--cc=andrew+netdev@lunn.ch \
--cc=christophe.leroy@csgroup.eu \
--cc=claudiu.manoil@nxp.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=imx@lists.linux.dev \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=vladimir.oltean@nxp.com \
--cc=xiaoning.wang@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).