From 25d189ea016270d1d7ab67eafc57bc8989b5381c Mon Sep 17 00:00:00 2001 From: Akhil Goyal Date: Fri, 13 Apr 2018 15:41:28 +0530 Subject: [PATCH] staging: fsl_ppfe/eth: support for userspace networking This patch adds the userspace mode support to fsl_ppfe network driver. In the new mode, basic hardware initialization is performed in kernel, while the datapath and HIF handling is the responsibility of the userspace. The new command line parameter is added to initialize the ppfe module in userspace mode. By default the module remains in kernelspace networking mode. To enable userspace mode, use "insmod pfe.ko us=1" Signed-off-by: Akhil Goyal Signed-off-by: Gagandeep Singh --- drivers/staging/fsl_ppfe/pfe_eth.c | 21 +++++++++++++++++++-- drivers/staging/fsl_ppfe/pfe_mod.c | 15 +++++++++++++++ drivers/staging/fsl_ppfe/pfe_mod.h | 2 ++ 3 files changed, 36 insertions(+), 2 deletions(-) --- a/drivers/staging/fsl_ppfe/pfe_eth.c +++ b/drivers/staging/fsl_ppfe/pfe_eth.c @@ -2296,6 +2296,8 @@ static int pfe_eth_init_one(struct pfe * goto err0; } + if (us) + emac_txq_cnt = EMAC_TXQ_CNT; /* Create an ethernet device instance */ ndev = alloc_etherdev_mq(sizeof(*priv), emac_txq_cnt); @@ -2342,6 +2344,9 @@ static int pfe_eth_init_one(struct pfe * } } + if (us) + goto phy_init; + ndev->mtu = 1500; /* Set MTU limits */ @@ -2381,6 +2386,8 @@ static int pfe_eth_init_one(struct pfe * netdev_err(ndev, "register_netdev() failed\n"); goto err3; } + +phy_init: device_init_wakeup(&ndev->dev, WAKE_MAGIC); if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) { @@ -2392,6 +2399,12 @@ static int pfe_eth_init_one(struct pfe * } } + if (us) { + if (priv->phydev) + phy_start(priv->phydev); + return 0; + } + netif_carrier_on(ndev); /* Create all the sysfs files */ @@ -2403,6 +2416,8 @@ static int pfe_eth_init_one(struct pfe * return 0; err4: + if (us) + goto err3; unregister_netdev(ndev); err3: pfe_eth_mdio_exit(priv->mii_bus); @@ -2449,9 +2464,11 @@ static void pfe_eth_exit_one(struct pfe_ { netif_info(priv, probe, priv->ndev, "%s\n", __func__); - pfe_eth_sysfs_exit(priv->ndev); + if (!us) { + pfe_eth_sysfs_exit(priv->ndev); - unregister_netdev(priv->ndev); + unregister_netdev(priv->ndev); + } if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) pfe_phy_exit(priv->ndev); --- a/drivers/staging/fsl_ppfe/pfe_mod.c +++ b/drivers/staging/fsl_ppfe/pfe_mod.c @@ -19,6 +19,10 @@ #include #include "pfe_mod.h" +unsigned int us; +module_param(us, uint, 0444); +MODULE_PARM_DESC(us, "0: module enabled for kernel networking (DEFAULT)\n" + "1: module enabled for userspace networking\n"); struct pfe *pfe; /* @@ -56,6 +60,9 @@ int pfe_probe(struct pfe *pfe) if (rc < 0) goto err_hw; + if (us) + goto firmware_init; + rc = pfe_hif_lib_init(pfe); if (rc < 0) goto err_hif_lib; @@ -64,6 +71,7 @@ int pfe_probe(struct pfe *pfe) if (rc < 0) goto err_hif; +firmware_init: rc = pfe_firmware_init(pfe); if (rc < 0) goto err_firmware; @@ -99,6 +107,9 @@ err_ctrl: pfe_firmware_exit(pfe); err_firmware: + if (us) + goto err_hif_lib; + pfe_hif_exit(pfe); err_hif: @@ -131,10 +142,14 @@ int pfe_remove(struct pfe *pfe) #endif pfe_firmware_exit(pfe); + if (us) + goto hw_exit; + pfe_hif_exit(pfe); pfe_hif_lib_exit(pfe); +hw_exit: pfe_hw_exit(pfe); return 0; --- a/drivers/staging/fsl_ppfe/pfe_mod.h +++ b/drivers/staging/fsl_ppfe/pfe_mod.h @@ -22,6 +22,8 @@ #include #include +extern unsigned int us; + struct pfe; #include "pfe_hw.h"