RE: [PATCH net-next] net: freescale: Remove unused declarations

2023-08-18 Thread Madalin Bucur
> -Original Message-
> From: Yue Haibing 
> Sent: 17 August 2023 16:42
> To: Madalin Bucur ; Sean Anderson
> ; da...@davemloft.net; eduma...@google.com;
> k...@kernel.org; pab...@redhat.com; pantelis.anton...@gmail.com; Camelia
> Alexandra Groza ; christophe.le...@csgroup.eu;
> yuehaib...@huawei.com
> Cc: net...@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
> Subject: [PATCH net-next] net: freescale: Remove unused declarations
> 
> Commit 5d93cfcf7360 ("net: dpaa: Convert to phylink") removed
> fman_set_mac_active_pause()/fman_get_pause_cfg() but not declarations.
> Commit 48257c4f168e ("Add fs_enet ethernet network driver, for several
> embedded platforms.") declared but never implemented
> fs_enet_platform_init() and fs_enet_platform_cleanup().
> 
> Signed-off-by: Yue Haibing 
> ---
>  drivers/net/ethernet/freescale/fman/mac.h| 4 
>  drivers/net/ethernet/freescale/fs_enet/fs_enet.h | 5 -
>  2 files changed, 9 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fman/mac.h
> b/drivers/net/ethernet/freescale/fman/mac.h
> index ad06f8d7924b..fe747915cc73 100644
> --- a/drivers/net/ethernet/freescale/fman/mac.h
> +++ b/drivers/net/ethernet/freescale/fman/mac.h
> @@ -68,10 +68,6 @@ struct dpaa_eth_data {
> 
>  extern const char*mac_driver_description;
> 
> -int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool
> tx);
> -
> -void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
> - bool *tx_pause);
>  int fman_set_multi(struct net_device *net_dev, struct mac_device
> *mac_dev);
> 
>  #endif   /* __MAC_H */
> diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
> b/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
> index d371072fff60..759bb7080e22 100644
> --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
> +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
> @@ -208,11 +208,6 @@ void fs_cleanup_bds(struct net_device *dev);
>  #define DRV_MODULE_NAME  "fs_enet"
>  #define PFX DRV_MODULE_NAME  ": "
> 
> -
> /
> ***/
> -
> -int fs_enet_platform_init(void);
> -void fs_enet_platform_cleanup(void);
> -
> 
> /
> ***/
>  /* buffer descriptor access macros */
> 
> --
> 2.34.1

Acked-by: Madalin Bucur 


RE: [PATCH net-next 0/9] net: freescale: Convert to platform remove callback returning void

2023-03-13 Thread Madalin Bucur
> -Original Message-
> From: Uwe Kleine-König 
> Sent: 13 March 2023 12:37
> To: Madalin Bucur ; David S. Miller
> ; Eric Dumazet ; Jakub Kicinski
> ; Paolo Abeni ; Russell King
> ; Wei Fang ; Wolfram Sang
> ; Chris Packham ; Andy
> Shevchenko ; Damien Le Moal
> ; Christophe Leroy
> ; Michael Ellerman ;
> Mark Brown ; Marc Kleine-Budde ;
> Pantelis Antoniou ; Claudiu Manoil
> ; Leo Li 
> Cc: net...@vger.kernel.org; ker...@pengutronix.de; Shenwei Wang
> ; Clark Wang ; dl-linux-imx
> ; linuxppc-dev@lists.ozlabs.org
> Subject: [PATCH net-next 0/9] net: freescale: Convert to platform remove
> callback returning void
> 
> Hello,
> 
> this patch set converts the platform drivers below
> drivers/net/ethernet/freescale to the .remove_new() callback. Compared to
> the
> traditional .remove() this one returns void. This is a good thing because
> the
> driver core (mostly) ignores the return value and still removes the
> device
> binding. This is part of a bigger effort to convert all 2000+ platform
> drivers to this new callback to eventually change .remove() itself to
> return void.
> 
> The first two patches here are preparation, the following patches
> actually convert the drivers.
> 
> Best regards
> Uwe
> 
> Uwe Kleine-König (9):
>   net: dpaa: Improve error reporting
>   net: fec: Don't return early on error in .remove()
>   net: dpaa: Convert to platform remove callback returning void
>   net: fec: Convert to platform remove callback returning void
>   net: fman: Convert to platform remove callback returning void
>   net: fs_enet: Convert to platform remove callback returning void
>   net: fsl_pq_mdio: Convert to platform remove callback returning void
>   net: gianfar: Convert to platform remove callback returning void
>   net: ucc_geth: Convert to platform remove callback returning void
> 
>  drivers/net/ethernet/freescale/dpaa/dpaa_eth.c|  8 
>  drivers/net/ethernet/freescale/fec_main.c | 11 ---
>  drivers/net/ethernet/freescale/fec_mpc52xx.c  |  6 ++
>  drivers/net/ethernet/freescale/fec_mpc52xx_phy.c  |  6 ++
>  drivers/net/ethernet/freescale/fman/mac.c |  5 ++---
>  drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c |  5 ++---
>  drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c  |  6 ++
>  drivers/net/ethernet/freescale/fs_enet/mii-fec.c  |  6 ++
>  drivers/net/ethernet/freescale/fsl_pq_mdio.c  |  6 ++
>  drivers/net/ethernet/freescale/gianfar.c  |  6 ++
>  drivers/net/ethernet/freescale/ucc_geth.c |  6 ++----
>  11 files changed, 26 insertions(+), 45 deletions(-)
> 
> base-commit: fe15c26ee26efa11741a7b632e9f23b01aca4cc6
> --
> 2.39.1

For the FMan and DPAA drivers,

Acked-by: Madalin Bucur 


RE: [PATCH devicetree 3/4] powerpc: dts: t1040rdb: put SGMII PHY under label

2020-07-22 Thread Madalin Bucur (OSS)
> -Original Message-
> From: Vladimir Oltean 
> Sent: Wednesday, July 22, 2020 8:24 PM
> To: robh...@kernel.org; shawn...@kernel.org; m...@ellerman.id.au;
> devicet...@vger.kernel.org
> Cc: b...@kernel.crashing.org; pau...@samba.org; linuxppc-
> d...@lists.ozlabs.org; linux-ker...@vger.kernel.org;
> net...@vger.kernel.org; Madalin Bucur (OSS) ;
> Radu-andrei Bulie ; fido_...@inbox.ru
> Subject: [PATCH devicetree 3/4] powerpc: dts: t1040rdb: put SGMII PHY
> under  label
> 
> We're going to add 8 more PHYs in a future patch. It is easier to follow
> the hardware description if we don't need to fish for the path of the
> MDIO controllers inside the SoC and just use the labels.
> 

Please align to the existing structure, it may be easier to add something
without paying attention to that but it's better to keep things organized.
This structure is used across all the device trees of the platforms using
DPAA, let's not start diverging now.

> Signed-off-by: Vladimir Oltean 
> ---
>  arch/powerpc/boot/dts/fsl/t1040rdb.dts | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts
> b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
> index 65ff34c49025..40d7126dbe90 100644
> --- a/arch/powerpc/boot/dts/fsl/t1040rdb.dts
> +++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts
> @@ -59,12 +59,6 @@ ethernet@e4000 {
>   phy-handle = <_sgmii_2>;
>   phy-connection-type = "sgmii";
>   };
> -
> - mdio@fc000 {
> - phy_sgmii_2: ethernet-phy@3 {
> - reg = <0x03>;
> - };
> - };
>   };
>   };
> 
> @@ -76,3 +70,9 @@ cpld@3,0 {
>  };
> 
>  #include "t1040si-post.dtsi"
> +
> + {
> + phy_sgmii_2: ethernet-phy@3 {
> + reg = <0x3>;
> + };
> +};
> --
> 2.25.1



RE: FSL P5020/P5040: DPAA Ethernet issue with the latest Git kernel

2020-07-08 Thread Madalin Bucur (OSS)
> From: Christian Zigotzky  
> Sent: Tuesday, July 7, 2020 9:26 PM
> To: Madalin Bucur (OSS) 
> Cc: mad skateman ; Camelia Alexandra Groza 
> ;
> linuxppc-...@ozlabs.org; net...@vger.kernel.org; R.T.Dickinson 
> ;
> Darren Stevens 
> Subject: Re: FSL P5020/P5040: DPAA Ethernet issue with the latest Git kernel
>
>
> On 7. Jul 2020, at 17:53, Madalin Bucur (OSS) 
> <mailto:madalin.bu...@oss.nxp.com> wrote:
> Was DPAA functional before commit A?
> How about after commit A and before commit B?

> The DPAA Ethernet works from  the kernel 5.6-rc4 [1] till the Git kernel from 
> the
> 11 of June [2]. It doesn’t work since the commit “fix bitmap_parse” [3].

> [1] https://forum.hyperion-entertainment.com/viewtopic.php?p=49936#p49936
> [2] https://forum.hyperion-entertainment.com/viewtopic.php?p=50848#p50848
> [3] https://forum.hyperion-entertainment.com/viewtopic.php?p=50980#p50980

Hi,

can you please try to disable the network manager (see [1]), then boot with
the latest kernel, that does not work, and setup the interfaces manually?

Madalin

[1] 
https://help.ubuntu.com/community/NetworkManager#Stopping_and_Disabling_NetworkManager



RE: [PATCH net-next 00/23] Clean driver, module and FW versions

2020-03-02 Thread Madalin Bucur (OSS)
> -Original Message-
> From: David Miller 
> Sent: Monday, March 2, 2020 5:02 AM
> To: l...@kernel.org
> Subject: Re: [PATCH net-next 00/23] Clean driver, module and FW versions
> 
> From: Leon Romanovsky 
> Date: Sun,  1 Mar 2020 16:44:33 +0200
> 
> > This is second batch of the series which removes various static
> > versions in favour of globaly defined Linux kernel version.
> 
> This generally looks fine to me but I'll let it sit for a few days so
> that others can review.

Reviewed drivers/net/ethernet/freescale changes, thank you!

Reviewed-by: Madalin Bucur 


[PATCH] soc: fsl: qbman: avoid race in clearing QMan interrupt

2018-12-21 Thread Madalin Bucur
By clearing all interrupt sources, not only those that
already occurred, the existing code may acknowledge by
mistake interrupts that occurred after the code checks
for them.

Signed-off-by: Madalin Bucur 
Signed-off-by: Roy Pledge 
---
 drivers/soc/fsl/qbman/qman.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 52c153cd795a..636f83f781f5 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1143,18 +1143,19 @@ static void qm_mr_process_task(struct work_struct 
*work);
 static irqreturn_t portal_isr(int irq, void *ptr)
 {
struct qman_portal *p = ptr;
-
-   u32 clear = QM_DQAVAIL_MASK | p->irq_sources;
u32 is = qm_in(>p, QM_REG_ISR) & p->irq_sources;
+   u32 clear = 0;
 
if (unlikely(!is))
return IRQ_NONE;
 
/* DQRR-handling if it's interrupt-driven */
-   if (is & QM_PIRQ_DQRI)
+   if (is & QM_PIRQ_DQRI) {
__poll_portal_fast(p, QMAN_POLL_LIMIT);
+   clear = QM_DQAVAIL_MASK | QM_PIRQ_DQRI;
+   }
/* Handling of anything else that's interrupt-driven */
-   clear |= __poll_portal_slow(p, is);
+   clear |= __poll_portal_slow(p, is) & QM_PIRQ_SLOW;
qm_out(>p, QM_REG_ISR, clear);
return IRQ_HANDLED;
 }
-- 
2.1.0



[PATCH v3 3/3] dpaa_eth: add ethtool coalesce control

2018-11-21 Thread Madalin Bucur
Allow ethtool control of the DPAA QMan portal interrupt coalescing
settings.

Signed-off-by: Madalin Bucur 
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 71 ++
 1 file changed, 71 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 13d6e2272ece..62497119c85f 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -529,6 +529,75 @@ static int dpaa_get_ts_info(struct net_device *net_dev,
return 0;
 }
 
+static int dpaa_get_coalesce(struct net_device *dev,
+struct ethtool_coalesce *c)
+{
+   struct qman_portal *portal;
+   u32 period;
+   u8 thresh;
+
+   portal = qman_get_affine_portal(smp_processor_id());
+   qman_portal_get_iperiod(portal, );
+   qman_dqrr_get_ithresh(portal, );
+
+   c->rx_coalesce_usecs = period;
+   c->rx_max_coalesced_frames = thresh;
+   c->use_adaptive_rx_coalesce = false;
+
+   return 0;
+}
+
+static int dpaa_set_coalesce(struct net_device *dev,
+struct ethtool_coalesce *c)
+{
+   const cpumask_t *cpus = qman_affine_cpus();
+   bool needs_revert[NR_CPUS] = {false};
+   struct qman_portal *portal;
+   u32 period, prev_period;
+   u8 thresh, prev_thresh;
+   int cpu, res;
+
+   if (c->use_adaptive_rx_coalesce)
+   return -EINVAL;
+
+   period = c->rx_coalesce_usecs;
+   thresh = c->rx_max_coalesced_frames;
+
+   /* save previous values */
+   portal = qman_get_affine_portal(smp_processor_id());
+   qman_portal_get_iperiod(portal, _period);
+   qman_dqrr_get_ithresh(portal, _thresh);
+
+   /* set new values */
+   for_each_cpu(cpu, cpus) {
+   portal = qman_get_affine_portal(cpu);
+   res = qman_portal_set_iperiod(portal, period);
+   if (res)
+   goto revert_values;
+   res = qman_dqrr_set_ithresh(portal, thresh);
+   if (res) {
+   qman_portal_set_iperiod(portal, prev_period);
+   goto revert_values;
+   }
+   needs_revert[cpu] = true;
+   }
+
+   return 0;
+
+revert_values:
+   /* restore previous values */
+   for_each_cpu(cpu, cpus) {
+   if (!needs_revert[cpu])
+   continue;
+   portal = qman_get_affine_portal(cpu);
+   /* previous values will not fail, ignore return value */
+   qman_portal_set_iperiod(portal, prev_period);
+   qman_dqrr_set_ithresh(portal, prev_thresh);
+   }
+
+   return res;
+}
+
 const struct ethtool_ops dpaa_ethtool_ops = {
.get_drvinfo = dpaa_get_drvinfo,
.get_msglevel = dpaa_get_msglevel,
@@ -545,4 +614,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
.get_rxnfc = dpaa_get_rxnfc,
.set_rxnfc = dpaa_set_rxnfc,
.get_ts_info = dpaa_get_ts_info,
+   .get_coalesce = dpaa_get_coalesce,
+   .set_coalesce = dpaa_set_coalesce,
 };
-- 
2.1.0



[PATCH v3 2/3] soc/qman: add return value to interrupt coalesce changing APIs

2018-11-21 Thread Madalin Bucur
Check that the values received by the portal interrupt coalesce
change APIs are in range.

Signed-off-by: Madalin Bucur 
Signed-off-by: Roy Pledge 
---
 drivers/soc/fsl/qbman/qman.c | 33 ++---
 include/soc/fsl/qman.h   |  8 ++--
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index ce7c03052e33..52c153cd795a 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -36,6 +36,8 @@
 #define MAX_IRQNAME16  /* big enough for "QMan portal %d" */
 #define QMAN_POLL_LIMIT 32
 #define QMAN_PIRQ_DQRR_ITHRESH 12
+#define QMAN_DQRR_IT_MAX 15
+#define QMAN_ITP_MAX 0xFFF
 #define QMAN_PIRQ_MR_ITHRESH 4
 #define QMAN_PIRQ_IPERIOD 100
 
@@ -727,9 +729,15 @@ static inline void qm_dqrr_vdqcr_set(struct qm_portal 
*portal, u32 vdqcr)
qm_out(portal, QM_REG_DQRR_VDQCR, vdqcr);
 }
 
-static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
+static inline int qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
 {
+
+   if (ithresh > QMAN_DQRR_IT_MAX)
+   return -EINVAL;
+
qm_out(portal, QM_REG_DQRR_ITR, ithresh);
+
+   return 0;
 }
 
 /* --- MR API --- */
@@ -1012,13 +1020,20 @@ static inline void put_affine_portal(void)
 
 static struct workqueue_struct *qm_portal_wq;
 
-void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
+int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
 {
+   int res;
+
if (!portal)
-   return;
+   return -EINVAL;
+
+   res = qm_dqrr_set_ithresh(>p, ithresh);
+   if (res)
+   return res;
 
-   qm_dqrr_set_ithresh(>p, ithresh);
portal->p.dqrr.ithresh = ithresh;
+
+   return 0;
 }
 EXPORT_SYMBOL(qman_dqrr_set_ithresh);
 
@@ -1036,10 +1051,14 @@ void qman_portal_get_iperiod(struct qman_portal 
*portal, u32 *iperiod)
 }
 EXPORT_SYMBOL(qman_portal_get_iperiod);
 
-void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
+int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
 {
-   if (portal)
-   qm_out(>p, QM_REG_ITPR, iperiod);
+   if (!portal || iperiod > QMAN_ITP_MAX)
+   return -EINVAL;
+
+   qm_out(>p, QM_REG_ITPR, iperiod);
+
+   return 0;
 }
 EXPORT_SYMBOL(qman_portal_set_iperiod);
 
diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
index 56877660d5ba..5cc7af06c1ba 100644
--- a/include/soc/fsl/qman.h
+++ b/include/soc/fsl/qman.h
@@ -1205,8 +1205,10 @@ void qman_dqrr_get_ithresh(struct qman_portal *portal, 
u8 *ithresh);
  * qman_dqrr_set_ithresh - Set coalesce interrupt threshold
  * @portal: portal to set the new value on
  * @ithresh: new threshold value
+ *
+ * Returns 0 on success, or a negative error code.
  */
-void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
+int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
 
 /**
  * qman_dqrr_get_iperiod - Get coalesce interrupt period
@@ -1219,7 +1221,9 @@ void qman_portal_get_iperiod(struct qman_portal *portal, 
u32 *iperiod);
  * qman_dqrr_set_iperiod - Set coalesce interrupt period
  * @portal: portal to set the new value on
  * @ithresh: new period value
+ *
+ * Returns 0 on success, or a negative error code.
  */
-void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
+int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
 
 #endif /* __FSL_QMAN_H */
-- 
2.1.0



[PATCH v3 0/3] dpaa_eth: add ethtool coalesce control

2018-11-21 Thread Madalin Bucur
Add control of the DPAA portal interrupt coalescing settings from
ethtool.

changes from v2: read ithresh from HW, set previous values on failure
changes from v1: added range checking for the QMan APIs

Madalin Bucur (3):
  soc: fsl: qbman: read ithresh from HW
  soc/qman: add return value to interrupt coalesce changing APIs
  dpaa_eth: add ethtool coalesce control

 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 71 ++
 drivers/soc/fsl/qbman/qman.c   | 35 ---
 include/soc/fsl/qman.h |  8 ++-
 3 files changed, 104 insertions(+), 10 deletions(-)

-- 
2.1.0



[PATCH v3 1/3] soc: fsl: qbman: read ithresh from HW

2018-11-21 Thread Madalin Bucur
Read the DQRR interrupt threshold directly from the hardware.

Signed-off-by: Madalin Bucur 
Signed-off-by: Roy Pledge 
---
 drivers/soc/fsl/qbman/qman.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 5ce24718c2fd..ce7c03052e33 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1025,7 +1025,7 @@ EXPORT_SYMBOL(qman_dqrr_set_ithresh);
 void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh)
 {
if (portal && ithresh)
-   *ithresh = portal->p.dqrr.ithresh;
+   *ithresh = qm_in(>p, QM_REG_DQRR_ITR);
 }
 EXPORT_SYMBOL(qman_dqrr_get_ithresh);
 
-- 
2.1.0



[PATCH v2 2/2] dpaa_eth: add ethtool coalesce control

2018-11-13 Thread Madalin Bucur
Allow ethtool control of the DPAA QMan portal interrupt coalescing
settings.

Signed-off-by: Madalin Bucur 
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 49 ++
 1 file changed, 49 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 13d6e2272ece..4df366b05976 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -529,6 +529,53 @@ static int dpaa_get_ts_info(struct net_device *net_dev,
return 0;
 }
 
+static int dpaa_get_coalesce(struct net_device *dev,
+struct ethtool_coalesce *c)
+{
+   struct qman_portal *portal;
+   u32 period;
+   u8 thresh;
+
+   portal = qman_get_affine_portal(smp_processor_id());
+   qman_portal_get_iperiod(portal, );
+   qman_dqrr_get_ithresh(portal, );
+
+   c->rx_coalesce_usecs = period;
+   c->rx_max_coalesced_frames = thresh;
+   c->use_adaptive_rx_coalesce = false;
+
+   return 0;
+}
+
+static int dpaa_set_coalesce(struct net_device *dev,
+struct ethtool_coalesce *c)
+{
+   const cpumask_t *cpus = qman_affine_cpus();
+   struct qman_portal *portal;
+   u32 period;
+   u8 thresh;
+   int cpu;
+   int res;
+
+   if (c->use_adaptive_rx_coalesce)
+   return -EINVAL;
+
+   period = c->rx_coalesce_usecs;
+   thresh = c->rx_max_coalesced_frames;
+
+   for_each_cpu(cpu, cpus) {
+   portal = qman_get_affine_portal(cpu);
+   res = qman_portal_set_iperiod(portal, period);
+   if (res)
+   return res;
+   res = qman_dqrr_set_ithresh(portal, thresh);
+   if (res)
+   return res;
+   }
+
+   return 0;
+}
+
 const struct ethtool_ops dpaa_ethtool_ops = {
.get_drvinfo = dpaa_get_drvinfo,
.get_msglevel = dpaa_get_msglevel,
@@ -545,4 +592,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
.get_rxnfc = dpaa_get_rxnfc,
.set_rxnfc = dpaa_set_rxnfc,
.get_ts_info = dpaa_get_ts_info,
+   .get_coalesce = dpaa_get_coalesce,
+   .set_coalesce = dpaa_set_coalesce,
 };
-- 
2.1.0



[PATCH v2 1/2] soc/qman: add return value to interrupt coalesce changing APIs

2018-11-13 Thread Madalin Bucur
Check that the values received by the portal interrupt coalesce
change APIs are in range.

Signed-off-by: Madalin Bucur 
Signed-off-by: Roy Pledge 
---
 drivers/soc/fsl/qbman/qman.c | 33 ++---
 include/soc/fsl/qman.h   |  8 ++--
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 5ce24718c2fd..5b9de224193c 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -36,6 +36,8 @@
 #define MAX_IRQNAME16  /* big enough for "QMan portal %d" */
 #define QMAN_POLL_LIMIT 32
 #define QMAN_PIRQ_DQRR_ITHRESH 12
+#define QMAN_DQRR_IT_MAX 15
+#define QMAN_ITP_MAX 0xFFF
 #define QMAN_PIRQ_MR_ITHRESH 4
 #define QMAN_PIRQ_IPERIOD 100
 
@@ -727,9 +729,15 @@ static inline void qm_dqrr_vdqcr_set(struct qm_portal 
*portal, u32 vdqcr)
qm_out(portal, QM_REG_DQRR_VDQCR, vdqcr);
 }
 
-static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
+static inline int qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
 {
+
+   if (ithresh > QMAN_DQRR_IT_MAX)
+   return -EINVAL;
+
qm_out(portal, QM_REG_DQRR_ITR, ithresh);
+
+   return 0;
 }
 
 /* --- MR API --- */
@@ -1012,13 +1020,20 @@ static inline void put_affine_portal(void)
 
 static struct workqueue_struct *qm_portal_wq;
 
-void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
+int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
 {
+   int res;
+
if (!portal)
-   return;
+   return -EINVAL;
+
+   res = qm_dqrr_set_ithresh(>p, ithresh);
+   if (res)
+   return res;
 
-   qm_dqrr_set_ithresh(>p, ithresh);
portal->p.dqrr.ithresh = ithresh;
+
+   return 0;
 }
 EXPORT_SYMBOL(qman_dqrr_set_ithresh);
 
@@ -1036,10 +1051,14 @@ void qman_portal_get_iperiod(struct qman_portal 
*portal, u32 *iperiod)
 }
 EXPORT_SYMBOL(qman_portal_get_iperiod);
 
-void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
+int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
 {
-   if (portal)
-   qm_out(>p, QM_REG_ITPR, iperiod);
+   if (!portal || iperiod > QMAN_ITP_MAX)
+   return -EINVAL;
+
+   qm_out(>p, QM_REG_ITPR, iperiod);
+
+   return 0;
 }
 EXPORT_SYMBOL(qman_portal_set_iperiod);
 
diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
index 56877660d5ba..5cc7af06c1ba 100644
--- a/include/soc/fsl/qman.h
+++ b/include/soc/fsl/qman.h
@@ -1205,8 +1205,10 @@ void qman_dqrr_get_ithresh(struct qman_portal *portal, 
u8 *ithresh);
  * qman_dqrr_set_ithresh - Set coalesce interrupt threshold
  * @portal: portal to set the new value on
  * @ithresh: new threshold value
+ *
+ * Returns 0 on success, or a negative error code.
  */
-void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
+int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
 
 /**
  * qman_dqrr_get_iperiod - Get coalesce interrupt period
@@ -1219,7 +1221,9 @@ void qman_portal_get_iperiod(struct qman_portal *portal, 
u32 *iperiod);
  * qman_dqrr_set_iperiod - Set coalesce interrupt period
  * @portal: portal to set the new value on
  * @ithresh: new period value
+ *
+ * Returns 0 on success, or a negative error code.
  */
-void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
+int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
 
 #endif /* __FSL_QMAN_H */
-- 
2.1.0



[PATCH v2 0/2] dpaa_eth: add ethtool coalesce control

2018-11-13 Thread Madalin Bucur
Add control of the DPAA portal interrupt coalescing settings from
ethtool.

changes from v1: added range checking for the QMan APIs

Madalin Bucur (2):
  soc/qman: add return value to interrupt coalesce changing APIs
  dpaa_eth: add ethtool coalesce control

 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 49 ++
 drivers/soc/fsl/qbman/qman.c   | 33 +++
 include/soc/fsl/qman.h |  8 +++-
 3 files changed, 81 insertions(+), 9 deletions(-)

-- 
2.1.0



[PATCH v2 5/5] soc/fsl_qbman: export coalesce change API

2018-09-28 Thread Madalin Bucur
Export the API required to control the QMan portal interrupt coalescing
settings.

Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/qman.c | 31 +++
 include/soc/fsl/qman.h   | 27 +++
 2 files changed, 58 insertions(+)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 99d0f87889b8..8ab75bb44c4d 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1012,6 +1012,37 @@ static inline void put_affine_portal(void)
 
 static struct workqueue_struct *qm_portal_wq;
 
+void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
+{
+   if (!portal)
+   return;
+
+   qm_dqrr_set_ithresh(>p, ithresh);
+   portal->p.dqrr.ithresh = ithresh;
+}
+EXPORT_SYMBOL(qman_dqrr_set_ithresh);
+
+void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh)
+{
+   if (portal && ithresh)
+   *ithresh = portal->p.dqrr.ithresh;
+}
+EXPORT_SYMBOL(qman_dqrr_get_ithresh);
+
+void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod)
+{
+   if (portal && iperiod)
+   *iperiod = qm_in(>p, QM_REG_ITPR);
+}
+EXPORT_SYMBOL(qman_portal_get_iperiod);
+
+void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
+{
+   if (portal)
+   qm_out(>p, QM_REG_ITPR, iperiod);
+}
+EXPORT_SYMBOL(qman_portal_set_iperiod);
+
 int qman_wq_alloc(void)
 {
qm_portal_wq = alloc_workqueue("qman_portal_wq", 0, 1);
diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
index d4dfefdee6c1..42f50eb51529 100644
--- a/include/soc/fsl/qman.h
+++ b/include/soc/fsl/qman.h
@@ -1186,4 +1186,31 @@ int qman_alloc_cgrid_range(u32 *result, u32 count);
  */
 int qman_release_cgrid(u32 id);
 
+/**
+ * qman_dqrr_get_ithresh - Get coalesce interrupt threshold
+ * @portal: portal to get the value for
+ * @ithresh: threshold pointer
+ */
+void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh);
+
+/**
+ * qman_dqrr_set_ithresh - Set coalesce interrupt threshold
+ * @portal: portal to set the new value on
+ * @ithresh: new threshold value
+ */
+void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
+
+/**
+ * qman_dqrr_get_iperiod - Get coalesce interrupt period
+ * @portal: portal to get the value for
+ * @iperiod: period pointer
+ */
+void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod);
+/*
+ * qman_dqrr_set_iperiod - Set coalesce interrupt period
+ * @portal: portal to set the new value on
+ * @ithresh: new period value
+ */
+void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
+
 #endif /* __FSL_QMAN_H */
