From dde1a3f205f84160109e99a6eeed957da5bc6e55 Mon Sep 17 00:00:00 2001
From: Yalu Zhang <yalu.zhang@iopsys.eu>
Date: Tue, 4 Jun 2019 17:27:36 +0200
Subject: [PATCH] Update from UGW-8.1.1.20

From 1.8.1.1 to 1.8.1.1.0
---
 ChangeLog                                     |  12 ++
 configure                                     |  20 +--
 configure.in                                  |   2 +-
 doc/doxyconfig                                |   2 +-
 .../mei_cpe_drv_dbg_strm_dmp.c                | 119 ++++++++++--------
 src/drv_mei_cpe_api_atm_ptm_intern.c          |  17 ++-
 src/drv_mei_cpe_api_atm_ptm_intern.h          |   8 +-
 src/drv_mei_cpe_api_intern.c                  |  36 ++++--
 src/drv_mei_cpe_interface.h                   |  18 ++-
 src/drv_mei_cpe_linux.c                       |  23 +++-
 10 files changed, 162 insertions(+), 95 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6ddc83d..ff68bde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 NEXT VERSION
 
+V1.8.1.1.0 - 2019-01-15
+- VRX (DSLCPE_SW-1163) IRQ mode is possible to used within UGW-8.x again
+- VRX (DSLCPE_SW-1097) Message dump printout within MEI Driver is not as expected
+- (DSLCPE_SW-1139) Generation of UMPR for API 4.19.x / R5 release
+   Make sure that IOCtl's which shall be part of the API UMPR are classified
+   accordingly
+- VRX (DSLCPE_SW-1149) Debug stream segmentation fault fix
+- VRX (DSLCPE_SW-1173) [VRX518][Power Saving] Switching BND->Single
+
 V1.8.1.1 - 2018-08-02
 common:
 - VRX (DSLCPE_SW-1150) Shutdown sequence does not work correctly for UGW-8.x
@@ -19,6 +28,9 @@ common:
 
 V1.8.0 - 2018-05-30
 common:
+- VRX518 (DSLCPE_SW-1131) Power Saving for Disabled DSL Lines in VRX518
+  + Entities disabling implementation
+  + Separate function for sending TC Request / setting callback
 - VRX518 (DSLCPE_SW-1122) Power Saving Support by the MEI-Driver (fallback)
   + Support GRX350 platform (DSL clock gating flag: 0x20ec0305)
 - VRX (DSLCPE_SW-1119) Update MCAT header files to latest revision (Rev.3.1)
diff --git a/configure b/configure
index 5da4ec6..c0ea165 100755
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.in Revision: 1.21 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for IFX MEI CPE Driver 1.8.1.1.
+# Generated by GNU Autoconf 2.69 for IFX MEI CPE Driver 1.8.1.1.0.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='IFX MEI CPE Driver'
 PACKAGE_TARNAME='drv_mei_cpe'
