[rtems-libbsd commit] dpaa: Add "libbsd, dedicated-portal" to QMan portals

Sebastian Huber sebh at rtems.org
Mon Oct 23 07:27:51 UTC 2017


Module:    rtems-libbsd
Branch:    master
Commit:    de5791b34591b88911c350d835d8b45d274cc852
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=de5791b34591b88911c350d835d8b45d274cc852

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Jul 13 08:31:46 2017 +0200

dpaa: Add "libbsd,dedicated-portal" to QMan portals

By default, the network interfaces use a pool channel, see
dpaa_get_channel() in dpaa_eth_priv_probe().  To enable a dedicated QMan
software portal, use libbsd,dedicated-portal = "enabled";.  This option
is useful for special purpose 10Gbit/s Ethernet processing.

/ {
        soc: soc at ffe000000 {
                fman0: fman at 400000 {
                        enet7: ethernet at f2000 {
                                libbsd,dedicated-portal = "enabled";
                        };
                };
        };
};

---

 .../drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 14 +++++++
 linux/drivers/net/ethernet/freescale/fman/mac.c    | 13 +++++++
 linux/drivers/net/ethernet/freescale/fman/mac.h    |  2 +
 linux/drivers/soc/fsl/qbman/qman.c                 | 43 ++++++++++++++++++++++
 linux/drivers/soc/fsl/qbman/qman_portal.c          | 28 ++++++++++++++
 linux/drivers/soc/fsl/qbman/qman_priv.h            |  6 +++
 linux/include/soc/fsl/qman.h                       |  7 ++++
 rtemsbsd/powerpc/include/soc/fsl/dpaa.h            |  2 +
 .../net/ethernet/freescale/dpaa/if_fmanmac.c       |  9 +++++
 9 files changed, 124 insertions(+)

diff --git a/linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index c2e9b37..3861420 100644
--- a/linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/linux/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -3078,6 +3078,17 @@ dpaa_eth_priv_probe(struct platform_device *pdev, struct mac_device *mac_dev)
 
 	priv->mac_dev = mac_dev;
 