-- 
2.1.0



[PATCH v2 4/5] soc/fsl/qbman: Use last response to determine valid bit

2018-09-28 Thread Madalin Bucur
From: Roy Pledge 

Use the last valid response when determining what valid bit
to use next for management commands. This is needed in the
case that the portal was previously used by other software
like a bootloader or if the kernel is restarted without a
hardware reset.

Signed-off-by: Roy Pledge 
Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/qman.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 0ffe7a1d0eae..99d0f87889b8 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -850,12 +850,24 @@ static inline void qm_mr_set_ithresh(struct qm_portal 
*portal, u8 ithresh)
 
 static inline int qm_mc_init(struct qm_portal *portal)
 {
+   u8 rr0, rr1;
struct qm_mc *mc = >mc;
 
mc->cr = portal->addr.ce + QM_CL_CR;
mc->rr = portal->addr.ce + QM_CL_RR0;
-   mc->rridx = (mc->cr->_ncw_verb & QM_MCC_VERB_VBIT)
-   ? 0 : 1;
+   /*
+* The expected valid bit polarity for the next CR command is 0
+* if RR1 contains a valid response, and is 1 if RR0 contains a
+* valid response. If both RR contain all 0, this indicates either
+* that no command has been executed since reset (in which case the
+* expected valid bit polarity is 1)
+*/
+   rr0 = mc->rr->verb;
+   rr1 = (mc->rr+1)->verb;
+   if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
+   mc->rridx = 1;
+   else
+   mc->rridx = 0;
mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
 #ifdef CONFIG_FSL_DPAA_CHECKING
mc->state = qman_mc_idle;
-- 
2.1.0



[PATCH v2 3/5] soc/fsl/qbman: Add 64 bit DMA addressing requirement to QBMan

2018-09-28 Thread Madalin Bucur
From: Roy Pledge 

The QBMan block is memory mapped on SoCs above a 32 bit (4 Gigabyte)
boundary so enabling 64 bit DMA addressing is needed for QBMan to
be usuable.

Signed-off-by: Roy Pledge 
Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/qbman/Kconfig b/drivers/soc/fsl/qbman/Kconfig
index d570cb5fd381..b0943e541796 100644
--- a/drivers/soc/fsl/qbman/Kconfig
+++ b/drivers/soc/fsl/qbman/Kconfig
@@ -1,6 +1,6 @@
 menuconfig FSL_DPAA
bool "QorIQ DPAA1 framework support"
-   depends on (FSL_SOC_BOOKE || ARCH_LAYERSCAPE)
+   depends on ((FSL_SOC_BOOKE || ARCH_LAYERSCAPE) && ARCH_DMA_ADDR_T_64BIT)
select GENERIC_ALLOCATOR
help
  The Freescale Data Path Acceleration Architecture (DPAA) is a set of
-- 
2.1.0



[PATCH v2 1/5] soc/fsl/qbman: Check if CPU is offline when initializing portals

2018-09-28 Thread Madalin Bucur
From: Roy Pledge 

If the CPU to affine the portal interrupt is offline at boot time
affine the portal interrupt to another online CPU. If the CPU is later
brought online the hotplug handler will correctly adjust the affinity.
Moved common code in a function.

Signed-off-by: Roy Pledge 
Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/bman.c |  6 ++
 drivers/soc/fsl/qbman/dpaa_sys.h | 20 
 drivers/soc/fsl/qbman/qman.c |  6 ++
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/fsl/qbman/bman.c b/drivers/soc/fsl/qbman/bman.c
index f9485cedc648..f84ab596bde8 100644
--- a/drivers/soc/fsl/qbman/bman.c
+++ b/drivers/soc/fsl/qbman/bman.c
@@ -562,11 +562,9 @@ static int bman_create_portal(struct bman_portal *portal,
dev_err(c->dev, "request_irq() failed\n");
goto fail_irq;
}
-   if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
-   irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
-   dev_err(c->dev, "irq_set_affinity() failed\n");
+
+   if (dpaa_set_portal_irq_affinity(c->dev, c->irq, c->cpu))
goto fail_affinity;
-   }
 
/* Need RCR to be empty before continuing */
ret = bm_rcr_get_fill(p);
diff --git a/drivers/soc/fsl/qbman/dpaa_sys.h b/drivers/soc/fsl/qbman/dpaa_sys.h
index 9f379000da85..ae8afa552b1e 100644
--- a/drivers/soc/fsl/qbman/dpaa_sys.h
+++ b/drivers/soc/fsl/qbman/dpaa_sys.h
@@ -111,4 +111,24 @@ int qbman_init_private_mem(struct device *dev, int idx, 
dma_addr_t *addr,
 #define QBMAN_MEMREMAP_ATTRMEMREMAP_WC
 #endif
 
+static inline int dpaa_set_portal_irq_affinity(struct device *dev,
+  int irq, int cpu)
+{
+   int ret = 0;
+
+   if (!irq_can_set_affinity(irq)) {
+   dev_err(dev, "unable to set IRQ affinity\n");
+   return -EINVAL;
+   }
+
+   if (cpu == -1 || !cpu_online(cpu))
+   cpu = cpumask_any(cpu_online_mask);
+
+   ret = irq_set_affinity(irq, cpumask_of(cpu));
+   if (ret)
+   dev_err(dev, "irq_set_affinity() on CPU %d failed\n", cpu);
+
+   return ret;
+}
+
 #endif /* __DPAA_SYS_H */
diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index ecb22749df0b..0ffe7a1d0eae 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1210,11 +1210,9 @@ static int qman_create_portal(struct qman_portal *portal,
dev_err(c->dev, "request_irq() failed\n");
goto fail_irq;
}
-   if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
-   irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
-   dev_err(c->dev, "irq_set_affinity() failed\n");
+
+   if (dpaa_set_portal_irq_affinity(c->dev, c->irq, c->cpu))
goto fail_affinity;
-   }
 
/* Need EQCR to be empty before continuing */
isdr &= ~QM_PIRQ_EQCI;
-- 
2.1.0



[PATCH v2 2/5] soc/fsl/qbman: replace CPU 0 with any online CPU in hotplug handlers

2018-09-28 Thread Madalin Bucur
The existing code sets portal IRQ affinity to CPU 0 in the
offline hotplug handler. If CPU 0 is offline this is invalid.
Use a different online CPU instead.

Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/bman_portal.c | 4 +++-
 drivers/soc/fsl/qbman/qman_portal.c | 6 --
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/fsl/qbman/bman_portal.c 
b/drivers/soc/fsl/qbman/bman_portal.c
index 2f71f7df3465..088cdfa7c034 100644
--- a/drivers/soc/fsl/qbman/bman_portal.c
+++ b/drivers/soc/fsl/qbman/bman_portal.c
@@ -65,7 +65,9 @@ static int bman_offline_cpu(unsigned int cpu)
if (!pcfg)
return 0;
 
-   irq_set_affinity(pcfg->irq, cpumask_of(0));
+   /* use any other online CPU */
+   cpu = cpumask_any_but(cpu_online_mask, cpu);
+   irq_set_affinity(pcfg->irq, cpumask_of(cpu));
return 0;
 }
 
diff --git a/drivers/soc/fsl/qbman/qman_portal.c 
b/drivers/soc/fsl/qbman/qman_portal.c
index a120002b630e..4efd6ea598b1 100644
--- a/drivers/soc/fsl/qbman/qman_portal.c
+++ b/drivers/soc/fsl/qbman/qman_portal.c
@@ -195,8 +195,10 @@ static int qman_offline_cpu(unsigned int cpu)
if (p) {
pcfg = qman_get_qm_portal_config(p);
if (pcfg) {
-   irq_set_affinity(pcfg->irq, cpumask_of(0));
-   qman_portal_update_sdest(pcfg, 0);
+   /* select any other online CPU */
+   cpu = cpumask_any_but(cpu_online_mask, cpu);
+   irq_set_affinity(pcfg->irq, cpumask_of(cpu));
+   qman_portal_update_sdest(pcfg, cpu);
}
}
return 0;
-- 
2.1.0



[PATCH 2/4] soc/fsl/qbman: Add 64 bit DMA addressing requirement to QBMan

2018-09-20 Thread Madalin Bucur
From: Roy Pledge 

The QBMan block is memory mapped on SoCs above a 32 bit (4 Gigabyte)
boundary so enabling 64 bit DMA addressing is needed for QBMan to
be usable.

Signed-off-by: Roy Pledge 
Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/qbman/Kconfig b/drivers/soc/fsl/qbman/Kconfig
index d570cb5fd381..19d6f4621e23 100644
--- a/drivers/soc/fsl/qbman/Kconfig
+++ b/drivers/soc/fsl/qbman/Kconfig
@@ -1,6 +1,6 @@
 menuconfig FSL_DPAA
bool "QorIQ DPAA1 framework support"
-   depends on (FSL_SOC_BOOKE || ARCH_LAYERSCAPE)
+   depends on ((FSL_SOC_BOOKE || ARCH_LAYERSCAPE || ARM) && 
ARCH_DMA_ADDR_T_64BIT)
select GENERIC_ALLOCATOR
help
  The Freescale Data Path Acceleration Architecture (DPAA) is a set of
-- 
2.1.0



[PATCH 0/4] soc/fsl/qbman: DPAA QBMan fixes and additions

2018-09-20 Thread Madalin Bucur
This patch set brings a number of fixes and the option to control
the QMan portal interrupt coalescing.

Madalin Bucur (1):
  soc/fsl_qbman: export coalesce change API

Roy Pledge (3):
  soc/fsl/qbman: Check if CPU is offline when initializing portals
  soc/fsl/qbman: Add 64 bit DMA addressing requirement to QBMan
  soc/fsl/qbman: Use last response to determine valid bit

 drivers/soc/fsl/qbman/Kconfig |  2 +-
 drivers/soc/fsl/qbman/bman.c  | 17 ---
 drivers/soc/fsl/qbman/qman.c  | 65 ++-
 include/soc/fsl/qman.h| 27 ++
 4 files changed, 99 insertions(+), 12 deletions(-)

-- 
2.1.0



[PATCH 1/4] soc/fsl/qbman: Check if CPU is offline when initializing portals

2018-09-20 Thread Madalin Bucur
From: Roy Pledge 

If the affine portal for a specific CPU is offline at boot time
affine its interrupt to CPU 0. If the CPU is later brought online
the hotplug handler will correctly adjust the affinity.

Signed-off-by: Roy Pledge 
Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/bman.c | 17 +
 drivers/soc/fsl/qbman/qman.c | 18 +-
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/soc/fsl/qbman/bman.c b/drivers/soc/fsl/qbman/bman.c
index f9485cedc648..2e6e682bf16b 100644
--- a/drivers/soc/fsl/qbman/bman.c
+++ b/drivers/soc/fsl/qbman/bman.c
@@ -562,10 +562,19 @@ static int bman_create_portal(struct bman_portal *portal,
dev_err(c->dev, "request_irq() failed\n");
goto fail_irq;
}
-   if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
-   irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
-   dev_err(c->dev, "irq_set_affinity() failed\n");
-   goto fail_affinity;
+   if (cpu_online(c->cpu) && c->cpu != -1 &&
+   irq_can_set_affinity(c->irq)) {
+   if (irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
+   dev_err(c->dev, "irq_set_affinity() failed %d\n",
+   c->cpu);
+   goto fail_affinity;
+   }
+   } else {
+   /* CPU is offline, direct IRQ to CPU 0 */
+   if (irq_set_affinity(c->irq, cpumask_of(0))) {
+   dev_err(c->dev, "irq_set_affinity() cpu 0 failed\n");
+   goto fail_affinity;
+   }
}
 
/* Need RCR to be empty before continuing */
diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index ecb22749df0b..7dbcb475a59c 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -935,7 +935,6 @@ static inline int qm_mc_result_timeout(struct qm_portal 
*portal,
break;
udelay(1);
} while (--timeout);
-
return timeout;
 }
 
@@ -1210,10 +1209,19 @@ static int qman_create_portal(struct qman_portal 
*portal,
dev_err(c->dev, "request_irq() failed\n");
goto fail_irq;
}
-   if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
-   irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
-   dev_err(c->dev, "irq_set_affinity() failed\n");
-   goto fail_affinity;
+   if (cpu_online(c->cpu) && c->cpu != -1 &&
+   irq_can_set_affinity(c->irq)) {
+   if (irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
+   dev_err(c->dev, "irq_set_affinity() failed %d\n",
+   c->cpu);
+   goto fail_affinity;
+   }
+   } else {
+   /* CPU is offline, direct IRQ to CPU 0 */
+   if (irq_set_affinity(c->irq, cpumask_of(0))) {
+   dev_err(c->dev, "irq_set_affinity() cpu 0 failed\n");
+   goto fail_affinity;
+   }
}
 
/* Need EQCR to be empty before continuing */
-- 
2.1.0



[PATCH 4/4] soc/fsl_qbman: export coalesce change API

2018-09-20 Thread Madalin Bucur
Allow changing the QMan portal interrupt coalescing settings.

Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/qman.c | 31 +++
 include/soc/fsl/qman.h   | 27 +++
 2 files changed, 58 insertions(+)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 7f4c57999e08..c270471a6e47 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1011,6 +1011,37 @@ static inline void put_affine_portal(void)
 
 static struct workqueue_struct *qm_portal_wq;
 
+void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
+{
+   if (!portal)
+   return;
+
+   qm_dqrr_set_ithresh(>p, ithresh);
+   portal->p.dqrr.ithresh = ithresh;
+}
+EXPORT_SYMBOL(qman_dqrr_set_ithresh);
+
+void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh)
+{
+   if (portal && ithresh)
+   *ithresh = portal->p.dqrr.ithresh;
+}
+EXPORT_SYMBOL(qman_dqrr_get_ithresh);
+
+void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod)
+{
+   if (portal && iperiod)
+   *iperiod = qm_in(>p, QM_REG_ITPR);
+}
+EXPORT_SYMBOL(qman_portal_get_iperiod);
+
+void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
+{
+   if (portal)
+   qm_out(>p, QM_REG_ITPR, iperiod);
+}
+EXPORT_SYMBOL(qman_portal_set_iperiod);
+
 int qman_wq_alloc(void)
 {
qm_portal_wq = alloc_workqueue("qman_portal_wq", 0, 1);
diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
index d4dfefdee6c1..42f50eb51529 100644
--- a/include/soc/fsl/qman.h
+++ b/include/soc/fsl/qman.h
@@ -1186,4 +1186,31 @@ int qman_alloc_cgrid_range(u32 *result, u32 count);
  */
 int qman_release_cgrid(u32 id);
 
+/**
+ * qman_dqrr_get_ithresh - Get coalesce interrupt threshold
+ * @portal: portal to get the value for
+ * @ithresh: threshold pointer
+ */
+void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh);
+
+/**
+ * qman_dqrr_set_ithresh - Set coalesce interrupt threshold
+ * @portal: portal to set the new value on
+ * @ithresh: new threshold value
+ */
+void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
+
+/**
+ * qman_dqrr_get_iperiod - Get coalesce interrupt period
+ * @portal: portal to get the value for
+ * @iperiod: period pointer
+ */
+void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod);
+/*
+ * qman_dqrr_set_iperiod - Set coalesce interrupt period
+ * @portal: portal to set the new value on
+ * @ithresh: new period value
+ */
+void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
+
 #endif /* __FSL_QMAN_H */
-- 
2.1.0



[PATCH 3/4] soc/fsl/qbman: Use last response to determine valid bit

2018-09-20 Thread Madalin Bucur
From: Roy Pledge 

Use the last valid response when determining what valid bit
to use next for management commands. This is needed in the
case that the portal was previously used by other software
like a bootloader or if the kernel is restarted without a
hardware reset.

Signed-off-by: Roy Pledge 
Signed-off-by: Madalin Bucur 
---
 drivers/soc/fsl/qbman/qman.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 7dbcb475a59c..7f4c57999e08 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -850,12 +850,24 @@ static inline void qm_mr_set_ithresh(struct qm_portal 
*portal, u8 ithresh)
 
 static inline int qm_mc_init(struct qm_portal *portal)
 {
+   u8 rr0, rr1;
struct qm_mc *mc = >mc;
 
mc->cr = portal->addr.ce + QM_CL_CR;
mc->rr = portal->addr.ce + QM_CL_RR0;
-   mc->rridx = (mc->cr->_ncw_verb & QM_MCC_VERB_VBIT)
-   ? 0 : 1;
+   /*
+* The expected valid bit polarity for the next CR command is 0
+* if RR1 contains a valid response, and is 1 if RR0 contains a
+* valid response. If both RR contain all 0, this indicates either
+* that no command has been executed since reset (in which case the
+* expected valid bit polarity is 1)
+*/
+   rr0 = mc->rr->verb;
+   rr1 = (mc->rr+1)->verb;
+   if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
+   mc->rridx = 1;
+   else
+   mc->rridx = 0;
mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
 #ifdef CONFIG_FSL_DPAA_CHECKING
mc->state = qman_mc_idle;
-- 
2.1.0



[PATCH 5/5] dpaa_eth: remove duplicate increment of the tx_errors counter

2018-03-14 Thread Madalin Bucur
From: Camelia Groza <camelia.gr...@nxp.com>

The tx_errors counter is incremented by the dpaa_xmit caller.

Signed-off-by: Camelia Groza <camelia.gr...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 76b3c9e..fd43f98 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2021,7 +2021,6 @@ static inline int dpaa_xmit(struct dpaa_priv *priv,
}
 
if (unlikely(err < 0)) {
-   percpu_stats->tx_errors++;
percpu_stats->tx_fifo_errors++;
return err;
}
-- 
2.1.0



[PATCH 4/5] dpaa_eth: increment the RX dropped counter when needed

2018-03-14 Thread Madalin Bucur
From: Camelia Groza 

Signed-off-by: Camelia Groza 
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 3e83d79..76b3c9e 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2321,8 +2321,10 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
 
skb_len = skb->len;
 
-   if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
+   if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) {
+   percpu_stats->rx_dropped++;
return qman_cb_dqrr_consume;
+   }
 
percpu_stats->rx_packets++;
percpu_stats->rx_bytes += skb_len;
-- 
2.1.0



[PATCH 3/5] dpaa_eth: remove duplicate initialization

2018-03-14 Thread Madalin Bucur
From: Camelia Groza 

The fd_format has already been initialized at this point.

Signed-off-by: Camelia Groza 
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 128e0a4..3e83d79 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2289,7 +2289,6 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
vaddr = phys_to_virt(addr);
prefetch(vaddr + qm_fd_get_offset(fd));
 
-   fd_format = qm_fd_get_format(fd);
/* The only FD types that we may receive are contig and S/G */
WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg));
 
-- 
2.1.0



[PATCH 2/5] dpaa_eth: fix error in dpaa_remove()

2018-03-14 Thread Madalin Bucur
The recent changes that make the driver probing compatible with DSA
were not propagated in the dpa_remove() function, breaking the
module unload function. Using the proper device to address the issue.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 159dc2d..128e0a4 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2871,7 +2871,7 @@ static int dpaa_remove(struct platform_device *pdev)
struct device *dev;
int err;
 
-   dev = >dev;
+   dev = pdev->dev.parent;
net_dev = dev_get_drvdata(dev);
 
priv = netdev_priv(net_dev);
-- 
2.1.0



[PATCH 1/5] soc/fsl/qbman: fix issue in qman_delete_cgr_safe()

2018-03-14 Thread Madalin Bucur
The wait_for_completion() call in qman_delete_cgr_safe()
was triggering a scheduling while atomic bug, replacing the
kthread with a smp_call_function_single() call to fix it.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
Signed-off-by: Roy Pledge <roy.ple...@nxp.com>
---
 drivers/soc/fsl/qbman/qman.c | 28 +---
 1 file changed, 5 insertions(+), 23 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index e4f5bb0..ba3cfa8 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -2443,39 +2443,21 @@ struct cgr_comp {
struct completion completion;
 };
 
-static int qman_delete_cgr_thread(void *p)
+static void qman_delete_cgr_smp_call(void *p)
 {
-   struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
-   int ret;
-
-   ret = qman_delete_cgr(cgr_comp->cgr);
-   complete(_comp->completion);
-
-   return ret;
+   qman_delete_cgr((struct qman_cgr *)p);
 }
 
 void qman_delete_cgr_safe(struct qman_cgr *cgr)
 {
-   struct task_struct *thread;
-   struct cgr_comp cgr_comp;
-
preempt_disable();
if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
-   init_completion(_comp.completion);
-   cgr_comp.cgr = cgr;
-   thread = kthread_create(qman_delete_cgr_thread, _comp,
-   "cgr_del");
-
-   if (IS_ERR(thread))
-   goto out;
-
-   kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
-   wake_up_process(thread);
-   wait_for_completion(_comp.completion);
+   smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
+qman_delete_cgr_smp_call, cgr, true);
preempt_enable();
return;
}
-out:
+
qman_delete_cgr(cgr);
preempt_enable();
 }
-- 
2.1.0



[PATCH 0/5] DPAA Ethernet fixes

2018-03-14 Thread Madalin Bucur
Hi,

This patch set is addressing several issues in the DPAA Ethernet
driver suite:

 - module unload crash caused by wrong reference to device being left
   in the cleanup code after the DSA related changes
 - scheduling wile atomic bug in QMan code revealed during dpaa_eth
   module unload
 - a couple of error counter fixes, a duplicated init in dpaa_eth.

Madalin

Camelia Groza (3):
  dpaa_eth: remove duplicate initialization
  dpaa_eth: increment the RX dropped counter when needed
  dpaa_eth: remove duplicate increment of the tx_errors counter

Madalin Bucur (2):
  soc/fsl/qbman: fix issue in qman_delete_cgr_safe()
  dpaa_eth: fix error in dpaa_remove()

 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  8 
 drivers/soc/fsl/qbman/qman.c   | 28 +-
 2 files changed, 9 insertions(+), 27 deletions(-)

-- 
2.1.0



[PATCH v4 7/7] dpaa_eth: check allocation result

2017-08-27 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 73ca8d7..4225806 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2561,6 +2561,9 @@ static struct dpaa_bp *dpaa_bp_alloc(struct device *dev)
 
dpaa_bp->bpid = FSL_DPAA_BPID_INV;
dpaa_bp->percpu_count = devm_alloc_percpu(dev, *dpaa_bp->percpu_count);
+   if (!dpaa_bp->percpu_count)
+   return ERR_PTR(-ENOMEM);
+
dpaa_bp->config_count = FSL_DPAA_ETH_MAX_BUF_COUNT;
 
dpaa_bp->seed_cb = dpaa_bp_seed;
-- 
2.1.0



[PATCH v4 6/7] Documentation: networking: add RSS information

2017-08-27 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 Documentation/networking/dpaa.txt | 68 ++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/dpaa.txt 
b/Documentation/networking/dpaa.txt
index 76e016d..f88194f 100644
--- a/Documentation/networking/dpaa.txt
+++ b/Documentation/networking/dpaa.txt
@@ -13,6 +13,7 @@ Contents
- Configuring DPAA Ethernet in your kernel
- DPAA Ethernet Frame Processing
- DPAA Ethernet Features
+   - DPAA IRQ Affinity and Receive Side Scaling
- Debugging
 
 DPAA Ethernet Overview
@@ -147,7 +148,10 @@ gradually.
 
 The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx
 checksum offload feature is enabled by default and cannot be controlled through
-ethtool.
+ethtool. Also, rx-flow-hash and rx-hashing was added. The addition of RSS
+provides a big performance boost for the forwarding scenarios, allowing
+different traffic flows received by one interface to be processed by different
+CPUs in parallel.
 
 The driver has support for multiple prioritized Tx traffic classes. Priorities
 range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with
@@ -166,6 +170,68 @@ classes as follows:
 tc qdisc add dev  root handle 1: \
 mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1
 
+DPAA IRQ Affinity and Receive Side Scaling
+==
+
+Traffic coming on the DPAA Rx queues or on the DPAA Tx confirmation
+queues is seen by the CPU as ingress traffic on a certain portal.
+The DPAA QMan portal interrupts are affined each to a certain CPU.
+The same portal interrupt services all the QMan portal consumers.
+
+By default the DPAA Ethernet driver enables RSS, making use of the
+DPAA FMan Parser and Keygen blocks to distribute traffic on 128
+hardware frame queues using a hash on IP v4/v6 source and destination
+and L4 source and destination ports, in present in the received frame.
+When RSS is disabled, all traffic received by a certain interface is
+received on the default Rx frame queue. The default DPAA Rx frame
+queues are configured to put the received traffic into a pool channel
+that allows any available CPU portal to dequeue the ingress traffic.
+The default frame queues have the HOLDACTIVE option set, ensuring that
+traffic bursts from a certain queue are serviced by the same CPU.
+This ensures a very low rate of frame reordering. A drawback of this
+is that only one CPU at a time can service the traffic received by a
+certain interface when RSS is not enabled.
+
+To implement RSS, the DPAA Ethernet driver allocates an extra set of
+128 Rx frame queues that are configured to dedicated channels, in a
+round-robin manner. The mapping of the frame queues to CPUs is now
+hardcoded, there is no indirection table to move traffic for a certain
+FQ (hash result) to another CPU. The ingress traffic arriving on one
+of these frame queues will arrive at the same portal and will always
+be processed by the same CPU. This ensures intra-flow order preservation
+and workload distribution for multiple traffic flows.
+
+RSS can be turned off for a certain interface using ethtool, i.e.
+
+   # ethtool -N fm1-mac9 rx-flow-hash tcp4 ""
+
+To turn it back on, one needs to set rx-flow-hash for tcp4/6 or udp4/6:
+
+   # ethtool -N fm1-mac9 rx-flow-hash udp4 sfdn
+
+There is no independent control for individual protocols, any command
+run for one of tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 is
+going to control the rx-flow-hashing for all protocols on that interface.
+
+Besides using the FMan Keygen computed hash for spreading traffic on the
+128 Rx FQs, the DPAA Ethernet driver also sets the skb hash value when
+the NETIF_F_RXHASH feature is on (active by default). This can be turned
+on or off through ethtool, i.e.:
+
+   # ethtool -K fm1-mac9 rx-hashing off
+   # ethtool -k fm1-mac9 | grep hash
+   receive-hashing: off
+   # ethtool -K fm1-mac9 rx-hashing on
+   Actual changes:
+   receive-hashing: on
+   # ethtool -k fm1-mac9 | grep hash
+   receive-hashing: on
+
+Please note that Rx hashing depends upon the rx-flow-hashing being on
+for that interface - turning off rx-flow-hashing will also disable the
+rx-hashing (without ethtool reporting it as off as that depends on the
+NETIF_F_RXHASH feature flag).
+
 Debugging
 =
 
-- 
2.1.0



[PATCH v4 5/7] dpaa_eth: add NETIF_F_RXHASH

