aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch
diff options
context:
space:
mode:
authorYangbo Lu <yangbo.lu@nxp.com>2020-04-10 10:47:05 +0800
committerPetr Štetiar <ynezz@true.cz>2020-05-07 12:53:06 +0200
commitcddd4591404fb4c53dc0b3c0b15b942cdbed4356 (patch)
tree392c1179de46b0f804e3789edca19069b64e6b44 /target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch
parentd1d2c0b5579ea4f69a42246c9318539d61ba1999 (diff)
downloadupstream-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.patch385
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