diff options
author | Yangbo Lu <yangbo.lu@nxp.com> | 2020-04-10 10:47:05 +0800 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2020-05-07 12:53:06 +0200 |
commit | cddd4591404fb4c53dc0b3c0b15b942cdbed4356 (patch) | |
tree | 392c1179de46b0f804e3789edca19069b64e6b44 /target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch | |
parent | d1d2c0b5579ea4f69a42246c9318539d61ba1999 (diff) | |
download | upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.gz upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.bz2 upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.zip |
layerscape: add patches-5.4
Add patches for linux-5.4. The patches are from NXP LSDK-20.04 release
which was tagged LSDK-20.04-V5.4.
https://source.codeaurora.org/external/qoriq/qoriq-components/linux/
For boards LS1021A-IOT, and Traverse-LS1043 which are not involved in
LSDK, port the dts patches from 4.14.
The patches are sorted into the following categories:
301-arch-xxxx
302-dts-xxxx
303-core-xxxx
701-net-xxxx
801-audio-xxxx
802-can-xxxx
803-clock-xxxx
804-crypto-xxxx
805-display-xxxx
806-dma-xxxx
807-gpio-xxxx
808-i2c-xxxx
809-jailhouse-xxxx
810-keys-xxxx
811-kvm-xxxx
812-pcie-xxxx
813-pm-xxxx
814-qe-xxxx
815-sata-xxxx
816-sdhc-xxxx
817-spi-xxxx
818-thermal-xxxx
819-uart-xxxx
820-usb-xxxx
821-vfio-xxxx
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Diffstat (limited to 'target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch b/target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch new file mode 100644 index 0000000000..b4767511f4 --- /dev/null +++ b/target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch @@ -0,0 +1,385 @@ +From 136d46d2fa27815cc4cc3a57d5e3d54523028768 Mon Sep 17 00:00:00 2001 +From: Sachin Saxena <sachin.saxena@nxp.com> +Date: Thu, 19 Dec 2019 12:57:35 +0530 +Subject: [PATCH] fsl_qbman: Framework for enabling Link status notification + + - This will enable link update event notification for + user space USDPAA application. + +Signed-off-by: Sachin Saxena <sachin.saxena@nxp.com> +DPDK-2128 +(cherry picked from commit fb53c813a779cc3fc28c8ed3fc8bc0dde24db0ea) +--- + drivers/staging/fsl_qbman/Makefile | 4 + + drivers/staging/fsl_qbman/fsl_usdpaa.c | 278 ++++++++++++++++++++++++++++++++- + include/linux/fsl_usdpaa.h | 32 ++++ + 3 files changed, 313 insertions(+), 1 deletion(-) + +--- a/drivers/staging/fsl_qbman/Makefile ++++ b/drivers/staging/fsl_qbman/Makefile +@@ -1,5 +1,9 @@ + subdir-ccflags-y := -Werror + ++# Include netcomm SW specific definitions ++include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk ++ccflags-y += -I$(NET_DPA) ++ + # Common + obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o + obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o +--- a/drivers/staging/fsl_qbman/fsl_usdpaa.c ++++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c +@@ -18,6 +18,8 @@ + #include <linux/slab.h> + #include <linux/mman.h> + #include <linux/of_reserved_mem.h> ++#include <linux/eventfd.h> ++#include <linux/fdtable.h> + + #if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64)) + #include <mm/mmu_decl.h> +@@ -27,6 +29,26 @@ + #include <linux/fsl_usdpaa.h> + #include "bman_low.h" + #include "qman_low.h" ++/* Headers requires for ++ * Link status support ++ */ ++#include <linux/device.h> ++#include <linux/of_mdio.h> ++#include "mac.h" ++#include "dpaa_eth_common.h" ++ ++/* Private data for Proxy Interface */ ++struct dpa_proxy_priv_s { ++ struct mac_device *mac_dev; ++ struct eventfd_ctx *efd_ctx; ++}; ++/* Interface Helpers */ ++static inline struct device *get_dev_ptr(char *if_name); ++static void phy_link_updates(struct net_device *net_dev); ++/* IOCTL handlers */ ++static inline int ioctl_usdpaa_get_link_status(char *if_name); ++static int ioctl_en_if_link_status(struct usdpaa_ioctl_link_status *args); ++static int ioctl_disable_if_link_status(char *if_name); + + /* Physical address range of the memory reservation, exported for mm/mem.c */ + static u64 phys_start; +@@ -556,7 +578,6 @@ static bool check_portal_channel(void *c + + + +- + static int usdpaa_release(struct inode *inode, struct file *filp) + { + int err = 0; +@@ -1656,6 +1677,220 @@ found: + return 0; + } + ++ ++static inline struct device *get_dev_ptr(char *if_name) ++{ ++ struct device *dev; ++ char node[NODE_NAME_LEN]; ++ ++ sprintf(node, "soc:fsl,dpaa:%s",if_name); ++ dev = bus_find_device_by_name(&platform_bus_type, NULL, node); ++ if (dev == NULL) { ++ pr_err(KBUILD_MODNAME "IF %s not found\n", if_name); ++ return NULL; ++ } ++ pr_debug("%s: found dev 0x%lX for If %s ,dev->platform_data %p\n", ++ __func__, (unsigned long)dev, ++ if_name, dev->platform_data); ++ ++ return dev; ++} ++ ++/* This function will return Current link status of the device ++ * '1' if Link is UP, '0' otherwise. ++ * ++ * Input parameter: ++ * if_name: Interface node name ++ * ++ */ ++static inline int ioctl_usdpaa_get_link_status(char *if_name) ++{ ++ struct net_device *net_dev = NULL; ++ struct device *dev; ++ ++ dev = get_dev_ptr(if_name); ++ if (dev == NULL) ++ return -ENODEV; ++ net_dev = dev->platform_data; ++ if (net_dev == NULL) ++ return -ENODEV; ++ ++ if (test_bit(__LINK_STATE_NOCARRIER, &net_dev->state)) ++ return 0; /* Link is DOWN */ ++ else ++ return 1; /* Link is UP */ ++} ++ ++ ++/* Link Status Callback Function ++ * This function will be resgitered to PHY framework to get ++ * Link update notifications and should be responsible for waking up ++ * user space task when there is a link update notification. ++ */ ++static void phy_link_updates(struct net_device *net_dev) ++{ ++ struct dpa_proxy_priv_s *priv = NULL; ++ ++ pr_debug("%s: Link '%s': Speed '%d-Mbps': Autoneg '%d': Duplex '%d'\n", ++ net_dev->name, ++ ioctl_usdpaa_get_link_status(net_dev->name)?"UP":"DOWN", ++ net_dev->phydev->speed, ++ net_dev->phydev->autoneg, ++ net_dev->phydev->duplex); ++ ++ /* Wake up the user space context to notify PHY update */ ++ priv = netdev_priv(net_dev); ++ eventfd_signal(priv->efd_ctx, 1); ++} ++ ++ ++/* IOCTL handler for enabling Link status request for a given interface ++ * Input parameters: ++ * args->if_name: This the network interface node name as defind in ++ * device tree file. Currently, it has format of ++ * "ethernet@x" type for each interface. ++ * args->efd: The eventfd value which should be waked up when ++ * there is any link update received. ++ */ ++static int ioctl_en_if_link_status(struct usdpaa_ioctl_link_status *args) ++{ ++ struct net_device *net_dev = NULL; ++ struct dpa_proxy_priv_s *priv = NULL; ++ struct device *dev; ++ struct mac_device *mac_dev; ++ struct proxy_device *proxy_dev; ++ struct task_struct *userspace_task = NULL; ++ struct file *efd_file = NULL; ++ ++ dev = get_dev_ptr(args->if_name); ++ if (dev == NULL) ++ return -ENODEV; ++ /* Utilize dev->platform_data to save netdevice ++ pointer as it will not be registered */ ++ if (dev->platform_data) { ++ pr_debug("%s: IF %s already initialized\n", ++ __func__, args->if_name); ++ /* This will happen when application is not able to initiate ++ * cleanup in last run. We still need to save the new ++ * eventfd context. ++ */ ++ net_dev = dev->platform_data; ++ priv = netdev_priv(net_dev); ++ ++ /* Get current task context from which IOCTL was called */ ++ userspace_task = current; ++ ++ rcu_read_lock(); ++ efd_file = fcheck_files(userspace_task->files, args->efd); ++ rcu_read_unlock(); ++ ++ priv->efd_ctx = eventfd_ctx_fileget(efd_file); ++ if (!priv->efd_ctx) { ++ pr_err(KBUILD_MODNAME "get eventfd context failed\n"); ++ /* Free the allocated memory for net device */ ++ dev->platform_data = NULL; ++ free_netdev(net_dev); ++ return -EINVAL; ++ } ++ /* Since there will be NO PHY update as link is already setup, ++ * wake user context once so that current PHY status can ++ * be fetched. ++ */ ++ phy_link_updates(net_dev); ++ return 0; ++ } ++ ++ proxy_dev = dev_get_drvdata(dev); ++ mac_dev = proxy_dev->mac_dev; ++ /* Allocate an dummy net device for proxy interface */ ++ net_dev = alloc_etherdev(sizeof(*priv)); ++ if (!net_dev) { ++ pr_err(KBUILD_MODNAME "alloc_etherdev failed\n"); ++ return -ENOMEM; ++ } else { ++ SET_NETDEV_DEV(net_dev, dev); ++ priv = netdev_priv(net_dev); ++ priv->mac_dev = mac_dev; ++ /* Get current task context from which IOCTL was called */ ++ userspace_task = current; ++ ++ rcu_read_lock(); ++ efd_file = fcheck_files(userspace_task->files, args->efd); ++ rcu_read_unlock(); ++ ++ priv->efd_ctx = eventfd_ctx_fileget(efd_file); ++ ++ if (!priv->efd_ctx) { ++ pr_err(KBUILD_MODNAME "get eventfd context failed\n"); ++ /* Free the allocated memory for net device */ ++ free_netdev(net_dev); ++ return -EINVAL; ++ } ++ strncpy(net_dev->name, args->if_name, IF_NAME_MAX_LEN); ++ dev->platform_data = net_dev; ++ } ++ ++ pr_debug("%s: mac_dev %p cell_index %d\n", ++ __func__, mac_dev, mac_dev->cell_index); ++ mac_dev->phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, ++ phy_link_updates, 0, mac_dev->phy_if); ++ if (unlikely(mac_dev->phy_dev == NULL) || IS_ERR(mac_dev->phy_dev)) { ++ pr_err("%s: --------Error in PHY Connect\n", __func__); ++ /* Free the allocated memory for net device */ ++ free_netdev(net_dev); ++ return -ENODEV; ++ } ++ net_dev->phydev = mac_dev->phy_dev; ++ mac_dev->start(mac_dev); ++ pr_debug("%s: --- PHY connected for %s\n", __func__, args->if_name); ++ ++ return 0; ++} ++ ++/* IOCTL handler for disabling Link status for a given interface ++ * Input parameters: ++ * if_name: This the network interface node name as defind in ++ * device tree file. Currently, it has format of ++ * "ethernet@x" type for each interface. ++ */ ++static int ioctl_disable_if_link_status(char *if_name) ++{ ++ struct net_device *net_dev = NULL; ++ struct device *dev; ++ struct mac_device *mac_dev; ++ struct proxy_device *proxy_dev; ++ struct dpa_proxy_priv_s *priv = NULL; ++ ++ dev = get_dev_ptr(if_name); ++ if (dev == NULL) ++ return -ENODEV; ++ /* Utilize dev->platform_data to save netdevice ++ pointer as it will not be registered */ ++ if (!dev->platform_data) { ++ pr_debug("%s: IF %s already Disabled for Link status\n", ++ __func__, if_name); ++ return 0; ++ } ++ ++ net_dev = dev->platform_data; ++ proxy_dev = dev_get_drvdata(dev); ++ mac_dev = proxy_dev->mac_dev; ++ mac_dev->stop(mac_dev); ++ ++ priv = netdev_priv(net_dev); ++ eventfd_ctx_put(priv->efd_ctx); ++ ++ /* This will also deregister the call back */ ++ phy_disconnect(mac_dev->phy_dev); ++ phy_resume(mac_dev->phy_dev); ++ ++ free_netdev(net_dev); ++ dev->platform_data = NULL; ++ ++ pr_debug("%s: Link status Disabled for %s\n", __func__, if_name); ++ return 0; ++} ++ + static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) + { + struct ctx *ctx = fp->private_data; +@@ -1722,6 +1957,47 @@ static long usdpaa_ioctl(struct file *fp + return -EFAULT; + return ioctl_free_raw_portal(fp, ctx, &input); + } ++ case USDPAA_IOCTL_ENABLE_LINK_STATUS_INTERRUPT: ++ { ++ struct usdpaa_ioctl_link_status input; ++ int ret; ++ ++ if (copy_from_user(&input, a, sizeof(input))) ++ return -EFAULT; ++ ret = ioctl_en_if_link_status(&input); ++ if (ret) ++ pr_err("Error(%d) enable link interrupt:IF: %s\n", ++ ret, input.if_name); ++ return ret; ++ } ++ case USDPAA_IOCTL_DISABLE_LINK_STATUS_INTERRUPT: ++ { ++ char *input; ++ int ret; ++ ++ if (copy_from_user(&input, a, sizeof(input))) ++ return -EFAULT; ++ ret = ioctl_disable_if_link_status(input); ++ if (ret) ++ pr_err("Error(%d) Disabling link interrupt:IF: %s\n", ++ ret, input); ++ return ret; ++ } ++ case USDPAA_IOCTL_GET_LINK_STATUS: ++ { ++ struct usdpaa_ioctl_link_status_args input; ++ ++ if (copy_from_user(&input, a, sizeof(input))) ++ return -EFAULT; ++ ++ input.link_status = ioctl_usdpaa_get_link_status(input.if_name); ++ if (input.link_status < 0) ++ return input.link_status; ++ if (copy_to_user(a, &input, sizeof(input))) ++ return -EFAULT; ++ ++ return 0; ++ } + } + return -EINVAL; + } +--- a/include/linux/fsl_usdpaa.h ++++ b/include/linux/fsl_usdpaa.h +@@ -365,6 +365,38 @@ int dpa_alloc_pop(struct dpa_alloc *allo + int dpa_alloc_check(struct dpa_alloc *list, u32 id); + #endif /* __KERNEL__ */ + ++ ++/************************************ ++ * Link Status support for user space ++ * interface ++ ************************************/ ++#define IF_NAME_MAX_LEN 16 ++#define NODE_NAME_LEN 32 ++ ++struct usdpaa_ioctl_link_status { ++ /* network device node name */ ++ char if_name[IF_NAME_MAX_LEN]; ++ /* Eventfd value */ ++ uint32_t efd; ++}; ++ ++#define USDPAA_IOCTL_ENABLE_LINK_STATUS_INTERRUPT \ ++ _IOW(USDPAA_IOCTL_MAGIC, 0x0E, struct usdpaa_ioctl_link_status) ++ ++#define USDPAA_IOCTL_DISABLE_LINK_STATUS_INTERRUPT \ ++ _IOW(USDPAA_IOCTL_MAGIC, 0x0F, char *) ++ ++struct usdpaa_ioctl_link_status_args { ++ /* network device node name */ ++ char if_name[IF_NAME_MAX_LEN]; ++ /* link status(UP/DOWN) */ ++ int link_status; ++}; ++ ++#define USDPAA_IOCTL_GET_LINK_STATUS \ ++ _IOWR(USDPAA_IOCTL_MAGIC, 0x10, struct usdpaa_ioctl_link_status_args) ++ ++ + #ifdef __cplusplus + } + #endif |