2017-08-27 Thread Madalin Bucur
Set the skb hash when then FMan Keygen hash result is available.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 23 +++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  1 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |  9 +++--
 drivers/net/ethernet/freescale/fman/fman_port.c| 11 +++
 drivers/net/ethernet/freescale/fman/fman_port.h|  2 ++
 5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 6d89e74..73ca8d7 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -236,7 +236,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
net_dev->max_mtu = dpaa_get_max_mtu();
 
net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-NETIF_F_LLTX);
+NETIF_F_LLTX | NETIF_F_RXHASH);
 
net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
/* The kernels enables GSO automatically, if we declare NETIF_F_SG.
@@ -2237,12 +2237,13 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_addr_t addr = qm_fd_addr(fd);
enum qm_fd_format fd_format;
struct net_device *net_dev;
-   u32 fd_status;
+   u32 fd_status, hash_offset;
struct dpaa_bp *dpaa_bp;
struct dpaa_priv *priv;
unsigned int skb_len;
struct sk_buff *skb;
int *count_ptr;
+   void *vaddr;
 
fd_status = be32_to_cpu(fd->status);
fd_format = qm_fd_get_format(fd);
@@ -2288,7 +2289,8 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE);
 
/* prefetch the first 64 bytes of the frame or the SGT start */
-   prefetch(phys_to_virt(addr) + qm_fd_get_offset(fd));
+   vaddr = phys_to_virt(addr);
+   prefetch(vaddr + qm_fd_get_offset(fd));
 
fd_format = qm_fd_get_format(fd);
/* The only FD types that we may receive are contig and S/G */
@@ -2309,6 +2311,18 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
 
skb->protocol = eth_type_trans(skb, net_dev);
 
+   if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
+   !fman_port_get_hash_result_offset(priv->mac_dev->port[RX],
+ _offset)) {
+   enum pkt_hash_types type;
+
+   /* if L4 exists, it was used in the hash generation */
+   type = be32_to_cpu(fd->status) & FM_FD_STAT_L4CV ?
+   PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3;
+   skb_set_hash(skb, be32_to_cpu(*(u32 *)(vaddr + hash_offset)),
+type);
+   }
+
skb_len = skb->len;
 
if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
@@ -2774,6 +2788,9 @@ static int dpaa_eth_probe(struct platform_device *pdev)
if (err)
goto init_ports_failed;
 
