[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/custom/modem/common/custom_port.c b/mcu/custom/modem/common/custom_port.c
new file mode 100644
index 0000000..42587d7
--- /dev/null
+++ b/mcu/custom/modem/common/custom_port.c
@@ -0,0 +1,275 @@
+#include "custom_port.h"
+
+#include "kal_public_defs.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "fs_general_types.h"
+#include "fs_general_api.h"
+
+#if defined(__MTK_TARGET__) && defined(__HIF_PCIE_SUPPORT__)
+extern kal_uint32 pcie_get_link_state(void);
+#else
+#define pcie_get_link_state(...) (-1)
+#define index(...) (NULL)
+#endif
+
+// 76543210 76543210 76543210 76543210
+// XXX                     YY       AZ
+//
+// XXX (MODE) ==> PORT_MODE_NONE or PORT_MODE_USB or PORT_MODE_PCIE or PORT_MODE_USB_AND_PCIE or PORT_MODE_AP
+// YY (DIPC configuration) ==> PORT_DIPC_MODE_NOT_SUPPORT or PORT_DIPC_MODE_PCIE_ONLY or PORT_DIPC_MODE_PCIE_ADVANCE or PORT_DIPC_MODE_DUAL_IPC
+// A (port enable/disable on PCIE) ==> PORT_PCIE_DISABLE or PORT_PCIE_ENABLE
+// Z (pcie link status) ==> PORT_PCIE_STATUS_LINK_DOWN or PORT_PCIE_STATUS_LINK_UP
+
+#if !defined(__DHL_TRACE_ENABLED__)
+    #define kal_prompt_trace(...)
+#endif
+
+#define FILEPATH_SIZE (128)
+#define BUFFER_SIZE (1024)
+kal_uint32 custom_port(custom_port_user_enum port)
+{
+    kal_uint32 ret = 0;
+#if defined(__HIF_USB_SUPPORT__) && defined(__HIF_PCIE_SUPPORT__)
+    //DUAL IPC load
+    static kal_bool first = KAL_TRUE;
+    FS_HANDLE file_handle;
+    static kal_uint32 config_dual_ipc_mode = PORT_DIPC_MODE_NOT_SUPPORT;
+    static kal_uint32 config_md_logging_interface = PORT_MODE_NONE;
+    static kal_uint32 config_md_at_interface = PORT_MODE_PCIE;
+    static kal_uint32 config_md_pcie_port = 0xffffffff;
+    kal_uint32 pcie_link_ready = (pcie_get_link_state() == 0) ? 1 : 0;
+
+    if (first) {
+        kal_wchar *filepath = NULL;
+        kal_uint8 *buffer = NULL;
+        do {
+            filepath = (kal_wchar *)get_ctrl_buffer(FILEPATH_SIZE);
+            buffer = (kal_uint8 *)get_ctrl_buffer(BUFFER_SIZE);
+
+            if (filepath == NULL || buffer == NULL) {
+                //cannot allocate memory for operation
+                break;
+            }
+ 
+            kal_wsprintf(filepath, "%s", DIPC_CONFIG_PATH);
+            if ((file_handle = FS_Open(filepath, FS_READ_ONLY | FS_OPEN_NO_DIR)) >= FS_NO_ERROR) {
+                kal_uint32 read_size;
+                memset(buffer, 0, BUFFER_SIZE);
+                if (FS_Read(file_handle, buffer, BUFFER_SIZE - 1, &read_size) >= FS_NO_ERROR) {
+                    kal_prompt_trace(MOD_NIL, "XXXX %s:%d read_size=%d", __FILE__, __LINE__, read_size);
+                    kal_uint8 *cur_ptr = &buffer[0];
+                    kal_uint8 *tail_ptr = &buffer[read_size];
+                    while (cur_ptr < tail_ptr) {
+                        kal_uint8 key[32];
+                        kal_uint32 val;
+                        kal_uint8 *next_ptr = (kal_uint8 *)index((char *)cur_ptr, '\n');
+                        kal_uint8 *delim_ptr;
+                        if (next_ptr == NULL) {
+                            break;
+                        }
+                        *next_ptr = '\0';
+                        delim_ptr = (kal_uint8 *)index((char *)cur_ptr, ':');
+                        if (delim_ptr == NULL) {
+                            break;
+                        }
+                        *delim_ptr++ = '\0';
+
+                        sscanf((char *)cur_ptr, "%s\n", (char *)key);
+                        sscanf((char *)delim_ptr, "%u\n", &val);
+
+                        cur_ptr = next_ptr + 1;
+                        kal_prompt_trace(MOD_NIL, "[%s][%x]", key, val);
+                        if (strcmp(KEY_DUAL_IPC_MODE, (char *)key) == 0) {
+                            switch(val) {
+                                case DIPC_MODE_NOT_CONFIG:
+                                    config_dual_ipc_mode = PORT_DIPC_MODE_NOT_SUPPORT;
+                                    break;
+                                case DIPC_MODE_PCIE_ADV:
+                                    config_dual_ipc_mode = PORT_DIPC_MODE_PCIE_ADVANCE;
+                                    break;
+                                case DIPC_MODE_PCIE_ONLY:
+                                    config_dual_ipc_mode = PORT_DIPC_MODE_PCIE_ONLY;
+                                    break;
+                                case DIPC_MODE_DUAL_IPC:
+                                    config_dual_ipc_mode = PORT_DIPC_MODE_DUAL_IPC;
+                                    break;
+                                case DIPC_MODE_USB_ONLY:
+                                    config_dual_ipc_mode = PORT_DIPC_MODE_USB_ONLY;
+                                    break;
+                            }
+                        } else if (strcmp(KEY_MD_LOGGING_INTERFACE, (char *)key) == 0) {
+                            switch(val) {
+                                case DIPC_INTF_USB:
+                                    config_md_logging_interface = PORT_MODE_USB;
+                                    break;
+                                case DIPC_INTF_PCIE:
+                                    config_md_logging_interface = PORT_MODE_PCIE;
+                                    break;
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+                                default:
+                                    config_md_logging_interface = PORT_MODE_NONE;
+                                    break;
+                            }
+                        } else if (strcmp(KEY_MD_AT_INTERFACE, (char *)key) == 0) {
+                            switch(val) {
+                                case DIPC_INTF_USB:
+                                    config_md_at_interface = PORT_MODE_USB;
+                                    break;
+                                case DIPC_INTF_PCIE:
+                                    config_md_at_interface = PORT_MODE_PCIE;
+                                    break;
+                                default:
+                                    config_md_at_interface = PORT_MODE_PCIE;
+                                    break;
+                            }
+                        } else if (strcmp(KEY_MD_PCIE_PORT_CONFIG, (char *)key) == 0) {
+                            if ((val & DIPC_CONFIG_MD_PORT_LOGGING) == 0) {
+                                config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_LOG);
+                            }
+                            if ((val & DIPC_CONFIG_MD_PORT_META) == 0) {
+                                config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_META);
+                            }
+                            if ((val & DIPC_CONFIG_MD_PORT_BINARY_TOOL) == 0) {
+                                config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_BINARY_TOOL);
+                                config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_MIPC);
+                            }
+                            if ((val & DIPC_CONFIG_MD_PORT_AT) == 0) {
+                                config_md_pcie_port &= ~(1 << CUSTOM_PORT_USER_AT);
+                            }
+                        }
+                    }
+                }
+                FS_Close(file_handle);
+            }
+            first = KAL_FALSE;
+        } while(0);
+
+        if (filepath) {
+            free_ctrl_buffer(filepath);
+            filepath = NULL;
+        }
+        if (buffer) {
+            free_ctrl_buffer(buffer);
+            buffer = NULL;
+        }
+    }
+
+    if (config_md_pcie_port & (1 << port)) {
+        ret |= (1 << PORT_PCIE_ENABLE_SHIFT);
+    }
+
+    switch (config_dual_ipc_mode) {
+        case PORT_DIPC_MODE_PCIE_ADVANCE:
+            if (pcie_link_ready) {
+                if (config_md_pcie_port & (1 << port)) {
+                    ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
+                } else {
+                    ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+                }
+            } else {
+                ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
+            }
+            ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
+            ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
+            return ret;
+        case PORT_DIPC_MODE_PCIE_ONLY:
+            if (config_md_pcie_port & (1 << port)) {
+                ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
+            } else {
+                ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+            }
+            ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
+            ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
+            return ret;
+        case PORT_DIPC_MODE_DUAL_IPC:
+            if (pcie_link_ready) {
+                switch (port) {
+                    case CUSTOM_PORT_USER_AT:
+                    	ret |= (config_md_at_interface << PORT_MODE_SHIFT);
+                    	break;
+                    case CUSTOM_PORT_USER_LOG:
+                        if (config_md_logging_interface == PORT_MODE_USB) {
+                            ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
+                        } else if ((config_md_logging_interface == PORT_MODE_PCIE) && (config_md_pcie_port & (1 << port))) {
+                            ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
+                        } else {
+                            ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+                        }
+                        break;
+                    case CUSTOM_PORT_USER_META:
+                    	ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
+                    	break;                    	
+                    default:
+                      ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
+                      break;
+                }
+            } else {
+                ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
+            }            
+            ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
+            ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
+            return ret;
+        case PORT_DIPC_MODE_USB_ONLY:
+            ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
+            ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
+            ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
+            return ret;
+        case PORT_DIPC_MODE_NOT_SUPPORT:
+            if (port == CUSTOM_PORT_USER_LOG) {
+#if   defined(__ELT_SET_PORT_TO_USB__)
+                ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
+#elif defined(__ELT_SET_PORT_TO_PCIE__)
+                ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
+#elif defined(__ELT_SET_PORT_TO_DUAL_IPC__)
+                ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+#else
+                ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+#endif
+            } else if (port == CUSTOM_PORT_USER_META) {
+#if   defined(__META_SET_PORT_TO_USB__)
+                ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
+#elif defined(__META_SET_PORT_TO_PCIE__)
+                ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
+#elif defined(__META_SET_PORT_TO_DUAL_IPC__)
+                ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+#else
+                ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+#endif
+            } else {
+                ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+            }
+            ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
+            ret |= (1 << PORT_PCIE_ENABLE_SHIFT);
+            ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
+            return ret;
+        default:
+            ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
+            ret |= (config_dual_ipc_mode << PORT_DIPC_MODE_SHIFT);
+            ret |= (1 << PORT_PCIE_ENABLE_SHIFT);
+            ret |= (pcie_link_ready << PORT_PCIE_STATUS_SHIFT);
+            return ret;
+    }
+#elif defined(__HIF_USB_SUPPORT__)
+    //support USB only
+    ret |= (PORT_MODE_USB << PORT_MODE_SHIFT);
+    return ret;
+#elif defined(__HIF_PCIE_SUPPORT__)
+    //support PCIE only
+    ret |= (PORT_MODE_PCIE << PORT_MODE_SHIFT);
+    return ret;
+#else
+#if defined(__ANDROID_MODEM__)
+    //SP
+    ret |= (PORT_MODE_AP << PORT_MODE_SHIFT);
+    return ret;
+#else
+    ret |= (PORT_MODE_NONE << PORT_MODE_SHIFT);
+    return ret;
+#endif
+#endif
+}