-PACKAGE_VERSION='1.8.1.1'
-PACKAGE_STRING='IFX MEI CPE Driver 1.8.1.1'
+PACKAGE_VERSION='1.8.1.1.0'
+PACKAGE_STRING='IFX MEI CPE Driver 1.8.1.1.0'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1312,7 +1312,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures IFX MEI CPE Driver 1.8.1.1 to adapt to many kinds of systems.
+\`configure' configures IFX MEI CPE Driver 1.8.1.1.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1378,7 +1378,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of IFX MEI CPE Driver 1.8.1.1:";;
+     short | recursive ) echo "Configuration of IFX MEI CPE Driver 1.8.1.1.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1525,7 +1525,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-IFX MEI CPE Driver configure 1.8.1.1
+IFX MEI CPE Driver configure 1.8.1.1.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1580,7 +1580,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by IFX MEI CPE Driver $as_me 1.8.1.1, which was
+It was created by IFX MEI CPE Driver $as_me 1.8.1.1.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2445,7 +2445,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='drv_mei_cpe'
- VERSION='1.8.1.1'
+ VERSION='1.8.1.1.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5576,7 +5576,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by IFX MEI CPE Driver $as_me 1.8.1.1, which was
+This file was extended by IFX MEI CPE Driver $as_me 1.8.1.1.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -5642,7 +5642,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-IFX MEI CPE Driver config.status 1.8.1.1
+IFX MEI CPE Driver config.status 1.8.1.1.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.in b/configure.in
index 69d5898..5f02645 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
 
 AC_REVISION($Revision: 1.21 $)
 
-AC_INIT(IFX MEI CPE Driver, 1.8.1.1, , drv_mei_cpe)
+AC_INIT(IFX MEI CPE Driver, 1.8.1.1.0, , drv_mei_cpe)
 AC_CONFIG_SRCDIR(src/Makefile.am)
 AM_INIT_AUTOMAKE([tar-pax])
 
diff --git a/doc/doxyconfig b/doc/doxyconfig
index e9c8f86..2ffd1e5 100644
--- a/doc/doxyconfig
+++ b/doc/doxyconfig
@@ -22,7 +22,7 @@ PROJECT_NAME           = "MEI CPE Driver"
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 1.8.1.1
+PROJECT_NUMBER         = 1.8.1.1.0
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
 # base path where the generated documentation will be put.
diff --git a/src/debug_stream_dump/mei_cpe_drv_dbg_strm_dmp.c b/src/debug_stream_dump/mei_cpe_drv_dbg_strm_dmp.c
index e210c28..5636b7e 100644
--- a/src/debug_stream_dump/mei_cpe_drv_dbg_strm_dmp.c
+++ b/src/debug_stream_dump/mei_cpe_drv_dbg_strm_dmp.c
@@ -772,10 +772,9 @@ static MEIOS_File_t* MEI_debug_stream_dump_new_file(MEIOS_File_t *dumpFd)
    return dumpFd;
 }
 
-static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   *dumpFd,
+static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   **pDumpFd,
                                               unsigned short *pBuffer,
-                                              unsigned long  *pCurLength,
-                                              MEIOS_File_t   **pDumpFd)
+                                              unsigned long  *pCurLength)
 {
    unsigned short i = 0;
    static unsigned long nWrittenBytesToFlush = 0;
@@ -787,6 +786,14 @@ static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   *dumpFd,
    data.maxStreamEntries = 20;
    data.pData = (unsigned char*)pBuffer;
    data.timeout_ms = 0;
+   
+   if (pDumpFd == NULL)
+   {
+      MEIOS_FPrintf(stdout, DBG_STRM_DMP_MEI_DBG_PREFIX
+         "ERROR - pDumpFd is NULL" MEIOS_CRLF);
+      return -1;
+   }
+
    if ((MEIOS_DeviceControl(fd,
                             FIO_MEI_DEBUG_STREAM_DATA_GET,
                             (MEI_IOCTL_ARG)&data)) < 0 )
@@ -799,52 +806,61 @@ static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   *dumpFd,
 
    if ((bText != 1) && (bFile == 1))
    {
-      if (data.dataBufferSize_byte >= g_nFileLength)
+      if(*pDumpFd != NULL)
       {
-         for (; data.dataBufferSize_byte >= g_nFileLength;
-                data.dataBufferSize_byte -= g_nFileLength)
+         if (data.dataBufferSize_byte >= g_nFileLength)
          {
-            *pCurLength = (data.dataBufferSize_byte < g_nFileLength)?
+            for (; data.dataBufferSize_byte >= g_nFileLength;
+               data.dataBufferSize_byte -= g_nFileLength)
+            {
+               *pCurLength = (data.dataBufferSize_byte < g_nFileLength)?
                data.dataBufferSize_byte :
                g_nFileLength;
-            fwrite(data.pData, sizeof(char), *pCurLength, dumpFd);
-            data.pData += *pCurLength;
-            dumpFd = MEI_debug_stream_dump_new_file(dumpFd);
-            if (dumpFd == NULL)
-            {
-               MEIOS_FPrintf(stdout, DBG_STRM_DMP_MEI_DBG_PREFIX
-                  "ERROR - could not open new dump file" MEIOS_CRLF);
-               return -1;
+               fwrite(data.pData, sizeof(char), *pCurLength, *pDumpFd);
+               data.pData += *pCurLength;
+               *pDumpFd = MEI_debug_stream_dump_new_file(*pDumpFd);
+               if (*pDumpFd == NULL)
+               {
+                  MEIOS_FPrintf(stdout, DBG_STRM_DMP_MEI_DBG_PREFIX
+                     "ERROR - could not open new dump file" MEIOS_CRLF);
+                  return -1;
+               }
             }
+            *pCurLength = 0;
          }
-         *pCurLength = 0;
-      }
-      else
-      {
-         *pCurLength += data.dataBufferSize_byte;
-         if (*pCurLength >= g_nFileLength)
+         else
          {
-            dumpFd = MEI_debug_stream_dump_new_file(dumpFd);
-            if (dumpFd == NULL)
+            *pCurLength += data.dataBufferSize_byte;
+            if (*pCurLength >= g_nFileLength)
             {
-               MEIOS_FPrintf(stdout, DBG_STRM_DMP_MEI_DBG_PREFIX
-                  "ERROR - could not open new dump file" MEIOS_CRLF);
-               return -1;
+               *pDumpFd = MEI_debug_stream_dump_new_file(*pDumpFd);
+               if (*pDumpFd == NULL)
+               {
+                  MEIOS_FPrintf(stdout, DBG_STRM_DMP_MEI_DBG_PREFIX
+                     "ERROR - could not open new dump file" MEIOS_CRLF);
+                  return -1;
+               }
+               *pCurLength = data.dataBufferSize_byte;
             }
-            *pCurLength = data.dataBufferSize_byte;
-         }
 
-         if (dumpFd != NULL)
-         {
-            fwrite(data.pData, sizeof(char), data.dataBufferSize_byte, dumpFd);
-            nWrittenBytesToFlush += data.dataBufferSize_byte;
-            if (nWrittenBytesToFlush >= DBG_STRM_DMP_MEI_BYTES_TO_FLUSH)
+            if (*pDumpFd != NULL)
             {
-                fflush(dumpFd);
-                nWrittenBytesToFlush = 0;
+               fwrite(data.pData, sizeof(char), data.dataBufferSize_byte, *pDumpFd);
+               nWrittenBytesToFlush += data.dataBufferSize_byte;
+               if (nWrittenBytesToFlush >= DBG_STRM_DMP_MEI_BYTES_TO_FLUSH)
+               {
+                  fflush(*pDumpFd);
+                  nWrittenBytesToFlush = 0;
+               }
             }
          }
       }
+      else
+      {
+         MEIOS_FPrintf(stdout, DBG_STRM_DMP_MEI_DBG_PREFIX
+            "ERROR - *pDumpFd is empty" MEIOS_CRLF);
+         return -1;
+      }
    }
    else
    {
@@ -855,16 +871,16 @@ static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   *dumpFd,
          /* Reset cycle byte counter */
          nWrittenBytes = 0;
 
-         if((dumpFd == stdout) && (dumpFd != NULL) &&
+         if((*pDumpFd == stdout) && (*pDumpFd != NULL) &&
            ((((unsigned short*)data.pData)[i]) == DBG_STRM_DMP_MEI_EVENT_NUM))
          {
-            nWrittenBytes += MEIOS_FPrintf(dumpFd, "\n");
+            nWrittenBytes += MEIOS_FPrintf(*pDumpFd, "\n");
          }
          if((((unsigned short*)data.pData)[i]) != DBG_STRM_DMP_MEI_EVENT_NUM)
          {
-            if (dumpFd != NULL)
+            if (*pDumpFd != NULL)
             {
-               nWrittenBytes += MEIOS_FPrintf(dumpFd, "%04X ",
+               nWrittenBytes += MEIOS_FPrintf(*pDumpFd, "%04X ",
                   ((unsigned short*)data.pData)[i]);
             }
          }
@@ -876,10 +892,10 @@ static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   *dumpFd,
          *pCurLength += nWrittenBytes;
          nWrittenBytesToFlush += nWrittenBytes;
 
-         if ((dumpFd != NULL) &&
+         if ((*pDumpFd != NULL) &&
              (nWrittenBytesToFlush >= DBG_STRM_DMP_MEI_BYTES_TO_FLUSH))
          {
-            fflush(dumpFd);
+            fflush(*pDumpFd);
             nWrittenBytesToFlush = 0;
          }
 
@@ -887,8 +903,8 @@ static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   *dumpFd,
          {
             if(*pCurLength >= g_nFileLength)
             {
-               dumpFd = MEI_debug_stream_dump_new_file(dumpFd);
-               if (dumpFd == NULL)
+               *pDumpFd = MEI_debug_stream_dump_new_file(*pDumpFd);
+               if (*pDumpFd == NULL)
                {
                   MEIOS_FPrintf(stdout, DBG_STRM_DMP_MEI_DBG_PREFIX
                      "ERROR - could not open new dump file" MEIOS_CRLF);
@@ -898,9 +914,9 @@ static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   *dumpFd,
                nWrittenBytes = 0;
                nWrittenBytesToFlush = 0;
             }
-            if (dumpFd != NULL)
+            if (*pDumpFd != NULL)
             {
-               MEIOS_FPrintf(dumpFd, "%04X ", DBG_STRM_DMP_MEI_EVENT_NUM);
+               MEIOS_FPrintf(*pDumpFd, "%04X ", DBG_STRM_DMP_MEI_EVENT_NUM);
             }
          }
       }
@@ -909,13 +925,9 @@ static int MEI_debug_stream_dump_save_to_file(MEIOS_File_t   *dumpFd,
    if (data.dataBufferSize_byte == 0)
    {
       /* The data from the buffer was written fully */
-      if (dumpFd != NULL)
+      if (*pDumpFd != NULL)
       {
-         if (pDumpFd != NULL)
-         {
-            *pDumpFd = dumpFd;
-         }
-         fflush(dumpFd);
+         fflush(*pDumpFd);
          nWrittenBytesToFlush = 0;
       }
 
@@ -1173,10 +1185,9 @@ int MEI_debug_stream_dump_daemon(void)
 
       do
       {
-         ret = MEI_debug_stream_dump_save_to_file(dumpFd,
+         ret = MEI_debug_stream_dump_save_to_file(&dumpFd,
                                                   pBuffer,
-                                                  &nCurrentLength,
-                                                  &dumpFd);
+                                                  &nCurrentLength);
       } while (ret == 0);
 
       if (ret == -1)
diff --git a/src/drv_mei_cpe_api_atm_ptm_intern.c b/src/drv_mei_cpe_api_atm_ptm_intern.c
index 27eea02..ac86c0e 100644
--- a/src/drv_mei_cpe_api_atm_ptm_intern.c
+++ b/src/drv_mei_cpe_api_atm_ptm_intern.c
@@ -265,7 +265,7 @@ IFX_int32_t MEI_TcRequest(void *data)
       MEI_DynCntrlStructFree(&pMeiDynCntrl);
    }
 
-#ifdef IRQ_POLLING_FORCE 
+#ifdef IRQ_POLLING_FORCE
    do_exit(retVal);
 #endif /* IRQ_POLLING_FORCE */
 
@@ -339,7 +339,12 @@ IFX_int32_t MEI_InternalTcRequest(
    return retVal;
 }
 
-IFX_int32_t MEI_InternalLineTCModeSwitch(IFX_int8_t nEntity, IFX_int8_t nInstance, IFX_boolean_t bPowerUp) {
+IFX_int32_t MEI_InternalLineTCModeSwitch(
+                              IFX_int8_t nEntity,
+                              IFX_int8_t nInstance,
+                              IFX_boolean_t bPowerUp,
+                              IFX_boolean_t bKillMEIControlThread)
+{
    IFX_int32_t retVal = IFX_SUCCESS;
 
 #if defined(PPA_SUPPORTS_CALLBACKS) && defined(PPA_SUPPORTS_TC_CALLBACKS)
@@ -349,7 +354,7 @@ IFX_int32_t MEI_InternalLineTCModeSwitch(IFX_int8_t nEntity, IFX_int8_t nInstanc
 #endif /* defined(PPA_SUPPORTS_CALLBACKS) && defined(PPA_SUPPORTS_TC_CALLBACKS) */
 
 #if (MEI_SUPPORT_PERIODIC_TASK == 1)
-   if (bPowerUp == IFX_FALSE)
+   if (bKillMEIControlThread == IFX_TRUE)
    {
       if ( MEI_DrvCntrlThreadParams.bValid == IFX_TRUE)
       {
@@ -365,7 +370,7 @@ IFX_int32_t MEI_InternalLineTCModeSwitch(IFX_int8_t nEntity, IFX_int8_t nInstanc
    pMeiDynCntrl = NULL;
    nLineNum = MEIX_Cntrl[nEntity]->MeiDevice[nInstance]->meiDrvCntrl.dslLineNum;
    MEI_DynCntrlStructAlloc(nLineNum, &pMeiDynCntrl);
- 
+
    if (pMeiDynCntrl != NULL)
    {
       pMeiDynCntrl->openInstance = 0xFF;
@@ -377,7 +382,7 @@ IFX_int32_t MEI_InternalLineTCModeSwitch(IFX_int8_t nEntity, IFX_int8_t nInstanc
 
       retVal = MEI_InternalTcRequest(pMeiDynCntrl, &argsTcRequest);
 
-      MEI_DRVOS_Wait_ms(200); 
+      MEI_DRVOS_Wait_ms(200);
 
       MEI_DynCntrlStructFree(&pMeiDynCntrl);
 
@@ -407,7 +412,7 @@ IFX_int32_t MEI_InternalLineTCModeSwitch(IFX_int8_t nEntity, IFX_int8_t nInstanc
       ("MEI_DRV[%02d]: PPA Callbacks disabled by compile option, "
        "to use this functionality you will need to enable them"
       MEI_DRV_CRLF, nEntity));
-      
+
 #endif /* defined(PPA_SUPPORTS_CALLBACKS) && defined(PPA_SUPPORTS_TC_CALLBACKS) */
 
    return retVal;
diff --git a/src/drv_mei_cpe_api_atm_ptm_intern.h b/src/drv_mei_cpe_api_atm_ptm_intern.h
index 4aa1478..36f6063 100644
--- a/src/drv_mei_cpe_api_atm_ptm_intern.h
+++ b/src/drv_mei_cpe_api_atm_ptm_intern.h
@@ -75,10 +75,10 @@ extern IFX_int32_t MEI_InternalErbAddrUpdate(
                               MEI_DYN_CNTRL_T        *pMeiDynCntrl);
 
 extern IFX_int32_t MEI_InternalLineTCModeSwitch(
-                              IFX_int8_t nEntity, 
-                              IFX_int8_t nInstance, 
-                              IFX_boolean_t bPowerUp);
-
+                              IFX_int8_t nEntity,
+                              IFX_int8_t nInstance,
+                              IFX_boolean_t bPowerUp,
+                              IFX_boolean_t bKillMEIControlThread);
 
 #ifdef PPA_SUPPORTS_CALLBACKS
 extern int ppa_callback_set(e_ltq_mei_cb_type type, void *func);
diff --git a/src/drv_mei_cpe_api_intern.c b/src/drv_mei_cpe_api_intern.c
index 7ed5a3c..909d9de 100644
--- a/src/drv_mei_cpe_api_intern.c
+++ b/src/drv_mei_cpe_api_intern.c
@@ -1,7 +1,6 @@
 /******************************************************************************
-
-                          Copyright (c) 2007-2015
-                     Lantiq Beteiligungs-GmbH & Co. KG
+          Copyright 2018 Intel Corporation
+          Copyright 2007 - 2015 Lantiq Beteiligungs-GmbH & Co. KG
 
   For licensing information, see the file 'LICENSE' in the root folder of
   this software module.
@@ -434,6 +433,13 @@ static IFX_void_t MEI_Internal_DumpMessage(
    static const IFX_uint32_t *pMsg32;
    IFX_boolean_t bDirSet = IFX_FALSE;
    IFX_uint8_t i;
+   const IFX_uint32_t nCommonPayloadSize = 5*nSize/2;
+   const IFX_uint8_t nInfoSize = 35;
+   const IFX_uint8_t nBufSize = 10;
+   IFX_uint32_t nMsgSize = nCommonPayloadSize + nInfoSize;
+   IFX_uint32_t nCharsWrittenToBuf = 0;
+   char msg[nMsgSize];
+   char buf[nBufSize];
 
    if((pData == IFX_NULL) || (nSize < 4))
    {
@@ -445,11 +451,12 @@ static IFX_void_t MEI_Internal_DumpMessage(
 
    bDirSet = (nMsgId & 0x40) ? IFX_TRUE : IFX_FALSE;
 
-   PRN_DBG_USR_RAW(MEI_MSG_DUMP_API, dbg_level,
-                  ("MEI[%02d/%s]: 0x%04x 0x%04x 0x%04x",
-                  MEI_DRV_DYN_LINENUM_GET(pMeiDynCntrl),
-                  (bReceive == IFX_TRUE ? "rx" : "tx"), nMsgId,
-                  pData[0], pData[1]));
+   snprintf(msg, nInfoSize,
+              "MEI[%02d/%s]: 0x%04x 0x%04x 0x%04x",
+              MEI_DRV_DYN_LINENUM_GET(pMeiDynCntrl),
+              (bReceive == IFX_TRUE ? "rx" : "tx"), nMsgId,
+              pData[0], pData[1]);
+   nMsgSize -= nInfoSize;
 
    /* decide wether to interpret the rest as 16 or 32 bit */
    if (nMsgId & 0x0010)
@@ -457,7 +464,9 @@ static IFX_void_t MEI_Internal_DumpMessage(
       /* 32-bit payload elements */
       for (i=0; i<((nSize-4)/4); i++)
       {
-         PRN_DBG_USR_RAW(MEI_MSG_DUMP_API, dbg_level, (" %08X", pMsg32[i]));
+         nCharsWrittenToBuf = snprintf(buf, nBufSize, " %08X", pMsg32[i]);
+         strncat(msg, buf, nMsgSize);
+         nMsgSize -= nCharsWrittenToBuf;
       }
    }
    else
@@ -465,11 +474,14 @@ static IFX_void_t MEI_Internal_DumpMessage(
       /* 16-bit payload elements */
       for (i=0; i<((nSize-4)/2); i++)
       {
-         PRN_DBG_USR_RAW(MEI_MSG_DUMP_API, dbg_level, (" %04X", pMsg16[i]));
+         nCharsWrittenToBuf = snprintf(buf, nBufSize, " %04X", pMsg16[i]);
+         strncat(msg, buf, nMsgSize);
+         nMsgSize -= nCharsWrittenToBuf;
       }
    }
+   strncat(msg, MEI_DRV_CRLF, nMsgSize);
 
-   PRN_DBG_USR_RAW(MEI_MSG_DUMP_API, dbg_level, (MEI_DRV_CRLF));
+   PRN_DBG_USR_RAW(MEI_MSG_DUMP_API, dbg_level, (msg));
 }
 
 IFX_int32_t MEI_InternalSendMessage(
@@ -501,7 +513,7 @@ IFX_int32_t MEI_InternalSendMessage(
    {
       MEI_Internal_DumpMessage(pMeiDynCntrl, msg.ack_msg.msgId,
          (IFX_uint16_t *)msg.ack_msg.pPayload, msg.ack_msg.paylSize_byte,
-         IFX_TRUE, MEI_DRV_PRN_LEVEL_LOW);
+         IFX_TRUE, MEI_DRV_PRN_LEVEL_NORMAL);
    }
 
    return ret;
diff --git a/src/drv_mei_cpe_interface.h b/src/drv_mei_cpe_interface.h
index cb0dac0..354a544 100644
--- a/src/drv_mei_cpe_interface.h
+++ b/src/drv_mei_cpe_interface.h
@@ -73,6 +73,18 @@
    \ingroup MEI_CEOC
 */
 
+/** \defgroup MEI_API Functions for common usage within Linux user space
+    This Group contains all the common functions for general purpose that might
+    be used from within Linux user space, independent from DSL CPE API Driver
+    usage.
+    \ingroup MEI_INTERFACE
+*/
+
+/**
+   \defgroup MEI_API_IOCTL IOCtl's
+   \ingroup MEI_API
+*/
+
 /** \defgroup MEI_DSM Functions for Digital Spectrum Management (DSM/vectoring)
     This Group contains all the commonly used functions for configuration,
     control and status request of the [D]igital [S]pectrum [M]anagement related
@@ -248,6 +260,7 @@
    \ingroup MEI_COMMON_IOCTL              */
 #define FIO_MEI_DRV_INIT               _IO(MEI_IOC_MAGIC, 4)
 
+#endif /* #ifndef DSL_DOC_GENERATION_EXCLUDE_UNWANTED */
 
 /** This returns information about the successfully detected respective
     available devices/lines.
@@ -269,9 +282,10 @@
      memset(&devInfo, 0x00, sizeof(IOCTL_MEI_drvDevinfoGet_t));
      ret = ioctl(fd, FIO_MEI_DRV_DEVINFO_GET, &devInfo)
    \endcode
-   \ingroup MEI_COMMON_IOCTL              */
+   \ingroup MEI_API_IOCTL              */
 #define FIO_MEI_DRV_DEVINFO_GET            _IO(MEI_IOC_MAGIC, 5)
 
+#ifndef DSL_DOC_GENERATION_EXCLUDE_UNWANTED
 
 /** This service resets the MEI CPE Device Driver and optional the
     device blocks via MEI register.
@@ -2133,6 +2147,7 @@ typedef struct
    unsigned int bmWaitStates;
 } IOCTL_MEI_drvInit_t;
 
+#endif /* #ifndef DSL_DOC_GENERATION_EXCLUDE_UNWANTED */
 
 /** ioctl structure to get the device/line availibility. */
 typedef struct
@@ -2150,6 +2165,7 @@ typedef struct
    unsigned int entitiesEnabled;
 } IOCTL_MEI_devinfo_t ;
 
+#ifndef DSL_DOC_GENERATION_EXCLUDE_UNWANTED
 
 /** modem Driver Reset Modes */
 typedef enum
diff --git a/src/drv_mei_cpe_linux.c b/src/drv_mei_cpe_linux.c
index 928e174..3b965d2 100644
--- a/src/drv_mei_cpe_linux.c
+++ b/src/drv_mei_cpe_linux.c
@@ -1937,6 +1937,8 @@ static int MEI_EntitiesEnableCtrl(struct file *file,
    char proc_str[16] = { '\0' };
    int nEntity = 0, nInstance = 0, ret = 0;
    int nEntitiesEnableCtrl = 0, nEntitiesEnabled = MEI_DEVICE_CFG_VALUE_GET(EntitiesEnabled);
+   IFX_uint8_t nDisabledLinesCounter = 0;
+   IFX_boolean_t bKillMEIControlThread = IFX_FALSE;
    MEIX_CNTRL_T *pXCntrl;
 
    if (count > sizeof(proc_str) - 1)
@@ -1952,7 +1954,7 @@ static int MEI_EntitiesEnableCtrl(struct file *file,
    proc_str[count] = 0;
    sscanf(proc_str, "%d", &nEntitiesEnableCtrl);
 
-   if(nEntitiesEnableCtrl > MEI_DFEX_ENTITIES || nEntitiesEnableCtrl < 0) 
+   if(nEntitiesEnableCtrl > MEI_DFEX_ENTITIES || nEntitiesEnableCtrl < 0)
    {
       PRN_DBG_USR_NL( MEI_DRV,MEI_DRV_PRN_LEVEL_HIGH,
          ("MEI_DRV: Incorrect parameter" MEI_DRV_CRLF));
@@ -1960,15 +1962,23 @@ static int MEI_EntitiesEnableCtrl(struct file *file,
       return e_MEI_ERR_INVAL_ARG;
    }
 
-   if(nEntitiesEnableCtrl < nEntitiesEnabled) 
+   if(nEntitiesEnableCtrl < nEntitiesEnabled)
    {
-      for(nEntity = nEntitiesEnabled - 1; nEntity >= nEntitiesEnableCtrl; --nEntity) 
+      nDisabledLinesCounter = 0;
+      for(nEntity = nEntitiesEnabled - 1; nEntity >= nEntitiesEnableCtrl; --nEntity)
       {
+         ++nDisabledLinesCounter;
+
+         if (nEntitiesEnabled == nDisabledLinesCounter)
+         {
+            bKillMEIControlThread = IFX_TRUE;
+         }
+
          if ((pXCntrl = MEIX_Cntrl[nEntity]) != NULL)
          {
             for (nInstance = 0; nInstance < MEI_DFE_INSTANCE_PER_ENTITY; ++nInstance)
             {
-               ret = MEI_InternalLineTCModeSwitch(nEntity, nInstance, IFX_FALSE);
+               ret = MEI_InternalLineTCModeSwitch(nEntity, nInstance, IFX_FALSE, bKillMEIControlThread);
             }
          }
       }
@@ -1981,7 +1991,7 @@ static int MEI_EntitiesEnableCtrl(struct file *file,
          {
             for (nInstance = 0; nInstance < MEI_DFE_INSTANCE_PER_ENTITY; ++nInstance)
             {
-               ret = MEI_InternalLineTCModeSwitch(nEntity, nInstance, IFX_TRUE);
+               ret = MEI_InternalLineTCModeSwitch(nEntity, nInstance, IFX_TRUE, bKillMEIControlThread);
             }
          }
       }
@@ -1991,7 +2001,7 @@ static int MEI_EntitiesEnableCtrl(struct file *file,
    {
       MEI_DEVICE_CFG_VALUE_SET(EntitiesEnabled, nEntitiesEnableCtrl);
    }
-   
+
    return count;
 }
 
@@ -3088,6 +3098,7 @@ IFX_int32_t MEI_IoctlInitDevice(
             pMeiDev->intMask   = ME_ARC2ME_INTERRUPT_UNMASK_ALL;
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) \
+      || (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) \
       || (MEI_SUPPORT_DEVICE_VR10_320 == 1) \
       || (MEI_TARGET_x86 == 1)
             virq = (IFX_uint32_t)pInitDev->usedIRQ;
-- 
GitLab