mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-30 21:44:27 -04:00 
			
		
		
		
	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>
		
			
				
	
	
		
			386 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			386 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| 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
 |