--- /dev/null
+# Copyright (C) 2012 OpenWrt.org
+# Copyright (C) 2015-2016 Lantiq Beteiligungs GmbH & Co KG.
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=ltq-vdsl-vr11
+PKG_VERSION:=4.23.1
+PKG_RELEASE:=$(AUTORELEASE)
+PKG_BASE_NAME:=dsl_cpe_api
+
+UGW_VERSION=8.5.2.10
+UGW_BASENAME=$(PKG_BASE_NAME)-ugw_$(UGW_VERSION)
+
+PKG_SOURCE:=$(UGW_BASENAME).tar.bz2
+PKG_SOURCE_URL:=https://gitlab.com/prpl-foundation/intel/$(PKG_BASE_NAME)/-/archive/ugw_$(UGW_VERSION)/
+PKG_HASH:=5e8bbab841d67dc16e329d9b3774f6db4189dd1d01f575d0e921ccf2c426dd9f
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(UGW_BASENAME)
+PKG_LICENSE:=GPL-2.0 BSD-2-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+# TODO this driver depends on the vrx518 dsl firmware, add this dependency if
+# that ever gets a compatible license
+define KernelPackage/ltq-vdsl-vr11
+ TITLE:=vdsl driver
+ SECTION:=sys
+ SUBMENU:=Network Devices
+ DEPENDS:=@TARGET_ipq40xx +kmod-ltq-vdsl-vr11-mei
+ FILES:=$(PKG_BUILD_DIR)/src/drv_dsl_cpe_api.ko
+ AUTOLOAD:=$(call AutoLoad,51,drv_dsl_cpe_api)
+endef
+
+define Package/ltq-vdsl-vr11/description
+ This package contains the Lantiq DSL CPE API driver.
+
+ Supported Devices:
+ - VRX500 Family
+endef
+
+MAKE_FLAGS += \
+ $(KERNEL_MAKE_FLAGS) \
+ SHELL="$(BASH)"
+
+CONFIGURE_ARGS += \
+ --enable-add-drv-cflags="" \
+ --enable-add_ext_drv_cflags="-DDSL_DRV_ATM_PTM_INTERFACE_ENABLE=1" \
+ --enable-debug-logger-support=no
+
+CONFIGURE_ARGS += --enable-kernel-include="$(LINUX_DIR)/include" \
+ --enable-vrx \
+ --enable-vrx-device=vr11 \
+ --enable-ifxos \
+ --enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos" \
+ --enable-driver-include="-I$(STAGING_DIR)/usr/include/vdsl" \
+ --enable-linux-26 \
+ --enable-kernelbuild="$(LINUX_DIR)" \
+ --enable-debug-prints=no \
+ ARCH=$(LINUX_KARCH)
+
+CONFIGURE_ARGS += \
+ --enable-model=full \
+ --enable-dsl-ceoc=no
+#CONFIGURE_ARGS += --enable-model=lite
+#CONFIGURE_ARGS += --enable-model=footprint
+#CONFIGURE_ARGS += --enable-model=typical
+#CONFIGURE_ARGS += --enable-model=debug
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/drv_vdsl_cpe_api
+ $(CP) $(PKG_BUILD_DIR)/src/include/drv_dsl_cpe*.h $(1)/usr/include/drv_vdsl_cpe_api/
+endef
+
+$(eval $(call KernelPackage,ltq-vdsl-vr11))
--- /dev/null
+--- a/src/include/drv_dsl_cpe_os_linux.h
++++ b/src/include/drv_dsl_cpe_os_linux.h
+@@ -36,6 +36,7 @@
+ #endif
+
+ #include <linux/sched.h>
++#include <linux/sched/signal.h>
+
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+--- a/configure.in
++++ b/configure.in
+@@ -422,7 +422,7 @@ AC_ARG_ENABLE(debug-prints,
+ AC_SUBST([DSL_DBG_MAX_LEVEL_SET],[no])
+
+ AC_SUBST([DSL_DBG_MAX_LEVEL_PRE],[n/a])
+- AC_SUBST([INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT],[no])
++ AC_SUBST([INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT],[yes])
+ ;;
+ no | none )
+ AC_DEFINE(DSL_DEBUG_DISABLE,,[Disabled debug prints])
+@@ -433,7 +433,7 @@ AC_ARG_ENABLE(debug-prints,
+ AC_SUBST([DSL_DBG_MAX_LEVEL_SET],[no])
+
+ AC_SUBST([DSL_DBG_MAX_LEVEL_PRE],[n/a])
+- AC_SUBST([INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT],[yes])
++ AC_SUBST([INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT],[no])
+ ;;
+ prn | 0x1 )
+ AC_SUBST([DSL_DEBUG_DISABLE],[no])
+--- a/src/common/drv_dsl_cpe_api.c
++++ b/src/common/drv_dsl_cpe_api.c
+@@ -88,8 +88,12 @@ static DSL_uint32_t g_VRxPD_IOctlWhiteli
+ DSL_FIO_BAND_PLAN_STATUS_GET,
+ DSL_FIO_DBG_MODULE_LEVEL_GET,
+ DSL_FIO_DBG_MODULE_LEVEL_SET,
++#ifdef INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT
++#ifndef DSL_DEBUG_DISABLE
+ DSL_FIO_DBG_MODULE_DESTINATION_GET,
+ DSL_FIO_DBG_MODULE_DESTINATION_SET,
++#endif /* DSL_DEBUG_DISABLE*/
++#endif /* INCLUDE_DSL_CPE_DEBUG_LOGGER_SUPPORT */
+ DSL_FIO_OPERATOR_CONFIG_GET,
+ DSL_FIO_OPERATOR_CONFIG_SET,
+ /* Delimeter only. Keep it! */
+--- a/src/common/drv_dsl_cpe_os_linux.c
++++ b/src/common/drv_dsl_cpe_os_linux.c
+@@ -625,7 +625,7 @@ DSL_void_t* DSL_DRV_VMalloc(
+ DSL_DRV_size_t nSize)
+ {
+ /* VRX500-BU: Better to use vmalloc or vzmalloc here?! */
+- return __vmalloc((unsigned long)nSize, GFP_KERNEL, PAGE_KERNEL);
++ return __vmalloc((unsigned long)nSize, GFP_KERNEL);
+ /* return vmalloc(nSize);*/
+ }
+
+--- a/src/include/drv_dsl_cpe_debug.h
++++ b/src/include/drv_dsl_cpe_debug.h
+@@ -99,6 +99,7 @@ DSL_void_t DSL_DRV_ErrorSet(DSL_void_t *
+ /** Terminate execution if assertion fails */
+ #define DSL_ASSERT(exp) ((void)0)
+
++ #define DSL_DEBUG_LIMIT(level, body) ((void)0)
+ #else
+
+ #define DSL_DEBUG_SET_ERROR(code) DSL_DRV_ErrorSet(pContext, code);
+--- a/src/pm/drv_dsl_cpe_pm_core.c
++++ b/src/pm/drv_dsl_cpe_pm_core.c
+@@ -26,6 +26,7 @@
+ #define DSL_DBG_BLOCK DSL_DBG_PM
+
+ #ifdef __LINUX__
++#ifndef DSL_DEBUG_DISABLE
+ #define DSL_PM_CORE_RATELIMIT_INTERVAL 20 * HZ /* for each 20 seconds */
+ #define DSL_PM_CORE_RATELIMIT_BURST 1 /* 1 occurrence */
+ /* struct ratelimit_state to be used in DSL_DEBUG_LIMIT */
+@@ -33,6 +34,7 @@ static DEFINE_RATELIMIT_STATE(
+ DSL_DBG_RATELIMIT_STRUCT_NAME(DSL_DBG_BLOCK),
+ DSL_PM_CORE_RATELIMIT_INTERVAL,
+ DSL_PM_CORE_RATELIMIT_BURST);
++#endif
+ #endif/* __LINUX__ */
+
+ DSL_boolean_t DSL_DRV_PM_IsPmReady(
--- /dev/null
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -283,10 +283,7 @@ else
+ drv_dsl_cpe_api_common_mod_cflags =
+ endif
+
+-drv_dsl_cpe_api_common_cflags = -DLINUX -D__LINUX__ -D__KERNEL__ -DEXPORT_SYMTAB \
+- -pipe -Wall -Wformat -Wimplicit -Wunused -Wswitch -Wcomment -Winline \
+- -Wuninitialized -Wparentheses -Wreturn-type \
+- -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common
++drv_dsl_cpe_api_common_cflags = -DLINUX -D__LINUX__ -D__KERNEL__ -DEXPORT_SYMTAB
+
+ if DSL_DBG_MAX_LEVEL_SET
+ drv_dsl_cpe_api_common_cflags += -DDSL_DBG_MAX_LEVEL=$(DSL_DBG_MAX_LEVEL_PRE)
+@@ -296,7 +293,7 @@ endif
+ drv_dsl_cpe_api_target_cflags = $(ADD_DRV_CFLAGS)
+
+ # compile cflags
+-drv_dsl_cpe_api_compile_cflags = $(EXTRA_DRV_CFLAGS)
++drv_dsl_cpe_api_compile_cflags =
+
+ if !KERNEL_2_6
+ # the headerfile of linux kernels 2.6.x contain to much arithmetic
--- /dev/null
+--- a/src/common/drv_dsl_cpe_os_linux.c
++++ b/src/common/drv_dsl_cpe_os_linux.c
+@@ -1051,12 +1051,11 @@ DSL_int32_t DSL_DRV_ThreadShutdown(
+
+ DSL_uint32_t DSL_DRV_SysTimeGet(DSL_uint32_t nOffset)
+ {
+- struct timeval tv;
++ struct timespec64 now;
+ DSL_uint32_t nTime = 0;
+
+- memset(&tv, 0, sizeof(tv));
+- do_gettimeofday(&tv);
+- nTime = (DSL_uint32_t)tv.tv_sec;
++ ktime_get_real_ts64(&now);
++ nTime = (DSL_uint32_t)now.tv_sec;
+
+ if ( (nOffset == 0) || (nOffset > nTime) )
+ {
--- /dev/null
+--- a/src/include/drv_dsl_cpe_pm_core.h
++++ b/src/include/drv_dsl_cpe_pm_core.h
+@@ -1554,9 +1554,9 @@ typedef struct
+ DSL_boolean_t bShowtimeProcessingStart;
+ /** Showtime reached flag*/
+ DSL_boolean_t bShowtimeInvTrigger;
+- /** Current Showtime synchronization time to be used, (msec) */
++ /** Current Showtime synchronization time to be used, (sec) */
+ DSL_uint32_t nCurrShowtimeTime;
+- /** Showtime synchronization time to be used, (msec) */
++ /** Showtime synchronization time to be used, (sec) */
+ DSL_uint32_t nElapsedShowtimeTime;
+ /** Actual Line state*/
+ DSL_LineStateValue_t nLineState;
+--- a/src/pm/drv_dsl_cpe_api_pm.c
++++ b/src/pm/drv_dsl_cpe_api_pm.c
+@@ -1633,7 +1633,7 @@ DSL_Error_t DSL_DRV_PM_ChannelCountersTo
+ }
+
+ /* Fill Total Counters elapsed time*/
+- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
++ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
+
+ pChCounters = DSL_DRV_PM_PTR_CHANNEL_COUNTERS_TOTAL(pCounters->nChannel,pCounters->nDirection);
+
+@@ -1693,7 +1693,7 @@ DSL_Error_t DSL_DRV_PM_ChannelCountersEx
+ }
+
+ /* Fill Total Counters elapsed time*/
+- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
++ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
+
+ pChCounters = DSL_DRV_PM_PTR_CHANNEL_COUNTERS_TOTAL_EXT(pCounters->nChannel);
+
+@@ -2764,7 +2764,7 @@ DSL_Error_t DSL_DRV_PM_DataPathCountersT
+ }
+
+ /* Fill Total Counters elapsed time*/
+- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
++ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
+
+ pDpCounters = DSL_DRV_PM_PTR_DATAPATH_COUNTERS_TOTAL(pCounters->nChannel,pCounters->nDirection);
+
+@@ -3678,7 +3678,7 @@ DSL_Error_t DSL_DRV_PM_DataPathFailureCo
+ }
+
+ /* Fill Total Counters elapsed time*/
+- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
++ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
+
+ pDpCounters = DSL_DRV_PM_PTR_DATAPATH_FAILURE_COUNTERS_TOTAL(pCounters->nChannel,pCounters->nDirection);
+
+@@ -4536,7 +4536,7 @@ DSL_Error_t DSL_DRV_PM_LineSecCountersTo
+ }
+
+ /* Fill Total Counters elapsed time*/
+- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
++ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
+
+ pLineCounters = DSL_DRV_PM_PTR_LINE_SEC_COUNTERS_TOTAL(pCounters->nDirection);
+
+@@ -5273,7 +5273,7 @@ DSL_Error_t DSL_DRV_PM_LineInitCountersT
+ }
+
+ /* Fill Total Counters elapsed time*/
+- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
++ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
+
+ pLinitCounters = DSL_DRV_PM_PTR_LINE_INIT_COUNTERS_TOTAL();
+
+@@ -5774,7 +5774,7 @@ DSL_Error_t DSL_DRV_PM_LineEventShowtime
+ }
+
+ /* Fill Total Counters elapsed time*/
+- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
++ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
+
+ pLfCounters = DSL_DRV_PM_PTR_LINE_EVENT_SHOWTIME_COUNTERS_TOTAL(pCounters->nDirection);
+
+@@ -6302,7 +6302,7 @@ DSL_Error_t DSL_DRV_PM_ReTxCountersTotal
+ }
+
+ /* Fill Total Counters elapsed time*/
+- pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime/DSL_PM_MSEC;
++ pCounters->total.nElapsedTime = DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime;
+
+ pReTxCounters = DSL_DRV_PM_PTR_RETX_COUNTERS_TOTAL(pCounters->nDirection);
+
+--- a/src/pm/drv_dsl_cpe_pm_core.c
++++ b/src/pm/drv_dsl_cpe_pm_core.c
+@@ -78,6 +78,7 @@ static DSL_Error_t DSL_DRV_PM_SyncTimeUp
+ {
+ DSL_Error_t nErrCode = DSL_SUCCESS;
+ DSL_uint32_t msecTimeFrame = DSL_PM_COUNTER_POLLING_CYCLE,
++ secTimeFrame = DSL_PM_COUNTER_POLLING_CYCLE/DSL_PM_MSEC,
+ nCurrMsTime = 0;
+ #ifdef INCLUDE_DSL_CPE_PM_HISTORY
+ DSL_uint32_t nCurrSysTime = 0, nPrevElapsedTime = 0;
+@@ -117,10 +118,13 @@ static DSL_Error_t DSL_DRV_PM_SyncTimeUp
+ {
+ /* Get elapsed time [msec] since the last entry*/
+ msecTimeFrame = nCurrMsTime - DSL_DRV_PM_CONTEXT(pContext)->nLastMsTimeCheck;
++
++ /* Get elapsed time [sec] since the last entry*/
++ secTimeFrame = (nCurrMsTime/DSL_PM_MSEC) - (DSL_DRV_PM_CONTEXT(pContext)->nLastMsTimeCheck/DSL_PM_MSEC);
+ }
+
+ /* Get Total Elapsed Time Since the PM module startup*/
+- DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime += msecTimeFrame;
++ DSL_DRV_PM_CONTEXT(pContext)->nPmTotalElapsedTime += secTimeFrame;
+
+ /* Set last time check to the current time*/
+ DSL_DRV_PM_CONTEXT(pContext)->nLastMsTimeCheck = nCurrMsTime;
+@@ -158,7 +162,7 @@ static DSL_Error_t DSL_DRV_PM_SyncTimeUp
+ else
+ {
+ /* Update current showtime elapsed time*/
+- DSL_DRV_PM_CONTEXT(pContext)->nCurrShowtimeTime += (msecTimeFrame/DSL_PM_MSEC);
++ DSL_DRV_PM_CONTEXT(pContext)->nCurrShowtimeTime += secTimeFrame;
+ DSL_DRV_PM_CONTEXT(pContext)->nElapsedShowtimeTime =
+ DSL_DRV_PM_CONTEXT(pContext)->nCurrShowtimeTime;
+ }
--- /dev/null
+--- a/src/pm/drv_dsl_cpe_api_pm_vrx.c
++++ b/src/pm/drv_dsl_cpe_api_pm_vrx.c
+@@ -1482,9 +1482,16 @@ DSL_Error_t DSL_DRV_PM_DEV_ReTxCountersG
+ /* ignore zero value*/
+ if (nEftrMin)
+ {
+- /* Fw Format: kBit/s */
+- /* API format: bit/s */
+- pCounters->nEftrMin = nEftrMin*1000;
++ if (nDirection == DSL_NEAR_END)
++ {
++ /* Fw Format: kBit/s */
++ /* API format: bit/s */
++ pCounters->nEftrMin = nEftrMin*1000;
++ }
++ else
++ {
++ pCounters->nEftrMin = nEftrMin;
++ }
+ }
+ }
+ else