+   /* Rx traffic distribution based on keygen hashing defaults to on */
+   priv->keygen_in_use = true;
+
priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (!priv->percpu_priv) {
dev_err(dev, "devm_alloc_percpu() failed\n");
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 496a12c..bd94220 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -159,6 +159,7 @@ struct dpaa_priv {
struct list_head dpaa_fq_list;
 
u8 num_tc;
+   bool keygen_in_use;
u32 msg_enable; /* net_device message level */
 
struct {
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 965f652..faea674 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -402,6 +402,8 @@ static void dpaa_get_strings(struct net_device *net_dev, 
u32 stringset,
 static int dpaa_get_hash_opts(struct net_device *dev,
  struct ethtool_rxnfc *cmd)
 {
+   struct dpaa_priv *priv = netdev_priv(dev);
+
cmd->data = 0;
 
switch (cmd->flow_type) {
@@ -409,7 +411,8 @@ static int dpaa_get_hash_opts(struct net_device *dev,
case TCP_V6_FLOW:
case UDP_V4_FLOW:
case UDP_V6_FLOW:
-   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+   if (priv->keygen_in_use)
+   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
/* Fall through */
case I

[PATCH v4 4/7] dpaa_eth: enable Rx hashing control

2017-08-27 Thread Madalin Bucur
Allow ethtool control of the Rx flow hashing. By default RSS is
enabled, this allows to turn it off by bypassing the FMan Keygen
block and sending all traffic on the default Rx frame queue.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 113 +
 1 file changed, 113 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index aad825088..965f652 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -399,6 +399,117 @@ static void dpaa_get_strings(struct net_device *net_dev, 
u32 stringset,
memcpy(strings, dpaa_stats_global, size);
 }
 
+static int dpaa_get_hash_opts(struct net_device *dev,
+ struct ethtool_rxnfc *cmd)
+{
+   cmd->data = 0;
+
+   switch (cmd->flow_type) {
+   case TCP_V4_FLOW:
+   case TCP_V6_FLOW:
+   case UDP_V4_FLOW:
+   case UDP_V6_FLOW:
+   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+   /* Fall through */
+   case IPV4_FLOW:
+   case IPV6_FLOW:
+   case SCTP_V4_FLOW:
+   case SCTP_V6_FLOW:
+   case AH_ESP_V4_FLOW:
+   case AH_ESP_V6_FLOW:
+   case AH_V4_FLOW:
+   case AH_V6_FLOW:
+   case ESP_V4_FLOW:
+   case ESP_V6_FLOW:
+   cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+   break;
+   default:
+   cmd->data = 0;
+   break;
+   }
+
+   return 0;
+}
+
+static int dpaa_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *unused)
+{
+   int ret = -EOPNOTSUPP;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_GRXFH:
+   ret = dpaa_get_hash_opts(dev, cmd);
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static void dpaa_set_hash(struct net_device *net_dev, bool enable)
+{
+   struct mac_device *mac_dev;
+   struct fman_port *rxport;
+   struct dpaa_priv *priv;
+
+   priv = netdev_priv(net_dev);
+   mac_dev = priv->mac_dev;
+   rxport = mac_dev->port[0];
+
+   fman_port_use_kg_hash(rxport, enable);
+}
+
+static int dpaa_set_hash_opts(struct net_device *dev,
+ struct ethtool_rxnfc *nfc)
+{
+   int ret = -EINVAL;
+
+   /* we support hashing on IPv4/v6 src/dest IP and L4 src/dest port */
+   if (nfc->data &
+   ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3))
+   return -EINVAL;
+
+   switch (nfc->flow_type) {
+   case TCP_V4_FLOW:
+   case TCP_V6_FLOW:
+   case UDP_V4_FLOW:
+   case UDP_V6_FLOW:
+   case IPV4_FLOW:
+   case IPV6_FLOW:
+   case SCTP_V4_FLOW:
+   case SCTP_V6_FLOW:
+   case AH_ESP_V4_FLOW:
+   case AH_ESP_V6_FLOW:
+   case AH_V4_FLOW:
+   case AH_V6_FLOW:
+   case ESP_V4_FLOW:
+   case ESP_V6_FLOW:
+   dpaa_set_hash(dev, !!nfc->data);
+   ret = 0;
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static int dpaa_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+   int ret = -EOPNOTSUPP;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_SRXFH:
+   ret = dpaa_set_hash_opts(dev, cmd);
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
 const struct ethtool_ops dpaa_ethtool_ops = {
.get_drvinfo = dpaa_get_drvinfo,
.get_msglevel = dpaa_get_msglevel,
@@ -412,4 +523,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
.get_strings = dpaa_get_strings,
.get_link_ksettings = dpaa_get_link_ksettings,
.set_link_ksettings = dpaa_set_link_ksettings,
+   .get_rxnfc = dpaa_get_rxnfc,
+   .set_rxnfc = dpaa_set_rxnfc,
 };
-- 
2.1.0



[PATCH v4 2/7] fsl/fman: enable FMan Keygen

2017-08-27 Thread Madalin Bucur
From: Iordache Florinel-R70177 <florinel.iorda...@nxp.com>

Add support for the FMan Keygen with a hardcoded scheme to spread
incoming traffic on a FQ range based on source and destination IPs
and ports.

Signed-off-by: Iordache Florinel <florinel.iorda...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Makefile  |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c|   8 +
 drivers/net/ethernet/freescale/fman/fman.h|   2 +
 drivers/net/ethernet/freescale/fman/fman_keygen.c | 783 ++
 drivers/net/ethernet/freescale/fman/fman_keygen.h |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c   |  40 +-
 drivers/net/ethernet/freescale/fman/fman_port.h   |   5 +
 7 files changed, 884 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index 6049177..2c38119 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -4,6 +4,6 @@ obj-$(CONFIG_FSL_FMAN) += fsl_fman.o
 obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o
 obj-$(CONFIG_FSL_FMAN) += fsl_mac.o
 
-fsl_fman-objs  := fman_muram.o fman.o fman_sp.o
+fsl_fman-objs  := fman_muram.o fman.o fman_sp.o fman_keygen.o
 fsl_fman_port-objs := fman_port.o
 fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index 8179cc1..f420dac 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -45,6 +45,7 @@
 
 #include "fman.h"
 #include "fman_muram.h"
+#include "fman_keygen.h"
 
 /* General defines */
 #define FMAN_LIODN_TBL 64  /* size of LIODN table */
@@ -56,6 +57,7 @@
 /* Modules registers offsets */
 #define BMI_OFFSET 0x0008
 #define QMI_OFFSET 0x00080400
+#define KG_OFFSET  0x000C1000
 #define DMA_OFFSET 0x000C2000
 #define FPM_OFFSET 0x000C3000
 #define IMEM_OFFSET0x000C4000
@@ -1737,6 +1739,7 @@ static int fman_config(struct fman *fman)
fman->qmi_regs = base_addr + QMI_OFFSET;
fman->dma_regs = base_addr + DMA_OFFSET;
fman->hwp_regs = base_addr + HWP_OFFSET;
+   fman->kg_regs = base_addr + KG_OFFSET;
fman->base_addr = base_addr;
 
spin_lock_init(>spinlock);
@@ -2009,6 +2012,11 @@ static int fman_init(struct fman *fman)
/* Init HW Parser */
hwp_init(fman->hwp_regs);
 
+   /* Init KeyGen */
+   fman->keygen = keygen_init(fman->kg_regs);
+   if (!fman->keygen)
+   return -EINVAL;
+
err = enable(fman, cfg);
if (err != 0)
return err;
diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index 1015dac..bfa02e0 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -328,6 +328,7 @@ struct fman {
struct fman_qmi_regs __iomem *qmi_regs;
struct fman_dma_regs __iomem *dma_regs;
struct fman_hwp_regs __iomem *hwp_regs;
+   struct fman_kg_regs __iomem *kg_regs;
fman_exceptions_cb *exception_cb;
fman_bus_error_cb *bus_error_cb;
/* Spinlock for FMan use */
@@ -336,6 +337,7 @@ struct fman {
 
struct fman_cfg *cfg;
struct muram_info *muram;
+   struct fman_keygen *keygen;
/* cam section in muram */
unsigned long cam_offset;
size_t cam_size;
diff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.c 
b/drivers/net/ethernet/freescale/fman/fman_keygen.c
new file mode 100644
index 000..f54da3c
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fman_keygen.c
@@ -0,0 +1,783 @@
+/*
+ * Copyright 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 NXP 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 Sof

[PATCH v4 3/7] dpaa_eth: use multiple Rx frame queues

2017-08-27 Thread Madalin Bucur
Add a block of 128 Rx frame queues per port. The FMan hardware will
send traffic on one of these queues based on the FMan port Parse
Classify Distribute setup. The hash computed by the FMan Keygen
block will select the Rx FQ.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 50 +++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  1 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |  3 ++
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index c7fa285..6d89e74 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -158,7 +158,7 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
 #define DPAA_RX_PRIV_DATA_SIZE (u16)(DPAA_TX_PRIV_DATA_SIZE + \
dpaa_rx_extra_headroom)
 
-#define DPAA_ETH_RX_QUEUES 128
+#define DPAA_ETH_PCD_RXQ_NUM   128
 
 #define DPAA_ENQUEUE_RETRIES   10
 
@@ -169,6 +169,7 @@ struct fm_port_fqs {
struct dpaa_fq *tx_errq;
struct dpaa_fq *rx_defq;
struct dpaa_fq *rx_errq;
+   struct dpaa_fq *rx_pcdq;
 };
 
 /* All the dpa bps in use at any moment */
@@ -628,6 +629,7 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq, int 
idx)
fq->wq = 5;
break;
case FQ_TYPE_RX_DEFAULT:
+   case FQ_TYPE_RX_PCD:
fq->wq = 6;
break;
case FQ_TYPE_TX:
@@ -688,6 +690,7 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct 
list_head *list,
  struct fm_port_fqs *port_fqs)
 {
struct dpaa_fq *dpaa_fq;
+   u32 fq_base, fq_base_aligned, i;
 
dpaa_fq = dpaa_fq_alloc(dev, 0, 1, list, FQ_TYPE_RX_ERROR);
if (!dpaa_fq)
@@ -701,6 +704,26 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct 
list_head *list,
 
port_fqs->rx_defq = _fq[0];
 
+   /* the PCD FQIDs range needs to be aligned for correct operation */
+   if (qman_alloc_fqid_range(_base, 2 * DPAA_ETH_PCD_RXQ_NUM))
+   goto fq_alloc_failed;
+
+   fq_base_aligned = ALIGN(fq_base, DPAA_ETH_PCD_RXQ_NUM);
+
+   for (i = fq_base; i < fq_base_aligned; i++)
+   qman_release_fqid(i);
+
+   for (i = fq_base_aligned + DPAA_ETH_PCD_RXQ_NUM;
+i < (fq_base + 2 * DPAA_ETH_PCD_RXQ_NUM); i++)
+   qman_release_fqid(i);
+
+   dpaa_fq = dpaa_fq_alloc(dev, fq_base_aligned, DPAA_ETH_PCD_RXQ_NUM,
+   list, FQ_TYPE_RX_PCD);
+   if (!dpaa_fq)
+   goto fq_alloc_failed;
+
+   port_fqs->rx_pcdq = _fq[0];
+
if (!dpaa_fq_alloc(dev, 0, DPAA_ETH_TXQ_NUM, list, FQ_TYPE_TX_CONF_MQ))
goto fq_alloc_failed;
 
@@ -870,13 +893,14 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
  const struct dpaa_fq_cbs *fq_cbs,
  struct fman_port *tx_port)
 {
-   int egress_cnt = 0, conf_cnt = 0, num_portals = 0, cpu;
+   int egress_cnt = 0, conf_cnt = 0, num_portals = 0, portal_cnt = 0, cpu;
const cpumask_t *affine_cpus = qman_affine_cpus();
-   u16 portals[NR_CPUS];
+   u16 channels[NR_CPUS];
struct dpaa_fq *fq;
 
for_each_cpu(cpu, affine_cpus)
-   portals[num_portals++] = qman_affine_channel(cpu);
+   channels[num_portals++] = qman_affine_channel(cpu);
+
if (num_portals == 0)
dev_err(priv->net_dev->dev.parent,
"No Qman software (affine) channels found");
@@ -890,6 +914,12 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
case FQ_TYPE_RX_ERROR:
dpaa_setup_ingress(priv, fq, _cbs->rx_errq);
break;
+   case FQ_TYPE_RX_PCD:
+   if (!num_portals)
+   continue;
+   dpaa_setup_ingress(priv, fq, _cbs->rx_defq);
+   fq->channel = channels[portal_cnt++ % num_portals];
+   break;
case FQ_TYPE_TX:
dpaa_setup_egress(priv, fq, tx_port,
  _cbs->egress_ern);
@@ -1039,7 +1069,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool 
td_enable)
/* Put all the ingress queues in our "ingress CGR". */
if (priv->use_ingress_cgr &&
(dpaa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
-dpaa_fq->fq_type == FQ_TYPE_RX_ERROR)) {
+dpaa_fq->fq_type == FQ_TYPE_RX_ERROR ||
+dpaa_fq->fq_type == FQ_TYPE_RX_PCD)) {
initfq.we_mask |= cpu_to_b

[PATCH v4 1/7] fsl/fman: move struct fman to header file

2017-08-27 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c  | 80 +
 drivers/net/ethernet/freescale/fman/fman.h  | 75 +++
 drivers/net/ethernet/freescale/fman/fman_port.c |  8 +--
 3 files changed, 82 insertions(+), 81 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index e714b8f..8179cc1 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -32,9 +32,6 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include "fman.h"
-#include "fman_muram.h"
-
 #include 
 #include 
 #include 
@@ -46,6 +43,9 @@
 #include 
 #include 
 
+#include "fman.h"
+#include "fman_muram.h"
+
 /* General defines */
 #define FMAN_LIODN_TBL 64  /* size of LIODN table */
 #define MAX_NUM_OF_MACS10
@@ -564,80 +564,6 @@ struct fman_cfg {
u32 qmi_def_tnums_thresh;
 };
 
-/* Structure that holds information received from device tree */
-struct fman_dts_params {
-   void __iomem *base_addr;/* FMan virtual address */
-   struct resource *res;   /* FMan memory resource */
-   u8 id;  /* FMan ID */
-
-   int err_irq;/* FMan Error IRQ */
-
-   u16 clk_freq;   /* FMan clock freq (In Mhz) */
-
-   u32 qman_channel_base;  /* QMan channels base */
-   u32 num_of_qman_channels;   /* Number of QMan channels */
-
-   struct resource muram_res;  /* MURAM resource */
-};
-
-/** fman_exceptions_cb
- * fman- Pointer to FMan
- * exception   - The exception.
- *
- * Exceptions user callback routine, will be called upon an exception
- * passing the exception identification.
- *
- * Return: irq status
- */
-typedef irqreturn_t (fman_exceptions_cb)(struct fman *fman,
-enum fman_exceptions exception);
-
-/** fman_bus_error_cb
- * fman- Pointer to FMan
- * port_id - Port id
- * addr- Address that caused the error
- * tnum- Owner of error
- * liodn   - Logical IO device number
- *
- * Bus error user callback routine, will be called upon bus error,
- * passing parameters describing the errors and the owner.
- *
- * Return: IRQ status
- */
-typedef irqreturn_t (fman_bus_error_cb)(struct fman *fman, u8 port_id,
-   u64 addr, u8 tnum, u16 liodn);
-
-struct fman {
-   struct device *dev;
-   void __iomem *base_addr;
-   struct fman_intr_src intr_mng[FMAN_EV_CNT];
-
-   struct fman_fpm_regs __iomem *fpm_regs;
-   struct fman_bmi_regs __iomem *bmi_regs;
-   struct fman_qmi_regs __iomem *qmi_regs;
-   struct fman_dma_regs __iomem *dma_regs;
-   struct fman_hwp_regs __iomem *hwp_regs;
-   fman_exceptions_cb *exception_cb;
-   fman_bus_error_cb *bus_error_cb;
-   /* Spinlock for FMan use */
-   spinlock_t spinlock;
-   struct fman_state_struct *state;
-
-   struct fman_cfg *cfg;
-   struct muram_info *muram;
-   /* cam section in muram */
-   unsigned long cam_offset;
-   size_t cam_size;
-   /* Fifo in MURAM */
-   unsigned long fifo_offset;
-   size_t fifo_size;
-
-   u32 liodn_base[64];
-   u32 liodn_offset[64];
-
-   struct fman_dts_params dts_params;
-};
-
 static irqreturn_t fman_exceptions(struct fman *fman,
   enum fman_exceptions exception)
 {
diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index f53e147..1015dac 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -34,6 +34,8 @@
 #define __FM_H
 
 #include 
+#include 
+#include 
 
 /* FM Frame descriptor macros  */
 /* Frame queue Context Override */
@@ -274,6 +276,79 @@ struct fman_intr_src {
void *src_handle;
 };
 
+/** fman_exceptions_cb
+ * fman - Pointer to FMan
+ * exception- The exception.
+ *
+ * Exceptions user callback routine, will be called upon an exception
+ * passing the exception identification.
+ *
+ * Return: irq status
+ */
+typedef irqreturn_t (fman_exceptions_cb)(struct fman *fman,
+enum fman_exceptions exception);
+/** fman_bus_error_cb
+ * fman - Pointer to FMan
+ * port_id  - Port id
+ * addr - Address that caused the error
+ * tnum - Owner of error
+ * liodn- Logical IO device number
+ *
+ * Bus error user callback routine, will be called upon bus error,
+ * passing parameters describing the errors and the owner.
+ *
+ * Return: IRQ status
+ */
+typedef irqreturn_t (fman_bus_error_cb)(struct fman *fman, u8 port_

[PATCH v4 0/7] Add RSS to DPAA 1.x Ethernet driver

2017-08-27 Thread Madalin Bucur
This patch set introduces Receive Side Scaling for the DPAA Ethernet
driver. Documentation is updated with details related to the new
feature and limitations that apply.
Added also a small fix.

v2: removed a C++ style comment
v3: move struct fman to header file to avoid exporting a function
v4: addressed compilation issues introduced in v3

Iordache Florinel-R70177 (1):
  fsl/fman: enable FMan Keygen

Madalin Bucur (6):
  fsl/fman: move struct fman to header file
  dpaa_eth: use multiple Rx frame queues
  dpaa_eth: enable Rx hashing control
  dpaa_eth: add NETIF_F_RXHASH
  Documentation: networking: add RSS information
  dpaa_eth: check allocation result

 Documentation/networking/dpaa.txt  |  68 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  76 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |   3 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 118 
 drivers/net/ethernet/freescale/fman/Makefile   |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c |  88 +--
 drivers/net/ethernet/freescale/fman/fman.h |  77 ++
 drivers/net/ethernet/freescale/fman/fman_keygen.c  | 783 +
 drivers/net/ethernet/freescale/fman/fman_keygen.h  |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c|  59 +-
 drivers/net/ethernet/freescale/fman/fman_port.h|   7 +
 12 files changed, 1235 insertions(+), 94 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

-- 
2.1.0



[PATCH v3 7/7] dpaa_eth: check allocation result

2017-08-24 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 73ca8d7..4225806 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2561,6 +2561,9 @@ static struct dpaa_bp *dpaa_bp_alloc(struct device *dev)
 
dpaa_bp->bpid = FSL_DPAA_BPID_INV;
dpaa_bp->percpu_count = devm_alloc_percpu(dev, *dpaa_bp->percpu_count);
+   if (!dpaa_bp->percpu_count)
+   return ERR_PTR(-ENOMEM);
+
dpaa_bp->config_count = FSL_DPAA_ETH_MAX_BUF_COUNT;
 
dpaa_bp->seed_cb = dpaa_bp_seed;
-- 
2.1.0



[PATCH v3 6/7] Documentation: networking: add RSS information

2017-08-24 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 Documentation/networking/dpaa.txt | 68 ++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/dpaa.txt 
b/Documentation/networking/dpaa.txt
index 76e016d..f88194f 100644
--- a/Documentation/networking/dpaa.txt
+++ b/Documentation/networking/dpaa.txt
@@ -13,6 +13,7 @@ Contents
- Configuring DPAA Ethernet in your kernel
- DPAA Ethernet Frame Processing
- DPAA Ethernet Features
+   - DPAA IRQ Affinity and Receive Side Scaling
- Debugging
 
 DPAA Ethernet Overview
@@ -147,7 +148,10 @@ gradually.
 
 The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx
 checksum offload feature is enabled by default and cannot be controlled through
-ethtool.
+ethtool. Also, rx-flow-hash and rx-hashing was added. The addition of RSS
+provides a big performance boost for the forwarding scenarios, allowing
+different traffic flows received by one interface to be processed by different
+CPUs in parallel.
 
 The driver has support for multiple prioritized Tx traffic classes. Priorities
 range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with
@@ -166,6 +170,68 @@ classes as follows:
 tc qdisc add dev  root handle 1: \
 mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1
 
+DPAA IRQ Affinity and Receive Side Scaling
+==
+
+Traffic coming on the DPAA Rx queues or on the DPAA Tx confirmation
+queues is seen by the CPU as ingress traffic on a certain portal.
+The DPAA QMan portal interrupts are affined each to a certain CPU.
+The same portal interrupt services all the QMan portal consumers.
+
+By default the DPAA Ethernet driver enables RSS, making use of the
+DPAA FMan Parser and Keygen blocks to distribute traffic on 128
+hardware frame queues using a hash on IP v4/v6 source and destination
+and L4 source and destination ports, in present in the received frame.
+When RSS is disabled, all traffic received by a certain interface is
+received on the default Rx frame queue. The default DPAA Rx frame
+queues are configured to put the received traffic into a pool channel
+that allows any available CPU portal to dequeue the ingress traffic.
+The default frame queues have the HOLDACTIVE option set, ensuring that
+traffic bursts from a certain queue are serviced by the same CPU.
+This ensures a very low rate of frame reordering. A drawback of this
+is that only one CPU at a time can service the traffic received by a
+certain interface when RSS is not enabled.
+
+To implement RSS, the DPAA Ethernet driver allocates an extra set of
+128 Rx frame queues that are configured to dedicated channels, in a
+round-robin manner. The mapping of the frame queues to CPUs is now
+hardcoded, there is no indirection table to move traffic for a certain
+FQ (hash result) to another CPU. The ingress traffic arriving on one
+of these frame queues will arrive at the same portal and will always
+be processed by the same CPU. This ensures intra-flow order preservation
+and workload distribution for multiple traffic flows.
+
+RSS can be turned off for a certain interface using ethtool, i.e.
+
+   # ethtool -N fm1-mac9 rx-flow-hash tcp4 ""
+
+To turn it back on, one needs to set rx-flow-hash for tcp4/6 or udp4/6:
+
+   # ethtool -N fm1-mac9 rx-flow-hash udp4 sfdn
+
+There is no independent control for individual protocols, any command
+run for one of tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 is
+going to control the rx-flow-hashing for all protocols on that interface.
+
+Besides using the FMan Keygen computed hash for spreading traffic on the
+128 Rx FQs, the DPAA Ethernet driver also sets the skb hash value when
+the NETIF_F_RXHASH feature is on (active by default). This can be turned
+on or off through ethtool, i.e.:
+
+   # ethtool -K fm1-mac9 rx-hashing off
+   # ethtool -k fm1-mac9 | grep hash
+   receive-hashing: off
+   # ethtool -K fm1-mac9 rx-hashing on
+   Actual changes:
+   receive-hashing: on
+   # ethtool -k fm1-mac9 | grep hash
+   receive-hashing: on
+
+Please note that Rx hashing depends upon the rx-flow-hashing being on
+for that interface - turning off rx-flow-hashing will also disable the
+rx-hashing (without ethtool reporting it as off as that depends on the
+NETIF_F_RXHASH feature flag).
+
 Debugging
 =
 
-- 
2.1.0



[PATCH v3 5/7] dpaa_eth: add NETIF_F_RXHASH

2017-08-24 Thread Madalin Bucur
Set the skb hash when then FMan Keygen hash result is available.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 23 +++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  1 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |  9 +++--
 drivers/net/ethernet/freescale/fman/fman_port.c| 11 +++
 drivers/net/ethernet/freescale/fman/fman_port.h|  2 ++
 5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 6d89e74..73ca8d7 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -236,7 +236,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
net_dev->max_mtu = dpaa_get_max_mtu();
 
net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-NETIF_F_LLTX);
+NETIF_F_LLTX | NETIF_F_RXHASH);
 
net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
/* The kernels enables GSO automatically, if we declare NETIF_F_SG.
@@ -2237,12 +2237,13 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_addr_t addr = qm_fd_addr(fd);
enum qm_fd_format fd_format;
struct net_device *net_dev;
-   u32 fd_status;
+   u32 fd_status, hash_offset;
struct dpaa_bp *dpaa_bp;
struct dpaa_priv *priv;
unsigned int skb_len;
struct sk_buff *skb;
int *count_ptr;
+   void *vaddr;
 
fd_status = be32_to_cpu(fd->status);
fd_format = qm_fd_get_format(fd);
@@ -2288,7 +2289,8 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE);
 
/* prefetch the first 64 bytes of the frame or the SGT start */
-   prefetch(phys_to_virt(addr) + qm_fd_get_offset(fd));
+   vaddr = phys_to_virt(addr);
+   prefetch(vaddr + qm_fd_get_offset(fd));
 
fd_format = qm_fd_get_format(fd);
/* The only FD types that we may receive are contig and S/G */
@@ -2309,6 +2311,18 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
 
skb->protocol = eth_type_trans(skb, net_dev);
 
+   if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
+   !fman_port_get_hash_result_offset(priv->mac_dev->port[RX],
+ _offset)) {
+   enum pkt_hash_types type;
+
+   /* if L4 exists, it was used in the hash generation */
+   type = be32_to_cpu(fd->status) & FM_FD_STAT_L4CV ?
+   PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3;
+   skb_set_hash(skb, be32_to_cpu(*(u32 *)(vaddr + hash_offset)),
+type);
+   }
+
skb_len = skb->len;
 
if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
@@ -2774,6 +2788,9 @@ static int dpaa_eth_probe(struct platform_device *pdev)
if (err)
goto init_ports_failed;
 
+   /* Rx traffic distribution based on keygen hashing defaults to on */
+   priv->keygen_in_use = true;
+
priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (!priv->percpu_priv) {
dev_err(dev, "devm_alloc_percpu() failed\n");
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 496a12c..bd94220 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -159,6 +159,7 @@ struct dpaa_priv {
struct list_head dpaa_fq_list;
 
u8 num_tc;
+   bool keygen_in_use;
u32 msg_enable; /* net_device message level */
 
struct {
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 965f652..faea674 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -402,6 +402,8 @@ static void dpaa_get_strings(struct net_device *net_dev, 
u32 stringset,
 static int dpaa_get_hash_opts(struct net_device *dev,
  struct ethtool_rxnfc *cmd)
 {
+   struct dpaa_priv *priv = netdev_priv(dev);
+
cmd->data = 0;
 
switch (cmd->flow_type) {
@@ -409,7 +411,8 @@ static int dpaa_get_hash_opts(struct net_device *dev,
case TCP_V6_FLOW:
case UDP_V4_FLOW:
case UDP_V6_FLOW:
-   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+   if (priv->keygen_in_use)
+   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
/* Fall through */
case I

[PATCH v3 4/7] dpaa_eth: enable Rx hashing control

2017-08-24 Thread Madalin Bucur
Allow ethtool control of the Rx flow hashing. By default RSS is
enabled, this allows to turn it off by bypassing the FMan Keygen
block and sending all traffic on the default Rx frame queue.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 113 +
 1 file changed, 113 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index aad825088..965f652 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -399,6 +399,117 @@ static void dpaa_get_strings(struct net_device *net_dev, 
u32 stringset,
memcpy(strings, dpaa_stats_global, size);
 }
 
+static int dpaa_get_hash_opts(struct net_device *dev,
+ struct ethtool_rxnfc *cmd)
+{
+   cmd->data = 0;
+
+   switch (cmd->flow_type) {
+   case TCP_V4_FLOW:
+   case TCP_V6_FLOW:
+   case UDP_V4_FLOW:
+   case UDP_V6_FLOW:
+   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+   /* Fall through */
+   case IPV4_FLOW:
+   case IPV6_FLOW:
+   case SCTP_V4_FLOW:
+   case SCTP_V6_FLOW:
+   case AH_ESP_V4_FLOW:
+   case AH_ESP_V6_FLOW:
+   case AH_V4_FLOW:
+   case AH_V6_FLOW:
+   case ESP_V4_FLOW:
+   case ESP_V6_FLOW:
+   cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+   break;
+   default:
+   cmd->data = 0;
+   break;
+   }
+
+   return 0;
+}
+
+static int dpaa_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *unused)
+{
+   int ret = -EOPNOTSUPP;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_GRXFH:
+   ret = dpaa_get_hash_opts(dev, cmd);
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static void dpaa_set_hash(struct net_device *net_dev, bool enable)
+{
+   struct mac_device *mac_dev;
+   struct fman_port *rxport;
+   struct dpaa_priv *priv;
+
+   priv = netdev_priv(net_dev);
+   mac_dev = priv->mac_dev;
+   rxport = mac_dev->port[0];
+
+   fman_port_use_kg_hash(rxport, enable);
+}
+
+static int dpaa_set_hash_opts(struct net_device *dev,
+ struct ethtool_rxnfc *nfc)
+{
+   int ret = -EINVAL;
+
+   /* we support hashing on IPv4/v6 src/dest IP and L4 src/dest port */
+   if (nfc->data &
+   ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3))
+   return -EINVAL;
+
+   switch (nfc->flow_type) {
+   case TCP_V4_FLOW:
+   case TCP_V6_FLOW:
+   case UDP_V4_FLOW:
+   case UDP_V6_FLOW:
+   case IPV4_FLOW:
+   case IPV6_FLOW:
+   case SCTP_V4_FLOW:
+   case SCTP_V6_FLOW:
+   case AH_ESP_V4_FLOW:
+   case AH_ESP_V6_FLOW:
+   case AH_V4_FLOW:
+   case AH_V6_FLOW:
+   case ESP_V4_FLOW:
+   case ESP_V6_FLOW:
+   dpaa_set_hash(dev, !!nfc->data);
+   ret = 0;
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static int dpaa_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+   int ret = -EOPNOTSUPP;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_SRXFH:
+   ret = dpaa_set_hash_opts(dev, cmd);
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
 const struct ethtool_ops dpaa_ethtool_ops = {
.get_drvinfo = dpaa_get_drvinfo,
.get_msglevel = dpaa_get_msglevel,
@@ -412,4 +523,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
.get_strings = dpaa_get_strings,
.get_link_ksettings = dpaa_get_link_ksettings,
.set_link_ksettings = dpaa_set_link_ksettings,
+   .get_rxnfc = dpaa_get_rxnfc,
+   .set_rxnfc = dpaa_set_rxnfc,
 };
-- 
2.1.0



[PATCH v3 2/7] fsl/fman: enable FMan Keygen

2017-08-24 Thread Madalin Bucur
From: Iordache Florinel-R70177 <florinel.iorda...@nxp.com>

Add support for the FMan Keygen with a hardcoded scheme to spread
incoming traffic on a FQ range based on source and destination IPs
and ports.

Signed-off-by: Iordache Florinel <florinel.iorda...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Makefile  |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c|   8 +
 drivers/net/ethernet/freescale/fman/fman.h|   2 +
 drivers/net/ethernet/freescale/fman/fman_keygen.c | 783 ++
 drivers/net/ethernet/freescale/fman/fman_keygen.h |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c   |  40 +-
 drivers/net/ethernet/freescale/fman/fman_port.h   |   5 +
 7 files changed, 884 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index 6049177..2c38119 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -4,6 +4,6 @@ obj-$(CONFIG_FSL_FMAN) += fsl_fman.o
 obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o
 obj-$(CONFIG_FSL_FMAN) += fsl_mac.o
 
-fsl_fman-objs  := fman_muram.o fman.o fman_sp.o
+fsl_fman-objs  := fman_muram.o fman.o fman_sp.o fman_keygen.o
 fsl_fman_port-objs := fman_port.o
 fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index 6ed383f..9383b99 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -34,6 +34,7 @@
 
 #include "fman.h"
 #include "fman_muram.h"
+#include "fman_keygen.h"
 
 #include 
 #include 
@@ -56,6 +57,7 @@
 /* Modules registers offsets */
 #define BMI_OFFSET 0x0008
 #define QMI_OFFSET 0x00080400
+#define KG_OFFSET  0x000C1000
 #define DMA_OFFSET 0x000C2000
 #define FPM_OFFSET 0x000C3000
 #define IMEM_OFFSET0x000C4000
@@ -1737,6 +1739,7 @@ static int fman_config(struct fman *fman)
fman->qmi_regs = base_addr + QMI_OFFSET;
fman->dma_regs = base_addr + DMA_OFFSET;
fman->hwp_regs = base_addr + HWP_OFFSET;
+   fman->kg_regs = base_addr + KG_OFFSET;
fman->base_addr = base_addr;
 
spin_lock_init(>spinlock);
@@ -2009,6 +2012,11 @@ static int fman_init(struct fman *fman)
/* Init HW Parser */
hwp_init(fman->hwp_regs);
 
+   /* Init KeyGen */
+   fman->keygen = keygen_init(fman->kg_regs);
+   if (!fman->keygen)
+   return -EINVAL;
+
err = enable(fman, cfg);
if (err != 0)
return err;
diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index 6745065..a4b1633 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -326,6 +326,7 @@ struct fman {
struct fman_qmi_regs __iomem *qmi_regs;
struct fman_dma_regs __iomem *dma_regs;
struct fman_hwp_regs __iomem *hwp_regs;
+   struct fman_kg_regs __iomem *kg_regs;
fman_exceptions_cb *exception_cb;
fman_bus_error_cb *bus_error_cb;
/* Spinlock for FMan use */
@@ -334,6 +335,7 @@ struct fman {
 
struct fman_cfg *cfg;
struct muram_info *muram;
+   struct fman_keygen *keygen;
/* cam section in muram */
unsigned long cam_offset;
size_t cam_size;
diff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.c 
b/drivers/net/ethernet/freescale/fman/fman_keygen.c
new file mode 100644
index 000..f54da3c
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fman_keygen.c
@@ -0,0 +1,783 @@
+/*
+ * Copyright 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 NXP 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
+

[PATCH v3 3/7] dpaa_eth: use multiple Rx frame queues

2017-08-24 Thread Madalin Bucur
Add a block of 128 Rx frame queues per port. The FMan hardware will
send traffic on one of these queues based on the FMan port Parse
Classify Distribute setup. The hash computed by the FMan Keygen
block will select the Rx FQ.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 50 +++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  1 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |  3 ++
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index c7fa285..6d89e74 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -158,7 +158,7 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
 #define DPAA_RX_PRIV_DATA_SIZE (u16)(DPAA_TX_PRIV_DATA_SIZE + \
dpaa_rx_extra_headroom)
 
-#define DPAA_ETH_RX_QUEUES 128
+#define DPAA_ETH_PCD_RXQ_NUM   128
 
 #define DPAA_ENQUEUE_RETRIES   10
 
@@ -169,6 +169,7 @@ struct fm_port_fqs {
struct dpaa_fq *tx_errq;
struct dpaa_fq *rx_defq;
struct dpaa_fq *rx_errq;
+   struct dpaa_fq *rx_pcdq;
 };
 
 /* All the dpa bps in use at any moment */
@@ -628,6 +629,7 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq, int 
idx)
fq->wq = 5;
break;
case FQ_TYPE_RX_DEFAULT:
+   case FQ_TYPE_RX_PCD:
fq->wq = 6;
break;
case FQ_TYPE_TX:
@@ -688,6 +690,7 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct 
list_head *list,
  struct fm_port_fqs *port_fqs)
 {
struct dpaa_fq *dpaa_fq;
+   u32 fq_base, fq_base_aligned, i;
 
dpaa_fq = dpaa_fq_alloc(dev, 0, 1, list, FQ_TYPE_RX_ERROR);
if (!dpaa_fq)
@@ -701,6 +704,26 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct 
list_head *list,
 
port_fqs->rx_defq = _fq[0];
 
+   /* the PCD FQIDs range needs to be aligned for correct operation */
+   if (qman_alloc_fqid_range(_base, 2 * DPAA_ETH_PCD_RXQ_NUM))
+   goto fq_alloc_failed;
+
+   fq_base_aligned = ALIGN(fq_base, DPAA_ETH_PCD_RXQ_NUM);
+
+   for (i = fq_base; i < fq_base_aligned; i++)
+   qman_release_fqid(i);
+
+   for (i = fq_base_aligned + DPAA_ETH_PCD_RXQ_NUM;
+i < (fq_base + 2 * DPAA_ETH_PCD_RXQ_NUM); i++)
+   qman_release_fqid(i);
+
+   dpaa_fq = dpaa_fq_alloc(dev, fq_base_aligned, DPAA_ETH_PCD_RXQ_NUM,
+   list, FQ_TYPE_RX_PCD);
+   if (!dpaa_fq)
+   goto fq_alloc_failed;
+
+   port_fqs->rx_pcdq = _fq[0];
+
if (!dpaa_fq_alloc(dev, 0, DPAA_ETH_TXQ_NUM, list, FQ_TYPE_TX_CONF_MQ))
goto fq_alloc_failed;
 
@@ -870,13 +893,14 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
  const struct dpaa_fq_cbs *fq_cbs,
  struct fman_port *tx_port)
 {
-   int egress_cnt = 0, conf_cnt = 0, num_portals = 0, cpu;
+   int egress_cnt = 0, conf_cnt = 0, num_portals = 0, portal_cnt = 0, cpu;
const cpumask_t *affine_cpus = qman_affine_cpus();
-   u16 portals[NR_CPUS];
+   u16 channels[NR_CPUS];
struct dpaa_fq *fq;
 
for_each_cpu(cpu, affine_cpus)
-   portals[num_portals++] = qman_affine_channel(cpu);
+   channels[num_portals++] = qman_affine_channel(cpu);
+
if (num_portals == 0)
dev_err(priv->net_dev->dev.parent,
"No Qman software (affine) channels found");
@@ -890,6 +914,12 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
case FQ_TYPE_RX_ERROR:
dpaa_setup_ingress(priv, fq, _cbs->rx_errq);
break;
+   case FQ_TYPE_RX_PCD:
+   if (!num_portals)
+   continue;
+   dpaa_setup_ingress(priv, fq, _cbs->rx_defq);
+   fq->channel = channels[portal_cnt++ % num_portals];
+   break;
case FQ_TYPE_TX:
dpaa_setup_egress(priv, fq, tx_port,
  _cbs->egress_ern);
@@ -1039,7 +1069,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool 
td_enable)
/* Put all the ingress queues in our "ingress CGR". */
if (priv->use_ingress_cgr &&
(dpaa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
-dpaa_fq->fq_type == FQ_TYPE_RX_ERROR)) {
+dpaa_fq->fq_type == FQ_TYPE_RX_ERROR ||
+dpaa_fq->fq_type == FQ_TYPE_RX_PCD)) {
initfq.we_mask |= cpu_to_b

[PATCH v3 1/7] fsl/fman: move struct fman to header file

2017-08-24 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c | 74 --
 drivers/net/ethernet/freescale/fman/fman.h | 73 +
 2 files changed, 73 insertions(+), 74 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index e714b8f..6ed383f 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -564,80 +564,6 @@ struct fman_cfg {
u32 qmi_def_tnums_thresh;
 };
 
-/* Structure that holds information received from device tree */
-struct fman_dts_params {
-   void __iomem *base_addr;/* FMan virtual address */
-   struct resource *res;   /* FMan memory resource */
-   u8 id;  /* FMan ID */
-
-   int err_irq;/* FMan Error IRQ */
-
-   u16 clk_freq;   /* FMan clock freq (In Mhz) */
-
-   u32 qman_channel_base;  /* QMan channels base */
-   u32 num_of_qman_channels;   /* Number of QMan channels */
-
-   struct resource muram_res;  /* MURAM resource */
-};
-
-/** fman_exceptions_cb
- * fman- Pointer to FMan
- * exception   - The exception.
- *
- * Exceptions user callback routine, will be called upon an exception
- * passing the exception identification.
- *
- * Return: irq status
- */
-typedef irqreturn_t (fman_exceptions_cb)(struct fman *fman,
-enum fman_exceptions exception);
-
-/** fman_bus_error_cb
- * fman- Pointer to FMan
- * port_id - Port id
- * addr- Address that caused the error
- * tnum- Owner of error
- * liodn   - Logical IO device number
- *
- * Bus error user callback routine, will be called upon bus error,
- * passing parameters describing the errors and the owner.
- *
- * Return: IRQ status
- */
-typedef irqreturn_t (fman_bus_error_cb)(struct fman *fman, u8 port_id,
-   u64 addr, u8 tnum, u16 liodn);
-
-struct fman {
-   struct device *dev;
-   void __iomem *base_addr;
-   struct fman_intr_src intr_mng[FMAN_EV_CNT];
-
-   struct fman_fpm_regs __iomem *fpm_regs;
-   struct fman_bmi_regs __iomem *bmi_regs;
-   struct fman_qmi_regs __iomem *qmi_regs;
-   struct fman_dma_regs __iomem *dma_regs;
-   struct fman_hwp_regs __iomem *hwp_regs;
-   fman_exceptions_cb *exception_cb;
-   fman_bus_error_cb *bus_error_cb;
-   /* Spinlock for FMan use */
-   spinlock_t spinlock;
-   struct fman_state_struct *state;
-
-   struct fman_cfg *cfg;
-   struct muram_info *muram;
-   /* cam section in muram */
-   unsigned long cam_offset;
-   size_t cam_size;
-   /* Fifo in MURAM */
-   unsigned long fifo_offset;
-   size_t fifo_size;
-
-   u32 liodn_base[64];
-   u32 liodn_offset[64];
-
-   struct fman_dts_params dts_params;
-};
-
 static irqreturn_t fman_exceptions(struct fman *fman,
   enum fman_exceptions exception)
 {
diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index f53e147..6745065 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -274,6 +274,79 @@ struct fman_intr_src {
void *src_handle;
 };
 
+/** fman_exceptions_cb
+ * fman - Pointer to FMan
+ * exception- The exception.
+ *
+ * Exceptions user callback routine, will be called upon an exception
+ * passing the exception identification.
+ *
+ * Return: irq status
+ */
+typedef irqreturn_t (fman_exceptions_cb)(struct fman *fman,
+enum fman_exceptions exception);
+/** fman_bus_error_cb
+ * fman - Pointer to FMan
+ * port_id  - Port id
+ * addr - Address that caused the error
+ * tnum - Owner of error
+ * liodn- Logical IO device number
+ *
+ * Bus error user callback routine, will be called upon bus error,
+ * passing parameters describing the errors and the owner.
+ *
+ * Return: IRQ status
+ */
+typedef irqreturn_t (fman_bus_error_cb)(struct fman *fman, u8 port_id,
+   u64 addr, u8 tnum, u16 liodn);
+
+/* Structure that holds information received from device tree */
+struct fman_dts_params {
+   void __iomem *base_addr;/* FMan virtual address */
+   struct resource *res;   /* FMan memory resource */
+   u8 id;  /* FMan ID */
+
+   int err_irq;/* FMan Error IRQ */
+
+   u16 clk_freq;   /* FMan clock freq (In Mhz) */
+
+   u32 qman_channel_base;  /* QMan channels base */
+

[PATCH v3 0/7] Add RSS to DPAA 1.x Ethernet driver

2017-08-24 Thread Madalin Bucur
This patch set introduces Receive Side Scaling for the DPAA Ethernet
driver. Documentation is updated with details related to the new
feature and limitations that apply.
Added also a small fix.

v2: removed a C++ style comment
v3: move struct fman to header file to avoid exporting a function

Iordache Florinel-R70177 (1):
  fsl/fman: enable FMan Keygen

Madalin Bucur (6):
  fsl/fman: move struct fman to header file
  dpaa_eth: use multiple Rx frame queues
  dpaa_eth: enable Rx hashing control
  dpaa_eth: add NETIF_F_RXHASH
  Documentation: networking: add RSS information
  dpaa_eth: check allocation result

 Documentation/networking/dpaa.txt  |  68 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  76 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |   3 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 118 
 drivers/net/ethernet/freescale/fman/Makefile   |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c |  82 +--
 drivers/net/ethernet/freescale/fman/fman.h |  75 ++
 drivers/net/ethernet/freescale/fman/fman_keygen.c  | 783 +
 drivers/net/ethernet/freescale/fman/fman_keygen.h  |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c|  51 +-
 drivers/net/ethernet/freescale/fman/fman_port.h|   7 +
 12 files changed, 1226 insertions(+), 87 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

-- 
2.1.0



[PATCH v2 6/6] dpaa_eth: check allocation result

2017-08-22 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 73ca8d7..4225806 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2561,6 +2561,9 @@ static struct dpaa_bp *dpaa_bp_alloc(struct device *dev)
 
dpaa_bp->bpid = FSL_DPAA_BPID_INV;
dpaa_bp->percpu_count = devm_alloc_percpu(dev, *dpaa_bp->percpu_count);
+   if (!dpaa_bp->percpu_count)
+   return ERR_PTR(-ENOMEM);
+
dpaa_bp->config_count = FSL_DPAA_ETH_MAX_BUF_COUNT;
 
dpaa_bp->seed_cb = dpaa_bp_seed;
-- 
2.1.0



[PATCH v2 5/6] Documentation: networking: add RSS information

2017-08-22 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 Documentation/networking/dpaa.txt | 68 ++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/dpaa.txt 
b/Documentation/networking/dpaa.txt
index 76e016d..f88194f 100644
--- a/Documentation/networking/dpaa.txt
+++ b/Documentation/networking/dpaa.txt
@@ -13,6 +13,7 @@ Contents
- Configuring DPAA Ethernet in your kernel
- DPAA Ethernet Frame Processing
- DPAA Ethernet Features
+   - DPAA IRQ Affinity and Receive Side Scaling
- Debugging
 
 DPAA Ethernet Overview
@@ -147,7 +148,10 @@ gradually.
 
 The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx
 checksum offload feature is enabled by default and cannot be controlled through
-ethtool.
+ethtool. Also, rx-flow-hash and rx-hashing was added. The addition of RSS
+provides a big performance boost for the forwarding scenarios, allowing
+different traffic flows received by one interface to be processed by different
+CPUs in parallel.
 
 The driver has support for multiple prioritized Tx traffic classes. Priorities
 range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with
@@ -166,6 +170,68 @@ classes as follows:
 tc qdisc add dev  root handle 1: \
 mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1
 
+DPAA IRQ Affinity and Receive Side Scaling
+==
+
+Traffic coming on the DPAA Rx queues or on the DPAA Tx confirmation
+queues is seen by the CPU as ingress traffic on a certain portal.
+The DPAA QMan portal interrupts are affined each to a certain CPU.
+The same portal interrupt services all the QMan portal consumers.
+
+By default the DPAA Ethernet driver enables RSS, making use of the
+DPAA FMan Parser and Keygen blocks to distribute traffic on 128
+hardware frame queues using a hash on IP v4/v6 source and destination
+and L4 source and destination ports, in present in the received frame.
+When RSS is disabled, all traffic received by a certain interface is
+received on the default Rx frame queue. The default DPAA Rx frame
+queues are configured to put the received traffic into a pool channel
+that allows any available CPU portal to dequeue the ingress traffic.
+The default frame queues have the HOLDACTIVE option set, ensuring that
+traffic bursts from a certain queue are serviced by the same CPU.
+This ensures a very low rate of frame reordering. A drawback of this
+is that only one CPU at a time can service the traffic received by a
+certain interface when RSS is not enabled.
+
+To implement RSS, the DPAA Ethernet driver allocates an extra set of
+128 Rx frame queues that are configured to dedicated channels, in a
+round-robin manner. The mapping of the frame queues to CPUs is now
+hardcoded, there is no indirection table to move traffic for a certain
+FQ (hash result) to another CPU. The ingress traffic arriving on one
+of these frame queues will arrive at the same portal and will always
+be processed by the same CPU. This ensures intra-flow order preservation
+and workload distribution for multiple traffic flows.
+
+RSS can be turned off for a certain interface using ethtool, i.e.
+
+   # ethtool -N fm1-mac9 rx-flow-hash tcp4 ""
+
+To turn it back on, one needs to set rx-flow-hash for tcp4/6 or udp4/6:
+
+   # ethtool -N fm1-mac9 rx-flow-hash udp4 sfdn
+
+There is no independent control for individual protocols, any command
+run for one of tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 is
+going to control the rx-flow-hashing for all protocols on that interface.
+
+Besides using the FMan Keygen computed hash for spreading traffic on the
+128 Rx FQs, the DPAA Ethernet driver also sets the skb hash value when
+the NETIF_F_RXHASH feature is on (active by default). This can be turned
+on or off through ethtool, i.e.:
+
+   # ethtool -K fm1-mac9 rx-hashing off
+   # ethtool -k fm1-mac9 | grep hash
+   receive-hashing: off
+   # ethtool -K fm1-mac9 rx-hashing on
+   Actual changes:
+   receive-hashing: on
+   # ethtool -k fm1-mac9 | grep hash
+   receive-hashing: on
+
+Please note that Rx hashing depends upon the rx-flow-hashing being on
+for that interface - turning off rx-flow-hashing will also disable the
+rx-hashing (without ethtool reporting it as off as that depends on the
+NETIF_F_RXHASH feature flag).
+
 Debugging
 =
 
-- 
2.1.0



[PATCH v2 4/6] dpaa_eth: add NETIF_F_RXHASH

2017-08-22 Thread Madalin Bucur
Set the skb hash when then FMan Keygen hash result is available.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 23 +++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  1 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |  9 +++--
 drivers/net/ethernet/freescale/fman/fman_port.c| 11 +++
 drivers/net/ethernet/freescale/fman/fman_port.h|  2 ++
 5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 6d89e74..73ca8d7 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -236,7 +236,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
net_dev->max_mtu = dpaa_get_max_mtu();
 
net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-NETIF_F_LLTX);
+NETIF_F_LLTX | NETIF_F_RXHASH);
 
net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
/* The kernels enables GSO automatically, if we declare NETIF_F_SG.
@@ -2237,12 +2237,13 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_addr_t addr = qm_fd_addr(fd);
enum qm_fd_format fd_format;
struct net_device *net_dev;
-   u32 fd_status;
+   u32 fd_status, hash_offset;
struct dpaa_bp *dpaa_bp;
struct dpaa_priv *priv;
unsigned int skb_len;
struct sk_buff *skb;
int *count_ptr;
+   void *vaddr;
 
fd_status = be32_to_cpu(fd->status);
fd_format = qm_fd_get_format(fd);
@@ -2288,7 +2289,8 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE);
 
/* prefetch the first 64 bytes of the frame or the SGT start */
-   prefetch(phys_to_virt(addr) + qm_fd_get_offset(fd));
+   vaddr = phys_to_virt(addr);
+   prefetch(vaddr + qm_fd_get_offset(fd));
 
fd_format = qm_fd_get_format(fd);
/* The only FD types that we may receive are contig and S/G */
@@ -2309,6 +2311,18 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
 
skb->protocol = eth_type_trans(skb, net_dev);
 
+   if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
+   !fman_port_get_hash_result_offset(priv->mac_dev->port[RX],
+ _offset)) {
+   enum pkt_hash_types type;
+
+   /* if L4 exists, it was used in the hash generation */
+   type = be32_to_cpu(fd->status) & FM_FD_STAT_L4CV ?
+   PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3;
+   skb_set_hash(skb, be32_to_cpu(*(u32 *)(vaddr + hash_offset)),
+type);
+   }
+
skb_len = skb->len;
 
if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
@@ -2774,6 +2788,9 @@ static int dpaa_eth_probe(struct platform_device *pdev)
if (err)
goto init_ports_failed;
 
+   /* Rx traffic distribution based on keygen hashing defaults to on */
+   priv->keygen_in_use = true;
+
priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (!priv->percpu_priv) {
dev_err(dev, "devm_alloc_percpu() failed\n");
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 496a12c..bd94220 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -159,6 +159,7 @@ struct dpaa_priv {
struct list_head dpaa_fq_list;
 
u8 num_tc;
+   bool keygen_in_use;
u32 msg_enable; /* net_device message level */
 
struct {
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 965f652..faea674 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -402,6 +402,8 @@ static void dpaa_get_strings(struct net_device *net_dev, 
u32 stringset,
 static int dpaa_get_hash_opts(struct net_device *dev,
  struct ethtool_rxnfc *cmd)
 {
+   struct dpaa_priv *priv = netdev_priv(dev);
+
cmd->data = 0;
 
switch (cmd->flow_type) {
@@ -409,7 +411,8 @@ static int dpaa_get_hash_opts(struct net_device *dev,
case TCP_V6_FLOW:
case UDP_V4_FLOW:
case UDP_V6_FLOW:
-   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+   if (priv->keygen_in_use)
+   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
/* Fall through */
case I

[PATCH v2 1/6] fsl/fman: enable FMan Keygen

2017-08-22 Thread Madalin Bucur
From: Iordache Florinel-R70177 <florinel.iorda...@nxp.com>

Add support for the FMan Keygen with a hardcoded scheme to spread
incoming traffic on a FQ range based on source and destination IPs
and ports.

Signed-off-by: Iordache Florinel <florinel.iorda...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Makefile  |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c|  26 +
 drivers/net/ethernet/freescale/fman/fman.h|   2 +
 drivers/net/ethernet/freescale/fman/fman_keygen.c | 783 ++
 drivers/net/ethernet/freescale/fman/fman_keygen.h |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c   |  40 +-
 drivers/net/ethernet/freescale/fman/fman_port.h   |   5 +
 7 files changed, 902 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index 6049177..2c38119 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -4,6 +4,6 @@ obj-$(CONFIG_FSL_FMAN) += fsl_fman.o
 obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o
 obj-$(CONFIG_FSL_FMAN) += fsl_mac.o
 
-fsl_fman-objs  := fman_muram.o fman.o fman_sp.o
+fsl_fman-objs  := fman_muram.o fman.o fman_sp.o fman_keygen.o
 fsl_fman_port-objs := fman_port.o
 fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index e714b8f..491a5ac 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -34,6 +34,7 @@
 
 #include "fman.h"
 #include "fman_muram.h"
+#include "fman_keygen.h"
 
 #include 
 #include 
@@ -56,6 +57,7 @@
 /* Modules registers offsets */
 #define BMI_OFFSET 0x0008
 #define QMI_OFFSET 0x00080400
+#define KG_OFFSET  0x000C1000
 #define DMA_OFFSET 0x000C2000
 #define FPM_OFFSET 0x000C3000
 #define IMEM_OFFSET0x000C4000
@@ -617,6 +619,7 @@ struct fman {
struct fman_qmi_regs __iomem *qmi_regs;
struct fman_dma_regs __iomem *dma_regs;
struct fman_hwp_regs __iomem *hwp_regs;
+   struct fman_kg_regs __iomem *kg_regs;
fman_exceptions_cb *exception_cb;
fman_bus_error_cb *bus_error_cb;
/* Spinlock for FMan use */
@@ -631,6 +634,8 @@ struct fman {
/* Fifo in MURAM */
unsigned long fifo_offset;
size_t fifo_size;
+   /* KeyGen handle */
+   struct fman_keygen *keygen;
 
u32 liodn_base[64];
u32 liodn_offset[64];
@@ -1811,6 +1816,7 @@ static int fman_config(struct fman *fman)
fman->qmi_regs = base_addr + QMI_OFFSET;
fman->dma_regs = base_addr + DMA_OFFSET;
fman->hwp_regs = base_addr + HWP_OFFSET;
+   fman->kg_regs = base_addr + KG_OFFSET;
fman->base_addr = base_addr;
 
spin_lock_init(>spinlock);
@@ -2083,6 +2089,11 @@ static int fman_init(struct fman *fman)
/* Init HW Parser */
hwp_init(fman->hwp_regs);
 
+   /* Init KeyGen */
+   fman->keygen = keygen_init(fman->kg_regs);
+   if (!fman->keygen)
+   return -EINVAL;
+
err = enable(fman, cfg);
if (err != 0)
return err;
@@ -2562,6 +2573,21 @@ int fman_get_rx_extra_headroom(void)
 EXPORT_SYMBOL(fman_get_rx_extra_headroom);
 
 /**
+ * fman_get_keygen
+ *
+ * @fman:  A Pointer to FMan device
+ *
+ * Get the handle to KeyGen module part of FM driver
+ *
+ * Return: Handle to KeyGen
+ */
+struct fman_keygen *fman_get_keygen(struct fman *fman)
+{
+   return fman->keygen;
+}
+EXPORT_SYMBOL(fman_get_keygen);
+
+/**
  * fman_bind
  * @dev:   FMan OF device pointer
  *
diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index f53e147..291990e 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -320,6 +320,8 @@ u16 fman_get_max_frm(void);
 
 int fman_get_rx_extra_headroom(void);
 
+struct fman_keygen *fman_get_keygen(struct fman *fman);
+
 struct fman *fman_bind(struct device *dev);
 
 #endif /* __FM_H */
diff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.c 
b/drivers/net/ethernet/freescale/fman/fman_keygen.c
new file mode 100644
index 000..f54da3c
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fman_keygen.c
@@ -0,0 +1,783 @@
+/*
+ * Copyright 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 

[PATCH v2 3/6] dpaa_eth: enable Rx hashing control

2017-08-22 Thread Madalin Bucur
Allow ethtool control of the Rx flow hashing. By default RSS is
enabled, this allows to turn it off by bypassing the FMan Keygen
block and sending all traffic on the default Rx frame queue.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 113 +
 1 file changed, 113 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index aad825088..965f652 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -399,6 +399,117 @@ static void dpaa_get_strings(struct net_device *net_dev, 
u32 stringset,
memcpy(strings, dpaa_stats_global, size);
 }
 
+static int dpaa_get_hash_opts(struct net_device *dev,
+ struct ethtool_rxnfc *cmd)
+{
+   cmd->data = 0;
+
+   switch (cmd->flow_type) {
+   case TCP_V4_FLOW:
+   case TCP_V6_FLOW:
+   case UDP_V4_FLOW:
+   case UDP_V6_FLOW:
+   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+   /* Fall through */
+   case IPV4_FLOW:
+   case IPV6_FLOW:
+   case SCTP_V4_FLOW:
+   case SCTP_V6_FLOW:
+   case AH_ESP_V4_FLOW:
+   case AH_ESP_V6_FLOW:
+   case AH_V4_FLOW:
+   case AH_V6_FLOW:
+   case ESP_V4_FLOW:
+   case ESP_V6_FLOW:
+   cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+   break;
+   default:
+   cmd->data = 0;
+   break;
+   }
+
+   return 0;
+}
+
+static int dpaa_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *unused)
+{
+   int ret = -EOPNOTSUPP;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_GRXFH:
+   ret = dpaa_get_hash_opts(dev, cmd);
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static void dpaa_set_hash(struct net_device *net_dev, bool enable)
+{
+   struct mac_device *mac_dev;
+   struct fman_port *rxport;
+   struct dpaa_priv *priv;
+
+   priv = netdev_priv(net_dev);
+   mac_dev = priv->mac_dev;
+   rxport = mac_dev->port[0];
+
+   fman_port_use_kg_hash(rxport, enable);
+}
+
+static int dpaa_set_hash_opts(struct net_device *dev,
+ struct ethtool_rxnfc *nfc)
+{
+   int ret = -EINVAL;
+
+   /* we support hashing on IPv4/v6 src/dest IP and L4 src/dest port */
+   if (nfc->data &
+   ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3))
+   return -EINVAL;
+
+   switch (nfc->flow_type) {
+   case TCP_V4_FLOW:
+   case TCP_V6_FLOW:
+   case UDP_V4_FLOW:
+   case UDP_V6_FLOW:
+   case IPV4_FLOW:
+   case IPV6_FLOW:
+   case SCTP_V4_FLOW:
+   case SCTP_V6_FLOW:
+   case AH_ESP_V4_FLOW:
+   case AH_ESP_V6_FLOW:
+   case AH_V4_FLOW:
+   case AH_V6_FLOW:
+   case ESP_V4_FLOW:
+   case ESP_V6_FLOW:
+   dpaa_set_hash(dev, !!nfc->data);
+   ret = 0;
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static int dpaa_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+   int ret = -EOPNOTSUPP;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_SRXFH:
+   ret = dpaa_set_hash_opts(dev, cmd);
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
 const struct ethtool_ops dpaa_ethtool_ops = {
.get_drvinfo = dpaa_get_drvinfo,
.get_msglevel = dpaa_get_msglevel,
@@ -412,4 +523,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
.get_strings = dpaa_get_strings,
.get_link_ksettings = dpaa_get_link_ksettings,
.set_link_ksettings = dpaa_set_link_ksettings,
+   .get_rxnfc = dpaa_get_rxnfc,
+   .set_rxnfc = dpaa_set_rxnfc,
 };
-- 
2.1.0



[PATCH v2 2/6] dpaa_eth: use multiple Rx frame queues

2017-08-22 Thread Madalin Bucur
Add a block of 128 Rx frame queues per port. The FMan hardware will
send traffic on one of these queues based on the FMan port Parse
Classify Distribute setup. The hash computed by the FMan Keygen
block will select the Rx FQ.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 50 +++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  1 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |  3 ++
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index c7fa285..6d89e74 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -158,7 +158,7 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
 #define DPAA_RX_PRIV_DATA_SIZE (u16)(DPAA_TX_PRIV_DATA_SIZE + \
dpaa_rx_extra_headroom)
 
-#define DPAA_ETH_RX_QUEUES 128
+#define DPAA_ETH_PCD_RXQ_NUM   128
 
 #define DPAA_ENQUEUE_RETRIES   10
 
@@ -169,6 +169,7 @@ struct fm_port_fqs {
struct dpaa_fq *tx_errq;
struct dpaa_fq *rx_defq;
struct dpaa_fq *rx_errq;
+   struct dpaa_fq *rx_pcdq;
 };
 
 /* All the dpa bps in use at any moment */
@@ -628,6 +629,7 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq, int 
idx)
fq->wq = 5;
break;
case FQ_TYPE_RX_DEFAULT:
+   case FQ_TYPE_RX_PCD:
fq->wq = 6;
break;
case FQ_TYPE_TX:
@@ -688,6 +690,7 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct 
list_head *list,
  struct fm_port_fqs *port_fqs)
 {
struct dpaa_fq *dpaa_fq;
+   u32 fq_base, fq_base_aligned, i;
 
dpaa_fq = dpaa_fq_alloc(dev, 0, 1, list, FQ_TYPE_RX_ERROR);
if (!dpaa_fq)
@@ -701,6 +704,26 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct 
list_head *list,
 
port_fqs->rx_defq = _fq[0];
 
+   /* the PCD FQIDs range needs to be aligned for correct operation */
+   if (qman_alloc_fqid_range(_base, 2 * DPAA_ETH_PCD_RXQ_NUM))
+   goto fq_alloc_failed;
+
+   fq_base_aligned = ALIGN(fq_base, DPAA_ETH_PCD_RXQ_NUM);
+
+   for (i = fq_base; i < fq_base_aligned; i++)
+   qman_release_fqid(i);
+
+   for (i = fq_base_aligned + DPAA_ETH_PCD_RXQ_NUM;
+i < (fq_base + 2 * DPAA_ETH_PCD_RXQ_NUM); i++)
+   qman_release_fqid(i);
+
+   dpaa_fq = dpaa_fq_alloc(dev, fq_base_aligned, DPAA_ETH_PCD_RXQ_NUM,
+   list, FQ_TYPE_RX_PCD);
+   if (!dpaa_fq)
+   goto fq_alloc_failed;
+
+   port_fqs->rx_pcdq = _fq[0];
+
if (!dpaa_fq_alloc(dev, 0, DPAA_ETH_TXQ_NUM, list, FQ_TYPE_TX_CONF_MQ))
goto fq_alloc_failed;
 
@@ -870,13 +893,14 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
  const struct dpaa_fq_cbs *fq_cbs,
  struct fman_port *tx_port)
 {
-   int egress_cnt = 0, conf_cnt = 0, num_portals = 0, cpu;
+   int egress_cnt = 0, conf_cnt = 0, num_portals = 0, portal_cnt = 0, cpu;
const cpumask_t *affine_cpus = qman_affine_cpus();
-   u16 portals[NR_CPUS];
+   u16 channels[NR_CPUS];
struct dpaa_fq *fq;
 
for_each_cpu(cpu, affine_cpus)
-   portals[num_portals++] = qman_affine_channel(cpu);
+   channels[num_portals++] = qman_affine_channel(cpu);
+
if (num_portals == 0)
dev_err(priv->net_dev->dev.parent,
"No Qman software (affine) channels found");
@@ -890,6 +914,12 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
case FQ_TYPE_RX_ERROR:
dpaa_setup_ingress(priv, fq, _cbs->rx_errq);
break;
+   case FQ_TYPE_RX_PCD:
+   if (!num_portals)
+   continue;
+   dpaa_setup_ingress(priv, fq, _cbs->rx_defq);
+   fq->channel = channels[portal_cnt++ % num_portals];
+   break;
case FQ_TYPE_TX:
dpaa_setup_egress(priv, fq, tx_port,
  _cbs->egress_ern);
@@ -1039,7 +1069,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool 
td_enable)
/* Put all the ingress queues in our "ingress CGR". */
if (priv->use_ingress_cgr &&
(dpaa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
-dpaa_fq->fq_type == FQ_TYPE_RX_ERROR)) {
+dpaa_fq->fq_type == FQ_TYPE_RX_ERROR ||
+dpaa_fq->fq_type == FQ_TYPE_RX_PCD)) {
initfq.we_mask |= cpu_to_b

[PATCH v2 0/6] Add RSS to DPAA 1.x Ethernet driver

2017-08-22 Thread Madalin Bucur
This patch set introduces Receive Side Scaling for the DPAA Ethernet
driver. Documentation is updated with details related to the new
feature and limitations that apply.
Added also a small fix.

Change from v1: removed a C++ style comment

Iordache Florinel-R70177 (1):
  fsl/fman: enable FMan Keygen

Madalin Bucur (5):
  dpaa_eth: use multiple Rx frame queues
  dpaa_eth: enable Rx hashing control
  dpaa_eth: add NETIF_F_RXHASH
  Documentation: networking: add RSS information
  dpaa_eth: check allocation result

 Documentation/networking/dpaa.txt  |  68 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  76 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |   3 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 118 
 drivers/net/ethernet/freescale/fman/Makefile   |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c |  26 +
 drivers/net/ethernet/freescale/fman/fman.h |   2 +
 drivers/net/ethernet/freescale/fman/fman_keygen.c  | 783 +
 drivers/net/ethernet/freescale/fman/fman_keygen.h  |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c|  51 +-
 drivers/net/ethernet/freescale/fman/fman_port.h|   7 +
 12 files changed, 1171 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

-- 
2.1.0



[PATCH 6/6] dpaa_eth: check allocation result

2017-08-18 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index ef30038..ff7f153 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2557,6 +2557,9 @@ static struct dpaa_bp *dpaa_bp_alloc(struct device *dev)
 
dpaa_bp->bpid = FSL_DPAA_BPID_INV;
dpaa_bp->percpu_count = devm_alloc_percpu(dev, *dpaa_bp->percpu_count);
+   if (!dpaa_bp->percpu_count)
+   return ERR_PTR(-ENOMEM);
+
dpaa_bp->config_count = FSL_DPAA_ETH_MAX_BUF_COUNT;
 
dpaa_bp->seed_cb = dpaa_bp_seed;
-- 
2.1.0



[PATCH 3/6] dpaa_eth: enable Rx hashing control

2017-08-18 Thread Madalin Bucur
Allow ethtool control of the Rx flow hashing. By default RSS is
enabled, this allows to turn it off by bypassing the FMan Keygen
block and sending all traffic on the default Rx frame queue.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 113 +
 1 file changed, 113 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index aad825088..965f652 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -399,6 +399,117 @@ static void dpaa_get_strings(struct net_device *net_dev, 
u32 stringset,
memcpy(strings, dpaa_stats_global, size);
 }
 
+static int dpaa_get_hash_opts(struct net_device *dev,
+ struct ethtool_rxnfc *cmd)
+{
+   cmd->data = 0;
+
+   switch (cmd->flow_type) {
+   case TCP_V4_FLOW:
+   case TCP_V6_FLOW:
+   case UDP_V4_FLOW:
+   case UDP_V6_FLOW:
+   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+   /* Fall through */
+   case IPV4_FLOW:
+   case IPV6_FLOW:
+   case SCTP_V4_FLOW:
+   case SCTP_V6_FLOW:
+   case AH_ESP_V4_FLOW:
+   case AH_ESP_V6_FLOW:
+   case AH_V4_FLOW:
+   case AH_V6_FLOW:
+   case ESP_V4_FLOW:
+   case ESP_V6_FLOW:
+   cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+   break;
+   default:
+   cmd->data = 0;
+   break;
+   }
+
+   return 0;
+}
+
+static int dpaa_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *unused)
+{
+   int ret = -EOPNOTSUPP;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_GRXFH:
+   ret = dpaa_get_hash_opts(dev, cmd);
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static void dpaa_set_hash(struct net_device *net_dev, bool enable)
+{
+   struct mac_device *mac_dev;
+   struct fman_port *rxport;
+   struct dpaa_priv *priv;
+
+   priv = netdev_priv(net_dev);
+   mac_dev = priv->mac_dev;
+   rxport = mac_dev->port[0];
+
+   fman_port_use_kg_hash(rxport, enable);
+}
+
+static int dpaa_set_hash_opts(struct net_device *dev,
+ struct ethtool_rxnfc *nfc)
+{
+   int ret = -EINVAL;
+
+   /* we support hashing on IPv4/v6 src/dest IP and L4 src/dest port */
+   if (nfc->data &
+   ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3))
+   return -EINVAL;
+
+   switch (nfc->flow_type) {
+   case TCP_V4_FLOW:
+   case TCP_V6_FLOW:
+   case UDP_V4_FLOW:
+   case UDP_V6_FLOW:
+   case IPV4_FLOW:
+   case IPV6_FLOW:
+   case SCTP_V4_FLOW:
+   case SCTP_V6_FLOW:
+   case AH_ESP_V4_FLOW:
+   case AH_ESP_V6_FLOW:
+   case AH_V4_FLOW:
+   case AH_V6_FLOW:
+   case ESP_V4_FLOW:
+   case ESP_V6_FLOW:
+   dpaa_set_hash(dev, !!nfc->data);
+   ret = 0;
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
+static int dpaa_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+   int ret = -EOPNOTSUPP;
+
+   switch (cmd->cmd) {
+   case ETHTOOL_SRXFH:
+   ret = dpaa_set_hash_opts(dev, cmd);
+   break;
+   default:
+   break;
+   }
+
+   return ret;
+}
+
 const struct ethtool_ops dpaa_ethtool_ops = {
.get_drvinfo = dpaa_get_drvinfo,
.get_msglevel = dpaa_get_msglevel,
@@ -412,4 +523,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
.get_strings = dpaa_get_strings,
.get_link_ksettings = dpaa_get_link_ksettings,
.set_link_ksettings = dpaa_set_link_ksettings,
+   .get_rxnfc = dpaa_get_rxnfc,
+   .set_rxnfc = dpaa_set_rxnfc,
 };
-- 
2.1.0



[PATCH 5/6] Documentation: networking: add RSS information

2017-08-18 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 Documentation/networking/dpaa.txt | 68 ++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/dpaa.txt 
b/Documentation/networking/dpaa.txt
index 76e016d..f88194f 100644
--- a/Documentation/networking/dpaa.txt
+++ b/Documentation/networking/dpaa.txt
@@ -13,6 +13,7 @@ Contents
- Configuring DPAA Ethernet in your kernel
- DPAA Ethernet Frame Processing
- DPAA Ethernet Features
+   - DPAA IRQ Affinity and Receive Side Scaling
- Debugging
 
 DPAA Ethernet Overview
@@ -147,7 +148,10 @@ gradually.
 
 The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx
 checksum offload feature is enabled by default and cannot be controlled through
-ethtool.
+ethtool. Also, rx-flow-hash and rx-hashing was added. The addition of RSS
+provides a big performance boost for the forwarding scenarios, allowing
+different traffic flows received by one interface to be processed by different
+CPUs in parallel.
 
 The driver has support for multiple prioritized Tx traffic classes. Priorities
 range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with
@@ -166,6 +170,68 @@ classes as follows:
 tc qdisc add dev  root handle 1: \
 mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1
 
+DPAA IRQ Affinity and Receive Side Scaling
+==
+
+Traffic coming on the DPAA Rx queues or on the DPAA Tx confirmation
+queues is seen by the CPU as ingress traffic on a certain portal.
+The DPAA QMan portal interrupts are affined each to a certain CPU.
+The same portal interrupt services all the QMan portal consumers.
+
+By default the DPAA Ethernet driver enables RSS, making use of the
+DPAA FMan Parser and Keygen blocks to distribute traffic on 128
+hardware frame queues using a hash on IP v4/v6 source and destination
+and L4 source and destination ports, in present in the received frame.
+When RSS is disabled, all traffic received by a certain interface is
+received on the default Rx frame queue. The default DPAA Rx frame
+queues are configured to put the received traffic into a pool channel
+that allows any available CPU portal to dequeue the ingress traffic.
+The default frame queues have the HOLDACTIVE option set, ensuring that
+traffic bursts from a certain queue are serviced by the same CPU.
+This ensures a very low rate of frame reordering. A drawback of this
+is that only one CPU at a time can service the traffic received by a
+certain interface when RSS is not enabled.
+
+To implement RSS, the DPAA Ethernet driver allocates an extra set of
+128 Rx frame queues that are configured to dedicated channels, in a
+round-robin manner. The mapping of the frame queues to CPUs is now
+hardcoded, there is no indirection table to move traffic for a certain
+FQ (hash result) to another CPU. The ingress traffic arriving on one
+of these frame queues will arrive at the same portal and will always
+be processed by the same CPU. This ensures intra-flow order preservation
+and workload distribution for multiple traffic flows.
+
+RSS can be turned off for a certain interface using ethtool, i.e.
+
+   # ethtool -N fm1-mac9 rx-flow-hash tcp4 ""
+
+To turn it back on, one needs to set rx-flow-hash for tcp4/6 or udp4/6:
+
+   # ethtool -N fm1-mac9 rx-flow-hash udp4 sfdn
+
+There is no independent control for individual protocols, any command
+run for one of tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 is
+going to control the rx-flow-hashing for all protocols on that interface.
+
+Besides using the FMan Keygen computed hash for spreading traffic on the
+128 Rx FQs, the DPAA Ethernet driver also sets the skb hash value when
+the NETIF_F_RXHASH feature is on (active by default). This can be turned
+on or off through ethtool, i.e.:
+
+   # ethtool -K fm1-mac9 rx-hashing off
+   # ethtool -k fm1-mac9 | grep hash
+   receive-hashing: off
+   # ethtool -K fm1-mac9 rx-hashing on
+   Actual changes:
+   receive-hashing: on
+   # ethtool -k fm1-mac9 | grep hash
+   receive-hashing: on
+
+Please note that Rx hashing depends upon the rx-flow-hashing being on
+for that interface - turning off rx-flow-hashing will also disable the
+rx-hashing (without ethtool reporting it as off as that depends on the
+NETIF_F_RXHASH feature flag).
+
 Debugging
 =
 
-- 
2.1.0



[PATCH 4/6] dpaa_eth: add NETIF_F_RXHASH

2017-08-18 Thread Madalin Bucur
Set the skb hash when then FMan Keygen hash result is available.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 19 ---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  1 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |  9 +++--
 drivers/net/ethernet/freescale/fman/fman_port.c| 11 +++
 drivers/net/ethernet/freescale/fman/fman_port.h|  2 ++
 5 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 6d89e74..ef30038 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -236,7 +236,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
net_dev->max_mtu = dpaa_get_max_mtu();
 
net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-NETIF_F_LLTX);
+NETIF_F_LLTX | NETIF_F_RXHASH);
 
net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
/* The kernels enables GSO automatically, if we declare NETIF_F_SG.
@@ -2237,12 +2237,13 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_addr_t addr = qm_fd_addr(fd);
enum qm_fd_format fd_format;
struct net_device *net_dev;
-   u32 fd_status;
+   u32 fd_status, hash_offset;
struct dpaa_bp *dpaa_bp;
struct dpaa_priv *priv;
unsigned int skb_len;
struct sk_buff *skb;
int *count_ptr;
+   void *vaddr;
 
fd_status = be32_to_cpu(fd->status);
fd_format = qm_fd_get_format(fd);
@@ -2288,7 +2289,8 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE);
 
/* prefetch the first 64 bytes of the frame or the SGT start */
-   prefetch(phys_to_virt(addr) + qm_fd_get_offset(fd));
+   vaddr = phys_to_virt(addr);
+   prefetch(vaddr + qm_fd_get_offset(fd));
 
fd_format = qm_fd_get_format(fd);
/* The only FD types that we may receive are contig and S/G */
@@ -2309,6 +2311,14 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
 
skb->protocol = eth_type_trans(skb, net_dev);
 
+   if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
+   !fman_port_get_hash_result_offset(priv->mac_dev->port[RX],
+ _offset))
+   skb_set_hash(skb, be32_to_cpu(*(u32 *)(vaddr + hash_offset)),
+// if L4 exists, it was used in the hash generation
+be32_to_cpu(fd->status) & FM_FD_STAT_L4CV ?
+   PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
+
skb_len = skb->len;
 
if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
@@ -2774,6 +2784,9 @@ static int dpaa_eth_probe(struct platform_device *pdev)
if (err)
goto init_ports_failed;
 
+   /* Rx traffic distribution based on keygen hashing defaults to on */
+   priv->keygen_in_use = true;
+
priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
if (!priv->percpu_priv) {
dev_err(dev, "devm_alloc_percpu() failed\n");
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 496a12c..bd94220 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -159,6 +159,7 @@ struct dpaa_priv {
struct list_head dpaa_fq_list;
 
u8 num_tc;
+   bool keygen_in_use;
u32 msg_enable; /* net_device message level */
 
struct {
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 965f652..faea674 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -402,6 +402,8 @@ static void dpaa_get_strings(struct net_device *net_dev, 
u32 stringset,
 static int dpaa_get_hash_opts(struct net_device *dev,
  struct ethtool_rxnfc *cmd)
 {
+   struct dpaa_priv *priv = netdev_priv(dev);
+
cmd->data = 0;
 
switch (cmd->flow_type) {
@@ -409,7 +411,8 @@ static int dpaa_get_hash_opts(struct net_device *dev,
case TCP_V6_FLOW:
case UDP_V4_FLOW:
case UDP_V6_FLOW:
-   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+   if (priv->keygen_in_use)
+   cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
/* Fall through */
case IPV4_FLOW:
case IPV6_FLOW:
@@ -421,7 +424,8 @@ static int dpaa_get_has

[PATCH 1/6] fsl/fman: enable FMan Keygen

2017-08-18 Thread Madalin Bucur
From: Iordache Florinel-R70177 <florinel.iorda...@nxp.com>

Add support for the FMan Keygen with a hardcoded scheme to spread
incoming traffic on a FQ range based on source and destination IPs
and ports.

Signed-off-by: Iordache Florinel <florinel.iorda...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Makefile  |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c|  26 +
 drivers/net/ethernet/freescale/fman/fman.h|   2 +
 drivers/net/ethernet/freescale/fman/fman_keygen.c | 783 ++
 drivers/net/ethernet/freescale/fman/fman_keygen.h |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c   |  40 +-
 drivers/net/ethernet/freescale/fman/fman_port.h   |   5 +
 7 files changed, 902 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

diff --git a/drivers/net/ethernet/freescale/fman/Makefile 
b/drivers/net/ethernet/freescale/fman/Makefile
index 6049177..2c38119 100644
--- a/drivers/net/ethernet/freescale/fman/Makefile
+++ b/drivers/net/ethernet/freescale/fman/Makefile
@@ -4,6 +4,6 @@ obj-$(CONFIG_FSL_FMAN) += fsl_fman.o
 obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o
 obj-$(CONFIG_FSL_FMAN) += fsl_mac.o
 
-fsl_fman-objs  := fman_muram.o fman.o fman_sp.o
+fsl_fman-objs  := fman_muram.o fman.o fman_sp.o fman_keygen.o
 fsl_fman_port-objs := fman_port.o
 fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index e714b8f..491a5ac 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -34,6 +34,7 @@
 
 #include "fman.h"
 #include "fman_muram.h"
+#include "fman_keygen.h"
 
 #include 
 #include 
@@ -56,6 +57,7 @@
 /* Modules registers offsets */
 #define BMI_OFFSET 0x0008
 #define QMI_OFFSET 0x00080400
+#define KG_OFFSET  0x000C1000
 #define DMA_OFFSET 0x000C2000
 #define FPM_OFFSET 0x000C3000
 #define IMEM_OFFSET0x000C4000
@@ -617,6 +619,7 @@ struct fman {
struct fman_qmi_regs __iomem *qmi_regs;
struct fman_dma_regs __iomem *dma_regs;
struct fman_hwp_regs __iomem *hwp_regs;
+   struct fman_kg_regs __iomem *kg_regs;
fman_exceptions_cb *exception_cb;
fman_bus_error_cb *bus_error_cb;
/* Spinlock for FMan use */
@@ -631,6 +634,8 @@ struct fman {
/* Fifo in MURAM */
unsigned long fifo_offset;
size_t fifo_size;
+   /* KeyGen handle */
+   struct fman_keygen *keygen;
 
u32 liodn_base[64];
u32 liodn_offset[64];
@@ -1811,6 +1816,7 @@ static int fman_config(struct fman *fman)
fman->qmi_regs = base_addr + QMI_OFFSET;
fman->dma_regs = base_addr + DMA_OFFSET;
fman->hwp_regs = base_addr + HWP_OFFSET;
+   fman->kg_regs = base_addr + KG_OFFSET;
fman->base_addr = base_addr;
 
spin_lock_init(>spinlock);
@@ -2083,6 +2089,11 @@ static int fman_init(struct fman *fman)
/* Init HW Parser */
hwp_init(fman->hwp_regs);
 
+   /* Init KeyGen */
+   fman->keygen = keygen_init(fman->kg_regs);
+   if (!fman->keygen)
+   return -EINVAL;
+
err = enable(fman, cfg);
if (err != 0)
return err;
@@ -2562,6 +2573,21 @@ int fman_get_rx_extra_headroom(void)
 EXPORT_SYMBOL(fman_get_rx_extra_headroom);
 
 /**
+ * fman_get_keygen
+ *
+ * @fman:  A Pointer to FMan device
+ *
+ * Get the handle to KeyGen module part of FM driver
+ *
+ * Return: Handle to KeyGen
+ */
+struct fman_keygen *fman_get_keygen(struct fman *fman)
+{
+   return fman->keygen;
+}
+EXPORT_SYMBOL(fman_get_keygen);
+
+/**
  * fman_bind
  * @dev:   FMan OF device pointer
  *
diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index f53e147..291990e 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -320,6 +320,8 @@ u16 fman_get_max_frm(void);
 
 int fman_get_rx_extra_headroom(void);
 
+struct fman_keygen *fman_get_keygen(struct fman *fman);
+
 struct fman *fman_bind(struct device *dev);
 
 #endif /* __FM_H */
diff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.c 
b/drivers/net/ethernet/freescale/fman/fman_keygen.c
new file mode 100644
index 000..f54da3c
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/fman_keygen.c
@@ -0,0 +1,783 @@
+/*
+ * Copyright 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 

[PATCH 2/6] dpaa_eth: use multiple Rx frame queues

2017-08-18 Thread Madalin Bucur
Add a block of 128 Rx frame queues per port. The FMan hardware will
send traffic on one of these queues based on the FMan port Parse
Classify Distribute setup. The hash computed by the FMan Keygen
block will select the Rx FQ.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 50 +++---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  1 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |  3 ++
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index c7fa285..6d89e74 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -158,7 +158,7 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
 #define DPAA_RX_PRIV_DATA_SIZE (u16)(DPAA_TX_PRIV_DATA_SIZE + \
dpaa_rx_extra_headroom)
 
-#define DPAA_ETH_RX_QUEUES 128
+#define DPAA_ETH_PCD_RXQ_NUM   128
 
 #define DPAA_ENQUEUE_RETRIES   10
 
@@ -169,6 +169,7 @@ struct fm_port_fqs {
struct dpaa_fq *tx_errq;
struct dpaa_fq *rx_defq;
struct dpaa_fq *rx_errq;
+   struct dpaa_fq *rx_pcdq;
 };
 
 /* All the dpa bps in use at any moment */
@@ -628,6 +629,7 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq, int 
idx)
fq->wq = 5;
break;
case FQ_TYPE_RX_DEFAULT:
+   case FQ_TYPE_RX_PCD:
fq->wq = 6;
break;
case FQ_TYPE_TX:
@@ -688,6 +690,7 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct 
list_head *list,
  struct fm_port_fqs *port_fqs)
 {
struct dpaa_fq *dpaa_fq;
+   u32 fq_base, fq_base_aligned, i;
 
dpaa_fq = dpaa_fq_alloc(dev, 0, 1, list, FQ_TYPE_RX_ERROR);
if (!dpaa_fq)
@@ -701,6 +704,26 @@ static int dpaa_alloc_all_fqs(struct device *dev, struct 
list_head *list,
 
port_fqs->rx_defq = _fq[0];
 
+   /* the PCD FQIDs range needs to be aligned for correct operation */
+   if (qman_alloc_fqid_range(_base, 2 * DPAA_ETH_PCD_RXQ_NUM))
+   goto fq_alloc_failed;
+
+   fq_base_aligned = ALIGN(fq_base, DPAA_ETH_PCD_RXQ_NUM);
+
+   for (i = fq_base; i < fq_base_aligned; i++)
+   qman_release_fqid(i);
+
+   for (i = fq_base_aligned + DPAA_ETH_PCD_RXQ_NUM;
+i < (fq_base + 2 * DPAA_ETH_PCD_RXQ_NUM); i++)
+   qman_release_fqid(i);
+
+   dpaa_fq = dpaa_fq_alloc(dev, fq_base_aligned, DPAA_ETH_PCD_RXQ_NUM,
+   list, FQ_TYPE_RX_PCD);
+   if (!dpaa_fq)
+   goto fq_alloc_failed;
+
+   port_fqs->rx_pcdq = _fq[0];
+
if (!dpaa_fq_alloc(dev, 0, DPAA_ETH_TXQ_NUM, list, FQ_TYPE_TX_CONF_MQ))
goto fq_alloc_failed;
 
@@ -870,13 +893,14 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
  const struct dpaa_fq_cbs *fq_cbs,
  struct fman_port *tx_port)
 {
-   int egress_cnt = 0, conf_cnt = 0, num_portals = 0, cpu;
+   int egress_cnt = 0, conf_cnt = 0, num_portals = 0, portal_cnt = 0, cpu;
const cpumask_t *affine_cpus = qman_affine_cpus();
-   u16 portals[NR_CPUS];
+   u16 channels[NR_CPUS];
struct dpaa_fq *fq;
 
for_each_cpu(cpu, affine_cpus)
-   portals[num_portals++] = qman_affine_channel(cpu);
+   channels[num_portals++] = qman_affine_channel(cpu);
+
if (num_portals == 0)
dev_err(priv->net_dev->dev.parent,
"No Qman software (affine) channels found");
@@ -890,6 +914,12 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,
case FQ_TYPE_RX_ERROR:
dpaa_setup_ingress(priv, fq, _cbs->rx_errq);
break;
+   case FQ_TYPE_RX_PCD:
+   if (!num_portals)
+   continue;
+   dpaa_setup_ingress(priv, fq, _cbs->rx_defq);
+   fq->channel = channels[portal_cnt++ % num_portals];
+   break;
case FQ_TYPE_TX:
dpaa_setup_egress(priv, fq, tx_port,
  _cbs->egress_ern);
@@ -1039,7 +1069,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool 
td_enable)
/* Put all the ingress queues in our "ingress CGR". */
if (priv->use_ingress_cgr &&
(dpaa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
-dpaa_fq->fq_type == FQ_TYPE_RX_ERROR)) {
+dpaa_fq->fq_type == FQ_TYPE_RX_ERROR ||
+dpaa_fq->fq_type == FQ_TYPE_RX_PCD)) {
initfq.we_mask |= cpu_to_b

[PATCH 0/6] Add RSS to DPAA 1.x Ethernet driver

2017-08-18 Thread Madalin Bucur
This patch set introduces Receive Side Scaling for the DPAA Ethernet
driver. Documentation is updated with details related to the new
feature and limitations that apply.
Added also a small fix.

Iordache Florinel-R70177 (1):
  fsl/fman: enable FMan Keygen

Madalin Bucur (5):
  dpaa_eth: use multiple Rx frame queues
  dpaa_eth: enable Rx hashing control
  dpaa_eth: add NETIF_F_RXHASH
  Documentation: networking: add RSS information
  dpaa_eth: check allocation result

 Documentation/networking/dpaa.txt  |  68 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c |  72 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |   2 +
 .../net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c   |   3 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 118 
 drivers/net/ethernet/freescale/fman/Makefile   |   2 +-
 drivers/net/ethernet/freescale/fman/fman.c |  26 +
 drivers/net/ethernet/freescale/fman/fman.h |   2 +
 drivers/net/ethernet/freescale/fman/fman_keygen.c  | 783 +
 drivers/net/ethernet/freescale/fman/fman_keygen.h  |  46 ++
 drivers/net/ethernet/freescale/fman/fman_port.c|  51 +-
 drivers/net/ethernet/freescale/fman/fman_port.h|   7 +
 12 files changed, 1167 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.c
 create mode 100644 drivers/net/ethernet/freescale/fman/fman_keygen.h

-- 
2.1.0



[PATCH v2] fsl/fman: add dependency on HAS_DMA

2017-06-26 Thread Madalin Bucur
A previous commit (5567e989198b5a8d) inserted a dependency on DMA
API that requires HAS_DMA to be added in Kconfig.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/freescale/fman/Kconfig 
b/drivers/net/ethernet/freescale/fman/Kconfig
index dc0850b..8870a9a 100644
--- a/drivers/net/ethernet/freescale/fman/Kconfig
+++ b/drivers/net/ethernet/freescale/fman/Kconfig
@@ -2,6 +2,7 @@ config FSL_FMAN
tristate "FMan support"
depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
select GENERIC_ALLOCATOR
+   depends on HAS_DMA
select PHYLIB
default n
help
-- 
2.1.0



[PATCH] fsl/fman: add dependency on HAS_DMA

2017-06-26 Thread Madalin Bucur
A previous commit inserted a dependency on DMA API that requires
HAS_DMA to be added in Kconfig.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/freescale/fman/Kconfig 
b/drivers/net/ethernet/freescale/fman/Kconfig
index dc0850b..8870a9a 100644
--- a/drivers/net/ethernet/freescale/fman/Kconfig
+++ b/drivers/net/ethernet/freescale/fman/Kconfig
@@ -2,6 +2,7 @@ config FSL_FMAN
tristate "FMan support"
depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
select GENERIC_ALLOCATOR
+   depends on HAS_DMA
select PHYLIB
default n
help
-- 
2.1.0



[PATCH 1/2] fsl/fman: propagate dma_ops

2017-06-19 Thread Madalin Bucur
Make sure dma_ops are set, to be later used by the Ethernet driver.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/mac.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fman/mac.c 
b/drivers/net/ethernet/freescale/fman/mac.c
index 0b31f85..6e67d22f 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -623,6 +623,8 @@ static struct platform_device *dpaa_eth_add_device(int 
fman_id,
goto no_mem;
}
 
+   set_dma_ops(>dev, get_dma_ops(priv->dev));
+
ret = platform_device_add_data(pdev, , sizeof(data));
if (ret)
goto err;
-- 
2.1.0



[PATCH 2/2] dpaa_eth: reuse the dma_ops provided by the FMan MAC device

2017-06-19 Thread Madalin Bucur
Remove the use of arch_setup_dma_ops() that was not exported
and was breaking loadable module compilation.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 9a520e4..290ad05 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2647,7 +2647,7 @@ static int dpaa_eth_probe(struct platform_device *pdev)
priv->buf_layout[TX].priv_data_size = DPAA_TX_PRIV_DATA_SIZE; /* Tx */
 
/* device used for DMA mapping */
-   arch_setup_dma_ops(dev, 0, 0, NULL, false);
+   set_dma_ops(dev, get_dma_ops(>dev));
err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
if (err) {
dev_err(dev, "dma_coerce_mask_and_coherent() failed\n");
-- 
2.1.0



[PATCH 0/2] fix loadable module for DPAA Ethernet

2017-06-19 Thread Madalin Bucur
The DPAA Ethernet makes use of a symbol that is not exported.
Address the issue by propagating the dma_ops rather than calling
arch_setup_dma_ops().

Madalin Bucur (2):
  fsl/fman: propagate dma_ops
  dpaa_eth: reuse the dma_ops provided by the FMan MAC device

 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +-
 drivers/net/ethernet/freescale/fman/mac.c  | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

-- 
2.1.0



[PATCH] Documentation: networking: add DPAA Ethernet document

2017-05-29 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
Signed-off-by: Camelia Groza <camelia.gr...@nxp.com>
---
 Documentation/networking/dpaa.txt | 194 ++
 1 file changed, 194 insertions(+)
 create mode 100644 Documentation/networking/dpaa.txt

diff --git a/Documentation/networking/dpaa.txt 
b/Documentation/networking/dpaa.txt
new file mode 100644
index 000..76e016d
--- /dev/null
+++ b/Documentation/networking/dpaa.txt
@@ -0,0 +1,194 @@
+The QorIQ DPAA Ethernet Driver
+==
+
+Authors:
+Madalin Bucur <madalin.bu...@nxp.com>
+Camelia Groza <camelia.gr...@nxp.com>
+
+Contents
+
+
+   - DPAA Ethernet Overview
+   - DPAA Ethernet Supported SoCs
+   - Configuring DPAA Ethernet in your kernel
+   - DPAA Ethernet Frame Processing
+   - DPAA Ethernet Features
+   - Debugging
+
+DPAA Ethernet Overview
+==
+
+DPAA stands for Data Path Acceleration Architecture and it is a
+set of networking acceleration IPs that are available on several
+generations of SoCs, both on PowerPC and ARM64.
+
+The Freescale DPAA architecture consists of a series of hardware blocks
+that support Ethernet connectivity. The Ethernet driver depends upon the
+following drivers in the Linux kernel:
+
+ - Peripheral Access Memory Unit (PAMU) (* needed only for PPC platforms)
+drivers/iommu/fsl_*
+ - Frame Manager (FMan)
+drivers/net/ethernet/freescale/fman
+ - Queue Manager (QMan), Buffer Manager (BMan)
+drivers/soc/fsl/qbman
+
+A simplified view of the dpaa_eth interfaces mapped to FMan MACs:
+
+  dpaa_eth   /eth0\ ...   /ethN\
+  driver|  | |  |
+  -      ---      -
+   -Ports  / Tx  Rx \.../ Tx  Rx \
+  FMan|  | |  |
+   -MACs  |   MAC0   | |   MACN   |
+ /   dtsec0   \  ...  /   dtsecN   \ (or tgec)
+/  \ /  \(or memac)
+  -  --  ---  --  -
+  FMan, FMan Port, FMan SP, FMan MURAM drivers
+  -
+  FMan HW blocks: MURAM, MACs, Ports, SP
+  -
+
+The dpaa_eth relation to the QMan, BMan and FMan:
+  
+  dpaa_eth   /eth0\
+  driver/  \
+  -   -^-   -^-   -^-   ----
+  QMan driver / \   / \   / \  \   /  | BMan|
+ |Rx | |Rx | |Tx | |Tx |  | driver  |
+  -  |Dfl| |Err| |Cnf| |FQs|  | |
+  QMan HW|FQ | |FQ | |FQs| |   |  | |
+ /   \ /   \ /   \  \ /   | |
+  -   ---   ---   ---   -v--
+|FMan QMI | |
+| FMan HW   FMan BMI  | BMan HW |
+  ---   
+
+where the acronyms used above (and in the code) are:
+DPAA = Data Path Acceleration Architecture
+FMan = DPAA Frame Manager
+QMan = DPAA Queue Manager
+BMan = DPAA Buffers Manager
+QMI = QMan interface in FMan
+BMI = BMan interface in FMan
+FMan SP = FMan Storage Profiles
+MURAM = Multi-user RAM in FMan
+FQ = QMan Frame Queue
+Rx Dfl FQ = default reception FQ
+Rx Err FQ = Rx error frames FQ
+Tx Cnf FQ = Tx confirmation FQs
+Tx FQs = transmission frame queues
+dtsec = datapath three speed Ethernet controller (10/100/1000 Mbps)
+tgec = ten gigabit Ethernet controller (10 Gbps)
+memac = multirate Ethernet MAC (10/100/1000/1)
+
+DPAA Ethernet Supported SoCs
+
+
+The DPAA drivers enable the Ethernet controllers present on the following SoCs:
+
+# PPC
+P1023
+P2041
+P3041
+P4080
+P5020
+P5040
+T1023
+T1024
+T1040
+T1042
+T2080
+T4240
+B4860
+
+# ARM
+LS1043A
+LS1046A
+
+Configuring DPAA Ethernet in your kernel
+
+
+To enable the DPAA Ethernet driver, the following Kconfig options are required:
+
+# common for arch/arm64 and arch/powerpc platforms
+CONFIG_FSL_DPAA=y
+CONFIG_FSL_FMAN=y
+CONFIG_FSL_DPAA_ETH=y
+CONFIG_FSL_XGMAC_MDIO=y
+
+# for arch/powerpc only
+CONFIG_FSL_PAMU=y
+
+# common options needed for the PHYs used on the RDBs
+CONFIG_VITESSE_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_AQUANTIA_PHY=y
+
+DPAA Ethernet Frame Processing
+==
+
+On Rx, buffers for the incoming frames are retrieved from one of the three
+existing buffers pools. The driver initializes and seeds these, each with
+buffers of different sizes: 1KB, 2KB and 4KB.
+
+On Tx, all transmitted frames are returned to the driver through Tx
+confirmation frame queues. The driver is then responsible for freeing the
+buffers. In order to do this properly, a backpointer is added to the buffer
+before transmission that points to the skb. When the buffer returns to the
+

[PATCH] dt-bindings: net: move FMan binding

2017-05-15 Thread Madalin Bucur
Besides the PPC SoCs, the QorIQ DPAA FMan is also present on ARM SoCs,
moving the device tree binding document into the bindings/net folder.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 Documentation/devicetree/bindings/net/fsl-fman.txt | 657 +
 .../devicetree/bindings/powerpc/fsl/fman.txt   | 657 -
 2 files changed, 657 insertions(+), 657 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/fsl-fman.txt
 delete mode 100644 Documentation/devicetree/bindings/powerpc/fsl/fman.txt

diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt 
b/Documentation/devicetree/bindings/net/fsl-fman.txt
new file mode 100644
index 000..df873d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/fsl-fman.txt
@@ -0,0 +1,657 @@
+=
+Freescale Frame Manager Device Bindings
+
+CONTENTS
+  - FMan Node
+  - FMan Port Node
+  - FMan MURAM Node
+  - FMan dTSEC/XGEC/mEMAC Node
+  - FMan IEEE 1588 Node
+  - FMan MDIO Node
+  - Example
+
+=
+FMan Node
+
+DESCRIPTION
+
+Due to the fact that the FMan is an aggregation of sub-engines (ports, MACs,
+etc.) the FMan node will have child nodes for each of them.
+
+PROPERTIES
+
+- compatible
+   Usage: required
+   Value type: 
+   Definition: Must include "fsl,fman"
+   FMan version can be determined via FM_IP_REV_1 register in the
+   FMan block. The offset is 0xc4 from the beginning of the
+   Frame Processing Manager memory map (0xc3000 from the
+   beginning of the FMan node).
+
+- cell-index
+   Usage: required
+   Value type: 
+   Definition: Specifies the index of the FMan unit.
+
+   The cell-index value may be used by the SoC, to identify the
+   FMan unit in the SoC memory map. In the table below,
+   there's a description of the cell-index use in each SoC:
+
+   - P1023:
+   register[bit]   FMan unit   cell-index
+   
+   DEVDISR[1]  1   0
+
+   - P2041, P3041, P4080 P5020, P5040:
+   register[bit]   FMan unit   cell-index
+   
+   DCFG_DEVDISR2[6]1   0
+   DCFG_DEVDISR2[14]   2   1
+   (Second FM available only in P4080 and P5040)
+
+   - B4860, T1040, T2080, T4240:
+   register[bit]   FMan unit   cell-index
+   
+   DCFG_CCSR_DEVDISR2[24]  1   0
+   DCFG_CCSR_DEVDISR2[25]  2   1
+   (Second FM available only in T4240)
+
+   DEVDISR, DCFG_DEVDISR2 and DCFG_CCSR_DEVDISR2 are located in
+   the specific SoC "Device Configuration/Pin Control" Memory
+   Map.
+
+- reg
+   Usage: required
+   Value type: 
+   Definition: A standard property. Specifies the offset of the
+   following configuration registers:
+   - BMI configuration registers.
+   - QMI configuration registers.
+   - DMA configuration registers.
+   - FPM configuration registers.
+   - FMan controller configuration registers.
+
+- ranges
+   Usage: required
+   Value type: 
+   Definition: A standard property.
+
+- clocks
+   Usage: required
+   Value type: 
+   Definition: phandle for the fman input clock.
+
+- clock-names
+   usage: required
+   Value type: 
+   Definition: "fmanclk" for the fman input clock.
+
+- interrupts
+   Usage: required
+   Value type: 
+   Definition: A pair of IRQs are specified in this property.
+   The first element is associated with the event interrupts and
+   the second element is associated with the error interrupts.
+
+- fsl,qman-channel-range
+   Usage: required
+   Value type: 
+   Definition: Specifies the range of the available dedicated
+   channels in the FMan. The first cell specifies the beginning
+   of the range and the second cell specifies the number of
+   channels.
+   Further information available at:
+   "Work Queue (WQ) Channel Assignments in the QMan" section
+   

[PATCH] dpaa_eth: use AVOIDBLOCK for Tx confirmation queues

2017-03-30 Thread Madalin Bucur
The AVOIDBLOCK flag determines the Tx confirmation queues processing
to be redirected to any available CPU when the current one is slow
in processing them. This may result in a higher Tx confirmation
interrupt count but may reduce pressure on a certain CPU that with
the previous setting would process all Tx confirmation frames.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index d4bb8bf..9a520e4 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -974,7 +974,7 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool 
td_enable)
 * Tx Confirmation FQs.
 */
if (dpaa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
-   initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_HOLDACTIVE);
+   initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_AVOIDBLOCK);
 
/* FQ placement */
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_DESTWQ);
-- 
2.1.0



[PATCH] fsl/fman: take into account all RGMII modes

2017-03-30 Thread Madalin Bucur
Accept the internal delay RGMII variants.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman_dtsec.c | 8 +++-
 drivers/net/ethernet/freescale/fman/fman_memac.c | 5 -
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c 
b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
index 84ea130..98bba10 100644
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
@@ -381,6 +381,9 @@ static int init(struct dtsec_regs __iomem *regs, struct 
dtsec_cfg *cfg,
 
/* check RGMII support */
if (iface == PHY_INTERFACE_MODE_RGMII ||
+   iface == PHY_INTERFACE_MODE_RGMII_ID ||
+   iface == PHY_INTERFACE_MODE_RGMII_RXID ||
+   iface == PHY_INTERFACE_MODE_RGMII_TXID ||
iface == PHY_INTERFACE_MODE_RMII)
if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
return -EINVAL;
@@ -390,7 +393,10 @@ static int init(struct dtsec_regs __iomem *regs, struct 
dtsec_cfg *cfg,
if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
return -EINVAL;
 
-   is_rgmii = iface == PHY_INTERFACE_MODE_RGMII;
+   is_rgmii = iface == PHY_INTERFACE_MODE_RGMII ||
+  iface == PHY_INTERFACE_MODE_RGMII_ID ||
+  iface == PHY_INTERFACE_MODE_RGMII_RXID ||
+  iface == PHY_INTERFACE_MODE_RGMII_TXID;
is_sgmii = iface == PHY_INTERFACE_MODE_SGMII;
is_qsgmii = iface == PHY_INTERFACE_MODE_QSGMII;
 
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c 
b/drivers/net/ethernet/freescale/fman/fman_memac.c
index cd6a53e..c029688 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -443,7 +443,10 @@ static int init(struct memac_regs __iomem *regs, struct 
memac_cfg *cfg,
break;
default:
tmp |= IF_MODE_GMII;
-   if (phy_if == PHY_INTERFACE_MODE_RGMII)
+   if (phy_if == PHY_INTERFACE_MODE_RGMII ||
+   phy_if == PHY_INTERFACE_MODE_RGMII_ID ||
+   phy_if == PHY_INTERFACE_MODE_RGMII_RXID ||
+   phy_if == PHY_INTERFACE_MODE_RGMII_TXID)
tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
}
iowrite32be(tmp, >if_mode);
-- 
2.1.0



[net-next v2 07/10] dpaa_eth: do not ignore port api return value

2017-03-09 Thread Madalin Bucur
Reported-by: Dan Carpenter <dan.carpen...@oracle.com>

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 65 +-
 1 file changed, 43 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index a7a595c..ae64cdb 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -1063,9 +1063,9 @@ static int dpaa_fq_free(struct device *dev, struct 
list_head *list)
return err;
 }
 
-static void dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq,
- struct dpaa_fq *defq,
- struct dpaa_buffer_layout *buf_layout)
+static int dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq,
+struct dpaa_fq *defq,
+struct dpaa_buffer_layout *buf_layout)
 {
struct fman_buffer_prefix_content buf_prefix_content;
struct fman_port_params params;
@@ -1084,23 +1084,29 @@ static void dpaa_eth_init_tx_port(struct fman_port 
*port, struct dpaa_fq *errq,
params.specific_params.non_rx_params.dflt_fqid = defq->fqid;
 
err = fman_port_config(port, );
-   if (err)
+   if (err) {
pr_err("%s: fman_port_config failed\n", __func__);
+   return err;
+   }
 
err = fman_port_cfg_buf_prefix_content(port, _prefix_content);
-   if (err)
+   if (err) {
pr_err("%s: fman_port_cfg_buf_prefix_content failed\n",
   __func__);
+   return err;
+   }
 
err = fman_port_init(port);
if (err)
pr_err("%s: fm_port_init failed\n", __func__);
+
+   return err;
 }
 
-static void dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps,
- size_t count, struct dpaa_fq *errq,
- struct dpaa_fq *defq,
- struct dpaa_buffer_layout *buf_layout)
+static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps,
+size_t count, struct dpaa_fq *errq,
+struct dpaa_fq *defq,
+struct dpaa_buffer_layout *buf_layout)
 {
struct fman_buffer_prefix_content buf_prefix_content;
struct fman_port_rx_params *rx_p;
@@ -1128,32 +1134,44 @@ static void dpaa_eth_init_rx_port(struct fman_port 
*port, struct dpaa_bp **bps,
}
 
err = fman_port_config(port, );
-   if (err)
+   if (err) {
pr_err("%s: fman_port_config failed\n", __func__);
+   return err;
+   }
 
err = fman_port_cfg_buf_prefix_content(port, _prefix_content);
-   if (err)
+   if (err) {
pr_err("%s: fman_port_cfg_buf_prefix_content failed\n",
   __func__);
+   return err;
+   }
 
err = fman_port_init(port);
if (err)
pr_err("%s: fm_port_init failed\n", __func__);
+
+   return err;
 }
 
-static void dpaa_eth_init_ports(struct mac_device *mac_dev,
-   struct dpaa_bp **bps, size_t count,
-   struct fm_port_fqs *port_fqs,
-   struct dpaa_buffer_layout *buf_layout,
-   struct device *dev)
+static int dpaa_eth_init_ports(struct mac_device *mac_dev,
+  struct dpaa_bp **bps, size_t count,
+  struct fm_port_fqs *port_fqs,
+  struct dpaa_buffer_layout *buf_layout,
+  struct device *dev)
 {
struct fman_port *rxport = mac_dev->port[RX];
struct fman_port *txport = mac_dev->port[TX];
+   int err;
 
-   dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
- port_fqs->tx_defq, _layout[TX]);
-   dpaa_eth_init_rx_port(rxport, bps, count, port_fqs->rx_errq,
- port_fqs->rx_defq, _layout[RX]);
+   err = dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
+   port_fqs->tx_defq, _layout[TX]);
+   if (err)
+   return err;
+
+   err = dpaa_eth_init_rx_port(rxport, bps, count, port_fqs->rx_errq,
+   port_fqs->rx_defq, _layout[RX]);
+
+   return err;
 }
 
 static int dpaa_bman_release(const struct dpaa_bp *dpaa_bp,
@@ -2649,8 +2667,10 @@ static int dpaa_eth_probe(struct platform_device *pdev)
priv->rx_headroom = dpaa_get_headroom(>buf_layout[RX]);
 
/* All real interfaces need their ports initialized */
-   dpaa_eth_

[net-next v2 10/10] dpaa_eth: enable context-A stashing

2017-03-09 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 1b3ea38..aa769cb 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -1052,7 +1052,8 @@ static int dpaa_fq_init(struct dpaa_fq *dpaa_fq, bool 
td_enable)
/* Initialization common to all ingress queues */
if (dpaa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_CONTEXTA);
-   initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_HOLDACTIVE);
+   initfq.fqd.fq_ctrl |= cpu_to_be16(QM_FQCTRL_HOLDACTIVE |
+   QM_FQCTRL_CTXASTASHING);
initfq.fqd.context_a.stashing.exclusive =
QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
QM_STASHING_EXCL_ANNOTATION;
-- 
2.1.0



[net-next v2 09/10] dpaa_eth: enable multiple Tx traffic classes

2017-03-09 Thread Madalin Bucur
From: Camelia Groza <camelia.gr...@nxp.com>

Implement the setup_tc ndo to configure prioritised Tx traffic classes.
Priorities range from 0 (lowest) to 3 (highest). The driver assigns
NR_CPUS queues to each traffic class.

Signed-off-by: Camelia Groza <camelia.gr...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 36 ++
 1 file changed, 36 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index ac75d09..1b3ea38 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -342,6 +342,41 @@ static void dpaa_get_stats64(struct net_device *net_dev,
}
 }
 
+static int dpaa_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
+struct tc_to_netdev *tc)
+{
+   struct dpaa_priv *priv = netdev_priv(net_dev);
+   int i;
+
+   if (tc->type != TC_SETUP_MQPRIO)
+   return -EINVAL;
+
+   if (tc->tc == priv->num_tc)
+   return 0;
+
+   if (!tc->tc) {
+   netdev_reset_tc(net_dev);
+   goto out;
+   }
+
+   if (tc->tc > DPAA_TC_NUM) {
+   netdev_err(net_dev, "Too many traffic classes: max %d 
supported.\n",
+  DPAA_TC_NUM);
+   return -EINVAL;
+   }
+
+   netdev_set_num_tc(net_dev, tc->tc);
+
+   for (i = 0; i < tc->tc; i++)
+   netdev_set_tc_queue(net_dev, i, DPAA_TC_TXQ_NUM,
+   i * DPAA_TC_TXQ_NUM);
+
+out:
+   priv->num_tc = tc->tc ? tc->tc : 1;
+   netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM);
+   return 0;
+}
+
 static struct mac_device *dpaa_mac_dev_get(struct platform_device *pdev)
 {
struct platform_device *of_dev;
@@ -2417,6 +2452,7 @@ static const struct net_device_ops dpaa_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_set_rx_mode = dpaa_set_rx_mode,
.ndo_do_ioctl = dpaa_ioctl,
+   .ndo_setup_tc = dpaa_setup_tc,
 };
 
 static int dpaa_napi_add(struct net_device *net_dev)
-- 
2.1.0



[net-next v2 08/10] dpaa_eth: add four prioritised Tx traffic classes

2017-03-09 Thread Madalin Bucur
From: Camelia Groza <camelia.gr...@nxp.com>

Each traffic class corresponds to a WQ priority level. The number of Tx
netdev queues and frame queues is increased to NR_CPUS queues for each
traffic class. In addition, the priority of the Rx, Error and Conf queues
is lowered but their order is maintained.

By default, only one traffic class is enabled, only the low priority Tx
queues are used and only the corresponding netdev queues are advertised.

Signed-off-by: Camelia Groza <camelia.gr...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 43 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  8 -
 2 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index ae64cdb..ac75d09 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -565,16 +565,18 @@ static void dpaa_bps_free(struct dpaa_priv *priv)
 
 /* Use multiple WQs for FQ assignment:
  * - Tx Confirmation queues go to WQ1.
- * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
- *   to be scheduled, in case there are many more FQs in WQ3).
- * - Rx Default and Tx queues go to WQ3 (no differentiation between
- *   Rx and Tx traffic).
+ * - Rx Error and Tx Error queues go to WQ5 (giving them a better chance
+ *   to be scheduled, in case there are many more FQs in WQ6).
+ * - Rx Default goes to WQ6.
+ * - Tx queues go to different WQs depending on their priority. Equal
+ *   chunks of NR_CPUS queues go to WQ6 (lowest priority), WQ2, WQ1 and
+ *   WQ0 (highest priority).
  * This ensures that Tx-confirmed buffers are timely released. In particular,
  * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
  * are greatly outnumbered by other FQs in the system, while
  * dequeue scheduling is round-robin.
  */
-static inline void dpaa_assign_wq(struct dpaa_fq *fq)
+static inline void dpaa_assign_wq(struct dpaa_fq *fq, int idx)
 {
switch (fq->fq_type) {
case FQ_TYPE_TX_CONFIRM:
@@ -583,11 +585,33 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq)
break;
case FQ_TYPE_RX_ERROR:
case FQ_TYPE_TX_ERROR:
-   fq->wq = 2;
+   fq->wq = 5;
break;
case FQ_TYPE_RX_DEFAULT:
+   fq->wq = 6;
+   break;
case FQ_TYPE_TX:
-   fq->wq = 3;
+   switch (idx / DPAA_TC_TXQ_NUM) {
+   case 0:
+   /* Low priority (best effort) */
+   fq->wq = 6;
+   break;
+   case 1:
+   /* Medium priority */
+   fq->wq = 2;
+   break;
+   case 2:
+   /* High priority */
+   fq->wq = 1;
+   break;
+   case 3:
+   /* Very high priority */
+   fq->wq = 0;
+   break;
+   default:
+   WARN(1, "Too many TX FQs: more than %d!\n",
+DPAA_ETH_TXQ_NUM);
+   }
break;
default:
WARN(1, "Invalid FQ type %d for FQID %d!\n",
@@ -615,7 +639,7 @@ static struct dpaa_fq *dpaa_fq_alloc(struct device *dev,
}
 
for (i = 0; i < count; i++)
-   dpaa_assign_wq(dpaa_fq + i);
+   dpaa_assign_wq(dpaa_fq + i, i);
 
return dpaa_fq;
 }
@@ -2683,6 +2707,9 @@ static int dpaa_eth_probe(struct platform_device *pdev)
memset(percpu_priv, 0, sizeof(*percpu_priv));
}
 
+   priv->num_tc = 1;
+   netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM);
+
/* Initialize NAPI */
err = dpaa_napi_add(net_dev);
if (err < 0)
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 1f9aebf..9941a78 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -39,7 +39,12 @@
 #include "mac.h"
 #include "dpaa_eth_trace.h"
 
-#define DPAA_ETH_TXQ_NUM   NR_CPUS
+/* Number of prioritised traffic classes */
+#define DPAA_TC_NUM4
+/* Number of Tx queues per traffic class */
+#define DPAA_TC_TXQ_NUMNR_CPUS
+/* Total number of Tx queues */
+#define DPAA_ETH_TXQ_NUM   (DPAA_TC_NUM * DPAA_TC_TXQ_NUM)
 
 #define DPAA_BPS_NUM 3 /* number of bpools per interface */
 
@@ -152,6 +157,7 @@ struct dpaa_priv {
u16 channel;
struct list_head dpaa_fq_list;
 
+   u8 num_tc;
u32 msg_enable; /* net_device message level */
 
struct {
-- 
2.1.0



[net-next v2 01/10] fsl/fman: parse result data is big endian

2017-03-09 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.h | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index 57aae8d..f53e147 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -134,14 +134,14 @@ enum fman_exceptions {
 struct fman_prs_result {
u8 lpid;/* Logical port id */
u8 shimr;   /* Shim header result  */
-   u16 l2r;/* Layer 2 result */
-   u16 l3r;/* Layer 3 result */
+   __be16 l2r; /* Layer 2 result */
+   __be16 l3r; /* Layer 3 result */
u8 l4r; /* Layer 4 result */
u8 cplan;   /* Classification plan id */
-   u16 nxthdr; /* Next Header  */
-   u16 cksum;  /* Running-sum */
+   __be16 nxthdr;  /* Next Header  */
+   __be16 cksum;   /* Running-sum */
/* Flags field of the last IP-header */
-   u16 flags_frag_off;
+   __be16 flags_frag_off;
/* Routing type field of a IPV6 routing extension header */
u8 route_type;
/* Routing Extension Header Present; last bit is IP valid */
-- 
2.1.0



[net-next v2 06/10] dpaa_eth: enable Rx checksum offload

2017-03-09 Thread Madalin Bucur
Use the FMan HW parser L4CV flag to offload Rx checksumming.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 29 --
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index e19181f..a7a595c 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -137,6 +137,13 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
 /* L4 Type field: TCP */
 #define FM_L4_PARSE_RESULT_TCP 0x20
 
+/* FD status field indicating whether the FM Parser has attempted to validate
+ * the L4 csum of the frame.
+ * Note that having this bit set doesn't necessarily imply that the checksum
+ * is valid. One would have to check the parse results to find that out.
+ */
+#define FM_FD_STAT_L4CV 0x0004
+
 #define DPAA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
 #define DPAA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once 
*/
 
@@ -235,6 +242,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
 * For conformity, we'll still declare GSO explicitly.
 */
net_dev->features |= NETIF_F_GSO;
+   net_dev->features |= NETIF_F_RXCSUM;
 
net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
/* we do not want shared skbs on TX */
@@ -1526,6 +1534,23 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct 
dpaa_priv *priv,
return skb;
 }
 
+static u8 rx_csum_offload(const struct dpaa_priv *priv, const struct qm_fd *fd)
+{
+   /* The parser has run and performed L4 checksum validation.
+* We know there were no parser errors (and implicitly no
+* L4 csum error), otherwise we wouldn't be here.
+*/
+   if ((priv->net_dev->features & NETIF_F_RXCSUM) &&
+   (be32_to_cpu(fd->status) & FM_FD_STAT_L4CV))
+   return CHECKSUM_UNNECESSARY;
+
+   /* We're here because either the parser didn't run or the L4 checksum
+* was not verified. This may include the case of a UDP frame with
+* checksum zero or an L4 proto other than TCP/UDP
+*/
+   return CHECKSUM_NONE;
+}
+
 /* Build a linear skb around the received buffer.
  * We are guaranteed there is enough room at the end of the data buffer to
  * accommodate the shared info area of the skb.
@@ -1556,7 +1581,7 @@ static struct sk_buff *contig_fd_to_skb(const struct 
dpaa_priv *priv,
skb_reserve(skb, fd_off);
skb_put(skb, qm_fd_get_length(fd));
 
-   skb->ip_summed = CHECKSUM_NONE;
+   skb->ip_summed = rx_csum_offload(priv, fd);
 
return skb;
 
@@ -1616,7 +1641,7 @@ static struct sk_buff *sg_fd_to_skb(const struct 
dpaa_priv *priv,
if (WARN_ON(unlikely(!skb)))
goto free_buffers;
 
-   skb->ip_summed = CHECKSUM_NONE;
+   skb->ip_summed = rx_csum_offload(priv, fd);
 
/* Make sure forwarded skbs will have enough space
 * on Tx, if extra headers are added.
-- 
2.1.0



[net-next v2 05/10] dpaa_eth: remove redundant initialization

2017-03-09 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index e2ca107..e19181f 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2093,7 +2093,7 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_addr_t addr = qm_fd_addr(fd);
enum qm_fd_format fd_format;
struct net_device *net_dev;
-   u32 fd_status = fd->status;
+   u32 fd_status;
struct dpaa_bp *dpaa_bp;
struct dpaa_priv *priv;
unsigned int skb_len;
-- 
2.1.0



[net-next v2 04/10] fsl/fman: enlarge FIFO to allow for the 5th port

2017-03-09 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index d755930..4aefe24 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -1212,7 +1212,7 @@ static int fill_soc_specific_params(struct 
fman_state_struct *state)
state->max_num_of_open_dmas = 32;
state->fm_port_num_of_cg= 256;
state->num_of_rx_ports  = 6;
-   state->total_fifo_size  = 122 * 1024;
+   state->total_fifo_size  = 136 * 1024;
break;
 
case 2:
-- 
2.1.0



[net-next v2 03/10] fsl/fman: remove wrong free

2017-03-09 Thread Madalin Bucur
Reported-by: Dan Carpenter <dan.carpen...@oracle.com>

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman_port.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c 
b/drivers/net/ethernet/freescale/fman/fman_port.c
index f314348..57bf44f 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1312,7 +1312,7 @@ int fman_port_config(struct fman_port *port, struct 
fman_port_params *params)
/* Allocate the FM driver's parameters structure */
port->cfg = kzalloc(sizeof(*port->cfg), GFP_KERNEL);
if (!port->cfg)
-   goto err_params;
+   return -EINVAL;
 
/* Initialize FM port parameters which will be kept by the driver */
port->port_type = port->dts_params.type;
@@ -1393,8 +1393,6 @@ int fman_port_config(struct fman_port *port, struct 
fman_port_params *params)
 
 err_port_cfg:
kfree(port->cfg);
-err_params:
-   kfree(port);
return -EINVAL;
 }
 EXPORT_SYMBOL(fman_port_config);
-- 
2.1.0



[net-next v2 02/10] fsl/fman: set HW parser as BMI next engine

2017-03-09 Thread Madalin Bucur
Enable the HW parser for all DPAA interfaces.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c  | 21 
 drivers/net/ethernet/freescale/fman/fman_port.c | 72 +++--
 2 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index f60845f..d755930 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -59,6 +59,7 @@
 #define DMA_OFFSET 0x000C2000
 #define FPM_OFFSET 0x000C3000
 #define IMEM_OFFSET0x000C4000
+#define HWP_OFFSET 0x000C7000
 #define CGP_OFFSET 0x000DB000
 
 /* Exceptions bit map */
@@ -218,6 +219,9 @@
 
 #define QMI_GS_HALT_NOT_BUSY   0x0002
 
+/* HWP defines */
+#define HWP_RPIMAC_PEN 0x0001
+
 /* IRAM defines */
 #define IRAM_IADD_AIE  0x8000
 #define IRAM_READY 0x8000
@@ -475,6 +479,12 @@ struct fman_dma_regs {
u32 res00e0[0x400 - 56];
 };
 
+struct fman_hwp_regs {
+   u32 res[0x844 / 4]; /* 0x000..0x843 */
+   u32 fmprrpimac; /* FM Parser Internal memory access control */
+   u32 res[(0x1000 - 0x848) / 4];  /* 0x848..0xFFF */
+};
+
 /* Structure that holds current FMan state.
  * Used for saving run time information.
  */
@@ -606,6 +616,7 @@ struct fman {
struct fman_bmi_regs __iomem *bmi_regs;
struct fman_qmi_regs __iomem *qmi_regs;
struct fman_dma_regs __iomem *dma_regs;
+   struct fman_hwp_regs __iomem *hwp_regs;
fman_exceptions_cb *exception_cb;
fman_bus_error_cb *bus_error_cb;
/* Spinlock for FMan use */
@@ -999,6 +1010,12 @@ static void qmi_init(struct fman_qmi_regs __iomem *qmi_rg,
iowrite32be(tmp_reg, _rg->fmqm_ien);
 }
 
+static void hwp_init(struct fman_hwp_regs __iomem *hwp_rg)
+{
+   /* enable HW Parser */
+   iowrite32be(HWP_RPIMAC_PEN, _rg->fmprrpimac);
+}
+
 static int enable(struct fman *fman, struct fman_cfg *cfg)
 {
u32 cfg_reg = 0;
@@ -1793,6 +1810,7 @@ static int fman_config(struct fman *fman)
fman->bmi_regs = base_addr + BMI_OFFSET;
fman->qmi_regs = base_addr + QMI_OFFSET;
fman->dma_regs = base_addr + DMA_OFFSET;
+   fman->hwp_regs = base_addr + HWP_OFFSET;
fman->base_addr = base_addr;
 
spin_lock_init(>spinlock);
@@ -2062,6 +2080,9 @@ static int fman_init(struct fman *fman)
/* Init QMI Registers */
qmi_init(fman->qmi_regs, fman->cfg);
 
+   /* Init HW Parser */
+   hwp_init(fman->hwp_regs);
+
err = enable(fman, cfg);
if (err != 0)
return err;
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c 
b/drivers/net/ethernet/freescale/fman/fman_port.c
index 9f3bb50..f314348 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -62,6 +62,7 @@
 
 #define BMI_PORT_REGS_OFFSET   0
 #define QMI_PORT_REGS_OFFSET   0x400
+#define HWP_PORT_REGS_OFFSET   0x800
 
 /* Default values */
 #define DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN \
@@ -182,7 +183,7 @@
 #define NIA_ENG_BMI0x0050
 #define NIA_ENG_QMI_ENQ0x0054
 #define NIA_ENG_QMI_DEQ0x0058
-
+#define NIA_ENG_HWP0x0044
 #define NIA_BMI_AC_ENQ_FRAME   0x0002
 #define NIA_BMI_AC_TX_RELEASE  0x02C0
 #define NIA_BMI_AC_RELEASE 0x00C0
@@ -317,6 +318,19 @@ struct fman_port_qmi_regs {
u32 fmqm_pndcc; /* PortID n Dequeue Confirm Counter */
 };
 
+#define HWP_HXS_COUNT 16
+#define HWP_HXS_PHE_REPORT 0x0800
+#define HWP_HXS_PCAC_PSTAT 0x0100
+#define HWP_HXS_PCAC_PSTOP 0x0001
+struct fman_port_hwp_regs {
+   struct {
+   u32 ssa; /* Soft Sequence Attachment */
+   u32 lcv; /* Line-up Enable Confirmation Mask */
+   } pmda[HWP_HXS_COUNT]; /* Parse Memory Direct Access Registers */
+   u32 reserved080[(0x3f8 - 0x080) / 4]; /* (0x080-0x3f7) */
+   u32 fmpr_pcac; /* Configuration Access Control */
+};
+
 /* QMI dequeue prefetch modes */
 enum fman_port_deq_prefetch {
FMAN_PORT_DEQ_NO_PREFETCH, /* No prefetch mode */
@@ -436,6 +450,7 @@ struct fman_port {
 
union fman_port_bmi_regs __iomem *bmi_regs;
struct fman_port_qmi_regs __iomem *qmi_regs;
+   struct fman_port_hwp_regs __iomem *hwp_regs;
 
struct fman_sp_buffer_offsets buffer_offsets;
 
@@ -521,9 +536,12 @@ static int init_bmi_rx(struct fman_port *port)
/* NI

[net-next v2 00/10] QorIQ DPAA 1 updates

2017-03-09 Thread Madalin Bucur
This patch set introduces a series of fixes and features to the DPAA 1
drivers. Besides activating hardware Rx checksum offloading, four traffic
classes are added for Tx traffic prioritisation.

The changes are also available on the dpaa_eth-next branch in the git
repository at:

  git://git.freescale.com/ppc/upstream/linux.git

changes from v1: added patch to enable context-A stashing

Camelia Groza (2):
  dpaa_eth: add four prioritised Tx traffic classes
  dpaa_eth: enable multiple Tx traffic classes

Madalin Bucur (8):
  fsl/fman: parse result data is big endian
  fsl/fman: set HW parser as BMI next engine
  fsl/fman: remove wrong free
  fsl/fman: enlarge FIFO to allow for the 5th port
  dpaa_eth: remove redundant initialization
  dpaa_eth: enable Rx checksum offload
  dpaa_eth: do not ignore port api return value
  dpaa_eth: enable context-A stashing

 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c  | 178 +++-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h  |   8 +-
 drivers/net/ethernet/freescale/fman/fman.c  |  23 ++-
 drivers/net/ethernet/freescale/fman/fman.h  |  10 +-
 drivers/net/ethernet/freescale/fman/fman_port.c |  76 +-
 5 files changed, 248 insertions(+), 47 deletions(-)

-- 
2.1.0



[PATCH 9/9] dpaa_eth: enable multiple Tx traffic classes

2017-02-21 Thread Madalin Bucur
From: Camelia Groza <camelia.gr...@nxp.com>

Implement the setup_tc ndo to configure prioritised Tx traffic classes.
Priorities range from 0 (lowest) to 3 (highest). The driver assigns
NR_CPUS queues to each traffic class.

Signed-off-by: Camelia Groza <camelia.gr...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 36 ++
 1 file changed, 36 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index ac75d09..1b3ea38 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -342,6 +342,41 @@ static void dpaa_get_stats64(struct net_device *net_dev,
}
 }
 
+static int dpaa_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
+struct tc_to_netdev *tc)
+{
+   struct dpaa_priv *priv = netdev_priv(net_dev);
+   int i;
+
+   if (tc->type != TC_SETUP_MQPRIO)
+   return -EINVAL;
+
+   if (tc->tc == priv->num_tc)
+   return 0;
+
+   if (!tc->tc) {
+   netdev_reset_tc(net_dev);
+   goto out;
+   }
+
+   if (tc->tc > DPAA_TC_NUM) {
+   netdev_err(net_dev, "Too many traffic classes: max %d 
supported.\n",
+  DPAA_TC_NUM);
+   return -EINVAL;
+   }
+
+   netdev_set_num_tc(net_dev, tc->tc);
+
+   for (i = 0; i < tc->tc; i++)
+   netdev_set_tc_queue(net_dev, i, DPAA_TC_TXQ_NUM,
+   i * DPAA_TC_TXQ_NUM);
+
+out:
+   priv->num_tc = tc->tc ? tc->tc : 1;
+   netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM);
+   return 0;
+}
+
 static struct mac_device *dpaa_mac_dev_get(struct platform_device *pdev)
 {
struct platform_device *of_dev;
@@ -2417,6 +2452,7 @@ static const struct net_device_ops dpaa_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_set_rx_mode = dpaa_set_rx_mode,
.ndo_do_ioctl = dpaa_ioctl,
+   .ndo_setup_tc = dpaa_setup_tc,
 };
 
 static int dpaa_napi_add(struct net_device *net_dev)
-- 
2.1.0



[PATCH 8/9] dpaa_eth: add four prioritised Tx traffic classes

2017-02-21 Thread Madalin Bucur
From: Camelia Groza <camelia.gr...@nxp.com>

Each traffic class corresponds to a WQ priority level. The number of Tx
netdev queues and frame queues is increased to NR_CPUS queues for each
traffic class. In addition, the priority of the Rx, Error and Conf queues
is lowered but their order is maintained.

By default, only one traffic class is enabled, only the low priority Tx
queues are used and only the corresponding netdev queues are advertised.

Signed-off-by: Camelia Groza <camelia.gr...@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 43 +-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h |  8 -
 2 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index ae64cdb..ac75d09 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -565,16 +565,18 @@ static void dpaa_bps_free(struct dpaa_priv *priv)
 
 /* Use multiple WQs for FQ assignment:
  * - Tx Confirmation queues go to WQ1.
- * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
- *   to be scheduled, in case there are many more FQs in WQ3).
- * - Rx Default and Tx queues go to WQ3 (no differentiation between
- *   Rx and Tx traffic).
+ * - Rx Error and Tx Error queues go to WQ5 (giving them a better chance
+ *   to be scheduled, in case there are many more FQs in WQ6).
+ * - Rx Default goes to WQ6.
+ * - Tx queues go to different WQs depending on their priority. Equal
+ *   chunks of NR_CPUS queues go to WQ6 (lowest priority), WQ2, WQ1 and
+ *   WQ0 (highest priority).
  * This ensures that Tx-confirmed buffers are timely released. In particular,
  * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
  * are greatly outnumbered by other FQs in the system, while
  * dequeue scheduling is round-robin.
  */
-static inline void dpaa_assign_wq(struct dpaa_fq *fq)
+static inline void dpaa_assign_wq(struct dpaa_fq *fq, int idx)
 {
switch (fq->fq_type) {
case FQ_TYPE_TX_CONFIRM:
@@ -583,11 +585,33 @@ static inline void dpaa_assign_wq(struct dpaa_fq *fq)
break;
case FQ_TYPE_RX_ERROR:
case FQ_TYPE_TX_ERROR:
-   fq->wq = 2;
+   fq->wq = 5;
break;
case FQ_TYPE_RX_DEFAULT:
+   fq->wq = 6;
+   break;
case FQ_TYPE_TX:
-   fq->wq = 3;
+   switch (idx / DPAA_TC_TXQ_NUM) {
+   case 0:
+   /* Low priority (best effort) */
+   fq->wq = 6;
+   break;
+   case 1:
+   /* Medium priority */
+   fq->wq = 2;
+   break;
+   case 2:
+   /* High priority */
+   fq->wq = 1;
+   break;
+   case 3:
+   /* Very high priority */
+   fq->wq = 0;
+   break;
+   default:
+   WARN(1, "Too many TX FQs: more than %d!\n",
+DPAA_ETH_TXQ_NUM);
+   }
break;
default:
WARN(1, "Invalid FQ type %d for FQID %d!\n",
@@ -615,7 +639,7 @@ static struct dpaa_fq *dpaa_fq_alloc(struct device *dev,
}
 
for (i = 0; i < count; i++)
-   dpaa_assign_wq(dpaa_fq + i);
+   dpaa_assign_wq(dpaa_fq + i, i);
 
return dpaa_fq;
 }
@@ -2683,6 +2707,9 @@ static int dpaa_eth_probe(struct platform_device *pdev)
memset(percpu_priv, 0, sizeof(*percpu_priv));
}
 
+   priv->num_tc = 1;
+   netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM);
+
/* Initialize NAPI */
err = dpaa_napi_add(net_dev);
if (err < 0)
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
index 1f9aebf..9941a78 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
@@ -39,7 +39,12 @@
 #include "mac.h"
 #include "dpaa_eth_trace.h"
 
-#define DPAA_ETH_TXQ_NUM   NR_CPUS
+/* Number of prioritised traffic classes */
+#define DPAA_TC_NUM4
+/* Number of Tx queues per traffic class */
+#define DPAA_TC_TXQ_NUMNR_CPUS
+/* Total number of Tx queues */
+#define DPAA_ETH_TXQ_NUM   (DPAA_TC_NUM * DPAA_TC_TXQ_NUM)
 
 #define DPAA_BPS_NUM 3 /* number of bpools per interface */
 
@@ -152,6 +157,7 @@ struct dpaa_priv {
u16 channel;
struct list_head dpaa_fq_list;
 
+   u8 num_tc;
u32 msg_enable; /* net_device message level */
 
struct {
-- 
2.1.0



[PATCH 7/9] dpaa_eth: do not ignore port api return value

2017-02-21 Thread Madalin Bucur
Reported-by: Dan Carpenter <dan.carpen...@oracle.com>

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 65 +-
 1 file changed, 43 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index a7a595c..ae64cdb 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -1063,9 +1063,9 @@ static int dpaa_fq_free(struct device *dev, struct 
list_head *list)
return err;
 }
 
-static void dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq,
- struct dpaa_fq *defq,
- struct dpaa_buffer_layout *buf_layout)
+static int dpaa_eth_init_tx_port(struct fman_port *port, struct dpaa_fq *errq,
+struct dpaa_fq *defq,
+struct dpaa_buffer_layout *buf_layout)
 {
struct fman_buffer_prefix_content buf_prefix_content;
struct fman_port_params params;
@@ -1084,23 +1084,29 @@ static void dpaa_eth_init_tx_port(struct fman_port 
*port, struct dpaa_fq *errq,
params.specific_params.non_rx_params.dflt_fqid = defq->fqid;
 
err = fman_port_config(port, );
-   if (err)
+   if (err) {
pr_err("%s: fman_port_config failed\n", __func__);
+   return err;
+   }
 
err = fman_port_cfg_buf_prefix_content(port, _prefix_content);
-   if (err)
+   if (err) {
pr_err("%s: fman_port_cfg_buf_prefix_content failed\n",
   __func__);
+   return err;
+   }
 
err = fman_port_init(port);
if (err)
pr_err("%s: fm_port_init failed\n", __func__);
+
+   return err;
 }
 
-static void dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps,
- size_t count, struct dpaa_fq *errq,
- struct dpaa_fq *defq,
- struct dpaa_buffer_layout *buf_layout)
+static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp **bps,
+size_t count, struct dpaa_fq *errq,
+struct dpaa_fq *defq,
+struct dpaa_buffer_layout *buf_layout)
 {
struct fman_buffer_prefix_content buf_prefix_content;
struct fman_port_rx_params *rx_p;
@@ -1128,32 +1134,44 @@ static void dpaa_eth_init_rx_port(struct fman_port 
*port, struct dpaa_bp **bps,
}
 
err = fman_port_config(port, );
-   if (err)
+   if (err) {
pr_err("%s: fman_port_config failed\n", __func__);
+   return err;
+   }
 
err = fman_port_cfg_buf_prefix_content(port, _prefix_content);
-   if (err)
+   if (err) {
pr_err("%s: fman_port_cfg_buf_prefix_content failed\n",
   __func__);
+   return err;
+   }
 
err = fman_port_init(port);
if (err)
pr_err("%s: fm_port_init failed\n", __func__);
+
+   return err;
 }
 
-static void dpaa_eth_init_ports(struct mac_device *mac_dev,
-   struct dpaa_bp **bps, size_t count,
-   struct fm_port_fqs *port_fqs,
-   struct dpaa_buffer_layout *buf_layout,
-   struct device *dev)
+static int dpaa_eth_init_ports(struct mac_device *mac_dev,
+  struct dpaa_bp **bps, size_t count,
+  struct fm_port_fqs *port_fqs,
+  struct dpaa_buffer_layout *buf_layout,
+  struct device *dev)
 {
struct fman_port *rxport = mac_dev->port[RX];
struct fman_port *txport = mac_dev->port[TX];
+   int err;
 
-   dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
- port_fqs->tx_defq, _layout[TX]);
-   dpaa_eth_init_rx_port(rxport, bps, count, port_fqs->rx_errq,
- port_fqs->rx_defq, _layout[RX]);
+   err = dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
+   port_fqs->tx_defq, _layout[TX]);
+   if (err)
+   return err;
+
+   err = dpaa_eth_init_rx_port(rxport, bps, count, port_fqs->rx_errq,
+   port_fqs->rx_defq, _layout[RX]);
+
+   return err;
 }
 
 static int dpaa_bman_release(const struct dpaa_bp *dpaa_bp,
@@ -2649,8 +2667,10 @@ static int dpaa_eth_probe(struct platform_device *pdev)
priv->rx_headroom = dpaa_get_headroom(>buf_layout[RX]);
 
/* All real interfaces need their ports initialized */
-   dpaa_eth_

[PATCH 6/9] dpaa_eth: enable Rx checksum offload

2017-02-21 Thread Madalin Bucur
Use the FMan HW parser L4CV flag to offload Rx checksumming.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 29 --
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index e19181f..a7a595c 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -137,6 +137,13 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
 /* L4 Type field: TCP */
 #define FM_L4_PARSE_RESULT_TCP 0x20
 
+/* FD status field indicating whether the FM Parser has attempted to validate
+ * the L4 csum of the frame.
+ * Note that having this bit set doesn't necessarily imply that the checksum
+ * is valid. One would have to check the parse results to find that out.
+ */
+#define FM_FD_STAT_L4CV 0x0004
+
 #define DPAA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
 #define DPAA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once 
*/
 
@@ -235,6 +242,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
 * For conformity, we'll still declare GSO explicitly.
 */
net_dev->features |= NETIF_F_GSO;
+   net_dev->features |= NETIF_F_RXCSUM;
 
net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
/* we do not want shared skbs on TX */
@@ -1526,6 +1534,23 @@ static struct sk_buff *dpaa_cleanup_tx_fd(const struct 
dpaa_priv *priv,
return skb;
 }
 
+static u8 rx_csum_offload(const struct dpaa_priv *priv, const struct qm_fd *fd)
+{
+   /* The parser has run and performed L4 checksum validation.
+* We know there were no parser errors (and implicitly no
+* L4 csum error), otherwise we wouldn't be here.
+*/
+   if ((priv->net_dev->features & NETIF_F_RXCSUM) &&
+   (be32_to_cpu(fd->status) & FM_FD_STAT_L4CV))
+   return CHECKSUM_UNNECESSARY;
+
+   /* We're here because either the parser didn't run or the L4 checksum
+* was not verified. This may include the case of a UDP frame with
+* checksum zero or an L4 proto other than TCP/UDP
+*/
+   return CHECKSUM_NONE;
+}
+
 /* Build a linear skb around the received buffer.
  * We are guaranteed there is enough room at the end of the data buffer to
  * accommodate the shared info area of the skb.
@@ -1556,7 +1581,7 @@ static struct sk_buff *contig_fd_to_skb(const struct 
dpaa_priv *priv,
skb_reserve(skb, fd_off);
skb_put(skb, qm_fd_get_length(fd));
 
-   skb->ip_summed = CHECKSUM_NONE;
+   skb->ip_summed = rx_csum_offload(priv, fd);
 
return skb;
 
@@ -1616,7 +1641,7 @@ static struct sk_buff *sg_fd_to_skb(const struct 
dpaa_priv *priv,
if (WARN_ON(unlikely(!skb)))
goto free_buffers;
 
-   skb->ip_summed = CHECKSUM_NONE;
+   skb->ip_summed = rx_csum_offload(priv, fd);
 
/* Make sure forwarded skbs will have enough space
 * on Tx, if extra headers are added.
-- 
2.1.0



[PATCH 5/9] dpaa_eth: remove redundant initialization

2017-02-21 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index e2ca107..e19181f 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2093,7 +2093,7 @@ static enum qman_cb_dqrr_result rx_default_dqrr(struct 
qman_portal *portal,
dma_addr_t addr = qm_fd_addr(fd);
enum qm_fd_format fd_format;
struct net_device *net_dev;
-   u32 fd_status = fd->status;
+   u32 fd_status;
struct dpaa_bp *dpaa_bp;
struct dpaa_priv *priv;
unsigned int skb_len;
-- 
2.1.0



[PATCH 4/9] fsl/fman: enlarge FIFO to allow for the 5th port

2017-02-21 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index d755930..4aefe24 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -1212,7 +1212,7 @@ static int fill_soc_specific_params(struct 
fman_state_struct *state)
state->max_num_of_open_dmas = 32;
state->fm_port_num_of_cg= 256;
state->num_of_rx_ports  = 6;
-   state->total_fifo_size  = 122 * 1024;
+   state->total_fifo_size  = 136 * 1024;
break;
 
case 2:
-- 
2.1.0



[PATCH 3/9] fsl/fman: remove wrong free

2017-02-21 Thread Madalin Bucur
Reported-by: Dan Carpenter <dan.carpen...@oracle.com>

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman_port.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c 
b/drivers/net/ethernet/freescale/fman/fman_port.c
index f314348..57bf44f 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1312,7 +1312,7 @@ int fman_port_config(struct fman_port *port, struct 
fman_port_params *params)
/* Allocate the FM driver's parameters structure */
port->cfg = kzalloc(sizeof(*port->cfg), GFP_KERNEL);
if (!port->cfg)
-   goto err_params;
+   return -EINVAL;
 
/* Initialize FM port parameters which will be kept by the driver */
port->port_type = port->dts_params.type;
@@ -1393,8 +1393,6 @@ int fman_port_config(struct fman_port *port, struct 
fman_port_params *params)
 
 err_port_cfg:
kfree(port->cfg);
-err_params:
-   kfree(port);
return -EINVAL;
 }
 EXPORT_SYMBOL(fman_port_config);
-- 
2.1.0



[PATCH 2/9] fsl/fman: set HW parser as BMI next engine

2017-02-21 Thread Madalin Bucur
Enable the HW parser for all DPAA interfaces.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c  | 21 
 drivers/net/ethernet/freescale/fman/fman_port.c | 72 +++--
 2 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index f60845f..d755930 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -59,6 +59,7 @@
 #define DMA_OFFSET 0x000C2000
 #define FPM_OFFSET 0x000C3000
 #define IMEM_OFFSET0x000C4000
+#define HWP_OFFSET 0x000C7000
 #define CGP_OFFSET 0x000DB000
 
 /* Exceptions bit map */
@@ -218,6 +219,9 @@
 
 #define QMI_GS_HALT_NOT_BUSY   0x0002
 
+/* HWP defines */
+#define HWP_RPIMAC_PEN 0x0001
+
 /* IRAM defines */
 #define IRAM_IADD_AIE  0x8000
 #define IRAM_READY 0x8000
@@ -475,6 +479,12 @@ struct fman_dma_regs {
u32 res00e0[0x400 - 56];
 };
 
+struct fman_hwp_regs {
+   u32 res[0x844 / 4]; /* 0x000..0x843 */
+   u32 fmprrpimac; /* FM Parser Internal memory access control */
+   u32 res[(0x1000 - 0x848) / 4];  /* 0x848..0xFFF */
+};
+
 /* Structure that holds current FMan state.
  * Used for saving run time information.
  */
@@ -606,6 +616,7 @@ struct fman {
struct fman_bmi_regs __iomem *bmi_regs;
struct fman_qmi_regs __iomem *qmi_regs;
struct fman_dma_regs __iomem *dma_regs;
+   struct fman_hwp_regs __iomem *hwp_regs;
fman_exceptions_cb *exception_cb;
fman_bus_error_cb *bus_error_cb;
/* Spinlock for FMan use */
@@ -999,6 +1010,12 @@ static void qmi_init(struct fman_qmi_regs __iomem *qmi_rg,
iowrite32be(tmp_reg, _rg->fmqm_ien);
 }
 
+static void hwp_init(struct fman_hwp_regs __iomem *hwp_rg)
+{
+   /* enable HW Parser */
+   iowrite32be(HWP_RPIMAC_PEN, _rg->fmprrpimac);
+}
+
 static int enable(struct fman *fman, struct fman_cfg *cfg)
 {
u32 cfg_reg = 0;
@@ -1793,6 +1810,7 @@ static int fman_config(struct fman *fman)
fman->bmi_regs = base_addr + BMI_OFFSET;
fman->qmi_regs = base_addr + QMI_OFFSET;
fman->dma_regs = base_addr + DMA_OFFSET;
+   fman->hwp_regs = base_addr + HWP_OFFSET;
fman->base_addr = base_addr;
 
spin_lock_init(>spinlock);
@@ -2062,6 +2080,9 @@ static int fman_init(struct fman *fman)
/* Init QMI Registers */
qmi_init(fman->qmi_regs, fman->cfg);
 
+   /* Init HW Parser */
+   hwp_init(fman->hwp_regs);
+
err = enable(fman, cfg);
if (err != 0)
return err;
diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c 
b/drivers/net/ethernet/freescale/fman/fman_port.c
index 9f3bb50..f314348 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -62,6 +62,7 @@
 
 #define BMI_PORT_REGS_OFFSET   0
 #define QMI_PORT_REGS_OFFSET   0x400
+#define HWP_PORT_REGS_OFFSET   0x800
 
 /* Default values */
 #define DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN \
@@ -182,7 +183,7 @@
 #define NIA_ENG_BMI0x0050
 #define NIA_ENG_QMI_ENQ0x0054
 #define NIA_ENG_QMI_DEQ0x0058
-
+#define NIA_ENG_HWP0x0044
 #define NIA_BMI_AC_ENQ_FRAME   0x0002
 #define NIA_BMI_AC_TX_RELEASE  0x02C0
 #define NIA_BMI_AC_RELEASE 0x00C0
@@ -317,6 +318,19 @@ struct fman_port_qmi_regs {
u32 fmqm_pndcc; /* PortID n Dequeue Confirm Counter */
 };
 
+#define HWP_HXS_COUNT 16
+#define HWP_HXS_PHE_REPORT 0x0800
+#define HWP_HXS_PCAC_PSTAT 0x0100
+#define HWP_HXS_PCAC_PSTOP 0x0001
+struct fman_port_hwp_regs {
+   struct {
+   u32 ssa; /* Soft Sequence Attachment */
+   u32 lcv; /* Line-up Enable Confirmation Mask */
+   } pmda[HWP_HXS_COUNT]; /* Parse Memory Direct Access Registers */
+   u32 reserved080[(0x3f8 - 0x080) / 4]; /* (0x080-0x3f7) */
+   u32 fmpr_pcac; /* Configuration Access Control */
+};
+
 /* QMI dequeue prefetch modes */
 enum fman_port_deq_prefetch {
FMAN_PORT_DEQ_NO_PREFETCH, /* No prefetch mode */
@@ -436,6 +450,7 @@ struct fman_port {
 
union fman_port_bmi_regs __iomem *bmi_regs;
struct fman_port_qmi_regs __iomem *qmi_regs;
+   struct fman_port_hwp_regs __iomem *hwp_regs;
 
struct fman_sp_buffer_offsets buffer_offsets;
 
@@ -521,9 +536,12 @@ static int init_bmi_rx(struct fman_port *port)
/* NI

[PATCH 1/9] fsl/fman: parse result data is big endian

2017-02-21 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.h | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.h 
b/drivers/net/ethernet/freescale/fman/fman.h
index 57aae8d..f53e147 100644
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
@@ -134,14 +134,14 @@ enum fman_exceptions {
 struct fman_prs_result {
u8 lpid;/* Logical port id */
u8 shimr;   /* Shim header result  */
-   u16 l2r;/* Layer 2 result */
-   u16 l3r;/* Layer 3 result */
+   __be16 l2r; /* Layer 2 result */
+   __be16 l3r; /* Layer 3 result */
u8 l4r; /* Layer 4 result */
u8 cplan;   /* Classification plan id */
-   u16 nxthdr; /* Next Header  */
-   u16 cksum;  /* Running-sum */
+   __be16 nxthdr;  /* Next Header  */
+   __be16 cksum;   /* Running-sum */
/* Flags field of the last IP-header */
-   u16 flags_frag_off;
+   __be16 flags_frag_off;
/* Routing type field of a IPV6 routing extension header */
u8 route_type;
/* Routing Extension Header Present; last bit is IP valid */
-- 
2.1.0



[PATCH 0/9] QorIQ DPAA 1 updates

2017-02-21 Thread Madalin Bucur
This patch set introduces a series of fixes and features to the DPAA 1
drivers. Besides activating hardware Rx checksum offloading, four traffic
classes are added for Tx traffic prioritisation.

Camelia Groza (2):
  dpaa_eth: add four prioritised Tx traffic classes
  dpaa_eth: enable multiple Tx traffic classes

Madalin Bucur (7):
  fsl/fman: parse result data is big endian
  fsl/fman: set HW parser as BMI next engine
  fsl/fman: remove wrong free
  fsl/fman: enlarge FIFO to allow for the 5th port
  dpaa_eth: remove redundant initialization
  dpaa_eth: enable Rx checksum offload
  dpaa_eth: do not ignore port api return value

 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c  | 175 +++-
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h  |   8 +-
 drivers/net/ethernet/freescale/fman/fman.c  |  23 +++-
 drivers/net/ethernet/freescale/fman/fman.h  |  10 +-
 drivers/net/ethernet/freescale/fman/fman_port.c |  76 +-
 5 files changed, 246 insertions(+), 46 deletions(-)

-- 
2.1.0



[PATCH 2/2] dpaa_eth: Initialize CGR structure before init

2017-01-04 Thread Madalin Bucur
From: Roy Pledge 

The QBMan CGR options needs to be zeroed before calling the init
function

Signed-off-by: Roy Pledge 
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 77517aa..c9b7ad6 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -733,6 +733,7 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)
priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
 
/* Enable Congestion State Change Notifications and CS taildrop */
+   memset(, 0, sizeof(initcgr));
initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES);
initcgr.cgr.cscn_en = QM_CGR_EN;
 
@@ -2422,6 +2423,7 @@ static int dpaa_ingress_cgr_init(struct dpaa_priv *priv)
}
 
/* Enable CS TD, but disable Congestion State Change Notifications. */
+   memset(, 0, sizeof(initcgr));
initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CS_THRES);
initcgr.cgr.cscn_en = QM_CGR_EN;
cs_th = DPAA_INGRESS_CS_THRESHOLD;
-- 
2.1.0



[PATCH 0/2] dpaa_eth: a couple of fixes

2017-01-04 Thread Madalin Bucur
Add cleanup on PHY initialization failure path, avoid using
uninitialized memory at CGR init.

Madalin Bucur (1):
  dpaa_eth: cleanup after init_phy() failure

Roy Pledge (1):
  dpaa_eth: Initialize CGR structure before init

 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

-- 
2.1.0



[PATCH 1/2] dpaa_eth: cleanup after init_phy() failure

2017-01-04 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 624ba90..77517aa 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2291,7 +2291,8 @@ static int dpaa_open(struct net_device *net_dev)
net_dev->phydev = mac_dev->init_phy(net_dev, priv->mac_dev);
if (!net_dev->phydev) {
netif_err(priv, ifup, net_dev, "init_phy() failed\n");
-   return -ENODEV;
+   err = -ENODEV;
+   goto phy_init_failed;
}
 
for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
@@ -2314,6 +2315,7 @@ static int dpaa_open(struct net_device *net_dev)
for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++)
fman_port_disable(mac_dev->port[i]);
 
+phy_init_failed:
dpaa_eth_napi_disable(priv);
 
return err;
-- 
2.1.0



[PATCH] dt-bindings: qman: Remove pool channel node

2017-01-04 Thread Madalin Bucur
From: Scott Wood 

No device tree has these, nor does any driver look for them.

Signed-off-by: Scott Wood 
---
 .../devicetree/bindings/soc/fsl/qman-portals.txt | 20 
 1 file changed, 20 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/fsl/qman-portals.txt 
b/Documentation/devicetree/bindings/soc/fsl/qman-portals.txt
index 47e46cc..5a34f3a 100644
--- a/Documentation/devicetree/bindings/soc/fsl/qman-portals.txt
+++ b/Documentation/devicetree/bindings/soc/fsl/qman-portals.txt
@@ -5,7 +5,6 @@ Copyright (C) 2008 - 2014 Freescale Semiconductor Inc.
 CONTENTS
 
- QMan Portal
-   - QMan Pool Channel
- Example
 
 QMan Portal Node
@@ -82,25 +81,6 @@ These subnodes should have the following properties:
Definition: The phandle to the particular hardware device that this
portal is connected to.
 
-DPAA QMan Pool Channel Nodes
-
-Pool Channels are defined with the following properties.
-
-PROPERTIES
-
-- compatible
-   Usage:  Required
-   Value type: 
-   Definition: Must include "fsl,qman-pool-channel"
-   May include "fsl,-qman-pool-channel"
-
-- fsl,qman-channel-id
-   Usage:  Required
-   Value type: 
-   Definition: The hardware index of the channel. This can also be
-   determined by dividing any of the channel's 8 work queue
-   IDs by 8
-
 EXAMPLE
 
 The example below shows a (P4080) QMan portals container/bus node with two 
portals
-- 
2.1.0



[PATCH net v4 4/4] fsl/fman: enable compilation on ARM64

2016-12-19 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fman/Kconfig 
b/drivers/net/ethernet/freescale/fman/Kconfig
index 79b7c84..dc0850b 100644
--- a/drivers/net/ethernet/freescale/fman/Kconfig
+++ b/drivers/net/ethernet/freescale/fman/Kconfig
@@ -1,6 +1,6 @@
 config FSL_FMAN
tristate "FMan support"
-   depends on FSL_SOC || COMPILE_TEST
+   depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
select GENERIC_ALLOCATOR
select PHYLIB
default n
-- 
2.1.0



[PATCH net v4 3/4] fsl/fman: A007273 only applies to PPC SoCs

2016-12-19 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
Reviewed-by: Camelia Groza <camelia.gr...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index 4b83263..f60845f 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -1890,6 +1890,7 @@ static int fman_reset(struct fman *fman)
 
goto _return;
} else {
+#ifdef CONFIG_PPC
struct device_node *guts_node;
struct ccsr_guts __iomem *guts_regs;
u32 devdisr2, reg;
@@ -1921,6 +1922,7 @@ static int fman_reset(struct fman *fman)
 
/* Enable all MACs */
iowrite32be(reg, _regs->devdisr2);
+#endif
 
/* Perform FMan reset */
iowrite32be(FPM_RSTC_FM_RESET, >fpm_regs->fm_rstc);
@@ -1932,25 +1934,31 @@ static int fman_reset(struct fman *fman)
} while (((ioread32be(>fpm_regs->fm_rstc)) &
 FPM_RSTC_FM_RESET) && --count);
if (count == 0) {
+#ifdef CONFIG_PPC
iounmap(guts_regs);
of_node_put(guts_node);
+#endif
err = -EBUSY;
goto _return;
}
+#ifdef CONFIG_PPC
 
/* Restore devdisr2 value */
iowrite32be(devdisr2, _regs->devdisr2);
 
iounmap(guts_regs);
of_node_put(guts_node);
+#endif
 
goto _return;
 
+#ifdef CONFIG_PPC
 guts_regs:
of_node_put(guts_node);
 guts_node:
dev_dbg(fman->dev, "%s: Didn't perform FManV3 reset due to 
Errata A007273!\n",
__func__);
+#endif
}
 _return:
return err;
-- 
2.1.0



[PATCH net v4 2/4] powerpc: fsl/fman: remove fsl, fman from of_device_ids[]

2016-12-19 Thread Madalin Bucur
The fsl/fman drivers will use of_platform_populate() on all
supported platforms. Call of_platform_populate() to probe the
FMan sub-nodes.

Signed-off-by: Igal Liberman <igal.liber...@freescale.com>
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
Acked-by: Scott Wood <o...@buserror.net>
---
 arch/powerpc/platforms/85xx/corenet_generic.c | 3 ---
 drivers/net/ethernet/freescale/fman/fman.c| 7 +++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c 
b/arch/powerpc/platforms/85xx/corenet_generic.c
index 1179115..824b7f1 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -117,9 +117,6 @@ static const struct of_device_id of_device_ids[] = {
{
.compatible = "fsl,qe",
},
-   {
-   .compatible= "fsl,fman",
-   },
/* The following two are for the Freescale hypervisor */
{
.name   = "hypervisor",
diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index dafd9e1..4b83263 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -2868,6 +2868,13 @@ static struct fman *read_dts_node(struct platform_device 
*of_dev)
 
fman->dev = _dev->dev;
 
+   err = of_platform_populate(fm_node, NULL, NULL, _dev->dev);
+   if (err) {
+   dev_err(_dev->dev, "%s: of_platform_populate() failed\n",
+   __func__);
+   goto fman_free;
+   }
+
return fman;
 
 fman_node_put:
-- 
2.1.0



[PATCH net v4 1/4] fsl/fman: fix 1G support for QSGMII interfaces

2016-12-19 Thread Madalin Bucur
QSGMII ports were not advertising 1G speed.

Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
Reviewed-by: Camelia Groza <camelia.gr...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/mac.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/freescale/fman/mac.c 
b/drivers/net/ethernet/freescale/fman/mac.c
index 69ca42c..0b31f85 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -594,6 +594,7 @@ static const u16 phy2speed[] = {
[PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
[PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
[PHY_INTERFACE_MODE_RTBI]   = SPEED_1000,
+   [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
[PHY_INTERFACE_MODE_XGMII]  = SPEED_1
 };
 
-- 
2.1.0



[PATCH net v4 0/4] fsl/fman: fixes for ARM

2016-12-19 Thread Madalin Bucur
The patch set fixes advertised speeds for QSGMII interfaces, disables
A007273 erratum workaround on non-PowerPC platforms where it does not
apply, enables compilation on ARM64 and addresses a probing issue on
non PPC platforms.

Changes from v3: removed redundant comment, added ack by Scott
Changes from v2: merged fsl/fman changes to avoid a point of failure
Changes from v1: unifying probing on all supported platforms

Madalin Bucur (4):
  fsl/fman: fix 1G support for QSGMII interfaces
  powerpc: fsl/fman: remove fsl,fman from of_device_ids[]
  fsl/fman: A007273 only applies to PPC SoCs
  fsl/fman: enable compilation on ARM64

 arch/powerpc/platforms/85xx/corenet_generic.c |  3 ---
 drivers/net/ethernet/freescale/fman/Kconfig   |  2 +-
 drivers/net/ethernet/freescale/fman/fman.c| 15 +++
 drivers/net/ethernet/freescale/fman/mac.c |  1 +
 4 files changed, 17 insertions(+), 4 deletions(-)

-- 
2.1.0



[PATCH net v3 4/4] fsl/fman: enable compilation on ARM64

2016-12-19 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fman/Kconfig 
b/drivers/net/ethernet/freescale/fman/Kconfig
index 79b7c84..dc0850b 100644
--- a/drivers/net/ethernet/freescale/fman/Kconfig
+++ b/drivers/net/ethernet/freescale/fman/Kconfig
@@ -1,6 +1,6 @@
 config FSL_FMAN
tristate "FMan support"
-   depends on FSL_SOC || COMPILE_TEST
+   depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
select GENERIC_ALLOCATOR
select PHYLIB
default n
-- 
2.1.0



[PATCH net v3 3/4] fsl/fman: A007273 only applies to PPC SoCs

2016-12-19 Thread Madalin Bucur
Signed-off-by: Madalin Bucur <madalin.bu...@nxp.com>
Reviewed-by: Camelia Groza <camelia.gr...@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c 
b/drivers/net/ethernet/freescale/fman/fman.c
index 0b7f711..003b86d 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -1890,6 +1890,7 @@ static int fman_reset(struct fman *fman)
 
goto _return;
} else {
+#ifdef CONFIG_PPC
struct device_node *guts_node;
struct ccsr_guts __iomem *guts_regs;
u32 devdisr2, reg;
@@ -1921,6 +1922,7 @@ static int fman_reset(struct fman *fman)
 
/* Enable all MACs */
iowrite32be(reg, _regs->devdisr2);
+#endif
 
/* Perform FMan reset */
iowrite32be(FPM_RSTC_FM_RESET, >fpm_regs->fm_rstc);
@@ -1932,25 +1934,31 @@ static int fman_reset(struct fman *fman)
} while (((ioread32be(>fpm_regs->fm_rstc)) &
 FPM_RSTC_FM_RESET) && --count);
if (count == 0) {
+#ifdef CONFIG_PPC
iounmap(guts_regs);
of_node_put(guts_node);
+#endif
err = -EBUSY;
goto _return;
}
+#ifdef CONFIG_PPC
 
/* Restore devdisr2 value */
iowrite32be(devdisr2, _regs->devdisr2);
 
iounmap(guts_regs);
of_node_put(guts_node);
+#endif
 
goto _return;
 
+#ifdef CONFIG_PPC
 guts_regs:
of_node_put(guts_node);
 guts_node:
dev_dbg(fman->dev, "%s: Didn't perform FManV3 reset due to 
Errata A007273!\n",
__func__);
+#endif
}
 _return:
return err;
-- 
2.1.0



  1   2   3   >