+#ifdef __rtems__
+	if (mac_dev->use_dedicated_portal) {
+		struct qman_portal *portal;
+
+		portal = qman_get_dedicated_portal(0);
+		BSD_ASSERT(portal != NULL);
+		mac_dev->portal = portal;
+		channel = qman_portal_get_channel(portal);
+		priv->channel = (u16)channel;
+	} else {
+#endif /* __rtems__ */
 	channel = dpaa_get_channel();
 	if (channel < 0) {
 		dev_err(dev, "dpaa_get_channel() failed\n");
@@ -3091,6 +3102,9 @@ dpaa_eth_priv_probe(struct platform_device *pdev, struct mac_device *mac_dev)
 	 * and add this pool channel to each's dequeue mask.
 	 */
 	dpaa_eth_add_channel(priv->channel);
+#ifdef __rtems__
+	}
+#endif /* __rtems__ */
 
 	dpaa_fq_setup(priv, &dpaa_fq_cbs, priv->mac_dev->port[TX]);
 
diff --git a/linux/drivers/net/ethernet/freescale/fman/mac.c b/linux/drivers/net/ethernet/freescale/fman/mac.c
index b058b4a..e34158e 100644
--- a/linux/drivers/net/ethernet/freescale/fman/mac.c
+++ b/linux/drivers/net/ethernet/freescale/fman/mac.c
@@ -748,6 +748,16 @@ MODULE_DEVICE_TABLE(of, mac_match);
 #ifndef __rtems__
 static int mac_probe(struct platform_device *_of_dev)
 #else /* __rtems__ */
+static bool
+use_dedicated_portal(const struct device_node *mac_node)
+{
+	const char *dp;
+	int len;
+
+	dp = of_get_property(mac_node, "libbsd,dedicated-portal", &len);
+	return (len > 0 && strcmp(dp, "enabled") == 0);
+}
+
 static int mac_probe(device_t _dev, struct platform_device *_of_dev, struct fman *fman)
 #endif /* __rtems__ */
 {
@@ -1096,6 +1106,9 @@ static int mac_probe(device_t _dev, struct platform_device *_of_dev, struct fman
 		 mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
 		 mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
 
+#ifdef __rtems__
+	mac_dev->use_dedicated_portal = use_dedicated_portal(mac_node);
+#endif /* __rtems__ */
 	priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev, mac_node);
 	if (IS_ERR(priv->eth_dev)) {
 		dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
diff --git a/linux/drivers/net/ethernet/freescale/fman/mac.h b/linux/drivers/net/ethernet/freescale/fman/mac.h
index 066072a..ba1fcbc 100644
--- a/linux/drivers/net/ethernet/freescale/fman/mac.h
+++ b/linux/drivers/net/ethernet/freescale/fman/mac.h
@@ -85,6 +85,8 @@ struct mac_device {
 	struct phy_device *(*init_phy)(struct net_device *net_dev,
 				       struct mac_device *mac_dev);
 #else /* __rtems__ */
+	bool use_dedicated_portal;
+	struct qman_portal *portal;
 	void (*adjust_link)(struct mac_device *mac_dev, u16 speed);
 #endif /* __rtems__ */
 	int (*init)(struct mac_device *mac_dev);
diff --git a/linux/drivers/soc/fsl/qbman/qman.c b/linux/drivers/soc/fsl/qbman/qman.c
index acb3a1d..73e1f09 100644
--- a/linux/drivers/soc/fsl/qbman/qman.c
+++ b/linux/drivers/soc/fsl/qbman/qman.c
@@ -1281,6 +1281,49 @@ fail_dqrr:
 fail_eqcr:
 	return -EIO;
 }
+#ifdef __rtems__
+int
+qman_portal_get_channel(const struct qman_portal *portal)
+{
+
+	if (portal == NULL) {
+		return (-1);
+	}
+
+	return (portal->config->channel);
+}
+
+int
+qman_portal_get_irq(const struct qman_portal *portal)
+{
+
+	if (portal == NULL) {
+		return (-1);
+	}
+
+	return (portal->config->irq);
+}
+
+struct qman_portal *
+qman_create_dedicated_portal(const struct qm_portal_config *c,
+    const struct qman_cgrs *cgrs)
+{
+	struct qman_portal *portal;
+	int err;
+
+	portal = kmalloc(sizeof(*portal), GFP_KERNEL);
+	if (portal == NULL)
+		return (NULL);
+
+	err = qman_create_portal(portal, c, cgrs);
+	if (err != 0) {
+		kfree(portal);
+		return (NULL);
+	}
+
+	return (portal);
+}
+#endif /* __rtems__ */
 
 struct qman_portal *qman_create_affine_portal(const struct qm_portal_config *c,
 					      const struct qman_cgrs *cgrs)
diff --git a/linux/drivers/soc/fsl/qbman/qman_portal.c b/linux/drivers/soc/fsl/qbman/qman_portal.c
index 45aba3a..b4dd1cd 100644
--- a/linux/drivers/soc/fsl/qbman/qman_portal.c
+++ b/linux/drivers/soc/fsl/qbman/qman_portal.c
@@ -385,6 +385,33 @@ module_driver(qman_portal_driver,
 
 static struct qm_portal_config qman_configs[MAX_QMAN_PORTALS];
 
+static LIST_HEAD(qman_free_portals);
+
+struct qman_portal *
+qman_get_dedicated_portal(int cpu)
+{
+	struct qm_portal_config *pcfg;
+	struct qman_portal *p;
+	u32 irq_sources;
+
+	if (list_empty(&qman_free_portals))
+		return (NULL);
+
+	pcfg = list_first_entry(&qman_free_portals, struct qm_portal_config,
+	   node);
+	pcfg->cpu = cpu;
+	p = qman_create_dedicated_portal(pcfg, NULL);
+	if (p == NULL)
+		return (NULL);
+
+	list_del(&pcfg->node);
+
+	irq_sources = QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI | QM_PIRQ_CSCI
+	    | QM_PIRQ_DQRI;
+	qman_p_irqsource_add(p, irq_sources);
+	return (p);
+}
+
 static bool
 is_dequeue_enabled(const struct device_node *dn)
 {
@@ -475,6 +502,7 @@ qman_sysinit_portals(void)
 			qman_portal_update_sdest(pcfg, val);
 		} else {
 			pcfg->cpu = -1;
+			list_add_tail(&pcfg->node, &qman_free_portals);
 		}
 
 		node = fdt_next_subnode(fdt, node);
diff --git a/linux/drivers/soc/fsl/qbman/qman_priv.h b/linux/drivers/soc/fsl/qbman/qman_priv.h
index 369ba75..2db1088 100644
--- a/linux/drivers/soc/fsl/qbman/qman_priv.h
+++ b/linux/drivers/soc/fsl/qbman/qman_priv.h
@@ -165,6 +165,8 @@ struct qm_portal_config {
 	struct iommu_domain *iommu_domain;
 	/* Allow these to be joined in lists */
 	struct list_head list;
+#else /* __rtems__ */
+	struct list_head node;
 #endif /* __rtems__ */
 	/* User-visible portal configuration settings */
 	/* portal is affined to this cpu */
@@ -201,6 +203,10 @@ int qman_wq_alloc(void);
 void qman_liodn_fixup(u16 channel);
 void qman_set_sdest(u16 channel, unsigned int cpu_idx);
 
+#ifdef __rtems__
+struct qman_portal *qman_create_dedicated_portal(
+    const struct qm_portal_config *c, const struct qman_cgrs *cgrs);
+#endif /* __rtems__ */
 struct qman_portal *qman_create_affine_portal(
 			const struct qm_portal_config *config,
 			const struct qman_cgrs *cgrs);
diff --git a/linux/include/soc/fsl/qman.h b/linux/include/soc/fsl/qman.h
index 2504eef..be4839b 100644
--- a/linux/include/soc/fsl/qman.h
+++ b/linux/include/soc/fsl/qman.h
@@ -918,6 +918,13 @@ u16 qman_affine_channel(int cpu);
  * @cpu: the cpu whose affine portal is the subject of the query
  */
 struct qman_portal *qman_get_affine_portal(int cpu);
+#ifdef __rtems__
+struct qman_portal *qman_get_dedicated_portal(int cpu);
+
+int qman_portal_get_channel(const struct qman_portal *portal);
+
+int qman_portal_get_irq(const struct qman_portal *portal);
+#endif /* __rtems__ */
 
 /**
  * qman_p_poll_dqrr - process DQRR (fast-path) entries
diff --git a/rtemsbsd/powerpc/include/soc/fsl/dpaa.h b/rtemsbsd/powerpc/include/soc/fsl/dpaa.h
index 1e9a676..9046bc7 100644
--- a/rtemsbsd/powerpc/include/soc/fsl/dpaa.h
+++ b/rtemsbsd/powerpc/include/soc/fsl/dpaa.h
@@ -40,6 +40,8 @@ struct mbuf;
 
 struct dpaa_priv *dpaa_get_priv_of_ifp(struct ifnet *);
 
+int dpaa_get_qman_portal_irq_of_ifp(struct ifnet *);
+
 typedef struct {
 	size_t count;
 	struct bm_buffer bmb[8];
diff --git a/rtemsbsd/sys/powerpc/drivers/net/ethernet/freescale/dpaa/if_fmanmac.c b/rtemsbsd/sys/powerpc/drivers/net/ethernet/freescale/dpaa/if_fmanmac.c
index c71a73c..640ca50 100644
--- a/rtemsbsd/sys/powerpc/drivers/net/ethernet/freescale/dpaa/if_fmanmac.c
+++ b/rtemsbsd/sys/powerpc/drivers/net/ethernet/freescale/dpaa/if_fmanmac.c
@@ -590,3 +590,12 @@ dpaa_get_priv_of_ifp(struct ifnet *ifp)
 	sc = ifp->if_softc;
 	return (netdev_priv(&sc->mac_dev.net_dev));
 }
+
+int
+dpaa_get_qman_portal_irq_of_ifp(struct ifnet *ifp)
+{
+	struct fman_mac_softc *sc;
+
+	sc = ifp->if_softc;
+	return (qman_portal_get_irq(sc->mac_dev.portal));
+}



More information about the vc mailing list