[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/middleware/hif/interface/cdcecm_data_path_trace_utmd.json b/mcu/middleware/hif/interface/cdcecm_data_path_trace_utmd.json
new file mode 100644
index 0000000..2348404
--- /dev/null
+++ b/mcu/middleware/hif/interface/cdcecm_data_path_trace_utmd.json
@@ -0,0 +1,106 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "CDCECM_L2",
+ "stringTranslationDefs": [],
+ "startGen": "Legacy",
+ "endGen": "Legacy",
+ "traceClassDefs": [
+ {
+ "ECM_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "ECM_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "ECM_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "ECM_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "CDCECM_BUF_DOWNLINK": {
+ "format": "[ECM] cdcecm_buf_downlink(): queue_no(%d), payload(%xl), payload_len(%d)",
+ "traceClass": "ECM_M"
+ }
+ },
+ {
+ "CDCECM_BUF_DL_MSG_INFO": {
+ "format": "[ECM] cdcecm_buf_downlink(): td_drb_idx(%d), payload_drb_idx(%d), payload_prb(%xl), payload_len(%d)",
+ "traceClass": "ECM_M"
+ }
+ },
+ {
+ "CDCECM_RB_DOWNLINK": {
+ "format": "[ECM] cdcecm_rb_downlink(): queue_no(%d), did(%xl), pkt_num(%d), seg_num(%d), state(%d), is_usb_suspend(%d)",
+ "traceClass": "ECM_M"
+ }
+ },
+ {
+ "CDCECM_RB_DL_ENUMERATION": {
+ "format": "[ECM] cdcecm_rb_downlink(): dl enumeration: i(%d), did(%xl), curr_sit(%xl), hif_type(%d), handled_seg_cnt(%d), seg_num(%d), total_len(%d)",
+ "traceClass": "ECM_M"
+ }
+ },
+ {
+ "CDCECM_RB_DL_PACKET": {
+ "format": "[ECM] cdcecm_rb_downlink(): dl packet: i(%d), data_addr(%xl), data_len(%ul)",
+ "traceClass": "ECM_M"
+ }
+ },
+ {
+ "CDCECM_RB_PWR_FILTER_NUM": {
+ "format": "[ECM] cdcecm_rb_downlink(): power management pattern filter check: filter_idx(%d)",
+ "traceClass": "ECM_M"
+ }
+ },
+ {
+ "CDCECM_RB_PWR_FILTER_DROP": {
+ "format": "[ECM] cdcecm_rb_downlink(): power management pattern filter drop: xmit_frames(%d)",
+ "traceClass": "ECM_M"
+ }
+ },
+ {
+ "CDCECM_RB_BULK_OUT_COMPLT": {
+ "format": "[ECM] cdcecm_rb_bulk_out_complete(): ul enumeration: curr_idx(%d), ul_meta(%xl), qtype(%d), net_type(%d), next_idx(%d), end_of_list(%d)",
+ "traceClass": "ECM_M"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_ECM"
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/interface/dhcp4c_common.h b/mcu/middleware/hif/interface/dhcp4c_common.h
new file mode 100644
index 0000000..d7d132c
--- /dev/null
+++ b/mcu/middleware/hif/interface/dhcp4c_common.h
@@ -0,0 +1,58 @@
+/*!
+ * @file dhcp4c_common.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides interface of dhcp4c ( DHCPv4 Client )
+ */
+
+#ifndef _DHCP4C_COMMON_H
+#define _DHCP4C_COMMON_H
+
+
+/*!
+ * @brief dhcp4c init function
+ */
+void dhcp4c_init(void);
+
+
+/*!
+ * @brief dhcp4c main function
+ */
+void dhcp4c_main(ilm_struct* ilm);
+
+
+#endif // _DHCP4C_COMMON_H
+
diff --git a/mcu/middleware/hif/interface/dpfm_data_path_trace_utmd.json b/mcu/middleware/hif/interface/dpfm_data_path_trace_utmd.json
new file mode 100644
index 0000000..9c61dfc
--- /dev/null
+++ b/mcu/middleware/hif/interface/dpfm_data_path_trace_utmd.json
@@ -0,0 +1,124 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "DPFM_L2",
+ "stringTranslationDefs": [],
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "DPFM_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "DPFM_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "DPFM_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "DPFM_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "DPFM_START_FILTER_EXPIRED_TIMER": {
+ "format": "[DPFM] dpfm_start_filter_expired_timer(): Start filter expired timer, current_tick(%xl), elapse_time(%xl)",
+ "traceClass": "DPFM_L"
+ }
+ },
+ {
+ "DPFM_CHECK_FILTER_VALID": {
+ "format": "[DPFM] dpfm_check_filter_valid_period(): Timer expired! Remaining filter number[%xl], expired filter number[%xl], timeout filter number[%xl]",
+ "traceClass": "DPFM_H"
+ }
+ },
+ {
+ "DPFM_START_TRACK_TABLE_EXPIRED_TIMER": {
+ "format": "[DPFM] dpfm_start_track_table_expired_timer(): Start track table expired timer, current_tick(%xl), elapse_time(%xl)",
+ "traceClass": "DPFM_L"
+ }
+ },
+ {
+ "DPFM_SET_GLOBAL_ALERT": {
+ "format": "[DPFM] dpfm_set_global_alert_value(): Set global alert value[%xl %xl]",
+ "traceClass": "DPFM_UH"
+ }
+ },
+ {
+ "DPFM_SET_IQUOTA_LIMIT": {
+ "format": "[DPFM] dpfm_set_iquota_value(): Set limit iquota dpfm_netif_id[%d], value[%xl %xl]",
+ "traceClass": "DPFM_UH"
+ }
+ },
+ {
+ "DPFM_DEL_IQUOTA_LIMIT": {
+ "format": "[DPFM] dpfm_del_iquota_value(): Del limit iquota dpfm_netif_id[%d]",
+ "traceClass": "DPFM_UH"
+ }
+ },
+ {
+ "DPFM_ALERT_GLOBAL_ALERT": {
+ "format": "[DPFM] dpfm_update_global_alert_data_usage(): Send global alert to AP, remaining value[%xl %xl]",
+ "traceClass": "DPFM_M"
+ }
+ },
+ {
+ "DPFM_ALERT_IQUOTA_LIMIT": {
+ "format": "[DPFM] dpfm_update_iquota_data_usage_of_netif(): dpfm_netif_id[%d] reaches iquota limit",
+ "traceClass": "DPFM_UH"
+ }
+ },
+ {
+ "DPFM_DO_DL_FILTER_INVALID_MATCH_FILTER": {
+ "format": "[DPFM] dpfm_check_route_by_dl_filter(): matched_filter is NULL!! No need to do filter",
+ "traceClass": "DPFM_H"
+ }
+ },
+ {
+ "DPFM_CHECK_ROUTE_RESULT_META": {
+ "format": "[DPFM] dpfm_check_route(): Check route with meta, result[%d], uplink[%d], match_result[%d], match_index[%d], filter_id[%d], out_netif_id[%xl]",
+ "traceClass": "DPFM_H"
+ }
+ },
+ {
+ "DPFM_CHECK_ROUTE_RESULT_DID": {
+ "format": "[DPFM] dpfm_check_route(): Check route with DID, result[%d], uplink[%d], filter_id[%d], out_netif_id[%xl]",
+ "traceClass": "DPFM_H"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_DPFM"
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/interface/ethercore_common.h b/mcu/middleware/hif/interface/ethercore_common.h
new file mode 100644
index 0000000..572c766
--- /dev/null
+++ b/mcu/middleware/hif/interface/ethercore_common.h
@@ -0,0 +1,259 @@
+/*!
+ * @file ethercore_common.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides common definitions of ethercore
+ */
+
+#ifndef _ETHERCORE_COMMON_H
+#define _ETHERCORE_COMMON_H
+
+#include "kal_public_api.h"
+#include "ethercore_struct.h"
+#include "lhif_if.h"
+
+#if !defined(__MTK_TARGET__) && defined(_MSC_VER) && (_MSC_VER >= 1500)
+#pragma warning( disable : 4214 )
+#endif
+
+#define ETHC_ETHER_TYPE_IP 0x0800
+#define ETHC_ETHER_TYPE_ARP 0x0806
+#define ETHC_ETHER_TYPE_VLAN 0x8100
+#define ETHC_ETHER_TYPE_IPV6 0x86dd
+
+#define ETHC_SWAP16(_x) ((_x & 0xff00) >> 8 | (_x & 0x00ff) << 8)
+#define ETHC_SWAP32(_x) ((_x & 0xff000000) >> 24 | \
+ (_x & 0x00ff0000) >> 8 | \
+ (_x & 0x0000ff00) << 8 | \
+ (_x & 0x000000ff) << 24)
+
+#define ETHC_HTONS(_x) ETHC_SWAP16(_x)
+#define ETHC_HTONL(_x) ETHC_SWAP32(_x)
+#define ETHC_NTOHS(_x) ETHC_SWAP16(_x)
+#define ETHC_NTOHL(_x) ETHC_SWAP32(_x)
+
+#define ETHC_ETHER_ADDR_SIZE 6
+
+typedef kal_uint8 ethc_mac_addr_t[ETHC_ETHER_ADDR_SIZE];
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ethc_ether_header {
+ ethc_mac_addr_t dst_mac;
+ ethc_mac_addr_t src_mac;
+ kal_uint16 ether_type;
+} ethc_ether_header_t;
+PRAGMA_END_PACK_STRUCT
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ethc_vlan_tag {
+ kal_uint16 tpid; /* Tag Protocol Identifier */
+ struct ethc_tci { /* Tag Control Identifier */
+ kal_uint16 pcp:3; /* Priority Code Point */
+ kal_uint16 cfi:1; /* Canonical Format Indicator */
+ kal_uint16 vid:12; /* VLAN Identifier */
+ } tci;
+} ethc_vlan_tag_t;
+PRAGMA_END_PACK_STRUCT
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ethc_vlan_ether_header {
+ ethc_mac_addr_t dst_mac;
+ ethc_mac_addr_t src_mac;
+ ethc_vlan_tag_t vlan_tag;
+ kal_uint16 ether_type;
+} ethc_vlan_ether_header_t;
+PRAGMA_END_PACK_STRUCT
+
+
+#define ETHC_ARP_HRD_ETHERNET 1
+#define ETHC_ARP_HRD_IEEE802 6
+#define ETHC_ARP_HRD_ARCNET 7
+#define ETHC_ARP_HRD_FRAMERELAY 15
+#define ETHC_ARP_HRD_ATM 16
+#define ETHC_ARP_HRD_HDLC 17
+#define ETHC_ARP_HRD_FIBRE_CHANNEL 18
+#define ETHC_ARP_HRD_SERIAL_LINE 20
+
+#define ETHC_ARP_PRO_IPV4 0x0800
+#define ETHC_ARP_HLN_IEEE802_MAC 6
+#define ETHC_ARP_PLN_IPV4 4
+
+#define ETHC_ARP_OP_ARP_REQUEST 1
+#define ETHC_ARP_OP_ARP_REPLY 2
+#define ETHC_ARP_OP_ARP_RARP_REQUEST 3
+#define ETHC_ARP_OP_ARP_RARP_REPLY 4
+#define ETHC_ARP_OP_ARP_DRARP_REQUEST 5
+#define ETHC_ARP_OP_ARP_DRARP_REPLY 6
+#define ETHC_ARP_OP_ARP_DRARP_ERROR 7
+#define ETHC_ARP_OP_ARP_INARP_REQUEST 8
+#define ETHC_ARP_OP_ARP_INARP_REPLY 9
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ethc_arp_packet {
+ kal_uint16 arp_hrd; /* hardware type */
+ kal_uint16 arp_pro; /* protocol type */
+ kal_uint8 arp_hln; /* hardware address length */
+ kal_uint8 arp_pln; /* protocol address length */
+ kal_uint16 arp_op; /* opcode */
+ ethc_mac_addr_t arp_sha; /* sender hardware address */
+ kal_uint8 arp_spa[4]; /* sender protocol address */
+ ethc_mac_addr_t arp_tha; /* target hardware address */
+ kal_uint8 arp_tpa[4]; /* target protocol address */
+} ethc_arp_packet_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief ethc_device_instance_t describe register information of a
+ * generic ether device
+ */
+typedef struct _ethc_device_info {
+ /*!
+ * @brief module id used to send ilm
+ */
+ module_type module_id;
+
+ /*!
+ * @brief context to be passed in context function
+ */
+ void *context;
+
+ /*!
+ * @brief index the identify which network interface it is.
+ */
+ kal_uint32 netif_id;
+
+ /*!
+ * @brief callback function to reload uplink buffers
+ * Running Level: TASK
+ */
+ kal_bool (*ul_reload)(void *context);
+
+ /*!
+ * @brief callback function to submit io request to ether device
+ * Running Level: TASK
+ */
+ void (*tx_submit)(ethc_device_instance_t* instance, hif_io_request_t* ior);
+
+ /*!
+ * @brief callback function to submit DID to ether device
+ * Running Level: TASK
+ */
+ kal_bool (*rb_tx_submit)(ethc_device_instance_t *instance, void *did, kal_uint8 *ethc_drb_fh_idx, kal_uint32 *ethc_drb_fh_len);
+
+ /*!
+ * @brief callback function to submit buffer to ether device
+ * Running Level: TASK
+ */
+ kal_bool (*buf_tx_submit)(ethc_device_instance_t *instance, void *buf, kal_uint16 buf_len);
+
+ /*!
+ * @used for SPD
+ */
+ kal_uint8 tx_header_offset;//SPD use
+ kal_uint8 tx_header_padding_align;//SPD use
+} ethc_device_info_t;
+
+
+/*!
+ * @brief attach new ether device to ethercore
+ * Running Level: HISR/TASK
+ * @param device_info ether device information used to register
+ * @return new instance of ether device if success, NULL if fail
+ */
+ethc_device_instance_t* ethc_device_attach(ethc_device_info_t* device_info);
+
+
+/*!
+ * @brief detach ether device from ethecore
+ * Running Level: HISR/TASK
+ * @param instance device instance obtained while attach
+ */
+void ethc_device_detach(ethc_device_instance_t* instance);
+
+
+/*!
+ * @brief indicate received io request to ethecore
+ * Running Level: TASK
+ * @param instance device instance obtained while attach
+ * @param ior io request list to be indicated
+ */
+void ethc_device_rx_complete(ethc_device_instance_t* instance, hif_io_request_t* ior);
+
+
+/*!
+ * @brief indicate received ring-buffer data to ethecore
+ * Running Level: TASK
+ * @param instance device instance obtained while attach
+ * @param index entry index
+ * @param queue_no queue number of usb
+ * @param header_len total header length
+ * @param net_type LHIF network type
+ * @param pkt_cnt total packet count
+ * @param byte_cnt total byte count
+ * @param drop_pkt_cnt total dropped packet count
+ * @param is_packet_handled whether the packet has been handled
+ */
+void ethc_rb_rx_complete(ethc_device_instance_t* instance, kal_uint32 index, kal_uint8 queue_no, kal_uint32* header_len, LHIF_NET_TYPE* net_type, kal_uint32* pkt_cnt, kal_uint32* byte_cnt, kal_uint32* drop_pkt_cnt, kal_bool* is_packet_handled, kal_uint32* cjq_len);
+
+
+/*!
+ * @brief indicate the underlying device needs to reload UL buffers
+ * Running Level: TASK
+ * @param instance device instance obtained while attach
+ */
+void ethc_device_rx_need_reload(ethc_device_instance_t* instance);
+
+
+/*!
+ * @brief notify ethercore to handle packets if needed
+ * Running Level: TASK
+ * @param instance device instance obtained while attach
+ */
+void ethc_send_handle_packet_req(ethc_device_instance_t* instance);
+
+void ethc_get_host_mac(kal_uint32 netid_if, kal_uint8* mac_addr);
+
+extern void *ethc_vir_dev_attach(kal_uint32 id);
+extern int ethc_vir_dev_detach(void);
+extern void *ethc_multiple_vir_dev_attach(kal_uint32 id);
+extern int ethc_multiple_vir_dev_detach(void);
+
+#endif // _ETHERCORE_COMMON_H
+
diff --git a/mcu/middleware/hif/interface/ethercore_data_path_trace_utmd.json b/mcu/middleware/hif/interface/ethercore_data_path_trace_utmd.json
new file mode 100644
index 0000000..f299103
--- /dev/null
+++ b/mcu/middleware/hif/interface/ethercore_data_path_trace_utmd.json
@@ -0,0 +1,263 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "ETHERCORE_L2",
+ "stringTranslationDefs": [],
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "ETHC_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline",
+ "Sensitive"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "ETHC_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "ETHC_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "ETHC_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "ETHC_HANDLE_ARP": {
+ "format": "[ETHERCORE] handle_arp_packet(): hrd(%d), pro(%ul), hln(%ul), pln(%ul), op(%ul)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_HANDLE_ARP_SHA_NOT_MATCH_NG": {
+ "format": "[ETHERCORE] handle_arp_packet(): eth%d, sha 0-1(%xl) 2-5(%xl) not match",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_HANDLE_ARP_THA_NOT_MATCH_NG": {
+ "format": "[ETHERCORE] handle_arp_packet(): eth%d, tha 0-1(%xl) 2-5(%xl) not match",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_HANDLE_ARP_GRATUITOUS_NG": {
+ "format": "[ETHERCORE] handle_arp_packet(): eth%d, spa(%ul %ul %ul %ul) is gratuitous",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_HANDLE_ARP_ZERO_IP_NG": {
+ "format": "[ETHERCORE] handle_arp_packet(): eth%d, spa(%ul %ul %ul %ul) is zero ip",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_HANDLE_ARP_ALLOC_NET_DL_NG": {
+ "format": "[ETHERCORE] handle_arp_packet(): failed to allocate NET_DL to handle ARP request(%xl), drop it!",
+ "traceClass": "ETHC_UH"
+ }
+ },
+ {
+ "ETHC_HANDLE_ARP_DONE": {
+ "format": "[ETHERCORE] handle_arp_packet(): eth%d, result(%ul), parse_arp_req(%ul), gpd(%xl), tx_gpd(%xl)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_PROC_RX_GPD": {
+ "format": "[ETHERCORE] [%d] process rx gpd(%xl), result(%l), ether_type(%xl), qos_priority(%l)",
+ "traceClass": "ETHC_M"
+ }
+ },
+ {
+ "ETHC_PROC_RX_GPD_TYPE_IP": {
+ "format": "[ETHERCORE] [%d] process rx gpd(%xl) w/ ipv4, ip_proto_type(%l)",
+ "traceClass": "ETHC_M"
+ }
+ },
+ {
+ "ETHC_PROC_RX_GPD_TYPE_ARP": {
+ "format": "[ETHERCORE] [%d] process rx gpd(%xl) w/ arp",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_PROC_RX_GPD_TYPE_IPV6": {
+ "format": "[ETHERCORE] [%d] process rx gpd(%xl) w/ ipv6, next_header(%l)",
+ "traceClass": "ETHC_M"
+ }
+ },
+ {
+ "ETHC_PROC_RX_GPD_TYPE_UNSUPPORTED": {
+ "format": "[ETHERCORE] [%d] process unsupported rx gpd(%xl)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_PROC_TX_TYPE_GPD_BD": {
+ "format": "[ETHERCORE] [%d] process_tx_gpd_list(): insert a header bd into tx gpd(%xl)",
+ "traceClass": "ETHC_M"
+ }
+ },
+ {
+ "ETHC_PROC_TX_ALLOC_BD_NG": {
+ "format": "[ETHERCORE] [%d] process_tx_gpd_list(): fail to allocate a header bd, current_gpd(%xl), first_gpd(%xl), last_gpd(%xl)",
+ "traceClass": "ETHC_UH"
+ }
+ },
+ {
+ "ETHC_RB_TX_FREE_ALL_VRB_ENUM": {
+ "format": "[ETHERCORE] ethc_rb_tx_free_all_vrb(): enumerate did_sit list, did(%xl), handled_seg_cnt(%ul), curr_sit(%xl), p_data(%xl), len(%ul)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_RB_TX_FREE_ALL_VRB_DONE": {
+ "format": "[ETHERCORE] ethc_rb_tx_free_all_vrb(): enumerate done, did(%xl), handled_seg_cnt(%ul)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_RB_TX_ENCAP_ETHER_HEADER_DONE": {
+ "format": "[ETHERCORE] ethc_rb_encap_ether_header(): ip_packet(%xl), ip_ver(%xl), ether_type_idx(%xl), vlan_enable_idx(%ul), fh_idx(%ul), fh_len(%ul)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_RB_PROC_TX_PKT": {
+ "format": "[ETHERCORE] ethc_rb_process_tx_pkt(): process TX packet, did(%xl), seg_num(%ul)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_RB_PROC_TX_PKT_INVALID_DID_FORMAT": {
+ "format": "[ETHERCORE] ethc_rb_process_tx_pkt(): invalid did format, curr_idx(%d), did(%xl)!",
+ "traceClass": "ETHC_UH"
+ }
+ },
+ {
+ "ETHC_RB_PROC_TX_PKT_ENUM": {
+ "format": "[ETHERCORE] ethc_rb_process_tx_pkt(): enumerate did list, curr_idx(%d), sit(%xl), p_data(%xl), len(%xl), pkt_cnt(%ul), byte_cnt(%ul), is_first_gpd(%ul)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_BUF_ENCAP_ETHER_HEADER_DONE": {
+ "format": "[ETHERCORE] ethc_buf_encap_ether_header(): encap ether header done, type(%ul), out_data(%xl), out_data_len(%ul)",
+ "traceClass": "ETHC_M"
+ }
+ },
+ {
+ "ETHC_RB_IPC_TX_SUBMIT_DONE": {
+ "format": "[ETHERCORE] ethc_rb_ipc_tx_submit(): ethcore tx submit done, ret(%d), did(%xl)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_RB_IPC_TX_SUBMIT_NOT_LINK_UP": {
+ "format": "[ETHERCORE] ethc_rb_ipc_tx_submit(): device state is not link up, did(%xl)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_RB_DECAP_ETHER_HEADER": {
+ "format": "[ETHERCORE] ethc_rb_decap_ether_header(): ether_type(%xl), eth_hdr(%xl), prb_addr(%xl), length(%ul)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_RB_DECAP_ETHER_HEADER_INVALID_VLAN_FORMAT": {
+ "format": "[ETHERCORE] ethc_rb_decap_ether_header(): invalid vlan format, vlan_cfi(%d)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_RB_DECAP_ETHER_HEADER_2": {
+ "format": "[ETHERCORE] ethc_rb_decap_ether_header(): decap ether header_2, data_addr(%xl), data_len(%ul), remove_len(%ul)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_RB_PROC_RX_PKT": {
+ "format": "[ETHERCORE] ethc_rb_process_rx_pkt(): result(%d), xit(%xl), ether_type(%xl), qos_priority(%ul)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_RB_PROC_RX_PKT_TYPE_IP": {
+ "format": "[ETHERCORE] ethc_rb_process_rx_pkt(): ipv4 type, xit(%xl), ip_pro(%ul)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_RB_PROC_RX_PKT_TYPE_ARP": {
+ "format": "[ETHERCORE] ethc_rb_process_rx_pkt(): arp type, xit(%xl)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_RB_PROC_RX_PKT_TYPE_IPV6": {
+ "format": "[ETHERCORE] ethc_rb_process_rx_pkt(): ipv6 type, xit(%xl), next_header(%ul)",
+ "traceClass": "ETHC_L"
+ }
+ },
+ {
+ "ETHC_RB_PROC_RX_PKT_ALLOC_GPD_NG": {
+ "format": "[ETHERCORE] ethc_rb_rx_complete(): fail to allocate GPD, drop packet. xit(%xl), ether_type(%xl), qos_priority(%ul)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_PROC_RX_PKT_TYPE_UNSUPPORTED": {
+ "format": "[ETHERCORE] ethc_rb_process_rx_pkt(): unknown type, xit(%xl)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_RX_PKT_DROP": {
+ "format": "[ETHERCORE] ethc_rb_rx_complete(): drop packet, eth_id(%d), dev_state(%d), xit(%xl)",
+ "traceClass": "ETHC_H"
+ }
+ },
+ {
+ "ETHC_FN_TX_SUBMIT_NONE": {
+ "format": "[ETHERCORE] ethc_rb_ipc_tx_submit(): tx_submit callback not register, dev_state(%d), tx_submit=(%xl)",
+ "traceClass": "ETHC_H"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_ETHERCORE"
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/interface/hif_mw_cccidev_trace_utmd.json b/mcu/middleware/hif/interface/hif_mw_cccidev_trace_utmd.json
new file mode 100644
index 0000000..49d4c2c
--- /dev/null
+++ b/mcu/middleware/hif/interface/hif_mw_cccidev_trace_utmd.json
@@ -0,0 +1,204 @@
+{
+ "endGen": "-",
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "HIF_MW_CCCIDEV",
+ "startGen": "Legacy",
+ "stringTranslationDefs": [],
+ "traceClassDefs": [
+ {
+ "DL_UL": {
+ "debugLevel": "Ultra-Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "CCMNI_UL": {
+ "debugLevel": "Ultra-Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "CCMNI_DL_UL": {
+ "debugLevel": "Ultra-Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "CCMNI_UL_UL": {
+ "debugLevel": "Ultra-Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "CCMNI_DUMP_UL": {
+ "debugLevel": "Ultra-Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "CCCITTY_DUMP_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "CCMNI_DATA_DUMP_TRACE": {
+ "format": "[CCMNI DUMP] %b: %10xl %10xl %10xl %10xl",
+ "traceClass": "CCMNI_DUMP_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_DATA_DUMP_GPD_PTR": {
+ "format": "[CCMNI DL] CCMNI%b: GDP=%xl BD1=%xl BD2=%xl DATA=%xl",
+ "traceClass": "CCMNI_DUMP_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_DL_DATA_IPv6_PACKET_TRACE": {
+ "format": "[CCMNI DLv6] Protocol:%b GPD=%xl Checksum=%xl Src Addr=%10xl %10xl %10xl %10xl",
+ "traceClass": "CCMNI_DL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_UL_DATA_IPv6_PACKET_TRACE": {
+ "format": "[CCMNI ULv6] Protocol:%b GPD=%xl Checksum=%xl Dst Addr=%10xl %10xl %10xl %10xl",
+ "traceClass": "CCMNI_UL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_DL_DATA_PACKET_TRACE": {
+ "format": "[CCMNI DL] CCMNI%b: CCCIHDR=%xl SEQ=%xd IPID=%xd checksum=%xd",
+ "traceClass": "CCMNI_DL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_DL_DATA_PACKET_NON_IPV4V6_TRACE": {
+ "format": "[CCMNI DL] CCMNI%b: CCCIHDR=%xl SEQ=%xd PAYLOAD=%xl PAYLOAD_LEN=%d",
+ "traceClass": "CCMNI_DL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_UL_DATA_PACKET_TRACE": {
+ "format": "[CCMNI UL] CCMNI%b: GPD=%xl IPID=%xd checksum=%xd",
+ "traceClass": "CCMNI_UL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_UL_GPD_IN_HIF": {
+ "format": "[CCMNI UL] CCMNI%b: Receive GPD=%d, Need Reload=%d, GPD in HIF=%d, Data_Q=%d, Ack_Q=%d",
+ "traceClass": "CCMNI_UL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_UL_RELOAD_RGPD": {
+ "format": "[CCMNI UL_RELOAD] CCMNI%b: Reload RGPD Want=%d, Allocated=%d, in HIF=%d",
+ "traceClass": "CCMNI_UL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_UL_RELOAD_RGPD_IN_HIF": {
+ "format": "[CCMNI UL_RELOAD] CCMNI%b: Nor_Q_before=%d, Nor_Q_after=%d, Nor_Q_MAX=%d, Ack_Q_before=%d, Ack_Q_after=%d, Ack_Q_MAX=%d",
+ "traceClass": "CCMNI_UL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_MAX_RELOAD_RGPD_IN_HIF": {
+ "format": "[CCMNI MAX RGPD] Data_Q_MAX=%d Ack_Q_MAX=%d, Misc_Q_MAX=%d",
+ "traceClass": "CCMNI_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_DEVICE_STATUS": {
+ "format": "[CCMNI STATUS] CCMNI%b: event=%b status=%b -> %b",
+ "traceClass": "CCMNI_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCMNI_DL_DATA_FIRST_FAST_CCCI_HDR": {
+ "format": "[CCMNI DL] CCMNI%b: Rem_gpd(%d)",
+ "traceClass": "CCMNI_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCCITTY_DATA_DUMP_TRACE": {
+ "format": "[CCCITTY DUMP] %b: %10xl %10xl %10xl %10xl",
+ "traceClass": "CCCITTY_DUMP_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCCIDEV_PROCESS_DL_SPD_TRACE": {
+ "format": "[CCCIDEV DL SPD] pkt_num:%d current_gpd:%xl",
+ "traceClass": "DL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCCIDEV_PROCESS_DL_SPD_SET_IGR_TRACE": {
+ "format": "[CCCIDEV DL SPD] ignore bit set (%d) in pkt:%d pie:%xl",
+ "traceClass": "DL_UL",
+ "traceHighlightOption": "warn"
+ }
+ },
+ {
+ "CCCIDEV_SPD_RELAYOUT_SET_PKTNUM_TRACE": {
+ "format": "[CCCIDEV DL SPD] Get pkt_num:%d from pi:%xl and write to spd_ext:%xl",
+ "traceClass": "DL_UL",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "CCCIDEV_SPD_RELAYOUT_GET_EOL_BREAK_TRACE": {
+ "format": "[CCCIDEV DL SPD] BREAK!!! total pkt_num:%d current pkt_num:%d spd_ph:%xl",
+ "traceClass": "DL_UL",
+ "traceHighlightOption": "warn"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_CCCIDEV"
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/interface/hif_mw_data_path_ipcore_trace_utmd.json b/mcu/middleware/hif/interface/hif_mw_data_path_ipcore_trace_utmd.json
new file mode 100755
index 0000000..d46d555
--- /dev/null
+++ b/mcu/middleware/hif/interface/hif_mw_data_path_ipcore_trace_utmd.json
@@ -0,0 +1,907 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "HIF_MW_IPCORE",
+ "startGen": "Legacy",
+ "endGen": "-",
+ "stringTranslationDefs": [
+ {
+ "IPC_IP_TYPE": [
+ "IPC_IP_TYPE_MIXED",
+ "IPC_IP_TYPE_IPV4",
+ "IPC_IP_TYPE_IPV6"
+ ]
+ }
+ ],
+ "traceClassDefs": [
+ {
+ "UL_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "DL_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "GE_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "UL_DETAIL_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "DL_DETAIL_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "GE_DETAIL_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "DPFM_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "DATA_PATH_SENSATIVE_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "DATA_PATH_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "IPC_UL_UPLINK_CALLBACK": {
+ "format": "[IPCORE] ipc_uplink() : [%ub] Callback with UL IP IOR[%xl] for netif[%xl], netif's features[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_META_UPLINK_CALLBACK": {
+ "format": "[IPCORE] ipc_meta_uplink() : Callback with UL IP Meta start_idx[%xl], end_idx[%xl], q_type[%ub]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_META_PN_MISS_MATCH": {
+ "format": "[IPCORE] ipc_check_and_fill_session_info() : UL IP Meta PDN info are different(mask with proto_idx). netif_id[%xl], ip_type[%xb], PDN_from_IPCORE[%xl], PDN_from_meta[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_META_DPFM_CMD": {
+ "format": "[IPCORE] ipc_on_process_UL_UHpc_result() : UL DPFM CMD result [%xl], meta_idx[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_DEQUEUE_UPLINK_PRIORITY_QUEUE": {
+ "format": "[IPCORE] ipc_on_process_ul_ior_list() : Pending IOR count[%d], Throttling state: blocking-latency-concern[%ub]/ims-emergency[%ub]. High priority IOR list head[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_DEQUEUE_UPLINK_QUEUE": {
+ "format": "[IPCORE] ipc_on_process_ul_queue() : UL data throttled! Pending q_type[%ub], q_priority[%ub], cnt[%ul].",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_PROCESS_UPLINK_QUEUE": {
+ "format": "[IPCORE] ipc_on_process_ul_queue()",
+ "traceClass": "DATA_PATH_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_UPLINK_QUEUE_PENDING": {
+ "format": "[IPCORE] ipc_on_process_ul_queue() : Queue: type[%ub], priority[%ub] and Pending_cnt[%l]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_IOR_CHANGE_GPD_TYPE": {
+ "format": "[IPCORE] ipc_ior_change_gpd_type() : Change to GPD type[%d], with origin IOR[%xl] and new IOR[%xl]",
+ "traceClass": "UL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_ON_PROCESS_NORMAL_IOR": {
+ "format": "[IPCORE] ipc_on_process_ul_ior_list() : [%ub] Handle IOR[%xl] belongs to netif[%xl]",
+ "traceClass": "UL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_FORWARD_META": {
+ "format": "[IPCORE] ipc_on_process_ul_meta_table() : Forward UL Meta: start_idx[%xl], end_idx[%xl], q_type[%ub]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_THROTTLE_IMS_EMERGEMCY_IND": {
+ "format": "[IPCORE] ipc_ims_emergency_call_ind_handler(): VDM indication to change ims_block_flag from [%ub] to [%ub]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_TR_TIMER_UL_THROTTLE_TIMEOUT": {
+ "format": "[IPCORE] ipc_ul_throttle_timeout(): UL throttle timer timeout, current_tick(%l), current_state(%ub), enable(%ub), active(%ub), suspend(%ub)",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_TR_START_UL_THROTTLE_TIMER": {
+ "format": "[IPCORE] ipc_start_ul_throttle_timer(): Start UL throttle timer, current_tick(%l), elapse_time(%l)",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_RELOAD_UPLINK": {
+ "format": "[IPCORE] ipc_reload_uplink() : [%ub] Reload uplink for netif[%xl], netif_id[%xl], callback[%xl]",
+ "traceClass": "UL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_RELOAD_UPLINK_RESULT": {
+ "format": "[IPCORE] ipc_reload_uplink() : [%ub] Reload uplink result for for netif[%xl], netif_id[%xl] : %ub",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_RELOAD_RETRY": {
+ "format": "[IPCORE] ipc_set_netif_ul_reload_retry() : Update retry-reload flag [%ub] for netif[%xl], netif_id[%xl], callback[%xl] while set-need-reload bit-mask[%xl]",
+ "traceClass": "UL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_RELOAD_RETRY_RACE_COND": {
+ "format": "[IPCORE] ipc_set_netif_ul_reload_retry() : [%ub] Update retry-reload race condition occurred with retry-reload flag [%ub], set-need-reload flag [%l] and reload retrial bit-mask[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_RELOAD_RETRY_FLAG": {
+ "format": "[IPCORE] ipc_set_netif_ul_reload_retry() : [%ub] Uplink reload retrial bit-mask[%xl] while set-need-reload bit-mask[%xl]",
+ "traceClass": "UL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SET_NEED_RELOAD": {
+ "format": "[IPCORE] ipc_set_netif_ul_set_need_reload() : Update set-need-reload flag [%ub] for netif[%xl], netif_id[%xl], callback[%xl]",
+ "traceClass": "UL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SET_NEED_RELOAD_FLAG": {
+ "format": "[IPCORE] ipc_set_netif_ul_set_need_reload() : [%ub] Netif set need reload bit-mask[%xl]",
+ "traceClass": "UL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_ON_RETRY_RELOAD": {
+ "format": "[IPCORE] ipc_on_retry_ul_reload() : [%ub] Current uplink reload retrial bit-mask[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_ON_RETRY_RELOAD_FOR_NETIF": {
+ "format": "[IPCORE] ipc_on_retry_ul_reload() : [%ub] Reload network interface[%xl] for bit[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_CHECK_UL_RELOAD_RETRY": {
+ "format": "[IPCORE] ipc_check_ul_reload_retry() : [%ub] Current uplink reload retrial bit-mask[%xl] : need retry reload !",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_DROP_UL_IOR": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : [%ub] Drop UL IOR for netif[%xl], ior[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_LOOPBACK_UL_IOR": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : [%ub] Loopback UL IOR for netif[%xl], ior[%xl], DL callback[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_LOOPBACK_UL_IOR_DROP": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : [%ub] Drop loopback UL IOR due to invalid DL callback for netif[%xl], ior[%xl], DL callback[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_HANDLE_UL_GPD_LIST": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : IP-Type(%ub) - To handle UL GPD : netif_id[%xl], first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_FORWARD_UL_SDU": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : IP-Type(%ub) - Forward UL GPD : pdn_id[%xl], first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_HANDLE_IPV4_UL_GPD_LIST": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : IP-Type(%ub) - To handle IPv4 UL GPD : netif_id[%xl], first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "UL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_FORWARD_IPV4_UL_SDU": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : IP-Type(%ub) - Forward IPv4 UL GPD : pdn_id[%xl], first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_HANDLE_IPV6_UL_GPD_LIST": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : IP-Type(%ub) - To handle IPv6 UL GPD : netif_id[%xl], first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_FORWARD_IPV6_UL_SDU": {
+ "format": "[IPCORE] ipc_forward_ul_ior() : IP-Type(%ub) - Forward IPv6 UL GPD : pdn_id[%xl], first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_FORWARD_UL_SDU_MULTI_PS": {
+ "format": "[IPCORE] IPC_FORWARD_UL_SDU() : Forward UL GPD with pdn_id[%l]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_FORWARD_UL_SDU_BY_EBI_MULTI_PS": {
+ "format": "[IPCORE] IPC_FORWARD_UL_SDU_BY_EBI() : Forward GPD to UL with EBI(%l)",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_DHCP4C_PKT_SESSION": {
+ "format": "[IPCORE] ipc_on_dhcp4c_packet_ind() : [%ub] Send DHCPv4 gpd[%xl], ip_id[%ub], session[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_DHCP4C_PKT_UPLINK": {
+ "format": "[IPCORE] ipc_on_dhcp4c_packet_ind() : [%ub] Send DHCPv4 gpd[%xl], session[%xl], netif_id[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SEND_PKT": {
+ "format": "[IPCORE] ipc_send_ul_pkt() : Receive GPD to UL with EBI(%l) : head[%xl] ~ tail[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SEND_PKT_BY_PDN": {
+ "format": "[IPCORE] ipc_send_ul_pkt_by_pdn() : Receive GPD to UL with PDN(%l), ip_type(%xb) : head[%xl] ~ tail[%xl], length (%xl)",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SEND_PKT_MULTI_PS": {
+ "format": "[IPCORE] ipc_send_ul_pkt_multiple_ps() : Function be called with EBI(%l) and proto_idx(%l)",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SEND_PKT_BY_PDN_MULTI_PS": {
+ "format": "[IPCORE] ipc_send_ul_pkt_by_pdn_multiple_ps() : Function be called with PDN(%l) and proto_idx(%l)",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SEND_PKT_BY_NETIF_ID": {
+ "format": "[IPCORE] ipc_send_ul_pkt_by_netif_id() : Send GPD to UL with NETIF_ID(%xl), ip_tpye(%xb) : head[%xl] ~ tail[%xl], length(%xl)",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SEND_PKT_FORWARD": {
+ "format": "[IPCORE] ipc_on_process_ul_ior_list() : Send GPD to UL with EBI(%l) : head[%xl] ~ tail[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_CLUB_PKT_B4_FORWARD": {
+ "format": "[IPCORE] ipc_on_process_ul_ior_list() : Club curr UL GPD for EBI(%l) : head[%xl] ~ tail[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_CLUB_PKT_BY_PDN_B4_FORWARD": {
+ "format": "[IPCORE] ipc_on_process_ul_ior_list() : Club curr UL GPD for PDN(%l), ip_type(%xb) : head[%xl] ~ tail[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_SEND_PKT_BY_PDN_FORWARD": {
+ "format": "[IPCORE] ipc_on_process_ul_ior_list() : Send GPD to UL with PDN(%l), ip_type(%xb) : head[%xl] ~ tail[%xl]",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_META_DROP_DID_ALLOC_NG": {
+ "format": "[IPCORE] ipc_ipf_meta_do_filter() : packet drop because DID allocation failed, out_netif[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_META_DOWNLINK_CALLBACK": {
+ "format": "[IPCORE] ipc_meta_downlink() : Callback with DL IPF Meta start_idx[%xl], end_idx[%xl], q_type[%ub]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_META_ON_PROC": {
+ "format": "[IPCORE] ipc_on_process_dl_meta() : Process DL IPF Meta read_idx[%xl], end_idx[%xl], q_type[%ub]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_META_ON_PROC_DONE": {
+ "format": "[IPCORE] ipc_on_process_dl_meta() : Free DL IPF Meta read_idx[%xl], end_idx[%xl], q_cnt[%xl], q_type[%ub]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_META_PROC_INFO": {
+ "format": "[IPCORE] ipc_meta_downlink_dequeue() : DL IPF Meta head_idx[%xl], tail_idx[%xl], q_cnt[%xl], Pending_cnt[%xl], tbl_size[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_META_MATCH_RESULT": {
+ "format": "[IPCORE] ipc_on_process_dl_meta() : read_idx[%xl], match_result[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_LAN_DIRECT_SEND_DL_IOR": {
+ "format": "[IPCORE] ipc_on_process_ul_ior_list() : [%ub] CCMNI-LAN directly send DL IOR from netif_id[%xl] to netif_id[%xl] - IOR[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_SEND_IPV4_PKT": {
+ "format": "[IPCORE] ipc_send_dl_pkt() : [%ub] Send IPv4 GPD to netif_id[%xl], first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_SEND_IPV6_PKT": {
+ "format": "[IPCORE] ipc_send_dl_pkt() : [%ub] Send IPv6 GPD to netif_id[%xl], first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_SEND_PKT_DID": {
+ "format": "[IPCORE] ipc_send_dl_pkt_in_did() : Send DID to netif_id[%xl], did[%xl], pkt_cnt[%d]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_SEND_PKT_DID_PENDING": {
+ "format": "[IPCORE] ipc_send_dl_pkt_in_did() : Netif refuse to receive DL DIDs, pending_head[%xl], pending_tail[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ON_DOWNLINK": {
+ "format": "[IPCORE] ipc_on_downlink() : Downlink handle from pdn_id[%l], head[%xl], tail[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ON_DOWNLINK_FILTER_OUT": {
+ "format": "[IPCORE] ipc_on_downlink() : [%ub] Filter out all downlink GPDs : session_type[%ub], netif_id[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ON_DOWNLINK_CALLBACK_INFO": {
+ "format": "[IPCORE] ipc_on_downlink() : Send DL GPDs from pdn_id[%l] - Session/netif information : session_type[%ub], netif_id[%xl]",
+ "traceClass": "DL_DETAIL_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ON_DOWNLINK_CALLBACK_GPD": {
+ "format": "[IPCORE] ipc_on_downlink() : Send DL GPDs from pdn_id[%l] - GPD information : first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ON_DOWNLINK_MULTI_PS": {
+ "format": "[IPCORE] ipc_on_downlink_multiple_ps() : Downlink handle from pdn_id[%l], proto_idx[%ub]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ON_DID_DOWNLINK": {
+ "format": "[IPCORE] ipc_did_downlink_enqueue() : Downlink handle from pdn_id[%xl] (mask with proto_idx), head[%xl], tail[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_PROCESS_DL_DID": {
+ "format": "[IPCORE][DL_PSN flow: %ub, from: %xd, to: %xd, seg_num: %ud] ipc_on_process_dl_did_list() : Process DL DID[%xl] from pdn_id[%l]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_FWD_DL_CALLBACK_DID": {
+ "format": "[IPCORE] ipc_forward_dl_did_default() : Send DL %ub packets to netif_id[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_DO_FILTER_DID_ZERO_SIT": {
+ "format": "[IPCORE] ipc_do_did_filter() : hif_type is ignore && legnth is zero, curr_id[%ub] bypass_seg[%ub] pkt_seg[%ub]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_FWD_DL_CALLBACK_DID_WO_FILTER": {
+ "format": "[IPCORE] ipc_forward_dl_did_default_wo_filter() : Send DL %ub packets to netif_id[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ON_DID_DOWNLINK_PENDING": {
+ "format": "[IPCORE] ipc_on_process_dl_did_list() : Netif refuse to receive DL DIDs, pending_head[%xl], pending_tail[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ON_DID_DOWNLINK_TEST_LOOPBACK": {
+ "format": "[IPCORE] ipc_on_did_downlink_test_mode() : Downlink handle from pdn_id[%l], head[%xl], tail[%xl], test_mode[%ub]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_DO_FILTER_WHEN_LINK_DOWN": {
+ "format": "[IPCORE] ipc_on_process_dl_did_list_when_link_down() : Do DL filter when link down did_head[%xl], did_tail[%xl], from pdn_id[%l]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_INVALID_LEN_CHK": {
+ "format": "[IPCORE] ipc_pkt_do_filter() : dl_invalid_len : cur_gpd[%xl], cur_bd[%xl], pkt_length[%xl], valid_length[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_INVALID_LEN_CHK_DID": {
+ "format": "[IPCORE][DL_PSN flow: %ub, psn: %xd] ipc_pkt_do_filter() : dl_invalid_len : pkt_length[%xl], valid_length[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_INVALID_LEN_PKT_IP_HDR": {
+ "format": "[IPCORE] ipc_pkt_do_filter() : dl_invalid_len ip_header[%ub] header data[%xl]",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_FILTER_RULE_MATCHED": {
+ "format": "[IPCORE] ipc_pkt_do_filter() : [%ub] filter rule matched - filter rules: rules[%xl], features[%xb], valid_fields[%xl], matched[%xl]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_SPD_DO_FILTER": {
+ "format": "[IPCORE] ipc_spd_do_filter() : [%ub] SPD[%xl] with length[%xl], pkt_num[%xb] is about to do filter",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_SPD_ENTRY_IGR_INFO": {
+ "format": "[IPCORE] ipc_spd_do_filter() : One of SPD entries has been ignored : uplink[%ub], curr_spd[%xl], idx[%l], payload_len[%l]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_SPD_ALL_IGR_INFO": {
+ "format": "[IPCORE] ipc_do_filter() : All entry of the SPD have been ignored : uplink[%ub], curr_spd[%xl], packet_num[%l]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_DO_FILTER_GPD_UPDATE": {
+ "format": "[IPCORE] ipc_do_filter() : GPD update after uniting : uplink[%ub], curr_gpd[%xl], united_gpd[%xl]/len[%l]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_FILTER_OUT_INFO": {
+ "format": "[IPCORE] ipc_call_filter_cbk() : filter out and callback - General info : uplink[%ub], callback_context[%xl], filter_id[%xl]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_FILTER_OUT_GPD": {
+ "format": "[IPCORE] ipc_call_filter_cbk() : filter out and callback - GPD info : uplink[%ub], gpd_head[%xl], gpd_tail[%xl], length[%l]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_UNITE_FAIL_DROP": {
+ "format": "[IPCORE] ipc_do_filter() : Unite Failed ! Drop packet with length[%l], orgGPD[%lx]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_UNITE_FAIL_DROP_INFO": {
+ "format": "[IPCORE] ipc_do_filter() : Dropped packet info : FilterID[%l], orgGPD[%lx], pdnID[%l], netifID[%l]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_HANDLE_GPD": {
+ "format": "[IPCORE] ipc_pack_pkt() : [%ub] Handle GPD - head[%xl], tail[%xl]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_SET_ALLOC_DATA": {
+ "format": "[IPCORE] ipc_pack_pkt() : Set and allocate GPD for data buffer - data_len[%l], data[%xl], ip_header_len[%l], udp_header_len[%l]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_FILL_HEADER": {
+ "format": "[IPCORE] ipc_pack_pkt() : Fill header with total_le[%d] for GPD[%xl], ip_header_len[%l], udp_header_len[%l]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_PACK_PACKET_PUBLIC": {
+ "format": "[IPCORE] ipc_pack_pkt_public() : [%ub] ipc_pack_pkt_public() is invoked.",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GE_UNITED_GPD": {
+ "format": "[IPCORE] ipc_gpd_unite() : GPD is united with new one : uplink[%ub], p_gpd_in[%xl], *pp_gpd_out[%xl]/len[%l]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UL_PKT_FILTER_RESULT_META": {
+ "format": "[IPCORE][UL_PSN: %xd] ipc_pkt_do_filter() : packet match result[%ub], dpfm_rule_id[%ub] (only valid when result=3)",
+ "traceClass": "UL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_PKT_FILTER_RESULT_DID": {
+ "format": "[IPCORE][DL_PSN flow: %ub, psn: %xd] ipc_pkt_do_filter() : packet match result[%ub], dpfm_rule_id[%ub] (only valid when result=3)",
+ "traceClass": "DL_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_PKT_FILTER_RESULT_GPD": {
+ "format": "[IPCORE] ipc_pkt_do_filter() : uplink[%ub], gpd[%xl], packet match result[%ub], dpfm_rule_id[%ub] (only valid when result=3)",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_PKT_FILTER_RESULT_SPD": {
+ "format": "[IPCORE] ipc_pkt_do_filter() : uplink[%ub], packet match result[%ub], dpfm_rule_id[%ub] (only valid when result=3)",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_TRANS_GPD_TO_DID": {
+ "format": "[IPCORE] ipc_send_dl_pkt_in_did_internal() : translate GPD[%xl] to DID head[%xl] and DID tail[%xl])",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "PFM_GE_MATCHED_PACKET_INFO": {
+ "format": "[PFM] pfm_matched_packet_trace(): The matched packet ! EBI[%d], IPID[%xb], checksum[%xd]",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "PFM_GE_MATCHED_PACKET_DUMP": {
+ "format": "[PFM DUMP] %3d: %10xl %10xl %10xl %10xl",
+ "traceClass": "DATA_PATH_SENSATIVE_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "PFM_DL_RECEIVED_FILTER_PACKET": {
+ "format": "[PFM] Received fin ack packet gpd_head (%xl) gpd_tail (%xl)",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DATA_DUMP_TRACE": {
+ "format": "[IPCORE] %b: %10xl %10xl %10xl %10xl",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_GET_NETIF_FROM_META": {
+ "format": "[IPCORE] ipc_get_netif_id_from_meta() : net_type(%d), channl_id(%d), netif(0x%xl)",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DL_ENQ_BY_NETIF": {
+ "format": "[IPCORE] ipc_data_dl_enq_by_netif() : Send did_head(0x%xl), did_head(0x%xl) to netif_id(%d)",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_CHECK_ROUTE_MATCHED": {
+ "format": "[IPCORE] ipc_pkt_do_filter() : uplink[%ub] ip_type[%ub] DPFM check route matched to out_netif_id[%xl]",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_ON_DOWNLINK": {
+ "format": "[IPCORE] ipc_dpfm_on_downlink() : [%ub] DPFM DL direct path : first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_ON_DOWNLINK_PKT_IPV4": {
+ "format": "[IPCORE] ipc_dpfm_on_downlink() : DPFM DL direct path IPV4 : curr_gpd[%xl], IPID = %xb, checksum = %xd",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_ON_DOWNLINK_PKT_IPV6": {
+ "format": "[IPCORE] ipc_dpfm_on_downlink() : DPFM DL direct path IPV6 : protocol:%d, curr_gpd[%xl], checksum = %xl, Src Addr=%10xl %10xl %10xl %10xl",
+ "traceClass": "DATA_PATH_SENSATIVE_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_ON_DOWNLINK_PKT_NON_IPV4V6": {
+ "format": "[IPCORE] ipc_dpfm_on_downlink() : DPFM DL direct path non IPv4 and IPv6 : curr_gpd[%xl], length = %d",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_FORWARD_UL_IOR": {
+ "format": "[IPCORE] ipc_dpfm_forward_ul_ior() : [%d] DPFM UL direct path : first_gpd[%xl], last_gpd[%xl]",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_FORWARD_UL_IOR_PKT_IPV4": {
+ "format": "[IPCORE] ipc_dpfm_forward_ul_ior() : DPFM UL direct path IPv4 : curr_gpd[%xl], IPID = %xl, checksum = %xl",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_FORWARD_UL_IOR_PKT_IPV6": {
+ "format": "[IPCORE] ipc_dpfm_forward_ul_ior() : DPFM UL direct path IPv6 : protocol:%d, curr_gpd[%xl], checksum = %xl, Src Addr=%10xl %10xl %10xl %10xl",
+ "traceClass": "DATA_PATH_SENSATIVE_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_FORWARD_UL_IOR_PKT_NON_IPV4V6": {
+ "format": "[IPCORE] ipc_dpfm_forward_ul_ior() : DPFM UL direct path non IPv4 and IPv6 : curr_gpd[%xl], length = %d",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_BIND_LAN_NETIF": {
+ "format": "[IPCORE] ipc_bind_lan_netif() : [%d] netif_1[%xl] id[%xl], netif_2[%xl] id[%xl]",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_UNBIND_LAN_NETIF": {
+ "format": "[IPCORE] ipc_unbind_lan_netif() : [%d] netif_1[%xl], id[%xl], netif_2[%xl] id[%xl]",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_DPFM_DETECT_FM_NOT_MATCH": {
+ "format": "[IPCORE] ipc_on_pdn_deact() : DPFM detect flight mode not match [%d] netif[%xl]",
+ "traceClass": "DPFM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_TR_CUST_FILTER_CBK": {
+ "format": "[IPCORE] Filter matched and invoke cust filter cbk with pkt (0x%xl) pkt_len (0x%xl) filter_id (0x%xl) result (0x%xl)",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "IPC_SEND_L2_UNK_INFO": {
+ "format": "[IPCORE] Send L2 unknown header info from meta (0x%xl) to meta (0x%xl) unk_cnt (0x%xl) begin_cntl (0x%xl) end_cntl (0x%xl) rb_idx (0x%xl) proto_idx (0x%xl)",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "LTM_SIM_TPUT_ANALYSIS": {
+ "format": "[LTM_SIM] REAL_PKT_NUM : %d, EXPECTED_PKT_NUM : %l, TIME_DIFF : %l, Current_Time: %l, Last_Time : %l, RECYCLE_PKT_NUM : %l.",
+ "traceClass": "GE_UH",
+ "traceHighlightOption": "info"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_IPCORE"
+}
diff --git a/mcu/middleware/hif/interface/ipcore_dhcph.h b/mcu/middleware/hif/interface/ipcore_dhcph.h
new file mode 100644
index 0000000..a59222b
--- /dev/null
+++ b/mcu/middleware/hif/interface/ipcore_dhcph.h
@@ -0,0 +1,201 @@
+/*!
+ * @file ipcore_dhcph.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides DHCP Header definitions of ipcore
+ */
+
+#ifndef _IPCORE_DHCPH_H
+#define _IPCORE_DHCPH_H
+
+#include "kal_public_api.h"
+
+#define IPC_BP_CHADDR_LEN 16
+#define IPC_BP_SNAME_LEN 64
+#define IPC_BP_FILE_LEN 128
+//#define IPC_BP_VEND_LEN 312+32
+
+#define IPC_BP_BOOT_REQUEST 1
+#define IPC_BP_BOOT_REPLY 2
+
+#define IPC_BP_HTYPE_ETHERNET 1
+#define IPC_BP_HTYPE_EXP_ETHERNET 2
+#define IPC_BP_HTYPE_AX25 3
+#define IPC_BP_HTYPE_PRONET 4
+#define IPC_BP_HTYPE_CHAOS 5
+#define IPC_BP_HTYPE_IEEE802 6
+#define IPC_BP_HTYPE_ARCNET 7
+
+#define IPC_BP_MAGIC_COOKIE {0x63, 0x82, 0x53, 0x63}
+
+#define IPC_BP_OPTION_PAD 0
+#define IPC_BP_OPTION_SUBNET_MASK 1
+#define IPC_BP_OPTION_ROUTER 3
+#define IPC_BP_OPTION_DOMAIN_NAME_SERVER 6
+#define IPC_BP_OPTION_HOST_NAME 12
+#define IPC_BP_OPTION_INTERFACE_MTU 26
+#define IPC_BP_OPTION_REQUESTED_IP_ADDRESS 50
+#define IPC_BP_OPTION_IP_ADDRESS_LEASE_TIME 51
+#define IPC_BP_OPTION_DHCP_MESSAGE_TYPE 53
+#define IPC_BP_OPTION_SERVER_IDENTIFIER 54
+#define IPC_BP_OPTION_PARAMETER_REQUEST_LIST 55
+#define IPC_BP_OPTION_MAXIMUM_DHCP_MESSAGE_SIZE 57
+#define IPC_BP_OPTION_RENEWAL_TIME_VALUE 58
+#define IPC_BP_OPTION_REBINDING_TIME_VALUE 59
+#define IPC_BP_OPTION_VENDOR_CLASS_IDENTIFIER 60
+#define IPC_BP_OPTION_CLIENT_IDENTIFIER 61
+#define IPC_BP_OPTION_CLIENT_FULLY_QUALIFIED_DOMAIN_NAME 81
+#define IPC_BP_OPTION_END 255
+
+#define IPC_BP_DHCP_MESSAGE_TYPE_DHCP_DISCOVER 1
+#define IPC_BP_DHCP_MESSAGE_TYPE_DHCP_OFFER 2
+#define IPC_BP_DHCP_MESSAGE_TYPE_DHCP_REQUEST 3
+#define IPC_BP_DHCP_MESSAGE_TYPE_DHCP_DECLINE 4
+#define IPC_BP_DHCP_MESSAGE_TYPE_DHCP_ACK 5
+#define IPC_BP_DHCP_MESSAGE_TYPE_DHCP_NAK 6
+#define IPC_BP_DHCP_MESSAGE_TYPE_DHCP_RELEASE 7
+#define IPC_BP_DHCP_MESSAGE_TYPE_DHCP_INFORM 8
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bootp_header {
+ kal_uint8 bp_op; // packet opcode type
+ kal_uint8 bp_htype; // hardware addr type
+ kal_uint8 bp_hlen; // hardware addr length
+ kal_uint8 bp_hops; // gateway hops
+ kal_uint32 bp_xid; // transaction ID
+ kal_uint16 bp_secs; // seconds since boot began
+ kal_uint16 bp_flags; // RFC1532 broadcazst, etc
+ ipc_ip4_addr_t bp_ciaddr; // client IP address
+ ipc_ip4_addr_t bp_yiaddr; // your IP address
+ ipc_ip4_addr_t bp_siaddr; // server IP address
+ ipc_ip4_addr_t bp_giaddr; // gateway IP address
+ kal_uint8 bp_chaddr[IPC_BP_CHADDR_LEN]; // client hardware address
+ kal_uint8 bp_sname[IPC_BP_SNAME_LEN]; // server host name
+ kal_uint8 bp_file[IPC_BP_FILE_LEN]; // boot file name
+} ipc_bootp_header_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_dhcp_message_type {
+ kal_uint8 code;
+ kal_uint8 len;
+ kal_uint8 type;
+} ipc_bp_option_dhcp_message_type_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_requested_ip_address {
+ kal_uint8 code;
+ kal_uint8 len;
+ ipc_ip4_addr_t address;
+} ipc_bp_option_requested_ip_address_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_server_identifier {
+ kal_uint8 code;
+ kal_uint8 len;
+ ipc_ip4_addr_t address;
+} ipc_bp_option_server_identifier_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_ip_address_lease_time {
+ kal_uint8 code;
+ kal_uint8 len;
+ kal_uint32 lease_time;
+} ipc_bp_option_ip_address_lease_time_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_maximum_dhcp_message_size {
+ kal_uint8 code;
+ kal_uint8 len;
+ kal_uint16 length;
+} ipc_bp_option_maximum_dhcp_message_size_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_subnet_mask {
+ kal_uint8 code;
+ kal_uint8 len;
+ ipc_ip4_addr_t subnet_mask;
+} ipc_bp_option_subnet_mask_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_router {
+ kal_uint8 code;
+ kal_uint8 len;
+ ipc_ip4_addr_t address;
+} ipc_bp_option_router_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_domain_name_server {
+ kal_uint8 code;
+ kal_uint8 len;
+ ipc_ip4_addr_t address;
+} ipc_bp_option_domain_name_server_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_renewal_time_value {
+ kal_uint8 code;
+ kal_uint8 len;
+ kal_uint32 t1_interval;
+} ipc_bp_option_renewal_time_value_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_rebinding_time_value {
+ kal_uint8 code;
+ kal_uint8 len;
+ kal_uint32 t2_interval;
+} ipc_bp_option_rebinding_time_value_t;
+PRAGMA_END_PACK_STRUCT
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_bp_option_interface_mtu {
+ kal_uint8 code;
+ kal_uint8 len;
+ kal_uint16 mtu;
+} ipc_bp_option_interface_mtu_t;
+PRAGMA_END_PACK_STRUCT
+
+#endif // _IPCORE_DHCPH_H
+
diff --git a/mcu/middleware/hif/interface/ipcore_icmph.h b/mcu/middleware/hif/interface/ipcore_icmph.h
new file mode 100644
index 0000000..50569b8
--- /dev/null
+++ b/mcu/middleware/hif/interface/ipcore_icmph.h
@@ -0,0 +1,311 @@
+/*!
+ * @file ipcore_icmph.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides ICMP Header definitions of ipcore
+ */
+
+#ifndef _IPCORE_ICMPH_H
+#define _IPCORE_ICMPH_H
+
+#include "kal_public_api.h"
+
+#define IPC_ICMP_ECHO_REPLY 0 /* Echo Reply */
+#define IPC_ICMP_ECHO_REQUEST 8 /* Echo Request */
+
+
+#define IPC_ICMP6_ECHO_REQUEST 128 /* echo request */
+#define IPC_ICMP6_ECHO_REPLY 129 /* echo reply */
+#define IPC_ICMP6_NDP_ROUTER_SOLICIT 133 /* router solicitation */
+#define IPC_ICMP6_NDP_ROUTER_ADVERT 134 /* router advertisment */
+#define IPC_ICMP6_NDP_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */
+#define IPC_ICMP6_NDP_NEIGHBOR_ADVERT 136 /* neighbor advertisment */
+#define IPC_ICMP6_NDP_REDIRECT 137 /* redirect */
+
+#define IPC_ICMP6_NDP_OPT_SOURCE_LINKADDR 1
+#define IPC_ICMP6_NDP_OPT_TARGET_LINKADDR 2
+#define IPC_ICMP6_NDP_OPT_PREFIX_INFORMATION 3
+#define IPC_ICMP6_NDP_OPT_REDIRECTED_HEADER 4
+#define IPC_ICMP6_NDP_OPT_MTU 5
+#define IPC_ICMP6_NDP_OPT_RDNSS 25
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_icmp_header {
+ kal_uint8 icmp_type; // type field
+ kal_uint8 icmp_code; // code field
+ kal_uint16 icmp_cksum; // checksum field
+ union {
+ kal_uint32 icmp_un_data32[1]; // type-specific field
+ kal_uint16 icmp_un_data16[2]; // type-specific field
+ kal_uint8 icmp_un_data8[4]; // type-specific field
+ } icmp_dataun;
+} ipc_icmp_header_t;
+PRAGMA_END_PACK_STRUCT
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_icmp_echo_header {
+ kal_uint8 icmp_type; // type field
+ kal_uint8 icmp_code; // code field
+ kal_uint16 icmp_cksum; // checksum field
+ kal_uint16 icmp_id; // identifier
+ kal_uint16 icmp_seq; // sequence
+} ipc_icmp_echo_header_t;
+PRAGMA_END_PACK_STRUCT
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_icmp6_header {
+ kal_uint8 icmp6_type; // type field
+ kal_uint8 icmp6_code; // code field
+ kal_uint16 icmp6_cksum; // checksum field
+ union {
+ kal_uint32 icmp6_un_data32[1]; // type-specific field
+ kal_uint16 icmp6_un_data16[2]; // type-specific field
+ kal_uint8 icmp6_un_data8[4]; // type-specific field
+ } icmp6_dataun;
+} ipc_icmp6_header_t;
+PRAGMA_END_PACK_STRUCT
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_icmp6_echo_header {
+ kal_uint8 icmp6_type; // type field
+ kal_uint8 icmp6_code; // code field
+ kal_uint16 icmp6_cksum; // checksum field
+ kal_uint16 icmp6_id; // identifier
+ kal_uint16 icmp6_seq; // sequence
+} ipc_icmp6_echo_header_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* router solicitation */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_router_solicit {
+ kal_uint8 icmp6_type; // type field
+ kal_uint8 icmp6_code; // code field
+ kal_uint16 icmp6_cksum; // checksum field
+ kal_uint32 reserve; // reserved
+ /* could be followed by options */
+} ipc_ndp_router_solicit_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* router advertisement */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_router_advert {
+ kal_uint8 icmp6_type; // type field
+ kal_uint8 icmp6_code; // code field
+ kal_uint16 icmp6_cksum; // checksum field
+ kal_uint8 hop_limit; // hop limit
+ kal_uint8 reserve:6,
+ is_other_stateful:1,// other stateful configuraiton flag
+ is_managed_addr:1; // managed address configuration flag
+ kal_uint16 router_lifetime; // router life time
+ kal_uint32 reachable_time; // reachable time
+ kal_uint32 retransmit_time; // retransmit timer
+ /* could be followed by options */
+} ipc_ndp_router_advert_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* neighbor solicitation */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_neighbor_solicit {
+ kal_uint8 icmp6_type; // type field
+ kal_uint8 icmp6_code; // code field
+ kal_uint16 icmp6_cksum; // checksum field
+ kal_uint32 reserve; // reserved
+ ipc_ip6_addr_t target_addr; // target address
+ /* could be followed by options */
+} ipc_ndp_neighbor_solicit_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* neighbor advertisement */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_neighbor_advert {
+ kal_uint8 icmp6_type; // type field
+ kal_uint8 icmp6_code; // code field
+ kal_uint16 icmp6_cksum; // checksum field
+ kal_uint32 reserve:29,
+ is_override:1, // override flag
+ is_solicited:1, // solicited flag
+ is_router:1; // router flag
+ ipc_ip6_addr_t target_addr; // target address
+ /* could be followed by options */
+} ipc_ndp_neighbor_advert_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* redirect */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_redirect {
+ kal_uint8 icmp6_type; // type field
+ kal_uint8 icmp6_code; // code field
+ kal_uint16 icmp6_cksum; // checksum field
+ kal_uint32 reserve; // reserved
+ ipc_ip6_addr_t target_addr; // target address
+ ipc_ip6_addr_t dst_addr; // destination address
+ /* could be followed by options */
+} ipc_ndp_redirect_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* Option Link-Layer Address */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_opt_link_layer_addr {
+ kal_uint8 type;
+ kal_uint8 len; // len = 1 for ieee 802 address
+ ipc_ieee_802_addr_t addr;
+} ipc_ndp_opt_link_layer_addr_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* Option Prefix Information */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_opt_prefix {
+ kal_uint8 type;
+ kal_uint8 len; // len = 4
+ kal_uint8 prefix_len;
+ kal_uint8 reserve1:6,
+ is_on_link:1,
+ is_autonomous:1;
+ kal_uint32 valid_lifetime;
+ kal_uint32 preferred_lifetime;
+ kal_uint32 reserve2;
+ ipc_ip6_addr_t prefix;
+} ipc_ndp_opt_prefix_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* Option MTU */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_opt_mtu {
+ kal_uint8 type;
+ kal_uint8 len; // len = 1
+ kal_uint16 reserve;
+ kal_uint32 mtu;
+} ipc_ndp_opt_mtu_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/* Option RDNSS */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ndp_opt_rdnss {
+ kal_uint8 type;
+ kal_uint8 len; // minimum 3
+ kal_uint16 reserve;
+ kal_uint32 life_time;
+ ipc_ip6_addr_t dns_addr;
+} ipc_ndp_opt_rdnss_t;
+PRAGMA_END_PACK_STRUCT
+
+static INLINE kal_uint16 ipc_icmp_cksum(ipc_icmp_header_t* pIcmp, kal_uint16 len)
+{
+ kal_uint32 cksum = 0;
+ kal_uint16 word = 0;
+ kal_uint16 i = 0;
+
+ for ( i=0; i<((len+1)&~1); i+=2 )
+ {
+ if ( i == (len -1) )
+ {
+ word = ((((kal_uint8*)pIcmp)[i] << 8) & 0xff00) + 0x00 ;
+ } else {
+ word = ((((kal_uint8*)pIcmp)[i] << 8) & 0xff00) + (((kal_uint8*)pIcmp)[i+1] & 0xff) ;
+ }
+ cksum = cksum + word;
+ }
+
+ while ( cksum >> 16 )
+ cksum = ( cksum & 0xffff ) + (cksum >> 16);
+
+ return (kal_uint16)~cksum;
+}
+
+
+static INLINE kal_uint16 ipc_icmp6_cksum(ipc_ip6_addr_t* src, ipc_ip6_addr_t* dst, kal_uint32 len, kal_uint16* data)
+{
+ kal_uint32 chksum = 0;
+ kal_uint32 i;
+ union {
+ kal_uint32 dword;
+ kal_uint16 word[2];
+ kal_uint8 byte[4];
+ } tmp;
+
+ for ( i=0; i<8; i++ )
+ {
+ chksum += src->s6_addr16[i];
+ }
+
+ for ( i=0; i<8; i++ )
+ {
+ chksum += dst->s6_addr16[i];
+ }
+
+ tmp.dword = IPC_NTOHL(len);
+ chksum += tmp.word[0];
+ chksum += tmp.word[1];
+
+ tmp.dword = 0;
+ tmp.byte[3] = IPC_IPPROTO_ICMP6;
+ chksum += tmp.word[0];
+ chksum += tmp.word[1];
+
+ for ( i=0; i<(len & ~1); i+=2 )
+ {
+ chksum += *data++;
+ }
+
+ if ( len & 1 )
+ chksum += *(kal_uint8*)data;
+
+ while ( chksum > 0xffff )
+ {
+ chksum = ( chksum & 0xffff ) + (chksum >> 16);
+ }
+
+ chksum = ~chksum & 0xffff;
+
+ return (kal_uint16)chksum;
+
+}
+
+#endif // _IPCORE_ICMPH_H
+
diff --git a/mcu/middleware/hif/interface/ipcore_iph.h b/mcu/middleware/hif/interface/ipcore_iph.h
new file mode 100644
index 0000000..1b5569c
--- /dev/null
+++ b/mcu/middleware/hif/interface/ipcore_iph.h
@@ -0,0 +1,336 @@
+/*!
+ * @file ipcore_iph.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides IP Header definitions of ipcore
+ */
+
+#ifndef _IPCORE_IPH_H
+#define _IPCORE_IPH_H
+
+#include "kal_public_api.h"
+
+#if !defined(__MTK_TARGET__) && defined(_MSC_VER) && (_MSC_VER >= 1500)
+#pragma warning( disable : 4214 )
+#endif
+
+#define IPC_IP4_VERSION 4
+#define IPC_IP6_VERSION 6
+
+#define IPC_IPPROTO_HOPOPTS 0 /* IP6 hop-by-hop options */
+#define IPC_IPPROTO_ICMP 1 /* ICMP */
+#define IPC_IPPROTO_TCP 6 /* TCP */
+#define IPC_IPPROTO_UDP 17 /* UDP */
+#define IPC_IPPROTO_ROUTING 43 /* IP6 routing header */
+#define IPC_IPPROTO_FRAGMENT 44 /* IP6 fragmentation header */
+#define IPC_IPPROTO_ESP 50 /* IP6 Encap Sec. Payload */
+#define IPC_IPPROTO_AH 51 /* IP6 Auth Header */
+#define IPC_IPPROTO_ICMP6 58 /* ICMP6 */
+#define IPC_IPPROTO_NONE 59 /* IP6 no next header */
+#define IPC_IPPROTO_DSTOPTS 60 /* IP6 destination option */
+
+#define IPC_IPPORT_BOOTPS 67 /* Bootstrap Protocol Server */
+#define IPC_IPPORT_BOOTPC 68 /* Bootstrap Protocol Client */
+
+#define IPC_EUI64_GBIT 0x01
+#define IPC_EUI64_UBIT 0x02
+
+#define IPC_IP6_IS_ADDR_UNSPECIFIED(_addr) \
+ ((*(const kal_uint32 *)(const void *)(&(_addr)->s6_addr8[0]) == 0) && \
+ (*(const kal_uint32 *)(const void *)(&(_addr)->s6_addr8[4]) == 0) && \
+ (*(const kal_uint32 *)(const void *)(&(_addr)->s6_addr8[8]) == 0) && \
+ (*(const kal_uint32 *)(const void *)(&(_addr)->s6_addr8[12]) == 0))
+
+#define IPC_SWAP16(_x) ((_x & 0xff00) >> 8 | (_x & 0x00ff) << 8)
+#define IPC_SWAP32(_x) ((_x & 0xff000000) >> 24 | \
+ (_x & 0x00ff0000) >> 8 | \
+ (_x & 0x0000ff00) << 8 | \
+ (_x & 0x000000ff) << 24)
+
+#define IPC_HTONS(_x) IPC_SWAP16(_x)
+#define IPC_HTONL(_x) IPC_SWAP32(_x)
+#define IPC_NTOHS(_x) IPC_SWAP16(_x)
+#define IPC_NTOHL(_x) IPC_SWAP32(_x)
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ieee_802_addr {
+ kal_uint8 addr[6];
+} ipc_ieee_802_addr_t;
+PRAGMA_END_PACK_STRUCT
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ip4_addr {
+ union {
+ kal_uint8 _u4_addr8[4];
+ kal_uint16 _u4_addr16[2];
+ kal_uint32 _u4_addr32;
+ } _u4_addr;
+} ipc_ip4_addr_t;
+PRAGMA_END_PACK_STRUCT
+#define s4_addr8 _u4_addr._u4_addr8
+#define s4_addr16 _u4_addr._u4_addr16
+#define s4_addr32 _u4_addr._u4_addr32
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ip6_addr {
+ union {
+ kal_uint8 _u6_addr8[16];
+ kal_uint16 _u6_addr16[8];
+ kal_uint32 _u6_addr32[4];
+ } _u6_addr;
+} ipc_ip6_addr_t;
+PRAGMA_END_PACK_STRUCT
+#define s6_addr8 _u6_addr._u6_addr8
+#define s6_addr16 _u6_addr._u6_addr16
+#define s6_addr32 _u6_addr._u6_addr32
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ip4_header {
+ kal_uint8 ip_hl:4, // header length
+ ip_ver:4; // version
+ kal_uint8 ip_tos; // type of service
+ kal_uint16 ip_len; // total length
+ kal_uint16 ip_id; // identification
+ kal_uint16 ip_off; // fragment offset field
+ kal_uint8 ip_ttl; // time to live
+ kal_uint8 ip_pro; // protocol
+ kal_uint16 ip_sum; // checksum
+ ipc_ip4_addr_t ip_src; // source address
+ ipc_ip4_addr_t ip_dst; // destination address
+} ipc_ip4_header_t;
+PRAGMA_END_PACK_STRUCT
+
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_ip6_header {
+ union {
+ kal_uint8 ip6_ver; // 4 bits version
+ kal_uint32 ip6_flow; // 20 bits of flow-ID
+ } ip6_un;
+ kal_uint16 ip6_plen; // payload length
+ kal_uint8 ip6_nxt; // next header
+ kal_uint8 ip6_hlim; // hop limit
+ ipc_ip6_addr_t ip6_src; // source address
+ ipc_ip6_addr_t ip6_dst; // destionation address
+} ipc_ip6_header_t;
+PRAGMA_END_PACK_STRUCT
+#define IPC_IP6_VERSION_OFFSET 4
+#define ip6_verion ip6_un.ip6_ver
+#define ip6_flow ip6_un.ip6_flow
+
+
+static INLINE void ipc_eui64_to_link_local(ipc_ip6_addr_t* dst)
+{
+ /* Link Local Prefix */
+ dst->s6_addr8[0] = 0xFE;
+ dst->s6_addr8[1] = 0x80;
+ /* Admin Subnet */
+ dst->s6_addr8[2] = 0x00;
+ dst->s6_addr8[3] = 0x00;
+ dst->s6_addr8[4] = 0x00;
+ dst->s6_addr8[5] = 0x00;
+ dst->s6_addr8[6] = 0x00;
+ dst->s6_addr8[7] = 0x00;
+}
+
+
+static INLINE void ipc_mac_to_eui64(ipc_ieee_802_addr_t* src, ipc_ip6_addr_t* dst)
+{
+ /* Link Local Prefix */
+ dst->s6_addr8[0] = 0x00;
+ dst->s6_addr8[1] = 0x00;
+ /* Admin Subnet */
+ dst->s6_addr8[2] = 0x00;
+ dst->s6_addr8[3] = 0x00;
+ dst->s6_addr8[4] = 0x00;
+ dst->s6_addr8[5] = 0x00;
+ dst->s6_addr8[6] = 0x00;
+ dst->s6_addr8[7] = 0x00;
+ /* Interface ID */
+ dst->s6_addr8[8] = src->addr[0];
+ dst->s6_addr8[8] &= ~IPC_EUI64_GBIT;
+ dst->s6_addr8[8] |= IPC_EUI64_UBIT;
+ dst->s6_addr8[9] = src->addr[1];
+ dst->s6_addr8[10] = src->addr[2];
+ dst->s6_addr8[11] = 0xff;
+ dst->s6_addr8[12] = 0xfe;
+ dst->s6_addr8[13] = src->addr[3];
+ dst->s6_addr8[14] = src->addr[4];
+ dst->s6_addr8[15] = src->addr[5];
+}
+
+
+static INLINE void ipc_eui64_to_mac(ipc_ip6_addr_t* src, ipc_ieee_802_addr_t* dst)
+{
+ dst->addr[0] = src->s6_addr8[8];
+ dst->addr[0] &= ~IPC_EUI64_UBIT;
+ dst->addr[1] = src->s6_addr8[9];
+ dst->addr[2] = src->s6_addr8[10];
+ dst->addr[3] = src->s6_addr8[13];
+ dst->addr[4] = src->s6_addr8[14];
+ dst->addr[5] = src->s6_addr8[15];
+}
+
+
+static INLINE void ipc_find_ipv4_data_header(ipc_ip4_header_t* pIp, kal_uint32* offset)
+{
+ *offset = pIp->ip_hl*4;
+}
+
+
+static INLINE void ipc_find_ipv6_data_header(ipc_ip6_header_t* pIp6, kal_uint8* next_header, kal_uint32* offset)
+{
+ kal_uint8 header_ext_len = 0;
+
+ /* search all next header, and find the last one */
+ *next_header = pIp6->ip6_nxt;
+ *offset = sizeof(ipc_ip6_header_t);
+ do {
+ kal_bool is_exit = KAL_FALSE;
+
+ switch ( *next_header )
+ {
+ case IPC_IPPROTO_HOPOPTS:
+ case IPC_IPPROTO_ROUTING:
+ case IPC_IPPROTO_DSTOPTS:
+ {
+ *next_header = *((kal_uint8*)pIp6 + *offset);
+ header_ext_len = *((kal_uint8*)pIp6 + *offset+1);
+ *offset = 8 * ( 1 + header_ext_len );
+ break;
+ }
+ case IPC_IPPROTO_FRAGMENT:
+ {
+ *next_header = *((kal_uint8*)pIp6 + *offset);
+ header_ext_len = 0;
+ *offset = 8;
+ break;
+ }
+ case IPC_IPPROTO_AH:
+ {
+ *next_header = *((kal_uint8*)pIp6 + *offset);
+ header_ext_len = *((kal_uint8*)pIp6 + *offset+1);
+ *offset = 4 * ( 2 + header_ext_len );
+ break;
+ }
+ case IPC_IPPROTO_NONE:
+ case IPC_IPPROTO_ESP:
+ default:
+ {
+ is_exit = KAL_TRUE;
+ break;
+ }
+ }
+
+ if ( is_exit == KAL_TRUE ) break;
+
+ } while (1);
+
+}
+
+
+static INLINE kal_uint16 ipc_ip4_cksum(ipc_ip4_header_t* pIp, kal_uint16 len)
+{
+ kal_uint32 cksum = 0;
+ kal_uint16 word = 0;
+ kal_uint32 i = 0;
+
+ for ( i=0; i<len; i+=2 )
+ {
+ word = ((((kal_uint8*)pIp)[i] << 8) & 0xff00) + (((kal_uint8*)pIp)[i+1] & 0xff) ;
+ cksum = cksum + word;
+ }
+
+ while ( cksum >> 16 )
+ cksum = ( cksum & 0xffff ) + (cksum >> 16);
+
+ return (kal_uint16)~cksum;
+}
+
+
+#define IPC_MASK_IP_VER (0xF0)
+#define IPC_IPV4_VER (0x40)
+#define IPC_IPV6_VER (0x60)
+#define IPC_MIN_IPV4_HDR_LEN (20)
+#define IPC_MIN_IPV6_HDR_LEN (40)
+#define IPC_MIN_IP_HEADER_LEN (40)
+
+#define IPC_IS_IPV4_PACKET(n) \
+ (((n) & IPC_MASK_IP_VER) == IPC_IPV4_VER)
+#define IPC_IS_IPV6_PACKET(n) \
+ (((n) & IPC_MASK_IP_VER) == IPC_IPV6_VER)
+static INLINE kal_bool ipc_swap_ip_addr(kal_uint8 *ip_hdr)
+{
+ kal_uint32 tmp;
+
+ if (IPC_IS_IPV4_PACKET(*ip_hdr)) {
+ ipc_ip4_header_t *ipv4 = (ipc_ip4_header_t *)ip_hdr;
+
+ tmp = ipv4->ip_src.s4_addr32;
+ ipv4->ip_src.s4_addr32 = ipv4->ip_dst.s4_addr32;
+ ipv4->ip_dst.s4_addr32 = tmp;
+ } else if (IPC_IS_IPV6_PACKET(*ip_hdr)) {
+ ipc_ip6_header_t *ipv6 = (ipc_ip6_header_t *)ip_hdr;
+
+ tmp = ipv6->ip6_src.s6_addr32[0];
+ ipv6->ip6_src.s6_addr32[0] = ipv6->ip6_dst.s6_addr32[0];
+ ipv6->ip6_dst.s6_addr32[0] = tmp;
+
+ tmp = ipv6->ip6_src.s6_addr32[1];
+ ipv6->ip6_src.s6_addr32[1] = ipv6->ip6_dst.s6_addr32[1];
+ ipv6->ip6_dst.s6_addr32[1] = tmp;
+
+ tmp = ipv6->ip6_src.s6_addr32[2];
+ ipv6->ip6_src.s6_addr32[2] = ipv6->ip6_dst.s6_addr32[2];
+ ipv6->ip6_dst.s6_addr32[2] = tmp;
+
+ tmp = ipv6->ip6_src.s6_addr32[3];
+ ipv6->ip6_src.s6_addr32[3] = ipv6->ip6_dst.s6_addr32[3];
+ ipv6->ip6_dst.s6_addr32[3] = tmp;
+ } else {
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+
+
+#endif // _IPCORE_IPH_H
+
diff --git a/mcu/middleware/hif/interface/ipcore_udph.h b/mcu/middleware/hif/interface/ipcore_udph.h
new file mode 100644
index 0000000..0ff957c
--- /dev/null
+++ b/mcu/middleware/hif/interface/ipcore_udph.h
@@ -0,0 +1,96 @@
+/*!
+ * @file ipcore_udph.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides UDP Header definitions of ipcore
+ */
+
+#ifndef _IPCORE_UDPH_H
+#define _IPCORE_UDPH_H
+
+#include "kal_public_api.h"
+
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _ipc_udp_header {
+ kal_uint16 udp_src_port; // udp source port
+ kal_uint16 udp_dst_port; // udp destination port
+ kal_uint16 udp_len; // udp length
+ kal_uint16 udp_sum; // udp checksum
+} ipc_udp_header_t;
+PRAGMA_END_PACK_STRUCT
+
+
+
+static INLINE kal_uint16 ipc_udp_cksum(ipc_udp_header_t* pUdp, kal_uint16 len, ipc_ip4_addr_t* ip_src, ipc_ip4_addr_t* ip_dst)
+{
+ kal_uint32 cksum = 0;
+ kal_uint16 word = 0;
+ kal_uint16 i = 0;
+
+ for (i=0; i< ((len+1)&~1); i=i+2)
+ {
+ if ( i == (len -1) )
+ {
+ word = ( (((kal_uint8*)pUdp)[i] << 8 ) & 0xff00 ) + 0x00;
+ } else {
+ word = ( (((kal_uint8*)pUdp)[i] << 8 ) & 0xff00 ) + (((kal_uint8*)pUdp)[i+1] & 0xff);
+ }
+ cksum = cksum + word;
+ }
+
+ for (i=0; i<sizeof(ipc_ip4_addr_t); i=i+2)
+ {
+ word = ( (((kal_uint8*)ip_src)[i] << 8 ) & 0xff00 ) + (((kal_uint8*)ip_src)[i+1] & 0xff);
+ cksum = cksum + word;
+ }
+
+ for (i=0; i<sizeof(ipc_ip4_addr_t); i=i+2)
+ {
+ word = ( (((kal_uint8*)ip_dst)[i] << 8 ) & 0xff00 ) + (((kal_uint8*)ip_dst)[i+1] & 0xff);
+ cksum = cksum + word;
+ }
+
+ cksum = cksum + IPC_IPPROTO_UDP +len;
+
+ while ( cksum >> 16 )
+ cksum = ( cksum & 0xffff ) + ( cksum >> 16 );
+
+ return (kal_uint16)~cksum;
+}
+
+
+#endif // _IPCORE_UDPH_H
+
diff --git a/mcu/middleware/hif/interface/ipfc_export_plugin_dl_filter.h b/mcu/middleware/hif/interface/ipfc_export_plugin_dl_filter.h
new file mode 100644
index 0000000..9f9a387
--- /dev/null
+++ b/mcu/middleware/hif/interface/ipfc_export_plugin_dl_filter.h
@@ -0,0 +1,18 @@
+#ifndef __INC_IPFC_PLUGIN_DL_FILTER
+#define __INC_IPFC_PLUGIN_DL_FILTER
+
+#include "ipfc_export_plugin_dl_filter_type.h"
+#include "kal_public_api.h"
+
+kal_bool ipfc_plugin_dl_filter_enable();
+
+void ipfc_plugin_dl_filter_query_meta_info(void** base, kal_uint16* entry_num, kal_uint32 queue_type);
+void ipfc_plugin_dl_filter_release_meta_entry(kal_uint16 rel_num, kal_uint32 queue_type);
+
+void ipfc_plugin_dl_filter_set_pn_match(kal_uint8 pdn_sim_id, kal_uint16 nc_id, kal_uint8 ipv4, kal_uint8 ipv6);
+
+kal_int32 ipfc_plugin_dl_filter_query_id_by_index(kal_uint32 ipf_index);
+kal_bool ipfc_plugin_dl_filter_take_tlb(void** buff_base, kal_uint32* max_entry_num);
+kal_bool ipfc_plugin_dl_filter_submit_tlb(kal_uint32 filter_num, kal_uint32 v6_unknow_pro_ck);
+
+#endif //__INC_IPFC_PLUGIN_DL_FILTER
diff --git a/mcu/middleware/hif/interface/ipfc_export_plugin_dl_filter_type.h b/mcu/middleware/hif/interface/ipfc_export_plugin_dl_filter_type.h
new file mode 100644
index 0000000..85f79d4
--- /dev/null
+++ b/mcu/middleware/hif/interface/ipfc_export_plugin_dl_filter_type.h
@@ -0,0 +1,13 @@
+#ifndef __INC_IPFC_PLUGIN_DL_FILTER_TYPE
+#define __INC_IPFC_PLUGIN_DL_FILTER_TYPE
+
+typedef enum _ipfc_dl_filter_queue_type
+{
+ IPFC_META_QUEUE_DL = 0,
+#if (CUR_GEN >= MD_GEN97)
+ IPFC_META_QUEUE_DL_NR,
+#endif
+ IPFC_META_QUEUE_MAX,
+} ipfc_dl_filter_queue_type;
+
+#endif //__INC_IPFC_PLUGIN_DL_FILTER_TYPE
diff --git a/mcu/middleware/hif/interface/ipfc_export_plugin_nat.h b/mcu/middleware/hif/interface/ipfc_export_plugin_nat.h
new file mode 100644
index 0000000..00db360
--- /dev/null
+++ b/mcu/middleware/hif/interface/ipfc_export_plugin_nat.h
@@ -0,0 +1,19 @@
+#ifndef __INC_IPFC_EXPORT_PLUGIN_NAT
+#define __INC_IPFC_EXPORT_PLUGIN_NAT
+
+#include "kal_public_api.h"
+
+kal_bool ipfc_plugin_nat_enable();
+
+void ipfc_plugin_nat_set_config(kal_uint32 nat_enable);
+kal_uint32 ipfc_plugin_nat_get_config();
+
+void ipfc_plugin_nat_set_public_ip(kal_uint32 ip_addr);
+kal_uint32 ipfc_plugin_nat_get_public_ip();
+
+void ipfc_plugin_nat_set_private_ip(kal_uint32 ip_addr, kal_uint32 lan_type);
+kal_uint32 ipfc_plugin_nat_get_private_ip(kal_uint32 lan_type);
+
+kal_uint32 ipfc_plugin_nat_get_rule_num();
+
+#endif
diff --git a/mcu/middleware/hif/interface/lms_api.h b/mcu/middleware/hif/interface/lms_api.h
new file mode 100644
index 0000000..219c6fd
--- /dev/null
+++ b/mcu/middleware/hif/interface/lms_api.h
@@ -0,0 +1,135 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * lms_api.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * LTM Simulation public structure and interface definition.
+ * It is used as a fork implementation of ltm_if.h.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __INC_LMS_API_H
+#define __INC_LMS_API_H
+
+#include "upcm.h"
+#include "ipcore_upcm_struct.h"
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+typedef void (*upcm_dlvr_dl_sdu_f)(kal_uint32 pdn_id, qbm_gpd* p_head, qbm_gpd* p_tail, kal_uint8 proto_id);
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+void lms_on_downlink(void* p_head, void* p_tail);
+
+void lms_rcv_ul_sdu_meta(kal_uint32 pit_start, kal_uint32 pit_end, LHIF_QUEUE_TYPE queue_type);
+
+void lms_rcv_ul_sdu(ip_type_e ip_type, kal_uint32 pdn_id, qbm_gpd *p_head, qbm_gpd *p_tail, kal_uint8 proto_id);
+
+void lms_rcv_ul_sdu_by_ebi(kal_uint32 ebi, qbm_gpd *p_head, qbm_gpd *p_tail, kal_uint8 proto_id);
+
+void lms_reg_cbk_notify_tick_source(upcm_nofify_lte_tick_f pf_notify);
+
+void lms_reg_cbk_dlvr_dl_sdu(upcm_dlvr_dl_sdu_93_f pf_dlvr_sdu);
+
+void lms_reg_cbk_dlvr_dl_sdu_legacy(upcm_dlvr_dl_sdu_f pf_dlvr_sdu);
+
+void lms_forced_sw_path_by_pdn(kal_uint8 _pdn_id_tmp, kal_bool KAL_TRUE, kal_uint8 _proto_idx);
+
+void lms_forced_sw_path_by_ebi(kal_uint8 _ebi_tmp, kal_bool KAL_TRUE, kal_uint8 _proto_idx);
+
+void lms_forced_sw_path_all(kal_bool option);
+
+#endif /* __INC_LMS_API_H */
diff --git a/mcu/middleware/hif/interface/mbim_common.h b/mcu/middleware/hif/interface/mbim_common.h
new file mode 100644
index 0000000..e4a747a
--- /dev/null
+++ b/mcu/middleware/hif/interface/mbim_common.h
@@ -0,0 +1,13 @@
+#ifndef _MBIM_COMMON_H
+#define _MBIM_COMMON_H
+
+#include "kal_public_api.h"
+
+#if !defined(__MTK_TARGET__) && defined(_MSC_VER) && (_MSC_VER >= 1500)
+#pragma warning( disable : 4214 )
+#endif
+
+
+void mbim_get_host_mac(kal_uint32 netid_if, kal_uint8* mac_addr);
+#endif // _ETHERCORE_COMMON_H
+
diff --git a/mcu/middleware/hif/interface/mbim_data_path_trace_utmd.json b/mcu/middleware/hif/interface/mbim_data_path_trace_utmd.json
new file mode 100644
index 0000000..caae09a
--- /dev/null
+++ b/mcu/middleware/hif/interface/mbim_data_path_trace_utmd.json
@@ -0,0 +1,361 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "MBIM_L2",
+ "stringTranslationDefs": [],
+ "startGen": "Legacy",
+ "endGen": "Legacy",
+ "traceClassDefs": [
+ {
+ "MBIM_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "MBIM_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "MBIM_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "MBIM_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "MBIM_RB_DOWNLINK": {
+ "format": "[MBIM] mbim_rb_downlink(): queue_no(%d), did(%xl), pkt_num(%d), seg_num(%d)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_DL_ENUMERATION": {
+ "format": "[MBIM] mbim_rb_downlink(): dl enumeration: i(%d), did(%xl), curr_sit(%xl), hif_type(%d), handled_seg_cnt(%d), seg_num(%d), agg_cnt(%d)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_DL_MULTI_PACKET": {
+ "format": "[MBIM] mbim_rb_downlink(): dl multi-packet transfer in DID_SIT: i(%d), curr_sit(%ul), address(%xl), length(%ul)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_DL_AGG_CONTINUE_1": {
+ "format": "[MBIM] mbim_rb_downlink(): add aggregation msg: i(%d), agg_cnt(%d), header_drb_idx(%d), header_len(%ul), curr_total_len(%ul)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_DL_AGG_CONTINUE_2": {
+ "format": "[MBIM] mbim_rb_downlink(): end to add aggregation msg: i(%d), agg_cnt(%d), payload_len(%ul), header_addr(%xl), sit_cnt(%d), submit_drb_cnt(%d), last_total_len(%ul)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_DL_AGG_FIRST_NDP_1": {
+ "format": "[MBIM] mbim_rb_downlink(): add first NDP header: i(%d), agg_cnt(%d), header_len(%ul), curr_total_len(%ul)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_DL_AGG_FIRST_NDP_2": {
+ "format": "[MBIM] mbim_rb_downlink(): end to add first NDP header: i(%d), payload_len(%ul), ndp_drb_idx(%d), header_len(%ul), sit_cnt(%d), submit_drb_cnt(%d)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_DL_AGG_END_EOL": {
+ "format": "[MBIM] mbim_rb_downlink(): aggregation done: i(%d), trans_cnt(%d), agg_cnt(%d), handled_seg_cnt(%d), submit_drb_cnt(%d)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_UL_ENUMERATION": {
+ "format": "[MBIM] mbim_rb_bulk_out_complete(): ul enumeration: curr_idx(%d), ul_meta(%xl), qtype(%d), net_type(%d), next_idx(%d), end_of_list(%d)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_LOOPBACK_ENUMERATION": {
+ "format": "[MBIM] mbim_rb_process_loopback(): loopback enumeration: curr_idx(%d), ul_meta(%xl), net_type(%d), next_idx(%d), end_of_list(%d)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_LOOPBACK_DL_MSG_INFO": {
+ "format": "[MBIM] mbim_rb_loopback_downlink(): payload_drb_idx(%d), payload_prb(%xl), payload_len(%d)",
+ "traceClass": "MBIM_M"
+ }
+ },
+ {
+ "MBIM_RB_START_DATA_PATH_SUCCESS": {
+ "format": "[MBIM][CLEAR STALL] mbim_on_bulk_stall success: class id = %ul, BULK type =%ul, queue num = %ul, is stall = %ul",
+ "traceClass": "MBIM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_START_DATA_PATH_FAIL": {
+ "format": "[MBIM][CLEAR STALL] mbim_on_bulk_stall fail: class id = %ul, BULK type =%ul, queue num = %ul, is stall = %ul",
+ "traceClass": "MBIM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_ENUMERATION1": {
+ "format": "[MBIM] mbim_rb_bulk_out_complete(): ul enumeration 1: rel_idx(%ul), start_idx(%ul), end_idx(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_ENUMERATION2": {
+ "format": "[MBIM] mbim_rb_bulk_out_complete(): ul enumeration 2: curr_idx(%ul), xit(%xl), next_idx(%ul), end_of_list(%d)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_DISCARD_ON_INVALID_NTH": {
+ "format": "[MBIM] mbim_rb_cal_header_len(): NTB Header: signature(%ul), header_length(%ul), sequence(%ul),block_length(%ul),fp_index(%ul)",
+ "traceClass": "MBIM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_DISCARD_ON_INVALID_NDP": {
+ "format": "[MBIM] mbim_rb_cal_header_len(): NDP Header: signature(%ul), length(%ul), next_fp_index(%ul),datagrams[0].index(%ul),datagrams[0].length(%ul) ,block_length(%ul)",
+ "traceClass": "MBIM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_DISCARD_ON_UNALIGN_NDP": {
+ "format": "[MBIM] mbim_rb_cal_header_len(): NDP Header address: (%ul)",
+ "traceClass": "MBIM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_DISCARD_ON_UNALIGN_DATAGRAM": {
+ "format": "[MBIM] mbim_rb_cal_header_len(): DATAGRAM address: (%ul)",
+ "traceClass": "MBIM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_DISCARD_ON_INVALID_NDP_1": {
+ "format": "[MBIM] mbim_rb_cal_header_len(): NDP Header: next_fp_index(%ul),datagrams[1].index(%ul),datagrams[1].length(%ul)",
+ "traceClass": "MBIM_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_ENQUEUE_EMPTY_DID": {
+ "format": "[MBIM][USB_UL] mbim_rb_ul_meta_enqueue_lhif_ul_queue_did(): DO NOT enqueue empty DID. start_idx(%d), end_idx(%d), rel_idx(%d), entry_num(%d)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_BULKOUT_COMPLETE": {
+ "format": "[MBIM][USB_UL] mbim_rb_bulk_out_complete(): rel_idx=%ul, start_idx=%ul, end_idx=%ul, curr_net_type=%ul",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_DONE": {
+ "format": "[MBIM] mbim_rb_bulk_out_complete(): ul process done. rel_idx(%ul), start_idx(%ul), end_idx(%ul), total_payload_len(%ul)",
+ "traceClass": "MBIM_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_UL_PROCESS_PACKET": {
+ "format": "[MBIM] mbim_rb_cal_header_len(): ul process IP packet. NTB sequence(%ul), session ID(%ul),packet length(%ul)",
+ "traceClass": "MBIM_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DOWNLINK": {
+ "format": "[MBIM] mbim_rb_downlink(): queue_no(%d), did(%xl), pkt_num(%d), seg_num(%d)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_ENUMERATION": {
+ "format": "[MBIM] mbim_rb_downlink_auto_header(): dl enumeration: curr_idx(%ul), did(%xl), curr_sit(%xl), hif_type(%d), handled_seg_cnt(%d), seg_num(%d), total_len(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_USB_PACKET": {
+ "format": "[MBIM] mbim_rb_downlink_auto_header(): usb dl packet: curr_idx(%ul), data_addr(%xl), data_len(%ul), is_first_pkt(%d), is_last_pkt(%d), ethc_drb_fh_idx(%d)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_AGG_NO_ROOM_FOR_NEXT": {
+ "format": "[MBIM] mbim_rb_downlink_auto_header(): no room to aggregate next msg: total_len(%ul)+curr_msg_len(%ul)+next_msg_len(%ul)=%ul > dl_max_trans_size(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_ADD_PACKET_HEADER_DRB": {
+ "format": "[MBIM] mbim_rb_add_payload_drb_auto_header(): add packet header drb, is_prb(%d), queue_no(%d), first_idx(%ul), additional_idx(%ul), padding_len(%ul), payload_len(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_AGG_CONTINUE_1": {
+ "format": "[MBIM] mbim_rb_downlink_auto_header(): add aggregation msg(1): curr_msg_len(%ul), curr_payload_len(%ul), ethc_drb_fh_len(%ul), total_len(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_AGG_CONTINUE_2": {
+ "format": "[MBIM] mbim_rb_downlink_auto_header(): add aggregation msg(2): agg_cnt(%d), sit_cnt(%d), submit_drb_cnt(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_ADD_PAYLOAD_DRB_1": {
+ "format": "[MBIM] mbim_rb_add_payload_drb_auto_header(): add payload drb(1), is_prb(%d), queue_no(%d), first_idx(%ul), additional_idx(%ul), p_data(%xl), len(%ul), seg_num(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_ADD_PAYLOAD_DRB_2": {
+ "format": "[MBIM] mbim_rb_add_payload_drb_auto_header(): add payload drb(2), create 1st drb, is_prb(%d), first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), phyAddr(%xl), phyLen(%ul), submit_urb_cnt(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_ADD_PAYLOAD_DRB_3": {
+ "format": "[MBIM] mbim_rb_add_payload_drb_auto_header(): add payload drb(3), 1st drb, set fixed header idx, is_prb(%d), first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), ethc_drb_fh_idx(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_ADD_PAYLOAD_DRB_4": {
+ "format": "[MBIM] mbim_rb_add_payload_drb_auto_header(): add payload drb(4), corss-page case, (%d)drb, first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), phyAddr(%xl), phyLen(%ul), submit_urb_cnt(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_ADD_PAYLOAD_DRB_5": {
+ "format": "[MBIM] mbim_rb_add_payload_drb_auto_header(): add payload drb(5), last drb, set padding len, is_prb(%d), first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), padding_len(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_ADD_PAYLOAD_DRB_6": {
+ "format": "[MBIM] mbim_rb_add_payload_drb_auto_header(): add payload drb(6), set EOT, first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_DL_ADD_HEADERS_BEGIN": {
+ "format": "[MBIM] mbim_rb_add_headers(): payload_len(%ul), is_first_pkt(%d), is_last_pkt(%d), last_padding(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_DL_CAL_HEADER_PADDING": {
+ "format": "[MBIM] mbim_rb_calculate_header_padding(): payload_len(%ul), is_last_pkt(%d), curr_padding(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_DL_CASE1": {
+ "format": "[MBIM] mbim_rb_add_headers(): Case 1",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_DL_CASE2": {
+ "format": "[MBIM] mbim_rb_add_headers(): Case 2: %d, curr_padding(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_DL_ADD_MBIM_PKT_MSG": {
+ "format": "[MBIM] mbim_rb_add_headers(): MBIM_PACKET_MSG added: message_length(%d), data_offset(%ul), data_length(%ul), msg(%xl)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_SUBMIT_DRB": {
+ "format": "[MBIM][USB_DL] mbim_rb_downlink_auto_header(): submit DRB to USBCore: queue_no(%d), submit_urb_cnt(%ul)",
+ "traceClass": "MBIM_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_RB_AH_DL_SUBMIT_DONE": {
+ "format": "[MBIM] mbim_rb_downlink_auto_header(): queue_no(%d), did(%xl), pkt_num(%d), seg_num(%d), submit_urb_cnt(%ul), total_payload_len(%ul)",
+ "traceClass": "MBIM_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "MBIM_LOOPBACK_DL_SUBMIT_DRB": {
+ "format": "[MBIM] mbim_rb_loopback_downlink(): submit DRB to USBCore: queue_no(%d), submit_urb_cnt(%d)",
+ "traceClass": "MBIM_M"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_MBIM"
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/interface/ndpc_common.h b/mcu/middleware/hif/interface/ndpc_common.h
new file mode 100644
index 0000000..9bd67c0
--- /dev/null
+++ b/mcu/middleware/hif/interface/ndpc_common.h
@@ -0,0 +1,58 @@
+/*!
+ * @file ndpc_common.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides interface of ndpc ( NDP Client )
+ */
+
+#ifndef _NDPC_COMMON_H
+#define _NDPC_COMMON_H
+
+
+/*!
+ * @brief ndpc init function
+ */
+void ndpc_init(void);
+
+
+/*!
+ * @brief ndpc main function
+ */
+void ndpc_main(ilm_struct* ilm);
+
+
+#endif // _NDPC_COMMON_H
+
diff --git a/mcu/middleware/hif/interface/nmu_data_path_trace_utmd.json b/mcu/middleware/hif/interface/nmu_data_path_trace_utmd.json
new file mode 100644
index 0000000..3b94f28
--- /dev/null
+++ b/mcu/middleware/hif/interface/nmu_data_path_trace_utmd.json
@@ -0,0 +1,257 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "NMU_L2",
+ "stringTranslationDefs": [],
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "NMU_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline",
+ "Sensitive"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "NMU_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "NMU_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "NMU_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "NMU_SET_PROPERTY": {
+ "format": "[NMU] nmu_set_property(): set property %d, len(%ul).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_GET_PROPERTY": {
+ "format": "[NMU] nmu_get_property(): get property %d, len(%ul).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_HOST_MAC": {
+ "format": "[NMU] nmu_set_host_mac(): set eth%d host_mac to 0-1(%xl) 2-5(%xl)",
+ "traceClass": "NMU_L"
+ }
+ },
+ {
+ "NMU_UTIL_GET_HOST_MAC": {
+ "format": "[NMU] nmu_get_host_mac(): get eth%d host_mac to 0-1(%xl) 2-5(%xl)",
+ "traceClass": "NMU_L"
+ }
+ },
+ {
+ "NMU_UTIL_SET_GW_MAC": {
+ "format": "[NMU] nmu_set_gateway_mac(): set eth%d gateway_mac to 0-1(%xl) 2-5(%xl)",
+ "traceClass": "NMU_L"
+ }
+ },
+ {
+ "NMU_UTIL_GET_GW_MAC": {
+ "format": "[NMU] nmu_get_gateway_mac(): get eth%d gateway_mac to 0-1(%xl) 2-5(%xl)",
+ "traceClass": "NMU_L"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_TX_PKT_CNT": {
+ "format": "[NMU] nmu_set_eth_tx_pkt_cnt(): set eth %d tx_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_TX_PKT_CNT": {
+ "format": "[NMU] nmu_add_eth_tx_pkt_cnt(): add eth %d tx_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_TX_PKT_CNT": {
+ "format": "[NMU] nmu_get_eth_tx_pkt_cnt(): get eth %d tx_pkt_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_RX_PKT_CNT": {
+ "format": "[NMU] nmu_set_eth_rx_pkt_cnt(): set eth %d rx_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_RX_PKT_CNT": {
+ "format": "[NMU] nmu_add_eth_rx_pkt_cnt(): add eth %d rx_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_RX_PKT_CNT": {
+ "format": "[NMU] nmu_get_eth_rx_pkt_cnt(): get eth %d rx_pkt_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_TX_BYTE_CNT": {
+ "format": "[NMU] nmu_set_eth_tx_byte_cnt(): set eth%d tx_byte_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_TX_BYTE_CNT": {
+ "format": "[NMU] nmu_add_eth_tx_byte_cnt(): add eth%d tx_byte_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_TX_BYTE_CNT": {
+ "format": "[NMU] nmu_get_eth_tx_byte_cnt(): get eth%d tx_byte_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_RX_BYTE_CNT": {
+ "format": "[NMU] nmu_set_eth_rx_byte_cnt(): set eth%d rx_byte_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_RX_BYTE_CNT": {
+ "format": "[NMU] nmu_add_eth_rx_byte_cnt(): add eth%d rx_byte_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_RX_BYTE_CNT": {
+ "format": "[NMU] nmu_get_eth_rx_byte_cnt(): get eth%d rx_byte_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_TX_ERROR_PKT_CNT": {
+ "format": "[NMU] nmu_set_eth_tx_error_pkt_cnt(): set eth%d tx_error_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_TX_ERROR_PKT_CNT": {
+ "format": "[NMU] nmu_add_eth_tx_error_pkt_cnt(): add eth%d tx_error_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_TX_ERROR_PKT_CNT": {
+ "format": "[NMU] nmu_get_eth_tx_error_pkt_cnt(): get eth%d tx_error_pkt_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_RX_ERROR_PKT_CNT": {
+ "format": "[NMU] nmu_set_eth_rx_error_pkt_cnt(): set eth%d rx_error_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_RX_ERROR_PKT_CNT": {
+ "format": "[NMU] nmu_add_eth_rx_error_pkt_cnt(): add eth%d rx_error_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_RX_ERROR_PKT_CNT": {
+ "format": "[NMU] nmu_get_eth_rx_error_pkt_cnt(): get eth%d rx_error_pkt_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_TX_DROP_PKT_CNT": {
+ "format": "[NMU] nmu_set_eth_tx_drop_pkt_cnt(): set eth%d tx_drop_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_TX_DROP_PKT_CNT": {
+ "format": "[NMU] nmu_add_eth_tx_drop_pkt_cnt(): add eth%d tx_drop_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_TX_DROP_PKT_CNT": {
+ "format": "[NMU] nmu_get_eth_tx_drop_pkt_cnt(): get eth%d tx_drop_pkt_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_RX_DROP_PKT_CNT": {
+ "format": "[NMU] nmu_set_eth_rx_drop_pkt_cnt(): set eth%d rx_drop_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_RX_DROP_PKT_CNT": {
+ "format": "[NMU] nmu_add_eth_rx_drop_pkt_cnt(): add eth%d rx_drop_pkt_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_RX_DROP_PKT_CNT": {
+ "format": "[NMU] nmu_get_eth_rx_drop_pkt_cnt(): get eth%d rx_drop_pkt_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_SET_ETH_RX_FRAME_ALIGN_ERROR_CNT": {
+ "format": "[NMU] nmu_set_eth_rx_frame_align_error_cnt(): set eth%d rx_frame_align_error_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_ADD_ETH_RX_FRAME_ALIGN_ERROR_CNT": {
+ "format": "[NMU] nmu_add_eth_rx_frame_align_error_cnt(): add eth%d rx_frame_align_error_cnt to u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ },
+ {
+ "NMU_UTIL_GET_ETH_RX_FRAME_ALIGN_ERROR_CNT": {
+ "format": "[NMU] nmu_get_eth_rx_frame_align_error_cnt(): get eth%d rx_frame_align_error_cnt u64(%xl %xl).",
+ "traceClass": "NMU_H"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_NMU"
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/interface/rndis_data_path_trace_utmd.json b/mcu/middleware/hif/interface/rndis_data_path_trace_utmd.json
new file mode 100644
index 0000000..79f08b4
--- /dev/null
+++ b/mcu/middleware/hif/interface/rndis_data_path_trace_utmd.json
@@ -0,0 +1,660 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "RNDIS_L2",
+ "stringTranslationDefs": [],
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "RNDIS_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "RNDIS_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "RNDIS_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "RNDIS_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "DesignInfo"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "RNDIS_DL_GPD_ADD_HEADERS_BEGIN": {
+ "format": "[RNDIS] rndis_add_headers(): eth_length(%d) is_first_gpd(%ul) is_last_gpd(%ul) last_padding(%ul) data_ptr(%xl)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_GPD_WITH_VLAN_PRI": {
+ "format": "[RNDIS] rndis_add_headers(): eth_length(%d) with vlan_pri_info: %2xl %2xl %2xl %2xl",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_GPD_PPI_VLAN_PRI_ADDED": {
+ "format": "[RNDIS] rndis_add_headers(): eth_length(%d) add ppi for vid: %3xl pri: %xl",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_GPD_DATA_OFFSET": {
+ "format": "[RNDIS] rndis_add_headers(): data_offset: %d",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_GPD_CASE1": {
+ "format": "[RNDIS] rndis_add_headers(): Case 1, last_padding(%d)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_GPD_CASE2": {
+ "format": "[RNDIS] rndis_add_headers(): Case 2.%d last_padding(%l)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_GPD_ADD_RNDIS_PKT_MSG": {
+ "format": "[RNDIS] rndis_add_headers(): RNDIS_PACKET_MSG added: message_length: %d, data_offset: %ul, data_length: %ul, data_ptr: %xl",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_IOR_ENUMERATION": {
+ "format": "[RNDIS] rndis_on_downlink(): netif_id(%d) curr_ior(%xl) next_ior(%xl) first_ior(%xl)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_GPD_ENUMERATION": {
+ "format": "[RNDIS] rndis_on_downlink(): netif_id(%d) curr_gpd: %xl, next_gpd: %xl, first_gpd: %xl, last_gpd: %xl",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_SPD_SINGLE_PKT_BEGIN": {
+ "format": "[RNDIS] rndis_process_tx_spd(): Begin DL single packet transfer in SPD: spd_entry_num(%d), spd1_header_len(%ul), curr_gpd(%xl)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_SPD_SINGLE_PKT_END": {
+ "format": "[RNDIS] rndis_process_tx_spd(): End DL single packet transfer in SPD: spd_entry_num(%d), total_header_len(%ul), total_data_len(%ul), flush_len(%ul)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_SPD_MULTI_PKT_BEGIN": {
+ "format": "[RNDIS] rndis_process_tx_spd(): Begin DL multi packet transfer in SPD: spd_entry_num(%d), total_payload_len(%ul), curr_gpd(%xl)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_SPD_MULTI_PKT_END": {
+ "format": "[RNDIS] rndis_process_tx_spd(): End DL multi packet transfer in SPD: spd_entry_num(%d), total_header_len(%ul), total_data_len(%ul), flush_len(%ul)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_SPD_ADD_RNDIS_PKT_MSG": {
+ "format": "[RNDIS] rndis_add_headers(): RNDIS_PACKET_MSG added: message_length: %d, data_length: %ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_AGG_CHECK_ROOM_FOR_NEXT": {
+ "format": "[RNDIS] rndis_on_downlink(): checking room for next msg: is_first_gpd: %d, is_last_gpd: %ul, last_padding: %ul, total_len: %ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_AGG_NO_ROOM_FOR_NEXT": {
+ "format": "[RNDIS] rndis_on_downlink(): no room to aggregate next msg: total_len(%d)+curr_msg_len(%ul)+next_msg_len(%ul)=%ul > dl_max_trans_size(%ul)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_ADD_HEADER": {
+ "format": "[RNDIS] rndis_on_downlink(): add RNDIS headers => curr_msg_len: %d total_len: %ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_AGG_END_NORMAL": {
+ "format": "[RNDIS] rndis_on_downlink(): aggregation ends normally, netif_id(%d)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_AGG_END_AND_RESTART": {
+ "format": "[RNDIS] rndis_on_downlink(): end this aggregation and restart it from next msg, netif_id(%d)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_SUBMIT_IOR_NG": {
+ "format": "[RNDIS] rndis_on_downlink(): submit IOR, dl_gpd_num=%d, dl_pkt_num=%ul to usbcore because usb_state is not ready. ior=%xl, next_ior=%xl, first_gpd=%xl, last_gpd=%xl",
+ "traceClass": "RNDIS_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_START_DP_CONNECTED": {
+ "format": "[RNDIS] set start data path indicate CONNECTED, netif_id(%d)",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_START_DP_RETRY_TIMEOUT": {
+ "format": "[RNDIS] start data path retry timer callback, netif_id(%d)",
+ "traceClass": "RNDIS_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_START_DP_RETRY_TIMER": {
+ "format": "[RNDIS] set start data path retry timer, netif_id(%d)",
+ "traceClass": "RNDIS_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_PPI_IN_FIRST_BUF": {
+ "format": "[RNDIS] PPI case 1, ppi_offset: %d, ppi_length: %ul <= 1st buf length: %ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_PPI_RECORD": {
+ "format": "[RNDIS] PPI size(%d), type(%ul), offset(%ul)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_PPI_MATCHED": {
+ "format": "[RNDIS] PPI matched, ppi_length(%d)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_PPI_VLAN_PRI_FOUND": {
+ "format": "[RNDIS] PPI vlan_pri_info: %d, vid: %3xl, pri:%xl",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_PPI_NOT_MATCHED": {
+ "format": "[RNDIS] PPI NOT matched, ppi_type(%d)",
+ "traceClass": "RNDIS_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_PPI_CROSS_BUF": {
+ "format": "[RNDIS] PPI case 2, ppi_offset: %d, ppi_length: %ul > 1st buf length: %ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_STRIP_PKT_MSG": {
+ "format": "[RNDIS] rndis_strip_off_headers(): msg_length:%d, data_offset:%ul, gpd:%xl",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_STRIP_PADDING_BD_CASE": {
+ "format": "[RNDIS] rndis_strip_off_headers(): BD list case, strip off pendding bytes:%d, curr desc is EOL:%ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_FREE_PADDING_BD": {
+ "format": "[RNDIS] rndis_strip_off_headers(): free padding BD, data_len:%d, is_eol:%ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_STRIP_PADDING_GPD_CASE": {
+ "format": "[RNDIS] rndis_strip_off_headers(): GPD case, strip off pendding bytes, MSG length:%d Previous GPD data length:%ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_RELOAD_BY_START_DATA_PATH_REQ": {
+ "format": "[RNDIS] rndis_reload_ul_buffers() called by MSG_ID_RNDIS_START_DATA_PATH_REQ, netif_id(%d)",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_GPD_SUBMITTED": {
+ "format": "[RNDIS] UL GPD submitted, in HIF: %d",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_BULKOUT_EMPTY_IOR": {
+ "format": "[RNDIS] rndis_on_bulk_out_complete(): empty IOR => drop it, num_gpd(%d)",
+ "traceClass": "RNDIS_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_BUF_DOWNLINK": {
+ "format": "[RNDIS] rndis_buf_downlink(): queue_no(%d), payload(%xl), payload_len(%d)",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_BUF_DL_MSG_INFO": {
+ "format": "[RNDIS] rndis_buf_downlink(): header_drb_idx(%d), payload_drb_idx(%d), header_addr(%xl), msg_len(%d), payload_prb(%xl), payload_len(%d)",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_BUF_DL_SUBMIT_DRB": {
+ "format": "[RNDIS] rndis_buf_downlink(): submit DRB to USBCore: queue_no(%d), submit_urb_cnt(%ul)",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DOWNLINK": {
+ "format": "[RNDIS] rndis_rb_downlink(): queue_no(%d), did(%xl), pkt_num(%d), seg_num(%d)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_ENUMERATION": {
+ "format": "[RNDIS] rndis_rb_downlink(): dl enumeration: curr_idx(%d), did(%xl), curr_sit(%xl), hif_type(%d), handled_seg_cnt(%d), seg_num(%d), total_len(%d)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_USB_PACKET": {
+ "format": "[RNDIS] rndis_rb_downlink(): usb dl packet: curr_idx(%d), data_addr(%xl), data_len(%ul), is_first_pkt(%d), is_last_pkt(%d), last_padding(%d), ethc_drb_fh_idx(%d)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_AGG_NO_ROOM_FOR_NEXT": {
+ "format": "[RNDIS] rndis_rb_downlink(): no room to aggregate next msg: total_len(%d)+curr_msg_len(%ul)+next_msg_len(%ul)=%ul > dl_max_trans_size(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_AGG_CONTINUE_1": {
+ "format": "[RNDIS] rndis_rb_downlink(): add aggregation msg(1): header_drb_idx(%d), header_addr(%xl), curr_msg_len(%ul), curr_payload_len(%ul), ethc_drb_fh_len(%ul), total_len(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_AGG_CONTINUE_2": {
+ "format": "[RNDIS] rndis_rb_downlink(): add aggregation msg(2): header_drb_idx(%d), agg_cnt(%d), sit_cnt(%d), submit_drb_cnt(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_ADD_PAYLOAD_DRB_1": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb(): add payload drb(1), queue_no(%d), first_idx(%ul), additional_idx(%ul), p_data(%xl), len(%ul), seg_num(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_ADD_PAYLOAD_DRB_2": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb(): add payload drb(2), create 1st prb, first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), phyAddr(%xl), phyLen(%ul), submit_urb_cnt(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_ADD_PAYLOAD_DRB_3": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb(): add payload drb(3), 1st prb, set fixed header idx, first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), ethc_drb_fh_idx(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_ADD_PAYLOAD_DRB_4": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb(): add payload drb(4), corss-page case, 2nd prb, first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), phyAddr(%xl), phyLen(%ul), submit_urb_cnt(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_ADD_PAYLOAD_DRB_5": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb(): add payload drb(5), set EOT, first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_BUF_AH_DOWNLINK": {
+ "format": "[RNDIS] rndis_buf_downlink_auto_header(): queue_no(%d), payload(%xl), payload_len(%d)",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_BUF_AH_DL_MSG_INFO": {
+ "format": "[RNDIS] rndis_buf_downlink_auto_header(): payload_drb_idx(%d), payload_prb(%xl), payload_len(%d)",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_BUF_AH_DL_SUBMIT_DRB": {
+ "format": "[RNDIS] rndis_buf_downlink_auto_header(): submit DRB to USBCore: queue_no(%d), submit_urb_cnt(%ul)",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DOWNLINK": {
+ "format": "[RNDIS] rndis_rb_downlink_auto_header(): queue_no(%d), did(%xl), pkt_num(%d), seg_num(%d)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_ENUMERATION": {
+ "format": "[RNDIS] rndis_rb_downlink_auto_header(): dl enumeration: curr_idx(%ul), did(%xl), curr_sit(%xl), hif_type(%d), handled_seg_cnt(%d), seg_num(%d), total_len(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_USB_PACKET": {
+ "format": "[RNDIS] rndis_rb_downlink_auto_header(): usb dl packet: curr_idx(%ul), data_addr(%xl), data_len(%ul), is_first_pkt(%d), is_last_pkt(%d), ethc_drb_fh_idx(%d)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_AGG_NO_ROOM_FOR_NEXT": {
+ "format": "[RNDIS] rndis_rb_downlink_auto_header(): no room to aggregate next msg: total_len(%ul)+curr_msg_len(%ul)+next_msg_len(%ul)=%ul > dl_max_trans_size(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_ADD_PACKET_HEADER_DRB": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb_auto_header(): add packet header drb, is_prb(%d), queue_no(%d), first_idx(%ul), additional_idx(%ul), padding_len(%ul), payload_len(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_AGG_CONTINUE_1": {
+ "format": "[RNDIS] rndis_rb_downlink_auto_header(): add aggregation msg(1): curr_msg_len(%ul), curr_payload_len(%ul), ethc_drb_fh_len(%ul), total_len(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_AGG_CONTINUE_2": {
+ "format": "[RNDIS] rndis_rb_downlink_auto_header(): add aggregation msg(2): agg_cnt(%d), sit_cnt(%d), submit_drb_cnt(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_ADD_PAYLOAD_DRB_1": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb_auto_header(): add payload drb(1), is_prb(%d), queue_no(%d), first_idx(%ul), additional_idx(%ul), p_data(%xl), len(%ul), seg_num(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_ADD_PAYLOAD_DRB_2": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb_auto_header(): add payload drb(2), create 1st drb, is_prb(%d), first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), phyAddr(%xl), phyLen(%ul), submit_urb_cnt(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_ADD_PAYLOAD_DRB_3": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb_auto_header(): add payload drb(3), 1st drb, set fixed header idx, is_prb(%d), first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), ethc_drb_fh_idx(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_ADD_PAYLOAD_DRB_4": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb_auto_header(): add payload drb(4), corss-page case, (%d)drb, first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), phyAddr(%xl), phyLen(%ul), submit_urb_cnt(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_ADD_PAYLOAD_DRB_5": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb_auto_header(): add payload drb(5), last drb, set padding len, is_prb(%d), first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul), padding_len(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_ADD_PAYLOAD_DRB_6": {
+ "format": "[RNDIS] rndis_rb_add_payload_drb_auto_header(): add payload drb(6), set EOT, first_idx(%ul), additional_idx(%ul), payload_drb_idx(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_ADD_HEADERS_BEGIN": {
+ "format": "[RNDIS] rndis_rb_add_headers(): payload_len(%ul), is_first_pkt(%d), is_last_pkt(%d), last_padding(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_CAL_HEADER_PADDING": {
+ "format": "[RNDIS] rndis_rb_calculate_header_padding(): payload_len(%ul), is_last_pkt(%d), curr_padding(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_CASE1": {
+ "format": "[RNDIS] rndis_rb_add_headers(): Case 1",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_CASE2": {
+ "format": "[RNDIS] rndis_rb_add_headers(): Case 2: %d, curr_padding(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_ADD_RNDIS_PKT_MSG": {
+ "format": "[RNDIS] rndis_rb_add_headers(): RNDIS_PACKET_MSG added: message_length(%d), data_offset(%ul), data_length(%ul), msg(%xl)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_UL_ENUMERATION1": {
+ "format": "[RNDIS] rndis_rb_bulk_out_complete(): ul enumeration 1: rel_idx(%ul), start_idx(%ul), end_idx(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_UL_ENUMERATION2": {
+ "format": "[RNDIS] rndis_rb_bulk_out_complete(): ul enumeration 2: curr_idx(%ul), xit(%xl), next_idx(%ul), end_of_list(%d)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_UL_DONE": {
+ "format": "[RNDIS] rndis_rb_bulk_out_complete(): ul process done. rel_idx(%ul), start_idx(%ul), end_idx(%ul), total_payload_len(%ul)",
+ "traceClass": "RNDIS_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_UL_STRIP_PKT_MSG": {
+ "format": "[RNDIS] rndis_rb_strip_off_headers(): msg_length(%d), data_length(%ul), data_offset(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_UL_CAL_HEADER_LEN": {
+ "format": "[RNDIS] rndis_rb_cal_header_len(): msg_length(%d), data_length(%ul), data_offset(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_DL_SUBMIT_IOR": {
+ "format": "[RNDIS][USB_DL] rndis_on_downlink(): submit IOR, dl_gpd_num=%d, dl_pkt_num=%ul to usbcore. ior=%xl, next_ior=%xl, first_gpd=%xl, last_gpd=%xl",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_ALLOC_GPD": {
+ "format": "[RNDIS][USB_UL_RELOAD] rndis_reload_ul_buffers(): usb_ul_gpd_want_allocate=%d, usb_ul_gpd_to_allocate=%ul, usb_ul_gpd_in_hif=%ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_UL_BULKOUT_COMPLETE": {
+ "format": "[RNDIS][USB_UL] rndis_on_bulk_out_complete(): usb_ul_gpd_received=%d, usb_ul_gpd_in_hif=%ul",
+ "traceClass": "RNDIS_M",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_DL_SUBMIT_DRB": {
+ "format": "[RNDIS][USB_DL] rndis_rb_downlink(): submit DRB to USBCore: queue_no(%d), submit_urb_cnt(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_SUBMIT_DRB": {
+ "format": "[RNDIS][USB_DL] rndis_rb_downlink_auto_header(): submit DRB to USBCore: queue_no(%d), submit_urb_cnt(%ul)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_AH_DL_SUBMIT_DONE": {
+ "format": "[RNDIS] rndis_rb_downlink_auto_header(): queue_no(%d), did(%xl), pkt_num(%d), seg_num(%d), submit_urb_cnt(%ul), total_payload_len(%ul)",
+ "traceClass": "RNDIS_H",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_UL_BULKOUT_COMPLETE": {
+ "format": "[RNDIS][USB_UL] rndis_rb_bulk_out_complete(): usb_ul_pkt_cnt=%ul, usb_ul_byte_cnt=%ul, usb_ul_error_pkt_cnt=%ul, usb_ul_drop_pkt_cnt=%ul",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_START_DATA_PATH_SUCCESS": {
+ "format": "[RNDIS][CLEAR STALL] rndis_on_bulk_stall success: class id = %ul, BULK type =%ul, queue num = %ul, is stall = %ul",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_START_DATA_PATH_FAIL": {
+ "format": "[RNDIS][CLEAR STALL] rndis_on_bulk_stall fail: class id = %ul, BULK type =%ul, queue num = %ul, is stall = %ul",
+ "traceClass": "RNDIS_UH",
+ "traceHighlightOption": "info"
+ }
+ },
+ {
+ "RNDIS_RB_UL_ENQUEUE_EMPTY_DID": {
+ "format": "[RNDIS][USB_UL] rndis_rb_ul_meta_enqueue_lhif_ul_queue_did(): DO NOT enqueue empty DID. start_idx(%d), end_idx(%d), rel_idx(%d), entry_num(%d)",
+ "traceClass": "RNDIS_L",
+ "traceHighlightOption": "info"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_RNDIS"
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/interface/ufpm_usbclass.h b/mcu/middleware/hif/interface/ufpm_usbclass.h
new file mode 100644
index 0000000..b30d109
--- /dev/null
+++ b/mcu/middleware/hif/interface/ufpm_usbclass.h
@@ -0,0 +1,69 @@
+/*!
+ * @file usbidle_main.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main definitions of usbcore
+ */
+
+#ifndef _UFPM_USBCLASS_H
+#define _UFPM_USBCLASS_H
+
+#include "ufpm_usb_struct.h"
+
+/***************************************************
+ * UFPM Function Common API
+ ***************************************************/
+void usbc_direct_class_device_submit_control_request(ufpm_send_ap_ep0_msg_t* ep0_rsp_ptr, kal_bool isIndication);
+
+
+/***************************************************
+ * UFPM Tethering RNDIS API
+ ***************************************************/
+void ufpm_query_tethering_activation_info(tethering_activate_meta_info_t* tethering_meta_info);
+
+void ufpm_set_tethering_deactivation_info(tethering_deactivate_meta_info_t* deactInfo);
+
+kal_bool ufpm_dpfm_lan_dev_register(kal_uint32 netif_id, kal_uint8 net_type);
+
+/***************************************************
+ * UFPM LOGGING ACM API
+ ***************************************************/
+void ufpm_query_logging_activation_info(logging_activate_meta_info_t* logging_meta_info);
+
+void ufpm_set_logging_deactivation_info(logging_deactivate_meta_info_t* deactInfo);
+
+#endif // _UFPM_USBCLASS_H
+
diff --git a/mcu/middleware/hif/interface/ufpm_usbcore.h b/mcu/middleware/hif/interface/ufpm_usbcore.h
new file mode 100644
index 0000000..3ff4829
--- /dev/null
+++ b/mcu/middleware/hif/interface/ufpm_usbcore.h
@@ -0,0 +1,59 @@
+/*!
+ * @file usbidle_main.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main definitions of usbcore
+ */
+
+#ifndef _UFPM_USBCORE_H
+#define _UFPM_USBCORE_H
+
+#include "hifusb_qmu.h"
+#include "ufpm_usb_struct.h"
+
+kal_bool ufpm_init(void);
+
+void ufpm_on_ilm(ilm_struct *current_ilm);
+
+kal_bool ufpm_check_func_support(ufpm_func_mode_e func_mode);
+
+kal_uint8 ufpm_query_ep_logic_to_phy(hif_queue_type_e queue_type, kal_uint8 logic_queue_no);
+
+void ufpm_set_control_request(ufpm_send_ap_ep0_msg_t* ep0_rsp_ptr, kal_bool isIndication);
+
+void ufpm_redirect_l4_ilm(ilm_struct *ilm);
+
+#endif // _UFPM_USBCORE_H
diff --git a/mcu/middleware/hif/interface/usbcore_class_device.h b/mcu/middleware/hif/interface/usbcore_class_device.h
new file mode 100644
index 0000000..4c0d208
--- /dev/null
+++ b/mcu/middleware/hif/interface/usbcore_class_device.h
@@ -0,0 +1,351 @@
+/*!
+ * @file usbcore_class_device.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.2
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides application interface of usbcore for class device
+ */
+
+#ifndef _USBCORE_CLASS_DEVICE_H
+#define _USBCORE_CLASS_DEVICE_H
+
+#include "usbcore_common.h"
+#include "usbcore_usbstd.h"
+#include "usbc_custom.h"
+
+#define USBC_USBCLASS_DEVICE_DRV_DRB_MACRO(HIFUSB_DRB_MACRO, _class_device_id, _q, ...) (HIFUSB_DRB_MACRO(usbc_class_device_get_phy_queue_num(_class_device_id, _q), __VA_ARGS__))
+
+/*!
+ * @brief usbc_class_device_info_t describe register information of a
+ * generic usb class device
+ */
+typedef struct _usbc_class_device_info {
+
+ /*!
+ * @brief class type of this device
+ */
+ usb_class_type_e class_type;
+ /*!
+ * @brief total pipes of this device
+ */
+ kal_uint8 total_pipes;
+ /*!
+ * @brief reserve for 4 bytes alignment
+ */
+ kal_uint8 reserve[2];
+ /*!
+ * @brief per class device context
+ */
+ void *class_device_context;
+ /*!
+ * @brief each pipe type of this device
+ */
+ usbc_pipe_type_e pipe_type[MAX_USBCORE_CLASS_PIPE_NUM];
+ /*!
+ * @brief callback function while usb state changed.
+ * Running Level: TASK
+ */
+ void (*notify_usb_state)(kal_uint8 class_device_id, usbc_usb_state_e state);
+ /*!
+ * @brief callback function while usb speed changed.
+ * Running Level: TASK
+ */
+ void (*notify_usb_speed)(kal_uint8 class_device_id, usbc_usb_speed_e speed);
+ /*!
+ * @brief callback function while control tranfer for this device
+ * is received
+ * Running Level: TASK
+ */
+ void (*notify_control_setup_packet)(kal_uint8 class_device_id, usbc_setup_packet_t* packet);
+ /*!
+ * @brief callback function while control tranfer is complete
+ * Running Level: TASK
+ */
+ void (*notify_control_complete)(kal_uint8 class_device_id);
+ /*!
+ * @brief callback function while interface alternate setting is set
+ * Running Level: TASK
+ */
+ void (*notify_alternate_setting)(kal_uint8 class_device_id, usbc_interface_type_e inteface, kal_uint8 alternate_setting);
+ /*!
+ * @brief callback function while each pipe tranfer is complete (GPD/SPD)
+ * Running Level: TASK
+ */
+ void (*notify_pipe_complete[MAX_USBCORE_CLASS_PIPE_NUM])(kal_uint8 class_device_id, usbc_io_request_t* io_request);
+ /*!
+ * @brief callback function while each pipe tranfer is complete (UL META/DRB)
+ * Running Level: TASK
+ */
+ void (*notify_rb_pipe_complete[MAX_USBCORE_CLASS_PIPE_NUM])(kal_uint8 class_device_id, kal_uint32 start_idx, kal_uint32 end_idx, kal_uint32 rel_idx);
+ /*!
+ * @brief callback function to indicate pipe is stall or not
+ * Running Level: TASK
+ */
+ void (*notify_pipe_stall[MAX_USBCORE_CLASS_PIPE_NUM])(kal_uint8 class_device_id, kal_bool stall);
+ /*!
+ * @brief callback function to notify a function enable/disable function remote wakeup
+ */
+ void (*notify_func_wk_ability)(kal_uint8 class_device_id, kal_bool ability);
+ /*!
+ * @brief callback function to query the status of class device
+ */
+ kal_uint16 (*query_func_wk_status)(kal_uint8 class_device_id);
+} usbc_class_device_info_t;
+
+typedef struct _usbc_class_device_esl_connect_parm {
+ LOCAL_PARA_HDR
+ kal_uint8 class_device_id;
+} usbc_class_device_esl_connect_parm;
+
+/*!
+ * @brief register new usb class device to usbcore
+ * Running Level: TASK INIT/TASK
+ * @param class_device_id device instance id to register
+ * @param device_info class device information used to register
+ * @param class_device_id device instance id obtained while register
+ * @return new instance of usb class device if success, NULL if fail
+ */
+usbc_class_device_instance_t* usbc_class_device_register(kal_uint8 class_device_id, usbc_class_device_info_t* device_info);
+
+
+/*!
+ * @brief deregister usb class device from usbcore
+ * Running Level: TASK INIT/TASK
+ * @param class_device_id device instance id obtained while register
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_deregister(kal_uint8 class_device_id);
+
+/*!
+ * @brief retrieve per usb class device context registed in usbc_class_device_register()
+ * Running Level: ANY
+ * @param class_device_id device instance id obtained while register
+ * @return per usb class device context
+ */
+void* usbc_class_device_get_context(kal_uint8 class_device_id);
+
+/*!
+ * @brief submit control transfer request to usbcore
+ * Running Level: TASK
+ * @param class_device_id class device id obtained while register
+ * @param buffer pointer to byte array to send or receive data
+ * @param length length of buffer to send, or to receive
+ * @param type send or receive or stall
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_submit_control_request(kal_uint8 class_device_id, kal_uint8* buffer, kal_uint32 length, usbc_control_request_type_e type);
+
+
+/*!
+ * @brief submit io request to usbcore
+ * Running Level: TASK
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no QMU queue no
+ * @param io_request io request submit to usbcore
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_submit_io_request(kal_uint8 class_device_id, kal_uint8 queue_no, usbc_io_request_t* io_request);
+
+/*!
+ * @brief submit io request to usbcore with more configurations
+ * Running Level: TASK
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no QMU queue no
+ * @param io_request io request submit to usbcore
+ * @param info configurations apply to the requests
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_submit_io_request_ext(kal_uint8 class_device_id, kal_uint8 queue_no, usbc_io_request_t *io_request, usbc_io_ext_info_t *info);
+
+/*!
+ * @brief flush io request already submitted to usbcore
+ * Running Level: TASK
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no QMU queue no
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_flush_io_request(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+
+/*!
+ * @brief flush DRB/XIT queue
+ * Running Level: TASK
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no QMU queue no
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_flush_rb(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+
+/*!
+ * @brief change notify complete function already registered to usbcore
+ * Running Level: TASK
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no QMU queue no
+ * @param notify_complete notify complete callback function
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_change_notify_complete(kal_uint8 class_device_id, kal_uint8 queue_no, void (*notify_complete)(kal_uint8 class_device_id, usbc_io_request_t* io_request));
+
+
+/*!
+ * @brief ask usbcore to detach from bus
+ * Running Level: TASK
+ * @param class_device_id device instance id obtained while register
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_set_hif_disconnect(kal_uint8 class_device_id);
+
+/*!
+ * @brief submit DRB to usbcore
+ * Running Level: TASK
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no QMU queue no
+ * @param submit_drb_count number of DRBs to be submitted
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_submit_drb(kal_uint8 class_device_id, kal_uint8 queue_no,kal_uint32 submit_drb_count);
+
+kal_bool usbc_class_device_rst_ep_pipe(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+
+kal_bool usbc_class_device_set_header_rule(kal_uint32 header_rule, void *ph_addr, void *xh_addr, kal_uint16 ph_length, kal_uint16 xh_length);
+
+void
+usbc_resource_reset(void);
+
+usbc_interface_info_t*
+usbc_get_interface_number(kal_uint8 config_num, kal_uint8 *if_num_p);
+
+kal_uint8
+usbc_get_string_number(void *string);
+
+usbc_interface_association_descriptor_t*
+usbc_get_iad_number(kal_uint8 config_num, kal_uint8 *iad_num_p);
+
+usbc_endpoint_info_t*
+usbc_get_endpoint_tx_number(kal_uint8 config_num, kal_uint8 *tx_ep_num_p);
+
+usbc_endpoint_info_t*
+usbc_get_endpoint_rx_number(kal_uint8 config_num, kal_uint8 *rx_ep_num_p);
+
+
+/*!
+ * @brief ask usbcore to send function remote wakeup notification to the host
+ * Running Level: TASK
+ * @param class_device_id device instance id obtained while register
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail
+ */
+kal_bool usbc_class_device_func_remote_wk(kal_uint8 class_device_id);
+
+/*!
+ * @brief the handler for function remote wakeup notification timeout
+ * @param class_device_id device instance id obtained while register
+ * @return
+ */
+void usbc_wk_notify_timeout();
+
+/*!
+ * @brief set timer for sending function remote wakeup notification
+ * @param class_device_id device instance id obtained while register
+ * @return
+ */
+void usbc_set_wk_notify_timer(kal_uint8 class_device_id);
+
+/*!
+ * @brief The netwotk USB function uses the API to notify L4 that it has been in suspending states
+ * @param class_device_id device instance id obtained while register
+ * @parm suspend the network USB funtion is going to suspending or resuming
+ * @param remote_wakeup Is remote wakeup of the suspended function enabled
+ * @return
+ */
+void usbc_class_device_netifx_suspend_notify(kal_uint8 class_device_id, kal_bool suspend, kal_bool remote_wakeup);
+
+kal_bool usbc_class_device_check_ep_empty(kal_uint8 class_device_id, kal_uint8 queue_no);
+/*!
+ * @brief Get physical USB queue number
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no queue number maintained in USBCLASS internal structure
+ * @return physical USB queuen umber
+ */
+kal_uint8 usbc_class_device_get_phy_queue_num(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+/*!
+ * @brief halt USB queue
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no queue number maintained in USBCLASS internal structure
+ * @return
+ */
+kal_bool usbc_class_device_set_stall(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+/*!
+ * @brief resume usb queue
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no queue number maintained in USBCLASS internal structure
+ * @return
+ */
+kal_bool usbc_class_device_clear_stall(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+/*!
+ * @brief Start USB ULQ/DLQ
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no queue number maintained in USBCLASS internal structure
+ * @return
+ */
+kal_bool usbc_class_device_start_data_q(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+/*!
+ * @brief Handle Invalid EP0
+ * @return
+ */
+void usbc_class_device_stall_ep0(void);
+
+/*!
+ * @brief restore GPDs from SW to HW
+ * @return T or F
+ */
+kal_bool usbc_class_device_restore_gpd_pwrsave(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+usb_class_owner_e usbc_class_get_class_device_owner(kal_uint8 class_device);
+/*!
+ * @brief Flush RX EP with GPD re-submit
+ * @param class_device_id device instance id obtained while register
+ * @param queue_no queue number maintained in USBCLASS internal structure
+ * @return
+ */
+kal_bool usbc_class_device_flush_rx_io_with_submit(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+#endif // _USBCORE_CLASS_DEVICE_H
+
diff --git a/mcu/middleware/hif/interface/usbcore_common.h b/mcu/middleware/hif/interface/usbcore_common.h
new file mode 100644
index 0000000..a7eeb26
--- /dev/null
+++ b/mcu/middleware/hif/interface/usbcore_common.h
@@ -0,0 +1,682 @@
+/*!
+ * @file usbcore_common.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides common definitions of usbcore
+ */
+
+#ifndef _USBCORE_COMMON_H
+#define _USBCORE_COMMON_H
+
+#include "qmu_bm.h"
+#include "usbc_custom_def.h"
+#include "usbc_custom.h"
+#include "hif_usb.h"
+#include "usbcore_usbstd.h"
+
+
+/*!
+ * @brief Swap the pointed-to 16-bit quantity from USB byte order
+ * (little-endian) to host byte order, in an alignment-safe manner.
+ * @param _pData pointer (as unsigned char*)
+ * @return quantity in host byte order
+ */
+#define USBC_EF16P(_pData) ((*(_pData+1) << 8) | *(_pData))
+
+
+/*!
+ * @brief Swap the pointed-to 24-bit quantity from USB byte order
+ * (little-endian) to host byte order, in an alignment-safe manner.
+ * @param _pData pointer (as unsigned char*)
+ * @return quantity in host byte order
+ */
+#define USBC_EF24P(_pData) ((*(_pData+2) << 16) | (*(_pData+1) << 8) | *(_pData))
+
+
+/*!
+ * @brief Swap the pointed-to 32-bit quantity from USB byte order
+ * (little-endian) to host byte order, in an alignment-safe manner.
+ * @param _pData pointer (as unsigned char*)
+ * @return quantity in host byte order
+ */
+#define USBC_EF32P(_pData) ((*(_pData+3) << 24) | (*(_pData+2) << 16) | (*(_pData+1) << 8) | *(_pData))
+
+
+/*!
+ * @brief MAX_USBCORE_CLASS_INTERFACE_NUM defines the maximum value of
+ * interface per class device that usbcore can support
+ */
+#define MAX_USBCORE_CLASS_INTERFACE_NUM 4
+
+
+/*!
+ * @brief MAX_USBCORE_CLASS_PIPE_NUM defines the maximum value of pipe
+ * per class device that usbcore can support
+ */
+#define MAX_USBCORE_CLASS_PIPE_NUM 8
+
+
+/*!
+ * @brief MAX_USBCORE_CONFIG_NUM defines the maximum value of configuration
+ * usbcore can handle
+ */
+#define MAX_USBCORE_CONFIG_NUM 8
+
+
+/*!
+ * @brief MAX_USBCORE_INTERFACE_NUM defines the maximum value of class
+ * interface usbcore can handle
+ */
+#define MAX_USBCORE_INTERFACE_NUM 16
+
+
+/*!
+ * @brief MAX_USBCORE_QUEUE_NUM defines the maximum value of QMU queues
+ * that usbcore can support
+ */
+#define MAX_USBCORE_QUEUE_NUM 16
+
+
+/*!
+ * @brief MAX_USBCORE_STRING_DESCRIPTOR_NUM defines the maximum value of string
+ * descriptors usbcore can handle
+ */
+#define MAX_USBCORE_STRING_DESCRIPTOR_NUM 254
+
+
+/*!
+ * @brief MAX_USBCORE_CONTROL_REQUEST_BUFFER_SIZE defines the maximum value
+ * of control request buffer
+ */
+#define MAX_USBCORE_CONTROL_REQUEST_BUFFER_SIZE 64
+
+
+
+
+
+
+
+#define MAX_USBCORE_CLASS_EPDESC_LENGTH 12
+#define MAX_USBCORE_IFDESC_LENGTH 258 // this will change depends on different class interface, refer to 6280
+#define MAX_USBCORE_EPNUM_PER_IF 3
+#define MAX_USBCORE_IAD_NUM 8
+
+
+
+/*!
+ * @brief USBC_USB11_MAX_PACKET_SIZE define maximum packet size in USB SPEED 1.1
+ */
+#define USBC_USB11_MAX_PACKET_SIZE 64
+
+
+/*!
+ * @brief USBC_USB20_MAX_PACKET_SIZE define maximum packet size in USB SPEED 2.0
+ */
+#define USBC_USB20_MAX_PACKET_SIZE 512
+
+
+/*!
+ * @brief USBC_USB30_MAX_PACKET_SIZE define maximum packet size in USB SPEED 3.0
+ */
+#define USBC_USB30_MAX_PACKET_SIZE 1024
+
+
+
+/*!
+ * @brief usbc_usb_state_e enumerate possible states of usb device
+ * @param USBC_USB_STATE_MIN pseudo state
+ * @param USBC_USB_STATE_ATTACHING start attaching to usb bus
+ * @param USBC_USB_STATE_ATTACHED attach to usb bus already
+ * @param USBC_USB_STATE_DETACHING start detaching from usb bus
+ * @param USBC_USB_STATE_DETACHED detach from usb bus already
+ * @param USBC_USB_STATE_SUSPENDING start suspending
+ * @param USBC_USB_STATE_SUSPENDED suspend already
+ * @param USBC_USB_STATE_RESUME recevie usb resume signal
+ * @param USBC_USB_STATE_RESET recevie usb bus reset
+ * @param USBC_USB_STATE_MAX pseudo state
+ */
+typedef enum _usbc_usb_state {
+ USBC_USB_STATE_MIN = 0,
+ USBC_USB_STATE_ATTACHING = 1,
+ USBC_USB_STATE_ATTACHED = 2,
+ USBC_USB_STATE_DETACHING = 3,
+ USBC_USB_STATE_DETACHED = 4,
+ USBC_USB_STATE_SUSPENDING = 5,
+ USBC_USB_STATE_SUSPENDED = 6,
+ USBC_USB_STATE_RESUME = 7,
+ USBC_USB_STATE_RESET = 8,
+ USBC_USB_STATE_PWRDOWN = 9,
+ USBC_USB_STATE_MAX = 10,
+} usbc_usb_state_e;
+
+/*!
+ * @brief usbc_func_state_e indicate possible states of class device for function suspend
+ * @param USBC_FUNC_WK_ENABLE to enable function remote wakeup
+ * @param USBC_FUNC_WK_DISABLE to disable function remote wakeup
+ * @param USBC_FUNC_STATE_SUSPENDING to suspend a class device
+ * @param USBC_FUNC_STATE_RESUME to resume a suspended class device
+ */
+typedef enum _usbc_func_state {
+ USBC_FUNC_WK_ENABLE = 0,
+ USBC_FUNC_WK_DISABLE = 1,
+ USBC_FUNC_STATE_SUSPENDING = 5,
+ USBC_FUNC_STATE_RESUME = 7,
+ USBC_FUNC_WK_ENABLE_STATE_SUSPENDING = 21,
+ USBC_FUNC_WK_ENABLE_STATE_RESUME = 22,
+ USBC_FUNC_WK_DISABLE_STATE_SUSPENDING = 23,
+ USBC_FUNC_WK_DISABLE_STATE_RESUME = 24,
+ USBC_FUNC_SET_FEATURE_ERROR = 25,
+} usbc_func_state_e;
+
+
+/*!
+ * @brief usbc_op_mode_e USB Core operation mode
+ * @param USBC_OP_MODE_UNKNOWN unknown operation mode
+ * @param USBC_OP_MODE_DETECTION host and driver detection mode
+ * @param USBC_OP_MODE_NORMAL normal operation mode
+ * @param USBC_OP_MODE_EXCEPTION exception mode
+ * @param USBC_OP_MODE_MDONLY DIPC only MD port
+ * @param USBC_OP_MODE_NOLOGGING DIPC no MD logging port
+ * @param USBC_OP_MODE_METADEBUG DIPC meta debug mode
+ * @param USBC_OP_MODE_UNUSED DIPC mode do not use USB
+ */
+typedef enum _usbc_op_mode {
+ USBC_OP_MODE_UNKNOWN = 0,
+ USBC_OP_MODE_DETECTION = 1,
+ USBC_OP_MODE_NORMAL = 2,
+ USBC_OP_MODE_EXCEPTION = 3,
+ USBC_OP_MODE_MDONLY =4,
+ USBC_OP_MODE_NOLOGGING = 5,
+ USBC_OP_MODE_METADEBUG = 6,
+ USBC_OP_MODE_FACTORY = 7,
+ USBC_OP_MODE_UNUSED =8,
+ USBC_OP_MODE_NUM,
+} usbc_op_mode_e;
+
+/*!
+ * @brief usbc_usb_speed_e enumerate possible speed of usb device
+ * @param USBC_USB_SPEED_MIN pseudo speed
+ * @param USBC_USB_SPEED_USB11 usb 1.1 full speed
+ * @param USBC_USB_SPEED_USB20 usb 2.0 high speed
+ * @param USBC_USB_SPEED_USB30 usb 3.0 super speed
+ * @param USBC_USB_SPEED_MAX pseudo speed
+ */
+typedef enum _usbc_usb_speed {
+ USBC_USB_SPEED_MIN = 0,
+ USBC_USB_SPEED_USB11 = 1,
+ USBC_USB_SPEED_USB20 = 2,
+ USBC_USB_SPEED_USB30 = 3,
+ USBC_USB_SPEED_MAX = 4,
+} usbc_usb_speed_e;
+
+
+/*!
+ * @brief usbc_request_owner_e enumerate all possible types of usb control
+ * request type
+ * @param USBC_CONTROL_REQUEST_TYPE_MIN pseudo type
+ * @param USBC_CONTROL_REQUEST_TYPE_SEND request to send
+ * @param USBC_CONTROL_REQUEST_TYPE_RECEIVE request to receive
+ * @param USBC_CONTROL_REQUEST_TYPE_STALL request to stall
+ * @param USBC_CONTROL_REQUEST_TYPE_MAX pseudo type
+ */
+typedef enum _usbc_control_request_type {
+ USBC_CONTROL_REQUEST_TYPE_MIN = 0,
+ USBC_CONTROL_REQUEST_TYPE_SEND = 1,
+ USBC_CONTROL_REQUEST_TYPE_RECEIVE = 2,
+ USBC_CONTROL_REQUEST_TYPE_STALL = 3,
+ USBC_CONTROL_REQUEST_TYPE_MAX = 4,
+} usbc_control_request_type_e;
+
+
+/*!
+ * @brief usbc_interface_type_e enumerate support list of interface types
+ * @param USBC_INTERFACE_TYPE_MIN pseudo interface
+ * @param USBC_INTERFACE_TYPE_CDC_ACM_CONTROL CDC ACM control interface
+ * @param USBC_INTERFACE_TYPE_CDC_ACM_DATA CDC ACM data interface
+ * @param USBC_INTERFACE_TYPE_RNDIS_CONTROL RNDIS control interface
+ * @param USBC_INTERFACE_TYPE_RNDIS_DATA RNDIS data interface
+ * @param USBC_INTERFACE_TYPE_MAX pseudo interface
+ */
+typedef enum _usbc_interface_type {
+ USBC_INTERFACE_TYPE_MIN = 0x0,
+ USBC_INTERFACE_TYPE_CDC_ACM_CONTROL = 0x1,
+ USBC_INTERFACE_TYPE_CDC_ACM_DATA = 0x2,
+ USBC_INTERFACE_TYPE_RNDIS_CONTROL = 0x3,
+ USBC_INTERFACE_TYPE_RNDIS_DATA = 0x4,
+ USBC_INTERFACE_TYPE_MBIM_CONTROL = 0x5,
+ USBC_INTERFACE_TYPE_MBIM_DATA = 0x6,
+ USBC_INTERFACE_TYPE_MSD_CONTROL = 0x7,
+ USBC_INTERFACE_TYPE_MSD_DATA = 0x8,
+ USBC_INTERFACE_TYPE_CDC_ECM_CONTROL = 0x9,
+ USBC_INTERFACE_TYPE_CDC_ECM_DATA = 0xA,
+ USBC_INTERFACE_TYPE_ADB_DATA = 0xB,
+ USBC_INTERFACE_TYPE_MAX
+} usbc_interface_type_e;
+
+
+/*!
+ * @brief usbc_pipe_type_e enumerate all possible types of usb classs
+ * device pipe
+ * @param USBC_PIPE_TYPE_MIN pseudo type
+ * @param USBC_PIPE_TYPE_CDC_ACM_DATA_IN CDC ACM data in pipe
+ * @param USBC_PIPE_TYPE_CDC_ACM_COMM_IN CDC ACM comm in pipe
+ * @param USBC_PIPE_TYPE_CDC_ACM_DATA_OUT CDC ACM data out pipe
+ * @param USBC_PIPE_TYPE_GCOM_DATA_IN Generic COM data in pipe
+ * @param USBC_PIPE_TYPE_GCOM_DATA_OUT Generic COM data out pipe
+ * @param USBC_PIPE_TYPE_CDC_ECM_DATA_IN CDC ECM data in pipe
+ * @param USBC_PIPE_TYPE_CDC_ECM_COMM_IN CDC ECM comm in pipe
+ * @param USBC_PIPE_TYPE_CDC_ECM_DATA_OUT CDC ECM data out pipe
+ * @param USBC_PIPE_TYPE_RNDIS_DATA_IN RNDIS data in pipe
+ * @param USBC_PIPE_TYPE_RNDIS_COMM_IN RNDIS comm in pipe
+ * @param USBC_PIPE_TYPE_RNDIS_DATA_OUT RNDIS data out pipe
+ * @param USBC_PIPE_TYPE_MASS_STORAGE_DATA_IN Mass Storage data in pipe
+ * @param USBC_PIPE_TYPE_MASS_STORAGE_DATA_OUT Mass Storage data out pipe
+ * @param USBC_PIPE_TYPE_MAX pseudo type
+ */
+typedef enum _usbc_pipe_type {
+ USBC_PIPE_TYPE_MIN = 0,
+ USBC_PIPE_TYPE_CDC_ACM_DATA_IN = 1,
+ USBC_PIPE_TYPE_CDC_ACM_COMM_IN = 2,
+ USBC_PIPE_TYPE_CDC_ACM_DATA_OUT = 3,
+ USBC_PIPE_TYPE_GCOM_DATA_IN = 4,
+ USBC_PIPE_TYPE_GCOM_DATA_OUT = 5,
+ USBC_PIPE_TYPE_CDC_ECM_DATA_IN = 6,
+ USBC_PIPE_TYPE_CDC_ECM_COMM_IN = 7,
+ USBC_PIPE_TYPE_CDC_ECM_DATA_OUT = 8,
+ USBC_PIPE_TYPE_RNDIS_DATA_IN = 9,
+ USBC_PIPE_TYPE_RNDIS_COMM_IN = 10,
+ USBC_PIPE_TYPE_RNDIS_DATA_OUT = 11,
+ USBC_PIPE_TYPE_MASS_STORAGE_DATA_IN = 12,
+ USBC_PIPE_TYPE_MASS_STORAGE_DATA_OUT = 13,
+ USBC_PIPE_TYPE_MBIM_DATA_IN = 14,
+ USBC_PIPE_TYPE_MBIM_COMM_IN = 15,
+ USBC_PIPE_TYPE_MBIM_DATA_OUT = 16,
+ USBC_PIPE_TYPE_ADB_DATA_IN = 17,
+ USBC_PIPE_TYPE_ADB_DATA_OUT = 18,
+ USBC_PIPE_TYPE_MAX
+} usbc_pipe_type_e;
+
+
+
+
+
+
+
+
+
+
+/*!
+ * @brief usbc_core_class_device_state_e enumerate all possible states of
+ * class device in USBCORE module
+ * @param USBC_CORE_CLASS_DEVICE_STATE_MIN pseudo state
+ * @param USBC_CORE_CLASS_DEVICE_STATE_NOTEXIST this device is not existed
+ * @param USBC_CORE_CLASS_DEVICE_STATE_INITIATED this device is initiated
+ * @param USBC_CORE_CLASS_DEVICE_STATE_REGISTERED this device is registered
+ * @param USBC_CORE_CLASS_DEVICE_STATE_MAX pseudo state
+ */
+typedef enum _usbc_core_class_device_state {
+ USBC_CORE_CLASS_DEVICE_STATE_MIN = 0,
+ USBC_CORE_CLASS_DEVICE_STATE_NOTEXIST = 1,
+ USBC_CORE_CLASS_DEVICE_STATE_INITIATED = 2,
+ USBC_CORE_CLASS_DEVICE_STATE_REGISTERED = 3,
+ USBC_CORE_CLASS_DEVICE_STATE_MAX = 4,
+} usbc_core_class_device_state_e;
+
+
+/*!
+ * @brief usbc_core_class_interface_state_e enumerate all possible states of
+ * class interface in USBCORE module
+ * @param USBC_CORE_CLASS_INTERFACE_STATE_MIN pseudo state
+ * @param USBC_CORE_CLASS_INTERFACE_STATE_DISABLE this interface is disabled
+ * @param USBC_CORE_CLASS_INTERFACE_STATE_INITIATED this interface is initiated
+ * @param USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE this interface is actived
+ * @param USBC_CORE_CLASS_INTERFACE_STATE_MAX pseudo state
+ */
+typedef enum _usbc_core_class_interface_state {
+ USBC_CORE_CLASS_INTERFACE_STATE_MIN = 0,
+ USBC_CORE_CLASS_INTERFACE_STATE_DISABLE = 1,
+ USBC_CORE_CLASS_INTERFACE_STATE_INITIATED = 2,
+ USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE = 3,
+ USBC_CORE_CLASS_INTERFACE_STATE_MAX = 4,
+} usbc_core_class_interface_state_e;
+
+
+/*!
+ * @brief usbc_core_queue_state_e enumerate all possible states of QMU Queue
+ * in USBCORE module
+ * @param USBC_CORE_QUEUE_STATE_MIN pseudo state
+ * @param USBC_CORE_QUEUE_STATE_DISABLE this queue is not used
+ * @param USBC_CORE_QUEUE_STATE_INITIATED this queue is initiated
+ * @param USBC_CORE_QUEUE_STATE_ACTIVE this queue is enabled,and used
+ * @param USBC_CORE_QUEUE_STATE_STALL this queue is enabled,but stalled
+ * @param USBC_CORE_QUEUE_STATE_MAX pseudo state
+ */
+typedef enum _usbc_core_queue_state {
+ USBC_CORE_QUEUE_STATE_MIN = 0,
+ USBC_CORE_QUEUE_STATE_DISABLE = 1,
+ USBC_CORE_QUEUE_STATE_INITIATED = 2,
+ USBC_CORE_QUEUE_STATE_ACTIVE = 3,
+ USBC_CORE_QUEUE_STATE_STALL = 4,
+ USBC_CORE_QUEUE_STATE_MAX = 5,
+} usbc_core_queue_state_e;
+
+/*!
+ * @brief usbc_setup_packet_sm_e USBCORE setup state machine
+ * @param USBC_CORE_SETUP_SM_INITIALIZE initialize state
+ * @param USBC_CORE_SETUP_SM_RECEIVED usbcore received setup packet
+ * @param USBC_CORE_SETUP_SM_MULTI_SETUP received multiple setup packet
+ * @param USBC_CORE_SETUP_SM_MAX pseudo state
+ */
+typedef enum _usbc_setup_packet_sm{
+ USBC_CORE_SETUP_SM_INITIALIZE = 0,
+ USBC_CORE_SETUP_SM_RECEIVED = 1,
+ USBC_CORE_SETUP_SM_MULTI_SETUP = 2,
+ USBC_CORE_SETUP_SM_MAX = 3,
+}usbc_setup_packet_sm_e;
+
+/*!
+ * @brief usbc_io_request_t is a typedef of struct _usbc_io_request
+ */
+typedef struct _usbc_io_request usbc_io_request_t;
+/*!
+ * @brief struct _usbc_io_request describe usbc io request used to communicate
+ * usb class device and usbcore
+ */
+struct _usbc_io_request {
+ /*!
+ * @brief next io request
+ */
+ usbc_io_request_t* next_request;
+ /*!
+ * @brief pointer to current gpd of this io request
+ */
+ qbm_gpd* first_gpd;
+ /*!
+ * @brief pointer to last gpd of this io request
+ */
+ qbm_gpd* last_gpd;
+};
+
+
+/*!
+ * @brief usbc_core_queue_t describe queue information maintain within usbcore
+ */
+typedef struct _usbc_core_queue {
+
+ /*!
+ * @brief current queue state of this queue
+ */
+ usbc_core_queue_state_e state;
+ /*!
+ * @brief id of class device that own this queue
+ */
+ kal_uint8 class_device_id;
+ /*!
+ * @brief pipe type of this queue
+ */
+ usbc_pipe_type_e pipe_type;
+ /*!
+ * @brief usb transfer type of this queue
+ */
+ hifusb_usb_xfer_type_e xfer_type;
+ /*!
+ * @brief endpoint number of this queue
+ */
+ kal_uint8 ep_no;
+ /*!
+ * @brief maximum packet size of this queue
+ */
+ kal_uint16 max_packet_size;
+ /*!
+ * @brief fifo type is DOUBLE FIFO or not
+ */
+ kal_uint8 fifo_n;
+ kal_uint8 rsvd[3];
+ /*!
+ * @brief queue configuration
+ */
+ kal_uint32 config;
+ /*!
+ * @brief queue owner
+ */
+ usb_class_owner_e owner;
+ /*!
+ * @brief complete function to notify class device (GPD/SPD)
+ */
+ void (*notify_complete)(kal_uint8 class_deivce_id, usbc_io_request_t* io_request);
+ /*!
+ * @brief complete function to notify class device (UL META/DRB)
+ */
+ void (*notify_rb_complete)(kal_uint8 class_deivce_id, kal_uint32 start_idx, kal_uint32 end_idx, kal_uint32 rel_idx);
+ /*!
+ * @brief callback function to notify class device queue is stall or not
+ */
+ void (*notify_stall)(kal_uint8 class_device_id, kal_bool stall);
+} usbc_core_queue_t;
+
+typedef struct _usbc_endpoint_info_t {
+
+ /*!
+ * @brief Descriptor length
+ */
+ kal_uint16 epdscr_size;
+
+ /*!
+ * @brief Endpoint descriptor
+ */
+ union {
+ usbc_endpoint_descriptor_t stdep;
+ kal_uint8 classep[MAX_USBCORE_CLASS_EPDESC_LENGTH];
+ } epdscr;
+
+ usbc_core_queue_t queue_info;
+} usbc_endpoint_info_t;
+
+typedef struct _usbc_alternate_interface_info_t {
+ /*!
+ * @brief Descriptor length
+ */
+ kal_uint16 ifdscr_size;
+
+ union {
+ usbc_interface_descriptor_t stdif;
+ kal_uint8 classif[MAX_USBCORE_IFDESC_LENGTH];
+ } ifdscr;
+
+ usbc_endpoint_info_t *ep_info[MAX_USBCORE_EPNUM_PER_IF];
+
+} usbc_alternate_interface_info_t;
+
+/*!
+ * @brief usbc_core_class_interface_t describe class interface information
+ * maintain within usbcore
+ */
+typedef struct _usbc_core_class_interface_t {
+ /*!
+ * @brief interace number of this interface
+ */
+ kal_uint8 interface_no;
+ /*!
+ * @brief interace type of this interface
+ */
+ usbc_interface_type_e interface_type;
+ /*!
+ * @brief id of class device that own this interface
+ */
+ kal_uint8 class_device_id;
+ /*!
+ * @brief current state of this interface
+ */
+ usbc_core_class_interface_state_e state;
+ /*!
+ * @brief bAlternateSetting of this interface
+ */
+ kal_uint8 alternate_setting;
+ kal_uint8 rsvd[3];
+ /*!
+ * @brief callback function while control tranfer for this device
+ * is received
+ */
+ void (*notify_control_setup_packet)(kal_uint8 class_device_id, usbc_setup_packet_t* packet);
+ /*!
+ * @brief callback function while control tranfer is complete
+ */
+ void (*notify_control_complete)(kal_uint8 class_device_id);
+ /*!
+ * @brief callback function while interface alternate setting is set
+ */
+ void (*notify_alternate_setting)(kal_uint8 class_device_id, usbc_interface_type_e inteface, kal_uint8 alternate_setting);
+
+} usbc_core_class_interface_t;
+
+/*!
+ * @brief usbc_core_class_interface_t describe class interface information
+ * maintain within usbcore
+ */
+typedef struct _usbc_interface_info_t {
+
+ usb_class_type_e type;
+
+ /*!
+ * @brief Descriptor length
+ */
+ kal_uint16 ifdscr_size;
+
+ /*!
+ * @brief Interface descriptor
+ */
+ union {
+ usbc_interface_descriptor_t stdif;
+ kal_uint8 classif[MAX_USBCORE_IFDESC_LENGTH];
+ } ifdscr;
+
+ usbc_endpoint_info_t *ep_info[MAX_USBCORE_EPNUM_PER_IF];
+
+ kal_bool altn_surpport; // FALSE (no alternate setting) or TRUE (has alternate setting)
+ usbc_alternate_interface_info_t altn_if_info;
+
+ usbc_core_class_interface_t class_interface;
+
+} usbc_interface_info_t;
+
+/*!
+ * @brief usbc_class_device_instance_t describe instance of a
+ * generic usb class device
+ */
+typedef struct _usbc_class_device_instance {
+ /*!
+ * @brief instance id of this device
+ */
+ kal_uint8 id;
+
+ /*!
+ * @brief current usb speed of this device
+ */
+ kal_uint8 speed;
+ /*!
+ * @brief total_interfaces for this class device
+ */
+ kal_uint8 total_interfaces;
+ kal_uint8 rsvd[1];
+ /*!
+ * @brief per class device context
+ */
+ void *context;
+ /*!
+ * @brief qmu queue no for each pipe
+ */
+ kal_uint8 queue_no_for_pipe[MAX_USBCORE_CLASS_PIPE_NUM];
+ /*!
+ * @brief interface type of each interface for this class device
+ */
+ usbc_interface_type_e interface_type[MAX_USBCORE_CLASS_INTERFACE_NUM];
+ /*!
+ * @brief interface number of each interface for this class device
+ */
+ kal_uint8 interface_no[MAX_USBCORE_CLASS_INTERFACE_NUM];
+} usbc_class_device_instance_t;
+
+/*!
+ * @brief usbc_io_req_type_e Type of operation to for requests to submit to USB HIF.
+ * @param USBC_IO_TX_NO_FLUSH Transmit operation without GPD checksum calcuation and cache flush.
+ */
+typedef enum _usbc_io_req_type {
+ USBC_IO_TX_NO_FLUSH = 0x00000010,
+ USBC_IO_TYPE_DUMMY = 0x7fffffff
+} usbc_io_req_type_e;
+
+/*!
+ * @brief usbc_io_ext_info_t Configurations apply to the requests to submit to USB HIF.
+ * @param type Type of operation.
+ */
+typedef struct _usbc_io_ext_info {
+ usbc_io_req_type_e type;
+} usbc_io_ext_info_t;
+
+
+/*
+ * @brief Settings of each type of node to checkin.
+ */
+typedef struct {
+ void *init_func; /* iniitialize descriptor function pointer. */
+ void *set_config_func; /* initialize configuration function pointer */
+ void *reinit_func; /* reinit function pointer */
+ void *query_func_wk_capability; /* callback function to remote wakeup capability of class device */
+} usbc_node_reg_entry_t;
+
+typedef kal_int32 (*usbc_class_init_func_t)(kal_uint8 class_device_id, usb_mode_e mode, kal_uint32 config_index, void *context, kal_uint32 flag);
+typedef kal_int32 (*usbc_class_set_config_func_t)(kal_uint8 class_device_id, kal_uint32 config_index, void *context);
+typedef void (*usbc_class_reinit_func_t)(kal_bool need_check_in);
+typedef kal_uint16 (*usbc_class_query_func_wk_capability_func_t)(void);
+
+
+usbc_class_set_config_func_t usbc_get_class_set_config_func(usb_class_type_e type);
+
+/*!
+ * @brief Add a node into USB stack, the USB stack will start loading configuration,
+ * initializing corresponding modules.
+ * Running Level: TASK INIT
+ * @param node Node of USB stack.
+ * @param reg_table An array of settings. The last entry is ended with type=USBC_NODE_REG_ENTRY_END_TYPE.
+ */
+void usbc_stack_checkin(usb_class_type_e func_type, usbc_node_reg_entry_t *reg_table);
+
+void usbc_mode_switch(usb_mode_e mode);
+
+void usbc_reinit_class(void);
+
+#endif // _USBCORE_COMMON_H
+
diff --git a/mcu/middleware/hif/interface/usbcore_direct.h b/mcu/middleware/hif/interface/usbcore_direct.h
new file mode 100644
index 0000000..b22f344
--- /dev/null
+++ b/mcu/middleware/hif/interface/usbcore_direct.h
@@ -0,0 +1,102 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * usbcore_direct.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * USB Core direct API.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *******************************************************************************/
+#ifndef _USBCORE_DIRECT_H
+#define _USBCORE_DIRECT_H
+
+#include "hifusb_qmu.h"
+#include "kal_public_api.h"
+#include "ufpm_usbcore.h"
+
+
+void usbc_direct_hif_usbcore_send_indication();
+
+void usbc_direct_hif_enable_poll_queue(kal_bool enable);
+
+void usbc_direct_hif_notify_usb_func_event(kal_uint8 class_device_id, usbc_usb_state_e state);
+
+void usbc_direct_hif_attach(usbc_usb_speed_e speed, kal_uint8 address, kal_uint8 configuration);
+
+void usbc_direct_hif_detach();
+
+void usbc_direct_set_config_class_device(kal_uint8 class_device_id, kal_uint8 configuration);
+
+void usbc_direct_core_set_config(kal_uint8 configuration);
+
+kal_bool usbc_direct_dispatch_control_setup_packet(kal_uint8 class_device_id, void* pkt_ptr);
+
+kal_bool usbc_direct_hif_usbq_set_gpd(hif_queue_type_e q_type, kal_uint8 logic_queue_no, qbm_gpd* first_gpd, qbm_gpd* last_gpd);
+
+kal_uint32 usbc_direct_hif_usbq_poll_gpd(hif_deq_info_t deq_info, void **first_gpd, void **last_gpd);
+
+kal_bool usbc_direct_hif_chk_newpkt(kal_bool isTx, kal_uint8 logic_queue_no);
+
+kal_bool usbc_direct_hif_usbq_chk_empty(hif_queue_type_e core_queue_hif_type, kal_uint8 q_num);
+
+kal_uint32 usbc_direct_hif_usbq_flush_gpd(hif_queue_type_e q_type, kal_uint8 logic_queue_no, hif_flush_type_e flush_type , void **pp_head, void **pp_tail);
+
+kal_uint32 usbc_direct_hif_sw_usbq_flush_gpd(hif_queue_type_e q_type, kal_uint8 logic_queue_no, hif_flush_type_e flush_type , void **pp_head, void **pp_tail);
+
+void usbc_direct_hifusb_set_usb_address_emulate(kal_uint8 address);
+
+void usbc_direct_init_ufpm_mapping_table(kal_uint8 config_no, kal_uint8 class_device_id, ufpm_usb_mapping_t* perClassMapTlb);
+
+kal_bool usbc_direct_hif_init(void);
+
+void usbc_direct_hif_notify_usb_core_event(usbc_usb_state_e state);
+
+kal_bool usbc_direct_hifusb_set_usbhif_connect_disconnect();
+
+void usbc_direct_set_usb_mapping(kal_bool isTx, kal_uint8 md_q_no, kal_uint8 ap_ep_no);
+
+#endif
diff --git a/mcu/middleware/hif/interface/usbcore_except.h b/mcu/middleware/hif/interface/usbcore_except.h
new file mode 100644
index 0000000..032d6da
--- /dev/null
+++ b/mcu/middleware/hif/interface/usbcore_except.h
@@ -0,0 +1,178 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * usbcore_except.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * USB Core exception mode interface.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __INC_USBCORE_EXCEPT_H
+#define __INC_USBCORE_EXCEPT_H
+
+#include "usbcore_common.h"
+#include "usbcore_class_device.h"
+
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+typedef enum _usbc_except_link_st {
+ USBC_LINK_NO_ERROR = 0,
+ USBC_LINK_TX_TIMEOUT = 1,
+} usbc_except_link_st_e;
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+
+/*!
+ * @brief Start exception mode HIF data path.
+ * See also hif_except_initial() for more information.
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool usbc_except_init(void);
+
+/*!
+ * @brief Stop the queue and flush USB pipe FIFO.
+ * See also hif_except_clear_q() for more information.
+ * @param class_device_id USB class device id.
+ * @param queue_no QMU queue no.
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool usbc_except_clear_ch(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+/*!
+ * @brief Register the device to be used in exception mode and then trigger USB enumeration.
+ * @param device_info class device information of the device.
+ * @return new instance of usb class device if succeeded, NULL otherwise.
+ */
+usbc_class_device_instance_t *usbc_except_reset_ch(usbc_class_device_info_t *device_info);
+
+/*!
+ * @brief Perform USB enumeration.
+ * Note that, this function exist either the enumeration process is completed or timeout.
+ * @return KAL_TRUE if the USB enumeration is completed, KAL_FALSE if timeout.
+ */
+kal_bool usbc_except_enum_loop(void);
+
+/*!
+ * @brief Check and handle USB control transfers and other device state changes.
+ * See also hifusb_except_poll_isr() for more information.
+ * @param class_device_id USB class device id.
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool usbc_except_hif_poll(kal_uint8 class_device_id);
+
+/*!
+ * @brief Submit a list of GPD to the specified queue of a USB class device instance.
+ * See also hif_except_set_gpd() for more information.
+ * @param class_device_id USB class device id.
+ * @param queue_no QMU queue no.
+ * @param p_first_gpd head of the GPD list.
+ * @param p_last_gpd tail of the GPD list.
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool usbc_except_submit_gpd(kal_uint8 class_device_id, kal_uint8 queue_no, void *p_first_gpd, void *p_last_gpd);
+
+/*!
+ * @brief Check if any GPD submitted to specified queue of a USB class device instance has been completed.
+ * See also hif_except_poll_queue() for more information.
+ * @param class_device_id USB class device id.
+ * @param queue_no QMU queue no.
+ * @param pp_first_gpd Caller allocated space for a pointer to head of the GPD list completed. Its value is invalid if this function returns KAL_FALSE.
+ * @param pp_last_gpd Caller allocated space for a pointer to tail of the GPD list copmleted. Its value is invalid if this function returns KAL_FALSE.
+ * @param gpd_num Number of GPD completed. Its value is invalid if this function returns KAL_FALSE.
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool usbc_except_poll_queue(kal_uint8 class_device_id, kal_uint8 queue_no, void **pp_first_gpd, void **pp_last_gpd, kal_uint32 *gpd_num);
+
+/*!
+ * @brief Check specified queue status.
+ * See also hif_except_get_txq_timeout(() for more information.
+ * @param class_device_id USB class device id.
+ * @param queue_no QMU queue no.
+ * @param link_state Return status of the queue if succeeded.
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool usbc_except_hif_state(kal_uint8 class_device_id, kal_uint8 queue_no, usbc_except_link_st_e *link_state);
+
+/*!
+ * @brief flush Tx/Rx queue in exception reset.
+ * @param class_device_id USB class device id.
+ * @param queue_no QMU queue no.
+ * @param number of returned flushed GPDs.
+ * @param address of the returned GPD's head.
+ * @param address of the returned GPD's tail.
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool usbc_except_reset_flush(kal_uint8 class_device_id, kal_uint8 queue_no, void** first_gpd, void** last_gpd, kal_uint32* gpd_num);
+#endif /* __INC_USBCORE_EXCEPT_H */
+
diff --git a/mcu/middleware/hif/interface/usbcore_usbstd.h b/mcu/middleware/hif/interface/usbcore_usbstd.h
new file mode 100644
index 0000000..e23203d
--- /dev/null
+++ b/mcu/middleware/hif/interface/usbcore_usbstd.h
@@ -0,0 +1,517 @@
+/*!
+ * @file usbcore_usbstd.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides standard definitions of usb-if specification
+ */
+
+#ifndef _USBCORE_USBSTD_H
+#define _USBCORE_USBSTD_H
+
+#include "kal_public_api.h"
+
+/*
+ * Helper routines.
+ */
+#define USBC_GET_UINT8(_buf, _offset) \
+ *((kal_uint8*)(_buf) + (_offset))
+
+#define USBC_GET_UINT16(_buf, _offset) \
+ ( ((kal_uint16)*((kal_uint8 *)(_buf) + (_offset))) | \
+ (((kal_uint16)*((kal_uint8 *)(_buf) + (_offset) + 1)) << 8) )
+
+#define USBC_GET_UINT32(_buf, _offset) \
+ ( ((kal_uint32)*((kal_uint8 *)(_buf) + (_offset))) | \
+ (((kal_uint32)*((kal_uint8 *)(_buf) + (_offset) + 1)) << 8) | \
+ (((kal_uint32)*((kal_uint8 *)(_buf) + (_offset) + 2)) << 16) | \
+ (((kal_uint32)*((kal_uint8 *)(_buf) + (_offset) + 3)) << 24) )
+
+#define USBC_SET_UINT8(_buf, _offset, _value) \
+ *((kal_uint8*)(_buf) + (_offset)) = (kal_uint8)(_value)
+
+#define USBC_SET_UINT16(_buf, _offset, _value) \
+ *((kal_uint8*)(_buf) + (_offset)) = (kal_uint8)(_value); \
+ *((kal_uint8*)(_buf) + (_offset) + 1) = (kal_uint8)((_value) >> 8)
+
+#define USBC_SET_UINT32(_buf, _offset, _value) \
+ *((kal_uint8*)(_buf) + (_offset)) = (kal_uint8)(_value); \
+ *((kal_uint8*)(_buf) + (_offset) + 1) = (kal_uint8)((_value) >> 8); \
+ *((kal_uint8*)(_buf) + (_offset) + 2) = (kal_uint8)((_value) >> 16); \
+ *((kal_uint8*)(_buf) + (_offset) + 3) = (kal_uint8)((_value) >> 24)
+
+#define USBC_GET_DESC_LENGTH(_desc) \
+ USBC_GET_UINT8(_desc, 0)
+
+#define USBC_SET_DESC_LENGTH(_desc, _value) \
+ USBC_SET_UINT8(_desc, 0, _value)
+
+#define USBC_GET_DESC_TYPE(_desc) \
+ USBC_GET_UINT8(_desc, 1)
+
+#define USBC_SET_DESC_TYPE(_desc, _value) \
+ USBC_SET_UINT8(_desc, 1, _value)
+
+
+/*!
+ * @brief USB Standard Requests
+ */
+#define USBC_REQ_GET_STATUS 0x00
+#define USBC_REQ_CLEAR_FEATURE 0x01
+#define USBC_REQ_SET_FEATURE 0x03
+#define USBC_REQ_SET_ADDRESS 0x05
+#define USBC_REQ_GET_DESCRIPTOR 0x06
+#define USBC_REQ_SET_DESCRIPTOR 0x07
+#define USBC_REQ_GET_CONFIGURATION 0x08
+#define USBC_REQ_SET_CONFIGURATION 0x09
+#define USBC_REQ_GET_INTERFACE 0x0A
+#define USBC_REQ_SET_INTERFACE 0x0B
+#define USBC_REQ_SYNCH_FRAME 0x0C
+#define USBC_REQ_SET_SEL 0x30
+#define USBC_REQ_SET_ISOCHRONOUS_DELAY 0x31
+
+/*!
+ * @brief Vendor Request Codes
+ */
+#define USBC_REQ_GET_MS_DESCRIPTOR 0xCC
+
+/*!
+ * @brief USB Request Types
+ */
+#define USBC_REQUEST_TYPE_MASK (0x03 << 5)
+#define USBC_REQUEST_TYPE_STANDARD (0x00 << 5)
+#define USBC_REQUEST_TYPE_CLASS (0x01 << 5)
+#define USBC_REQUEST_TYPE_VENDOR (0x02 << 5)
+#define USBC_REQUEST_TYPE_RESERVED (0x03 << 5)
+
+
+/*!
+ * @brief USB Request Recipients
+ */
+#define USBC_REQUEST_RECIP_MASK 0x1f
+#define USBC_REQUEST_RECIP_DEVICE 0x00
+#define USBC_REQUEST_RECIP_INTERFACE 0x01
+#define USBC_REQUEST_RECIP_ENDPOINT 0x02
+#define USBC_REQUEST_RECIP_OTHER 0x03
+
+
+/*!
+ * @breif USB Request Directions
+ */
+#define USBC_REQUEST_DIR_OUT 0
+#define USBC_REQUEST_DIR_IN 0x80
+
+/*!
+ * @brief USB Set Features
+ */
+#define USBC_FEATURE_ENDPOINT_HALT 0x00
+#define USBC_FEATURE_FUNCTION_SUSPEND 0x00
+#define USBC_FEATURE_DEVICE_REMOTE_WAKEUP 0x01
+#define USBC_FEATURE_TEST_MODE 0x02
+#define USBC_FEATURE_U1_ENABLE 0x30
+#define USBC_FEATURE_U2_ENABLE 0x31
+#define USBC_FEATURE_LTM_ENABLE 0x32
+
+
+/*!
+ * @brief Device Descriptor Types
+ */
+#define USBC_DT_DEVICE 0x01
+#define USBC_DT_CONFIG 0x02
+#define USBC_DT_STRING 0x03
+#define USBC_DT_INTERFACE 0x04
+#define USBC_DT_ENDPOINT 0x05
+#define USBC_DT_DEVICE_QUALIFIER 0x06
+#define USBC_DT_OTHER_SPEED 0X07
+#define USBC_DT_INTERFACE_POWER 0x08
+#define USBC_DT_OTG 0x09
+#define USBC_DT_IAD 0x0B
+#define USBC_DT_BOS 0x0F
+#define USBC_DT_DEVICE_CAPABILITY 0x10
+#define USBC_DT_ENDPOINT_COMPANION 0x30
+
+
+/*!
+ * @breif USB Request Directions
+ */
+#define USBC_EP_ADDR_DIR_IN 0x80
+#define USBC_EP_ADDR_NUM_MASK 0x7F
+
+
+
+/*!
+ * @brief usbc_setup_packet_t describe the detail field definition of
+ * control setup packet
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_setup_packet {
+ /*!
+ * @brief request type of setup packet
+ * Bit 7: Request direction
+ * (0=Host to device - Out, 1=Device to host - In)
+ * Bits 5-6: Request type
+ * (0=standard, 1=class, 2=vendor, 3=reserved)
+ * Bits 0-4: Recipient
+ * (0=device, 1=interface, 2=endpoint,3=other)
+ */
+ kal_uint8 bmRequestType;
+ /*!
+ * @brief the actual request, see the Standard Device Request Codes table
+ */
+ kal_uint8 bRequest;
+ /*!
+ * @brief a word-size value that varies according to the request
+ */
+ kal_uint16 wValue;
+ /*!
+ * @brief a word-size value that varies according to the request,
+ * the index is generally used to specify an endpoint or
+ * an interface.
+ */
+ kal_uint16 wIndex;
+ /*!
+ * @brief a word-size value that indicates the number of bytes to be
+ * transferred if there is a data stage
+ */
+ kal_uint16 wLength;
+} usbc_setup_packet_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief Device Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_device_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint16 bcdUSB;
+ kal_uint8 bDeviceClass;
+ kal_uint8 bDeviceSubClass;
+ kal_uint8 bDeviceProtocol;
+ kal_uint8 bMaxPacketSize0;
+ kal_uint16 idVendor;
+ kal_uint16 idProduct;
+ kal_uint16 bcdDevice;
+ kal_uint8 iManufacturer;
+ kal_uint8 iProduct;
+ kal_uint8 iSerialNumber;
+ kal_uint8 bNumConfigurations;
+} usbc_device_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+#define USBC_DEVICE_DESC_SIZE sizeof(usbc_device_descriptor_t)
+
+/*!
+ * @brief Configuration Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_configuration_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint16 wTotalLength;
+ kal_uint8 bNumInterfaces;
+ kal_uint8 bConfigurationValue;
+ kal_uint8 iConfiguration;
+ kal_uint8 bmAttributes;
+ kal_uint8 bMaxPower;
+} usbc_configuration_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+#define USBC_CONFIGURATION_DESC_SIZE sizeof(usbc_configuration_descriptor_t)
+#define USBC_MAX_CONF_SIZE 1024
+#define USBC_USB20_POWER_DESC_UINT 2 /* 2 mA unit */
+#define USBC_USB30_POWER_DESC_UINT 8 /* 8 mA unit */
+#define USBC_USB30_EP0_PACKET_SIZE 9 /* in power of 2 */
+
+#define USBC_GET_CONF_TOTAL_LENGTH(_desc) \
+ USBC_GET_UINT16(_desc, 2)
+#define USBC_SET_CONF_TOTAL_LENGTH(_desc, _value) \
+ USBC_SET_UINT16(_desc, 2, _value)
+
+#define USBC_GET_CONF_MAX_POWER(_desc) \
+ USBC_GET_UINT8(_desc, 8)
+#define USBC_SET_CONF_MAX_POWER(_desc, _value) \
+ USBC_SET_UINT8(_desc, 8, _value)
+
+
+/*!
+ * @brief Interface Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_interface_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 bInterfaceNumber;
+ kal_uint8 bAlternateSetting;
+ kal_uint8 bNumEndpoints;
+ kal_uint8 bInterfaceClass;
+ kal_uint8 bInterfaceSubClass;
+ kal_uint8 bInterfaceProtocol;
+ kal_uint8 iInterface;
+} usbc_interface_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief Interface Association Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_interface_association_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 bFirstInterface;
+ kal_uint8 bInterfaceCount;
+ kal_uint8 bFunctionClass;
+ kal_uint8 bFunctionSubClass;
+ kal_uint8 bFunctionProtocol;
+ kal_uint8 iFunction;
+} usbc_interface_association_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief Endpoint Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_endpoint_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 bEndpointAddress;
+ kal_uint8 bmAttributes;
+ kal_uint16 wMaxPacketSize;
+ kal_uint8 bInterval;
+} usbc_endpoint_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+#define USBC_GET_EP_ATTRIBUTES(_desc) \
+ USBC_GET_UINT8(_desc, 3)
+#define USBC_SET_EP_ATTRIBUTES(_desc, _value) \
+ USBC_SET_UINT8(_desc, 3, _value)
+
+#define USBC_GET_EP_MAX_PACKET_SIZE(_desc) \
+ USBC_GET_UINT16(_desc, 4)
+#define USBC_SET_EP_MAX_PACKET_SIZE(_desc, _value) \
+ USBC_SET_UINT16(_desc, 4, _value)
+
+#define USBC_GET_EP_ADDR(_desc) \
+ USBC_GET_UINT16(_desc, 2)
+
+#define USBC_CONTROL_TRANSFER 0x00
+#define USBC_ISOCHRONOUS_TRANSFER 0x01
+#define USBC_BULK_TRANSFER 0x02
+#define USBC_INTERRUPT_TRANSFER 0x03
+
+#define USBC_GET_EP_TRANSFER_TYPE(_desc) \
+ (USBC_GET_EP_ATTRIBUTES(_desc) & 0x03)
+
+#define USBC_USB30_BULK_PACKET_SIZE 1024
+
+/*!
+ * @brief String Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_string_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint16 wData[1];
+} usbc_string_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief Qualifier Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_device_qualifier_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint16 bcdUSB;
+ kal_uint8 bDeviceClass;
+ kal_uint8 bDeviceSubClass;
+ kal_uint8 bDeviceProtocol;
+ kal_uint8 bMaxPacketSize0;
+ kal_uint8 bNumConfigurations;
+ kal_uint8 bRESERVED;
+} usbc_device_qualifier_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief CS Header Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_cs_header_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 bDescriptorSubType;
+ kal_uint16 bcdCDC;
+} usbc_cs_header_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief CS Call Manage Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_cs_call_manager_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 bDescriptorSubType;
+ kal_uint8 bmCapabilities;
+ kal_uint8 bDataInterface;
+} usbc_cs_call_manage_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief CS Abstract Control Manage Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_cs_abstract_control_manage_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 bDescriptorSubType;
+ kal_uint8 bmCapabilities;
+} usbc_cs_abstract_control_manage_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief CS Union Function Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_cs_union_function_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 bDescriptorSubType;
+ kal_uint8 bMasterInterface;
+ kal_uint8 bSlaveInterface;
+} usbc_cs_union_function_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+
+/*!
+ * @brief CS Ethernet Networking Function Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_cs_ethernet_networking_function_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 bDescriptorSubType;
+ kal_uint8 iMACAddress;
+ kal_uint32 bmEthernetStatistics;
+ kal_uint16 wMaxSegmentSize;
+ kal_uint16 wNumberMCFilters;
+ kal_uint8 bNumberPowerFilters;
+} usbc_cs_ethernet_networking_function_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+/*!
+ * @brief Microsoft OS String Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_os_string_descriptor {
+ kal_uint8 bLength;
+ kal_uint8 bDescriptorType;
+ kal_uint8 qwSignature[14];
+ kal_uint8 bMS_VendorCode;
+ kal_uint8 bPad;
+} usbc_os_string_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+/*!
+ * @brief Microsoft OS String Descriptor Structure
+ */
+PRAGMA_BEGIN_PACK_STRUCT
+typedef struct _usbc_ext_compat_id_os_feature_descriptor {
+ kal_uint32 dwLength;
+ kal_uint16 bcdVersion;
+ kal_uint16 wIndex;
+ kal_uint8 bCount;
+ kal_uint8 bPads_1[7];
+ kal_uint8 bFirstInterfaceNumber;
+ kal_uint8 bInterfaceCount;
+ kal_uint8 compatibleID[8];
+ kal_uint8 subcompatibleID[8];
+ kal_uint8 bPads_2[6];
+} usbc_ext_compat_id_os_feature_descriptor_t;
+PRAGMA_END_PACK_STRUCT
+
+/*
+ * USB 3.0 BOS descriptor.
+ */
+#define USBC_BOS_DESC_SIZE 5
+#define USBC_MAX_BOS_SIZE \
+ ( USBC_BOS_DESC_SIZE + \
+ USBC_SUPERSPEED_USB_DEV_CAP_DESC_SIZE + \
+ USBC_USB20_EXT_DEV_CAP_DESC_SIZE )
+
+#define USBC_GET_BOS_TOTAL_LENGTH(_desc) \
+ USBC_GET_UINT16(_desc, 2)
+#define USBC_SET_BOS_TOTAL_LENGTH(_desc, _value) \
+ USBC_SET_UINT16(_desc, 2, _value)
+
+/*
+ * USB 2.0 Extension descriptor.
+ */
+#define USBC_USB20_EXT_DEV_CAP_DESC_SIZE 7
+
+/*
+ * SuperSpeed USB Device Capabilities descriptor.
+ */
+#define USBC_SUPERSPEED_USB_DEV_CAP_DESC_SIZE 10
+
+/*
+ * SuperSpeed Endpoint Companion descriptor.
+ */
+#define USBC_ENDPOINT_COMPANION_DESC_SIZE 6
+
+#define USBC_GET_EPC_MAX_BURST(_desc) \
+ USBC_GET_UINT8(_desc, 2)
+#define USBC_SET_EPC_MAX_BURST(_desc, _value) \
+ USBC_SET_UINT8(_desc, 2, _value)
+
+#define USBC_GET_EPC_ATTRIBUTES(_desc) \
+ USBC_GET_UINT8(_desc, 3)
+#define USBC_SET_EPC_ATTRIBUTES(_desc, _value) \
+ USBC_SET_UINT8(_desc, 3, _value)
+
+#define USBC_GET_EPC_BYTES_PER_INTERVAL(_desc) \
+ USBC_GET_UINT16(_desc, 4)
+#define USBC_SET_EPC_BYTES_PER_INTERVAL(_desc, _value) \
+ USBC_SET_UINT16(_desc, 4, _value)
+
+#endif // _USBCORE_USBSTD_H
diff --git a/mcu/middleware/hif/interface/usbidle_if.h b/mcu/middleware/hif/interface/usbidle_if.h
new file mode 100644
index 0000000..9814f15
--- /dev/null
+++ b/mcu/middleware/hif/interface/usbidle_if.h
@@ -0,0 +1,57 @@
+/*!
+ * @file usbidle_main.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main definitions of usbcore
+ */
+
+#ifndef _USBIDLE_IF_H
+#define _USBIDLE_IF_H
+
+typedef struct {
+ LOCAL_PARA_HDR
+ kal_bool notify_suspend;
+ kal_bool notify_suspend_with_remote_wk;
+}usbcore_usbidle_l4_power_saving_req_struct;
+
+void usb_idle_set_clockGating(kal_bool);
+
+void usb_idle_set_l4_power_saving(kal_bool);
+
+void usb_idle_event_notify_to_l4(kal_bool, kal_bool);
+
+#endif // _USBIDLE_IF_H
+
diff --git a/mcu/middleware/hif/ipcore/include/ipc_config.h b/mcu/middleware/hif/ipcore/include/ipc_config.h
new file mode 100644
index 0000000..fa7643a
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_config.h
@@ -0,0 +1,110 @@
+#if defined(__L1_STANDALONE__) || defined(__L1EDPS_ENABLE__)
+#if defined(__LTM_SIMULATION_SUPPORT__)
+IPC_MODULE_ID(MOD_LTM_SIM)
+IPC_MODULE_PREFIX(lms)
+#endif
+#if defined(__ETHERCORE_SUPPORT__)
+IPC_MODULE_ID(MOD_ETHERCORE)
+IPC_MODULE_PREFIX(ethc_core)
+#endif
+#if defined(__DPFM_SUPPORT__)
+IPC_MODULE_ID(MOD_DPFM)
+IPC_MODULE_PREFIX(dpfm)
+#endif
+/*
+ For L1-only mode, L4 related modules are not included.
+
+ __L1_STANDALONE__ : Used in 23G
+ __L1EDPS_ENABLE__ : Used in 4G
+*/
+#else
+
+/************************* IP Core Modue Begin ******************/
+#if defined(__UMTS_RAT__) || defined(__GSM_RAT__)
+IPC_MODULE_ID(MOD_RATDM)
+IPC_MODULE_PREFIX(ratdm_multimode)
+#if defined(__GEMINI__)
+IPC_MODULE_ID(MOD_RATDM_2)
+IPC_MODULE_PREFIX(ratdm_multimode)
+#if (GEMINI_PLUS >= 3)
+IPC_MODULE_ID(MOD_RATDM_3)
+IPC_MODULE_PREFIX(ratdm_multimode)
+#if (GEMINI_PLUS >= 4)
+IPC_MODULE_ID(MOD_RATDM_4)
+IPC_MODULE_PREFIX(ratdm_multimode)
+#endif /* GEMINI_PLUS >= 4 */
+#endif /* GEMINI_PLUS >= 3 */
+#endif /* __GEMINI__ */
+#endif /* __UMTS_RAT__ || __GSM_RAT__ */
+/************************* IP Core Modue End ******************/
+/************************* IP Core Modue Begin ******************/
+IPC_MODULE_ID(MOD_UPCM)
+IPC_MODULE_PREFIX(upcm)
+#ifdef __GEMINI__
+IPC_MODULE_ID(MOD_UPCM_2)
+IPC_MODULE_PREFIX(upcm)
+#if (GEMINI_PLUS >= 3)
+IPC_MODULE_ID(MOD_UPCM_3)
+IPC_MODULE_PREFIX(upcm)
+#if (GEMINI_PLUS >= 4)
+IPC_MODULE_ID(MOD_UPCM_4)
+IPC_MODULE_PREFIX(upcm)
+#endif /* GEMINI_PLUS >= 4 */
+#endif /* GEMINI_PLUS >= 3 */
+#endif /* __GEMINI__ */
+
+
+/************************* IP Core Modue End ******************/
+/************************* IP Core Modue Begin ******************/
+#if defined(__LTM_SIMULATION_SUPPORT__)
+IPC_MODULE_ID(MOD_LTM_SIM)
+IPC_MODULE_PREFIX(lms)
+#endif
+/************************* IP Core Modue End ******************/
+/************************* IP Core Modue Begin ******************/
+#if defined(__LTM_EPDCP_SIMULATION_SUPPORT__)
+IPC_MODULE_ID(MOD_EPDCP)
+IPC_MODULE_PREFIX(ltm_epdcp)
+#endif
+/************************* IP Core Modue End ******************/
+/************************* IP Core Modue Begin ******************/
+#if defined(__TMC_SUPPORT__)
+IPC_MODULE_ID(MOD_TMC)
+IPC_MODULE_PREFIX(tmc)
+#endif
+/************************* IP Core Modue End ******************/
+/************************* IP Core Modue Begin ******************/
+#if defined(__ETHERCORE_SUPPORT__)
+IPC_MODULE_ID(MOD_ETHERCORE)
+IPC_MODULE_PREFIX(ethc_core)
+#endif
+/************************* IP Core Modue End ******************/
+/************************* IP Core Modue Begin ******************/
+#if defined(__DPFM_SUPPORT__)
+IPC_MODULE_ID(MOD_DPFM)
+IPC_MODULE_PREFIX(dpfm)
+#endif
+/************************* IP Core Modue End ******************/
+/************************* IP Core Modue Begin ******************/
+IPC_MODULE_ID(MOD_IPC_FRAGMENT)
+IPC_MODULE_PREFIX(ipc_fragment)
+/************************* IP Core Modue End ******************/
+/************************* IP Core Modue Begin ******************/
+#if defined(__DISPATCHER_SUPPORT__)
+IPC_MODULE_ID(MOD_DISPATCHER)
+IPC_MODULE_PREFIX(dispatcher)
+#ifdef __GEMINI__
+IPC_MODULE_ID(MOD_DISPATCHER_2)
+IPC_MODULE_PREFIX(dispatcher)
+#if (GEMINI_PLUS >= 3)
+IPC_MODULE_ID(MOD_DISPATCHER_3)
+IPC_MODULE_PREFIX(dispatcher)
+#if (GEMINI_PLUS >= 4)
+IPC_MODULE_ID(MOD_DISPATCHER_4)
+IPC_MODULE_PREFIX(dispatcher)
+#endif /* GEMINI_PLUS >= 4 */
+#endif /* GEMINI_PLUS >= 3 */
+#endif /* __GEMINI__ */
+#endif
+/************************* IP Core Modue End ******************/
+#endif /* __L1_STANDALONE__ || __L1EDPS_ENABLE__ */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_data.h b/mcu/middleware/hif/ipcore/include/ipc_data.h
new file mode 100644
index 0000000..846b928
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_data.h
@@ -0,0 +1,912 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2016
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_data.h
+ *
+ * Project:
+ * --------
+ * UMOLYA
+ *
+ * Description:
+ * ------------
+ * IP Core Uplink/Downlink data path implementation.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_DATA_H
+#define __INC_IPC_DATA_H
+
+#include "kal_public_api.h"
+#include "upcm.h"
+#include "upcm_did.h"
+#include "dpcopro_custom.h"
+#include "dispatcher_if.h"
+
+#include "ipc_defs.h"
+#include "ipc_struct.h"
+#include "lms_api.h"
+#include "el2_public_api.h"
+
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+#define IPC_PROXY_IPV6_RA_POOL_SIZE 256
+
+/* Free Copro vrb helper macro */
+#define IPC_FREE_META_VRB(_meta) \
+ do { \
+ IPC_ASSERT(_meta); \
+ IPC_UL_PKT_DUMP(_meta->vrb_addr, _meta->length); \
+ copro_vrb_release(_meta->vrb_addr, _meta->length, VRB_USER_IPCORE_TASK); \
+ } while (0)
+
+/* Free DID list w/ data ptr helper macro */
+#define IPC_FREE_DID_W_DATABUF(_did_head, _did_tail, _hif_type) \
+ do { \
+ ipc_utils_pkt_dump_did(_did_head, _did_tail, _hif_type); \
+ upcm_did_dest_q_free_buf(_did_head, _did_tail); \
+ } while (0);
+
+/* Allocate & Free prb helper macro */
+#define IPC_PRB_DL_ID PRB_TYPE_DL_IP_FRAG
+#define IPC_ALLOCATE_PRBM prbm_allocate
+#define IPC_FREE_PRBM prbm_release
+
+#if IPC_PEER==IPC_PEER_LTM_SIM
+ #if defined(__LTM_SIMULATION_SUPPORT__)
+ #define _IPC_REG_CBK_DLVR_DL_SDU lms_reg_cbk_dlvr_dl_sdu
+ #define _IPC_REG_CBK_NOTIFY_LTE_TICK_SOURCE lms_reg_cbk_notify_tick_source
+ #define _IPC_FORWARD_UL_SDU lms_rcv_ul_sdu
+ #define _IPC_FORWARD_UL_SDU_BY_EBI lms_rcv_ul_sdu_by_ebi
+ #define _IPC_FORWARD_UL_META lms_rcv_ul_sdu_meta
+ #define _IPC_QUERY_META_TABLE lhif_query_meta_table
+ #define _IPC_FORCED_SW_PATH_BY_PDN lms_forced_sw_path_by_pdn
+ #define _IPC_FORCED_SW_PATH_BY_EBI lms_forced_sw_path_by_ebi
+ #define _IPC_FORCED_SW_PATH_ALL lms_forced_sw_path_all
+ #define _IPC_NOTIFY_L2_STATS enpdcp_ipcore_unknown_header_statistics
+ #define _IPC_SEND_RA_DL(_p_head_gpd, _netif_id) ipc_send_dl_pkt_enqueue(_p_head_gpd, _netif_id, IPC_IP_TYPE_IPV6)
+ #else
+ #define "Please define turn on LTM_SIMULATION_SUPPORT while setting IPC_PEER as IPC_PEER_LTM_SIM!"
+ #endif
+#elif IPC_PEER==IPC_PEER_UPCM
+ #define _IPC_REG_CBK_DLVR_DL_SDU upcm_reg_cbk_dlvr_dl_sdu
+ #define _IPC_REG_CBK_NOTIFY_LTE_TICK_SOURCE upcm_reg_cbk_notify_lte_tick
+ #define _IPC_FORWARD_UL_SDU upcm_rcv_ul_sdu_93_gpd
+ #define _IPC_FORWARD_UL_SDU_BY_EBI upcm_rcv_ul_sdu_by_ebi_93_gpd
+ #define _IPC_FORWARD_UL_META upcm_rcv_ul_sdu_93
+ #define _IPC_QUERY_META_TABLE lhif_query_meta_table
+ #define _IPC_FORCED_SW_PATH_BY_PDN upcm_forced_sw_path_by_pdn
+ #define _IPC_FORCED_SW_PATH_BY_EBI upcm_forced_sw_path_by_ebi
+ #define _IPC_FORCED_SW_PATH_ALL upcm_forced_sw_path_all
+ #define _IPC_NOTIFY_L2_STATS enpdcp_ipcore_unknown_header_statistics
+ #define _IPC_SEND_RA_DL(_p_head_gpd, _netif_id) tcpip_rsra_proxy_bind_complete(_p_head_gpd, _netif_id)
+#elif IPC_PEER==IPC_PEER_UT
+ #define _IPC_REG_CBK_DLVR_DL_SDU ipc_ut_reg_cbk_dlvr_dl_sdu
+ #define _IPC_REG_CBK_NOTIFY_LTE_TICK_SOURCE ipc_ut_reg_cbk_notify_tick_source
+ #define _IPC_FORWARD_UL_SDU ipc_ut_rcv_ul_sdu
+ #define _IPC_FORWARD_UL_SDU_BY_EBI ipc_ut_rcv_ul_sdu_by_ebi
+ #define _IPC_FORWARD_UL_META ipc_ut_rcv_ul_sdu_meta
+ #define _IPC_QUERY_META_TABLE ipc_ut_query_meta_table
+ #define _IPC_FORCED_SW_PATH_BY_PDN(...)
+ #define _IPC_FORCED_SW_PATH_BY_EBI(...)
+ #define _IPC_FORCED_SW_PATH_ALL(...)
+ #define _IPC_NOTIFY_L2_STATS ipc_ut_notify_l2
+ #define _IPC_SEND_RA_DL(_p_head_gpd, _netif_id) ipc_send_dl_pkt_enqueue(_p_head_gpd, _netif_id, IPC_IP_TYPE_IPV6)
+
+ #undef IPC_FREE_META_VRB
+ #define IPC_FREE_META_VRB
+ #define upcm_did_dest_q_free_buf upcm_did_dest_q
+#elif IPC_PEER==IPC_PEER_NULL_DROP || IPC_PEER==IPC_PEER_NULL_LOOPBACK
+ #define _IPC_REG_CBK_DLVR_DL_SDU(...)
+ #define _IPC_REG_CBK_NOTIFY_LTE_TICK_SOURCE(...)
+ #define _IPC_FORWARD_UL_SDU(...)
+ #define _IPC_FORWARD_UL_SDU_BY_EBI(...)
+ #define _IPC_FORWARD_UL_META(...)
+ #define _IPC_QUERY_META_TABLE(...)
+ #define _IPC_FORCED_SW_PATH_BY_PDN(...)
+ #define _IPC_FORCED_SW_PATH_BY_EBI(...)
+ #define _IPC_FORCED_SW_PATH_ALL(...)
+ #define _IPC_NOTIFY_L2_STATS enpdcp_ipcore_unknown_header_statistics
+ #define _IPC_SEND_RA_DL(_p_head_gpd, _netif_id) ipc_send_dl_pkt_enqueue(_p_head_gpd, _netif_id, IPC_IP_TYPE_IPV6)
+#elif IPC_PEER==IPC_PEER_DISPATCHER
+ #define _IPC_REG_CBK_DLVR_DL_SDU ipc_reg_cbk_dlvr_dl_did
+ #define _IPC_REG_CBK_NOTIFY_LTE_TICK_SOURCE upcm_reg_cbk_notify_lte_tick
+ #define _IPC_FORWARD_UL_SDU dispatcher_rcv_ul_gpd_by_pdn
+ #define _IPC_FORWARD_UL_SDU_BY_EBI dispatcher_rcv_ul_gpd_by_ebi
+ #define _IPC_FORWARD_UL_META dispatcher_rcv_ul_meta_queue
+ #define _IPC_QUERY_META_TABLE lhif_query_meta_table
+ #define _IPC_FORCED_SW_PATH_BY_PDN upcm_forced_sw_path_by_pdn
+ #define _IPC_FORCED_SW_PATH_BY_EBI upcm_forced_sw_path_by_ebi
+ #define _IPC_FORCED_SW_PATH_ALL upcm_forced_sw_path_all
+ #define _IPC_NOTIFY_L2_STATS enpdcp_ipcore_unknown_header_statistics
+ #define _IPC_SEND_RA_DL(_p_head_gpd, _netif_id) tcpip_rsra_proxy_bind_complete(_p_head_gpd, _netif_id)
+#else
+ #error "Unknown peer module of IPCORE!"
+#endif
+
+#define IPC_REG_CBK_DLVR_DL_SDU _IPC_REG_CBK_DLVR_DL_SDU
+#define IPC_REG_CBK_NOTIFY_LTE_TICK_SOURCE _IPC_REG_CBK_NOTIFY_LTE_TICK_SOURCE
+#define IPC_FORWARD_UL_SDU(_ip_type, _pdn_id, _p_head, _p_tail) \
+ do { \
+ kal_uint32 _pdn_id_tmp = _pdn_id; \
+ kal_uint8 _proto_idx; \
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(_pdn_id_tmp, _proto_idx); \
+ IPC_UNMASK_PROTOID_FROM_PDNID(_pdn_id_tmp); \
+ ipc_utils_pkt_dump_buff_gpd_list(_p_head, _p_tail, KAL_TRUE); \
+ _IPC_FORWARD_UL_SDU(_ip_type, _pdn_id_tmp, _p_head, _p_tail, _proto_idx); \
+ } while (0)
+#define IPC_FORWARD_UL_SDU_BY_EBI(_ebi, _p_head, _p_tail) \
+ do { \
+ kal_uint32 _ebi_tmp = _ebi; \
+ kal_uint8 _proto_idx; \
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(_ebi_tmp, _proto_idx); \
+ IPC_UNMASK_PROTOID_FROM_PDNID(_ebi_tmp); \
+ ipc_utils_pkt_dump_buff_gpd_list(_p_head, _p_tail, KAL_TRUE); \
+ _IPC_FORWARD_UL_SDU_BY_EBI(_ebi_tmp, _p_head, _p_tail, _proto_idx); \
+ } while (0)
+#define IPC_FORWARD_UL_META(_start_idx, _end_idx, _q_type) \
+ do { \
+ _IPC_FORWARD_UL_META(_start_idx, _end_idx, _q_type); \
+ } while (0)
+#define IPC_QUERY_META_TABLE _IPC_QUERY_META_TABLE
+#define IPC_FORCED_SW_PATH_BY_PDN(_pdn_id, _is_set) \
+ do { \
+ kal_uint32 _pdn_id_tmp = _pdn_id; \
+ kal_uint8 _proto_idx; \
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(_pdn_id_tmp, _proto_idx); \
+ IPC_UNMASK_PROTOID_FROM_PDNID(_pdn_id_tmp); \
+ _IPC_FORCED_SW_PATH_BY_PDN(_pdn_id_tmp, _is_set, _proto_idx); \
+ } while (0)
+#define IPC_FORCED_SW_PATH_BY_EBI(_ebi, _is_set) \
+ do { \
+ kal_uint32 _ebi_tmp = _ebi; \
+ kal_uint8 _proto_idx; \
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(_ebi_tmp, _proto_idx); \
+ IPC_UNMASK_PROTOID_FROM_PDNID(_ebi_tmp); \
+ _IPC_FORCED_SW_PATH_BY_EBI(_ebi_tmp, _is_set, _proto_idx); \
+ } while (0)
+#define IPC_FORCED_SW_PATH_ALL _IPC_FORCED_SW_PATH_ALL
+#define IPC_SEND_RA_DL(_p_head_gpd, _netif_id) \
+do { \
+ _IPC_SEND_RA_DL(_p_head_gpd, _netif_id); \
+} while (0)
+
+/*------------------------------------------------------------------------------
+ * Internal data structure defintion.
+ *----------------------------------------------------------------------------*/
+typedef struct _ipc_internal_ior_t {
+ ipc_io_request_t io_req;
+ union {
+ ipc_netif_t *netif;
+ kal_uint8 ebi;
+ kal_uint8 pdn;
+ kal_uint32 netif_id;
+ };
+} ipc_internal_ior_t;
+
+typedef struct _ipc_dlq_ior_t {
+ ipc_netif_t *netif;
+ ipc_session_t *session;
+ kal_uint32 netif_id;
+ kal_uint32 session_type;
+} ipc_dlq_ior_t;
+
+typedef enum _ipc_ul_queue_type_e {
+ IPC_UL_QUEUE_TYPE_IOR,
+ IPC_UL_QUEUE_TYPE_META,
+ IPC_UL_QUEUE_TYPE_MAX,
+} ipc_ul_queue_type_e;
+
+typedef enum _ipc_ul_queue_priority_e {
+ IPC_UL_QUEUE_PRIORITY_HIGH,
+ IPC_UL_QUEUE_PRIORITY_LOW,
+ IPC_UL_QUEUE_PRIORITY_MAX,
+} ipc_ul_queue_priority_e;
+
+typedef struct _ipc_ul_queue_t ipc_ul_queue_t;
+typedef struct _ipc_ul_queue_t {
+ IPC_DECLARE_OBJECT
+
+ ipc_ul_queue_type_e queue_type;
+ ipc_ul_queue_priority_e priority;
+ kal_uint32 cnt; // Totol count of IOR/meta in this queue.
+ kal_uint32 pending_cnt; // Pending count of IOR/meta in this queue.
+ union {
+ struct {
+ ipc_internal_ior_t *ior_head;
+ ipc_internal_ior_t *ior_tail;
+ };
+ struct {
+ kal_int32 meta_head;
+ kal_int32 meta_tail;
+ kal_int32 meta_queue_size;
+ LHIF_QUEUE_TYPE meta_queue_type;
+ };
+ };
+ void (*ipc_clear_callback_t)(ipc_ul_queue_t *ul_queue);
+ void (*ipc_process_callback_t)(ipc_ul_queue_t *ul_queue);
+} ipc_ul_queue_t;
+
+#define _IPC_GET_UL_QUEUE_INDEX(_q_type, _q_priority) ((_q_type * IPC_UL_QUEUE_PRIORITY_MAX) + _q_priority)
+
+#define IPC_UL_QUEUE_NUM (IPC_UL_QUEUE_TYPE_MAX * IPC_UL_QUEUE_PRIORITY_MAX)
+#define IPC_QUEUE_META_INVALID_VALUE -1
+#define IPC_DL_QUEUE_NUM (IPC_MAX_SESSION_CNT + 1)
+#define IPC_DL_NON_PDN_QUEUE_IDX (IPC_DL_QUEUE_NUM - 1)
+#define IPC_DL_QUEUE_DID_MAP_SIZE 3
+
+typedef enum _ipc_did_queue_type_e {
+ IPC_DID_QUEUE_TYPE_DEFAULT, /*< it was normal DL path, it will enter filter stage */
+ IPC_DID_QUEUE_TYPE_WO_FILTER, /*< it will not entered filter stage */
+ IPC_DID_QUEUE_TYPE_DPFM, /*< it was ued for DPFM */
+ IPC_DID_QUEUE_TYPE_USB_PATH, /*< it was MD internal DL path, it was not entered filter stage */
+ IPC_DID_QUEUE_TYPE_MAX,
+} ipc_did_queue_type_e;
+
+typedef struct _ipc_did_queue_t {
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 si_index; //current si index for tail DID
+} ipc_did_queue_t;
+
+typedef struct _ipc_dl_queue_t {
+ ipc_did_queue_t did_queues[IPC_DID_QUEUE_TYPE_MAX];
+} ipc_dl_queue_t;
+
+typedef enum _ipc_test_loopback_mode_e {
+ IPC_TEST_LOOPBACK_MODE_OFF,
+ IPC_TEST_LOOPBACK_MODE_A,
+ IPC_TEST_LOOPBACK_MODE_B,
+} ipc_test_loopback_mode_e;
+
+typedef struct _ipc_meta_info_des {
+ kal_uint32 len;
+ kal_uint16 psn_countL;
+ void *addr;
+} ipc_meta_info_des;
+
+#if defined(__MD97__)
+
+#define IPC_DATA_RQ_INFO_TABLE_NUM 128 /*< Assume "MTBL_ENTRY_NUM_DL_IPF = 1" */
+#define IPC_DATA_GET_QFI(val) (val & 0x3F)
+#define IPC_DATA_GET_RQI(val) ((val & 0x40) >> 6)
+
+typedef enum _ipc_data_src_qfi_e {
+ IPC_DATA_QFI_SRC_IPF_META,
+ IPC_DATA_QFI_SRC_DL_DID,
+} ipc_data_src_qfi_e;
+
+typedef struct _ipc_data_rq_info_list {
+ kal_uint32 cnt;
+ ipc_rq_info_t rq_info_list[IPC_DATA_RQ_INFO_TABLE_NUM];
+} ipc_data_rq_info_list;
+
+#endif
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+extern kal_uint32 ipc_em_on_s;
+extern ipc_test_loopback_mode_e ipc_test_loopback_mode_s;
+extern kal_uint32 ipc_test_loopback_a_netif_id_s;
+extern kal_uint32 ipc_test_loopback_b_netif_id_s;
+extern kal_bool ipc_ul_processing_s;
+extern kal_bool ipc_ul_reload_retrying_s;
+extern event_scheduler *ipc_es_ul_throttle_s; /* Timer for UL throttle mechanism. */
+
+/*------------------------------------------------------------------------------
+ * General Function prototype.
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Init uplink and downlink queue structures
+ *
+ * @return return KAL_TRUE when succeeded, otherwise return KAL_FALSE.
+ */
+kal_bool ipc_queue_init();
+
+/*
+ * Check whether uplink queues are empty or not.
+ *
+ * @return return KAL_TRUE if empty, otherwise return KAL_FALSE.
+ *
+ * @note ipc_spinlock_g is acquired. This function should be very light. MUST NOT do any heavy jobs.
+ */
+kal_bool ipc_are_ul_queues_empty();
+
+/*
+ * Get IP TYPE from packet header (do cache invalidation automatically).
+ *
+ * @return return IPC_IP_TYPE_IPV4 / IPC_IP_TYPE_IPV6 according to IP_TYPE. Otherwise return IPC_IP_TYPE_INVALID.
+ *
+ * @note
+ */
+kal_uint8 ipc_get_ip_type_from_meta(lhif_meta_tbl_t *meta);
+
+/*
+ * Obtain netif id from UL LHIF meta info (net_type & channel_id).
+ *
+ * @return return netif_id.
+ *
+ * @note
+ */
+kal_uint32 ipc_get_netif_id_from_meta(kal_uint8 net_type, kal_uint8 channel_id);
+
+/*
+ * Get session context based on netif id.
+ *
+ * @return void.
+ *
+ * @note
+ */
+void ipc_get_pdn_id_from_netif(kal_uint32 *ipv4_pdn_id, kal_uint32 *ipv6_pdn_id, ipc_netif_t *netif);
+
+/*------------------------------------------------------------------------------
+ * Uplink Function prototype.
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Fill PDN id into Uplink META.
+ *
+ * @param ip_type [IN] The IP type of the packet.
+ * @param ipv4_pdn_id [IN] The PDN id of IPv4 session.
+ * @param ipv6_pdn_id [IN] The PDN id of IPv6 session.
+ * @param netif_id [IN] the identify of the NETIF which the META comes from.
+ * @param meta [IN] The META descriptor pointer of the packet.
+ */
+void ipc_fill_session_info_into_meta(kal_uint8 ip_type, kal_uint32 ipv4_pdn_id, kal_uint32 ipv6_pdn_id, kal_uint32 netif_id, lhif_meta_tbl_t *meta);
+
+/**
+ * Enqueue IOR list to Uplink IOR queue.
+ * This function will be called by ipc_uplink().
+ *
+ * @param head_ior [IN] The head of the IOR list.
+ * @param tail_ior [IN] The tail of the IOR list.
+ * @param ior_cnt [IN] The number of the IOR in IOR list.
+ * @param q_priority [IN] The priority of the IOR queue.
+ */
+void ipc_push_ior_list_to_ior_queue(ipc_io_request_t *head_ior, ipc_io_request_t *tail_ior, kal_uint32 ior_cnt, ipc_ul_queue_priority_e q_priority);
+
+/**
+ * Enqueue META list to Uplink META queue.
+ * This function will be called by ipc_meta_uplink().
+ *
+ * @param start_idx [IN] The started index of the META list.
+ * @param end_idx [IN] The ended index of the META list.
+ * @param q_type [IN] The type of the LHIF queue where the META comes from.
+ */
+void ipc_push_meta_list_to_meta_queue(kal_uint16 start_idx, kal_uint16 end_idx, LHIF_QUEUE_TYPE q_type);
+
+/**
+ * Uplink data path entrance function of IPCore context.
+ * Check, process and forward each uplink queue.
+ */
+void ipc_on_process_ul_queue(void);
+
+/**
+ * Retry reloading uplink RxGPD queue of netifs
+ */
+void ipc_on_retry_ul_reload(void);
+
+/*------------------------------------------------------------------------------
+ * Downlink Function prototype.
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Dequeue DID list from internal Downlink DID queue.
+ *
+ * @param pp_did_head [OUT] Head of a list of DIDs.
+ * @param pp_did_tail [OUT] Tail of a list of DIDs.
+ * @param pp_si_idx [OUT] sit index of DIDs.
+ * @param pdn_id [IN] queue index.
+ * @param queue_type [IN] Downlink queue type of the queue.
+ */
+void ipc_did_internal_queue_dequeue(upcm_did **pp_did_head, upcm_did **pp_did_tail, kal_uint32 **pp_si_idx, kal_uint8 pdn_id, ipc_did_queue_type_e queue_type);
+
+/**
+ * Enqueue DID list to Downlink DID IPC_DID_QUEUE_TYPE_WO_FILTER queue.
+ *
+ * @param did_head [IN] Head of a list of DIDs.
+ * @param did_tail [IN] Tail of a list of DIDs.
+ * @param queue_idx [IN] Downlink queue index of the queue.
+ * @param position [IN] enqueue did to tail or head.
+ */
+void ipc_did_enqueue_wo_filter_queue(upcm_did *did_head, upcm_did *did_tail, kal_uint32 queue_idx, ipc_data_enq_position_e position);
+
+/**
+ * Enqueue DID list to Downlink DID IPC_DID_QUEUE_TYPE_DPFM queue.
+ *
+ * @param did_head [IN] Head of a list of DIDs.
+ * @param did_tail [IN] Tail of a list of DIDs.
+ * @param queue_idx [IN] Downlink queue index of the queue.
+ * @param position [IN] enqueue did to tail or head.
+ */
+void ipc_did_enqueue_dpfm_queue(upcm_did *did_head, upcm_did *did_tail, kal_uint32 queue_idx, ipc_data_enq_position_e position);
+
+
+/**
+ * Enqueue DID list to Downlink DID IPC_DID_QUEUE_TYPE_DEFAULT queue.
+ *
+ * @param did_head [IN] Head of a list of DIDs.
+ * @param did_tail [IN] Tail of a list of DIDs.
+ * @param queue_idx [IN] Downlink queue index of the queue.
+ * @param position [IN] enqueue did to tail or head.
+ */
+void ipc_did_enqueue_default_queue(upcm_did *did_head, upcm_did *did_tail, kal_uint32 queue_idx, ipc_data_enq_position_e position);
+
+/**
+ * Downlink retry function.
+ * Try to re-send DID to netif which can't receive DID in last time.
+ */
+void ipc_on_process_dl_queue(void);
+
+/**
+ * Downlink data path entrance function.
+ *
+ * @param pdn_id [IN] PDN ID where the GPD's come from.
+ * @param p_head [IN] Head of a list of GPDs.
+ * @param p_tail [IN] Tail of a list of GPDs.
+ */
+void ipc_on_downlink(kal_uint32 pdn_id, qbm_gpd *p_head, qbm_gpd *p_tail);
+
+/**
+ * Downlink data path entrance function (Multiple PS version).
+ *
+ * @param pdn_id [IN] PDN ID where the GPD's come from.
+ * @param p_head [IN] Head of a list of GPDs.
+ * @param p_tail [IN] Tail of a list of GPDs.
+ * @param proto_idx [IN] The index to distinquish from different SIM Card.
+ */
+void ipc_on_downlink_multiple_ps(kal_uint32 pdn_id, qbm_gpd *p_head, qbm_gpd *p_tail, kal_uint8 proto_idx);
+
+/**
+ * Downlink data path entrance function (Gen93).
+ *
+ * @param pdn_id [IN] PDN ID where the DID's come from.
+ * @param queue_type [IN] The type of DID queue.
+ * @param did_head [IN] Head of a list of DIDs.
+ * @param did_tail [IN] Tail of a list of DIDs.
+ */
+void ipc_on_did_downlink(kal_uint32 pdn_id, ipc_did_queue_type_e queue_type, upcm_did *did_head, upcm_did *did_tail);
+
+/**
+ * Downlink data path entrance function (Gen93 Multiple PS version).
+ *
+ * @param pdn_id [IN] PDN ID where the DID's come from.
+ * @param did_head [IN] Head of a list of DIDs.
+ * @param did_tail [IN] Tail of a list of DIDs.
+ * @param proto_idx [IN] The index to distinquish from different SIM Card.
+ */
+void ipc_on_did_downlink_multiple_ps(kal_uint32 pdn_id, upcm_did *did_head, upcm_did *did_tail, kal_uint8 proto_idx);
+
+/**
+ * Downlink data path entrance function (Gen93).
+ *
+ * @param pdn_id [IN] PDN ID where the DID's come from.
+ * @param did_head [IN] Head of a list of DIDs.
+ * @param did_tail [IN] Tail of a list of DIDs.
+ * @param proto_idx [IN] The index to distinquish from different SIM Card.
+ */
+void ipc_on_did_downlink_test_mode(kal_uint32 pdn_id, upcm_did *did_head, upcm_did *did_tail, kal_uint8 proto_idx);
+
+/**
+ * Downlink data path entrance function (Gen93).
+ *
+ * @param pdn_id [IN] PDN ID where the DID's come from.
+ * @param did_head [IN] Head of a list of DIDs.
+ * @param did_tail [IN] Tail of a list of DIDs.
+ */
+void ipc_did_downlink_enqueue(kal_uint32 pdn_id, upcm_did *did_head, upcm_did *did_tail);
+
+/**
+ * Downlink data path entrance function (Gen93).
+ */
+void ipc_did_downlink_dequeue();
+
+/**
+ * Downlink data path entrance function (QBM).
+ *
+ * @param pdn_id [IN] PDN ID where the GPD's come from.
+ * @param head [IN] Head of a list of GPDs.
+ * @param tail [IN] Tail of a list of GPDs.
+ */
+void ipc_on_downlink_qbm_enqueue(qbm_gpd *head, qbm_gpd *tail);
+
+/**
+ * Downlink data path entrance function (QBM).
+ */
+void ipc_data_qbm_downlink_dequeue(void);
+
+/**
+ * Clear downlink ILM request flag (take/give spinlock).
+ */
+void ipc_data_clear_dl_ilm_flag();
+
+/**
+ * Check whether sending downlink ILM request (take/give spinlock).
+ * @retval KAL_FALSE no need to send ILM
+ * @retval KAL_TRUE need to send ILM
+ */
+kal_bool ipc_data_check_and_set_dl_ilm_flag();
+
+#if defined(__MD97__)
+/**
+ * Updated rq_info with packet desciptor (Gen97).
+ *
+ * @param p_rq_info updated rq_info struct
+ * @param pdn_id PDN ID
+ * @param p_pkt_info packet descriptor
+ * @param src_qfi QFI source from meta or did
+ * @return return KAL_FALSE if parameters are invalid
+ */
+kal_bool ipc_data_set_rq_info(ipc_rq_info_t *p_rq_info, kal_uint32 pdn_id, ipc_pkt_des_t *p_pkt_info, ipc_data_src_qfi_e src_qfi);
+
+/**
+ * Insert rq_info into rq_info list (Gen97).
+ *
+ * @param p_rq_list updated rq_info list struct
+ * @param p_rq_info updated rq_info struct
+ */
+void ipc_data_saved_rq_info_list(ipc_data_rq_info_list *p_rq_list, ipc_rq_info_t *p_rq_info);
+
+/**
+ * Sent did list to the netif (Gen97).
+ *
+ * @param netif_id sent prepared did list to the netif_id
+ * @param p_did_head did head pointer
+ * @param p_did_tail did tail pointer
+ */
+void ipc_data_dl_enq_by_netif(kal_uint32 netif_id, upcm_did *p_did_head, upcm_did *p_did_tail);
+
+/**
+ * Sent rq_info list to NAS (Gen97).
+ *
+ * @param p_rq_list rq_info struct
+ * @return return KAL_FALSE if parameters are invalid
+ */
+kal_bool ipc_data_send_rq_info(ipc_data_rq_info_list *p_rq_list);
+#endif
+
+/*------------------------------------------------------------------------------
+ * Uplink Data Throttling Function prototype.
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Init throttling timer.
+ */
+void ipc_timer_init();
+
+/**
+ * Function to control throttling states.
+ *
+ * @param local_para_ptr [IN] local parameters of ILM.
+ */
+void ipc_set_ul_throttle(local_para_struct *local_para_ptr);
+
+/**
+ * Function to update throttling status on EM.
+ */
+void ipc_em_send_ul_throttle_status(void);
+
+/**
+ * Function to indicate the status change of IMS emergency call.
+ *
+ * @param local_para_ptr [IN] local parameters of ILM.
+ */
+void ipc_ims_emergency_call_ind_handler(local_para_struct *local_para_ptr);
+
+/**
+ * Function to drop the UL packets when PDN is unbinded and UL is throttled.
+ *
+ * @param pdn_id [IN] unbinded PDN ID.
+ */
+void ipc_data_drop_ul_meta_by_pdn(kal_uint8 pdn_id);
+
+#ifdef ATEST_SYS_IPCORE
+/**
+ * Function to handle timeout event of throttling.
+ *
+ * @param event_hf_param [IN] parameter from event handler callback function
+ */
+void ipc_ul_throttle_timeout(void *event_hf_param);
+#endif
+
+/**
+ * Function to pop RA packet.
+ *
+ * @param pdn_id [IN] queued RA packet's PDN ID.
+ *
+ * @return RA packet's GPD.
+ */
+qbm_gpd* ipc_data_ipv6_ra_pool_pop(kal_uint32 pdn_id);
+
+/**
+ * Function to push RA packet.
+ *
+ * @param pdn_id [IN] queued RA packet's PDN ID.
+ * @param gpd [IN] queued RA packet's GPD.
+ *
+ */
+void ipc_data_ipv6_ra_pool_push(kal_uint32 pdn_id, qbm_gpd* gpd);
+
+/**
+ * Function to get data-usage for pdn_sim_id
+ *
+ * @param pdn_sim_id [IN] PDN ID + SIM_ID.
+ *
+ * @return pdn_sim_id's data usage.
+ *
+ */
+ipc_data_usage_info_t* ipc_get_data_usage_by_pdn_sim_id(kal_uint32 pdn_sim_id);
+
+/**
+ * Function to store data-usage for netif_id
+ *
+ * @param data_path_direct [IN] data packet's direction
+ * @param ip_type [IN] ip type of packet
+ * @param netif_id [IN] Netif id sent packet
+ * @param data_usage [IN] Data bytes and packet count of sent packet
+ *
+ */
+kal_bool ipc_set_data_usage_by_netif_id(ipc_data_path_direction_e data_path_direct, kal_uint8 ip_type, kal_uint32 netif_id, ipc_data_usage_info_t *data_usage);
+
+/**
+ * Function to store data-usage for pdn_sim_id
+ *
+ * @param data_path_direct [IN] data packet's direction
+ * @param pdn_sim_id [IN] PDN_ID + SIM_Idx of packet
+ * @param data_usage [IN] Data bytes and packet count of sent packet
+ *
+ */
+kal_bool ipc_set_data_usage_by_pdn_sim_id(ipc_data_path_direction_e data_path_direct, kal_uint32 pdn_sim_id, ipc_data_usage_info_t* data_usage);
+
+/**
+ * Function to reset data-usage for pdn_sim_id
+ *
+ * @param pdn_sim_id [IN] PDN ID + SIM_ID.
+ *
+ */
+void ipc_reset_data_usage_by_pdn_sim_id(kal_uint8 pdn_sim_id);
+
+#endif /* __INC_IPC_DATA_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_data_ipf.h b/mcu/middleware/hif/ipcore/include/ipc_data_ipf.h
new file mode 100644
index 0000000..d7d4953
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_data_ipf.h
@@ -0,0 +1,296 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2016
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_hpc.h
+ *
+ * Project:
+ * --------
+ * UMOLYA
+ *
+ * Description:
+ * ------------
+ * IP Core Uplink/Downlink data path implementation with HPC.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_DATA_IPF_H
+#define __INC_IPC_DATA_IPF_H
+
+#include "ipfc_export_plugin_dl_filter.h"
+#include "ipc_dpfm.h"
+
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+
+#if IPC_PEER==IPC_PEER_LTM_SIM
+ #if defined(__LTM_SIMULATION_SUPPORT__)
+ #define _IPC_QUERY_IPF_META_TABLE ipfc_plugin_dl_filter_query_meta_info
+ #define _IPC_FREE_IPF_META ipfc_plugin_dl_filter_release_meta_entry
+ #define _IPC_QUERY_FILTER_ID_BY_IDX ipfc_plugin_dl_filter_query_id_by_index
+ #define _IPC_TAKE_HW_FILTER_TABLE ipfc_plugin_dl_filter_take_tlb
+ #define _IPC_SUBMIT_HW_FILTER_TABLE ipfc_plugin_dl_filter_submit_tlb
+ #define _IPC_PN_MATCH_SETTING ipfc_plugin_dl_filter_set_pn_match
+ #define _IPC_ENABLE_IPF_DL_FILTER ipfc_plugin_dl_filter_enable
+ #define _IPC_IPF_DL_META_THRESHOLD 500
+ #else
+ #define "Please define turn on LTM_SIMULATION_SUPPORT while setting IPC_PEER as IPC_PEER_LTM_SIM!"
+ #endif
+#elif IPC_PEER==IPC_PEER_UPCM || IPC_PEER==IPC_PEER_DISPATCHER
+ #if defined(__IPF_SUPPORT__)
+ #define _IPC_PN_MATCH_SETTING ipfc_plugin_dl_filter_set_pn_match
+ #define _IPC_QUERY_IPF_META_TABLE ipfc_plugin_dl_filter_query_meta_info
+ #define _IPC_FREE_IPF_META ipfc_plugin_dl_filter_release_meta_entry
+ #define _IPC_QUERY_FILTER_ID_BY_IDX ipfc_plugin_dl_filter_query_id_by_index
+ #define _IPC_TAKE_HW_FILTER_TABLE ipfc_plugin_dl_filter_take_tlb
+ #define _IPC_SUBMIT_HW_FILTER_TABLE ipfc_plugin_dl_filter_submit_tlb
+ #define _IPC_ENABLE_IPF_DL_FILTER ipfc_plugin_dl_filter_enable
+ #define _IPC_IPF_DL_META_THRESHOLD 500
+ #else
+ #define _IPC_QUERY_IPF_META_TABLE(...)
+ #define _IPC_FREE_IPF_META(...)
+ #define _IPC_QUERY_FILTER_ID_BY_IDX(...)
+ #define _IPC_TAKE_HW_FILTER_TABLE(...)
+ #define _IPC_SUBMIT_HW_FILTER_TABLE(...)
+ #define _IPC_PN_MATCH_SETTING(...)
+ #define _IPC_ENABLE_IPF_DL_FILTER(...)
+ #define _IPC_IPF_DL_META_THRESHOLD 500
+ #endif
+#elif IPC_PEER==IPC_PEER_UT
+ #define _IPC_QUERY_IPF_META_TABLE ipc_ut_query_ipf_meta_info
+ #define _IPC_FREE_IPF_META ipc_ut_release_ipf_meta_entry
+ #define _IPC_QUERY_FILTER_ID_BY_IDX ipc_ut_ipf_query_filter_id_by_index
+ #define _IPC_TAKE_HW_FILTER_TABLE ipc_ut_ipf_take_filter_tlb
+ #define _IPC_SUBMIT_HW_FILTER_TABLE ipc_ut_ipf_submit_filter_tlb
+ #define _IPC_PN_MATCH_SETTING ipc_ut_ipf_pn_match_setting
+ #define _IPC_ENABLE_IPF_DL_FILTER(...)
+ #define _IPC_IPF_DL_META_THRESHOLD 5
+
+#elif IPC_PEER==IPC_PEER_NULL_DROP || IPC_PEER==IPC_PEER_NULL_LOOPBACK
+ #define _IPC_QUERY_IPF_META_TABLE(...)
+ #define _IPC_FREE_IPF_META(...)
+ #define _IPC_QUERY_FILTER_ID_BY_IDX(...)
+ #define _IPC_TAKE_HW_FILTER_TABLE(...)
+ #define _IPC_SUBMIT_HW_FILTER_TABLE(...)
+ #define _IPC_PN_MATCH_SETTING(...)
+ #define _IPC_ENABLE_IPF_DL_FILTER(...)
+ #define _IPC_IPF_DL_META_THRESHOLD 500
+#else
+ #error "Unknown peer module of IPCORE!"
+#endif
+
+#define IPC_QUERY_IPF_META_TABLE _IPC_QUERY_IPF_META_TABLE
+#define IPC_FREE_IPF_META _IPC_FREE_IPF_META
+#define IPC_QUERY_FILTER_ID_BY_IDX _IPC_QUERY_FILTER_ID_BY_IDX
+#define IPC_TAKE_HW_FILTER_TABLE _IPC_TAKE_HW_FILTER_TABLE
+#define IPC_SUBMIT_HW_FILTER_TABLE _IPC_SUBMIT_HW_FILTER_TABLE
+#define IPC_PN_MATCH_SETTING _IPC_PN_MATCH_SETTING
+#define IPC_ENABLE_IPF_DL_FILTER _IPC_ENABLE_IPF_DL_FILTER
+#define IPC_IPF_DL_META_THRESHOLD _IPC_IPF_DL_META_THRESHOLD
+
+#if IPC_PEER==IPC_PEER_UT || IPC_PEER==IPC_PEER_NULL_DROP || IPC_PEER==IPC_PEER_NULL_LOOPBACK
+#define IPC_FREE_DL_META_PRB ipc_ut_free_ipf_meta_buf
+#else
+#define IPC_FREE_DL_META_PRB(_meta, _dump_len) \
+ do { \
+ kal_uint8* _addr; \
+ kal_uint32 _len; \
+ IPC_ASSERT(_meta); \
+ _addr = (void*)(_meta->addr);\
+ _len = _meta->len;\
+ IPC_DL_PKT_DUMP(_addr, _dump_len); \
+ dpcopro_rbuf_release(_addr, _len);\
+ } while (0)
+#endif
+
+/*------------------------------------------------------------------------------
+ * Internal data structure definition.
+ *----------------------------------------------------------------------------*/
+#define IPC_DL_META_QUEUE_NUM (IPFC_META_QUEUE_MAX)
+#define IPC_UL_META_INVALID_PDN_SIM_ID (0) /*< HW will fill 0 when UL PN match failed */
+#define IPC_HPC_ENTRY_SIZE (128) /*< Number should sync with platform driver */
+#define IPC_PN_NCID_DEFAULT (0x7FF)
+#define IPC_PKT_DUMP_LIMITED_LEN (64)
+
+typedef enum _ipc_hpc_match_result_e {
+ IPC_HPC_MR_MATCH = 0,
+ IPC_HPC_MR_NEW,
+ IPC_HPC_MR_DPFM_MATCH,
+ IPC_HPC_MR_DPFM_MATCH_BUT_NO_NAT,
+ IPC_HPC_MR_DPFM_DEL_CMD_MATCH,
+ IPC_HPC_MR_DPFM_DEL_CMD_MISS,
+ IPC_HPC_MR_DPFM_ADD_CMD,
+ IPC_HPC_MR_UNKNOWN,
+ IPC_HPC_MR_MAX,
+}ipc_hpc_match_result_e;
+
+typedef enum _ipc_hpc_match_action_e {
+ IPC_HPC_MA_INVALID,
+ IPC_HPC_MA_DEFAULT,
+ IPC_HPC_MA_FILTER_MATCH,
+ IPC_HPC_MA_FILTER_DPFM_MATCH,
+ IPC_HPC_MA_MAX,
+}ipc_hpc_match_action_e;
+
+typedef enum _ipc_ipf_dl_match_result_e {
+ IPC_IPF_MR_DIRECT_TO_AP = 0,
+ IPC_IPF_MR_FILTER_MATCH,
+ IPC_IPF_MR_UNKNOWN_HEADER,
+ IPC_IPF_MR_NET_INVALID,
+ IPC_IPF_MR_PN_NO_MATCH,
+ IPC_IPF_MR_DPFM_MATCH,
+ IPC_IPF_MR_DPFM_OPEN_AND_DPFM_NOT_MATCH,
+ IPC_IPF_MR_DPFM_MATCH_BUT_NO_NAT,
+ IPC_IPF_MR_MAX = 8,
+}ipc_ipf_dl_match_result_e;
+
+typedef struct _ipc_hpc_info_tbl_t {
+ kal_bool is_dirty;
+ ipc_packet_info_t packet_info;
+}ipc_hpc_info_tbl_t;
+
+typedef struct _ipc_dl_meta_queue_t ipc_dl_meta_queue_t;
+typedef struct _ipc_dl_meta_queue_t {
+ IPC_DECLARE_OBJECT
+
+ kal_uint32 meta_head;
+ kal_uint32 meta_tail;
+ kal_uint32 meta_size;
+ kal_uint32 cnt;
+ kal_uint32 pending_cnt;
+ ipfc_dl_filter_queue_type meta_queue_type;
+ void (*ipc_clear_callback_t)(ipc_dl_meta_queue_t *queue);
+ void (*ipc_process_callback_t)(ipc_dl_meta_queue_t *queue);
+} ipc_dl_meta_queue_t;
+
+typedef enum _ipc_ipf_pn_match_cmd_e {
+ IPC_IPF_PN_MATCH_BIND = 0,
+ IPC_IPF_PN_MATCH_UNBIND,
+}ipc_ipf_pn_match_cmd_e;
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * General Function prototype.
+ *----------------------------------------------------------------------------*/
+void ipc_meta_downlink_dequeue();
+void ipc_update_pn_match_setting(kal_uint8 pdn_sim_id, kal_uint32 network_interface_id, kal_uint32 ip_type, ipc_ipf_pn_match_cmd_e pnm_cmd);
+void ipc_dl_meta_queue_init();
+kal_uint16 ipc_on_process_ul_hpc_result(kal_uint8 *ip_type, kal_uint32 meta_idx, lhif_meta_tbl_t *meta, kal_uint32 netif_id, ipc_dpfm_mirror_des_t *dpfm_mirror_des);
+kal_bool ipc_on_process_dpfm_cmd_result(kal_uint32 meta_idx, lhif_meta_tbl_t *meta);
+void ipc_hpc_init();
+void ipc_check_and_fill_session_info(kal_uint8 ip_type, kal_uint32 ipv4_pdn_id, kal_uint32 ipv6_pdn_id, kal_uint32 netif_id, lhif_meta_tbl_t *meta);
+void ipc_ipf_drop_packet_handler(kal_uint8* p_packet, kal_uint32 len, kal_uint8 pdn_sim_id);
+void ipc_ipf_dhlr_for_tcp_rst(kal_uint8 *p_packet, ipc_packet_info_t packet_info, kal_uint8 pdn_sim_id);
+void ipc_ipf_dhlr_for_udp_rst(kal_uint8 *p_packet, kal_uint8 pdn_sim_id);
+#endif
diff --git a/mcu/middleware/hif/ipcore/include/ipc_debug.h b/mcu/middleware/hif/ipcore/include/ipc_debug.h
new file mode 100644
index 0000000..02450f8
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_debug.h
@@ -0,0 +1,35 @@
+#ifndef __INC_IPC_DEBUG_H
+#define __INC_IPC_DEBUG_H
+
+#define HIF_DATA_TRACE_ENABLED 1
+
+#if defined(__MTK_TARGET__)
+ #define HIF_CONSOLE_TRACE_ENABLED 0
+#else
+ #define HIF_CONSOLE_TRACE_ENABLED 0
+#endif
+
+#include "hif_trace.h"
+#include "ipc_trace.h"
+#include "TrcMod.h"
+#include "hif_swla.h"
+
+/**
+ * SWLA TAG Notes : only support 3 charactors. each tag should be unique.
+ * IU0 : ipc_uplink
+ * IU1 : ipc_meta_uplink
+ * IU2 : ipc_on_process_ul_queue
+ * IU3 : ipc_on_process_ul_ior_list
+ * IU4 : ipc_on_process_ul_meta_table
+ * IU5 : IPC_FORWARD_UL_META
+ * IDO : ipc_on_downlink
+ * ID1 : ipc_on_did_downlink
+ * ID2 : ipc_meta_downlink
+ * ID3 : ipc_dlink_callback_t
+ * ID4 : ipc_on_process_dl_meta
+ * IF1 : ipc_call_filter_cbk
+ * IM1 : IPC_MDT_TRACK_PACKET
+ * IM2 : IPC_QUERY_MDT_ROUTE
+ */
+
+#endif /* __INC_IPC_DEBUG_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_defs.h b/mcu/middleware/hif/ipcore/include/ipc_defs.h
new file mode 100644
index 0000000..abe670f
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_defs.h
@@ -0,0 +1,479 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_defs.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IP Core internal configuration and data structure definition.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_DEFS_H
+#define __INC_IPC_DEFS_H
+
+#include "kal_public_api.h"
+#include "sim_public_enum.h"
+#include "dispatcher_if.h"
+#include "ipc_session.h"
+#include "ipc_api.h"
+#include "ipc_ut.h"
+
+#define IPC_PEER_NULL_DROP 1
+#define IPC_PEER_NULL_LOOPBACK 2
+#define IPC_PEER_LTM_SIM 3
+#define IPC_PEER_UPCM 4
+#define IPC_PEER_UT 5
+#define IPC_PEER_DISPATCHER 6
+
+#define IPC_DBG_DL_PKT_DUMP_ENABLE 0 /*< Debug and test only */
+#define IPC_DBG_UL_PKT_DUMP_ENABLE 0 /*< Debug and test only */
+
+/*------------------------------------------------------------------------------
+ * Configuration.
+ *----------------------------------------------------------------------------*/
+#ifdef IPC_PEER_LOOPBACK
+ #define IPC_PEER IPC_PEER_NULL_LOOPBACK
+#else
+ #ifdef __DISPATCHER_SUPPORT__
+ #define IPC_PEER IPC_PEER_DISPATCHER
+ #else
+ #define IPC_PEER IPC_PEER_UPCM
+ #endif
+#endif
+
+#if defined(__LTM_SIMULATION_SUPPORT__)
+ #undef IPC_PEER
+ #define IPC_PEER IPC_PEER_LTM_SIM
+#endif
+
+#ifdef ATEST_SYS_IPCORE
+ #undef IPC_PEER
+ #define IPC_PEER IPC_PEER_UT
+ #define IPCORE_SRC_MOD MOD_NIL
+ #define NAS_DST_MOD MOD_IPCORE
+ #define REBIND_DST_MOD MOD_IPCORE
+ #define QUERY_DST_MOD MOD_IPCORE
+ #define FILTER_SRC_MOD MOD_NIL
+#else
+ #define IPCORE_SRC_MOD MOD_IPCORE
+ #define NAS_DST_MOD MOD_TFTLIB
+ #define REBIND_DST_MOD src_mod_id
+ #define QUERY_DST_MOD src_mod_id
+ #define FILTER_SRC_MOD kal_get_active_module_id()
+#endif
+
+#if 1//defined(__MTK_MD_DIRECT_TETHERING_SUPPORT__) || defined(__MDT_MDONLY_SUPPORT__)
+ #define __MD_DIRECT_TETHERING_SUPPORT__
+#endif
+
+#define IPC_95_ACK_REDUCTION_ENABLE 0
+
+#if (CUR_GEN >= MD_GEN95)
+ #define __IPF_SUPPORT__
+ #if (IPC_95_ACK_REDUCTION_ENABLE == 1)
+ #define __IPC_95_ACK_REDUCTION_SUPPORT__
+ #endif
+#endif
+
+#define IPC_IPV6_RA_WORKAROUND 1
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+/*
+ * pdn_id use 0~5 bits (from the LSB) and proto_idx use 6~7
+ * which means IPCore only support pdn_id from 0 to 63 and proto_idx from 0 to 3
+ */
+#define IPC_CHECK_PDNID(_pdn_id) (((kal_uint32)_pdn_id) & 0xFFFFFFC0)
+#define IPC_CHECK_EBI(_ebi) (((kal_uint32)_ebi) & 0xFFFFFFC0)
+#define IPC_CHECK_PROTOID(_proto_idx) (((kal_uint8)_proto_idx) & 0xFC)
+
+#define IPC_MASK_PROTOID_ON_PDNID(_pdn_id, _proto_idx) \
+ _pdn_id = ( ((kal_uint32)_pdn_id) | (((kal_uint32)_proto_idx) << 6) )
+
+#define IPC_UNMASK_PROTOID_FROM_PDNID(_pdn_id) \
+ _pdn_id = (((kal_uint32)_pdn_id) & 0x0000003F)
+
+#define IPC_RETRIEVE_PROTOID_FROM_PDNID(_pdn_id, _proto_idx) \
+ _proto_idx = ( (kal_uint8)((((kal_uint32)_pdn_id) & 0x000000C0) >> 6) )
+
+#define IPC_GET_PROTOID_FROM_MODID(_mod_id, _proto_idx) \
+ if ((_mod_id >= MOD_UPCM) && (_mod_id <= MOD_UPCM + MAX_SIM_NUM)) { \
+ _proto_idx = _mod_id - MOD_UPCM; \
+ } else if ((_mod_id >= MOD_DISPATCHER) && (_mod_id <= MOD_DISPATCHER + MAX_SIM_NUM)) { \
+ _proto_idx = _mod_id - MOD_DISPATCHER; \
+ } else { \
+ IPC_ASSERT(KAL_FALSE); \
+ }
+
+#if defined(__MTK_TARGET__)
+/*
+ * 2017/08/03 Peter.Hsu
+ * kal_mem_cpy() will read source memory exceed the length we provided, which may access to invalid VRB page.
+ * Therefore, we will use dpcopro_vrb_copy() instead if the source memory is bank 5 (VRB).
+ */
+
+#ifndef __MD97__
+
+#define VRB_ADDR_BANK (0x5)
+#define VRB_CHECK_VADDR(vrb_addr) (VRB_ADDR_BANK==(((kal_uint32)(vrb_addr))>>28))
+#define VRB_GET_VADDR_OFS(addr) (((kal_uint32)(addr))&(~(0xf<<28)))
+
+#else
+
+#define VRB_ADDR_BANK (0xe)
+#define VRB_CHECK_VADDR(__vrb_addr) ({kal_uint32 __ret=0,__addr_bank=((kal_uint32)(__vrb_addr))>>27,__vrb_bank=VRB_ADDR_BANK<<1; \
+ if(__vrb_bank<=__addr_bank && __addr_bank<(__vrb_bank+3)){__ret=1;} __ret;})
+#define VRB_GET_VADDR_OFS(addr) (((kal_uint32)(addr))-(VRB_ADDR_BANK<<28))
+
+#endif
+
+extern void dpcopro_vrb_copy(kal_uint8 *des, kal_uint8 *src, kal_uint32 len);
+#undef kal_mem_cpy
+#define kal_mem_cpy(_p_dst, _p_src, _len) \
+ do { \
+ if (VRB_CHECK_VADDR(_p_src)) { \
+ dpcopro_vrb_copy((kal_uint8 *)_p_dst, (kal_uint8 *)_p_src, (kal_uint32)_len); \
+ } else { \
+ kal_mem_cpy(_p_dst, _p_src, _len); \
+ } \
+ } while (0)
+#endif
+/*------------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+#define IPC_ASSERT ASSERT /* To completely bypass the overhead of ASSERT(), we could define IPC_ASSERT(...) to nothing. */
+
+#define IPC_DL_INVALID_LEN_DROP_EN 0 /*< 0: disable, 1: enable */
+#define IPC_DL_INVALID_LEN_DEFAULT 3568
+
+#define IPC_LOCK_NAME "IPCORE_LOCK"
+#define IPC_UL_LOCK_NAME "IPCORE_UL_LOCK"
+
+#define IPC_ES_INDEX_UL_THROTTLE 2
+
+#define IPC_INVALID_FILTER_ID -1
+#define IPC_INVALID_NETIF_ID 0xFFFFFFFF
+#define IPC_INVALID_PDN_ID 0xFFFFFFFF
+#define IPC_INVALID_EBI_ID 0xFF
+
+#define IPC_DUMP_ENABLE 0
+#define IPC_DUMP_SIZE 48
+#define IPC_IPV6_DUMP 1
+#define IPC_HAS_GPD_MASK (1 << 15)
+
+/*------------------------------------------------------------------------------
+ * Internal data structure definition.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+extern kal_uint32 ipc_dl_valid_packet_len_s;
+extern kal_bool ipc_is_support_ccci_fast_header_s;
+extern kal_spinlockid ipc_spinlock_g;
+extern kal_bool ipc_ul_enable_g;
+extern kal_spinlockid g_ul_spinlock;
+
+/*------------------------------------------------------------------------------
+ * Internal function prototype.
+ *----------------------------------------------------------------------------*/
+kal_bool ipc_init(void);
+void ipc_on_ilm(ilm_struct *ilm);
+kal_bool ipc_reset(void);
+kal_bool ipc_is_in_reset(void);
+void ipc_set_ul_throttle(local_para_struct *local_para_ptr);
+kal_bool ipc_send_dl_pkt_in_did_internal(ipc_pkt_t *pkt, ipc_hdr_t *hdr, kal_uint32 netif_id);
+void ipc_module_clean(void);
+void ipc_clean_private_data(void);
+
+#ifdef __DISPATCHER_SUPPORT__
+void ipc_reg_cbk_dlvr_dl_did(dispatcher_dlvr_dl_did_f pf_dlvr_did);
+#endif
+
+#endif /* __INC_IPC_DEFS_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_dhcp_adp.h b/mcu/middleware/hif/ipcore/include/ipc_dhcp_adp.h
new file mode 100644
index 0000000..c847fee
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_dhcp_adp.h
@@ -0,0 +1,122 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_dhcp_adp.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * DHCP adaption.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_DHCP_ADP_H
+#define __INC_IPC_DHCP_ADP_H
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Function prototype.
+ *----------------------------------------------------------------------------*/
+/*!
+ * Enable DHCPv4 client for a IPv4 or IPv4v6 session.
+ *
+ * @param session_ptr [IN] The session object.
+ */
+void ipc_enable_dhcp4c(void *session_ptr);
+
+/*!
+ * Handler of the message MSG_ID_DHCP4C_ACTIVATE_RSP.
+ *
+ * @param activate_rsp_ptr [IN] Pointer to a dhcp4c_activate_rsp_struct object.
+ */
+void ipc_on_dhcp4c_activate_rsp(void *activate_rsp_ptr);
+
+/*!
+ * Disable DHCPv4 client for a IPv4 or IPv4v6 session.
+ *
+ * @param session_ptr [IN] The session object.
+ */
+void ipc_disable_dhcp4c(void *session_ptr);
+
+/*!
+ * Handler of the message MSG_ID_DHCP4C_DEACTIVATE_RSP.
+ *
+ * @param deactivate_rsp_ptr [IN] Pointer to a dhcp4c_deactivate_rsp_struct object.
+ */
+void ipc_on_dhcp4c_deactivate_rsp(void *deactivate_rsp_ptr);
+
+/*!
+ * Handler of the message MSG_ID_DHCP4C_IP_UP_IND.
+ *
+ * @param dhcp4c_ip_up_ind_ptr [IN] Pointer to a dhcp4c_ip_up_ind_struct object.
+ */
+void ipc_on_dhcp4c_ip_up_ind(void *dhcp4c_ip_up_ind_ptr);
+
+/*!
+ * Handler of the message MSG_ID_DHCP4C_IP_DOWN_IND.
+ *
+ * @param dhcp4c_ip_down_ind_ptr [IN] Pointer to a dhcp4c_ip_down_ind_struct object.
+ */
+void ipc_on_dhcp4c_ip_down_ind(void *dhcp4c_ip_down_ind_ptr);
+
+/*!
+ * Handler of the message MSG_ID_DHCP4C_PACKET_IND.
+ *
+ * @param dhcp4c_packet_ind_ptr [IN] Pointer to a dhcp4c_packet_ind_struct object.
+ */
+void ipc_on_dhcp4c_packet_ind(void *dhcp4c_packet_ind_ptr);
+
+#endif /* __INC_IPC_DHCP_ADP_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_dpfm.h b/mcu/middleware/hif/ipcore/include/ipc_dpfm.h
new file mode 100644
index 0000000..7fdc53a
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_dpfm.h
@@ -0,0 +1,248 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2017
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_data.h
+ *
+ * Project:
+ * --------
+ * UMOLYA
+ *
+ * Description:
+ * ------------
+ * IP Core Uplink/Downlink data path implementation.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_DPFM_H
+#define __INC_IPC_DPFM_H
+
+#include "kal_public_api.h"
+#include "ipc_defs.h"
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ #include "dpfm_api.h"
+#endif
+
+#include "ipc_session.h"
+
+/*------------------------------------------------------------------------------
+ * Internal data structure defintion.
+ *----------------------------------------------------------------------------*/
+#define IPC_DPFM_MAX_DEVICE_NUM 2 /* USB and WiFi */
+#define IPC_DPFM_DEFAULT_ROUTE_DEVICE_NUM IPC_MAX_SESSION_CNT
+
+typedef struct _ipc_dpfm_mirror_des_t {
+ kal_uint32 netif_id;
+ union {
+ struct {
+ kal_uint8 dpfm_matched_num;
+ kal_bool mirror_spd_pie_idx[QBM_SPD_MAX_PKTNUM];
+ };
+ struct {
+ kal_uint32 pdn_ids[IPC_SESSION_MAP_SIZE];
+ };
+ struct {
+ kal_uint8 pkt_num;
+ kal_uint8 seg_num;
+ ipc_si_hif_type_e hif_type;
+ upcm_did *mirror_did_head;
+ upcm_did *mirror_did_tail;
+ };
+ };
+} ipc_dpfm_mirror_des_t;
+
+typedef struct _ipc_dpfm_routing_packet_list_t {
+ qbm_gpd *first_gpd;
+ qbm_gpd *last_gpd;
+} ipc_dpfm_routing_packet_list_t;
+
+typedef struct _ipc_dpfm_lan_des_t {
+ kal_bool is_did;
+ kal_bool is_need_adjust_seq;
+ kal_uint32 dst_netif_id;
+ kal_uint32 src_netif_id;
+ ipc_si_hif_type_e hif_type;
+ upcm_did *did;
+ kal_uint32 curr_si_idx;
+} ipc_dpfm_lan_des_t;
+
+typedef struct _ipc_dpfm_default_route_des_t
+{
+ kal_uint32 netif_id;
+ upcm_did *head_did;
+ upcm_did *tail_did;
+}ipc_dpfm_default_route_des_t;
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+extern ipc_dpfm_routing_packet_list_t ipc_dpfm_packet_routing_queue[2][IPC_MAX_NETIF_CNT];
+extern kal_bool ipc_dpfm_queue_non_empty[2];
+
+#if IPC_PEER==IPC_PEER_UT
+ #define IPC_QUERY_DPFM_ROUTE ipc_ut_dpfm_check_route
+ #define IPC_DPFM_IS_ACTIVE ipc_ut_dpfm_is_activated
+ #define IPC_DPFM_PROCESS_FILTER_CMD(...)
+ #define IPC_DPFM_TRACK_PACKET(...)
+#else
+ #define IPC_QUERY_DPFM_ROUTE dpfm_check_route
+ #define IPC_DPFM_IS_ACTIVE dpfm_is_active
+ #define IPC_DPFM_PROCESS_FILTER_CMD dpfm_process_filter_cmd_result
+ #define IPC_DPFM_TRACK_PACKET dpfm_track_packet
+#endif
+
+/*------------------------------------------------------------------------------
+ * General Function prototype.
+ *----------------------------------------------------------------------------*/
+
+/*!
+ * Downlink data path entrance function for lan NETIF.
+ *
+ * @param lan_des_array [IN] lan_des array of all DPFM devices.
+ */
+void ipc_dpfm_lan_on_did_downlink(ipc_dpfm_lan_des_t *lan_des_array);
+
+/*
+ * Fill the DID/SIT descriptor from the META.
+ *
+ * @param lan_des_array [IN] lan_des array of all DPFM devices.
+ * @param src_meta [IN] The META of the packet.
+ * @param src_netif_id [IN] The id of the netif of the source lan device.
+ * @param src_netif [IN] The pointer of the source netif.
+ *
+ * @return KAL_TRUE if successful, KAL_FALSE otherwise.
+ */
+kal_bool ipc_dpfm_fill_did_si_from_meta(ipc_dpfm_lan_des_t *lan_des_array, lhif_meta_tbl_t *src_meta, kal_uint32 src_netif_id, ipc_netif_t *src_netif);
+
+/*!
+ * Set the corresponding PDN id into META of the packet which is about to use DPFM Direct Path.
+ *
+ * @param mirror_des_array [IN] mirror_des array of all DPFM devices.
+ * @param META [IN] The META of the packet.
+ * @param netif_id [IN] The id of the netif of the routed DPFM device.
+ * @param ip_type [IN] The IP type of the packet.
+ *
+ * @return return KAL_TRUE for the packet is available to use the direct path, otherwise return KAL_FALSE.
+ */
+kal_bool ipc_dpfm_set_pdn_id_in_meta(ipc_dpfm_mirror_des_t *mirror_des_array, lhif_meta_tbl_t *meta, kal_uint32 netif_id, kal_uint8 ip_type);
+
+/*!
+ * Mark the mirror descriptor and DID to indicate the packet is about to use DPFM Direct Path.
+ *
+ * @param mirror_des_array [IN] mirror_des array of all DPFM devices.
+ * @param did [IN] DID of the packet.
+ * @param p_curr_si_idx [IN|OUT] The started SIT index of the packet.
+ * @param netif_id [IN] The id of the netif of the routed DPFM device.
+ *
+ * @return return KAL_TRUE for the packet is marked to use the direct path, otherwise return KAL_FALSE.
+ */
+kal_bool ipc_dpfm_set_pkt_in_did_mirror_des(ipc_dpfm_mirror_des_t *mirror_des_array, upcm_did *did, kal_uint32 *p_curr_si_idx, kal_uint32 netif_id);
+
+/*!
+ * Fill the mirror descriptor and DID to indicate the packet is about to use DPFM Direct Path.
+ *
+ * @param mirror_des_array [IN] mirror_des array of all DPFM devices.
+ * @param packet_des [IN] IPCore internal packet descriptor.
+ * @param netif_id [IN] The id of the netif of the routed DPFM device.
+ *
+ * @return return KAL_TRUE for the packet is marked to use the direct path, otherwise return KAL_FALSE.
+ */
+kal_bool ipc_dpfm_set_ipf_pkt_in_did_mirror_des(ipc_dpfm_mirror_des_t *mirror_des_array, ipc_pkt_des_t *packet_des, kal_uint32 netif_id);
+
+/*!
+ * Mirror the DID with the correct packet and segment numbers of the corresponding hif type.
+ *
+ * @param mirror_des [IN] mirror_des of the DPFM device.
+ * @param src_did [IN] The source DID.
+ */
+void ipc_dpfm_mirror_did(ipc_dpfm_mirror_des_t *mirror_des, upcm_did *src_did);
+
+/*!
+ * Push the DID to Downlink IPC_DID_QUEUE_TYPE_DPFM queue.
+ *
+ * @param did [IN] DID of the packet.
+ * @param pdn_id [IN] PDN ID where the DID comes from.
+ */
+void ipc_dpfm_push_did_to_dpfm_queue(upcm_did *did, kal_uint32 pdn_id);
+
+kal_bool ipc_dpfm_check_route(kal_bool uplink, ipc_pkt_des_t *pkt_des, kal_uint32 netif_id);
+
+qbm_spd * ipc_dpfm_mirror_spd(qbm_spd *p_origin_spd, kal_bool *mirror_spd_pie_idx, kal_uint8 dpfm_matched_num);
+
+void ipc_dpfm_push_gpd_to_routing_queue(kal_bool uplink, kal_uint32 netif_id, qbm_gpd *gpd);
+
+kal_bool ipc_dpfm_need_pkt_info(kal_bool is_uplink, ipc_pkt_des_t *pkt_des);
+
+#endif /* __MD_DIRECT_TETHERING_SUPPORT__) */
+#endif /* __INC_IPC_DPFM_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_filter.h b/mcu/middleware/hif/ipcore/include/ipc_filter.h
new file mode 100644
index 0000000..2cfa5eb
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_filter.h
@@ -0,0 +1,489 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_filter.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * Packet filtering.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_FILTER_H
+#define __INC_IPC_FILTER_H
+
+#include "kal_public_api.h"
+
+#include "ipc_struct.h"
+#include "ipc_dpfm.h"
+
+typedef enum _ipc_match_result_e {
+ IPC_MATCH_RESULT_NOT_MATCHED = 0x0000,
+ IPC_MATCH_RESULT_MATCHED = 0x0001,
+ IPC_MATCH_RESULT_FRAG_MATCHED = 0x0010,
+} ipc_match_result_e;
+
+typedef enum _ipc_pkt_do_filter_result_e {
+ IPC_PKT_DO_FILTER_NOT_MATCHED = 0,
+ IPC_PKT_DO_FILTER_MATCHED = 1,
+ IPC_PKT_DO_FILTER_BWM_MATCHED = 2,
+ IPC_PKT_DO_FILTER_DPFM_MATCHED = 3,
+ IPC_PKT_DO_FILTER_INVALID_LEN = 4,
+ IPC_PKT_DO_FILTER_HANDLE_FRAG = 5,
+ IPC_PKT_DO_FILTER_HANDLE_CLONE = 6,
+ IPC_PKT_DO_FILTER_ERROR,
+ IPC_PKT_DO_FILTER_NONE
+} ipc_pkt_do_filter_result_e;
+
+#define IPF_HW_FILTER_ENTRY_NUM 64
+
+/* IPF HW Filter IP Type */
+#define IPF_HW_FILTER_IPV4 (0x4)
+#define IPF_HW_FILTER_IPV6 (0x6)
+#define IPF_HW_FILTER_IPV6_1 (0x7)
+
+/* IPF HW Filter Valid Field */
+#define IPF_HW_FILTER_V_FRAG ( 0x1 << 0)
+#define IPF_HW_FILTER_V_PROTO ( 0x1 << 1)
+#define IPF_HW_FILTER_V_PDNSIM_ID ( 0x1 << 2)
+#define IPF_HW_FILTER_V_R_ADDR ( 0x1 << 3)
+#define IPF_HW_FILTER_V_L_ADDR ( 0x1 << 7)
+#define IPF_HW_FILTER_V_F_WORD_DONTC ( 0x0 << 4) // First word don't care
+#define IPF_HW_FILTER_V_F_WORD_TYPE ( 0x1 << 4) // only compare least significant byte of first word
+#define IPF_HW_FILTER_V_F_WORD_TYPE2 ( 0x2 << 4) // only compare low half-word of first word
+#define IPF_HW_FILTER_V_F_WORD_TYPE3 ( 0x3 << 4) // only compare high half-word of first word
+#define IPF_HW_FILTER_V_F_WORD_TYPE4 ( 0x4 << 4) // compare whole first word
+
+#define IPF_HW_FILTER_SET_VALID(_p, _value) \
+ ((_p) = (_p) | _value)
+
+
+typedef enum {
+ IPC_HW_DL_MODE = 0,
+ IPC_SW_DL_MODE_STR = (1 << 0),
+ IPC_SW_DL_MODE_PCI = (1 << 1),
+ IPC_SW_DL_MODE_MAX = (1 << 7),
+ IPC_HW_DL_MODE_PCI = (~IPC_SW_DL_MODE_PCI),
+ IPC_HW_DL_MODE_STR = (~IPC_SW_DL_MODE_STR)
+} ipc_sw_dl_mode_e;
+
+#define IPC_SW_DL_FILTER_ID 0xFF
+/*------------------------------------------------------------------------------
+ * Data structure definition.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Function prototype.
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Initialize IP packet filtering resources.
+ */
+void ipc_filter_init(void);
+
+/**
+ * Send ILM to indicate registering a filter for uplink or downlink traffic.
+ *
+ * @param data_path_direct [IN] UL_DATA_PATH for uplink filter rule. DL_DATA_PATH for downlink filter rule
+ * @param rules [IN] Rules to filter of downlink IP datagrams.
+ * @param p_ntfy_ctxt [IN] Context to pass in the callback function.
+ *
+ * @return Zero or positive value as filter ID if registration succeeded, negative value otherwise.
+ */
+kal_int32 ipc_filter_reg_filter_by_ilm(ipc_data_path_direction_e data_path_direct,
+ ipc_filter_rules_t *p_rules,
+ ipc_filter_ntfy_ctxt_t *p_ntfy_ctxt);
+
+/**
+ * ILM handler for MSG_ID_IPCORE_REGISTER_FILTER_REQ.
+ *
+ * @param local_para_ptr [IN] local parameter for the ILM.
+ */
+void ipc_filter_reg_handler(local_para_struct *local_para_ptr);
+
+/**
+ * Send ILM to remove the filter from uplink or downlink traffic.
+ *
+ * @param filter_id [IN] filter ID to remove.
+ *
+ * @return KAL_TRUE for success, KAL_FALSE for failed.
+ */
+kal_bool ipc_filter_dereg_filter_by_ilm(kal_int32 filter_id);
+
+/**
+ * ILM handler for MSG_ID_IPCORE_DEREGISTER_FILTER_REQ.
+ *
+ * @param local_para_ptr [IN] local parameter for the ILM.
+ */
+void ipc_filter_dereg_handler(local_para_struct *local_para_ptr);
+
+/**
+ * Do filter for uplink traffic.
+ *
+ * @param session_type [IN] Type of PDN session where the GPDs are (only V4 or V6 are allowed).
+ * @param netif_id [IN] Network interface ID where the GPD's come from.
+ * @param pp_head [IN|OUT] header of a list of GPD's.
+ * @param pp_tail [IN|OUT] tail of a list of GPD's.
+ *
+ * @return the number of remained packets, which are not filterd out.
+ */
+kal_uint16
+ipc_do_ul_filter(
+ kal_uint8 session_type,
+ kal_uint32 netif_id,
+ qbm_gpd **pp_head,
+ qbm_gpd **pp_tail);
+
+/**
+ * Do filter for downlink traffic.
+ *
+ * @param session_type [IN] Type of PDN session where the GPD's come from.
+ * @param netif_id [IN] Network interface ID where the GPD's come to.
+ * @param pdn_id [IN] PDN ID where the GPD's come from.
+ * @param pp_head [IN|OUT] header of a list of GPD's.
+ * @param pp_tail [IN|OUT] tail of a list of GPD's.
+ *
+ * @return the number of remained packets, which are not filterd out.
+ */
+kal_uint16
+ipc_do_dl_filter(
+ kal_uint8 session_type,
+ kal_uint32 netif_id,
+ kal_uint32 pdn_id,
+ qbm_gpd **pp_head,
+ qbm_gpd **pp_tail);
+
+/**
+ * Do filter for uplink traffic in META format.
+ *
+ * @param ip_type [IN] The IP type of the packet.
+ * @param netif_id [IN] Network interface ID where the META's come from.
+ * @param meta [IN] the META of the packet.
+ * @param mirror_des [IN] mirror_des array of all DPFM devices.
+ *
+ * @return 1 if the packet is not filtered out, 0 otherwise.
+ */
+kal_uint16
+ipc_meta_do_filter(
+ kal_uint8 ip_type,
+ kal_uint32 netif_id,
+ lhif_meta_tbl_t *meta,
+ ipc_dpfm_mirror_des_t *dpfm_mirror_des,
+ ipc_pkt_des_t *packet_des_p);
+
+/**
+ * Do filter for downlink traffic in DID format.
+ *
+ * @param session_type [IN] Type of PDN session where the GPDs are (only V4 or V6 are allowed).
+ * @param netif_id [IN] Network interface ID where the GPD's come from.
+ * @param pdn_id [IN] PDN ID where the GPD's come from.
+ * @param did [IN|OUT] the DID of the packet.
+ *
+ * @return the number of remained packets, which are not filterd out.
+ */
+kal_uint16
+ipc_did_do_filter(
+ kal_uint8 session_type,
+ kal_uint32 netif_id,
+ kal_uint32 pdn_id,
+ upcm_did *did);
+
+/**
+ * Forward packet filtered to specified module.
+ * Note that, it's for IPCORE internal use only.
+ */
+void
+ipc_forward_packet_by_msg(
+ msg_type msg_id,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length);
+
+/**
+ * Forward uplink packet filtered to specified module.
+ * Note that, it's for IPCORE internal use only.
+ */
+void ipc_filter_fwd_ul_pkt_by_msg(void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length);
+
+/**
+ * Forward downlink packet filtered to specified module.
+ * Note that, it's for IPCORE internal use only.
+ */
+void ipc_filter_fwd_dl_pkt_by_msg(void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length);
+
+/**
+ * Forward packet filtered to specified module (with information).
+ * Note that, it's for IPCORE internal use only.
+ */
+void ipc_forward_packet_with_info_by_msg(msg_type msg_id,
+ ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length);
+
+/**
+ * Forward uplink packet filtered to specified module (with information).
+ * Note that, it's for IPCORE internal use only.
+ */
+void ipc_filter_fwd_ul_pkt_with_info_by_msg(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length);
+
+/**
+ * Forward downlink packet filtered to specified module (with information).
+ * Note that, it's for IPCORE internal use only.
+ */
+void ipc_filter_fwd_dl_pkt_with_info_by_msg(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length);
+
+/**
+ * Updated IPF HW filter
+ */
+void ipc_filter_update_hw_filter();
+
+/**
+ * Updated IPF one HW filter
+ */
+kal_bool ipc_update_one_hw_filter(kal_int32 filter_id,
+ ipc_filter_rules_t* rules,
+ void* p_cur_base);
+
+/**
+ * IPF meta filter
+ */
+void ipc_ipf_meta_do_filter(kal_int32 filter_id,
+ ipc_pkt_des_t *packet_des,
+ kal_uint8 ip_type,
+ kal_uint8 pdn_sim_id,
+ kal_uint32 netif_id,
+ ipc_dpfm_mirror_des_t *dpfm_mirror_des,
+ kal_bool *is_mirror_did,
+ kal_bool *is_saved);
+
+#endif /* __INC_IPC_FILTER_H */
+
+/**
+ * Check for current DID list contains special content before drop
+ *
+ * @param pdn_id [IN] pdn_sim_id
+ * @param p_head [IN] DID head
+ * @param p_tail [IN] DID tail
+ *
+ */
+void ipc_filter_did_drop_pkt_handler(kal_uint32 pdn_id, upcm_did *p_head, upcm_did *p_tail);
+
+/**
+ * Switch DL mode by installing IPF HW rule
+ *
+ * @param mode [IN] IPC_HW_DL_MODE or IPC_SW_DL_MODE
+ *
+ */
+void ipc_filter_switch_dl_mode(kal_uint8 mode);
diff --git a/mcu/middleware/hif/ipcore/include/ipc_fragment_def.h b/mcu/middleware/hif/ipcore/include/ipc_fragment_def.h
new file mode 100644
index 0000000..60d3642
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_fragment_def.h
@@ -0,0 +1,18 @@
+#ifndef _IPC_FRAGMENT_DEF_INC
+#define _IPC_FRAGMENT_DEF_INC
+
+#define IPC_FRAG_AFM_BUFFER_SIZE (64 * 1024)
+#if !defined(__GEN97_ESL_SPEEDUP__)
+#define IPC_FRAG_HASH_TABLE_BUCK_NUM 256 // must be power of 2
+#else
+#define IPC_FRAG_HASH_TABLE_BUCK_NUM 64
+#endif
+#define IPC_FRAG_HASH_NODE_NUM 128
+#define IPC_FRAG_PKT_META_NODE_NUM 512
+
+#define IPC_FRAG_EXPIRE_CB_NUM 64
+#define IPC_FRAG_POLLING_EXPIRE_SEC KAL_TICKS_5_SEC_REAL
+#define IPC_FRAG_QUEUING_EXPIRE_SEC (KAL_TICKS_5_SEC_REAL * 1)
+#define IPC_FRAG_ES_IDX_QUEUE_EXPIRE 10
+
+#endif /* _IPC_FRAGMENT_DEF_INC */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_fragment_export.h b/mcu/middleware/hif/ipcore/include/ipc_fragment_export.h
new file mode 100644
index 0000000..a61a173
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_fragment_export.h
@@ -0,0 +1,17 @@
+#ifndef _IPC_FRAGMENT_EXPORT_INC
+#define _IPC_FRAGMENT_EXPORT_INC
+
+#include "ipc_api.h"
+#include "kal_public_api.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+
+kal_bool ipc_fragment_init();
+kal_bool ipc_fragment_deinit();
+kal_bool ipc_fragment_reset();
+void ipc_fragment_on_ilm(ilm_struct* ilm);
+void ipc_fragment_defrag(qbm_gpd* new_gpd, ipc_frag_refilter_info_t* info, kal_bool is_v4);
+kal_uint32 ipc_fragment_frag(void* buff, kal_uint32 buff_len, qbm_gpd** frag_gpd_head, qbm_gpd** frag_gpd_tail, kal_bool is_v4);
+void ipc_fragment_test();
+
+#endif /* _IPC_FRAGMENT_EXPORT_INC */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_notify.h b/mcu/middleware/hif/ipcore/include/ipc_notify.h
new file mode 100644
index 0000000..1d6bb22
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_notify.h
@@ -0,0 +1,123 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_notify.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IPCore notification.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_NOTIFY_H
+#define __INC_IPC_NOTIFY_H
+
+#include "kal_public_api.h"
+#include "ipc_enums.h"
+
+/** Initialize IPCore notification resources. */
+void ipc_ntfy_init(void);
+
+/**
+ * Create a notification.
+ *
+ * @param callback_func [IN] Callback function pointer.
+ * @param callback_context [IN] Context to pass in the callback function.
+ *
+ * @return Zero or positive value as notification ID if registration succeeded, negative value otherwise.
+ */
+kal_int32 ipc_ntfy_new_cbk(ipc_ntfy_callback_t cbk_func, void *p_cbk_args);
+
+/**
+ * Remove the notification entry.
+ *
+ * @param ntfy_id [IN] notification ID to remove.
+ */
+void ipc_ntfy_del_cbk(kal_int32 ntfy_id);
+
+/**
+ * Execute IPCore notification callback.
+ *
+ * @param netif [IN] Corresponding network interface for the notification.
+ * @param ntfy_type [IN] Notification type to indicate.
+ */
+void ipc_ntfy_do_event_cbk(ipc_netif_t *p_netif, ipc_ntfy_type_e ntfy_type);
+
+#endif /* __INC_IPC_NOTIFY_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_object.h b/mcu/middleware/hif/ipcore/include/ipc_object.h
new file mode 100644
index 0000000..9a48a2e
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_object.h
@@ -0,0 +1,287 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_object.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * Helper for object management and synchronization.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_OBJECT_H
+#define __INC_IPC_OBJECT_H
+
+#include "kal_public_api.h"
+
+struct _ipc_object_template;
+extern kal_spinlockid ipc_spinlock_g;
+static INLINE kal_bool ipc_is_object_valid(struct _ipc_object_template *object);
+
+/*------------------------------------------------------------------------------
+ * Data structure definition.
+ *----------------------------------------------------------------------------*/
+#define IPC_SPIN_LOCK(_lock) kal_take_spinlock(_lock, KAL_INFINITE_WAIT)
+#define IPC_SPIN_UNLOCK(_lock) kal_give_spinlock(_lock)
+
+#define IPC_DECLARE_OBJECT \
+ kal_int32 ref_count; \
+ kal_int32 reader_cnt; \
+ kal_int32 writer_cnt;
+
+#define IPC_IS_VALID_OBJECT_WO_LOCK(_object) \
+ ((_object) != NULL && (_object)->ref_count == 2)
+
+#define IPC_IS_VALID_OBJECT(_object) \
+ ipc_is_object_valid((struct _ipc_object_template *)_object)
+
+#define IPC_R_LOCK_OBJECT(_object, _lock) \
+ IPC_SPIN_LOCK(_lock); \
+ if (IPC_IS_VALID_OBJECT_WO_LOCK(_object) && ((_object)->writer_cnt == 0)) { \
+ ++((_object)->reader_cnt); \
+ } else { \
+ (_object) = NULL; \
+ } \
+ IPC_SPIN_UNLOCK(_lock)
+
+#define IPC_R_UNLOCK_OBJECT(_object, _lock) \
+ ASSERT((_object)); \
+ IPC_SPIN_LOCK(_lock); \
+ ASSERT((_object)->reader_cnt > 0); \
+ --((_object)->reader_cnt); \
+ IPC_SPIN_UNLOCK(_lock)
+
+#define IPC_INIT_OBJECT_BEGIN(_object, _lock) \
+ IPC_ASSERT(_object); \
+ IPC_SPIN_LOCK(_lock); \
+ IPC_ASSERT((_object)->ref_count == 0); \
+ (_object)->ref_count = 1; \
+ IPC_SPIN_UNLOCK(_lock)
+
+#define IPC_INIT_OBJECT_END(_object, _lock) \
+ IPC_ASSERT(_object); \
+ IPC_SPIN_LOCK(_lock); \
+ IPC_ASSERT(_object->ref_count == 1); \
+ (_object)->ref_count = 2; \
+ (_object)->reader_cnt = 0; \
+ (_object)->writer_cnt = 0; \
+ IPC_SPIN_UNLOCK(_lock)
+
+#define IPC_DEINIT_OBJECT_BEGIN(_object, _lock) \
+ IPC_ASSERT(kal_if_hisr() == KAL_FALSE); \
+ IPC_SPIN_LOCK(_lock); \
+ if (IPC_IS_VALID_OBJECT_WO_LOCK(_object)) { \
+ --((_object)->ref_count); \
+ while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
+ IPC_SPIN_UNLOCK(_lock); \
+ kal_sleep_task(IPC_DEL_OBJECT_SLEEP_TICKS); \
+ IPC_SPIN_LOCK(_lock); \
+ } \
+ IPC_ASSERT((_object)->ref_count == 1); \
+ } else { \
+ (_object) = NULL; \
+ } \
+ IPC_SPIN_UNLOCK(_lock)
+
+#define IPC_DEINIT_OBJECT_END(_object, _lock) \
+ IPC_SPIN_LOCK(_lock); \
+ IPC_ASSERT((_object)->ref_count == 1); \
+ IPC_ASSERT((_object)->reader_cnt == 0); \
+ IPC_ASSERT((_object)->writer_cnt == 0); \
+ (_object)->ref_count = 0; \
+ IPC_SPIN_UNLOCK(_lock)
+
+#define IPC_W_LOCK_OBJECT(_object, _lock) \
+ IPC_ASSERT(kal_if_hisr() == KAL_FALSE || KAL_TRUE == kal_query_systemInit()); \
+ IPC_SPIN_LOCK(_lock); \
+ if (IPC_IS_VALID_OBJECT_WO_LOCK(_object)) { \
+ while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
+ IPC_SPIN_UNLOCK(_lock); \
+ kal_sleep_task(IPC_W_LOCK_OBJECT_SLEEP_TICKS); \
+ IPC_SPIN_LOCK(_lock); \
+ } \
+ if (IPC_IS_VALID_OBJECT_WO_LOCK(_object)) { \
+ ++((_object)->writer_cnt); \
+ } else { \
+ (_object) = NULL; \
+ IPC_SPIN_UNLOCK(_lock); \
+ } \
+ } else { \
+ (_object) = NULL; \
+ IPC_SPIN_UNLOCK(_lock); \
+ }
+
+#define IPC_W_UNLOCK_OBJECT(_object, _lock) \
+ IPC_ASSERT((_object)); \
+ IPC_ASSERT((_object)->writer_cnt == 1); \
+ --((_object)->writer_cnt); \
+ IPC_SPIN_UNLOCK(_lock)
+
+/* Safely convert between Read & Write lock at the same time. */
+#define IPC_R_TO_W_LOCK_OBJECT(_object, _lock) \
+ IPC_ASSERT(kal_if_hisr() == KAL_FALSE); \
+ IPC_SPIN_LOCK(_lock); \
+ if (IPC_IS_VALID_OBJECT_WO_LOCK(_object)) { \
+ ASSERT((_object)->reader_cnt > 0); \
+ --((_object)->reader_cnt); \
+ while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
+ IPC_SPIN_UNLOCK(_lock); \
+ kal_sleep_task(IPC_W_LOCK_OBJECT_SLEEP_TICKS); \
+ IPC_SPIN_LOCK(_lock); \
+ } \
+ if (IPC_IS_VALID_OBJECT_WO_LOCK(_object)) { \
+ ++((_object)->writer_cnt); \
+ } else { \
+ (_object) = NULL; \
+ IPC_SPIN_UNLOCK(_lock); \
+ } \
+ } else { \
+ (_object) = NULL; \
+ IPC_SPIN_UNLOCK(_lock); \
+ }
+
+#define IPC_W_TO_R_LOCK_OBJECT(_object, _lock) \
+ IPC_ASSERT((_object)); \
+ IPC_ASSERT((_object)->reader_cnt == 0); \
+ IPC_ASSERT((_object)->writer_cnt == 1); \
+ --((_object)->writer_cnt); \
+ ++((_object)->reader_cnt); \
+ IPC_SPIN_UNLOCK(_lock)
+
+/*------------------------------------------------------------------------------
+ * Functions for Synchronization
+ *----------------------------------------------------------------------------*/
+struct _ipc_object_template {
+ IPC_DECLARE_OBJECT
+};
+
+static INLINE kal_bool ipc_is_object_valid(struct _ipc_object_template *object)
+{
+ kal_bool ret;
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ ret = IPC_IS_VALID_OBJECT_WO_LOCK(object)? KAL_TRUE:KAL_FALSE;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ return ret;
+}
+
+#endif /* __INC_IPC_OBJECT_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_packet_parser.h b/mcu/middleware/hif/ipcore/include/ipc_packet_parser.h
new file mode 100644
index 0000000..52df1b4
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_packet_parser.h
@@ -0,0 +1,79 @@
+#ifndef __INC_IPC_PACKET_PARSER_H
+#define __INC_IPC_PACKET_PARSER_H
+
+#include "ipc_api.h"
+#include "kal_public_api.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+
+kal_bool ipc_get_packet_info(kal_uint8 *p_packet, kal_uint16 packet_len, ipc_packet_info_t *p_info);
+kal_bool ipc_get_packet_info_gpd(kal_uint8 *p_packet, qbm_gpd *gpd, qbm_gpd *base_bd, ipc_packet_info_t *p_info);
+kal_bool ipc_get_packet_info_did(kal_uint8 *p_packet, upcm_did *did, kal_uint32 base_si_idx, ipc_packet_info_t *p_info);
+
+/*!
+ * Get new address in GPD with shift for specific offset.
+ *
+ * @param base_addr_p [IN] Basic address pointer from GPD/BD payload content.
+ * @param gpd [IN] GPD of input packet.
+ * @param base_bd [IN] Corresponding BD for base_addr_p. It might be NULL if the GPD does not have BD list.
+ * @param offset [IN] Offset to shift.
+ * @param offset_addr_pp [OUT] Pointer of packet content after shift.
+ * @param offset_bd_p [OUT] Pointer of corresponding BD for *offset_addr_pp.
+ *
+ * @return true if the process is success.
+ * @return false if the process is failed.
+ */
+kal_bool ipc_shift_content_ptr(kal_uint8 *base_addr_p, qbm_gpd *gpd, qbm_gpd *base_bd, kal_uint32 offset, kal_uint8 **offset_addr_pp, qbm_gpd **offset_bd_p);
+
+/*!
+ * Return pointer with "continous content" with specific length.
+ * If original GPD/BD is already continuous within gotten length, this procedure will return pointer from it.
+ * If packet content of original GPD/BD is divided in multiple pieces, this procedure will use "cont_addr_p" buffer to collect continous content to return.
+ *
+ * @param base_addr_p [IN] Basic address pointer from GPD/BD payload content.
+ * @param offset [IN] Offset to get payload content.
+ * @param gpd [IN] GPD of input packet.
+ * @param base_bd [IN] Corresponding BD for base_addr_p. It might be NULL if the GPD does not have BD list.
+ * @param len [IN] Length of return continuous content.
+ * @param cont_addr_pp [OUT] Pointer of returned continuous content. It might point to GPD payload or cont_buff_p if process SUCCESS.
+ * @param cont_buff_p [IN] Alternative buffer used if GPD content is not continuous. Caller should guarantee its size >= length.
+ *
+ * @return true if the process is success.
+ * @return false if the process is failed.
+ */
+kal_bool ipc_get_continuous_content(kal_uint8 *base_addr_p, kal_uint32 offset, qbm_gpd *gpd, qbm_gpd *base_bd, kal_uint32 len, kal_uint8 **cont_addr_pp, kal_uint8 *cont_buff_p);
+
+/*!
+ * Get new address in DID with shift for specific offset.
+ *
+ * @param base_addr_p [IN] Basic address pointer from DID/SIT payload content.
+ * @param did [IN] DID of input packet.
+ * @param base_si_idx [IN] Corresponding SIT index for base_addr_p.
+ * @param offset [IN] Offset to shift.
+ * @param offset_addr_pp [OUT] Pointer of packet content after shift.
+ * @param offset_si_idx_p [OUT] Pointer of corresponding SIT idx for *offset_addr_pp.
+ *
+ * @return true if the process is success.
+ * @return false if the process is failed.
+ */
+kal_bool ipc_shift_did_content_ptr(kal_uint8 *base_addr_p, upcm_did *did, kal_uint32 base_si_idx, kal_uint32 offset, kal_uint8 **offset_addr_pp, kal_uint32 *offset_si_idx_p);
+
+/*!
+ * Return pointer with "continous content" with specific length.
+ * If original DID/SIT is already continuous within gotten length, this procedure will return pointer from it.
+ * If packet content of original DID/SIT is divided in multiple pieces, this procedure will use "cont_addr_p" buffer to collect continous content to return.
+ *
+ * @param base_addr_p [IN] Basic address pointer from DID/SIT payload content.
+ * @param offset [IN] Offset to get payload content.
+ * @param did [IN] DID of input packet.
+ * @param base_si_idx [IN] Corresponding SIT index for base_addr_p.
+ * @param len [IN] Length of return continuous content.
+ * @param cont_addr_pp [OUT] Pointer of returned continuous content. It might point to DID/SIT payload or cont_buff_p if process SUCCESS.
+ * @param cont_buff_p [IN] Alternative buffer used if DID/SIT content is not continuous. Caller should guarantee its size >= length.
+ *
+ * @return true if the process is success.
+ * @return false if the process is failed.
+ */
+kal_bool ipc_get_continuous_content_did(kal_uint8 *base_addr_p, kal_uint32 offset, upcm_did *did, kal_uint32 base_si_idx, kal_uint32 len, kal_uint8 **cont_addr_pp, kal_uint8 *cont_buff_p);
+
+#endif // INC_IPC_PACKET_PARSER_H
diff --git a/mcu/middleware/hif/ipcore/include/ipc_session.h b/mcu/middleware/hif/ipcore/include/ipc_session.h
new file mode 100644
index 0000000..35cff11
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_session.h
@@ -0,0 +1,451 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_session.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IP session management.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_SESSION_H
+#define __INC_IPC_SESSION_H
+
+#include "ipc_struct.h"
+#include "ipc_object.h"
+
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+#define ipc_session_type_hash(_session_type) \
+ ((_session_type) & 0x1)
+
+/*------------------------------------------------------------------------------
+ * Data structure definition.
+ *----------------------------------------------------------------------------*/
+#define IPC_SESSION_MAP_SIZE 2
+
+typedef enum _ipc_session_state_e {
+ IPC_SESSION_STATE_MIN = 0,
+ IPC_SESSION_STATE_UNBIND,
+ IPC_SESSION_STATE_PRE_BIND,
+ IPC_SESSION_STATE_BIND,
+ IPC_SESSION_STATE_PRE_LINKUP,
+ IPC_SESSION_STATE_PRE_LINKUP_IPV4_LEASE,
+ IPC_SESSION_STATE_LINKUP,
+ IPC_SESSION_STATE_IPV4_LEASE,
+ IPC_SESSION_STATE_PRE_IPV4_RELOCATE,
+ IPC_SESSION_STATE_IP_REVOKE,
+ IPC_SESSION_STATE_MAX,
+ IPC_SESSION_STATE_INVALID,
+} ipc_session_state_e;
+
+typedef enum _ipc_session_transition_action_case_e {
+ IPC_SST_NULL = 0,
+ IPC_SST_MIN,
+ IPC_SST_NA, /* Do nothing excepting state transition */
+ IPC_SST_LUI, /* Send Link up indication to handler */
+ IPC_SST_LUR, /* Send Link up request to network interface */
+ IPC_SST_LDR, /* Send Link down request to network interface */
+ IPC_SST_IUI, /* Send IPv4 up indication to handler */
+ IPC_SST_IUR, /* Send IPv4 up request to network interface */
+ IPC_SST_IDR, /* Send IPv4 down request to network interface */
+ IPC_SST_MAX,
+} ipc_session_transition_action_case_e;
+
+typedef struct _ipc_netif_t ipc_netif_t;
+typedef struct _ipc_netif_t {
+ IPC_DECLARE_OBJECT
+ kal_uint32 object_idx;
+ ipc_conf_t config;
+ kal_uint64 bit_id;
+ void *session_map[IPC_SESSION_MAP_SIZE];
+ kal_uint32 session_cnt;
+ ipc_netif_t *lan_netif;
+} ipc_netif_t;
+
+typedef struct _ipc_session_t {
+ IPC_DECLARE_OBJECT
+
+ kal_uint32 context; /**< Key to identify the IP session. */
+ ipc_session_state_e state; /**< FSM state of session */
+ kal_uint8 type; /**< Type of the IP session, including IPC_IP_TYPE_IPV4, IPC_IP_TYPE_IPV6, IPC_IP_TYPE_MIXED. */
+ kal_uint8 dhcp4c_id; /**< DHCPv4 client instance ID if dhcp4c_running is KAL_TRUE. */
+ kal_uint8 reserved[2];
+ kal_bool dhcp4c_running; /**< Indicate if DHCPv4 client is running or not. */
+ kal_int32 dhcp4c_dl_filter_id; /**< Zero or positive value for a downlink filter installed DHCPv4; Negative value otherwise. */
+
+ kal_int32 ip_id; /**< An ID for an HIF network interface to tell the associated IP session(s). */
+ ipc_netif_t *netif; /**< Associated HIF network interface. */
+} ipc_session_t;
+
+/*------------------------------------------------------------------------------
+ * Function prototype.
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Initialize all objects.
+ */
+void ipc_object_init(void);
+
+/**
+ * Find an HIF network interface.
+ * Note that, caller MUST release the control to network interface
+ * through IPC_R_UNLOCK_OBJECT() once done with it.
+ *
+ * @param netif_id [IN] ID of the network interface interested.
+ *
+ * @return An ipc_netif_t object if found, NULL otherwise.
+ */
+ipc_netif_t *ipc_find_netif(kal_uint32 netif_id);
+
+/**
+ * Find an HIF network interface through a bit index.
+ * Note that, caller MUST release the control to network interface
+ * through IPC_R_UNLOCK_OBJECT() once done with it.
+ *
+ * @param bit_id [IN] bit index.
+ *
+ * @return An ipc_netif_t object if found, NULL otherwise.
+ */
+ipc_netif_t *ipc_find_netif_by_bit_id(kal_uint64 bit_id);
+
+/**
+ * Find an HIF network interface through a object index.
+ * Note that, caller MUST release the control to network interface
+ * through IPC_R_UNLOCK_OBJECT() once done with it.
+ *
+ * @param object_idx [IN] bit index.
+ *
+ * @return An ipc_netif_t object if found, NULL otherwise.
+ */
+ipc_netif_t *ipc_find_netif_by_object_id(kal_uint32 object_id);
+
+/**
+ * Create an ipc_netif_t object for an HIF network interface attached.
+ * Note that, if the network interface is already attached, this function will return NULL.
+ *
+ * @param config [IN] Configuration of the netowrk interface attached.
+ *
+ * @return An ipc_netif_t object if succeeded, NULL otherwise.
+ */
+ipc_netif_t *ipc_new_netif(ipc_conf_t *config);
+
+/**
+ * Destroy the ipc_netif_t object for the HIF network interface to detach.
+ * Note that, if the netowrk interface is not a valid one, this function wll fail.
+ *
+ * @param netif [IN] The netowrk interface to detach.
+ *
+ * @return KAL_TRUE if succeed, KAL_FALSE otherwise.
+ */
+kal_bool ipc_del_netif(ipc_netif_t *netif);
+
+/**
+ * Query netif list to get latest status.
+ *
+ * @param netif_list_p [IN] The network interface list strcture to collect status.
+ *
+ * @return KAL_TRUE if succeed, KAL_FALSE otherwise.
+ */
+kal_bool ipc_query_netif_list(ipc_netif_list_t *netif_list_p);
+
+/**
+ * Update handling module of LINK_UP_IND ILM
+ *
+ * @param module_id [IN] Module ID to handle MSG_ID_IPCORE_LINK_UP_IND and send MSG_ID_IPCORE_LINK_UP_RSP as response.
+ */
+void ipc_update_link_up_ind_handler(module_type module_id);
+
+/**
+ * Update handling module of IP_UP_IND ILM
+ *
+ * @param module_id [IN] Module ID to handle MSG_ID_IPCORE_IP_UP_IND and send MSG_ID_IPCORE_IP_UP_RSP as response.
+ */
+void ipc_update_ip_up_ind_handler(module_type module_id);
+
+/**
+ * Indicate the HIF network interface link/IP status changed for handler process. Real IPCORE operation will done after handler response for the indication.
+ *
+ * @param netif [IN] The netowrk interface.
+ * @param ip_type [IN] Type of the PDN, IPC_IP_TYPE_IPV4, IPC_IP_TYPE_IPV6, or IPC_IP_TYPE_MIXED.
+ * @param link_update[IN] KAL_TRUE if an IP session is established/deactived and link status is changed. KAL_FALSE if an IP information is updated for an activated IP session.
+ * @param link_up [IN] (If link_update is KAL_TRUE) KAL_TRUE if an IP session is established, KAL_FALSE if an IP session is deactived ;
+ (If link_update is KAL_FALSE) KAL_TRUE if new IP information is available, KAL_FALSE if original IP information is obsoleted
+ */
+void ipc_indicate_netif_link_change(ipc_netif_t *netif, kal_uint8 ip_type, kal_bool link_update, kal_bool is_up);
+
+/**
+ * Notify the HIF network interface link/IP status changed.
+ *
+ * @param netif [IN] The netowrk interface.
+ * @param ip_type [IN] Type of the PDN, IPC_IP_TYPE_IPV4, IPC_IP_TYPE_IPV6, or IPC_IP_TYPE_MIXED.
+ * @param link_update[IN] KAL_TRUE if an IP session is established/deactived and link status is changed. KAL_FALSE if an IP information is updated for an activated IP session.
+ * @param link_up [IN] (If link_update is KAL_TRUE) KAL_TRUE if an IP session is established, KAL_FALSE if an IP session is deactived ;
+ (If link_update is KAL_FALSE) KAL_TRUE if new IP information is available, KAL_FALSE if original IP information is obsoleted
+ */
+void ipc_notify_netif_link_change(ipc_netif_t *netif, kal_uint8 ip_type, kal_bool link_update, kal_bool is_up);
+
+/**
+ * Find index of the associated IP session.
+ *
+ * @param netif [IN] The netowrk interface.
+ *
+ * @return Index of the associated IP session, <0 means no associated IP session is found.
+ */
+kal_int32 ipc_map_netif_to_ip_id(ipc_netif_t *netif);
+
+/**
+ * Find PDN ID of the associated IP session.
+ *
+ * @param netif [IN] The netowrk interface.
+ * @param ip_type [IN] The IP type of the session.
+ *
+ * @return PDN ID of the associated IP session, IPC_INVALID_PDN_ID means no associated IP session is found.
+ */
+kal_int32 ipc_map_netif_to_pdn_id(ipc_netif_t *netif, kal_uint8 ip_type);
+
+/**
+ * Specify the network interface needs UL reload retry or not.
+ *
+ * @param netif [IN] The netowrk interface.
+ * @param need_ul_reload [IN] KAL_TRUE if it needs UL reload retry, KAL_FALSE otherwise.
+ */
+void ipc_set_netif_ul_reload_retry(ipc_netif_t *netif, kal_bool need_ul_reload);
+
+/**
+ * Specify if the network interface calls ipc_need_ul_retry between netif's reload cbk and ul_reload_retry be set.
+ *
+ * @param netif [IN] The netowrk interface.
+ * @param need_ul_reload [IN] KAL_TRUE if it needs UL reload retry, KAL_FALSE otherwise.
+ */
+void ipc_set_netif_ul_set_need_reload(ipc_netif_t *netif, kal_bool need_ul_reload);
+
+/**
+ * Get UL reload status of all network interfaces.
+ *
+ * @return Each bit indicate if the corresponding network interface needs UL reload retry.
+ */
+kal_uint64 ipc_get_all_netif_ul_reload_retry(void);
+
+/**
+ * Execute session state transition and corresponding behavior.
+ *
+ * @param session [IN] The netowrk session.
+ * @param session_state [IN] New session type to translate.
+ * @return KAL_TRUE if succeed, KAL_FALSE otherwise.
+ */
+kal_bool ipc_update_session_state(ipc_session_t *session, ipc_session_state_e session_state);
+
+/**
+ * Find an IP session with specified session_context.
+ * Note that, caller MUST release the control to IP session
+ * through IPC_R_UNLOCK_OBJECT() once done with it.
+ *
+ * @param session_context [IN] Key to identify the IP session.
+ *
+ * @return An ipc_session_t object if found, NULL otherwise.
+ */
+ipc_session_t *ipc_find_session_by_context(kal_uint32 session_context);
+
+/**
+ * Find the session object associated with specified HIF network interface and session_type.
+ * Note that, caller MUST release the control to IP session
+ * through IPC_R_UNLOCK_OBJECT() once done with it.
+ *
+ * @param netif [IN] The netowrk interface.
+ * @param session_type [IN] Type of the IP session, either IPC_IP_TYPE_IPV4 or IPC_IP_TYPE_IPV6.
+ *
+ * @return An ipc_session_t object if found, NULL otherwise.
+ */
+ipc_session_t *ipc_find_session_by_netif(ipc_netif_t *netif, kal_uint8 session_type);
+
+/**
+ * Find the session object associated with specified ip_id and session type.
+ * Note that, caller MUST release the control to IP session
+ * through IPC_R_UNLOCK_OBJECT() once done with it.
+ *
+ * @param ip_id [IN] An ID for an HIF network interface to tell the associated IP session(s).
+ * @param session_type [IN] Type of the IP session, either IPC_IP_TYPE_IPV4 or IPC_IP_TYPE_IPV6.
+ *
+ * @return An ipc_session_t object if found, NULL otherwise.
+ */
+ipc_session_t *ipc_find_session_by_ip_id(kal_int32 ip_id, kal_uint8 session_type);
+
+/**
+ * Create an ipc_session_t object for the IP session established.
+ *
+ * @param netif [IN] HIF network interface associated with the IP sesion.
+ * @param session_context [IN] Key to identify the IP session.
+ * @param session_type [IN] Type of the IP session: IPC_IP_TYPE_IPV4, IPC_IP_TYPE_IPV6, or IPC_IP_TYPE_MIXED.
+ * @param session_state [IN] Initial state of the IP session.
+ *
+ * @return An ipc_session_t object if succeeded, NULL otherwise.
+ */
+ipc_session_t *ipc_new_session(ipc_netif_t *netif, kal_uint32 session_context, kal_uint8 session_type, ipc_session_state_e session_state);
+
+/**
+ * Destroy the ipc_session_t object for the IP session deactivated.
+ *
+ * @param session [IN] IP session deactivated.
+ */
+void ipc_del_session(ipc_session_t *session);
+
+/**
+ * Destroy the old session and replace with the new IP session.
+ * Note that the ip_id will remain the same as before.
+ *
+ * @param netif [IN] HIF network interface associated with the IP session.
+ * @param old_session [IN] IP session deactivated.
+ * @param new_session_context [IN] Key to identify the IP session.
+ * @param new_session_type [IN] Type of the IP session: IPC_IP_TYPE_IPV4, IPC_IP_TYPE_IPV6, or IPC_IP_TYPE_MIXED.
+ * @param new_session_state [IN] Initial state of the IP session.
+ *
+ * @return An ipc_session_t object if succeeded, NULL otherwise.
+ */
+ipc_session_t *ipc_replace_session(ipc_netif_t *netif, ipc_session_t *old_session, kal_uint32 new_session_context, kal_uint8 new_session_type, ipc_session_state_e new_session_state);
+
+/**
+ * restore netif / session mapping
+ *
+ * @param p_netif [IN] which netif should restore session
+ * @param p_ip_type [IN] session type
+ *
+ * @return KAL_TRUE / KAL_FALSE
+ */
+kal_bool ipc_session_restore_netif_map(ipc_netif_t *p_netif, kal_uint8 *p_ip_type);
+
+/**
+ * send restore ind to IPCore context
+ *
+ * @param netif_id [IN] which netif_id should restore
+ * @param ip_type [IN] session ip type
+ * @param is_link_update [IN] link_update status
+ * @param is_up [IN] up status
+ *
+ * @return KAL_TRUE / KAL_FALSE
+ */
+void ipc_session_send_restore_netif_ind(kal_uint32 netif_id, kal_uint8 ip_type, kal_bool is_link_update, kal_bool is_up);
+
+#endif /* __INC_IPC_SESSION_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_trace.h b/mcu/middleware/hif/ipcore/include/ipc_trace.h
new file mode 100644
index 0000000..498cc74
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_trace.h
@@ -0,0 +1,17 @@
+#ifndef __INC_IPC_TRACE_H
+#define __INC_IPC_TRACE_H
+#if HIF_CONSOLE_TRACE_ENABLED != 1
+#ifndef GEN_FOR_PC
+ #include "kal_public_defs.h"
+#endif /* GEN_FOR_PC */
+#include "dhl_trace.h"
+#include "dhl_def.h"
+#if !defined(GEN_FOR_PC)
+#if defined(__DHL_MODULE__) || defined(__CUSTOM_RELEASE__)
+#endif /* TST Trace Defintion */
+#endif
+#endif /* HIF_CONSOLE_TRACE_ENABLED != 1 */
+#if !defined(GEN_FOR_PC)
+#include"ipc_trace_mod_ipcore_utmd.h"
+#endif
+#endif /* __INC_IPC_TRACE_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_trace_mod_ipcore_utmd.json b/mcu/middleware/hif/ipcore/include/ipc_trace_mod_ipcore_utmd.json
new file mode 100644
index 0000000..465b99c
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_trace_mod_ipcore_utmd.json
@@ -0,0 +1,2870 @@
+{
+ "legacyParameters": {},
+ "module": "MOD_IPCORE",
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "TRACE_DEBUG": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline",
+ "TRACE_DEBUG"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "TRACE_INFO": {
+ "debugLevel": "Ultra-High",
+ "tag": [
+ "Baseline",
+ "TRACE_INFO"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_WARNING": {
+ "debugLevel": "High",
+ "tag": [
+ "Baseline",
+ "TRACE_WARNING"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_SENSITIVE_USIR": {
+ "debugLevel": "Ultra-High",
+ "tag": [
+ "Baseline",
+ "TRACE_SENSITIVE_USIR",
+ "USIR"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "TRACE_ERROR": {
+ "debugLevel": "Ultra-High",
+ "tag": [
+ "Baseline",
+ "TRACE_ERROR"
+ ],
+ "traceType": "Public"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "IPC_TR_ILM_WRONG_DEST_MOD": {
+ "format": "[IPCORE] ipc_on_ilm(): wrong dest_mod_id(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NETIF_ATTACHING": {
+ "format": "[IPCORE] ipc_attach(): module_id(%d), netif_id(%d), callback_context(0x%x), features(0x%x)...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NETIF_ATTACHED": {
+ "format": "[IPCORE] ipc_new_netif(): module_id(%d), netif_id(%d) has attached successfully",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NETIF_ATTACH_OUT_OF_SPACE": {
+ "format": "[IPCORE] ipc_new_netif(): module_id(%d), netif_id(%d) failed for out of space!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NETIF_ATTACH_DUPLICATED": {
+ "format": "[IPCORE] ipc_new_netif(): module_id(%d), netif_id(%d) has attached before!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NETIF_DETACHING": {
+ "format": "[IPCORE] ipc_detach(): handle(0x%x)...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NETIF_DETACHED": {
+ "format": "[IPCORE] ipc_detach(): module_id(%d), netif_id(%d) has detached successfully",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NETIF_DETACH_INVALID": {
+ "format": "[IPCORE] ipc_del_netif(): invalid netif to detach!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_RESET_START": {
+ "format": "[IPCORE] ipc_reset(): Start to handle IPCore reset",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GET_QBM_DATAHEAD_ZERO_LENGTH_BD": {
+ "format": "[IPCORE] ipc_get_qbm_datahead(): Found non-zero length GPD with all-zero length BD list, this should not happen: gpd(0x%x), gpd_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_SESSION": {
+ "format": "[IPCORE] ipc_reset(): Delete session[0x%x] for idx[%d]",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_SESSION_INFO": {
+ "format": "[IPCORE] ipc_reset(): Delete session information(type[%d], ip_id[%d]) for idx[%d]",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_NETIF": {
+ "format": "[IPCORE] ipc_reset(): Delete netif[0x%x] for idx[%d]",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_RESET_END": {
+ "format": "[IPCORE] ipc_reset(): Handle IPCore reset is done",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_START": {
+ "format": "[IPCORE] ipc_on_pdn_bind_top(): binding request received",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_INFO": {
+ "format": "[IPCORE] ipc_on_pdn_bind_top(): network_interface_id(0x%X), pdn_id(0x%X), ip_addr_type(%d)...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IP_INFO": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Configure IP information for network_interface_id(0x%X), pdn_id(0x%X), ip_addr_type(%d):Mapped NMU ip_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV6_DNS_USIR": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Add IPv6 DNS to NMU ip_id(%d):[%02X] %S%S:%S%S:%S%S:%S%S:%S%S:%S%S:%S%S:%S%S",
+ "traceClass": "TRACE_SENSITIVE_USIR"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV6_DNS_NUM": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Set IPv6 DNS number(%d) to NMU ip_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV6_ZERO_IID_LEN": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Set IPv6 IID length of NMU ip_id(%d) to ZERO",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV6_IID_USIR": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Set IPv6 IID to NMU ip_id(%d):IID length(%d) %S%S:%S%S:%S%S:%S%S:%S%S:%S%S:%S%S:%S%S",
+ "traceClass": "TRACE_SENSITIVE_USIR"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV6_DOWN": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): NMU ip_id(%d) - IPv6 DOWN",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV6_UP": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): NMU ip_id(%d) - IPv6 UP",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV4_DNS_USIR": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Add IPv4 DNS to NMU ip_id(%d):[%02X] %S.%S.%S.%S",
+ "traceClass": "TRACE_SENSITIVE_USIR"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV4_DNS_NUM": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Set IPv4 DNS number(%d) to NMU ip_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV4_ADDR_USIR": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Set IPv4 address to NMU ip_id(%d): %S.%S.%S.%S",
+ "traceClass": "TRACE_SENSITIVE_USIR"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV4_FAKE_INFO_USIR": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): NMU ip_id(%d) - Trigger IPv4 fake info generation for IPv4 address %S.%S.%S.%S",
+ "traceClass": "TRACE_SENSITIVE_USIR"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV4_UP": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): NMU ip_id(%d) - IPv4 UP",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_CFG_IPV4_DOWN": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): NMU ip_id(%d) - IPv4 DOWN",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_DHCP4C": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Enable DHCP4C for netif_id(%d), features(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_SESSION_RLOCK_FAIL": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): session readlock is failed for network_card(0x%X), pdn_id(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_DYNAMIC_Q_ERROR": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): dynamic HW queue setting error : network_card(0x%X), pdn_id(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_NEW_SESSION_FAIL": {
+ "format": "[IPCORE] ipc_on_pdn_bind_top(): session allocation is failed for network_card(0x%X), pdn_id(0x%X), ip_type(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_INVALID_NETIF": {
+ "format": "[IPCORE] ipc_on_pdn_bind_top(): no netif found for network_card(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_UNSUPPORTED_IP_ADDR_TYPE": {
+ "format": "[IPCORE] ipc_on_pdn_bind_top(): unsupported ip_addr_type(%d)! pdn_id(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_NULL_PARAM": {
+ "format": "[IPCORE] ipc_on_pdn_bind_top(): NULL parameter!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_START": {
+ "format": "[IPCORE] ipc_new_session(): New session - session_context(0x%X), session_type(0x%X), session_state(0x%X).",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_NETIF_BOUND_MIXED": {
+ "format": "[IPCORE] ipc_new_session():(IPV4V6) netif(0x%x)/netif_id(%d) has already bound with session (map[v4]=0x%x, map[v6]=0x%x)! session_context(0x%X), session_type(0x%X), session_state(0x%X) bind fail.",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_NETIF_BOUND_SPECIFIC_IP_VER": {
+ "format": "[IPCORE] ipc_new_session():(v4_or_v6) netif(0x%x)/netif_id(%d) has already bound with session (map[v4]=0x%x, map[v6]=0x%x)! session_context(0x%X), session_type(0x%X), session_state(0x%X) bind fail.",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_DUPLICATED": {
+ "format": "[IPCORE] ipc_new_session(): session_context(0x%X), session_type(0x%X), session_state(0x%X) has already bound!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BIND_OUT_OF_SPACE": {
+ "format": "[IPCORE] ipc_new_session(): session_context(0x%X), session_type(0x%X), session_state(0x%X) failed for out of space!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_RESULT": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): binding request handling - result(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_RSP_PARAM_GEN": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): Generate binding response parameter - network_interface_id(%d), pdn_id(%d), sizeof(ip_addr_struct)=%d, sizeof(dns_struct)=%d, sizeof(upcm_ipcore_back_info_t)=%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BINDING_RSP": {
+ "format": "[IPCORE] ipc_on_pdn_bind_bot(): sending response for binding request - result(0x%X), dst_module(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_BOUND": {
+ "format": "[IPCORE] ipc_new_session(): session_context(0x%X), session_type(0x%X), session_state(0x%X) has bound successfully => ip_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_DEACTIVATING": {
+ "format": "[IPCORE] ipc_on_pdn_unbind(): pdn_id(0x%X)...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_DEACTIVATE_NO_SESSION_FOUND": {
+ "format": "[IPCORE] ipc_on_pdn_unbind(): no session found for pdn_id(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_DEACTIVATE_NULL_PARAM": {
+ "apiType": "index",
+ "format": "[IPCORE] ipc_on_pdn_unbind(): NULL parameter!",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_SESSION_DEACTIVATE_INVALID_SESSION": {
+ "format": "[IPCORE] ipc_del_session(): it's not a valid session!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_DEACTIVATED": {
+ "format": "[IPCORE] ipc_del_session(): session_context(0x%X), session_type(0x%X), ip_id(%d) has deactivated successfully",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBINDING_INFO": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): network_interface_id(0x%X), old_pdn_id(0x%X), new_pdn_id(0x%X), ip_addr_type(%d)...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBIND_UNSUPPORTED_IP_ADDR_TYPE": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): unsupported ip_addr_type(%d)! new_pdn_id(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBIND_REPLACE_SESSION_FAIL": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): old session deletion or session allocation is failed for network_card(0x%X), old_pdn_id(0x%X), new_pdn_id(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBIND_SESSION_RLOCK_FAIL": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): session readlock is failed for network_card(0x%X), old_pdn_id(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBIND_INVALID_NETIF": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): no netif found for network_card(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBIND_NULL_PARAM": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): NULL parameter!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBINDING_RESULT": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): binding request handling - result(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBINDING_RSP_PARAM_GEN": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): Generate rebinding response parameter - network_interface_id(%d), old_pdn_id(%d), new_pdn_id(%d), sizeof(ip_addr_struct)=%d, sizeof(dns_struct)=%d, sizeof(upcm_ipcore_back_info_t)=%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBINDING_RSP": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): sending response for binding request - result(0x%X), dst_module(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REBIND_START": {
+ "format": "[IPCORE] ipc_replace_session(): Replace session - netif(0x%X), old_session(0x%X), new_session_context(0x%X), new_session_type(0x%X), new_session_state(0x%X).",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REPLACED": {
+ "apiType": "index",
+ "format": "[IPCORE] ipc_replace_session(): session_context(0x%X), session_type(0x%X), session_state(0x%X) has been replaced successfully => ip_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REPLACE_NETIF_RLOCK_FAIL": {
+ "format": "[IPCORE] ipc_replace_session(): netif readlock is failed!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SESSION_REPLACE_SESSION_RLOCK_FAIL": {
+ "format": "[IPCORE] ipc_on_pdn_rebind(): session readlock is failed!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_START": {
+ "format": "[IPCORE] ipc_update_session_state(): Update session_context(0x%X) to state(%d) start",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_ORG_AND_NEW": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X) session_type(0x%X) of netif_context(0x%X) from org_state(%d) to new_state(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_TRANSITION_SUCCESS": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X) update to state(%d) successfully",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_WRITE_FAIL": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X) update to state(%d) fail",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_SST_NA": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), do nothing else",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_SST_LUI": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), LinkUpIndication",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_SST_LUR": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), LinkUpRequest(netif[0x%X], IPType[%d])",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_SST_LDR": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), LinkDownRequest(netif[0x%X], IPType[%d])",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_SST_IUI": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), IpUpIndication",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_SST_IUR": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), IpUpRequestion(netif[0x%X], IPType[%d])",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_SST_IDR": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), IpDownRequestion(netif[0x%X], IPType[%d])",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_ILLEGAL_TRANSITION": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), Unknown action(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_OUT_OF_RANGE": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), state(%d)->(%d), Illegal transaction!(Min state[%d], Max state[%d])",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_READ_FAIL": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), session state read error !",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_CHK_FAIL": {
+ "format": "[IPCORE] ipc_update_session_state(): Session_context(0x%X), session check error !",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_SESSION_STATE_END": {
+ "format": "[IPCORE] ipc_update_session_state(): Update session_context(0x%X) to state(%d) end with retval(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_INVALID_PARAM": {
+ "format": "[IPCORE] invalid parameters for uplink handle(0x%X), ior (0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_DROP_FOR_SESSION_DEACT": {
+ "format": "[IPCORE] netif_id(%d) drops ior(0x%X) ip_type(%d) uplink packets for session deactivated!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_DROP_FOR_INVALID_NETIF": {
+ "format": "[IPCORE] netif(0x%X) drops uplink packets [ior(0x%X)] for invalid netif!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_SESSION_DEACT": {
+ "format": "[IPCORE] netif_id(0x%X) drops uplink packet META(0x%x) ip_type(%d) for session deactivated!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_INVALID_NETIF": {
+ "format": "[IPCORE] netif_id(0x%X) drops uplink packet [META: idx(%d), q_type(%d)] for invalid netif!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_NONE_IP_PKT": {
+ "format": "[IPCORE] netif_id(0x%X) Found non-IPv4/IPv6 packet [META: idx(%d), q_type(%d)], drop!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_NONE_IP_PKT2": {
+ "format": "[IPCORE] netif_id(0x%X) Found non-IPv4/IPv6 packet META: idx(%d), drop!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL": {
+ "format": "[IPCORE] lan netif_id(%d) drops uplink packet META(0x%x) read_idx(%d) for lan DID allocation failed!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL_CAUSE_DID_NULL": {
+ "format": "[IPCORE] lan netif is_DID is NULL, lan src_netif_id(0x%x), is_DID(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL_DID_ALLOC_NG": {
+ "format": "[IPCORE] lan DID allocation failed, lan src_netif_id(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL_NETIF_NULL": {
+ "format": "[IPCORE] lan DID allocation failed, lan src_netif_id(0x%x), lan_netif(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_UL_DROP_FOR_LAN_DEVICE_NG": {
+ "format": "[IPCORE] lan device is out of bound, lan src_netif_id(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_DROP_FOR_INVALID_IOR": {
+ "format": "[IPCORE] netif_id(%d) drops uplink packets for invalid ior(0x%X) first_gpd(0x%X) last_gpd(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DPFM_DROP_FOR_LAN_NETIF_DETACH": {
+ "format": "[IPCORE] drops type(%d) head_ior(0x%X) downlink packets for lan netif detached!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_DROP_FOR_NETIF_INFO_LOCK_FAIL": {
+ "format": "[IPCORE] pdn_id(%d) ip_id(%d) drops type(%d) [p_head(0x%X), p_tail(0x%X)] downlink packets : netif detach found during getting netif information!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_DID_DROP_FOR_NETIF_INFO_LOCK_FAIL": {
+ "format": "[IPCORE] pdn_id(%d) ip_id(%d) drops type(%d) [did_head(0x%X), did_tail(0x%X)] downlink packets : netif detach found during getting netif information!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_DROP_FOR_NETIF_INFO_LOCK_FAIL": {
+ "format": "[IPCORE] pdn_id(%d) ip_id(%d) drops type(%d) [meta_idx(0x%X)] downlink packets : netif detach found during getting netif information!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_DROP_FOR_NETIF_DETACH": {
+ "format": "[IPCORE] pdn_id(%d) ip_id(%d) drops type(%d) [p_head(0x%X), p_tail(0x%X)] downlink packets for netif detached!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_DID_DROP_FOR_NETIF_DETACH": {
+ "format": "[IPCORE] pdn_id(%d) ip_id(%d) drops type(%d) [did_head(0x%X), did_tail(0x%X)] downlink packets for netif detached!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_PENDING_DID_DROP_FOR_NETIF_DETACH": {
+ "format": "[IPCORE] drops type(%d) Pending DID:[did_head(0x%X), did_tail(0x%X)] downlink packets for netif detached!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_DROP_FOR_INVALID_SESSION": {
+ "format": "[IPCORE] pdn_id(%d) drops downlink packets [p_head(0x%X), p_tail(0x%X)] for invalid session!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_DID_DROP_FOR_INVALID_SESSION": {
+ "format": "[IPCORE] pdn_id(%d) drops downlink packets [did_head(0x%X), did_tail(0x%X)] for invalid session!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_DROP_FOR_INVALID_SESSION": {
+ "format": "[IPCORE] pdn_id(%d) drops downlink packets [meta_idx(0x%X)] for invalid session!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_PENDING_DID_DROP_FOR_INVALID_SESSION": {
+ "format": "[IPCORE] netif(0x%X) drops downlink pending packets [did_head(0x%X), did_tail(0x%X)] for invalid session!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NOTIFY_LINK_CHANGE_BEGIN": {
+ "format": "[IPCORE] ipc_notify_link_change(): Link change notification start: netif_id(%d) ip_type(%d) link_update(%d) is_up(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NOTIFY_LINK_CHANGE_FOR_NETIF_BEGIN": {
+ "format": "[IPCORE] ipc_notify_link_change(): Link change for found netif(0x%x) for netif_id(%d) start",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NOTIFY_LINK_CHANGE_FOR_NETIF_END": {
+ "format": "[IPCORE] ipc_notify_link_change(): Link change for found netif(0x%x) for netif_id(%d) done",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NOTIFY_LINK_CHANGE_UNKNOWN_NETIF": {
+ "format": "[IPCORE] ipc_notify_link_change(): Unknown netif_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NOTIFY_LINK_CHANGE_END": {
+ "format": "[IPCORE] ipc_notify_link_change(): Link change notification done: netif_id(%d) ip_type(%d) link_update(%d) is_up(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_UL_FILTER_CBK_BEGIN": {
+ "format": "[IPCORE] ipc_register_ul_filter_cbk(): rules(0x%X) callback_func(0x%X) callback_context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_DL_FILTER_CBK_BEGIN": {
+ "format": "[IPCORE] ipc_register_dl_filter_cbk(): rules(0x%X) callback_func(0x%X) callback_context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_UL_FILTER_MSG_BEGIN": {
+ "format": "[IPCORE] ipc_register_ul_filter_msg(): rules(0x%X) callback_module(0x%X) callback_context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_DL_FILTER_MSG_BEGIN": {
+ "format": "[IPCORE] ipc_register_dl_filter_msg(): rules(0x%X) callback_module(0x%X) callback_context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_UL_FILTER_WITH_INFO_CBK_BEGIN": {
+ "format": "[IPCORE] ipc_register_ul_filter_with_info_cbk(): rules(0x%X) callback_func(0x%X) callback_context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_DL_FILTER_WITH_INFO_CBK_BEGIN": {
+ "format": "[IPCORE] ipc_register_dl_filter_with_info_cbk(): rules(0x%X) callback_func(0x%X) callback_context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_UL_FILTER_WITH_INFO_MSG_BEGIN": {
+ "format": "[IPCORE] ipc_register_ul_filter_with_info_msg(): rules(0x%X) callback_module(0x%X) callback_context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_DL_FILTER_WITH_INFO_MSG_BEGIN": {
+ "format": "[IPCORE] ipc_register_dl_filter_with_info_msg(): rules(0x%X) callback_module(0x%X) callback_context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREG_UL_FILTER_BEGIN": {
+ "format": "[IPCORE] ipc_deregister_ul_filter(): filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREG_DL_FILTER_BEGIN": {
+ "format": "[IPCORE] ipc_deregister_dl_filter(): filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_ZERO_VALID_FIELD": {
+ "format": "[IPCORE] ipc_validate_rules(): valid_fields cannot be 0!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_UL": {
+ "format": "[IPCORE] ipc_validate_rules(): uplink(%d), valid_fields(0x%X) and ip_type(%d) are invalid for uplink filter!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_DL": {
+ "format": "[IPCORE] ipc_validate_rules(): uplink(%d), valid_fields(0x%X) and ip_type(%d) are invalid for downlink filter!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_L4_INFO": {
+ "format": "[IPCORE] ipc_validate_rules(): uplink(%d), valid_fields(0x%X) and ip_type(%d) are invalid for L4 INFO!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_IPV4": {
+ "format": "[IPCORE] ipc_validate_rules(): uplink(%d), valid_fields(0x%X) and ip_type(%d) are invalid for IPv4 or MIXED type!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_IPV6": {
+ "format": "[IPCORE] ipc_validate_rules(): uplink(%d), valid_fields(0x%X) and ip_type(%d) are invalid for IPv6 or MIXED type!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_UNSUPPORTED_PROTOCOL": {
+ "format": "[IPCORE] ipc_validate_rules(): unsupported protocol(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_FRAG": {
+ "format": "[IPCORE] ipc_validate_rules(): uplink(%d), valid_fields(0x%X), ip_type(%d) and features(0x%X) are invalid for fragment!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NEW_FILTER_INVALID_PARAMS": {
+ "format": "[IPCORE] ipc_new_filter_id(): failed with invalid parameters: rules(0x%X), callback_func(0x%X), module_id(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NEW_FILTER_UNAVAILABLE": {
+ "format": "[IPCORE] ipc_new_filter_id(): failed with all filters are busy now!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_HW_FILTER_OK": {
+ "format": "[IPCORE] ipc_update_hw_filter(): update to HW total_entry(%d) v6_unknown_check(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_HW_FILTER_COUNT": {
+ "format": "[IPCORE] ipc_update_hw_filter(): ip_type(%d) count(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_HW_FILTER_TOO_MUCH": {
+ "format": "[IPCORE] ipc_update_hw_filter(): too much filter, ip_type(%d) filter_num(%d) entry_num(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_HW_FILTER_TABLE_INFO": {
+ "format": "[IPCORE] ipc_update_hw_filter(): table base addr(0x%X) max_entry_num (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REGISTER_FILTER_VALIDATE_FAIL": {
+ "format": "[IPCORE] ipc_register_filter_by_ilm(): filter rule validate fail: uplink?(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REGISTER_FILTER_OK": {
+ "format": "[IPCORE] ipc_register_filter(): created a new filter successfully: uplink?(%d), filter_id(%d), features(0x%X), ip_type(%d) valid_fields(0x%X), with_ipv4(%d), with_ipv6(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REGISTER_FILTER_NG": {
+ "format": "[IPCORE] ipc_register_filter_by_ilm(): failed to create a new filter!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REGISTER_FILTER_ADD_TO_LIST": {
+ "format": "[IPCORE] ipc_register_filter(): add filter_id(%d) to IPv%d filter list. uplink?(%d). v4_de_pending_cnt (0x%x), v6_de_pending_cnt (0x%x), reserved_cnt (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_CNT": {
+ "format": "[IPCORE] ipc_filter_list_dump_all(): total filter num : v4_ul(%d) v4_dl(%d) v6_ul(%d) v6_dl(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_ID_DUMP_4": {
+ "format": "[IPCORE] ipc_filter_list_dump(): filter ID dump : (%d) (%d) (%d) (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_ID_DUMP_3": {
+ "format": "[IPCORE] ipc_filter_list_dump(): filter ID dump : (%d) (%d) (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_ID_DUMP_2": {
+ "format": "[IPCORE] ipc_filter_list_dump(): filter ID dump : (%d) (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_ID_DUMP_1": {
+ "format": "[IPCORE] ipc_filter_list_dump(): filter ID dump : (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_ID_DUMP_INFO_v4": {
+ "format": "[IPCORE] ipc_filter_list_dump_all(): IPv4 filter ID number info : is_uplink(%d) number(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_ID_DUMP_INFO_v6": {
+ "format": "[IPCORE] ipc_filter_list_dump_all(): IPv6 filter ID number info : is_uplink(%d) number(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_FILTER_INVALID_OBJECT": {
+ "format": "[IPCORE] ipc_del_filter(): filter (0x%x) an invalid object!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREGISTER_FILTER_WITH_INVALID_ID": {
+ "format": "[IPCORE] ipc_deregister_filter_by_ilm(): this filter invalid filter_id(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREGISTER_FILTER_NOT_FOUND": {
+ "format": "[IPCORE] ipc_deregister_filter(): filter_id(%d) is not found!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREGISTER_FILTER_INFO": {
+ "format": "[IPCORE] ipc_deregister_filter(): deleting a filter: filter_id(%d), features(0x%X), valid_fields(0x%X), with_ipv4(%d), with_ipv6(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REMOVE_DL_FILTER_FROM_LIST": {
+ "format": "[IPCORE] ipc_deregister_filter(): remove filter_id(%d) from IPv%d filter list",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REMOVE_DL_FILTER_RETRY": {
+ "format": "[IPCORE] ipc_deregister_filter(): need retry remove filter_id(%d) ",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_EN_REG_DL_FILTER_OK": {
+ "format": "[IPCORE] ipc_enable_dhcp4c(): session context(%d) type(%d) registered DL filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_EN_REG_DL_FILTER_NG": {
+ "format": "[IPCORE] ipc_enable_dhcp4c(): session context(%d) type(%d) failed to register DL filter(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_EN_FAILED_WITH_INVALID_PARAMETER": {
+ "format": "[IPCORE] ipc_enable_dhcp4c(): invalid session_ptr!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_DIS_INFO": {
+ "format": "[IPCORE] ipc_disable_dhcp4c(): session context(%d) type(%d) dhcp4c: running(%d)/dhcp_id(%d)/filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_DIS_DEREG_DL_FILTER_OK": {
+ "format": "[IPCORE] ipc_disable_dhcp4c(): session context(%d) type(%d) deregistered DL filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_DIS_FAILED_WITH_INVALID_PARAMETER": {
+ "format": "[IPCORE] ipc_disable_dhcp4c(): invalid session_ptr!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_ACT_RSP_FIND_NO_SESSION": {
+ "format": "[IPCORE] ipc_on_dhcp4c_activate_rsp(): failed to find session for ip_id(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_ACT_RSP_OK": {
+ "format": "[IPCORE] ipc_on_dhcp4c_activate_rsp(): session context(%d) type(%d) gets dhcp4c_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_ACT_RSP_INVALID_SESSION": {
+ "format": "[IPCORE] ipc_on_dhcp4c_activate_rsp(): the session for ip_id(%d) became invalid!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_ACT_RSP_NG": {
+ "format": "[IPCORE] ipc_on_dhcp4c_activate_rsp(): session context(%d) type(%d) failed to activate DHCPv4!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_UP_IND_START": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_up_ind(): Start to handle DHCPv4 IP up indication : dhcp4c_ip_up_ind_ptr(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_UP_IND_FIND_SESSION_RESULT": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_up_ind(): Result of finding session to for ip up indication : session(0x%x), ip_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_UP_IND_SESSION_STATE": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_up_ind(): Current session state : session(0x%x), session_state(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_UP_IND_END": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_up_ind(): Handle DHCPv4 IP up indication is done : dhcp4c_ip_up_ind_ptr(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_UP_IND_SESSION_STATE_INCORRECT": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_up_ind(): session state is incorrect for ip_id(%d) : session(0x%x), state(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_UP_IND_FIND_NO_SESSION": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_up_ind(): failed to find session for ip_id(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_DOWN_IND_START": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_down_ind(): Start to handle DHCPv4 IP down indication : dhcp4c_ip_down_ind_ptr(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_DOWN_IND_FIND_SESSION_RESULT": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_down_ind(): Result of finding session to for ip down indication : session(0x%x), ip_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_DOWN_IND_SESSION_STATE": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_down_ind(): Current session state : session(0x%x), session_state(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_DOWN_IND_END": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_down_ind(): Handle DHCPv4 IP down indication is done : dhcp4c_ip_down_ind_ptr(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_DOWN_IND_SESSION_STATE_INCORRECT": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_down_ind(): session state is incorrect for ip_id(%d) : session(0x%x), state(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_DOWN_IND_FIND_NO_SESSION": {
+ "format": "[IPCORE] ipc_on_dhcp4c_ip_down_ind(): failed to find session for ip_id(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_PACKET_IND_UPLINK_NG": {
+ "format": "[IPCORE] ipc_on_dhcp4c_packet_ind(): failed to send the uplink GPD with ip_id(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_IP_PACKET_IND_FIND_NO_SESSION": {
+ "format": "[IPCORE] ipc_on_dhcp4c_packet_ind(): failed to find session for ip_id(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_ON_DL_PACKET_FIND_NO_SESSION": {
+ "format": "[IPCORE] ipc_on_dl_dhcp4_packet(): failed to find the session(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DHCP4C_ON_DL_PACKET_INVALID_GPD_LIST": {
+ "format": "[IPCORE] ipc_on_dl_dhcp4_packet(): discard the downlink IP datagram since head_gpd(0x%x) != tail_gpd(0x%x), length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_PACK_PKT_UDP_SIZE_NG": {
+ "format": "[IPCORE] ipc_pack_pkt(): uplink(%d) : ip_header(%u)+udp_header(%u)+data_len(%u) exceeds %u-byte!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_PACK_PKT_ALLOC_GPD_NG": {
+ "format": "[IPCORE] ipc_pack_pkt(): failed to allocate NET_UL_GPD for %u-byte of packet to send!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_PACK_PKT_SKIP_INVALID_GPD": {
+ "format": "[IPCORE] ipc_pack_pkt(): skip header pack for invalid GPD : gpd(0x%x), gpd_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_PACK_PKT_PUBLIC_FAILED": {
+ "format": "[IPCORE] ipc_pack_pkt_public(): failed to pack packet : isGPD(%d), hdr(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_PKT_PKT_PACK_FAILED": {
+ "format": "[IPCORE] ipc_send_ul_pkt(): failed to pack uplink packet : isGPD(%d), hdr(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_PKT_BY_PDN_PKT_PACK_FAILED": {
+ "format": "[IPCORE] ipc_send_ul_pkt_by_pdn(): failed to pack uplink packet : isGPD(%d), hdr(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_PKT_BY_PDN_SESSION_NOT_FOUND": {
+ "format": "[IPCORE] ipc_send_ul_pkt_by_pdn(): destination sesssion for pdn(%d), ip_type(%d) is not found!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_PKT_BY_NETIF_ID_PKT_PACK_FAILED": {
+ "format": "[IPCORE] ipc_send_ul_pkt_by_netif_id(): failed to pack uplink packet : isGPD(%d), hdr(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_PKT_BY_NETIF_ID_SESSION_NOT_FOUND": {
+ "format": "[IPCORE] ipc_send_ul_pkt_by_netif_id(): destination sesssion for netif_id(%d), ip_type(%d) is not found!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_PKT_BY_NETIF_ID_NETIF_NOT_FOUND": {
+ "format": "[IPCORE] ipc_send_ul_pkt_by_netif_id(): source netif for netif_id(%d) is not found!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_PKT_PKT_PACK_FAILED": {
+ "format": "[IPCORE] ipc_send_dl_pkt(): failed to pack downlink packet : isGPD(%d), hdr(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_PKT_NETIF_NOT_FOUND": {
+ "format": "[IPCORE] ipc_send_dl_pkt(): destination network interface for ID(%d) is not found!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_PKT_NETIF_DID_NOT_FOUND": {
+ "format": "[IPCORE] ipc_send_dl_pkt_in_did(): destination network interface for ID(0x%x) is not found for did_head(0x%x), did_tail(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_PKT_NETIF_DID_ALLOC_DID_NG": {
+ "format": "[IPCORE] ipc_send_dl_pkt_in_did(): Allocating new DID FAILED: head_gpd(0x%x), tail_gpd(0x%x), netif_id(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_PKT_NETIF_GPD_SENDING_FAIL": {
+ "format": "[IPCORE] ipc_data_qbm_downlink_dequeue(): Sending failed: head_gpd(0x%x), tail_gpd(0x%x), netif_id(0x%x), ",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DPFM_DL_ALLOC_DID_NG": {
+ "format": "[IPCORE] ipc_on_process_dl_meta(): Allocating new DID FAILED, Drop DL meta: pdn(%d) channel_id(0x%x) net_type(%d) line(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_NTFY_BEGIN": {
+ "format": "[IPCORE] ipc_register_ntfy(): register notification callback : callback(0x%X), callback context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_NTFY_END": {
+ "format": "[IPCORE] ipc_register_ntfy(): gotten ntfy ID(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREG_NTFY_BEGIN": {
+ "format": "[IPCORE] ipc_deregister_ntfy(): uinstall notification callback : ntfy ID(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREG_NTFY_END": {
+ "format": "[IPCORE] ipc_deregister_ntfy(): uinstall notification callback complete : ntfy ID(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_ALLOCATE_NTFY_INVALID_PARAMS": {
+ "apiType": "index",
+ "format": "[IPCORE] ipc_allocate_ntfy(): failed with invalid parameters: callback(0x%X), callback context(0x%X)",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_ALLOCATE_NTFY_UNAVAILABLE": {
+ "format": "[IPCORE] ipc_allocate_ntfy(): failed with all notification entries are busy now! : callback(0x%X), callback context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FREE_NTFY_INVALID_OBJECT": {
+ "format": "[IPCORE] ipc_free_ntfy(): it's an invalid object!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_ADD_NTFY_TO_LIST_INVALID_LIST": {
+ "format": "[IPCORE] ipc_add_ntfy_to_list(): invalid list(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REMOVE_NTFY_FROM_LIST_INVALID_LIST": {
+ "format": "[IPCORE] ipc_remove_ntfy_from_list(): invalid list(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NTFY_INIT_POOL_INFO": {
+ "format": "[IPCORE] ipc_ntfy_init(): IP CORE ntfy entry pool : addr(0x%X), count(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NTFY_INIT_LIST_INFO": {
+ "format": "[IPCORE] ipc_ntfy_init(): IP CORE ntfy list[%d] : addr(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NEW_NTFY_ADD_TO_LIST": {
+ "format": "[IPCORE] ipc_new_ntfy(): Add new ntfy with ID(%d) successfully for callback(0x%X) context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NEW_NTFY_NG": {
+ "format": "[IPCORE] ipc_new_ntfy(): Add new ntfy for callback(0x%X) context(0x%X) is failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_NTFY_WITH_INVALID_ID": {
+ "format": "[IPCORE] ipc_del_ntfy(): ntfy ID(%d) is invalid",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_NTFY_INFO": {
+ "format": "[IPCORE] ipc_del_ntfy(): entry with ntfy ID(%d) to delete : callback(0x%X), context(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_NTFY_REMOVE_FROM_LIST": {
+ "format": "[IPCORE] ipc_del_ntfy(): Remove entry with ntfy ID(%d) from list",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_NTFY_FREE_NTFY": {
+ "format": "[IPCORE] ipc_del_ntfy(): Free entry with ntfy ID(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEL_NTFY_NOT_FOUND": {
+ "apiType": "index",
+ "format": "[IPCORE] ipc_del_ntfy(): Entry with ntfy ID(%d) is not found/already invalid",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "IPC_TR_DO_NTFY_INFO": {
+ "format": "[IPCORE] ipc_do_ntfy(): Execute callback(0x%X) context(0x%X) for ntfy ID(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DO_NTFY_NTFY_INFO": {
+ "format": "[IPCORE] ipc_do_ntfy(): ntfy type(%d), netif_id(0x%X), ip_id(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_LINK_UP_IND_START": {
+ "format": "[IPCORE] ipc_on_ipcore_link_up_ind(): Start of default LINK_UP_IND handling for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_LINK_UP_IND_SEND_LINK_UP_RSP": {
+ "format": "[IPCORE] ipc_on_ipcore_link_up_ind(): Send LINK_UP_RSP ILM for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_LINK_UP_IND_END": {
+ "format": "[IPCORE] ipc_on_ipcore_link_up_ind(): End of default LINK_UP_IND handling for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_IP_UP_IND_START": {
+ "format": "[IPCORE] ipc_on_ipcore_ip_up_ind(): Start of default IP_UP_IND handling for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_IP_UP_IND_SEND_IP_UP_RSP": {
+ "format": "[IPCORE] ipc_on_ipcore_ip_up_ind(): Send IP_UP_RSP ILM for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_IP_UP_IND_END": {
+ "format": "[IPCORE] ipc_on_ipcore_ip_up_ind(): End of default IP_UP_IND handling for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_UP_RSP_START": {
+ "format": "[IPCORE] ipc_on_ipcore_up_rsp(): Start of LINK/IP_UP_RSP handling for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_UP_RSP_UPDATE_SESSION_STATE_TO_LINKUP": {
+ "format": "[IPCORE] ipc_on_ipcore_up_rsp(): Update session(0x%X) state to LINKUP",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_UP_RSP_SESSION_NOT_FOUND": {
+ "format": "[IPCORE] ipc_on_ipcore_up_rsp(): Session not found for netif(0x%X), netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_UP_RSP_NETIF_NOT_FOUND": {
+ "format": "[IPCORE] ipc_on_ipcore_up_rsp(): network interface not found for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_UP_RSP_END": {
+ "format": "[IPCORE] ipc_on_ipcore_up_rsp(): End of LINK/IP_UP_RSP handling for netif_id(0x%X), ip_id(0x%X), ip_type(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_LINK_UP_IND_HDLR_BEGIN": {
+ "format": "[IPCORE] ipc_register_link_up_ind_handler(): Register LINK_UP_IND ILM handler : Module (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_LINK_UP_IND_HDLR_END": {
+ "format": "[IPCORE] ipc_register_link_up_ind_handler(): Register LINK_UP_IND ILM handler complete : Module (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREG_LINK_UP_IND_HDLR_BEGIN": {
+ "format": "[IPCORE] ipc_deregister_link_up_ind_handler(): Uninstall registered LINK_UP_IND ILM handler",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREG_LINK_UP_IND_HDLR_END": {
+ "format": "[IPCORE] ipc_deregister_link_up_ind_handler(): Uninstall registered LINK_UP_IND ILM handler complete",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_IP_UP_IND_HDLR_BEGIN": {
+ "format": "[IPCORE] ipc_register_ip_up_handler(): Register IP_UP_IND ILM handler : Module (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SET_UL_THROTTLE_BEGIN": {
+ "format": "[IPCORE] ipc_set_ul_throttle(): Set UL throttle, old_state(%d), new_conf_enabled(%d), new_conf_activate(%d), new_conf_suspend(%d), features(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SET_UL_THROTTLE_END": {
+ "format": "[IPCORE] ipc_set_ul_throttle(): Set UL throttle, new_state(%d), new_conf_enabled(%d), new_conf_activate(%d), new_conf_suspend(%d), is_block_IMS(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_THROTTLE_SYSMSGSRV_CBK": {
+ "format": "[IPCORE] ipc_ul_throttle_sysmsgsvc_cbk(): CCCI_SYSMSG Set UL throttle, new_state(%d), new_conf_enabled(%d), new_conf_activate(%d), new_conf_suspend(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_IP_UP_IND_HDLR_END": {
+ "format": "[IPCORE] ipc_register_ip_up_handler(): Register IP_UP_IND ILM handler complete : Module (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREG_IP_UP_IND_HDLR_BEGIN": {
+ "format": "[IPCORE] ipc_deregister_ip_up_handler(): Uninstall registered IP_UP_IND ILM handler",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEREG_IP_UP_IND_HDLR_END": {
+ "format": "[IPCORE] ipc_deregister_ip_up_handler(): Uninstall registered IP_UP_IND ILM handler complete",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_LINK_UP_IND_HDLR_START": {
+ "format": "[IPCORE] ipc_update_link_up_ind_handler(): Update LINK_UP_IND ILM handler : Module (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATE_IP_UP_IND_HDLR_START": {
+ "format": "[IPCORE] ipc_update_ip_up_ind_handler(): Update IP_UP_IND ILM handler : Module (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_QUERY_INFO_START": {
+ "format": "[IPCORE] ipc_on_query_info(): Start to query information: src_mod_id(%d), local_para_ptr(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_QUERY_INFO_CNF": {
+ "format": "[IPCORE] ipc_on_query_info(): Send confirmation back to src_mod_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_QUERY_INFO_NO_MOD_ID_FOR_CFN": {
+ "format": "[IPCORE] ipc_on_query_info(): No source module ID to send confirmation back ! src_mod_id(%d) is MOD_NIL(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_QUERY_INFO_END": {
+ "format": "[IPCORE] ipc_on_query_info(): Query information handling is done",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_QUERY_NETIF_LIST_START": {
+ "format": "[IPCORE] ipc_query_netif_list(): Query netif list : netif_list_p(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_QUERY_NETIF_LIST_INFO": {
+ "format": "[IPCORE] ipc_query_netif_list(): Attached netif: idx(%d) netif_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_QUERY_NETIF_LIST_SUCCESS": {
+ "format": "[IPCORE] ipc_query_netif_list(): Netif list query success. Total attached netif count(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_QUERY_NETIF_LIST_FAILED": {
+ "format": "[IPCORE] ipc_query_netif_list(): No structure to store netif list status, failed !",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_CLARIFY_ZERO_LENGTH_PKT": {
+ "format": "[IPCORE] ipc_clarify_gpd(): Found zero length packet during clarification : curr_gpd(0x%x), length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_CLARIFY_ZERO_LENGTH_BD": {
+ "format": "[IPCORE] ipc_clarify_gpd(): Found packet with ALL ZERO-length BD list during clarification : curr_gpd(0x%x), gpd length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_CLARIFY_NONE_IP_PKT": {
+ "format": "[IPCORE] ipc_clarify_gpd(): Found non-IPv4/IPv6 packet, drop : curr_gpd(0x%x), gpd length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_CLARIFY_ZERO_LENGTH_PKT_DROP": {
+ "format": "[IPCORE] ipc_clarify_gpd(): Drop packet with invalid payload : curr_gpd(0x%x), gpd length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_CHANGE_GPD_TYPE_ZERO_LENGTH_BD": {
+ "format": "[IPCORE] ipc_gpd_change_gpd_type(): Found packet with ALL ZERO-length BD list during clarification : curr_gpd(0x%x), gpd length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_CHANGE_GPD_TYPE_ALLOC_GPD_NG": {
+ "format": "[IPCORE] ipc_gpd_change_gpd_type(): Allocate new GPD for different type is FAILED: gpd_type(%d), p_gpd(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GPD_COPY_BEGIN": {
+ "format": "[IPCORE] ipc_gpd_copy(): Start to copy GPD: dst_buffer(0x%x), dst_max_len(%d), dst_len_copied(0x%x), src_head_gpd(0x%x), src_tail_gpd(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GPD_COPY_END": {
+ "format": "[IPCORE] ipc_gpd_copy(): GPD copy result: retval(%d), dst_max_len(%d), *dst_len_copied(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GPD_UNITE_NULL_BD_LIST": {
+ "format": "[IPCORE] ipc_gpd_unite(): Null BD list (no BD have data) is found: uplink(%d), p_gpd_in(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GPD_UNITE_ZERO_LENGTH_GPD": {
+ "format": "[IPCORE] ipc_gpd_unite(): zero length GPD is found: uplink(%d), p_gpd_in(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GPD_UNITE_ALLOC_GPD_NG": {
+ "format": "[IPCORE] ipc_gpd_unite(): Allocate new GPD for uniting is FAILED: uplink(%d), p_gpd_in(0x%x), total_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GPD_UNITE_GPD_COPY_NG": {
+ "format": "[IPCORE] ipc_gpd_unite(): GPD copy is FAILED: uplink(%d), p_buff(0x%x), total_len(%d), copied_len(%d), p_gpd_in(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GPD_UNITE_FAILED": {
+ "format": "[IPCORE] ipc_gpd_unite(): GPD uniting is FAILED: uplink(%d), p_gpd_in(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SIT_TO_GPD_FAIL": {
+ "format": "[IPCORE] %s(): Allocate new GPD for packet_len(%d) is FAILED: gpd_type(%d), did(0x%x), curr_si_idx(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_TO_GPD_FAIL": {
+ "format": "[IPCORE] %s(): Allocate new GPD for packet_len(%d) is FAILED: gpd_type(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SI_UNITE_ALLOC_GPD_NG": {
+ "format": "[IPCORE] ipc_si_unite_to_gpd(): Allocate new GPD for uniting is FAILED: gpd_type(%d), did(0x%x), curr_si_idx(%d), pkt_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SHIFT_OFFSET_FAILED": {
+ "format": "[IPCORE] ipc_shift_gpd_content_ptr(): GPD is too short to get offset! gpd(0x%x) base_bd(0x%x) curr_bd(0x%x) curr_bd_len(%d) remaining_offset(%d) base_addr_p(0x%x) offset(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DID_SHIFT_OFFSET_FAILED": {
+ "format": "[IPCORE] ipc_shift_did_content_ptr(): DID/SIT is too short to get offset! did(0x%x) base_si_idx(%d) curr_si_idx(%d) curr_si_len(%d) remaining_offset(%d) base_addr_p(0x%x) offset(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_CONTENT_LENGTH_TOO_SHORT": {
+ "format": "[IPCORE] ipc_get_continuous_content(): GPD is too short to shift offset! gpd(0x%x) base_bd(0x%x) curr_bd(0x%x) base_addr_p(0x%x) offset(%d) length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_CONTENT_LENGTH_TOO_SHORT_TO_COPY": {
+ "format": "[IPCORE] ipc_get_continuous_content(): GPD is too short to copy specific continuous content! gpd(0x%x) base_bd(0x%x) curr_bd(0x%x) curr_bd_len(%d) remaining_length(%d) base_addr_p(0x%x) offset(%d) length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DID_CONTENT_LENGTH_TOO_SHORT": {
+ "format": "[IPCORE] ipc_get_continuous_content_did(): DID/SIT is too short to shift offset! did(0x%x) base_si_idx(%d) curr_si_idx(%d) base_addr_p(0x%x) offset(%d) length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DID_CONTENT_LENGTH_TOO_SHORT_TO_COPY": {
+ "format": "[IPCORE] ipc_get_continuous_content_did(): DID/SIT is too short to copy specific continuous content! did(0x%x) base_si_idx(%d) curr_si_idx(%d) curr_si_len(%d) remaining_length(%d) base_addr_p(0x%x) offset(%d) length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GET_INFO_FAILED": {
+ "format": "[IPCORE] ipc_get_packet_info(): fail_reason(%Mipc_packet_info_parser_error_code), ip_packet(0x%x), offset(%d), gpd(0x%x), curr_bd(0x%x), length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GET_INFO_SHIFT_FAILED": {
+ "format": "[IPCORE] ipc_get_packet_info(): fail_reason(%Mipc_packet_info_parser_error_code), gpd(0x%x) base_bd(0x%x) ip_packet(0x%x) offset(%d) next_header(0x%x) curr_bd(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GET_INFO_SPD_FAILED": {
+ "format": "[IPCORE] ipc_get_packet_info_spd(): fail_reason(%Mipc_packet_info_parser_error_code),ip_packet(0x%x), data_len(%d), packet_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GET_INFO_DID_FAILED": {
+ "format": "[IPCORE] ipc_get_packet_info_did(): fail_reason(%Mipc_packet_info_parser_error_code): ip_packet(0x%x), offset(%d), did(0x%x), base_si_idx(0x%x), length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GET_INFO_DID_SHIFT_FAILED": {
+ "format": "[IPCORE] ipc_get_packet_info_did(): fail_reason(%Mipc_packet_info_parser_error_code) did(0x%x) base_si_idx(%d) ip_packet(0x%x) offset(%x) next_header(0x%x) curr_si_idx(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DO_FILTER_INVALID_GPD": {
+ "format": "[IPCORE] ipc_do_filter(): got an invalid GPD(0x%X)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DO_FILTER_ALLOC_GPD_NG": {
+ "format": "[IPCORE] ipc_do_filter(): Allocating new GPD for the SPD filtered out packet is FAILED: uplink(%d), QBM_TYPE_NET(%d), spd(0x%x), idx(%d), payload_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_META_DO_FILTER_ALLOC_GPD_NG": {
+ "format": "[IPCORE] ipc_meta_do_filter(): Allocating new GPD for the META filtered out packet is FAILED: uplink(%d), META(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_LAN_NETIF_BIND_INVALID_NETIF": {
+ "format": "[IPCORE] ipc_bind_lan_netif(): netifs not found for netif_1(0x%x)/id(0x%x) && netif_2(0x%x)/id(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_LAN_NETIF_UNBIND_INVALID_NETIF": {
+ "format": "[IPCORE] ipc_unbind_lan_netif(): netifs not found for netif_1(0x%x)/id(0x%x) && netif_2(0x%x)/id(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DID_GET_PKT_LENGTH_FAILED": {
+ "format": "[IPCORE] ipc_did_do_filter(): Get first 6B continuous content failed: ip_packet(0x%x), did(0x%x), curr_idx(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_COPY_GPD_TO_DID_ZERO_LENGTH_GPD": {
+ "format": "[IPCORE] ipc_copy_gpd_to_did(): Zero length GPD: curr_gpd(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_COPY_GPD_TO_DID_ZERO_ALLOC_PRB_NG": {
+ "format": "[IPCORE] ipc_copy_gpd_to_did(): Allocating new PRB FAILED: curr_gpd(0x%x), tail_gpd(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_COPY_GPD_TO_DID_GPD_LENGTH_NG": {
+ "format": "[IPCORE] ipc_copy_gpd_to_did(): GPD/BD length is not expected: curr_gpd(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FIND_PDN_BY_NETIF_SESSION_RLOCK_FAILED": {
+ "format": "[IPCORE] ipc_find_pdn_id_by_netif_id(): session RLOCK is FAILED: netif_id(0x%x), ip_type(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FIND_PDN_BY_NETIF_NETIF_RLOCK_FAILED": {
+ "format": "[IPCORE] ipc_find_pdn_id_by_netif_id(): netif RLOCK is FAILED: netif_id(0x%x), ip_type(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_MATCHED_CLONED": {
+ "format": "[IPCORE] ipc_pkt_do_one_filter(): Filter matched cloned !!!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILTER_MATCHED_CLONED_DEFAULT_PATH": {
+ "format": "[IPCORE] ipc_did_do_filter(): Filter matched cloned case, it didn't set ignore bit, keep default data path",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_DROP_FOR_INVALID_NETIF": {
+ "format": "[IPCORE] ipc_on_process_dl_meta(): invalid netif reported by pn_match cur_idx(%d) pdn_id(0x%x) net_type(0x%x) channel_id(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_DROP_FOR_PN_NO_MATCH": {
+ "format": "[IPCORE] ipc_on_process_dl_meta(): packet drop !! pn_no_match cur_idx(%d) rb_id(%d) pdn_id(0x%x) net_type(0x%x) channel_id(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_PN_MATCH_SETTING": {
+ "format": "[IPCORE] ipc_update_pn_match_setting(): pn_match setting param pdn_sim_id(0x%x) nc_id(0x%x) ipv4(%d) ipv6(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UNKNOWN_ILM": {
+ "format": "[IPCORE] ipc_on_ilm(): unknown ilm ID (0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_PN_MATCH_CMD_UNKNOWN": {
+ "format": "[IPCORE] ipc_update_pn_match_setting(): unknown pnm_cmd(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UNBIND_DROP_UL_META": {
+ "format": "[IPCORE] ipc_data_drop_ul_meta_by_pdn(): PDN(0x%x) is unbinding! drop UL meta index(%d), meta_pdn_sim_id(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UL_IGNORE_NET_TYPE_DROP": {
+ "format": "[IPCORE] ipc_on_process_ul_meta_table(): NET_TYPE is IGNORE! drop UL meta index(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_FILL_DID_FROM_META_NG": {
+ "format": "[IPCORE] ipc_utils_fill_did_si_from_meta(): cur_si_idx(%d) exceeds maximum, is_adjust(%d), did_ptr(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SET_RQ_INFO_FAILED_PROTOCOL": {
+ "format": "[IPCORE] ipc_data_set_rq_info(): Set rq info failed : no protocol",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SET_RQ_INFO_FAILED_IP": {
+ "format": "[IPCORE] ipc_data_set_rq_info(): Set rq info failed : no IP address",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SET_RQ_INFO_FAILED_QFI": {
+ "format": "[IPCORE] ipc_data_set_rq_info(): Set rq info failed : no QFI",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_ALLOC_PEER_BUF_FAILED": {
+ "format": "[IPCORE] %s(): Allocate Peer buffer failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPCORE_SESSION_NOT_FOUND": {
+ "format": "[IPCORE] %s(): Session not found for pdn_id(0x%x))",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_NO_PKT_INFO": {
+ "format": "[IPCORE] %s(): Cannot save RQ info since no packet info",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NO_PKT_INFO_DID": {
+ "format": "[IPCORE] ipc_did_do_filter(): ipc_get_packet_info_did failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_NR_RQI_IS_SET": {
+ "format": "[IPCORE] %s(): To save RQ Rule from meta(0x%x) HW filter result(0x%x) SW filter result(0x%x) meta->tcp_flag(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_INPUT_DID": {
+ "format": "[IPCORE] %s(): Invalid argument : p_did_head or p_did_tail is NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_NETIF_ID": {
+ "format": "[IPCORE] %s(): Invalid netif_id : net_type(0x%x) ch_id(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RQ_LIST": {
+ "format": "[IPCORE] %s(): Invalid argument : p_rq_list is NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RQ_LIST_INFO": {
+ "format": "[IPCORE] %s(): Invalid argument : p_rq_list is NULL or p_rq_info is NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RQ_INFO_PKT_DES": {
+ "format": "[IPCORE] %s(): Invalid argument : p_rq_info is NULL or p_pkt_info is NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_ARGS": {
+ "format": "[IPCORE] %s(): Invalid argument : input pointer was NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_PDN_PROTO_IDX": {
+ "format": "[IPCORE] %s(): Invalid argument : invalid pdn (0x%x) proto_idx (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_DESCRIPTOR": {
+ "format": "[IPCORE] %s(): Invalid descriptor des_type (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_NETIF": {
+ "format": "[IPCORE] %s(): Invalid netif_id (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_DATA_PATH_DIR": {
+ "format": "[IPCORE] %s(): Invalid data_path_direct (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_FILTER_RULES": {
+ "format": "[IPCORE] %s(): p_rules was NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_FILTER_CTXT": {
+ "format": "[IPCORE] %s(): p_ntfy_ctxt was NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_FILTER_NTFY_TYPE": {
+ "format": "[IPCORE] %s(): Invalid filter ntfy_type (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REGISTER_FILTER": {
+ "format": "[IPCORE] %s(): Register filter data_path_dir (0x%x) ntfy_type (0x%x) filter_id (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DEGISTER_FILTER": {
+ "format": "[IPCORE] %s(): Deregister filter filter_id (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_SPI": {
+ "format": "[IPCORE] ipc_validate_rules(): uplink(%d), valid_fields(0x%X), ip_type(%d) and features(0x%X) are invalid for spi!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_INVALID_RULES_FOR_CUST_FILTER": {
+ "format": "[IPCORE] ipc_validate_rules(): uplink(%d), valid_fields(0x%X), ip_type(%d) and features(0x%X) are invalid for cust filter!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_B4_DROP_GPD_ALLOC_NG": {
+ "format": "[IPCORE] %s():%d: GPD allocation failed in drop packet handler",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_B4_DROP_GPD_ALLOC_NG_CNT": {
+ "format": "[IPCORE] %s():%d: failed_cnt=%d: GPD allocation failed in drop packet handler",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_B4_DROP_INVALID_PARAM": {
+ "format": "[IPCORE] %s(): Invalid input parameter p_packet(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DROP_HDLR_NG_PROTO": {
+ "format": "[IPCORE] %s(): unknown protocol(0x%x) is not supported in drop packet handler",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_B4_DROP_SEND_UL_GPD": {
+ "format": "[IPCORE] %s(): detect TCP packet before drop, send response 1st GPD(0x%x) and 2nd GPD(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DROP_HDLR_UNKNOWN_IPTYPE": {
+ "format": "[IPCORE] %s(): unknown IP_TYPE is not supported in drop packet handler",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DROP_HDLR_PKT_INFO_NG": {
+ "format": "[IPCORE] %s(): packet info parsing NG in drop packet handler",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DOWNLINK_RA_PROXY_GPD": {
+ "format": "[IPCORE] %s(): pdn_id = 0x%x, copy RA did to GPD 0x%x",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DOWNLINK_RA_PROXY_GPD_ALLOC_NG": {
+ "format": "[IPCORE] %s(): pdn_id - 0x%x, copy RA did to GPD 0x%x",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_GET_PDN_ID_FAILED": {
+ "format": "[IPCORE] %s(): Get pdn by netif failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SEND_RA_GPD_NETIF": {
+ "format": "[IPCORE] %s(): Send RA GPD (0x%x) to RSRA proxy for netif_id (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SEND_RA_GPD_PUSH_BY_PDN": {
+ "format": "[IPCORE] %s(): push RA GPD (0x%x) for PDNID (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPF_DROP_HDR_INVALID_PARAM": {
+ "format": "[IPCORE] %s(): Invalid parameter p_packet(0x%x), len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DID_DROP_HDR_INVALID_PARAM": {
+ "format": "[IPCORE] %s(): Invalid parameter p_head(0x%x), p_tail(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DROP_HDR_GPD_ALLOC_NG": {
+ "format": "[IPCORE] %s():%d: GPD allocation failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_B4_DROP_UDP_PREPARE_UL_GPD_NG": {
+ "format": "[IPCORE] %s(): rsp not sent, packet len [%d], exceed max gpd size",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_B4_DROP_UDP_PREPARE_UL_GPD": {
+ "format": "[IPCORE] %s(): ICMP port unreachable pkt prepared",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DL_META_B4_DROP_UDP_SEND_UL_GPD": {
+ "format": "[IPCORE] %s(): detect UDP packet before drop, send response 1st GPD(0x%x) and 2nd GPD(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_RESTORE_PDN_MAPPING": {
+ "format": "[IPCORE] %s(): restore pdn session (0x%x) with netif_id (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_DELETE_PDN_MAPPING": {
+ "format": "[IPCORE] %s(): delete pdn session (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_UPDATED_PDN_MAPPING": {
+ "format": "[IPCORE] %s(): updated pdn session (0x%x) with new pdn session (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SAVED_PDN_MAPPING": {
+ "format": "[IPCORE] %s(): saved pdn session (0x%x) with netif_id (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SAVED_PDN_MAPPING_FAILED": {
+ "format": "[IPCORE] %s(): ipc_session_save_netif_map failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_UNEXPECTED_FILTER_CHK_RESULT": {
+ "format": "[IPCORE] %s():%d: pending dereg v4_cnt (0x%x) v6_cnt (0x%x), cannot add ip_type(0x%x) filter, reserved_cnt (0x%x)",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_FILTER_HW_NUM_FULL": {
+ "format": "[IPCORE] %s(): hw filter entry was full (0x%x), pending dereg cnt (0x%x), cannot add ip_type(0x%x) filter, reserved_cnt (0x%x)",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_FILTER_HW_NUM_CHK_FAILED": {
+ "format": "[IPCORE] %s(): hw filter entry check wrong full (0x%x), pending dereg v4_cnt (0x%x) v6_cnt (0x%x), cannot add ip_type(0x%x) filter, reserved_cnt (0x%x)",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_BYPASS_HW_FILTER_SYNC": {
+ "format": "[IPCORE] %s(): bypass sync to HW filter with filter_id (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_SET_BYPASS_HW_FILTER_SYNC": {
+ "format": "[IPCORE] %s(): set bypass sync to HW filter with filter_id (0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_REG_FILTER_FAILED_HW_ENTRY_FULL": {
+ "format": "[IPCORE] %s(): hw filter entry was full",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_IPF_DL_MODE_SWITCH": {
+ "format": "[IPCORE] %s(): IPF DL mode switch, request_is_hw_mode(%d), cur_is_hw_mode(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_TR_IPF_DL_MODE_SWITCH_NOTHING": {
+ "format": "[IPCORE] %s(): IPF DL mode switch, target mode is equal to current mode, do nothing!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GET_FILTER_SET_INVALID_PARAMS": {
+ "format": "[PFM] pfm_get_filter_set_by_id(): Invalid parameters: filter_set_list(0x%x), list_size(%d), filter_set_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GET_FILTER_SET_NEW_FILTER_SET": {
+ "format": "[PFM] pfm_get_filter_set_by_id(): New filter set: filter_set_list(0x%x), filter_set_id(%d), filter_set(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEL_FILTER_SET_BEGIN": {
+ "format": "[PFM] pfm_delete_filter_set(): Delete filter set: filter_set(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DISPATCH_REGISTER_CMD_NULL_PARAMS": {
+ "format": "[PFM] pfm_dispatch_register_cmd(): Invalid parameters: parameters should not be NULL!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DISPATCH_REGISTER_CMD_INVALID_PARAMS": {
+ "format": "[PFM] pfm_dispatch_register_cmd(): Invalid parameters: local_para_ptr(0x%x), filter_set_id(%d), filter_cnt(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DISPATCH_REGISTER_CMD_BEGIN": {
+ "format": "[PFM] pfm_dispatch_register_cmd(): Dispatch register cmd: filter_set_id(0x%x), filter_cnt(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_FILTER_BEGIN": {
+ "format": "[PFM] pfm_deregister_filter(): Deregister the filter: uplink(%d), filter_set(0x%x), filter_id(%d), ipc_filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_FILTER_WITH_INVALID_PARAMS": {
+ "format": "[PFM] pfm_deregister_filter(): Invalid parameters: uplink(%d), filter_set(0x%x), filter_id(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_FILTERS_NULL_PARAMS": {
+ "format": "[PFM] pfm_deregister_filters(): Invalid parameters: parameters should not be NULL!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_FILTERS_INVALID_PARAMS": {
+ "format": "[PFM] pfm_deregister_filters(): Invalid parameters: local_para_ptr(0x%x), filter_set_id(%d), filter_cnt(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_FILTERS_INFO": {
+ "format": "[PFM] pfm_deregister_filters(): Deregister some filters: uplink(%d), filter_set_id(%d), filter_cnt(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_FILTERS_FILTER_SET_NOT_FOUND": {
+ "format": "[PFM] pfm_deregister_filters(): uplink(%d), filter_set_id(%d) is not found!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_REG_FILTER_INVALID_PARAMS": {
+ "format": "[PFM] pfm_register_filter(): Invalid parameters: filter_set_id(%d), filter_id(%d), rules(0x%x)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_REG_FILTER_FAILED": {
+ "format": "[PFM] pfm_register_filter(): Register filter is failed!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_REG_FILTER_FILTER_SET_NOT_FOUND": {
+ "format": "[PFM] pfm_register_filter(): uplink(%d), filter_set_id(%d) is not found!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_REG_FILTER_CBK_BEGIN": {
+ "format": "[PFM] pfm_register_filter_cbk(): filter_set_id(%d), filter_id(%d), uplink(%d), rules(0x%x) callback_func(0x%x) callback_context(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_REG_FILTER_MSG_BEGIN": {
+
+ "format": "[PFM] pfm_register_filter_msg(): filter_set_id(%d), filter_id(%d), uplink(%d), rules(0x%x) callback_module(0x%x) callback_context(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_REG_FILTER_WITH_INFO_CBK_BEGIN": {
+ "format": "[PFM] pfm_register_filter_with_info_cbk(): filter_set_id(%d), filter_id(%d), uplink(%d), rules(0x%x) callback_func(0x%x) callback_context(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_REG_FILTER_WITH_INFO_MSG_BEGIN": {
+ "format": "[PFM] pfm_register_filter_with_info_msg(): filter_set_id(%d), filter_id(%d), uplink(%d), rules(0x%x) callback_module(0x%x) callback_context(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_ZERO_LENGTH_GPD": {
+ "format": "[PFM] pfm_garbage_filter_deregister_callback(): Get zero length GPD(0x%x).",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_NON_TCP_PACKET": {
+ "format": "[PFM] pfm_garbage_filter_deregister_callback(): Should get TCP packets only! GPD(0x%x), proto(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_NON_IPV4_PACKET": {
+ "format": "[PFM] pfm_garbage_filter_deregister_callback(): Should get IPv4 packets only! GPD(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_REPLY_RST_FAIL": {
+ "format": "[PFM] pfm_garbage_filter_deregister_callback(): Replay TCP RST is failed! Can't alloc HIF_UL_TYPE_S GPD! dst_address(0x%x), src_port(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_REPLY_RST": {
+ "format": "[PFM] pfm_garbage_filter_deregister_callback(): Replay TCP RST dst_address(0x%x), src_port(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_REG_PARSER": {
+ "format": "[PFM] pfm_garbage_filter_register_parser(): Register filter rules: filter_id(%d), ip_type(%d), protocol(%d), dst_port(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_WRONG_MAGIC_CODE": {
+ "format": "[PFM] %s(): Wrong magic code is detected when registering filter(%d)!",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_INVALID_PARAMS": {
+ "format": "[PFM] pfm_garbage_filter_register_parser(): Invalid parameters is detected: ip_type(%d), protocol(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_FILTER_INVALID_FILTER_ID": {
+ "format": "[PFM] %s(): Invalid Filter ID!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_RECEIVED_AP_STATUS": {
+ "format": "[PFM] pfm_ap_status_parser(): Received AP status (%s)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_RECEIVED_AP_INVALID_STATUS": {
+ "format": "[PFM] pfm_ap_status_parser(): Invalid AP status",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_RECEIVED_AP_SUSPEND_CMD": {
+ "format": "[PFM] pfm_ap_suspend_handler(): Received AP command (%u)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_FIN_ACK_FILTER_REQ": {
+ "format": "[PFM] pfm_ap_fin_ack_reduction_handler(): Send PFM Register ILM with set id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_ALLOCATE_FAILED": {
+ "format": "[PFM] pfm_ap_fin_ack_reduction_handler(): Allocate local para failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_SEND_ILM_FAILED": {
+ "format": "[PFM] pfm_ap_fin_ack_reduction_handler(): Send ILM failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_REGISTER_FILTER_ID_V4": {
+ "format": "[PFM] pfm_fin_ack_filter_register_parser(): Registered fin ack v4 filter with filter id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_REGISTER_FILTER_ID_V6": {
+ "format": "[PFM] pfm_fin_ack_filter_register_parser(): Registered fin ack v6 filter with filter id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_REGISTER_FILTER_FAILED": {
+ "format": "[PFM] pfm_fin_ack_filter_register_parser(): Registered filter failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_DEREGISTER_FILTER": {
+ "format": "[PFM] pfm_fin_ack_filter_deregister_callback(): Deregistered fin ack v4 filter id (%d), v6 filter id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_REPLY_RST": {
+ "format": "[PFM] pfm_fin_ack_filter_cbk(): Replay TCP RST GPD(0x%x), src_port(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_NO_ACTION_V4": {
+ "format": "[PFM] pfm_fin_ack_filter_register_parser(): Already registered v4 filter (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FIN_ACK_FILTER_NO_ACTION_V6": {
+ "format": "[PFM] pfm_fin_ack_filter_register_parser(): Already registered v6 filter (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_UDP_IGMP_FILTER_DROP": {
+ "format": "[PFM] %s(): drop packet with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_IGMP_FILTER_REGISTER_FILTER_ID_V4": {
+ "format": "[PFM] %s(): register v4 IGMP filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_IGMP_FILTER_REGISTER_FILTER_ID_V6": {
+ "format": "[PFM] %s(): register v6 IGMP filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_UDP_FILTER_REGISTER_FILTER_ID_V4": {
+ "format": "[PFM] %s(): register v4 UDP filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_UDP_FILTER_REGISTER_FILTER_ID_V6": {
+ "format": "[PFM] %s(): register v6 UDP filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FILTER_REGISTER_NO_ACTION": {
+ "format": "[PFM] %s(): already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEGISTER_IGMP_FILTER": {
+ "format": "[PFM] %s(): deregistered IGMP filter with v4_filter_id (%d), v6_filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEGISTER_UDP_FILTER": {
+ "format": "[PFM] %s(): deregistered UDP filter with v4_filter_id (%d), v6_filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s(): register filter failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_CMD_PARSER": {
+ "format": "[PFM] %s(): garbage string filter command parser, is_reg(%d), buf(0x%x), filter_cnt(%d), is_uplink(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_FLT_ID_EXIST": {
+ "format": "[PFM] %s(): garbage string filter_id is in-used, filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_NETIF_ALLOC_NG": {
+ "format": "[PFM] %s(): garbage string netif is exhausted, mask(0x%x), num(%d), netif_id(0x%x)",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_ALLOC_NG": {
+ "format": "[PFM] %s(): garbage string filter is exhausted, mask(0x%x), num(%d), filter_id(%d)",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_REG_PARSER": {
+ "format": "[PFM] %s(): garbage string filter register parser, filter_id(%d), netif_id(0x%x), filter_len(%d), mask_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_DEREG_CNT_NG": {
+ "format": "[PFM] %s(): garbage string filter deregister number is un-synced",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_DEREG_DEL": {
+ "format": "[PFM] %s(): garbage string filter set is going to delete, ipc_filter_id(%d)",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): garbage string filter ipc filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMP_PING_FILTER_ALLOCATE_FAILED": {
+ "format": "[PFM] %s(): Allocate local para failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMP_PING_FILTER_SEND_ILM_FAILED": {
+ "format": "[PFM] %s(): Send ILM failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV4_PING_REQ_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV4 echo request filter ipc filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV4_PING_REPLY_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV4 echo reply filter ipc filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_PING_REQ_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV6 echo request filter ipc filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_PING_REPLY_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV6 echo reply filter ipc filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMP_PING_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s():%d: ICMP ping register filter failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_ICMP_PING_FILTER_NO_ACTION": {
+ "format": "[PFM] %s():%d: already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEGISTER_ICMPV4_PING_FILTER": {
+ "format": "[PFM] %s(): deregistered ICMPV4 filters with echo_req_filter_id (%d), echo_reply_filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEGISTER_ICMPV6_PING_FILTER": {
+ "format": "[PFM] %s(): deregistered ICMPV6 filters with echo_req_filter_id (%d), echo_reply_filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DISABLE_ALL_PACKETS_FILTER_REGISTER_FILTER_ID": {
+ "format": "[PFM] %s(): UL disable-all-packets filter filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DISABLE_ALL_PACKETS_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s(): UL disable-all-packets filter register failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_DISABLE_ALL_PACKETS_FILTER_NO_ACTION": {
+ "format": "[PFM] %s(): already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DISABLE_ALL_PACKETS_FILTER_DROP": {
+ "format": "[PFM] %s(): drop packet with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_DISABLE_ALL_PACKETS_FILTER": {
+ "format": "[PFM] %s(): filter_id (%d) deregistered",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV4_PING_REQ_BYPASS_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV4 echo request bypass filter ipc filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV4_PING_REQ_BYPASS_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s(): ICMPV4 echo request bypass filter register failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_ICMPV4_PING_REQ_BYPASS_FILTER_NO_ACTION": {
+ "format": "[PFM] %s(): already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV4_PING_REPLY_BYPASS_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV4 echo reply bypass filter ipc filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV4_PING_REPLY_BYPASS_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s(): ICMPV4 echo reply bypass filter register failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_ICMPV4_PING_REPLY_BYPASS_FILTER_NO_ACTION": {
+ "format": "[PFM] %s(): already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_PING_REQ_BYPASS_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV6 echo request bypass filter ipc filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_PING_REQ_BYPASS_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s(): ICMPV6 echo request bypass filter register failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_PING_REQ_BYPASS_FILTER_NO_ACTION": {
+ "format": "[PFM] %s(): already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_PING_REPLY_BYPASS_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV6 echo reply bypass filter ipc filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_PING_REPLY_BYPASS_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s(): ICMPV6 echo reply bypass filter register failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_PING_REPLY_BYPASS_FILTER_NO_ACTION": {
+ "format": "[PFM] %s(): already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_NON_PING_FILTER_REGISTER_FILTER_ID": {
+ "format": "[PFM] %s(): Non-Ping packets wild card filter ipc filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_NON_PING_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s(): Non-Ping packets wild card filter register failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_NON_PING_FILTER_NO_ACTION": {
+ "format": "[PFM] %s(): already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_RS_BYPASS_FILTER_IPC_FILTER_ID": {
+ "format": "[PFM] %s(): ICMPV6 rs bypass filter ipc filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_RS_BYPASS_FILTER_REGISTER_FAILED": {
+ "format": "[PFM] %s(): ICMPV6 rs bypass filter register failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_ICMPV6_RS_BYPASS_FILTER_NO_ACTION": {
+ "format": "[PFM] %s(): already registered filter with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_ICMP_PING_WHITELIST_FILTER_DROP": {
+ "format": "[PFM] %s(): drop packet with filter_id (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_ICMPV4_PING_REQ_BYPASS_FILTER": {
+ "format": "[PFM] %s(): filter_id (%d) deregistered",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_ICMPV4_PING_REPLY_BYPASS_FILTER": {
+ "format": "[PFM] %s(): filter_id (%d) deregistered",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_ICMPV6_PING_REQ_BYPASS_FILTER": {
+ "format": "[PFM] %s(): filter_id (%d) deregistered",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_ICMPV6_PING_REPLY_BYPASS_FILTER": {
+ "format": "[PFM] %s(): filter_id (%d) deregistered",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_ICMPV6_RS_BYPASS_FILTER": {
+ "format": "[PFM] %s(): filter_id (%d) deregistered",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_NON_PING_FILTER": {
+ "format": "[PFM] %s(): filter_id (%d) deregistered",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_UL_DISABLE_ALL_PACKETS_FILTER_ALLOCATE_FAILED": {
+ "format": "[PFM] %s(): UL disable-all-packets filter allocate failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_UL_DISABLE_ALL_PACKETS_FILTER_SEND_ILM_FAILED": {
+ "format": "[PFM] %s(): UL disable-all-packets filter send ILM failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_UL_ICMP_PING_WHITELIST_FILTER_ALLOCATE_FAILED": {
+ "format": "[PFM] %s(): UL icmp ping whitelist filter send ILM failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_UL_ICMP_PING_WHITELIST_FILTER_SEND_ILM_FAILED": {
+ "format": "[PFM] %s(): UL icmp ping whitelist filter send ILM failed",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_TR_DATA_USAGE_INFO": {
+ "format": "[IPCORE] %s(): PDN(%u), Uplink Bytes(%u), Downlink Bytes(%u), Uplink Packets(%u), Downlink Packets(%u)",
+ "traceClass": "TRACE_DEBUG"
+ }
+ },
+ {
+ "IPC_TR_DATA_USAGE_RESET": {
+ "format": "[IPCORE] %s(): Reset Data usage for pdn_id(%u)",
+ "traceClass": "TRACE_DEBUG"
+ }
+ },
+ {
+ "IPC_TR_INVALID_PDN_ID": {
+ "format": "[IPCORE] %s(): Invalid pdn_id",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "PFM_TR_REG_CBK_WAKE_TYPE_PKT": {
+ "format": "[PFM] %s(): Register callback(0x%x) for wake type packet",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_DEREG_CBK_WAKE_TYPE_PKT": {
+ "format": "[PFM] %s(): De-register callback of wake type packet",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_PKT_FW": {
+ "format": "[PFM] %s(): Matched Packet forwared in callback(0x%x), pkt(0x%x), len(%d), pfm_str_filter_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "PFM_TR_GARBAGE_STR_FILTER_CBK_NULL": {
+ "format": "[PFM] %s(): No callback registered for wake type packet",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "IPC_RECEIVED_UL_META_INFO": {
+ "format": "[IPCORE] Received ul meta meta_idx (%d) match_idx (%d), match_result (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_FORCE_SW_PATH": {
+ "format": "[IPCORE] %s(): switch to SW path (%d) with proto_idx (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_RESET_HW_FILTER": {
+ "format": "[IPCORE] %s(): reset hw filter entry",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPC_DATA_PATH_STATUS": {
+ "format": "[IPCORE] %s(): current is_sw_path (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPF_IT_REGISTERED_FILTER_CASE": {
+ "format": "[IPF_IT] Registered filter for case = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPF_IT_GENERATED_DATA_CASE": {
+ "format": "[IPF_IT] Generate data for case = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPF_IT_TIMEOUT_CASE": {
+ "format": "[IPF_IT] Time out : check case %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPF_IT_PASS_CASE": {
+ "format": "[IPF_IT] it_case %2d PASS",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPF_IT_RECEIVED_RAW_DATA": {
+ "format": "[IPF_IT] invoke transfer raw data %d packets to cipher HW data",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPF_IT_RECEIVED_CBK_DATA": {
+ "format": "[IPF_IT] Received cbk data for case = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "IPF_IT_ALL_PASS": {
+ "format": "[IPF_IT] ALL Test Case PASS ~",
+ "traceClass": "TRACE_INFO"
+ }
+ }
+ ],
+ "traceFamily": "PS",
+ "userModule": "MOD_IPCORE"
+}
diff --git a/mcu/middleware/hif/ipcore/include/ipc_ut.h b/mcu/middleware/hif/ipcore/include/ipc_ut.h
new file mode 100644
index 0000000..5ed6577
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_ut.h
@@ -0,0 +1,211 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_ut.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IPCORE unit test defines and helper macros.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_UT_H
+#define __INC_IPC_UT_H
+
+#include "upcm.h"
+#include "ipc_defs.h"
+
+typedef enum {
+ IPC_UT_NO_ERROR = 0,
+ IPC_UT_SESSION_BIND_NEW_SESSION_FAIL,
+ IPC_UT_SESSION_DEACTIVATE_NO_SESSION_FOUND,
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL,
+ IPC_UT_REGISTER_FILTER_NG,
+ IPC_UT_DEREGISTER_FILTER_WITH_INVALID_ID,
+ IPC_UT_DEREGISTER_FILTER_NOT_FOUND,
+ IPC_UT_NEW_NTFY_NG,
+ IPC_UT_DEL_NTFY_WITH_INVALID_ID,
+ IPC_UT_DEL_NTFY_NOT_FOUND,
+ IPC_UT_DL_PKT_NETIF_NOT_FOUND,
+} ipc_ut_error_e;
+
+#ifdef ATEST_SYS_IPCORE
+ extern ipc_ut_error_e ipc_ut_error_g;
+ extern kal_bool ipc_ut_dpfm_is_activated_g;
+
+ #define ipc_ut_set_error(_ut_error) ipc_ut_error_g = (_ut_error)
+ #define ipc_ut_get_error() ipc_ut_error_g
+ #define IPC_UT_ASSERT(_cond, _ut_error) if (!(_cond)) ipc_ut_set_error(_ut_error)
+
+ void ipc_ut_on_ul_packet_filtered_req(void *req_ptr);
+ void ipc_ut_on_dl_packet_filtered_req(void *req_ptr);
+ void ipc_ut_on_ul_packet_filtered_with_info_req(void *req_ptr);
+ void ipc_ut_on_dl_packet_filtered_with_info_req(void *req_ptr);
+ kal_bool ipc_ut_msg_send6(module_type _src_mod_id, module_type _dest_mod_id, sap_type _sap_id, msg_type _msg_id, local_para_struct *_local_para_ptr, peer_buff_struct *_peer_buff_ptr);
+ void ipc_ut_rcv_ul_sdu(ip_type_e ip_type, kal_uint32 pdn_id, qbm_gpd *p_head, qbm_gpd *p_tail, kal_uint8 proto_idx);
+ void ipc_ut_rcv_ul_sdu_by_ebi(kal_uint32 ebi, qbm_gpd *p_head, qbm_gpd *p_tail, kal_uint8 proto_idx);
+ void ipc_ut_reg_cbk_notify_tick_source(upcm_nofify_lte_tick_f pf_notify);
+ void ipc_ut_reg_cbk_dlvr_dl_sdu(upcm_dlvr_dl_sdu_93_f pf_dlvr_sdu);
+ void ipc_ut_rcv_ul_sdu_meta(kal_uint32 start_idx, kal_uint32 end_idx, LHIF_QUEUE_TYPE q_type);
+ kal_bool ipc_ut_query_meta_table(kal_uint32 **base_addr, kal_uint16 *size, LHIF_QUEUE_TYPE queue_type);
+ kal_bool ipc_ut_dpfm_check_route(kal_bool uplink, kal_uint8 ip_type, ipc_pkt_des_t *pkt_des, kal_uint32 in_netif_id, kal_uint32 *out_netif_id);
+ kal_bool ipc_ut_dpfm_is_activated(void);
+
+ /* Gen95 Wrapper Function */
+ kal_int32 ipc_ut_ipf_query_filter_id_by_index(kal_uint32 ipf_index);
+ void ipc_ut_query_ipf_meta_info(void** base, kal_uint16* entry_num, kal_uint32 ipf_meta_q_type);
+ void ipc_ut_ipf_pn_match_setting(kal_uint8 pdn_sim_id, kal_uint16 nc_id, kal_uint8 ipv4, kal_uint8 ipv6);
+ void ipc_ut_release_ipf_meta_entry(kal_uint16 rel_num, kal_uint32 ipf_meta_q_type);
+ kal_bool ipc_ut_ipf_take_filter_tlb(void** buff_base, kal_uint32* max_entry_num);
+ kal_bool ipc_ut_ipf_submit_filter_tlb(kal_uint32 filter_num, kal_uint32 v6_unknow_pro_ck);
+ void ipc_ut_free_ipf_meta_buf(void* meta, kal_uint32 len);
+ kal_bool ipc_ut_on_ilm(ilm_struct *p_ilm);
+ extern void ipc_fragment_test();
+
+#else /* not defined(ATEST_SYS_IPCORE) */
+ #define ipc_ut_set_error(_ut_error)
+ #define ipc_ut_get_error() IPC_UT_NO_ERROR
+ #define IPC_UT_ASSERT(_cond, _ut_error) IPC_ASSERT(_cond)
+#endif /* ATEST_SYS_IPCORE */
+
+#endif /* __INC_IPC_UT_H */
diff --git a/mcu/middleware/hif/ipcore/include/ipc_utils.h b/mcu/middleware/hif/ipcore/include/ipc_utils.h
new file mode 100644
index 0000000..748bdf5
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/ipc_utils.h
@@ -0,0 +1,378 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_utils.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IPCore internal utilities.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_IPC_UTILS_H
+#define __INC_IPC_UTILS_H
+
+#include "kal_public_api.h"
+#include "ipc_enums.h"
+#include "ipc_data.h"
+#include "tst_msgid.h"
+
+#define MSG_IPC_DL_RAW_DATA (MSG_ID_DHL_UPCM_IMS_DL_RAW_DATA)
+#define MSG_IPC_UL_RAW_DATA (MSG_ID_DHL_UPCM_IMS_UL_RAW_DATA)
+#define IPC_DL_PKT_DUMP(buf_p, len) ipc_utils_pkt_dump_buf(MSG_IPC_DL_RAW_DATA, MOD_IPCORE, buf_p, len)
+#define IPC_UL_PKT_DUMP(buf_p, len) ipc_utils_pkt_dump_buf(MSG_IPC_UL_RAW_DATA, MOD_IPCORE, buf_p, len)
+
+/**
+ * Internal API to set GPD data length.
+ *
+ * @param gpd [IN] GPD to set data length.
+ * @param datalen [IN] data length to set.
+ * @param payload_ptr [OUT] Pointer of payload to return.
+ *
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+void ipc_utils_set_gpd_datalen(void *p_gpd, kal_uint32 datalen, void **p_payload);
+
+/**
+ * Internal API to get GPD data pointer.
+ *
+ * @param gpd [IN] GPD to set data length.
+ * @param payload_ptr [OUT] Pointer of payload to return.
+ *
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool ipc_utils_get_gpd_dataptr(void *p_gpd, void **p_payload);
+
+/**
+ * Internal API to copy buffers in the GPD list to the buffer prepared by caller.
+ *
+ * @param dst_buffer [OUT] Destination buffer to copy to, which is prepared by caller.
+ * @param dst_max_len [IN] Size of the destination buffer prepared by caller in bytes.
+ * @param dst_len_copied [OUT] Number of bytes copied to the destination buffer.
+ * @param src_head_gpd [IN] Head of the GPD list with source buffers to copy from.
+ * @param src_tail_gpd [IN] Tail of the GPD list with source buffers to copy from.
+ *
+ * @return KAL_TRUE if succeeded, KAL_FALSE otherwise.
+ */
+kal_bool ipc_utils_gpd_copy(kal_uint8 *p_dst_buf,
+ kal_uint32 dst_max_len,
+ kal_uint32 *p_dst_len_copied,
+ qbm_gpd *p_head_gpd,
+ qbm_gpd *p_tail_gpd);
+
+/**
+ * Internal API to classify IPv4v6 GPD list into separated IPv4 & IPv6 GPD lists.
+ *
+ * @param head_gpd [IN] Head of the source IPv4v6 GPD list.
+ * @param tail_gpd [IN] Tail of the source IPv4v6 GPD list.
+ * @param ipv4_head_gpd [OUT] Head of the classified IPv4 GPD list.
+ * @param ipv4_tail_gpd [OUT] Tail of the classified IPv4 GPD list.
+ * @param ipv6_head_gpd [OUT] Head of the classified IPv6 GPD list.
+ * @param ipv6_tail_gpd [OUT] Tail of the classified IPv6 GPD list.
+ */
+void ipc_utils_clarify_gpd(qbm_gpd *p_head_gpd,
+ qbm_gpd *p_tail_gpd,
+ qbm_gpd **p_ipv4_head_gpd,
+ qbm_gpd **p_ipv4_tail_gpd,
+ qbm_gpd **p_ipv6_head_gpd,
+ qbm_gpd **p_ipv6_tail_gpd);
+
+/**
+ * Internal API to get hif type of the netif from the netif_id
+ *
+ * @param netif_id [IN] The id of the netif.
+ *
+ * @return the hif type of the netif.
+ */
+ipc_si_hif_type_e ipc_utils_get_hif_type_by_netif_id(kal_uint32 netif_id);
+
+/**
+ * Internal API to set hif type of all SI entries of the packet.
+ *
+ * @param did [IN] The DID contained the packet.
+ * @param hif_type [IN] The hif type to set.
+ * @param p_curr_si_idx [IN|OUT] The current SI idx.
+ */
+void ipc_utils_pkt_set_si_hif_type(upcm_did *p_did, ipc_si_hif_type_e hif_type, kal_uint32 *p_curr_si_idx);
+
+/**
+ * Internal API to copy GPD list to DID.
+ *
+ * @param src_head_gpd [IN] The head of the source GPD list.
+ * @param src_tail_gpd [IN] The tail of the source GPD list.
+ * @param did [IN] The destination DID.
+ * @param hif_type [IN] The hif type to set.
+ */
+kal_bool ipc_utils_cpy_gpd_to_did(qbm_gpd *p_head_gpd, qbm_gpd *p_tail_gpd, upcm_did *p_did, ipc_si_hif_type_e hif_type);
+
+/**
+ * Internal API to set hif type of all SI entries of the packet as IGR and free the data buffer.
+ *
+ * @param did [IN] The DID contained the packet.
+ * @param p_curr_si_idx [IN|OUT] The current SI idx.
+ */
+void ipc_utils_pkt_free_si_data_buf(upcm_did *p_did, kal_uint32 *p_curr_si_idx);
+
+/**
+ * Internal API to fill DID/SI descriptor based on the META descriptor.
+ *
+ * @param dst_did [IN] The destination DID.
+ * @param p_si_idx [IN|OUT] The pointer of the current SI index.
+ * @param src_meta [IN] The source META.
+ * @param hif_type [IN] The hif type of the destination netif.
+ */
+kal_bool ipc_utils_fill_did_si_from_meta(kal_bool is_need_adjust,
+ upcm_did *p_dst_did,
+ kal_uint32 *p_si_idx,
+ ipc_meta_info_des *p_pkt_info,
+ ipc_si_hif_type_e hif_type);
+
+/**
+ * Internal API to dump raw packet content with continuous buffer.
+ *
+ * @param msg_id [IN] DHL message ID.
+ * @param src_mod [IN] Module ID of message source.
+ * @param buf_p [IN] The buffer address of packet.
+ * @param pkt_len [IN] The length of packet to be dumped.
+ */
+void ipc_utils_pkt_dump_buf(msg_type msg_id,
+ module_type src_mod,
+ kal_uint8 *p_buf,
+ kal_uint32 pkt_len);
+
+/**
+ * Internal API to dump all raw packets' content within a GPD list.
+ * Note that it can only support GPD type with continuous buffer.
+ *
+ * @param first_gpd [IN] The head of the GPD list.
+ * @param last_gpd [IN] The tail of the GPD list.
+ * @param uplink [IN] The packets are uplink or downlink.
+ */
+void ipc_utils_pkt_dump_buff_gpd_list(qbm_gpd *p_head_gpd, qbm_gpd *p_tail_gpd, kal_bool is_uplink);
+
+/**
+ * Internal API to dump the packet's raw content within a DID.
+ * @param did [IN] DID descriptor.
+ * @param p_curr_si_idx [IN|OUT] The current SI index.
+ */
+void ipc_utils_pkt_dump_did_one_pkt(upcm_did *p_did, kal_uint32 *p_curr_si_idx);
+
+/**
+ * Internal API to dump all packets' raw content within a DID list.
+ * @param did_head [IN] DID descriptor head.
+ * @param did_tail [IN] DID descriptor tail.
+ * @param hif_type [IN] Specified hif_type to be dumped within a DID list.
+ */
+void ipc_utils_pkt_dump_did(upcm_did *p_did_head, upcm_did *p_did_tail, ipc_si_hif_type_e hif_type);
+
+/**
+ * Internal API to dump N bytes of packets' raw content.
+ * @param p_data [IN] packet start point. (Data buffer should be continuous buffer)
+ * @param bytes [IN] dump length.
+ */
+void ipc_utils_dump_data(void *p_data, kal_uint32 bytes);
+
+/**
+ * delete given entry of GPD list
+ *
+ * @param p_first_gpd first GPD
+ * @param p_last_gpd last GPD
+ * @param p_curr_gpd current GPD
+ * @param p_prev_gpd previous GPD
+ * @param p_next_gpd next GPD
+ */
+void ipc_utils_gpd_list_del_entry(qbm_gpd **p_first_gpd,
+ qbm_gpd **p_last_gpd,
+ qbm_gpd **p_curr_gpd,
+ qbm_gpd **p_prev_gpd,
+ qbm_gpd **p_next_gpd);
+
+/**
+ * united GPD as GPD only, it doesn't has BD
+ *
+ * @param is_uplink uplink or downlink
+ * @param p_gpd_in input GPD
+ * @param pp_gpd_out output GPD
+ */
+void ipc_utils_unite_gpd(kal_bool is_uplink, qbm_gpd *p_gpd_in, qbm_gpd **pp_gpd_out);
+
+/**
+ * transfer SIT to GPD format
+ *
+ * @param type GPD type
+ * @param p_did input did
+ * @param curr_si_idx current sit index
+ * @param pkt_len packet length
+ * @param pp_gpd_out output GPD
+ */
+kal_bool ipc_utils_sit_to_gpd(qbm_type type,
+ upcm_did *p_did,
+ kal_uint32 curr_si_idx,
+ kal_uint32 pkt_len,
+ qbm_gpd **pp_gpd_out);
+
+/**
+ * calculate TCP checksum
+ *
+ * @param is_ipv4 ipv4 or ipv6
+ * @param src_addr source address
+ * @param dst_addr destination address
+ * @param tcp_header tcp header pointer
+ * @param tcp_len tcp length
+ */
+kal_uint16 ipc_utils_calc_tcp_checksum(kal_bool is_ipv4,
+ kal_uint8 *src_addr,
+ kal_uint8 *dst_addr,
+ kal_uint8 *tcp_header,
+ kal_uint32 tcp_len);
+
+/**
+ * calculate UDP checksum
+ *
+ * @param is_ipv4 ipv4 or ipv6
+ * @param src_addr source address
+ * @param dst_addr destination address
+ * @param udp_header udp header pointer
+ * @param udp_len udp length
+ */
+kal_uint16 ipc_utils_calc_udp_checksum(kal_bool is_ipv4,
+ kal_uint8 *src_addr,
+ kal_uint8 *dst_addr,
+ kal_uint8 *udp_header,
+ kal_uint32 udp_len);
+
+/**
+ * calculate IPv4 checksum
+ *
+ * @param ip_header IP header pointer
+ */
+kal_uint16 ipc_utils_calc_ipv4_checksum(kal_uint8 *ip_header);
+
+
+/**
+ * calculate ICMP checksum
+ *
+ * @param icmp_header ICMP header pointer
+ * @param len legth over which checksum need to calculate
+ */
+kal_uint16 ipc_utils_calc_icmp_checksum(kal_uint8 *icmp_header, kal_uint32 len);
+
+
+#endif /* __INC_IPC_UTILS_H */
diff --git a/mcu/middleware/hif/ipcore/include/pfm_defs.h b/mcu/middleware/hif/ipcore/include/pfm_defs.h
new file mode 100644
index 0000000..f460868
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/pfm_defs.h
@@ -0,0 +1,222 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2014
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * pfm_defs.h
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * This file provides the filter set index for different features.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_PFM_DEFS_H
+#define __INC_PFM_DEFS_H
+
+#include "kal_public_api.h"
+#include "pfm_struct.h"
+
+/*------------------------------------------------------------------------------
+ * Auto produced register parser function prototypes. DO NOT MODIFY!!
+ *----------------------------------------------------------------------------*/
+/* pfm_xxx_register_parser function prototype */
+#undef PFM_FILTER_SET_FEATURE_NAME
+#undef PFM_FILTER_SET_PREFIX
+#define PFM_FILTER_SET_FEATURE_NAME(_name)
+#define PFM_FILTER_SET_PREFIX(_prefix) void pfm_ ## _prefix ## _register_parser(void *, kal_uint32, kal_bool);
+#include "pfm_config.h"
+
+/* pfm_xxx_deregister_callback function prototype */
+#undef PFM_FILTER_SET_FEATURE_NAME
+#undef PFM_FILTER_SET_PREFIX
+#define PFM_FILTER_SET_FEATURE_NAME(_name)
+#define PFM_FILTER_SET_PREFIX(_prefix) void pfm_ ## _prefix ## _deregister_callback(void *, kal_uint32, kal_bool);
+#include "pfm_config.h"
+
+/*------------------------------------------------------------------------------
+ * Configuration.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+#define PFM_ASSERT ASSERT /* To completely bypass the overhead of ASSERT(), we could define PFM_ASSERT(...) to nothing. */
+#define PFM_DEL_OBJECT_SLEEP_TICKS KAL_TICKS_10_MSEC
+#define PFM_W_LOCK_OBJECT_SLEEP_TICKS 1
+#define PFM_FILTER_SET_MAX_SIZE 256
+#define PFM_IPC_REGISTER_FILTER_FAIL -1
+#define PFM_FILTER_STRUCT_MAGIC_CODE 168
+#define PFM_MATCHED_PACKET_DUMP_SIZE 40
+#define PFM_LOCK_NAME "PFM_LOCK"
+
+typedef enum {
+ PFM_STATE_RESUME,
+ PFM_STATE_SUSPEND,
+ PFM_STATE_INVALID
+} pfm_pcie_state_e;
+/*------------------------------------------------------------------------------
+ * Internal data structure defintion.
+ *----------------------------------------------------------------------------*/
+#define PFM_DECLARE_OBJECT \
+ kal_int32 ref_count; \
+ kal_int32 reader_cnt; \
+ kal_int32 writer_cnt;
+
+typedef struct _pfm_internal_filter_set_t {
+ PFM_DECLARE_OBJECT
+
+ kal_uint32 filter_set_id;
+ kal_int32 filter_cnt;
+ kal_int32 filters[PFM_FILTER_SET_MAX_SIZE];
+} pfm_internal_filter_set_t;
+
+typedef enum emPfmApStatus {
+ PFM_AP_STATUS_SUSPEND = 0x00000000,
+ PFM_AP_STATUS_WAKE_UP = 0x00000001
+} emPfmApStatus;
+
+#define PFM_AP_CMD_NONE (0)
+#define PFM_AP_CMD_FIN_ACK_REDUCTION (0x01 << 0)
+
+typedef struct pfmApStatusInd {
+ LOCAL_PARA_HDR
+ emPfmApStatus em_ap_status;
+ kal_uint32 bm_cmd;
+} pfmApStatusInd;
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Internal function prototype.
+ *----------------------------------------------------------------------------*/
+pfm_internal_filter_set_t* pfm_get_filter_set_list(kal_bool is_uplink);
+
+void pfm_dispatch_cmd(ilm_struct *ilm, kal_bool is_register);
+
+void pfm_deregister_filters(local_para_struct *local_para_ptr);
+
+void pfm_delete_filter_set(pfm_internal_filter_set_t *filter_set);
+
+void pfm_deregister_filter(kal_bool uplink, pfm_internal_filter_set_t *filter_set, kal_int32 filter_id);
+
+kal_bool pfm_register_filter_cbk(kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ ipc_filter_callback_t callback_func,
+ void *callback_context);
+
+kal_bool pfm_register_filter_msg(kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ module_type callback_module,
+ void *callback_context);
+
+kal_bool pfm_register_filter_with_info_cbk(kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ ipc_filter_with_info_callback_t callback_func,
+ void *callback_context);
+
+kal_bool pfm_register_filter_with_info_msg(kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ module_type callback_module,
+ void *callback_context);
+
+void pfm_matched_packet_trace(kal_int16 ebi, kal_uint8 *p_data, kal_uint32 bytes);
+
+pfm_internal_filter_set_t *pfm_get_filter_set_by_id(pfm_internal_filter_set_t *filter_set_list,
+ kal_uint32 list_size,
+ kal_uint32 filter_set_id);
+
+#endif /* __INC_PFM_DEFS_H */
diff --git a/mcu/middleware/hif/ipcore/include/pfm_object.h b/mcu/middleware/hif/ipcore/include/pfm_object.h
new file mode 100644
index 0000000..9beb619
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/include/pfm_object.h
@@ -0,0 +1,215 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2014
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * PFM_object.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * Helper for object management and synchronization.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_PFM_OBJECT_H
+#define __INC_PFM_OBJECT_H
+
+#include "kal_public_api.h"
+
+#include "pfm_defs.h"
+
+struct _pfm_object_template;
+extern kal_spinlockid pfm_spinlock_g;
+static INLINE kal_bool pfm_is_object_valid(struct _pfm_object_template *object);
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+#define PFM_SPIN_LOCK(_lock) kal_take_spinlock(_lock, KAL_INFINITE_WAIT)
+#define PFM_SPIN_UNLOCK(_lock) kal_give_spinlock(_lock)
+
+#define PFM_IS_VALID_OBJECT_WO_LOCK(_object) \
+ ((_object) != NULL && (_object)->ref_count == 2)
+
+#define PFM_IS_VALID_OBJECT(_object) \
+ pfm_is_object_valid((struct _pfm_object_template *)_object)
+
+#define PFM_R_LOCK_OBJECT(_object, _lock) \
+ PFM_SPIN_LOCK(_lock); \
+ if (PFM_IS_VALID_OBJECT_WO_LOCK(_object) && ((_object)->writer_cnt == 0)) { \
+ ++((_object)->reader_cnt); \
+ } else { \
+ (_object) = NULL; \
+ } \
+ PFM_SPIN_UNLOCK(_lock)
+
+#define PFM_R_UNLOCK_OBJECT(_object, _lock) \
+ ASSERT((_object)); \
+ PFM_SPIN_LOCK(_lock); \
+ ASSERT((_object)->reader_cnt > 0); \
+ --((_object)->reader_cnt); \
+ PFM_SPIN_UNLOCK(_lock)
+
+#define PFM_INIT_OBJECT_BEGIN(_object, _lock) \
+ PFM_ASSERT(_object); \
+ PFM_SPIN_LOCK(_lock); \
+ PFM_ASSERT((_object)->ref_count == 0); \
+ (_object)->ref_count = 1; \
+ PFM_SPIN_UNLOCK(_lock)
+
+#define PFM_INIT_OBJECT_END(_object, _lock) \
+ PFM_ASSERT(_object); \
+ PFM_SPIN_LOCK(_lock); \
+ PFM_ASSERT(_object->ref_count == 1); \
+ (_object)->ref_count = 2; \
+ (_object)->reader_cnt = 0; \
+ (_object)->writer_cnt = 0; \
+ PFM_SPIN_UNLOCK(_lock)
+
+#define PFM_DEINIT_OBJECT_BEGIN(_object, _lock) \
+ PFM_ASSERT(kal_if_hisr() == KAL_FALSE); \
+ PFM_SPIN_LOCK(_lock); \
+ if (PFM_IS_VALID_OBJECT_WO_LOCK(_object)) { \
+ --((_object)->ref_count); \
+ while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
+ PFM_SPIN_UNLOCK(_lock); \
+ kal_sleep_task(PFM_DEL_OBJECT_SLEEP_TICKS); \
+ PFM_SPIN_LOCK(_lock); \
+ } \
+ PFM_ASSERT((_object)->ref_count == 1); \
+ } else { \
+ (_object) = NULL; \
+ } \
+ PFM_SPIN_UNLOCK(_lock)
+
+#define PFM_DEINIT_OBJECT_END(_object, _lock) \
+ PFM_SPIN_LOCK(_lock); \
+ PFM_ASSERT((_object)->ref_count == 1); \
+ PFM_ASSERT((_object)->reader_cnt == 0); \
+ PFM_ASSERT((_object)->writer_cnt == 0); \
+ (_object)->ref_count = 0; \
+ PFM_SPIN_UNLOCK(_lock)
+
+#define PFM_W_LOCK_OBJECT(_object, _lock) \
+ PFM_ASSERT(kal_if_hisr() == KAL_FALSE); \
+ PFM_SPIN_LOCK(_lock); \
+ if (PFM_IS_VALID_OBJECT_WO_LOCK(_object)) { \
+ while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
+ PFM_SPIN_UNLOCK(_lock); \
+ kal_sleep_task(PFM_W_LOCK_OBJECT_SLEEP_TICKS); \
+ PFM_SPIN_LOCK(_lock); \
+ } \
+ if (PFM_IS_VALID_OBJECT_WO_LOCK(_object)) { \
+ ++((_object)->writer_cnt); \
+ } else { \
+ (_object) = NULL; \
+ PFM_SPIN_UNLOCK(_lock); \
+ } \
+ } else { \
+ (_object) = NULL; \
+ PFM_SPIN_UNLOCK(_lock); \
+ }
+
+#define PFM_W_UNLOCK_OBJECT(_object, _lock) \
+ PFM_ASSERT((_object)); \
+ PFM_ASSERT((_object)->writer_cnt == 1); \
+ --((_object)->writer_cnt); \
+ PFM_SPIN_UNLOCK(_lock)
+
+/*------------------------------------------------------------------------------
+ * Functions for Synchronization
+ *----------------------------------------------------------------------------*/
+struct _pfm_object_template {
+ PFM_DECLARE_OBJECT
+};
+
+static INLINE kal_bool pfm_is_object_valid(struct _pfm_object_template *object)
+{
+ kal_bool ret;
+
+ PFM_SPIN_LOCK(pfm_spinlock_g);
+ ret = PFM_IS_VALID_OBJECT_WO_LOCK(object);
+ PFM_SPIN_UNLOCK(pfm_spinlock_g);
+
+ return ret;
+}
+
+#endif /* __INC_PFM_OBJECT_H */
diff --git a/mcu/middleware/hif/ipcore/src/ipc_data.c b/mcu/middleware/hif/ipcore/src/ipc_data.c
new file mode 100644
index 0000000..626d818
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_data.c
@@ -0,0 +1,2651 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2016
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_data.c
+ *
+ * Project:
+ * --------
+ * UMOLYA
+ *
+ * Description:
+ * ------------
+ * IP Core Uplink/Downlink data path implementation.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "mw_sap.h"
+#include "em_msgid.h"
+#include "hif_mw_msgid.h"
+#include "nl2_msgid.h"
+#include "upcm.h"
+#include "qmu_bm_util.h"
+
+#include "ipc_data.h"
+#include "ipc_debug.h"
+#include "ipc_filter.h"
+#include "ipc_utils.h"
+
+#if defined(__IPF_SUPPORT__)
+#include "ipc_data_ipf.h"
+#endif
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+kal_uint32 ipc_em_on_s = 0;
+kal_bool ipc_ul_enable_g = KAL_TRUE;
+
+/* Test loopback mode */
+ipc_test_loopback_mode_e ipc_test_loopback_mode_s = IPC_TEST_LOOPBACK_MODE_OFF;
+kal_uint32 ipc_test_loopback_a_netif_id_s = 0;
+kal_uint32 ipc_test_loopback_b_netif_id_s = 0;
+
+/*------------------------------------------------------------------------------
+ * Private data structure.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Private variables.
+ *----------------------------------------------------------------------------*/
+static ipc_ul_queue_t ipc_ul_queues_s[IPC_UL_QUEUE_NUM];
+/* All DL queue processing MUST be in IPCore own context */
+static ipc_dl_queue_t ipc_dl_queues_s[IPC_DL_QUEUE_NUM];
+kal_bool ipc_ul_processing_s = KAL_FALSE;
+static kal_bool ipc_dl_processing_s = KAL_FALSE;
+kal_bool ipc_ul_reload_retrying_s = KAL_FALSE;
+
+event_scheduler *ipc_es_ul_throttle_s = NULL; /* Timer for UL throttle mechanism. */
+
+static ipc_ul_throttle_state_e ipc_ul_throttle_state_s = IPC_UL_THROTTLE_STATE_NONE;
+static ipc_ul_throttle_conf_t ipc_ul_throttle_conf_s = {0, 0, 0};
+static eventid ipc_eid_ul_throttle_s = NULL; /* Timer for UL throttle mechanism. */
+static kal_bool ipc_ul_throttle_is_block_latency_concern_s = KAL_FALSE;
+static kal_bool ipc_ul_throttle_is_ims_emergency_s = KAL_FALSE;
+static qbm_gpd* ipc_proxy_ipv6_ra_pool[IPC_PROXY_IPV6_RA_POOL_SIZE] = {NULL};
+static qbm_gpd* ipc_dl_qbm_head_s, *ipc_dl_qbm_tail_s;
+static ipc_data_usage_info_t ipc_data_usage_info_s[IPC_MAX_SESSION_CNT];
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ *----------------------------------------------------------------------------*/
+void ipc_dest_ior(
+ ipc_io_request_t *ior)
+{
+ ipc_io_request_t *next_ior;
+
+ IPC_ASSERT(ior);
+ for (; ior; ior = next_ior) {
+ next_ior = ior->next_request;
+ if ( ior->first_gpd && ior->last_gpd ) {
+ qbmt_dest_q(ior->first_gpd, ior->last_gpd);
+ }
+ }
+}
+
+/*
+ * Assumption: netif read lock is acquired.
+ */
+void ipc_reload_uplink(ipc_netif_t *netif)
+{
+ kal_bool need_retry;
+
+ hif_data_trace(MD_TRC_IPC_UL_RELOAD_UPLINK, 0, netif, netif->config.netif_id, netif->config.ipc_ul_reload_callback_t);
+
+ if (netif->config.ipc_ul_reload_callback_t) {
+ /* Clear netif_ul_need_reload before call netif reload cbk */
+ ipc_set_netif_ul_set_need_reload(netif, KAL_FALSE);
+ need_retry = netif->config.ipc_ul_reload_callback_t(
+ netif->config.ul_reload_context);
+
+ hif_data_trace(MD_TRC_IPC_UL_RELOAD_UPLINK_RESULT, 0, netif, netif->config.netif_id, need_retry);
+
+ ipc_set_netif_ul_reload_retry(netif, need_retry);
+ }
+}
+
+/*
+ * Assumption: netif read lock is acquired.
+ */
+static void ipc_forward_ul_ior(ipc_netif_t *netif, ipc_io_request_t *ior)
+{
+#if IPC_PEER == IPC_PEER_NULL_DROP
+ /*
+ * Drop all uplink packets (Only for test purpose).
+ */
+ hif_data_trace(MD_TRC_IPC_UL_DROP_UL_IOR, 0, netif, ior);
+
+ ipc_dest_ior(ior);
+#elif IPC_PEER == IPC_PEER_NULL_LOOPBACK
+ /*
+ * Loopback uplink packets. (Only for test purpose).
+ */
+ if (NULL != netif->config.ipc_dlink_callback_t) {
+ hif_data_trace(MD_TRC_IPC_UL_LOOPBACK_UL_IOR, 0, netif, ior, netif->config.ipc_dlink_callback_t);
+ netif->config.ipc_dlink_callback_t(netif->config.callback_context, ior);
+ } else {
+ hif_data_trace(MD_TRC_IPC_UL_LOOPBACK_UL_IOR_DROP, 0, netif, ior, netif->config.ipc_dlink_callback_t);
+ ipc_dest_ior(ior);
+ }
+#else
+ ipc_session_t *session = NULL;
+ ipc_io_request_t *next_ior = NULL;
+ qbm_gpd *ipv4_first_gpd = NULL;
+ qbm_gpd *ipv4_last_gpd = NULL;
+ qbm_gpd *ipv6_first_gpd = NULL;
+ qbm_gpd *ipv6_last_gpd = NULL;
+
+ for (; ior; ior = next_ior) {
+ next_ior = ior->next_request;
+ if ( ior->first_gpd && ior->last_gpd ) {
+ if (ior->ip_type != IPC_IP_TYPE_MIXED) {
+ qbm_gpd *first_gpd = NULL;
+ qbm_gpd *last_gpd = NULL;
+
+ first_gpd = ior->first_gpd;
+ last_gpd = ior->last_gpd;
+
+ hif_data_trace(MD_TRC_IPC_UL_HANDLE_UL_GPD_LIST, ior->ip_type, netif->config.netif_id, first_gpd, last_gpd);
+
+ /* HIF network interface told IPv4 or IPv6 case. */
+ ipc_do_ul_filter(ior->ip_type, netif->config.netif_id, &first_gpd, &last_gpd);
+ if (first_gpd) {
+ session = ipc_find_session_by_netif(netif, ior->ip_type);
+ if (session) {
+
+ hif_data_trace(MD_TRC_IPC_UL_FORWARD_UL_SDU, ior->ip_type, session->context, first_gpd, last_gpd);
+ hif_data_trace(MD_TRC_IPC_UL_FORWARD_UL_SDU_MULTI_PS, session->context);
+ IPC_FORWARD_UL_SDU((ip_type_e )ior->ip_type, /* ip_type */
+ session->context, /* pdn_id */
+ first_gpd, /* p_head */
+ last_gpd); /* p_tail */
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_UL_DROP_FOR_SESSION_DEACT, netif->config.netif_id, ior, ior->ip_type);
+ qbmt_dest_q(first_gpd, last_gpd);
+ }
+ }
+ } else {
+ /*
+ * HIF network interface cannot tell IPv4 or IPv6 case.
+ * Classify GPD into IPv4 and IPv6 lists, and then send them to wireless network respectively.
+ */
+ /* ipv4_first_gpd / ipv4_last_gpd / ipv6_first_gpd / ipv6_last_gpd are initiated in this procedure */
+ ipc_utils_clarify_gpd(ior->first_gpd, ior->last_gpd, &ipv4_first_gpd, &ipv4_last_gpd, &ipv6_first_gpd, &ipv6_last_gpd);
+
+ if (ipv4_first_gpd) {
+
+ hif_data_trace(MD_TRC_IPC_UL_HANDLE_IPV4_UL_GPD_LIST, ior->ip_type, netif->config.netif_id, ipv4_first_gpd, ipv4_last_gpd);
+
+ ipc_do_ul_filter( IPC_IP_TYPE_IPV4, netif->config.netif_id, &ipv4_first_gpd, &ipv4_last_gpd);
+ if (ipv4_first_gpd) {
+ session = ipc_find_session_by_netif(netif, IPC_IP_TYPE_IPV4);
+ if (session) {
+
+ hif_data_trace(MD_TRC_IPC_UL_FORWARD_IPV4_UL_SDU, ior->ip_type, session->context, ipv4_first_gpd, ipv4_last_gpd);
+ hif_data_trace(MD_TRC_IPC_UL_FORWARD_UL_SDU_MULTI_PS, session->context);
+ IPC_FORWARD_UL_SDU((ip_type_e)IPC_IP_TYPE_IPV4, /* ip_type */
+ session->context, /* pdn_id */
+ ipv4_first_gpd, /* p_head */
+ ipv4_last_gpd); /* p_tail */
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_UL_DROP_FOR_SESSION_DEACT, netif->config.netif_id, ior, IPC_IP_TYPE_IPV4);
+ qbmt_dest_q(ipv4_first_gpd, ipv4_last_gpd);
+ }
+ }
+ }
+
+ if (ipv6_first_gpd) {
+
+ hif_data_trace(MD_TRC_IPC_UL_HANDLE_IPV6_UL_GPD_LIST, ior->ip_type, netif->config.netif_id, ipv6_first_gpd, ipv6_last_gpd);
+ ipc_do_ul_filter( IPC_IP_TYPE_IPV6, netif->config.netif_id, &ipv6_first_gpd, &ipv6_last_gpd);
+
+ if (ipv6_first_gpd) {
+ session = ipc_find_session_by_netif(netif, IPC_IP_TYPE_IPV6);
+ if (session) {
+
+ hif_data_trace(MD_TRC_IPC_UL_FORWARD_IPV6_UL_SDU, ior->ip_type, session->context, ipv6_first_gpd, ipv6_last_gpd);
+ hif_data_trace(MD_TRC_IPC_UL_FORWARD_UL_SDU_MULTI_PS, session->context);
+ IPC_FORWARD_UL_SDU((ip_type_e)IPC_IP_TYPE_IPV6, /* ip_type */
+ session->context, /* pdn_id */
+ ipv6_first_gpd, /* p_head */
+ ipv6_last_gpd); /* p_tail */
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_UL_DROP_FOR_SESSION_DEACT, netif->config.netif_id, ior, IPC_IP_TYPE_IPV6);
+ qbmt_dest_q(ipv6_first_gpd, ipv6_last_gpd);
+ }
+ }
+ }
+ } /* end of HIF network interface cannot tell IPv4 or IPv6 case. */
+ } else {
+ hif_trace_error(IPC_TR_UL_DROP_FOR_INVALID_IOR, netif->config.netif_id, ior, ior->first_gpd, ior->last_gpd);
+ IPC_ASSERT(KAL_FALSE);
+ }
+ } /* end of for (ior) */
+#endif
+}
+
+static void ipc_calc_data_usage(kal_uint32 pdn_id,
+ qbm_gpd *p_head_gpd,
+ qbm_gpd *p_tail_gpd)
+{
+ ipc_data_usage_info_t data_usage = {0};
+ qbm_gpd *p_curr_gpd = NULL;
+ qbm_gpd *p_next_gpd = NULL;
+ qbm_gpd *p_bd = NULL;
+ kal_uint32 pkt_len = 0;
+ kal_bool is_eol = KAL_FALSE;
+
+ IPC_ASSERT(p_head_gpd && p_tail_gpd);
+
+ for (p_curr_gpd = p_head_gpd; p_curr_gpd && !is_eol; p_curr_gpd = p_next_gpd) {
+ p_next_gpd = QBM_DES_GET_NEXT(p_curr_gpd);
+ is_eol = (p_curr_gpd == p_tail_gpd);
+
+ pkt_len = QBM_DES_GET_DATALEN(p_curr_gpd);
+ p_bd = QBM_DES_GET_DATAPTR(p_curr_gpd);
+ if ((0 != pkt_len) && (pkt_len == QBM_DES_GET_DATALEN(p_bd))) {
+ data_usage.uplink_bytes += pkt_len;
+ ++data_usage.uplink_packets;
+ }
+ }
+
+ ipc_set_data_usage_by_pdn_sim_id(UL_DIRECT, pdn_id, &data_usage);
+}
+
+static void ipc_on_process_ul_ior_list(ipc_ul_queue_t *q)
+{
+ ipc_internal_ior_t *head_ior = q->ior_head;
+ ipc_internal_ior_t *curr_ior = NULL;
+ ipc_internal_ior_t *next_ior = NULL;
+ ipc_netif_t *netif = NULL;
+ qbm_gpd *head_gpd_p = NULL;
+ qbm_gpd *tail_gpd_p = NULL;
+ kal_uint8 prev_pdnid = 0;
+ kal_uint8 prev_iptype = 0;
+ qbm_gpd *head_gpd_ebi_p = NULL;
+ qbm_gpd *tail_gpd_ebi_p = NULL;
+ kal_uint8 prev_ebi = 0;
+
+ HIF_SWLA_START("IU3");
+
+ for (curr_ior = head_ior; curr_ior; curr_ior = next_ior) {
+ next_ior = (ipc_internal_ior_t *)(curr_ior->io_req.next_request);
+
+ if (IPC_NORMAL_DATA_PATH == curr_ior->io_req.data_path_type) {
+ /* IOR of ipc_uplink() */
+ hif_data_trace(MD_TRC_IPC_UL_ON_PROCESS_NORMAL_IOR, 0, curr_ior, curr_ior->netif);
+
+ if ((NULL == next_ior) ||
+ (IPC_NORMAL_DATA_PATH != next_ior->io_req.data_path_type) ||
+ (head_ior->netif != next_ior->netif)) {
+
+ curr_ior->io_req.next_request = NULL;
+ netif = head_ior->netif;
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ /* Reload uplink buffers for the network interface. */
+ ipc_reload_uplink(netif);
+ ipc_forward_ul_ior(netif, &(head_ior->io_req));
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_UL_DROP_FOR_INVALID_NETIF, head_ior->netif, &(head_ior->io_req));
+ ipc_dest_ior(&(head_ior->io_req));
+ }
+
+ head_ior = next_ior;
+ }
+ } else if (IPC_INTERNAL_DATA_PATH == curr_ior->io_req.data_path_type) {
+ /* IOR of ipc_send_ul_pkt() & ipc_send_ul_pkt_by_pdn() */
+ IPC_ASSERT(head_ior == curr_ior);
+
+ if (curr_ior->io_req.ip_type == 0xFF) {
+ if ((NULL == head_gpd_ebi_p) && (NULL == tail_gpd_ebi_p)) {
+ head_gpd_ebi_p = curr_ior->io_req.first_gpd;
+ tail_gpd_ebi_p = curr_ior->io_req.last_gpd;
+ prev_ebi = curr_ior->ebi;
+ } else {
+ if (prev_ebi == curr_ior->ebi) {
+ /* same EBI packet,need to group here */
+ QBM_DES_SET_NEXT(tail_gpd_ebi_p, curr_ior->io_req.first_gpd);
+ tail_gpd_ebi_p = curr_ior->io_req.last_gpd;
+ hif_data_trace(MD_TRC_IPC_UL_CLUB_PKT_B4_FORWARD, prev_ebi, head_gpd_ebi_p, tail_gpd_ebi_p);
+ } else {
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_FORWARD, prev_ebi, head_gpd_ebi_p, tail_gpd_ebi_p);
+ /* Sent to UPCM by EBI */
+ IPC_FORWARD_UL_SDU_BY_EBI(prev_ebi, head_gpd_ebi_p, tail_gpd_ebi_p);
+ head_gpd_ebi_p = curr_ior->io_req.first_gpd;
+ tail_gpd_ebi_p = curr_ior->io_req.last_gpd;
+ prev_ebi = curr_ior->ebi;
+ }
+ }
+ } else {
+ if ((NULL == head_gpd_p) && (NULL == tail_gpd_p)) {
+ head_gpd_p = curr_ior->io_req.first_gpd;
+ tail_gpd_p = curr_ior->io_req.last_gpd;
+ prev_pdnid = curr_ior->pdn;
+ prev_iptype = curr_ior->io_req.ip_type;
+ } else {
+ if ((prev_pdnid == curr_ior->pdn) && (prev_iptype == curr_ior->io_req.ip_type)) {
+ /* same PDN & IP packet,need to group here */
+ QBM_DES_SET_NEXT(tail_gpd_p, curr_ior->io_req.first_gpd);
+ tail_gpd_p = curr_ior->io_req.last_gpd;
+ hif_data_trace(MD_TRC_IPC_UL_CLUB_PKT_BY_PDN_B4_FORWARD, prev_pdnid, prev_iptype, head_gpd_p, tail_gpd_p);
+ } else {
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_BY_PDN_FORWARD, prev_pdnid, prev_iptype, head_gpd_p, tail_gpd_p);
+ /*calculate Data usage for uplink packets*/
+ ipc_calc_data_usage(prev_pdnid, head_gpd_p, tail_gpd_p);
+ /* Sent to UPCM by PDN */
+ IPC_FORWARD_UL_SDU((kal_uint8 )prev_iptype, prev_pdnid, head_gpd_p, tail_gpd_p);
+ head_gpd_p = curr_ior->io_req.first_gpd;
+ tail_gpd_p = curr_ior->io_req.last_gpd;
+ prev_pdnid = curr_ior->pdn;
+ prev_iptype = curr_ior->io_req.ip_type;
+ }
+ }
+ }
+
+ head_ior = next_ior;
+ } else {
+ /* unsupported data path type */
+ ASSERT(KAL_FALSE);
+ }
+ }
+
+ if (NULL != head_gpd_ebi_p) {
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_FORWARD, prev_ebi, head_gpd_ebi_p, tail_gpd_ebi_p);
+ /* Sent to UPCM by EBI */
+ IPC_FORWARD_UL_SDU_BY_EBI(prev_ebi, head_gpd_ebi_p, tail_gpd_ebi_p);
+ }
+
+ if (NULL != head_gpd_p) {
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_BY_PDN_FORWARD, prev_pdnid, prev_iptype, head_gpd_p, tail_gpd_p);
+ /*calculate Data usage for uplink packets*/
+ ipc_calc_data_usage(prev_pdnid, head_gpd_p, tail_gpd_p);
+ /* Sent to UPCM by PDN */
+ IPC_FORWARD_UL_SDU((kal_uint8 )prev_iptype, prev_pdnid, head_gpd_p, tail_gpd_p);
+ }
+
+ HIF_SWLA_STOP("IU3");
+}
+
+static void ipc_start_ul_throttle_timer(kal_uint32 elapse_time);
+#ifndef ATEST_SYS_IPCORE
+static
+#endif
+void ipc_ul_throttle_timeout(void *event_hf_param)
+{
+ kal_bool to_send_msg;
+
+#ifndef ATEST_SYS_IPCORE
+ IPC_ASSERT(ipc_eid_ul_throttle_s);
+ ipc_eid_ul_throttle_s = NULL;
+#endif
+
+ hif_data_trace(MD_TRC_IPC_TR_TIMER_UL_THROTTLE_TIMEOUT, kal_get_systicks(),
+ ipc_ul_throttle_state_s,
+ ipc_ul_throttle_conf_s.enabled,
+ ipc_ul_throttle_conf_s.active_period_100ms,
+ ipc_ul_throttle_conf_s.suspend_period_100ms);
+
+ if (ipc_ul_throttle_conf_s.enabled) {
+ if (IPC_UL_THROTTLE_STATE_ACTIVE == ipc_ul_throttle_state_s) {
+ /* UL throttle state: ACTIVE -> SUSPEND */
+ ipc_start_ul_throttle_timer(ipc_ul_throttle_conf_s.suspend_period_100ms * KAL_TICKS_100_MSEC);
+ ipc_ul_throttle_state_s = IPC_UL_THROTTLE_STATE_SUSPEND;
+ } else if (IPC_UL_THROTTLE_STATE_SUSPEND == ipc_ul_throttle_state_s) {
+ /* UL throttle state: SUSPEND -> ACTIVE */
+ ipc_start_ul_throttle_timer(ipc_ul_throttle_conf_s.active_period_100ms * KAL_TICKS_100_MSEC);
+ ipc_ul_throttle_state_s = IPC_UL_THROTTLE_STATE_ACTIVE;
+
+ /* IPCORE need to process ul queue if ul pending queue is not empty */
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = ((!ipc_ul_processing_s) && (!ipc_are_ul_queues_empty()));
+ if (to_send_msg) {
+ ipc_ul_processing_s = KAL_TRUE;
+ }
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ }
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_ENPDCP, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ (IPC_UL_THROTTLE_STATE_SUSPEND == ipc_ul_throttle_state_s) ?
+ MSG_ID_IPCORE_ENPDCP_UL_SUSPEND_NTF : MSG_ID_IPCORE_ENPDCP_UL_ACTIVE_NTF, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+
+ /* For EM ELT update info*/
+ ipc_em_send_ul_throttle_status();
+ }
+}
+
+static void ipc_start_ul_throttle_timer(kal_uint32 elapse_time)
+{
+#ifndef ATEST_SYS_IPCORE
+ IPC_ASSERT(ipc_es_ul_throttle_s && elapse_time);
+
+ ipc_eid_ul_throttle_s =
+ evshed_set_event(ipc_es_ul_throttle_s,
+ ipc_ul_throttle_timeout,
+ NULL,
+ elapse_time);
+
+ IPC_ASSERT(ipc_eid_ul_throttle_s);
+ hif_data_trace(MD_TRC_IPC_TR_START_UL_THROTTLE_TIMER, kal_get_systicks(), elapse_time);
+#endif
+}
+
+/*------------------------------------------------------------------------------
+ * Private functions. (Gen93)
+ *----------------------------------------------------------------------------*/
+static INLINE ipc_ul_queue_priority_e
+ipc_get_queue_priority_from_lhif_queue_type(LHIF_QUEUE_TYPE lhif_q_type)
+{
+ switch (lhif_q_type) {
+ case LHIF_HWQ_AP_UL_Q0:
+ return IPC_UL_QUEUE_PRIORITY_LOW;
+ case LHIF_HWQ_AP_UL_Q1:
+ return IPC_UL_QUEUE_PRIORITY_HIGH;
+ default:
+ /*can't reach here*/
+ IPC_ASSERT(KAL_FALSE);
+ return IPC_UL_QUEUE_PRIORITY_LOW;
+ }
+}
+
+/*
+ * Assumption: UL queue write lock is acquired.
+ * This function should be very light. MUST NOT do any heavy jobs.
+ */
+static INLINE kal_bool
+ipc_is_ul_queue_allowed_to_send(ipc_ul_queue_t *queue)
+{
+ kal_bool ret = KAL_FALSE;
+
+ if (0 == queue->cnt) {
+ return KAL_FALSE;
+ }
+
+ switch (queue->queue_type) {
+ case IPC_UL_QUEUE_TYPE_IOR:
+ ret = (NULL != queue->ior_head);
+ break;
+ case IPC_UL_QUEUE_TYPE_META:
+ ret = (0 <= queue->meta_head);
+ break;
+ default:
+ /*can't reach here*/
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ switch (queue->priority) {
+ case IPC_UL_QUEUE_PRIORITY_HIGH:
+ return ( ret && (!ipc_ul_throttle_is_block_latency_concern_s || ipc_ul_throttle_is_ims_emergency_s) );
+ case IPC_UL_QUEUE_PRIORITY_LOW:
+ return ( ret && (ipc_ul_throttle_state_s != IPC_UL_THROTTLE_STATE_SUSPEND) && ipc_ul_enable_g );
+ default:
+ /*can't reach here*/
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+}
+
+/*
+ * Assumption: UL queue write lock is acquired.
+ * This function should be very light. MUST NOT do any heavy jobs.
+ */
+static void
+ipc_clear_ior_queue(ipc_ul_queue_t *q)
+{
+ q->cnt = 0;
+ q->pending_cnt = 0;
+ q->ior_head = NULL;
+ q->ior_tail = NULL;
+}
+
+/*
+ * Assumption: UL queue write lock is acquired.
+ * This function should be very light. MUST NOT do any heavy jobs.
+ */
+static void
+ipc_clear_meta_queue(ipc_ul_queue_t *q)
+{
+ q->cnt = 0;
+ q->pending_cnt = 0;
+ q->meta_head = IPC_QUEUE_META_INVALID_VALUE;
+ q->meta_tail = IPC_QUEUE_META_INVALID_VALUE;
+}
+
+static void ipc_on_process_ul_meta_table(ipc_ul_queue_t *q)
+{
+ kal_uint16 start_idx, read_idx, end_idx;
+ LHIF_QUEUE_TYPE queue_type;
+ lhif_meta_tbl_t *meta_tbl;
+ lhif_meta_tbl_t *meta;
+ kal_uint16 tbl_size;
+ kal_uint32 netif_id, prev_netif_id;
+ ipc_netif_t *netif = NULL;
+ kal_uint8 ip_type;
+ kal_uint32 ipv4_pdn_id, ipv6_pdn_id;
+
+#ifdef __IPC_95_ACK_REDUCTION_SUPPORT__
+ lhif_meta_tbl_t *p_drop_ea_table[IPC_HPC_ENTRY_SIZE] = {NULL};
+#endif
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ kal_uint32 i;
+ kal_uint32 netif_features;
+
+ static ipc_dpfm_lan_des_t ap_to_host_des[IPC_DPFM_MAX_DEVICE_NUM];
+ static ipc_dpfm_lan_des_t host_to_ap_des[IPC_DPFM_MAX_DEVICE_NUM];
+ static ipc_dpfm_mirror_des_t dpfm_mirror_des[IPC_DPFM_MAX_DEVICE_NUM];
+#else
+ ipc_dpfm_mirror_des_t *dpfm_mirror_des = NULL;
+#endif
+
+ HIF_SWLA_START("IU4");
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ kal_mem_set(ap_to_host_des, 0, sizeof(ap_to_host_des));
+ kal_mem_set(host_to_ap_des, 0, sizeof(host_to_ap_des));
+ kal_mem_set(dpfm_mirror_des, 0, sizeof(dpfm_mirror_des));
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ ap_to_host_des[i].dst_netif_id = IPC_INVALID_NETIF_ID;
+ ap_to_host_des[i].src_netif_id = IPC_INVALID_NETIF_ID;
+ /* the host interface don't care the sequence */
+ ap_to_host_des[i].is_need_adjust_seq = KAL_FALSE;
+ host_to_ap_des[i].dst_netif_id = IPC_INVALID_NETIF_ID;
+ host_to_ap_des[i].src_netif_id = IPC_INVALID_NETIF_ID;
+ host_to_ap_des[i].is_need_adjust_seq = KAL_FALSE;
+
+ dpfm_mirror_des[i].netif_id = IPC_INVALID_NETIF_ID;
+ dpfm_mirror_des[i].pdn_ids[0] = IPC_INVALID_NETIF_ID;
+ dpfm_mirror_des[i].pdn_ids[1] = IPC_INVALID_NETIF_ID;
+ }
+#endif
+
+ IPC_ASSERT(q);
+ start_idx = read_idx = q->meta_head;
+ end_idx = q->meta_tail;
+ queue_type = q->meta_queue_type;
+
+ IPC_QUERY_META_TABLE((kal_uint32 **)&meta_tbl, &tbl_size, queue_type);
+
+ prev_netif_id = IPC_INVALID_NETIF_ID;
+ ipv4_pdn_id = IPC_INVALID_PDN_ID;
+ ipv6_pdn_id = IPC_INVALID_PDN_ID;
+
+ do {
+ meta = &meta_tbl[read_idx];
+
+#if IPC_DBG_UL_PKT_DUMP_ENABLE
+ hif_trace_info(IPC_RECEIVED_UL_META_INFO, read_idx, meta->match_index, meta->mr);
+ ipc_utils_pkt_dump_buf(MSG_ID_DHL_UPCM_IMS_UL_RAW_DATA, MOD_IPCORE, (void*)meta->vrb_addr, meta->length);
+#endif
+
+ /* Filter & route packets */
+ if ( !meta->ignore &&
+ (LHIF_NET_TYPE_PDCP_LBA != meta->net_type) &&
+ (LHIF_NET_TYPE_PDCP_LBB != meta->net_type) &&
+ (LHIF_NET_TYPE_IGNORE != meta->net_type)) {
+
+#ifdef __IPC_95_ACK_REDUCTION_SUPPORT__
+ if (meta->ea && (IPC_HPC_MR_MATCH == meta->mr)) {
+ if (NULL != p_drop_ea_table[meta->match_index]) {
+ /* free previous one */
+ p_drop_ea_table[meta->match_index]->ignore = 1;
+ IPC_FREE_META_VRB(p_drop_ea_table[meta->match_index]);
+ }
+
+ /* updated new one */
+ p_drop_ea_table[meta->match_index] = meta;
+ }
+#endif
+
+#if (CUR_GEN >= MD_GEN95)
+ //Gen95
+ netif_id = ipc_get_netif_id_from_meta(meta->net_type, meta->channel_id);
+#else
+ //Gen93
+ netif_id = ipc_get_netif_id_from_meta(meta->net_type, meta->net_if);
+#endif
+ if (netif_id != prev_netif_id) {
+ prev_netif_id = netif_id;
+
+ if (netif) {
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+ netif = ipc_find_netif(netif_id);
+ if (netif) {
+ ipc_get_pdn_id_from_netif(&ipv4_pdn_id, &ipv6_pdn_id, netif);
+ } else {
+ ipv4_pdn_id = IPC_INVALID_NETIF_ID;
+ ipv6_pdn_id = IPC_INVALID_NETIF_ID;
+ }
+ }
+ if (netif) {
+ #if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ /* Note that we don't support DPFM in Gen93 */
+ netif_features = netif->config.features;
+ if ( (netif_features & IPC_F_LAN) &&
+ !(netif_features & IPC_F_TETHERING_ROUTE)) {
+ ipc_pkt_des_t packet_des;
+
+ /* Fill packet_des */
+ kal_mem_set(&packet_des, 0, sizeof(ipc_pkt_des_t));
+ packet_des.des_type = IPC_PKT_DES_TYPE_META;
+ packet_des.packet = meta->vrb_addr;
+ packet_des.packet_len = meta->length;
+ packet_des.meta = meta;
+
+ /*
+ * Direct Tethering
+ * The UL META from LHIF-LAN should be directly send to RNDIS.
+ */
+ meta->ignore = 1;
+ if (!ipc_dpfm_fill_did_si_from_meta(ap_to_host_des, meta, netif_id, netif)) {
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL, netif->config.netif_id, meta, read_idx);
+ IPC_FREE_META_VRB(meta);
+ }
+ }
+ else {
+ /* HPC supported */
+ if (ipc_on_process_ul_hpc_result(&ip_type, read_idx, meta, netif_id, dpfm_mirror_des)) {
+ /* return 1 means no filter match or no DPFM match. */
+ if (netif_features & IPC_F_LAN) {
+ meta->ignore = 1;
+ if (!ipc_dpfm_fill_did_si_from_meta(host_to_ap_des, meta, netif_id, netif)) {
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL, netif->config.netif_id, meta, read_idx);
+ IPC_FREE_META_VRB(meta);
+ }
+ }
+ else {
+ ipc_check_and_fill_session_info(ip_type, ipv4_pdn_id, ipv6_pdn_id, netif_id, meta);
+ }
+ }
+ }
+ #else //__MD_DIRECT_TETHERING_SUPPORT__
+ #if defined(__MD93__)
+ ip_type = ipc_get_ip_type_from_meta(meta);
+ if (IPC_IP_TYPE_INVALID != ip_type) {
+ /* local used only */
+ ipc_filter_info_t filter_info;
+ ipc_packet_info_t packet_info;
+ ipc_pkt_des_t packet_des;
+ ipc_filter_t *filter;
+
+ /* Fill packet_des */
+ packet_des.des_type = IPC_PKT_DES_TYPE_META;
+ packet_des.packet = meta->vrb_addr;
+ packet_des.packet_len = meta->length;
+ packet_des.meta = meta;
+ packet_des.matched_filter = &filter;
+ packet_des.filter_info = &filter_info;
+ packet_des.packet_info = &packet_info;
+ packet_des.ip_type = ip_type;
+ packet_des.is_packet_info = KAL_FALSE;
+ kal_mem_set(packet_des.packet_info, 0, sizeof(ipc_packet_info_t));
+
+ if (ipc_meta_do_filter(ip_type, netif_id, meta, dpfm_mirror_des, &packet_des)) {
+ ipc_fill_session_info_into_meta(ip_type, ipv4_pdn_id, ipv6_pdn_id, netif_id, meta);
+ }
+ } else {
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_NONE_IP_PKT, netif_id, read_idx, queue_type);
+ meta->ignore = 1;
+ IPC_FREE_META_VRB(meta);
+ }
+ #elif (CUR_GEN >= MD_GEN95)
+ /* HPC supported */
+ if (ipc_on_process_ul_hpc_result(&ip_type, read_idx, meta, netif_id, dpfm_mirror_des)) {
+ ipc_check_and_fill_session_info(ip_type, ipv4_pdn_id, ipv6_pdn_id, netif_id, meta);
+ }
+ #endif
+ #endif
+ } else if (ipc_on_process_dpfm_cmd_result(read_idx, meta)) {
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_INVALID_NETIF, netif_id, read_idx, queue_type);
+ meta->ignore = 1;
+ IPC_FREE_META_VRB(meta);
+ }
+ }
+ else
+ {
+ if(LHIF_NET_TYPE_IGNORE == meta->net_type)
+ {
+ hif_trace_info(IPC_TR_UL_IGNORE_NET_TYPE_DROP, read_idx);
+ meta->ignore = 1;
+ IPC_FREE_META_VRB(meta);
+ }
+ }
+
+ read_idx ++;
+ if (read_idx == tbl_size) {
+ read_idx = 0;
+ }
+ } while (read_idx != end_idx);
+
+ if (netif) {
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ /* For IPC_F_LAN netif, send packet to netif instead of upcm. */
+ ipc_dpfm_lan_on_did_downlink(ap_to_host_des);
+ ipc_dpfm_lan_on_did_downlink(host_to_ap_des);
+#endif
+ HIF_SWLA_STOP("IU4");
+
+ HIF_SWLA_START("IU5");
+ hif_data_trace(MD_TRC_IPC_UL_FORWARD_META, start_idx, end_idx, queue_type);
+ IPC_FORWARD_UL_META(q->meta_head, q->meta_tail, q->meta_queue_type);
+ HIF_SWLA_STOP("IU5");
+}
+
+static INLINE void ipc_clear_did_queue(ipc_did_queue_t *did_queue)
+{
+ did_queue->did_head = NULL;
+ did_queue->did_tail = NULL;
+}
+
+static INLINE void ipc_push_did_list_to_did_queue_tail(ipc_did_queue_t *did_queue, upcm_did *did_head, upcm_did *did_tail)
+{
+ upcm_did **did_queue_head = &(did_queue->did_head);
+ upcm_did **did_queue_tail = &(did_queue->did_tail);
+
+ if (*did_queue_tail) {
+ UPCM_DID_SET_NEXT(*did_queue_tail, did_head);
+ *did_queue_tail = did_tail;
+ } else {
+ *did_queue_head = did_head;
+ *did_queue_tail = did_tail;
+ }
+}
+
+static INLINE void ipc_push_did_list_to_did_queue_head(ipc_did_queue_t *did_queue, upcm_did *did_head, upcm_did *did_tail)
+{
+ upcm_did **did_queue_head = &(did_queue->did_head);
+ upcm_did **did_queue_tail = &(did_queue->did_tail);
+
+ if (*did_queue_head) {
+ UPCM_DID_SET_NEXT(did_tail, *did_queue_head);
+ *did_queue_head = did_head;
+ } else {
+ *did_queue_head = did_head;
+ *did_queue_tail = did_tail;
+ }
+}
+
+/*
+ * Assumption: netif read lock is acquired.
+ */
+static kal_bool ipc_forward_dl_did_default(kal_uint8 ip_type, ipc_netif_t *netif, kal_uint32 pdn_id, upcm_did *did)
+{
+ kal_bool dl_cbk_ret = KAL_TRUE;
+ kal_uint32 netif_id = netif->config.netif_id;
+ kal_uint16 pkt_num_to_netif;
+
+ pkt_num_to_netif = ipc_did_do_filter(ip_type, netif_id, pdn_id, did);
+ if (pkt_num_to_netif) {
+ hif_data_trace(MD_TRC_IPC_DL_FWD_DL_CALLBACK_DID, pkt_num_to_netif, netif_id);
+
+ HIF_SWLA_START("ID3");
+ dl_cbk_ret = netif->config.ipc_dlink_did_cb_t(
+ netif->config.callback_context,
+ did);
+ HIF_SWLA_STOP("ID3");
+ }
+
+ return dl_cbk_ret;
+}
+
+/*
+ * Assumption: netif read lock is acquired.
+ */
+static kal_bool ipc_forward_dl_did_wo_filter(kal_uint8 ip_type, ipc_netif_t *netif, kal_uint32 pdn_id, upcm_did *did)
+{
+ kal_bool dl_cbk_ret = KAL_TRUE;
+
+ hif_data_trace(MD_TRC_IPC_DL_FWD_DL_CALLBACK_DID_WO_FILTER, UPCM_DID_GET_PKT_NUM(did), netif->config.netif_id);
+
+ HIF_SWLA_START("ID3");
+ dl_cbk_ret = netif->config.ipc_dlink_did_cb_t(
+ netif->config.callback_context,
+ did);
+ HIF_SWLA_STOP("ID3");
+
+ return dl_cbk_ret;
+}
+
+typedef kal_bool (*ipc_fw_dl_did_f)(kal_uint8 ip_type, ipc_netif_t *netif, kal_uint32 pdn_id, upcm_did *did);
+typedef void (*ipc_enq_retry_dl_did_f)(upcm_did *did_head, upcm_did *did_tail, kal_uint32 queue_idx, ipc_data_enq_position_e position);
+
+/*
+ * Assumption: netif read lock is acquired.
+ */
+static ipc_fw_dl_did_f ipc_fw_dl_did_f_dispatcher_s[IPC_DID_QUEUE_TYPE_MAX] = {ipc_forward_dl_did_default,
+ ipc_forward_dl_did_wo_filter,
+ ipc_forward_dl_did_wo_filter};
+
+/*
+ * Assumption: netif read lock is acquired.
+ */
+static ipc_enq_retry_dl_did_f ipc_enq_retry_dl_did_f_dispatcher_s[IPC_DID_QUEUE_TYPE_MAX] = {ipc_did_enqueue_default_queue,
+ ipc_did_enqueue_wo_filter_queue,
+ ipc_did_enqueue_dpfm_queue};
+
+/*
+ * Assumption: netif read lock is acquired.
+ */
+static void ipc_on_process_dl_did_list(kal_uint8 ip_type, ipc_netif_t *netif, kal_uint32 pdn_id, ipc_did_queue_type_e queue_type, upcm_did *did_head, upcm_did *did_tail)
+{
+ upcm_did *did;
+ upcm_did *prev_did = NULL;
+ upcm_did *next_did;
+ kal_bool end_of_list;
+ kal_bool dl_cbk_ret = KAL_TRUE;
+ kal_uint32 dl_queue_idx = pdn_id;
+
+ IPC_ASSERT(netif && did_head && did_tail);
+
+ end_of_list = KAL_FALSE;
+ for (did = did_head; did && !end_of_list; did = next_did) {
+ next_did = UPCM_DID_GET_NEXT(did);
+ end_of_list = (did == did_tail);
+
+ if (IPC_DID_QUEUE_TYPE_DEFAULT == queue_type) {
+ hif_data_trace(MD_TRC_IPC_DL_PROCESS_DL_DID, UPCM_DID_GET_FLOW(did),
+ UPCM_DID_GET_COUNT_L(did),
+ (UPCM_DID_GET_COUNT_L(did) + UPCM_DID_GET_PKT_NUM(did) - 1),
+ UPCM_DID_GET_SEG_NUM(did),
+ did,
+ pdn_id);
+ }
+
+ dl_cbk_ret = (ipc_fw_dl_did_f_dispatcher_s[queue_type])(ip_type, netif, pdn_id, did);
+ if (!dl_cbk_ret) {
+ /*
+ * The netif is not able to receive DID for now.
+ * Queue all remaining DID to DL queue (IPC_DID_QUEUE_TYPE_WO_FILTER).
+ */
+ break;
+ }
+
+ prev_did = did;
+ }
+
+ if (did && !dl_cbk_ret) {
+ kal_bool to_send_msg;
+
+ hif_data_trace(MD_TRC_IPC_DL_ON_DID_DOWNLINK_PENDING, did, did_tail);
+
+ if (did != did_head) {
+ /* Free DID which have been sent */
+ if (prev_did) {
+ IPC_ASSERT(UPCM_DID_GET_NEXT(prev_did) == did);
+ UPCM_DID_SET_NEXT(prev_did, NULL);
+ }
+ upcm_did_dest_q(did_head, prev_did);
+ }
+
+ /* Enqueue all remaining DID */
+ (ipc_enq_retry_dl_did_f_dispatcher_s[queue_type])(did, did_tail, dl_queue_idx, IPC_DATA_DID_HEAD);
+
+ /* Send ILM to IPCore for processing DL queue */
+ to_send_msg = ipc_data_check_and_set_dl_ilm_flag();
+
+ /*
+ * Switch to IPCORE context.
+ */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ } else {
+ upcm_did_dest_q(did_head, did_tail);
+ }
+
+ return;
+}
+
+/* Unused static function */
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/*------------------------------------------------------------------------------
+ * Public functions.
+ *----------------------------------------------------------------------------*/
+void ipc_on_process_ul_queue(void)
+{
+ kal_uint32 i = 0;
+ ipc_ul_queue_t tmp_queue;
+ kal_bool to_send_pkt = KAL_FALSE;
+
+ HIF_SWLA_START("IU2");
+
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ ipc_ul_processing_s = KAL_FALSE;
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ hif_data_trace(MD_TRC_IPC_UL_PROCESS_UPLINK_QUEUE);
+
+ for (i = 0; i < IPC_UL_QUEUE_NUM; i++) {
+ ipc_ul_queue_t *q = &ipc_ul_queues_s[i];
+ to_send_pkt = KAL_FALSE;
+
+ /*
+ * Check whether the ul queue is allowed to sent or not.
+ * If yes, dequeue the queue.
+ */
+ IPC_W_LOCK_OBJECT(q, g_ul_spinlock);
+ if (q) {
+ kal_mem_cpy(&tmp_queue, q, sizeof(ipc_ul_queue_t));
+ if (ipc_is_ul_queue_allowed_to_send(q)) {
+ q->ipc_clear_callback_t(q);
+ to_send_pkt = KAL_TRUE;
+ } else {
+ q->pending_cnt = q->cnt;
+ }
+ IPC_W_UNLOCK_OBJECT(q, g_ul_spinlock);
+
+ if (to_send_pkt) {
+ /* Process the queue by calling it's cbk */
+ tmp_queue.ipc_process_callback_t(&tmp_queue);
+ } else if (tmp_queue.pending_cnt) {
+ hif_data_trace(MD_TRC_IPC_UL_DEQUEUE_UPLINK_QUEUE, tmp_queue.queue_type, tmp_queue.priority, tmp_queue.pending_cnt);
+ }
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ }
+ }
+
+ HIF_SWLA_STOP("IU2");
+}
+
+void ipc_on_retry_ul_reload(void)
+{
+ kal_uint64 netif_bit_ids;
+ kal_uint64 lbs; /* least significant bit set to 1 */
+ ipc_netif_t *netif;
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ ipc_ul_reload_retrying_s = KAL_FALSE;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ netif_bit_ids = ipc_get_all_netif_ul_reload_retry();
+
+ hif_data_trace(MD_TRC_IPC_UL_ON_RETRY_RELOAD, 0, netif_bit_ids);
+
+ while (netif_bit_ids) {
+ lbs = netif_bit_ids & ((~netif_bit_ids) + 1);
+ netif_bit_ids &= (~lbs);
+
+ netif = ipc_find_netif_by_bit_id(lbs);
+
+ hif_data_trace(MD_TRC_IPC_UL_ON_RETRY_RELOAD_FOR_NETIF, 0, netif, lbs);
+
+ if (netif) {
+ ipc_reload_uplink(netif);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+ }
+}
+
+void ipc_on_downlink(kal_uint32 pdn_id, qbm_gpd *p_head, qbm_gpd *p_tail)
+{
+ ipc_session_t *session;
+ ipc_netif_t *netif;
+ ipc_io_request_t *ior;
+ kal_uint8 session_type;
+ kal_uint32 netif_id;
+
+ HIF_SWLA_START("ID0");
+
+ IPC_ASSERT(p_head);
+ IPC_ASSERT(p_tail);
+
+ hif_data_trace(MD_TRC_IPC_DL_ON_DOWNLINK, pdn_id, p_head, p_tail);
+
+ session = ipc_find_session_by_context(pdn_id);
+ if (session) {
+ netif = session->netif;
+ session_type = session->type;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /* Get network interface information for following operations */
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif)
+ {
+ netif_id = netif->config.netif_id;
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ } else
+ {
+ kal_uint8 ip_id = 0xff;
+
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session)
+ {
+ ip_id = (kal_uint8)session->ip_id;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+
+ hif_trace_error(IPC_TR_DL_DROP_FOR_NETIF_INFO_LOCK_FAIL, pdn_id, ip_id, session_type, p_head, p_tail);
+ goto drop;
+ }
+
+ /* Do DL filter */
+ ipc_do_dl_filter(session_type, netif_id, pdn_id, &p_head, &p_tail);
+
+ if (NULL == p_head || NULL == p_tail)
+ {
+ hif_data_trace(MD_TRC_IPC_DL_ON_DOWNLINK_FILTER_OUT, 0, session_type, netif_id);
+ IPC_ASSERT(NULL == p_head && NULL == p_tail);
+ goto done;
+ }
+
+ /* Send DL traffic */
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif)
+ {
+ ior = (ipc_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+ ior->next_request = NULL;
+ ior->first_gpd = p_head;
+ ior->last_gpd = p_tail;
+ ior->ip_type = session_type;
+ ior->qos_priority = 0;
+
+ hif_data_trace(MD_TRC_IPC_DL_ON_DOWNLINK_CALLBACK_INFO, pdn_id, session_type, netif_id);
+ hif_data_trace(MD_TRC_IPC_DL_ON_DOWNLINK_CALLBACK_GPD, pdn_id, p_head, p_tail);
+
+ HIF_SWLA_START("ID3");
+ netif->config.ipc_dlink_callback_t(
+ netif->config.callback_context,
+ ior);
+ HIF_SWLA_STOP("ID3");
+
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ goto done;
+ } else
+ {
+ kal_uint8 ip_id = 0xff;
+
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session)
+ {
+ ip_id = (kal_uint8)session->ip_id;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+ hif_trace_error(IPC_TR_DL_DROP_FOR_NETIF_DETACH, pdn_id, ip_id, session_type, p_head, p_tail);
+ goto drop;
+ }
+ } else
+ {
+ hif_trace_error(IPC_TR_DL_DROP_FOR_INVALID_SESSION, pdn_id, p_head, p_tail);
+ }
+
+drop:
+ qbmt_dest_q(p_head, p_tail); /* Discard packets if something wrong. */
+done:
+
+ HIF_SWLA_STOP("ID0");
+ return;
+}
+
+void ipc_on_downlink_multiple_ps(kal_uint32 pdn_id, qbm_gpd *p_head, qbm_gpd *p_tail, kal_uint8 proto_idx)
+{
+ upcm_dlvr_dl_info_t *p_info = (upcm_dlvr_dl_info_t *)QBM_DES_GET_SW_CTRL_FIELD(p_head);
+
+ hif_data_trace(MD_TRC_IPC_DL_ON_DOWNLINK_MULTI_PS, pdn_id, proto_idx);
+
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, proto_idx);
+ IPC_MASK_PROTOID_ON_PDNID(p_info->ebi, proto_idx);
+ ipc_on_downlink(pdn_id, p_head, p_tail);
+}
+
+void ipc_timer_init()
+{
+ ipc_es_ul_throttle_s = evshed_create(
+ "IPC_UL_THROTTLE", /* timer_name: event scheduler name */
+ MOD_IPCORE, /* dest_mod_id: system sends timeout message to this module when event scheduler timeout happens */
+ 0, /* fuzz */
+ 0); /* max_delay_ticks */
+
+ if (ipc_es_ul_throttle_s) {
+ evshed_set_index(ipc_es_ul_throttle_s, IPC_ES_INDEX_UL_THROTTLE);
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ }
+}
+
+void ipc_set_ul_throttle(local_para_struct *local_para_ptr)
+{
+ ipc_set_ul_throttle_param_t *param = (ipc_set_ul_throttle_param_t *)local_para_ptr;
+ ipc_ul_throttle_conf_t *conf = (ipc_ul_throttle_conf_t *)(&(param->conf));
+ kal_bool to_send_msg = KAL_FALSE;
+
+ hif_trace_info(IPC_TR_SET_UL_THROTTLE_BEGIN, ipc_ul_throttle_state_s,
+ ipc_ul_throttle_conf_s.enabled,
+ ipc_ul_throttle_conf_s.active_period_100ms,
+ ipc_ul_throttle_conf_s.suspend_period_100ms,
+ ipc_ul_throttle_is_block_latency_concern_s);
+
+ /* Cancel original timer. */
+ if (NULL != ipc_eid_ul_throttle_s) {
+ ipc_ul_throttle_conf_s.enabled = KAL_FALSE;
+ evshed_cancel_event(ipc_es_ul_throttle_s, &ipc_eid_ul_throttle_s);
+ ipc_eid_ul_throttle_s = NULL;
+ }
+
+ if (conf->enabled) {
+ /* Enable IPC UL throttle. */
+ IPC_ASSERT(conf->active_period_100ms && conf->suspend_period_100ms);
+
+ kal_mem_cpy(&ipc_ul_throttle_conf_s, conf, sizeof(ipc_ul_throttle_conf_t));
+ /* Check if its the SUSPEND-FOREVER mode. (active:suspend = 1:255) */
+ if ( (1 == ipc_ul_throttle_conf_s.active_period_100ms) &&
+ (255 == ipc_ul_throttle_conf_s.suspend_period_100ms) ) {
+ /* It's SUSPEND-FOREVER mode */
+ ipc_ul_throttle_state_s = IPC_UL_THROTTLE_STATE_SUSPEND;
+ } else {
+ // Start new timer.
+ ipc_start_ul_throttle_timer(ipc_ul_throttle_conf_s.active_period_100ms * KAL_TICKS_100_MSEC);
+ ipc_ul_throttle_state_s = IPC_UL_THROTTLE_STATE_ACTIVE;
+ }
+
+ /* Check block-latency-concern enable bit */
+ if (1 == (conf->features & IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN)) {
+ IPC_ASSERT(255 == ipc_ul_throttle_conf_s.suspend_period_100ms);
+ ipc_ul_throttle_is_block_latency_concern_s = KAL_TRUE;
+ } else {
+ ipc_ul_throttle_is_block_latency_concern_s = KAL_FALSE;
+ }
+ } else {
+ /* Disable IPC UL throttle. */
+ kal_mem_set(&ipc_ul_throttle_conf_s, 0, sizeof(ipc_ul_throttle_conf_t));
+
+ ipc_ul_throttle_state_s = IPC_UL_THROTTLE_STATE_NONE;
+ ipc_ul_throttle_is_block_latency_concern_s = KAL_FALSE;
+
+ /* IPCORE need to process ul queue if ul pending queue is not empty */
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = ((!ipc_ul_processing_s) && (!ipc_are_ul_queues_empty()));
+ if (to_send_msg) {
+ ipc_ul_processing_s = KAL_TRUE;
+ }
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ }
+ hif_trace_info(IPC_TR_SET_UL_THROTTLE_END, ipc_ul_throttle_state_s,
+ ipc_ul_throttle_conf_s.enabled,
+ ipc_ul_throttle_conf_s.active_period_100ms,
+ ipc_ul_throttle_conf_s.suspend_period_100ms,
+ ipc_ul_throttle_is_block_latency_concern_s);
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_ENPDCP, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ (IPC_UL_THROTTLE_STATE_SUSPEND == ipc_ul_throttle_state_s) ?
+ MSG_ID_IPCORE_ENPDCP_UL_SUSPEND_NTF : MSG_ID_IPCORE_ENPDCP_UL_ACTIVE_NTF, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ /* For EM ELT update info*/
+ ipc_em_send_ul_throttle_status();
+}
+
+void ipc_em_send_ul_throttle_status(void)
+{
+#ifdef __EM_MODE__
+ em_ipc_ul_throttle_status_ind_struct_t *em_info_ptr;
+ ilm_struct ilm;
+
+ if (ipc_em_on_s) {
+ em_info_ptr = (em_ipc_ul_throttle_status_ind_struct_t *)
+ construct_local_para(sizeof(em_ipc_ul_throttle_status_ind_struct_t), TD_RESET);
+
+ kal_mem_cpy(&(em_info_ptr->throttle_conf), &ipc_ul_throttle_conf_s, sizeof(ipc_ul_throttle_conf_t));
+ em_info_ptr->throttle_state = ipc_ul_throttle_state_s;
+
+ ilm.src_mod_id = MOD_IPCORE;
+ ilm.dest_mod_id = MOD_DHL;
+ ilm.msg_id = MSG_ID_EM_IPC_UL_THROTTLE_STATUS_IND;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.local_para_ptr = (local_para_struct *)em_info_ptr;
+ ilm.peer_buff_ptr = NULL;
+
+ dhl_EM_logger(&ilm);
+ destroy_ilm(&ilm);
+ }
+#endif
+}
+
+void ipc_ims_emergency_call_ind_handler(local_para_struct *local_para_ptr)
+{
+ ipc_vdm_ims_emergency_call_ind_struct_t *p = (ipc_vdm_ims_emergency_call_ind_struct_t *)local_para_ptr;
+ kal_bool to_send_msg;
+
+ hif_data_trace(MD_TRC_IPC_UL_THROTTLE_IMS_EMERGEMCY_IND, ipc_ul_throttle_is_ims_emergency_s, p->is_calling);
+
+ ipc_ul_throttle_is_ims_emergency_s = p->is_calling;
+
+ if (ipc_ul_throttle_is_ims_emergency_s) {
+ /* IPCORE need to process ul queue if ul pending queue is not empty */
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = ((!ipc_ul_processing_s) && (!ipc_are_ul_queues_empty()));
+ if (to_send_msg) {
+ ipc_ul_processing_s = KAL_TRUE;
+ }
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions. (Gen93)
+ *----------------------------------------------------------------------------*/
+kal_uint32
+ipc_get_netif_id_from_meta(kal_uint8 net_type, kal_uint8 channel_id)
+{
+ kal_uint32 netif_id = channel_id;
+
+ switch (net_type) {
+ case LHIF_NET_TYPE_LHIF:
+ netif_id |= IPC_NETIF_ID_LHIF_BEGIN;
+ break;
+ case LHIF_NET_TYPE_RNDIS:
+ netif_id |= IPC_NETIF_ID_ETH_BEGIN;
+ break;
+ case LHIF_NET_TYPE_MBIM:
+ netif_id |= IPC_NETIF_ID_MBIM_BEGIN;
+ break;
+ case LHIF_NET_TYPE_MCIF:
+ netif_id |= IPC_NETIF_ID_MCIF_BEGIN;
+ break;
+ case LHIF_NET_TYPE_VNIF:
+ netif_id |= IPC_NETIF_ID_VNIF_BEGIN;
+ break;
+ default:
+ /* Unexpected netif net_type. */
+ netif_id = IPC_INVALID_NETIF_ID;
+ hif_data_trace(MD_TRC_IPC_GET_NETIF_FROM_META, net_type, channel_id, netif_id);
+ break;
+ }
+
+ return netif_id;
+}
+
+kal_uint8
+ipc_get_ip_type_from_meta(lhif_meta_tbl_t *meta)
+{
+ /*
+ * 2016/11/29 Cammie.Yang
+ * Invalidate the first 64B of uplink packets to eliminate the duplicate cache-invalid effort in UPCM.
+ */
+ QBM_CACHE_INVALID(meta->vrb_addr, 64);
+ if (IPC_HDR_IS_V4(meta->vrb_addr)) {
+ return IPC_IP_TYPE_IPV4;
+ } else if (IPC_HDR_IS_V6(meta->vrb_addr)) {
+ return IPC_IP_TYPE_IPV6;
+ } else {
+ /* Unexpected packets, which is neither IPv4 or IPv6 */
+ return IPC_IP_TYPE_INVALID;
+ }
+}
+
+void
+ipc_get_pdn_id_from_netif(kal_uint32 *ipv4_pdn_id, kal_uint32 *ipv6_pdn_id, ipc_netif_t *netif)
+{
+ ipc_session_t *session;
+
+ /* Get the IPv4 PDN ID of the netif */
+ session = ipc_find_session_by_netif(netif, IPC_IP_TYPE_IPV4);
+ if (session) {
+ IPC_ASSERT((session->context & 0xFFFFFF00) == 0);
+
+ *ipv4_pdn_id = session->context;
+
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ } else {
+ *ipv4_pdn_id = IPC_INVALID_PDN_ID;
+ }
+
+ /* Get the IPv6 PDN ID of the netif */
+ session = ipc_find_session_by_netif(netif, IPC_IP_TYPE_IPV6);
+ if (session) {
+ IPC_ASSERT((session->context & 0xFFFFFF00) == 0);
+
+ *ipv6_pdn_id = session->context;
+
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ } else {
+ *ipv6_pdn_id = IPC_INVALID_PDN_ID;
+ }
+}
+
+kal_bool ipc_queue_init()
+{
+ int i_type, i_priority;
+
+ /* Init UL queues */
+ for (i_type = 0; i_type < IPC_UL_QUEUE_TYPE_MAX; i_type++) {
+ for (i_priority = 0; i_priority < IPC_UL_QUEUE_PRIORITY_MAX; i_priority++) {
+ ipc_ul_queue_t *ul_queue = &ipc_ul_queues_s[_IPC_GET_UL_QUEUE_INDEX(i_type, i_priority)];
+
+ kal_mem_set(ul_queue, 0, sizeof(ipc_ul_queue_t));
+ if (!IPC_IS_VALID_OBJECT(ul_queue)) {
+ IPC_INIT_OBJECT_BEGIN(ul_queue, g_ul_spinlock);
+
+ ul_queue->queue_type = i_type;
+ ul_queue->priority = i_priority;
+ if (IPC_UL_QUEUE_TYPE_META == i_type) {
+ switch (i_priority) {
+ case IPC_UL_QUEUE_PRIORITY_HIGH:
+ ul_queue->meta_queue_type = LHIF_HWQ_AP_UL_Q1;
+ break;
+ case IPC_UL_QUEUE_PRIORITY_LOW:
+ ul_queue->meta_queue_type = LHIF_HWQ_AP_UL_Q0;
+ break;
+ default:
+ /*can't reach here*/
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ ul_queue->meta_queue_size = IPC_QUEUE_META_INVALID_VALUE;
+ ul_queue->meta_head = IPC_QUEUE_META_INVALID_VALUE;
+ ul_queue->meta_tail = IPC_QUEUE_META_INVALID_VALUE;
+ ul_queue->ipc_clear_callback_t = ipc_clear_meta_queue;
+ ul_queue->ipc_process_callback_t = ipc_on_process_ul_meta_table;
+ } else {
+ ul_queue->ipc_clear_callback_t = ipc_clear_ior_queue;
+ ul_queue->ipc_process_callback_t = ipc_on_process_ul_ior_list;
+ }
+ IPC_INIT_OBJECT_END(ul_queue, g_ul_spinlock);
+ }
+ }
+ }
+
+ /* Init DL queues */
+ kal_mem_set(ipc_dl_queues_s, 0, sizeof(ipc_dl_queues_s));
+ ipc_dl_qbm_head_s = NULL;
+ ipc_dl_qbm_tail_s = NULL;
+
+#if defined(__IPF_SUPPORT__)
+ /* Init DL meta queues */
+ ipc_dl_meta_queue_init();
+
+ /* Init UL HPC table */
+ ipc_hpc_init();
+#endif
+
+ return KAL_TRUE;
+}
+
+/*
+ * Assumption: ipc_spinlock_g is acquired.
+ * This function should be very light. MUST NOT do any heavy jobs.
+ */
+kal_bool ipc_are_ul_queues_empty()
+{
+ kal_bool ret = KAL_TRUE;
+ kal_uint32 i = 0;
+
+ for (i = 0; i < IPC_UL_QUEUE_NUM; i++) {
+ ipc_ul_queue_t *q = &ipc_ul_queues_s[i];
+ ret &= (q->cnt == 0);
+ }
+
+ return ret;
+}
+
+void ipc_fill_session_info_into_meta(kal_uint8 ip_type, kal_uint32 ipv4_pdn_id, kal_uint32 ipv6_pdn_id, kal_uint32 netif_id, lhif_meta_tbl_t *meta)
+{
+ kal_uint32 pdn_id;
+ kal_uint32 proto_idx;
+
+ pdn_id = (IPC_IP_TYPE_IPV4 == ip_type) ? ipv4_pdn_id : ipv6_pdn_id;
+
+ if (IPC_INVALID_PDN_ID != pdn_id) {
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(pdn_id, proto_idx);
+ IPC_UNMASK_PROTOID_FROM_PDNID(pdn_id);
+ meta->pdn = pdn_id;
+ meta->protocol_idx = proto_idx;
+ } else {
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_SESSION_DEACT, netif_id, meta, ip_type);
+ meta->ignore = 1;
+ IPC_FREE_META_VRB(meta);
+ }
+}
+
+void ipc_push_ior_list_to_ior_queue(ipc_io_request_t *head_ior, ipc_io_request_t *tail_ior, kal_uint32 ior_cnt, ipc_ul_queue_priority_e q_priority)
+{
+ ipc_ul_queue_t *q;
+
+ IPC_ASSERT(head_ior && tail_ior);
+
+ q = &ipc_ul_queues_s[_IPC_GET_UL_QUEUE_INDEX(IPC_UL_QUEUE_TYPE_IOR, q_priority)];
+
+ IPC_W_LOCK_OBJECT(q, g_ul_spinlock);
+ if (q) {
+ if (q->ior_tail) {
+ q->ior_tail->io_req.next_request = head_ior;
+ q->ior_tail = (ipc_internal_ior_t *)tail_ior;
+ } else {
+ q->ior_head = (ipc_internal_ior_t *)head_ior;
+ q->ior_tail = (ipc_internal_ior_t *)tail_ior;
+ }
+
+ q->cnt += ior_cnt;
+ IPC_W_UNLOCK_OBJECT(q, g_ul_spinlock);
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ }
+}
+
+void ipc_push_meta_list_to_meta_queue(kal_uint16 start_idx, kal_uint16 end_idx, LHIF_QUEUE_TYPE q_type)
+{
+ ipc_ul_queue_priority_e q_priority;
+ ipc_ul_queue_t *q;
+
+ q_priority = ipc_get_queue_priority_from_lhif_queue_type(q_type);
+ q = &ipc_ul_queues_s[_IPC_GET_UL_QUEUE_INDEX(IPC_UL_QUEUE_TYPE_META, q_priority)];
+
+ IPC_W_LOCK_OBJECT(q, g_ul_spinlock);
+ if (q) {
+ IPC_ASSERT(q->meta_queue_type == q_type);
+
+ /*
+ * Since the LHIF API can't use in INIT stage,
+ * get meta_queue_size when the first uplink packet arrived.
+ */
+ if (IPC_QUEUE_META_INVALID_VALUE == q->meta_queue_size) {
+ kal_uint32 *base_addr;
+ kal_uint16 tbl_size;
+
+ IPC_QUERY_META_TABLE(&base_addr, &tbl_size, q_type);
+ q->meta_queue_size = tbl_size;
+ }
+
+ if (IPC_QUEUE_META_INVALID_VALUE == q->meta_tail) {
+ q->meta_head = start_idx;
+ q->meta_tail = end_idx;
+ } else {
+ IPC_ASSERT(start_idx == q->meta_tail);
+ q->meta_tail = end_idx;
+ }
+
+ q->cnt = (q->meta_tail >= q->meta_head)? (q->meta_tail - q->meta_head):(q->meta_queue_size - q->meta_head + q->meta_tail);
+ IPC_W_UNLOCK_OBJECT(q, g_ul_spinlock);
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ }
+}
+
+void ipc_did_enqueue_wo_filter_queue(upcm_did *did_head, upcm_did *did_tail, kal_uint32 queue_idx, ipc_data_enq_position_e position)
+{
+ ipc_dl_queue_t *dl_queue = &(ipc_dl_queues_s[queue_idx]);
+
+ switch (position) {
+ case IPC_DATA_DID_HEAD :
+ ipc_push_did_list_to_did_queue_head(&(dl_queue->did_queues[IPC_DID_QUEUE_TYPE_WO_FILTER]), did_head, did_tail);
+ break;
+ case IPC_DATA_DID_TAIL :
+ ipc_push_did_list_to_did_queue_tail(&(dl_queue->did_queues[IPC_DID_QUEUE_TYPE_WO_FILTER]), did_head, did_tail);
+ break;
+ default :
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+
+ return;
+}
+
+void ipc_did_enqueue_dpfm_queue(upcm_did *did_head, upcm_did *did_tail, kal_uint32 queue_idx, ipc_data_enq_position_e position)
+{
+ ipc_dl_queue_t *dl_queue = &(ipc_dl_queues_s[queue_idx]);
+
+ switch (position) {
+ case IPC_DATA_DID_HEAD :
+ ipc_push_did_list_to_did_queue_head(&(dl_queue->did_queues[IPC_DID_QUEUE_TYPE_DPFM]), did_head, did_tail);
+ break;
+ case IPC_DATA_DID_TAIL :
+ ipc_push_did_list_to_did_queue_tail(&(dl_queue->did_queues[IPC_DID_QUEUE_TYPE_DPFM]), did_head, did_tail);
+ break;
+ default :
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+
+ return;
+}
+
+void ipc_did_enqueue_default_queue(upcm_did *did_head, upcm_did *did_tail, kal_uint32 queue_idx, ipc_data_enq_position_e position)
+{
+ ipc_dl_queue_t *dl_queue = &(ipc_dl_queues_s[queue_idx]);
+
+ switch (position) {
+ case IPC_DATA_DID_HEAD :
+ ipc_push_did_list_to_did_queue_head(&(dl_queue->did_queues[IPC_DID_QUEUE_TYPE_DEFAULT]), did_head, did_tail);
+ break;
+ case IPC_DATA_DID_TAIL :
+ ipc_push_did_list_to_did_queue_tail(&(dl_queue->did_queues[IPC_DID_QUEUE_TYPE_DEFAULT]), did_head, did_tail);
+ break;
+ default :
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+
+ return;
+}
+
+void ipc_did_internal_queue_dequeue(upcm_did **pp_did_head,
+ upcm_did **pp_did_tail,
+ kal_uint32 **pp_si_idx,
+ kal_uint8 pdn_id,
+ ipc_did_queue_type_e queue_type)
+{
+ kal_uint32 queue_idx = pdn_id;
+ ipc_dl_queue_t *p_dl_queue = &(ipc_dl_queues_s[queue_idx]);
+
+ if ((IPC_DID_QUEUE_TYPE_DEFAULT <= queue_type) && (IPC_DID_QUEUE_TYPE_MAX > queue_type)) {
+ *pp_did_head = p_dl_queue->did_queues[queue_type].did_head;
+ *pp_did_tail = p_dl_queue->did_queues[queue_type].did_tail;
+ *pp_si_idx = &(p_dl_queue->did_queues[queue_type].si_index);
+ }
+
+ return;
+}
+
+void ipc_on_did_downlink(kal_uint32 pdn_id, ipc_did_queue_type_e queue_type, upcm_did *did_head, upcm_did *did_tail)
+{
+ ipc_session_t *session;
+ ipc_netif_t *netif;
+ kal_uint8 session_type;
+
+ HIF_SWLA_START("ID1");
+
+ IPC_ASSERT(did_head && did_tail);
+
+ session = ipc_find_session_by_context(pdn_id);
+ if (session && (IPC_SESSION_STATE_LINKUP == session->state)) {
+ netif = session->netif;
+ session_type = session->type;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /* Send DL traffic */
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif)
+ {
+ /* Send DL traffic after DL filtering */
+ ipc_on_process_dl_did_list(session_type, netif, pdn_id, queue_type, did_head, did_tail);
+
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ goto done;
+ } else
+ {
+ kal_uint8 ip_id = 0xff;
+
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session)
+ {
+ ip_id = (kal_uint8)session->ip_id;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+ hif_trace_error(IPC_TR_DL_DID_DROP_FOR_NETIF_INFO_LOCK_FAIL, pdn_id, ip_id, session_type, did_head, did_tail);
+ goto drop;
+ }
+ } else {
+ if(session){
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+ hif_trace_error(IPC_TR_DL_DID_DROP_FOR_INVALID_SESSION, pdn_id, did_head, did_tail);
+ goto drop;
+ }
+
+drop:
+ ipc_filter_did_drop_pkt_handler(pdn_id, did_head, did_tail);
+ IPC_FREE_DID_W_DATABUF(did_head, did_tail, IPC_SI_HIF_TYPE_MAX);
+done:
+ HIF_SWLA_STOP("ID1");
+ return;
+}
+
+void ipc_data_qbm_downlink_dequeue(void)
+{
+ qbm_gpd *head = NULL, *tail = NULL, *prev_head = NULL, *nxt_head = NULL;
+ ipc_pkt_t pkt = {0};
+ ipc_dlq_ior_t *ior = NULL;
+ kal_uint32 netif_id = IPC_INVALID_NETIF_ID, session_type = IPC_IP_TYPE_INVALID;
+ ipc_netif_t *netif = NULL;
+ ipc_session_t *session = NULL;
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ head = ipc_dl_qbm_head_s;
+ tail = ipc_dl_qbm_tail_s;
+ ipc_dl_qbm_head_s = NULL;
+ ipc_dl_qbm_tail_s = NULL;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ pkt.buf_type = IPC_PKT_DES_TYPE_GPD;
+ pkt.head = head;
+ prev_head = head;
+ if (head == NULL) {
+ return;
+ }
+ QBM_DES_SET_NEXT(tail, NULL);
+ while (head != NULL) {
+ pkt.tail = prev_head;
+ nxt_head = QBM_DES_GET_NEXT(head);
+ ior = (ipc_dlq_ior_t *)QBM_DES_GET_SW_CTRL_FIELD(head);
+
+ if (netif_id != ior->netif_id || session_type != ior->session_type) {
+ kal_bool update_head = (head == pkt.head);
+
+ netif = ipc_find_netif(ior->netif_id);
+ if (netif == NULL) {
+ /* Drop packet & don't update state */
+ qbm_free_one(head);
+ if (!update_head) {
+ QBM_DES_SET_NEXT(prev_head, nxt_head);
+ }
+ head = nxt_head;
+ if (update_head) {
+ pkt.head = head;
+ prev_head = head;
+ }
+ continue;
+ }
+ session = ipc_find_session_by_netif(netif, ior->session_type);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ if (session == NULL || IPC_SESSION_STATE_LINKUP != session->state) {
+ if(session) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+ /* Drop packet */
+ qbm_free_one(head);
+ if (!update_head) {
+ QBM_DES_SET_NEXT(prev_head, nxt_head);
+ }
+ head = nxt_head;
+ if (update_head) {
+ pkt.head = head;
+ prev_head = head;
+ }
+ continue;
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ if (netif_id != IPC_INVALID_NETIF_ID) {
+ if (ipc_send_dl_pkt_in_did(&pkt, NULL, netif_id) != KAL_TRUE) {
+ hif_trace_error(IPC_TR_DL_PKT_NETIF_DID_ALLOC_DID_NG, pkt.head, pkt.tail, netif_id);
+ }
+ pkt.head = head;
+ }
+ netif_id = ior->netif_id;
+ session_type = ior->session_type;
+ }
+ prev_head = head;
+ head = nxt_head;
+ }
+ if (pkt.head != NULL) {
+ pkt.tail = prev_head;
+ ipc_send_dl_pkt_in_did(&pkt, NULL, netif_id);
+ }
+
+}
+
+void ipc_on_downlink_qbm_enqueue(qbm_gpd *head, qbm_gpd *tail)
+{
+ kal_bool to_send_msg;
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ if (ipc_dl_qbm_head_s == NULL) {
+ ipc_dl_qbm_head_s = head;
+ ipc_dl_qbm_tail_s = tail;
+ } else {
+ QBM_DES_SET_NEXT(ipc_dl_qbm_tail_s, head);
+ ipc_dl_qbm_tail_s = tail;
+ }
+ QBM_DES_SET_NEXT(ipc_dl_qbm_tail_s, NULL);
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ to_send_msg = ipc_data_check_and_set_dl_ilm_flag();
+
+ if (to_send_msg) {
+ msg_send6( kal_get_active_module_id(), /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+}
+
+void ipc_on_did_downlink_multiple_ps(kal_uint32 pdn_id, upcm_did *did_head, upcm_did *did_tail, kal_uint8 proto_idx)
+{
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, proto_idx);
+ ipc_did_downlink_enqueue(pdn_id, did_head, did_tail);
+}
+
+void ipc_on_did_downlink_test_mode(kal_uint32 pdn_id, upcm_did *did_head, upcm_did *did_tail, kal_uint8 proto_idx)
+{
+ upcm_did *did;
+ upcm_did *next_did;
+ kal_bool end_of_list;
+ kal_bool to_send_msg;
+
+ IPC_ASSERT(did_head && did_tail);
+
+ hif_data_trace(MD_TRC_IPC_DL_ON_DID_DOWNLINK_TEST_LOOPBACK, pdn_id, did_head, did_tail, ipc_test_loopback_mode_s);
+
+ end_of_list = KAL_FALSE;
+ for (did = did_head; did && !end_of_list; did = next_did) {
+ next_did = UPCM_DID_GET_NEXT(did);
+ end_of_list = (did == did_tail);
+
+ if (IPC_TEST_LOOPBACK_MODE_A == ipc_test_loopback_mode_s) {
+ UPCM_DID_SET_SW_CTRL_FIELD(did, ipc_test_loopback_a_netif_id_s);
+ } else {
+ UPCM_DID_SET_FLOW(did, pdn_id);
+ UPCM_DID_SET_SW_CTRL_FIELD(did, ipc_test_loopback_b_netif_id_s);
+ }
+ }
+
+ /* Enqueue DID to DID queue, We have to protect IPC_DL_NON_PDN_QUEUE_IDX queue, it may enq by other context */
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ ipc_did_enqueue_wo_filter_queue(did_head, did_tail, IPC_DL_NON_PDN_QUEUE_IDX, IPC_DATA_DID_TAIL);
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ /* Send ILM to IPCore for processing DL queue */
+ to_send_msg = ipc_data_check_and_set_dl_ilm_flag();
+
+ /*
+ * Switch to IPCORE context.
+ */
+ if (to_send_msg) {
+ msg_send6( kal_get_active_module_id(), /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+}
+
+void ipc_did_downlink_enqueue(kal_uint32 pdn_id, upcm_did *did_head, upcm_did *did_tail)
+{
+ ipc_dl_queue_t *dl_queue;
+ kal_bool to_send_msg;
+
+ /* For 95 log reduction, we disable the following log temporarily */
+ //hif_data_trace(MD_TRC_IPC_DL_ON_DID_DOWNLINK, pdn_id, did_head, did_tail);
+
+ dl_queue = &ipc_dl_queues_s[pdn_id];
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ ipc_push_did_list_to_did_queue_tail(&(dl_queue->did_queues[IPC_DID_QUEUE_TYPE_DEFAULT]), did_head, did_tail);
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ /* Send ILM to IPCore for processing DL queue */
+ to_send_msg = ipc_data_check_and_set_dl_ilm_flag();
+
+ if (to_send_msg) {
+ msg_send6( kal_get_active_module_id(), /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+}
+
+void ipc_did_downlink_dequeue()
+{
+ kal_uint32 pdn_id;
+ ipc_did_queue_type_e queue_type;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ ipc_dl_queue_t *dl_queue;
+
+ /* In test mode, there is a reqirement that UE shall loopback UL packet in time,
+ * so we will skip these process to enhance the latency.
+ * We expect that there is no packets in normal queue when test mode is enabled.
+ */
+ if(IPC_TEST_LOOPBACK_MODE_OFF == ipc_test_loopback_mode_s){
+ for (pdn_id = 0; pdn_id < IPC_MAX_SESSION_CNT; pdn_id++) {
+ for (queue_type = 0; queue_type < IPC_DID_QUEUE_TYPE_MAX; queue_type++) {
+ dl_queue = &(ipc_dl_queues_s[pdn_id]);
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ did_head = dl_queue->did_queues[queue_type].did_head;
+ did_tail = dl_queue->did_queues[queue_type].did_tail;
+ ipc_clear_did_queue(&(dl_queue->did_queues[queue_type]));
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ if (did_head) {
+ ipc_on_did_downlink(pdn_id, queue_type, did_head, did_tail);
+ }
+ }
+ }
+ }
+
+ /*
+ * Dequeue the "send_dl" did_queue.
+ * Note that only IPC_DID_QUEUE_TYPE_WO_FILTER queue should be used.
+ * We have to protect IPC_DL_NON_PDN_QUEUE_IDX queue, it may enq by other context
+ */
+ for (queue_type = IPC_DID_QUEUE_TYPE_WO_FILTER; queue_type <= IPC_DID_QUEUE_TYPE_USB_PATH; queue_type++) {
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ dl_queue = &(ipc_dl_queues_s[IPC_DL_NON_PDN_QUEUE_IDX]);
+ did_head = dl_queue->did_queues[queue_type].did_head;
+ did_tail = dl_queue->did_queues[queue_type].did_tail;
+ /* Clear Q before processing it */
+ ipc_clear_did_queue(&(dl_queue->did_queues[queue_type]));
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ if (did_head) {
+ ipc_pkt_t pkt;
+ upcm_did *did;
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ end_of_list = KAL_FALSE;
+ for (did = did_head; did && !end_of_list; did = next_did) {
+ next_did = UPCM_DID_GET_NEXT(did);
+ end_of_list = (did == did_tail);
+
+ if ( (end_of_list) ||
+ (UPCM_DID_GET_SW_CTRL_FIELD(did_head) != UPCM_DID_GET_SW_CTRL_FIELD(next_did)) ) {
+ pkt.buf_type = IPC_PKT_DES_TYPE_DID;
+ pkt.did_head = did_head;
+ pkt.did_tail = did;
+
+ ipc_send_dl_pkt_in_did_internal(&pkt, NULL, UPCM_DID_GET_SW_CTRL_FIELD(did_head));
+
+ did_head = next_did;
+ }
+ }
+ }
+ }
+}
+
+void ipc_data_drop_ul_meta_by_pdn(kal_uint8 pdn_id)
+{
+ kal_uint32 pkt_count = 0;
+ kal_uint32 start_idx = 0;
+ kal_uint32 read_idx = 0;
+ kal_uint32 end_idx = 0;
+ ipc_ul_queue_t *q;
+ lhif_meta_tbl_t *meta_tbl;
+ lhif_meta_tbl_t *meta;
+ kal_uint16 tbl_size = 0;
+ LHIF_QUEUE_TYPE meta_queue_type;
+ kal_uint8 pdn_id_from_meta;
+ kal_uint8 i;
+ kal_bool is_queue_active = KAL_FALSE;
+
+
+ for (i = 0; i < IPC_UL_QUEUE_NUM; i++) {
+
+ q = &ipc_ul_queues_s[i];
+
+ /* Skip IOR queue */
+ if(q->queue_type == IPC_UL_QUEUE_TYPE_IOR){
+ continue;
+ }
+
+ /* Get queue's info snapshot */
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ pkt_count = q->cnt;
+ start_idx = q->meta_head;
+ end_idx = q->meta_tail;
+ meta_queue_type = q->meta_queue_type;
+ is_queue_active = ipc_is_ul_queue_allowed_to_send(q);
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ /* We only search the queue which is inactive */
+ if(!is_queue_active && pkt_count){
+ IPC_QUERY_META_TABLE((kal_uint32 **)&meta_tbl, &tbl_size, meta_queue_type);
+ read_idx = start_idx;
+ do{
+ meta = &meta_tbl[read_idx];
+ pdn_id_from_meta = IPC_MASK_PROTOID_ON_PDNID(meta->pdn, meta->protocol_idx);
+
+ if(pdn_id == pdn_id_from_meta){
+ /*
+ * Set net_type to IGNORE if the corresponding PDN is unbinding
+ * The buffer will be released when IPCore process the UL meta
+ */
+ meta->net_type = LHIF_NET_TYPE_IGNORE;
+ hif_trace_info(IPC_TR_UNBIND_DROP_UL_META, pdn_id, read_idx, pdn_id_from_meta);
+ }
+
+ read_idx++;
+ if(read_idx == tbl_size){
+ read_idx = 0;
+ }
+ }while(read_idx != end_idx);
+ }
+ }
+ return;
+}
+
+void ipc_data_clear_dl_ilm_flag()
+{
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ ipc_dl_processing_s = KAL_FALSE;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+}
+
+void ipc_data_set_dl_ilm_flag()
+{
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ ipc_dl_processing_s = KAL_TRUE;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+}
+
+kal_bool ipc_data_check_and_set_dl_ilm_flag()
+{
+ kal_bool to_send_msg = KAL_FALSE;
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ to_send_msg = (!ipc_dl_processing_s);
+ ipc_dl_processing_s = KAL_TRUE;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ return to_send_msg;
+}
+
+#if defined(__MD97__)
+kal_bool ipc_data_set_rq_info(ipc_rq_info_t *p_rq_info, kal_uint32 pdn_id, ipc_pkt_des_t *p_pkt_info, ipc_data_src_qfi_e src_qfi)
+{
+ upcm_did_si *p_sit = NULL;
+
+ if (NULL == p_rq_info || NULL == p_pkt_info) {
+ hif_trace_error(IPC_TR_INVALID_RQ_INFO_PKT_DES);
+ return KAL_FALSE;
+ }
+
+ if (KAL_FALSE == p_pkt_info->is_packet_info) {
+ hif_trace_error(IPC_TR_NO_PKT_INFO, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ p_rq_info->psi = UPCM_FIVEG_PDN_ID_TO_PSI(pdn_id);
+
+ if (p_pkt_info->packet_info->info_valid_fields & IPC_FILTER_BY_PROTOCOL) {
+ p_rq_info->protocol = p_pkt_info->packet_info->protocol;
+
+ if ((IPC_HDR_PROT_ESP == p_rq_info->protocol) &&
+ (p_pkt_info->packet_info->info_valid_fields & IPC_FILTER_BY_SPI)) {
+ p_rq_info->spi = p_pkt_info->packet_info->spi;
+ }
+ } else {
+ hif_trace_info(IPC_TR_SET_RQ_INFO_FAILED_PROTOCOL);
+ return KAL_FALSE;
+ }
+
+ if ((p_pkt_info->packet_info->info_valid_fields & IPC_FILTER_BY_SRC_IPV4) &&
+ (p_pkt_info->packet_info->info_valid_fields & IPC_FILTER_BY_DST_IPV4)) {
+
+ kal_mem_cpy(&p_rq_info->dst_ipv4.addr32, &p_pkt_info->packet_info->dst_addr[0], sizeof(kal_uint32));
+ kal_mem_cpy(&p_rq_info->src_ipv4.addr32, &p_pkt_info->packet_info->src_addr[0], sizeof(kal_uint32));
+ p_rq_info->valid_field = IPC_RQ_INFO_3_TUPLE;
+ p_rq_info->is_ipv4 = KAL_TRUE;
+
+ } else if((p_pkt_info->packet_info->info_valid_fields & IPC_FILTER_BY_SRC_IPV6) &&
+ (p_pkt_info->packet_info->info_valid_fields & IPC_FILTER_BY_DST_IPV6)){
+
+ kal_mem_cpy(&p_rq_info->dst_ipv6.addr32[0], &p_pkt_info->packet_info->dst_addr[0], 4*sizeof(kal_uint32));
+ kal_mem_cpy(&p_rq_info->src_ipv6.addr32[0], &p_pkt_info->packet_info->src_addr[0], 4*sizeof(kal_uint32));
+ p_rq_info->valid_field = IPC_RQ_INFO_3_TUPLE;
+ p_rq_info->is_ipv4 = KAL_FALSE;
+
+ } else {
+ hif_trace_info(IPC_TR_SET_RQ_INFO_FAILED_IP);
+ return KAL_FALSE;
+ }
+
+ switch (src_qfi) {
+ case IPC_DATA_QFI_SRC_IPF_META :
+ p_rq_info->qfi = IPC_DATA_GET_QFI(((ipf_dl_meta *)p_pkt_info->ipf_meta)->tcp_flag);
+ break;
+ case IPC_DATA_QFI_SRC_DL_DID :
+ p_sit = UPCM_DID_GET_SIT_PTR(p_pkt_info->did);
+ p_rq_info->qfi = p_sit->qfi;
+ break;
+ default :
+ hif_trace_info(IPC_TR_SET_RQ_INFO_FAILED_QFI);
+ return KAL_FALSE;
+ }
+
+ if ((p_pkt_info->packet_info->info_valid_fields & IPC_FILTER_BY_SRC_PORT) &&
+ (p_pkt_info->packet_info->info_valid_fields & IPC_FILTER_BY_DST_PORT)) {
+
+ p_rq_info->dst_port = p_pkt_info->packet_info->dst_port;
+ p_rq_info->src_port = p_pkt_info->packet_info->src_port;
+ p_rq_info->valid_field = IPC_RQ_INFO_5_TUPLE;
+ }
+
+ return KAL_TRUE;
+}
+
+void ipc_data_saved_rq_info_list(ipc_data_rq_info_list *p_rq_list, ipc_rq_info_t *p_rq_info)
+{
+ kal_uint32 i = 0;
+ kal_bool is_matched = KAL_FALSE;
+
+ if (NULL == p_rq_list || NULL == p_rq_info) {
+ hif_trace_error(IPC_TR_INVALID_RQ_LIST_INFO);
+ return;
+ }
+
+ for (i = 0; i < p_rq_list->cnt; i++) {
+ if ((p_rq_list->rq_info_list[i].protocol == p_rq_info->protocol) &&
+ (p_rq_list->rq_info_list[i].is_ipv4 == p_rq_info->is_ipv4) &&
+ (p_rq_list->rq_info_list[i].valid_field == p_rq_info->valid_field) &&
+ (p_rq_list->rq_info_list[i].qfi == p_rq_info->qfi)) {
+
+ if (IPC_RQ_INFO_5_TUPLE == p_rq_info->valid_field) {
+ if (p_rq_info->is_ipv4) {
+ if ((0 == kal_mem_cmp(&p_rq_list->rq_info_list[i].dst_ipv4.addr32, &p_rq_info->dst_ipv4.addr32, 4)) &&
+ (0 == kal_mem_cmp(&p_rq_list->rq_info_list[i].src_ipv4.addr32, &p_rq_info->src_ipv4.addr32, 4)) &&
+ (p_rq_list->rq_info_list[i].dst_port == p_rq_info->dst_port) &&
+ (p_rq_list->rq_info_list[i].src_port == p_rq_info->src_port)) {
+ is_matched = KAL_TRUE;
+ }
+ } else {
+ if ((0 == kal_mem_cmp(p_rq_list->rq_info_list[i].dst_ipv6.addr32, p_rq_info->dst_ipv6.addr32, 16)) &&
+ (0 == kal_mem_cmp(p_rq_list->rq_info_list[i].src_ipv6.addr32, p_rq_info->src_ipv6.addr32, 16)) &&
+ (p_rq_list->rq_info_list[i].dst_port == p_rq_info->dst_port) &&
+ (p_rq_list->rq_info_list[i].src_port == p_rq_info->src_port)) {
+ is_matched = KAL_TRUE;
+ }
+ }
+ } else {
+ if (p_rq_info->is_ipv4) {
+ if ((0 == kal_mem_cmp(&p_rq_list->rq_info_list[i].dst_ipv4.addr32, &p_rq_info->dst_ipv4.addr32, 4)) &&
+ (0 == kal_mem_cmp(&p_rq_list->rq_info_list[i].src_ipv4.addr32, &p_rq_info->src_ipv4.addr32, 4))) {
+ is_matched = KAL_TRUE;
+ }
+ } else {
+ if ((0 == kal_mem_cmp(p_rq_list->rq_info_list[i].dst_ipv6.addr32, p_rq_info->dst_ipv6.addr32, 16)) &&
+ (0 == kal_mem_cmp(p_rq_list->rq_info_list[i].src_ipv6.addr32, p_rq_info->src_ipv6.addr32, 16))) {
+ is_matched = KAL_TRUE;
+ }
+ }
+
+ if (IPC_HDR_PROT_ESP == p_rq_info->protocol) {
+ if (p_rq_list->rq_info_list[i].spi == p_rq_info->spi) {
+ is_matched = KAL_TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ if (!is_matched || 0 == p_rq_list->cnt) {
+ kal_mem_cpy(&p_rq_list->rq_info_list[p_rq_list->cnt], p_rq_info, sizeof(ipc_rq_info_t));
+ p_rq_list->cnt++;
+ }
+
+ return;
+}
+
+void ipc_data_dl_enq_by_netif(kal_uint32 netif_id, upcm_did *p_did_head, upcm_did *p_did_tail)
+{
+ ipc_dl_queue_t *p_dl_queue = NULL;
+ kal_bool is_send_msg = KAL_FALSE;
+ kal_bool end_of_list = KAL_FALSE;
+ upcm_did *p_current_did = NULL;
+ upcm_did *p_next_did = NULL;
+
+ ASSERT((NULL != p_did_head) && (NULL != p_did_head));
+ hif_data_trace(MD_TRC_IPC_DL_ENQ_BY_NETIF, p_did_head, p_did_tail, netif_id);
+
+ /* Save netif_id in SW_CTRL_FIELD */
+ for (p_current_did = p_did_head; p_current_did && !end_of_list; p_current_did = p_next_did) {
+ p_next_did = UPCM_DID_GET_NEXT(p_current_did);
+ end_of_list = (p_current_did == p_did_tail);
+ UPCM_DID_SET_SW_CTRL_FIELD(p_current_did, (kal_uint16)(netif_id & 0x0000FFFF));
+ }
+
+ /* enqueue DL without filter queue */
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ p_dl_queue = &ipc_dl_queues_s[IPC_DL_NON_PDN_QUEUE_IDX];
+ ipc_push_did_list_to_did_queue_tail(&(p_dl_queue->did_queues[IPC_DID_QUEUE_TYPE_WO_FILTER]), p_did_head, p_did_tail);
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ /* Send ILM to IPCore for processing DL queue */
+ is_send_msg = ipc_data_check_and_set_dl_ilm_flag();
+
+ /* Send ILM to IPCore for processing DL queue */
+ if (is_send_msg) {
+ msg_send6(kal_get_active_module_id(), /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+
+ return;
+}
+
+kal_bool ipc_data_send_rq_info(ipc_data_rq_info_list *p_rq_list)
+{
+ if (NULL == p_rq_list) {
+ hif_trace_error(IPC_TR_INVALID_RQ_LIST, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ if (p_rq_list->cnt) {
+ peer_buff_struct *p_peer = construct_peer_buff(p_rq_list->cnt*sizeof(ipc_rq_info_t) + 4, 0, 0,TD_RESET);
+ ipc_rq_info_t *p_rq_info = NULL;
+ kal_uint32 i = 0;
+ kal_uint16 peer_buf_len = 0;
+
+ if (NULL == p_peer) {
+ hif_trace_error(IPC_TR_ALLOC_PEER_BUF_FAILED, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ p_rq_info = (ipc_rq_info_t *)get_peer_buff_pdu(p_peer, &peer_buf_len);
+ for (i = 0; i < p_rq_list->cnt; i++) {
+ kal_mem_cpy(p_rq_info, &p_rq_list->rq_info_list[i], sizeof(ipc_rq_info_t));
+ p_rq_info++;
+ }
+
+ msg_send6(IPCORE_SRC_MOD, NAS_DST_MOD, IPCORE_SAP, MSG_ID_IPCORE_NAS_RQ_INFO_IND, NULL, (peer_buff_struct *)p_peer);
+ }
+
+ return KAL_TRUE;
+}
+#endif
+
+void ipc_data_ipv6_ra_pool_push(kal_uint32 pdn_id, qbm_gpd* gpd)
+{
+ qbm_gpd* old_gpd = NULL;
+
+ IPC_ASSERT(pdn_id < IPC_PROXY_IPV6_RA_POOL_SIZE);
+
+ old_gpd = ipc_proxy_ipv6_ra_pool[pdn_id];
+
+ if(old_gpd) {
+ qbmt_dest_q(old_gpd, old_gpd);
+ }
+
+ ipc_proxy_ipv6_ra_pool[pdn_id] = gpd;
+}
+
+qbm_gpd* ipc_data_ipv6_ra_pool_pop(kal_uint32 pdn_id)
+{
+ qbm_gpd* gpd = NULL;
+
+ IPC_ASSERT(pdn_id < IPC_PROXY_IPV6_RA_POOL_SIZE);
+
+ gpd = ipc_proxy_ipv6_ra_pool[pdn_id];
+ ipc_proxy_ipv6_ra_pool[pdn_id] = NULL;
+
+ return gpd;
+}
+
+kal_bool ipc_set_data_usage_by_pdn_sim_id(ipc_data_path_direction_e data_path_direct,
+ kal_uint32 pdn_sim_id,
+ ipc_data_usage_info_t* data_usage)
+{
+ if (pdn_sim_id != IPC_INVALID_PDN_ID) {
+ IPC_ASSERT(pdn_sim_id < IPC_MAX_SESSION_CNT);
+
+ if (DL_DIRECT != data_path_direct && UL_DIRECT != data_path_direct) {
+ hif_trace_error(IPC_TR_INVALID_DATA_PATH_DIR, __FUNCTION__, data_path_direct);
+ return KAL_FALSE;
+ }
+ if (DL_DIRECT == data_path_direct) {
+ ipc_data_usage_info_s[pdn_sim_id].downlink_bytes += data_usage->downlink_bytes;
+ ipc_data_usage_info_s[pdn_sim_id].downlink_packets += data_usage->downlink_packets;
+ } else {
+ ipc_data_usage_info_s[pdn_sim_id].uplink_bytes += data_usage->uplink_bytes;
+ ipc_data_usage_info_s[pdn_sim_id].uplink_packets += data_usage->uplink_packets;
+ }
+
+ return KAL_TRUE;
+ } else {
+ hif_trace_error(IPC_TR_INVALID_PDN_ID, __FUNCTION__);
+ return KAL_FALSE;
+ }
+}
+
+kal_bool ipc_set_data_usage_by_netif_id(ipc_data_path_direction_e data_path_direct,
+ kal_uint8 ip_type,
+ kal_uint32 netif_id,
+ ipc_data_usage_info_t *data_usage)
+{
+ kal_int32 pdn_sim_id;
+
+ if (KAL_FALSE == ipc_query_pdn_by_netif(netif_id, ip_type, &pdn_sim_id)) {
+ hif_trace_error(IPC_TR_GET_PDN_ID_FAILED, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ return ipc_set_data_usage_by_pdn_sim_id(data_path_direct, pdn_sim_id, data_usage);
+}
+
+ipc_data_usage_info_t* ipc_get_data_usage_by_pdn_sim_id(kal_uint32 pdn_sim_id)
+{
+ ipc_data_usage_info_t* data_usage = NULL;
+ if (pdn_sim_id != IPC_INVALID_PDN_ID) {
+ IPC_ASSERT(pdn_sim_id < IPC_MAX_SESSION_CNT);
+ data_usage = &ipc_data_usage_info_s[pdn_sim_id];
+ hif_trace_debug(IPC_TR_DATA_USAGE_INFO, __FUNCTION__, pdn_sim_id, data_usage->uplink_bytes, data_usage->downlink_bytes,
+ data_usage->uplink_packets, data_usage->downlink_packets);
+ return data_usage;
+ } else {
+ hif_trace_error(IPC_TR_INVALID_PDN_ID, __FUNCTION__);
+ return NULL;
+ }
+}
+
+void ipc_reset_data_usage_by_pdn_sim_id(kal_uint8 pdn_sim_id)
+{
+ hif_trace_debug(IPC_TR_DATA_USAGE_RESET, __FUNCTION__, pdn_sim_id);
+ memset(&ipc_data_usage_info_s[pdn_sim_id], 0, sizeof(ipc_data_usage_info_t));
+}
diff --git a/mcu/middleware/hif/ipcore/src/ipc_data_ipf.c b/mcu/middleware/hif/ipcore/src/ipc_data_ipf.c
new file mode 100644
index 0000000..cd98ed4
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_data_ipf.c
@@ -0,0 +1,1321 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2016
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_hpc.c
+ *
+ * Project:
+ * --------
+ * UMOLYA
+ *
+ * Description:
+ * ------------
+ * IP Core Uplink data path functions related with HPC.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "mw_sap.h"
+#include "hif_mw_msgid.h"
+#include "qmu_bm_util.h"
+#include "cache_sw.h"
+
+#include "ipc_defs.h"
+#include "ipc_debug.h"
+#include "ipc_utils.h"
+#include "ipc_data_ipf.h"
+#include "ipc_object.h"
+#include "ipc_filter.h"
+#include "ipc_dpfm.h"
+#include "dpcopro_custom.h"
+#include "hif_lhif.h"
+#include "sim_public_enum.h"
+#include "el2_public_api.h"
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Private data structure.
+ *----------------------------------------------------------------------------*/
+
+typedef struct ipc_unk_hdr_stats_t {
+ kal_bool is_valid;
+ kal_uint32 unk_hdr_cnt;
+ kal_uint16 begin_cntl;
+ kal_uint16 end_cntl;
+ kal_uint16 rb_idx;
+ kal_uint16 protocol_idx;
+} ipc_unk_hdr_stats_t;
+
+#define MAX_SIM_RBIDX_NUM 37
+#define MAX_RBIDX_NUM (MAX_SIM_RBIDX_NUM * MAX_SIM_NUM)
+
+/*------------------------------------------------------------------------------
+ * Private variables.
+ *----------------------------------------------------------------------------*/
+static ipc_hpc_info_tbl_t ipc_hpc_tbl[IPC_HPC_ENTRY_SIZE];
+static ipc_dl_meta_queue_t ipc_dl_meta_queues_s[IPC_DL_META_QUEUE_NUM];
+#if defined(__MD97__)
+ static ipc_data_rq_info_list g_rq_list = {0};
+#endif
+static kal_uint8 g_ipc_qbm_failed_gpd_cnt = 0;
+static ipc_unk_hdr_stats_t g_unk_hdr_stat[MAX_RBIDX_NUM] = {0};
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ *----------------------------------------------------------------------------*/
+static LHIF_NET_TYPE ipc_get_net_type_from_netif_id(kal_uint32 netif_id)
+{
+
+ IPC_ASSERT(IPC_INVALID_NETIF_ID != netif_id);
+
+ switch (netif_id & 0xFFFFFF00) {
+ case IPC_NETIF_ID_LHIF_BEGIN:
+ return LHIF_NET_TYPE_LHIF;
+ case IPC_NETIF_ID_ETH_BEGIN:
+ return LHIF_NET_TYPE_RNDIS;
+ case IPC_NETIF_ID_MCIF_BEGIN:
+ return LHIF_NET_TYPE_MCIF;
+ case IPC_NETIF_ID_VNIF_BEGIN:
+ return LHIF_NET_TYPE_VNIF;
+ case IPC_NETIF_ID_MBIM_BEGIN:
+ return LHIF_NET_TYPE_MBIM;
+ default:
+ /*can't reach here*/
+ IPC_ASSERT(KAL_FALSE);
+ return LHIF_NET_TYPE_IGNORE;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions.
+ *----------------------------------------------------------------------------*/
+
+void ipc_check_and_fill_session_info(kal_uint8 ip_type, kal_uint32 ipv4_pdn_id, kal_uint32 ipv6_pdn_id, kal_uint32 netif_id, lhif_meta_tbl_t *meta)
+{
+ kal_uint8 pdn_id_from_meta = IPC_MASK_PROTOID_ON_PDNID(meta->pdn, meta->protocol_idx) ;
+ kal_uint32 pdn_id = (IPC_IP_TYPE_IPV4 == ip_type) ? ipv4_pdn_id : ipv6_pdn_id;
+
+ if (IPC_INVALID_PDN_ID != pdn_id)
+ {
+ if((IPC_UL_META_INVALID_PDN_SIM_ID == pdn_id_from_meta) && !meta->ignore)
+ {
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(pdn_id, meta->protocol_idx);
+ IPC_UNMASK_PROTOID_FROM_PDNID(pdn_id);
+ meta->pdn = pdn_id;
+ }
+ else
+ {
+ /* IPF has filled the PDN_SIM_ID from pn match, just confirm if the value is same as IPcore. */
+ if(!meta->ignore && (pdn_id_from_meta != pdn_id))
+ {
+ hif_data_trace(MD_TRC_IPC_UL_META_PN_MISS_MATCH, netif_id, ip_type, pdn_id, pdn_id_from_meta);
+ /* restore IPCore PDN info to meta */
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(pdn_id, meta->protocol_idx);
+ IPC_UNMASK_PROTOID_FROM_PDNID(pdn_id);
+ meta->pdn = pdn_id;
+ /* Clear HPC mr because HW/SW may unsync */
+ meta->mr = IPC_HPC_MR_UNKNOWN;
+ }
+ }
+ }
+ else
+ {
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_SESSION_DEACT, netif_id, meta, ip_type);
+ meta->ignore = 1;
+ IPC_FREE_META_VRB(meta);
+ }
+}
+
+kal_uint16 ipc_on_process_ul_hpc_result(kal_uint8 *ip_type, kal_uint32 meta_idx, lhif_meta_tbl_t *meta, kal_uint32 netif_id, ipc_dpfm_mirror_des_t *dpfm_mirror_des)
+{
+ kal_uint16 result = 0;
+ ipc_pkt_des_t packet_des = {0};
+ ipc_filter_t *filter = NULL;
+ /*
+ * In order to reduce MCPS, we would not do initialization for these two variables.
+ * Make sure all elements are assigned correct value before using them.
+ */
+ ipc_filter_info_t filter_info;
+ ipc_packet_info_t packet_info;
+
+ *ip_type = (meta->ip)?IPC_IP_TYPE_IPV6 : IPC_IP_TYPE_IPV4;
+ switch(meta->mr)
+ {
+ case IPC_HPC_MR_NEW:
+ case IPC_HPC_MR_UNKNOWN:
+ case IPC_HPC_MR_DPFM_MATCH:
+ case IPC_HPC_MR_MATCH:
+ {
+ if(IPC_HPC_MR_UNKNOWN == meta->mr) {
+ /* If the packet is unknown, we need to get correct packet info from raw buffer */
+ *ip_type = ipc_get_ip_type_from_meta(meta);
+ }
+
+ if (IPC_IP_TYPE_INVALID != *ip_type){
+ /* Fill packet_des */
+ if (IPC_HPC_MR_UNKNOWN != meta->mr){
+ /* If MR == HPC_MR_NEW or IPC_HPC_MR_MATCH or IPC_HPC_MR_DPFM_MATCH, we store or get pacekt_info from HPC table */
+ packet_des.packet_info = &(ipc_hpc_tbl[meta->match_index].packet_info);
+ }else{
+ packet_des.packet_info = &packet_info;
+ }
+
+ if(IPC_HPC_MR_NEW == meta->mr || IPC_HPC_MR_UNKNOWN == meta->mr || ipc_hpc_tbl[meta->match_index].is_dirty){
+ /*
+ * Reset packet info for HPC_NEW/UNKNOWN cases.
+ * If dirty flag is set, we also need to re-parse packet info to prevent using out-of-date info.
+ */
+ kal_mem_set(packet_des.packet_info, 0, sizeof(ipc_packet_info_t));
+ packet_des.is_packet_info = KAL_FALSE;
+ if(KAL_TRUE == ipc_hpc_tbl[meta->match_index].is_dirty){
+ ipc_hpc_tbl[meta->match_index].is_dirty = KAL_FALSE;
+ }
+ }else{
+ packet_des.is_packet_info = KAL_TRUE;
+ if(IPC_HPC_MR_MATCH == meta->mr){
+ /* update latest TCP flags from meta */
+ if((packet_des.packet_info->info_valid_fields & IPC_FILTER_BY_PROTOCOL) &&
+ (packet_des.packet_info->protocol == IPC_HDR_PROT_TCP)){
+ packet_des.packet_info->tcp_flags = meta->tcp_flags;
+ }
+ }
+ }
+
+ packet_des.des_type = IPC_PKT_DES_TYPE_META;
+ packet_des.packet = meta->vrb_addr;
+ packet_des.packet_len = meta->length;
+ packet_des.meta = meta;
+ packet_des.matched_filter = &filter;
+ packet_des.filter_info = &filter_info;
+ packet_des.ip_type = *ip_type;
+
+ result = ipc_meta_do_filter(*ip_type, netif_id, meta, dpfm_mirror_des, &packet_des);
+ }
+ else
+ {
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_NONE_IP_PKT2, netif_id, meta_idx);
+ IPC_FREE_META_VRB(meta);
+ meta->ignore = 1;
+ }
+ break;
+ }
+ case IPC_HPC_MR_DPFM_MATCH_BUT_NO_NAT:
+ {
+ /* Assumption: there is no filter request for these data from LAN NETIF.
+ So just forward these data to AP (Host2AP) */
+ result = 1;
+ break;
+ }
+ case IPC_HPC_MR_DPFM_DEL_CMD_MATCH:
+ /* Set dirty flag to prevent using wrong packet info if rule is deleted and result is HPC_MR_MATCH with same match_index*/
+ ipc_hpc_tbl[meta->match_index].is_dirty = KAL_TRUE;
+ case IPC_HPC_MR_DPFM_DEL_CMD_MISS:
+ case IPC_HPC_MR_DPFM_ADD_CMD:
+ {
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ /* DPFM command, no data */
+ hif_data_trace(MD_TRC_IPC_UL_META_DPFM_CMD, meta->mr, meta_idx);
+
+ /* Note that UPCM need DPFM_ADD_CMD for HPC state sync */
+ /* So we don't need to set ignore bit. */
+ if(IPC_HPC_MR_DPFM_ADD_CMD != meta->mr)
+ {
+ meta->ignore = 1;
+ }
+
+ packet_des.des_type = IPC_PKT_DES_TYPE_META;
+ packet_des.packet = meta->vrb_addr;
+ packet_des.packet_len = meta->length;
+ packet_des.meta = meta;
+ packet_des.is_packet_info = KAL_FALSE;
+ IPC_DPFM_PROCESS_FILTER_CMD(&packet_des);
+
+ result = 0;
+ break;
+#endif
+ }
+ default:
+ /* should not reach here */
+ IPC_ASSERT(0);
+ break;
+ }
+ return result;
+}
+
+kal_bool ipc_on_process_dpfm_cmd_result(kal_uint32 meta_idx, lhif_meta_tbl_t *meta)
+{
+ kal_bool result = 0;
+
+ switch(meta->mr)
+ {
+ case IPC_HPC_MR_DPFM_DEL_CMD_MATCH:
+ /* Set dirty flag to prevent using wrong packet info if rule is deleted and result is HPC_MR_MATCH with same match_index*/
+ ipc_hpc_tbl[meta->match_index].is_dirty = KAL_TRUE;
+ case IPC_HPC_MR_DPFM_DEL_CMD_MISS:
+ case IPC_HPC_MR_DPFM_ADD_CMD:
+ {
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ ipc_pkt_des_t packet_des = {0};
+ /* DPFM command, no data */
+ hif_data_trace(MD_TRC_IPC_UL_META_DPFM_CMD, meta->mr, meta_idx);
+
+ /* Note that UPCM need DPFM_ADD_CMD for HPC state sync */
+ /* So we don't need to set ignore bit. */
+ if(IPC_HPC_MR_DPFM_ADD_CMD != meta->mr)
+ {
+ meta->ignore = 1;
+ }
+
+ packet_des.des_type = IPC_PKT_DES_TYPE_META;
+ packet_des.packet = meta->vrb_addr;
+ packet_des.packet_len = meta->length;
+ packet_des.meta = meta;
+ packet_des.is_packet_info = KAL_FALSE;
+ IPC_DPFM_PROCESS_FILTER_CMD(&packet_des);
+
+ result = 0;
+ break;
+#else
+ /* should not reach here */
+ IPC_ASSERT(KAL_FALSE);
+#endif
+ }
+ default:
+ result = 1;
+ break;
+ }
+ return result;
+}
+
+void ipc_hpc_init()
+{
+ kal_mem_set(ipc_hpc_tbl, 0, sizeof(ipc_hpc_info_tbl_t)*IPC_HPC_ENTRY_SIZE);
+}
+
+void ipc_push_meta_list_to_dl_meta_queue(kal_uint16 start_idx, kal_uint16 end_idx, ipfc_dl_filter_queue_type q_type)
+{
+ ipc_dl_meta_queue_t *q;
+
+ q = &ipc_dl_meta_queues_s[q_type];
+
+ IPC_W_LOCK_OBJECT(q, ipc_spinlock_g);
+ if (q) {
+ IPC_ASSERT(q->meta_queue_type == q_type);
+
+ /*
+ * Get meta_queue_size when the first downlink packet arrived.
+ */
+ if (IPC_QUEUE_META_INVALID_VALUE == q->meta_size) {
+ kal_uint32 *base_addr;
+ kal_uint16 tbl_size;
+
+ IPC_QUERY_IPF_META_TABLE((void**)&base_addr, &tbl_size, q_type);
+ q->meta_size = tbl_size;
+ q->pending_cnt = 0;
+ }
+
+ if (IPC_QUEUE_META_INVALID_VALUE == q->meta_tail) {
+ q->meta_head = start_idx;
+ q->meta_tail = end_idx;
+ } else {
+ IPC_ASSERT(start_idx == q->meta_tail);
+ q->meta_tail = end_idx;
+ }
+
+ q->cnt = (q->meta_tail >= q->meta_head)? (q->meta_tail - q->meta_head):(q->meta_size - q->meta_head + q->meta_tail);
+ IPC_W_UNLOCK_OBJECT(q, ipc_spinlock_g);
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ }
+}
+
+void ipc_meta_downlink(kal_uint16 start_idx, kal_uint16 end_idx, kal_uint32 queue_type)
+{
+ kal_bool to_send_msg;
+
+ HIF_SWLA_START("ID2");
+
+ hif_data_trace(MD_TRC_IPC_DL_META_DOWNLINK_CALLBACK, start_idx, end_idx, queue_type);
+
+ ipc_push_meta_list_to_dl_meta_queue(start_idx, end_idx, (ipfc_dl_filter_queue_type) queue_type);
+
+ to_send_msg = ipc_data_check_and_set_dl_ilm_flag();
+ /*
+ * Switch to IPCORE context.
+ */
+ if (to_send_msg) {
+ msg_send6( MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+
+ HIF_SWLA_STOP("ID2");
+}
+
+void ipc_meta_downlink_dequeue()
+{
+ kal_uint8 i;
+ ipc_dl_meta_queue_t tmp_queue;
+
+ for (i = 0; i < IPC_DL_META_QUEUE_NUM; i++)
+ {
+ ipc_dl_meta_queue_t *q = &ipc_dl_meta_queues_s[i];
+
+ /*
+ * Check whether the ul queue is allowed to sent or not.
+ * If yes, dequeue the queue.
+ */
+ IPC_W_LOCK_OBJECT(q, ipc_spinlock_g);
+ if (q)
+ {
+ if(0 == q->cnt || IPC_QUEUE_META_INVALID_VALUE == q->cnt)
+ {
+ IPC_W_UNLOCK_OBJECT(q, ipc_spinlock_g);
+ continue;
+ }
+ else
+ {
+ kal_mem_cpy(&tmp_queue, q, sizeof(ipc_dl_meta_queue_t));
+ q->ipc_clear_callback_t(q);
+ }
+
+ IPC_W_UNLOCK_OBJECT(q, ipc_spinlock_g);
+
+ /* Process the queue upto IPC_IPF_DL_META_THRESHOLD */
+ if (tmp_queue.cnt > IPC_IPF_DL_META_THRESHOLD)
+ {
+ hif_data_trace(MD_TRC_IPC_DL_META_PROC_INFO, tmp_queue.meta_head, tmp_queue.meta_tail, tmp_queue.cnt, tmp_queue.pending_cnt, tmp_queue.meta_size);
+ tmp_queue.pending_cnt = tmp_queue.cnt - IPC_IPF_DL_META_THRESHOLD;
+ tmp_queue.cnt = IPC_IPF_DL_META_THRESHOLD;
+ tmp_queue.meta_tail = tmp_queue.meta_head + IPC_IPF_DL_META_THRESHOLD;
+ if (tmp_queue.meta_tail >= tmp_queue.meta_size) {
+ tmp_queue.meta_tail = tmp_queue.meta_tail - tmp_queue.meta_size;
+ }
+ }
+
+ /* Process the queue by calling it's cbk */
+ tmp_queue.ipc_process_callback_t(&tmp_queue);
+
+ /* Process the pending counts of queue by calling it's cbk */
+ while (tmp_queue.pending_cnt) {
+ hif_data_trace(MD_TRC_IPC_DL_META_PROC_INFO, tmp_queue.meta_head, tmp_queue.meta_tail, tmp_queue.cnt, tmp_queue.pending_cnt, tmp_queue.meta_size);
+ if (tmp_queue.pending_cnt > IPC_IPF_DL_META_THRESHOLD) {
+ tmp_queue.cnt = IPC_IPF_DL_META_THRESHOLD;
+ tmp_queue.pending_cnt = tmp_queue.pending_cnt - IPC_IPF_DL_META_THRESHOLD;
+ } else {
+ tmp_queue.cnt = tmp_queue.pending_cnt;
+ tmp_queue.pending_cnt = 0;
+ }
+
+ tmp_queue.meta_head = tmp_queue.meta_tail;
+ tmp_queue.meta_tail = tmp_queue.meta_tail + tmp_queue.cnt;
+ if (tmp_queue.meta_tail >= tmp_queue.meta_size) {
+ tmp_queue.meta_tail = tmp_queue.meta_tail - tmp_queue.meta_size;
+ }
+
+ /* Process the queue by calling it's cbk */
+ tmp_queue.ipc_process_callback_t(&tmp_queue);
+ }
+ }
+ else
+ {
+ IPC_ASSERT(KAL_FALSE);
+ }
+ }
+ return;
+}
+
+void ipc_on_process_dl_meta(ipc_dl_meta_queue_t *q)
+{
+ kal_uint16 read_idx, end_idx, current_idx;
+ ipfc_dl_filter_queue_type q_type = q->meta_queue_type;
+ ipf_dl_meta *meta;
+ ipf_dl_meta *meta_base;
+ kal_uint16 tbl_size;
+ ipc_ipf_dl_match_result_e match_result;
+ kal_bool is_saved = KAL_FALSE;
+ kal_uint32 last_l2cache_invalidate_mask = 0;
+ kal_uint32 i = 0;
+ kal_bool is_matched = KAL_FALSE;
+ kal_uint16 insert_idx = 0;
+
+ /*For packet not matched case, IPCore will diret DL data to default HIF*/
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+#if defined(__MODEM_ONLY__) || defined(__L1_STANDALONE__)
+ ipc_si_hif_type_e default_dl_hif_type = IPC_SI_HIF_TYPE_USB;
+#else
+ ipc_si_hif_type_e default_dl_hif_type = IPC_SI_HIF_TYPE_LHIF;
+#endif
+#endif
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ ipc_dpfm_mirror_des_t dpfm_mirror_des[IPC_DPFM_MAX_DEVICE_NUM] = {0};
+ kal_bool is_mirror_did = KAL_FALSE;
+
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ dpfm_mirror_des[i].netif_id = IPC_INVALID_NETIF_ID;
+ }
+#else
+ ipc_dpfm_mirror_des_t *dpfm_mirror_des = NULL;
+ kal_bool is_mirror_did = KAL_FALSE;
+#endif
+
+ HIF_SWLA_START("ID4");
+
+ read_idx = q->meta_head;
+ end_idx = q->meta_tail;
+ current_idx = read_idx;
+
+ IPC_QUERY_IPF_META_TABLE((void**)&meta_base, &tbl_size, q_type);
+ hif_data_trace(MD_TRC_IPC_DL_META_ON_PROC, read_idx, end_idx, q_type);
+ kal_mem_set(&g_unk_hdr_stat, 0, sizeof(g_unk_hdr_stat));
+#if defined(__MD97__)
+ kal_mem_set(&g_rq_list, 0, sizeof(g_rq_list));
+ g_rq_list.cnt = 0;
+#endif
+
+ do
+ {
+ read_idx = current_idx;
+#if defined(__MD97__)
+ if (IPFC_META_QUEUE_DL_NR == q_type) {
+ read_idx = lhif_drv_data_get_real_meta_id(read_idx);
+ }
+#endif
+
+ meta = &meta_base[read_idx];
+ if(last_l2cache_invalidate_mask != L2CACHE_LINE_ALIGN_ADDR((kal_uint32)meta)){
+ QBM_CACHE_INVALID(meta, CPU_L2CACHE_LINE_SIZE);
+ last_l2cache_invalidate_mask = L2CACHE_LINE_ALIGN_ADDR((kal_uint32)meta);
+ }
+ match_result = meta->mr;
+ is_saved = KAL_FALSE;
+
+#if IPC_DBG_DL_PKT_DUMP_ENABLE
+ if((match_result != IPC_IPF_MR_NET_INVALID) && (match_result != IPC_IPF_MR_DIRECT_TO_AP) && (match_result != IPC_IPF_MR_PN_NO_MATCH))
+ {
+ ipc_utils_dump_data((void*)meta->addr,64);
+ }
+#endif
+
+ switch(match_result){
+ case IPC_IPF_MR_FILTER_MATCH:
+ case IPC_IPF_MR_UNKNOWN_HEADER:
+ case IPC_IPF_MR_DPFM_MATCH:
+ {
+ kal_int32 filter_id;
+ ipc_pkt_des_t packet_des;
+ kal_uint8 ip_type;
+ kal_uint8 pdn_sim_id = meta->pdn_sim_id;
+ kal_uint32 netif_id = ipc_get_netif_id_from_meta(meta->net_type, meta->channel_id);
+ ipc_session_t *session;
+ ipc_netif_t *netif;
+ kal_uint8 filter_idx;
+ ipc_packet_info_t packet_info = {0};
+ ipc_filter_info_t filter_info = {0};
+ ipc_filter_t *p_filter = NULL;
+ kal_uint8 proto_idx = 0;
+ kal_uint8 pdn_id = meta->pdn_sim_id;;
+
+ hif_data_trace(MD_TRC_IPC_DL_META_MATCH_RESULT, read_idx, match_result);
+
+ if(IPC_IPF_MR_UNKNOWN_HEADER != match_result)
+ {
+ ip_type = (meta->ip)?IPC_IP_TYPE_IPV6:IPC_IP_TYPE_IPV4;
+ }
+ else
+ {
+ ip_type = IPC_IP_TYPE_INVALID;
+ }
+
+ session = ipc_find_session_by_context(pdn_sim_id);
+ if (session) {
+ netif = session->netif;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /* Send DL traffic */
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif)
+ {
+ if(match_result == IPC_IPF_MR_FILTER_MATCH)
+ {
+ filter_idx = (ip_type == IPC_IP_TYPE_IPV4)?meta->filter_idx:(meta->filter_idx)-1;
+ filter_id = IPC_QUERY_FILTER_ID_BY_IDX(filter_idx);
+ if(IPC_SW_DL_FILTER_ID == filter_id){
+ filter_id = IPC_INVALID_FILTER_ID;
+ }
+ }
+ else
+ {
+ filter_id = IPC_INVALID_FILTER_ID;
+ }
+
+ /* Fill packet_des */
+ packet_des.des_type = IPC_PKT_DES_TYPE_META;
+ packet_des.packet = (kal_uint8*)meta->addr;
+ packet_des.packet_len = meta->len;
+ packet_des.ipf_meta = (void*) meta;
+ packet_des.matched_filter = &p_filter;
+ packet_des.filter_info = &filter_info;
+ packet_des.packet_info = &packet_info;
+ packet_des.ip_type = ip_type;
+ packet_des.is_packet_info = KAL_FALSE;
+
+ ipc_ipf_meta_do_filter(filter_id, &packet_des, ip_type, pdn_sim_id, netif_id, dpfm_mirror_des, &is_mirror_did, &is_saved);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ if ((IPC_IPF_MR_UNKNOWN_HEADER == match_result) &&
+ (IPC_IP_TYPE_INVALID == packet_des.ip_type)) {
+ IPC_DL_PKT_DUMP((void *)meta->addr, meta->len);
+
+ /* calculate statistics */
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(pdn_id, proto_idx);
+ is_matched = KAL_FALSE;
+ insert_idx = 0;
+ for (i = 0; i < MAX_RBIDX_NUM; i++) {
+ if (KAL_TRUE == g_unk_hdr_stat[i].is_valid) {
+ if ((meta->rbid == g_unk_hdr_stat[i].rb_idx) &&
+ (proto_idx == g_unk_hdr_stat[i].protocol_idx)) {
+ is_matched = KAL_TRUE;
+ insert_idx = i;
+ break;
+ }
+ insert_idx = i;
+ }
+ }
+
+ if (is_matched) {
+ g_unk_hdr_stat[insert_idx].end_cntl = meta->count;
+ g_unk_hdr_stat[insert_idx].unk_hdr_cnt++;
+ } else {
+ if (!((0 == insert_idx) && (KAL_FALSE == g_unk_hdr_stat[insert_idx].is_valid))) {
+ insert_idx++;
+ }
+
+ g_unk_hdr_stat[insert_idx].is_valid = KAL_TRUE;
+ g_unk_hdr_stat[insert_idx].unk_hdr_cnt++;
+ g_unk_hdr_stat[insert_idx].begin_cntl = meta->count;
+ g_unk_hdr_stat[insert_idx].end_cntl = meta->count;
+ g_unk_hdr_stat[insert_idx].protocol_idx = proto_idx;
+ g_unk_hdr_stat[insert_idx].rb_idx = meta->rbid;
+ }
+ }
+
+ goto _done;
+ }
+ else
+ {
+ kal_uint8 ip_id = 0xff;
+ kal_uint8 session_type = IPC_IP_TYPE_INVALID;
+
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session)
+ {
+ ip_id = (kal_uint8)session->ip_id;
+ session_type = session->type;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+ hif_trace_error(IPC_TR_DL_META_DROP_FOR_NETIF_INFO_LOCK_FAIL, pdn_sim_id, ip_id, session_type, read_idx);
+ goto _drop;
+ }
+ }
+ else
+ {
+
+ hif_trace_error(IPC_TR_DL_META_DROP_FOR_INVALID_SESSION, pdn_sim_id, read_idx);
+ goto _drop;
+ }
+
+_drop:
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+_done:
+#if defined(__MD97__)
+ if (is_saved) {
+ ipc_rq_info_t rq_info = {0};
+ kal_uint32 pdn_id = IPC_UNMASK_PROTOID_FROM_PDNID(pdn_sim_id);
+
+ if (packet_des.is_packet_info) {
+ if (ipc_data_set_rq_info(&rq_info, pdn_id, &packet_des, IPC_DATA_QFI_SRC_IPF_META)) {
+ ipc_data_saved_rq_info_list(&g_rq_list, &rq_info);
+ }
+ } else {
+ hif_trace_info(IPC_TR_NO_PKT_INFO, __FUNCTION__);
+ }
+ }
+#endif
+
+ break;
+ }
+ case IPC_IPF_MR_NET_INVALID:
+ {
+ /* check packet before drop */
+ ipc_ipf_drop_packet_handler((kal_uint8 *)meta->addr, meta->len, meta->pdn_sim_id);
+
+ /* do Drop */
+ hif_trace_error(IPC_TR_DL_META_DROP_FOR_INVALID_NETIF, read_idx, meta->pdn_sim_id, meta->net_type, meta->channel_id);
+
+ /* we only dump first 64 bytes to optimize user experience on ELT */
+ if (IPC_PKT_DUMP_LIMITED_LEN > meta->len) {
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+ } else {
+ IPC_FREE_DL_META_PRB(meta, IPC_PKT_DUMP_LIMITED_LEN);
+ }
+ break;
+ }
+ case IPC_IPF_MR_DIRECT_TO_AP:
+ case IPC_IPF_MR_PN_NO_MATCH:
+ {
+ // Do nothing, should not arrive here.
+ // No need to release data buffer.
+ if(IPC_IPF_MR_PN_NO_MATCH == match_result)
+ {
+ hif_trace_error(IPC_TR_DL_META_DROP_FOR_PN_NO_MATCH, read_idx, meta->rbid, meta->pdn_sim_id, meta->net_type, meta->channel_id);
+ }
+ break;
+ }
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ case IPC_IPF_MR_DPFM_MATCH_BUT_NO_NAT:
+ case IPC_IPF_MR_DPFM_OPEN_AND_DPFM_NOT_MATCH:
+ {
+ //Just forward to AP
+ ipc_meta_info_des pkt_info;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ upcm_did *did;
+ kal_uint32 *p_si_idx;
+
+ pkt_info.addr = (void*)(meta->addr);
+ pkt_info.len = meta->len;
+ pkt_info.psn_countL = meta->count;
+
+ //retrieve DID by PDN ID
+ ipc_did_internal_queue_dequeue(&did_head, &did_tail, &p_si_idx, meta->pdn_sim_id, IPC_DID_QUEUE_TYPE_DPFM);
+
+ if(!did_head)
+ {
+ //allocate DID
+ did = upcm_did_alloc_one();
+ if (!did) {
+ hif_trace_error(IPC_TR_DPFM_DL_ALLOC_DID_NG, meta->pdn_sim_id, meta->channel_id, meta->net_type, __LINE__);
+ //Drop packet here
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+ break;
+ }
+ did_head = did_tail = did;
+ ipc_dpfm_push_did_to_dpfm_queue(did, meta->pdn_sim_id);
+ *p_si_idx = 0;
+ UPCM_DID_SET_COUNT_L(did, meta->count);
+ UPCM_DID_SET_PKT_NUM(did, 0);
+ UPCM_DID_SET_SEG_NUM(did, 0);
+ }
+
+ if(!ipc_utils_fill_did_si_from_meta(KAL_TRUE, did_tail, p_si_idx, &pkt_info, default_dl_hif_type))
+ {
+ //count-L overflow, need a new DID, and try again.
+ did = upcm_did_alloc_one();
+ if (!did) {
+ hif_trace_error(IPC_TR_DPFM_DL_ALLOC_DID_NG, meta->pdn_sim_id, meta->channel_id, meta->net_type, __LINE__);
+ //Drop packet here
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+ break;
+ }
+
+ ipc_dpfm_push_did_to_dpfm_queue(did, meta->pdn_sim_id);
+ *p_si_idx = 0;
+ UPCM_DID_SET_COUNT_L(did, meta->count);
+ UPCM_DID_SET_PKT_NUM(did, 0);
+ UPCM_DID_SET_SEG_NUM(did, 0);
+
+ ipc_utils_fill_did_si_from_meta(KAL_TRUE, did, p_si_idx, &pkt_info, default_dl_hif_type);
+ }
+ }
+ break;
+#endif
+ default:
+ IPC_ASSERT(0);
+ break;
+ }
+
+ current_idx ++;
+ if (current_idx == tbl_size) {
+ current_idx = 0;
+ }
+ } while(current_idx != end_idx);
+
+ /* notification to L2 */
+ for (i = 0; i < MAX_RBIDX_NUM; i++) {
+ if (KAL_TRUE == g_unk_hdr_stat[i].is_valid) {
+ _IPC_NOTIFY_L2_STATS(g_unk_hdr_stat[i].unk_hdr_cnt,
+ g_unk_hdr_stat[i].begin_cntl,
+ g_unk_hdr_stat[i].end_cntl,
+ g_unk_hdr_stat[i].rb_idx,
+ g_unk_hdr_stat[i].protocol_idx);
+ hif_data_trace(MD_TRC_IPC_SEND_L2_UNK_INFO, q->meta_head,
+ q->meta_tail,
+ g_unk_hdr_stat[i].unk_hdr_cnt,
+ g_unk_hdr_stat[i].begin_cntl,
+ g_unk_hdr_stat[i].end_cntl,
+ g_unk_hdr_stat[i].rb_idx,
+ g_unk_hdr_stat[i].protocol_idx);
+ }
+ }
+
+ hif_data_trace(MD_TRC_IPC_DL_META_ON_PROC_DONE, q->meta_head, q->meta_tail, q->cnt, q_type);
+ IPC_FREE_IPF_META(q->cnt, q_type);
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ /* Check if there is DPFM DL data */
+ if (is_mirror_did) {
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ if (dpfm_mirror_des[i].mirror_did_head) {
+ ipc_pkt_t pkt;
+
+ IPC_ASSERT(dpfm_mirror_des[i].netif_id != IPC_INVALID_NETIF_ID);
+
+ pkt.buf_type = IPC_PKT_DES_TYPE_DID;
+ pkt.did_head = dpfm_mirror_des[i].mirror_did_head;
+ pkt.did_tail = dpfm_mirror_des[i].mirror_did_tail;
+
+ ipc_send_dl_pkt_in_did_internal(&pkt, NULL, dpfm_mirror_des[i].netif_id);
+ }
+ }
+ }
+#endif
+
+#if defined(__MD97__)
+ ipc_data_send_rq_info(&g_rq_list);
+#endif
+
+ HIF_SWLA_STOP("ID4");
+
+ /*
+ * We don't send DID to AP immediately,
+ * because IPcore will continue to process all DID queue after DL meta is processed
+ */
+
+ return;
+}
+
+/**
+ * Assumption: DL queue write lock is acquired.
+ * This function should be very light. MUST NOT do any heavy jobs.
+ */
+static void ipc_clear_dl_meta_queue(ipc_dl_meta_queue_t *q)
+{
+ q->cnt = 0;
+ q->pending_cnt = 0;
+ q->meta_head = IPC_QUEUE_META_INVALID_VALUE;
+ q->meta_tail = IPC_QUEUE_META_INVALID_VALUE;
+}
+
+void ipc_dl_meta_queue_init()
+{
+ kal_uint8 i;
+ ipc_dl_meta_queue_t *queue_p;
+
+ for( i = 0; i < IPFC_META_QUEUE_MAX; i++)
+ {
+ queue_p = &ipc_dl_meta_queues_s[i];
+ kal_mem_set(queue_p, 0, sizeof(ipc_dl_meta_queue_t));
+ if (!IPC_IS_VALID_OBJECT(queue_p))
+ {
+ IPC_INIT_OBJECT_BEGIN(queue_p, ipc_spinlock_g);
+ queue_p->meta_size = IPC_QUEUE_META_INVALID_VALUE;
+ queue_p->meta_head = IPC_QUEUE_META_INVALID_VALUE;
+ queue_p->meta_tail = IPC_QUEUE_META_INVALID_VALUE;
+ queue_p->cnt = IPC_QUEUE_META_INVALID_VALUE;
+ queue_p->pending_cnt = IPC_QUEUE_META_INVALID_VALUE;
+ queue_p->ipc_clear_callback_t = ipc_clear_dl_meta_queue;
+ queue_p->ipc_process_callback_t = ipc_on_process_dl_meta;
+ queue_p->meta_queue_type = i;
+ IPC_INIT_OBJECT_END(queue_p, ipc_spinlock_g);
+ }
+ }
+}
+
+void ipc_update_pn_match_setting(kal_uint8 pdn_sim_id, kal_uint32 network_interface_id, kal_uint32 ip_type, ipc_ipf_pn_match_cmd_e pnm_cmd )
+{
+ kal_uint8 ipv4 = 0;
+ kal_uint8 ipv6 = 0;
+ kal_uint8 net_type = 0;
+ kal_uint16 nc_id = 0;
+
+ IPC_ASSERT(pdn_sim_id != 0);
+
+ IPC_ASSERT((IPC_IP_TYPE_IPV4 == ip_type) || (IPC_IP_TYPE_IPV6 == ip_type) || (IPC_IP_TYPE_MIXED == ip_type));
+
+ ipv4 = (IPC_IP_TYPE_IPV4 == ip_type || IPC_IP_TYPE_MIXED == ip_type)? 1 : 0 ;
+ ipv6 = (IPC_IP_TYPE_IPV6 == ip_type || IPC_IP_TYPE_MIXED == ip_type)? 1 : 0 ;
+
+ switch(pnm_cmd)
+ {
+ case IPC_IPF_PN_MATCH_UNBIND:
+ /* Clear IPF PN match setting to default value */
+ nc_id = IPC_PN_NCID_DEFAULT;
+ break;
+ case IPC_IPF_PN_MATCH_BIND:
+ net_type = ipc_get_net_type_from_netif_id(network_interface_id);
+ nc_id = (net_type << 8) | ((0xFF) & network_interface_id);
+ break;
+ default:
+ hif_trace_error(IPC_TR_PN_MATCH_CMD_UNKNOWN, pnm_cmd);
+ IPC_ASSERT(0);
+ break;
+ }
+
+ hif_trace_info(IPC_TR_PN_MATCH_SETTING, pdn_sim_id, nc_id, ipv4, ipv6);
+
+ IPC_PN_MATCH_SETTING(pdn_sim_id, nc_id, ipv4, ipv6);
+}
+
+static void ipc_ipf_fill_tcpip_header_in_gpd(kal_uint8 ip_type, qbm_gpd *p_gpd, kal_uint8* p_tcp_hdr_in, kal_uint8* p_ip_hdr_in, kal_uint8 ref_index, kal_uint8 tcp_flag)
+{
+ void* p_bd = NULL;
+ kal_uint32 ip_header_len = 0;
+ kal_uint32 tcp_header_len = 0;
+ kal_uint32 total_len = 0;
+ kal_uint8 *tcp_header = NULL;
+ kal_uint8 *ip_header = NULL;
+ kal_uint8 *src_addr = NULL;
+ kal_uint8 *dst_addr = NULL;
+ kal_uint16 sum16;
+ kal_bool is_ipv4;
+ kal_uint16 ipid = 0;
+
+ ip_header_len = (ip_type == IPC_IP_TYPE_IPV4) ? IPC_HDR_V4_HEADER_SIZE : IPC_HDR_V6_HEADER_SIZE;
+ is_ipv4 = (ip_type == IPC_IP_TYPE_IPV4) ? KAL_TRUE : KAL_FALSE;
+ tcp_header_len = IPC_HDR_TCP_HEADER_SIZE;
+ total_len = ip_header_len + tcp_header_len;
+
+ IPC_ASSERT(p_gpd);
+
+ p_bd = QBM_DES_GET_DATAPTR(p_gpd);
+ ip_header = QBM_DES_GET_DATAPTR(p_bd);
+ tcp_header = ip_header + ip_header_len;
+
+ if (ip_type == IPC_IP_TYPE_IPV4) {
+ src_addr = IPC_HDR_V4_GET_DST_ADDR(p_ip_hdr_in);
+ dst_addr = IPC_HDR_V4_GET_SRC_ADDR(p_ip_hdr_in);
+ ipid = IPC_HDR_V4_GET_IDENTITY(p_ip_hdr_in);
+ } else if (ip_type == IPC_IP_TYPE_IPV6) {
+ src_addr = IPC_HDR_V6_GET_DST_ADDR(p_ip_hdr_in);
+ dst_addr = IPC_HDR_V6_GET_SRC_ADDR(p_ip_hdr_in);
+ } else {
+ /* unknown packet type */
+ DEBUG_ASSERT(0);
+ return;
+ }
+
+ /* Fill TCP header */
+ IPC_HDR_TCP_SET_SRC_PORT(tcp_header, IPC_HDR_TCP_GET_DST_PORT(p_tcp_hdr_in));
+ IPC_HDR_TCP_SET_DST_PORT(tcp_header, IPC_HDR_TCP_GET_SRC_PORT(p_tcp_hdr_in));
+ IPC_HDR_TCP_SET_SEQ_NUM(tcp_header, IPC_HDR_TCP_GET_ACK_NUM(p_tcp_hdr_in) + ref_index);
+ if(IPC_HDR_TCP_FLAG_RST == tcp_flag){
+ IPC_HDR_TCP_SET_ACK_NUM(tcp_header, 0);
+ /* set reserved1 flag for TCP RST UL packet*/
+ QBM_DES_SET_DRP_ALLW(p_gpd, IPC_DRP_ALLW_PKT);
+ }else{
+ IPC_HDR_TCP_SET_ACK_NUM(tcp_header, (IPC_HDR_TCP_GET_SEQ_NUM(p_tcp_hdr_in)+1));
+ }
+ IPC_HDR_TCP_SET_OFFSET(tcp_header, IPC_HDR_TCP_HEADER_SIZE);
+ IPC_HDR_TCP_SET_RESERVED(tcp_header, 0);
+ IPC_HDR_TCP_SET_FLAGS(tcp_header, tcp_flag);
+ IPC_HDR_TCP_SET_WINDOW(tcp_header, 0);
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, 0);
+ IPC_HDR_TCP_SET_URGENT_PTR(tcp_header, 0);
+ sum16 = ipc_calc_tcp_checksum(is_ipv4, src_addr, dst_addr, tcp_header, tcp_header_len);
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, sum16);
+
+ /* Fill IP header */
+ if (is_ipv4) {
+ IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN(ip_header);
+ IPC_HDR_V4_SET_TOTAL_LENGTH(ip_header, total_len);
+ IPC_HDR_V4_SET_IDENTITY(ip_header, (ipid+ref_index)); /* reference peer IPID */
+ IPC_HDR_V4_SET_FLAGS(ip_header, 0x2); /* Set Do Not Fragment */
+ IPC_HDR_V4_SET_FRAG_OFFSET(ip_header, 0);
+ IPC_HDR_V4_SET_TTL(ip_header, IPC_DEF_TTL);
+ IPC_HDR_V4_SET_PROTOCOL(ip_header, IPC_HDR_PROT_TCP);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, 0);
+ IPC_HDR_V4_SET_SRC_ADDR(ip_header, src_addr);
+ IPC_HDR_V4_SET_DST_ADDR(ip_header, dst_addr);
+ sum16 = ipc_calc_ipv4_checksum(ip_header);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, sum16);
+ } else {
+ IPC_HDR_V6_RESET_VER_TC_FL(ip_header);
+ IPC_HDR_V6_SET_TC(ip_header, IPC_HDR_V6_GET_TC(p_ip_hdr_in));
+ IPC_HDR_V6_SET_FLOW_LABEL(ip_header, IPC_HDR_V6_GET_FLOW_LABEL(p_ip_hdr_in));
+ IPC_HDR_V6_SET_LENGTH(ip_header, (total_len - ip_header_len));
+ IPC_HDR_V6_SET_NH_TYPE(ip_header, IPC_HDR_PROT_TCP);
+ IPC_HDR_V6_SET_HOP_LIMIT(ip_header, IPC_HDR_V6_GET_HOP_LIMIT(p_ip_hdr_in));
+ IPC_HDR_V6_SET_SRC_ADDR(ip_header, src_addr);
+ IPC_HDR_V6_SET_DST_ADDR(ip_header, dst_addr);
+ }
+
+ /* Flush GPD and BD */
+ QBM_CACHE_FLUSH(ip_header, total_len);
+ QBM_DES_SET_DATALEN(p_bd, total_len);
+ qbm_cal_set_checksum(p_bd);
+ QBM_DES_SET_DATALEN(p_gpd, total_len);
+ qbm_cal_set_checksum(p_gpd);
+
+ return;
+}
+
+static kal_bool ipc_ipf_fill_icmp_port_unreachable_in_gpd(kal_uint8 ip_type, qbm_gpd *p_gpd, kal_uint8* p_ip_hdr_in)
+{
+ kal_uint32 ip_header_len = 0;
+ kal_uint32 icmp_header_len = 0;
+ kal_uint32 total_len = 0;
+ kal_bool is_ipv4;
+ kal_uint16 input_ip_pkt_len = 0;
+
+ kal_uint8 *p_ip_header = NULL;
+ kal_uint8 *p_icmp_header = NULL;
+ kal_uint8 *p_data_ptr = NULL;
+ void* p_bd = NULL;
+
+ kal_uint16 sum16;
+ kal_uint16 ipid = 0;
+
+ kal_uint8 *p_src_addr = NULL;
+ kal_uint8 *p_dst_addr = NULL;
+
+
+ ip_header_len = (ip_type == IPC_IP_TYPE_IPV4) ? IPC_HDR_V4_HEADER_SIZE : IPC_HDR_V6_HEADER_SIZE;
+ is_ipv4 = (ip_type == IPC_IP_TYPE_IPV4) ? KAL_TRUE : KAL_FALSE;
+ icmp_header_len = IPC_HDR_ICMP_HEADER_SIZE;
+ if(is_ipv4 == KAL_TRUE) {
+ input_ip_pkt_len = IPC_HDR_V4_GET_TOTAL_LENGTH(p_ip_hdr_in);
+ } else {
+ input_ip_pkt_len = IPC_HDR_V6_GET_LENGTH(p_ip_hdr_in) + IPC_HDR_V6_HEADER_SIZE;
+ }
+ /*this is the length of response message*/
+ total_len = ip_header_len + icmp_header_len + input_ip_pkt_len;
+
+ IPC_ASSERT(p_gpd);
+
+ p_bd = QBM_DES_GET_DATAPTR(p_gpd);
+ p_ip_header = QBM_DES_GET_DATAPTR(p_bd);
+
+ /*out response = IPv4/v6 + ICMP header + data(return IP packet)*/
+
+ p_icmp_header = p_ip_header + ip_header_len;
+ p_data_ptr = p_icmp_header + icmp_header_len;
+
+ /*fill the return ip packet*/
+ /*there could be a need of length check to copy, MTU size exceed issue*/
+ if (total_len < (QBM_NET_UL_DATA_LEN - QBM_CACHE_SIZE)) {
+ kal_mem_cpy(p_data_ptr, p_ip_hdr_in, input_ip_pkt_len);
+ } else {
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_UDP_PREPARE_UL_GPD_NG, __FUNCTION__, total_len);
+ return KAL_FALSE;
+ }
+
+ if (ip_type == IPC_IP_TYPE_IPV4) {
+ p_src_addr = IPC_HDR_V4_GET_DST_ADDR(p_ip_hdr_in);
+ p_dst_addr = IPC_HDR_V4_GET_SRC_ADDR(p_ip_hdr_in);
+ ipid = IPC_HDR_V4_GET_IDENTITY(p_ip_hdr_in);
+ } else if (ip_type == IPC_IP_TYPE_IPV6) {
+ p_src_addr = IPC_HDR_V6_GET_DST_ADDR(p_ip_hdr_in);
+ p_dst_addr = IPC_HDR_V6_GET_SRC_ADDR(p_ip_hdr_in);
+ } else {
+ /* unknown packet type */
+ DEBUG_ASSERT(0);
+ return KAL_FALSE;
+ }
+
+ /*fill icmp header, type, code, checksum*/
+ if(is_ipv4) {
+ IPC_HDR_ICMP_SET_TYPE(p_icmp_header, 3);
+ IPC_HDR_ICMP_SET_CODE(p_icmp_header, 3);
+ IPC_HDR_ICMP_SET_CHECKSUM(p_icmp_header, 0);
+ IPC_HDR_ICMP_SET_UNUSED(p_icmp_header, 0);
+ sum16 = ipc_utils_calc_icmp_checksum(p_icmp_header, total_len-ip_header_len);
+ IPC_HDR_ICMP_SET_CHECKSUM(p_icmp_header, sum16);
+ } else {
+ IPC_HDR_ICMP_SET_TYPE(p_icmp_header, 1);
+ IPC_HDR_ICMP_SET_CODE(p_icmp_header, 4);
+ IPC_HDR_ICMP_SET_CHECKSUM(p_icmp_header, 0);
+ IPC_HDR_ICMP_SET_UNUSED(p_icmp_header, 0);
+ sum16 = ipc_utils_calc_icmp_checksum(p_icmp_header, total_len-ip_header_len);
+ IPC_HDR_ICMP_SET_CHECKSUM(p_icmp_header, sum16);
+ }
+
+ /* Fill IP header */
+ if (is_ipv4) {
+ IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN(p_ip_header);
+ //IPC_HDR_V4_SET_DSCP(ip_header, 192);
+ IPC_HDR_V4_SET_TOTAL_LENGTH(p_ip_header, total_len);
+ IPC_HDR_V4_SET_IDENTITY(p_ip_header, (ipid)); /* reference peer IPID */
+ IPC_HDR_V4_SET_FLAGS(p_ip_header, 0x2); /* Set Do Not Fragment */
+ IPC_HDR_V4_SET_FRAG_OFFSET(p_ip_header, 0);
+ IPC_HDR_V4_SET_TTL(p_ip_header, IPC_DEF_TTL);
+ IPC_HDR_V4_SET_PROTOCOL(p_ip_header, IPC_HDR_PROT_ICMP);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(p_ip_header, 0);
+ IPC_HDR_V4_SET_SRC_ADDR(p_ip_header, p_src_addr);
+ IPC_HDR_V4_SET_DST_ADDR(p_ip_header, p_dst_addr);
+ sum16 = ipc_calc_ipv4_checksum(p_ip_header);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(p_ip_header, sum16);
+ } else {
+ IPC_HDR_V6_RESET_VER_TC_FL(p_ip_header);
+ IPC_HDR_V6_SET_TC(p_ip_header, IPC_HDR_V6_GET_TC(p_ip_hdr_in));
+ IPC_HDR_V6_SET_FLOW_LABEL(p_ip_header, IPC_HDR_V6_GET_FLOW_LABEL(p_ip_hdr_in));
+ IPC_HDR_V6_SET_LENGTH(p_ip_header, (total_len - ip_header_len));
+ IPC_HDR_V6_SET_NH_TYPE(p_ip_header, IPC_HDR_PROT_ICMPV6);
+ IPC_HDR_V6_SET_HOP_LIMIT(p_ip_header, IPC_HDR_V6_GET_HOP_LIMIT(p_ip_hdr_in));
+ IPC_HDR_V6_SET_SRC_ADDR(p_ip_header, p_src_addr);
+ IPC_HDR_V6_SET_DST_ADDR(p_ip_header, p_dst_addr);
+ }
+
+ /* set reserved1 flag for UDP Response UL packet*/
+ QBM_DES_SET_DRP_ALLW(p_gpd, IPC_DRP_ALLW_PKT);
+
+ /* Flush GPD and BD */
+ QBM_CACHE_FLUSH(p_ip_header, total_len);
+ QBM_DES_SET_DATALEN(p_bd, total_len);
+ qbm_cal_set_checksum(p_bd);
+ QBM_DES_SET_DATALEN(p_gpd, total_len);
+ qbm_cal_set_checksum(p_gpd);
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_UDP_PREPARE_UL_GPD, __FUNCTION__);
+ return KAL_TRUE;
+}
+
+void ipc_ipf_dhlr_for_udp_rst(kal_uint8 *p_packet, kal_uint8 pdn_sim_id)
+{
+ kal_uint8 ip_type;
+ qbm_gpd *p_head = NULL;
+ qbm_gpd *p_tail = NULL;
+ ipc_pkt_t ipc_pkt = {0};
+ kal_bool result = KAL_TRUE;
+
+ if(NULL == p_packet){
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_INVALID_PARAM, __FUNCTION__, p_packet);
+ return;
+ }
+
+ /* Alias */
+ if (IPC_HDR_IS_V4(p_packet)) {
+ ip_type = IPC_IP_TYPE_IPV4;
+ } else if (IPC_HDR_IS_V6(p_packet)) {
+ ip_type = IPC_IP_TYPE_IPV6;
+ } else {
+ /* unknown packet type */
+ hif_trace_info(IPC_TR_DROP_HDLR_UNKNOWN_IPTYPE, __FUNCTION__);
+ return;
+ }
+
+ if(1 != qbmt_alloc_q(QBM_TYPE_NET_UL, 1, (void**)&p_head, (void**)&p_tail)){
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_GPD_ALLOC_NG, __FUNCTION__, __LINE__);
+ return;
+ }
+ if (KAL_FALSE == ipc_ipf_fill_icmp_port_unreachable_in_gpd(ip_type, p_head, p_packet)) {
+ qbmt_dest_q(p_head, p_tail);
+ p_head = p_tail = NULL;
+ return;
+ }
+
+ /* Send response */
+ if(p_head && p_tail){
+ ipc_pkt.isGPD = KAL_TRUE;
+ ipc_pkt.head = p_head;
+ ipc_pkt.tail = p_tail;
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_UDP_SEND_UL_GPD, __FUNCTION__, p_head, p_tail);
+ result = ipc_send_ul_pkt_by_pdn(&ipc_pkt, NULL, pdn_sim_id, ip_type);
+ if(KAL_FALSE == result){
+ qbmt_dest_q(p_head, p_tail);
+ }
+ }
+}
+
+void ipc_ipf_dhlr_for_tcp_rst(kal_uint8 *p_packet, ipc_packet_info_t packet_info, kal_uint8 pdn_sim_id)
+{
+ kal_uint8 *p_tcp_header = NULL;
+ kal_uint8 ip_type;
+ kal_uint8 gpd_num = 0;
+ qbm_gpd *p_head = NULL;
+ qbm_gpd *p_tail = NULL;
+ ipc_pkt_t ipc_pkt = {0};
+ kal_bool result = KAL_TRUE;
+
+ if(NULL == p_packet){
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_INVALID_PARAM, __FUNCTION__, p_packet);
+ return;
+ }
+
+ /* Alias */
+ if (IPC_HDR_IS_V4(p_packet)) {
+ ip_type = IPC_IP_TYPE_IPV4;
+ } else if (IPC_HDR_IS_V6(p_packet)) {
+ ip_type = IPC_IP_TYPE_IPV6;
+ } else {
+ /* unknown packet type */
+ hif_trace_info(IPC_TR_DROP_HDLR_UNKNOWN_IPTYPE, __FUNCTION__);
+ return;
+ }
+ p_tcp_header = p_packet + packet_info.l4_offset;
+
+ /* Determine Response:
+ * If received [ACK], response [RST]
+ * If received [FIN,ACK], response [ACK] + [FIN,ACK]
+ * If received [SYN], response [ACK] + [RST]
+ */
+ if (packet_info.tcp_flags & (IPC_HDR_TCP_FLAG_FIN | IPC_HDR_TCP_FLAG_SYN)) {
+ gpd_num = 2;
+ if (gpd_num != qbmt_alloc_q(QBM_TYPE_NET_UL, gpd_num, (void**) &p_head, (void**) &p_tail)) {
+ if (p_head && p_tail) {
+ g_ipc_qbm_failed_gpd_cnt++;
+ qbmt_dest_q(p_head, p_tail);
+ }
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_GPD_ALLOC_NG_CNT, __FUNCTION__, __LINE__, g_ipc_qbm_failed_gpd_cnt);
+ return;
+ }
+
+ /* 1st GPD : [ACK]*/
+ ipc_ipf_fill_tcpip_header_in_gpd(ip_type, p_head, p_tcp_header, p_packet, 0, IPC_HDR_TCP_FLAG_ACK);
+
+ /* 2nd GPD : [FIN,ACK] or [RST] */
+ if (packet_info.tcp_flags & IPC_HDR_TCP_FLAG_FIN) {
+ ipc_ipf_fill_tcpip_header_in_gpd(ip_type, p_tail, p_tcp_header, p_packet, 0, IPC_HDR_TCP_FLAG_ACK | IPC_HDR_TCP_FLAG_FIN);
+ } else {
+ ipc_ipf_fill_tcpip_header_in_gpd(ip_type, p_tail, p_tcp_header, p_packet, 0, IPC_HDR_TCP_FLAG_RST);
+ }
+ } else {
+ gpd_num = 1;
+ if (gpd_num != qbmt_alloc_q(QBM_TYPE_NET_UL, gpd_num, (void**) &p_head, (void**) &p_tail)) {
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_GPD_ALLOC_NG, __FUNCTION__, __LINE__);
+ return;
+ }
+ /* [RST] packet only */
+ ipc_ipf_fill_tcpip_header_in_gpd(ip_type, p_head, p_tcp_header, p_packet, 0, IPC_HDR_TCP_FLAG_RST);
+ }
+
+ /* Send response */
+ if (p_head && p_tail) {
+ kal_mem_set(&ipc_pkt, 0, sizeof(ipc_pkt));
+ ipc_pkt.isGPD = KAL_TRUE;
+ ipc_pkt.head = p_head;
+ ipc_pkt.tail = p_tail;
+ hif_trace_info(IPC_TR_DL_META_B4_DROP_SEND_UL_GPD, __FUNCTION__, p_head, p_tail);
+ result = ipc_send_ul_pkt_by_pdn(&ipc_pkt, NULL, pdn_sim_id, ip_type);
+ if (KAL_FALSE == result) {
+ qbmt_dest_q(p_head, p_tail);
+ }
+ }
+
+ return;
+}
+
+void ipc_ipf_drop_packet_handler(kal_uint8* p_packet, kal_uint32 len, kal_uint8 pdn_sim_id)
+{
+ kal_bool result = KAL_FALSE;
+ ipc_packet_info_t packet_info;
+ qbm_gpd *p_ra_gpd = NULL;
+ kal_uint8 *p_gpd_data = NULL;
+
+ if((NULL == p_packet) || (0 == len)){
+ hif_trace_info(IPC_TR_IPF_DROP_HDR_INVALID_PARAM, __FUNCTION__, p_packet, len);
+ return;
+ }
+
+ kal_mem_set(&packet_info, 0, sizeof(ipc_packet_info_t));
+ /* Parsing packet first */
+ result = ipc_get_packet_info(p_packet, len, &packet_info);
+ if(KAL_FALSE == result){
+ hif_trace_info(IPC_TR_DROP_HDLR_PKT_INFO_NG, __FUNCTION__);
+ return;
+ }
+
+ switch(packet_info.protocol){
+ case IPC_HDR_PROT_TCP:
+ {
+ if((IPC_HDR_TCP_FLAG_RST == (packet_info.tcp_flags & IPC_HDR_TCP_FLAG_RST)) || (!packet_info.tcp_flags)){
+ /* Skipped if received [RST] packet */
+ break;
+ }
+ ipc_ipf_dhlr_for_tcp_rst(p_packet, packet_info, pdn_sim_id);
+ break;
+ }
+ case IPC_HDR_PROT_ICMPV6:
+ {
+ if(IPC_HDR_ICMPV6_TYPE_RA == packet_info.icmpv6_type){
+ ipc_data_ipv6_ra_pool_push(pdn_sim_id, NULL);
+ p_ra_gpd = qbm_alloc_one(QBM_TYPE_NET_DL);
+ if(!p_ra_gpd){
+ hif_trace_info(IPC_TR_DROP_HDR_GPD_ALLOC_NG, __FUNCTION__, __LINE__);
+ break;
+ }
+ ipc_utils_set_gpd_datalen(p_ra_gpd, len, (void**)&p_gpd_data);
+ QBM_CACHE_INVALID(p_packet, len);
+ kal_mem_cpy(p_gpd_data, p_packet, len);
+ ipc_data_ipv6_ra_pool_push(pdn_sim_id, p_ra_gpd);
+ hif_trace_info(IPC_TR_DOWNLINK_RA_PROXY_GPD, __FUNCTION__, pdn_sim_id, p_ra_gpd);
+ }
+ break;
+ }
+ case IPC_HDR_PROT_UDP:
+ {
+ ipc_ipf_dhlr_for_udp_rst(p_packet, pdn_sim_id);
+ break;
+ }
+ default :
+ {
+ /* Protocol not support log */
+ hif_trace_info(IPC_TR_DROP_HDLR_NG_PROTO, __FUNCTION__, packet_info.protocol);
+ break;
+ }
+ }
+
+ return;
+}
+
+
diff --git a/mcu/middleware/hif/ipcore/src/ipc_dhcp_adp.c b/mcu/middleware/hif/ipcore/src/ipc_dhcp_adp.c
new file mode 100644
index 0000000..fe8334b
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_dhcp_adp.c
@@ -0,0 +1,555 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_dhcp_adp.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * DHCP adaption.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "intrCtrl.h"
+#include "mw_sap.h"
+#include "hif_mw_msgid.h"
+#include "dhcp4c_struct.h"
+#include "ipcore_iph.h"
+
+#include "ipc_defs.h"
+#include "ipc_debug.h"
+#include "ipc_utils.h"
+#include "ipc_dhcp_adp.h"
+#include "ipc_filter.h"
+#include "ipc_notify.h"
+#include "ipc_filter_priority.h"
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Privatate implementation.
+ *----------------------------------------------------------------------------*/
+void
+ipc_on_dl_dhcp4_packet(
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_session_t *session = (ipc_session_t *)context;
+ kal_int32 ip_id;
+ dhcp4c_packet_req_struct *packet_req;
+ kal_uint8 dhcp_id;
+
+ IPC_ASSERT(NULL != context && NULL != head_gpd && NULL != tail_gpd && 0 < length);
+
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ ip_id = session->ip_id;
+ dhcp_id = session->dhcp4c_id;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ if (head_gpd == tail_gpd) {
+ packet_req = (dhcp4c_packet_req_struct *)construct_local_para(sizeof(dhcp4c_packet_req_struct), 0);
+ packet_req->ip_id = ip_id;
+ packet_req->dhcp_id = dhcp_id;
+ packet_req->gpd = head_gpd;
+
+ msg_send6(MOD_IPCORE, /* src_mod_id */
+ MOD_DHCP4C, /* dest_mod_id */
+ DHCP4C_SAP, /* sap_id */
+ MSG_ID_DHCP4C_PACKET_REQ, /* msg_id */
+ (local_para_struct *)packet_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ return;
+ } else {
+ hif_trace_error(IPC_TR_DHCP4C_ON_DL_PACKET_INVALID_GPD_LIST, head_gpd, tail_gpd, length);
+ }
+ } else {
+ hif_trace_error(IPC_TR_DHCP4C_ON_DL_PACKET_FIND_NO_SESSION, context);
+ }
+
+ /*
+ * Free the downlink IP datagram filtered to BM if something wrong.
+ */
+ if (NULL != head_gpd && NULL != tail_gpd) {
+ qbmt_dest_q(head_gpd, tail_gpd);
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+void ipc_enable_dhcp4c(void *session_ptr)
+{
+ ipc_session_t *session = (ipc_session_t *)session_ptr;
+ ipc_filter_rules_t rules;
+ kal_int32 filter_id;
+ dhcp4c_activate_req_struct *activate_req;
+ kal_int32 ip_id;
+ kal_uint8 context;
+ kal_uint8 type;
+ static kal_uint8 hw_addr[] = {0x00, 0x0c, 0x7c, 0x00, 0x00, 0x00};
+
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ context = session->context;
+ type = session->type;
+ ip_id = session->ip_id;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /*
+ * Install a downlink filter for packet from DHCPv4 server.
+ */
+ kal_mem_set(&rules, 0, sizeof(rules));
+ rules.priority = IPC_DL_FILTER_PRIORITY_IPC_DHCP_BEGIN;
+ rules.valid_fields = ( IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID );
+ rules.pdn_id = context;
+
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(context, rules.proto_idx);
+ IPC_UNMASK_PROTOID_FROM_PDNID(rules.pdn_id);
+
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.src_port = IPC_PORT_BOOTPS;
+ rules.dst_port = IPC_PORT_BOOTPC;
+
+ filter_id = ipc_register_dl_filter_cbk(&rules, ipc_on_dl_dhcp4_packet, session);
+ if (0 <= filter_id) {
+ hif_trace_info(IPC_TR_DHCP4C_EN_REG_DL_FILTER_OK, context, type, filter_id);
+
+ IPC_W_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ session->dhcp4c_dl_filter_id = filter_id;
+ IPC_W_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+
+ /*
+ * Activate DHCPv4 client.
+ */
+ activate_req = (dhcp4c_activate_req_struct *)construct_local_para(sizeof(dhcp4c_activate_req_struct), 0);
+ activate_req->ip_id = ip_id;
+ activate_req->hardware_address_type = DHCP4C_HTYPE_ETHERNET;
+ kal_mem_cpy(activate_req->hardware_address, hw_addr, sizeof(hw_addr));
+ activate_req->hardware_address[5] = context;
+
+ msg_send6(MOD_IPCORE, /* src_mod_id */
+ MOD_DHCP4C, /* dest_mod_id */
+ DHCP4C_SAP, /* sap_id */
+ MSG_ID_DHCP4C_ACTIVATE_REQ, /* msg_id */
+ (local_para_struct *)activate_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ } else {
+ hif_trace_error(IPC_TR_DHCP4C_EN_REG_DL_FILTER_NG, context, type, filter_id);
+ IPC_ASSERT(KAL_FALSE);
+ }
+ } else {
+ hif_trace_error(IPC_TR_DHCP4C_EN_FAILED_WITH_INVALID_PARAMETER);
+ }
+}
+
+void ipc_on_dhcp4c_activate_rsp(void *activate_rsp_ptr)
+{
+ dhcp4c_activate_rsp_struct *activate_rsp = (dhcp4c_activate_rsp_struct *)activate_rsp_ptr;
+ ipc_session_t *session;
+ kal_uint8 context;
+ kal_uint8 type;
+ kal_uint8 dhcp4c_id;
+
+ session = ipc_find_session_by_ip_id(activate_rsp->ip_id, IPC_IP_TYPE_IPV4);
+ if (session) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ if (DHCP4C_CAUSE_SUCCESS == activate_rsp->cause) {
+ IPC_W_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ context = session->context;
+ type = session->type;
+ dhcp4c_id = session->dhcp4c_id;
+ session->dhcp4c_id = activate_rsp->dhcp_id;
+ session->dhcp4c_running = KAL_TRUE;
+ IPC_W_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ hif_trace_info(IPC_TR_DHCP4C_ACT_RSP_OK, context, type, dhcp4c_id);
+ return;
+ } else {
+ hif_trace_error(IPC_TR_DHCP4C_ACT_RSP_INVALID_SESSION, activate_rsp->ip_id);
+ }
+ } else {
+ hif_trace_error(IPC_TR_DHCP4C_ACT_RSP_NG, session->context, session->type);
+ }
+
+ ipc_disable_dhcp4c(session);
+ } else {
+ hif_trace_error(IPC_TR_DHCP4C_ACT_RSP_FIND_NO_SESSION, activate_rsp->ip_id);
+ }
+}
+
+void ipc_disable_dhcp4c(void *session_ptr)
+{
+ ipc_session_t *session = (ipc_session_t *)session_ptr;
+ kal_int32 filter_id;
+ kal_int32 ip_id;
+ dhcp4c_deactivate_req_struct *deactivate_req;
+ kal_bool to_stop_dhcpc;
+ kal_uint8 dhcp_id;
+ kal_uint8 context;
+ kal_uint8 type;
+
+ IPC_W_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ to_stop_dhcpc = session->dhcp4c_running;
+ filter_id = session->dhcp4c_dl_filter_id;
+ ip_id = session->ip_id;
+ dhcp_id = session->dhcp4c_id;
+ context = session->context;
+ type = session->type;
+
+ session->dhcp4c_running = KAL_FALSE;
+ session->dhcp4c_dl_filter_id = -1;
+ IPC_W_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ hif_trace_info(IPC_TR_DHCP4C_DIS_INFO, context, type, to_stop_dhcpc, dhcp_id, filter_id);
+
+ /*
+ * Deactivate DHCPv4 client.
+ */
+ if (to_stop_dhcpc) {
+ deactivate_req = (dhcp4c_deactivate_req_struct *)construct_local_para(sizeof(dhcp4c_deactivate_req_struct), 0);
+ deactivate_req->ip_id = ip_id;
+ deactivate_req->dhcp_id = dhcp_id;
+
+ msg_send6(MOD_IPCORE, /* src_mod_id */
+ MOD_DHCP4C, /* dest_mod_id */
+ DHCP4C_SAP, /* sap_id */
+ MSG_ID_DHCP4C_DEACTIVATE_REQ, /* msg_id */
+ (local_para_struct *)deactivate_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+
+ /*
+ * Uninstall the downlink filter.
+ */
+ if (0 <= filter_id) {
+ ipc_deregister_dl_filter(filter_id);
+ hif_trace_info(IPC_TR_DHCP4C_DIS_DEREG_DL_FILTER_OK, session->context, session->type, filter_id);
+ }
+ } else {
+ hif_trace_error(IPC_TR_DHCP4C_DIS_FAILED_WITH_INVALID_PARAMETER);
+ }
+}
+
+void ipc_on_dhcp4c_deactivate_rsp(void *deactivate_rsp_ptr)
+{
+ /* do nothing since we have done the clean up in ipc_disable_dhcp4c(). */
+}
+
+void ipc_on_dhcp4c_ip_up_ind(void *dhcp4c_ip_up_ind_ptr)
+{
+ dhcp4c_ip_up_ind_struct *ip_up_ind = (dhcp4c_ip_up_ind_struct *)dhcp4c_ip_up_ind_ptr;
+ ipc_session_t *session;
+ ipc_session_state_e session_state;
+
+ hif_trace_info(IPC_TR_DHCP4C_IP_UP_IND_START, dhcp4c_ip_up_ind_ptr);
+
+ session = ipc_find_session_by_ip_id(ip_up_ind->ip_id, IPC_IP_TYPE_IPV4);
+
+ hif_trace_info(IPC_TR_DHCP4C_IP_UP_IND_FIND_SESSION_RESULT, session, ip_up_ind->ip_id);
+
+ if (session) {
+ session_state = session->state;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ hif_trace_info(IPC_TR_DHCP4C_IP_UP_IND_SESSION_STATE, session, session_state);
+
+ /* Only handle following states */
+ if ( session_state == IPC_SESSION_STATE_BIND ||
+ session_state == IPC_SESSION_STATE_PRE_LINKUP_IPV4_LEASE ||
+ session_state == IPC_SESSION_STATE_IPV4_LEASE)
+ {
+
+ if ( session_state == IPC_SESSION_STATE_BIND ||
+ session_state == IPC_SESSION_STATE_PRE_LINKUP_IPV4_LEASE )
+ { /* Not linkup for IPv4 yet : swtich to Pre-link up */
+ ipc_update_session_state(session, IPC_SESSION_STATE_PRE_LINKUP);
+
+ } else
+ { /* Already linkup for IPv4 before : swtich to Pre-IPv4 relocate */
+ ipc_update_session_state(session, IPC_SESSION_STATE_PRE_IPV4_RELOCATE);
+ }
+ } else
+ {
+ hif_trace_error(IPC_TR_DHCP4C_IP_UP_IND_SESSION_STATE_INCORRECT, ip_up_ind->ip_id, session, session_state);
+ }
+ } else
+ {
+ hif_trace_error(IPC_TR_DHCP4C_IP_UP_IND_FIND_NO_SESSION, ip_up_ind->ip_id);
+ }
+
+ hif_trace_info(IPC_TR_DHCP4C_IP_UP_IND_END, dhcp4c_ip_up_ind_ptr);
+}
+
+void ipc_on_dhcp4c_ip_down_ind(void *dhcp4c_ip_down_ind_ptr)
+{
+ dhcp4c_ip_down_ind_struct *ip_down_ind = (dhcp4c_ip_down_ind_struct *)dhcp4c_ip_down_ind_ptr;
+ ipc_session_t *session;
+ ipc_session_state_e session_state;
+
+ hif_trace_info(IPC_TR_DHCP4C_IP_DOWN_IND_START, dhcp4c_ip_down_ind_ptr);
+
+
+ session = ipc_find_session_by_ip_id(ip_down_ind->ip_id, IPC_IP_TYPE_IPV4);
+
+ hif_trace_info(IPC_TR_DHCP4C_IP_DOWN_IND_FIND_SESSION_RESULT, session, ip_down_ind->ip_id);
+
+ if (session) {
+ session_state = session->state;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ hif_trace_info(IPC_TR_DHCP4C_IP_DOWN_IND_SESSION_STATE, session, session_state);
+
+
+ /* Only handle following states */
+ if( session_state == IPC_SESSION_STATE_PRE_LINKUP ||
+ session_state == IPC_SESSION_STATE_PRE_IPV4_RELOCATE ||
+ session_state == IPC_SESSION_STATE_LINKUP)
+ {
+ if (session_state == IPC_SESSION_STATE_PRE_LINKUP)
+ { /* Not linkup for IPv4 yet : swtich to Pre-link up lease state */
+ ipc_update_session_state(session, IPC_SESSION_STATE_PRE_LINKUP_IPV4_LEASE);
+ } else
+ { /* Already linkup for IPv4 before : swtich to IPv4 lease state */
+ ipc_update_session_state(session, IPC_SESSION_STATE_IPV4_LEASE);
+ }
+ } else
+ {
+ hif_trace_error(IPC_TR_DHCP4C_IP_DOWN_IND_SESSION_STATE_INCORRECT, ip_down_ind->ip_id, session, session_state);
+ }
+ } else
+ {
+ hif_trace_error(IPC_TR_DHCP4C_IP_DOWN_IND_FIND_NO_SESSION, ip_down_ind->ip_id);
+ }
+
+ hif_trace_info(IPC_TR_DHCP4C_IP_DOWN_IND_END, ip_down_ind);
+}
+
+void ipc_on_dhcp4c_packet_ind(void *dhcp4c_packet_ind_ptr)
+{
+ dhcp4c_packet_ind_struct *packet_ind = (dhcp4c_packet_ind_struct *)dhcp4c_packet_ind_ptr;
+ ipc_session_t *session;
+ ipc_netif_t *netif;
+ qbm_gpd *gpd;
+ ipc_io_request_t *ior;
+
+ IPC_ASSERT(packet_ind);
+ gpd = packet_ind->gpd;
+ IPC_ASSERT(gpd);
+
+ session = ipc_find_session_by_ip_id(packet_ind->ip_id, IPC_IP_TYPE_IPV4);
+
+ hif_data_trace(MD_TRC_IPC_UL_DHCP4C_PKT_SESSION, 0, gpd, packet_ind->ip_id, session);
+
+ if (session)
+ {
+ netif = session->netif;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ hif_data_trace(MD_TRC_IPC_UL_DHCP4C_PKT_UPLINK, 0, gpd, session, netif->config.netif_id);
+
+ ior = (ipc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(gpd);
+ kal_mem_set(ior, 0, sizeof(ipc_io_request_t));
+ ior->first_gpd = gpd;
+ ior->last_gpd = gpd;
+ ior->ip_type = IPC_IP_TYPE_IPV4;
+
+ if (!ipc_uplink(netif, ior))
+ {
+ hif_trace_error(IPC_TR_DHCP4C_IP_PACKET_IND_UPLINK_NG, packet_ind->ip_id);
+ qbmt_dest_q(gpd, gpd);
+ }
+ } else
+ {
+ hif_trace_error(IPC_TR_DHCP4C_IP_PACKET_IND_FIND_NO_SESSION, packet_ind->ip_id);
+ qbmt_dest_q(gpd, gpd);
+ }
+}
+
diff --git a/mcu/middleware/hif/ipcore/src/ipc_dpfm.c b/mcu/middleware/hif/ipcore/src/ipc_dpfm.c
new file mode 100644
index 0000000..9f6acbe
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_dpfm.c
@@ -0,0 +1,565 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2017
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_dpfm.c
+ *
+ * Project:
+ * --------
+ * UMOLYA
+ *
+ * Description:
+ * ------------
+ * MD Direct Tethering API of IPCore
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "mw_sap.h"
+
+#include "ipc_dpfm.h"
+#include "ipc_data.h"
+#include "ipc_utils.h"
+#include "ipc_object.h"
+#include "ipc_data_ipf.h"
+#include "ipc_debug.h"
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+#define ipc_dpfm_fill_pdn_id_into_meta(_ip_type, _mirror_des, _netif_id, _meta) \
+{ \
+ kal_uint8 _pdn_idx_v4 = ipc_session_type_hash(IPC_IP_TYPE_IPV4); \
+ kal_uint8 _pdn_idx_v6 = ipc_session_type_hash(IPC_IP_TYPE_IPV6); \
+ ipc_fill_session_info_into_meta(_ip_type, \
+ _mirror_des->pdn_ids[_pdn_idx_v4], \
+ _mirror_des->pdn_ids[_pdn_idx_v6], \
+ _netif_id, \
+ _meta); \
+}
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Private data structure.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Public functions.
+ *----------------------------------------------------------------------------*/
+
+void ipc_dpfm_lan_on_did_downlink(ipc_dpfm_lan_des_t *lan_des_array)
+{
+ kal_uint32 i;
+
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ ipc_dpfm_lan_des_t *lan_des = &lan_des_array[i];
+ ipc_pkt_t pkt;
+
+ if (lan_des->is_did) {
+ IPC_ASSERT(lan_des->dst_netif_id != IPC_INVALID_NETIF_ID);
+
+ pkt.buf_type = IPC_PKT_DES_TYPE_DID;
+ pkt.did_head = lan_des->did;
+ pkt.did_tail = lan_des->did;
+
+ ipc_send_dl_pkt_in_did_internal(&pkt, NULL, lan_des->dst_netif_id);
+ }
+ }
+}
+
+/*
+ * Assumption: netif read lock is acquired.
+ */
+kal_bool ipc_dpfm_fill_did_si_from_meta(ipc_dpfm_lan_des_t *lan_des_array, lhif_meta_tbl_t *src_meta, kal_uint32 src_netif_id, ipc_netif_t *src_netif)
+{
+ kal_uint32 i;
+ ipc_meta_info_des pkt_info;
+
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ ipc_dpfm_lan_des_t *lan_des = &lan_des_array[i];
+
+ if (src_netif_id == lan_des->src_netif_id) {
+ if (lan_des->is_did) {
+ pkt_info.addr = (void *)(src_meta->vrb_addr);
+ pkt_info.len = src_meta->length;
+ pkt_info.psn_countL = src_meta->psn;
+ if(!ipc_utils_fill_did_si_from_meta(lan_des->is_need_adjust_seq, lan_des->did, &(lan_des->curr_si_idx), &pkt_info, lan_des->hif_type)){
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+ } else {
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL_CAUSE_DID_NULL, src_netif_id, lan_des->is_did);
+ return KAL_FALSE;
+ }
+ } else if (IPC_INVALID_NETIF_ID == lan_des->src_netif_id) {
+ /* The first lan-routed packet in the META list */
+ ipc_netif_t *netif;
+
+ netif = src_netif->lan_netif;
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ lan_des->did = upcm_did_alloc_one();
+ if (lan_des->did) {
+ /* Init lan_des */
+ lan_des->is_did = KAL_TRUE;
+ lan_des->dst_netif_id = netif->config.netif_id;
+ lan_des->src_netif_id = src_netif_id;
+ lan_des->hif_type = ipc_utils_get_hif_type_by_netif_id(lan_des->dst_netif_id);
+
+ /* Init DID: Set FLOW and COUNT-L */
+ UPCM_DID_SET_FLOW(lan_des->did, 0);
+ UPCM_DID_SET_COUNT_L(lan_des->did, src_meta->psn);
+
+ pkt_info.addr = (void *)(src_meta->vrb_addr);
+ pkt_info.len = src_meta->length;
+ pkt_info.psn_countL = src_meta->psn;
+ if(!ipc_utils_fill_did_si_from_meta(lan_des->is_need_adjust_seq, lan_des->did, &(lan_des->curr_si_idx), &pkt_info, lan_des->hif_type)){
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ return KAL_FALSE;
+ }
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ return KAL_TRUE;
+ } else {
+ /* Fail to allocate DID */
+ lan_des->is_did = KAL_FALSE;
+ lan_des->src_netif_id = IPC_INVALID_NETIF_ID;
+
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL_DID_ALLOC_NG, src_netif_id);
+ return KAL_FALSE;
+ }
+ } else {
+ /* Fail to get netif read lock */
+ lan_des->is_did = KAL_FALSE;
+ lan_des->src_netif_id = IPC_INVALID_NETIF_ID;
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_LAN_DID_ALLOC_FAIL_NETIF_NULL, src_netif_id, src_netif->lan_netif);
+ return KAL_FALSE;
+ }
+ }
+ }
+ hif_trace_error(IPC_TR_META_UL_DROP_FOR_LAN_DEVICE_NG, src_netif_id);
+ return KAL_FALSE;
+}
+
+kal_bool ipc_dpfm_set_pdn_id_in_meta(ipc_dpfm_mirror_des_t *mirror_des_array, lhif_meta_tbl_t *meta, kal_uint32 netif_id, kal_uint8 ip_type)
+{
+ kal_uint32 i;
+
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ ipc_dpfm_mirror_des_t *mirror_des = &mirror_des_array[i];
+
+ if (netif_id == mirror_des->netif_id) {
+ ipc_dpfm_fill_pdn_id_into_meta(ip_type, mirror_des, netif_id, meta);
+ return KAL_TRUE;
+ } else if (IPC_INVALID_NETIF_ID == mirror_des->netif_id) {
+ /* The first DPFM_MATCHED packet in the META list */
+ ipc_netif_t *netif;
+
+ netif = ipc_find_netif(netif_id);
+ if (netif) {
+ /* Init mirror_des */
+ mirror_des->netif_id = netif_id;
+ mirror_des->pdn_ids[ipc_session_type_hash(IPC_IP_TYPE_IPV4)] = ipc_map_netif_to_pdn_id(netif, IPC_IP_TYPE_IPV4);
+ mirror_des->pdn_ids[ipc_session_type_hash(IPC_IP_TYPE_IPV6)] = ipc_map_netif_to_pdn_id(netif, IPC_IP_TYPE_IPV6);
+
+ ipc_dpfm_fill_pdn_id_into_meta(ip_type, mirror_des, netif_id, meta);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ return KAL_TRUE;
+ } else {
+ /* Fail to get netif read lock */
+ mirror_des->netif_id = netif_id;
+ return KAL_FALSE;
+ }
+ }
+ }
+ return KAL_FALSE;
+}
+
+kal_bool ipc_dpfm_set_ipf_pkt_in_did_mirror_des(ipc_dpfm_mirror_des_t *mirror_des_array, ipc_pkt_des_t *packet_des, kal_uint32 netif_id)
+{
+ kal_uint32 i;
+ upcm_did_si *sit;
+ upcm_did_si *si;
+ ipf_dl_meta *meta = packet_des->ipf_meta;
+ upcm_did *did;
+
+ for(i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++)
+ {
+ ipc_dpfm_mirror_des_t *mirror_des = &mirror_des_array[i];
+
+ if(netif_id == mirror_des->netif_id)
+ {
+ //IPF DL meta
+ IPC_ASSERT(IPC_PKT_DES_TYPE_META == packet_des->des_type);
+
+ if(mirror_des->mirror_did_tail){
+ did = mirror_des->mirror_did_tail;
+
+ /* Check if DID SEG_NUM exceeds UPCM_DID_MAX_SIT_ENT_NUM(62) */
+ if(mirror_des->seg_num >= UPCM_DID_MAX_SIT_ENT_NUM){
+ did = upcm_did_alloc_one();
+ if(did){
+ /* Init new DID */
+ UPCM_DID_SET_FLOW(did, 0);
+ UPCM_DID_SET_COUNT_L(did, 0);
+ mirror_des->seg_num = 0;
+ mirror_des->pkt_num = 0;
+ UPCM_DID_SET_NEXT(mirror_des->mirror_did_tail, did);
+ mirror_des->mirror_did_tail = did;
+ }else{
+ /* new DID allocation is failed */
+ return KAL_FALSE;
+ }
+ }
+
+ /* We don't adjust the COUNT_L, because USB/WIFI doesn't care this */
+ sit = UPCM_DID_GET_SIT_PTR(did);
+ si = &sit[mirror_des->seg_num];
+
+ UPCM_DID_SI_SET_EOL(si);
+ UPCM_DID_SI_SET_F(si);
+ UPCM_DID_SI_SET_LEN(si, meta->len);
+ UPCM_DID_SI_SET_DATAPTR(si, (void*)meta->addr);
+ UPCM_DID_SI_SET_HIF_TYPE(si, mirror_des->hif_type);
+ UPCM_DID_SI_SET_OFFSET(si, 0);
+
+ mirror_des->seg_num++;
+ mirror_des->pkt_num++;
+ UPCM_DID_SET_PKT_NUM(did, mirror_des->pkt_num);
+ UPCM_DID_SET_SEG_NUM(did, mirror_des->seg_num);
+
+ return KAL_TRUE;
+ }
+ else
+ {
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ }
+ else if (IPC_INVALID_NETIF_ID == mirror_des->netif_id)
+ {
+ /* The first DPFM_MATCHED packet in the DID */
+ mirror_des->mirror_did_head = upcm_did_alloc_one();
+ if (mirror_des->mirror_did_head) {
+ /* Init mirror_des */
+ mirror_des->netif_id = netif_id;
+ mirror_des->hif_type = ipc_utils_get_hif_type_by_netif_id(netif_id);
+
+ IPC_ASSERT(IPC_PKT_DES_TYPE_META == packet_des->des_type);
+
+ /*Init flow, assume USB/Wifi don't need count_L and flow info*/
+ UPCM_DID_SET_FLOW(mirror_des->mirror_did_head, 0);
+ UPCM_DID_SET_COUNT_L(mirror_des->mirror_did_head, 0);
+ mirror_des->seg_num = 0;
+ mirror_des->pkt_num = 0;
+ mirror_des->mirror_did_tail = mirror_des->mirror_did_head;
+
+ sit = UPCM_DID_GET_SIT_PTR(mirror_des->mirror_did_head);
+ si = &sit[mirror_des->seg_num];
+
+ UPCM_DID_SI_SET_EOL(si);
+ UPCM_DID_SI_SET_F(si);
+ UPCM_DID_SI_SET_LEN(si, meta->len);
+ UPCM_DID_SI_SET_DATAPTR(si, (void*)meta->addr);
+ UPCM_DID_SI_SET_HIF_TYPE(si, mirror_des->hif_type);
+ UPCM_DID_SI_SET_OFFSET(si, 0);
+
+ mirror_des->seg_num++;
+ mirror_des->pkt_num++;
+ UPCM_DID_SET_PKT_NUM(mirror_des->mirror_did_head, mirror_des->pkt_num);
+ UPCM_DID_SET_SEG_NUM(mirror_des->mirror_did_head, mirror_des->seg_num);
+
+ return KAL_TRUE;
+ }
+ else
+ {
+ /* Fail to allocate DID for direct path, we will retry allocation next time*/
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* More than IPC_DPFM_MAX_DEVICE_NUM direct path device. */
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+}
+
+kal_bool ipc_dpfm_set_pkt_in_did_mirror_des(ipc_dpfm_mirror_des_t *mirror_des_array, upcm_did *did, kal_uint32 *p_curr_si_idx, kal_uint32 netif_id)
+{
+ kal_uint32 i;
+ kal_uint32 pkt_start_idx = *p_curr_si_idx;
+
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ ipc_dpfm_mirror_des_t *mirror_des = &mirror_des_array[i];
+
+ if (netif_id == mirror_des->netif_id) {
+ /* Because this is copied from original DID, so the total sit number should not exceed the original one */
+ if (mirror_des->mirror_did_head) {
+ ipc_utils_pkt_set_si_hif_type(did, mirror_des->hif_type, p_curr_si_idx);
+ mirror_des->seg_num += *p_curr_si_idx - pkt_start_idx;
+ mirror_des->pkt_num ++;
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+ } else if (IPC_INVALID_NETIF_ID == mirror_des->netif_id) {
+ /* The first DPFM_MATCHED packet in the DID */
+ mirror_des->mirror_did_head = upcm_did_alloc_one();
+ if (mirror_des->mirror_did_head) {
+ /* Init mirror_des */
+ mirror_des->mirror_did_tail = mirror_des->mirror_did_head;
+ mirror_des->netif_id = netif_id;
+ mirror_des->hif_type = ipc_utils_get_hif_type_by_netif_id(netif_id);
+
+ ipc_utils_pkt_set_si_hif_type(did, mirror_des->hif_type, p_curr_si_idx);
+ mirror_des->seg_num += *p_curr_si_idx - pkt_start_idx;
+ mirror_des->pkt_num ++;
+ return KAL_TRUE;
+ } else {
+ /* Fail to allocate DID for direct path */
+ mirror_des->netif_id = netif_id;
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* More than IPC_DPFM_MAX_DEVICE_NUM direct path device. */
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+}
+
+void ipc_dpfm_mirror_did(ipc_dpfm_mirror_des_t *mirror_des, upcm_did *src_did)
+{
+ kal_mem_cpy(mirror_des->mirror_did_head, src_did, sizeof(upcm_did));
+
+ UPCM_DID_SET_PKT_NUM(mirror_des->mirror_did_head, mirror_des->pkt_num);
+ UPCM_DID_SET_SEG_NUM(mirror_des->mirror_did_head, mirror_des->seg_num);
+}
+
+void ipc_dpfm_push_did_to_dpfm_queue(upcm_did *did, kal_uint32 pdn_id)
+{
+ kal_bool to_send_msg;
+
+ ipc_did_enqueue_dpfm_queue(did, did, pdn_id, IPC_DATA_DID_TAIL);
+
+ /* Send ILM to IPCore for processing DL queue */
+ to_send_msg = ipc_data_check_and_set_dl_ilm_flag();
+
+ if (to_send_msg) {
+ msg_send6( kal_get_active_module_id(), /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+}
+
+kal_bool
+ipc_dpfm_check_route(
+ kal_bool uplink,
+ ipc_pkt_des_t *pkt_des,
+ kal_uint32 netif_id)
+{
+ ipc_packet_info_t *packet_info;
+ kal_bool ret = KAL_FALSE;
+ kal_uint32 out_netif_id = 0;
+
+ IPC_ASSERT(pkt_des);
+
+ /* Only when DPFM is enabled, we need to check packet route. */
+ /* In inactive case, IPCore still need forwarding special packet (DPFM delet filter ACK) to DPFM */
+ if(IPC_DPFM_IS_ACTIVE() || (uplink && ( DPFM_PKT_TYPE_FILTER_DEL_ACK == DPFM_GET_PKT_TYPE_FROM_PSN(pkt_des->meta->psn)))){
+ packet_info = pkt_des->packet_info;
+
+ /* For NOT_MATCHED & BWM_MATCHED cases, check DPFM routing. */
+ HIF_SWLA_START("IM2");
+ ret = IPC_QUERY_DPFM_ROUTE(uplink, pkt_des->ip_type, pkt_des, netif_id, &out_netif_id);
+ HIF_SWLA_STOP("IM2");
+ packet_info->out_netif_id = out_netif_id;
+ }
+
+ return ret;
+}
+
+/* Return TRUE means need packet info */
+kal_bool ipc_dpfm_need_pkt_info(kal_bool is_uplink, ipc_pkt_des_t *pkt_des)
+{
+ lhif_meta_tbl_t *lhif_meta; //UL
+ ipf_dl_meta *ipf_meta; //DL
+ kal_bool result = KAL_TRUE;
+
+ if(is_uplink)
+ {
+ lhif_meta = (lhif_meta_tbl_t*) pkt_des->meta;
+ switch(lhif_meta->mr)
+ {
+ case IPC_HPC_MR_DPFM_MATCH:
+ case IPC_HPC_MR_DPFM_MATCH_BUT_NO_NAT:
+ result = KAL_FALSE;
+ break;
+ case IPC_HPC_MR_MATCH:
+ case IPC_HPC_MR_NEW:
+ case IPC_HPC_MR_UNKNOWN:
+ result = KAL_TRUE;
+ break;
+ default:
+ IPC_ASSERT(0);
+ break;
+ }
+ }
+ else
+ {
+ if (IPC_PKT_DES_TYPE_META == pkt_des->des_type) {
+ ipf_meta = (ipf_dl_meta*) pkt_des->ipf_meta;
+ switch(ipf_meta->mr)
+ {
+ case IPC_IPF_MR_DPFM_MATCH:
+ case IPC_IPF_MR_DPFM_MATCH_BUT_NO_NAT:
+ case IPC_IPF_MR_DPFM_OPEN_AND_DPFM_NOT_MATCH:
+ result = KAL_FALSE;
+ break;
+ case IPC_IPF_MR_FILTER_MATCH:
+ case IPC_IPF_MR_UNKNOWN_HEADER:
+ result = KAL_TRUE;
+ break;
+ default:
+ IPC_ASSERT(0);
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+/**** Legacy code for GPD/SPD mode ****/
+qbm_spd *
+ipc_dpfm_mirror_spd(
+ qbm_spd *p_origin_spd,
+ kal_bool *mirror_spd_pie_idx,
+ kal_uint8 dpfm_matched_num)
+{
+ IPC_ASSERT(0);
+ return NULL;
+}
+
+void
+ipc_dpfm_push_gpd_to_routing_queue(
+ kal_bool uplink,
+ kal_uint32 netif_id,
+ qbm_gpd *gpd)
+{
+ IPC_ASSERT(0);
+ return;
+}
+/**** Legacy code for GPD/SPD mode ****/
+
+
+#endif
diff --git a/mcu/middleware/hif/ipcore/src/ipc_filter.c b/mcu/middleware/hif/ipcore/src/ipc_filter.c
new file mode 100644
index 0000000..0b7f163
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_filter.c
@@ -0,0 +1,4172 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_filter.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * Packet filtering.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "mw_sap.h"
+#include "ipc_packet_parser.h"
+#include "ipc_fragment_export.h"
+#include "ipc_defs.h"
+#include "ipc_debug.h"
+#include "ipc_utils.h"
+#include "ipc_filter.h"
+#include "ipc_filter_priority.h"
+#include "qmu_bm_util.h"
+#include "hif_mw_msgid.h"
+#if defined(__IPF_SUPPORT__)
+#include "ipc_data_ipf.h"
+#include "ipfc_export_plugin_dl_filter.h"
+#endif
+#include "dpcopro_custom.h"
+#include "upcm.h"
+
+#if defined (__GEN97_ESL_SPEEDUP__)
+/* reduce mips in ESL by skipping the memory init */
+#define kal_mem_set(a,b,c)
+#endif
+
+typedef struct _ipc_filter_list_t {
+ kal_uint32 count;
+ ipc_filter_t *filter_head;
+ kal_uint8 ip_type;
+} ipc_filter_list_t;
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+kal_uint32 ipc_dl_valid_packet_len_s;
+kal_bool ipc_is_support_ccci_fast_header_s;
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ /* For MD Direct Tethering packet routing queue */
+ ipc_dpfm_routing_packet_list_t ipc_dpfm_packet_routing_queue[2][IPC_MAX_NETIF_CNT];
+ kal_bool ipc_dpfm_queue_non_empty[2];
+#endif
+#if defined(__MD97__)
+ static ipc_data_rq_info_list g_rq_info_list = {0};
+#endif
+kal_uint8 g_ipc_dl_mode = IPC_HW_DL_MODE;
+/*------------------------------------------------------------------------------
+ * Private variables.
+ *----------------------------------------------------------------------------*/
+static ipc_filter_t ipc_filter_pool_s[IPC_MAX_FILTER_CNT];
+static kal_bool ipc_filter_id_s[IPC_MAX_FILTER_CNT];
+static kal_uint32 ipc_filter_cnt_s;
+static kal_uint32 ipc_filter_magic_number_s;
+static kal_int32 ipc_deregistering_filter_id_s[IPC_MAX_FILTER_CNT];
+static kal_uint32 ipc_deregistering_filter_cnt_s;
+static kal_int32 ipc_retry_deregistering_filter_id_s[IPC_MAX_FILTER_CNT];
+static kal_uint32 ipc_retry_deregistering_filter_cnt_s;
+static kal_uint32 g_ipc_filter_max_hw_entry;
+static kal_uint32 g_ipc_dereg_filter_cnt_v4;
+static kal_uint32 g_ipc_dereg_filter_cnt_v6;
+static kal_uint32 g_ipc_filter_recerved_cnt;
+static kal_bool g_is_sw_path = KAL_FALSE;
+
+/* For downlink */
+static ipc_filter_list_t ipc_dl_registering_filter_list_s[1];
+static ipc_filter_list_t ipc_dl_v4_filter_list_s[1];
+static ipc_filter_list_t ipc_dl_v6_filter_list_s[1];
+/* For uplink */
+static ipc_filter_list_t ipc_ul_registering_filter_list_s[1];
+static ipc_filter_list_t ipc_ul_v4_filter_list_s[1];
+static ipc_filter_list_t ipc_ul_v6_filter_list_s[1];
+
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+#define ipc_next_filter_hash(_ip_type) ((((_ip_type) & 0x1) == 1) ? 1 : 0)
+
+#define _PRIORITY_OF_FILTER(_filter) (_filter->rules.priority)
+
+#define _FEATURES_CONTAIN(_rules, _name) \
+ (IPC_FILTER_FEATURE_ ## _name == ((_rules)->features & IPC_FILTER_FEATURE_ ## _name))
+
+#define _RULES_CONTAIN(_rules, _name) \
+ (IPC_FILTER_BY_ ## _name == ((_rules)->valid_fields & IPC_FILTER_BY_ ## _name))
+
+#define _RULES_CONTAIN_IPV4(_rules) \
+ (IPC_IP_TYPE_IPV4 == (_rules)->ip_type || IPC_IP_TYPE_MIXED == (_rules)->ip_type)
+
+#define _RULES_CONTAIN_IPV6(_rules) \
+ (IPC_IP_TYPE_IPV6 == (_rules)->ip_type || IPC_IP_TYPE_MIXED == (_rules)->ip_type)
+
+#define _IS_UNSUPPORTED_PROTOCOL(_protocol) \
+ ((IPC_HDR_PROT_UDP != (_protocol)) && \
+ (IPC_HDR_PROT_TCP != (_protocol)) && \
+ (IPC_HDR_PROT_ICMP != (_protocol)) && \
+ (IPC_HDR_PROT_ICMPV6 != (_protocol)) && \
+ (IPC_HDR_PROT_IGMP != (_protocol)) && \
+ (IPC_HDR_PROT_ESP != (_protocol)))
+
+/*------------------------------------------------------------------------------
+ * Private function.
+ *----------------------------------------------------------------------------*/
+
+static void ipc_filter_list_dump(ipc_filter_list_t *list)
+{
+ kal_uint32 i = 0;
+ kal_uint8 filter_id_list[IPC_MAX_FILTER_CNT]={0};
+ ipc_filter_t *p_cur_filter = NULL;
+
+ if(NULL == list){
+ return;
+ }
+
+ p_cur_filter = list->filter_head;
+ for(i = 0; (i < list->count) && p_cur_filter; i++){
+ filter_id_list[i] = p_cur_filter->filter_id;
+ p_cur_filter = p_cur_filter->next_filter_map[ipc_next_filter_hash(list->ip_type)];
+ }
+
+ for(i = 0; (i+3) < list->count; i+=4){
+ hif_trace_info(IPC_TR_FILTER_ID_DUMP_4, filter_id_list[i], filter_id_list[i+1], filter_id_list[i+2], filter_id_list[i+3]);
+ }
+ switch (list->count % 4){
+ case 1:
+ hif_trace_info(IPC_TR_FILTER_ID_DUMP_1, filter_id_list[i]);
+ break;
+ case 2:
+ hif_trace_info(IPC_TR_FILTER_ID_DUMP_2, filter_id_list[i], filter_id_list[i+1]);
+ break;
+ case 3:
+ hif_trace_info(IPC_TR_FILTER_ID_DUMP_3, filter_id_list[i], filter_id_list[i+1], filter_id_list[i+2]);
+ break;
+ default:
+ break;
+ }
+}
+
+static void ipc_filter_list_dump_all()
+{
+ hif_trace_info(IPC_TR_FILTER_CNT, ipc_ul_v4_filter_list_s->count, ipc_dl_v4_filter_list_s->count, ipc_ul_v6_filter_list_s->count, ipc_dl_v6_filter_list_s->count);
+
+ if(0 < ipc_ul_v4_filter_list_s->count){
+ hif_trace_info(IPC_TR_FILTER_ID_DUMP_INFO_v4, KAL_TRUE, ipc_ul_v4_filter_list_s->count);
+ ipc_filter_list_dump(ipc_ul_v4_filter_list_s);
+ }
+ if(0 < ipc_dl_v4_filter_list_s->count){
+ hif_trace_info(IPC_TR_FILTER_ID_DUMP_INFO_v4, KAL_FALSE, ipc_dl_v4_filter_list_s->count);
+ ipc_filter_list_dump(ipc_dl_v4_filter_list_s);
+ }
+ if(0 < ipc_ul_v6_filter_list_s->count){
+ hif_trace_info(IPC_TR_FILTER_ID_DUMP_INFO_v6, KAL_TRUE, ipc_ul_v6_filter_list_s->count);
+ ipc_filter_list_dump(ipc_ul_v6_filter_list_s);
+ }
+ if(0 < ipc_dl_v6_filter_list_s->count){
+ hif_trace_info(IPC_TR_FILTER_ID_DUMP_INFO_v6, KAL_FALSE, ipc_dl_v6_filter_list_s->count);
+ ipc_filter_list_dump(ipc_dl_v6_filter_list_s);
+ }
+}
+
+static void ipc_filter_dump_invalid_len_pkt(ipc_pkt_des_t *p_pkt_des)
+{
+ kal_uint8 *p_packet = p_pkt_des->packet;
+ kal_uint32 pkt_len = p_pkt_des->packet_len;
+
+ ASSERT(NULL != p_pkt_des);
+
+ /* packet info */
+ switch (p_pkt_des->des_type) {
+ case IPC_PKT_DES_TYPE_DID:
+ hif_data_trace(MD_TRC_IPC_DL_INVALID_LEN_CHK_DID, UPCM_DID_GET_FLOW(p_pkt_des->did), p_pkt_des->psn, pkt_len, ipc_dl_valid_packet_len_s);
+ break;
+ case IPC_PKT_DES_TYPE_GPD:
+ case IPC_PKT_DES_TYPE_SPD:
+ hif_data_trace(MD_TRC_IPC_DL_INVALID_LEN_CHK, p_pkt_des->gpd, p_pkt_des->bd, pkt_len, ipc_dl_valid_packet_len_s);
+ break;
+ default:
+ /* can't reach here */
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+
+ /* dump ip header */
+ hif_data_trace(MD_TRC_IPC_DL_INVALID_LEN_PKT_IP_HDR, 0, IPC_NE_GET_4B(p_packet));
+ hif_data_trace(MD_TRC_IPC_DL_INVALID_LEN_PKT_IP_HDR, 1, IPC_NE_GET_4B(p_packet+4));
+ hif_data_trace(MD_TRC_IPC_DL_INVALID_LEN_PKT_IP_HDR, 2, IPC_NE_GET_4B(p_packet+8));
+ hif_data_trace(MD_TRC_IPC_DL_INVALID_LEN_PKT_IP_HDR, 3, IPC_NE_GET_4B(p_packet+12));
+ hif_data_trace(MD_TRC_IPC_DL_INVALID_LEN_PKT_IP_HDR, 4, IPC_NE_GET_4B(p_packet+16));
+}
+
+static void ipc_filter_dump_matched_pkt(kal_bool is_uplink,
+ ipc_pkt_des_t *p_pkt_des,
+ kal_uint8 match_result,
+ kal_uint8 dpfm_rule_id)
+{
+ ASSERT(NULL != p_pkt_des);
+
+ switch (p_pkt_des->des_type) {
+ case IPC_PKT_DES_TYPE_META:
+ hif_data_trace(MD_TRC_IPC_UL_PKT_FILTER_RESULT_META, p_pkt_des->meta->psn, match_result, dpfm_rule_id);
+ break;
+ case IPC_PKT_DES_TYPE_DID:
+ hif_data_trace(MD_TRC_IPC_DL_PKT_FILTER_RESULT_DID, UPCM_DID_GET_FLOW(p_pkt_des->did), p_pkt_des->psn, match_result, dpfm_rule_id);
+ break;
+ case IPC_PKT_DES_TYPE_GPD:
+ hif_data_trace(MD_TRC_IPC_PKT_FILTER_RESULT_GPD, is_uplink, p_pkt_des->gpd, match_result, dpfm_rule_id);
+ break;
+ case IPC_PKT_DES_TYPE_SPD:
+ hif_data_trace(MD_TRC_IPC_PKT_FILTER_RESULT_SPD, is_uplink, match_result, dpfm_rule_id);
+ break;
+ default:
+ /* can't reach here */
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+}
+
+static void ipc_filter_dump_pkt(kal_bool is_uplink,
+ ipc_pkt_des_t *p_des,
+ ipc_pkt_do_filter_result_e match_result,
+ kal_uint8 dpfm_rule_id)
+{
+ if (NULL == p_des) {
+ /* TODO : error log */
+ return;
+ }
+
+ switch (match_result) {
+ case IPC_PKT_DO_FILTER_INVALID_LEN:
+ ipc_filter_dump_invalid_len_pkt(p_des);
+ break;
+ case IPC_PKT_DO_FILTER_MATCHED:
+ case IPC_PKT_DO_FILTER_BWM_MATCHED:
+ case IPC_PKT_DO_FILTER_DPFM_MATCHED:
+ case IPC_PKT_DO_FILTER_HANDLE_FRAG:
+ ipc_filter_dump_matched_pkt(is_uplink, p_des, match_result, dpfm_rule_id);
+ break;
+ default:
+ break;
+ }
+}
+
+static kal_bool ipc_filter_chk_rules(ipc_data_path_direction_e data_path_direct, ipc_filter_rules_t *rules)
+{
+ IPC_ASSERT(NULL != rules);
+
+ if (_FEATURES_CONTAIN(rules, WC)) {
+ /* Pass other checking if it's WC filter. */
+ return KAL_TRUE;
+ }
+
+ if (0 == rules->valid_fields) {
+ hif_trace_error(IPC_TR_INVALID_RULES_ZERO_VALID_FIELD);
+ return KAL_FALSE;
+ }
+
+ if ((UL_DIRECT == data_path_direct) &&
+ (_RULES_CONTAIN(rules, EBI) /* EBI is used for downlink filter only */||
+ _RULES_CONTAIN(rules, PDN_ID) /* PDN ID is used in downlink filter only */)) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_UL, data_path_direct, rules->valid_fields, rules->ip_type);
+ return KAL_FALSE;
+ }
+
+ if ((DL_DIRECT == data_path_direct) &&
+ !( _RULES_CONTAIN(rules, EBI) || _RULES_CONTAIN(rules, PDN_ID) || _FEATURES_CONTAIN(rules, PFM_DL) || _RULES_CONTAIN(rules, NETIF_ID) ||
+ _FEATURES_CONTAIN(rules, IG_PN))) {
+ /*
+ * [Gen93] downlink filter must contain either EBI or PDN_ID in filter rule,
+ * except the one registered through PFM. (to support Garbage Filter)
+ */
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_DL, data_path_direct, rules->valid_fields, rules->ip_type);
+ return KAL_FALSE;
+ }
+
+ if ((IPC_IP_TYPE_IPV4 == rules->ip_type) &&
+ (((UL_DIRECT == data_path_direct) ||
+ ((DL_DIRECT == data_path_direct) && !_RULES_CONTAIN(rules, EBI))) &&
+ !_RULES_CONTAIN(rules, NETIF_ID) &&
+ !_RULES_CONTAIN(rules, PROTOCOL) &&
+ !_RULES_CONTAIN(rules, SRC_PORT) && !_RULES_CONTAIN(rules, DST_PORT) &&
+ !_RULES_CONTAIN(rules, SRC_IPV4) && !_RULES_CONTAIN(rules, DST_IPV4) &&
+ !_RULES_CONTAIN(rules, ICMPV4_TYPE))) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_IPV4, data_path_direct, rules->valid_fields, rules->ip_type);
+ return KAL_FALSE;
+ }
+
+ if ((IPC_IP_TYPE_IPV6 == rules->ip_type) &&
+ (((UL_DIRECT == data_path_direct) ||
+ ((DL_DIRECT == data_path_direct) && !_RULES_CONTAIN(rules, EBI))) &&
+ !_RULES_CONTAIN(rules, NETIF_ID) &&
+ !_RULES_CONTAIN(rules, PROTOCOL) &&
+ !_RULES_CONTAIN(rules, SRC_PORT) && !_RULES_CONTAIN(rules, DST_PORT) &&
+ !_RULES_CONTAIN(rules, SRC_IPV6) && !_RULES_CONTAIN(rules, DST_IPV6) &&
+ !_RULES_CONTAIN(rules, ICMPV6_TYPE))) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_IPV6, data_path_direct, rules->valid_fields, rules->ip_type);
+ return KAL_FALSE;
+ }
+
+ /* Make sure user will both set L4 field value and protocol value*/
+ if ( _RULES_CONTAIN(rules, SRC_PORT) || _RULES_CONTAIN(rules, DST_PORT)) {
+ if (!((_RULES_CONTAIN(rules, PROTOCOL) && ( (IPC_HDR_PROT_UDP == rules->protocol) || (IPC_HDR_PROT_TCP == rules->protocol))))) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_L4_INFO, data_path_direct, rules->valid_fields, rules->ip_type);
+ return KAL_FALSE;
+ }
+ }
+
+ if (_RULES_CONTAIN(rules, ICMPV4_TYPE)) {
+ if (! (_RULES_CONTAIN(rules, PROTOCOL) && (IPC_HDR_PROT_ICMP == rules->protocol) && (IPC_IP_TYPE_IPV4 == rules->ip_type))) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_L4_INFO, data_path_direct, rules->valid_fields, rules->ip_type);
+ return KAL_FALSE;
+ }
+ }
+
+ if (_RULES_CONTAIN(rules, ICMPV6_TYPE)) {
+ if (! (_RULES_CONTAIN(rules, PROTOCOL) && (IPC_HDR_PROT_ICMPV6 == rules->protocol) && (IPC_IP_TYPE_IPV6 == rules->ip_type))) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_L4_INFO, data_path_direct, rules->valid_fields, rules->ip_type);
+ return KAL_FALSE;
+ }
+ }
+
+ if ( _RULES_CONTAIN(rules, PROTOCOL) && _IS_UNSUPPORTED_PROTOCOL(rules->protocol)) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_UNSUPPORTED_PROTOCOL, rules->protocol);
+ return KAL_FALSE;
+ }
+
+ /* Make sure user will set protocol value when fragment feature is set*/
+ if (_FEATURES_CONTAIN(rules, FRAG)) {
+ if (!_RULES_CONTAIN(rules, PROTOCOL)) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_FRAG, data_path_direct, rules->valid_fields, rules->ip_type, rules->features);
+ return KAL_FALSE;
+ }
+ }
+
+ if (_RULES_CONTAIN(rules, SPI)) {
+ if (!(_RULES_CONTAIN(rules, PROTOCOL) && (IPC_HDR_PROT_ESP == rules->protocol))) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_SPI, data_path_direct, rules->valid_fields, rules->ip_type, rules->features);
+ return KAL_FALSE;
+ }
+ }
+
+ if (_FEATURES_CONTAIN(rules, CUST_FILTER)) {
+ if (NULL == rules->cust_cbk_func) {
+ hif_trace_error(IPC_TR_INVALID_RULES_FOR_CUST_FILTER, data_path_direct, rules->valid_fields, rules->ip_type, rules->features);
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+static kal_int32 ipc_new_filter_id(kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ void *callback_func,
+ module_type module_id)
+{
+ kal_uint32 i = 0;
+
+ IPC_ASSERT(KAL_FALSE == kal_if_hisr());
+
+ if ((NULL == rules) ||
+ (!(_FEATURES_CONTAIN(rules, BWM) ||
+ _FEATURES_CONTAIN(rules, IPV6_DPFM)) && NULL == callback_func && MOD_NIL == module_id)) {
+ hif_trace_error(IPC_TR_NEW_FILTER_INVALID_PARAMS, rules, callback_func, module_id);
+ goto fail;
+ }
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ if (ipc_filter_cnt_s >= IPC_MAX_FILTER_CNT) {
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+ goto fail;
+ }
+
+ for (i = 0; i < IPC_MAX_FILTER_CNT; i++) {
+ if (KAL_FALSE == ipc_filter_id_s[i]) {
+ ipc_filter_cnt_s++;
+ ipc_filter_id_s[i] = KAL_TRUE;
+ ipc_filter_magic_number_s++;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ return i;
+ }
+ }
+
+fail :
+ hif_trace_error(IPC_TR_NEW_FILTER_UNAVAILABLE);
+ ipc_ut_set_error(IPC_UT_REGISTER_FILTER_NG);
+ return IPC_INVALID_FILTER_ID;
+}
+
+static ipc_filter_t *ipc_new_filter(kal_int32 filter_id,
+ ipc_filter_t *p_filter_pool,
+ ipc_filter_rules_t *p_rules,
+ ipc_filter_ntfy_ctxt_t *p_ntfy_ctxt)
+{
+ ipc_filter_t *filter = NULL;
+
+ IPC_ASSERT(NULL != p_filter_pool);
+ IPC_ASSERT(NULL != p_rules);
+ IPC_ASSERT(NULL != p_ntfy_ctxt);
+ filter = p_filter_pool + filter_id;
+
+ IPC_ASSERT(filter->filter_id == IPC_INVALID_FILTER_ID);
+ filter->filter_id = filter_id;
+ filter->is_updated_to_list = KAL_FALSE;
+
+ kal_mem_cpy(&(filter->rules), p_rules, sizeof(ipc_filter_rules_t));
+
+ IPC_MASK_PROTOID_ON_PDNID(filter->rules.pdn_id, filter->rules.proto_idx);
+ IPC_MASK_PROTOID_ON_PDNID(filter->rules.ebi, filter->rules.proto_idx);
+
+ if ((IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO == p_ntfy_ctxt->ntfy_type) ||
+ (IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO == p_ntfy_ctxt->ntfy_type)) {
+ filter->callback_with_info = KAL_TRUE;
+ } else {
+ filter->callback_with_info = KAL_FALSE;
+ }
+
+ if (filter->callback_with_info) {
+ filter->callback_func = p_ntfy_ctxt->ntfy_mod.with_info_cbk_func;
+ } else {
+ filter->callback_func = p_ntfy_ctxt->ntfy_mod.cbk_func;
+ }
+
+ filter->module_id = p_ntfy_ctxt->ntfy_mod.cbk_mod;
+
+ if (MOD_NIL == p_ntfy_ctxt->ntfy_mod.cbk_mod) {
+ filter->callback_context = p_ntfy_ctxt->p_ntfy_args;
+ filter->module_context = NULL;
+ } else {
+ filter->callback_context = filter;
+ filter->module_context = p_ntfy_ctxt->p_ntfy_args;
+ }
+
+ filter->cust_cbk_func = p_rules->cust_cbk_func;
+ filter->p_cust_cbk_args = p_rules->p_cust_cbk_args;
+ filter->is_bypass_sync_hw = KAL_FALSE;
+
+ kal_mem_set(filter->next_filter_map, 0, sizeof(filter->next_filter_map));
+ return filter;
+}
+
+static void ipc_del_filter(ipc_filter_t *filter)
+{
+
+ if (filter) {
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ IPC_ASSERT(ipc_filter_cnt_s > 0);
+ ipc_filter_cnt_s--;
+ if ((0 <= filter->filter_id) && (IPC_MAX_FILTER_CNT > filter->filter_id)) {
+ ipc_filter_id_s[filter->filter_id] = KAL_FALSE;
+ }
+ ipc_filter_magic_number_s++;
+ filter->filter_id = IPC_INVALID_FILTER_ID;
+ filter->is_bypass_sync_hw = KAL_FALSE;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_DEL_FILTER_INVALID_OBJECT, filter);
+ }
+}
+
+static ipc_filter_t *ipc_find_filter_by_id(ipc_filter_t *filter_pool, kal_int32 filter_id)
+{
+ if ((0 <= filter_id) && (IPC_MAX_FILTER_CNT > filter_id)) {
+ return (filter_pool + filter_id);
+ } else {
+ return NULL;
+ }
+}
+
+static kal_bool ipc_add_filter_to_reg_list(ipc_filter_list_t *list,
+ ipc_filter_t *filter)
+{
+ ipc_filter_t *tmp = NULL;
+ kal_bool is_first_filter = KAL_FALSE;
+
+ IPC_ASSERT(list && filter);
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ is_first_filter = (NULL == list->filter_head);
+ tmp = list->filter_head;
+ list->filter_head = filter;
+ list->count++;
+ filter->next_filter_map[0] = tmp;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ return is_first_filter;
+}
+
+static void ipc_get_filter_list_from_reg_list(ipc_filter_t **ul_filter,
+ ipc_filter_t **dl_filter)
+{
+ IPC_ASSERT(ul_filter && dl_filter);
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ *ul_filter = ipc_ul_registering_filter_list_s->filter_head;
+ ipc_ul_registering_filter_list_s->filter_head = NULL;
+ ipc_ul_registering_filter_list_s->count = 0;
+
+ *dl_filter = ipc_dl_registering_filter_list_s->filter_head;
+ ipc_dl_registering_filter_list_s->filter_head = NULL;
+ ipc_dl_registering_filter_list_s->count = 0;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+}
+
+static void ipc_add_filter_to_list(ipc_filter_list_t *list,
+ ipc_filter_t *filter,
+ kal_uint8 ip_type)
+{
+ ipc_filter_t *curr_filter = NULL;
+ ipc_filter_t *prev_filter = NULL;
+
+ IPC_ASSERT(NULL != list);
+ IPC_ASSERT(NULL != filter);
+
+ prev_filter = NULL;
+ if (list) {
+ if (!list->filter_head) {
+ list->filter_head = filter;
+ } else {
+ curr_filter = list->filter_head;
+ while (curr_filter) {
+ if (_PRIORITY_OF_FILTER(curr_filter) >= _PRIORITY_OF_FILTER(filter)) {
+ /* Insert the filter to this position. */
+ if (prev_filter) {
+ /* It's not the head of the list. */
+ filter->next_filter_map[ipc_next_filter_hash(ip_type)] = curr_filter;
+ prev_filter->next_filter_map[ipc_next_filter_hash(ip_type)] = filter;
+ } else {
+ /* Insert to the head of the list. */
+ filter->next_filter_map[ipc_next_filter_hash(ip_type)] = curr_filter;
+ list->filter_head = filter;
+ }
+ break;
+ } else if (!curr_filter->next_filter_map[ipc_next_filter_hash(ip_type)]) {
+ /* The current filter is the last one. Insert the filter after it. */
+ curr_filter->next_filter_map[ipc_next_filter_hash(ip_type)] = filter;
+ break;
+ } else {
+ /* Keep searching */
+ prev_filter = curr_filter;
+ curr_filter = curr_filter->next_filter_map[ipc_next_filter_hash(ip_type)];
+ }
+ }
+ }
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ list->count++;
+ /* SW_PATH don't check reserved_cnt */
+ if (0 != g_ipc_filter_max_hw_entry) {
+ if (IPC_IP_TYPE_IPV4 == filter->rules.ip_type) {
+ if (0 < g_ipc_filter_recerved_cnt) {
+ g_ipc_filter_recerved_cnt = g_ipc_filter_recerved_cnt - 1;
+ } else {
+ /* equal 0 */
+ g_ipc_filter_recerved_cnt = 0;
+ hif_trace_error(IPC_TR_UNEXPECTED_FILTER_CHK_RESULT, __FUNCTION__, __LINE__, g_ipc_dereg_filter_cnt_v4, g_ipc_dereg_filter_cnt_v6, g_ipc_filter_recerved_cnt);
+ }
+ } else {
+ if (1 < g_ipc_filter_recerved_cnt) {
+ g_ipc_filter_recerved_cnt = g_ipc_filter_recerved_cnt - 2;
+ } else {
+ /* equal 0/1 */
+ g_ipc_filter_recerved_cnt = 0;
+ hif_trace_error(IPC_TR_UNEXPECTED_FILTER_CHK_RESULT, __FUNCTION__, __LINE__, g_ipc_dereg_filter_cnt_v4, g_ipc_dereg_filter_cnt_v6, g_ipc_filter_recerved_cnt);
+ }
+ }
+ } else {
+ g_ipc_filter_recerved_cnt = 0;
+ hif_trace_error(IPC_TR_UNEXPECTED_FILTER_CHK_RESULT, __FUNCTION__, __LINE__, g_ipc_dereg_filter_cnt_v4, g_ipc_dereg_filter_cnt_v6, g_ipc_filter_recerved_cnt);
+ }
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ }
+}
+
+static void ipc_filter_rm_filter_from_list(ipc_filter_list_t *list,
+ ipc_filter_t *filter,
+ kal_uint8 ip_type)
+{
+ ipc_filter_t *curr_filter = NULL;
+ ipc_filter_t *prev_filter = NULL;
+
+ prev_filter = NULL;
+ if (list) {
+ curr_filter = list->filter_head;
+ while (curr_filter) {
+ if (curr_filter == filter) {
+ /* Found the filter! */
+ if (prev_filter) {
+ /* It's not the head of the list. */
+ prev_filter->next_filter_map[ipc_next_filter_hash(ip_type)] = curr_filter->next_filter_map[ipc_next_filter_hash(ip_type)];
+ } else {
+ /* Remove the head of the list. */
+ list->filter_head = curr_filter->next_filter_map[ipc_next_filter_hash(ip_type)];
+ }
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ list->count--;
+ /* SW_PATH don't check reserved_cnt */
+ if (0 != g_ipc_filter_max_hw_entry) {
+ if (IPC_IP_TYPE_IPV4 == curr_filter->rules.ip_type) {
+ if (0 < g_ipc_dereg_filter_cnt_v4) {
+ g_ipc_dereg_filter_cnt_v4--;
+ } else {
+ /* equal 0 */
+ g_ipc_dereg_filter_cnt_v4 = 0;
+ hif_trace_error(IPC_TR_UNEXPECTED_FILTER_CHK_RESULT, __FUNCTION__, __LINE__, g_ipc_dereg_filter_cnt_v4, g_ipc_dereg_filter_cnt_v6, g_ipc_filter_recerved_cnt);
+ }
+ } else {
+ if (0 < g_ipc_dereg_filter_cnt_v6) {
+ g_ipc_dereg_filter_cnt_v6--;
+ } else {
+ /* equal 0 */
+ g_ipc_dereg_filter_cnt_v6 = 0;
+ hif_trace_error(IPC_TR_UNEXPECTED_FILTER_CHK_RESULT, __FUNCTION__, __LINE__, g_ipc_dereg_filter_cnt_v4, g_ipc_dereg_filter_cnt_v6, g_ipc_filter_recerved_cnt);
+ }
+ }
+ } else {
+ g_ipc_dereg_filter_cnt_v4 = 0;
+ g_ipc_dereg_filter_cnt_v6 = 0;
+ hif_trace_error(IPC_TR_UNEXPECTED_FILTER_CHK_RESULT, __FUNCTION__, __LINE__, g_ipc_dereg_filter_cnt_v4, g_ipc_dereg_filter_cnt_v6, g_ipc_filter_recerved_cnt);
+ }
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ break;
+ } else {
+ /* Keep searching */
+ prev_filter = curr_filter;
+ curr_filter = curr_filter->next_filter_map[ipc_next_filter_hash(ip_type)];
+ }
+ }
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ }
+}
+
+static void ipc_filter_reset_hw_filter(void)
+{
+ ipv4_filter_rule *hw_filter_base = NULL;
+ kal_bool result = KAL_FALSE;
+ kal_uint8 hw_entry_idx = 0;
+ kal_uint32 total_entry_num = 0;
+ kal_bool ipv6_unknown_proto_chk = KAL_FALSE;
+
+ result = IPC_TAKE_HW_FILTER_TABLE((void**) &hw_filter_base, &total_entry_num);
+
+ /* result shall be true. */
+ IPC_ASSERT(result);
+ hif_trace_info(IPC_TR_UPDATE_HW_FILTER_TABLE_INFO, hw_filter_base, total_entry_num);
+ kal_mem_set(hw_filter_base, 0, sizeof(ipv4_filter_rule) * total_entry_num);
+
+ hif_trace_info(IPC_RESET_HW_FILTER, __FUNCTION__);
+ IPC_SUBMIT_HW_FILTER_TABLE(hw_entry_idx, ipv6_unknown_proto_chk);
+}
+
+static void ipc_filter_chk_sw_path(void)
+{
+ kal_uint32 v4_cnt = 0;
+ kal_uint32 v6_cnt = 0;
+ kal_uint32 proto_idx = 0;
+ kal_uint32 need_hw_entry = 0;
+
+ /* already existed cnt */
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ v4_cnt = ipc_dl_v4_filter_list_s->count;
+ v6_cnt = ipc_dl_v6_filter_list_s->count;
+ need_hw_entry = v4_cnt + 2*v6_cnt;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ if (IPF_HW_FILTER_ENTRY_NUM < need_hw_entry) {
+ /* exceed hw filter entry : SW path
+ * SW => SW : no action */
+ if (KAL_FALSE == g_is_sw_path) {
+ /* HW => SW */
+ for (proto_idx = 0; proto_idx < MAX_SIM_NUM; proto_idx++) {
+ upcm_forced_sw_path_all_by_protocol(KAL_TRUE, proto_idx);
+ hif_trace_info(IPC_FORCE_SW_PATH, __FUNCTION__, KAL_TRUE, proto_idx);
+ }
+ ipc_filter_reset_hw_filter();
+ }
+ g_is_sw_path = KAL_TRUE;
+ } else {
+ /* HW path
+ * HW => HW : no action */
+ ipc_filter_update_hw_filter();
+ if (KAL_TRUE == g_is_sw_path) {
+ /* SW => HW */
+ for (proto_idx = 0; proto_idx < MAX_SIM_NUM; proto_idx++) {
+ upcm_forced_sw_path_all_by_protocol(KAL_FALSE, proto_idx);
+ hif_trace_info(IPC_FORCE_SW_PATH, __FUNCTION__, KAL_FALSE, proto_idx);
+ }
+ }
+ g_is_sw_path = KAL_FALSE;
+ }
+
+ hif_trace_info(IPC_DATA_PATH_STATUS, __FUNCTION__, g_is_sw_path);
+ return;
+}
+
+static INLINE kal_bool ipc_filter_get_ip_pkt(qbm_gpd *desc, /* GPD to get IP header */
+ qbm_gpd **bd, /* BD of IP header pointer (NULL if not exist) */
+ kal_uint8 **buffer, /* IP header pointer */
+ kal_uint32 *length /* GPD total length */)
+{
+ IPC_ASSERT(desc);
+ IPC_ASSERT(bd);
+ IPC_ASSERT(buffer);
+ IPC_ASSERT(length);
+
+ *bd = NULL;
+ *length = QBM_DES_GET_DATALEN(desc);
+
+ if (QBM_DES_GET_BDP(desc)) {
+ desc = (qbm_gpd *) QBM_DES_GET_DATAPTR(desc);
+ while (0 == QBM_DES_GET_DATALEN(desc)) {
+ if (!QBM_DES_GET_EOL(desc)) {
+ desc = (qbm_gpd *) QBM_DES_GET_NEXT(desc);
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+ }
+ /* Found : record BD pointer */
+ *bd = desc;
+ }
+
+ *buffer = (kal_uint8*) QBM_DES_GET_DATAPTR(desc);
+
+ return KAL_TRUE;
+}
+
+static INLINE ipc_match_result_e ipc_filter_match_ipv4_rules(ipc_filter_rules_t *rules,
+ ipc_packet_info_t *content)
+{
+ ipc_match_result_e ret = IPC_MATCH_RESULT_NOT_MATCHED;
+
+ /* Start to compare multi-byte IPv4 header content, content dividing issue need to handle */
+ if (_RULES_CONTAIN(rules, SRC_IPV4)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_SRC_IPV4)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->src_addr[0] != rules->src_ipv4.addr32) {
+ goto not_matched;
+ }
+ }
+
+ if (_RULES_CONTAIN(rules, DST_IPV4)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_DST_IPV4)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->dst_addr[0] != rules->dst_ipv4.addr32) {
+ goto not_matched;
+ }
+ }
+
+ if (_RULES_CONTAIN(rules, PROTOCOL)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_PROTOCOL)) {
+ goto not_matched;
+ }
+
+ if (content->protocol != rules->protocol) {
+ goto not_matched;
+ }
+
+ /* For IPv4, we are not handle fragment packets with different protocol. */
+ if (content->fragment) {
+ if (!_FEATURES_CONTAIN(rules, FRAG)) {
+ goto not_matched;
+ } else {
+ ret |= IPC_MATCH_RESULT_FRAG_MATCHED;
+ }
+ }
+
+ /* L4 packet content */
+ switch (rules->protocol) {
+ case IPC_HDR_PROT_UDP:
+ case IPC_HDR_PROT_TCP: {
+ if (_RULES_CONTAIN(rules, SRC_PORT)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_SRC_PORT)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->src_port != rules->src_port) {
+ goto not_matched;
+ }
+ }
+ if (_RULES_CONTAIN(rules, DST_PORT)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_DST_PORT)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->dst_port != rules->dst_port) {
+ goto not_matched;
+ }
+ }
+ if (_RULES_CONTAIN(rules, TCP_FLAGS)) {
+ if ((IPC_HDR_PROT_TCP != rules->protocol) || !(content->info_valid_fields & IPC_FILTER_BY_TCP_FLAGS)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->tcp_flags != rules->tcp_flags) {
+ goto not_matched;
+ }
+ }
+
+ break;
+ }
+ case IPC_HDR_PROT_ICMP: {
+ if (_RULES_CONTAIN(rules, ICMPV4_TYPE)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_ICMPV4_TYPE)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->icmpv4_type != rules->icmpv4_type) {
+ goto not_matched;
+ }
+ }
+
+ break;
+ }
+ case IPC_HDR_PROT_ESP: {
+ if (_RULES_CONTAIN(rules, SPI)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_SPI)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->spi != rules->spi) {
+ goto not_matched;
+ }
+ }
+
+ break;
+ }
+ default:
+ /* No L4 content checking rule, pass it directly */
+ break;
+ }
+ }
+
+ ret |= IPC_MATCH_RESULT_MATCHED;
+ return ret;
+
+not_matched :
+ if (0 == (ret & IPC_MATCH_RESULT_FRAG_MATCHED)) {
+ ret = IPC_MATCH_RESULT_NOT_MATCHED;
+ }
+ return ret;
+}
+
+static INLINE ipc_match_result_e ipc_filter_match_ipv6_rules(ipc_filter_rules_t *rules,
+ ipc_packet_info_t *content)
+{
+ ipc_match_result_e ret = IPC_MATCH_RESULT_NOT_MATCHED;
+
+ /* Start to compare multi-byte IPv4 header content, content dividing issue need to handle */
+
+ if (_RULES_CONTAIN(rules, SRC_IPV6)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_SRC_IPV6)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->src_addr[0] != rules->src_ipv6.addr32[0]) {
+ goto not_matched;
+ }
+ if (content->src_addr[1] != rules->src_ipv6.addr32[1]) {
+ goto not_matched;
+ }
+ if (content->src_addr[2] != rules->src_ipv6.addr32[2]) {
+ goto not_matched;
+ }
+ if (content->src_addr[3] != rules->src_ipv6.addr32[3]) {
+ goto not_matched;
+ }
+ }
+
+ if (_RULES_CONTAIN(rules, DST_IPV6)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_DST_IPV6)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->dst_addr[0] != rules->dst_ipv6.addr32[0]) {
+ goto not_matched;
+ }
+ if (content->dst_addr[1] != rules->dst_ipv6.addr32[1]) {
+ goto not_matched;
+ }
+ if (content->dst_addr[2] != rules->dst_ipv6.addr32[2]) {
+ goto not_matched;
+ }
+ if (content->dst_addr[3] != rules->dst_ipv6.addr32[3]) {
+ goto not_matched;
+ }
+ }
+
+ if (_RULES_CONTAIN(rules, PROTOCOL)) {
+ /* We only compare protocol for the first IPv6 fragment packets. */
+ if (content->fragment) {
+ if (!_FEATURES_CONTAIN(rules, FRAG)) {
+ goto not_matched;
+ } else {
+ ret |= IPC_MATCH_RESULT_FRAG_MATCHED;
+ }
+ }
+
+ if (!(content->info_valid_fields & IPC_FILTER_BY_PROTOCOL)) {
+ goto not_matched;
+ }
+
+ /* Protocol not match */
+ if (content->protocol != rules->protocol) {
+ goto not_matched;
+ }
+
+ /* L4 packet content */
+ switch (rules->protocol) {
+ case IPC_HDR_PROT_UDP:
+ case IPC_HDR_PROT_TCP: {
+ if (_RULES_CONTAIN(rules, SRC_PORT)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_SRC_PORT)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->src_port != rules->src_port) {
+ goto not_matched;
+ }
+ }
+ if (_RULES_CONTAIN(rules, DST_PORT)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_DST_PORT)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->dst_port != rules->dst_port) {
+ goto not_matched;
+ }
+ }
+ if (_RULES_CONTAIN(rules, TCP_FLAGS)) {
+ if ((IPC_HDR_PROT_TCP != rules->protocol) ||
+ !(content->info_valid_fields & IPC_FILTER_BY_TCP_FLAGS)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->tcp_flags != rules->tcp_flags) {
+ goto not_matched;
+ }
+ }
+
+ break;
+ }
+ case IPC_HDR_PROT_ICMPV6: {
+ if (_RULES_CONTAIN(rules, ICMPV6_TYPE)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_ICMPV6_TYPE)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->icmpv6_type != rules->icmpv6_type) {
+ goto not_matched;
+ }
+ }
+
+ break;
+ }
+ case IPC_HDR_PROT_ESP: {
+ if (_RULES_CONTAIN(rules, SPI)) {
+ if (!(content->info_valid_fields & IPC_FILTER_BY_SPI)) {
+ goto not_matched;
+ }
+
+ /* Compare content */
+ if (content->spi != rules->spi) {
+ goto not_matched;
+ }
+ }
+
+ break;
+ }
+ default:
+ /* No L4 content checking rule, pass it directly */
+ break;
+ }
+ }
+
+ ret |= IPC_MATCH_RESULT_MATCHED;
+ return ret;
+
+not_matched :
+ if (0 == (ret & IPC_MATCH_RESULT_FRAG_MATCHED)) {
+ ret = IPC_MATCH_RESULT_NOT_MATCHED;
+ }
+
+ return ret;
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions.
+ *----------------------------------------------------------------------------*/
+void ipc_filter_init(void)
+{
+ kal_uint32 idx = 0;
+ static ipc_filter_list_t *fls_v4_set[] = {ipc_ul_v4_filter_list_s, ipc_dl_v4_filter_list_s};
+ static ipc_filter_list_t *fls_v6_set[] = {ipc_ul_v6_filter_list_s, ipc_dl_v6_filter_list_s};
+
+#if defined(__MTK_TARGET__)
+ IPC_ASSERT(sizeof(ipc_filter_t) % 4 == 0);
+ IPC_ASSERT(sizeof(ipc_filter_list_t) % 4 == 0);
+#endif
+
+ kal_mem_set( ipc_filter_pool_s, 0, sizeof(ipc_filter_pool_s) );
+ for (idx = 0; idx < IPC_MAX_FILTER_CNT; idx++) {
+ ipc_filter_pool_s[idx].filter_id = IPC_INVALID_FILTER_ID;
+ ipc_filter_pool_s[idx].is_bypass_sync_hw = KAL_FALSE;
+ ipc_deregistering_filter_id_s[idx] = IPC_INVALID_FILTER_ID;
+ ipc_retry_deregistering_filter_id_s[idx] = IPC_INVALID_FILTER_ID;
+ }
+ kal_mem_set(ipc_filter_id_s, 0, sizeof(ipc_filter_id_s));
+ ipc_filter_cnt_s = 0;
+ ipc_filter_magic_number_s = 0;
+ ipc_deregistering_filter_cnt_s = 0;
+ ipc_retry_deregistering_filter_cnt_s = 0;
+#if defined(__MTK_TARGET__)
+ g_ipc_filter_max_hw_entry = IPF_HW_FILTER_ENTRY_NUM;
+#else
+ g_ipc_filter_max_hw_entry = 0;
+#endif
+ g_ipc_dereg_filter_cnt_v4 = 0;
+ g_ipc_dereg_filter_cnt_v6 = 0;
+ g_ipc_filter_recerved_cnt = 0;
+ g_is_sw_path = KAL_FALSE;
+
+ kal_mem_set(ipc_dl_registering_filter_list_s, 0, sizeof(ipc_filter_list_t));
+ kal_mem_set(ipc_ul_registering_filter_list_s, 0, sizeof(ipc_filter_list_t));
+
+ for (idx = 0; idx < sizeof(fls_v4_set) / sizeof(ipc_filter_list_t*); idx++) {
+ kal_mem_set( fls_v4_set[idx], 0, sizeof(ipc_filter_list_t) );
+ fls_v4_set[idx]->ip_type = IPC_IP_TYPE_IPV4;
+ }
+ for (idx = 0; idx < sizeof(fls_v6_set) / sizeof(ipc_filter_list_t*); idx++) {
+ kal_mem_set( fls_v6_set[idx], 0, sizeof(ipc_filter_list_t) );
+ fls_v6_set[idx]->ip_type = IPC_IP_TYPE_IPV6;
+ }
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ kal_mem_set(ipc_dpfm_packet_routing_queue, 0, sizeof(ipc_dpfm_packet_routing_queue));
+ kal_mem_set(ipc_dpfm_queue_non_empty, 0, sizeof(ipc_dpfm_queue_non_empty));
+#endif
+}
+
+static kal_int32 ipc_filter_add_filter(ipc_filter_t *filter, kal_bool uplink)
+{
+ ipc_filter_rules_t *rules = NULL;
+ kal_bool with_ipv4 = KAL_FALSE;
+ kal_bool with_ipv6 = KAL_FALSE;
+
+ IPC_ASSERT(filter);
+
+ rules = &(filter->rules);
+
+#if !defined(__IPF_SUPPORT__)
+ /* [Gen93] Set forced SW path when registering filter. */
+ if (_RULES_CONTAIN(rules, PDN_ID)) {
+ //IPC_FORCED_SW_PATH_BY_PDN(rules->pdn_id, KAL_TRUE);
+ }
+ if (_RULES_CONTAIN(rules, EBI)) {
+ //IPC_FORCED_SW_PATH_BY_EBI(rules->ebi, KAL_TRUE);
+ }
+#endif
+ /*
+ * [Gen93] For DL filters registered through PFM and without PDN/EBI,
+ * set forced SW path to all bearers (to support Garbage Filter).
+ */
+ if ((KAL_FALSE == uplink) && _FEATURES_CONTAIN(rules, PFM_DL) && !( _RULES_CONTAIN(rules, EBI) || _RULES_CONTAIN(rules, PDN_ID))) {
+ //IPC_FORCED_SW_PATH_ALL(KAL_TRUE);
+ }
+
+ /* WC filter should be added to both lists (ipv4 & ipv6). */
+ with_ipv4 = _RULES_CONTAIN_IPV4(rules) || _FEATURES_CONTAIN(rules, WC);
+ with_ipv6 = _RULES_CONTAIN_IPV6(rules) || _FEATURES_CONTAIN(rules, WC);
+ hif_trace_info(IPC_TR_REGISTER_FILTER_OK, uplink, filter->filter_id, rules->features, rules->ip_type, rules->valid_fields, with_ipv4, with_ipv6);
+
+ IPC_ASSERT(0 <= _PRIORITY_OF_FILTER(filter) &&
+ _PRIORITY_OF_FILTER(filter) < ((KAL_TRUE == uplink) ? MAX_IPC_UL_FILTER_PRIORITY : MAX_IPC_DL_FILTER_PRIORITY));
+
+ if (with_ipv4) {
+ ipc_add_filter_to_list(
+ (KAL_TRUE == uplink) ? ipc_ul_v4_filter_list_s : ipc_dl_v4_filter_list_s, filter, IPC_IP_TYPE_IPV4);
+ hif_trace_info(IPC_TR_REGISTER_FILTER_ADD_TO_LIST, filter->filter_id, 4, uplink, g_ipc_dereg_filter_cnt_v4, g_ipc_dereg_filter_cnt_v6, g_ipc_filter_recerved_cnt);
+ }
+ if (with_ipv6) {
+ ipc_add_filter_to_list(
+ (KAL_TRUE == uplink) ? ipc_ul_v6_filter_list_s : ipc_dl_v6_filter_list_s, filter, IPC_IP_TYPE_IPV6);
+ hif_trace_info(IPC_TR_REGISTER_FILTER_ADD_TO_LIST, filter->filter_id, 4, uplink, g_ipc_dereg_filter_cnt_v4, g_ipc_dereg_filter_cnt_v6, g_ipc_filter_recerved_cnt);
+ }
+
+ /* Set flag after filter is added to list*/
+ filter->is_updated_to_list = KAL_TRUE;
+
+ return filter->filter_id;
+}
+
+static INLINE void ipc_filter_set_filter_req_msg(ipc_register_filter_req_struct_t *p_req,
+ ipc_data_path_direction_e data_path_direct,
+ kal_int32 filter_id,
+ ipc_filter_ntfy_ctxt_t *p_ntfy_ctxt)
+{
+ IPC_ASSERT(NULL != p_req);
+ IPC_ASSERT(NULL != p_ntfy_ctxt);
+
+ p_req->filter_id = filter_id;
+ p_req->data_path_direct = data_path_direct;
+
+ if ((IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO == p_ntfy_ctxt->ntfy_type) ||
+ (IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO == p_ntfy_ctxt->ntfy_type)) {
+ p_req->callback_with_info = KAL_TRUE;
+ } else {
+ p_req->callback_with_info = KAL_FALSE;
+ }
+
+ if (p_req->callback_with_info) {
+ p_req->callback_func = p_ntfy_ctxt->ntfy_mod.with_info_cbk_func;
+ } else {
+ p_req->callback_func = p_ntfy_ctxt->ntfy_mod.cbk_func;
+ }
+
+ p_req->callback_context = p_ntfy_ctxt->p_ntfy_args;
+ p_req->module_id = p_ntfy_ctxt->ntfy_mod.cbk_mod;
+
+ return;
+}
+
+kal_int32 ipc_filter_reg_filter_by_ilm(ipc_data_path_direction_e data_path_direct,
+ ipc_filter_rules_t *p_rules,
+ ipc_filter_ntfy_ctxt_t *p_ntfy_ctxt)
+{
+ ipc_filter_t *p_filter = NULL;
+ kal_int32 filter_id = 0;
+ kal_bool is_send_msg = KAL_FALSE;
+
+ if (!ipc_filter_chk_rules(data_path_direct, p_rules)) {
+ hif_trace_error(IPC_TR_REGISTER_FILTER_VALIDATE_FAIL, data_path_direct);
+ ipc_ut_set_error(IPC_UT_REGISTER_FILTER_VALIDATE_FAIL);
+ return IPC_INVALID_FILTER_ID;
+ }
+
+ if ((IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO == p_ntfy_ctxt->ntfy_type) ||
+ (IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO == p_ntfy_ctxt->ntfy_type)) {
+ filter_id = ipc_new_filter_id(data_path_direct, p_rules, p_ntfy_ctxt->ntfy_mod.with_info_cbk_func, p_ntfy_ctxt->ntfy_mod.cbk_mod);
+ } else {
+ filter_id = ipc_new_filter_id(data_path_direct, p_rules, p_ntfy_ctxt->ntfy_mod.cbk_func, p_ntfy_ctxt->ntfy_mod.cbk_mod);
+ }
+
+ if (filter_id < 0) {
+ hif_trace_info(IPC_TR_REGISTER_FILTER_NG);
+ ipc_ut_set_error(IPC_UT_REGISTER_FILTER_NG);
+ return IPC_INVALID_FILTER_ID;
+ }
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ if (IPC_IP_TYPE_IPV4 == p_rules->ip_type) {
+ if (IPF_HW_FILTER_ENTRY_NUM > g_ipc_filter_recerved_cnt) {
+ g_ipc_filter_recerved_cnt = g_ipc_filter_recerved_cnt + 1;
+ }
+ } else {
+ if (IPF_HW_FILTER_ENTRY_NUM - 1 > g_ipc_filter_recerved_cnt) {
+ g_ipc_filter_recerved_cnt = g_ipc_filter_recerved_cnt + 2;
+ }
+ }
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ p_filter = ipc_new_filter(filter_id, ipc_filter_pool_s, p_rules, p_ntfy_ctxt);
+
+ is_send_msg = ipc_add_filter_to_reg_list(
+ (data_path_direct) ? ipc_ul_registering_filter_list_s : ipc_dl_registering_filter_list_s, p_filter);
+
+ if (is_send_msg) {
+ ipc_register_filter_req_struct_t *p_req = NULL;
+
+ p_req = (ipc_register_filter_req_struct_t *)construct_local_para(sizeof(ipc_register_filter_req_struct_t), TD_RESET);
+ IPC_ASSERT(NULL != p_req);
+ ipc_filter_set_filter_req_msg(p_req, data_path_direct, filter_id, p_ntfy_ctxt);
+ kal_mem_cpy(&(p_req->rules), p_rules, sizeof(ipc_filter_rules_t));
+
+ msg_send6(FILTER_SRC_MOD,
+ MOD_IPCORE,
+ IPCORE_USER_SENSITIVE_SAP,
+ MSG_ID_IPCORE_REGISTER_FILTER_REQ,
+ (local_para_struct *)p_req,
+ NULL);
+ } else {
+ /* Dump filter structure (ILM like) when registering ILM aggregated. */
+ ipc_register_filter_req_struct_t req_msg = {0};
+
+ req_msg.msg_len = sizeof(ipc_register_filter_req_struct_t);
+ ipc_filter_set_filter_req_msg(&req_msg, data_path_direct, filter_id, p_ntfy_ctxt);
+ kal_mem_cpy(&(req_msg.rules), p_rules, sizeof(ipc_filter_rules_t));
+
+ dhl_log_primitive6(FILTER_SRC_MOD,
+ MOD_IPCORE,
+ IPCORE_USER_SENSITIVE_SAP,
+ MSG_ID_IPCORE_REGISTER_FILTER_REQ,
+ (local_para_struct *)&req_msg,
+ NULL);
+ }
+
+ return filter_id;
+}
+
+void ipc_filter_reg_handler(local_para_struct *local_para_ptr)
+{
+ ipc_filter_t *filter_list[2];
+ ipc_filter_t *curr_filter, *next_filter;
+ kal_uint32 i = 0;
+#if defined(__IPF_SUPPORT__)
+ kal_bool is_DL_updated = KAL_FALSE;
+#endif
+
+ ipc_get_filter_list_from_reg_list(&filter_list[0], &filter_list[1]);
+
+ for (i = 0; i < 2; i++) {
+ curr_filter = filter_list[i];
+ while (curr_filter) {
+ next_filter = curr_filter->next_filter_map[0];
+ curr_filter->next_filter_map[0] = NULL;
+ ipc_filter_add_filter(curr_filter, (0 == i) ? KAL_TRUE : KAL_FALSE);
+#if defined(__IPF_SUPPORT__)
+ if (!(0 == i)) {
+ is_DL_updated = KAL_TRUE;
+ }
+#endif
+ curr_filter = next_filter;
+ }
+ }
+
+#if defined(__IPF_SUPPORT__)
+ if (is_DL_updated && (IPC_HW_DL_MODE == g_ipc_dl_mode)) {
+ ipc_filter_chk_sw_path();
+ }
+#endif
+
+ ipc_filter_list_dump_all();
+}
+
+void ipc_filter_dereg(kal_int32 filter_id)
+{
+ ipc_filter_t *filter = NULL;
+ ipc_filter_rules_t *rules = NULL;
+ kal_bool with_ipv4 = KAL_FALSE;
+ kal_bool with_ipv6 = KAL_FALSE;
+
+ filter = ipc_find_filter_by_id(ipc_filter_pool_s, filter_id);
+ if ((NULL != filter) && (filter->filter_id != IPC_INVALID_FILTER_ID)) {
+
+ /* Check if the filter is already stored to IPcore internal list. */
+ if (filter->is_updated_to_list != KAL_TRUE) {
+ ipc_retry_deregistering_filter_id_s[ipc_retry_deregistering_filter_cnt_s] = filter->filter_id;
+ ipc_retry_deregistering_filter_cnt_s++;
+ hif_trace_info(IPC_TR_REMOVE_DL_FILTER_RETRY, filter->filter_id);
+ return;
+ }
+
+ rules = &(filter->rules);
+
+#if !defined(__IPF_SUPPORT__)
+ /* [Gen93] Clear forced SW path when deregistering filter. */
+ if (_RULES_CONTAIN(rules, PDN_ID)) {
+ //IPC_FORCED_SW_PATH_BY_PDN(rules->pdn_id, KAL_FALSE);
+ }
+ if (_RULES_CONTAIN(rules, EBI)) {
+ //IPC_FORCED_SW_PATH_BY_EBI(rules->ebi, KAL_FALSE);
+ }
+#endif
+ /*
+ * [Gen93] For DL filters registered through PFM and without PDN/EBI,
+ * clear forced SW path to all bearers (to support Garbage Filter).
+ */
+ if ( _FEATURES_CONTAIN(rules, PFM_DL) && !( _RULES_CONTAIN(rules, EBI) || _RULES_CONTAIN(rules, PDN_ID))) {
+ //IPC_FORCED_SW_PATH_ALL(KAL_FALSE);
+ }
+
+ with_ipv4 = _RULES_CONTAIN_IPV4(rules) || _FEATURES_CONTAIN(rules, WC);
+ with_ipv6 = _RULES_CONTAIN_IPV6(rules) || _FEATURES_CONTAIN(rules, WC);
+ hif_trace_info(IPC_TR_DEREGISTER_FILTER_INFO, filter->filter_id, rules->features, rules->valid_fields, with_ipv4, with_ipv6);
+
+ if (with_ipv4) {
+ /* Remove from UL filter list */
+ ipc_filter_rm_filter_from_list(ipc_ul_v4_filter_list_s, filter, IPC_IP_TYPE_IPV4);
+ /* Remove from DL filter list */
+ ipc_filter_rm_filter_from_list(ipc_dl_v4_filter_list_s, filter, IPC_IP_TYPE_IPV4);
+ hif_trace_info(IPC_TR_REMOVE_DL_FILTER_FROM_LIST, filter->filter_id, 4);
+ }
+ if (with_ipv6) {
+ /* Remove from UL filter list */
+ ipc_filter_rm_filter_from_list(ipc_ul_v6_filter_list_s, filter, IPC_IP_TYPE_IPV6);
+ /* Remove from DL filter list */
+ ipc_filter_rm_filter_from_list(ipc_dl_v6_filter_list_s, filter, IPC_IP_TYPE_IPV6);
+ hif_trace_info(IPC_TR_REMOVE_DL_FILTER_FROM_LIST, filter->filter_id, 6);
+ }
+
+ ipc_del_filter(filter);
+ } else {
+ hif_trace_error(IPC_TR_DEREGISTER_FILTER_NOT_FOUND, filter_id);
+ ipc_ut_set_error(IPC_UT_DEREGISTER_FILTER_NOT_FOUND);
+ }
+}
+
+kal_bool ipc_filter_dereg_filter_by_ilm(kal_int32 filter_id)
+{
+ kal_bool to_send_msg = KAL_FALSE;
+ ipc_filter_t *p_filter = NULL;
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ p_filter = ipc_find_filter_by_id(ipc_filter_pool_s, filter_id);
+ if ((0 > filter_id) ||
+ (IPC_MAX_FILTER_CNT <= filter_id) ||
+ (NULL == p_filter) ||
+ (IPC_INVALID_FILTER_ID == p_filter->filter_id)) {
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+ hif_trace_error(IPC_TR_DEREGISTER_FILTER_WITH_INVALID_ID, filter_id);
+ ipc_ut_set_error(IPC_UT_DEREGISTER_FILTER_WITH_INVALID_ID);
+ return KAL_FALSE;
+ }
+
+ to_send_msg = (0 == ipc_deregistering_filter_cnt_s);
+ ipc_deregistering_filter_id_s[ipc_deregistering_filter_cnt_s] = filter_id;
+ if (IPC_IP_TYPE_IPV4 == p_filter->rules.ip_type) {
+ if (IPC_MAX_FILTER_CNT > g_ipc_dereg_filter_cnt_v4) {
+ g_ipc_dereg_filter_cnt_v4++;
+ }
+ } else {
+ if (IPC_MAX_FILTER_CNT > g_ipc_dereg_filter_cnt_v6) {
+ g_ipc_dereg_filter_cnt_v6++;
+ }
+ }
+ ipc_deregistering_filter_cnt_s++;
+
+ /* add tag in register list and pending register list */
+ if (filter_id == p_filter->filter_id) {
+ /* already in filter list */
+ p_filter->is_bypass_sync_hw = KAL_TRUE;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+ hif_trace_info(IPC_TR_SET_BYPASS_HW_FILTER_SYNC, __FUNCTION__, filter_id);
+ } else {
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+ }
+
+ if (to_send_msg) {
+ ipc_deregister_filter_req_struct_t *p_req_msg = NULL;
+
+ p_req_msg = (ipc_deregister_filter_req_struct_t *) construct_local_para(sizeof(ipc_deregister_filter_req_struct_t), TD_RESET);
+ IPC_ASSERT(p_req_msg);
+
+ p_req_msg->filter_id = filter_id;
+
+ msg_send6(FILTER_SRC_MOD, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_DEREGISTER_FILTER_REQ, /* msg_id */
+ (local_para_struct *)p_req_msg, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ } else {
+ /* Dump filter structure (ILM like) when registering ILM aggregated. */
+ ipc_deregister_filter_req_struct_t tmp = {0};
+ ipc_deregister_filter_req_struct_t *p_req_msg = &tmp;
+
+ p_req_msg->msg_len = sizeof(ipc_deregister_filter_req_struct_t);
+ p_req_msg->filter_id = filter_id;
+
+ dhl_log_primitive6(FILTER_SRC_MOD, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_DEREGISTER_FILTER_REQ, /* msg_id */
+ (local_para_struct *)p_req_msg, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+
+ return KAL_TRUE;
+}
+
+void ipc_filter_dereg_handler(local_para_struct *local_para_ptr)
+{
+ static kal_int32 deregistering_filter_id[IPC_MAX_FILTER_CNT] = {0};
+ kal_uint32 deregistering_filter_cnt = 0;
+ kal_uint32 i = 0;
+ kal_bool to_send_msg = KAL_FALSE;
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ deregistering_filter_cnt = ipc_deregistering_filter_cnt_s;
+ ipc_deregistering_filter_cnt_s = 0;
+ for (i = 0; i < deregistering_filter_cnt; i++) {
+ IPC_ASSERT(ipc_deregistering_filter_id_s[i] >= 0);
+ deregistering_filter_id[i] = ipc_deregistering_filter_id_s[i];
+ ipc_deregistering_filter_id_s[i] = IPC_INVALID_FILTER_ID;
+ }
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ for (i = 0; i < deregistering_filter_cnt; i++) {
+ IPC_ASSERT(deregistering_filter_id[i] >= 0);
+ ipc_filter_dereg(deregistering_filter_id[i]);
+ }
+
+#if defined(__IPF_SUPPORT__)
+ if(IPC_HW_DL_MODE == g_ipc_dl_mode){
+ ipc_filter_chk_sw_path();
+ }
+#endif
+
+ ipc_filter_list_dump_all();
+
+ /* If retry list is not NULL, insert retry ids back to ipc_deregistering_filter_id_s*/
+ if (ipc_retry_deregistering_filter_cnt_s != 0) {
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ to_send_msg = (0 == ipc_deregistering_filter_cnt_s);
+ for (i = 0; i < ipc_retry_deregistering_filter_cnt_s; i++) {
+ IPC_ASSERT(ipc_retry_deregistering_filter_id_s[i] >= 0);
+ ipc_deregistering_filter_id_s[ipc_deregistering_filter_cnt_s] = ipc_retry_deregistering_filter_id_s[i];
+ ipc_retry_deregistering_filter_id_s[i] = IPC_INVALID_FILTER_ID;
+ ipc_deregistering_filter_cnt_s++;
+ }
+ ipc_retry_deregistering_filter_cnt_s = 0;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ if (to_send_msg) {
+ ipc_deregister_filter_req_struct_t *req_msg_p = NULL;
+ ilm_struct ilm = {0};
+
+ req_msg_p = (ipc_deregister_filter_req_struct_t *) construct_local_para(sizeof(ipc_deregister_filter_req_struct_t), TD_RESET);
+ IPC_ASSERT(req_msg_p);
+
+ req_msg_p->filter_id = IPC_INVALID_FILTER_ID;
+
+ ilm.src_mod_id = IPCORE_SRC_MOD;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.msg_id = MSG_ID_IPCORE_DEREGISTER_FILTER_REQ;
+ ilm.local_para_ptr = (local_para_struct *)req_msg_p;
+ ilm.peer_buff_ptr = NULL;
+ ilm.sap_id = IPCORE_SAP;
+
+ /* Be careful that this message should send to IPcore's external queue, */
+ /* Otherwise, it will block in infinite loop for processing internal message. */
+ msg_send_ext_queue(&ilm);
+
+ } else {
+ /* Dump filter structure (ILM like) when registering ILM aggregated. */
+ ipc_deregister_filter_req_struct_t tmp;
+ ipc_deregister_filter_req_struct_t *req_msg_p = &tmp;
+
+ req_msg_p->msg_len = sizeof(ipc_deregister_filter_req_struct_t);
+ req_msg_p->filter_id = IPC_INVALID_FILTER_ID;
+
+ dhl_log_primitive6(IPCORE_SRC_MOD,
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_DEREGISTER_FILTER_REQ, /* msg_id */
+ (local_para_struct *) req_msg_p, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ }
+}
+
+static INLINE ipc_pkt_do_filter_result_e ipc_pkt_do_one_filter(kal_bool uplink,
+ kal_uint8 ip_type,
+ ipc_packet_info_t *packet_info,
+ ipc_filter_t *filter,
+ kal_uint32 pdn_id,
+ kal_uint32 netif_id,
+ kal_uint8 ebi_info,
+ ipc_filter_t **matched_filter,
+ ipc_filter_info_t *filter_info)
+{
+ ipc_pkt_do_filter_result_e ret;
+ ipc_match_result_e matched = KAL_FALSE;
+
+ /* Check if its the Wild Card filter */
+ if (_FEATURES_CONTAIN(&filter->rules, WC)) {
+ goto filter_matched;
+ }
+
+ /* PDN ID is only valid for downlink filter */
+ if ((KAL_FALSE == uplink) && _RULES_CONTAIN(&filter->rules, PDN_ID) && pdn_id != filter->rules.pdn_id) {
+ ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ goto done;
+ /* Skip the filter if PDN ID mismatched. */
+ }
+
+ if (_RULES_CONTAIN(&filter->rules, NETIF_ID) && netif_id != filter->rules.netif_id) {
+ ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ goto done;
+ /* Skip the filter if Network interface ID mismatched. */
+ }
+
+ /*
+ * 1. ebi is only valid for downlink filter
+ * 2. (2013/11/4) According to UPCM comment, EBI is only brought in first GPD of GPD list.
+ * 3. (2015/1/14) EBI info in the 1st GPD is recorded before filtering. (saved in ebi_info)
+ */
+ if ((KAL_FALSE == uplink) && _RULES_CONTAIN(&filter->rules, EBI) && ebi_info != 0xff && ebi_info != filter->rules.ebi) {
+ ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ goto done;
+ }
+
+ do {
+ /* Check for IP version : single byte check, no content dividing issue */
+ if (IPC_IP_TYPE_IPV4 == ip_type) {
+ if (_RULES_CONTAIN_IPV4(&filter->rules)) {
+ matched = ipc_filter_match_ipv4_rules(&filter->rules, packet_info);
+ }
+ } else {
+ if (_RULES_CONTAIN_IPV6(&filter->rules)) {
+ matched = ipc_filter_match_ipv6_rules(&filter->rules, packet_info);
+ }
+ }
+ } while (0);
+
+ if (!matched) {
+ ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ goto done;
+ }
+
+filter_matched:
+ hif_data_trace(MD_TRC_IPC_GE_FILTER_RULE_MATCHED, 0, &filter->rules, filter->rules.features, filter->rules.valid_fields, matched);
+
+ if (0 != (matched & IPC_MATCH_RESULT_FRAG_MATCHED)) {
+ /*
+ * Handle "FRAG_MATCHED" fragment packets.
+ * Note that the filter should be set to support fragment.
+ */
+ IPC_ASSERT(_FEATURES_CONTAIN(&filter->rules, FRAG));
+
+ *matched_filter = filter;
+
+ ret = IPC_PKT_DO_FILTER_HANDLE_FRAG;
+ goto done;
+ }
+
+ if (_FEATURES_CONTAIN(&filter->rules, BWM)) {
+ /* For BWM filter, there is no filter callback funtion, so it's not necessary to cache filter info. */
+
+ ret = IPC_PKT_DO_FILTER_BWM_MATCHED;
+ goto done;
+ }
+
+ *matched_filter = filter;
+
+ if (KAL_TRUE == filter->callback_with_info) {
+ /* Fill filter_info */
+ ipc_netif_t *netif;
+
+ kal_mem_set(filter_info, 0, sizeof(ipc_filter_info_t));
+ filter_info->netif_id = netif_id;
+
+ netif = ipc_find_netif(netif_id);
+ if (netif) {
+ filter_info->ip_id = ipc_map_netif_to_ip_id(netif);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ } else {
+ filter_info->ip_id = -1;
+ }
+
+ /*
+ * 1. ebi is only valid for downlink filter
+ * 2. (2013/11/4) According to UPCM comment, EBI is only brought in first GPD of GPD list.
+ */
+ if (KAL_FALSE == uplink) {
+
+ if (0xFF == ebi_info) {
+ filter_info->ebi = -1;
+ } else {
+ filter_info->ebi = ebi_info;
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(filter_info->ebi, filter_info->proto_idx);
+ IPC_UNMASK_PROTOID_FROM_PDNID(filter_info->ebi);
+ }
+ } else {
+ filter_info->ebi = -1;
+ }
+
+ /* (2014/11/11) Based on LTECSR's requirement, carry RTP data_offset info to them. */
+ filter_info->data_offset = packet_info->data_offset;
+ }
+
+ ret = IPC_PKT_DO_FILTER_MATCHED;
+ goto done;
+
+done :
+ if (_FEATURES_CONTAIN(&filter->rules, CLONE) && (IPC_PKT_DO_FILTER_MATCHED == ret)) {
+ ret = IPC_PKT_DO_FILTER_HANDLE_CLONE;
+ hif_trace_info(IPC_TR_FILTER_MATCHED_CLONED);
+ }
+
+ return ret;
+}
+
+static INLINE ipc_pkt_do_filter_result_e ipc_pkt_do_filter(kal_bool uplink,
+ ipc_filter_list_t **fls_set_p,
+ kal_uint32 fls_set_cnt,
+ kal_uint8 session_type,
+ kal_uint32 pdn_id,
+ kal_uint32 netif_id,
+ kal_uint8 ebi_info, /*< for record ebi, which is saved in the 1st GPD */
+ ipc_pkt_des_t *packet_des)
+{
+ ipc_filter_list_t *filter_list = NULL;
+ kal_uint8 filter_list_type = 0;
+ ipc_filter_t *filter = NULL;
+ kal_uint32 fls_idx = 0;
+ ipc_pkt_do_filter_result_e ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ kal_uint8 dpfm_rule_id = 0;
+ kal_uint8 ip_type = session_type;
+
+ /* Alias local parameter */
+ kal_uint8 *ip_packet = packet_des->packet;
+ kal_uint32 packet_len = packet_des->packet_len;
+ qbm_gpd *curr_gpd = packet_des->gpd;
+ qbm_gpd *curr_bd = packet_des->bd;
+ ipc_filter_t **matched_filter = packet_des->matched_filter;
+ ipc_filter_info_t *filter_info = packet_des->filter_info;
+ ipc_packet_info_t *packet_info = packet_des->packet_info;
+ upcm_did *did = packet_des->did;
+ kal_uint32 pkt_start_si_idx = packet_des->pkt_start_idx;
+ kal_bool get_pkt_info = packet_des->is_packet_info; //No need to parse packet again if TRUE
+
+#if (IPC_DL_INVALID_LEN_DROP_EN)
+ if ((!uplink) && (packet_len > ipc_dl_valid_packet_len_s)) {
+ ret = IPC_PKT_DO_FILTER_INVALID_LEN;
+ goto done;
+ }
+#endif
+
+ filter_list = NULL; // init per GPD start
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ /*
+ * When MD Direct Tethering is activated, we need packet_info for every packets.
+ */
+ if (IPC_DPFM_IS_ACTIVE()) {
+
+ if(!get_pkt_info && ipc_dpfm_need_pkt_info(uplink, packet_des))
+ {
+ /* get packet info */
+ if (IPC_PKT_DES_TYPE_GPD == packet_des->des_type) {
+ IPC_ASSERT(ip_packet && curr_gpd);
+ ipc_get_packet_info_gpd(ip_packet, curr_gpd, curr_bd, packet_info);
+ } else if (IPC_PKT_DES_TYPE_DID == packet_des->des_type) {
+ IPC_ASSERT(ip_packet && did);
+ ipc_get_packet_info_did(ip_packet, did, pkt_start_si_idx, packet_info);
+ } else {
+ IPC_ASSERT(ip_packet);
+ ipc_get_packet_info(ip_packet, packet_len, packet_info);
+ }
+
+ get_pkt_info = KAL_TRUE; /* already get info, get info GPD */
+ }
+
+ /* Check if the packet should be tracked (UL only)*/
+ if (uplink) {
+ HIF_SWLA_START("IM1");
+ IPC_DPFM_TRACK_PACKET(uplink, packet_des, netif_id);
+ HIF_SWLA_STOP("IM1");
+ }
+ }
+#endif
+
+ for (fls_idx = 0; fls_idx < fls_set_cnt; fls_idx++) {
+ filter_list = fls_set_p[fls_idx];
+
+ if (!filter_list || 0 == filter_list->count) {
+ continue; /* Skip empty filter list. */
+ }
+
+ filter_list_type = filter_list->ip_type;
+
+ if (IPC_IP_TYPE_IPV4 == session_type) {
+ if (IPC_IP_TYPE_IPV4 != filter_list_type) {
+ continue; /* Skip the filter list if IP type mismatched. */
+ }
+ } else if (IPC_IP_TYPE_IPV6 == session_type) {
+ if (IPC_IP_TYPE_IPV6 != filter_list_type) {
+ continue; /* Skip the filter list if IP type mismatched. */
+ }
+ }
+
+ if (KAL_FALSE == get_pkt_info) {
+ /* get packet info */
+ if (IPC_PKT_DES_TYPE_GPD == packet_des->des_type) {
+ IPC_ASSERT(ip_packet && curr_gpd);
+ get_pkt_info = ipc_get_packet_info_gpd(ip_packet, curr_gpd, curr_bd, packet_info);
+ } else if (IPC_PKT_DES_TYPE_DID == packet_des->des_type) {
+ IPC_ASSERT(ip_packet && did);
+ get_pkt_info = ipc_get_packet_info_did(ip_packet, did, pkt_start_si_idx, packet_info);
+ } else {
+ IPC_ASSERT(ip_packet);
+ get_pkt_info = ipc_get_packet_info(ip_packet, packet_len, packet_info);
+ }
+
+ if (get_pkt_info) {
+ packet_des->is_packet_info = KAL_TRUE;
+ }
+ }
+
+ for (filter = filter_list->filter_head;
+ filter;
+ filter = filter->next_filter_map[ipc_next_filter_hash(filter_list_type)]) {
+
+ ret = ipc_pkt_do_one_filter(uplink,
+ ip_type,
+ packet_info,
+ filter,
+ pdn_id,
+ netif_id,
+ ebi_info,
+ matched_filter,
+ filter_info);
+ #ifdef __TEMP_MDDP_WH_SUPPORT__
+ /* If filter feature contains IPV6_MDT, skip quick filtering */
+ if ((_FEATURES_CONTAIN(&(filter->rules), IPV6_DPFM)) && (IPC_PKT_DO_FILTER_MATCHED == ret)) {
+ ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ goto dpfm_check_route;
+ }
+ #endif
+
+ if (_FEATURES_CONTAIN(&filter->rules, CUST_FILTER) && (IPC_PKT_DO_FILTER_MATCHED == ret)) {
+ if (KAL_FALSE == filter->cust_cbk_func(packet_des->packet,
+ packet_des->packet_len,
+ filter->filter_id,
+ filter->p_cust_cbk_args)) {
+ ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ }
+ hif_data_trace(MD_TRC_IPC_TR_CUST_FILTER_CBK, packet_des->packet, packet_des->packet_len, filter->filter_id, ret);
+ }else if (_FEATURES_CONTAIN(&filter->rules, CUST_FILTER_W_INFO) && (IPC_PKT_DO_FILTER_MATCHED == ret)) {
+ if(IPC_PKT_DES_TYPE_DID == packet_des->des_type){
+ filter_info->src_desc_type = IPC_FI_DESC_TYPE_DID;
+ filter_info->src_desc_ptr = packet_des->did;
+ filter_info->src_desc_indx = packet_des->pkt_start_idx;
+ }else{
+ filter_info->src_desc_type = IPC_FI_DESC_TYPE_NONE;
+ }
+ if (KAL_FALSE == filter->cust_cbk_func(packet_des->packet,
+ packet_des->packet_len,
+ filter->filter_id,
+ filter_info)) {
+ ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ }
+ hif_data_trace(MD_TRC_IPC_TR_CUST_FILTER_CBK, packet_des->packet, packet_des->packet_len, filter->filter_id, ret);
+ }
+
+ if (IPC_PKT_DO_FILTER_NOT_MATCHED != ret) {
+ if (IPC_PKT_DO_FILTER_BWM_MATCHED == ret || IPC_PKT_DO_FILTER_HANDLE_CLONE == ret) {
+ goto dpfm_check_route;
+ } else {
+ goto done;
+ }
+ }
+ }
+ } /* for each filter_list, fls_idx */
+
+ ret = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ goto dpfm_check_route;
+
+dpfm_check_route :
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ /* For NOT_MATCHED & BWM_MATCHED cases, check DPFM routing before return. */
+
+ if (ipc_dpfm_check_route(uplink, packet_des, netif_id)) {
+ hif_data_trace(MD_TRC_IPC_DPFM_CHECK_ROUTE_MATCHED, uplink, session_type, packet_info->out_netif_id);
+ ret = IPC_PKT_DO_FILTER_DPFM_MATCHED;
+ }
+
+#endif
+ goto done;
+
+done :
+ ipc_filter_dump_pkt(uplink, packet_des, (kal_uint8) ret, dpfm_rule_id);
+ return ret;
+}
+
+static INLINE void ipc_call_filter_cbk(kal_bool uplink,
+ qbm_gpd *p_head,
+ qbm_gpd *p_tail,
+ kal_uint16 callback_gpd_data_len,
+ ipc_filter_t *filter,
+ ipc_filter_info_t *filter_info)
+{
+ IPC_ASSERT(p_head && p_tail);
+ IPC_ASSERT(filter);
+ IPC_ASSERT(filter_info);
+
+ hif_data_trace(MD_TRC_IPC_GE_FILTER_OUT_INFO, uplink, filter->callback_context, filter->filter_id);
+ hif_data_trace(MD_TRC_IPC_GE_FILTER_OUT_GPD, uplink, p_head, p_tail, callback_gpd_data_len);
+
+ HIF_SWLA_START("IF1");
+
+ if (KAL_TRUE == filter->callback_with_info) {
+ ipc_filter_with_info_callback_t callback_func;
+
+ callback_func = (ipc_filter_with_info_callback_t)(filter->callback_func);
+ callback_func(filter_info, filter->callback_context, filter->filter_id, p_head, p_tail, (kal_uint32) callback_gpd_data_len);
+ } else {
+ ipc_filter_callback_t callback_func;
+
+ callback_func = (ipc_filter_callback_t) (filter->callback_func);
+ callback_func(filter->callback_context, filter->filter_id, p_head, p_tail, (kal_uint32) callback_gpd_data_len);
+ }
+
+ HIF_SWLA_STOP("IF1");
+}
+
+static INLINE kal_uint32 ipc_spd_do_filter(kal_bool uplink,
+ ipc_filter_list_t **fls_set_p,
+ kal_uint32 fls_set_cnt,
+ kal_uint8 session_type,
+ kal_uint32 pdn_id,
+ kal_uint32 netif_id,
+ kal_uint8 ebi_info, // for record ebi, which is saved in the 1st GPD
+ qbm_gpd *curr_gpd)
+{
+ kal_uint8 *ip_packet = NULL;
+ kal_uint32 length = 0;
+ ipc_filter_t *filter = NULL;
+ ipc_filter_info_t filter_info = {0};
+ ipc_packet_info_t packet_info = {0};
+ qbm_spd_pi *p_spd_pi = NULL;
+ qbm_spd_pie *p_spd_pie = NULL; // spd payload info element
+ qbm_spd_pie *p_prev_spd_pie = NULL;
+ kal_uint8 idx = 0;
+ kal_uint32 payload_len = 0;
+ kal_uint16 packet_num = 0;
+ kal_uint16 remain_packet_num = 0; // the num of packets not filtered out
+ ipc_pkt_do_filter_result_e result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ ipc_pkt_des_t packet_des = {0};
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ kal_uint8 dpfm_matched_num = 0;
+ kal_bool mirror_spd_pie_idx[QBM_SPD_MAX_PKTNUM];
+ kal_uint32 dpfm_out_netif_id = 0;
+
+ kal_mem_set(mirror_spd_pie_idx, 0, sizeof(mirror_spd_pie_idx));
+#endif
+ kal_uint8 ip_type = 0;
+
+ /* SPD only supports for downlink traffic. */
+ IPC_ASSERT(!uplink);
+
+ /* Init packet_des */
+ kal_mem_set(&packet_des, 0, sizeof(ipc_pkt_des_t));
+ packet_des.des_type = IPC_PKT_DES_TYPE_SPD;
+ packet_des.matched_filter = &filter;
+ packet_des.filter_info = &filter_info;
+ packet_des.packet_info = &packet_info;
+
+ ip_packet = QBM_DES_GET_DATAPTR(curr_gpd);
+ length = QBM_DES_GET_DATALEN(curr_gpd);
+ IPC_ASSERT(length > 0);
+ p_spd_pi = QBM_SPD_GET_PI((qbm_spd *) curr_gpd);
+ p_prev_spd_pie = NULL;
+
+ packet_num = QBM_SPD_PI_GET_PKTNUM(p_spd_pi);
+ IPC_ASSERT(packet_num > 0);
+
+ hif_data_trace(MD_TRC_IPC_GE_SPD_DO_FILTER, 0, curr_gpd, length, packet_num);
+ remain_packet_num = 0;
+ for (idx = 0; idx < packet_num; idx++) {
+ if (idx == 0) {
+ p_spd_pie = QBM_SPD_PI_GET_FIRST_PIE(p_spd_pi);
+ } else {
+ ip_packet = QBM_SPD_PAYLOAD_NEXT(ip_packet, payload_len);
+ p_spd_pie = QBM_SPD_PIE_NEXT(p_spd_pie);
+ IPC_ASSERT(p_spd_pie != NULL);
+ }
+
+ payload_len = QBM_SPD_PIE_GET_PAYLOAD_LEN(p_spd_pie);
+
+ /* Bypass the packets with IGR bit set. */
+ if (!QBM_SPD_PIE_GET_IGR(p_spd_pie)) {
+ IPC_ASSERT(payload_len > 0);
+
+ /* Fill packet_des */
+ packet_des.packet = ip_packet;
+ packet_des.packet_len = payload_len;
+ packet_des.ip_type = ip_type = (IPC_HDR_IS_V4(ip_packet)) ? IPC_IP_TYPE_IPV4 : IPC_IP_TYPE_IPV6;
+
+ result = ipc_pkt_do_filter(uplink, fls_set_p, fls_set_cnt, ip_type, pdn_id, netif_id, ebi_info, &packet_des);
+
+ if ((IPC_PKT_DO_FILTER_MATCHED == result) || (IPC_PKT_DO_FILTER_INVALID_LEN == result) || (IPC_PKT_DO_FILTER_DPFM_MATCHED == result)) {
+ hif_data_trace(MD_TRC_IPC_GE_SPD_ENTRY_IGR_INFO, uplink, curr_gpd, idx, payload_len);
+
+ QBM_SPD_PIE_SET_IGR(p_spd_pie);
+ length -= payload_len;
+
+ if (QBM_SPD_PIE_GET_EOL(p_spd_pie) && (NULL != p_prev_spd_pie)) {
+ /* Move the EOL bit to the previous SPD entry */
+ IPC_ASSERT(remain_packet_num > 0);
+
+ QBM_SPD_PIE_SET_EOL(p_prev_spd_pie);
+ }
+
+ if (IPC_PKT_DO_FILTER_MATCHED == result) {
+ qbm_gpd *callback_gpd_p = NULL;
+ kal_uint8 *callback_gpd_data_p = NULL;
+ /*
+ * 1. A packet is indivisible from the SPD, so we need to allocate a GPD for it.
+ * 2. Uplink SPD is not used.
+ * 3. (2014/8/13 Stan.Chen) Use QBM_TYPE_NET_DL, if it use out, use QBM_TYPE_HIF_DL instead.
+ * 4. (2016/10/14 Wen-Jiunn.Liu) QBM_TYPE_HIF_DL is not provided anymore in Gen93.
+ */
+ if (1 != qbmt_alloc_q_no_tail((KAL_TRUE == uplink) ? QBM_TYPE_NET_UL_SHRD : QBM_TYPE_NET_DL,
+ 1,
+ (void**)&callback_gpd_p,
+ (void**) &callback_gpd_p)) {
+
+ hif_trace_error(IPC_TR_DO_FILTER_ALLOC_GPD_NG, uplink, 0, curr_gpd, idx, payload_len);
+ continue;
+ }
+
+ /* Copy data from SPD payload to output GPD */
+ IPC_ASSERT(callback_gpd_p);
+ ipc_utils_set_gpd_datalen(callback_gpd_p, payload_len, (void**) &callback_gpd_data_p);
+ IPC_ASSERT(callback_gpd_data_p);
+
+ QBM_CACHE_INVALID(ip_packet, payload_len);
+ kal_mem_cpy(callback_gpd_data_p, ip_packet, payload_len);
+ QBM_CACHE_FLUSH(callback_gpd_data_p, payload_len);
+
+ /* Forward GPD by filter's callback function */
+ ipc_call_filter_cbk(uplink, callback_gpd_p, callback_gpd_p, payload_len, filter, &filter_info);
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ } else if (IPC_PKT_DO_FILTER_DPFM_MATCHED == result) {
+ dpfm_matched_num++;
+ mirror_spd_pie_idx[idx] = KAL_TRUE;
+ dpfm_out_netif_id = packet_info.out_netif_id;
+#endif
+ }
+ } else {
+ remain_packet_num++;
+ p_prev_spd_pie = p_spd_pie;
+ }
+ }
+
+ if (QBM_SPD_PIE_GET_EOL(p_spd_pie)) {
+ /* end of packet list */
+ break;
+ }
+ }
+
+ /* If there is no remain packet, then the SPD's Transfer Data Length should be zero. */
+ IPC_ASSERT((0 != remain_packet_num) || (0 == length));
+
+ /* Update SPD's Transfer Data Length */
+ QBM_DES_SET_DATALEN(curr_gpd, length);
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ /* Mirror the SPD if there is any packet routing to direct path. */
+ if (dpfm_matched_num) {
+ qbm_spd *p_mirror_spd;
+
+ p_mirror_spd = ipc_dpfm_mirror_spd((qbm_spd *)curr_gpd, mirror_spd_pie_idx, dpfm_matched_num);
+ IPC_ASSERT(p_mirror_spd);
+
+ ipc_dpfm_push_gpd_to_routing_queue(uplink, dpfm_out_netif_id, (qbm_gpd *)p_mirror_spd);
+ }
+#endif
+
+ return remain_packet_num;
+}
+
+static INLINE kal_uint16 ipc_do_filter(kal_bool uplink,
+ ipc_filter_list_t **fls_set_p,
+ kal_uint32 fls_set_cnt,
+ kal_uint8 session_type,
+ kal_uint32 pdn_id,
+ kal_uint32 netif_id,
+ qbm_gpd **pp_head,
+ qbm_gpd **pp_tail)
+{
+ qbm_gpd *first_gpd = NULL;
+ qbm_gpd *last_gpd = NULL;
+ qbm_gpd *curr_gpd = NULL;
+ qbm_gpd *prev_gpd = NULL;
+ qbm_gpd *next_gpd = NULL;
+ qbm_gpd *curr_bd = NULL;
+ kal_bool end_of_list = KAL_FALSE;
+ kal_uint8 ebi_info = 0; // for record ebi, which is saved in the 1st GPD
+ kal_uint8 *ip_packet = NULL;
+ kal_uint32 length = 0;
+ ipc_filter_t *filter = NULL;
+ ipc_filter_info_t filter_info = {0};
+ ipc_packet_info_t packet_info = {0};
+ kal_bool spd = KAL_FALSE;
+ kal_uint8 remain_packet_num = 0; // the num of packets not filtered out
+ kal_uint32 total_remain_packet_num = 0; // the total num of packets not filtered out
+ ipc_pkt_do_filter_result_e result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ ipc_pkt_des_t packet_des = {0};
+ kal_uint8 ip_type = 0;
+ kal_uint8 idx = (KAL_TRUE == uplink) ? 1 : 0;
+
+ first_gpd = *pp_head;
+ last_gpd = *pp_tail;
+
+ if (first_gpd) {
+ ebi_info = ((upcm_dlvr_dl_info_t *) QBM_DES_GET_SW_CTRL_FIELD(first_gpd))->ebi;
+ }
+
+ prev_gpd = NULL;
+ end_of_list = (NULL == first_gpd);
+
+ /* Init packet_des */
+ kal_mem_set(&packet_des, 0, sizeof(ipc_pkt_des_t));
+ packet_des.des_type = IPC_PKT_DES_TYPE_GPD;
+ packet_des.matched_filter = &filter;
+ packet_des.filter_info = &filter_info;
+ packet_des.packet_info = &packet_info;
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ {
+ /*
+ * Check ipc_dpfm_packet_routing_queue has been set to 0 or not.
+ * It should be done before calling ipc_do_filter().
+ */
+ kal_uint32 i;
+
+ for (i = 0; i < IPC_MAX_NETIF_CNT; i++) {
+ IPC_ASSERT( (ipc_dpfm_packet_routing_queue[idx][i].first_gpd == NULL) &&
+ (ipc_dpfm_packet_routing_queue[idx][i].last_gpd == NULL) );
+ }
+ IPC_ASSERT(!ipc_dpfm_queue_non_empty[idx]);
+ }
+#endif
+
+ for (curr_gpd = first_gpd; curr_gpd && !end_of_list; curr_gpd = next_gpd) {
+ spd = (QBM_DES_GET_PDT(curr_gpd) != 0);
+
+ next_gpd = QBM_DES_GET_NEXT(curr_gpd);
+ end_of_list = (curr_gpd == last_gpd);
+ result = IPC_PKT_DO_FILTER_NONE; // reset for each GPD
+
+ if (spd) {
+ /*
+ * It's SPD (PDT != 0)
+ * Need to traverse all of the packets in it.
+ */
+ remain_packet_num = ipc_spd_do_filter(uplink, fls_set_p, fls_set_cnt, session_type, pdn_id, netif_id, ebi_info, curr_gpd);
+
+ if (0 == remain_packet_num) {
+ /*
+ * All packets of the SPD were filtered out,
+ * extract the SPD from the list.
+ */
+ ipc_utils_gpd_list_del_entry(&first_gpd, &last_gpd, &curr_gpd, &prev_gpd, &next_gpd);
+
+ /* Destroy SPD since there is no packet remained. */
+ hif_data_trace(MD_TRC_IPC_GE_SPD_ALL_IGR_INFO, uplink, curr_gpd, QBM_SPD_PI_GET_PKTNUM(QBM_SPD_GET_PI((qbm_spd *) curr_gpd)));
+ qbmt_dest_q(curr_gpd, curr_gpd);
+ } else {
+ /* Update prev_gpd if the curr_gpd is not deleted from the list. */
+ prev_gpd = curr_gpd;
+ total_remain_packet_num += remain_packet_num;
+ }
+ } else {
+ /*
+ * It's GPD (PDT == 0)
+ * There is only one packet, so just do it.
+ */
+ /*
+ * For DL 3G packet, packet content might be divided in several pieces in BD list.
+ * To handle this situation, IPCore MUST aware this during packet content checking.
+ */
+ if (KAL_TRUE != ipc_filter_get_ip_pkt(curr_gpd, &curr_bd, &ip_packet, &length)) {
+ hif_trace_error(IPC_TR_DO_FILTER_INVALID_GPD, curr_gpd);
+ result = IPC_PKT_DO_FILTER_ERROR;
+ } else {
+ /* Fill packet_des */
+ packet_des.packet = ip_packet;
+ packet_des.packet_len = length;
+ packet_des.gpd = curr_gpd;
+ packet_des.bd = curr_bd;
+ packet_des.is_packet_info = KAL_FALSE;
+ packet_des.ip_type = ip_type = (IPC_HDR_IS_V4(ip_packet)) ? IPC_IP_TYPE_IPV4 : IPC_IP_TYPE_IPV6;
+
+ result = ipc_pkt_do_filter(uplink, fls_set_p, fls_set_cnt, ip_type, pdn_id, netif_id, ebi_info, &packet_des);
+ }
+
+ if (IPC_PKT_DO_FILTER_MATCHED == result) {
+ /* Delete curr_gpd from the list */
+ ipc_utils_gpd_list_del_entry(&first_gpd, &last_gpd, &curr_gpd, &prev_gpd, &next_gpd);
+
+ {
+ /* Forward "curr_gpd" to callback function */
+ qbm_gpd *callback_gpd_p;
+
+ length = QBM_DES_GET_DATALEN(curr_gpd);
+
+ if (KAL_TRUE == uplink) { /* For UL GPD, NO unite issue */
+ callback_gpd_p = curr_gpd;
+ } else {
+ /* For DL GPD, do unite before actually calling callback functions */
+ ipc_utils_unite_gpd(uplink, curr_gpd, &callback_gpd_p);
+
+ if (callback_gpd_p != curr_gpd) {
+ hif_data_trace(MD_TRC_IPC_GE_DO_FILTER_GPD_UPDATE, uplink, curr_gpd, callback_gpd_p,
+ (callback_gpd_p) ? (QBM_DES_GET_DATALEN(callback_gpd_p)) : 0);
+
+ /* Always destroy "curr_gpd" */
+ QBM_DES_SET_NEXT(curr_gpd, NULL);
+ qbmt_dest_q(curr_gpd, curr_gpd);
+ }
+
+ if (!callback_gpd_p) {
+ hif_data_trace(MD_TRC_IPC_GE_UNITE_FAIL_DROP, length, curr_gpd);
+ hif_data_trace(MD_TRC_IPC_GE_UNITE_FAIL_DROP_INFO, filter->filter_id, curr_gpd, pdn_id, netif_id);
+ continue;
+ }
+ }
+
+ /* Forward GPD by filter's callback function */
+ ipc_call_filter_cbk(uplink, callback_gpd_p, callback_gpd_p, length, filter, &filter_info);
+ }
+ } else if (IPC_PKT_DO_FILTER_HANDLE_FRAG == result) {
+ qbm_gpd *callback_gpd_p;
+ ipc_frag_refilter_info_t info;
+
+ /* Delete curr_gpd from the list */
+ ipc_utils_gpd_list_del_entry(&first_gpd, &last_gpd, &curr_gpd, &prev_gpd, &next_gpd);
+ ipc_utils_unite_gpd(uplink, curr_gpd, &callback_gpd_p);
+
+ if (callback_gpd_p != curr_gpd) {
+ /* Always destroy "curr_gpd" */
+ QBM_DES_SET_NEXT(curr_gpd, NULL);
+ qbmt_dest_q(curr_gpd, curr_gpd);
+ }
+
+ info.netif_id = netif_id;
+ info.pdn_id = pdn_id;
+ info.uplink = KAL_FALSE;
+ info.is_pkt_info = KAL_TRUE;
+ info.packet_info = &packet_info;
+ info.filter_id = filter->filter_id;
+ info.filter_magic_number = ipc_filter_magic_number_s;
+ ((upcm_dlvr_dl_info_t *) QBM_DES_GET_SW_CTRL_FIELD(callback_gpd_p))->ebi = ebi_info;
+
+ ipc_fragment_defrag(callback_gpd_p, &info, (IPC_HDR_IS_V4(ip_packet)) ? IPC_IP_TYPE_IPV4 : IPC_IP_TYPE_IPV6);
+
+ } else if (IPC_PKT_DO_FILTER_INVALID_LEN == result) {
+ /* Delete curr_gpd from the list & destroy the GPD */
+ ipc_utils_gpd_list_del_entry(&first_gpd, &last_gpd, &curr_gpd, &prev_gpd, &next_gpd);
+ qbmt_dest_q(curr_gpd, curr_gpd);
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ } else if (IPC_PKT_DO_FILTER_DPFM_MATCHED == result) {
+ /* Delete curr_gpd from the list & push the GPD to DPFM queue */
+ ipc_utils_gpd_list_del_entry(&first_gpd, &last_gpd, &curr_gpd, &prev_gpd, &next_gpd);
+ ipc_dpfm_push_gpd_to_routing_queue(uplink, packet_info.out_netif_id, curr_gpd);
+#endif
+ } else {
+ /* Update prev_gpd if the curr_gpd is not deleted from the list. */
+ prev_gpd = curr_gpd;
+ total_remain_packet_num++;
+ total_remain_packet_num |= IPC_HAS_GPD_MASK;
+ }
+ }
+
+ } /* for each GPD, curr_gpd */
+
+ *pp_head = first_gpd;
+ *pp_tail = last_gpd;
+
+ return total_remain_packet_num;
+}
+
+kal_uint16 ipc_do_ul_filter(kal_uint8 session_type,
+ kal_uint32 netif_id,
+ qbm_gpd **pp_head,
+ qbm_gpd **pp_tail)
+{
+ static ipc_filter_list_t *fls_set[] = {ipc_ul_v4_filter_list_s,
+ ipc_ul_v6_filter_list_s};
+
+ return ipc_do_filter(KAL_TRUE, fls_set, sizeof(fls_set) / sizeof(ipc_filter_list_t*), session_type, 0, netif_id, pp_head, pp_tail);
+}
+
+kal_uint16 ipc_do_dl_filter(kal_uint8 session_type,
+ kal_uint32 netif_id,
+ kal_uint32 pdn_id,
+ qbm_gpd **pp_head,
+ qbm_gpd **pp_tail)
+{
+ static ipc_filter_list_t *fls_set[] = {ipc_dl_v4_filter_list_s,
+ ipc_dl_v6_filter_list_s};
+
+ return ipc_do_filter(KAL_FALSE, fls_set, sizeof(fls_set) / sizeof(ipc_filter_list_t*), session_type, pdn_id, netif_id, pp_head, pp_tail);
+}
+
+void ipc_frag_refilter(kal_uint8 ip_type,
+ ipc_frag_refilter_info_t *info,
+ qbm_gpd *p_head,
+ qbm_gpd *p_tail)
+{
+ static ipc_filter_list_t *fls_ul_set[] = {ipc_ul_v4_filter_list_s,
+ ipc_ul_v6_filter_list_s};
+ static ipc_filter_list_t *fls_dl_set[] = {ipc_dl_v4_filter_list_s,
+ ipc_dl_v6_filter_list_s};
+
+ ipc_pkt_do_filter_result_e match_result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ kal_uint8 ebi_info = 0;
+ qbm_gpd *curr_bd = NULL;
+ kal_uint8 *ip_packet = NULL;
+ kal_uint32 length = 0;
+ ipc_pkt_des_t packet_des = {0};
+ ipc_filter_t *filter = NULL;
+ ipc_filter_t *matched_filter = NULL;
+ ipc_filter_info_t filter_info = {0};
+
+ IPC_ASSERT(p_head && p_tail && info);
+
+ if (p_head) {
+ ebi_info = ((upcm_dlvr_dl_info_t *) QBM_DES_GET_SW_CTRL_FIELD(p_head))->ebi;
+ }
+
+ /* Set fragment to KAL_FALSE */
+ info->packet_info->fragment = KAL_FALSE;
+
+ /* Get packet and len*/
+ if (KAL_TRUE != ipc_filter_get_ip_pkt(p_head, &curr_bd, &ip_packet, &length)) {
+ IPC_ASSERT(KAL_FALSE);
+ }
+
+ /*
+ * If filter lists haven't been changed (magic number hasn't changed),
+ * do Quick-Refiltering: only match the original matched filter.
+ */
+ if ((info->filter_magic_number == ipc_filter_magic_number_s) &&
+ (IPC_INVALID_FILTER_ID != info->filter_id) && info->is_pkt_info == KAL_TRUE) {
+
+ filter = ipc_find_filter_by_id(ipc_filter_pool_s, info->filter_id);
+ if ((NULL != filter) && (IPC_INVALID_FILTER_ID != filter->filter_id)) {
+ match_result = ipc_pkt_do_one_filter(info->uplink, ip_type, info->packet_info, filter, info->pdn_id, info->netif_id, ebi_info, &matched_filter, &filter_info);
+
+ if (match_result) {
+ IPC_ASSERT(matched_filter == filter);
+ IPC_ASSERT(IPC_PKT_DO_FILTER_HANDLE_FRAG != match_result);
+
+ goto match_done;
+ }
+ }
+ }
+
+ /* Refiltering: go through all filters */
+
+ /* Init packet_des */
+ kal_mem_set(&packet_des, 0, sizeof(ipc_pkt_des_t));
+ packet_des.des_type = IPC_PKT_DES_TYPE_GPD;
+ packet_des.matched_filter = &filter;
+ packet_des.filter_info = &filter_info;
+ packet_des.packet_info = info->packet_info;
+
+ if (info->is_pkt_info == KAL_FALSE) {
+ IPC_ASSERT(ip_packet && p_head);
+ ipc_get_packet_info_gpd(ip_packet, p_head, curr_bd, packet_des.packet_info);
+ //Debug fragment, spi, protocol
+ } else {
+ /* Clear fragment indicator in packet_info */
+ packet_des.packet_info->fragment = KAL_FALSE;
+ }
+ packet_des.is_packet_info = KAL_TRUE; /* already get info, get info GPD */
+
+
+ /* Fill packet_des */
+ packet_des.packet = ip_packet;
+ packet_des.packet_len = length;
+ packet_des.gpd = p_head;
+ packet_des.bd = curr_bd;
+
+
+ if (info->uplink) {
+ match_result = ipc_pkt_do_filter(KAL_TRUE, fls_ul_set, sizeof(fls_ul_set) / sizeof(ipc_filter_list_t*), ip_type, info->pdn_id, info->netif_id, ebi_info, &packet_des);
+ } else {
+ match_result = ipc_pkt_do_filter(KAL_FALSE, fls_dl_set, sizeof(fls_dl_set) / sizeof(ipc_filter_list_t*), ip_type, info->pdn_id, info->netif_id, ebi_info, &packet_des);
+ }
+
+match_done:
+ if ((NULL != filter) && (IPC_PKT_DO_FILTER_MATCHED == match_result)) {
+ if (_FEATURES_CONTAIN(&filter->rules, CUST_FILTER)) {
+ if (KAL_FALSE == filter->cust_cbk_func(ip_packet,
+ length,
+ filter->filter_id,
+ filter->p_cust_cbk_args)) {
+ match_result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ }
+ }
+ hif_data_trace(MD_TRC_IPC_TR_CUST_FILTER_CBK, ip_packet, length, filter->filter_id, match_result);
+ }
+
+ switch (match_result) {
+ ipc_pkt_t pkt;
+
+ case IPC_PKT_DO_FILTER_MATCHED:
+ ipc_call_filter_cbk(info->uplink, p_head, p_tail, length, filter, &filter_info);
+ break;
+ case IPC_PKT_DO_FILTER_NOT_MATCHED:
+ case IPC_PKT_DO_FILTER_BWM_MATCHED:
+ pkt.buf_type = IPC_PKT_DES_TYPE_GPD;
+ pkt.head = p_head;
+ pkt.tail = p_tail;
+
+ if (info->uplink) {
+ ipc_send_ul_pkt_by_netif_id(&pkt, NULL, info->netif_id, ip_type);
+ } else {
+ ipc_send_dl_pkt_in_did_internal(&pkt, NULL, info->netif_id);
+ }
+ break;
+ case IPC_PKT_DO_FILTER_HANDLE_FRAG:
+ ipc_fragment_defrag(p_head, info, (IPC_HDR_IS_V4(ip_packet)) ? IPC_IP_TYPE_IPV4 : IPC_IP_TYPE_IPV6);
+ break;
+ default:
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+}
+
+void ipc_frag_send_pkt(kal_uint8 ip_type,
+ ipc_frag_refilter_info_t *info,
+ qbm_gpd *p_head,
+ qbm_gpd *p_tail)
+{
+ ipc_pkt_t pkt;
+
+ IPC_ASSERT(p_head && p_tail && info);
+
+ pkt.buf_type = IPC_PKT_DES_TYPE_GPD;
+ pkt.head = p_head;
+ pkt.tail = p_tail;
+
+ if (info->uplink) {
+ ipc_send_ul_pkt_by_netif_id(&pkt, NULL, info->netif_id, ip_type);
+ } else {
+ ipc_send_dl_pkt_in_did_internal(&pkt, NULL, info->netif_id);
+ }
+}
+
+static void ipc_filter_fwd_pkt_by_msg(msg_type msg_id,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_filter_t *filter = (ipc_filter_t *)context;
+ ipc_packet_filtered_req_t *req = NULL;
+
+ req = (ipc_packet_filtered_req_t *) construct_local_para(sizeof(ipc_packet_filtered_req_t), TD_RESET);
+ req->context = filter->module_context;
+ req->filter_id = filter_id;
+ req->head_gpd = head_gpd;
+ req->tail_gpd = tail_gpd;
+ req->length = length;
+
+ msg_send6(IPCORE_SRC_MOD, /* src mod id */
+ filter->module_id, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ msg_id, /* msg_id */
+ (local_para_struct *)req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+}
+
+static void ipc_filter_fwd_pkt_with_info_by_msg(msg_type msg_id,
+ ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_filter_t *filter = (ipc_filter_t *)context;
+ ipc_packet_filtered_with_info_req_t *req = NULL;
+
+ req = (ipc_packet_filtered_with_info_req_t *) construct_local_para(sizeof(ipc_packet_filtered_with_info_req_t), TD_RESET);
+ kal_mem_cpy(&(req->info), info_p, sizeof(ipc_filter_info_t));
+ req->context = filter->module_context;
+ req->filter_id = filter_id;
+ req->head_gpd = head_gpd;
+ req->tail_gpd = tail_gpd;
+ req->length = length;
+
+ msg_send6(IPCORE_SRC_MOD, /* src_mod_id */
+ filter->module_id, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ msg_id, /* msg_id */
+ (local_para_struct *)req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+}
+
+void ipc_filter_fwd_ul_pkt_by_msg(void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_filter_fwd_pkt_by_msg(MSG_ID_IPCORE_UL_PACKET_FILTERED_REQ,
+ context,
+ filter_id,
+ head_gpd,
+ tail_gpd,
+ length);
+}
+
+void ipc_filter_fwd_dl_pkt_by_msg(void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_filter_fwd_pkt_by_msg(MSG_ID_IPCORE_DL_PACKET_FILTERED_REQ,
+ context,
+ filter_id,
+ head_gpd,
+ tail_gpd,
+ length);
+}
+
+void ipc_filter_fwd_ul_pkt_with_info_by_msg(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_filter_fwd_pkt_with_info_by_msg(MSG_ID_IPCORE_UL_PACKET_FILTERED_WITH_INFO_REQ,
+ info_p,
+ context,
+ filter_id,
+ head_gpd,
+ tail_gpd,
+ length);
+}
+
+void ipc_filter_fwd_dl_pkt_with_info_by_msg(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_filter_fwd_pkt_with_info_by_msg(MSG_ID_IPCORE_DL_PACKET_FILTERED_WITH_INFO_REQ,
+ info_p,
+ context,
+ filter_id,
+ head_gpd,
+ tail_gpd,
+ length);
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions. (Gen93)
+ *----------------------------------------------------------------------------*/
+kal_uint16 ipc_meta_do_filter(kal_uint8 ip_type,
+ kal_uint32 netif_id,
+ lhif_meta_tbl_t *meta,
+ ipc_dpfm_mirror_des_t *dpfm_mirror_des,
+ ipc_pkt_des_t *p_packet_des)
+{
+ kal_uint8 *ip_packet = NULL;
+ kal_uint32 length = 0;
+ ipc_pkt_do_filter_result_e result;
+ ipc_filter_t *matched_filter = NULL; /*< alias */
+
+ static ipc_filter_list_t *fls_set[] = {ipc_ul_v4_filter_list_s,
+ ipc_ul_v6_filter_list_s};
+
+ IPC_ASSERT(NULL != p_packet_des);
+
+ /* Alias parameter */
+ ip_packet = p_packet_des->packet;
+ length = p_packet_des->packet_len;
+
+ result = ipc_pkt_do_filter(KAL_TRUE, fls_set, sizeof(fls_set) / sizeof(ipc_filter_list_t*), ip_type, 0, netif_id, 0, p_packet_des);
+ matched_filter = *(p_packet_des->matched_filter); //alias
+
+ switch (result) {
+ qbm_gpd *callback_gpd_p = NULL;
+ kal_uint8 *callback_gpd_data_p = NULL;
+
+ case IPC_PKT_DO_FILTER_MATCHED:
+ case IPC_PKT_DO_FILTER_HANDLE_FRAG:
+ case IPC_PKT_DO_FILTER_HANDLE_CLONE:
+ /*
+ * 1. A packet is indivisible from the meta, so we need to allocate a GPD for it.
+ * 2. Meta is for uplink only.
+ */
+ if (1 != qbmt_alloc_q_no_tail(QBM_TYPE_NET_UL_SHRD, 1, (void**) &callback_gpd_p, (void**) &callback_gpd_p)) {
+ hif_trace_error(IPC_TR_META_DO_FILTER_ALLOC_GPD_NG, KAL_FALSE, meta);
+ meta->ignore = 1;
+ IPC_FREE_META_VRB(meta);
+ return 0;
+ }
+
+ /* Copy data from UL META to output GPD */
+ IPC_ASSERT(callback_gpd_p);
+ ipc_utils_set_gpd_datalen(callback_gpd_p, length, (void**) &callback_gpd_data_p);
+ IPC_ASSERT(callback_gpd_data_p);
+
+ QBM_CACHE_INVALID(ip_packet, length);
+ kal_mem_cpy(callback_gpd_data_p, ip_packet, length);
+ QBM_CACHE_FLUSH(callback_gpd_data_p, length);
+
+ if ((IPC_PKT_DO_FILTER_MATCHED == result) || (IPC_PKT_DO_FILTER_HANDLE_CLONE == result)) {
+ /* Forward GPD by filter's callback function */
+ ipc_call_filter_cbk(KAL_TRUE, callback_gpd_p, callback_gpd_p, length, matched_filter, p_packet_des->filter_info);
+ } else {
+ /* Forward GPD to ipc_fragment sub-module to handle fragment. */
+ ipc_frag_refilter_info_t info;
+
+ info.netif_id = netif_id;
+ info.pdn_id = IPC_INVALID_PDN_ID;
+ info.uplink = KAL_TRUE;
+ info.is_pkt_info = KAL_TRUE;
+ info.packet_info = p_packet_des->packet_info;
+ info.filter_id = matched_filter->filter_id;
+ info.filter_magic_number = ipc_filter_magic_number_s;
+
+ ipc_fragment_defrag(callback_gpd_p, &info, ((ip_type == IPC_IP_TYPE_IPV4) ? KAL_TRUE : KAL_FALSE));
+ }
+
+ if (IPC_PKT_DO_FILTER_HANDLE_CLONE == result) {
+ return 1;
+ } else {
+ meta->ignore = KAL_TRUE;
+ IPC_FREE_META_VRB(meta);
+ return 0;
+ }
+
+ case IPC_PKT_DO_FILTER_INVALID_LEN:
+ meta->ignore = KAL_TRUE;
+ IPC_FREE_META_VRB(meta);
+ return 0;
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ case IPC_PKT_DO_FILTER_DPFM_MATCHED: {
+ ipc_packet_info_t* p_packet_info;
+ p_packet_info = p_packet_des->packet_info;
+
+ /* DPFM will set meta ignore and release buffer for delelte filter ACK packet. */
+ if (1 != meta->ignore) {
+ /* Because LAN NETIF is not bound, so HW can't fill corresponding PDN info into meta*/
+ ipc_dpfm_set_pdn_id_in_meta(dpfm_mirror_des, meta, p_packet_info->out_netif_id, ip_type);
+ }
+ }
+ return 0;
+#endif
+
+ case IPC_PKT_DO_FILTER_NOT_MATCHED:
+ case IPC_PKT_DO_FILTER_BWM_MATCHED:
+ default:
+ return 1;
+ }
+}
+
+kal_uint16 ipc_did_do_filter(kal_uint8 session_type,
+ kal_uint32 netif_id,
+ kal_uint32 pdn_id,
+ upcm_did *did)
+{
+ kal_uint8 *ip_packet;
+ kal_uint8 ip_type;
+ kal_uint32 packet_len;
+ ipc_filter_t *filter;
+ ipc_filter_info_t filter_info;
+ ipc_packet_info_t packet_info;
+ ipc_pkt_do_filter_result_e result;
+ ipc_pkt_des_t packet_des;
+ kal_uint32 pkt_num, seg_num;
+ kal_uint16 base_psn;
+ kal_uint8 remain_pkt_cnt = 0;
+ kal_uint8 total_pkt_cnt = 0;
+ kal_uint8 remain_seg_cnt = 0;
+ upcm_did_si *sit;
+ upcm_did_si *curr_si;
+ kal_uint32 pkt_start_idx;
+ kal_uint32 curr_idx = 0;
+ kal_bool uplink = KAL_FALSE; // DID is for uplink only.
+ kal_uint8 comm_buff[16];// max is ipv6 src/dest addr
+ kal_uint8 *comm_continuous_p = NULL;
+ ipc_si_hif_type_e hif_type;
+ kal_uint8 ebi_info;
+ kal_uint32 bypass_seg_num = 0; /* the number of sit which is ignore && zero length and to be skipped*/
+ static ipc_filter_list_t *fls_set[] = {ipc_dl_v4_filter_list_s, ipc_dl_v6_filter_list_s};
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ ipc_dpfm_mirror_des_t dpfm_mirror_des[IPC_DPFM_MAX_DEVICE_NUM];
+ kal_bool is_mirror_did = KAL_FALSE;
+ kal_uint32 i;
+
+ kal_mem_set(dpfm_mirror_des, 0, sizeof(dpfm_mirror_des));
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ dpfm_mirror_des[i].netif_id = IPC_INVALID_NETIF_ID;
+ }
+#endif
+
+ IPC_ASSERT(did);
+
+ pkt_num = UPCM_DID_GET_PKT_NUM(did);
+ seg_num = UPCM_DID_GET_SEG_NUM(did); /* this num only count valid seg number in DID */
+ base_psn = UPCM_DID_GET_COUNT_L(did);
+ sit = UPCM_DID_GET_SIT_PTR(did);
+ ebi_info = (kal_uint8)UPCM_DID_GET_SW_CTRL_FIELD(did);
+
+ /* Init packet_des */
+ kal_mem_set(&packet_des, 0, sizeof(ipc_pkt_des_t));
+ packet_des.des_type = IPC_PKT_DES_TYPE_DID;
+ packet_des.matched_filter = &filter;
+ packet_des.filter_info = &filter_info;
+ packet_des.packet_info = &packet_info;
+
+ hif_type = ipc_utils_get_hif_type_by_netif_id(netif_id);
+ curr_idx = 0;
+
+#if defined(__MD97__)
+ kal_mem_set(&g_rq_info_list, 0, sizeof(g_rq_info_list));
+ g_rq_info_list.cnt = 0;
+#endif
+
+ while (curr_idx < (seg_num + bypass_seg_num)) {
+ IPC_ASSERT(curr_idx < UPCM_DID_MAX_SIT_ENT_NUM);
+ curr_si = &sit[curr_idx];
+
+ if((IPC_SI_HIF_TYPE_IGR == UPCM_DID_SI_GET_HIF_TYPE(curr_si)) && (UPCM_DID_SI_GET_LEN(curr_si) == 0))
+ {
+ /* if we found the hif_type is ignore and sit length is 0,
+ it means this sit entry is processed last time because of HIF retry.
+ So we have to skip the sit entry and update totoal sit entries for while loop */
+ hif_data_trace(MD_TRC_IPC_DL_DO_FILTER_DID_ZERO_SIT, curr_idx, bypass_seg_num+1, seg_num);
+ curr_idx++;
+ bypass_seg_num++;
+ continue;
+ }
+
+ /* SIT length should not be zero */
+ IPC_ASSERT(UPCM_DID_SI_GET_LEN(curr_si));
+
+ pkt_start_idx = curr_idx;
+ ip_packet = (kal_uint8 *)UPCM_DID_SI_GET_DATAPTR(curr_si) + UPCM_DID_SI_GET_OFFSET(curr_si);
+
+ /* Can't get packet length from the descriptor, so get it from IP header instead. */
+ if (KAL_TRUE != ipc_get_continuous_content_did(ip_packet, 0, did, curr_idx, 6, &comm_continuous_p, comm_buff))
+ {
+ hif_trace_error(IPC_TR_DID_GET_PKT_LENGTH_FAILED, ip_packet, did, curr_idx);
+ result = IPC_PKT_DO_FILTER_ERROR;
+ goto process_pkt;
+ }
+ if (IPC_HDR_IS_V4(comm_continuous_p)) {
+ packet_len = IPC_HDR_V4_GET_TOTAL_LENGTH(comm_continuous_p);
+ ip_type = IPC_IP_TYPE_IPV4;
+ } else if (IPC_HDR_IS_V6(comm_continuous_p)) {
+ packet_len = IPC_HDR_V6_GET_LENGTH(comm_continuous_p) + IPC_HDR_V6_HEADER_SIZE;
+ ip_type = IPC_IP_TYPE_IPV6;
+ } else {
+ result = IPC_PKT_DO_FILTER_ERROR;
+ goto process_pkt;
+ }
+
+ /* Fill packet_des */
+ packet_des.packet = ip_packet;
+ packet_des.packet_len = packet_len;
+ packet_des.did = did;
+ packet_des.pkt_start_idx = pkt_start_idx;
+ packet_des.psn = base_psn + total_pkt_cnt;
+ packet_des.ip_type = ip_type;
+ packet_des.is_packet_info = KAL_FALSE;
+ kal_mem_set(&packet_info, 0, sizeof(ipc_packet_info_t));
+
+ result = ipc_pkt_do_filter(KAL_FALSE, fls_set, sizeof(fls_set)/sizeof(ipc_filter_list_t*), ip_type, pdn_id, netif_id, ebi_info, &packet_des);
+
+process_pkt:
+ switch (result) {
+ qbm_gpd *callback_gpd_p;
+ qbm_type type;
+ ipc_data_usage_info_t data_usage = {0};
+
+ case IPC_PKT_DO_FILTER_HANDLE_CLONE:
+ case IPC_PKT_DO_FILTER_MATCHED:
+ type = (uplink)?QBM_TYPE_NET_UL_SHRD:QBM_TYPE_NET_DL;
+ if (KAL_FALSE == ipc_utils_sit_to_gpd(type, did, curr_idx, packet_des.packet_len, &callback_gpd_p)) {
+ /* Free the data when GPD is exhausted */
+ ipc_utils_pkt_set_si_hif_type(did, IPC_SI_HIF_TYPE_IGR, &curr_idx);
+ break;
+ }
+
+ /*Set Data usage for current packet*/
+ data_usage.downlink_bytes = packet_len;
+ data_usage.downlink_packets = 1;
+ ipc_set_data_usage_by_pdn_sim_id(DL_DIRECT, pdn_id, &data_usage);
+
+ if (IPC_PKT_DO_FILTER_MATCHED == result) {
+ ipc_utils_pkt_set_si_hif_type(did, IPC_SI_HIF_TYPE_IGR, &curr_idx);
+ } else {
+ ipc_utils_pkt_set_si_hif_type(did, hif_type, &curr_idx);
+ remain_seg_cnt += curr_idx - pkt_start_idx;
+ remain_pkt_cnt ++;
+ hif_trace_info(IPC_TR_FILTER_MATCHED_CLONED_DEFAULT_PATH);
+ }
+
+ if (callback_gpd_p) {
+ if(KAL_TRUE == filter->callback_with_info)
+ {
+ filter_info.src_desc_ptr = (void*) did;
+ filter_info.src_desc_type = IPC_FI_DESC_TYPE_DID;
+ filter_info.src_desc_indx = pkt_start_idx;
+ }
+ /* Forward GPD by filter's callback function */
+ ipc_call_filter_cbk(KAL_FALSE, callback_gpd_p, callback_gpd_p, packet_len, filter, &filter_info);
+ }
+ break;
+
+ case IPC_PKT_DO_FILTER_INVALID_LEN:
+ ipc_utils_pkt_set_si_hif_type(did, IPC_SI_HIF_TYPE_IGR, &curr_idx);
+ break;
+
+ case IPC_PKT_DO_FILTER_HANDLE_FRAG:
+ type = (uplink)?QBM_TYPE_NET_UL_SHRD:QBM_TYPE_NET_DL;
+ ipc_utils_sit_to_gpd(type, did, curr_idx, packet_des.packet_len, &callback_gpd_p);
+ ipc_utils_pkt_set_si_hif_type(did, IPC_SI_HIF_TYPE_IGR, &curr_idx);
+
+ if (callback_gpd_p) {
+ /* Forward GPD to ipc_fragment sub-module to handle fragment. */
+ ipc_frag_refilter_info_t info;
+
+ info.netif_id = netif_id;
+ info.pdn_id = pdn_id;
+ info.uplink = KAL_FALSE;
+ info.is_pkt_info = KAL_TRUE;
+ info.packet_info = &packet_info;
+ info.filter_id = filter->filter_id;
+ info.filter_magic_number = ipc_filter_magic_number_s;
+ ((upcm_dlvr_dl_info_t *)QBM_DES_GET_SW_CTRL_FIELD(callback_gpd_p))->ebi = ebi_info;
+
+ ipc_fragment_defrag(callback_gpd_p, &info, ((ip_type == IPC_IP_TYPE_IPV4) ? KAL_TRUE : KAL_FALSE) );
+ }
+ break;
+
+ #if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ case IPC_PKT_DO_FILTER_DPFM_MATCHED:
+ if (!ipc_dpfm_set_pkt_in_did_mirror_des(dpfm_mirror_des, did, &curr_idx, packet_info.out_netif_id)) {
+ /*
+ * Direct path is not available.
+ * Send packets to default route (indirect path).
+ */
+ ipc_utils_pkt_set_si_hif_type(did, hif_type, &curr_idx);
+
+ remain_seg_cnt += curr_idx - pkt_start_idx;
+ remain_pkt_cnt ++;
+ break;
+ }
+ is_mirror_did = KAL_TRUE;
+ break;
+ #endif
+
+ case IPC_PKT_DO_FILTER_NOT_MATCHED:
+ case IPC_PKT_DO_FILTER_BWM_MATCHED:
+ case IPC_PKT_DO_FILTER_ERROR:
+ default:
+ ipc_utils_pkt_set_si_hif_type(did, hif_type, &curr_idx);
+
+ remain_seg_cnt += curr_idx - pkt_start_idx;
+ remain_pkt_cnt ++;
+ break;
+ }
+
+#if defined(__MD97__)
+ if ((IPC_PKT_DO_FILTER_ERROR != result) && (curr_si->nrqi)) {
+ ipc_rq_info_t rq_info = {0};
+
+ if (KAL_FALSE == packet_des.is_packet_info) {
+ if (KAL_FALSE == ipc_get_packet_info_did(ip_packet, did, curr_idx, packet_des.packet_info)) {
+ hif_trace_error(IPC_TR_NO_PKT_INFO_DID);
+ } else {
+ packet_des.is_packet_info = KAL_TRUE;
+ }
+ }
+
+ if (ipc_data_set_rq_info(&rq_info, pdn_id, &packet_des, IPC_DATA_QFI_SRC_DL_DID)) {
+ ipc_data_saved_rq_info_list(&g_rq_info_list, &rq_info);
+ }
+ }
+#endif
+
+ total_pkt_cnt ++;
+ }
+
+#if defined(__MD97__)
+ ipc_data_send_rq_info(&g_rq_info_list);
+#endif
+
+ IPC_ASSERT(remain_pkt_cnt <= pkt_num);
+ IPC_ASSERT(total_pkt_cnt == pkt_num);
+ IPC_ASSERT(remain_seg_cnt <= seg_num);
+
+ UPCM_DID_SET_PKT_NUM(did, remain_pkt_cnt);
+ UPCM_DID_SET_SEG_NUM(did, remain_seg_cnt);
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ if (is_mirror_did) {
+ for (i = 0; i < IPC_DPFM_MAX_DEVICE_NUM; i++) {
+ if (dpfm_mirror_des[i].mirror_did_head) {
+ ipc_pkt_t pkt;
+
+ ipc_dpfm_mirror_did(&(dpfm_mirror_des[i]), did);
+ IPC_ASSERT(dpfm_mirror_des[i].netif_id != IPC_INVALID_NETIF_ID);
+
+ pkt.buf_type = IPC_PKT_DES_TYPE_DID;
+ pkt.did_head = dpfm_mirror_des[i].mirror_did_head;
+ pkt.did_tail = dpfm_mirror_des[i].mirror_did_tail;
+
+ ipc_send_dl_pkt_in_did_internal(&pkt, NULL, dpfm_mirror_des[i].netif_id);
+ }
+ }
+ }
+#endif
+
+ return remain_pkt_cnt;
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions. (Gen95)
+ *----------------------------------------------------------------------------*/
+#if defined(__IPF_SUPPORT__)
+
+/* check if the specified filter is matched, otherwise go through all filters */
+void ipc_ipf_meta_do_filter(kal_int32 filter_id,
+ ipc_pkt_des_t *packet_des,
+ kal_uint8 ip_type,
+ kal_uint8 pdn_sim_id,
+ kal_uint32 netif_id,
+ ipc_dpfm_mirror_des_t *dpfm_mirror_des,
+ kal_bool *is_mirror_did,
+ kal_bool *is_saved)
+{
+ static ipc_filter_list_t *fls_dl_set[] = {ipc_dl_v4_filter_list_s,
+ ipc_dl_v6_filter_list_s};
+ ipc_filter_t *filter = NULL;
+ ipc_pkt_do_filter_result_e match_result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ kal_bool ret = KAL_FALSE;
+ ipc_pkt_t pkt = {0};
+ ipf_dl_meta *meta = (ipf_dl_meta *) (packet_des->ipf_meta);
+
+ /* Alias local parameter */
+ kal_uint8 *ip_packet = packet_des->packet;
+ kal_uint32 packet_len = packet_des->packet_len;
+ ipc_filter_t **pp_matched_filter = packet_des->matched_filter;
+ ipc_filter_info_t *p_filter_info = packet_des->filter_info;
+ ipc_packet_info_t *p_packet_info = packet_des->packet_info;
+ kal_uint32 fls_set_cnt = sizeof(fls_dl_set) / sizeof(ipc_filter_list_t*);
+
+ /* Check IP Type */
+ if (IPC_IP_TYPE_INVALID == ip_type) {
+ QBM_CACHE_INVALID(ip_packet, 1);
+ if (IPC_HDR_IS_V4(ip_packet)) {
+ ip_type = IPC_IP_TYPE_IPV4;
+ } else if (IPC_HDR_IS_V6(ip_packet)) {
+ ip_type = IPC_IP_TYPE_IPV6;
+ } else {
+ match_result = IPC_PKT_DO_FILTER_ERROR;
+ goto _process_pkt;
+ }
+ packet_des->ip_type = ip_type;
+ }
+
+ /* Process meta match result */
+ switch (meta->mr) {
+ case IPC_IPF_MR_FILTER_MATCH:
+ case IPC_IPF_MR_UNKNOWN_HEADER:
+ if (filter_id != IPC_INVALID_FILTER_ID) {
+ filter = ipc_find_filter_by_id(ipc_filter_pool_s, filter_id);
+ if ((NULL != filter) && (IPC_INVALID_FILTER_ID != filter->filter_id)) {
+ /* Get packet info for quick filtering */
+ ret = ipc_get_packet_info(ip_packet, packet_len, p_packet_info);
+ if (KAL_FALSE == ret) {
+ match_result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ break;
+ }
+
+ packet_des->is_packet_info = KAL_TRUE;
+
+ /* If filter feature contains IPV6_MDT, skip quick filtering */
+ if (_FEATURES_CONTAIN(&(filter->rules), IPV6_DPFM)) {
+ *(packet_des->matched_filter) = filter;
+ goto _dpfm_check_route;
+ }
+
+ /* Do quick filtering for specified filter */
+ match_result = ipc_pkt_do_one_filter(KAL_FALSE,
+ ip_type,
+ p_packet_info,
+ filter,
+ pdn_sim_id,
+ netif_id,
+ 0xFF, /* HW Path no EBI */
+ pp_matched_filter,
+ p_filter_info);
+
+ if (_FEATURES_CONTAIN(&filter->rules, CUST_FILTER) && (IPC_PKT_DO_FILTER_MATCHED == match_result)) {
+ if (KAL_FALSE == filter->cust_cbk_func(packet_des->packet,
+ packet_des->packet_len,
+ filter->filter_id,
+ filter->p_cust_cbk_args)) {
+ match_result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ }
+ hif_data_trace(MD_TRC_IPC_TR_CUST_FILTER_CBK, packet_des->packet, packet_des->packet_len, filter->filter_id, ret);
+ } else if (_FEATURES_CONTAIN(&filter->rules, CUST_FILTER_W_INFO) && (IPC_PKT_DO_FILTER_MATCHED == match_result)) {
+ p_filter_info->src_desc_type = IPC_FI_DESC_TYPE_NONE;
+ if (KAL_FALSE == filter->cust_cbk_func(packet_des->packet,
+ packet_des->packet_len,
+ filter->filter_id,
+ p_filter_info)) {
+ match_result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ }
+ hif_data_trace(MD_TRC_IPC_TR_CUST_FILTER_CBK, packet_des->packet, packet_des->packet_len, filter->filter_id, ret);
+ }
+
+ if (match_result) {
+ IPC_ASSERT(*pp_matched_filter == filter);
+ break;
+ }
+ }
+ }
+
+ /* Do full check when unknown packet and quick match failed */
+ match_result = ipc_pkt_do_filter(KAL_FALSE,
+ fls_dl_set,
+ fls_set_cnt,
+ ip_type,
+ pdn_sim_id,
+ netif_id,
+ 0xFF, /* HW Path no EBI */
+ packet_des);
+ break;
+
+ case IPC_IPF_MR_DPFM_MATCH:
+_dpfm_check_route :
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ ret = ipc_dpfm_check_route(KAL_FALSE, packet_des, netif_id);
+
+ if(KAL_TRUE == ret)
+ {
+ hif_data_trace(MD_TRC_IPC_DPFM_CHECK_ROUTE_MATCHED, 0, ip_type, p_packet_info->out_netif_id);
+ match_result = IPC_PKT_DO_FILTER_DPFM_MATCHED;
+ }
+ else
+ {
+ /* forward to AP (default NETIF) */
+ match_result = IPC_PKT_DO_FILTER_NOT_MATCHED;
+ }
+
+ break;
+#endif
+ default:
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+
+_process_pkt :
+ /* Process filter match result */
+ switch (match_result) {
+ case IPC_PKT_DO_FILTER_MATCHED:
+ case IPC_PKT_DO_FILTER_HANDLE_FRAG: {
+ qbm_gpd *callback_gpd_p = NULL;
+ kal_uint8 *callback_gpd_data_p = NULL;
+
+ if (QBM_NET_DL_DATA_LEN < packet_len) {
+ hif_trace_error(IPC_TR_META_TO_GPD_FAIL, __FUNCTION__, packet_len, QBM_TYPE_NET_DL);
+ /* release IPF PRB buffer */
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+ break;
+ }
+
+ filter = *(packet_des->matched_filter);
+
+ if (1 != qbmt_alloc_q_no_tail(QBM_TYPE_NET_DL, /* type */
+ 1, /* buff_num */
+ (void**) &callback_gpd_p, /* pp_head */
+ (void**) &callback_gpd_p /* pp_tail */)) {
+
+ hif_trace_error(IPC_TR_META_DO_FILTER_ALLOC_GPD_NG, KAL_FALSE, packet_des->ipf_meta);
+ /* Release PRB when GPD is exhausted */
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+ break;
+ }
+
+ /* Copy data from UL META to output GPD */
+ IPC_ASSERT(callback_gpd_p);
+ ipc_utils_set_gpd_datalen(callback_gpd_p, packet_len, (void**) &callback_gpd_data_p);
+ IPC_ASSERT(callback_gpd_data_p);
+
+ QBM_CACHE_INVALID(ip_packet, packet_len);
+ kal_mem_cpy(callback_gpd_data_p, ip_packet, packet_len);
+ QBM_CACHE_FLUSH(callback_gpd_data_p, packet_len);
+
+ if (IPC_PKT_DO_FILTER_MATCHED == match_result) {
+ /*Set Data usage for current packet*/
+ ipc_data_usage_info_t data_usage = {0};
+ data_usage.downlink_bytes = packet_len;
+ data_usage.downlink_packets = 1;
+ ipc_set_data_usage_by_pdn_sim_id(DL_DIRECT, pdn_sim_id, &data_usage);
+
+ if (KAL_TRUE == filter->callback_with_info) {
+ /* This case is not SW path, so we can't provide source DID pointer */
+ p_filter_info->src_desc_ptr = NULL;
+ p_filter_info->src_desc_type = IPC_FI_DESC_TYPE_NONE;
+ p_filter_info->src_desc_indx = 0;
+ }
+ /* Forward GPD by filter's callback function */
+ ipc_call_filter_cbk(KAL_FALSE, callback_gpd_p, callback_gpd_p, packet_len, *pp_matched_filter, p_filter_info);
+ } else {
+ /* Forward GPD to ipc_fragment sub-module to handle fragment. */
+ ipc_frag_refilter_info_t info;
+
+ info.netif_id = netif_id;
+ info.pdn_id = pdn_sim_id;
+ info.uplink = KAL_FALSE;
+ info.is_pkt_info = KAL_TRUE;
+ info.packet_info = p_packet_info;
+ info.filter_id = filter->filter_id;
+ info.filter_magic_number = ipc_filter_magic_number_s;
+
+ ipc_fragment_defrag(callback_gpd_p,
+ &info,
+ ((ip_type == IPC_IP_TYPE_IPV4) ? KAL_TRUE : KAL_FALSE));
+ }
+
+ /* release IPF PRB buffer */
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+ }
+ break;
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ case IPC_PKT_DO_FILTER_DPFM_MATCHED:
+ {
+ if(!ipc_dpfm_set_ipf_pkt_in_did_mirror_des(dpfm_mirror_des, packet_des, p_packet_info->out_netif_id))
+ {
+ /* DID is failed to allocate, drop it. */
+ hif_data_trace(MD_TRC_IPC_DL_META_DROP_DID_ALLOC_NG, p_packet_info->out_netif_id);
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+ }
+ *is_mirror_did = KAL_TRUE;
+ }
+ break;
+#endif
+ case IPC_PKT_DO_FILTER_ERROR:
+ case IPC_PKT_DO_FILTER_NOT_MATCHED:
+ case IPC_PKT_DO_FILTER_BWM_MATCHED: {
+ pkt.buf_type = IPC_PKT_DES_TYPE_NO_DESC;
+ pkt.data_len = packet_len;
+ pkt.data = ip_packet;
+ if (!ipc_send_dl_pkt_in_did_internal(&pkt, NULL, netif_id)) {
+ /* DID is failed to allocate, drop it. */
+ hif_data_trace(MD_TRC_IPC_DL_META_DROP_DID_ALLOC_NG, netif_id);
+ IPC_FREE_DL_META_PRB(meta, meta->len);
+ }
+ }
+ break;
+ default:
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+
+#if defined(__MD97__)
+ if (meta->mr == IPC_IPF_MR_UNKNOWN_HEADER && match_result != IPC_PKT_DO_FILTER_ERROR) {
+ if (IPC_DATA_GET_QFI(meta->tcp_flag)) {
+ hif_trace_info(IPC_TR_NR_RQI_IS_SET, __FUNCTION__, meta, meta->mr, match_result, meta->tcp_flag);
+ *is_saved = KAL_TRUE;
+ }
+ }
+#endif
+
+ return;
+}
+
+kal_bool ipc_update_one_hw_filter(kal_int32 filter_id,
+ ipc_filter_rules_t *p_rules,
+ void *p_cur_base)
+{
+ ipv4_filter_rule *hw_filter = NULL;
+ ipv6_filter_rule *hw_filter_v6 = NULL;
+
+ if (NULL == p_rules) {
+ hif_trace_info(IPC_TR_INVALID_FILTER_RULES, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ /*Note : if the value is more than 1 byte, we should transform it to big-endian format. */
+
+ /* do casting with same base address. */
+ hw_filter = (ipv4_filter_rule*) p_cur_base;
+ hw_filter_v6 = (ipv6_filter_rule*) p_cur_base;
+
+ if (_RULES_CONTAIN(p_rules, PDN_ID)) {
+ hw_filter->pdn_sim_id = IPC_MASK_PROTOID_ON_PDNID(p_rules->pdn_id, p_rules->proto_idx);
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_PDNSIM_ID);
+ }
+
+ if (_RULES_CONTAIN_IPV4(p_rules)) {
+ hw_filter->ip = IPF_HW_FILTER_IPV4;
+ if (_RULES_CONTAIN(p_rules, SRC_IPV4)) {
+ /* SRC ADDR means Remote ADDR (DL) */
+ hw_filter->remote_addr0 = p_rules->src_ipv4.addr32;
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_R_ADDR);
+ } else if (_RULES_CONTAIN(p_rules, DST_IPV4)) {
+ //hw_filter->remote_addr0 = p_rules->dst_ipv4.addr32;
+ //IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_L_ADDR);
+ }
+ }
+
+ if (_RULES_CONTAIN_IPV6(p_rules)) {
+ hw_filter_v6->ip = IPF_HW_FILTER_IPV6;
+ hw_filter_v6->ip1 = IPF_HW_FILTER_IPV6_1;
+ if (_RULES_CONTAIN(p_rules, SRC_IPV6)) /* SRC ADDR means Remote ADDR (DL) */
+ {
+ hw_filter_v6->remote_addr0 = p_rules->src_ipv6.addr32[0];
+ hw_filter_v6->remote_addr1 = p_rules->src_ipv6.addr32[1];
+ hw_filter_v6->remote_addr2 = p_rules->src_ipv6.addr32[2];
+ hw_filter_v6->remote_addr3 = p_rules->src_ipv6.addr32[3];
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_R_ADDR);
+ } else if (_RULES_CONTAIN(p_rules, DST_IPV6)) {
+ //hw_filter_v6->remote_addr0 = p_rules->dst_ipv6.addr32[0];
+ //hw_filter_v6->remote_addr1 = p_rules->dst_ipv6.addr32[1];
+ //hw_filter_v6->remote_addr2 = p_rules->dst_ipv6.addr32[2];
+ //hw_filter_v6->remote_addr3 = p_rules->dst_ipv6.addr32[3];
+ //IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_L_ADDR);
+ }
+ }
+
+ if (_RULES_CONTAIN(p_rules, PROTOCOL)) {
+ hw_filter->protocol = p_rules->protocol;
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_PROTO);
+
+ if (_FEATURES_CONTAIN(p_rules, FRAG)) {
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_FRAG);
+ }
+
+ switch (p_rules->protocol) {
+ case IPC_HDR_PROT_UDP:
+ case IPC_HDR_PROT_TCP:
+ if (_RULES_CONTAIN(p_rules, SRC_PORT) && _RULES_CONTAIN(p_rules, DST_PORT)) {
+ IPC_NE_SET_2B(&(hw_filter->f_pro_word), p_rules->dst_port);
+ hw_filter->f_pro_word = hw_filter->f_pro_word << 16;
+ IPC_NE_SET_2B(&(hw_filter->f_pro_word), p_rules->src_port);
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_F_WORD_TYPE4);
+ } else if (_RULES_CONTAIN(p_rules, DST_PORT)) {
+ IPC_NE_SET_2B(&(hw_filter->f_pro_word), p_rules->dst_port);
+ hw_filter->f_pro_word = hw_filter->f_pro_word << 16;
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_F_WORD_TYPE3);
+ } else if (_RULES_CONTAIN(p_rules, SRC_PORT)) {
+ IPC_NE_SET_2B(&(hw_filter->f_pro_word), p_rules->src_port);
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_F_WORD_TYPE2);
+ }
+ break;
+ case IPC_HDR_PROT_ICMP:
+ case IPC_HDR_PROT_ICMPV6:
+ if (_RULES_CONTAIN(p_rules, ICMPV4_TYPE)) {
+ hw_filter->f_pro_word = p_rules->icmpv4_type;
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_F_WORD_TYPE);
+ }
+
+ if (_RULES_CONTAIN(p_rules, ICMPV6_TYPE)) {
+ hw_filter->f_pro_word = p_rules->icmpv6_type;
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_F_WORD_TYPE);
+ }
+ break;
+ case IPC_HDR_PROT_ESP:
+ if (_RULES_CONTAIN(p_rules, SPI)) {
+ IPC_NE_SET_4B(&(hw_filter->f_pro_word), p_rules->spi);
+ IPF_HW_FILTER_SET_VALID(hw_filter->valid, IPF_HW_FILTER_V_F_WORD_TYPE4);
+ }
+ break;
+ default:
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+ }
+
+ /*
+ * a trick for storing filter id in hw table,
+ * then we can quickly get the corresponding filter id when IPF match by match index
+ */
+ hw_filter->resv1 = filter_id;
+
+ return KAL_TRUE;
+}
+
+void ipc_filter_update_hw_filter(void)
+{
+ static ipc_filter_list_t *fls_dl_set[] = {ipc_dl_v4_filter_list_s,
+ ipc_dl_v6_filter_list_s};
+ ipv4_filter_rule *hw_filter_base = NULL;
+ ipv4_filter_rule *p_cur_base = NULL;
+ kal_bool result = KAL_FALSE;
+ kal_uint8 fls_set_idx = 0;
+ kal_uint8 fls_set_cnt = sizeof(fls_dl_set) / sizeof(ipc_filter_list_t*);
+ ipc_filter_list_t *filter_list = NULL;
+ ipc_filter_t *filter = NULL;
+ kal_uint8 hw_entry_idx = 0;
+ kal_uint8 filter_num = 0;
+ kal_uint32 total_entry_num = 0;
+ kal_uint8 entry_num_for_each_filter = 0;
+ kal_bool ipv6_unknown_proto_chk = KAL_FALSE;
+
+ result = IPC_TAKE_HW_FILTER_TABLE((void**) &hw_filter_base, &total_entry_num);
+
+ /* result shall be true. */
+ IPC_ASSERT(result);
+ hif_trace_info(IPC_TR_UPDATE_HW_FILTER_TABLE_INFO, hw_filter_base, total_entry_num);
+ kal_mem_set(hw_filter_base, 0, sizeof(ipv4_filter_rule) * total_entry_num);
+
+ for (fls_set_idx = 0; fls_set_idx < fls_set_cnt; fls_set_idx++) {
+ filter_list = fls_dl_set[fls_set_idx];
+
+ if (!filter_list || 0 == filter_list->count) {
+ /* skip the loop */
+ continue;
+ }
+
+ (IPC_IP_TYPE_IPV4 == filter_list->ip_type) ? (entry_num_for_each_filter = 1) : (entry_num_for_each_filter = 2);
+
+ if ((IPC_IP_TYPE_IPV6 == filter_list->ip_type) && (filter_list->count > 0)) {
+ ipv6_unknown_proto_chk = KAL_TRUE;
+ }
+
+ hif_trace_info(IPC_TR_UPDATE_HW_FILTER_COUNT, filter_list->ip_type, filter_list->count);
+
+ for (filter = filter_list->filter_head; filter;
+ filter = filter->next_filter_map[ipc_next_filter_hash(filter_list->ip_type)]) {
+ if (KAL_TRUE == filter->is_bypass_sync_hw) {
+ /* skip deregistered filter */
+ hif_trace_info(IPC_TR_BYPASS_HW_FILTER_SYNC, __FUNCTION__, filter->filter_id);
+ continue;
+ }
+
+ if (hw_entry_idx <= (total_entry_num - entry_num_for_each_filter)) {
+ p_cur_base = &hw_filter_base[hw_entry_idx]; /* 1 entry = 16 Bytes */
+ if (KAL_TRUE == ipc_update_one_hw_filter(filter->filter_id, &filter->rules, (void*) p_cur_base)) {
+ hw_entry_idx = hw_entry_idx + entry_num_for_each_filter;
+ filter_num++;
+ }
+ } else {
+ /* exceed HW filter count */
+ hif_trace_info(IPC_TR_UPDATE_HW_FILTER_TOO_MUCH, filter_list->ip_type, filter_num, hw_entry_idx);
+ IPC_ASSERT(KAL_FALSE);
+ }
+ }
+ }
+
+ hif_trace_info(IPC_TR_UPDATE_HW_FILTER_OK, hw_entry_idx, ipv6_unknown_proto_chk);
+ IPC_SUBMIT_HW_FILTER_TABLE(hw_entry_idx, ipv6_unknown_proto_chk);
+}
+
+#endif
+
+static void ipc_filter_update_sit_idx_by_skip_segment(upcm_did *did, kal_uint32 *p_curr_si_idx)
+{
+ kal_bool end_of_seg_list;
+ upcm_did_si *sit;
+ kal_uint32 pkt_start_idx;
+
+ IPC_ASSERT((did) && (p_curr_si_idx));
+ sit = UPCM_DID_GET_SIT_PTR(did);
+ pkt_start_idx = *p_curr_si_idx;
+
+ IPC_ASSERT( pkt_start_idx < UPCM_DID_MAX_SIT_ENT_NUM );
+
+ end_of_seg_list = KAL_FALSE;
+
+ for ( *p_curr_si_idx = pkt_start_idx;
+ *p_curr_si_idx < UPCM_DID_MAX_SIT_ENT_NUM && !end_of_seg_list;
+ (*p_curr_si_idx) ++) {
+ upcm_did_si *curr_si = &sit[*p_curr_si_idx];
+ end_of_seg_list = UPCM_DID_SI_GET_EOL(curr_si);
+ }
+}
+
+void ipc_filter_did_drop_pkt_handler(kal_uint32 pdn_id, upcm_did *p_head, upcm_did *p_tail)
+{
+ upcm_did *did = NULL;
+ upcm_did *next_did = NULL;
+ kal_bool end_of_list = KAL_FALSE;
+ upcm_did_si *curr_si = NULL;
+ kal_uint32 pkt_start_idx = 0;
+ kal_uint8 comm_buff[16] = {0}; /*< max is ipv6 src/dest addr */
+ kal_uint8 *comm_continuous_p = NULL;
+ kal_uint8 seg_num = 0;
+ upcm_did_si *sit = NULL;
+ kal_uint32 curr_idx = 0;
+ kal_uint8 *ip_packet = NULL;
+ kal_uint32 packet_len = 0;
+ qbm_gpd *p_gpd = NULL;
+ ipc_packet_info_t packet_info;
+
+ if(!p_head || !p_tail){
+ hif_trace_info(IPC_TR_DID_DROP_HDR_INVALID_PARAM, __FUNCTION__, p_head, p_tail);
+ return;
+ }
+
+ for (did = p_head; did && !end_of_list; did = next_did) {
+ next_did = UPCM_DID_GET_NEXT(did);
+ end_of_list = (did == p_tail);
+
+ /* operate on each did */
+ IPC_ASSERT(did);
+ seg_num = UPCM_DID_GET_SEG_NUM(did);
+ sit = UPCM_DID_GET_SIT_PTR(did);
+
+ curr_idx = 0;
+ while (curr_idx < seg_num) {
+ curr_si = &sit[curr_idx];
+ IPC_ASSERT(UPCM_DID_SI_GET_LEN(curr_si));
+ pkt_start_idx = curr_idx;
+ ip_packet = (kal_uint8 *)UPCM_DID_SI_GET_DATAPTR(curr_si) + UPCM_DID_SI_GET_OFFSET(curr_si);
+
+ if(KAL_TRUE == ipc_get_continuous_content_did(ip_packet, 0, did, curr_idx, 6, &comm_continuous_p, comm_buff)) {
+ if (IPC_HDR_IS_V4(comm_continuous_p)) {
+ packet_len = IPC_HDR_V4_GET_TOTAL_LENGTH(comm_continuous_p);
+ } else if (IPC_HDR_IS_V6(comm_continuous_p)) {
+ packet_len = IPC_HDR_V6_GET_LENGTH(comm_continuous_p) + IPC_HDR_V6_HEADER_SIZE;
+ } else{
+ /* Invalid IP type, skip this packet */
+ ipc_filter_update_sit_idx_by_skip_segment(did, &curr_idx);
+ continue;
+ }
+ kal_mem_set(&packet_info, 0, sizeof(ipc_packet_info_t));
+ if(ipc_get_packet_info_did(ip_packet, did, pkt_start_idx, &packet_info)){
+ if(IPC_HDR_ICMPV6_TYPE_RA == packet_info.icmpv6_type) {
+ /*call did ra check*/
+ ipc_data_ipv6_ra_pool_push(pdn_id, NULL);
+ packet_len = IPC_HDR_V6_GET_LENGTH(comm_continuous_p) + IPC_HDR_V6_HEADER_SIZE;
+ ipc_utils_sit_to_gpd(QBM_TYPE_NET_DL, did, curr_idx, packet_len, &p_gpd);
+ if(p_gpd) {
+ ipc_data_ipv6_ra_pool_push(pdn_id, p_gpd);
+ hif_trace_info(IPC_TR_DOWNLINK_RA_PROXY_GPD, __FUNCTION__, pdn_id, p_gpd);
+ }else{
+ hif_trace_info(IPC_TR_DROP_HDR_GPD_ALLOC_NG, __FUNCTION__, __LINE__);
+ }
+ } else if(IPC_HDR_PROT_TCP == packet_info.protocol){
+ if( (IPC_HDR_TCP_FLAG_RST != (packet_info.tcp_flags & IPC_HDR_TCP_FLAG_RST)) && (packet_info.tcp_flags) ){
+ /* Skipped if received [RST] packet */
+ /* make sure packet content is continuous : copy data to continuous buffer(GPD) */
+ ipc_utils_sit_to_gpd(QBM_TYPE_NET_DL, did, curr_idx, packet_len, &p_gpd);
+ if(p_gpd) {
+ kal_uint8 *p_packet;
+ if(KAL_TRUE == ipc_utils_get_gpd_dataptr(p_gpd, (void**)&p_packet)){
+ ipc_ipf_dhlr_for_tcp_rst(p_packet, packet_info, pdn_id);
+ }
+ qbm_free_one(p_gpd);
+ }else{
+ hif_trace_info(IPC_TR_DROP_HDR_GPD_ALLOC_NG, __FUNCTION__, __LINE__);
+ }
+ }
+ } else if(IPC_HDR_PROT_UDP == packet_info.protocol) {
+ /*udp packet is going to drop*/
+ /*fill data in p_gpd*/
+ ipc_utils_sit_to_gpd(QBM_TYPE_NET_DL, did, curr_idx, packet_len, &p_gpd);
+ if(p_gpd) {
+ kal_uint8 *p_packet;
+ if(KAL_TRUE == ipc_utils_get_gpd_dataptr(p_gpd, (void**)&p_packet)){
+ ipc_ipf_dhlr_for_udp_rst(p_packet, pdn_id);
+ }
+ qbm_free_one(p_gpd);
+ }else{
+ hif_trace_info(IPC_TR_DROP_HDR_GPD_ALLOC_NG, __FUNCTION__, __LINE__);
+ }
+
+ } else {
+ hif_trace_info(IPC_TR_DROP_HDLR_NG_PROTO, __FUNCTION__, packet_info.protocol);
+ }
+ }else{
+ hif_trace_info(IPC_TR_DROP_HDLR_PKT_INFO_NG, __FUNCTION__);
+ }
+ }
+ ipc_filter_update_sit_idx_by_skip_segment(did, &curr_idx);
+ }
+ }
+ return;
+}
+
+void ipc_filter_switch_dl_mode(kal_uint8 mode)
+{
+#if defined(__IPF_SUPPORT__)
+ kal_bool result = KAL_FALSE;
+ ipv4_filter_rule *hw_filter_base = NULL;
+ ipv6_filter_rule *hw_filter_v6 = NULL;
+ ipv4_filter_rule *hw_filter_v4 = NULL;
+ kal_uint32 total_entry_num = 0;
+ kal_uint8 hw_filter_idx = 0;
+ kal_bool ipv6_unknown_proto_chk = KAL_FALSE;
+
+ hif_trace_info(IPC_TR_IPF_DL_MODE_SWITCH, __FUNCTION__, mode, g_ipc_dl_mode);
+ if (mode & IPC_SW_DL_MODE_MAX) {
+ mode = g_ipc_dl_mode & mode;
+ } else {
+ mode = g_ipc_dl_mode | mode;
+ }
+
+ if(mode == g_ipc_dl_mode || ((mode != IPC_HW_DL_MODE) && (g_ipc_dl_mode != IPC_HW_DL_MODE))){
+ /* Update mode to include */
+ g_ipc_dl_mode = mode;
+ hif_trace_info(IPC_TR_IPF_DL_MODE_SWITCH_NOTHING, __FUNCTION__);
+ return;
+ }
+
+ /* Force SW DL mode */
+ if (IPC_HW_DL_MODE != mode) {
+ result = IPC_TAKE_HW_FILTER_TABLE((void**) &hw_filter_base, &total_entry_num);
+ IPC_ASSERT(result);
+ kal_mem_set(hw_filter_base, 0, sizeof(ipv4_filter_rule) * total_entry_num);
+
+ /* Set IPv4 rule */
+ hw_filter_v4 = (ipv4_filter_rule*) &hw_filter_base[hw_filter_idx];
+ hw_filter_v4->ip = IPF_HW_FILTER_IPV4;
+ IPF_HW_FILTER_SET_VALID(hw_filter_v4->valid, IPF_HW_FILTER_V_FRAG);
+ hw_filter_idx++;
+ hw_filter_v4->resv1 = IPC_SW_DL_FILTER_ID;
+
+ /* Set IPv6 rule */
+ hw_filter_v6 = (ipv6_filter_rule*) &hw_filter_base[hw_filter_idx];
+ hw_filter_v6->ip = IPF_HW_FILTER_IPV6;
+ hw_filter_v6->ip1 = IPF_HW_FILTER_IPV6_1;
+ IPF_HW_FILTER_SET_VALID(hw_filter_v6->valid, IPF_HW_FILTER_V_FRAG);
+ hw_filter_idx += 2;
+ hw_filter_v6->resv1 = IPC_SW_DL_FILTER_ID;
+
+ ipv6_unknown_proto_chk = KAL_TRUE;
+ hif_trace_info(IPC_TR_UPDATE_HW_FILTER_OK, hw_filter_idx, ipv6_unknown_proto_chk);
+ IPC_SUBMIT_HW_FILTER_TABLE(hw_filter_idx, ipv6_unknown_proto_chk);
+
+ g_ipc_dl_mode = mode;
+ } else {
+ /* restore HW filter */
+ ipc_filter_chk_sw_path();
+ g_ipc_dl_mode = IPC_HW_DL_MODE;
+ }
+#endif
+ return;
+}
+
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment.h b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment.h
new file mode 100644
index 0000000..d977c34
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment.h
@@ -0,0 +1,38 @@
+#ifndef _IPC_FRAGMENT_INC
+#define _IPC_FRAGMENT_INC
+
+#include "ipc_api.h"
+#include "ipc_fragment_def.h"
+#include "kal_public_api.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+#include "hif_mw_msgid.h"
+
+#define HIF_DATA_TRACE_ENABLED 1
+#define HIF_CONSOLE_TRACE_ENABLED 0
+
+#include "TrcMod.h"
+#include "hif_trace.h"
+#include "ipc_utils.h"
+
+#define IPC_FRAGMENT_DL_PKT_DUMP(buf_p, len) ipc_utils_pkt_dump_buf(MSG_ID_IPC_FRAG_DL_RAW_DATA, MOD_IPC_FRAGMENT, (unsigned char*)buf_p, len)
+#define IPC_FRAGMENT_UL_PKT_DUMP(buf_p, len) ipc_utils_pkt_dump_buf(MSG_ID_IPC_FRAG_UL_RAW_DATA, MOD_IPC_FRAGMENT, (unsigned char*)buf_p, len)
+
+#define IPC_FRAG_INVALID_FILTER_ID -1
+#define IPC_FRAG_IPV6_MAX_LEN 65535
+#define IPC_FRAG_FLAG_MF 0x01
+#define IPC_FRAG_INFO_RECEIVE_FIRST_PKT 0x1
+#define IPC_FRAG_INFO_RECEIVE_LAST_PKT 0x2
+#define IPC_FRAG_INFO_RECEIVE_COMPLETE 0x4
+#define IPC_FRAG_INFO_RECEIVE_DROPPED 0x8
+
+void ipc_fragment_mp_init();
+void ipc_fragment_mp_deinit();
+
+void ipc_fragment_queuing_expire_init();
+void ipc_fragment_queuing_expire_deinit();
+
+void ipc_fragment_queuing_v4(qbm_gpd *new_gpd, ipc_packet_info_t *packet_info, kal_uint32 matched_filter_id, ipc_frag_refilter_info_t *refilter_info);
+void ipc_fragment_queuing_v6(qbm_gpd *new_gpd, ipc_packet_info_t *packet_info, kal_uint32 matched_filter_id, ipc_frag_refilter_info_t *refilter_info);
+
+#endif /* _IPC_FRAGMENT_INC */
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_data_path_trace_utmd.json b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_data_path_trace_utmd.json
new file mode 100644
index 0000000..e97db50
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_data_path_trace_utmd.json
@@ -0,0 +1,172 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "IPC_FRAGMENT_L2",
+ "stringTranslationDefs": [],
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "IPC_FRAG_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "IPC_FRAG_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "IPC_FRAG_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "IPC_FRAG_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "IPC_FRAG_QUE_V4_KEY_INFO": {
+ "format": "[IPC_FRAG] ipc_fragment_queuing_v4(): src = %xl, dst = %xl, ip_id = %xl, protocol = %d",
+ "traceClass": "IPC_FRAG_L"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_V6_KEY_INFO_SRC": {
+ "format": "[IPC_FRAG] ipc_fragment_queuing_v6(): src = %xl %xl %xl %xl",
+ "traceClass": "IPC_FRAG_L"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_V6_KEY_INFO_DST": {
+ "format": "[IPC_FRAG] dst = %xl %xl %xl %xl",
+ "traceClass": "IPC_FRAG_L"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_V6_KEY_INFO_ID": {
+ "format": "[IPC_FRAG] ip_id = %xl",
+ "traceClass": "IPC_FRAG_M"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_FRAG_INFO": {
+ "format": "[IPC_FRAG] frag_offset = %xd, frag_len = %xd, frag_flag = %xd, frag_end = %xd",
+ "traceClass": "IPC_FRAG_M"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_GRP_INFO": {
+ "format": "[IPC_FRAG] info_mask = %xd, accumulate_len = %xl, total_len = %xl, head_gpd = %xl",
+ "traceClass": "IPC_FRAG_M"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_FIND_POS": {
+ "format": "[IPC_FRAG] Find position in v4 queuing: priv_gpd = %xl, priv_meta = %xl, next_gpd = %xl, next_meta = %xl",
+ "traceClass": "IPC_FRAG_M"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_OVERLAP_PRIV": {
+ "format": "[IPC_FRAG] Overlap with priv fragment: priv_offset = %xd, priv_len = %xd, shrink_len = %xd",
+ "traceClass": "IPC_FRAG_L"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_OVERLAP_NXT": {
+ "format": "[IPC_FRAG] Overlap with next fragment: next_offset = %xd, next_len = %xd, shrink_len = %xd",
+ "traceClass": "IPC_FRAG_L"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_INSERT": {
+ "format": "[IPC_FRAG] Insert new fragment into list: new_offset = %xd, new_len = %xd, accumulate_len = %xd, offset(new) = %xl",
+ "traceClass": "IPC_FRAG_M"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_ERR": {
+ "format": "[IPC_FRAG] Queuing error: release gpd = %xl, meta = %xl",
+ "traceClass": "IPC_FRAG_UH"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_FIRST_FRAG": {
+ "format": "[IPC_FRAG] First fragment is received!! filter_id = %xl",
+ "traceClass": "IPC_FRAG_H"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_LAST_FRAG": {
+ "format": "[IPC_FRAG] Last fragment is received!!",
+ "traceClass": "IPC_FRAG_H"
+ }
+ },
+ {
+ "IPC_FRAG_QUE_COMPLETE": {
+ "format": "[IPC_FRAG] Queuing completing!! ba~ba~la~la~la~la~",
+ "traceClass": "IPC_FRAG_H"
+ }
+ },
+ {
+ "IPC_FRAG_RECYCLE_NO_SPACE": {
+ "format": "[IPC_FRAG] Queuing recycle when space is not enough: is_v4 = %ub, ip_id = %xl",
+ "traceClass": "IPC_FRAG_H"
+ }
+ },
+ {
+ "IPC_FRAG_RECYCLE": {
+ "format": "[IPC_FRAG] Queuing recycle: is_v4 = %ub, ip_id = %xl",
+ "traceClass": "IPC_FRAG_H"
+ }
+ },
+ {
+ "IPC_FRAG_FRAG_START": {
+ "format": "[IPC_FRAG] ipc_fragment_frag start: is_v4 = %ub, buffer_addr = %xl, buffer_len = %ud, ip_id = %xl",
+ "traceClass": "IPC_FRAG_M"
+ }
+ },
+ {
+ "IPC_FRAG_FRAG_END": {
+ "format": "[IPC_FRAG] ipc_fragment_frag end: frag_gpd_num = %ud, frag_gpd_head = %ul, frag_gpd_tail = %ul",
+ "traceClass": "IPC_FRAG_M"
+ }
+ },
+ {
+ "IPC_FRAG_REASM": {
+ "format": "[IPC_FRAG] ipc_fragment_reassemble: is_v4 = %ub, reasm_gpd = %ul",
+ "traceClass": "IPC_FRAG_H"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_IPC_FRAGMENT"
+}
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_defrag.c b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_defrag.c
new file mode 100644
index 0000000..cdffa4f
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_defrag.c
@@ -0,0 +1,1057 @@
+#include "ipc_fragment.h"
+#include "ipc_fragment_struct.h"
+#include "ipc_fragment_utility.h"
+
+// Todo: reasm is disabled by default, we are waiting for the implementation of IPCORE filter
+// Users can set the on/off of reasm of a IPCORE filter, and ipc_fragment will do reassemble if the reasm is on in IPCORE filter
+#define IPC_FRAGMENT_DEFRAG_REASM_EN KAL_FALSE
+#define IPCF_CHK_TO(_k, _e, _c) ((_e > _k && _c > _e) || (_e > _k && _k >= _c) || (_c > _e && _k >= _c) ? KAL_TRUE : KAL_FALSE)
+#define IPCF_Q_EXP_NXTP(_i) ((_i + 1) % IPC_FRAG_EXPIRE_CB_NUM)
+
+kal_bool ipc_fragment_defrag_reasm_en = IPC_FRAGMENT_DEFRAG_REASM_EN;
+
+static IpcFragIpv4L3KeyWithTStamp ipc_q_exp_buff_v4[IPC_FRAG_EXPIRE_CB_NUM];
+static IpcFragIpv6L3KeyWithTStamp ipc_q_exp_buff_v6[IPC_FRAG_EXPIRE_CB_NUM];
+static kal_uint32 ipc_q_exp_pw_v4 = 0, ipc_q_exp_pr_v4 = 0, ipc_q_exp_pw_v6 = 0, ipc_q_exp_pr_v6 = 0;
+static IpcFragUM4 ipc_ipv4_mp;
+static IpcFragUM6 ipc_ipv6_mp;
+
+void ipc_fragment_mp_clear(kal_bool is_v4)
+{
+ IpcFragMnd4 *curr_node4 = NULL;
+ IpcFragMnd6 *curr_node6 = NULL;
+ kal_uint32 index;
+
+ if (is_v4 == KAL_TRUE)
+ {
+ for (index = 0; index < ipc_ipv4_mp.mp_num; ++index)
+ {
+ curr_node4 = ipc_ipv4_mp.mp[index];
+
+ while (curr_node4)
+ {
+ ipc_ipv4_mp.mp[index] = curr_node4->next;
+ ipc_fragment_pktg_rel_gpd_list(&(curr_node4->val));
+ ipc_fragment_pktg_rel_meta_list(&(curr_node4->val));
+ ipc_fragment_mem_free(curr_node4);
+ curr_node4 = ipc_ipv4_mp.mp[index];
+ }
+ }
+ }
+ else
+ {
+ for (index = 0; index < ipc_ipv6_mp.mp_num; ++index)
+ {
+ curr_node6 = ipc_ipv6_mp.mp[index];
+
+ while (curr_node6)
+ {
+ ipc_ipv6_mp.mp[index] = curr_node6->next;
+ ipc_fragment_pktg_rel_gpd_list(&(curr_node6->val));
+ ipc_fragment_pktg_rel_meta_list(&(curr_node6->val));
+ ipc_fragment_mem_free(curr_node6);
+ curr_node6 = ipc_ipv6_mp.mp[index];
+ }
+ }
+ }
+}
+
+void ipc_fragment_mp_erase(void *pk, kal_bool is_v4)
+{
+ IpcFragMnd4 *curr_node4 = NULL, *priv_node4 = NULL;
+ IpcFragMnd6 *curr_node6 = NULL, *priv_node6 = NULL;
+ kal_uint32 index;
+
+ if (is_v4 == KAL_TRUE)
+ {
+ index = ipc_fragment_mf(pk, sizeof(IpcFragIpv4L3Key)) % ipc_ipv4_mp.mp_num;
+ curr_node4 = ipc_ipv4_mp.mp[index];
+ while (curr_node4 && KAL_FALSE == ipc_fragment_ipv4_l3eq((IpcFragIpv4L3Key *)pk, &(curr_node4->key)))
+ {
+ priv_node4 = curr_node4;
+ curr_node4 = curr_node4->next;
+ }
+
+ if (curr_node4)
+ {
+ if (!priv_node4)
+ {
+ ipc_ipv4_mp.mp[index] = curr_node4->next;
+ }
+ else
+ {
+ priv_node4->next = curr_node4->next;
+ }
+ ipc_fragment_pktg_rel_gpd_list(&(curr_node4->val));
+ ipc_fragment_pktg_rel_meta_list(&(curr_node4->val));
+ ipc_fragment_mem_free(curr_node4);
+ }
+ }
+ else
+ {
+ index = ipc_fragment_mf(pk, sizeof(IpcFragIpv6L3Key)) % ipc_ipv6_mp.mp_num;
+ curr_node6 = ipc_ipv6_mp.mp[index];
+ while (curr_node6 && KAL_FALSE == ipc_fragment_ipv6_l3eq((IpcFragIpv6L3Key *)pk, &(curr_node6->key)))
+ {
+ priv_node6 = curr_node6;
+ curr_node6 = curr_node6->next;
+ }
+
+ if (curr_node6)
+ {
+ if (!priv_node6)
+ {
+ ipc_ipv6_mp.mp[index] = curr_node6->next;
+ }
+ else
+ {
+ priv_node6->next = curr_node6->next;
+ }
+ ipc_fragment_pktg_rel_gpd_list(&(curr_node6->val));
+ ipc_fragment_pktg_rel_meta_list(&(curr_node6->val));
+ ipc_fragment_mem_free(curr_node6);
+ }
+ }
+}
+
+void *ipc_fragment_mp_getMN(void *pk, kal_bool is_v4)
+{
+ IpcFragMnd4 *curr_node4 = NULL;
+ IpcFragMnd6 *curr_node6 = NULL;
+ kal_uint32 index;
+
+ if (is_v4 == KAL_TRUE)
+ {
+ index = ipc_fragment_mf(pk, sizeof(IpcFragIpv4L3Key)) % ipc_ipv4_mp.mp_num;
+ curr_node4 = ipc_ipv4_mp.mp[index];
+ while (curr_node4 && KAL_FALSE == ipc_fragment_ipv4_l3eq((IpcFragIpv4L3Key *)pk, &(curr_node4->key)))
+ {
+ curr_node4 = curr_node4->next;
+ }
+ return curr_node4;
+ }
+ else
+ {
+ index = ipc_fragment_mf(pk, sizeof(IpcFragIpv6L3Key)) % ipc_ipv6_mp.mp_num;
+ curr_node6 = ipc_ipv6_mp.mp[index];
+ while (curr_node6 && KAL_FALSE == ipc_fragment_ipv6_l3eq((IpcFragIpv6L3Key *)pk, &(curr_node6->key)))
+ {
+ curr_node6 = curr_node6->next;
+ }
+ return curr_node6;
+ }
+}
+
+IpcFragPktGroupInfo *ipc_fragment_mp_addMN(void *pk, kal_bool is_v4)
+{
+ IpcFragMnd4 *curr_node4 = NULL;
+ IpcFragMnd6 *curr_node6 = NULL;
+ kal_uint32 index;
+
+ if (is_v4 == KAL_TRUE)
+ {
+ index = ipc_fragment_mf(pk, sizeof(IpcFragIpv4L3Key)) % ipc_ipv4_mp.mp_num;
+ curr_node4 = ipc_ipv4_mp.mp[index];
+ while (curr_node4 && KAL_FALSE == ipc_fragment_ipv4_l3eq((IpcFragIpv4L3Key *)pk, &(curr_node4->key)))
+ {
+ curr_node4 = curr_node4->next;
+ }
+ if (!curr_node4)
+ {
+ curr_node4 = (IpcFragMnd4 *)ipc_fragment_mem_alloc(sizeof(IpcFragMnd4));
+ ASSERT(curr_node4);
+ ipc_fragment_pktg_init(&(curr_node4->val));
+ curr_node4->key = *((IpcFragIpv4L3Key *)pk);
+ curr_node4->next = ipc_ipv4_mp.mp[index];
+ ipc_ipv4_mp.mp[index] = curr_node4;
+ }
+
+ return &(curr_node4->val);
+ }
+ else
+ {
+ index = ipc_fragment_mf(pk, sizeof(IpcFragIpv6L3Key)) % ipc_ipv6_mp.mp_num;
+ curr_node6 = ipc_ipv6_mp.mp[index];
+ while (curr_node6 && KAL_FALSE == ipc_fragment_ipv6_l3eq((IpcFragIpv6L3Key *)pk, &(curr_node6->key)))
+ {
+ curr_node6 = curr_node6->next;
+ }
+ if (!curr_node6)
+ {
+ curr_node6 = (IpcFragMnd6 *)ipc_fragment_mem_alloc(sizeof(IpcFragMnd6));
+ ASSERT(curr_node6);
+ ipc_fragment_pktg_init(&(curr_node6->val));
+ curr_node6->key = *((IpcFragIpv6L3Key *)pk);
+ curr_node6->next = ipc_ipv6_mp.mp[index];
+ ipc_ipv6_mp.mp[index] = curr_node6;
+ }
+
+ return &(curr_node6->val);
+ }
+}
+
+void ipc_fragment_queuing_recycle(kal_bool is_v4)
+{
+ IpcFragPktGroupInfo *pkt_grp_info;
+
+ if (is_v4)
+ {
+ IpcFragIpv4L3Key v4_key = ipc_q_exp_buff_v4[ipc_q_exp_pr_v4].v4_key;
+ ipc_q_exp_pr_v4 = IPCF_Q_EXP_NXTP(ipc_q_exp_pr_v4);
+
+ if (ipc_fragment_mp_getMN(&v4_key, KAL_TRUE))
+ {
+ pkt_grp_info = ipc_fragment_mp_addMN(&v4_key, KAL_TRUE);
+
+ hif_data_trace(MD_TRC_IPC_FRAG_RECYCLE, 1, v4_key.ip_id);
+
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_COMPLETE) == 0)
+ {
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_FIRST_PKT) != 0)
+ {
+ ipc_fragment_icmp4_send(IPC_ICMP4_TYPE_TIME_EXCEEDED, IPC_ICMP4_CODE_FRAG_REASM_TIME_EXCEEDED, pkt_grp_info->head_gpd);
+ }
+ ipc_frag_send_pkt(IPC_IP_TYPE_IPV4, &(pkt_grp_info->first_packet_refilter_info), pkt_grp_info->head_gpd, pkt_grp_info->tail_gpd);
+ pkt_grp_info->head_gpd = pkt_grp_info->tail_gpd = NULL;
+ }
+ ipc_fragment_mp_erase(&v4_key, KAL_TRUE);
+ }
+ }
+ else
+ {
+ IpcFragIpv6L3Key v6_key = ipc_q_exp_buff_v6[ipc_q_exp_pr_v6].v6_key;
+ ipc_q_exp_pr_v6 = IPCF_Q_EXP_NXTP(ipc_q_exp_pr_v6);
+
+ if (ipc_fragment_mp_getMN(&v6_key, KAL_FALSE))
+ {
+ pkt_grp_info = ipc_fragment_mp_addMN(&v6_key, KAL_FALSE);
+
+ hif_data_trace(MD_TRC_IPC_FRAG_RECYCLE, 0, v6_key.ip_id);
+
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_COMPLETE) == 0)
+ {
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_FIRST_PKT) != 0)
+ {
+ ipc_fragment_icmp6_send(IPC_ICMP6_TYPE_TIME_EXCEEDED, IPC_ICMP6_CODE_FRAG_REASM_TIME_EXCEEDED, pkt_grp_info->head_gpd);
+ }
+ ipc_frag_send_pkt(IPC_IP_TYPE_IPV6, &(pkt_grp_info->first_packet_refilter_info), pkt_grp_info->head_gpd, pkt_grp_info->tail_gpd);
+ pkt_grp_info->head_gpd = pkt_grp_info->tail_gpd = NULL;
+ }
+ ipc_fragment_mp_erase(&v6_key, KAL_FALSE);
+ }
+ }
+}
+
+kal_bool ipc_fragment_queuing_recycle_meta_in_insufficient_space(kal_bool is_v4)
+{
+ kal_bool result = KAL_FALSE;
+ IpcFragIpv4L3Key v4_key;
+ IpcFragIpv6L3Key v6_key;
+ IpcFragPktGroupInfo *pkt_grp_info;
+ kal_uint32 pr = 0;
+
+ if (is_v4 && ipc_q_exp_pw_v4 != ipc_q_exp_pr_v4)
+ {
+ pr = ipc_q_exp_pr_v4;
+ while (pr != ipc_q_exp_pw_v4 && result == KAL_FALSE)
+ {
+ v4_key = ipc_q_exp_buff_v4[pr].v4_key;
+ if (ipc_fragment_mp_getMN(&v4_key, KAL_TRUE))
+ {
+ pkt_grp_info = ipc_fragment_mp_addMN(&v4_key, KAL_TRUE);
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_COMPLETE) == 0 && (pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_DROPPED) == 0)
+ {
+ hif_data_trace(MD_TRC_IPC_FRAG_RECYCLE_NO_SPACE, 1, v4_key.ip_id);
+ pkt_grp_info->info_mask |= IPC_FRAG_INFO_RECEIVE_DROPPED;
+ ipc_fragment_pktg_rel_meta_list(pkt_grp_info);
+ result = KAL_TRUE;
+ }
+ }
+ pr = IPCF_Q_EXP_NXTP(pr);
+ }
+ }
+ else if (!is_v4 && ipc_q_exp_pw_v6 != ipc_q_exp_pr_v6)
+ {
+ pr = ipc_q_exp_pr_v6;
+ while (pr != ipc_q_exp_pw_v6 && result == KAL_FALSE)
+ {
+ v6_key = ipc_q_exp_buff_v6[pr].v6_key;
+ if (ipc_fragment_mp_getMN(&v6_key, KAL_FALSE))
+ {
+ pkt_grp_info = ipc_fragment_mp_addMN(&v6_key, KAL_FALSE);
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_COMPLETE) == 0 && (pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_DROPPED) == 0)
+ {
+ hif_data_trace(MD_TRC_IPC_FRAG_RECYCLE_NO_SPACE, 0, v6_key.ip_id);
+ pkt_grp_info->info_mask |= IPC_FRAG_INFO_RECEIVE_DROPPED;
+ ipc_fragment_pktg_rel_meta_list(pkt_grp_info);
+ result = KAL_TRUE;
+ }
+ }
+ pr = IPCF_Q_EXP_NXTP(pr);
+ }
+ }
+
+ return result;
+}
+
+void ipc_fragment_queueing_timeout(void *parm);
+
+void ipc_fragment_queuing_set_expire_timer()
+{
+ ipc_fragment_t *p = ipc_fragment_get_inst();
+
+ if (p->ipc_frag_queue_expire_es && !p->ipc_frag_queue_expire_evt)
+ {
+ p->ipc_frag_queue_expire_evt = evshed_set_event(p->ipc_frag_queue_expire_es,
+ ipc_fragment_queueing_timeout, // timeout handler
+ NULL, // event_hf_param
+ IPC_FRAG_POLLING_EXPIRE_SEC);
+
+ ASSERT(p->ipc_frag_queue_expire_evt);
+ }
+}
+
+void ipc_fragment_queueing_timeout(void *parm)
+{
+ kal_uint32 curr_tick = 0, end_tick = 0, key_tick = 0;
+ kal_bool is_timeout = KAL_TRUE;
+ ipc_fragment_t *p = ipc_fragment_get_inst();
+
+ p->ipc_frag_queue_expire_evt = NULL;
+ curr_tick = kal_get_systicks();
+
+ is_timeout = KAL_TRUE;
+ while (ipc_q_exp_pw_v4 != ipc_q_exp_pr_v4 && is_timeout == KAL_TRUE)
+ {
+ key_tick = ipc_q_exp_buff_v4[ipc_q_exp_pr_v4].tickStamp;
+ end_tick = key_tick + IPC_FRAG_QUEUING_EXPIRE_SEC;
+
+ is_timeout = IPCF_CHK_TO(key_tick, end_tick, curr_tick);
+ if (is_timeout == KAL_TRUE)
+ {
+ ipc_fragment_queuing_recycle(KAL_TRUE);
+ }
+ }
+
+ is_timeout = KAL_TRUE;
+ while (ipc_q_exp_pw_v6 != ipc_q_exp_pr_v6 && is_timeout == KAL_TRUE)
+ {
+ key_tick = ipc_q_exp_buff_v6[ipc_q_exp_pr_v6].tickStamp;
+ end_tick = key_tick + IPC_FRAG_QUEUING_EXPIRE_SEC;
+
+ is_timeout = IPCF_CHK_TO(key_tick, end_tick, curr_tick);
+ if (is_timeout == KAL_TRUE)
+ {
+ ipc_fragment_queuing_recycle(KAL_FALSE);
+ }
+ }
+
+ if (ipc_q_exp_pw_v4 != ipc_q_exp_pr_v4 || ipc_q_exp_pw_v6 != ipc_q_exp_pr_v6)
+ {
+ ipc_fragment_queuing_set_expire_timer();
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+void ipc_fragment_mp_init()
+{
+ kal_uint32 i;
+
+ kal_mem_set(&ipc_ipv4_mp, 0, sizeof(ipc_ipv4_mp));
+ ipc_ipv4_mp.mp_num = IPC_FRAG_HASH_TABLE_BUCK_NUM;
+ ipc_ipv4_mp.mp = (IpcFragMnd4 **)ipc_fragment_mem_alloc(sizeof(IpcFragMnd4 *) * IPC_FRAG_HASH_TABLE_BUCK_NUM);
+ ASSERT(ipc_ipv4_mp.mp);
+ for (i = 0; i < IPC_FRAG_HASH_TABLE_BUCK_NUM; ++i)
+ {
+ ipc_ipv4_mp.mp[i] = NULL;
+ }
+
+ kal_mem_set(&ipc_ipv6_mp, 0, sizeof(ipc_ipv6_mp));
+ ipc_ipv6_mp.mp_num = IPC_FRAG_HASH_TABLE_BUCK_NUM;
+ ipc_ipv6_mp.mp = (IpcFragMnd6 **)ipc_fragment_mem_alloc(sizeof(IpcFragMnd6 *) * IPC_FRAG_HASH_TABLE_BUCK_NUM);
+ ASSERT(ipc_ipv6_mp.mp);
+ for (i = 0; i < IPC_FRAG_HASH_TABLE_BUCK_NUM; ++i)
+ {
+ ipc_ipv6_mp.mp[i] = NULL;
+ }
+}
+
+void ipc_fragment_mp_deinit()
+{
+ kal_uint32 index;
+ IpcFragMnd4 *curr_node4 = NULL;
+ IpcFragMnd6 *curr_node6 = NULL;
+
+ if (ipc_ipv4_mp.mp && (ipc_ipv4_mp.mp_num > 0))
+ {
+ for (index = 0; index < ipc_ipv4_mp.mp_num; ++index)
+ {
+ curr_node4 = ipc_ipv4_mp.mp[index];
+ while (curr_node4)
+ {
+ ipc_ipv4_mp.mp[index] = curr_node4->next;
+ ipc_fragment_pktg_rel_gpd_list(&(curr_node4->val));
+ ipc_fragment_pktg_rel_meta_list(&(curr_node4->val));
+ ipc_fragment_mem_free(curr_node4);
+ curr_node4 = ipc_ipv4_mp.mp[index];
+ }
+ }
+ ipc_fragment_mem_free(ipc_ipv4_mp.mp);
+ }
+ kal_mem_set(&ipc_ipv4_mp, 0, sizeof(ipc_ipv4_mp));
+
+ if (ipc_ipv6_mp.mp && (ipc_ipv6_mp.mp_num > 0))
+ {
+ for (index = 0; index < ipc_ipv6_mp.mp_num; ++index)
+ {
+ curr_node6 = ipc_ipv6_mp.mp[index];
+ while (curr_node6)
+ {
+ ipc_ipv6_mp.mp[index] = curr_node6->next;
+ ipc_fragment_pktg_rel_gpd_list(&(curr_node6->val));
+ ipc_fragment_pktg_rel_meta_list(&(curr_node6->val));
+ ipc_fragment_mem_free(curr_node6);
+ curr_node6 = ipc_ipv6_mp.mp[index];
+ }
+ }
+ ipc_fragment_mem_free(ipc_ipv6_mp.mp);
+ }
+ kal_mem_set(&ipc_ipv6_mp, 0, sizeof(ipc_ipv6_mp));
+}
+
+void ipc_fragment_queuing_expire_init()
+{
+ char ipc_fragment_es[] = {'I', 'P', 'C', '_', 'F', 'R', 'A', 'G', '_', 'E', 'S', '\0'};
+ ipc_fragment_t *p = ipc_fragment_get_inst();
+
+ if (ipc_q_exp_pw_v4 != ipc_q_exp_pr_v4 || ipc_q_exp_pw_v6 != ipc_q_exp_pr_v6)
+ {
+ ASSERT(0);
+ }
+
+ p->ipc_frag_queue_expire_evt = NULL;
+ p->ipc_frag_queue_expire_es = evshed_create(ipc_fragment_es, /* timer_name: event scheduler name */
+ MOD_IPC_FRAGMENT, /* dest_mod_id: system sends timeout message to this module when event scheduler timeout happens */
+ 0, /* fuzz */
+ 0); /* max_delay_ticks */
+
+ if (p->ipc_frag_queue_expire_es)
+ {
+ evshed_set_index(p->ipc_frag_queue_expire_es, IPC_FRAG_ES_IDX_QUEUE_EXPIRE);
+ }
+ else
+ {
+ ASSERT(0);
+ }
+}
+
+void ipc_fragment_queuing_expire_deinit()
+{
+ ipc_fragment_t *p = ipc_fragment_get_inst();
+
+ evshed_delete_all_events(p->ipc_frag_queue_expire_es);
+ p->ipc_frag_queue_expire_evt = NULL;
+ ipc_q_exp_pr_v4 = ipc_q_exp_pw_v4;
+ ipc_q_exp_pr_v6 = ipc_q_exp_pw_v6;
+}
+
+void ipc_fragment_queuing_v4(qbm_gpd *new_gpd, ipc_packet_info_t *packet_info, kal_uint32 matched_filter_id, ipc_frag_refilter_info_t *refilter_info)
+{
+ IpcFragPktGroupInfo *pkt_grp_info;
+ IpcFragPktMetaInfo *new_meta = NULL, *next_meta, *priv_meta, *free_meta;
+ qbm_gpd *next_gpd, *priv_gpd, *free_gpd, *reasm_gpd;
+ IpcFragIpv4L3Key v4_key;
+ kal_uint8 frag_flag;
+ kal_uint32 frag_offset, frag_end;
+ kal_int32 shrink_len;
+ IpcFragIpv4L3KeyWithTStamp key_with_time;
+ kal_bool need_insert_cb = KAL_FALSE;
+ void *buff;
+ kal_uint16 buff_len;
+
+ if (!new_gpd || !packet_info || !refilter_info)
+ {
+ goto ipc_frag_v4_queue_err;
+ }
+
+ v4_key.src_addr = packet_info->src_addr[0];
+ v4_key.dst_addr = packet_info->dst_addr[0];
+ v4_key.ip_id = packet_info->ip_id;
+ v4_key.protocol = packet_info->protocol;
+ v4_key.reserved = 0;
+ if (ipc_fragment_mp_getMN(&v4_key, KAL_TRUE))
+ {
+ pkt_grp_info = ipc_fragment_mp_addMN(&v4_key, KAL_TRUE);
+ }
+ else
+ {
+ pkt_grp_info = ipc_fragment_mp_addMN(&v4_key, KAL_TRUE);
+ ipc_fragment_pktg_init(pkt_grp_info);
+ }
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_V4_KEY_INFO, v4_key.src_addr, v4_key.dst_addr, v4_key.ip_id, v4_key.protocol);
+
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_COMPLETE) || (pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_DROPPED))
+ {
+ goto ipc_frag_v4_queue_err;
+ }
+
+ new_meta = (IpcFragPktMetaInfo *)ipc_fragment_mem_alloc(sizeof(IpcFragPktMetaInfo));
+ if (!new_meta)
+ {
+ if (ipc_fragment_queuing_recycle_meta_in_insufficient_space(KAL_TRUE) || ipc_fragment_queuing_recycle_meta_in_insufficient_space(KAL_FALSE))
+ {
+ new_meta = (IpcFragPktMetaInfo *)ipc_fragment_mem_alloc(sizeof(IpcFragPktMetaInfo));
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ if (pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_DROPPED)
+ {
+ goto ipc_frag_v4_queue_err;
+ }
+ }
+ frag_offset = new_meta->offset = new_meta->orig_offset = packet_info->frag_payload_offset;
+ new_meta->pkt_len = new_meta->orig_pkt_len = packet_info->frag_payload_len;
+ new_meta->gpd_payload_offset = packet_info->frag_buffer_payload_offset;
+ frag_end = new_meta->offset + new_meta->pkt_len;
+ frag_flag = packet_info->frag_flag;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_FRAG_INFO, frag_offset, new_meta->pkt_len, frag_flag, frag_end);
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_GRP_INFO, pkt_grp_info->info_mask, pkt_grp_info->accumulate_len, pkt_grp_info->total_len, pkt_grp_info->head_gpd);
+
+ // Dump the GPD packet in ELT, assume the input GPD must be followed with one BD
+ buff_len = QBM_DES_GET_DATALEN(new_gpd);
+ buff = QBM_DES_GET_DATAPTR(QBM_DES_GET_DATAPTR(new_gpd));
+ IPC_FRAGMENT_DL_PKT_DUMP(buff, buff_len);
+
+ if (pkt_grp_info->head_gpd == NULL)
+ {
+ memcpy(&(pkt_grp_info->first_packet_refilter_info), refilter_info, sizeof(ipc_frag_refilter_info_t));
+ need_insert_cb = KAL_TRUE;
+ }
+
+ if ((frag_flag & IPC_FRAG_FLAG_MF) == 0)
+ {
+ if ((frag_end < pkt_grp_info->accumulate_len) || ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_LAST_PKT) && (frag_end != pkt_grp_info->total_len)))
+ {
+ goto ipc_frag_v4_queue_err;
+ }
+
+ pkt_grp_info->info_mask |= IPC_FRAG_INFO_RECEIVE_LAST_PKT;
+ pkt_grp_info->total_len = frag_end;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_LAST_FRAG);
+ }
+ else
+ {
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_LAST_PKT) && (frag_end > pkt_grp_info->total_len))
+ {
+ goto ipc_frag_v4_queue_err;
+ }
+ }
+
+ if (new_meta->pkt_len == 0)
+ {
+ goto ipc_frag_v4_queue_err;
+ }
+
+ priv_meta = pkt_grp_info->tail_meta;
+ priv_gpd = pkt_grp_info->tail_gpd;
+ if (!priv_gpd || priv_meta->offset < frag_offset)
+ {
+ next_gpd = NULL;
+ next_meta = NULL;
+ }
+ else
+ {
+ priv_meta = NULL;
+ priv_gpd = NULL;
+ next_gpd = pkt_grp_info->head_gpd;
+ next_meta = pkt_grp_info->head_meta;
+
+ while (next_gpd)
+ {
+ if (next_meta->offset >= frag_offset)
+ {
+ break;
+ }
+ else
+ {
+ priv_gpd = next_gpd;
+ priv_meta = next_meta;
+ next_gpd = QBM_DES_GET_NEXT(next_gpd);
+ next_meta = next_meta->next;
+ }
+ }
+ }
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_FIND_POS, priv_gpd, priv_meta, next_gpd, next_meta);
+
+ if (priv_gpd)
+ {
+ shrink_len = (kal_int32)priv_meta->offset + priv_meta->pkt_len - frag_offset;
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_OVERLAP_PRIV, priv_meta->offset, priv_meta->pkt_len, shrink_len);
+
+ if (shrink_len > 0)
+ {
+ frag_offset += shrink_len;
+ if (frag_offset < frag_end)
+ {
+ new_meta->offset = frag_offset;
+ new_meta->pkt_len -= shrink_len;
+ }
+ else
+ {
+ goto ipc_frag_v4_queue_err;
+ }
+ }
+ }
+
+ while (next_gpd && next_meta->offset < frag_end)
+ {
+ shrink_len = (kal_int32)frag_end - next_meta->offset;
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_OVERLAP_NXT, next_meta->offset, next_meta->pkt_len, shrink_len);
+
+ if (shrink_len < next_meta->pkt_len)
+ {
+ if (shrink_len > 0)
+ {
+ next_meta->offset += shrink_len;
+ pkt_grp_info->accumulate_len -= shrink_len;
+ }
+ break;
+ }
+ else
+ {
+ free_gpd = next_gpd;
+ free_meta = next_meta;
+ next_gpd = QBM_DES_GET_NEXT(next_gpd);
+ next_meta = next_meta->next;
+
+ if (priv_gpd)
+ {
+ QBM_DES_SET_NEXT(priv_gpd, next_gpd);
+ priv_meta->next = next_meta;
+ }
+ else
+ {
+ pkt_grp_info->head_gpd = next_gpd;
+ pkt_grp_info->head_meta = next_meta;
+ }
+
+ pkt_grp_info->accumulate_len -= free_meta->pkt_len;
+ qbmt_dest_q(free_gpd, free_gpd);
+ ipc_fragment_mem_free(free_meta);
+ }
+ }
+
+ QBM_DES_SET_NEXT(new_gpd, next_gpd);
+ new_meta->next = next_meta;
+
+ if (!next_gpd)
+ {
+ pkt_grp_info->tail_gpd = new_gpd;
+ pkt_grp_info->tail_meta = new_meta;
+ }
+
+ if (priv_gpd)
+ {
+ QBM_DES_SET_NEXT(priv_gpd, new_gpd);
+ priv_meta->next = new_meta;
+ }
+ else
+ {
+ pkt_grp_info->head_gpd = new_gpd;
+ pkt_grp_info->head_meta = new_meta;
+ }
+
+ pkt_grp_info->accumulate_len += new_meta->pkt_len;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_INSERT, new_meta->offset, new_meta->pkt_len, pkt_grp_info->accumulate_len, frag_offset);
+
+ if (frag_offset == 0)
+ {
+ pkt_grp_info->info_mask |= IPC_FRAG_INFO_RECEIVE_FIRST_PKT;
+ pkt_grp_info->filter_id = matched_filter_id;
+ memcpy(&(pkt_grp_info->first_packet_info), packet_info, sizeof(ipc_packet_info_t));
+ memcpy(&(pkt_grp_info->first_packet_refilter_info), refilter_info, sizeof(ipc_frag_refilter_info_t));
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_FIRST_FRAG, pkt_grp_info->filter_id);
+ }
+
+ if (pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_FIRST_PKT && pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_LAST_PKT &&
+ pkt_grp_info->total_len == pkt_grp_info->accumulate_len)
+ {
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_COMPLETE);
+
+ // Send collected fragments to IPCORE for refiltering, and IPCORE will help to trigger reassemable if needed
+ (pkt_grp_info->first_packet_refilter_info).packet_info = &(pkt_grp_info->first_packet_info);
+ if (ipc_fragment_defrag_reasm_en)
+ {
+ ipc_fragment_reassemble(KAL_TRUE, &reasm_gpd, pkt_grp_info);
+ }
+ ipc_fragment_refiltering_queued_packets(IPC_IP_TYPE_IPV4, &(pkt_grp_info->first_packet_refilter_info), pkt_grp_info->head_gpd, pkt_grp_info->tail_gpd);
+ pkt_grp_info->head_gpd = pkt_grp_info->tail_gpd = NULL;
+
+ pkt_grp_info->info_mask |= IPC_FRAG_INFO_RECEIVE_COMPLETE;
+ ipc_fragment_mp_erase(&v4_key, KAL_TRUE);
+ }
+
+ if (need_insert_cb == KAL_TRUE)
+ {
+ key_with_time.v4_key = v4_key;
+ key_with_time.tickStamp = kal_get_systicks();
+
+ if (IPCF_Q_EXP_NXTP(ipc_q_exp_pw_v4) == ipc_q_exp_pr_v4)
+ {
+ ipc_fragment_queuing_recycle(KAL_TRUE);
+ }
+
+ if (ipc_q_exp_pw_v4 == ipc_q_exp_pr_v4 && ipc_q_exp_pw_v6 == ipc_q_exp_pr_v6)
+ {
+ ipc_fragment_queuing_set_expire_timer();
+ }
+
+ ipc_q_exp_buff_v4[ipc_q_exp_pw_v4] = key_with_time;
+ ipc_q_exp_pw_v4 = IPCF_Q_EXP_NXTP(ipc_q_exp_pw_v4);
+ }
+
+ return;
+
+ipc_frag_v4_queue_err:
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_ERR, new_gpd, new_meta);
+
+ if (new_meta)
+ {
+ ipc_fragment_mem_free(new_meta);
+ }
+
+ if (new_gpd)
+ {
+ ipc_frag_send_pkt(IPC_IP_TYPE_IPV4, refilter_info, new_gpd, new_gpd);
+ }
+
+ return;
+}
+
+void ipc_fragment_queuing_v6(qbm_gpd *new_gpd, ipc_packet_info_t *packet_info, kal_uint32 matched_filter_id, ipc_frag_refilter_info_t *refilter_info)
+{
+ IpcFragPktGroupInfo *pkt_grp_info;
+ IpcFragPktMetaInfo *new_meta = NULL, *next_meta, *priv_meta;
+ qbm_gpd *next_gpd, *priv_gpd, *reasm_gpd;
+ IpcFragIpv6L3Key v6_key;
+ kal_uint8 frag_flag;
+ kal_uint32 frag_offset, frag_end;
+ kal_uint8 i;
+ IpcFragIpv6L3KeyWithTStamp key_with_time;
+ kal_bool need_insert_cb = KAL_FALSE;
+ void *buff;
+ kal_uint16 buff_len;
+
+ if (!new_gpd || !packet_info || !refilter_info)
+ {
+ goto ipc_frag_v6_queue_err;
+ }
+
+ for (i = 0; i < 4; ++i)
+ {
+ v6_key.src_addr[i] = packet_info->src_addr[i];
+ v6_key.dst_addr[i] = packet_info->dst_addr[i];
+ }
+ v6_key.ip_id = packet_info->ip_id;
+ if (ipc_fragment_mp_getMN(&v6_key, KAL_FALSE))
+ {
+ pkt_grp_info = ipc_fragment_mp_addMN(&v6_key, KAL_FALSE);
+ }
+ else
+ {
+ pkt_grp_info = ipc_fragment_mp_addMN(&v6_key, KAL_FALSE);
+ ipc_fragment_pktg_init(pkt_grp_info);
+ }
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_V6_KEY_INFO_SRC, v6_key.src_addr[0], v6_key.src_addr[1], v6_key.src_addr[2], v6_key.src_addr[3]);
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_V6_KEY_INFO_DST, v6_key.dst_addr[0], v6_key.dst_addr[1], v6_key.dst_addr[2], v6_key.dst_addr[3]);
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_V6_KEY_INFO_ID, v6_key.ip_id);
+
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_COMPLETE) || (pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_DROPPED))
+ {
+ goto ipc_frag_v6_queue_err;
+ }
+
+ new_meta = (IpcFragPktMetaInfo *)ipc_fragment_mem_alloc(sizeof(IpcFragPktMetaInfo));
+ if (!new_meta)
+ {
+ if (ipc_fragment_queuing_recycle_meta_in_insufficient_space(KAL_FALSE) || ipc_fragment_queuing_recycle_meta_in_insufficient_space(KAL_TRUE))
+ {
+ new_meta = (IpcFragPktMetaInfo *)ipc_fragment_mem_alloc(sizeof(IpcFragPktMetaInfo));
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ if (pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_DROPPED)
+ {
+ goto ipc_frag_v6_queue_err;
+ }
+ }
+ frag_offset = new_meta->offset = new_meta->orig_offset = packet_info->frag_payload_offset;
+ new_meta->pkt_len = new_meta->orig_pkt_len = packet_info->frag_payload_len;
+ new_meta->gpd_payload_offset = packet_info->frag_buffer_payload_offset;
+ frag_end = new_meta->offset + new_meta->pkt_len;
+ frag_flag = packet_info->frag_flag;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_FRAG_INFO, frag_offset, new_meta->pkt_len, frag_flag, frag_end);
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_GRP_INFO, pkt_grp_info->info_mask, pkt_grp_info->accumulate_len, pkt_grp_info->total_len, pkt_grp_info->head_gpd);
+
+ // Dump the GPD packet in ELT, assume the input GPD must be followed with one BD
+ buff_len = QBM_DES_GET_DATALEN(new_gpd);
+ buff = QBM_DES_GET_DATAPTR(QBM_DES_GET_DATAPTR(new_gpd));
+ IPC_FRAGMENT_DL_PKT_DUMP(buff, buff_len);
+
+ if (frag_end > IPC_FRAG_IPV6_MAX_LEN)
+ {
+ // TODO: send ICMP
+ goto ipc_frag_v6_queue_err;
+ }
+
+ if (pkt_grp_info->head_gpd == NULL)
+ {
+ memcpy(&(pkt_grp_info->first_packet_refilter_info), refilter_info, sizeof(ipc_frag_refilter_info_t));
+ need_insert_cb = KAL_TRUE;
+ }
+
+ if ((frag_flag & IPC_FRAG_FLAG_MF) == 0)
+ {
+ if ((frag_end < pkt_grp_info->accumulate_len) || ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_LAST_PKT) && (frag_end != pkt_grp_info->total_len)))
+ {
+ goto ipc_frag_v6_queue_err;
+ }
+
+ pkt_grp_info->info_mask |= IPC_FRAG_INFO_RECEIVE_LAST_PKT;
+ pkt_grp_info->total_len = frag_end;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_LAST_FRAG);
+ }
+ else
+ {
+ if ((pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_LAST_PKT) && (frag_end > pkt_grp_info->total_len))
+ {
+ goto ipc_frag_v6_queue_err;
+ }
+ }
+
+ if (new_meta->pkt_len == 0)
+ {
+ goto ipc_frag_v6_queue_err;
+ }
+
+ priv_meta = pkt_grp_info->tail_meta;
+ priv_gpd = pkt_grp_info->tail_gpd;
+ if (!priv_gpd || priv_meta->offset < frag_offset)
+ {
+ next_gpd = NULL;
+ next_meta = NULL;
+ }
+ else
+ {
+ priv_meta = NULL;
+ priv_gpd = NULL;
+ next_gpd = pkt_grp_info->head_gpd;
+ next_meta = pkt_grp_info->head_meta;
+
+ while (next_gpd)
+ {
+ if (next_meta->offset >= frag_offset)
+ {
+ break;
+ }
+ else
+ {
+ priv_gpd = next_gpd;
+ priv_meta = next_meta;
+ next_gpd = QBM_DES_GET_NEXT(next_gpd);
+ next_meta = next_meta->next;
+ }
+ }
+ }
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_FIND_POS, priv_gpd, priv_meta, next_gpd, next_meta);
+
+ if (priv_gpd && (kal_uint32)priv_meta->offset + priv_meta->pkt_len > frag_offset)
+ {
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_OVERLAP_PRIV, priv_meta->offset, priv_meta->pkt_len, 0);
+ ipc_fragment_mp_erase(&v6_key, KAL_FALSE);
+ goto ipc_frag_v6_queue_err;
+ }
+
+ if (next_gpd && next_meta->offset < frag_end)
+ {
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_OVERLAP_NXT, next_meta->offset, next_meta->pkt_len, 0);
+ ipc_fragment_mp_erase(&v6_key, KAL_FALSE);
+ goto ipc_frag_v6_queue_err;
+ }
+
+ QBM_DES_SET_NEXT(new_gpd, next_gpd);
+ new_meta->next = next_meta;
+
+ if (!next_gpd)
+ {
+ pkt_grp_info->tail_gpd = new_gpd;
+ pkt_grp_info->tail_meta = new_meta;
+ }
+
+ if (priv_gpd)
+ {
+ QBM_DES_SET_NEXT(priv_gpd, new_gpd);
+ priv_meta->next = new_meta;
+ }
+ else
+ {
+ pkt_grp_info->head_gpd = new_gpd;
+ pkt_grp_info->head_meta = new_meta;
+ }
+
+ pkt_grp_info->accumulate_len += new_meta->pkt_len;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_INSERT, new_meta->offset, new_meta->pkt_len, pkt_grp_info->accumulate_len, frag_offset);
+
+ if (frag_offset == 0)
+ {
+ pkt_grp_info->info_mask |= IPC_FRAG_INFO_RECEIVE_FIRST_PKT;
+ pkt_grp_info->filter_id = matched_filter_id;
+ memcpy(&(pkt_grp_info->first_packet_info), packet_info, sizeof(ipc_packet_info_t));
+ memcpy(&(pkt_grp_info->first_packet_refilter_info), refilter_info, sizeof(ipc_frag_refilter_info_t));
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_FIRST_FRAG, pkt_grp_info->filter_id);
+ }
+
+ if (pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_FIRST_PKT && pkt_grp_info->info_mask & IPC_FRAG_INFO_RECEIVE_LAST_PKT &&
+ pkt_grp_info->total_len == pkt_grp_info->accumulate_len)
+ {
+
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_COMPLETE);
+
+ // Send collected fragments to IPCORE for refiltering, and IPCORE will help to trigger reassemable if needed
+ (pkt_grp_info->first_packet_refilter_info).packet_info = &(pkt_grp_info->first_packet_info);
+ if (ipc_fragment_defrag_reasm_en || pkt_grp_info->first_packet_info.need_reassemble)
+ {
+ ipc_fragment_reassemble(KAL_FALSE, &reasm_gpd, pkt_grp_info);
+ pkt_grp_info->first_packet_refilter_info.is_pkt_info = KAL_FALSE;
+ pkt_grp_info->first_packet_info.need_reassemble = KAL_FALSE;
+ } else {
+ pkt_grp_info->first_packet_refilter_info.is_pkt_info = KAL_TRUE;
+ }
+ ipc_fragment_refiltering_queued_packets(IPC_IP_TYPE_IPV6, &(pkt_grp_info->first_packet_refilter_info), pkt_grp_info->head_gpd, pkt_grp_info->tail_gpd);
+ pkt_grp_info->head_gpd = pkt_grp_info->tail_gpd = NULL;
+
+ pkt_grp_info->info_mask |= IPC_FRAG_INFO_RECEIVE_COMPLETE;
+ ipc_fragment_mp_erase(&v6_key, KAL_FALSE);
+ }
+
+ if (need_insert_cb == KAL_TRUE)
+ {
+ key_with_time.v6_key = v6_key;
+ key_with_time.tickStamp = kal_get_systicks();
+
+ if (IPCF_Q_EXP_NXTP(ipc_q_exp_pw_v6) == ipc_q_exp_pr_v6)
+ {
+ ipc_fragment_queuing_recycle(KAL_FALSE);
+ }
+
+ if (ipc_q_exp_pw_v4 == ipc_q_exp_pr_v4 && ipc_q_exp_pw_v6 == ipc_q_exp_pr_v6)
+ {
+ ipc_fragment_queuing_set_expire_timer();
+ }
+
+ ipc_q_exp_buff_v6[ipc_q_exp_pw_v6] = key_with_time;
+ ipc_q_exp_pw_v6 = IPCF_Q_EXP_NXTP(ipc_q_exp_pw_v6);
+ }
+
+ return;
+
+ipc_frag_v6_queue_err:
+ hif_data_trace(MD_TRC_IPC_FRAG_QUE_ERR, new_gpd, new_meta);
+ if (new_meta)
+ {
+ ipc_fragment_mem_free(new_meta);
+ }
+
+ if (new_gpd)
+ {
+ ipc_frag_send_pkt(IPC_IP_TYPE_IPV6, refilter_info, new_gpd, new_gpd);
+ }
+
+ return;
+}
+
+void ipc_fragment_mp_test()
+{
+ kal_int32 i, j;
+ IpcFragIpv4L3Key v4_key = {0};
+ IpcFragIpv6L3Key v6_key = {0};
+ IpcFragPktMetaInfo *meta_node = NULL;
+ IpcFragPktGroupInfo *p_info = NULL;
+ IpcFragMnd4 *p_ptr= NULL;
+
+ for (i = 0; i < 20; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ v4_key.src_addr = i;
+ v4_key.dst_addr = 30000 + i;
+ v4_key.ip_id = 2000 + i;
+ v4_key.protocol = 100 + i;
+
+ meta_node = (IpcFragPktMetaInfo *)ipc_fragment_mem_alloc(sizeof(IpcFragPktMetaInfo));
+ ASSERT(meta_node);
+ meta_node->next = ipc_fragment_mp_addMN(&v4_key, KAL_TRUE)->head_meta;
+ meta_node->offset = j;
+ meta_node->pkt_len = i + j;
+ p_info = ipc_fragment_mp_addMN(&v4_key, KAL_TRUE);
+ if (NULL == p_info) {
+ return;
+ }
+ p_info->head_meta = meta_node;
+
+ p_ptr = ipc_fragment_mp_getMN(&v4_key, KAL_TRUE);
+ if (NULL == p_ptr) {
+ return;
+ }
+
+ ASSERT(ipc_fragment_ipv4_l3eq(&v4_key, &(p_ptr->key)) == KAL_TRUE);
+ v4_key.protocol = i;
+ ASSERT(ipc_fragment_mp_getMN(&v4_key, KAL_TRUE) == NULL);
+ }
+
+ for (j = 0; j < 4; ++j)
+ {
+ v6_key.src_addr[0] = i + 0;
+ v6_key.src_addr[1] = i + 1;
+ v6_key.src_addr[2] = i + 2;
+ v6_key.src_addr[3] = i + 3;
+ v6_key.dst_addr[0] = 30000 + i;
+ v6_key.dst_addr[1] = 30001 + i;
+ v6_key.dst_addr[2] = 30002 + i;
+ v6_key.dst_addr[3] = 30003 + i;
+ v6_key.ip_id = 4000 + i;
+
+ meta_node = (IpcFragPktMetaInfo *)ipc_fragment_mem_alloc(sizeof(IpcFragPktMetaInfo));
+ ASSERT(meta_node);
+ meta_node->next = ipc_fragment_mp_addMN(&v6_key, KAL_FALSE)->head_meta;
+ meta_node->offset = j;
+ meta_node->pkt_len = i + j;
+ ipc_fragment_mp_addMN(&v6_key, KAL_FALSE)->head_meta = meta_node;
+ ASSERT(ipc_fragment_ipv6_l3eq(&v6_key, &(((IpcFragMnd6 *)ipc_fragment_mp_getMN(&v6_key, KAL_FALSE))->key)) == KAL_TRUE);
+ v6_key.ip_id = i;
+ ASSERT(ipc_fragment_mp_getMN(&v6_key, KAL_FALSE) == NULL);
+ }
+ }
+}
+
+void ipc_fragment_efrag_reasm_en_test(kal_bool is_enable)
+{
+ ipc_fragment_defrag_reasm_en = is_enable;
+}
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_export.c b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_export.c
new file mode 100644
index 0000000..d7c5fdf
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_export.c
@@ -0,0 +1,102 @@
+#include "ipc_fragment.h"
+#include "ipc_fragment_frag.h"
+#include "ipc_fragment_utility.h"
+#include "ipc_fragment_export.h"
+
+static inline kal_bool ipc_fragment_init_internal(kal_bool is_reset)
+{
+ ipc_fragment_afm_init();
+ ipc_fragment_mp_init();
+
+ if (KAL_FALSE == is_reset)
+ {
+ ipc_fragment_set_ipc_refilter_func_ptr(ipc_frag_refilter);
+ ipc_fragment_queuing_expire_init(); // event scheduler should be only created at init stage
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_fragment_init()
+{
+ return ipc_fragment_init_internal(KAL_FALSE);
+}
+
+kal_bool ipc_fragment_deinit()
+{
+ ipc_fragment_queuing_expire_deinit();
+ ipc_fragment_mp_deinit();
+ ipc_fragment_afm_deinit();
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_fragment_reset()
+{
+ ipc_fragment_deinit();
+ ipc_fragment_init_internal(KAL_TRUE);
+
+ return KAL_TRUE;
+}
+
+kal_uint32 ipc_fragment_frag(void *buff, kal_uint32 buff_len, qbm_gpd **frag_gpd_head, qbm_gpd **frag_gpd_tail, kal_bool is_v4)
+{
+ kal_uint32 reasm_gpd_num = 0;
+
+ ASSERT(buff);
+ ASSERT(buff_len > 0);
+
+ if (is_v4 == KAL_TRUE)
+ {
+ reasm_gpd_num = ipc_fragment_frag_v4(buff, buff_len, frag_gpd_head, frag_gpd_tail, NULL);
+ }
+ else
+ {
+ reasm_gpd_num = ipc_fragment_frag_v6(buff, buff_len, frag_gpd_head, frag_gpd_tail, NULL);
+ }
+
+ return reasm_gpd_num;
+}
+
+void ipc_fragment_defrag(qbm_gpd *new_gpd, ipc_frag_refilter_info_t *info, kal_bool is_v4)
+{
+ ipc_packet_info_t *packet_info;
+ kal_uint32 matched_filter_id;
+
+ ASSERT(info);
+
+ packet_info = info->packet_info;
+ matched_filter_id = info->filter_id;
+
+ if (is_v4 == KAL_TRUE)
+ {
+ ipc_fragment_queuing_v4(new_gpd, packet_info, matched_filter_id, info);
+ }
+ else
+ {
+ ipc_fragment_queuing_v6(new_gpd, packet_info, matched_filter_id, info);
+ }
+}
+
+void ipc_fragment_on_ilm(ilm_struct *ilm)
+{
+ ipc_fragment_t *p = ipc_fragment_get_inst();
+
+ switch (ilm->msg_id)
+ {
+ case MSG_ID_TIMER_EXPIRY:
+ switch (evshed_get_index(ilm))
+ {
+ case IPC_FRAG_ES_IDX_QUEUE_EXPIRE:
+ evshed_timer_handler(p->ipc_frag_queue_expire_es);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_frag.c b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_frag.c
new file mode 100644
index 0000000..c5ac2f4
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_frag.c
@@ -0,0 +1,245 @@
+#include "ipc_fragment_frag.h"
+#include "ipc_fragment.h"
+#include "ipc_fragment_struct.h"
+#include "ipc_fragment_utility.h"
+
+#define IPC_FRAGMENT_FRAG_HEADER_BUFF_LEN 128
+
+kal_uint32 ipc_fragment_frag_v4(void *buff, kal_uint32 buff_len, qbm_gpd **frag_gpd_head, qbm_gpd **frag_gpd_tail, ipc_fragment_pkt_info *frag_pkt_info)
+{
+ kal_uint8 header[IPC_FRAGMENT_FRAG_HEADER_BUFF_LEN] = {0};
+ qbm_gpd *gpd = NULL, *priv_gpd = NULL;
+ kal_uint8 *gpd_bd_data_p = NULL;
+ const kal_uint8 *ip_buff = (const kal_uint8 *)buff;
+ kal_uint32 frag_pkt_len = buff_len, header_len, num = 0;
+ kal_uint16 frag_flag, checksum;
+ kal_uint32 frag_dword_align;
+ ipc_packet_info_t info_frag_pkt;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_FRAG_START, 1, buff, buff_len, IPC_NE_GET_2B(ip_buff + 4));
+ IPC_FRAGMENT_UL_PKT_DUMP(buff, buff_len);
+
+ header_len = (IPC_NE_GET_1B(ip_buff) & 0x0f) << 2;
+ ASSERT(IPC_FRAGMENT_FRAG_HEADER_BUFF_LEN > header_len);
+ memcpy(header, ip_buff, header_len);
+ if (frag_pkt_info)
+ {
+ info_frag_pkt.src_addr[0] = IPC_NE_GET_4B(header + 12);
+ info_frag_pkt.dst_addr[0] = IPC_NE_GET_4B(header + 16);
+ info_frag_pkt.ip_id = IPC_NE_GET_2B(header + 4);
+ info_frag_pkt.protocol = IPC_NE_GET_1B(header + 9);
+ info_frag_pkt.fragment = KAL_TRUE;
+ }
+
+ ip_buff += header_len;
+ buff_len -= header_len;
+ frag_flag = (IPC_NE_GET_2B(header + 6) & 0x4000) | 0x2000;
+
+ while (buff_len > 0)
+ {
+ frag_pkt_len = (IPC_FRAG_FRAGMENT_MTU_SIZE - header_len) & (~0x7);
+ frag_pkt_len = (buff_len >= frag_pkt_len) ? frag_pkt_len : buff_len;
+ gpd = (qbm_gpd *)qbm_alloc_one(QBM_TYPE_NET_DL);
+ ASSERT(gpd);
+ ipc_fragment_set_gpd_datalen(gpd, header_len + frag_pkt_len, (void **)&gpd_bd_data_p);
+ memcpy(gpd_bd_data_p, header, header_len);
+ memcpy(gpd_bd_data_p + header_len, ip_buff, frag_pkt_len);
+ IPC_NE_SET_2B(gpd_bd_data_p + 2, frag_pkt_len + header_len);
+ IPC_NE_SET_2B(gpd_bd_data_p + 6, frag_flag);
+ checksum = ipc_fragment_ipv4_cal_header_checksum(gpd_bd_data_p);
+ IPC_NE_SET_2B(gpd_bd_data_p + 10, checksum);
+ if (frag_pkt_info)
+ {
+ info_frag_pkt.frag_payload_len = frag_pkt_len;
+ info_frag_pkt.frag_payload_offset = (frag_flag & 0x1fff) << 3;
+ info_frag_pkt.frag_flag = frag_flag >> 13;
+ info_frag_pkt.frag_buffer_payload_offset = header_len;
+ kal_mem_cpy(&(frag_pkt_info->packet_info[frag_pkt_info->frag_pkt_num++]), &info_frag_pkt, sizeof(ipc_packet_info_t));
+ }
+
+ if (priv_gpd)
+ {
+ QBM_DES_SET_NEXT(priv_gpd, gpd);
+ }
+ else
+ {
+ *frag_gpd_head = gpd;
+ }
+ priv_gpd = gpd;
+ qbm_cal_set_checksum(priv);
+
+ ++num;
+ frag_dword_align = frag_pkt_len & (~0x7);
+ frag_flag += frag_dword_align >> 3;
+ ip_buff += frag_dword_align;
+ buff_len -= (buff_len > frag_pkt_len) ? frag_dword_align : buff_len;
+
+ if (buff_len > 0)
+ {
+ IPC_FRAGMENT_UL_PKT_DUMP(gpd_bd_data_p, header_len + frag_pkt_len);
+ }
+ }
+
+ frag_flag = IPC_NE_GET_2B(gpd_bd_data_p + 6) & 0xdfff;
+ IPC_NE_SET_2B(gpd_bd_data_p + 6, frag_flag);
+ checksum = ipc_fragment_ipv4_cal_header_checksum(gpd_bd_data_p);
+ IPC_NE_SET_2B(gpd_bd_data_p + 10, checksum);
+ if (frag_pkt_info && num - 1 < frag_pkt_info->frag_pkt_num)
+ {
+ frag_pkt_info->packet_info[num - 1].frag_flag &= 0x6;
+ }
+
+ QBM_DES_SET_NEXT(priv_gpd, NULL);
+ qbm_cal_set_checksum(priv_gpd);
+ IPC_FRAGMENT_UL_PKT_DUMP(gpd_bd_data_p, header_len + frag_pkt_len);
+
+ *frag_gpd_tail = priv_gpd;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_FRAG_END, num, *frag_gpd_head, *frag_gpd_tail);
+
+ return num;
+}
+
+kal_uint32 ipc_fragment_frag_v6(void *buff, kal_uint32 buff_len, qbm_gpd **frag_gpd_head, qbm_gpd **frag_gpd_tail, ipc_fragment_pkt_info *frag_pkt_info)
+{
+ static kal_uint32 ip_id = 0;
+ kal_uint8 header[IPC_FRAGMENT_FRAG_HEADER_BUFF_LEN] = {0};
+ kal_uint8 frag_header[IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN] = {0};
+ kal_uint8 *gpd_bd_data_p = NULL;
+ const kal_uint8 *ip_buff = (const kal_uint8 *)buff;
+ kal_uint32 frag_pkt_len = buff_len, header_len, num = 0, priv_header_len;
+ kal_uint8 next_header, priv_next_header;
+ kal_bool find = KAL_FALSE;
+ qbm_gpd *gpd = NULL, *priv_gpd = NULL;
+ kal_uint16 frag_offset;
+ ipc_packet_info_t info_frag_pkt;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_FRAG_START, 0, buff, buff_len, ip_id);
+ IPC_FRAGMENT_UL_PKT_DUMP(buff, buff_len);
+
+ header_len = 40;
+ priv_header_len = 0;
+ next_header = IPC_NE_GET_1B(ip_buff + 6);
+ priv_next_header = IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_NON;
+ while (find == KAL_FALSE)
+ {
+ switch (next_header)
+ {
+ case IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_HOP:
+ case IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_DST:
+ case IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_ROUT:
+ priv_next_header = next_header;
+ next_header = IPC_NE_GET_1B(ip_buff + header_len);
+ priv_header_len = header_len;
+ header_len += 8 + (IPC_NE_GET_1B(ip_buff + header_len + 1) << 3);
+ break;
+
+ default:
+ find = KAL_TRUE;
+ break;
+ }
+ }
+ ASSERT(IPC_FRAGMENT_FRAG_HEADER_BUFF_LEN >= header_len);
+ memcpy(header, ip_buff, header_len);
+ switch (priv_next_header)
+ {
+ case IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_NON:
+ IPC_NE_SET_1B(header + 6, IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_FRAG);
+ break;
+
+ case IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_HOP:
+ case IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_DST:
+ case IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_ROUT:
+ IPC_NE_SET_1B(header + priv_header_len, IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_FRAG);
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ if (frag_pkt_info)
+ {
+ info_frag_pkt.src_addr[0] = IPC_NE_GET_4B(header + 8);
+ info_frag_pkt.src_addr[1] = IPC_NE_GET_4B(header + 12);
+ info_frag_pkt.src_addr[2] = IPC_NE_GET_4B(header + 16);
+ info_frag_pkt.src_addr[3] = IPC_NE_GET_4B(header + 20);
+ info_frag_pkt.dst_addr[0] = IPC_NE_GET_4B(header + 24);
+ info_frag_pkt.dst_addr[1] = IPC_NE_GET_4B(header + 28);
+ info_frag_pkt.dst_addr[2] = IPC_NE_GET_4B(header + 32);
+ info_frag_pkt.dst_addr[3] = IPC_NE_GET_4B(header + 36);
+ info_frag_pkt.ip_id = ip_id;
+ info_frag_pkt.fragment = KAL_TRUE;
+ }
+
+ frag_offset = 1;
+ IPC_NE_SET_1B(frag_header, next_header);
+ IPC_NE_SET_2B(frag_header + 2, frag_offset);
+ IPC_NE_SET_4B(frag_header + 4, ip_id);
+
+ ip_buff += header_len;
+ buff_len -= header_len;
+
+ while (buff_len > 0)
+ {
+ frag_pkt_len = (IPC_FRAG_FRAGMENT_MTU_SIZE - header_len - IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN) & (~0x7);
+ frag_pkt_len = (buff_len >= frag_pkt_len) ? frag_pkt_len : buff_len;
+ gpd = (qbm_gpd *)qbm_alloc_one(QBM_TYPE_NET_DL);
+ ASSERT(gpd);
+ ipc_fragment_set_gpd_datalen(gpd, frag_pkt_len + header_len + IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN, (void **)&gpd_bd_data_p);
+ memcpy(gpd_bd_data_p, header, header_len);
+ memcpy(gpd_bd_data_p + header_len, frag_header, IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN);
+ memcpy(gpd_bd_data_p + header_len + IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN, ip_buff, frag_pkt_len);
+ IPC_NE_SET_2B(gpd_bd_data_p + 4, frag_pkt_len + header_len + IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN - 40);
+ if (frag_pkt_info)
+ {
+ info_frag_pkt.frag_payload_len = frag_pkt_len;
+ info_frag_pkt.frag_payload_offset = frag_offset & (~0x7);
+ info_frag_pkt.frag_flag = 0x01;
+ info_frag_pkt.frag_buffer_payload_offset = header_len + IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN;
+ kal_mem_cpy(&(frag_pkt_info->packet_info[frag_pkt_info->frag_pkt_num++]), &info_frag_pkt, sizeof(ipc_packet_info_t));
+ }
+
+ if (priv_gpd)
+ {
+ QBM_DES_SET_NEXT(priv_gpd, gpd);
+ }
+ else
+ {
+ *frag_gpd_head = gpd;
+ }
+ priv_gpd = gpd;
+ qbm_cal_set_checksum(priv);
+
+ ++num;
+ ASSERT(((frag_pkt_len & 0x7) == 0) || (frag_pkt_len == buff_len));
+ frag_offset += frag_pkt_len;
+
+ IPC_NE_SET_2B(frag_header + 2, frag_offset);
+ ip_buff += frag_pkt_len;
+ buff_len -= frag_pkt_len;
+
+ if (buff_len > 0)
+ {
+ IPC_FRAGMENT_UL_PKT_DUMP(gpd_bd_data_p, header_len + IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN + frag_pkt_len);
+ }
+ }
+
+ frag_offset = IPC_NE_GET_2B(gpd_bd_data_p + header_len + 2) & (~0x1);
+ IPC_NE_SET_2B(gpd_bd_data_p + header_len + 2, (frag_offset & (~0x7)));
+
+ if (frag_pkt_info && num - 1 < frag_pkt_info->frag_pkt_num)
+ {
+ frag_pkt_info->packet_info[num - 1].frag_flag &= 0;
+ }
+
+ QBM_DES_SET_NEXT(priv_gpd, NULL);
+ qbm_cal_set_checksum(priv_gpd);
+ IPC_FRAGMENT_UL_PKT_DUMP(gpd_bd_data_p, header_len + IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN + frag_pkt_len);
+
+ *frag_gpd_tail = priv_gpd;
+ ++ip_id;
+
+ hif_data_trace(MD_TRC_IPC_FRAG_FRAG_END, num, *frag_gpd_head, *frag_gpd_tail);
+
+ return num;
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_frag.h b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_frag.h
new file mode 100644
index 0000000..105ee1a
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_frag.h
@@ -0,0 +1,34 @@
+#ifndef _IPC_FRAGMENT_FRAG_INC
+#define _IPC_FRAGMENT_FRAG_INC
+
+#include "ipc_fragment.h"
+#include "ipc_fragment_struct.h"
+
+#define IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_HOP 0
+#define IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_DST 60
+#define IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_ROUT 43
+#define IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_FRAG 44
+#define IPC_FRAGMENT_FRAG_IPV6_EXT_HEADER_NON 59
+
+#define IPC_FRAGMENT_IPV6_FRAG_HEADER_LEN 8
+#define IPC_FRAG_FRAGMENT_MTU_SIZE 1500
+
+#define IPC_FRAG_INVALID_FILTER_ID -1
+#define IPC_FRAG_IPV6_MAX_LEN 65535
+#define IPC_FRAG_FLAG_MF 0x01
+#define IPC_FRAG_INFO_RECEIVE_FIRST_PKT 0x1
+#define IPC_FRAG_INFO_RECEIVE_LAST_PKT 0x2
+#define IPC_FRAG_INFO_RECEIVE_COMPLETE 0x4
+
+#define IPC_FRAG_FRAGMENT_INFO_PKT_NUM_MAX 40
+
+typedef struct _ipc_fragment_pkt_info
+{
+ ipc_packet_info_t packet_info[IPC_FRAG_FRAGMENT_INFO_PKT_NUM_MAX];
+ unsigned frag_pkt_num;
+} ipc_fragment_pkt_info;
+
+kal_uint32 ipc_fragment_frag_v4(void *buff, kal_uint32 buff_len, qbm_gpd **frag_gpd_head, qbm_gpd **frag_gpd_tail, ipc_fragment_pkt_info *frag_pkt_info);
+kal_uint32 ipc_fragment_frag_v6(void *buff, kal_uint32 buff_len, qbm_gpd **frag_gpd_head, qbm_gpd **frag_gpd_tail, ipc_fragment_pkt_info *frag_pkt_info);
+
+#endif /* _IPC_FRAGMENT_FRAG_INC */
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_reassemble.c b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_reassemble.c
new file mode 100644
index 0000000..f345b7d
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_reassemble.c
@@ -0,0 +1,275 @@
+#include "ipc_fragment.h"
+#include "ipc_fragment_frag.h"
+#include "ipc_fragment_utility.h"
+
+#define IPC_FRAGMENT_EXT_HDR_IPV6 (-1)
+#define IPC_FRAGMENT_TMP_BUFFER_LEN (1024)
+
+inline void ipc_fragment_ipv6_set_next_header(void *new_header_buffer, kal_int16 curr_next_header, kal_int16 next_header, kal_int32 offset)
+{
+ kal_uint8 *p_hdr = (kal_uint8 *)new_header_buffer + offset;
+
+ switch (curr_next_header)
+ {
+ case IPC_FRAGMENT_EXT_HDR_IPV6:
+ IPC_NE_SET_1B(p_hdr + 6, next_header);
+ break;
+
+ case IPC_HDR_PROT_IPV6_HOP:
+ case IPC_HDR_PROT_IPV6_ROUTE:
+ case IPC_HDR_PROT_IPV6_DEST:
+ case IPC_HDR_PROT_AH:
+ case IPC_HDR_PROT_IPV6_FRAG:
+ IPC_NE_SET_1B(p_hdr + 0, next_header);
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+kal_int32 ipc_fragment_ipv6_remove_fragment_header(const void *original_ip_hdr, void *out_buffer)
+{
+ kal_int32 ip_header_len;
+ kal_int32 priv_offset;
+ kal_int16 next_header, priv_next_header;
+ const kal_uint8 *original_ip_header = (const kal_uint8 *)original_ip_hdr;
+ kal_uint8 *new_header_buffer = (kal_uint8 *)out_buffer;
+
+ ASSERT(new_header_buffer && new_header_buffer);
+
+ priv_offset = 0;
+ ip_header_len = 40;
+ priv_next_header = IPC_FRAGMENT_EXT_HDR_IPV6; // use -1 to present IPv6 header here
+ next_header = IPC_NE_GET_1B(original_ip_header + 6);
+
+ while (priv_next_header != IPC_HDR_PROT_IPV6_FRAG)
+ {
+
+ switch (next_header)
+ {
+ case IPC_HDR_PROT_IPV6_HOP:
+ case IPC_HDR_PROT_IPV6_ROUTE:
+ case IPC_HDR_PROT_IPV6_DEST:
+ priv_next_header = next_header;
+ next_header = IPC_NE_GET_1B(original_ip_header + ip_header_len + 0);
+ priv_offset = ip_header_len;
+ ip_header_len += (IPC_NE_GET_1B(original_ip_header + ip_header_len + 1) + 1) * 8;
+ break;
+
+ case IPC_HDR_PROT_AH:
+ priv_next_header = next_header;
+ next_header = IPC_NE_GET_1B(original_ip_header + ip_header_len + 0);
+ priv_offset = ip_header_len;
+ ip_header_len += (IPC_NE_GET_1B(original_ip_header + ip_header_len + 1) + 2) * 4;
+ break;
+
+ case IPC_HDR_PROT_IPV6_FRAG:
+ next_header = IPC_NE_GET_1B(original_ip_header + ip_header_len + 0);
+ ASSERT(IPC_FRAGMENT_TMP_BUFFER_LEN >= ip_header_len);
+ memcpy(new_header_buffer, original_ip_header, ip_header_len);
+ ipc_fragment_ipv6_set_next_header(new_header_buffer, priv_next_header, next_header, priv_offset);
+ priv_next_header = IPC_HDR_PROT_IPV6_FRAG;
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+
+ return ip_header_len;
+}
+
+void ipc_fragment_dump_packet_from_gpd_with_multi_bd(const qbm_gpd *gpd)
+{
+ static kal_uint8 buff[65600] = {0};
+ kal_int32 buff_len = 0, offset = 0;
+ void *bd = NULL;
+ kal_bool end_of_bd = KAL_FALSE;
+
+ ASSERT(gpd);
+ buff_len = QBM_DES_GET_DATALEN(gpd);
+
+ if (QBM_DES_GET_BDP(gpd))
+ {
+ bd = QBM_DES_GET_DATAPTR(gpd);
+ while (!end_of_bd)
+ {
+ memcpy(buff + offset, QBM_DES_GET_DATAPTR(bd), QBM_DES_GET_DATALEN(bd));
+ offset += QBM_DES_GET_DATALEN(bd);
+ if (!QBM_DES_GET_EOL(bd))
+ {
+ bd = QBM_DES_GET_NEXT(bd);
+ }
+ else
+ {
+ end_of_bd = KAL_TRUE;
+ }
+ }
+ }
+ else
+ {
+ memcpy(buff, QBM_DES_GET_DATAPTR(gpd), QBM_DES_GET_DATALEN(gpd));
+ }
+
+ IPC_FRAGMENT_DL_PKT_DUMP(buff, buff_len);
+}
+
+kal_bool ipc_fragment_reassemble_v4(qbm_gpd **reasm_gpd, IpcFragPktGroupInfo *pkt_grp_info)
+{
+ kal_uint8 *bd_data_addr;
+ kal_uint16 reasm_header_len;
+ kal_uint16 checksum, frag_flag;
+ qbm_gpd *head_gpd, *tail_gpd, *curr_gpd, *next_gpd;
+ IpcFragPktMetaInfo *head_meta, *tail_meta, *curr_meta;
+ kal_uint8 *bd;
+ kal_bool result = KAL_FALSE;
+
+ head_gpd = curr_gpd = pkt_grp_info->head_gpd;
+ tail_gpd = pkt_grp_info->tail_gpd;
+ head_meta = curr_meta = pkt_grp_info->head_meta;
+ tail_meta = pkt_grp_info->tail_meta;
+
+ ASSERT(head_gpd && tail_gpd && head_meta && tail_meta);
+
+ *reasm_gpd = (qbm_gpd *)qbm_alloc_one(QBM_TYPE_TGPD);
+ hif_data_trace(MD_TRC_IPC_FRAG_REASM, 1, *reasm_gpd);
+
+ if (*reasm_gpd)
+ {
+ reasm_header_len = curr_meta->gpd_payload_offset;
+ QBM_DES_SET_BDP(*reasm_gpd);
+ QBM_DES_SET_DATAPTR(*reasm_gpd, curr_gpd);
+ QBM_DES_SET_DATALEN(*reasm_gpd, reasm_header_len + pkt_grp_info->total_len);
+
+ next_gpd = QBM_DES_GET_NEXT(curr_gpd);
+ bd = (kal_uint8 *)QBM_DES_GET_DATAPTR(curr_gpd);
+ bd_data_addr = (kal_uint8 *)QBM_DES_GET_DATAPTR(bd) + curr_meta->offset - curr_meta->orig_offset;
+ QBM_DES_SET_DATAPTR(curr_gpd, bd_data_addr);
+ QBM_DES_SET_DATALEN(curr_gpd, reasm_header_len + curr_meta->pkt_len);
+ QBM_DES_CLR_BDP(curr_gpd);
+ QBM_DES_CLR_EOL(curr_gpd);
+
+ frag_flag = IPC_NE_GET_1B(bd_data_addr + 6);
+ frag_flag &= 0xdf;
+ IPC_NE_SET_1B(bd_data_addr + 6, frag_flag);
+ IPC_NE_SET_2B(bd_data_addr + 2, pkt_grp_info->total_len + reasm_header_len);
+ checksum = ipc_fragment_ipv4_cal_header_checksum(bd_data_addr);
+ IPC_NE_SET_2B(bd_data_addr + 10, checksum);
+ qbm_cal_set_checksum(curr_gpd);
+
+ while (curr_gpd != tail_gpd)
+ {
+ ASSERT(curr_meta != tail_meta);
+
+ curr_gpd = next_gpd;
+ curr_meta = curr_meta->next;
+ next_gpd = QBM_DES_GET_NEXT(next_gpd);
+
+ bd = (kal_uint8 *)QBM_DES_GET_DATAPTR(curr_gpd);
+ bd_data_addr = (kal_uint8 *)QBM_DES_GET_DATAPTR(bd) + curr_meta->gpd_payload_offset + curr_meta->offset - curr_meta->orig_offset;
+ QBM_DES_SET_DATAPTR(curr_gpd, bd_data_addr);
+ QBM_DES_SET_DATALEN(curr_gpd, curr_meta->pkt_len);
+ QBM_DES_CLR_BDP(curr_gpd);
+ QBM_DES_CLR_EOL(curr_gpd);
+ qbm_cal_set_checksum(curr_gpd);
+ }
+ QBM_DES_SET_EOL(curr_gpd);
+ qbm_cal_set_checksum(curr_gpd);
+
+ qbm_cal_set_checksum(*reasm_gpd);
+
+ pkt_grp_info->head_gpd = pkt_grp_info->tail_gpd = *reasm_gpd;
+
+ ipc_fragment_dump_packet_from_gpd_with_multi_bd(*reasm_gpd);
+
+ result = KAL_TRUE;
+ }
+
+ return result;
+}
+
+kal_bool ipc_fragment_reassemble_v6(qbm_gpd **reasm_gpd, IpcFragPktGroupInfo *pkt_grp_info)
+{
+ kal_uint8 *bd_data_addr;
+ kal_uint16 reasm_header_len, cpy_header_len;
+ qbm_gpd *head_gpd, *tail_gpd, *curr_gpd, *next_gpd;
+ IpcFragPktMetaInfo *head_meta, *tail_meta, *curr_meta;
+ kal_uint8 *bd;
+ static kal_uint8 tmp_buffer[IPC_FRAGMENT_TMP_BUFFER_LEN];
+ kal_bool result = KAL_FALSE;
+
+ head_gpd = curr_gpd = pkt_grp_info->head_gpd;
+ tail_gpd = pkt_grp_info->tail_gpd;
+ head_meta = curr_meta = pkt_grp_info->head_meta;
+ tail_meta = pkt_grp_info->tail_meta;
+
+ ASSERT(head_gpd && tail_gpd && head_meta && tail_meta);
+
+ *reasm_gpd = (qbm_gpd *)qbm_alloc_one(QBM_TYPE_TGPD);
+ hif_data_trace(MD_TRC_IPC_FRAG_REASM, 0, *reasm_gpd);
+
+ if (*reasm_gpd)
+ {
+ reasm_header_len = curr_meta->gpd_payload_offset - 8;
+ QBM_DES_SET_BDP(*reasm_gpd);
+ QBM_DES_SET_DATAPTR(*reasm_gpd, curr_gpd);
+ QBM_DES_SET_DATALEN(*reasm_gpd, reasm_header_len + pkt_grp_info->total_len);
+
+ next_gpd = QBM_DES_GET_NEXT(curr_gpd);
+ bd = (kal_uint8 *)QBM_DES_GET_DATAPTR(curr_gpd);
+ bd_data_addr = (kal_uint8 *)QBM_DES_GET_DATAPTR(bd) + curr_meta->offset - curr_meta->orig_offset;
+
+ cpy_header_len = ipc_fragment_ipv6_remove_fragment_header(bd_data_addr, tmp_buffer);
+ ASSERT(cpy_header_len == reasm_header_len);
+ bd_data_addr += 8;
+ memcpy(bd_data_addr, tmp_buffer, reasm_header_len);
+ IPC_NE_SET_2B(bd_data_addr + 4, reasm_header_len + pkt_grp_info->total_len - 40);
+ QBM_CACHE_FLUSH(bd_data_addr, reasm_header_len);
+
+ QBM_DES_SET_DATAPTR(curr_gpd, bd_data_addr);
+ QBM_DES_SET_DATALEN(curr_gpd, reasm_header_len + curr_meta->pkt_len);
+ QBM_DES_CLR_BDP(curr_gpd);
+ QBM_DES_CLR_EOL(curr_gpd);
+ qbm_cal_set_checksum(curr_gpd);
+
+ while (curr_gpd != tail_gpd)
+ {
+ ASSERT(curr_meta != tail_meta);
+
+ curr_gpd = next_gpd;
+ curr_meta = curr_meta->next;
+ next_gpd = QBM_DES_GET_NEXT(next_gpd);
+
+ bd = (kal_uint8 *)QBM_DES_GET_DATAPTR(curr_gpd);
+ bd_data_addr = (kal_uint8 *)QBM_DES_GET_DATAPTR(bd) + curr_meta->gpd_payload_offset + curr_meta->offset - curr_meta->orig_offset;
+ QBM_DES_SET_DATAPTR(curr_gpd, bd_data_addr);
+ QBM_DES_SET_DATALEN(curr_gpd, curr_meta->pkt_len);
+ QBM_DES_CLR_BDP(curr_gpd);
+ QBM_DES_CLR_EOL(curr_gpd);
+ qbm_cal_set_checksum(curr_gpd);
+ }
+ QBM_DES_SET_EOL(curr_gpd);
+ qbm_cal_set_checksum(curr_gpd);
+
+ qbm_cal_set_checksum(*reasm_gpd);
+
+ pkt_grp_info->head_gpd = pkt_grp_info->tail_gpd = *reasm_gpd;
+
+ #ifndef __MTK_TARGET__
+ ipc_fragment_dump_packet_from_gpd_with_multi_bd(*reasm_gpd);
+ #endif
+
+ result = KAL_TRUE;
+ }
+
+ return result;
+}
+
+kal_bool ipc_fragment_reassemble(kal_bool is_v4, qbm_gpd **reasm_gpd, IpcFragPktGroupInfo *pkt_grp_info)
+{
+ return is_v4 == KAL_TRUE ? ipc_fragment_reassemble_v4(reasm_gpd, pkt_grp_info) : ipc_fragment_reassemble_v6(reasm_gpd, pkt_grp_info);
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_struct.h b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_struct.h
new file mode 100644
index 0000000..ef90b8a
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_struct.h
@@ -0,0 +1,96 @@
+#ifndef _IPC_FRAGMENT_STRUCT_INC
+#define _IPC_FRAGMENT_STRUCT_INC
+
+#include "ipc_fragment.h"
+
+typedef struct _ipc_fragment_t
+{
+ KAL_AFM_ID k_afm_id;
+ kal_uint8 *afm_buffer_p;
+ kal_uint32 *afm_sub_buffer_size_p;
+ kal_uint32 *afm_sub_buffer_num_p;
+ kal_uint32 afm_left_mem_size;
+ event_scheduler *ipc_frag_queue_expire_es;
+ eventid ipc_frag_queue_expire_evt;
+} ipc_fragment_t;
+
+typedef struct _IpcFragIpv4L3Key
+{
+ kal_uint32 src_addr;
+ kal_uint32 dst_addr;
+ kal_uint16 ip_id;
+ kal_uint8 protocol;
+ kal_uint8 reserved;
+} IpcFragIpv4L3Key;
+
+typedef struct _IpcFragIpv6L3Key
+{
+ kal_uint32 src_addr[4];
+ kal_uint32 dst_addr[4];
+ kal_uint32 ip_id;
+} IpcFragIpv6L3Key;
+
+typedef struct _IpcFragPktMetaInfo IpcFragPktMetaInfo;
+struct _IpcFragPktMetaInfo
+{
+ kal_uint16 offset;
+ kal_uint16 pkt_len;
+ kal_uint16 orig_offset;
+ kal_uint16 orig_pkt_len;
+ kal_uint16 gpd_payload_offset;
+ IpcFragPktMetaInfo *next;
+};
+
+typedef struct _IpcFragPktGroupInfo
+{
+ qbm_gpd *head_gpd, *tail_gpd;
+ IpcFragPktMetaInfo *head_meta, *tail_meta;
+ kal_uint32 info_mask;
+ kal_uint16 total_len;
+ kal_uint16 accumulate_len;
+ kal_int32 filter_id;
+ ipc_packet_info_t first_packet_info;
+ ipc_frag_refilter_info_t first_packet_refilter_info;
+} IpcFragPktGroupInfo;
+
+typedef struct _IpcFragIpv4L3KeyWithTStamp
+{
+ IpcFragIpv4L3Key v4_key;
+ kal_uint32 tickStamp;
+} IpcFragIpv4L3KeyWithTStamp;
+
+typedef struct _IpcFragIpv6L3KeyWithTStamp
+{
+ IpcFragIpv6L3Key v6_key;
+ kal_uint32 tickStamp;
+} IpcFragIpv6L3KeyWithTStamp;
+
+typedef struct _IpcFragMnd4 IpcFragMnd4;
+struct _IpcFragMnd4
+{
+ IpcFragIpv4L3Key key;
+ IpcFragPktGroupInfo val;
+ IpcFragMnd4 *next;
+};
+
+typedef struct _IpcFragMnd6 IpcFragMnd6;
+struct _IpcFragMnd6
+{
+ IpcFragIpv6L3Key key;
+ IpcFragPktGroupInfo val;
+ IpcFragMnd6 *next;
+};
+
+typedef struct _IpcFragUM4
+{
+ IpcFragMnd4 **mp;
+ kal_uint32 mp_num;
+} IpcFragUM4;
+
+typedef struct _IpcFragUM6
+{
+ IpcFragMnd6 **mp;
+ kal_uint32 mp_num;
+} IpcFragUM6;
+
+#endif /* _IPC_FRAGMENT_STRUCTINC */
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_ut.c b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_ut.c
new file mode 100644
index 0000000..c32b51d
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_ut.c
@@ -0,0 +1,270 @@
+#include "ipc_fragment.h"
+#include "ipc_fragment_frag.h"
+#include "ipc_fragment_struct.h"
+#include "ipc_fragment_utility.h"
+#include "ipc_fragment_export.h"
+
+#define IPC_FRAG_TEST_REASM_IPV4_LEN 24
+#define IPC_FRAG_TEST_REASM_IPV6_LEN 56
+#define IPC_FRAG_TEST_REASM_UDP_LEN 8
+#define IPC_FRAG_TEST_REASM_LARGE_DATA_LEN 16214
+
+static qbm_gpd *reasm_pkt_v4_gpd;
+static qbm_gpd *reasm_pkt_v6_gpd;
+
+void ipc_fragment_reassemble_test_send2defrag(kal_bool is_v4, kal_uint32 frag_gpd_num, qbm_gpd *frag_gpd_head, qbm_gpd *frag_gpd_tail, ipc_fragment_pkt_info *frag_pkt_info, kal_bool quening_in_order)
+{
+ ipc_frag_refilter_info_t refilter_info;
+ kal_uint32 idx, idx2;
+ qbm_gpd *curr_gpd;
+ ipc_packet_info_t *p_pkt_info;
+
+ if (is_v4 == KAL_TRUE)
+ {
+ reasm_pkt_v4_gpd = NULL;
+ }
+ else
+ {
+ reasm_pkt_v6_gpd = NULL;
+ }
+
+ refilter_info.uplink = KAL_FALSE;
+ refilter_info.netif_id = 0;
+ refilter_info.pdn_id = 0;
+ refilter_info.filter_id = 1;
+ refilter_info.filter_magic_number = 0xABCDEFFF;
+
+ if (quening_in_order == KAL_TRUE)
+ {
+ for (idx = 0; idx < frag_gpd_num; ++idx)
+ {
+ curr_gpd = frag_gpd_head;
+ ASSERT(curr_gpd);
+ frag_gpd_head = (qbm_gpd *)QBM_DES_GET_NEXT(frag_gpd_head);
+ p_pkt_info = &(frag_pkt_info->packet_info[idx]);
+ refilter_info.packet_info = p_pkt_info;
+ ipc_fragment_defrag(curr_gpd, &refilter_info, is_v4);
+ }
+ }
+ else
+ {
+ for (idx = frag_gpd_num; idx > 0; --idx)
+ {
+ curr_gpd = frag_gpd_head;
+ for (idx2 = 1; idx2 < idx; ++idx2)
+ {
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+ ASSERT(curr_gpd);
+ p_pkt_info = &(frag_pkt_info->packet_info[idx - 1]);
+ refilter_info.packet_info = p_pkt_info;
+ ipc_fragment_defrag(curr_gpd, &refilter_info, is_v4);
+ }
+ }
+}
+
+kal_uint8 conn_buff[IPC_FRAG_TEST_REASM_LARGE_DATA_LEN];
+kal_bool ipc_fragment_reassemble_test_cmp_reasm_gpd(qbm_gpd *reasm_gpd, const kal_uint8 *large_packet)
+{
+ kal_bool end_of_bd = KAL_FALSE;
+ void *bd = NULL;
+ kal_uint32 offset = 0;
+ kal_int32 cmp;
+
+ ASSERT(reasm_gpd);
+ kal_mem_set(conn_buff, 0, IPC_FRAG_TEST_REASM_LARGE_DATA_LEN);
+
+ if (QBM_DES_GET_BDP(reasm_gpd))
+ {
+ bd = QBM_DES_GET_DATAPTR(reasm_gpd);
+ while (end_of_bd == KAL_FALSE)
+ {
+ memcpy(conn_buff + offset, QBM_DES_GET_DATAPTR(bd), QBM_DES_GET_DATALEN(bd));
+ offset += QBM_DES_GET_DATALEN(bd);
+ if (!QBM_DES_GET_EOL(bd))
+ {
+ bd = QBM_DES_GET_NEXT(bd);
+ }
+ else
+ {
+ end_of_bd = KAL_TRUE;
+ }
+ }
+ }
+ else
+ {
+ memcpy(conn_buff, QBM_DES_GET_DATAPTR(reasm_gpd), QBM_DES_GET_DATALEN(reasm_gpd));
+ }
+ cmp = memcmp(conn_buff, large_packet, IPC_FRAG_TEST_REASM_LARGE_DATA_LEN);
+
+ return (cmp == 0) ? KAL_TRUE : KAL_FALSE;
+}
+
+kal_uint8 header_v4[IPC_FRAG_TEST_REASM_IPV4_LEN] = {0x45, 0x00, 0x00, 0x00, 0x12, 0x34, 0x40, 0x00, 0x40, 0x11, 0xeb, 0x59,
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0d, 0x0c, 0x0b, 0x0a, 0x00, 0x00, 0x00, 0x00};
+kal_uint8 header_v6[IPC_FRAG_TEST_REASM_IPV6_LEN] = {0x60, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x20, //
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x1a, 0x1b, 0x1c, 0x1d, // v6 src
+ 0x2a, 0x2b, 0x2c, 0x2d, 0x3a, 0x3b, 0x3c, 0x3d, //
+ 0x3a, 0x3b, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2d, // v6 dst
+ 0x1a, 0x1b, 0x1c, 0x1d, 0x0a, 0x0b, 0x0c, 0x0d, //
+ 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // hop-by-hop opt
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // destination opt
+kal_uint8 udp_header[IPC_FRAG_TEST_REASM_UDP_LEN] = {0xea, 0xfb, 0x13, 0x8c, 0x00, 0x00, 0x00, 0x00};
+kal_uint8 large_packet[IPC_FRAG_TEST_REASM_LARGE_DATA_LEN];
+ipc_fragment_pkt_info frag_pkt_info;
+void ipc_fragment_reassemble_test_v4(kal_bool quening_in_order)
+{
+ static kal_uint16 ip_id = 0;
+ kal_uint16 pkt_len = 0, header_len;
+ qbm_gpd *frag_gpd_head = NULL, *frag_gpd_tail = NULL;
+ kal_uint32 frag_gpd_num = 0;
+ kal_uint32 checksum;
+ kal_uint8 raw_data;
+ kal_uint32 offset;
+ kal_bool cmp_result;
+
+ kal_mem_set(large_packet, 0, IPC_FRAG_TEST_REASM_LARGE_DATA_LEN);
+ kal_mem_set(&frag_pkt_info, 0, sizeof(ipc_fragment_pkt_info));
+ /* Generate large packet */
+ IPC_NE_SET_2B(header_v4 + 4, ip_id);
+ ++ip_id;
+ header_len = (IPC_NE_GET_1B(header_v4) & 0x0f) << 2;
+ memcpy(large_packet, header_v4, header_len);
+ pkt_len += header_len;
+ memcpy(large_packet + pkt_len, udp_header, IPC_FRAG_TEST_REASM_UDP_LEN);
+ pkt_len += IPC_FRAG_TEST_REASM_UDP_LEN;
+ for (raw_data = 0; pkt_len < IPC_FRAG_TEST_REASM_LARGE_DATA_LEN; ++raw_data)
+ {
+ large_packet[pkt_len++] = raw_data;
+ }
+ // Update IPv4 header and header checksum
+ IPC_NE_SET_2B(large_packet + 2, IPC_FRAG_TEST_REASM_LARGE_DATA_LEN);
+ checksum = ipc_fragment_ipv4_cal_header_checksum(large_packet);
+ IPC_NE_SET_2B(large_packet + 10, checksum);
+ // Update udp_header
+ IPC_NE_SET_2B(large_packet + header_len + 4, IPC_FRAG_TEST_REASM_LARGE_DATA_LEN - header_len);
+ checksum = IPC_NE_GET_2B(header_v4 + 12) + IPC_NE_GET_2B(header_v4 + 14) + IPC_NE_GET_2B(header_v4 + 16) + IPC_NE_GET_2B(header_v4 + 18) + IPC_NE_GET_1B(header_v4 + 9) +
+ IPC_NE_GET_2B(large_packet + header_len + 4);
+ checksum += IPC_NE_GET_2B(udp_header + 0) + IPC_NE_GET_2B(udp_header + 2) + IPC_NE_GET_2B(large_packet + header_len + 4);
+ for (offset = header_len + IPC_FRAG_TEST_REASM_UDP_LEN; offset < IPC_FRAG_TEST_REASM_LARGE_DATA_LEN; offset += 2)
+ {
+ checksum += ((offset + 2) <= IPC_FRAG_TEST_REASM_LARGE_DATA_LEN) ? IPC_NE_GET_2B(large_packet + offset) : (IPC_NE_GET_1B(large_packet + offset) << 8);
+ while (checksum & 0xffff0000)
+ {
+ checksum = (checksum & 0xffff) + ((checksum & 0xffff0000) >> 16);
+ }
+ }
+ checksum = ((checksum == 0xffff) ? checksum : ~checksum) & 0xffff;
+ IPC_NE_SET_2B(large_packet + header_len + 6, checksum);
+
+ /* Large packet fragment */
+ frag_gpd_num = ipc_fragment_frag_v4(large_packet, pkt_len, &frag_gpd_head, &frag_gpd_tail, &frag_pkt_info);
+
+ /* IPv4 defragment */
+ ipc_fragment_reassemble_test_send2defrag(KAL_TRUE, frag_gpd_num, frag_gpd_head, frag_gpd_tail, &frag_pkt_info, quening_in_order);
+
+ /* Compare orignial packet with reassemabled packet */
+ cmp_result = ipc_fragment_reassemble_test_cmp_reasm_gpd(reasm_pkt_v4_gpd, large_packet);
+ ASSERT(cmp_result == KAL_TRUE);
+
+ qbmt_dest_q(reasm_pkt_v4_gpd, reasm_pkt_v4_gpd);
+}
+
+void ipc_fragment_reassemble_test_v6(kal_bool quening_in_order)
+{
+ kal_uint32 large_pkt_len;
+ kal_uint16 pkt_len = 0, header_len;
+ qbm_gpd *frag_gpd_head = NULL, *frag_gpd_tail = NULL;
+ kal_uint32 frag_gpd_num = 0;
+ kal_uint32 checksum;
+ kal_uint8 raw_data;
+ kal_uint32 offset;
+ kal_bool cmp_result;
+
+ kal_mem_set(large_packet, 0, IPC_FRAG_TEST_REASM_LARGE_DATA_LEN);
+ kal_mem_set(&frag_pkt_info, 0, sizeof(ipc_fragment_pkt_info));
+ /* Generate large packet */
+ header_len = IPC_FRAG_TEST_REASM_IPV6_LEN;
+ memcpy(large_packet, header_v6, header_len);
+ pkt_len += header_len;
+ memcpy(large_packet + pkt_len, udp_header, IPC_FRAG_TEST_REASM_UDP_LEN);
+ pkt_len += IPC_FRAG_TEST_REASM_UDP_LEN;
+ large_pkt_len = IPC_FRAG_TEST_REASM_LARGE_DATA_LEN;
+ for (raw_data = 0; pkt_len < large_pkt_len; ++raw_data)
+ {
+ large_packet[pkt_len++] = raw_data;
+ }
+ // Update IPv6 header
+ IPC_NE_SET_2B(large_packet + 4, large_pkt_len - 40);
+ // Update UDP header
+ IPC_NE_SET_2B(large_packet + header_len + 4, large_pkt_len - header_len);
+ checksum = 0x11 + IPC_NE_GET_2B(large_packet + header_len + 4);
+ for (offset = 8; offset < 40; offset += 2)
+ {
+ checksum += IPC_NE_GET_2B(header_v6 + offset);
+ }
+ checksum += IPC_NE_GET_2B(udp_header + 0) + IPC_NE_GET_2B(udp_header + 2) + IPC_NE_GET_2B(large_packet + header_len + 4);
+ for (offset = header_len + IPC_FRAG_TEST_REASM_UDP_LEN; offset < large_pkt_len; offset += 2)
+ {
+ checksum += IPC_NE_GET_2B(large_packet + offset);
+ while (checksum & 0xffff0000)
+ {
+ checksum = (checksum & 0xffff) + ((checksum & 0xffff0000) >> 16);
+ }
+ }
+ checksum = ((checksum == 0xffff) ? checksum : ~checksum) & 0xffff;
+ IPC_NE_SET_2B(large_packet + header_len + 6, checksum);
+
+ /* Large packet fragment */
+ frag_gpd_num = ipc_fragment_frag_v6(large_packet, pkt_len, &frag_gpd_head, &frag_gpd_tail, &frag_pkt_info);
+
+ /* IPv6 defragment */
+ ipc_fragment_reassemble_test_send2defrag(KAL_FALSE, frag_gpd_num, frag_gpd_head, frag_gpd_tail, &frag_pkt_info, quening_in_order);
+
+ /* Compare orignial packet with reassemabled packet */
+ cmp_result = ipc_fragment_reassemble_test_cmp_reasm_gpd(reasm_pkt_v6_gpd, large_packet);
+ ASSERT(cmp_result == KAL_TRUE);
+
+ qbmt_dest_q(reasm_pkt_v6_gpd, reasm_pkt_v6_gpd);
+}
+
+void ipc_fragment_ut_refilter(kal_uint8 ip_type, ipc_frag_refilter_info_t *info, qbm_gpd *p_head, qbm_gpd *p_tail)
+{
+ /* Assign reassembled packet into global variable, and test function will compare original data with reassembled packet */
+ ASSERT(p_head == p_tail);
+ if (ip_type == IPC_IP_TYPE_IPV4)
+ {
+ reasm_pkt_v4_gpd = p_head;
+ }
+ else
+ {
+ reasm_pkt_v6_gpd = p_head;
+ }
+}
+
+extern void ipc_fragment_mp_test();
+extern void ipc_fragment_efrag_reasm_en_test(kal_bool is_enable);
+void ipc_fragment_test()
+{
+ ipc_fragment_set_ipc_refilter_func_ptr(ipc_fragment_ut_refilter);
+ ipc_fragment_efrag_reasm_en_test(KAL_TRUE);
+
+ ipc_fragment_reset();
+ ipc_fragment_mp_test();
+
+ ipc_fragment_reset();
+ ipc_fragment_reassemble_test_v4(KAL_TRUE);
+
+ ipc_fragment_reset();
+ ipc_fragment_reassemble_test_v6(KAL_TRUE);
+
+ ipc_fragment_reset();
+ ipc_fragment_reassemble_test_v4(KAL_FALSE);
+
+ ipc_fragment_reset();
+ ipc_fragment_reassemble_test_v6(KAL_FALSE);
+
+ ipc_fragment_reset();
+ ipc_fragment_efrag_reasm_en_test(KAL_FALSE);
+ ipc_fragment_set_ipc_refilter_func_ptr(ipc_frag_refilter);
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_utility.c b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_utility.c
new file mode 100644
index 0000000..1e940ed
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_utility.c
@@ -0,0 +1,196 @@
+#include "ipc_fragment_utility.h"
+
+static void (*ipc_fragment_refiltering_func)(kal_uint8 ip_type, ipc_frag_refilter_info_t *info, qbm_gpd *p_head, qbm_gpd *p_tail);
+static ipc_fragment_t ipc_fragment_inst;
+
+static kal_uint8 ipc_frag_buffer[IPC_FRAG_AFM_BUFFER_SIZE];
+static kal_uint32 ipc_frag_sub_buffer_size[] = {sizeof(IpcFragPktMetaInfo), // Ipv4/v6 framgment pkt_info nodes
+ sizeof(IpcFragMnd6), // IPv4 and Ipv6 shared hash nodes
+ sizeof(void *) * IPC_FRAG_HASH_TABLE_BUCK_NUM, // IPv4/v6 Hash table
+ AFM_SUBPOOL_END_PATTERN};
+static kal_uint32 ipc_frag_sub_buffer_num[] = {IPC_FRAG_PKT_META_NODE_NUM, IPC_FRAG_HASH_NODE_NUM, 2, AFM_SUBPOOL_END_PATTERN};
+
+ipc_fragment_t *ipc_fragment_get_inst()
+{
+ return &ipc_fragment_inst;
+}
+
+void *ipc_fragment_mem_alloc(size_t size)
+{
+ return kal_afm_alloc(ipc_fragment_get_inst()->k_afm_id, size);
+}
+
+void ipc_fragment_mem_free(void *p)
+{
+ kal_afm_free(ipc_fragment_get_inst()->k_afm_id, p);
+}
+
+void ipc_fragment_afm_init()
+{
+ ipc_fragment_t *p = ipc_fragment_get_inst();
+
+ p->afm_buffer_p = ipc_frag_buffer;
+ p->afm_sub_buffer_size_p = ipc_frag_sub_buffer_size;
+ p->afm_sub_buffer_num_p = ipc_frag_sub_buffer_num;
+
+ p->k_afm_id = kal_afm_create(p->afm_buffer_p, IPC_FRAG_AFM_BUFFER_SIZE, p->afm_sub_buffer_size_p, p->afm_sub_buffer_num_p, 0x00, &(p->afm_left_mem_size));
+ ASSERT(p->k_afm_id);
+}
+
+void ipc_fragment_afm_deinit()
+{
+ static kal_uint32 ipc_fragment_afm_delete_fail_cnt = 0;
+ ipc_fragment_t *p = ipc_fragment_get_inst();
+
+ if (p->k_afm_id)
+ {
+ ipc_fragment_afm_delete_fail_cnt += kal_afm_delete(p->k_afm_id) == KAL_MEMORY_NOT_RELEASE;
+ }
+}
+
+void ipc_fragment_set_gpd_datalen(void *gpd, kal_uint32 datalen, void **payload_ptr)
+{
+ void *bd;
+
+ if (QBM_DES_GET_BDP(gpd))
+ {
+ bd = QBM_DES_GET_DATAPTR(gpd);
+ *payload_ptr = QBM_DES_GET_DATAPTR(bd);
+ QBM_DES_SET_DATALEN(bd, datalen);
+ qbm_cal_set_checksum(bd);
+ }
+ else
+ {
+ *payload_ptr = QBM_DES_GET_DATAPTR(gpd);
+ }
+
+ QBM_DES_SET_DATALEN(gpd, datalen);
+ qbm_cal_set_checksum(gpd);
+}
+
+kal_uint16 ipc_fragment_ipv4_cal_header_checksum(void *original_ip_header)
+{
+
+ kal_uint32 sum32 = 0;
+ kal_uint32 offset = 0;
+ kal_uint8 *ip_header = (kal_uint8 *)original_ip_header;
+ kal_uint32 ip_header_len;
+
+ ASSERT(original_ip_header);
+
+ ip_header_len = (IPC_NE_GET_1B(ip_header) & 0xf) << 2;
+
+ while (offset < ip_header_len)
+ {
+ sum32 += IPC_NE_GET_2B(ip_header + offset);
+ offset += 2;
+ }
+
+ sum32 -= IPC_NE_GET_2B(ip_header + 10);
+
+ while (sum32 & 0xffff0000)
+ {
+ sum32 = (sum32 & 0xffff) + ((sum32 & 0xffff0000) >> 16);
+ }
+
+ return ~sum32;
+}
+
+void ipc_fragment_refiltering_queued_packets(kal_uint8 ip_type, ipc_frag_refilter_info_t *info, qbm_gpd *p_head, qbm_gpd *p_tail)
+{
+ ipc_fragment_refiltering_func(ip_type, info, p_head, p_tail);
+}
+
+void ipc_fragment_set_ipc_refilter_func_ptr(void (*func)(kal_uint8 ip_type, ipc_frag_refilter_info_t *info, qbm_gpd *p_head, qbm_gpd *p_tail))
+{
+ ipc_fragment_refiltering_func = func;
+}
+
+kal_bool ipc_fragment_icmp4_send(kal_int32 type, kal_int32 code, void *payload)
+{
+ return KAL_TRUE;
+}
+
+kal_bool ipc_fragment_icmp6_send(kal_int32 type, kal_int32 code, void *payload)
+{
+ return KAL_TRUE;
+}
+
+void ipc_fragment_pktg_init(IpcFragPktGroupInfo *gif)
+{
+ gif->head_gpd = gif->tail_gpd = NULL;
+ gif->head_meta = gif->tail_meta = NULL;
+ gif->info_mask = gif->total_len = gif->accumulate_len = 0;
+ gif->filter_id = IPC_FRAG_INVALID_FILTER_ID;
+}
+
+void ipc_fragment_pktg_rel_gpd_list(IpcFragPktGroupInfo *gif)
+{
+ qbm_gpd *curr_gpd, *priv_gpd;
+ curr_gpd = gif->head_gpd;
+ while (curr_gpd)
+ {
+ priv_gpd = curr_gpd;
+ curr_gpd = QBM_DES_GET_NEXT(curr_gpd);
+ qbmt_dest_q(priv_gpd, priv_gpd);
+ }
+ gif->head_gpd = gif->tail_gpd = NULL;
+}
+
+void ipc_fragment_pktg_rel_meta_list(IpcFragPktGroupInfo *gif)
+{
+ IpcFragPktMetaInfo *curr_meta, *priv_meta;
+ curr_meta = gif->head_meta;
+ while (curr_meta)
+ {
+ priv_meta = curr_meta;
+ curr_meta = curr_meta->next;
+ ipc_fragment_mem_free(priv_meta);
+ }
+ gif->head_meta = gif->tail_meta = NULL;
+}
+
+kal_bool ipc_fragment_ipv4_l3eq(IpcFragIpv4L3Key *a, IpcFragIpv4L3Key *b)
+{
+ return a->src_addr == b->src_addr && a->dst_addr == b->dst_addr && a->ip_id == b->ip_id && a->protocol == b->protocol ? KAL_TRUE : KAL_FALSE;
+}
+
+kal_bool ipc_fragment_ipv6_l3eq(IpcFragIpv6L3Key *a, IpcFragIpv6L3Key *b)
+{
+ return a->src_addr[0] == b->src_addr[0] && a->src_addr[1] == b->src_addr[1] && a->src_addr[2] == b->src_addr[2] && a->src_addr[3] == b->src_addr[3] &&
+ a->dst_addr[0] == b->dst_addr[0] && a->dst_addr[1] == b->dst_addr[1] && a->dst_addr[2] == b->dst_addr[2] && a->dst_addr[3] == b->dst_addr[3] &&
+ a->ip_id == b->ip_id
+ ? KAL_TRUE
+ : KAL_FALSE;
+}
+
+kal_uint32 ipc_fragment_mf(void *pk, kal_uint32 ks)
+{
+ kal_uint32 a[4] = {0x014589cd, 0x2367abef, 0xf2d4c3e1, ks}, kv = 0;
+ kal_uint32 c[4] = {0, 0, 0, 0};
+ kal_uint32 ls = ks;
+ const kal_uint32 *k = (kal_uint32 *)pk;
+
+ while (ls > 0)
+ {
+ for (kal_uint8 i = 0; i < 4; ++i)
+ {
+ kv = 0;
+ if (ls >= 4)
+ {
+ kv = *k;
+ ls -= 4;
+ }
+ else
+ {
+ kal_mem_cpy(&kv, k, ls);
+ ls -= ls;
+ }
+ c[i] = 0xffffffff - a[i] < kv + c[(i + 3) % 4];
+ a[i] += kv + c[(i + 3) % 4];
+ ++k;
+ }
+ }
+
+ return a[0] ^ a[1] ^ a[2] ^ a[3];
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_utility.h b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_utility.h
new file mode 100644
index 0000000..5117f84
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_fragment/ipc_fragment_utility.h
@@ -0,0 +1,37 @@
+#ifndef _IPC_FRAGMENT_UTILITY_INC
+#define _IPC_FRAGMENT_UTILITY_INC
+
+#include "ipc_api.h"
+#include "ipc_fragment.h"
+#include "ipc_fragment_struct.h"
+
+#define IPC_ICMP4_TYPE_TIME_EXCEEDED 11
+#define IPC_ICMP4_CODE_FRAG_REASM_TIME_EXCEEDED 1
+#define IPC_ICMP6_TYPE_TIME_EXCEEDED 3
+#define IPC_ICMP6_TYPE_PARAMETER_PROBLEM 4
+#define IPC_ICMP6_CODE_FRAG_REASM_TIME_EXCEEDED 1
+#define IPC_ICMP6_CODE_ERR_HDR_FIELD_ENCOUNTERED 0
+
+ipc_fragment_t *ipc_fragment_get_inst();
+void *ipc_fragment_mem_alloc(size_t size);
+void ipc_fragment_mem_free(void *p);
+void ipc_fragment_afm_init();
+void ipc_fragment_afm_deinit();
+
+void ipc_fragment_set_gpd_datalen(void *gpd, kal_uint32 datalen, void **payload_ptr);
+kal_uint16 ipc_fragment_ipv4_cal_header_checksum(void *original_ip_header);
+void ipc_fragment_refiltering_queued_packets(kal_uint8 ip_type, ipc_frag_refilter_info_t *info, qbm_gpd *p_head, qbm_gpd *p_tail);
+void ipc_fragment_set_ipc_refilter_func_ptr(void (*func)(kal_uint8 ip_type, ipc_frag_refilter_info_t *info, qbm_gpd *p_head, qbm_gpd *p_tail));
+kal_bool ipc_fragment_icmp4_send(kal_int32 type, kal_int32 code, void *payload);
+kal_bool ipc_fragment_icmp6_send(kal_int32 type, kal_int32 code, void *payload);
+
+void ipc_fragment_pktg_rel_gpd_list(IpcFragPktGroupInfo *gif);
+void ipc_fragment_pktg_rel_meta_list(IpcFragPktGroupInfo *gif);
+void ipc_fragment_pktg_init(IpcFragPktGroupInfo *gif);
+kal_bool ipc_fragment_ipv4_l3eq(IpcFragIpv4L3Key *a, IpcFragIpv4L3Key *b);
+kal_bool ipc_fragment_ipv6_l3eq(IpcFragIpv6L3Key *a, IpcFragIpv6L3Key *b);
+kal_uint32 ipc_fragment_mf(void *pk, kal_uint32 ks);
+
+kal_bool ipc_fragment_reassemble(kal_bool is_v4, qbm_gpd **reasm_gpd, IpcFragPktGroupInfo *pkt_grp_info);
+
+#endif /* _IPC_FRAGMENT_INC */
\ No newline at end of file
diff --git a/mcu/middleware/hif/ipcore/src/ipc_if.c b/mcu/middleware/hif/ipcore/src/ipc_if.c
new file mode 100644
index 0000000..a1a0a11
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_if.c
@@ -0,0 +1,3875 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_if.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IP Core public interface implementation.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "sysservice_msgid.h"
+#include "em_struct.h"
+#include "em_msgid.h"
+#include "intrCtrl.h"
+#include "mw_sap.h"
+#include "ps_public_enum.h"
+#include "l4_msgid.h"
+#include "l4c_ipcore_struct.h"
+
+#include "upcm.h"
+#include "ipcore_upcm_struct.h"
+#include "upcm_msgid.h"
+#if defined(__LTM_SIMULATION_SUPPORT__)
+ #include "lms_api.h"
+#endif
+#include "qmu_bm.h"
+#include "qmu_bm_size.h"
+#include "qmu_bm_util.h"
+
+#include "nmu.h"
+#include "nmu_util.h"
+#include "hmu.h"
+
+#ifdef __ESL_COSIM_HIF__
+ #include "hif_esl_common.h"
+#endif
+
+#include "tcpip_rsra_proxy_public_apis.h"
+
+#include "ccci_ipc_msgid.h"
+#include "hif_mw_msgid.h"
+#include "dispatcher_msgid.h"
+#include "pfm_api.h"
+
+#include "ipc_dpfm.h"
+#include "ipc_api.h"
+#include "ipc_defs.h"
+#include "ipc_debug.h"
+#include "ipc_utils.h"
+#include "ipc_filter.h"
+#include "ipc_dhcp_adp.h"
+#include "ipc_notify.h"
+#include "ipc_data.h"
+
+#include "rsra_public.h"
+
+#if defined (__HIF_CCCI_SUPPORT__)
+#include "ccci_if.h"
+#endif
+
+#if !defined(__MTK_TARGET__) && defined(_MSC_VER) && (_MSC_VER >= 1500)
+#pragma warning( disable : 4100 )
+#endif
+
+#if defined(__IPF_SUPPORT__)
+#include "ipc_data_ipf.h"
+#endif
+
+#define IPC_IPV4_FORMAT_NUM 4
+#define IPC_IPV6_FORMAT_NUM 16
+#define IPC_IP_MAX_LENGTH 4
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+kal_spinlockid ipc_spinlock_g = NULL;
+kal_spinlockid g_ul_spinlock = NULL;
+static volatile kal_bool ipc_in_reset_s = KAL_FALSE;
+/*------------------------------------------------------------------------------
+ * Private functions.
+ *----------------------------------------------------------------------------*/
+
+void ipc_on_lte_tick_source(kal_bool is_lte_tick)
+{
+ if (is_lte_tick) {
+ hmu_switch_hif_timer(HMU_TIMER_SOURCE_DSP);
+ } else {
+ hmu_switch_hif_timer(HMU_TIMER_SOURCE_SYS);
+ }
+}
+
+static ipc_netif_type_e ipc_get_netif_type_by_apn_type(kal_uint32 apn_type)
+{
+ switch (apn_type) {
+ case DDM_APN_TYPE_DEFAULT:
+ return IPC_NETIF_TYPE_NORMAL;
+ case DDM_APN_TYPE_IMS:
+ case DDM_APN_TYPE_EMERGENCY:
+ case DDM_APN_TYPE_XCAP:
+ return IPC_NETIF_TYPE_LATENCY_CONCERN;
+ default:
+ return IPC_NETIF_TYPE_NORMAL;
+ }
+}
+
+static void ipc_config_pdn_info_ipv4(ipc_session_t *session,
+ kal_uint32 session_ip_id,
+ ip_addr_struct *ip_addr,
+ dns_struct *dns,
+ kal_uint32 netif_id,
+ kal_uint32 netif_features,
+ kal_bool *trigger_linkup)
+{
+ kal_uint32 input_dns_idx;
+ kal_uint32 total_dns_cnt;
+ kal_char dns_ip_v4[IPC_IPV4_FORMAT_NUM][IPC_IP_MAX_LENGTH] = {0}; /*< used for save ip string */
+ kal_char ip_v4[IPC_IPV4_FORMAT_NUM][IPC_IP_MAX_LENGTH] = {0}; /*< used for save ip string */
+ kal_uint8 i = 0;
+
+ /* Configure IPv4 address */
+ IPC_ASSERT((IPV4_ADDR_TYPE == ip_addr->ip_addr_type) || (IPV4V6_ADDR_TYPE == ip_addr->ip_addr_type));
+
+ /* Set IPv4 information into nmu */
+ total_dns_cnt = 0;
+ for (input_dns_idx = 0; input_dns_idx < NUM_OF_DNS_ADDR; input_dns_idx++) {
+ if (KAL_TRUE == dns->v4[input_dns_idx].is_dnsv4_present) {
+ for (i = 0; i < IPC_IPV4_FORMAT_NUM; i++) {
+ /* ex: "192.168.1.1" save as 4 string "ip_v4[0], ip_v4[1], ip_v4[2], ip_v4[3]" */
+ if (0 > kal_snprintf(dns_ip_v4[i], IPC_IP_MAX_LENGTH, "%d", dns->v4[input_dns_idx].dnsv4[i])) {
+ /* no log */
+ }
+ }
+
+ hif_trace_debug(IPC_TR_SESSION_BINDING_CFG_IPV4_DNS_USIR, session_ip_id, total_dns_cnt, dns_ip_v4[0], dns_ip_v4[1], dns_ip_v4[2], dns_ip_v4[3]);
+ nmu_set_ip4_dns(session_ip_id, total_dns_cnt, dns->v4[input_dns_idx].dnsv4);
+ total_dns_cnt++;
+ }
+ }
+ hif_trace_info(IPC_TR_SESSION_BINDING_CFG_IPV4_DNS_NUM, total_dns_cnt, session_ip_id);
+ nmu_set_ip4_dns_num(session_ip_id, total_dns_cnt);
+
+ for (i = 0; i < IPC_IPV4_FORMAT_NUM; i++) {
+ if (0 > kal_snprintf(ip_v4[i], IPC_IP_MAX_LENGTH, "%d", ip_addr->ipv4[i])) {
+ /* no log */
+ }
+ }
+ hif_trace_debug(IPC_TR_SESSION_BINDING_CFG_IPV4_ADDR_USIR, session_ip_id, ip_v4[0], ip_v4[1], ip_v4[2], ip_v4[3]);
+ nmu_set_ip4_ip(session_ip_id, ip_addr->ipv4);
+
+ hif_trace_debug(IPC_TR_SESSION_BINDING_CFG_IPV4_FAKE_INFO_USIR, session_ip_id, ip_v4[0], ip_v4[1], ip_v4[2], ip_v4[3]);
+ nmu_set_ip4_fake_mask_and_gateway(session_ip_id, ip_addr->ipv4);
+
+ if (IPC_IS_V4_UNSPECIFIED_ADDR(ip_addr->ipv4)) { /* IPv4 information is not complete in control path */
+
+ /* set IPv4 down */
+ hif_trace_info(IPC_TR_SESSION_BINDING_CFG_IPV4_DOWN, session_ip_id);
+ nmu_set_ip4_down(session_ip_id);
+
+ /* Trigger DHCPv4 client if needed */
+ if (netif_features & IPC_F_DHCP4C) { /* enable DHCPv4 if necessary */
+ hif_trace_info(IPC_TR_SESSION_BINDING_DHCP4C, netif_id, netif_features);
+ ipc_enable_dhcp4c(session);
+
+ /* Stop triggering link up if DHCPv4 client is enabled */
+ *trigger_linkup = KAL_FALSE;
+ }
+ } else { /* IPv4 information is complete, set IPv4 up */
+ hif_trace_info(IPC_TR_SESSION_BINDING_CFG_IPV4_UP, session_ip_id);
+ nmu_set_ip4_up(session_ip_id);
+ }
+}
+
+static void ipc_config_pdn_info_ipv6(kal_uint32 session_ip_id,
+ ip_addr_struct *ip_addr,
+ dns_struct *dns)
+{
+ kal_uint32 input_dns_idx = 0;
+ kal_uint32 total_dns_cnt = 0;
+ kal_char dns_ip_v6[IPC_IPV6_FORMAT_NUM][IPC_IP_MAX_LENGTH] = {0}; /*< used for save ip string */
+ kal_char ip_v6[IPC_IPV6_FORMAT_NUM][IPC_IP_MAX_LENGTH] = {0}; /*< used for save ip string */
+ kal_uint8 i = 0;
+
+ /*
+ * Configure IPv6 address
+ * Always only configure network interface identifier /64
+ */
+ IPC_ASSERT((IPV6_ADDR_TYPE == ip_addr->ip_addr_type) || (IPV4V6_ADDR_TYPE == ip_addr->ip_addr_type));
+
+ /* Set IPv6 information into nmu */
+ total_dns_cnt = 0;
+ for (input_dns_idx = 0; input_dns_idx < NUM_OF_DNS_ADDR; input_dns_idx++) {
+ if (KAL_TRUE == dns->v6[input_dns_idx].is_dnsv6_present) {
+ for (i = 0; i < IPC_IPV6_FORMAT_NUM; i++) {
+ /* ex: "fe80:..." save as 16 string "ip_v6[0], ip_v6[1], ip_v6[2], ip_v6[3]..." */
+ if (0 > kal_snprintf(dns_ip_v6[i], IPC_IP_MAX_LENGTH, "%d", dns->v6[input_dns_idx].dnsv6[i])) {
+ /* no log */
+ }
+ }
+ hif_trace_debug(IPC_TR_SESSION_BINDING_CFG_IPV6_DNS_USIR, session_ip_id, total_dns_cnt, dns_ip_v6[0], dns_ip_v6[1], dns_ip_v6[2], dns_ip_v6[3],
+ dns_ip_v6[4], dns_ip_v6[5], dns_ip_v6[6], dns_ip_v6[7],
+ dns_ip_v6[8], dns_ip_v6[9], dns_ip_v6[10], dns_ip_v6[11],
+ dns_ip_v6[12], dns_ip_v6[13], dns_ip_v6[14], dns_ip_v6[15]);
+ nmu_set_ip6_dns(session_ip_id, total_dns_cnt, dns->v6[input_dns_idx].dnsv6);
+ total_dns_cnt++;
+ }
+ }
+ hif_trace_info(IPC_TR_SESSION_BINDING_CFG_IPV6_DNS_NUM, total_dns_cnt, session_ip_id);
+ nmu_set_ip6_dns_num(session_ip_id, total_dns_cnt);
+
+ if (IPC_IS_V6_UNSPECIFIED_ADDR(ip_addr->ipv6)) {
+ hif_trace_info(IPC_TR_SESSION_BINDING_CFG_IPV6_ZERO_IID_LEN, session_ip_id);
+ nmu_set_ip6_iid_len(session_ip_id, 0);
+
+ hif_trace_info(IPC_TR_SESSION_BINDING_CFG_IPV6_DOWN, session_ip_id);
+ nmu_set_ip6_down(session_ip_id);
+ } else {
+ for (i = 0; i < IPC_IPV6_FORMAT_NUM; i++) {
+ if (0 > kal_snprintf(ip_v6[i], IPC_IP_MAX_LENGTH, "%d", ip_addr->ipv6[i])) {
+ /* no log */
+ }
+ }
+ hif_trace_debug(IPC_TR_SESSION_BINDING_CFG_IPV6_IID_USIR, session_ip_id, IPV6_VALID_IID_BITS, ip_v6[0], ip_v6[1], ip_v6[2], ip_v6[3],
+ ip_v6[4], ip_v6[5], ip_v6[6], ip_v6[7],
+ ip_v6[8], ip_v6[9], ip_v6[10], ip_v6[11],
+ ip_v6[12], ip_v6[13], ip_v6[14], ip_v6[15]);
+ nmu_set_ip6_iid(session_ip_id, ip_addr->ipv6);
+ nmu_set_ip6_iid_len(session_ip_id, IPV6_VALID_IID_BITS);
+
+ hif_trace_info(IPC_TR_SESSION_BINDING_CFG_IPV6_UP, session_ip_id);
+ nmu_set_ip6_up(session_ip_id);
+ }
+}
+
+void ipc_on_pdn_bind_bot(module_type src_mod_id,
+ kal_uint32 netif_features,
+ local_para_struct *local_para_ptr,
+ ps_cause_enum result)
+{
+ ipcore_upcm_pdn_bind_ind_struct *param = (ipcore_upcm_pdn_bind_ind_struct *) local_para_ptr;
+ ipc_session_t *session;
+ kal_uint32 session_ip_id;
+ kal_uint8 ip_type = IPC_IP_TYPE_INVALID;
+ kal_bool trigger_linkup;
+ module_type dst_mod_id = src_mod_id;
+ msg_type msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_RSP;
+
+ if (HIF_IPC_OK == result) {
+ session = ipc_find_session_by_context(param->pdn_id);
+ if (session) {
+ session_ip_id = session->ip_id;
+ ip_type = session->type;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ ipc_update_session_state(session, IPC_SESSION_STATE_BIND);
+
+ hif_trace_info(IPC_TR_SESSION_BINDING_CFG_IP_INFO, param->network_interface_id, param->pdn_id, param->ip_addr.ip_addr_type, session_ip_id);
+
+ trigger_linkup = KAL_TRUE;
+
+ /*
+ * Configure IPv6 address
+ * Always only configure network interface identifier /64
+ */
+ if (IPC_IP_TYPE_IPV6 == ip_type || IPC_IP_TYPE_MIXED == ip_type) {
+ ipc_config_pdn_info_ipv6(session_ip_id, &(param->ip_addr), &(param->dns));
+ }
+
+ /*
+ * Configure IPv4 address
+ */
+ if (IPC_IP_TYPE_IPV4 == ip_type || IPC_IP_TYPE_MIXED == ip_type) {
+ ipc_config_pdn_info_ipv4(session, session_ip_id, &(param->ip_addr), &(param->dns), param->network_interface_id, netif_features, &trigger_linkup);
+ }
+
+ if (KAL_TRUE == trigger_linkup) {
+ ipc_update_session_state(session, IPC_SESSION_STATE_PRE_LINKUP);
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_BIND_SESSION_RLOCK_FAIL, param->network_interface_id, param->pdn_id);
+ result = HIF_IPC_PDN_BIND_RSP_SESSION_RLOCK_FAIL;
+ }
+ }else{
+ if(HIF_IPC_PDN_BIND_RSP_INVALID_NETIF == result){
+ session = ipc_find_session_by_context(param->pdn_id);
+ if(session){
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ ipc_update_session_state(session, IPC_SESSION_STATE_UNBIND);
+ ipc_del_session(session);
+ hif_trace_error(IPC_TR_SESSION_BIND_DYNAMIC_Q_ERROR, param->network_interface_id, param->pdn_id);
+ }
+ }
+ }
+
+ hif_trace_info(IPC_TR_SESSION_BINDING_RESULT, result);
+ if (MOD_NIL != src_mod_id) {
+ ipcore_upcm_pdn_bind_rsp_struct *rsp_msg_p;
+
+ rsp_msg_p = (ipcore_upcm_pdn_bind_rsp_struct *) construct_local_para(sizeof(ipcore_upcm_pdn_bind_rsp_struct), TD_RESET);
+ IPC_ASSERT(rsp_msg_p);
+
+ /* Sync to HW */
+#if defined(__IPF_SUPPORT__)
+ if (HIF_IPC_OK == result) {
+ ipc_update_pn_match_setting(param->pdn_id, param->network_interface_id, ip_type, IPC_IPF_PN_MATCH_BIND);
+ }
+#endif
+ /* Fill response from indication structure */
+ if (param) {
+ hif_trace_info(IPC_TR_SESSION_BINDING_RSP_PARAM_GEN, param->network_interface_id, param->pdn_id, sizeof(ip_addr_struct), sizeof(dns_struct), sizeof(upcm_ipcore_back_info_t));
+
+ rsp_msg_p->network_interface_id = param->network_interface_id;
+ /*
+ * 2016/4/28 Peter.Hsu
+ * The MSB of pdn id is used as sim idx in IPCore internal design for Multiple PS feature.
+ * Therefore, we mask out the MSB before sent the pdn id information to other module.
+ */
+ rsp_msg_p->pdn_id = IPC_UNMASK_PROTOID_FROM_PDNID(param->pdn_id);
+ kal_mem_cpy(&(rsp_msg_p->ip_addr), &(param->ip_addr), sizeof(ip_addr_struct));
+ kal_mem_cpy(&(rsp_msg_p->dns), &(param->dns), sizeof(dns_struct));
+ kal_mem_cpy(&(rsp_msg_p->back_info), &(param->back_info), sizeof(upcm_ipcore_back_info_t));
+ }
+
+ /* Fill result */
+ rsp_msg_p->result = result;
+ hif_trace_info(IPC_TR_SESSION_BINDING_RSP, result, src_mod_id);
+
+#ifdef ATEST_SYS_IPCORE
+ ipc_ut_msg_send6(MOD_IPCORE,
+ src_mod_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_UPCM_PDN_BIND_RSP,
+ (local_para_struct*)rsp_msg_p,
+ NULL);
+#else
+
+#ifdef __LTM_SIMULATION_SUPPORT__
+ dst_mod_id = MOD_LTM_SIM;
+#endif
+
+#ifdef __DISPATCHER_SUPPORT__
+ if ((src_mod_id >= MOD_DISPATCHER) && (src_mod_id <= MOD_DISPATCHER + MAX_SIM_NUM)) {
+ /* DISPATCHER */
+ msg_id = MSG_ID_IPCORE_DISPATCHER_PDN_BIND_RSP;
+ }
+#endif
+
+ msg_send6(MOD_IPCORE, dst_mod_id, IPCORE_SAP, msg_id, (local_para_struct*)rsp_msg_p, NULL);
+#endif
+ }
+}
+
+void ipc_on_pdn_bind_top(module_type src_mod_id,
+ local_para_struct *local_para_ptr)
+{
+ ipcore_upcm_pdn_bind_ind_struct *param = (ipcore_upcm_pdn_bind_ind_struct *) local_para_ptr;
+ ipc_netif_t *netif;
+ ipc_session_t *session;
+ kal_uint32 features = 0;
+ void *netif_cbk_context;
+ module_type netif_module_id;
+ ipc_netif_type_e netif_type = IPC_NETIF_TYPE_NORMAL;
+ kal_uint8 ip_type;
+ ps_cause_enum result;
+ ilm_struct ilm = {0};
+
+ result = HIF_IPC_OK;
+
+ hif_trace_info(IPC_TR_SESSION_BINDING_START);
+
+ if (param) {
+ IPC_ASSERT(local_para_ptr->msg_len == sizeof(ipcore_upcm_pdn_bind_ind_struct));
+ hif_trace_info(IPC_TR_SESSION_BINDING_INFO, param->network_interface_id, param->pdn_id, param->ip_addr.ip_addr_type);
+
+ switch (param->ip_addr.ip_addr_type) {
+ case IPV4_ADDR_TYPE:
+ ip_type = IPC_IP_TYPE_IPV4;
+ break;
+ case IPV6_ADDR_TYPE:
+ ip_type = IPC_IP_TYPE_IPV6;
+ break;
+ case IPV4V6_ADDR_TYPE:
+ ip_type = IPC_IP_TYPE_MIXED;
+ break;
+ default:
+ hif_trace_error(IPC_TR_SESSION_BIND_UNSUPPORTED_IP_ADDR_TYPE, param->ip_addr.ip_addr_type, param->pdn_id);
+ result = HIF_IPC_PDN_BIND_RSP_UNSUPPORTED_IP_ADDR_TYPE;
+ goto rsp;
+ }
+
+ netif = ipc_find_netif(param->network_interface_id);
+ if (netif) {
+ session = ipc_new_session(netif, param->pdn_id, ip_type, IPC_SESSION_STATE_PRE_BIND);
+ features = netif->config.features;
+ netif_cbk_context = netif->config.callback_context;
+ netif_module_id = netif->config.module_id;
+ if (session) {
+ netif_type = ipc_get_netif_type_by_apn_type(param->apn_type_info.apn_type_activate);
+ if (IPC_NETIF_TYPE_LATENCY_CONCERN == netif_type) {
+ IPC_R_TO_W_LOCK_OBJECT(netif, ipc_spinlock_g);
+ netif->config.features |= IPC_F_LATENCY_CONCERN;
+ IPC_W_TO_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+ }
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ if (session) {
+ /*
+ * Send netif type to LHIF for dynamic queue mapping.
+ */
+ if (features & IPC_F_DYNAMIC_Q_MAPPING) {
+ ipc_lhifcore_q_mapping_msg_t *req_msg_p;
+
+ req_msg_p = (ipc_lhifcore_q_mapping_msg_t *) construct_local_para(sizeof(ipc_lhifcore_q_mapping_msg_t), TD_RESET);
+ IPC_ASSERT(req_msg_p);
+
+ /* Fill request from indication structure */
+ kal_mem_cpy(&(req_msg_p->bind_ind), param, sizeof(ipcore_upcm_pdn_bind_ind_struct));
+
+ req_msg_p->netif_features = features;
+ req_msg_p->callback_context = netif_cbk_context;
+ req_msg_p->bind_src_mod_id = src_mod_id;
+ req_msg_p->netif_type = netif_type;
+
+ ilm.src_mod_id = MOD_IPCORE;
+ ilm.dest_mod_id = netif_module_id;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_LHIFCORE_QUEUE_MAPPING_REQ;
+ ilm.local_para_ptr = (local_para_struct *)req_msg_p;
+ ilm.peer_buff_ptr = NULL;
+
+ msg_send_ext_queue(&ilm);
+ return;
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_BIND_NEW_SESSION_FAIL, param->network_interface_id, param->pdn_id, ip_type);
+ result = HIF_IPC_PDN_BIND_RSP_NEW_SESSION_FAIL;
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_BIND_INVALID_NETIF, param->network_interface_id);
+ result = HIF_IPC_PDN_BIND_RSP_INVALID_NETIF;
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_BIND_NULL_PARAM);
+ result = HIF_IPC_PDN_BIND_RSP_NULL_PARAM;
+ }
+
+ rsp : ipc_on_pdn_bind_bot(src_mod_id, features, local_para_ptr, result);
+}
+
+void ipc_on_pdn_unbind(local_para_struct *local_para_ptr)
+{
+ ipcore_upcm_pdn_unbind_ind_struct *param = (ipcore_upcm_pdn_unbind_ind_struct *) local_para_ptr;
+ ipc_session_t *session;
+ kal_uint32 session_ip_id;
+ kal_uint8 session_type;
+
+ if (param) {
+ IPC_ASSERT(local_para_ptr->msg_len == sizeof(ipcore_upcm_pdn_unbind_ind_struct));
+ hif_trace_info(IPC_TR_SESSION_DEACTIVATING, param->pdn_id);
+
+ session = ipc_find_session_by_context(param->pdn_id);
+ if (session) {
+ session_ip_id = session->ip_id;
+ session_type = session->type;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ if (IPC_IP_TYPE_IPV6 == session_type || IPC_IP_TYPE_MIXED == session_type) {
+ nmu_set_ip6_dns_num(session_ip_id, 0);
+ nmu_set_ip6_down(session_ip_id);
+ }
+ if (IPC_IP_TYPE_IPV4 == session_type || IPC_IP_TYPE_MIXED == session_type) {
+ nmu_set_ip4_dns_num(session_ip_id, 0);
+ nmu_set_ip4_down(session_ip_id);
+ }
+
+ ipc_disable_dhcp4c(session); /* disable DHCPv4 it's been enabled */
+ ipc_update_session_state(session, IPC_SESSION_STATE_UNBIND);
+ ipc_del_session(session);
+
+ /* Sync to HW */
+#if defined(__IPF_SUPPORT__)
+ ipc_update_pn_match_setting(param->pdn_id, IPC_INVALID_NETIF_ID, session_type, IPC_IPF_PN_MATCH_UNBIND);
+#endif
+
+#if (CUR_GEN >= MD_GEN95)
+ /* Discard Packets which are already in IPCore's internal queue */
+ ipc_data_drop_ul_meta_by_pdn(param->pdn_id);
+#endif
+ /* Reset data usage of pdn_id on Unbind */
+ ipc_reset_data_usage_by_pdn_sim_id(param->pdn_id);
+
+ } else {
+ hif_trace_error(IPC_TR_SESSION_DEACTIVATE_NO_SESSION_FOUND, param->pdn_id);
+ ipc_ut_set_error(IPC_UT_SESSION_DEACTIVATE_NO_SESSION_FOUND);
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_DEACTIVATE_NULL_PARAM);
+ }
+}
+
+static void ipc_on_pdn_rebind(module_type src_mod_id,
+ local_para_struct *local_para_ptr)
+{
+ ipcore_upcm_pdn_rebind_ind_struct *param = (ipcore_upcm_pdn_rebind_ind_struct *) local_para_ptr;
+ ipc_session_t *session;
+ ipc_netif_t *netif;
+ kal_uint32 session_ip_id;
+ kal_uint8 old_session_type;
+ kal_uint8 old_ipv4_addr[4];
+ kal_uint8 old_ipv6_addr[16];
+ kal_uint8 new_session_type = IPC_IP_TYPE_INVALID;
+ kal_uint32 netif_features;
+ kal_bool trigger_linkup = KAL_TRUE;
+ ps_cause_enum result = HIF_IPC_OK;
+
+ if (param) {
+ IPC_ASSERT(local_para_ptr->msg_len == sizeof(ipcore_upcm_pdn_rebind_ind_struct));
+ hif_trace_info(IPC_TR_SESSION_REBINDING_INFO, param->network_interface_id, param->old_pdn_id, param->new_pdn_id, param->ip_addr.ip_addr_type);
+
+ switch (param->ip_addr.ip_addr_type) {
+ case IPV4_ADDR_TYPE:
+ new_session_type = IPC_IP_TYPE_IPV4;
+ break;
+ case IPV6_ADDR_TYPE:
+ new_session_type = IPC_IP_TYPE_IPV6;
+ break;
+ case IPV4V6_ADDR_TYPE:
+ new_session_type = IPC_IP_TYPE_MIXED;
+ break;
+ default:
+ hif_trace_error(IPC_TR_SESSION_REBIND_UNSUPPORTED_IP_ADDR_TYPE, param->ip_addr.ip_addr_type, param->new_pdn_id);
+ result = HIF_IPC_PDN_BIND_RSP_UNSUPPORTED_IP_ADDR_TYPE;
+ goto rsp;
+ }
+
+ netif = ipc_find_netif(param->network_interface_id);
+ if (netif) {
+ netif_features = netif->config.features;
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ session = ipc_find_session_by_context((kal_uint8)(param->old_pdn_id));
+ if (session) {
+ session_ip_id = session->ip_id;
+ old_session_type = session->type;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ session = ipc_replace_session(netif, session, param->new_pdn_id, new_session_type, IPC_SESSION_STATE_LINKUP);
+ if (session) {
+ if (IPC_IP_TYPE_IPV6 == old_session_type || IPC_IP_TYPE_MIXED == old_session_type) {
+ if (IPC_IP_TYPE_IPV6 == new_session_type || IPC_IP_TYPE_MIXED == new_session_type) {
+ nmu_get_ip6_iid(session_ip_id, &old_ipv6_addr);
+ if (0 != kal_mem_cmp(param->ip_addr.ipv6, &old_ipv6_addr, sizeof(old_ipv6_addr))) {
+ /*
+ * IPv6 addr has been changed.
+ * Update addr/dns to nmu.
+ */
+ /* Delete old info */
+ nmu_set_ip6_dns_num(session_ip_id, 0);
+ nmu_set_ip6_down(session_ip_id);
+
+ ipc_update_session_state(session, IPC_SESSION_STATE_IP_REVOKE);
+
+ /* Update new info */
+ ipc_config_pdn_info_ipv6(session_ip_id, &(param->ip_addr), &(param->dns));
+
+ ipc_update_session_state(session, IPC_SESSION_STATE_LINKUP);
+ }
+ } else {
+ /* Delete old info */
+ nmu_set_ip6_dns_num(session_ip_id, 0);
+ nmu_set_ip6_down(session_ip_id);
+ }
+ }
+
+ if (IPC_IP_TYPE_IPV4 == old_session_type || IPC_IP_TYPE_MIXED == old_session_type) {
+ if (IPC_IP_TYPE_IPV4 == new_session_type || IPC_IP_TYPE_MIXED == new_session_type) {
+ nmu_get_ip4_ip(session_ip_id, &old_ipv4_addr);
+ if (0 != kal_mem_cmp(param->ip_addr.ipv4, &old_ipv4_addr, sizeof(old_ipv4_addr))) {
+ /*
+ * IPv4 addr has been changed.
+ * Update addr/dns to nmu.
+ */
+ /* Delete old info */
+ nmu_set_ip4_dns_num(session_ip_id, 0);
+ nmu_set_ip4_down(session_ip_id);
+ ipc_disable_dhcp4c(session); /* disable DHCPv4 it's been enabled */
+
+ ipc_update_session_state(session, IPC_SESSION_STATE_IP_REVOKE);
+
+ /* Update new info */
+ ipc_config_pdn_info_ipv4(session, session_ip_id, &(param->ip_addr), &(param->dns), param->network_interface_id, netif_features, &trigger_linkup);
+
+ ipc_update_session_state(session, IPC_SESSION_STATE_LINKUP);
+ }
+ } else {
+ /* Delete old info */
+ nmu_set_ip4_dns_num(session_ip_id, 0);
+ nmu_set_ip4_down(session_ip_id);
+ ipc_disable_dhcp4c(session); /* disable DHCPv4 it's been enabled */
+ }
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_REBIND_REPLACE_SESSION_FAIL, param->network_interface_id, param->old_pdn_id, param->new_pdn_id);
+ result = HIF_IPC_PDN_BIND_RSP_NEW_SESSION_FAIL;
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_REBIND_SESSION_RLOCK_FAIL, param->network_interface_id, param->old_pdn_id);
+ result = HIF_IPC_PDN_BIND_RSP_SESSION_RLOCK_FAIL;
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_REBIND_INVALID_NETIF, param->network_interface_id);
+ result = HIF_IPC_PDN_BIND_RSP_INVALID_NETIF;
+ }
+ } else {
+ hif_trace_error(IPC_TR_SESSION_DEACTIVATE_NULL_PARAM);
+ result = HIF_IPC_PDN_BIND_RSP_NULL_PARAM;
+ }
+
+rsp :
+ hif_trace_info(IPC_TR_SESSION_REBINDING_RESULT, result);
+ if (MOD_NIL != src_mod_id) {
+ ipcore_upcm_pdn_rebind_rsp_struct *rsp_msg_p = NULL;
+
+ rsp_msg_p = (ipcore_upcm_pdn_rebind_rsp_struct *) construct_local_para(sizeof(ipcore_upcm_pdn_rebind_rsp_struct), TD_RESET);
+ IPC_ASSERT(rsp_msg_p);
+
+ /* Sync to HW */
+#if defined(__IPF_SUPPORT__)
+ if (HIF_IPC_OK == result) {
+ /* Clear old pn_match_setting */
+ ipc_update_pn_match_setting(param->old_pdn_id, IPC_INVALID_NETIF_ID, old_session_type, IPC_IPF_PN_MATCH_UNBIND);
+ /* Update new pn_match_setting */
+ ipc_update_pn_match_setting(param->new_pdn_id, param->network_interface_id, new_session_type, IPC_IPF_PN_MATCH_BIND);
+ }
+#endif
+
+ /* Reset data usage of old pdn_id on PDN Rebind */
+ if (HIF_IPC_OK == result) {
+ ipc_reset_data_usage_by_pdn_sim_id(param->old_pdn_id);
+ }
+
+ /* Fill response from indication structure */
+ if (param) {
+ hif_trace_info(IPC_TR_SESSION_REBINDING_RSP_PARAM_GEN, param->network_interface_id, param->old_pdn_id, param->new_pdn_id, sizeof(ip_addr_struct), sizeof(dns_struct), sizeof(upcm_ipcore_back_info_t));
+
+ rsp_msg_p->network_interface_id = param->network_interface_id;
+ rsp_msg_p->old_pdn_id = IPC_UNMASK_PROTOID_FROM_PDNID(param->old_pdn_id);
+ rsp_msg_p->new_pdn_id = IPC_UNMASK_PROTOID_FROM_PDNID(param->new_pdn_id);
+ kal_mem_cpy(&(rsp_msg_p->ip_addr), &(param->ip_addr), sizeof(ip_addr_struct));
+ kal_mem_cpy(&(rsp_msg_p->dns), &(param->dns), sizeof(dns_struct));
+ }
+
+ /* Fill result */
+ rsp_msg_p->result = result;
+
+ hif_trace_info(IPC_TR_SESSION_REBINDING_RSP, result, src_mod_id);
+ msg_send6(IPCORE_SRC_MOD, REBIND_DST_MOD, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_REBIND_RSP, (local_para_struct*)rsp_msg_p, NULL);
+ }
+}
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+void ipc_bind_lan_netif(kal_uint32 netif_id_1, kal_uint32 netif_id_2)
+{
+ ipc_netif_t *netif_1, *netif_2;
+ kal_uint32 features_1, features_2;
+ ipc_link_req_t *link_req;
+ void *context_1, *context_2;
+ module_type module_id_1, module_id_2;
+
+ netif_1 = ipc_find_netif(netif_id_1);
+ netif_2 = ipc_find_netif(netif_id_2);
+ IPC_R_TO_W_LOCK_OBJECT(netif_1, ipc_spinlock_g);
+ hif_data_trace(MD_TRC_IPC_BIND_LAN_NETIF, 0, netif_1, netif_id_1, netif_2, netif_id_2);
+
+ /* Setup LAN netif 1 */
+ if (netif_1 && netif_2) {
+ features_1 = netif_1->config.features;
+
+ IPC_ASSERT(features_1 & IPC_F_LAN);
+ IPC_ASSERT(!netif_1->lan_netif && !netif_2->lan_netif);
+
+ /* Bind to one another netif */
+ netif_1->lan_netif = netif_2;
+
+ context_1 = netif_1->config.callback_context;
+ module_id_1 = netif_1->config.module_id;
+ } else {
+ hif_trace_error(IPC_TR_LAN_NETIF_BIND_INVALID_NETIF, netif_1, netif_id_1, netif_2, netif_id_2);
+ if (netif_1) {
+ IPC_W_UNLOCK_OBJECT(netif_1, ipc_spinlock_g);
+ }
+ if (netif_2) {
+ IPC_R_UNLOCK_OBJECT(netif_2, ipc_spinlock_g);
+ }
+ IPC_ASSERT(KAL_FALSE);
+ }
+
+ IPC_W_TO_R_LOCK_OBJECT(netif_1, ipc_spinlock_g);
+ IPC_R_TO_W_LOCK_OBJECT(netif_2, ipc_spinlock_g);
+
+ /* Setup LAN netif 2 */
+ if (netif_2) {
+ features_2 = netif_2->config.features;
+
+ IPC_ASSERT(features_2 & IPC_F_LAN);
+ IPC_ASSERT(!netif_2->lan_netif);
+
+ /* Bind to one another netif */
+ netif_2->lan_netif = netif_1;
+
+ context_2 = netif_2->config.callback_context;
+ module_id_2 = netif_2->config.module_id;
+ } else {
+ hif_trace_error(IPC_TR_LAN_NETIF_BIND_INVALID_NETIF, netif_1, netif_id_1, netif_2, netif_id_2);
+ if (netif_2) {
+ IPC_W_UNLOCK_OBJECT(netif_2, ipc_spinlock_g);
+ }
+ IPC_R_UNLOCK_OBJECT(netif_1, ipc_spinlock_g);
+ IPC_ASSERT(KAL_FALSE);
+ }
+
+ IPC_W_UNLOCK_OBJECT(netif_2, ipc_spinlock_g);
+ IPC_R_UNLOCK_OBJECT(netif_1, ipc_spinlock_g);
+
+ /* Link up LAN netif 1 */
+ link_req = (ipc_link_req_t *)construct_local_para(sizeof(ipc_link_req_t), TD_RESET);
+ IPC_ASSERT(link_req);
+
+ link_req->callback_context = context_1;
+ link_req->ip_type = IPC_IP_TYPE_MIXED;
+ link_req->req_type = IPC_LINK_REQ_TYPE_DPFM;
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ module_id_1, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_LINK_UP_REQ, /* msg_id */
+ (struct local_para_struct *)link_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+
+ /* Link up LAN netif 2 */
+ link_req = (ipc_link_req_t *)construct_local_para(sizeof(ipc_link_req_t), TD_RESET);
+ IPC_ASSERT(link_req);
+
+ link_req->callback_context = context_2;
+ link_req->ip_type = IPC_IP_TYPE_MIXED;
+ link_req->req_type = IPC_LINK_REQ_TYPE_DPFM;
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ module_id_2, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_LINK_UP_REQ, /* msg_id */
+ (struct local_para_struct *)link_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+}
+
+void ipc_unbind_lan_netif(kal_uint32 netif_id_1, kal_uint32 netif_id_2)
+{
+ ipc_netif_t *netif_1, *netif_2;
+ kal_uint32 features_1, features_2;
+ ipc_link_req_t *link_req;
+ void *context_1, *context_2;
+ module_type module_id_1, module_id_2;
+
+ netif_1 = ipc_find_netif(netif_id_1);
+ netif_2 = ipc_find_netif(netif_id_2);
+ IPC_R_TO_W_LOCK_OBJECT(netif_1, ipc_spinlock_g);
+ hif_data_trace(MD_TRC_IPC_UNBIND_LAN_NETIF, 0, netif_1, netif_id_1, netif_2, netif_id_2);
+
+ /* Setup LAN netif 1 */
+ if (netif_1 && netif_2) {
+ features_1 = netif_1->config.features;
+
+ IPC_ASSERT(features_1 & IPC_F_LAN);
+ IPC_ASSERT(netif_1->lan_netif && netif_2->lan_netif);
+
+ /* Unbind netif */
+ netif_1->lan_netif = NULL;
+
+ context_1 = netif_1->config.callback_context;
+ module_id_1 = netif_1->config.module_id;
+ } else {
+ hif_trace_error(IPC_TR_LAN_NETIF_UNBIND_INVALID_NETIF, netif_1, netif_id_1, netif_2, netif_id_2);
+ if (netif_1) {
+ IPC_W_UNLOCK_OBJECT(netif_1, ipc_spinlock_g);
+ }
+ if (netif_2) {
+ IPC_R_UNLOCK_OBJECT(netif_2, ipc_spinlock_g);
+ }
+ IPC_ASSERT(KAL_FALSE);
+ }
+
+ IPC_W_TO_R_LOCK_OBJECT(netif_1, ipc_spinlock_g);
+ IPC_R_TO_W_LOCK_OBJECT(netif_2, ipc_spinlock_g);
+
+ /* Setup LAN netif 2 */
+ if (netif_2) {
+ features_2 = netif_2->config.features;
+
+ IPC_ASSERT(features_2 & IPC_F_LAN);
+ IPC_ASSERT(netif_2->lan_netif);
+
+ /* Unbind netif */
+ netif_2->lan_netif = NULL;
+
+ context_2 = netif_2->config.callback_context;
+ module_id_2 = netif_2->config.module_id;
+ } else {
+ hif_trace_error(IPC_TR_LAN_NETIF_UNBIND_INVALID_NETIF, netif_1, netif_id_1, netif_2, netif_id_2);
+ if (netif_2) {
+ IPC_W_UNLOCK_OBJECT(netif_2, ipc_spinlock_g);
+ }
+ IPC_R_UNLOCK_OBJECT(netif_1, ipc_spinlock_g);
+ IPC_ASSERT(KAL_FALSE);
+ }
+
+ IPC_W_UNLOCK_OBJECT(netif_2, ipc_spinlock_g);
+ IPC_R_UNLOCK_OBJECT(netif_1, ipc_spinlock_g);
+
+ /* Link down LAN netif 1 */
+ link_req = (ipc_link_req_t *)construct_local_para(sizeof(ipc_link_req_t), TD_RESET);
+ IPC_ASSERT(link_req);
+
+ link_req->callback_context = context_1;
+ link_req->ip_type = IPC_IP_TYPE_MIXED;
+ link_req->req_type = IPC_LINK_REQ_TYPE_DPFM;
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ module_id_1, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_LINK_DOWN_REQ, /* msg_id */
+ (struct local_para_struct *)link_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+
+ /* Link down LAN netif 2 */
+ link_req = (ipc_link_req_t *)construct_local_para(sizeof(ipc_link_req_t), TD_RESET);
+ IPC_ASSERT(link_req);
+
+ link_req->callback_context = context_2;
+ link_req->ip_type = IPC_IP_TYPE_MIXED;
+ link_req->req_type = IPC_LINK_REQ_TYPE_DPFM;
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ module_id_2, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_LINK_DOWN_REQ, /* msg_id */
+ (struct local_para_struct *)link_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+}
+#endif
+
+void ipc_on_query_info(module_type src_mod_id, local_para_struct *local_para_ptr)
+{
+ ipc_netif_list_t netif_list_info;
+
+ hif_trace_info(IPC_TR_QUERY_INFO_START, src_mod_id, local_para_ptr);
+
+ /* Initiate information for response */
+ kal_mem_set(&netif_list_info, 0, sizeof(ipc_netif_list_t));
+
+ /* Collect information */
+ ipc_query_netif_list(&netif_list_info);
+
+ /* Response */
+ if (MOD_NIL != src_mod_id) {
+ ipc_query_info_t *cnf_msg_p;
+
+ cnf_msg_p = (ipc_query_info_t *) construct_local_para(sizeof(ipc_query_info_t), TD_RESET);
+ IPC_ASSERT(cnf_msg_p);
+
+ /* Fill response from indication structure */
+ kal_mem_cpy(&(cnf_msg_p->netif), &netif_list_info, sizeof(ipc_netif_list_t));
+
+ hif_trace_info(IPC_TR_QUERY_INFO_CNF, src_mod_id);
+
+ msg_send6(IPCORE_SRC_MOD,
+ QUERY_DST_MOD,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_QUERY_INFO_CNF,
+ (local_para_struct*)cnf_msg_p,
+ NULL);
+ } else {
+ hif_trace_error(IPC_TR_QUERY_INFO_NO_MOD_ID_FOR_CFN, src_mod_id, MOD_NIL);
+ }
+
+ hif_trace_info(IPC_TR_QUERY_INFO_END);
+}
+
+static void ipc_reg_callbacks(void)
+{
+ /* Register the callback functions with UPCM. */
+ IPC_REG_CBK_DLVR_DL_SDU(ipc_on_did_downlink_multiple_ps); /* LTE downlink callback. */
+ IPC_REG_CBK_NOTIFY_LTE_TICK_SOURCE(ipc_on_lte_tick_source); /* LTE change polling source */
+}
+
+static void ipc_get_qbm_datahead(void* gpd, kal_uint32 *datalen_ptr, void **payload_ptr)
+{
+ IPC_ASSERT(gpd && datalen_ptr && payload_ptr);
+
+ /* Get total data length */
+ *datalen_ptr = QBM_DES_GET_DATALEN(gpd);
+
+ /* Get first data pointer */
+ if (QBM_DES_GET_BDP(gpd))
+ {
+ if (*datalen_ptr) {
+ /* GPD with data : get 1st BD with-data for payload head */
+ qbm_gpd* bd = NULL;
+
+ /* get bd data ptr */
+ bd = QBM_DES_GET_DATAPTR(gpd);
+
+ /* Loop to trace 1st DL BD with data buffer */
+ while (bd && (QBM_DES_GET_DATALEN(bd) == 0)) {
+ bd = (QBM_DES_GET_EOL(bd)) ? (NULL) : ((qbm_gpd*) QBM_DES_GET_NEXT(bd));
+ }
+
+ if (bd) {
+ *payload_ptr = (kal_uint8 *) QBM_DES_GET_DATAPTR(bd);
+ } else {
+ hif_trace_error(IPC_TR_GET_QBM_DATAHEAD_ZERO_LENGTH_BD, gpd, QBM_DES_GET_DATALEN(gpd));
+ *payload_ptr = NULL;
+ }
+ } else {
+ /* GPD without data : get 1st BD */
+ void* bd = NULL;
+
+ /* get bd data ptr */
+ bd = QBM_DES_GET_DATAPTR(gpd);
+
+ *payload_ptr = (kal_uint8 *)QBM_DES_GET_DATAPTR(bd);
+ }
+ } else {
+ *payload_ptr = (kal_uint8*)QBM_DES_GET_DATAPTR(gpd);
+ }
+}
+
+static void ipc_push_qbm_datahead(void* gpd, kal_uint32 offset, kal_uint32 *datalen_ptr, void **payload_ptr)
+{
+ kal_uint8* data_ptr = NULL;
+ kal_uint32 data_len = 0;
+
+ IPC_ASSERT(gpd && datalen_ptr && payload_ptr);
+
+ if (QBM_DES_GET_BDP(gpd)) {
+ void* bd;
+
+ /* set bd data ptr */
+ bd = QBM_DES_GET_DATAPTR(gpd);
+
+ data_ptr = (kal_uint8*)QBM_DES_GET_DATAPTR(bd);
+ QBM_DES_SET_DATAPTR(bd, data_ptr-offset);
+
+ /* set bd data len */
+ data_len = QBM_DES_GET_DATALEN(bd);
+ QBM_DES_SET_DATALEN(bd, data_len+offset);
+
+ /* set bd checksum */
+ qbm_cal_set_checksum(bd);
+ } else {
+ data_ptr = (kal_uint8*)QBM_DES_GET_DATAPTR(gpd);
+ QBM_DES_SET_DATAPTR(gpd, data_ptr-offset);
+ }
+
+ /* set gpd data len */
+ data_len = QBM_DES_GET_DATALEN(gpd);
+ QBM_DES_SET_DATALEN(gpd, data_len+offset);
+
+ /* set gpd checksum */
+ qbm_cal_set_checksum(gpd);
+
+ *datalen_ptr = data_len + offset;
+ *payload_ptr = (void*)(data_ptr - offset);
+}
+
+#ifdef __ESL_COSIM_HIF__
+void ipc_on_esl_netif_attach_done(local_para_struct *local_para_ptr)
+{
+ hif_esl_netif_parm *in_parm = (hif_esl_netif_parm *)local_para_ptr;
+ hif_esl_netif_parm *out_parm;
+
+ out_parm = (hif_esl_netif_parm *)construct_local_para(sizeof(hif_esl_netif_parm), TD_RESET);
+ out_parm->netif_id = in_parm->netif_id;
+
+ /* In ESL environment, IPCore needs to send ILM to UPCM to request binding if network interface sent the ILM MSG_ID_HIF_IPCORE_ESL_ATTACH_DONE_IND */
+ msg_send6(MOD_IPCORE, /* src_mod_id */
+ MOD_UPCM, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_UPCM_ESL_PDN_BIND_REQ, /* msg_id */
+ (local_para_struct *)out_parm, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+}
+#endif
+
+static void ipc_em_update_req_hdlr(local_para_struct *local_para_ptr)
+{
+ l4cps_em_update_req_struct *p_req = (l4cps_em_update_req_struct *)local_para_ptr;
+
+ /*
+ * only process Tool source,
+ * Ignore AP.
+ * AP EM needed to be discussed.
+ */
+ if (p_req->em_src == EM_FROM_ELT) {
+ switch (p_req->info_request[IPC_EM_UL_THROTTLE_STATUS]) {
+ case EM_ON:
+ ipc_em_on_s = 1;
+ break;
+
+ case EM_OFF:
+ ipc_em_on_s = 0;
+ break;
+
+ case EM_NC:
+ /* no change */
+ break;
+
+ default:
+ /*can't reach here*/
+ IPC_ASSERT(KAL_FALSE);
+ }
+
+ /* For EM ELT update info*/
+ ipc_em_send_ul_throttle_status();
+ }
+}
+
+static void ipc_plmn_list_ind_handler(local_para_struct *local_para_ptr)
+{
+ l4c_ipcore_ul_throttle_req_struct *p_ind = (l4c_ipcore_ul_throttle_req_struct *)local_para_ptr;
+ kal_bool to_send_msg = KAL_FALSE;
+
+ switch (p_ind->ul_throttle_action) {
+ case UL_THROTTLE_NO_ACTION:
+
+ /* IPCORE need to process ul queue if ul pending queue is not empty */
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = ((!ipc_ul_enable_g) && (!ipc_ul_processing_s) && (!ipc_are_ul_queues_empty()));
+ if (to_send_msg) {
+ ipc_ul_processing_s = KAL_TRUE;
+ }
+ ipc_ul_enable_g = KAL_TRUE;
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ break;
+ case UL_THROTTLE_ONGOING:
+ ipc_ul_enable_g = KAL_FALSE;
+ break;
+ case UL_THROTTLE_ABORTING:
+ default:
+ break;
+ }
+}
+
+static void ipc_query_ccci_runtime_data()
+{
+#if defined(__HIF_CCCI_SUPPORT__)
+ kal_uint32 mtu = 0;
+ kal_uint32 ccci_fast_runtime = 0;
+ CCCI_RUNTIME_FEATURE_SUPPORT_T result;
+
+ /* MTU */
+ result = ccci_runtime_data_query(AP_CCCI_RUNTIME_NETWORK_MTU_SIZE, &mtu, 4);
+ if (CCCI_RUNTIME_FEATURE_MUST_SUPPORT == result.support_mask) {
+ ipc_dl_valid_packet_len_s = mtu;
+ } else {
+ ipc_dl_valid_packet_len_s = IPC_DL_INVALID_LEN_DEFAULT;
+ }
+
+#if defined(__FAST_CCCI_HEADER__)
+ /* CCCI Fast Header */
+ result = ccci_runtime_data_query(AP_CCCI_RUNTIME_CCCI_FAST_HEADER, &ccci_fast_runtime, 4);
+ if (CCCI_RUNTIME_FEATURE_MUST_SUPPORT == result.support_mask) {
+ ipc_is_support_ccci_fast_header_s = KAL_TRUE;
+ } else {
+ ipc_is_support_ccci_fast_header_s = KAL_FALSE;
+ }
+#endif // __FAST_CCCI_HEADER__
+#else
+ /* MTU */
+ ipc_dl_valid_packet_len_s = IPC_DL_INVALID_LEN_DEFAULT;
+
+#if defined(__FAST_CCCI_HEADER__)
+ /* CCCI Fast Header */
+ ipc_is_support_ccci_fast_header_s = KAL_FALSE;
+#endif // __FAST_CCCI_HEADER__
+#endif
+}
+
+static void ipc_spinlock_init()
+{
+ IPC_ASSERT(!ipc_spinlock_g);
+ ipc_spinlock_g = kal_create_spinlock(IPC_LOCK_NAME);
+
+ /** used for UL operation */
+ IPC_ASSERT(!g_ul_spinlock);
+ g_ul_spinlock = kal_create_spinlock(IPC_UL_LOCK_NAME);
+}
+
+static void ipc_test_loopback_ind_handler(ilm_struct *ilm)
+{
+ ipcore_upcm_testloop_ind_struct *ind = (ipcore_upcm_testloop_ind_struct *)(ilm->local_para_ptr);
+ ipcore_upcm_testloop_rsp_struct *rsp;
+
+ switch (ind->cmd) {
+ case TESTLOOP_CMD_MODE_A_ACTIVATE:
+ IPC_ASSERT(ipc_test_loopback_mode_s != IPC_TEST_LOOPBACK_MODE_B);
+ ipc_test_loopback_mode_s = IPC_TEST_LOOPBACK_MODE_A;
+ IPC_REG_CBK_DLVR_DL_SDU(ipc_on_did_downlink_test_mode);
+ break;
+ case TESTLOOP_CMD_MODE_A_DEACTIVATE:
+ IPC_ASSERT(ipc_test_loopback_mode_s == IPC_TEST_LOOPBACK_MODE_A);
+ ipc_test_loopback_mode_s = IPC_TEST_LOOPBACK_MODE_OFF;
+ IPC_REG_CBK_DLVR_DL_SDU(ipc_on_did_downlink_multiple_ps);
+ break;
+ case TESTLOOP_CMD_MODE_B_ACTIVATE:
+ IPC_ASSERT(ipc_test_loopback_mode_s != IPC_TEST_LOOPBACK_MODE_A);
+ ipc_test_loopback_mode_s = IPC_TEST_LOOPBACK_MODE_B;
+ IPC_REG_CBK_DLVR_DL_SDU(ipc_on_did_downlink_test_mode);
+ break;
+ case TESTLOOP_CMD_MODE_B_DEACTIVATE:
+ IPC_ASSERT(ipc_test_loopback_mode_s == IPC_TEST_LOOPBACK_MODE_B);
+ ipc_test_loopback_mode_s = IPC_TEST_LOOPBACK_MODE_OFF;
+ IPC_REG_CBK_DLVR_DL_SDU(ipc_on_did_downlink_multiple_ps);
+ break;
+ default:
+ /*can't reach here*/
+ IPC_ASSERT(KAL_FALSE);
+ }
+
+ rsp = (ipcore_upcm_testloop_rsp_struct *)construct_local_para(sizeof(ipcore_upcm_testloop_rsp_struct), TD_RESET);
+ IPC_ASSERT(rsp);
+
+ /* Fill result */
+ rsp->is_success = KAL_TRUE;
+
+ msg_send6(MOD_IPCORE, /* src_mod_id */
+ ilm->src_mod_id, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_UPCM_TESTLOOP_RSP, /* msg_id */
+ (struct local_para_struct *)rsp, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+}
+
+static void ipc_on_ipcore_link_up_ind(void *link_handshake_msg_ind_ptr)
+{
+ ipc_link_handshake_msg_t *link_handshake_msg_ind_p = (ipc_link_handshake_msg_t *)link_handshake_msg_ind_ptr;
+ ipc_link_handshake_msg_t *link_handshake_msg_rsp_p = NULL;
+
+ hif_trace_info(IPC_TR_IPCORE_LINK_UP_IND_START, link_handshake_msg_ind_p->netif_id, link_handshake_msg_ind_p->ip_id, link_handshake_msg_ind_p->ip_type);
+
+ /* Always response the indication with same handshake message */
+ link_handshake_msg_rsp_p = (ipc_link_handshake_msg_t *) construct_local_para(sizeof(ipc_link_handshake_msg_t), TD_RESET);
+ IPC_ASSERT(link_handshake_msg_rsp_p);
+
+ kal_mem_cpy(link_handshake_msg_rsp_p, link_handshake_msg_ind_p, sizeof(ipc_link_handshake_msg_t));
+
+ hif_trace_info(IPC_TR_IPCORE_LINK_UP_IND_SEND_LINK_UP_RSP, link_handshake_msg_ind_p->netif_id, link_handshake_msg_ind_p->ip_id, link_handshake_msg_ind_p->ip_type);
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_LINK_UP_RSP, /* msg_id */
+ (struct local_para_struct *) link_handshake_msg_rsp_p, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+
+ hif_trace_info(IPC_TR_IPCORE_LINK_UP_IND_END, link_handshake_msg_ind_p->netif_id, link_handshake_msg_ind_p->ip_id, link_handshake_msg_ind_p->ip_type);
+}
+
+static void ipc_on_ipcore_ip_up_ind(void *link_handshake_msg_ind_ptr)
+{
+ ipc_link_handshake_msg_t *link_handshake_msg_ind_p = (ipc_link_handshake_msg_t *)link_handshake_msg_ind_ptr;
+ ipc_link_handshake_msg_t *link_handshake_msg_rsp_p = NULL;
+
+ hif_trace_info(IPC_TR_IPCORE_IP_UP_IND_START, link_handshake_msg_ind_p->netif_id, link_handshake_msg_ind_p->ip_id, link_handshake_msg_ind_p->ip_type);
+
+ /* Always response the indication with same handshake message */
+ link_handshake_msg_rsp_p = (ipc_link_handshake_msg_t *) construct_local_para(sizeof(ipc_link_handshake_msg_t), TD_RESET);
+ IPC_ASSERT(link_handshake_msg_rsp_p);
+
+ kal_mem_cpy(link_handshake_msg_rsp_p, link_handshake_msg_ind_p, sizeof(ipc_link_handshake_msg_t));
+
+ hif_trace_info(IPC_TR_IPCORE_IP_UP_IND_SEND_IP_UP_RSP, link_handshake_msg_ind_p->netif_id, link_handshake_msg_ind_p->ip_id, link_handshake_msg_ind_p->ip_type);
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_IP_UP_RSP, /* msg_id */
+ (struct local_para_struct *) link_handshake_msg_rsp_p, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+
+ hif_trace_info(IPC_TR_IPCORE_IP_UP_IND_END, link_handshake_msg_ind_p->netif_id, link_handshake_msg_ind_p->ip_id, link_handshake_msg_ind_p->ip_type);
+}
+
+#if (IPC_IPV6_RA_WORKAROUND != 1)
+static void ipc_send_ra_pkt(kal_uint32 netif_id)
+{
+ qbm_gpd *p_ra_gpd = NULL;
+ kal_int32 pdn_id = 0;
+
+ if (KAL_FALSE == ipc_query_pdn_by_netif(netif_id, IPC_IP_TYPE_IPV6, &pdn_id)) {
+ hif_trace_error(IPC_TR_GET_PDN_ID_FAILED, __FUNCTION__);
+ return;
+ }
+
+ /* Forward previous IPv6 RA to AP here */
+ p_ra_gpd = ipc_data_ipv6_ra_pool_pop(pdn_id);
+ if(p_ra_gpd) {
+
+ hif_trace_info(IPC_TR_SEND_RA_GPD_NETIF, __FUNCTION__, p_ra_gpd, netif_id);
+ IPC_SEND_RA_DL(p_ra_gpd, netif_id);
+ }
+
+ return;
+}
+#else
+static void ipc_send_ra_pkt_from_ilm(ilm_struct *p_ilm)
+{
+ qbm_gpd *p_ra_gpd = NULL;
+ d2cm_ipcore_info_ind_struct *p_ind = NULL;
+ kal_int32 pdn_id = 0;
+ kal_uint32 netif_id = 0;
+ kal_bool keep_store = KAL_FALSE;
+ ipc_session_t *session = NULL;
+
+ p_ind = (d2cm_ipcore_info_ind_struct *)p_ilm->local_para_ptr;
+ netif_id = IPC_NETIF_ID_LHIF_BEGIN | p_ind->netif_id;
+ if (KAL_FALSE == ipc_query_pdn_by_netif(netif_id, IPC_IP_TYPE_IPV6, &pdn_id)) {
+ hif_trace_error(IPC_TR_GET_PDN_ID_FAILED, __FUNCTION__);
+ return;
+ }
+ keep_store = p_ind->keep_ra;
+
+ /* get previous IPv6 RA here */
+ p_ra_gpd = ipc_data_ipv6_ra_pool_pop(pdn_id);
+
+ if(p_ra_gpd) {
+ session = ipc_find_session_by_context(pdn_id);
+ if (session == NULL || IPC_SESSION_STATE_PRE_LINKUP == session->state) {
+ if(session) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ d2cm_ipcore_info_ind_struct *retry_ind = (d2cm_ipcore_info_ind_struct *)construct_local_para(sizeof(d2cm_ipcore_info_ind_struct), TD_RESET);
+ retry_ind->netif_id = p_ind->netif_id;
+ retry_ind->keep_ra= p_ind->keep_ra;
+ msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_D2CM_IPCORE_INFO_IND, (local_para_struct *)retry_ind, NULL);
+ } else {
+ hif_trace_error(IPC_TR_IPCORE_SESSION_NOT_FOUND, __FUNCTION__, pdn_id);
+ }
+ ipc_data_ipv6_ra_pool_push(pdn_id, p_ra_gpd);
+ return;
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ if (KAL_TRUE == keep_store) {
+ kal_uint8 *p_packet = NULL;
+ qbm_gpd *bd = NULL;
+ kal_uint32 packet_len = 0;
+ qbm_gpd *p_copy_ra_gpd = NULL;
+
+ /* copy p_ra_gpd to p_copy_ra_gpd */
+ if (!QBM_DES_GET_BDP(p_ra_gpd)) {
+ p_packet = QBM_DES_GET_DATAPTR(p_ra_gpd);
+ packet_len = QBM_DES_GET_DATALEN(p_ra_gpd);
+ } else {
+ /* get 1st bd data ptr */
+ bd = QBM_DES_GET_DATAPTR(p_ra_gpd);
+ /* Loop to trace 1st DL BD with data buffer */
+ while (bd && (QBM_DES_GET_DATALEN(bd) == 0)) {
+ bd = (QBM_DES_GET_EOL(bd))?(NULL):((qbm_gpd*)QBM_DES_GET_NEXT(bd));
+ }
+ /* No any BD have data */
+ if (NULL == bd) {
+ /* zero length gpd */
+ qbmt_dest_q(p_ra_gpd, p_ra_gpd);
+ return;
+ }
+ p_packet = QBM_DES_GET_DATAPTR(bd);
+ packet_len = QBM_DES_GET_DATALEN(p_ra_gpd);
+ }
+ p_copy_ra_gpd = QBM_ALLOC_ONE(QBM_TYPE_NET_DL);
+ if (p_copy_ra_gpd != NULL) {
+ bd = QBM_DES_GET_DATAPTR(p_copy_ra_gpd);
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), p_packet, packet_len);
+ QBM_CACHE_FLUSH(QBM_DES_GET_DATAPTR(bd), packet_len);
+ QBM_DES_SET_DATALEN(bd, packet_len);
+ qbm_cal_set_checksum(bd);
+ QBM_DES_SET_DATALEN(p_copy_ra_gpd, packet_len);
+ qbm_cal_set_checksum(p_copy_ra_gpd);
+ /* for DTAG operator keep RA for future */
+ ipc_data_ipv6_ra_pool_push(pdn_id, p_copy_ra_gpd);
+ hif_trace_info(IPC_TR_SEND_RA_GPD_PUSH_BY_PDN, __FUNCTION__, p_copy_ra_gpd, pdn_id);
+ }
+ }
+
+ hif_trace_info(IPC_TR_SEND_RA_GPD_NETIF, __FUNCTION__, p_ra_gpd, netif_id);
+ IPC_SEND_RA_DL(p_ra_gpd, netif_id);
+ }
+}
+#endif
+
+static void ipc_on_ipcore_up_rsp(void *link_handshake_msg_rsp_ptr) {
+ ipc_link_handshake_msg_t *link_handshake_msg_rsp_p = (ipc_link_handshake_msg_t *) link_handshake_msg_rsp_ptr;
+ ipc_netif_t *netif = NULL;
+ ipc_session_t *session = NULL;
+
+ hif_trace_info(IPC_TR_IPCORE_UP_RSP_START, link_handshake_msg_rsp_p->netif_id, link_handshake_msg_rsp_p->ip_id, link_handshake_msg_rsp_p->ip_type);
+
+ netif = ipc_find_netif(link_handshake_msg_rsp_p->netif_id);
+ if (netif) {
+ session = ipc_find_session_by_netif(netif, link_handshake_msg_rsp_p->ip_type);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ if (session) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ hif_trace_info(IPC_TR_IPCORE_UP_RSP_UPDATE_SESSION_STATE_TO_LINKUP, session);
+ ipc_update_session_state(session, IPC_SESSION_STATE_LINKUP);
+
+ #if (IPC_IPV6_RA_WORKAROUND != 1)
+ /* flush RA when netif linkup */
+ ipc_send_ra_pkt(link_handshake_msg_rsp_p->netif_id);
+ #endif
+ } else {
+ hif_trace_error(IPC_TR_IPCORE_UP_RSP_SESSION_NOT_FOUND, netif, link_handshake_msg_rsp_p->netif_id, link_handshake_msg_rsp_p->ip_id, link_handshake_msg_rsp_p->ip_type);
+ }
+ } else {
+ hif_trace_error(IPC_TR_IPCORE_UP_RSP_NETIF_NOT_FOUND, link_handshake_msg_rsp_p->netif_id, link_handshake_msg_rsp_p->ip_id, link_handshake_msg_rsp_p->ip_type);
+ }
+
+ hif_trace_info(IPC_TR_IPCORE_UP_RSP_END, link_handshake_msg_rsp_p->netif_id, link_handshake_msg_rsp_p->ip_id, link_handshake_msg_rsp_p->ip_type);
+}
+
+kal_uint16 ipc_calc_tcp_checksum(kal_bool is_ipv4,
+ kal_uint8 *src_addr,
+ kal_uint8 *dst_addr,
+ kal_uint8 *tcp_header,
+ kal_uint32 tcp_len)
+{
+ return ipc_utils_calc_tcp_checksum(is_ipv4, src_addr, dst_addr, tcp_header, tcp_len);
+}
+
+kal_uint16 ipc_calc_udp_checksum(kal_bool is_ipv4,
+ kal_uint8 *src_addr,
+ kal_uint8 *dst_addr,
+ kal_uint8 *udp_header,
+ kal_uint32 udp_len)
+{
+ return ipc_utils_calc_udp_checksum(is_ipv4, src_addr, dst_addr, udp_header, udp_len);
+}
+
+kal_uint16 ipc_calc_ipv4_checksum(kal_uint8 *ip_header)
+{
+ return ipc_utils_calc_ipv4_checksum(ip_header);
+}
+
+static void ipc_restore_netif_hdlr(local_para_struct *p_param)
+{
+ IPC_ASSERT(NULL != p_param);
+
+ ipc_restore_netif_struct_t *p_restore_info = (ipc_restore_netif_struct_t *)p_param;
+ ipc_netif_t *p_netif = NULL;
+
+ p_netif = ipc_find_netif(p_restore_info->netif_id);
+ if (p_netif) {
+ ipc_notify_netif_link_change(p_netif,
+ p_restore_info->ip_type,
+ p_restore_info->is_link_update,
+ p_restore_info->is_up);
+ IPC_R_UNLOCK_OBJECT(p_netif, ipc_spinlock_g);
+ }
+
+ return;
+}
+
+static void ipc_inject_msg_hdlr(tst_inject_string_struct *p_inject_cmd)
+{
+ ASSERT(NULL != p_inject_cmd);
+
+ if (0 == p_inject_cmd->index) {
+ msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_IPCORE_UDP_IGMP_DEREG_FILTER_REQ, NULL, NULL);
+ } else if (1 == p_inject_cmd->index) {
+ msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_IPCORE_UDP_IGMP_REG_FILTER_REQ, NULL, NULL);
+ } else if (4 == p_inject_cmd->index) {
+ // AT+EGCMD=481,1,"10" cancel discarding all uplink packets
+ msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_UL_DISABLE_ALL_PACKETS_DEREG_FILTER_REQ, NULL, NULL);
+ } else if (5 == p_inject_cmd->index) {
+ // AT+EGCMD=481,1,"11" discarding all uplink packets for test purpose
+ msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_UL_DISABLE_ALL_PACKETS_REG_FILTER_REQ, NULL, NULL);
+ } else if (6 == p_inject_cmd->index) {
+ // AT+EGCMD=481,1,"20" cancel discarding all uplink packets except ping & RS
+ msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_UL_ICMP_PING_WHITELIST_DEREG_FILTER_REQ, NULL, NULL);
+ } else if (7 == p_inject_cmd->index) {
+ // AT+EGCMD=481,1,"21" discarding all uplink packets except ping & RS
+ msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_UL_ICMP_PING_WHITELIST_REG_FILTER_REQ, NULL, NULL);
+ }
+
+ return;
+}
+
+static void ipc_pdn_info_notify(module_type src_mod_id, local_para_struct *local_para_ptr)
+{
+ ipcore_upcm_pdn_info_ind_struct *p_param = (ipcore_upcm_pdn_info_ind_struct*)local_para_ptr;
+ kal_uint32 pdn_id = p_param->pdn_id;
+ kal_uint32 proto_idx = 0;
+
+ IPC_GET_PROTOID_FROM_MODID(src_mod_id, proto_idx);
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, proto_idx);
+
+ switch(p_param->pdn_info) {
+ case UPCM_PDN_ACT:
+ break;
+
+ case UPCM_PDN_DEACT:
+ IPC_ASSERT(IPC_PROXY_IPV6_RA_POOL_SIZE > pdn_id);
+ /* Reset RA pool when PDN is deactivated */
+ ipc_data_ipv6_ra_pool_push(pdn_id, NULL);
+ break;
+
+ default:
+ IPC_ASSERT(KAL_FALSE);
+ break;
+ }
+
+ return;
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions.
+ *----------------------------------------------------------------------------*/
+kal_bool ipc_init(void)
+{
+ nmu_init();
+ hmu_boot_init();
+
+ ipc_spinlock_init();
+ ipc_object_init();
+ ipc_filter_init();
+ ipc_ntfy_init();
+ ipc_queue_init();
+ ipc_reg_callbacks();
+ ipc_timer_init();
+ ipc_query_ccci_runtime_data();
+
+ pfm_init();
+
+#if defined(__IPF_SUPPORT__)
+ IPC_ENABLE_IPF_DL_FILTER();
+#endif
+
+ return KAL_TRUE;
+}
+
+void ipc_on_ilm(ilm_struct *ilm)
+{
+ switch (ilm->msg_id) {
+ case MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ:
+ ipc_on_process_ul_queue();
+ break;
+
+ case MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ:
+
+ /* Clear processing flag */
+ ipc_data_clear_dl_ilm_flag();
+
+ ipc_data_qbm_downlink_dequeue();
+
+#if defined(__IPF_SUPPORT__)
+ ipc_meta_downlink_dequeue();
+#endif
+ ipc_did_downlink_dequeue();
+ break;
+
+ case MSG_ID_IPCORE_RETRY_UL_RELOAD_REQ:
+ ipc_on_retry_ul_reload();
+ break;
+ case MSG_ID_IPCORE_DISPATCHER_PDN_BIND_IND:
+ case MSG_ID_IPCORE_UPCM_PDN_BIND_IND: {
+ ipcore_upcm_pdn_bind_ind_struct *param = (ipcore_upcm_pdn_bind_ind_struct *)ilm->local_para_ptr;
+ kal_uint8 proto_idx;
+
+ IPC_GET_PROTOID_FROM_MODID(ilm->src_mod_id, proto_idx);
+ IPC_MASK_PROTOID_ON_PDNID(param->pdn_id, proto_idx);
+ }
+ ipc_on_pdn_bind_top(ilm->src_mod_id, ilm->local_para_ptr);
+ break;
+ case MSG_ID_IPCORE_DISPATCHER_PDN_UNBIND_IND:
+ case MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND: {
+ ipcore_upcm_pdn_unbind_ind_struct *param = (ipcore_upcm_pdn_unbind_ind_struct *)ilm->local_para_ptr;
+ kal_uint8 proto_idx;
+
+ IPC_GET_PROTOID_FROM_MODID(ilm->src_mod_id, proto_idx);
+ IPC_MASK_PROTOID_ON_PDNID(param->pdn_id, proto_idx);
+ }
+ ipc_on_pdn_unbind(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_UPCM_PDN_REBIND_IND: {
+ ipcore_upcm_pdn_rebind_ind_struct *param = (ipcore_upcm_pdn_rebind_ind_struct *)ilm->local_para_ptr;
+ kal_uint8 proto_idx;
+
+ IPC_GET_PROTOID_FROM_MODID(ilm->src_mod_id, proto_idx);
+ IPC_MASK_PROTOID_ON_PDNID(param->old_pdn_id, proto_idx);
+ IPC_MASK_PROTOID_ON_PDNID(param->new_pdn_id, proto_idx);
+ }
+ ipc_on_pdn_rebind(ilm->src_mod_id, ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_LHIFCORE_QUEUE_MAPPING_RSP: {
+ ipc_lhifcore_q_mapping_msg_t *msg = (ipc_lhifcore_q_mapping_msg_t *) ilm->local_para_ptr;
+ if(KAL_FALSE == msg->result){
+ ipc_on_pdn_bind_bot(msg->bind_src_mod_id, msg->netif_features, (local_para_struct *)&(msg->bind_ind), HIF_IPC_PDN_BIND_RSP_INVALID_NETIF);
+ }else{
+ ipc_on_pdn_bind_bot(msg->bind_src_mod_id, msg->netif_features, (local_para_struct *)&(msg->bind_ind), HIF_IPC_OK);
+ }
+ break;
+ }
+
+ case MSG_ID_DHCP4C_ACTIVATE_RSP:
+ ipc_on_dhcp4c_activate_rsp(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_DHCP4C_DEACTIVATE_RSP:
+ ipc_on_dhcp4c_deactivate_rsp(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_DHCP4C_IP_UP_IND:
+ ipc_on_dhcp4c_ip_up_ind(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_DHCP4C_IP_DOWN_IND:
+ ipc_on_dhcp4c_ip_down_ind(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_DHCP4C_PACKET_IND:
+ ipc_on_dhcp4c_packet_ind(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_LINK_UP_IND:
+ ipc_on_ipcore_link_up_ind(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_IP_UP_IND:
+ ipc_on_ipcore_ip_up_ind(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_LINK_UP_RSP:
+ ipc_on_ipcore_up_rsp(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_IP_UP_RSP:
+ ipc_on_ipcore_up_rsp(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_QUERY_INFO_REQ:
+ ipc_on_query_info(ilm->src_mod_id, ilm->local_para_ptr);
+ break;
+
+#ifdef __ESL_COSIM_HIF__
+ case MSG_ID_HIF_IPCORE_ESL_ATTACH_DONE_IND:
+ ipc_on_esl_netif_attach_done(ilm->local_para_ptr);
+ break;
+#endif
+
+ case MSG_ID_IPCORE_SET_UL_THROTTLE:
+ ipc_set_ul_throttle(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_VDM_IMS_EMERGENCY_CALL_IND:
+ ipc_ims_emergency_call_ind_handler(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_REGISTER_FILTER_REQ:
+ ipc_filter_reg_handler(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_DEREGISTER_FILTER_REQ:
+ ipc_filter_dereg_handler(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_TIMER_EXPIRY: {
+#ifndef ATEST_SYS_IPCORE
+ switch (evshed_get_index(ilm)) {
+ case IPC_ES_INDEX_UL_THROTTLE:
+ evshed_timer_handler(ipc_es_ul_throttle_s);
+ break;
+ default:
+ IPC_ASSERT(0);
+ break;
+ }
+#else
+ ipc_ul_throttle_timeout(NULL);
+#endif
+ break;
+ }
+
+ case MSG_ID_L4CPS_EM_UPDATE_REQ:
+ ipc_em_update_req_hdlr(ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_L4C_IPCORE_UL_THROTTLE_REQ:
+#ifndef __NOT_BLOCK_TX_WHEN_PLMN_LIST__
+ ipc_plmn_list_ind_handler(ilm->local_para_ptr);
+#endif
+ break;
+
+ case MSG_ID_IPCORE_RESTORE_NETIF_IND:
+ ipc_restore_netif_hdlr(ilm->local_para_ptr);
+ break;
+
+ /* MSG for Test loopback mode */
+ case MSG_ID_IPCORE_UPCM_TESTLOOP_IND:
+ ipc_test_loopback_ind_handler(ilm);
+ break;
+
+ /* MSG to PFM (Packet Filter Manager) */
+ case MSG_ID_PFM_REGISTER_FILTER_REQ:
+ case MSG_ID_PFM_DEREGISTER_FILTER_REQ:
+ case MSG_ID_AP_STATUS_IND:
+ case MSG_ID_IPCORE_UDP_IGMP_REG_FILTER_REQ:
+ case MSG_ID_IPCORE_UDP_IGMP_DEREG_FILTER_REQ:
+ case MSG_ID_PFM_ICMP_PING_REG_FILTER_REQ:
+ case MSG_ID_PFM_ICMP_PING_DEREG_FILTER_REQ:
+ case MSG_ID_PFM_UL_DISABLE_ALL_PACKETS_REG_FILTER_REQ:
+ case MSG_ID_PFM_UL_DISABLE_ALL_PACKETS_DEREG_FILTER_REQ:
+ case MSG_ID_PFM_UL_ICMP_PING_WHITELIST_REG_FILTER_REQ:
+ case MSG_ID_PFM_UL_ICMP_PING_WHITELIST_DEREG_FILTER_REQ:
+ case MSG_ID_PFM_PCIE_STATE_CHANGE_IND:
+ pfm_on_ilm(ilm);
+ break;
+
+ case MSG_ID_TST_INJECT_STRING:
+ ipc_inject_msg_hdlr((tst_inject_string_struct *)ilm->local_para_ptr);
+ break;
+
+ case MSG_ID_IPCORE_UPCM_PDN_INFO_IND:
+ ipc_pdn_info_notify(ilm->src_mod_id, ilm->local_para_ptr);
+ break;
+
+/* Received ILM sent by IPCore */
+#ifdef ATEST_SYS_IPCORE
+ case MSG_ID_IPCORE_UL_PACKET_FILTERED_REQ:
+ case MSG_ID_IPCORE_DL_PACKET_FILTERED_REQ:
+ case MSG_ID_IPCORE_UL_PACKET_FILTERED_WITH_INFO_REQ:
+ case MSG_ID_IPCORE_DL_PACKET_FILTERED_WITH_INFO_REQ:
+ case MSG_ID_IPCORE_NAS_RQ_INFO_IND:
+ case MSG_ID_IPCORE_UPCM_PDN_REBIND_RSP:
+ case MSG_ID_IPCORE_QUERY_INFO_CNF:
+ case MSG_ID_IPCORE_LHIFCORE_QUEUE_MAPPING_REQ:
+ IPC_ASSERT(ipc_ut_on_ilm(ilm));
+ break;
+#endif
+
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ case MSG_ID_D2CM_IPCORE_INFO_IND:
+ ipc_send_ra_pkt_from_ilm(ilm);
+ break;
+#endif
+ default:
+ hif_trace_error(IPC_TR_UNKNOWN_ILM, ilm->msg_id);
+ break;
+ }
+}
+
+void ipc_clean_private_data(void)
+{
+ ipc_filter_init();
+ pfm_reset();
+}
+
+kal_bool ipc_reset(void)
+{
+ kal_uint64 idx = 0;
+ ipc_session_t *session = NULL;
+ kal_uint32 session_ip_id = 0;
+ kal_uint8 session_type = 0;
+
+ hif_trace_info(IPC_TR_RESET_START);
+
+ ipc_in_reset_s = KAL_TRUE;
+
+ /*
+ * 2012/07/24, per moja.hsu MoDIS unit test requirement,
+ * deactivate all sessions and register callback functions with UPCM at reset.
+ */
+ for (idx = 0; idx < IPC_MAX_SESSION_CNT; idx++) {
+ session = ipc_find_session_by_context((kal_uint32)idx);
+
+ hif_trace_info(IPC_TR_DEL_SESSION, session, idx);
+
+ if (session) {
+ session_ip_id = session->ip_id;
+ session_type = session->type;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ hif_trace_info(IPC_TR_DEL_SESSION_INFO, session_type, session->ip_id, idx);
+
+ if (IPC_IP_TYPE_IPV6 == session_type || IPC_IP_TYPE_MIXED == session_type) {
+ nmu_set_ip6_dns_num(session_ip_id, 0);
+ nmu_set_ip6_down(session_ip_id);
+ }
+ if (IPC_IP_TYPE_IPV4 == session_type || IPC_IP_TYPE_MIXED == session_type) {
+ nmu_set_ip4_dns_num(session_ip_id, 0);
+ nmu_set_ip4_down(session_ip_id);
+ }
+
+ ipc_disable_dhcp4c(session); /* disable DHCPv4 it's been enabled */
+ ipc_update_session_state(session, IPC_SESSION_STATE_UNBIND);
+ ipc_del_session(session);
+ }
+ }
+
+ /* Remove all attached network interface during reset */
+ for (idx = 0; idx < IPC_MAX_NETIF_CNT; idx++) {
+ ipc_netif_t *netif;
+
+ netif = ipc_find_netif_by_bit_id(1ULL << idx);
+ hif_trace_info(IPC_TR_DEL_NETIF, netif, idx);
+
+ if (netif) {
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ ipc_del_netif(netif);
+ }
+ }
+
+ ipc_filter_init();
+ ipc_ntfy_init();
+
+ ipc_queue_init();
+ ipc_reg_callbacks();
+
+ pfm_reset();
+
+ ipc_in_reset_s = KAL_FALSE;
+
+ hif_trace_info(IPC_TR_RESET_END);
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_is_in_reset(void)
+{
+ return ipc_in_reset_s;
+}
+
+kal_bool ipc_attach(ipc_conf_t *config, ipc_handle_t *handle)
+{
+ ipc_netif_t *netif = NULL;
+ kal_uint32 netif_id = 0;
+ kal_uint8 ip_type = 0;
+ kal_bool is_send = KAL_FALSE;
+
+ *handle = IPC_INVALID_HANDLE;
+
+ if (NULL == config) {
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+ hif_trace_info(IPC_TR_NETIF_ATTACHING, config->module_id, config->netif_id, config->callback_context, config->features);
+
+ netif = ipc_new_netif(config);
+ if (netif) {
+ /*
+ * For Test loopback mode.
+ * IPCore will save the ID of the netif which set the IPC_F_TEST_LOOPBACK_X flag.
+ */
+ if (config->features & IPC_F_TEST_LOOPBACK_A) {
+ ipc_test_loopback_a_netif_id_s = config->netif_id;
+ } else if (config->features & IPC_F_TEST_LOOPBACK_B) {
+ ipc_test_loopback_b_netif_id_s = config->netif_id;
+ }
+
+ *handle = (ipc_handle_t) netif;
+
+ /* Notify for attach event */
+ ipc_ntfy_do_event_cbk(netif, IPC_NTFY_TYPE_ATTACH);
+
+ /* Restore saved netif info */
+ IPC_W_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif->config.features & IPC_F_KEEP_PDN_MAPPING) {
+ is_send = ipc_session_restore_netif_map(netif, &ip_type);
+ netif_id = netif->config.netif_id;
+ }
+ IPC_W_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ if (is_send) {
+ ipc_session_send_restore_netif_ind(netif_id, ip_type, KAL_TRUE, KAL_TRUE);
+ }
+
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+}
+
+kal_bool ipc_detach(ipc_handle_t handle)
+{
+ hif_trace_info(IPC_TR_NETIF_DETACHING, handle);
+
+ /* Notify for detach event "before" actually detach network interface */
+ ipc_ntfy_do_event_cbk((ipc_netif_t *) handle, IPC_NTFY_TYPE_DETACH);
+
+ return ipc_del_netif((ipc_netif_t *) handle);
+}
+
+kal_bool ipc_uplink(ipc_handle_t handle, ipc_io_request_t *ior)
+{
+ ipc_io_request_t *curr_ior = NULL;
+ ipc_io_request_t *tail_ior = NULL;
+ kal_uint32 ior_cnt = 0;
+ kal_bool to_send_msg = KAL_FALSE;
+ ipc_netif_t *netif = (ipc_netif_t *)handle;
+ kal_uint32 netif_features = 0;
+ ipc_ul_queue_priority_e q_priority = IPC_UL_QUEUE_PRIORITY_HIGH;
+
+ HIF_SWLA_START("IU0");
+
+ /*
+ * Note that, since we reload UL buffers in IPCORE context (ipc_on_process_ul_queue()),
+ * all exception cases reuquired for dropping UL packets discard will be done there
+ * for simplicity. So, netif lock is not required here.
+ */
+
+ if (ior) {
+ /* Enqueue the IOR list and keep the information about the corresponding netif. */
+ curr_ior = ior;
+ ior_cnt = 0;
+ do {
+ ((ipc_internal_ior_t *) curr_ior)->netif = netif;
+ tail_ior = curr_ior;
+ ior_cnt++;
+ curr_ior = curr_ior->next_request;
+ } while (curr_ior);
+
+ netif_features = netif->config.features;
+ hif_data_trace(MD_TRC_IPC_UL_UPLINK_CALLBACK, 0, ior, netif, netif_features);
+
+ if (!(netif_features & IPC_F_LATENCY_CONCERN)) {
+ /* IOR from normal Netif should be low-priority */
+ q_priority = IPC_UL_QUEUE_PRIORITY_LOW;
+ } else {
+ /* IOR from LATENCY-CONCERN Netif should be high-priority */
+ q_priority = IPC_UL_QUEUE_PRIORITY_HIGH;
+ }
+ ipc_push_ior_list_to_ior_queue(ior, tail_ior, ior_cnt, q_priority);
+
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = (!ipc_ul_processing_s);
+ ipc_ul_processing_s = KAL_TRUE;
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+
+ HIF_SWLA_STOP("IU0");
+ return KAL_TRUE;
+ } else {
+ hif_trace_error(IPC_TR_UL_INVALID_PARAM, handle, ior);
+ HIF_SWLA_STOP("IU0");
+ return KAL_FALSE;
+ }
+}
+
+kal_int32 ipc_get_ip_id(ipc_handle_t handle)
+{
+ ipc_netif_t *netif = (ipc_netif_t *)handle;
+ kal_int32 ip_id;
+
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ ip_id = ipc_map_netif_to_ip_id(netif);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ } else {
+ ip_id = -1;
+ }
+
+ return ip_id;
+}
+
+void ipc_need_ul_reload(ipc_handle_t handle)
+{
+ ipc_netif_t *netif = (ipc_netif_t *)handle;
+
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ ipc_set_netif_ul_reload_retry(netif, KAL_TRUE);
+ ipc_set_netif_ul_set_need_reload(netif, KAL_TRUE);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+}
+
+void ipc_check_ul_reload_retry(void)
+{
+ kal_uint64 netif_ul_reload_retry;
+ kal_bool to_send_msg;
+
+ netif_ul_reload_retry = ipc_get_all_netif_ul_reload_retry();
+
+ if (0 != netif_ul_reload_retry) {
+ hif_data_trace(MD_TRC_IPC_UL_CHECK_UL_RELOAD_RETRY, 0, netif_ul_reload_retry);
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ to_send_msg = (!ipc_ul_reload_retrying_s);
+ ipc_ul_reload_retrying_s = KAL_TRUE;
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_RETRY_UL_RELOAD_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ hmu_hifeg_start(HIF_DRV_EG_HIF_RELOAD_EVNET);
+ } else {
+ hmu_hifeg_stop(HIF_DRV_EG_HIF_RELOAD_EVNET);
+ }
+}
+
+void ipc_notify_link_change(kal_uint32 netif_id, kal_uint8 ip_type, kal_bool link_update, kal_bool is_up)
+{
+ ipc_netif_t *netif;
+
+ hif_trace_info(IPC_TR_NOTIFY_LINK_CHANGE_BEGIN, netif_id, ip_type, link_update, is_up);
+
+ netif = ipc_find_netif(netif_id);
+ if (netif)
+ {
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ hif_trace_info(IPC_TR_NOTIFY_LINK_CHANGE_FOR_NETIF_BEGIN, netif, netif_id);
+ ipc_notify_netif_link_change(netif, ip_type, link_update, is_up);
+ hif_trace_info(IPC_TR_NOTIFY_LINK_CHANGE_FOR_NETIF_END, netif, netif_id);
+ } else
+ {
+ hif_trace_info(IPC_TR_NOTIFY_LINK_CHANGE_UNKNOWN_NETIF, netif_id);
+ }
+
+ hif_trace_info(IPC_TR_NOTIFY_LINK_CHANGE_END, netif_id, ip_type, link_update, is_up);
+}
+
+kal_int32 ipc_register_ul_filter_cbk(ipc_filter_rules_t *rules,
+ ipc_filter_callback_t callback_func,
+ void *callback_context)
+{
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ ntfy_ctxt.ntfy_mod.cbk_func = callback_func;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_NIL;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ ntfy_ctxt.p_ntfy_args = callback_context;
+
+ hif_trace_info(IPC_TR_REG_UL_FILTER_CBK_BEGIN, rules, callback_func, callback_context);
+ return ipc_filter_reg_filter_by_ilm(UL_DIRECT, rules, &ntfy_ctxt);
+}
+
+kal_int32 ipc_register_dl_filter_cbk(ipc_filter_rules_t *rules,
+ ipc_filter_callback_t callback_func,
+ void *callback_context)
+{
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ ntfy_ctxt.ntfy_mod.cbk_func = callback_func;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_NIL;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ ntfy_ctxt.p_ntfy_args = callback_context;
+
+ hif_trace_info(IPC_TR_REG_DL_FILTER_CBK_BEGIN, rules, callback_func, callback_context);
+ return ipc_filter_reg_filter_by_ilm(DL_DIRECT, rules, &ntfy_ctxt);
+}
+
+kal_int32 ipc_register_ul_filter_msg(ipc_filter_rules_t *rules,
+ module_type callback_module,
+ void *callback_context)
+{
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_filter_fwd_ul_pkt_by_msg;
+ ntfy_ctxt.ntfy_mod.cbk_mod = callback_module;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM;
+ ntfy_ctxt.p_ntfy_args = callback_context;
+
+ hif_trace_info(IPC_TR_REG_UL_FILTER_MSG_BEGIN, rules, callback_module, callback_context);
+ return ipc_filter_reg_filter_by_ilm(UL_DIRECT, rules, &ntfy_ctxt);
+}
+
+kal_int32 ipc_register_dl_filter_msg(ipc_filter_rules_t *rules,
+ module_type callback_module,
+ void *callback_context)
+{
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_filter_fwd_ul_pkt_by_msg;
+ ntfy_ctxt.ntfy_mod.cbk_mod = callback_module;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM;
+ ntfy_ctxt.p_ntfy_args = callback_context;
+
+ hif_trace_info(IPC_TR_REG_DL_FILTER_MSG_BEGIN, rules, callback_module, callback_context);
+ return ipc_filter_reg_filter_by_ilm(DL_DIRECT, rules, &ntfy_ctxt);
+}
+
+kal_int32 ipc_register_ul_filter_with_info_cbk(ipc_filter_rules_t *rules,
+ ipc_filter_with_info_callback_t callback_func,
+ void *callback_context)
+{
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = callback_func;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_NIL;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ ntfy_ctxt.p_ntfy_args = callback_context;
+
+ hif_trace_info(IPC_TR_REG_UL_FILTER_WITH_INFO_CBK_BEGIN, rules, callback_func, callback_context);
+ return ipc_filter_reg_filter_by_ilm(UL_DIRECT, rules, &ntfy_ctxt);
+}
+
+kal_int32 ipc_register_dl_filter_with_info_cbk(ipc_filter_rules_t *rules,
+ ipc_filter_with_info_callback_t callback_func,
+ void *callback_context)
+{
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = callback_func;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_NIL;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ ntfy_ctxt.p_ntfy_args = callback_context;
+
+ hif_trace_info(IPC_TR_REG_DL_FILTER_WITH_INFO_CBK_BEGIN, rules, callback_func, callback_context);
+ return ipc_filter_reg_filter_by_ilm(DL_DIRECT, rules, &ntfy_ctxt);
+}
+
+kal_int32 ipc_register_ul_filter_with_info_msg(ipc_filter_rules_t *rules,
+ module_type callback_module,
+ void *callback_context)
+{
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_filter_fwd_ul_pkt_with_info_by_msg;
+ ntfy_ctxt.ntfy_mod.cbk_mod = callback_module;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO;
+ ntfy_ctxt.p_ntfy_args = callback_context;
+
+ hif_trace_info(IPC_TR_REG_UL_FILTER_WITH_INFO_MSG_BEGIN, rules, callback_module, callback_context);
+ return ipc_filter_reg_filter_by_ilm(UL_DIRECT, rules, &ntfy_ctxt);
+}
+
+kal_int32 ipc_register_dl_filter_with_info_msg(ipc_filter_rules_t *rules,
+ module_type callback_module,
+ void *callback_context)
+{
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_filter_fwd_ul_pkt_with_info_by_msg;
+ ntfy_ctxt.ntfy_mod.cbk_mod = callback_module;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO;
+ ntfy_ctxt.p_ntfy_args = callback_context;
+
+ hif_trace_info(IPC_TR_REG_DL_FILTER_WITH_INFO_MSG_BEGIN, rules, callback_module, callback_context);
+ return ipc_filter_reg_filter_by_ilm(DL_DIRECT, rules, &ntfy_ctxt);
+}
+
+void ipc_deregister_ul_filter(kal_int32 filter_id)
+{
+ hif_trace_info(IPC_TR_DEREG_UL_FILTER_BEGIN, filter_id);
+ ipc_filter_dereg_filter_by_ilm(filter_id);
+}
+
+void ipc_deregister_dl_filter(kal_int32 filter_id)
+{
+ hif_trace_info(IPC_TR_DEREG_DL_FILTER_BEGIN, filter_id);
+ ipc_filter_dereg_filter_by_ilm(filter_id);
+}
+
+kal_bool ipc_gpd_copy(kal_uint8 *dst_buffer,
+ kal_uint32 dst_max_len,
+ kal_uint32 *dst_len_copied,
+ qbm_gpd *src_head_gpd,
+ qbm_gpd *src_tail_gpd)
+{
+ kal_bool retval;
+
+ IPC_ASSERT(dst_buffer);
+ IPC_ASSERT(dst_len_copied);
+ IPC_ASSERT(src_head_gpd);
+ IPC_ASSERT(src_tail_gpd);
+
+ hif_trace_info(IPC_TR_GPD_COPY_BEGIN, dst_buffer, dst_max_len, dst_len_copied, src_head_gpd, src_tail_gpd);
+ retval = ipc_utils_gpd_copy(dst_buffer, dst_max_len, dst_len_copied, src_head_gpd, src_tail_gpd);
+ hif_trace_info(IPC_TR_GPD_COPY_END, retval, dst_max_len, *dst_len_copied);
+
+ return retval;
+}
+
+static INLINE kal_bool ipc_pack_pkt(kal_bool uplink,
+ ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ qbm_gpd **head_gpd,
+ qbm_gpd **tail_gpd)
+{
+ kal_bool fill_in_headroom = KAL_FALSE;
+
+ IPC_ASSERT(pkt);
+ IPC_ASSERT(head_gpd);
+ IPC_ASSERT(tail_gpd);
+
+ if (NULL == pkt) {
+ return KAL_FALSE;
+ }
+
+ if (KAL_TRUE == pkt->isGPD) {
+
+ hif_data_trace(MD_TRC_IPC_GE_HANDLE_GPD, 0, pkt->head, pkt->tail);
+
+ /* For GPD TX : Set GPD pointer */
+ *head_gpd = pkt->head;
+ *tail_gpd = pkt->tail;
+
+ /* Per-discussion with user (IMS), caller does NOT reserve IP/UDP header fields in GPD, and IP Core needs to fill them using headroom */
+ fill_in_headroom = KAL_TRUE;
+ } else {
+ /* For Buffer TX : Allocate single GPD and execute memory copy */
+ kal_uint32 ip_header_len = 0;
+ kal_uint32 udp_header_len = 0;
+ kal_uint32 total_len = 0;
+ kal_uint8 *ip_header = NULL;
+
+ /* Check total packet length */
+ if (hdr) {
+ /* Reserve for IP/UDP header fields if needed */
+ ip_header_len = ((IPC_IP_TYPE_IPV4 == hdr->ip_type) ? IPC_HDR_V4_HEADER_SIZE : IPC_HDR_V6_HEADER_SIZE);
+ udp_header_len = IPC_HDR_UDP_HEADER_SIZE;
+ } else {
+ ip_header_len = 0;
+ udp_header_len = 0;
+ }
+
+ total_len = ip_header_len + udp_header_len + pkt->data_len;
+ hif_data_trace(MD_TRC_IPC_GE_SET_ALLOC_DATA, pkt->data_len, pkt->data, ip_header_len, udp_header_len);
+
+ if (total_len > ((KAL_TRUE == uplink) ? ((kal_uint32) QBM_SIZE_NET_UL_SHRD) : ((kal_uint32) QBM_SIZE_NET_DL))) {
+ hif_trace_error(IPC_TR_PACK_PKT_UDP_SIZE_NG, uplink, ip_header_len, udp_header_len, pkt->data_len,
+ ((KAL_TRUE == uplink) ? QBM_SIZE_NET_UL_SHRD : QBM_SIZE_NET_DL));
+ return KAL_FALSE;
+ }
+
+ /* Allocate single GPD */
+ if (1 != qbmt_alloc_q_no_tail((KAL_TRUE == uplink) ? QBM_TYPE_NET_UL/*UL*/: QBM_TYPE_NET_DL/*DL*/,
+ 1,
+ (void**) head_gpd,
+ (void**) tail_gpd)) {
+ hif_trace_error(IPC_TR_PACK_PKT_ALLOC_GPD_NG, total_len);
+ return KAL_FALSE;
+ }
+
+ ipc_utils_set_gpd_datalen(*head_gpd, total_len, (void**) &ip_header);
+
+ /* IP/UDP header has reserved in payload field, no more headroom is needed in following header fill */
+ fill_in_headroom = KAL_FALSE;
+
+ /* Memory copy from data buffer to GPD */
+ kal_mem_cpy(ip_header + (ip_header_len + udp_header_len), pkt->data, pkt->data_len);
+ QBM_CACHE_FLUSH(ip_header + (ip_header_len + udp_header_len), pkt->data_len);
+
+ }
+
+ /* Fill header */
+ if (hdr) {
+ qbm_gpd *curr_gpd = NULL;
+ kal_bool end_of_gpd_list = KAL_FALSE;
+
+ /* Trace GPD list to configure UDP/IP headers one-by-one */
+ for (curr_gpd = *head_gpd; curr_gpd && (KAL_FALSE == end_of_gpd_list);
+ curr_gpd = (qbm_gpd *) QBM_DES_GET_NEXT(curr_gpd)) {
+
+ /* Fill IP/UDP header */
+ static kal_uint32 ip_v4_local_id_s = 0;
+ kal_uint16 sum16;
+ kal_uint32 ip_header_len;
+ kal_uint32 udp_header_len;
+ kal_uint32 total_len;
+ kal_uint8 *ip_header;
+ kal_uint8 *udp_header;
+
+ ip_header_len = (
+ (IPC_IP_TYPE_IPV4 == hdr->ip_type) ? IPC_HDR_V4_HEADER_SIZE : IPC_HDR_V6_HEADER_SIZE);
+ udp_header_len = IPC_HDR_UDP_HEADER_SIZE;
+
+ /* Push and get IP/UDP header pointers */
+ if (KAL_TRUE == fill_in_headroom) {
+ ipc_push_qbm_datahead(curr_gpd, ip_header_len + udp_header_len, &total_len, (void**) &ip_header);
+ } else {
+ ipc_get_qbm_datahead(curr_gpd, &total_len, (void**) &ip_header);
+ }
+
+ if (ip_header) {
+ udp_header = ip_header + ip_header_len;
+
+ hif_data_trace(MD_TRC_IPC_GE_FILL_HEADER, total_len, curr_gpd, ip_header_len, udp_header_len);
+ IPC_ASSERT(total_len >= (ip_header_len + udp_header_len));
+
+ /* Fill UDP header */
+ IPC_HDR_UDP_SET_SRC_PORT(udp_header, hdr->src_port);
+ IPC_HDR_UDP_SET_DST_PORT(udp_header, hdr->dst_port);
+ IPC_HDR_UDP_SET_LENGTH(udp_header, total_len - ip_header_len/* UDP length */);
+ IPC_HDR_UDP_SET_CHECKSUM(udp_header, 0);
+ sum16 = ipc_calc_udp_checksum(
+ (IPC_IP_TYPE_IPV4 == hdr->ip_type) ? KAL_TRUE : KAL_FALSE, hdr->src_addr, hdr->dst_addr, udp_header, total_len - ip_header_len/* UDP length */);
+ IPC_HDR_UDP_SET_CHECKSUM(udp_header, sum16);
+
+ if (IPC_IP_TYPE_IPV4 == hdr->ip_type) {
+ IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN(ip_header);
+ IPC_HDR_V4_SET_DSCP(ip_header, hdr->dscp_tc);
+ IPC_HDR_V4_SET_TOTAL_LENGTH(ip_header, total_len);
+ IPC_HDR_V4_SET_IDENTITY(ip_header, ip_v4_local_id_s);
+ ip_v4_local_id_s++;
+ IPC_HDR_V4_SET_FLAGS(ip_header, 0);
+ IPC_HDR_V4_SET_FRAG_OFFSET(ip_header, 0);
+ IPC_HDR_V4_SET_TTL(ip_header, IPC_DEF_TTL);
+ IPC_HDR_V4_SET_PROTOCOL(ip_header, IPC_HDR_PROT_UDP);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, 0);
+ IPC_HDR_V4_SET_SRC_ADDR(ip_header, hdr->src_addr);
+ IPC_HDR_V4_SET_DST_ADDR(ip_header, hdr->dst_addr);
+ sum16 = ipc_calc_ipv4_checksum(ip_header);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, sum16);
+ } else {
+ IPC_HDR_V6_RESET_VER_TC_FL(ip_header);
+ IPC_HDR_V6_SET_TC(ip_header, hdr->dscp_tc);
+ IPC_HDR_V6_SET_LENGTH(ip_header, total_len - ip_header_len/* UDP length */);
+ IPC_HDR_V6_SET_NH_TYPE(ip_header, IPC_HDR_PROT_UDP);
+ IPC_HDR_V6_SET_HOP_LIMIT(ip_header, IPC_DEF_TTL);
+ IPC_HDR_V6_SET_SRC_ADDR(ip_header, hdr->src_addr);
+ IPC_HDR_V6_SET_DST_ADDR(ip_header, hdr->dst_addr);
+ }
+
+ QBM_CACHE_FLUSH(ip_header, total_len);
+ } else {
+ hif_trace_error(IPC_TR_PACK_PKT_SKIP_INVALID_GPD, curr_gpd, QBM_DES_GET_DATALEN(curr_gpd));
+ }
+
+ /* Check if current GPD is last one or not */
+ end_of_gpd_list = (curr_gpd == (*tail_gpd)) ? KAL_TRUE : KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_pack_pkt_public(kal_bool uplink,
+ ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ qbm_gpd **head_gpd,
+ qbm_gpd **tail_gpd)
+{
+ hif_data_trace(MD_TRC_IPC_GE_PACK_PACKET_PUBLIC, 0);
+
+ if (KAL_FALSE == ipc_pack_pkt(uplink, pkt, hdr, head_gpd, tail_gpd)) {
+ hif_trace_error(IPC_TR_PACK_PKT_PUBLIC_FAILED, pkt->isGPD, hdr);
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_send_ul_pkt(ipc_pkt_t *pkt, ipc_hdr_t *hdr, kal_uint32 ebi)
+{
+ qbm_gpd *head_gpd = NULL;
+ qbm_gpd *tail_gpd = NULL;
+ ipc_internal_ior_t *ior = NULL;
+ kal_bool to_send_msg = KAL_FALSE;
+
+ if (NULL == pkt) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ if (KAL_FALSE == ipc_pack_pkt(KAL_TRUE, pkt, hdr, &head_gpd, &tail_gpd)) {
+ hif_trace_error(IPC_TR_UL_PKT_PKT_PACK_FAILED, pkt->isGPD, hdr);
+ return KAL_FALSE;
+ }
+
+ /*
+ * New throttling level needs to block latency-concern packets as well.
+ * Queue packets till throttling policy changes.
+ */
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT, ebi, head_gpd, tail_gpd);
+
+ ior = (ipc_internal_ior_t *)QBM_DES_GET_SW_CTRL_FIELD(head_gpd);
+ kal_mem_set(ior, 0, sizeof(ipc_internal_ior_t));
+ ior->io_req.next_request = NULL;
+ ior->io_req.first_gpd = head_gpd;
+ ior->io_req.last_gpd = tail_gpd;
+ ior->io_req.ip_type = 0xFF; //to distinquish from ipc_send_ul_pkt_by_pdn()
+ ior->io_req.data_path_type = IPC_INTERNAL_DATA_PATH; /*< to distinquish from normal data path */
+ ior->ebi = ebi;
+
+ ipc_push_ior_list_to_ior_queue((ipc_io_request_t *)ior, (ipc_io_request_t *)ior, 1, IPC_UL_QUEUE_PRIORITY_HIGH);
+
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = (!ipc_ul_processing_s);
+ ipc_ul_processing_s = KAL_TRUE;
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_send_ul_pkt_path_by_pdn(ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ kal_uint32 pdn,
+ kal_uint8 ip_type,
+ ipc_io_req_data_path_e data_path)
+{
+ qbm_gpd *head_gpd = NULL;
+ qbm_gpd *tail_gpd = NULL;
+ ipc_internal_ior_t *ior = NULL;
+ kal_bool to_send_msg = KAL_FALSE;
+ ipc_session_t *session;
+ ipc_netif_t *netif;
+
+ if (NULL == pkt || !((IPC_IP_TYPE_IPV4 == ip_type) || (IPC_IP_TYPE_IPV6 == ip_type))) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ if (KAL_FALSE == ipc_pack_pkt(KAL_TRUE, pkt, hdr, &head_gpd, &tail_gpd)) {
+ hif_trace_error(IPC_TR_UL_PKT_PKT_PACK_FAILED, pkt->isGPD, hdr);
+ return KAL_FALSE;
+ }
+
+ /*
+ * New throttling level needs to block latency-concern packets as well.
+ * Queue packets till throttling policy changes.
+ */
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_BY_PDN, pdn, ip_type, head_gpd, tail_gpd, head_gpd->data_len);
+
+ ior = (ipc_internal_ior_t *)QBM_DES_GET_SW_CTRL_FIELD(head_gpd);
+ kal_mem_set(ior, 0, sizeof(ipc_internal_ior_t));
+ ior->io_req.next_request = NULL;
+ ior->io_req.first_gpd = head_gpd;
+ ior->io_req.last_gpd = tail_gpd;
+ ior->io_req.ip_type = ip_type;
+ if (data_path == IPC_INTERNAL_DATA_PATH) {
+ ior->io_req.data_path_type = IPC_INTERNAL_DATA_PATH; /*< to distinquish from normal data path */
+ ior->pdn = pdn;
+ } else {
+ session = ipc_find_session_by_context(pdn);
+ if (session) {
+ netif = session->netif;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ ior->netif = netif;
+ } else {
+ /* Error case should not happen, bypass normal path filtering to drop directly */
+ ior->io_req.data_path_type = IPC_INTERNAL_DATA_PATH; /*< to distinquish from normal data path */
+ ior->pdn = pdn;
+ }
+ }
+
+ ipc_push_ior_list_to_ior_queue((ipc_io_request_t *)ior, (ipc_io_request_t *)ior, 1, IPC_UL_QUEUE_PRIORITY_HIGH);
+
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = (!ipc_ul_processing_s);
+ ipc_ul_processing_s = KAL_TRUE;
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_send_ul_pkt_by_pdn(ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ kal_uint32 pdn,
+ kal_uint8 ip_type)
+{
+ return ipc_send_ul_pkt_path_by_pdn(pkt, hdr, pdn, ip_type, IPC_INTERNAL_DATA_PATH);
+}
+
+kal_bool ipc_send_ul_pkt_by_netif_id(ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ kal_uint32 netif_id,
+ kal_uint8 ip_type)
+{
+ qbm_gpd *head_gpd = NULL;
+ qbm_gpd *tail_gpd = NULL;
+ ipc_netif_t *netif = NULL;
+ ipc_session_t *session = NULL;
+ ipc_internal_ior_t *ior = NULL;
+ kal_bool to_send_msg = KAL_FALSE;
+
+ if (NULL == pkt || !((IPC_IP_TYPE_IPV4 == ip_type) || (IPC_IP_TYPE_IPV6 == ip_type) || (IPC_IP_TYPE_MIXED == ip_type))) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ if (KAL_FALSE == ipc_pack_pkt(KAL_TRUE, pkt, hdr, &head_gpd, &tail_gpd)) {
+ hif_trace_error(IPC_TR_UL_PKT_BY_NETIF_ID_PKT_PACK_FAILED, pkt->isGPD, hdr);
+ return KAL_FALSE;
+ }
+
+ /*
+ * New throttling level needs to block latency-concern packets as well.
+ * Queue packets till throttling policy changes.
+ */
+
+ netif = ipc_find_netif(netif_id);
+ if (netif) {
+ session = ipc_find_session_by_netif(netif, ip_type);
+ if (session) {
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_BY_NETIF_ID, netif_id, ip_type, head_gpd, tail_gpd, head_gpd->data_len);
+
+ ior = (ipc_internal_ior_t *)QBM_DES_GET_SW_CTRL_FIELD(head_gpd);
+ kal_mem_set(ior, 0, sizeof(ipc_internal_ior_t));
+ ior->io_req.next_request = NULL;
+ ior->io_req.first_gpd = head_gpd;
+ ior->io_req.last_gpd = tail_gpd;
+ ior->io_req.ip_type = ip_type;
+ ior->io_req.data_path_type = IPC_INTERNAL_DATA_PATH; /*< to distinquish from normal data path */
+ ior->pdn = session->context;
+
+ ipc_push_ior_list_to_ior_queue((ipc_io_request_t *)ior, (ipc_io_request_t *)ior, 1, IPC_UL_QUEUE_PRIORITY_HIGH);
+
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = (!ipc_ul_processing_s);
+ ipc_ul_processing_s = KAL_TRUE;
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_UL_PKT_BY_NETIF_ID_SESSION_NOT_FOUND, netif_id, ip_type);
+ qbmt_dest_q(head_gpd, tail_gpd);
+ }
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_UL_PKT_BY_NETIF_ID_NETIF_NOT_FOUND, netif_id);
+ qbmt_dest_q(head_gpd, tail_gpd);
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_send_ul_pkt_multiple_ps(ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ kal_uint32 ebi,
+ kal_uint8 proto_idx)
+{
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_MULTI_PS, ebi, proto_idx);
+
+ if (NULL == pkt) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ if ((0 != IPC_CHECK_EBI(ebi)) ||
+ (0 != IPC_CHECK_PROTOID(proto_idx))) {
+ hif_trace_error(IPC_TR_INVALID_PDN_PROTO_IDX, __FUNCTION__, ebi, proto_idx);
+ return KAL_FALSE;
+ }
+
+ IPC_MASK_PROTOID_ON_PDNID(ebi, proto_idx);
+
+ return ipc_send_ul_pkt(pkt, hdr, ebi);
+}
+
+kal_bool ipc_send_ul_pkt_on_normal_path_by_pdn_multiple_ps(ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ kal_uint32 pdn,
+ kal_uint8 ip_type,
+ kal_uint8 proto_idx)
+{
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_BY_PDN_MULTI_PS, pdn, proto_idx);
+
+ if (NULL == pkt) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ if ((0 != IPC_CHECK_PDNID(pdn)) ||
+ (0 != IPC_CHECK_PROTOID(proto_idx))) {
+ hif_trace_error(IPC_TR_INVALID_PDN_PROTO_IDX, __FUNCTION__, pdn, proto_idx);
+ return KAL_FALSE;
+ }
+
+ IPC_MASK_PROTOID_ON_PDNID(pdn, proto_idx);
+
+ return ipc_send_ul_pkt_path_by_pdn(pkt, hdr, pdn, ip_type, IPC_NORMAL_DATA_PATH);
+}
+
+kal_bool ipc_send_ul_pkt_by_pdn_multiple_ps(ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ kal_uint32 pdn,
+ kal_uint8 ip_type,
+ kal_uint8 proto_idx)
+{
+ hif_data_trace(MD_TRC_IPC_UL_SEND_PKT_BY_PDN_MULTI_PS, pdn, proto_idx);
+
+ if (NULL == pkt) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ if ((0 != IPC_CHECK_PDNID(pdn)) ||
+ (0 != IPC_CHECK_PROTOID(proto_idx))) {
+ hif_trace_error(IPC_TR_INVALID_PDN_PROTO_IDX, __FUNCTION__, pdn, proto_idx);
+ return KAL_FALSE;
+ }
+
+ IPC_MASK_PROTOID_ON_PDNID(pdn, proto_idx);
+
+ return ipc_send_ul_pkt_by_pdn(pkt, hdr, pdn, ip_type);
+}
+
+kal_bool ipc_send_dl_pkt_enqueue(qbm_gpd *pkt, kal_uint32 netif_id, kal_uint32 session_type)
+{
+ ipc_dlq_ior_t *ior = NULL;
+
+ if (pkt == NULL) {
+ return KAL_FALSE;
+ }
+ ior = (ipc_dlq_ior_t*)QBM_DES_GET_SW_CTRL_FIELD(pkt);
+ memset(ior, 0, sizeof(ipc_dlq_ior_t));
+ ior->session_type = session_type;
+
+ if (session_type >= IPC_IP_TYPE_INVALID) {
+ return KAL_FALSE;
+ }
+
+ if (0 != (netif_id & 0xFFFF0000)) {
+ hif_trace_error(IPC_TR_INVALID_NETIF, __FUNCTION__, netif_id);
+ return KAL_FALSE;
+ }
+ ior->netif_id = netif_id;
+
+ ipc_on_downlink_qbm_enqueue(pkt, pkt);
+ return KAL_TRUE;
+}
+
+kal_bool ipc_send_dl_pkt(ipc_pkt_t *pkt, ipc_hdr_t *hdr, kal_uint32 netif_id)
+{
+ ipc_netif_t *netif = NULL;
+ qbm_gpd *head_gpd = NULL;
+ qbm_gpd *tail_gpd = NULL;
+ qbm_gpd *ipv4_first_gpd = NULL;
+ qbm_gpd *ipv4_last_gpd = NULL;
+ qbm_gpd *ipv6_first_gpd = NULL;
+ qbm_gpd *ipv6_last_gpd = NULL;
+
+ if (NULL == pkt) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ /* Packet and Clarify IPv4/IPv6 GPDs */
+ if (KAL_FALSE == ipc_pack_pkt(KAL_FALSE, pkt, hdr, &head_gpd, &tail_gpd)) {
+ hif_trace_error(IPC_TR_DL_PKT_PKT_PACK_FAILED, pkt->isGPD, hdr);
+
+ if (KAL_TRUE == pkt->isGPD) {
+ qbmt_dest_q(pkt->head, pkt->tail);
+ }
+
+ return KAL_FALSE;
+ }
+
+ ipc_utils_clarify_gpd(head_gpd, tail_gpd, &ipv4_first_gpd, &ipv4_last_gpd, &ipv6_first_gpd, &ipv6_last_gpd);
+
+ netif = ipc_find_netif(netif_id);
+ if (netif) {
+ ipc_io_request_t *ior;
+
+ hif_data_trace(MD_TRC_IPC_DL_SEND_IPV4_PKT, 0, netif->config.netif_id, ipv4_first_gpd, ipv4_last_gpd);
+
+ /* Sent to corresponding network interface */
+ if (ipv4_first_gpd) {
+ ior = (ipc_io_request_t *) QBM_DES_GET_SW_CTRL_FIELD(ipv4_first_gpd);
+ ior->next_request = NULL;
+ ior->first_gpd = ipv4_first_gpd;
+ ior->last_gpd = ipv4_last_gpd;
+ ior->ip_type = IPC_IP_TYPE_IPV4;
+ ior->qos_priority = 0;
+
+ netif->config.ipc_dlink_callback_t(netif->config.callback_context, ior);
+ }
+
+ hif_data_trace(MD_TRC_IPC_DL_SEND_IPV6_PKT, 0, netif->config.netif_id, ipv6_first_gpd, ipv6_last_gpd);
+
+ if (ipv6_first_gpd) {
+ ior = (ipc_io_request_t *) QBM_DES_GET_SW_CTRL_FIELD(ipv6_first_gpd);
+ ior->next_request = NULL;
+ ior->first_gpd = ipv6_first_gpd;
+ ior->last_gpd = ipv6_last_gpd;
+ ior->ip_type = IPC_IP_TYPE_IPV6;
+ ior->qos_priority = 0;
+
+ netif->config.ipc_dlink_callback_t(netif->config.callback_context, ior);
+ }
+
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ return KAL_TRUE;
+ }
+
+ hif_trace_error(IPC_TR_DL_PKT_NETIF_NOT_FOUND, netif_id);
+ IPC_UT_ASSERT(KAL_FALSE, IPC_UT_DL_PKT_NETIF_NOT_FOUND);
+
+ if (ipv4_first_gpd) {
+ qbmt_dest_q(ipv4_first_gpd, ipv4_last_gpd);
+ }
+ if (ipv6_first_gpd) {
+ qbmt_dest_q(ipv6_first_gpd, ipv6_last_gpd);
+ }
+
+ /* Network interface is not found */
+ return KAL_FALSE;
+}
+
+kal_int32 ipc_register_ntfy(ipc_ntfy_callback_t callback_func,
+ void *callback_context)
+{
+ kal_int32 ntfy_id = 0;
+
+ hif_trace_info(IPC_TR_REG_NTFY_BEGIN, callback_func, callback_context);
+ ntfy_id = ipc_ntfy_new_cbk(callback_func, callback_context);
+ hif_trace_info(IPC_TR_REG_NTFY_END, ntfy_id);
+
+ return ntfy_id;
+}
+
+void ipc_deregister_ntfy(kal_int32 ntfy_id)
+{
+ hif_trace_info(IPC_TR_DEREG_NTFY_BEGIN, ntfy_id);
+ ipc_ntfy_del_cbk(ntfy_id);
+ hif_trace_info(IPC_TR_DEREG_NTFY_END, ntfy_id);
+}
+
+kal_bool ipc_register_link_up_ind_handler(module_type module_id)
+{
+ hif_trace_info(IPC_TR_REG_LINK_UP_IND_HDLR_BEGIN, module_id);
+ ipc_update_link_up_ind_handler(module_id);
+ hif_trace_info(IPC_TR_REG_LINK_UP_IND_HDLR_END, module_id);
+ return KAL_TRUE;
+}
+
+void ipc_deregister_link_up_ind_handler(void)
+{
+ hif_trace_info(IPC_TR_DEREG_LINK_UP_IND_HDLR_BEGIN);
+ ipc_update_link_up_ind_handler(MOD_IPCORE);
+ hif_trace_info(IPC_TR_DEREG_LINK_UP_IND_HDLR_END);
+}
+
+kal_bool ipc_register_ip_up_ind_handler(module_type module_id)
+{
+ hif_trace_info(IPC_TR_REG_IP_UP_IND_HDLR_BEGIN, module_id);
+ ipc_update_ip_up_ind_handler(module_id);
+ hif_trace_info(IPC_TR_REG_IP_UP_IND_HDLR_END, module_id);
+ return KAL_TRUE;
+}
+
+void ipc_deregister_ip_up_ind_handler(void)
+{
+ hif_trace_info(IPC_TR_DEREG_IP_UP_IND_HDLR_BEGIN);
+ ipc_update_ip_up_ind_handler(MOD_IPCORE);
+ hif_trace_info(IPC_TR_DEREG_IP_UP_IND_HDLR_END);
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions. (Gen93)
+ *----------------------------------------------------------------------------*/
+kal_bool ipc_meta_uplink(kal_uint16 start_idx, kal_uint16 end_idx, LHIF_QUEUE_TYPE queue_type)
+{
+ kal_bool to_send_msg = KAL_FALSE;
+
+ HIF_SWLA_START("IU1");
+ hif_data_trace(MD_TRC_IPC_UL_META_UPLINK_CALLBACK, start_idx, end_idx, queue_type);
+
+ ipc_push_meta_list_to_meta_queue(start_idx, end_idx, queue_type);
+
+ IPC_SPIN_LOCK(g_ul_spinlock);
+ to_send_msg = (!ipc_ul_processing_s);
+ ipc_ul_processing_s = KAL_TRUE;
+ IPC_SPIN_UNLOCK(g_ul_spinlock);
+
+ /* Switch to IPCORE context. */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+
+ HIF_SWLA_STOP("IU1");
+ return KAL_TRUE;
+}
+
+kal_bool ipc_find_pdn_id_by_netif_id(kal_uint32 netif_id, kal_uint8 ip_type, kal_uint32 *p_pdn_id, kal_uint8 *p_proto_idx)
+{
+ ipc_netif_t *netif;
+ ipc_session_t *session;
+ kal_bool ret = KAL_FALSE;
+
+ if ((NULL == p_pdn_id) || (NULL == p_proto_idx)) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ netif = ipc_find_netif(netif_id);
+ if (netif) {
+ session = ipc_find_session_by_netif(netif, ip_type);
+ if (session) {
+ *p_pdn_id = session->context;
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(*p_pdn_id, *p_proto_idx);
+ IPC_UNMASK_PROTOID_FROM_PDNID(*p_pdn_id);
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ ret = KAL_TRUE;
+ } else {
+ hif_trace_error(IPC_TR_FIND_PDN_BY_NETIF_SESSION_RLOCK_FAILED, netif_id, ip_type);
+ }
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_FIND_PDN_BY_NETIF_NETIF_RLOCK_FAILED, netif_id, ip_type);
+ }
+
+ return ret;
+}
+
+kal_bool ipc_send_dl_pkt_in_did_internal(ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ kal_uint32 netif_id)
+{
+ ipc_netif_t *netif = NULL;
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+ upcm_did *did = NULL;
+ upcm_did *retry_prev_did = NULL;
+ upcm_did *next_did = NULL;
+ upcm_did *retry_did = NULL;
+ kal_bool end_of_list = KAL_FALSE;
+ kal_bool dl_cbk_ret = KAL_FALSE;
+
+ if (NULL == pkt) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ if (0 != (netif_id & 0xFFFF0000)) {
+ hif_trace_error(IPC_TR_INVALID_NETIF, __FUNCTION__, netif_id);
+ return KAL_FALSE;
+ }
+
+ if (IPC_PKT_DES_TYPE_DID == pkt->buf_type) {
+ did_head = pkt->did_head;
+ did_tail = pkt->did_tail;
+ } else if (IPC_PKT_DES_TYPE_GPD == pkt->buf_type || IPC_PKT_DES_TYPE_NO_DESC == pkt->buf_type) {
+ ipc_si_hif_type_e hif_type = ipc_utils_get_hif_type_by_netif_id(netif_id);
+
+ /* Copy GPD list to DID/SIT + PRB format */
+ did = upcm_did_alloc_one();
+ if (!did) {
+ hif_trace_error(IPC_TR_DL_PKT_NETIF_DID_ALLOC_DID_NG, pkt->head, pkt->tail, netif_id);
+ return KAL_FALSE;
+ }
+
+ if (IPC_PKT_DES_TYPE_GPD == pkt->buf_type) {
+ if (KAL_TRUE != ipc_utils_cpy_gpd_to_did(pkt->head, pkt->tail, did, hif_type)) {
+ upcm_did_free_one(did);
+ return KAL_FALSE;
+ }
+
+ hif_data_trace(MD_TRC_IPC_DL_TRANS_GPD_TO_DID, pkt->head, did_head, did_tail);
+
+ /* Free the original GPD list */
+ qbmt_dest_q(pkt->head, pkt->tail);
+ } else {
+ /* IPC_PKT_DES_TYPE_NO_DESC == pkt->buf_type */
+ upcm_did_si *sit = UPCM_DID_GET_SIT_PTR(did);
+ upcm_did_si *si_ptr = &sit[0];
+
+ kal_mem_set(si_ptr, 0, sizeof(upcm_did_si));
+ UPCM_DID_SI_SET_EOL(si_ptr);
+ UPCM_DID_SI_SET_F(si_ptr);
+ UPCM_DID_SI_SET_LEN(si_ptr, pkt->data_len);
+ UPCM_DID_SI_SET_DATAPTR(si_ptr, pkt->data);
+ UPCM_DID_SI_SET_HIF_TYPE(si_ptr, hif_type);
+
+ UPCM_DID_SET_PKT_NUM(did, 1);
+ UPCM_DID_SET_SEG_NUM(did, 1);
+ }
+
+ did_head = did;
+ did_tail = did;
+ } else {
+ hif_trace_error(IPC_TR_INVALID_DESCRIPTOR, __FUNCTION__, pkt->buf_type);
+ return KAL_FALSE;
+ }
+
+ netif = ipc_find_netif(netif_id);
+ if (netif) {
+ end_of_list = KAL_FALSE;
+ for (did = did_head; did && !end_of_list; did = next_did) {
+ next_did = UPCM_DID_GET_NEXT(did);
+ end_of_list = (did == did_tail);
+
+ if (!retry_did) {
+ HIF_SWLA_START("ID3");
+
+ hif_data_trace(MD_TRC_IPC_DL_SEND_PKT_DID, netif_id, did, UPCM_DID_GET_PKT_NUM(did));
+ dl_cbk_ret = netif->config.ipc_dlink_did_cb_t(netif->config.callback_context, did);
+
+ HIF_SWLA_STOP("ID3");
+
+ if (!dl_cbk_ret) {
+ retry_did = did;
+ UPCM_DID_SET_SW_CTRL_FIELD(did, (kal_uint16)(netif_id & 0x0000FFFF));
+ } else {
+ retry_prev_did = did;
+ }
+ } else {
+ UPCM_DID_SET_SW_CTRL_FIELD(did, (kal_uint16)(netif_id & 0x0000FFFF));
+ }
+ }
+
+ if (retry_did) {
+ kal_bool to_send_msg;
+
+ hif_data_trace(MD_TRC_IPC_DL_SEND_PKT_DID_PENDING, retry_did, did_tail);
+
+ if (retry_did != did_head) {
+ /* Free DID which have been sent */
+ if (retry_prev_did) {
+ IPC_ASSERT(UPCM_DID_GET_NEXT(retry_prev_did) == retry_did);
+ UPCM_DID_SET_NEXT(retry_prev_did, NULL);
+ }
+ upcm_did_dest_q(did_head, retry_prev_did);
+ }
+
+ /* Enqueue all remaining DID, We have to protect IPC_DL_NON_PDN_QUEUE_IDX queue, it may enq by other context */
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ ipc_did_enqueue_wo_filter_queue(retry_did, did_tail, IPC_DL_NON_PDN_QUEUE_IDX, IPC_DATA_DID_HEAD);
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ /* Send ILM to IPCore for processing DL queue */
+ to_send_msg = ipc_data_check_and_set_dl_ilm_flag();
+
+ /*
+ * Switch to IPCORE context.
+ */
+ if (to_send_msg) {
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_DATAPATH_SAP, /* sap_id */
+ MSG_ID_IPCORE_PROCESS_DL_QUEUE_REQ, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+ } else {
+ upcm_did_dest_q(did_head, did_tail);
+ }
+
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ return KAL_TRUE;
+ } else {
+ hif_trace_error(IPC_TR_DL_PKT_NETIF_DID_NOT_FOUND, netif_id, did_head, did_tail);
+ upcm_did_dest_q_free_buf(did_head, did_tail);
+ }
+
+ return KAL_FALSE;
+}
+
+kal_bool ipc_send_dl_pkt_in_did(ipc_pkt_t *pkt,
+ ipc_hdr_t *hdr,
+ kal_uint32 netif_id)
+{
+ ipc_si_hif_type_e hif_type = ipc_utils_get_hif_type_by_netif_id(netif_id);
+
+ IPC_ASSERT(pkt);
+
+ if (IPC_PKT_DES_TYPE_DID == pkt->buf_type) {
+ ipc_utils_pkt_dump_did(pkt->did_head, pkt->did_tail, hif_type);
+ } else if (IPC_PKT_DES_TYPE_GPD == pkt->buf_type) {
+ ipc_utils_pkt_dump_buff_gpd_list(pkt->head, pkt->tail, KAL_FALSE);
+ } else {
+ IPC_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ return ipc_send_dl_pkt_in_did_internal(pkt, hdr, netif_id);
+}
+
+kal_bool ipc_query_pdn_by_netif(kal_uint32 netif_id,
+ kal_uint8 ip_type,
+ kal_int32 *pdn_id)
+{
+ ipc_netif_t *netif = NULL;
+ kal_bool ret = KAL_FALSE;
+
+ if (NULL == pdn_id) {
+ hif_trace_error(IPC_TR_INVALID_ARGS, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ netif = ipc_find_netif(netif_id);
+
+ if (netif) {
+ *pdn_id = ipc_map_netif_to_pdn_id(netif, ip_type);
+ if (IPC_INVALID_PDN_ID != *pdn_id) {
+ ret = KAL_TRUE;
+ }
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+
+ return ret;
+}
+
+#if defined(__MD97__)
+kal_bool ipc_send_dl_did_by_ch_id(kal_uint8 net_type, kal_uint8 ch_id, upcm_did *p_did_head, upcm_did *p_did_tail)
+{
+ kal_uint32 netif_id = 0;
+
+ if ((NULL == p_did_head) || (NULL == p_did_tail)) {
+ hif_trace_error(IPC_TR_INVALID_INPUT_DID, __FUNCTION__);
+ return KAL_FALSE;
+ }
+
+ netif_id = ipc_get_netif_id_from_meta(net_type, ch_id);
+ if (IPC_INVALID_NETIF_ID == netif_id) {
+ hif_trace_error(IPC_TR_INVALID_NETIF_ID, __FUNCTION__, net_type, ch_id);
+ return KAL_FALSE;
+ }
+
+ ipc_data_dl_enq_by_netif(netif_id, p_did_head, p_did_tail);
+ return KAL_TRUE;
+}
+#endif
+
+kal_int32 ipc_reg_filter(ipc_data_path_direction_e data_path_direct,
+ ipc_filter_rules_t *p_rules,
+ ipc_filter_ntfy_ctxt_t *p_ntfy_ctxt)
+{
+ kal_int32 filter_id = 0;
+
+ if (DL_DIRECT != data_path_direct && UL_DIRECT != data_path_direct) {
+ hif_trace_error(IPC_TR_INVALID_DATA_PATH_DIR, __FUNCTION__, data_path_direct);
+ return IPC_INVALID_FILTER_ID;
+ }
+
+ if (NULL == p_rules) {
+ hif_trace_error(IPC_TR_INVALID_FILTER_RULES, __FUNCTION__);
+ return IPC_INVALID_FILTER_ID;
+ }
+
+ if (NULL == p_ntfy_ctxt) {
+ hif_trace_error(IPC_TR_INVALID_FILTER_CTXT, __FUNCTION__);
+ return IPC_INVALID_FILTER_ID;
+ }
+
+ switch (p_ntfy_ctxt->ntfy_type) {
+ case IPC_FILTER_NTFY_CBK_FUNC :
+ p_ntfy_ctxt->ntfy_mod.cbk_mod = MOD_NIL;
+ break;
+ case IPC_FILTER_NTFY_ILM :
+ if (DL_DIRECT == data_path_direct) {
+ p_ntfy_ctxt->ntfy_mod.cbk_func = ipc_filter_fwd_dl_pkt_by_msg;
+ } else {
+ p_ntfy_ctxt->ntfy_mod.cbk_func = ipc_filter_fwd_ul_pkt_by_msg;
+ }
+ break;
+ case IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO :
+ p_ntfy_ctxt->ntfy_mod.cbk_mod = MOD_NIL;
+ break;
+ case IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO :
+ if (DL_DIRECT == data_path_direct) {
+ p_ntfy_ctxt->ntfy_mod.with_info_cbk_func = ipc_filter_fwd_dl_pkt_with_info_by_msg;
+ } else {
+ p_ntfy_ctxt->ntfy_mod.with_info_cbk_func = ipc_filter_fwd_ul_pkt_with_info_by_msg;
+ }
+ break;
+ default :
+ hif_trace_error(IPC_TR_INVALID_FILTER_NTFY_TYPE, __FUNCTION__, p_ntfy_ctxt->ntfy_type);
+ return IPC_INVALID_FILTER_ID;
+ }
+ filter_id = ipc_filter_reg_filter_by_ilm(data_path_direct, p_rules, p_ntfy_ctxt);
+
+ hif_trace_info(IPC_TR_REGISTER_FILTER, __FUNCTION__, data_path_direct, p_ntfy_ctxt->ntfy_type, filter_id);
+ return filter_id;
+}
+
+kal_bool ipc_dereg_filter(kal_int32 filter_id)
+{
+ hif_trace_info(IPC_TR_DEGISTER_FILTER, __FUNCTION__, filter_id);
+ return ipc_filter_dereg_filter_by_ilm(filter_id);
+}
+
+kal_bool ipc_get_data_usage_by_netif_id(kal_uint32 netif_id, ipc_data_usage_info_t *data_usage)
+{
+ IPC_ASSERT(data_usage);
+ ipc_data_usage_info_t *ipv4_data_usage = NULL, *ipv6_data_usage = NULL;
+ kal_uint32 ipv4_pdn_id, ipv6_pdn_id;
+ ipc_netif_t *netif = NULL;
+
+ netif = ipc_find_netif(netif_id);
+ if (netif) {
+ ipc_get_pdn_id_from_netif(&ipv4_pdn_id, &ipv6_pdn_id, netif);
+ } else {
+ hif_trace_error(IPC_TR_INVALID_NETIF, __FUNCTION__, netif_id);
+ return KAL_FALSE;
+ }
+
+ if ((ipv4_pdn_id == ipv6_pdn_id) && (ipv4_pdn_id != IPC_INVALID_PDN_ID)) {
+ kal_uint32 ipv4v6_pdn_id = ipv4_pdn_id;
+ ipc_data_usage_info_t *ipv4v6_data_usage = ipc_get_data_usage_by_pdn_sim_id(ipv4v6_pdn_id);
+ memcpy(data_usage, ipv4v6_data_usage, sizeof(ipc_data_usage_info_t));
+ } else if ((ipv4_pdn_id != IPC_INVALID_PDN_ID) && (ipv6_pdn_id == IPC_INVALID_PDN_ID)) {
+ ipv4_data_usage = ipc_get_data_usage_by_pdn_sim_id(ipv4_pdn_id);
+ memcpy(data_usage, ipv4_data_usage, sizeof(ipc_data_usage_info_t));
+ } else if ((ipv4_pdn_id == IPC_INVALID_PDN_ID) && (ipv6_pdn_id != IPC_INVALID_PDN_ID)) {
+ ipv6_data_usage = ipc_get_data_usage_by_pdn_sim_id(ipv6_pdn_id);
+ memcpy(data_usage, ipv6_data_usage, sizeof(ipc_data_usage_info_t));
+ } else if (ipv4_pdn_id != ipv6_pdn_id) {
+ ipv4_data_usage = ipc_get_data_usage_by_pdn_sim_id(ipv4_pdn_id);
+ ipv6_data_usage = ipc_get_data_usage_by_pdn_sim_id(ipv6_pdn_id);
+ data_usage->uplink_bytes = ipv4_data_usage->uplink_bytes + ipv6_data_usage->uplink_bytes;
+ data_usage->downlink_bytes = ipv4_data_usage->downlink_bytes + ipv6_data_usage->downlink_bytes;
+ data_usage->uplink_packets = ipv4_data_usage->uplink_packets + ipv6_data_usage->uplink_packets;
+ data_usage->downlink_packets = ipv4_data_usage->downlink_packets + ipv6_data_usage->downlink_packets;
+ } else {
+ /*invalid ipv4 and ipv6 pdn id*/
+ hif_trace_info(IPC_TR_INVALID_PDN_ID, __FUNCTION__);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ return KAL_FALSE;
+ }
+
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ return KAL_TRUE;
+}
+
+kal_bool ipc_get_data_usage_by_pdn_id(kal_uint32 pdn_id, kal_uint8 proto_idx, ipc_data_usage_info_t *data_usage)
+{
+ IPC_ASSERT(data_usage);
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, proto_idx);
+
+ ipc_data_usage_info_t *get_data_usage = ipc_get_data_usage_by_pdn_sim_id(pdn_id);
+
+ if (get_data_usage) {
+ data_usage->uplink_bytes = get_data_usage->uplink_bytes;
+ data_usage->downlink_bytes = get_data_usage->downlink_bytes;
+ return KAL_TRUE;
+ }
+
+ return KAL_FALSE;
+}
+
+#ifdef __DISPATCHER_SUPPORT__
+void ipc_reg_cbk_dlvr_dl_did(dispatcher_dlvr_dl_did_f pf_dlvr_did)
+{
+ /* registered both cbk function when IPC_PEER was dispatcher */
+ upcm_reg_cbk_dlvr_dl_sdu(pf_dlvr_did);
+ dispatcher_reg_cbk_dlvr_dl_did(pf_dlvr_did);
+}
+#endif
diff --git a/mcu/middleware/hif/ipcore/src/ipc_module_clean.c b/mcu/middleware/hif/ipcore/src/ipc_module_clean.c
new file mode 100644
index 0000000..98c60f7
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_module_clean.c
@@ -0,0 +1,16 @@
+/*
+ * ipc_module_clean.c
+ *
+ * Created on: 2018/10/24
+ * Author: MTK15439
+ */
+
+
+#include "ipc_defs.h"
+
+void ipc_module_clean(void)
+{
+#if defined(__SENSITIVE_DATA_MOSAIC__)
+ ipc_clean_private_data();
+#endif
+}
diff --git a/mcu/middleware/hif/ipcore/src/ipc_notify.c b/mcu/middleware/hif/ipcore/src/ipc_notify.c
new file mode 100644
index 0000000..df9ae02
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_notify.c
@@ -0,0 +1,335 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_notify.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IPCore notification.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "ipc_defs.h"
+#include "ipc_debug.h"
+#include "ipc_notify.h"
+#include "ipc_object.h"
+
+#define IPC_NTFY_MAX_NUM 4
+
+typedef struct _ipc_ntfy_t {
+ IPC_DECLARE_OBJECT
+ kal_int32 ntfy_id;
+ ipc_ntfy_callback_t cbk_func;
+ void *p_cbk_args;
+} ipc_ntfy_t;
+
+typedef struct _ipc_ntfy_list_t {
+ IPC_DECLARE_OBJECT
+ kal_uint32 cnt;
+ ipc_ntfy_t *p_ntfy[IPC_NTFY_MAX_NUM];
+} ipc_ntfy_list_t;
+
+static ipc_ntfy_t g_ipc_ntfy_pool[IPC_NTFY_MAX_NUM];
+static ipc_ntfy_list_t g_ipc_ntfy_list[1];
+
+static ipc_ntfy_t *ipc_ntfy_alloc_entry(ipc_ntfy_t *p_ntfy_pool,
+ kal_uint32 pool_size,
+ ipc_ntfy_callback_t cbk_func,
+ void *p_cbk_args)
+{
+ ipc_ntfy_t *p_ntfy = NULL;
+ kal_uint32 idx = 0;
+
+ if (NULL == cbk_func) {
+ hif_trace_error(IPC_TR_ALLOCATE_NTFY_INVALID_PARAMS, cbk_func, p_cbk_args);
+ return NULL;
+ }
+
+ for (idx = 0; idx < pool_size; idx++) {
+ p_ntfy = p_ntfy_pool + idx;
+
+ if (!IPC_IS_VALID_OBJECT(p_ntfy)) {
+ IPC_INIT_OBJECT_BEGIN(p_ntfy, ipc_spinlock_g);
+
+ p_ntfy->ntfy_id = idx;
+ p_ntfy->cbk_func = cbk_func;
+ p_ntfy->p_cbk_args = p_cbk_args;
+
+ IPC_INIT_OBJECT_END(p_ntfy, ipc_spinlock_g);
+ return p_ntfy;
+ }
+ }
+
+ hif_trace_error(IPC_TR_ALLOCATE_NTFY_UNAVAILABLE, cbk_func, p_cbk_args);
+ return NULL;
+}
+
+static void ipc_ntfy_del_entry(ipc_ntfy_t *p_ntfy)
+{
+ IPC_DEINIT_OBJECT_BEGIN(p_ntfy, ipc_spinlock_g);
+ if (p_ntfy) {
+ IPC_DEINIT_OBJECT_END(p_ntfy, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_FREE_NTFY_INVALID_OBJECT);
+ }
+}
+
+static ipc_ntfy_t *ipc_ntfy_get_entry(ipc_ntfy_t *p_ntfy_pool, kal_int32 ntfy_id)
+{
+ ASSERT((0 <= ntfy_id) && (IPC_NTFY_MAX_NUM > ntfy_id));
+
+ return (p_ntfy_pool + ntfy_id);
+}
+
+static void ipc_ntfy_add_to_list(ipc_ntfy_list_t *p_list, ipc_ntfy_t *p_ntfy)
+{
+ IPC_W_LOCK_OBJECT(p_list, ipc_spinlock_g);
+ if (p_list) {
+ p_list->p_ntfy[p_list->cnt] = p_ntfy;
+ p_list->cnt++;
+ IPC_W_UNLOCK_OBJECT(p_list, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_ADD_NTFY_TO_LIST_INVALID_LIST, p_list);
+ IPC_ASSERT(KAL_FALSE);
+ }
+}
+
+static void ipc_ntfy_rm_from_list(ipc_ntfy_list_t *p_list, ipc_ntfy_t *p_ntfy)
+{
+ kal_uint32 idx1 = 0;
+ kal_uint32 idx2 = 0;
+
+ IPC_W_LOCK_OBJECT(p_list, ipc_spinlock_g);
+ if (p_list) {
+ for (idx1 = 0; idx1 < p_list->cnt; idx1++) {
+ if (p_list->p_ntfy[idx1] == p_ntfy) {
+ for (idx2 = idx1; idx2 < p_list->cnt - 1; idx2++) {
+ p_list->p_ntfy[idx2] = p_list->p_ntfy[idx2 + 1];
+ }
+
+ p_list->p_ntfy[idx2] = NULL;
+ p_list->cnt--;
+ break;
+ }
+ }
+
+ IPC_W_UNLOCK_OBJECT(p_list, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_REMOVE_NTFY_FROM_LIST_INVALID_LIST, p_list);
+ IPC_ASSERT(KAL_FALSE);
+ }
+}
+
+void ipc_ntfy_init(void)
+{
+ kal_uint32 idx = 0;
+ static ipc_ntfy_list_t *nls_set[] = {g_ipc_ntfy_list};
+
+#if defined(__MTK_TARGET__)
+ IPC_ASSERT(0 == sizeof(ipc_ntfy_t) % 4);
+ IPC_ASSERT(0 == sizeof(ipc_ntfy_list_t) % 4);
+#endif
+
+ hif_trace_info(IPC_TR_NTFY_INIT_POOL_INFO, g_ipc_ntfy_pool, sizeof(g_ipc_ntfy_pool) / sizeof(ipc_ntfy_t));
+ kal_mem_set(g_ipc_ntfy_pool, 0, sizeof(g_ipc_ntfy_pool));
+
+ for (idx = 0; idx < sizeof(nls_set) / sizeof(ipc_ntfy_list_t*); idx++) {
+ hif_trace_info(IPC_TR_NTFY_INIT_LIST_INFO, idx, nls_set[idx]);
+ kal_mem_set(nls_set[idx], 0, sizeof(ipc_ntfy_list_t));
+ IPC_INIT_OBJECT_BEGIN(nls_set[idx], ipc_spinlock_g);
+ IPC_INIT_OBJECT_END(nls_set[idx], ipc_spinlock_g);
+ }
+}
+
+kal_int32 ipc_ntfy_new_cbk(ipc_ntfy_callback_t cbk_func, void *p_cbk_args)
+{
+ ipc_ntfy_t *p_ntfy = NULL;
+
+ p_ntfy = ipc_ntfy_alloc_entry(g_ipc_ntfy_pool, IPC_NTFY_MAX_NUM, cbk_func, p_cbk_args);
+ if (p_ntfy) {
+ ipc_ntfy_add_to_list(g_ipc_ntfy_list, p_ntfy);
+ hif_trace_info(IPC_TR_NEW_NTFY_ADD_TO_LIST, p_ntfy->ntfy_id, cbk_func, p_cbk_args);
+
+ return p_ntfy->ntfy_id;
+ } else {
+ hif_trace_info(IPC_TR_NEW_NTFY_NG, cbk_func, p_cbk_args);
+ ipc_ut_set_error(IPC_UT_NEW_NTFY_NG);
+
+ return -1;
+ }
+}
+
+void ipc_ntfy_del_cbk(kal_int32 ntfy_id)
+{
+ ipc_ntfy_t *p_ntfy = NULL;
+
+ if (0 > ntfy_id || IPC_NTFY_MAX_NUM <= ntfy_id) {
+ hif_trace_error(IPC_TR_DEL_NTFY_WITH_INVALID_ID, ntfy_id);
+ ipc_ut_set_error(IPC_UT_DEL_NTFY_WITH_INVALID_ID);
+ return;
+ }
+
+ p_ntfy = ipc_ntfy_get_entry(g_ipc_ntfy_pool, ntfy_id);
+ IPC_R_LOCK_OBJECT(p_ntfy, ipc_spinlock_g);
+ if (p_ntfy) {
+ hif_trace_info(IPC_TR_DEL_NTFY_INFO, ntfy_id, p_ntfy->cbk_func, p_ntfy->p_cbk_args);
+
+ hif_trace_info(IPC_TR_DEL_NTFY_REMOVE_FROM_LIST, ntfy_id);
+ ipc_ntfy_rm_from_list(g_ipc_ntfy_list, p_ntfy);
+
+ IPC_R_UNLOCK_OBJECT(p_ntfy, ipc_spinlock_g);
+ hif_trace_info(IPC_TR_DEL_NTFY_FREE_NTFY, ntfy_id);
+ ipc_ntfy_del_entry(p_ntfy);
+ } else {
+ hif_trace_error(IPC_TR_DEL_NTFY_NOT_FOUND, ntfy_id);
+ ipc_ut_set_error(IPC_UT_DEL_NTFY_NOT_FOUND);
+ }
+}
+
+void ipc_ntfy_do_event_cbk(ipc_netif_t *p_netif, ipc_ntfy_type_e ntfy_type)
+{
+ ipc_ntfy_t *p_ntfy = NULL;
+ kal_uint32 ntfy_idx = 0;
+ kal_int32 ip_id = 0;
+
+ IPC_ASSERT(NULL != p_netif);
+ IPC_ASSERT((IPC_NTFY_TYPE_MIN < ntfy_type) && (IPC_NTFY_TYPE_MAX > ntfy_type));
+
+ IPC_R_LOCK_OBJECT(p_netif, ipc_spinlock_g);
+ if (p_netif) {
+ ip_id = ipc_map_netif_to_ip_id(p_netif);
+ IPC_R_UNLOCK_OBJECT(p_netif, ipc_spinlock_g);
+
+ for (ntfy_idx = 0; ntfy_idx < g_ipc_ntfy_list->cnt; ntfy_idx++) {
+ ipc_ntfy_param_t param;
+
+ p_ntfy = g_ipc_ntfy_list->p_ntfy[ntfy_idx];
+
+ IPC_ASSERT(NULL != p_ntfy);
+ IPC_ASSERT(NULL != p_ntfy->cbk_func);
+
+ param.context = p_ntfy->p_cbk_args;
+ param.ntfy_id = p_ntfy->ntfy_id;
+ param.ntfy_type = ntfy_type;
+ param.netif_id = p_netif->config.netif_id;
+ param.ip_id = ip_id;
+
+ hif_trace_info(IPC_TR_DO_NTFY_INFO, p_ntfy->cbk_func, param.context, param.ntfy_id);
+ hif_trace_info(IPC_TR_DO_NTFY_NTFY_INFO, param.ntfy_type, param.netif_id, param.ip_id);
+
+ /** execute callback function */
+ p_ntfy->cbk_func(¶m);
+ }
+ }
+}
+
diff --git a/mcu/middleware/hif/ipcore/src/ipc_packet_parser.c b/mcu/middleware/hif/ipcore/src/ipc_packet_parser.c
new file mode 100644
index 0000000..bee4aeb
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_packet_parser.c
@@ -0,0 +1,560 @@
+#include "ipc_api.h"
+#include "ipc_debug.h"
+#include "kal_public_api.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+
+#define IPC_PACKET_PARSER_CONTINUOUS_BUFF_LEN 18
+#define SHIFT_CONTENT_MF(_msg) shift_content(&p_addr, tmp_len, ip_packet, _msg, ct_data)
+#define GET_CONTINUOUS_CONTENTMF(_hd, _of, _msg) get_continuous_content(p_addr, _hd, _of, &comm_continuous_p, _msg, ct_data)
+#define INVALID_SHIFT_RET(_msg) if(KAL_FALSE == SHIFT_CONTENT_MF(_msg)) return KAL_FALSE
+#define INVALID_GET_CONT_RET(_hd, _of, _msg) if(KAL_FALSE == GET_CONTINUOUS_CONTENTMF(_hd, _of, _msg)) return KAL_FALSE
+
+typedef kal_bool (*SHIFT_CONTENT)(kal_uint8**, kal_uint32, void*, ipc_packet_info_parser_error_code, void*);
+typedef kal_bool (*GET_CONTINUOUS_CONTENT)(kal_uint8*, kal_uint32, kal_uint32, kal_uint8**, ipc_packet_info_parser_error_code, void*);
+typedef struct _ct_data_buff {kal_uint32 data_len; kal_uint16 packet_len;} ct_data_buff;
+typedef struct _ct_data_gpd {qbm_gpd *gpd, *next_bd, *base_bd; kal_uint8 comm_buff[IPC_PACKET_PARSER_CONTINUOUS_BUFF_LEN];} ct_data_gpd;
+typedef struct _ct_data_did {upcm_did* did; kal_uint32 base_si_idx, next_si_idx; kal_uint8 comm_buff[IPC_PACKET_PARSER_CONTINUOUS_BUFF_LEN];} ct_data_did;
+
+void fill_packet_info_udp(const kal_uint8 *udp_header, ipc_packet_info_t *p_info)
+{
+ p_info->src_port= IPC_NE_GET_2B(udp_header);
+ p_info->dst_port= IPC_NE_GET_2B(udp_header + 2);
+ p_info->info_valid_fields|= (IPC_FILTER_BY_SRC_PORT + IPC_FILTER_BY_DST_PORT);
+ p_info->l4_offset= p_info->data_offset;
+ p_info->data_offset+= IPC_HDR_UDP_HEADER_SIZE;
+ p_info->l4_checksum= IPC_NE_GET_2B(udp_header + 6);
+}
+
+void fill_packet_info_tcp(const kal_uint8 *tcp_header, ipc_packet_info_t *p_info)
+{
+ p_info->src_port= IPC_NE_GET_2B(tcp_header);
+ p_info->dst_port= IPC_NE_GET_2B(tcp_header + 2);
+ p_info->tcp_flags= IPC_HDR_TCP_GET_FLAGS(tcp_header);
+ p_info->info_valid_fields|= (IPC_FILTER_BY_SRC_PORT + IPC_FILTER_BY_DST_PORT + IPC_FILTER_BY_TCP_FLAGS);
+ p_info->l4_offset= p_info->data_offset;
+ p_info->data_offset+= IPC_HDR_TCP_GET_OFFSET(tcp_header);
+ p_info->l4_checksum= IPC_NE_GET_2B(tcp_header + 16);
+}
+
+void fill_packet_info_icmp(kal_bool is_v4, const kal_uint8 *icmp_header, ipc_packet_info_t *p_info)
+{
+ if(is_v4 == KAL_TRUE) {
+ p_info->icmpv4_type= IPC_NE_GET_1B(icmp_header);
+ p_info->info_valid_fields|= IPC_FILTER_BY_ICMPV4_TYPE;
+ }
+ else {
+ p_info->icmpv6_type= IPC_NE_GET_1B(icmp_header);
+ p_info->info_valid_fields|= IPC_FILTER_BY_ICMPV6_TYPE;
+ }
+
+ p_info->l4_offset= p_info->data_offset;
+ p_info->data_offset+= IPC_HDR_ICMP_HEADER_SIZE;
+ p_info->l4_checksum= IPC_NE_GET_2B(icmp_header + 2);
+}
+
+void fill_packet_info_esp(const kal_uint8 *esp_header, ipc_packet_info_t *p_info)
+{
+ p_info->spi= IPC_NE_GET_4B(esp_header);
+ p_info->info_valid_fields|= IPC_FILTER_BY_SPI;
+}
+
+kal_bool get_packet_info(void *ip_packet, ipc_packet_info_t *p_info, SHIFT_CONTENT shift_content, GET_CONTINUOUS_CONTENT get_continuous_content, void *ct_data)
+{
+ kal_uint32 ip_header_len= 0;
+ kal_uint16 tmp_len, tmp_payload_len;
+ kal_uint8 *p_addr= (kal_uint8 *)ip_packet;
+ kal_uint8 *comm_continuous_p= NULL;
+
+ p_info->info_valid_fields= 0;
+ QBM_CACHE_INVALID(ip_packet, 1);
+
+ if(IPC_HDR_IS_V4(ip_packet)) {
+ INVALID_GET_CONT_RET(0, 12, V4_IPV4_HDR_FAILED);
+ p_info->ip_id= IPC_NE_GET_2B(comm_continuous_p + 4);
+ p_info->fragment= ((IPC_NE_GET_2B(comm_continuous_p + 6) & 0x3FFF) > 0) ? KAL_TRUE : KAL_FALSE;
+ ip_header_len= (kal_uint32)IPC_HDR_V4_GET_IHL(comm_continuous_p + 0);
+ if(p_info->fragment) {
+ p_info->frag_payload_offset= (IPC_NE_GET_2B(comm_continuous_p + 6) & 0x1FFF) << 3;
+ p_info->frag_flag= (IPC_NE_GET_1B(comm_continuous_p + 6) & 0x60) >> 5;
+ p_info->frag_payload_len= IPC_NE_GET_2B(comm_continuous_p + 2);
+ p_info->frag_buffer_payload_offset= ip_header_len;
+ }
+ p_info->protocol= IPC_NE_GET_1B(comm_continuous_p + 9);
+ p_info->info_valid_fields|= IPC_FILTER_BY_PROTOCOL;
+ p_info->ipv4_checksum= IPC_NE_GET_2B(comm_continuous_p + 10);
+
+ INVALID_GET_CONT_RET(12, 8, V4_IPV4_HDR_FAILED);
+ kal_mem_cpy(p_info->src_addr, comm_continuous_p, 4);
+ kal_mem_cpy(p_info->dst_addr, comm_continuous_p + 4, 4);
+ p_info->info_valid_fields|= (IPC_FILTER_BY_SRC_IPV4 + IPC_FILTER_BY_DST_IPV4);
+
+ if(p_info->fragment && (p_info->frag_payload_offset != 0 || p_info->frag_payload_len < 4)) return KAL_TRUE;
+ p_info->data_offset= ip_header_len;
+
+ if(p_info->protocol == IPC_HDR_PROT_AH) {
+ INVALID_GET_CONT_RET(ip_header_len, 1, V4_AH_HDR_FAILED);
+ p_info->protocol= IPC_NE_GET_1B(comm_continuous_p);
+ p_addr= p_addr + (IPC_NE_GET_1B(comm_continuous_p + 1) + 2) * 4;
+ }
+
+ if(p_info->protocol == IPC_HDR_PROT_UDP) {
+ INVALID_GET_CONT_RET(ip_header_len, 8, V4_UDP_HDR_FAILED);
+ fill_packet_info_udp(comm_continuous_p, p_info);
+ }
+ else if(p_info->protocol == IPC_HDR_PROT_TCP) {
+ INVALID_GET_CONT_RET(ip_header_len, 18, V4_TCP_HDR_FAILED);
+ fill_packet_info_tcp(comm_continuous_p, p_info);
+ }
+ else if(p_info->protocol == IPC_HDR_PROT_ICMP) {
+ INVALID_GET_CONT_RET(ip_header_len, 4, V4_ICMP_HDR_FAILED);
+ fill_packet_info_icmp(KAL_TRUE, comm_continuous_p, p_info);
+ }
+ else if(p_info->protocol == IPC_HDR_PROT_ESP) {
+ INVALID_GET_CONT_RET(ip_header_len, 4, V4_ESP_HDR_FAILED);
+ fill_packet_info_esp(comm_continuous_p, p_info);
+ }
+ }
+ else if(IPC_HDR_IS_V6(ip_packet)) {
+ p_info->fragment= KAL_FALSE;
+
+ INVALID_GET_CONT_RET(0, 8, V6_IPV6_HDR_FAILED);
+ ip_header_len= 40;
+ p_info->data_offset= ip_header_len;
+ p_info->protocol= IPC_NE_GET_1B(comm_continuous_p + 6);
+ p_info->info_valid_fields|= IPC_FILTER_BY_PROTOCOL;
+ tmp_payload_len= IPC_NE_GET_2B(comm_continuous_p + 4);
+ INVALID_GET_CONT_RET(8, 16, V6_IPV6_HDR_FAILED);
+ kal_mem_cpy(p_info->src_addr, comm_continuous_p, 16);
+ p_info->info_valid_fields|= IPC_FILTER_BY_SRC_IPV6;
+ INVALID_GET_CONT_RET(24, 16, V6_IPV6_HDR_FAILED);
+ kal_mem_cpy(p_info->dst_addr, comm_continuous_p, 16);
+ p_info->info_valid_fields|= IPC_FILTER_BY_DST_IPV6;
+
+ tmp_len= ip_header_len;
+ while(1) {
+ if((p_info->protocol == IPC_HDR_PROT_IPV6_HOP) || (p_info->protocol == IPC_HDR_PROT_IPV6_ROUTE) || (p_info->protocol == IPC_HDR_PROT_IPV6_DEST)) {
+ INVALID_SHIFT_RET(FIND_V6_EXT_HDR_SHIFT_FAILED);
+ INVALID_GET_CONT_RET(0, 2, FIND_V6_EXT_HDR_FAILED);
+ p_info->protocol= IPC_NE_GET_1B(comm_continuous_p);
+ tmp_len= (IPC_NE_GET_1B(comm_continuous_p + 1) + 1) * 8;
+ p_info->data_offset+= tmp_len;
+ if(tmp_payload_len >= tmp_len)
+ tmp_payload_len-= tmp_len;
+ else
+ return KAL_FALSE;
+ }
+ else if(p_info->protocol == IPC_HDR_PROT_AH) {
+ INVALID_SHIFT_RET(FIND_V6_EXT_HDR_SHIFT_FAILED);
+ INVALID_GET_CONT_RET(0, 2, FIND_V6_EXT_HDR_FAILED);
+ p_info->protocol= IPC_NE_GET_1B(comm_continuous_p);
+ tmp_len= (IPC_NE_GET_1B(comm_continuous_p + 1) + 2) * 4;
+ p_info->data_offset+= tmp_len;
+ if(tmp_payload_len >= tmp_len)
+ tmp_payload_len-= tmp_len;
+ else
+ return KAL_FALSE;
+ }
+ else if(p_info->protocol == IPC_HDR_PROT_IPV6_FRAG) {
+ INVALID_SHIFT_RET(FIND_V6_EXT_HDR_SHIFT_FAILED);
+ INVALID_GET_CONT_RET(0, 8, FIND_V6_EXT_HDR_FAILED);
+ p_info->fragment= KAL_TRUE;
+ p_info->ip_id= IPC_NE_GET_4B(comm_continuous_p + 4);
+ p_info->frag_payload_offset= IPC_NE_GET_2B(comm_continuous_p + 2) & 0xFFF8;
+ p_info->frag_flag= IPC_NE_GET_1B(comm_continuous_p + 3) & 0x1;
+ if(tmp_payload_len >= 8)
+ p_info->frag_payload_len= tmp_payload_len - 8;
+ else
+ return KAL_FALSE;
+ p_info->protocol= IPC_NE_GET_1B(comm_continuous_p);
+ if (p_info->protocol == IPC_HDR_PROT_IPV6_FRAG) {
+ p_info->need_reassemble = KAL_TRUE;
+
+ p_info->data_offset+= IPC_HDR_V6_FRAGMENT_HEADER_SIZE;
+ p_info->frag_buffer_payload_offset= p_info->data_offset;
+ break;
+ }
+ tmp_len= IPC_HDR_V6_FRAGMENT_HEADER_SIZE;
+ p_info->data_offset+= IPC_HDR_V6_FRAGMENT_HEADER_SIZE;
+ p_info->frag_buffer_payload_offset= p_info->data_offset;
+ }
+ else
+ break;
+ }
+
+ if(p_info->protocol == IPC_HDR_PROT_UDP) {
+ INVALID_SHIFT_RET(FIND_V6_EXT_HDR_SHIFT_FAILED);
+ INVALID_GET_CONT_RET(0, 8, V6_UDP_HDR_FAILED);
+ fill_packet_info_udp(comm_continuous_p, p_info);
+ }
+ else if(p_info->protocol == IPC_HDR_PROT_TCP) {
+ INVALID_SHIFT_RET(FIND_V6_EXT_HDR_SHIFT_FAILED);
+ INVALID_GET_CONT_RET(0, 18, V6_TCP_HDR_FAILED);
+ fill_packet_info_tcp(comm_continuous_p, p_info);
+ }
+ else if(p_info->protocol == IPC_HDR_PROT_ICMPV6) {
+ INVALID_SHIFT_RET(FIND_V6_EXT_HDR_SHIFT_FAILED);
+ INVALID_GET_CONT_RET(0, 4, V6_ICMP_HDR_FAILED);
+ fill_packet_info_icmp(KAL_FALSE, comm_continuous_p, p_info);
+ }
+ else if(p_info->protocol == IPC_HDR_PROT_ESP) {
+ INVALID_SHIFT_RET(FIND_V6_EXT_HDR_SHIFT_FAILED);
+ INVALID_GET_CONT_RET(0, 4, V6_ESP_HDR_FAILED);
+ fill_packet_info_esp(comm_continuous_p, p_info);
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_shift_content_ptr(kal_uint8 *base_addr_p, qbm_gpd *gpd, qbm_gpd *base_bd, kal_uint32 offset, kal_uint8 **offset_addr_pp, qbm_gpd **offset_bd_p)
+{
+ kal_uint32 remaining_offset;
+ kal_uint32 remaining_bd_length;
+ kal_uint8 *offset_addr_p;
+ qbm_gpd *curr_bd;
+
+ ASSERT(base_addr_p);
+ ASSERT(gpd);
+ ASSERT(offset_addr_pp);
+ ASSERT(offset_bd_p);
+
+ if(NULL == base_bd) {
+ *offset_addr_pp= base_addr_p + offset;
+ *offset_bd_p= NULL;
+ }
+ else {
+ curr_bd= base_bd;
+ offset_addr_p= base_addr_p;
+ remaining_offset= offset;
+ remaining_bd_length= (kal_uint32)QBM_DES_GET_DATALEN(curr_bd) - (kal_uint32)(base_addr_p - (kal_uint8 *)QBM_DES_GET_DATAPTR(curr_bd));
+
+ while(remaining_offset) {
+ if(remaining_offset <= remaining_bd_length) {
+ /* Found */
+ offset_addr_p= offset_addr_p + remaining_offset;
+ remaining_offset= 0;
+ }
+ else {
+ if(!QBM_DES_GET_EOL(curr_bd)) {
+ remaining_offset= remaining_offset - remaining_bd_length;
+
+ /* Shift to next BD and get information for next loop */
+ curr_bd= (qbm_gpd *)QBM_DES_GET_NEXT(curr_bd);
+ remaining_bd_length= QBM_DES_GET_DATALEN(curr_bd);
+ offset_addr_p= (kal_uint8 *)QBM_DES_GET_DATAPTR(curr_bd);
+ }
+ else {
+ hif_trace_error(IPC_TR_SHIFT_OFFSET_FAILED, gpd, base_bd, curr_bd, QBM_DES_GET_DATALEN(curr_bd), remaining_offset, base_addr_p, offset);
+ goto process_failed;
+ }
+ }
+ }
+
+ ASSERT(offset_addr_p);
+ /* Set return values */
+ *offset_addr_pp= offset_addr_p;
+ *offset_bd_p= curr_bd;
+ }
+
+ return KAL_TRUE;
+
+process_failed:
+ return KAL_FALSE;
+}
+
+kal_bool ipc_get_continuous_content(kal_uint8 *base_addr_p, kal_uint32 offset, qbm_gpd *gpd, qbm_gpd *base_bd, kal_uint32 length, kal_uint8 **cont_addr_pp, kal_uint8 *cont_buff_p)
+{
+ kal_uint8 *data_src_p;
+ kal_uint8 *data_dst_p;
+ qbm_gpd *curr_bd;
+ kal_uint32 remaining_length;
+ kal_uint32 remaining_bd_length;
+ ASSERT(base_addr_p);
+ ASSERT(gpd);
+ ASSERT(cont_addr_pp);
+ ASSERT(cont_buff_p);
+ *cont_addr_pp= NULL;
+ /* Decide whether original GPD/BD can provide continuous content */
+ /* ----------------------------------------------------- */
+ if(NULL == base_bd) {
+ /* This packet is single GPD and content is continuous */
+ goto org_buff_is_continuous;
+ }
+ if((kal_uint32)QBM_DES_GET_DATALEN(base_bd) >= ((kal_uint32)((kal_uint8 *)base_addr_p - (kal_uint8 *)QBM_DES_GET_DATAPTR(base_bd)) + offset + length)) {
+ /* This BD is enough to support continuous content */
+ goto org_buff_is_continuous;
+ }
+ /* Using alternative buffer (cont_buff_p) */
+ /* ----------------------------------------------------- */
+ /* Copy content to alternative buffer */
+ {
+ data_dst_p= cont_buff_p;
+ curr_bd= base_bd;
+ /* Find data source pointer */
+ if(KAL_TRUE != ipc_shift_content_ptr(base_addr_p, gpd, curr_bd, offset, &data_src_p, &curr_bd)) {
+ hif_trace_error(IPC_TR_CONTENT_LENGTH_TOO_SHORT, gpd, base_bd, curr_bd, base_addr_p, offset, length);
+ goto process_failed;
+ }
+ ASSERT(data_src_p);
+ /* Copy data from source (BD list) to destination (single buffer) */
+ {
+ remaining_length= length;
+ remaining_bd_length= (kal_uint32)QBM_DES_GET_DATALEN(curr_bd) - (kal_uint32)(data_src_p - (kal_uint8 *)QBM_DES_GET_DATAPTR(curr_bd));
+ while(remaining_length) {
+ if(remaining_length <= remaining_bd_length) {
+ /* Latest copy */
+ QBM_CACHE_INVALID(data_src_p, remaining_length);
+ kal_mem_cpy(data_dst_p, data_src_p, remaining_length);
+ remaining_length= 0;
+ }
+ else {
+ QBM_CACHE_INVALID(data_src_p, remaining_bd_length);
+ kal_mem_cpy(data_dst_p, data_src_p, remaining_bd_length);
+ data_dst_p= data_dst_p + remaining_bd_length;
+ if(!QBM_DES_GET_EOL(curr_bd)) {
+ remaining_length= remaining_length - remaining_bd_length;
+ /* Shift to next BD and get information for next loop */
+ curr_bd= (qbm_gpd *)QBM_DES_GET_NEXT(curr_bd);
+ remaining_bd_length= QBM_DES_GET_DATALEN(curr_bd);
+ data_src_p= (kal_uint8 *)QBM_DES_GET_DATAPTR(curr_bd);
+ }
+ else {
+ hif_trace_error(IPC_TR_CONTENT_LENGTH_TOO_SHORT_TO_COPY, gpd, base_bd, curr_bd, QBM_DES_GET_DATALEN(curr_bd), remaining_length, base_addr_p, offset, length);
+ goto process_failed;
+ }
+ }
+ }
+ }
+ }
+ /* continuous buffer is from cont_buff_p and return TRUE */
+ *cont_addr_pp= cont_buff_p;
+ return KAL_TRUE;
+org_buff_is_continuous:
+ QBM_CACHE_INVALID((kal_uint8 *)(base_addr_p + offset), length);
+ *cont_addr_pp= base_addr_p + offset;
+ return KAL_TRUE;
+process_failed:
+ return KAL_FALSE;
+}
+
+kal_bool ipc_shift_did_content_ptr(kal_uint8 *base_addr_p, upcm_did *did, kal_uint32 base_si_idx, kal_uint32 offset, kal_uint8 **offset_addr_pp, kal_uint32 *offset_si_idx_p)
+{
+ kal_uint32 curr_si_idx;
+ upcm_did_si *sit;
+ upcm_did_si *curr_si;
+ kal_uint32 remaining_offset;
+ kal_uint32 remaining_si_length;
+ kal_uint8 *offset_addr_p;
+ ASSERT(base_addr_p);
+ ASSERT(did);
+ ASSERT(offset_addr_pp);
+ ASSERT(offset_si_idx_p);
+ sit= UPCM_DID_GET_SIT_PTR(did);
+ curr_si_idx= base_si_idx;
+ curr_si= &sit[base_si_idx];
+ if(UPCM_DID_SI_GET_EOL(curr_si)) {
+ *offset_addr_pp= base_addr_p + offset;
+ *offset_si_idx_p= base_si_idx;
+ }
+ else {
+ offset_addr_p= base_addr_p;
+ remaining_offset= offset;
+ remaining_si_length= (kal_uint32)(UPCM_DID_SI_GET_LEN(curr_si)) - (kal_uint32)(base_addr_p - ((kal_uint8 *)UPCM_DID_SI_GET_DATAPTR(curr_si) + UPCM_DID_SI_GET_OFFSET(curr_si)));
+ while(remaining_offset) {
+ if(remaining_offset <= remaining_si_length) {
+ /* Found */
+ offset_addr_p= offset_addr_p + remaining_offset;
+ remaining_offset= 0;
+ }
+ else {
+ if(!UPCM_DID_SI_GET_EOL(curr_si)) {
+ remaining_offset= remaining_offset - remaining_si_length;
+ /* Shift to next SIT and get information for next loop */
+ curr_si_idx++;
+ ASSERT(curr_si_idx < UPCM_DID_MAX_SIT_ENT_NUM);
+ curr_si= &sit[curr_si_idx];
+ remaining_si_length= UPCM_DID_SI_GET_LEN(curr_si);
+ offset_addr_p= (kal_uint8 *)UPCM_DID_SI_GET_DATAPTR(curr_si) + UPCM_DID_SI_GET_OFFSET(curr_si);
+ }
+ else {
+ hif_trace_error(IPC_TR_DID_SHIFT_OFFSET_FAILED, did, base_si_idx, curr_si_idx, UPCM_DID_SI_GET_LEN(curr_si), remaining_offset, base_addr_p, offset);
+ goto process_failed;
+ }
+ }
+ }
+ ASSERT(offset_addr_p);
+ /* Set return values */
+ *offset_addr_pp= offset_addr_p;
+ *offset_si_idx_p= curr_si_idx;
+ }
+ return KAL_TRUE;
+process_failed:
+ return KAL_FALSE;
+}
+
+kal_bool ipc_get_continuous_content_did(kal_uint8 *base_addr_p, kal_uint32 offset, upcm_did *did, kal_uint32 base_si_idx, kal_uint32 length, kal_uint8 **cont_addr_pp, kal_uint8 *cont_buff_p)
+{
+ kal_uint32 curr_si_idx;
+ upcm_did_si *sit;
+ upcm_did_si *curr_si;
+ kal_uint8 *data_src_p;
+ kal_uint8 *data_dst_p;
+ kal_uint32 remaining_length;
+ kal_uint32 remaining_si_length;
+ ASSERT(base_addr_p);
+ ASSERT(did);
+ ASSERT(cont_addr_pp);
+ ASSERT(cont_buff_p);
+ *cont_addr_pp= NULL;
+ curr_si_idx= base_si_idx;
+ sit= UPCM_DID_GET_SIT_PTR(did);
+ curr_si= &sit[base_si_idx];
+ /* Determine whether original SIT can provide continuous content or not*/
+ /* ----------------------------------------------------- */
+ if(UPCM_DID_SI_GET_EOL(curr_si)) {
+ /* It's the last SIT and content is continuous */
+ goto org_buff_is_continuous;
+ }
+ if(UPCM_DID_SI_GET_LEN(curr_si) >= ((kal_uint32)((kal_uint8 *)base_addr_p - ((kal_uint8 *)UPCM_DID_SI_GET_DATAPTR(curr_si) + UPCM_DID_SI_GET_OFFSET(curr_si))) + offset + length)) {
+ /* This SIT is enough to support continuous content */
+ goto org_buff_is_continuous;
+ }
+ /* Using alternative buffer (cont_buff_p) */
+ /* ----------------------------------------------------- */
+ /* Copy content to alternative buffer */
+ {
+ data_dst_p= cont_buff_p;
+ /* Find data source pointer */
+ if(KAL_TRUE != ipc_shift_did_content_ptr(base_addr_p, did, curr_si_idx, offset, &data_src_p, &curr_si_idx)) {
+ hif_trace_error(IPC_TR_DID_CONTENT_LENGTH_TOO_SHORT, did, base_si_idx, curr_si_idx, base_addr_p, offset, length);
+ goto process_failed;
+ }
+ ASSERT(data_src_p);
+ curr_si= &sit[curr_si_idx];
+ /* Copy data from source (sit) to destination (single buffer) */
+ {
+ remaining_length= length;
+ remaining_si_length= (kal_uint32)(UPCM_DID_SI_GET_LEN(curr_si)) - (kal_uint32)(data_src_p - ((kal_uint8 *)UPCM_DID_SI_GET_DATAPTR(curr_si) + UPCM_DID_SI_GET_OFFSET(curr_si)));
+ while(remaining_length) {
+ if(remaining_length <= remaining_si_length) {
+ /* Last copy */
+ QBM_CACHE_INVALID(data_src_p, remaining_length);
+ kal_mem_cpy(data_dst_p, data_src_p, remaining_length);
+ remaining_length= 0;
+ }
+ else {
+ QBM_CACHE_INVALID(data_src_p, remaining_si_length);
+ kal_mem_cpy(data_dst_p, data_src_p, remaining_si_length);
+ data_dst_p= data_dst_p + remaining_si_length;
+ if(!UPCM_DID_SI_GET_EOL(curr_si)) {
+ remaining_length= remaining_length - remaining_si_length;
+ /* Shift to next SI and get information for next loop */
+ curr_si_idx++;
+ curr_si= &sit[curr_si_idx];
+ remaining_si_length= UPCM_DID_SI_GET_LEN(curr_si);
+ data_src_p= ((kal_uint8 *)UPCM_DID_SI_GET_DATAPTR(curr_si) + UPCM_DID_SI_GET_OFFSET(curr_si));
+ }
+ else {
+ hif_trace_error(IPC_TR_DID_CONTENT_LENGTH_TOO_SHORT_TO_COPY, did, base_si_idx, curr_si_idx, UPCM_DID_SI_GET_LEN(curr_si), remaining_length, base_addr_p, offset, length);
+ goto process_failed;
+ }
+ }
+ }
+ }
+ }
+ /* continuous buffer is from cont_buff_p and return TRUE */
+ *cont_addr_pp= cont_buff_p;
+ return KAL_TRUE;
+org_buff_is_continuous:
+ QBM_CACHE_INVALID((kal_uint8 *)(base_addr_p + offset), length);
+ *cont_addr_pp= base_addr_p + offset;
+ return KAL_TRUE;
+process_failed:
+ return KAL_FALSE;
+}
+
+kal_bool _shift_content_buff(kal_uint8 **packet_addr, kal_uint32 offset, void *ip_packet, ipc_packet_info_parser_error_code err_code, void *ct_data)
+{
+ ct_data_buff *s_data= (ct_data_buff*)ct_data;
+ s_data->data_len+= offset;
+ return KAL_TRUE;
+}
+
+kal_bool _get_continuous_content_buff(kal_uint8 *packet_addr, kal_uint32 offset, kal_uint32 content_len, kal_uint8 **comm_continuous_p, ipc_packet_info_parser_error_code err_code, void *ct_data)
+{
+ ct_data_buff *s_data= (ct_data_buff*)ct_data;
+ QBM_CACHE_INVALID(packet_addr + offset, content_len);
+ *comm_continuous_p= packet_addr + s_data->data_len + offset;
+ if(s_data->packet_len < s_data->data_len + offset + content_len) {
+ hif_trace_error(IPC_TR_GET_INFO_SPD_FAILED, err_code, packet_addr, (s_data->data_len + offset + content_len), s_data->packet_len);
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool ipc_get_packet_info(kal_uint8 *p_packet, kal_uint16 packet_len, ipc_packet_info_t *p_info)
+{
+ ct_data_buff ct_data;
+ ct_data.data_len= 0;
+ ct_data.packet_len= packet_len;
+ /* TODO : we seek a general solution for Cache invalidate for all packet content, this is temp solution */
+ QBM_CACHE_INVALID(p_packet, packet_len);
+ return get_packet_info((kal_uint8 *)p_packet, p_info, _shift_content_buff, _get_continuous_content_buff, &ct_data);
+}
+
+kal_bool _shift_content_gpd(kal_uint8 **packet_addr, kal_uint32 offset, void *ip_packet, ipc_packet_info_parser_error_code err_code, void *ct_data)
+{
+ ct_data_gpd *s_data= (ct_data_gpd*)ct_data;
+ if(KAL_FALSE == ipc_shift_content_ptr(*packet_addr, s_data->gpd, s_data->next_bd, offset, packet_addr, &(s_data->next_bd))) {
+ hif_trace_error(IPC_TR_GET_INFO_SHIFT_FAILED, err_code, s_data->gpd, s_data->base_bd, ip_packet, offset, packet_addr, s_data->next_bd);
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool _get_continuous_content_gpd(kal_uint8 *packet_addr, kal_uint32 offset, kal_uint32 content_len, kal_uint8 **comm_continuous_p, ipc_packet_info_parser_error_code err_code, void *ct_data)
+{
+ ct_data_gpd *s_data= (ct_data_gpd*)ct_data;
+ if(KAL_FALSE == ipc_get_continuous_content(packet_addr, offset, s_data->gpd, s_data->next_bd, content_len, comm_continuous_p, s_data->comm_buff)) {
+ hif_trace_error(IPC_TR_GET_INFO_FAILED, err_code, packet_addr, offset, s_data->gpd, s_data->next_bd, content_len);
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool ipc_get_packet_info_gpd(kal_uint8 *p_packet, qbm_gpd *gpd, qbm_gpd *base_bd, ipc_packet_info_t *p_info)
+{
+ ct_data_gpd ct_data;
+ ct_data.gpd= gpd;
+ ct_data.base_bd= ct_data.next_bd= base_bd;
+ return get_packet_info((kal_uint8 *)p_packet, p_info, _shift_content_gpd, _get_continuous_content_gpd, &ct_data);
+}
+
+kal_bool _shift_content_did(kal_uint8 **packet_addr, kal_uint32 offset, void *ip_packet, ipc_packet_info_parser_error_code err_code, void *ct_data)
+{
+ ct_data_did *s_data= (ct_data_did*)ct_data;
+ if(KAL_FALSE == ipc_shift_did_content_ptr(*packet_addr, s_data->did, s_data->next_si_idx, offset, packet_addr, &(s_data->next_si_idx))) {
+ hif_trace_error(IPC_TR_GET_INFO_DID_SHIFT_FAILED, err_code, s_data->did, s_data->base_si_idx, ip_packet, offset, packet_addr, s_data->next_si_idx);
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool _get_continuous_content_did(kal_uint8 *packet_addr, kal_uint32 offset, kal_uint32 content_len, kal_uint8 **comm_continuous_p, ipc_packet_info_parser_error_code err_code, void *ct_data)
+{
+ ct_data_did *s_data= (ct_data_did*)ct_data;
+ if(KAL_FALSE == ipc_get_continuous_content_did(packet_addr, offset, s_data->did, s_data->next_si_idx, content_len, comm_continuous_p, s_data->comm_buff)) {
+ hif_trace_error(IPC_TR_GET_INFO_DID_FAILED, err_code, packet_addr, offset, s_data->did, s_data->next_si_idx, content_len);
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+kal_bool ipc_get_packet_info_did(kal_uint8 *p_packet, upcm_did *did, kal_uint32 base_si_idx, ipc_packet_info_t *p_info)
+{
+ ct_data_did ct_data;
+ ct_data.did= did;
+ ct_data.base_si_idx= ct_data.next_si_idx= base_si_idx;
+ return get_packet_info((kal_uint8 *)p_packet, p_info, _shift_content_did, _get_continuous_content_did, &ct_data);
+}
diff --git a/mcu/middleware/hif/ipcore/src/ipc_session.c b/mcu/middleware/hif/ipcore/src/ipc_session.c
new file mode 100644
index 0000000..a17d0a1
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_session.c
@@ -0,0 +1,1335 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_session.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IP session management.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "intrCtrl.h"
+#include "mw_sap.h"
+#include "hif_mw_msgid.h"
+
+#include "qmu_bm.h"
+#include "qmu_bm_size.h"
+#include "qmu_bm_util.h"
+
+#include "ipc_defs.h"
+#include "ipc_debug.h"
+#include "ipc_utils.h"
+#include "ipc_filter.h"
+#include "ipc_notify.h"
+
+#if defined (__GEN97_ESL_SPEEDUP__)
+/* reduce mips in ESL by skipping the memory init */
+#define kal_mem_set(a,b,c)
+#endif
+
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+
+/*
+ * 2011/12/16: SD1/Moja guarantees pdn_id falls in [0,15].
+ */
+#define IPC_CONTEXT_TO_SESSION(_context, _session) (_session) = &(ipc_sessions_s[(_context)])
+#define IPC_SESSION_SAVED_MAP_NUM 1
+
+/*------------------------------------------------------------------------------
+ * Private data structure.
+ *----------------------------------------------------------------------------*/
+typedef struct _ipc_session_saved_map_t {
+ kal_bool is_saved;
+ ipc_conf_t netif_cfg;
+ kal_uint32 session_cnt;
+ void *p_session_map[IPC_SESSION_MAP_SIZE];
+} ipc_session_saved_map_t;
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+static ipc_netif_t ipc_netifs_s[IPC_MAX_NETIF_CNT];
+
+/*
+ * Prevent the race condition of UL reload:
+ * - ipc_netif_ul_reload_retry_s: modified in IPCORE context.
+ * - ipc_netif_ul_set_need_reload_s: modified by netifs in their context.
+ */
+static kal_uint64 ipc_netif_ul_reload_retry_s = 0;
+static kal_uint64 ipc_netif_ul_set_need_reload_s = 0;
+
+static ipc_session_t ipc_sessions_s[IPC_MAX_SESSION_CNT];
+static kal_bool ipc_ids_s[IPC_MAX_IP_ID_CNT];
+
+static const ipc_session_transition_action_case_e session_transition_action_table[IPC_SESSION_STATE_MAX /* ORG */][IPC_SESSION_STATE_MAX /* NEW */] =
+{
+/* NEW ORG */
+/* MIN UNBIND PRE_BIND BIND PRE_LINKUP PRE_LINKUP_IPV4_LEASE LINKUP IPV4_LEASE PRE_IPV4_RELOCATE IP_REVOKE */
+{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MIN */ },
+{ 0, 0, IPC_SST_NA, 0, 0, 0, 0, 0, 0, 0, /* UNBIND */ },
+{ 0, IPC_SST_NA, 0, IPC_SST_NA, 0, 0, 0, 0, 0, 0, /* PRE_BIND */ },
+{ 0, IPC_SST_NA, IPC_SST_NA, 0, IPC_SST_LUI,0, 0, 0, 0, 0, /* BIND */ },
+{ 0, IPC_SST_NA, 0, 0, 0, IPC_SST_NA, IPC_SST_LUR,0, 0, 0, /* PRE_LINKUP */ },
+{ 0, IPC_SST_NA, 0, 0, IPC_SST_LUI,0, 0, 0, 0, 0, /* PRE_LINKUP_IPV4_LEASE */},
+{ 0, IPC_SST_LDR,0, 0, 0, 0, IPC_SST_LUR,IPC_SST_IDR,0, IPC_SST_IDR, /* LINKUP */ },
+{ 0, IPC_SST_LDR,0, 0, 0, 0, 0, 0, IPC_SST_IUI, 0, /* IPV4_LEASE */ },
+{ 0, IPC_SST_LDR,0, 0, 0, IPC_SST_NA, IPC_SST_IUR,0, 0, 0, /* PRE_IPV4_RELOCATE */ },
+{ 0, 0, 0, 0, 0, 0, IPC_SST_IUR,0, 0, 0, /* IP_REVOKE */ },
+};
+
+static module_type ipc_link_up_indication_handler;
+static module_type ipc_ip_up_indication_handler;
+static ipc_session_saved_map_t g_saved_session_map[IPC_SESSION_SAVED_MAP_NUM] = {0};
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ *----------------------------------------------------------------------------*/
+static kal_int32 ipc_new_id(ipc_netif_t *netif)
+{
+ kal_int32 ip_id = -1;
+ kal_int32 idx;
+
+ /*
+ * No need to protect ipc_ids_s[] if only one possible context.
+ */
+ IPC_ASSERT(KAL_FALSE == kal_if_hisr());
+ IPC_UT_ASSERT( (ipc_is_in_reset() || MOD_IPCORE == kal_get_active_module_id()),
+ IPC_UT_NO_ERROR );
+
+ /*
+ * If the associated netif has a valid ip_id (e.g. IPv4 + IPv6 case), use it.
+ */
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ ip_id = ipc_map_netif_to_ip_id(netif);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+
+ /*
+ * Otherwise, select minimal ip_id available.
+ */
+ if (ip_id < 0) {
+ for (idx = 0; idx < IPC_MAX_IP_ID_CNT; idx++) {
+ if (!ipc_ids_s[idx]) {
+ ipc_ids_s[idx] = KAL_TRUE;
+ ip_id = idx;
+ break;
+ }
+ }
+ }
+ return ip_id;
+}
+
+static void ipc_del_id(kal_int32 ip_id)
+{
+ /* No need to protect ipc_ids_s[] if only one possible context. */
+ IPC_ASSERT(KAL_FALSE == kal_if_hisr());
+ IPC_UT_ASSERT( (ipc_is_in_reset() || MOD_IPCORE == kal_get_active_module_id()),
+ IPC_UT_NO_ERROR );
+
+ if ((ip_id >= 0) && (ip_id < IPC_MAX_IP_ID_CNT)) {
+ ipc_ids_s[ip_id] = KAL_FALSE;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions.
+ *----------------------------------------------------------------------------*/
+void ipc_object_init(void)
+{
+ kal_uint32 idx = 0;
+
+ kal_mem_set(ipc_netifs_s, 0, sizeof(ipc_netifs_s));
+ for (idx = 0; idx < IPC_MAX_NETIF_CNT; idx++) {
+ ipc_netifs_s[idx].bit_id = (1ULL << idx);
+ ipc_netifs_s[idx].object_idx = idx;
+ }
+
+ ipc_netif_ul_reload_retry_s = 0;
+
+ kal_mem_set(ipc_sessions_s, 0, sizeof(ipc_sessions_s));
+ kal_mem_set(ipc_ids_s, 0, sizeof(ipc_ids_s));
+
+ for (idx = 0; idx < IPC_SESSION_SAVED_MAP_NUM; idx++) {
+ kal_mem_set(&g_saved_session_map[idx], 0, sizeof(ipc_session_saved_map_t));
+ }
+
+ ipc_link_up_indication_handler = MOD_IPCORE;
+ ipc_ip_up_indication_handler = MOD_IPCORE;
+}
+
+ipc_netif_t *ipc_find_netif(kal_uint32 netif_id)
+{
+ ipc_netif_t *netif;
+ kal_uint32 idx;
+
+ for (idx = 0; idx < IPC_MAX_NETIF_CNT; idx++) {
+ netif = &(ipc_netifs_s[idx]);
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ if (netif->config.netif_id == netif_id) {
+ return netif;
+ } else {
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+ }
+ }
+ return NULL;
+}
+
+ipc_netif_t *ipc_find_netif_by_bit_id(kal_uint64 bit_id)
+{
+ ipc_netif_t *netif;
+ kal_uint32 min = 0;
+ kal_uint32 max = IPC_MAX_NETIF_CNT - 1;
+ kal_uint32 cut;
+
+ do {
+ cut = ((max + min) >> 1);
+ netif = &(ipc_netifs_s[cut]);
+
+ if (bit_id == netif->bit_id) {
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ return netif;
+ } else {
+ break;
+ }
+ } else if (bit_id < netif->bit_id) {
+ max = cut - 1;
+ } else {
+ min = cut + 1;
+ }
+ } while (min <= max);
+
+ return NULL;
+}
+
+ipc_netif_t *ipc_find_netif_by_object_id(kal_uint32 object_idx)
+{
+ ipc_netif_t *netif = &ipc_netifs_s[object_idx];
+
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ return netif;
+}
+
+/* Should be spinlock protect from caller function with p_netif */
+static kal_bool ipc_session_save_netif_map(ipc_netif_t *p_netif, kal_uint8 ip_type)
+{
+ kal_uint32 i = 0;
+ kal_uint32 idx = 0;
+ kal_uint32 pdn_id = 0;
+ kal_bool is_matched = KAL_FALSE;
+ ipc_session_t *p_session = NULL;
+
+ IPC_ASSERT(NULL != p_netif);
+
+ for (i = 0; i < IPC_SESSION_SAVED_MAP_NUM; i++) {
+ if (KAL_FALSE == g_saved_session_map[i].is_saved) {
+ kal_mem_cpy(&(g_saved_session_map[i].netif_cfg), &(p_netif->config), sizeof(ipc_conf_t));
+ g_saved_session_map[i].session_cnt = p_netif->session_cnt;
+
+ if (ip_type != IPC_IP_TYPE_MIXED) {
+ idx = ipc_session_type_hash(ip_type);
+ g_saved_session_map[i].p_session_map[idx] = p_netif->session_map[idx];
+ p_session = (ipc_session_t * )g_saved_session_map[i].p_session_map[idx];
+ } else {
+ g_saved_session_map[i].p_session_map[0] = p_netif->session_map[0];
+ g_saved_session_map[i].p_session_map[1] = p_netif->session_map[1];
+ p_session = (ipc_session_t * )g_saved_session_map[i].p_session_map[0];
+ }
+ pdn_id = p_session->context;
+ g_saved_session_map[i].is_saved = KAL_TRUE;
+ is_matched = KAL_TRUE;
+
+ hif_trace_info(IPC_TR_SAVED_PDN_MAPPING, __FUNCTION__, pdn_id, p_netif->config.netif_id);
+ break;
+ }
+ }
+
+ return is_matched;
+}
+
+void ipc_session_send_restore_netif_ind(kal_uint32 netif_id, kal_uint8 ip_type, kal_bool is_link_update, kal_bool is_up)
+{
+ ipc_restore_netif_struct_t *p_param = NULL;
+
+ p_param = (ipc_restore_netif_struct_t *)construct_local_para(sizeof(ipc_restore_netif_struct_t), TD_RESET);
+ IPC_ASSERT(NULL != p_param);
+
+ p_param->netif_id = netif_id;
+ p_param->ip_type = ip_type;
+ p_param->is_link_update = is_link_update;
+ p_param->is_up = is_up;
+
+ msg_send6(kal_get_active_module_id(), /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_RESTORE_NETIF_IND, /* msg_id */
+ (struct local_para_struct *)p_param, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+
+ return;
+}
+
+/* Should be spinlock protect from caller function with p_netif */
+kal_bool ipc_session_restore_netif_map(ipc_netif_t *p_netif, kal_uint8 *p_ip_type)
+{
+ kal_uint32 i = 0;
+ ipc_session_t *p_session = NULL;
+ kal_bool ret = KAL_FALSE;
+
+ IPC_ASSERT(NULL != p_netif);
+ IPC_ASSERT(NULL != p_ip_type);
+
+ for (i = 0; i < IPC_SESSION_SAVED_MAP_NUM; i++) {
+ if (KAL_TRUE == g_saved_session_map[i].is_saved) {
+ if (p_netif->config.netif_id == g_saved_session_map[i].netif_cfg.netif_id) {
+ kal_mem_cpy(&(p_netif->config), &(g_saved_session_map[i].netif_cfg), sizeof(ipc_conf_t));
+ p_netif->session_cnt = g_saved_session_map[i].session_cnt;
+ p_netif->session_map[0] = g_saved_session_map[i].p_session_map[0];
+ p_netif->session_map[1] = g_saved_session_map[i].p_session_map[1];
+
+ if (1 == p_netif->session_cnt) {
+ if (NULL != p_netif->session_map[0]) {
+ p_session = (ipc_session_t *)p_netif->session_map[0];
+ p_session->netif = (ipc_netif_t *)p_netif;
+ *p_ip_type = p_session->type;
+ } else if (NULL != p_netif->session_map[1]) {
+ p_session = (ipc_session_t *)p_netif->session_map[1];
+ p_session->netif = (ipc_netif_t *)p_netif;
+ *p_ip_type = p_session->type;
+ } else {
+ /* it should not exist two session context are NULL */
+ IPC_ASSERT(KAL_FALSE);
+ }
+ } else if ((2 == p_netif->session_cnt) && (NULL != p_netif->session_map[1])) {
+ p_session = (ipc_session_t *)p_netif->session_map[1];
+ p_session->netif = (ipc_netif_t *)p_netif;
+ *p_ip_type = p_session->type;
+ } else {
+ /* it should not exist two session context are NULL */
+ IPC_ASSERT(KAL_FALSE);
+ }
+
+ hif_trace_info(IPC_TR_RESTORE_PDN_MAPPING, __FUNCTION__, p_session->context, p_netif->config.netif_id);
+
+ kal_mem_set(&g_saved_session_map[i], 0, sizeof(ipc_session_saved_map_t));
+ g_saved_session_map[i].is_saved = KAL_FALSE;
+ ret = KAL_TRUE;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static void ipc_session_delete_saved_map(ipc_session_t *p_session)
+{
+ kal_uint32 i = 0;
+ kal_uint32 idx = 0;
+ ipc_session_t *p_saved_session = NULL;
+
+ IPC_ASSERT(NULL != p_session);
+ IPC_R_LOCK_OBJECT(p_session, ipc_spinlock_g);
+
+ for (i = 0; i < IPC_SESSION_SAVED_MAP_NUM; i++) {
+ if (KAL_TRUE == g_saved_session_map[i].is_saved) {
+ if (0 < g_saved_session_map[i].session_cnt) {
+ idx = ipc_session_type_hash(p_session->type);
+ p_saved_session = (ipc_session_t *)g_saved_session_map[i].p_session_map[idx];
+ if (p_saved_session->context == p_session->context) {
+ /* unbind pdn matched saved pdn, we will delete it */
+ kal_mem_set(&g_saved_session_map[i], 0, sizeof(ipc_session_saved_map_t));
+ g_saved_session_map[i].is_saved = KAL_FALSE;
+ hif_trace_info(IPC_TR_DELETE_PDN_MAPPING, __FUNCTION__, p_session->context);
+ }
+ }
+ }
+ }
+
+ IPC_R_UNLOCK_OBJECT(p_session, ipc_spinlock_g);
+ return;
+}
+
+static void ipc_session_update_saved_map(ipc_session_t *p_old_session, kal_uint32 new_session_context)
+{
+ kal_uint32 i = 0;
+ kal_uint32 idx = 0;
+ ipc_session_t *p_saved_session = NULL;
+
+ IPC_ASSERT(NULL != p_old_session);
+ IPC_R_LOCK_OBJECT(p_old_session, ipc_spinlock_g);
+
+ for (i = 0; i < IPC_SESSION_SAVED_MAP_NUM; i++) {
+ if (KAL_TRUE == g_saved_session_map[i].is_saved) {
+ if (0 < g_saved_session_map[i].session_cnt) {
+ idx = ipc_session_type_hash(p_old_session->type);
+ p_saved_session = (ipc_session_t *)g_saved_session_map[i].p_session_map[idx];
+ if (p_saved_session->context == p_old_session->context) {
+ /* rebind pdn matched saved pdn, we will update it with new pdn */
+ p_saved_session->context = new_session_context;
+ hif_trace_info(IPC_TR_UPDATED_PDN_MAPPING, __FUNCTION__, p_saved_session->context, new_session_context);
+ }
+ }
+ }
+ }
+
+ IPC_R_UNLOCK_OBJECT(p_old_session, ipc_spinlock_g);
+ return;
+}
+
+ipc_netif_t *ipc_new_netif(ipc_conf_t *config)
+{
+ ipc_netif_t *netif;
+ kal_uint32 idx;
+
+ netif = ipc_find_netif(config->netif_id);
+ if (NULL == netif) {
+ for (idx = 0; idx < IPC_MAX_NETIF_CNT; idx++) {
+ netif = &(ipc_netifs_s[idx]);
+ if (!IPC_IS_VALID_OBJECT(netif)) {
+ IPC_INIT_OBJECT_BEGIN(netif, ipc_spinlock_g);
+
+ kal_mem_cpy( &(netif->config), config, sizeof(ipc_conf_t) );
+ netif->session_cnt = 0;
+ kal_mem_set( netif->session_map, 0, sizeof(netif->session_map) );
+
+ IPC_INIT_OBJECT_END(netif, ipc_spinlock_g);
+
+ ipc_set_netif_ul_reload_retry(netif, KAL_FALSE);
+ hif_trace_info(IPC_TR_NETIF_ATTACHED, config->module_id, config->netif_id);
+ return netif;
+ }
+ }
+ hif_trace_error(IPC_TR_NETIF_ATTACH_OUT_OF_SPACE, config->module_id, config->netif_id);
+ } else {
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ hif_trace_error(IPC_TR_NETIF_ATTACH_DUPLICATED, config->module_id, config->netif_id);
+ }
+
+ return NULL;
+}
+
+kal_bool ipc_del_netif(ipc_netif_t *netif)
+{
+ kal_uint32 idx;
+ ipc_session_t *session;
+
+ if (IPC_IS_VALID_OBJECT(netif)) {
+ ipc_set_netif_ul_reload_retry(netif, KAL_FALSE);
+ IPC_DEINIT_OBJECT_BEGIN(netif, ipc_spinlock_g);
+ IPC_ASSERT(netif);
+
+ for (idx = 0; idx < IPC_SESSION_MAP_SIZE; idx++) {
+ session = netif->session_map[idx];
+
+ IPC_W_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session)
+ {
+ if (netif->config.features & IPC_F_KEEP_PDN_MAPPING) {
+ if (KAL_FALSE == ipc_session_save_netif_map(netif, session->type)) {
+ hif_trace_error(IPC_TR_SAVED_PDN_MAPPING_FAILED, __FUNCTION__);
+ }
+ }
+
+ session->netif = NULL;
+ IPC_W_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+ }
+
+ hif_trace_info(IPC_TR_NETIF_DETACHED, netif->config.module_id, netif->config.netif_id);
+ IPC_DEINIT_OBJECT_END(netif, ipc_spinlock_g);
+ return KAL_TRUE;
+ } else {
+ hif_trace_error(IPC_TR_NETIF_DETACH_INVALID);
+ return KAL_FALSE;
+ }
+}
+
+kal_bool ipc_query_netif_list(ipc_netif_list_t *netif_list_p)
+{
+ ipc_netif_t *netif;
+ kal_uint32 idx;
+
+ IPC_ASSERT(netif_list_p);
+
+ hif_trace_info(IPC_TR_QUERY_NETIF_LIST_START, netif_list_p);
+ if (netif_list_p)
+ {
+ kal_mem_set(netif_list_p, 0, sizeof(ipc_netif_list_t));
+
+ for (idx = 0; idx < IPC_MAX_NETIF_CNT; idx++) {
+ netif = &(ipc_netifs_s[idx]);
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ netif_list_p->list[netif_list_p->netif_cnt].netif_id = netif->config.netif_id;
+ netif_list_p->netif_cnt ++;
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ hif_trace_info(IPC_TR_QUERY_NETIF_LIST_INFO, netif_list_p->netif_cnt,
+ netif_list_p->list[netif_list_p->netif_cnt-1].netif_id);
+ }
+ }
+
+ hif_trace_info(IPC_TR_QUERY_NETIF_LIST_SUCCESS, netif_list_p->netif_cnt);
+ return KAL_TRUE;
+ }
+ hif_trace_error(IPC_TR_QUERY_NETIF_LIST_FAILED);
+ return KAL_FALSE;
+}
+
+void ipc_update_link_up_ind_handler(module_type module_id)
+{
+ hif_trace_info(IPC_TR_UPDATE_LINK_UP_IND_HDLR_START, module_id);
+ ipc_link_up_indication_handler = module_id;
+}
+
+void ipc_update_ip_up_ind_handler(module_type module_id)
+{
+ hif_trace_info(IPC_TR_UPDATE_IP_UP_IND_HDLR_START, module_id);
+ ipc_ip_up_indication_handler = module_id;
+}
+
+void ipc_indicate_netif_link_change(ipc_netif_t *netif, kal_uint8 ip_type, kal_bool link_update, kal_bool is_up)
+{
+ ipc_link_handshake_msg_t *link_handshake_msg_p;
+ module_type src_mod_id;
+ module_type dest_mod_id;
+ msg_type message_type;
+ kal_uint32 netif_id;
+ kal_int32 ip_id;
+
+ if (NULL == netif) return;
+
+ /* IP CORE supports LINK_UP_IND / IP_UP_IND only */
+ IPC_ASSERT(KAL_TRUE == is_up);
+
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ netif_id = netif->config.netif_id;
+ ip_id = ipc_map_netif_to_ip_id(netif);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ link_handshake_msg_p = (ipc_link_handshake_msg_t *)construct_local_para(sizeof(ipc_link_handshake_msg_t), TD_RESET);
+ IPC_ASSERT(link_handshake_msg_p);
+
+ link_handshake_msg_p->netif_id = netif_id;
+ link_handshake_msg_p->ip_id = ip_id;
+ link_handshake_msg_p->ip_type = ip_type;
+
+ if (KAL_TRUE == link_update)
+ { /* To update Link status */
+ src_mod_id = (MOD_IPCORE == ipc_link_up_indication_handler)?MOD_NIL:MOD_IPCORE;
+ dest_mod_id = ipc_link_up_indication_handler;
+ message_type = MSG_ID_IPCORE_LINK_UP_IND;
+ } else
+ { /* To update IP status */
+ src_mod_id = (MOD_IPCORE == ipc_ip_up_indication_handler)?MOD_NIL:MOD_IPCORE;
+ dest_mod_id = ipc_ip_up_indication_handler;
+ message_type = MSG_ID_IPCORE_IP_UP_IND;
+ }
+
+ msg_send6(src_mod_id, /* src_mod_id */
+ dest_mod_id, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ message_type, /* msg_id */
+ (struct local_para_struct *)link_handshake_msg_p, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ }
+}
+
+void ipc_notify_netif_link_change(ipc_netif_t *netif, kal_uint8 ip_type, kal_bool link_update, kal_bool is_up)
+{
+ ipc_link_req_t *p_link_req = NULL;
+ void *p_context = NULL;
+ module_type module_id = 0;
+ msg_type message_type = 0;
+ ipc_ntfy_type_e notify_type = IPC_NTFY_TYPE_INVALID;
+
+ if (NULL == netif) {
+ return;
+ }
+
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ p_context = netif->config.callback_context;
+ module_id = netif->config.module_id;
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ p_link_req = (ipc_link_req_t *)construct_local_para(sizeof(ipc_link_req_t), TD_RESET);
+ IPC_ASSERT(p_link_req);
+
+ p_link_req->callback_context = p_context;
+ p_link_req->ip_type = ip_type;
+
+ if (KAL_TRUE == link_update) {
+ /* To update Link status */
+ message_type = is_up ? MSG_ID_IPCORE_LINK_UP_REQ : MSG_ID_IPCORE_LINK_DOWN_REQ;
+ notify_type = is_up ? IPC_NTFY_TYPE_LINK_UP : IPC_NTFY_TYPE_LINK_DOWN;
+ } else {
+ /* To update IP status */
+ message_type = is_up ? MSG_ID_IPCORE_IP_UP_REQ : MSG_ID_IPCORE_IP_DOWN_REQ;
+ notify_type = is_up ? IPC_NTFY_TYPE_IP_UP : IPC_NTFY_TYPE_IP_DOWN;
+ }
+
+ /* Callback for notifications */
+ ipc_ntfy_do_event_cbk(netif, notify_type);
+
+#ifdef ATEST_SYS_IPCORE
+ ipc_ut_msg_send6(MOD_IPCORE, /* src_mod_id */
+ module_id, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ message_type, /* msg_id */
+ (struct local_para_struct *) p_link_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+#else
+ msg_send6(MOD_IPCORE, /* src_mod_id */
+ module_id, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ message_type, /* msg_id */
+ (struct local_para_struct *)p_link_req, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+#endif
+ }
+
+ return;
+}
+
+void ipc_notify_all_netif_link_change(kal_uint8 ip_type, kal_bool link_up)
+{
+ kal_uint32 idx;
+ ipc_netif_t *netif;
+
+ for (idx = 0; idx < IPC_MAX_NETIF_CNT; idx++) {
+ netif = &(ipc_netifs_s[idx]);
+
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+
+ ipc_notify_netif_link_change(netif, ip_type, KAL_TRUE, link_up);
+ }
+ }
+}
+
+kal_int32 ipc_map_netif_to_ip_id(ipc_netif_t *netif)
+{
+ ipc_session_t *session;
+ kal_uint32 idx;
+ kal_int32 ip_id;
+
+ IPC_ASSERT(IPC_IS_VALID_OBJECT(netif));
+
+ if (netif->session_cnt > 0) {
+ for (idx = 0; idx < IPC_SESSION_MAP_SIZE; idx++) {
+ session = netif->session_map[idx];
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ ip_id = session->ip_id;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ return ip_id;
+ }
+ }
+ }
+
+ return -1;
+}
+
+kal_int32 ipc_map_netif_to_pdn_id(ipc_netif_t *netif, kal_uint8 ip_type)
+{
+ ipc_session_t *session = NULL;
+ kal_uint32 pdn_id = 0;
+ kal_uint32 idx = 0;
+
+ IPC_ASSERT(IPC_IS_VALID_OBJECT(netif));
+
+ if (netif->session_cnt > 0) {
+ idx = ipc_session_type_hash(ip_type);
+
+ if ((0 <= idx) && (idx < 2)) {
+ session = netif->session_map[idx];
+ } else {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ return IPC_INVALID_PDN_ID;
+ }
+
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ pdn_id = session->context;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ return pdn_id;
+ }
+ }
+
+ return IPC_INVALID_PDN_ID;
+}
+
+void ipc_set_netif_ul_reload_retry(ipc_netif_t *netif, kal_bool need_ul_reload)
+{
+ kal_uint64 netif_bit_id = netif->bit_id;
+ kal_uint64 set_reload;
+
+ IPC_ASSERT(IPC_IS_VALID_OBJECT(netif));
+
+ hif_data_trace(MD_TRC_IPC_UL_RELOAD_RETRY, need_ul_reload, netif, netif->config.netif_id, netif->config.ipc_ul_reload_callback_t, ipc_netif_ul_set_need_reload_s);
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+
+ /*
+ * Check if netif_ul_set_need_reload has been set
+ * since the last time IPCORE called the netif reload cbk.
+ */
+ set_reload = ipc_netif_ul_set_need_reload_s & netif_bit_id;
+ if ( ((need_ul_reload) || (set_reload)) &&
+ (netif->config.ipc_ul_reload_callback_t) )
+ {
+ ipc_netif_ul_reload_retry_s |= (netif_bit_id);
+ } else
+ {
+ ipc_netif_ul_reload_retry_s &= (~(netif_bit_id));
+ }
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ if ((!need_ul_reload) && (set_reload))
+ {
+ hif_data_trace(MD_TRC_IPC_UL_RELOAD_RETRY_RACE_COND, 0, need_ul_reload, set_reload, ipc_netif_ul_reload_retry_s);
+ } else
+ {
+ hif_data_trace(MD_TRC_IPC_UL_RELOAD_RETRY_FLAG, 0, ipc_netif_ul_reload_retry_s, ipc_netif_ul_set_need_reload_s);
+ }
+}
+
+void ipc_set_netif_ul_set_need_reload(ipc_netif_t *netif, kal_bool need_ul_reload)
+{
+ kal_uint64 netif_bit_id = netif->bit_id;
+
+ IPC_ASSERT(IPC_IS_VALID_OBJECT(netif));
+
+ hif_data_trace(MD_TRC_IPC_UL_SET_NEED_RELOAD, need_ul_reload, netif, netif->config.netif_id, netif->config.ipc_ul_reload_callback_t);
+
+ IPC_SPIN_LOCK(ipc_spinlock_g);
+ if ((need_ul_reload) && (netif->config.ipc_ul_reload_callback_t))
+ {
+ ipc_netif_ul_set_need_reload_s |= (netif_bit_id);
+ } else
+ {
+ ipc_netif_ul_set_need_reload_s &= (~(netif_bit_id));
+ }
+ IPC_SPIN_UNLOCK(ipc_spinlock_g);
+
+ hif_data_trace(MD_TRC_IPC_UL_SET_NEED_RELOAD_FLAG, 0, ipc_netif_ul_set_need_reload_s);
+}
+
+kal_uint64 ipc_get_all_netif_ul_reload_retry(void)
+{
+ return ipc_netif_ul_reload_retry_s;
+}
+
+kal_bool ipc_update_session_state(ipc_session_t *session, ipc_session_state_e session_state)
+{
+ ipc_session_state_e org_session_state;
+ ipc_netif_t *netif;
+ kal_uint8 type;
+ kal_bool retval = KAL_TRUE;
+
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_START, session, session_state);
+
+ if (session)
+ {
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session)
+ {
+ org_session_state = session->state;
+ netif = session->netif;
+ type = session->type;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_ORG_AND_NEW, session, type, netif, org_session_state, session_state);
+
+ /* Update state */
+ IPC_W_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ session->state = session_state;
+ IPC_W_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_TRANSITION_SUCCESS, session, session_state);
+ } else
+ { /* Session write fail */
+ hif_trace_error(IPC_TR_UPDATE_SESSION_STATE_WRITE_FAIL, session, session_state);
+ IPC_ASSERT(0);
+ retval = KAL_FALSE;
+ }
+
+ /* Run corresponding state transition action */
+ if ( (org_session_state > IPC_SESSION_STATE_MIN) &&
+ (org_session_state < IPC_SESSION_STATE_MAX) &&
+ (session_state > IPC_SESSION_STATE_MIN) &&
+ (session_state < IPC_SESSION_STATE_MAX) )
+ {
+ switch (session_transition_action_table[org_session_state][session_state])
+ {
+ case IPC_SST_NA:
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_SST_NA, session, org_session_state, session_state);
+ break;
+ case IPC_SST_LUI:
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_SST_LUI, session, org_session_state, session_state);
+ ipc_indicate_netif_link_change(netif, type, KAL_TRUE, KAL_TRUE);
+ break;
+ case IPC_SST_LUR:
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_SST_LUR, session, org_session_state, session_state, netif, type);
+ ipc_notify_netif_link_change(netif, type, KAL_TRUE, KAL_TRUE);
+ break;
+ case IPC_SST_LDR:
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_SST_LDR, session, org_session_state, session_state, netif, type);
+ ipc_notify_netif_link_change(netif, type, KAL_TRUE, KAL_FALSE);
+ break;
+ case IPC_SST_IUI:
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_SST_IUI, session, org_session_state, session_state);
+ ipc_indicate_netif_link_change(netif, type, KAL_FALSE, KAL_TRUE);
+ break;
+ case IPC_SST_IUR:
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_SST_IUR, session, org_session_state, session_state, netif, type);
+ ipc_notify_netif_link_change(netif, type, KAL_FALSE, KAL_TRUE);
+ break;
+ case IPC_SST_IDR:
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_SST_IDR, session, org_session_state, session_state, netif, type);
+ ipc_notify_netif_link_change(netif, type, KAL_FALSE, KAL_FALSE);
+ break;
+ default:
+ /* Illegal state transition */
+ hif_trace_error(IPC_TR_UPDATE_SESSION_STATE_ILLEGAL_TRANSITION, session, org_session_state, session_state, session_transition_action_table[org_session_state][session_state]);
+ IPC_ASSERT(0);
+ retval = KAL_FALSE;
+ }
+ } else
+ { /* Invalid state */
+ hif_trace_error(IPC_TR_UPDATE_SESSION_STATE_OUT_OF_RANGE, session, org_session_state, session_state, IPC_SESSION_STATE_MIN, IPC_SESSION_STATE_MAX);
+ IPC_ASSERT(0);
+ retval = KAL_FALSE;
+ }
+
+ } else
+ { /* Session read fail */
+ hif_trace_error(IPC_TR_UPDATE_SESSION_STATE_READ_FAIL, session);
+ retval = KAL_FALSE;
+ }
+ }else
+ { /* Session check fail */
+ hif_trace_error(IPC_TR_UPDATE_SESSION_STATE_CHK_FAIL, session);
+ retval = KAL_FALSE;
+ }
+
+ hif_trace_info(IPC_TR_UPDATE_SESSION_STATE_END, session, session_state, retval);
+
+ return retval;
+}
+
+ipc_session_t *ipc_find_session_by_context(kal_uint32 session_context)
+{
+ ipc_session_t *session;
+
+ IPC_CONTEXT_TO_SESSION(session_context, session);
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ IPC_ASSERT(session->context == session_context);
+ return session;
+ }
+ return NULL;
+}
+
+ipc_session_t *ipc_find_session_by_netif(ipc_netif_t *netif, kal_uint8 session_type)
+{
+ kal_uint32 idx;
+ ipc_session_t *session;
+ ipc_netif_t *netif_local;
+
+ session = NULL;
+ netif_local = netif;
+
+ IPC_R_LOCK_OBJECT(netif_local, ipc_spinlock_g);
+ if (netif_local)
+ {
+ idx = ipc_session_type_hash((session_type == IPC_IP_TYPE_MIXED) ? IPC_IP_TYPE_IPV4: session_type);
+ IPC_ASSERT(idx < IPC_SESSION_MAP_SIZE);
+ session = netif_local->session_map[idx];
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ IPC_R_UNLOCK_OBJECT(netif_local, ipc_spinlock_g);
+ }
+
+ return session;
+}
+
+ipc_session_t *ipc_find_session_by_ip_id(kal_int32 ip_id, kal_uint8 session_type)
+{
+ ipc_netif_t *netif;
+ ipc_session_t *session;
+ ipc_session_t *session_found = NULL;
+ kal_uint32 idx1, idx2;
+
+ IPC_ASSERT(0 <= ip_id);
+
+ for (idx1 = 0; idx1 < IPC_MAX_NETIF_CNT && NULL == session_found; idx1++) {
+ netif = &(ipc_netifs_s[idx1]);
+
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+
+ idx2 = ipc_session_type_hash((session_type == IPC_IP_TYPE_MIXED) ? IPC_IP_TYPE_IPV4: session_type);
+ session = netif->session_map[idx2];
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (session) {
+ if ( session->ip_id == ip_id) {
+ session_found = session;
+ /*
+ * Caller is expected to release session's read lock,
+ * so don't release it here.
+ */
+ } else {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ }
+ }
+
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+ }
+
+ return session_found;
+}
+
+ipc_session_t *ipc_new_session_internal(ipc_netif_t *netif, kal_uint32 session_context, kal_uint8 session_type, ipc_session_state_e session_state, kal_int32 ip_id)
+{
+ ipc_session_t *session = NULL;
+ kal_uint32 idx = 0;
+
+ IPC_ASSERT(IPC_IS_VALID_OBJECT(netif));
+ IPC_ASSERT(session_type == IPC_IP_TYPE_IPV4 ||
+ session_type == IPC_IP_TYPE_IPV6 ||
+ session_type == IPC_IP_TYPE_MIXED );
+ IPC_ASSERT((session_state > IPC_SESSION_STATE_MIN) &&
+ (session_state < IPC_SESSION_STATE_MAX));
+
+ hif_trace_info(IPC_TR_SESSION_BIND_START, session_context, session_type, session_state);
+
+ /*
+ * If netif already bind session, return NULL directly
+ */
+ if (session_type == IPC_IP_TYPE_MIXED) {
+ if (netif->session_map[0] || netif->session_map[1]) {
+ hif_trace_error(IPC_TR_SESSION_BIND_NETIF_BOUND_MIXED,
+ netif,
+ netif->config.netif_id,
+ netif->session_map[ipc_session_type_hash(IPC_IP_TYPE_IPV4)],
+ netif->session_map[ipc_session_type_hash(IPC_IP_TYPE_IPV6)],
+ session_context,
+ session_type,
+ session_state);
+ return NULL;
+ }
+ } else {
+ idx = ipc_session_type_hash(session_type);
+ if (netif->session_map[idx]) {
+ hif_trace_error(IPC_TR_SESSION_BIND_NETIF_BOUND_SPECIFIC_IP_VER,
+ netif,
+ netif->config.netif_id,
+ netif->session_map[ipc_session_type_hash(IPC_IP_TYPE_IPV4)],
+ netif->session_map[ipc_session_type_hash(IPC_IP_TYPE_IPV6)],
+ session_context,
+ session_type,
+ session_state);
+ return NULL;
+ }
+ }
+
+ /*
+ * Allocate and configure new session
+ */
+ session = ipc_find_session_by_context(session_context);
+ if (NULL == session) {
+ IPC_CONTEXT_TO_SESSION(session_context, session);
+ if (!IPC_IS_VALID_OBJECT(session)) {
+ IPC_INIT_OBJECT_BEGIN(session, ipc_spinlock_g);
+
+ session->context = session_context;
+ session->type = session_type;
+ session->dhcp4c_running = KAL_FALSE;
+ session->dhcp4c_id = 0xff;
+ session->dhcp4c_dl_filter_id = -1;
+ session->ip_id = (ip_id == -1) ? ipc_new_id(netif) : ip_id;
+ session->netif = netif;
+ session->state = session_state;
+
+ /*
+ * If there's no IP session conflict (i.e. the same type),
+ * no need to acquire a write lock on netif.
+ */
+ if (session_type != IPC_IP_TYPE_MIXED) {
+ idx = ipc_session_type_hash(session_type);
+ IPC_ASSERT(netif->session_map[idx] == NULL);
+ netif->session_map[idx] = session;
+ netif->session_cnt++;
+ } else {
+ IPC_ASSERT(netif->session_map[0] == NULL && netif->session_map[1] == NULL);
+ netif->session_map[0] = session;
+ netif->session_map[1] = session;
+ netif->session_cnt += 2;
+ }
+
+ IPC_INIT_OBJECT_END(session, ipc_spinlock_g);
+ hif_trace_info(IPC_TR_SESSION_BOUND, session_context, session_type, session_state, session->ip_id);
+ return session;
+ } else {
+ hif_trace_error(IPC_TR_SESSION_BIND_OUT_OF_SPACE, session_context, session_type,session_state);
+ }
+ } else {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ hif_trace_error(IPC_TR_SESSION_BIND_DUPLICATED, session_context, session_type, session_state);
+ }
+
+ return NULL;
+}
+
+ipc_session_t *ipc_new_session(ipc_netif_t *netif, kal_uint32 session_context, kal_uint8 session_type, ipc_session_state_e session_state)
+{
+ return ipc_new_session_internal(netif, session_context, session_type, session_state, -1);
+}
+
+void ipc_del_session_internal(ipc_session_t *session, kal_bool to_del_ip_id)
+{
+ ipc_netif_t *netif;
+ kal_uint32 idx;
+
+ IPC_DEINIT_OBJECT_BEGIN(session, ipc_spinlock_g);
+ if (session) {
+
+ netif = session->netif;
+ IPC_W_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ if (session->type != IPC_IP_TYPE_MIXED) {
+ idx = ipc_session_type_hash(session->type);
+ IPC_ASSERT(netif->session_map[idx] == session);
+ netif->session_map[idx] = NULL;
+ netif->session_cnt--;
+ } else {
+ IPC_ASSERT(netif->session_map[0] == session && netif->session_map[1] == session);
+ netif->session_map[0] = NULL;
+ netif->session_map[1] = NULL;
+ netif->session_cnt = 0;
+ }
+ if (to_del_ip_id) {
+ to_del_ip_id = (netif->session_cnt == 0);
+ }
+
+ IPC_W_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ }
+
+ if (to_del_ip_id) {
+ ipc_del_id(session->ip_id);
+ }
+
+ hif_trace_info(IPC_TR_SESSION_DEACTIVATED, session->context, session->type, session->ip_id);
+ IPC_DEINIT_OBJECT_END(session, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_SESSION_DEACTIVATE_INVALID_SESSION);
+ }
+}
+
+void ipc_del_session(ipc_session_t *session)
+{
+ ipc_session_delete_saved_map(session);
+ ipc_del_session_internal(session, KAL_TRUE);
+}
+
+ipc_session_t *ipc_replace_session(ipc_netif_t *netif, ipc_session_t *old_session, kal_uint32 new_session_context, kal_uint8 new_session_type, ipc_session_state_e new_session_state)
+{
+ kal_int32 ip_id;
+ ipc_session_t *new_session;
+
+ hif_trace_info(IPC_TR_SESSION_BIND_START, new_session_context, new_session_type, new_session_state);
+
+ IPC_R_LOCK_OBJECT(old_session, ipc_spinlock_g);
+ if (old_session) {
+ ip_id = old_session->ip_id;
+ IPC_R_UNLOCK_OBJECT(old_session, ipc_spinlock_g);
+
+ ipc_session_update_saved_map(old_session, new_session_context);
+ ipc_del_session_internal(old_session, KAL_FALSE);
+ new_session = ipc_new_session_internal(netif, new_session_context, new_session_type, new_session_state, ip_id);
+ if (!new_session) {
+ /* Replace session failed. Need to check whether to delete ip_id or not. */
+ IPC_R_LOCK_OBJECT(netif, ipc_spinlock_g);
+ if (netif) {
+ if (netif->session_cnt == 0) {
+ ipc_del_id(ip_id);
+ }
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ } else {
+ hif_trace_error(IPC_TR_SESSION_REPLACE_NETIF_RLOCK_FAIL);
+ }
+
+ return NULL;
+ }
+
+ hif_trace_info(IPC_TR_SESSION_REPLACED, new_session_context, new_session_type, new_session_state, ip_id);
+ return new_session;
+ } else {
+ hif_trace_error(IPC_TR_SESSION_REPLACE_SESSION_RLOCK_FAIL);
+ }
+
+ return NULL;
+}
diff --git a/mcu/middleware/hif/ipcore/src/ipc_task.c b/mcu/middleware/hif/ipcore/src/ipc_task.c
new file mode 100644
index 0000000..fd1a579
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_task.c
@@ -0,0 +1,307 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_task.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IP Core task implementation.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "ipc_defs.h"
+#include "ipc_debug.h"
+#include "ipc_utils.h"
+#include "ipc_data.h"
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+#define IPC_MOD_CNT (sizeof(ipc_module_list_g) / sizeof(module_type))
+
+/*------------------------------------------------------------------------------
+ * Private data structure.
+ *----------------------------------------------------------------------------*/
+typedef kal_bool (*ipc_init_func_t)(void);
+typedef void (*ipc_on_ilm_func_t)(ilm_struct *);
+typedef kal_bool (*ipc_on_reset_func_t)(void);
+
+/*------------------------------------------------------------------------------
+ * Private variables.
+ *----------------------------------------------------------------------------*/
+module_type ipc_module_list_g[] = {
+ #undef IPC_MODULE_ID
+ #undef IPC_MODULE_PREFIX
+ #define IPC_MODULE_ID(_id) _id,
+ #define IPC_MODULE_PREFIX(_prefix)
+ #include "ipc_config.h"
+
+ MOD_IPCORE,
+};
+
+/*
+ * Note, each module in IP Core task with prefix xyz must implement the following functions:
+ *
+ * 1. module initializeation function:
+ * kal_bool xyz_init(void);
+ *
+ * 2. ilm handler:
+ * void xyz_on_ilm(ilm_struct *ilm);
+ *
+ * 3. reset handler:
+ * kal_bool xyz_reset(void);
+ */
+#undef IPC_MODULE_ID
+#undef IPC_MODULE_PREFIX
+#define IPC_MODULE_ID(_id)
+#define IPC_MODULE_PREFIX(_prefix) extern kal_bool _prefix ## _init (void);
+#include "ipc_config.h"
+
+const ipc_init_func_t ipc_init_func_list_g[] = {
+ #undef IPC_MODULE_ID
+ #undef IPC_MODULE_PREFIX
+ #define IPC_MODULE_ID(_id)
+ #define IPC_MODULE_PREFIX(_prefix) _prefix ## _init,
+ #include "ipc_config.h"
+
+ ipc_init,
+};
+
+#undef IPC_MODULE_ID
+#undef IPC_MODULE_PREFIX
+#define IPC_MODULE_ID(_id)
+#define IPC_MODULE_PREFIX(_prefix) extern void _prefix ## _on_ilm (ilm_struct *ilm);
+#include "ipc_config.h"
+
+const ipc_on_ilm_func_t ipc_ilm_func_list_g[] = {
+ #undef IPC_MODULE_ID
+ #undef IPC_MODULE_PREFIX
+ #define IPC_MODULE_ID(_id)
+ #define IPC_MODULE_PREFIX(_prefix) _prefix ## _on_ilm,
+ #include "ipc_config.h"
+
+ ipc_on_ilm,
+};
+
+#undef IPC_MODULE_ID
+#undef IPC_MODULE_PREFIX
+#define IPC_MODULE_ID(_id)
+#define IPC_MODULE_PREFIX(_prefix) extern kal_bool _prefix ## _reset (void);
+#include "ipc_config.h"
+
+const ipc_on_reset_func_t ipc_reset_func_list_g[] = {
+ #undef IPC_MODULE_ID
+ #undef IPC_MODULE_PREFIX
+ #define IPC_MODULE_ID(_id)
+ #define IPC_MODULE_PREFIX(_prefix) _prefix ## _reset,
+ #include "ipc_config.h"
+
+ ipc_reset,
+};
+
+/*------------------------------------------------------------------------------
+ * Private fucntions.
+ *----------------------------------------------------------------------------*/
+static kal_bool ipc_task_init(void)
+{
+ kal_uint32 idx;
+ kal_bool ret = KAL_TRUE;;
+
+ for (idx = 0; idx < IPC_MOD_CNT; ++idx) {
+ ret = ipc_init_func_list_g[idx]();
+ if (!ret) {
+ break;
+ }
+ }
+ return ret;
+}
+
+void ipc_dispatch_ilm(ilm_struct *ilm)
+{
+ kal_uint32 idx;
+
+ for (idx = 0; idx < IPC_MOD_CNT; ++idx) {
+ if (ilm->dest_mod_id == ipc_module_list_g[idx]) {
+ /*
+ * Switch to active module.
+ */
+ kal_set_active_module_id(ilm->dest_mod_id);
+
+ /*
+ * Dispatch ILM according to dest_mod_id.
+ */
+ ipc_ilm_func_list_g[idx](ilm);
+ break;
+ }
+ }
+
+ if (IPC_MOD_CNT == idx) {
+ /*
+ * Wrong destination.
+ */
+ hif_trace_error(IPC_TR_ILM_WRONG_DEST_MOD, ilm->dest_mod_id);
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(ilm);
+}
+
+static void ipc_task_main(task_entry_struct *task_entry_ptr)
+{
+ ilm_struct current_ilm;
+
+#if IPC_PEER==IPC_PEER_NULL_DROP || IPC_PEER==IPC_PEER_NULL_LOOPBACK
+ ipc_notify_all_netif_link_change(IPC_IP_TYPE_MIXED, KAL_TRUE);
+#endif
+
+ while (1) {
+ /*
+ * Receive message from ext queue, this may suspend.
+ */
+ if (KAL_TRUE == msg_receive_extq(¤t_ilm)) {
+ ipc_dispatch_ilm(¤t_ilm);
+ while (msg_receive_intq(¤t_ilm)){
+ ipc_dispatch_ilm(¤t_ilm);
+ }
+ }
+ }
+}
+
+#ifndef ATEST_SYS_IPCORE
+static
+#endif
+kal_bool ipc_task_reset(void)
+{
+ kal_uint32 idx;
+ kal_bool ret = KAL_TRUE;
+
+ for (idx = 0; idx < IPC_MOD_CNT; ++idx) {
+ ret = ipc_reset_func_list_g[idx]();
+ if (!ret) {
+ break;
+ }
+ }
+ return ret;
+}
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+kal_bool ipc_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct info =
+ {
+ ipc_task_main, /* task entry function */
+ ipc_task_init, /* task initialization function */
+ ipc_task_reset, /* task reset handler */
+ };
+
+ *handle = (comptask_handler_struct *)&info;
+ return KAL_TRUE;
+}
diff --git a/mcu/middleware/hif/ipcore/src/ipc_task_clean.c b/mcu/middleware/hif/ipcore/src/ipc_task_clean.c
new file mode 100644
index 0000000..1d8fa18
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_task_clean.c
@@ -0,0 +1,26 @@
+/*
+ * ipc_task_clean.c
+ *
+ * Created on: 2018/10/24
+ * Author: MTK15439
+ */
+
+#include "ipc_defs.h"
+#if defined(__MDDP_WH_SUPPORT__) || defined(__MDDP_USB_SUPPORT__)
+#include "dpfm_api.h"
+#endif
+
+void IPCore_Task_Clean_Handler(void)
+{
+#if defined(__SENSITIVE_DATA_MOSAIC__)
+ ipc_module_clean();
+ upcm_module_clean();
+#if defined(__MDDP_WH_SUPPORT__) || defined(__MDDP_USB_SUPPORT__)
+ dpfm_module_clean();
+#endif
+#ifdef __DISPATCHER_SUPPORT__
+ dispatcher_module_clean();
+#endif
+#endif
+}
+
diff --git a/mcu/middleware/hif/ipcore/src/ipc_ut.c b/mcu/middleware/hif/ipcore/src/ipc_ut.c
new file mode 100644
index 0000000..8f32406
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_ut.c
@@ -0,0 +1,26211 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_ut.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IPCORE unit test implementation.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifdef ATEST_SYS_IPCORE
+
+#include "kal_public_api.h"
+#include "sysservice_msgid.h"
+#include "intrCtrl.h"
+#include "sys_test.h"
+
+#include "upcm.h"
+#include "ipcore_upcm_struct.h"
+#include "upcm_msgid.h"
+#include "l4c_ipcore_struct.h"
+#include "l4_msgid.h"
+#include "dispatcher_msgid.h"
+#if defined(__LTM_SIMULATION_SUPPORT__)
+ #include "lms_api.h"
+#endif
+
+#include "dhcp4c_struct.h"
+#include "ipc_dhcp_adp.h"
+#include "mw_sap.h"
+#include "md_sap.h"
+#include "hif_mw_msgid.h"
+#include "dpcopro_custom.h"
+
+#include "nmu_util.h"
+#include "hmu.h"
+
+#include "ipc_defs.h"
+#include "ipc_debug.h"
+#include "ipc_utils.h"
+#include "ipc_filter.h"
+#include "ipc_enums.h"
+#include "ipc_data.h"
+#include "ipc_data_ipf.h"
+#include "sim_public_enum.h"
+
+#include "ccci_ipc_msgid.h"
+#include "pfm_api.h"
+#include "pfm_struct.h"
+#include "pfm_defs.h"
+#include "pfm_enums.h"
+#include "tmc_struct.h"
+
+#ifdef __SE7_SD8_AUTO_UT__
+ #define IPC_UT_LOG_LV 3
+#else
+ #define IPC_UT_LOG_LV 2
+#endif
+#define IPC_UT_MAX_NET_CNT 3
+#define IPC_UT_NETID_START 0x1A
+#define IPC_UT_LHIF_NETID_START 0x41A
+#define IPC_UT_DPFM_NETID_START 0x11A
+#define IPC_UT_BAD_NETIF_ID 0xc9
+#define IPC_UT_PDN_ID 0xf
+#define IPC_UT_PDN_ID_2 0xe
+#define IPC_UT_MSG_LATENCY (1 * KAL_MILLISECS_PER_TICK)
+#define IPC_UT_INVALID_IP_ID IPC_MAX_IP_ID_CNT
+#define IPC_UT_UL_EBI 0x1F
+#define IPC_UT_DL_EBI 0x1F
+#define IPC_UT_LOW_PRIORITY 3
+#define IPC_UT_MID_PRIORITY 2
+#define IPC_UT_HIGH_PRIORITY 1
+
+#define IPC_UT_GEN_INVALID_LEN_PKT 1
+#define IPC_INVALID_MAX_PKT_LEN 2048
+#define IPC_INVALID_PKT_LEN1 1501
+#define IPC_INVALID_PKT_LEN2 1502
+#define IPC_INVALID_PKT_LEN3 1503
+
+#define IPC_UT_INVALID_PKT_CASE 5
+#define IPC_UT_INVALID_PKT_CNT 5
+
+#define IPC_UT_SPD_RING_BUFFER_SIZE 20480 //(IPC_INVALID_MAX_PKT_LEN * IPC_UT_INVALID_PKT_CNT * 2)
+#define IPC_UT_META_TABLE_SIZE 20
+#define IPC_UT_DID_TABLE_SIZE 2
+#define IPC_UT_DID_MAX_SIT_NUM 30
+#define IPC_UT_DID_MAX_DATA_BUF_NUM 60 //(IPC_UT_DID_TABLE_SIZE * IPC_UT_DID_MAX_SIT_NUM)
+
+#define IPC_UT_INVALID_UL_PROTO_IDX -1
+
+#define IPC_UT_META_MATCH_IDX 5
+#define IPC_UT_RBID_MAX_NUM 37
+
+#define IPC_UT_HW_FLTR_TOTAL_NUM IPC_MAX_FILTER_CNT
+#define IPC_UT_HW_FLTR_PER_ENT_SIZE 16 //each entry 16B
+#define IPC_UT_HW_FLTR_BUF_SIZE (IPC_UT_HW_FLTR_TOTAL_NUM*IPC_UT_HW_FLTR_PER_ENT_SIZE)
+#define IPC_UT_EA_MAX_CASE_NUM 3
+#define IPC_UT_IPV4_TCP_EA_LEN 40
+#define IPC_UT_IPV6_TCP_EA_LEN 20
+#define IPC_UT_INAVLID_PRIV_DATA -1
+
+#define IPC_UT_IPV6_DPFM_SRC_PORT 0x222
+#define IPC_UT_IPV6_DPFM_DST_PORT 0x223
+
+typedef enum {
+ IPC_UT_STAGE_BEFORE_BINDING = 0,
+ IPC_UT_STAGE_BINDING,
+ IPC_UT_STAGE_UNBINDING
+} ipc_ut_test_stage_e;
+
+typedef enum {
+ IPC_UT_SPD_AT_THE_HEAD_OF_LIST = 0,
+ IPC_UT_SPD_AT_THE_END_OF_LIST = 1,
+ IPC_UT_SPD_IN_THE_MIDDLE_OF_LIST = 2
+} ipc_ut_spd_position_e;
+
+typedef struct {
+ ipc_conf_t conf;
+ ipc_handle_t handle;
+
+ kal_uint8 pdn_id;
+ kal_uint8 ip_type;
+ kal_bool need_retry;
+ kal_bool ul_reload_called;
+
+ ipc_session_t *session[3]; // 0: v4v6, 1: v4, 2: v6
+} ipc_ut_netif_t;
+
+typedef struct {
+ ipc_filter_rules_t rules;
+ kal_int32 filter_id;
+} ipc_ut_filter_info_t;
+
+typedef struct {
+ /* Content */
+ module_type _src_mod_id;
+ module_type _dest_mod_id;
+ sap_type _sap_id;
+ msg_type _msg_id;
+ local_para_struct *_local_para_ptr;
+ peer_buff_struct *_peer_buff_ptr;
+
+ /* Trigger count */
+ kal_int32 _trigger_cnt;
+} ipc_ut_msg_t;
+
+#define IPC_UT_NTFY_PARAM_MAX_COUNT (IPC_NTFY_TYPE_MAX * IPC_MAX_NTFY_CNT * IPC_MAX_NETIF_CNT)
+typedef struct {
+ kal_int32 count;
+ ipc_ntfy_param_t params[IPC_UT_NTFY_PARAM_MAX_COUNT];
+} ipc_ut_ntfy_param_t;
+
+typedef struct {
+ kal_int32 count;
+ kal_bool ntfy_valid[IPC_MAX_NTFY_CNT];
+ kal_int32 ntfy_context[IPC_MAX_NTFY_CNT];
+ kal_int32 ntfy_id[IPC_MAX_NTFY_CNT];
+} ipc_ut_ntfy_info_t;
+
+typedef struct {
+ kal_int32 filter_id;
+ kal_uint8 ip_type;
+ kal_uint8 protocol;
+ kal_uint16 dst_port;
+ kal_uint32 magic_code;
+} ipc_ut_garbage_filter_t;
+
+typedef enum {
+ IPC_UT_LHIF_META_AP0 = 0,
+ IPC_UT_IPF_DL_0,
+ IPC_UT_META_QUEUE_NUM_MAX,
+}ipc_ut_meta_type_e;
+
+typedef struct {
+ kal_uint32 type_idx;
+ kal_uint8 *base_addr;
+ kal_uint8 read_idx;
+ kal_uint8 write_idx;
+ kal_uint8 *buff_addr_base;
+}ipc_ut_meta_queue_t;
+
+typedef struct tmc_ut_ul_thrott {
+ kal_uint8 ctrl_cmd; /* tmc_ctrl_cmd_enum */
+ kal_uint8 thrott_ctrl; /* tmc_throt_ctrl_enum */
+ kal_uint8 active_period_100ms;
+ kal_uint8 suspend_period_100ms;
+} tmc_ut_ul_thrott;
+
+typedef struct ipc_ut_unk_hdr_stats_t {
+ kal_bool is_valid;
+ kal_uint32 unk_hdr_cnt;
+ kal_uint16 begin_cntl;
+ kal_uint16 end_cntl;
+ kal_uint16 rb_idx;
+ kal_uint16 protocol_idx;
+} ipc_ut_unk_hdr_stats_t;
+
+extern kal_bool ipc_reset(void);
+extern kal_bool ipc_task_reset(void);
+extern void ipc_on_retry_ul_reload(void);
+extern void ipc_dest_ior(ipc_io_request_t *ior);
+extern void ipc_on_downlink(kal_uint32 pdn_id, qbm_gpd *p_head, qbm_gpd *p_tail);
+extern void ipc_on_lte_tick_source(kal_bool is_lte_tick);
+extern void ipc_on_pdn_bind_top(module_type src_mod_id, local_para_struct *local_para_ptr);
+extern void ipc_on_query_info(module_type src_mod_id, local_para_struct *local_para_ptr);
+extern void ipc_on_pdn_unbind(local_para_struct *local_para_ptr);
+extern void ipc_notify_all_netif_link_change(kal_uint8 ip_type, kal_bool link_up);
+#if defined(__MD93__)
+extern void tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(kal_uint32 ap_param);
+#else
+extern void tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk(kal_uint32 ap_param);
+#endif
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+ipc_ut_error_e ipc_ut_error_g;
+kal_bool ipc_ut_dpfm_is_activated_g = KAL_FALSE;
+
+/*------------------------------------------------------------------------------
+ * Private variables.
+ *----------------------------------------------------------------------------*/
+static ipc_ut_netif_t ipc_ut_nets_s[IPC_UT_MAX_NET_CNT];
+static ipc_ut_filter_info_t ipc_ut_info_set[IPC_MAX_FILTER_CNT];
+static ipc_filter_info_t ipc_ut_ul_filter_info;
+static kal_int32 ipc_ut_ul_filter_id = -1;
+static kal_int32 ipc_ut_ul_filter_gpd_cnt = 0;
+static kal_uint32 ipc_ut_ul_pdn_id = 0;
+static kal_int32 ipc_ut_ul_gpd_cnt = 0;
+static kal_uint32 ipc_ut_ul_meta_cnt = 0;
+static kal_uint32 ipc_ut_ul_meta_non_igr_cnt = 0;
+static qbm_gpd *ipc_ut_ul_head_gpd = NULL;
+static qbm_gpd *ipc_ut_ul_tail_gpd = NULL;
+static ipc_filter_info_t ipc_ut_dl_filter_info;
+static kal_int32 ipc_ut_dl_filter_id = -1;
+static kal_int32 ipc_ut_dl_filter_gpd_cnt = 0;
+static kal_int32 ipc_ut_dl_filter_expect_gpd_cnt = 0;
+static kal_int32 ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt = 0;
+static kal_int32 ipc_ut_str_garbage_expect_host_cnt = 0;
+static kal_int32 ipc_ut_dl_filter_spd_payload_cnt = 0;
+static kal_int32 ipc_ut_dl_callback_gpd_cnt = 0;
+static kal_int32 ipc_ut_dl_callback_spd_payload_cnt = 0;
+static kal_int32 ipc_ut_dl_callback_did_cnt = 0;
+static kal_int32 ipc_ut_dl_callback_did_pkt_cnt = 0;
+static kal_int32 ipc_ut_dl_callback_did_dpfm_cnt = 0;
+static kal_int32 ipc_ut_dl_callback_did_dpfm_pkt_cnt = 0;
+static qbm_gpd *ipc_ut_dl_head_gpd = NULL;
+static qbm_gpd *ipc_ut_dl_tail_gpd = NULL;
+static qbm_gpd *ipc_ut_ul_ebi_head_gpd = NULL;
+static qbm_gpd *ipc_ut_ul_ebi_tail_gpd = NULL;
+static kal_int16 ipc_ut_ul_proto_idx = IPC_UT_INVALID_UL_PROTO_IDX;
+static ipc_ut_msg_t ipc_ut_msg_sent;
+static void *ipc_latest_local_param_p = NULL;
+static kal_uint32 ipc_latest_local_param_size = 0;
+static void *ipc_latest_peer_buff_p = NULL;
+static kal_uint32 ipc_latest_peer_buff_size = 0;
+static ipc_ut_ntfy_param_t ipc_ut_ntfy_param;
+static ipc_ut_ntfy_info_t ipc_ut_ntfy_info;
+static kal_uint8 ipc_ut_garbage_filter_buf_s[2048];
+static kal_uint8 ipc_ut_checksum_buf_s[2048];
+static kal_uint32 g_received_cnt = 0;
+static kal_uint32 g_ipc_ut_igr_meta_cnt = 0;
+static kal_uint32 g_ipc_ut_received_ignore_ea_cnt = 0;
+static kal_uint32 g_ipc_ut_ea_cnt = 0;
+static kal_uint32 g_ipc_ut_ea_drop_cnt = 0;
+static kal_uint32 g_cbk_pkt_recv_cnt = 0;
+static kal_uint32 g_cbk_pkt_send_cnt = 0;
+static kal_uint32 g_normal_cbk_pkt_recv_cnt = 0;
+static kal_bool g_is_block = KAL_TRUE;
+static kal_bool g_is_insert = KAL_FALSE;
+static kal_uint32 g_current_flow = 0;
+static kal_uint32 g_chk_pkt_cnt = 0;
+static ipc_ut_unk_hdr_stats_t g_ut_unk_hdr_stat_recv[MAX_SIM_NUM][IPC_UT_RBID_MAX_NUM] = {0};
+static ipc_ut_unk_hdr_stats_t g_ut_unk_hdr_stat_send[MAX_SIM_NUM][IPC_UT_RBID_MAX_NUM] = {0};
+static kal_uint32 g_unk_pkt_v4_cnt = 0;
+static kal_uint32 g_unk_pkt_v6_cnt = 0;
+static kal_uint32 g_mbim_priv_data = 0;
+
+#if defined(__MD97__)
+static kal_uint32 g_ipc_ut_sdap_pkt_alloc_cnt = 0;
+static kal_uint32 g_ipc_ut_sdap_pkt_received_cnt = 0;
+static ipc_data_rq_info_list g_rq_info_list = {0};
+static ipc_data_rq_info_list g_prepare_rq_info_list = {0};
+#endif
+
+static upcm_did ipc_ut_did_tbl_s[IPC_UT_DID_TABLE_SIZE];
+static kal_uint8 ipc_ut_did_data_buf_s[IPC_UT_DID_MAX_DATA_BUF_NUM][2048];
+static kal_uint8 ipc_ut_did_packet_igr_s[] = {
+ 1, 0, 0, 1, 0, 1, 0, 0, 0, 1,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 1, 0, 0, 0, 1};
+
+static ipc_ut_meta_queue_t ipc_ut_meta_queues[IPC_UT_META_QUEUE_NUM_MAX];
+
+static lhif_meta_tbl_t ipc_ut_meta_tbl_s[IPC_UT_META_TABLE_SIZE];
+static kal_uint8 (*ipc_ut_meta_ring_buf_s)[2048] = ipc_ut_did_data_buf_s;
+static kal_uint8 ipc_ut_meta_tbl_read_idx_s = 0;
+static kal_uint8 ipc_ut_meta_tbl_write_idx_s = 0;
+
+static ipf_dl_meta ipc_ut_dl_meta_tbl_s[IPC_UT_META_TABLE_SIZE];
+static kal_uint8 ipc_ut_dl_meta_tbl_read_idx_s = 0;
+static kal_uint8 ipc_ut_dl_meta_tbl_write_idx_s = 0;
+static kal_uint8 ipc_ut_hw_filter_buf_s[IPC_UT_HW_FLTR_BUF_SIZE];
+static kal_uint8 ipc_ut_dl_meta_buf_free_num_s = 0;
+static kal_uint8 ipc_ut_dl_ipf_match_filter_id_v4_s = 0xFF;
+static kal_uint8 ipc_ut_dl_ipf_match_filter_id_v6_s = 0xFF;
+
+// static kal_uint8 ipc_ut_spd_ring_buf_s[IPC_UT_SPD_RING_BUFFER_SIZE];
+static kal_uint8 *ipc_ut_spd_ring_buf_s = ipc_ut_did_data_buf_s[0];
+static kal_uint8 ipc_ut_spd_packet_igr_s[] = {
+ 1, 0, 0, 1, 0, 1, 0, 0, 0, 1,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 1, 0, 0, 0, 1};
+
+static kal_uint8 ipc_ut_ipv4_udp_packet_example[] = {
+0x45,0x00,0x01,0xd2,0x0e,0x18,0x40,0x00,0x40,0x11,0x2d,0x01,0x7f,0x00,0x00,0x01
+,0x7f,0x00,0x00,0x01,0xe4,0xad,0xa1,0xb8,0x01,0xbe,0xff,0xd1,0xb2,0x01,0x00,0x00
+,0x73,0x73,0x6c,0x5f,0x76,0x65,0x72,0x69,0x66,0x79,0x5f,0x63,0x61,0x6c,0x6c,0x62
+,0x61,0x63,0x6b,0x3a,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65
+,0x3a,0x0a,0x20,0x20,0x20,0x20,0x44,0x61,0x74,0x61,0x3a,0x0a,0x20,0x20,0x20,0x20
+,0x20,0x20,0x20,0x20,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3a,0x20,0x33,0x20,0x28
+,0x30,0x78,0x32,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x53,0x65,0x72
+,0x69,0x61,0x6c,0x20,0x4e,0x75,0x6d,0x62,0x65,0x72,0x3a,0x0a,0x20,0x20,0x20,0x20
+,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x37,0x33,0x3a,0x37,0x62,0x3a,0x36,0x63
+,0x3a,0x63,0x65,0x3a,0x64,0x66,0x3a,0x30,0x31,0x3a,0x36,0x63,0x3a,0x61,0x64,0x3a
+,0x64,0x31,0x3a,0x33,0x33,0x3a,0x35,0x64,0x3a,0x33,0x61,0x3a,0x62,0x63,0x3a,0x35
+,0x61,0x3a,0x61,0x33,0x3a,0x31,0x37,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20
+,0x49,0x73,0x73,0x75,0x65,0x72,0x3a,0x20,0x43,0x3d,0x55,0x53,0x2c,0x20,0x4f,0x3d
+,0x47,0x6f,0x6f,0x67,0x6c,0x65,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x53,0x65,0x72
+,0x76,0x69,0x63,0x65,0x73,0x2c,0x20,0x43,0x4e,0x3d,0x47,0x6f,0x6f,0x67,0x6c,0x65
+,0x20,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x20,0x41,0x75,0x74,0x68,0x6f,0x72
+,0x69,0x74,0x79,0x20,0x47,0x33,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x56
+,0x61,0x6c,0x69,0x64,0x69,0x74,0x79,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20
+,0x20,0x20,0x20,0x20,0x4e,0x6f,0x74,0x20,0x42,0x65,0x66,0x6f,0x72,0x65,0x3a,0x20
+,0x4d,0x61,0x79,0x20,0x32,0x31,0x20,0x32,0x30,0x3a,0x34,0x34,0x3a,0x31,0x31,0x20
+,0x32,0x30,0x31,0x39,0x20,0x47,0x4d,0x54,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20
+,0x20,0x20,0x20,0x20,0x20,0x4e,0x6f,0x74,0x20,0x41,0x66,0x74,0x65,0x72,0x20,0x3a
+,0x20,0x41,0x75,0x67,0x20,0x31,0x33,0x20,0x32,0x30,0x3a,0x33,0x31,0x3a,0x30,0x30
+,0x20,0x32,0x30,0x31,0x39,0x20,0x47,0x4d,0x54,0x0a,0x20,0x20,0x20,0x20,0x20,0x20
+,0x20,0x20,0x53,0x75,0x62,0x6a,0x65,0x63,0x74,0x3a,0x20,0x43,0x3d,0x55,0x53,0x2c
+,0x20,0x53,0x54,0x3d,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x2c,0x20
+,0x4c,0x3d,0x4d,0x6f,0x75,0x6e,0x74,0x61,0x69,0x6e,0x20,0x56,0x69,0x65,0x77,0x2c
+,0x20,0x4f,0x3d,0x47,0x6f,0x6f,0x67,0x6c,0x65,0x20,0x4c,0x4c,0x43,0x2c,0x20,0x43
+,0x4e,0x3d,0x73,0x75,0x70,0x6c,0x2e,0x67,0x6f,0x6f,0x67,0x6c,0x65,0x2e,0x63,0x6f
+,0x6d,0x0a};
+
+static kal_uint8 ipc_ut_ipv4_udp_packet[] = {
+ 0x45, 0x28, 0x00, 0x24, 0x01, 0x53, 0x00, 0x00, 0x80, 0x11, 0x2f, 0xd1, 0x90, 0x4C, 0x9a, 0x72,
+ 0x0a, 0x13, 0x0c, 0x84,
+ 0x9c, 0x8d, /*src port*/
+ 0xec, 0xb9, /*dst port*/
+ 0x00, 0x10, /*length*/
+ 0x48, 0xc7, /*checksum*/
+ 0x81, 0xcb, 0x00, 0x01,
+ 0xb0, 0xd4, 0xf1, 0xa0};
+
+static kal_uint8 ipc_ut_ipv6_udp_packet[] = {
+ 0x6b,0x80,0x00,0x00,0x00,0x34,0x11,0x77,0x24,0x09,0x80,0x19,0x88,0x30,0x41,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x24,0x09,0x88,0x09,0x88,0x74,0x07,0x4d,
+ 0x40,0xbf,0x4c,0x60,0x96,0x75,0x53,0x94,0x55,0x86,0x9c,0x8a,0x00,0x34,0x25,0x40,
+ 0x80,0x60,0xc1,0x87,0x13,0x39,0x58,0x18,0x16,0x9c,0xbd,0x7c,0xf3,0xd2,0x6f,0x2f,
+ 0x7e,0x14,0x57,0x92,0x79,0xe7,0x0d,0xc4,0x54,0x14,0x2a,0x23,0xda,0x0d,0xb5,0xd3,
+ 0xc2,0xd5,0x0f,0xfd,0x35,0x62,0xce,0xca,0xca,0x37,0xd6,0xdc};
+
+
+static kal_uint8 ipc_ut_ipv4_tcp_syn_packet[] = {
+ 0x45, 0x00, 0x00, 0x34, 0x31, 0xde, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x94,
+ 0x4a, 0x7d, 0x17, 0x5e, 0xdd, 0x5c, 0x01, 0xbb, 0xc4, 0xb9, 0x44, 0x47, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x20, 0x00, 0xc1, 0x71, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x03, 0x03, 0x08,
+ 0x01, 0x01, 0x04, 0x02};
+
+static kal_uint8 ipc_ut_ipv4_tcp_ack_packet[] = {
+ 0x45, 0x00, 0x00, 0x28, 0x31, 0xeb, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x94,
+ 0x4a, 0x7d, 0x17, 0x5e, 0xdd, 0x5c, 0x01, 0xbb, 0xc4, 0xb9, 0x44, 0x48, 0x7e, 0xd3, 0x4c, 0xcc,
+ 0x50, 0x10, 0x01, 0x00, 0xa5, 0xa0, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv4_tcp_syn_packet_2[] = {
+ 0x45, 0x00, 0x00, 0x34, 0xa1, 0x26, 0x40, 0x00, 0x80, 0x06, 0xd6, 0x35, 0xc0, 0xa8, 0x01, 0x0c,
+ 0xc0, 0xa8, 0x01, 0x0b, 0x04, 0x43, 0x13, 0x8e, 0xd9, 0x25, 0x44, 0x8c, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0xff, 0xff, 0xb6, 0x2d, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x03, 0x03, 0x00,
+ 0x01, 0x01, 0x04, 0x02};
+
+static kal_uint8 ipc_ut_ipv6_tcp_syn_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40, 0x20, 0x01, 0x06, 0xf8, 0x10, 0x2d, 0x00, 0x00,
+ 0x02, 0xd0, 0x09, 0xff, 0xfe, 0xe3, 0xe8, 0xde, 0x20, 0x01, 0x06, 0xf8, 0x09, 0x00, 0x07, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7, 0x41, 0x00, 0x50, 0xab, 0xdc, 0xd6, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0x80, 0x41, 0xa2, 0x00, 0x00, 0x02, 0x04, 0x05, 0xa0,
+ 0x04, 0x02, 0x08, 0x0a, 0x00, 0x0a, 0x22, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x05};
+
+static kal_uint8 ipc_ut_ipv6_tcp_ack_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x20, 0x01, 0x06, 0xf8, 0x10, 0x2d, 0x00, 0x00,
+ 0x02, 0xd0, 0x09, 0xff, 0xfe, 0xe3, 0xe8, 0xde, 0x20, 0x01, 0x06, 0xf8, 0x09, 0x00, 0x07, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7, 0x41, 0x00, 0x50, 0xab, 0xdc, 0xd6, 0x61,
+ 0x01, 0x4a, 0x73, 0x9f, 0x50, 0x10, 0x16, 0x80, 0x57, 0x28, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv6_tcp_syn_packet_2[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40, 0x3f, 0xfe, 0x05, 0x07, 0x00, 0x00, 0x00, 0x01,
+ 0x02, 0x00, 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, 0x05, 0x01, 0x04, 0x10, 0x00, 0x00,
+ 0x02, 0xc0, 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe, 0x00, 0x16, 0xd6, 0x76, 0xf3, 0x21,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x20, 0x00, 0x18, 0xd5, 0x00, 0x00, 0x02, 0x04, 0x05, 0xa0,
+ 0x01, 0x03, 0x03, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, 0xca, 0x57, 0x00, 0x00, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_non_ip_packet[] = {
+ 0x00, 0x00, 0x45, 0x50, 0x9e, 0x00, 0x00, 0x80, 0x11, 0x96, 0x3a, 0xac, 0x16, 0x97, 0x53,
+ 0xac, 0x15, 0x64, 0x50, 0xc0, 0x51, 0x00, 0x35, 0x00, 0x31, 0x7d, 0x15, 0x2d, 0x89, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x50, 0x43, 0x31, 0x30, 0x30, 0x36, 0x30,
+ 0x30, 0x31, 0x34, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6b, 0x03, 0x69, 0x6e, 0x63,
+ 0x00, 0x00, 0x1c, 0x00, 0x01};
+
+static kal_uint8 ipc_ut_ipv4_dns_packet[] = {
+ 0x45, 0x00, 0x00, 0x45, 0x50, 0x9e, 0x00, 0x00, 0x80, 0x11, 0x96, 0x3a, 0xac, 0x16, 0x97, 0x53,
+ 0xac, 0x15, 0x64, 0x50, 0xc0, 0x51, 0x00, 0x35, 0x00, 0x31, 0x7d, 0x15, 0x2d, 0x89, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x50, 0x43, 0x31, 0x30, 0x30, 0x36, 0x30,
+ 0x30, 0x31, 0x34, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6b, 0x03, 0x69, 0x6e, 0x63,
+ 0x00, 0x00, 0x1c, 0x00, 0x01};
+
+/* DHCP REQ packet : 172.22.151.76(Client) => 172.21.95.1(Server) */
+static kal_uint8 ipc_ut_ipv4_dhcp_ul_packet[] = {
+ 0x45, 0x00, 0x01, 0x61, 0x97, 0xe6, 0x00, 0x00, 0x80, 0x11, 0x53, 0x2c, 0xac, 0x16, 0x97, 0x4c,
+ 0xac, 0x15, 0x5f, 0x01, 0x00, 0x44, 0x00, 0x43, 0x01, 0x4d, 0xf5, 0xa2, 0x01, 0x01, 0x06, 0x00,
+ 0xa9, 0x29, 0x06, 0x7b, 0x00, 0x00, 0x00, 0x00, 0xac, 0x16, 0x97, 0x4c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xd4, 0x80, 0x56, 0x15, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x03, 0x3d,
+ 0x07, 0x01, 0x00, 0x13, 0xd4, 0x80, 0x56, 0x15, 0x0c, 0x0c, 0x70, 0x63, 0x30, 0x37, 0x30, 0x31,
+ 0x30, 0x31, 0x33, 0x39, 0x39, 0x37, 0x51, 0x1c, 0x00, 0x00, 0x00, 0x70, 0x63, 0x30, 0x37, 0x30,
+ 0x31, 0x30, 0x31, 0x33, 0x39, 0x39, 0x37, 0x2e, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6b,
+ 0x2e, 0x69, 0x6e, 0x63, 0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, 0x37, 0x0b,
+ 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21, 0xf9, 0x2b, 0x2b, 0x03, 0xdc, 0x01, 0x00,
+ 0xff};
+
+/* DHCP ACK packet : 172.22.151.252(Server) => 172.22.151.76(Client) */
+static kal_uint8 ipc_ut_ipv4_dhcp_packet[] = {
+ 0x45, 0x01, 0x01, 0x5f, 0x5f, 0x54, 0x00, 0x00, 0x40, 0x11, 0x92, 0xc3, 0xac, 0x16, 0x97, 0xfc,
+ 0xac, 0x16, 0x97, 0x4c, 0x00, 0x43, 0x00, 0x44, 0x01, 0x4b, 0xcf, 0x7d, 0x02, 0x01, 0x06, 0x01,
+ 0x58, 0xdc, 0x8b, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x16, 0x97, 0x4c,
+ 0x00, 0x00, 0x00, 0x00, 0xac, 0x16, 0x97, 0xfc, 0x00, 0x13, 0xd4, 0x80, 0x56, 0x15, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x3a,
+ 0x04, 0x00, 0x05, 0x46, 0x00, 0x3b, 0x04, 0x00, 0x09, 0x3a, 0x80, 0x33, 0x04, 0x00, 0x0a, 0x8c,
+ 0x00, 0x36, 0x04, 0xac, 0x15, 0x5f, 0x01, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x51, 0x03, 0x00,
+ 0xff, 0xff, 0x0f, 0x0d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6b, 0x2e, 0x69, 0x6e, 0x63,
+ 0x00, 0x03, 0x04, 0xac, 0x16, 0x97, 0xfe, 0x06, 0x08, 0xac, 0x15, 0x64, 0x50, 0xac, 0x15, 0x64,
+ 0x03, 0x2c, 0x08, 0xac, 0x15, 0x65, 0x0a, 0xac, 0x15, 0x64, 0x2a, 0x2e, 0x01, 0x08, 0xff};
+
+static kal_uint8 ipc_ut_ipv4_incomplete_ip_header_packet[] = {
+ 0x45, 0x00, 0x01
+ };
+
+static kal_uint8 ipc_ut_ipv4_incomplete_udp_header_packet[] = {
+ 0x45, 0x00, 0x00, 0x1a, 0x50, 0x9e, 0x00, 0x00, 0x80, 0x11, 0x96, 0x3a, 0xac, 0x16, 0x97, 0x53,
+ 0xac, 0x15, 0x64, 0x50, 0xc0, 0x51, 0x00, 0x35, 0x00, 0x31};
+
+static kal_uint8 ipc_ut_ipv4_frag0_packet[] = {
+ 0x45, 0x00, 0x01, 0x48, 0x13, 0xb6, 0x80, 0x00, 0x80, 0x11, 0xe2, 0x10, 0xac, 0x16, 0x97, 0xc8,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, 0x82, 0x90, 0x01, 0x01, 0x06, 0x00,
+ 0x6f, 0x4c, 0x32, 0x9a, 0x00, 0x00, 0x00, 0x00, 0xac, 0x16, 0x97, 0xc8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x37, 0xe6, 0x5d, 0xe8, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x08, 0x3d,
+ 0x07, 0x01, 0x44, 0x37, 0xe6, 0x5d, 0xe8, 0x6f, 0x0c, 0x0a, 0x50, 0x43, 0x31, 0x31, 0x30, 0x39,
+ 0x30, 0x30, 0x30, 0x35, 0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, 0x37, 0x0c,
+ 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21, 0xf9, 0x2b, 0xfc, 0x2b, 0x03, 0xdc, 0x01,
+ 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv4_frag1_packet[] = {
+ 0x45, 0x00, 0x01, 0x48, 0x13, 0xb6, 0x00, 0x10, 0x80, 0x11, 0xe2, 0x10, 0xac, 0x16, 0x97, 0xc8,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, 0x82, 0x90, 0x01, 0x01, 0x06, 0x00,
+ 0x6f, 0x4c, 0x32, 0x9a, 0x00, 0x00, 0x00, 0x00, 0xac, 0x16, 0x97, 0xc8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x37, 0xe6, 0x5d, 0xe8, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x08, 0x3d,
+ 0x07, 0x01, 0x44, 0x37, 0xe6, 0x5d, 0xe8, 0x6f, 0x0c, 0x0a, 0x50, 0x43, 0x31, 0x31, 0x30, 0x39,
+ 0x30, 0x30, 0x30, 0x35, 0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, 0x37, 0x0c,
+ 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21, 0xf9, 0x2b, 0xfc, 0x2b, 0x03, 0xdc, 0x01,
+ 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv6_mdns_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x39, 0x11, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x17, 0x31, 0xff, 0xfe, 0x7e, 0x96, 0xab, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x39, 0x1d, 0x62,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x57, 0x69, 0x6d,
+ 0x61, 0x78, 0x4d, 0x61, 0x63, 0x2d, 0x74, 0x6a, 0x2d, 0x31, 0x30, 0x36, 0x04, 0x5f, 0x72, 0x66,
+ 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x00,
+ 0x01};
+
+static kal_uint8 ipc_ut_ipv6_dhcp_ul_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x56, 0x11, 0x80, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x13, 0xd4, 0xff, 0xfe, 0x80, 0x56, 0x15, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, 0x02, 0x23, 0x00, 0x56, 0x98, 0x9b,
+ 0x01, 0x00, 0x12, 0x69, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x06, 0x18, 0xc5, 0xe1, 0xd2,
+ 0x00, 0x13, 0xd4, 0x80, 0x56, 0x15, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x17};
+
+static kal_uint8 ipc_ut_ipv6_dhcp_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x42, 0x11, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, 0x02, 0x23, 0x00, 0x42, 0x93, 0x19,
+ 0x01, 0x5d, 0x6f, 0xba, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x15, 0xbd, 0x26, 0xde,
+ 0x20, 0xcf, 0x30, 0x0d, 0xe2, 0x47, 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x12,
+ 0x47, 0xe2, 0x0d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18};
+
+static kal_uint8 ipc_ut_ipv6_ext0_dhcp_ul_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 86+16+24+24, /* payload length */ 0, /* next header */ 0x80, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x13, 0xd4, 0xff, 0xfe, 0x80, 0x56, 0x15, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* hop-by-hop */
+ 60, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* destination options header */
+ 43, 2, 1, 2, 0, 0, 201, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* routing header*/
+ 17, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ /* 86-byte */
+ 0x02, 0x22, 0x02, 0x23, 0x00, 0x56, 0x98, 0x9b,
+ 0x01, 0x00, 0x12, 0x69, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x06, 0x18, 0xc5, 0xe1, 0xd2,
+ 0x00, 0x13, 0xd4, 0x80, 0x56, 0x15, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x17};
+
+static kal_uint8 ipc_ut_ipv6_ext0_dhcp_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+16+24+24, /* payload length */ 0, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* hop-by-hop */
+ 60, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* destination options header */
+ 43, 2, 1, 2, 0, 0, 201, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* routing header*/
+ 17, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ /* 66-byte */
+ 0x02, 0x22, 0x02, 0x23, 0x00, 0x42, 0x93, 0x19,
+ 0x01, 0x5d, 0x6f, 0xba, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x15, 0xbd, 0x26, 0xde,
+ 0x20, 0xcf, 0x30, 0x0d, 0xe2, 0x47, 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x12,
+ 0x47, 0xe2, 0x0d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18};
+
+static kal_uint8 ipc_ut_ipv6_ext1_dhcp_ul_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 86+16+12, /* payload length */ 0, /* next header */ 0x80, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x13, 0xd4, 0xff, 0xfe, 0x80, 0x56, 0x15, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* hop-by-hop */
+ 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* authentication header */
+ 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ /* 86-byte */
+ 0x02, 0x22, 0x02, 0x23, 0x00, 0x56, 0x98, 0x9b,
+ 0x01, 0x00, 0x12, 0x69, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x06, 0x18, 0xc5, 0xe1, 0xd2,
+ 0x00, 0x13, 0xd4, 0x80, 0x56, 0x15, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x17};
+
+static kal_uint8 ipc_ut_ipv6_ext1_dhcp_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+16+12, /* payload length */ 0, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* hop-by-hop */
+ 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* authentication header */
+ 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ /* 66-byte */
+ 0x02, 0x22, 0x02, 0x23, 0x00, 0x42, 0x93, 0x19,
+ 0x01, 0x5d, 0x6f, 0xba, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x15, 0xbd, 0x26, 0xde,
+ 0x20, 0xcf, 0x30, 0x0d, 0xe2, 0x47, 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x12,
+ 0x47, 0xe2, 0x0d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18};
+
+static kal_uint8 ipc_ut_ipv6_incomplete_ip_header_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x39, 0x11, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv6_incomplete_hop_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+15, /* payload length */ 0, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* hop-by-hop */
+ 60, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+static kal_uint8 ipc_ut_ipv6_incomplete_ah_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+11, /* payload length */ 51, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* authentication header */
+ 41, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+static kal_uint8 ipc_ut_ipv6_unknown_ext_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+16+16, /* payload length */ 0, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* hop-by-hop */
+ 254, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* unknown header */
+ 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ /* 66-byte */
+ 0x02, 0x22, 0x02, 0x23, 0x00, 0x42, 0x93, 0x19,
+ 0x01, 0x5d, 0x6f, 0xba, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x15, 0xbd, 0x26, 0xde,
+ 0x20, 0xcf, 0x30, 0x0d, 0xe2, 0x47, 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x12,
+ 0x47, 0xe2, 0x0d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18};
+
+static kal_uint8 ipc_ut_ipv6_incomplete_ipv4enc_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+12+2, /* payload length */ 51, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* authentication header */
+ 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* IPv4 encapsulation */
+ 0x45, 0x00};
+
+static kal_uint8 ipc_ut_ipv6_frag_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+8, /* payload length */ 44, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* fragment header */
+ 17, 0, 0, 0, 0, 0, 0, 0,
+
+ /* 66-byte */
+ 0x02, 0x22, 0x02, 0x23, 0x00, 0x42, 0x93, 0x19,
+ 0x01, 0x5d, 0x6f, 0xba, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x15, 0xbd, 0x26, 0xde,
+ 0x20, 0xcf, 0x30, 0x0d, 0xe2, 0x47, 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x12,
+ 0x47, 0xe2, 0x0d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18};
+
+static kal_uint8 ipc_ut_ipv6_ipv4enc_frag0_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+12+20, /* payload length */ 51, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* authentication header */
+ 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* IPv4 encapsulation */
+ 0x45, 0x00, 0x00, 66+20, /* total length */ 0x13, 0xb6, 0x80, 0x00, 0x80, 17, /* protocol*/ 0xe2, 0x10, 0xac, 0x16, 0x97, 0xc8,
+ 0xff, 0xff, 0xff, 0xff,
+
+ /* 66-byte */
+ 0x02, 0x22, 0x02, 0x23, 0x00, 0x42, 0x93, 0x19,
+ 0x01, 0x5d, 0x6f, 0xba, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x15, 0xbd, 0x26, 0xde,
+ 0x20, 0xcf, 0x30, 0x0d, 0xe2, 0x47, 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x12,
+ 0x47, 0xe2, 0x0d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18};
+
+static kal_uint8 ipc_ut_ipv6_ipv4enc_frag1_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+12+20, /* payload length */ 51, /* next header */ 0x01, 0xfe, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* authentication header */
+ 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* IPv4 encapsulation */
+ 0x45, 0x00, 0x00, 66+20, /* total length */ 0x13, 0xb6, 0x80, 0x00, 0x80, 17, /* protocol*/ 0xe2, 0x10, 0xac, 0x16, 0x97, 0xc8,
+ 0xff, 0xff, 0xff, 0xff,
+
+ /* 66-byte */
+ 0x02, 0x22, 0x02, 0x23, 0x00, 0x42, 0x93, 0x19,
+ 0x01, 0x5d, 0x6f, 0xba, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x15, 0xbd, 0x26, 0xde,
+ 0x20, 0xcf, 0x30, 0x0d, 0xe2, 0x47, 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x12,
+ 0x47, 0xe2, 0x0d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18};
+
+static kal_uint8 ipc_ut_ipv6_incomplete_ipv6enc_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 66+12+4, /* payload length */ 51, /* next header */ 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0xcf, 0x30, 0xff, 0xfe, 0x0d, 0xe2, 0x47, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+
+ /* authentication header */
+ 41, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* IPv6 encapsulation */
+ 0x60, 0x00, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv6_udp_zero_checksum_packet[] = {
+ 0x60, 0x50, 0x00, 0x00, 0x00, 0x51, 0x11, 0x80, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9c, 0x40, 0xea, 0x60, 0x00, 0x51, 0x00, 0x00,
+ 0x80, 0x62, 0x51, 0x8a, 0x00, 0x66, 0x60, 0xc0, 0x52, 0x77, 0xd1, 0x80, 0xf4, 0x60, 0xc3, 0x1b,
+ 0x84, 0xc7, 0xce, 0x42, 0xa1, 0x2d, 0xff, 0xff, 0x84, 0x7d, 0xe8, 0x63, 0x77, 0xf5, 0xe7, 0xc1,
+ 0x47, 0xf4, 0x59, 0x85, 0x3c, 0xa8, 0xab, 0xcc, 0xe8, 0xfb, 0xab, 0x99, 0x5d, 0x20, 0x6c, 0x24,
+ 0x7b, 0x94, 0xfa, 0xd3, 0x25, 0x3e, 0x68, 0x7c, 0x93, 0x39, 0x24, 0x36, 0xc3, 0xd4, 0x8a, 0x54,
+ 0x87, 0xb6, 0x06, 0x30, 0xaa, 0x1a, 0xdf, 0xc4, 0x60};
+
+static kal_uint8 ipc_ut_ipv4_tcp_fin_ack_packet[] = {
+ 0x45, 0x00, 0x00, 0x28, 0x31, 0xeb, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x94,
+ 0x4a, 0x7d, 0x17, 0x5e, 0xdd, 0x5c, 0x01, 0xbb, 0xc4, 0xb9, 0x44, 0x48, 0x7e, 0xd3, 0x4c, 0xcc,
+ 0x50, 0x11, 0x01, 0x00, 0xa5, 0xa0, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv4_tcp_fin_ack_packet_2[] = {
+ 0x45, 0x00, 0x00, 0x28, 0x31, 0xeb, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x92, 0x91,
+ 0x4a, 0x7d, 0x17, 0x5e, 0xdd, 0x5c, 0x01, 0xbb, 0xc4, 0xb9, 0x44, 0x48, 0x7e, 0xd3, 0x4c, 0xcc,
+ 0x50, 0x11, 0x01, 0x00, 0xa5, 0xa0, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv6_tcp_fin_ack_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x20, 0x01, 0x06, 0xf8, 0x10, 0x2d, 0x00, 0x00,
+ 0x02, 0xd0, 0x09, 0xff, 0xfe, 0xe3, 0xe8, 0xde, 0x20, 0x01, 0x06, 0xf8, 0x09, 0x00, 0x07, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7, 0x41, 0x00, 0x50, 0xab, 0xdc, 0xd6, 0x61,
+ 0x01, 0x4a, 0x73, 0x9f, 0x50, 0x11, 0x16, 0x80, 0x57, 0x28, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv6_tcp_fin_ack_packet_2[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x20, 0x02, 0x06, 0xf8, 0x10, 0x2d, 0x00, 0x00,
+ 0x02, 0xd0, 0x06, 0xff, 0xfe, 0xe5, 0xe9, 0xde, 0x20, 0x01, 0x06, 0xf8, 0x09, 0x00, 0x07, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7, 0x41, 0x00, 0x50, 0xab, 0xdc, 0xd6, 0x61,
+ 0x01, 0x4a, 0x73, 0x9f, 0x50, 0x11, 0x16, 0x80, 0x57, 0x28, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv4_tcp_empty_ack_packet[] = {
+ 0x45, 0x00, 0x00, 0x28, 0x31, 0xeb, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x94,
+ 0x4a, 0x7d, 0x17, 0x5e, 0xdd, 0x5c, 0x01, 0xbb, 0xc4, 0xb9, 0x44, 0x48, 0x7e, 0xd3, 0x4c, 0xcc,
+ 0x50, 0x10, 0x01, 0x00, 0xa5, 0xa0, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv6_tcp_empty_ack_packet[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x20, 0x01, 0x06, 0xf8, 0x10, 0x2d, 0x00, 0x00,
+ 0x02, 0xd0, 0x09, 0xff, 0xfe, 0xe3, 0xe8, 0xde, 0x20, 0x01, 0x06, 0xf8, 0x09, 0x00, 0x07, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7, 0x41, 0x00, 0x50, 0xab, 0xdc, 0xd6, 0x61,
+ 0x01, 0x4a, 0x73, 0x9f, 0x50, 0x10, 0x16, 0x80, 0x57, 0x28, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv4_ul_syn_window_scale_packets_1[] = {
+ 0x45, 0x00, 0x00, 0x34, 0x5c, 0x32, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x2c,
+ 0xd8, 0x3a, 0xc8, 0xee, 0xea, 0x7d, 0x01, 0xbb, 0x1e, 0x2a, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x20, 0x00, 0xe4, 0x92, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x02, 0x02, 0x04,
+ 0x01, 0x01, 0x04, 0x02};
+
+static kal_uint8 ipc_ut_ipv4_ul_syn_window_scale_packets_2[] = {
+ 0x45, 0x00, 0x00, 0x34, 0x5c, 0x32, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x2d,
+ 0xd8, 0x3a, 0xc8, 0xee, 0xea, 0x7d, 0x01, 0xbb, 0x1e, 0x2a, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x20, 0x00, 0xe4, 0x92, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x03, 0x03, 0x04,
+ 0x01, 0x01, 0x04, 0x02};
+
+static kal_uint8 ipc_ut_ipv4_ul_syn_window_scale_packets_3[] = {
+ 0x45, 0x00, 0x00, 0x34, 0x5c, 0x32, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x2e,
+ 0xd8, 0x3a, 0xc8, 0xee, 0xea, 0x7d, 0x01, 0xbb, 0x1e, 0x2a, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x20, 0x00, 0xe4, 0x92, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x03, 0x03, 0x08,
+ 0x01, 0x01, 0x04, 0x02};
+
+/* ack */
+static kal_uint8 ipc_ut_ipv4_ul_syn_window_scale_packets_4[] = {
+ 0x45, 0x00, 0x00, 0x28, 0xef, 0xf3, 0x00, 0x00, 0x33, 0x06, 0xb3, 0x70, 0xd8, 0x3a, 0xc8, 0xee, 0xac, 0x16,
+ 0x97, 0x2e, 0x01, 0xbb, 0xea, 0x7d, 0xf2, 0xd1, 0x7b, 0x3f, 0x1e, 0x2a, 0x0c, 0x23, 0x50, 0x10, 0x00, 0xac,
+ 0x46, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+/* not formal packet, only for TCP RST error testing */
+static kal_uint8 ipc_ut_ipv4_tcp_error_frag1_packet[] = {
+ 0x45, 0x00, 0x00, 0x28, 0x31, 0xeb, 0x00, 0x10, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x94,
+ 0x4a, 0x7d, 0x17, 0x5e, 0xdd, 0x5c, 0x01, 0xbb, 0xc4, 0xb9, 0x44, 0x48, 0x7e, 0xd3, 0x4c, 0xcc,
+ 0x50, 0x10, 0x01, 0x00, 0xa5, 0xa0, 0x00, 0x00};
+
+static kal_uint8 ipc_ut_ipv4_ul_syn_window_scale_packets_5[] = {
+ 0x45, 0x00, 0x00, 0x34, 0x5c, 0x32, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x2c,
+ 0xd8, 0x3a, 0xc8, 0xee, 0xea, 0x7d, 0x01, 0xbb, 0x1e, 0x2a, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x20, 0x01, 0xe4, 0x92, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x02, 0x02, 0x04,
+ 0x01, 0x01, 0x04, 0x02};
+
+static kal_uint8 ipc_ut_ipv4_ul_syn_window_scale_packets_6[] = {
+ 0x45, 0x00, 0x00, 0x34, 0x5c, 0x32, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x2d,
+ 0xd8, 0x3a, 0xc8, 0xee, 0xea, 0x7d, 0x01, 0xbb, 0x1e, 0x2a, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x20, 0x02, 0xe4, 0x92, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x03, 0x03, 0x04,
+ 0x01, 0x01, 0x04, 0x02};
+
+static kal_uint8 ipc_ut_ipv4_ul_syn_window_scale_packets_7[] = {
+ 0x45, 0x00, 0x00, 0x34, 0x5c, 0x32, 0x40, 0x00, 0x80, 0x06, 0x00, 0x00, 0xac, 0x16, 0x97, 0x2e,
+ 0xd8, 0x3a, 0xc8, 0xee, 0xea, 0x7d, 0x01, 0xbb, 0x1e, 0x2a, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x20, 0x03, 0xe4, 0x92, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x01, 0x03, 0x03, 0x08,
+ 0x01, 0x01, 0x04, 0x02};
+
+static kal_uint8 g_ipc_ut_v6_esp_pkt_1[] = {0x60, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x32, 0x3f, 0x20, 0x01, 0x04, 0x70,
+ 0xe5, 0xbf, 0x10, 0x01, 0x85, 0x19,
+ 0x2d, 0x1f, 0xc5, 0x7d, 0xfc, 0x4f,
+ 0x20, 0x01, 0x04, 0x70, 0xe5, 0xbf,
+ 0xde, 0xad, 0x7d, 0xb0, 0x09, 0x21,
+ 0xa2, 0xe9, 0x1c, 0x21, 0x49, 0x50,
+ 0x76, 0x46, 0x20, 0x45, 0x53, 0x50};
+
+static kal_uint8 g_ipc_ut_v6_ah_esp_pkt_1[] = {0x60, 0x00, 0x00, 0x00, 0x00,
+ 8 + 24, 0x33, 0x3f, 0x20, 0x01,
+ 0x04, 0x70, 0xe5, 0xbf, 0x10,
+ 0x01, 0x85, 0x19, 0x2d, 0x1f,
+ 0xc5, 0x7d, 0xfc, 0x4f, 0x20,
+ 0x01, 0x04, 0x70, 0xe5, 0xbf,
+ 0xde, 0xad, 0x7d, 0xb0, 0x09,
+ 0x21, 0xa2, 0xe9, 0x1c, 0x21,
+ 0x32, 0x04, 0x00, 0x00, 0x81,
+ 0x79, 0xb7, 0x05, 0x00, 0x00,
+ 0x00, 0x01, 0x27, 0xcf, 0xc0,
+ 0xa5, 0xe4, 0x3d, 0x69, 0xb3,
+ 0x72, 0x8e, 0xc5, 0xb0, 0x49,
+ 0x50, 0x76, 0x56, 0x20, 0x45,
+ 0x53, 0x50};
+
+static kal_uint8 g_ipc_ut_v6_routing_esp_pkt_1[] = {0x60, 0x0f, 0xbb, 0x74,
+ 0x00, 0x88, 0x2b, 0x3f,
+ 0xfc, 0x00, 0x00, 0x42,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02,
+ 0xfc, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x32, 0x06, 0x04, 0x02,
+ 0x02, 0x00, 0x00, 0x00,
+ 0xfc, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0xfc, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0xfc, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x49, 0x50, 0x76, 0x76,
+ 0x20, 0x45, 0x53, 0x50};
+
+static kal_uint8 g_ipc_ut_v6_routing_ah_esp_pkt_1[] = {0x60, 0x0f, 0xbb, 0x74,
+ 0x00, 0x88 + 24, 0x2b,
+ 0x3f, 0xfc, 0x00, 0x00,
+ 0x42, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0xfc, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x33, 0x06, 0x04,
+ 0x02, 0x02, 0x00, 0x00,
+ 0x00, 0xfc, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0xfc, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00,
+ 0x07, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0xfc, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x32, 0x04, 0x00,
+ 0x00, 0x81, 0x79, 0xb7,
+ 0x05, 0x00, 0x00, 0x00,
+ 0x01, 0x27, 0xcf, 0xc0,
+ 0xa5, 0xe4, 0x3d, 0x69,
+ 0xb3, 0x72, 0x8e, 0xc5,
+ 0xb0, 0x49, 0x50, 0x76,
+ 0x66, 0x20, 0x45, 0x53,
+ 0x50};
+
+static kal_uint8 g_ipc_ut_v4_esp_pkt_1[] = {0x45, 0x00, 0x00, 0xb8, 0x20, 0x20,
+ 0x40, 0x00, 0x40, 0x32, 0x05, 0xf2,
+ 0x0a, 0x00, 0x00, 0x01, 0x0a, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x00, 0x00, 0xf4, 0xf4, 0xcf,
+ 0xf9, 0x23, 0x0a, 0x5d, 0x0f, 0x97,
+ 0x16, 0xde, 0xd0, 0xa7, 0xdd, 0x25,
+ 0x7c, 0x83, 0x97, 0x17, 0xeb, 0x36,
+ 0xf4, 0x22, 0xd1, 0x31, 0x4e, 0xaa,
+ 0xfc, 0x14, 0x32, 0x17, 0x74, 0x60,
+ 0x96, 0x28, 0xdf, 0x6c, 0x0a, 0x21,
+ 0x78, 0x49, 0xa6, 0xc7, 0xc3, 0x0b,
+ 0x47, 0xa9, 0x92, 0xdb, 0x1b, 0x7b,
+ 0xcb, 0x74, 0x7c, 0xc1, 0xd1, 0xf7,
+ 0x8d, 0x88, 0xf9, 0x8e, 0x79, 0xc7,
+ 0x31, 0xdd, 0x6a, 0x88, 0xc0, 0x35,
+ 0x5c, 0x7b, 0x2a, 0x82, 0x1a, 0x14,
+ 0x7e, 0x7b, 0x6b, 0xd3, 0xec, 0x76,
+ 0xd4, 0x93, 0x19, 0xdf, 0xc9, 0x09,
+ 0xab, 0xa5, 0xc7, 0x5d, 0x6c, 0x92,
+ 0x9c, 0xeb, 0xce, 0xd6, 0x52, 0x70,
+ 0xce, 0x83, 0x58, 0xea, 0x85, 0x9c,
+ 0x25, 0xc0, 0xdf, 0x5f, 0xd9, 0xe0,
+ 0x14, 0xf6, 0x91, 0x04, 0x69, 0xca,
+ 0x73, 0x95, 0xd7, 0xed, 0xfb, 0x01,
+ 0x7e, 0xa1, 0x31, 0xea, 0x21, 0x06,
+ 0x82, 0xd8, 0x77, 0xa8, 0x63, 0x0e,
+ 0xb4, 0x14, 0xe5, 0x1e, 0x4e, 0x2a,
+ 0xd4, 0x2f, 0x00, 0x1a, 0x2d, 0x90,
+ 0xc2, 0x89, 0xb4, 0x2a, 0xba, 0xb0,
+ 0x05, 0x05, 0x3e, 0xf1};
+
+static kal_uint8 g_ipc_ut_v4_ah_esp_pkt_1[] = {0x45, 0x00, 0x00, 0xb4, 0x00,
+ 0x6b, 0x00, 0x00, 0xff, 0x33,
+ 0xa6, 0xa9, 0x0a, 0x00, 0x00,
+ 0x01, 0x0a, 0x00, 0x00, 0x02,
+ 0x32, 0x04, 0x00, 0x00, 0x81,
+ 0x79, 0xb7, 0x05, 0x00, 0x00,
+ 0x00, 0x01, 0x27, 0xcf, 0xc0,
+ 0xa5, 0xe4, 0x3d, 0x69, 0xb3,
+ 0x72, 0x8e, 0xc5, 0xb0, 0x48,
+ 0xda, 0xc2, 0xe4, 0x00, 0x00,
+ 0x00, 0x01, 0x07, 0x41, 0xbe,
+ 0x7f, 0x8a, 0xde, 0x40, 0xc0,
+ 0x2b, 0xd8, 0x1a, 0xee, 0x0f,
+ 0x50, 0x6f, 0x2c, 0x46, 0xdc,
+ 0xbd, 0x49, 0xac, 0xad, 0x30,
+ 0xbb, 0x5a, 0x09, 0x70, 0x80,
+ 0xc3, 0xd6, 0x88, 0xd4, 0x9b,
+ 0x5f, 0x22, 0x5c, 0xe8, 0x71,
+ 0x84, 0xd1, 0xf9, 0xf8, 0xad,
+ 0x62, 0x67, 0xfa, 0x1a, 0xa2,
+ 0x18, 0x97, 0x0f, 0xd1, 0x35,
+ 0xb6, 0x99, 0x37, 0x24, 0x54,
+ 0x44, 0x5f, 0x6b, 0xd3, 0xcc,
+ 0x19, 0xb1, 0x5f, 0xb7, 0x01,
+ 0xb2, 0x34, 0xd9, 0x4a, 0x07,
+ 0xec, 0x6b, 0xfc, 0x2d, 0x3d,
+ 0x13, 0x35, 0xb3, 0x01, 0x35,
+ 0x66, 0xb4, 0x74, 0xd7, 0xc3,
+ 0x25, 0x9b, 0x7f, 0xe4, 0xb9,
+ 0x22, 0xa5, 0xbf, 0xa3, 0xd0,
+ 0x90, 0xc8, 0x9a, 0x9b, 0x6d,
+ 0x6a, 0xb7, 0xf2, 0xba, 0x11,
+ 0xff, 0xc7, 0xa3, 0x87, 0xb6,
+ 0x05, 0x58, 0x7a, 0x24, 0xa8,
+ 0x29, 0x9c, 0x7d, 0x89, 0xc2,
+ 0x21, 0x99, 0xa1, 0xbd, 0x00};
+
+static kal_uint8 g_ipc_ut_v6_hop_dst_route_esp_pkt_1[] = {0x60, 0x00, 0x00,
+ 0x00, 0x00,
+ 8 + 16 + 24 + 24 + 24,
+ 0x0, 0x3f, 0x20, 0x01,
+ 0x04, 0x70, 0xe5,
+ 0xbf, 0x10, 0x01,
+ 0x85, 0x19, 0x2d,
+ 0x1f, 0xc5, 0x7d,
+ 0xfc, 0x4f, 0x20,
+ 0x01, 0x04, 0x70,
+ 0xe5, 0xbf, 0xde,
+ 0xad, 0x7d, 0xb0,
+ 0x09, 0x21, 0xa2,
+ 0xe9, 0x1c, 0x21,
+
+ /* hop-by-hop */
+ 60,
+ 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0,
+ /* destination options header */
+ 43,
+ 2, 1, 2, 0, 0, 201,
+ 16, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ /* routing header*/
+ 0x32,
+ 2, 2, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+
+ 0x49,
+ 0x50, 0x86, 0x37,
+ 0x20, 0x45, 0x53, 0x50};
+
+static kal_uint8 g_ipc_ut_v6_hop_dst_route_ah_esp_pkt_1[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 8 + 16 + 24 + 24 + 24, 0x0, 0x3f, 0x20,
+ 0x01, 0x04, 0x70, 0xe5, 0xbf, 0x10, 0x01, 0x85, 0x19, 0x2d, 0x1f, 0xc5,
+ 0x7d, 0xfc, 0x4f, 0x20, 0x01, 0x04, 0x70, 0xe5, 0xbf, 0xde, 0xad, 0x7d,
+ 0xb0, 0x09, 0x21, 0xa2, 0xe9, 0x1c, 0x21,
+
+ /* hop-by-hop */
+ 60,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* destination options header */
+ 43,
+ 2, 1, 2, 0, 0, 201, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* routing header*/
+ 0x33,
+ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0x32,
+ 0x04, 0x00, 0x00, 0x81, 0x79, 0xb7, 0x05, 0x00, 0x00, 0x00, 0x01, 0x27,
+ 0xcf, 0xc0, 0xa5, 0xe4, 0x3d, 0x69, 0xb3, 0x72, 0x8e, 0xc5, 0xb0, 0x49,
+ 0x50, 0x76, 0x37, 0x20, 0x45, 0x53, 0x50};
+
+static kal_uint8 g_ipc_ut_v6_hop_dst_route_frag_ah_esp_pkt_1[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 8 + 16 + 24 + 24 + 24 + 8, 0x0, 0x3f,
+ 0x20, 0x01, 0x04, 0x70, 0xe5, 0xbf, 0x10, 0x01, 0x85, 0x19, 0x2d, 0x1f,
+ 0xc5, 0x7d, 0xfc, 0x4f, 0x20, 0x01, 0x04, 0x70, 0xe5, 0xbf, 0xde, 0xad,
+ 0x7d, 0xb0, 0x09, 0x21, 0xa2, 0xe9, 0x1c, 0x21,
+
+ /* hop-by-hop */
+ 60,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* destination options header */
+ 43,
+ 2, 1, 2, 0, 0, 201, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* routing header*/
+ 44,
+ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* fragment header */
+ 0x33,
+ 0, 0, 0, 0, 0, 0, 0,
+
+ 0x32,
+ 0x04, 0x00, 0x00, 0x81, 0x79, 0xb7, 0x05, 0x00, 0x00, 0x00, 0x01, 0x27,
+ 0xcf, 0xc0, 0xa5, 0xe4, 0x3d, 0x69, 0xb3, 0x72, 0x8e, 0xc5, 0xb0, 0x49,
+ 0x50, 0x77, 0x37, 0x20, 0x45, 0x53, 0x50};
+
+static kal_uint8 g_ipc_ut_igmp_pkt_1[] = {0x46, 0x00, 0x00, 0x30, 0x05, 0xf9,
+ 0x00, 0x00, 0x01, 0x02, 0x7c, 0x0e,
+ 0xc0, 0xa8, 0x02, 0x02, 0xe0, 0x00,
+ 0x00, 0x16, 0x94, 0x04, 0x00, 0x00,
+ 0x22, 0x00, 0x05, 0x06, 0x00, 0x00,
+ 0x00, 0x02, 0x04, 0x00, 0x00, 0x00,
+ 0xe0, 0x00, 0x00, 0xfc, 0x04, 0x00,
+ 0x00, 0x00, 0xef, 0xff, 0xff, 0xfa};
+
+static kal_uint8 g_ipc_ut_igmp_pkt_2[] = {0x46, 0x00, 0x00, 0x28, 0x05, 0xf0,
+ 0x00, 0x00, 0x01, 0x02, 0x7c, 0x1f,
+ 0xc0, 0xa8, 0x02, 0x02, 0xe0, 0x00,
+ 0x00, 0x16, 0x94, 0x04, 0x00, 0x00,
+ 0x22, 0x00, 0xf9, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x04, 0x00, 0x00, 0x00,
+ 0xe0, 0x00, 0x00, 0xfc, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+/* UDP large packet 2000 bytes */
+static kal_uint8 g_ipc_ut_large_udp_pkt[] = {
+ 0x45, 0x00, 0x07, 0xec, 0x28, 0xb3, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0xac, 0x11, 0x15, 0x8e,
+ 0x3e, 0xd2, 0x12, 0x28, 0xf1, 0xca, 0x14, 0x50, 0x07, 0xd8, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x7f,
+ 0x5d, 0x6f, 0x34, 0xae, 0x00, 0x09, 0x61, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x14, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x18,
+ 0x00, 0x10, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
+};
+
+/* UDP large packet 3632 bytes */
+static kal_uint8 g_ipc_ut_large_udp_pkt_s3632[] = {
+ 0x45, 0x00, 0x0E, 0x30, 0x28, 0xb3, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0xac, 0x11, 0x15, 0x8e,
+ 0x3e, 0xd2, 0x12, 0x28, 0x1e, 0xd2, 0x14, 0x50, 0x07, 0xd8, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x7f,
+ 0x5d, 0x6f, 0x34, 0xae, 0x00, 0x09, 0x61, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x14, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x18,
+ 0x00, 0x10, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x36, 0x37, 0x38, 0x39,
+ 0x45, 0x00, 0x0E, 0x30, 0x28, 0xb3, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0xac, 0x11, 0x15, 0x8e,
+ 0x3e, 0xd2, 0x12, 0x28, 0xf1, 0xca, 0x14, 0x50, 0x07, 0xd8, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x7f,
+ 0x5d, 0x6f, 0x34, 0xae, 0x00, 0x09, 0x61, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x14, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x18,
+ 0x00, 0x10, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31
+};
+
+/* ICMPv6 RA packet */
+static kal_uint8 g_ipc_ut_icmpv6_ra_pkt[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, 0xc6, 0x34, 0xff, 0x00, 0xfd, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x40, 0x40, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x24, 0x08, 0x84, 0xe2, 0x03, 0x1a, 0xbf, 0xca,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x9c
+};
+
+static kal_uint8 g_ipc_ut_icmpv6_rs_pkt[] = {
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3a, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xbc, 0x5a, 0xf9, 0x63, 0x58, 0x32, 0x0f, 0xab, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x85, 0x00, 0xf0, 0xee, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01, 0x00, 0x0c, 0x29, 0xc4, 0x43, 0xd3
+};
+
+static kal_uint8 g_ipc_ut_icmp_rs_pkt[] = {
+ 0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x01, 0x01, 0xee, 0xa1, 0xc0, 0xa8, 0xca, 0x97,
+ 0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0xf5, 0xff, 0x00, 0x00, 0x00, 0x00
+};
+
+static kal_uint8 g_ipc_ut_icmp_ra_pkt[] = {
+ 0x45, 0x00, 0x00, 0x24, 0x00, 0x00, 0x40, 0x00, 0x01, 0x01, 0xee, 0xa1, 0xc0, 0xa8, 0xca, 0x97,
+ 0xff, 0xff, 0xff, 0xff, 0x09, 0x00, 0x34, 0x55, 0x01, 0x02, 0x00, 0xff, 0xc0, 0xa8, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x8f, 0x00, 0x2b, 0x5a, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0xff, 0x05, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00,
+ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02
+};
+
+static const unsigned char pkt2508_1[] = {
+ 0x66, 0x80, 0x00, 0x00, 0x04, 0xe8, 0x2c, 0x38, 0x20, 0x01, 0x20, 0x61, 0x20, 0x00, 0x00, 0x1d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x20, 0x61, 0x20, 0x40, 0x90, 0x53,
+ 0x07, 0x09, 0x05, 0x6b, 0x52, 0xfa, 0x05, 0xdd, 0x2c, 0x00, 0x00, 0x01, 0x00, 0x28, 0x74, 0x4a,
+ 0x32, 0x00, 0x00, 0x01, 0x67, 0xa1, 0xfe, 0x64, 0x48, 0x1f, 0xde, 0x70, 0x00, 0x00, 0x00, 0x0b,
+ 0xed, 0xf8, 0x54, 0x8b, 0xc8, 0x3f, 0xa2, 0x02, 0x39, 0xf8, 0x9c, 0xd2, 0xd8, 0xec, 0xcc, 0x03,
+ 0xa4, 0x70, 0x7c, 0xfc, 0xa4, 0x79, 0x86, 0xfc, 0xcf, 0x15, 0x6c, 0x2b, 0xbe, 0x33, 0x1d, 0x22,
+ 0x85, 0x69, 0xc0, 0x90, 0x88, 0xa1, 0x4d, 0xbc, 0x92, 0x27, 0x4a, 0x6c, 0xbb, 0x38, 0xda, 0xcf,
+ 0x0d, 0xc2, 0x88, 0xd9, 0x7c, 0x34, 0xaf, 0x30, 0xde, 0x72, 0xb6, 0xd5, 0x66, 0xd7, 0x2a, 0x01,
+ 0xfb, 0x4a, 0x87, 0x66, 0x27, 0x72, 0xa5, 0x35, 0x41, 0x02, 0x4b, 0x46, 0x0d, 0xa4, 0xb6, 0xd3,
+ 0x91, 0xae, 0x88, 0x6a, 0x92, 0x32, 0x3f, 0x1e, 0xe5, 0xc2, 0x15, 0x55, 0x0d, 0x04, 0xc9, 0x83,
+ 0x09, 0xa4, 0x3a, 0x39, 0x59, 0xda, 0xda, 0x4f, 0xb1, 0x07, 0xa3, 0x17, 0xa1, 0x13, 0x7b, 0xfb,
+ 0x72, 0xe5, 0xce, 0x16, 0xfd, 0x18, 0xa9, 0xe2, 0xbe, 0xbf, 0x7a, 0xd9, 0x73, 0x70, 0xb7, 0xc4,
+ 0xa7, 0xb3, 0x06, 0x16, 0xb8, 0x6e, 0x21, 0x36, 0xd7, 0xf3, 0x67, 0xbf, 0x58, 0x6d, 0xdf, 0x52,
+ 0x12, 0x18, 0x60, 0xf7, 0xe2, 0xf7, 0x6d, 0x97, 0xaa, 0xd9, 0xf8, 0x78, 0xb9, 0xdb, 0x82, 0x7a,
+ 0xc4, 0x91, 0xba, 0xfe, 0xdd, 0x9e, 0x17, 0x3b, 0x31, 0xb6, 0xc8, 0x2a, 0x5f, 0xbc, 0x53, 0x01,
+ 0xbf, 0xb8, 0x53, 0x23, 0x98, 0xbd, 0xdd, 0x45, 0x83, 0xee, 0x31, 0x06, 0xa7, 0x4b, 0x37, 0x77,
+ 0x4d, 0xb3, 0x23, 0xa3, 0xce, 0x0e, 0x3c, 0xbc, 0x28, 0x1b, 0xa0, 0xf8, 0x64, 0x1a, 0x92, 0xc3,
+ 0x9c, 0xf0, 0x94, 0x8c, 0x96, 0x5c, 0x90, 0xb2, 0x72, 0x1e, 0x0b, 0x44, 0x8d, 0xee, 0x69, 0x4c,
+ 0x4f, 0xb2, 0xca, 0x1a, 0x38, 0x6d, 0x37, 0x56, 0xf8, 0x7b, 0xa4, 0x4e, 0xd4, 0xf7, 0xb4, 0xa9,
+ 0x3f, 0x74, 0xf8, 0x99, 0x8d, 0x12, 0x93, 0x97, 0x09, 0x41, 0xb4, 0x06, 0xe1, 0xbb, 0x1b, 0x22,
+ 0x13, 0xb3, 0x48, 0x13, 0x55, 0x4b, 0x78, 0xdd, 0x96, 0x31, 0x78, 0x46, 0x72, 0xc5, 0xfd, 0x54,
+ 0x8d, 0x0e, 0xfc, 0x37, 0x68, 0xed, 0xb2, 0x72, 0x03, 0x85, 0x06, 0x55, 0x7b, 0xfc, 0x3a, 0x59,
+ 0xc4, 0x48, 0x0e, 0x0e, 0x14, 0x79, 0xaa, 0x8a, 0x73, 0xfa, 0xd8, 0x9d, 0xe1, 0x58, 0xb6, 0x2c,
+ 0x19, 0x81, 0xbb, 0x3d, 0x5e, 0x81, 0x45, 0x6e, 0x97, 0x26, 0x75, 0x62, 0x67, 0x00, 0x88, 0x8e,
+ 0x48, 0xf9, 0x90, 0xf6, 0xb6, 0x70, 0x9e, 0xd8, 0x45, 0x93, 0x60, 0xa9, 0x2d, 0xc4, 0x26, 0xa7,
+ 0x1d, 0x94, 0x27, 0x79, 0x1f, 0xa9, 0xc6, 0x48, 0xd6, 0x58, 0xeb, 0xef, 0x8b, 0x4b, 0x8c, 0x25,
+ 0x9d, 0x2d, 0x89, 0x70, 0x01, 0x80, 0x7a, 0xe7, 0xfb, 0x43, 0x90, 0x8b, 0x1c, 0x0b, 0xc9, 0x4f,
+ 0xd0, 0x1e, 0xac, 0x64, 0x41, 0x7c, 0x7c, 0x63, 0xec, 0xe1, 0xad, 0xdd, 0x8f, 0xb8, 0x42, 0x87,
+ 0xfe, 0x76, 0xab, 0x88, 0x8a, 0x55, 0x7a, 0x6a, 0xd0, 0x86, 0xa5, 0x29, 0x84, 0x75, 0x01, 0xca,
+ 0x38, 0x7f, 0x0e, 0xc9, 0xfc, 0xfe, 0xb1, 0xf0, 0x89, 0xb4, 0x7e, 0x15, 0xce, 0xcc, 0xcf, 0x76,
+ 0xec, 0x68, 0xa1, 0xeb, 0xa6, 0x8a, 0x8c, 0xec, 0x59, 0x9f, 0x4c, 0x28, 0xea, 0x8b, 0x83, 0x57,
+ 0xe8, 0x78, 0x36, 0x56, 0x2a, 0x13, 0xcf, 0x7d, 0x10, 0x3d, 0x83, 0x31, 0xca, 0xaa, 0xc3, 0xa4,
+ 0xf1, 0x41, 0xd0, 0x02, 0xa9, 0x04, 0x70, 0xa9, 0x39, 0x00, 0x41, 0x41, 0x12, 0x95, 0xea, 0xfd,
+ 0xa9, 0xe3, 0x15, 0xe6, 0x84, 0x9a, 0x3d, 0xbf, 0x6b, 0x88, 0xf3, 0x3b, 0xce, 0x06, 0xef, 0x8d,
+ 0x14, 0x72, 0xb1, 0x11, 0x09, 0x1c, 0xf9, 0x53, 0xa5, 0x15, 0xd5, 0x95, 0xe4, 0xd5, 0x65, 0xdb,
+ 0xab, 0xf0, 0x3f, 0x0f, 0xba, 0xb8, 0x7f, 0xf1, 0x36, 0x6b, 0xf2, 0x4d, 0xb5, 0xd9, 0xf7, 0xe2,
+ 0xad, 0x9c, 0x54, 0xfb, 0x01, 0x54, 0xc3, 0x2d, 0x2b, 0x00, 0xb2, 0xdb, 0xd0, 0x8c, 0x15, 0xe0,
+ 0x3b, 0xab, 0x3d, 0x29, 0xe1, 0x6b, 0xcd, 0x43, 0x71, 0x0c, 0xbe, 0xcd, 0x3d, 0xd1, 0xf6, 0xd0,
+ 0x80, 0x13, 0xbd, 0x61, 0x21, 0x7e, 0x03, 0x7b, 0x25, 0x5d, 0xf3, 0xce, 0xa6, 0x9c, 0xd6, 0x4c,
+ 0x70, 0x1b, 0x92, 0x52, 0xf3, 0x8d, 0x5a, 0x9a, 0xa6, 0x21, 0x50, 0x3b, 0x02, 0x95, 0x1f, 0xa1,
+ 0x86, 0x22, 0xb6, 0x4a, 0x57, 0x22, 0x78, 0x7d, 0xbd, 0x44, 0xb8, 0x05, 0x99, 0x26, 0x75, 0x01,
+ 0xec, 0xeb, 0x58, 0xe9, 0xe8, 0xc5, 0xfd, 0x2f, 0xf2, 0xf6, 0x0c, 0xdc, 0x1d, 0x34, 0xe1, 0x15,
+ 0x30, 0x41, 0xfd, 0x23, 0x2e, 0x85, 0x37, 0x5f, 0xd1, 0xe7, 0x61, 0xb6, 0x60, 0x30, 0x8b, 0x6d,
+ 0xe7, 0xe4, 0xd3, 0x67, 0x37, 0xb8, 0xec, 0xe8, 0x7e, 0xa5, 0xde, 0xd0, 0x1c, 0x4d, 0x4c, 0x2b,
+ 0x29, 0x88, 0x19, 0x9f, 0xbf, 0xba, 0xa8, 0x36, 0x43, 0x6c, 0xde, 0xfd, 0x5e, 0x61, 0x5d, 0x3c,
+ 0xe3, 0x89, 0x87, 0xb8, 0x92, 0x26, 0xc5, 0xf6, 0xdb, 0x1d, 0x89, 0x2b, 0x01, 0x98, 0x3b, 0x2d,
+ 0xfe, 0xe5, 0x28, 0x00, 0x9f, 0x76, 0x75, 0xae, 0x50, 0xd7, 0xb8, 0x88, 0x6f, 0xcb, 0x11, 0x25,
+ 0xbd, 0x8d, 0x57, 0x5c, 0xfb, 0x45, 0x9b, 0xfe, 0x1c, 0xac, 0x09, 0x11, 0x55, 0x1b, 0x11, 0x8c,
+ 0xc8, 0x54, 0x1f, 0x65, 0x1a, 0x4f, 0xcb, 0x70, 0x7d, 0x45, 0x64, 0x73, 0x11, 0x08, 0x46, 0x88,
+ 0x5d, 0x84, 0x56, 0x6b, 0x19, 0xfc, 0x77, 0x8e, 0x0d, 0x26, 0x44, 0xad, 0x37, 0x6b, 0x2d, 0xdf,
+ 0xfe, 0x41, 0xb0, 0x4f, 0x1f, 0x5d, 0x5e, 0x9c, 0x2c, 0x56, 0xf8, 0x89, 0x52, 0x09, 0x97, 0x5c,
+ 0x8e, 0xbb, 0xcb, 0x8d, 0x26, 0xac, 0xa3, 0xbd, 0xa6, 0x87, 0x68, 0xaa, 0xa5, 0x0c, 0x30, 0xa7,
+ 0x13, 0x8f, 0x13, 0x23, 0x84, 0x88, 0x5b, 0xa0, 0xeb, 0x39, 0x5e, 0xce, 0x00, 0x8d, 0x19, 0x54,
+ 0x1d, 0x12, 0x52, 0xe9, 0x4b, 0xb2, 0x08, 0x87, 0x2b, 0xda, 0xf4, 0x53, 0x7c, 0xfa, 0x9e, 0x92,
+ 0x76, 0x54, 0x1c, 0x4f, 0xd8, 0x1b, 0x5b, 0x20, 0xe6, 0xfc, 0x17, 0x14, 0x72, 0x5c, 0xe1, 0xce,
+ 0x41, 0x68, 0x16, 0x62, 0xc8, 0x16, 0x0a, 0x63, 0x30, 0x90, 0xf4, 0xa8, 0x8d, 0x0f, 0xe2, 0xf9,
+ 0xda, 0x32, 0x8b, 0xd0, 0x72, 0x25, 0x01, 0xbf, 0x0a, 0xeb, 0xbb, 0x50, 0x1e, 0x7c, 0x69, 0xad,
+ 0xba, 0x3f, 0x7d, 0x25, 0x99, 0xbf, 0x9c, 0x57, 0x7e, 0xb0, 0x35, 0xcc, 0xfd, 0x51, 0x67, 0x14,
+ 0x9c, 0x55, 0xd0, 0xb5, 0xb6, 0xb6, 0x51, 0xc4, 0x0a, 0x35, 0x81, 0xbd, 0x8b, 0x62, 0xf4, 0x87,
+ 0xa5, 0x85, 0x64, 0x77, 0x73, 0x5e, 0x3c, 0x0f, 0x5d, 0xb1, 0xe4, 0x9c, 0x58, 0xbb, 0x80, 0x3a,
+ 0x38, 0xaa, 0x30, 0x38, 0xd9, 0xfb, 0x75, 0x1d, 0x93, 0xfb, 0xd3, 0xf2, 0xd3, 0x4a, 0x45, 0x2f,
+ 0xe5, 0xb8, 0x03, 0xe8, 0x83, 0x78, 0x80, 0x1a, 0x76, 0x20, 0x41, 0x6f, 0x82, 0x18, 0x89, 0x11,
+ 0xe2, 0x3a, 0xad, 0xd5, 0x0c, 0x5e, 0xa6, 0x4a, 0x95, 0x51, 0x23, 0x4c, 0xc1, 0x4d, 0x88, 0x45,
+ 0x6c, 0xaa, 0xe9, 0xf7, 0x18, 0x44, 0xfa, 0x4c, 0x47, 0x1d, 0xc7, 0x9e, 0xa5, 0x12, 0xd3, 0x80,
+ 0x30, 0x05, 0x2e, 0x5f, 0x77, 0x09, 0xc3, 0xfa, 0x78, 0x48, 0x36, 0x92, 0x40, 0x86, 0x39, 0x47,
+ 0x63, 0xaa, 0x75, 0x27, 0x44, 0xb9, 0x5c, 0x9c, 0xf7, 0x9d, 0x3e, 0x4e, 0x95, 0x5e, 0x10, 0x67,
+ 0x4a, 0xdf, 0xbb, 0xcb, 0x82, 0x1c, 0x7d, 0xf0, 0xfd, 0xe1, 0x74, 0x34, 0x4d, 0xa4, 0x14, 0x94,
+ 0x55, 0x67, 0x88, 0x01, 0xff, 0xd5, 0x62, 0x11, 0x37, 0xb1, 0xea, 0x7d, 0x52, 0xf3, 0x2e, 0xe2,
+ 0x95, 0x9f, 0xa1, 0x81, 0x9b, 0xef, 0xe5, 0x14, 0x75, 0x13, 0x73, 0x69, 0xf4, 0xfa, 0x09, 0xeb,
+ 0x2f, 0x1c, 0xed, 0xf4, 0x2d, 0xc7, 0x2b, 0xda, 0x55, 0xb8, 0xe4, 0xd0, 0x9c, 0x32, 0x38, 0xbb,
+ 0x34, 0xaf, 0xf8, 0x09, 0x4d, 0x00, 0x97, 0x4c, 0x93, 0x80, 0x22, 0xdf, 0xd1, 0xe6, 0x57, 0x1c,
+ 0x86, 0xc9, 0xa7, 0x1f, 0xbb, 0xd1, 0x12, 0x93, 0x0a, 0xbc, 0x3a, 0xf8, 0x5b, 0xaf, 0x33, 0xd6,
+ 0xd6, 0x17, 0x73, 0x6b, 0xc5, 0x4f, 0xda, 0x8b, 0x45, 0xe5, 0xab, 0x88, 0x42, 0x6b, 0xe7, 0xbb,
+ 0x96, 0xc9, 0x89, 0xc0, 0x71, 0xb6, 0x0a, 0x8f, 0x43, 0xf2, 0x80, 0xe4, 0x3b, 0xe9, 0x60, 0x98,
+ 0xa2, 0x6b, 0x56, 0xef, 0xe7, 0x81, 0x72, 0x71, 0xd5, 0x3c, 0x73, 0xff, 0x3d, 0x15, 0x21, 0x3b,
+ 0x3b, 0xa0, 0x0d, 0x57, 0x8e, 0x82, 0x82, 0x6c, 0x47, 0xc1, 0x32, 0x24, 0x77, 0xb2, 0xe3, 0x38,
+ 0x68, 0x57, 0x7f, 0xa3, 0x04, 0xa2, 0x20, 0x4d, 0xee, 0xe8, 0x6b, 0x18, 0xb1, 0x0f, 0x37, 0x6d,
+ 0x67, 0x9b, 0xd6, 0xbd, 0xb7, 0x65, 0x7d, 0x0f, 0xb0, 0x17, 0x5f, 0xd8, 0x37, 0x6d, 0x12, 0xdb,
+ 0x69, 0x1c, 0x12, 0x11, 0x4d, 0xaa, 0x58, 0xf9, 0x7d, 0x6d, 0x40, 0x69, 0xd2, 0x3e, 0x5c, 0x35,
+ 0xc9, 0x49, 0xd9, 0x44, 0xfd, 0x17, 0x5c, 0xa8, 0x8d, 0xe2, 0xe9, 0x5c, 0x39, 0x85, 0xab, 0xbe,
+ 0xd2, 0x61, 0xab, 0x41, 0x37, 0xd0, 0x6c, 0x39, 0xb9, 0x57, 0x2c, 0xdf, 0x03, 0x34, 0x4b, 0xed
+};
+
+static const unsigned char pkt2509_1[] = {
+ 0x66, 0x80, 0x00, 0x00, 0x00, 0xa8, 0x2c, 0x38, 0x20, 0x01, 0x20, 0x61, 0x20, 0x00, 0x00, 0x1d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x20, 0x61, 0x20, 0x40, 0x90, 0x53,
+ 0x07, 0x09, 0x05, 0x6b, 0x52, 0xfa, 0x05, 0xdd, 0x2c, 0x00, 0x04, 0xe0, 0x00, 0x28, 0x74, 0x4a,
+ 0x28, 0xb0, 0x77, 0xea, 0x91, 0x1e, 0xfc, 0xda, 0xa2, 0xc3, 0xf1, 0x57, 0x96, 0xd9, 0xd5, 0x72,
+ 0xbc, 0xe4, 0x9c, 0xa8, 0xba, 0x77, 0x93, 0x3c, 0x04, 0x9f, 0x86, 0xc5, 0x12, 0xe3, 0x09, 0x07,
+ 0x63, 0xa0, 0xd3, 0x0f, 0xff, 0x36, 0xe9, 0xf0, 0x0b, 0x65, 0x10, 0xe8, 0xa5, 0x0d, 0xf9, 0x4e,
+ 0x3f, 0x4a, 0x27, 0xee, 0x51, 0x82, 0x28, 0xca, 0xfa, 0xfd, 0x9e, 0xb2, 0x32, 0x9f, 0x2e, 0xa8,
+ 0x8e, 0x25, 0xcd, 0xb0, 0xc2, 0x59, 0x8a, 0xd6, 0x5b, 0x7b, 0xff, 0x56, 0x18, 0xae, 0x2a, 0x18,
+ 0xd2, 0x9e, 0x99, 0xc1, 0x12, 0xf5, 0x76, 0x4c, 0x8a, 0xd1, 0xf9, 0x96, 0xba, 0x97, 0xfc, 0xf6,
+ 0x65, 0xe6, 0xf3, 0x6a, 0x2d, 0x82, 0x80, 0x19, 0x59, 0x41, 0x9a, 0x0d, 0x5d, 0x7d, 0x1d, 0x59,
+ 0x7a, 0x55, 0xe0, 0x3b, 0x4b, 0x24, 0x30, 0x8f, 0xab, 0x5f, 0x4e, 0x4f, 0x0f, 0x25, 0x5d, 0x11,
+ 0x6d, 0xcc, 0xba, 0x9c, 0xc6, 0xa1, 0x73, 0xe1, 0xac, 0x18, 0x3c, 0xe8, 0xff, 0xee, 0x25, 0x2f,
+ 0xba, 0x47, 0x75, 0x9f, 0x4f, 0x6a, 0x97, 0x4c, 0xe4, 0xa5, 0xef, 0xc9, 0xb1, 0x6c, 0xed, 0xfc
+};
+
+static const unsigned char pkt2510_1[108] = {
+ 0x66, 0x80, 0x00, 0x00, 0x00, 0x34, 0x2c, 0x38, 0x20, 0x01, 0x20, 0x61, 0x20, 0x00, 0x00, 0x1d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x20, 0x61, 0x20, 0x40, 0x90, 0x53,
+ 0x07, 0x09, 0x05, 0x6b, 0x52, 0xfa, 0x05, 0xdd, 0x32, 0x00, 0x05, 0x78, 0x67, 0xa1, 0xfe, 0x64,
+ 0x9c, 0x19, 0xe0, 0x15, 0xfe, 0x43, 0x1e, 0x06, 0xe6, 0x9f, 0xb8, 0x96, 0x12, 0x58, 0x77, 0xfc,
+ 0xa3, 0x84, 0x78, 0xac, 0x60, 0xa5, 0x78, 0x10, 0xfd, 0x7e, 0x39, 0xd1, 0x85, 0xee, 0xc3, 0xb5,
+ 0x0d, 0x47, 0x2a, 0x79, 0x30, 0x67, 0x6d, 0x9d, 0xc7, 0xcd, 0x65, 0x3b
+};
+
+
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+static kal_uint8 ipc_ut_invalid_len_ip_packet[IPC_INVALID_MAX_PKT_LEN];
+#endif
+
+#define UT_ASSERT ASSERT
+
+/*------------------------------------------------------------------------------
+ * Private Helper macros
+ *
+ * IPCore log level = {1, 2, 3, etc}
+ * level = 1 => use fake printf
+ * level = 2 => open utILOG utDLOG utELOG
+ * level = 3 => open utILOG utELOG
+ * level = etc => no log
+ *----------------------------------------------------------------------------*/
+#define IPC_UT_ERR_PREFIX __FILE__ ":" __LINE__ ": "
+
+#define ipc_ut_log(_fmts, ...) \
+ _ipc_ut_log("%s():%d " _fmts "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#ifdef __unix__
+#define utELOG(_fmts, ...) \
+ kal_sprintf(p_ret_err_str, "%s:%d: " _fmts, __FILE__, __LINE__, ##__VA_ARGS__); \
+ _ipc_ut_log("[FAILED] %s():%d - " _fmts "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+ UT_ASSERT(KAL_FALSE);
+#else
+#define utELOG(_fmts, ...) \
+ _ipc_ut_log("[FAILED] %s():%d - " _fmts "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+ UT_ASSERT(KAL_FALSE);
+#endif
+
+#define utILOG ipc_ut_log
+#define utDLOG ipc_ut_log
+
+#if IPC_UT_LOG_LV == 1
+ extern int fake_print(const char *fmt, ...);
+ #define _ipc_ut_log fake_print
+#elif IPC_UT_LOG_LV == 2
+ #define _ipc_ut_log printf
+#elif IPC_UT_LOG_LV == 3
+ #define _ipc_ut_log printf
+ #undef utDLOG
+ #define utDLOG
+#else
+ #define _ipc_ut_log
+#endif
+
+#define IPC_UT_PASS() utILOG("\r\n===================================>PASSED\r\n")
+
+#ifdef __SE7_SD8_AUTO_UT__
+ #undef UT_ASSERT
+ #define UT_ASSERT(args) \
+ { \
+ if (!(args)) { \
+ ipc_ut_log("Assert failed !!! (%s)", #args); \
+ } \
+ }
+ #undef IPC_UT_PASS()
+ #define IPC_UT_PASS()
+#endif
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ *----------------------------------------------------------------------------*/
+void ipc_ut_msg_reset(void * latest_local_param_p, kal_uint32 latest_local_param_size, void * latest_peer_buff_p, kal_uint32 latest_peer_buff_size);
+void ipc_ut_init(void);
+
+void ipc_ut_ul_filter_callback(void *context, kal_int32 filter_id, qbm_gpd *head_gpd, qbm_gpd *tail_gpd, kal_uint32 length);
+void ipc_ut_dl_filter_callback(void *context, kal_int32 filter_id, qbm_gpd *head_gpd, qbm_gpd *tail_gpd, kal_uint32 length);
+void ipc_ut_ul_filter_with_info_callback(ipc_filter_info_t *info_p, void *context, kal_int32 filter_id, qbm_gpd *head_gpd, qbm_gpd *tail_gpd, kal_uint32 length);
+void ipc_ut_dl_filter_with_info_callback(ipc_filter_info_t *info_p, void *context, kal_int32 filter_id, qbm_gpd *head_gpd, qbm_gpd *tail_gpd, kal_uint32 length);
+kal_bool ipc_ut_ul_filter_registration(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz);
+kal_bool ipc_ut_dl_filter_registration(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz);
+void ipc_ut_reset_ul_info(void);
+void ipc_ut_reset_ul_filter_info(void);
+void ipc_ut_reset_dl_filter_info(void);
+void ipc_ut_reset_dl_callback_info(void);
+kal_bool ipc_ut_ul_reload(void *context);
+kal_bool ipc_ut_dl_callback(void *context, ipc_io_request_t *ior);
+kal_int32 ipc_ut_check_netif(ipc_netif_t *netif, ipc_ut_netif_t *net);
+kal_int32 ipc_ut_check_session(ipc_session_t *session, ipc_ut_netif_t *net);
+void ipc_ut_prepare_ul_gpd_list(kal_bool allValidIpPkt, kal_uint32 ipv4_cnt, kal_uint32 dhcpv4_idx, kal_uint32 ipv6_cnt, kal_uint32 dhcpv6_idx, qbm_gpd **head_gpd, qbm_gpd **tail_gpd, ipc_io_request_t **ior);
+void ipc_ut_prepare_dl_gpd_list(kal_uint32 ipv4_cnt, kal_uint32 dhcpv4_idx, kal_bool dnsv4_only, kal_bool v4hdr_exist, kal_uint32 ipv6_cnt, kal_uint32 dhcpv6_idx, kal_bool dnsv6_only, kal_bool v6hdr_exist, kal_uint32 additional_bd_cnt, kal_uint32 align_offset, qbm_gpd **head_gpd, qbm_gpd **tail_gpd, kal_uint16 *ipv4_invalid_packet_len, kal_uint16 *ipv6_invalid_packet_len, kal_bool spd_enable, kal_bool spd_igr_bit_enable, ipc_ut_spd_position_e spd_position);
+void ipc_ut_free_gpd_list(qbm_gpd *head_gpd, qbm_gpd *tail_gpd);
+kal_uint32 ipc_ut_gpd_list_count(qbm_gpd *head_gpd, qbm_gpd *tail_gpd);
+kal_uint32 ipc_ut_non_igr_meta_count(kal_uint32 start_idx, kal_uint32 end_idx, LHIF_QUEUE_TYPE q_type);
+kal_uint32 ipc_ut_spd_payload_count(qbm_gpd *head_gpd, qbm_gpd *tail_gpd);
+void ipc_ut_install_ul_filters(kal_bool callback_with_info, kal_bool with_callback, kal_uint32 ipv4_filter_cnt, kal_uint32 ipv6_filter_cnt, kal_bool with_wildcard, kal_bool with_bwm, kal_uint8 matched_filter_idx_v4, kal_uint8 matched_filter_idx_v6, kal_uint32 good_netif_id);
+void ipc_ut_install_dl_filters(kal_bool callback_with_info, kal_bool with_callback, kal_uint32 ipv4_filter_cnt, kal_uint32 ipv6_filter_cnt, kal_uint8 matched_filter_idx_v4, kal_uint8 matched_filter_idx_v6, kal_uint32 netif_id);
+void ipc_ut_uninstall_ul_filters(kal_uint32 ipv4_filter_cnt, kal_uint32 ipv6_filter_cnt, kal_bool with_wildcard, kal_bool with_bwm);
+void ipc_ut_uninstall_dl_filters(kal_uint32 ipv4_filter_cnt, kal_uint32 ipv6_filter_cnt);
+#if defined(__MTK_TARGET__)
+kal_bool ipc_ut_struct(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz);
+#endif
+
+void ipc_ut_msg_reset(void * latest_local_param_p,
+ kal_uint32 latest_local_param_size,
+ void * latest_peer_buff_p,
+ kal_uint32 latest_peer_buff_size) {
+ kal_mem_set(&ipc_ut_msg_sent, 0, sizeof(ipc_ut_msg_sent));
+ ipc_latest_local_param_p = latest_local_param_p;
+ ipc_latest_local_param_size = latest_local_param_size;
+ ipc_latest_peer_buff_p = latest_peer_buff_p;
+ ipc_latest_peer_buff_size = latest_peer_buff_size;
+}
+
+void ipc_ut_init_meta(void) {
+ kal_uint32 idx;
+ kal_uint8 i;
+ static kal_bool is_first_init = KAL_TRUE;
+
+ if (is_first_init) {
+ kal_mem_set(ipc_ut_meta_queues, 0, sizeof(ipc_ut_meta_queue_t));
+ is_first_init = KAL_FALSE;
+ }
+
+ for (i = 0; i < IPC_UT_META_QUEUE_NUM_MAX; i++) {
+ switch (i) {
+ case IPC_UT_LHIF_META_AP0:
+ kal_mem_set(ipc_ut_meta_tbl_s, 0, sizeof(ipc_ut_meta_tbl_s)*IPC_UT_META_TABLE_SIZE);
+ for (idx = 0; idx < IPC_UT_META_TABLE_SIZE; idx++) {
+ ipc_ut_meta_tbl_s[idx].vrb_addr = ipc_ut_meta_ring_buf_s[idx];
+ }
+ ipc_ut_meta_queues[i].base_addr = (kal_uint8*)ipc_ut_meta_tbl_s;
+ ipc_ut_meta_queues[i].type_idx = i;
+ break;
+ case IPC_UT_IPF_DL_0:
+ kal_mem_set(ipc_ut_dl_meta_tbl_s, 0, sizeof(ipc_ut_dl_meta_tbl_s)*IPC_UT_META_TABLE_SIZE);
+ for (idx = 0; idx < IPC_UT_META_TABLE_SIZE; idx++) {
+ ipc_ut_dl_meta_tbl_s[idx].addr = (kal_uint32)ipc_ut_meta_ring_buf_s[idx];
+ }
+ ipc_ut_meta_queues[i].base_addr = (kal_uint8*)ipc_ut_dl_meta_tbl_s;
+ ipc_ut_meta_queues[i].type_idx = i;
+ break;
+ default:
+ UT_ASSERT(0);
+ break;
+ }
+ }
+}
+
+void ipc_ut_init_spd(void) {
+ //qbm_reg_cbk_peek_before_free(QBM_TYPE_HIF_DL_SPD, NULL);
+}
+
+void ipc_ut_init(void) {
+ // init for ut case
+ ipc_ut_init_meta();
+ ipc_ut_init_spd();
+
+ // reset message
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+
+ // disabled DPFM
+ ipc_ut_dpfm_is_activated_g = KAL_FALSE;
+}
+
+void ipc_ut_ul_filter_callback(void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length) {
+ ipc_ut_ul_filter_with_info_callback(NULL, context, filter_id, head_gpd, tail_gpd, length);
+}
+
+void ipc_ut_dl_filter_callback(void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length) {
+ ipc_ut_dl_filter_with_info_callback(NULL, context, filter_id, head_gpd, tail_gpd, length);
+}
+
+void ipc_ut_ul_filter_with_info_callback(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length) {
+ if (info_p) {
+ kal_mem_cpy(&ipc_ut_ul_filter_info, info_p, sizeof(ipc_filter_info_t));
+ } else {
+ kal_mem_set(&ipc_ut_ul_filter_info, 0, sizeof(ipc_filter_info_t));
+ ipc_ut_ul_filter_info.ip_id = -1;
+ ipc_ut_ul_filter_info.ebi = -1;
+ }
+
+ ipc_ut_ul_filter_id = filter_id;
+ ipc_ut_ul_filter_gpd_cnt += ipc_ut_gpd_list_count(head_gpd, tail_gpd);
+
+
+ if (NULL == ipc_ut_ul_head_gpd) {
+ ipc_ut_ul_head_gpd = head_gpd;
+ }
+
+ if (ipc_ut_ul_tail_gpd) {
+ QBM_DES_SET_NEXT(ipc_ut_ul_tail_gpd, head_gpd);
+ }
+ ipc_ut_ul_tail_gpd = tail_gpd;
+}
+
+void ipc_ut_dl_filter_with_info_callback(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length) {
+ if (info_p) {
+ kal_mem_cpy(&ipc_ut_dl_filter_info, info_p, sizeof(ipc_filter_info_t));
+ ((upcm_dlvr_dl_info_t *)QBM_DES_GET_SW_CTRL_FIELD(head_gpd))->ebi = 0;
+ } else {
+ kal_mem_set(&ipc_ut_dl_filter_info, 0, sizeof(ipc_filter_info_t));
+ ipc_ut_dl_filter_info.ip_id = -1;
+ }
+
+ ipc_ut_dl_filter_id = filter_id;
+ ipc_ut_dl_filter_gpd_cnt += ipc_ut_gpd_list_count(head_gpd, tail_gpd);
+ ipc_ut_dl_filter_spd_payload_cnt += ipc_ut_spd_payload_count(head_gpd, tail_gpd);
+
+ if (NULL == ipc_ut_dl_head_gpd) {
+ ipc_ut_dl_head_gpd = head_gpd;
+ }
+
+ if (ipc_ut_dl_tail_gpd) {
+ QBM_DES_SET_NEXT(ipc_ut_dl_tail_gpd, head_gpd);
+ }
+ ipc_ut_dl_tail_gpd = tail_gpd;
+}
+
+kal_bool ipc_ut_ul_filter_registration(void *p_param,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 callback_with_info = {0};
+ kal_uint32 idx = 0;
+ ipc_ut_filter_info_t *info = NULL;
+ ipc_filter_rules_t *rules = NULL;
+ ipc_filter_rules_t invalid_rules = {0};
+ kal_int32 filter_id = 0;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ /* init before test */
+ ipc_ut_init();
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++) {
+ /*
+ * Negative cases for filter registration:
+ * 1. Register without callback function.
+ * 2. invalid rules.
+ */
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->valid_fields = IPC_FILTER_BY_SRC_IPV4;
+ kal_mem_set(&ntfy_ctxt, 0, sizeof(ipc_filter_ntfy_ctxt_t));
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_NG != ipc_ut_get_error()) {
+ utELOG("register a filter without callback function shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->valid_fields = 0;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register an invalid UL filter is shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->valid_fields = IPC_FILTER_BY_SRC_IPV6;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a IPv4 filter with invalid rules shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->valid_fields = IPC_FILTER_BY_SRC_IPV4;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a IPv6 filter with invalid rules shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_MIXED;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a IPv4v6 filter with invalid rules shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->valid_fields = IPC_FILTER_BY_PROTOCOL;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a IPv4 filter with invalid protocol type shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->valid_fields = IPC_FILTER_BY_EBI;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register an EBI rule to uplink filter shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->valid_fields = IPC_FILTER_BY_PDN_ID;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a PDN ID rule to uplink filter shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Positive cases for filter registration:
+ */
+ kal_mem_set(ipc_ut_info_set, 0, sizeof(ipc_ut_info_set));
+ for (idx = 0; idx < IPC_MAX_FILTER_CNT; idx++) {
+ info = &ipc_ut_info_set[idx];
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT);
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 3344+idx;
+ rules->dst_port = 5566;
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ ntfy_ctxt.p_ntfy_args = (void *)info;
+
+ if (idx < (IPC_MAX_FILTER_CNT / 2)) {
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+ } else {
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+ }
+ if (0 > info->filter_id || IPC_UT_NO_ERROR != ipc_ut_get_error()) {
+ utELOG("failed to register a valid filter!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /*
+ * Negative cases for filter registration:
+ * 3. all filters are busy.
+ */
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT);
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 67;
+ rules->dst_port = 66;
+ rules->valid_fields = IPC_FILTER_BY_PROTOCOL;
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ ntfy_ctxt.p_ntfy_args = NULL;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_NG != ipc_ut_get_error()) {
+ utELOG("register a filter while all filters are busy shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Negative case for filter deregisteration:
+ * 1. invalid filter id in invalid range.
+ */
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ ipc_dereg_filter(IPC_MAX_FILTER_CNT);
+ if (IPC_UT_DEREGISTER_FILTER_WITH_INVALID_ID != ipc_ut_get_error()) {
+ utELOG("deregister a invalid filter shall get a fail resule!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ ipc_dereg_filter(-1);
+ if (IPC_UT_DEREGISTER_FILTER_WITH_INVALID_ID != ipc_ut_get_error()) {
+ utELOG("deregister a invalid filter shall get a fail resule!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Positive case for filter deregisteration.
+ */
+ for (idx = 0; idx < IPC_MAX_FILTER_CNT; idx++) {
+ info = &ipc_ut_info_set[idx];
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ ipc_dereg_filter(info->filter_id);
+ if (IPC_UT_NO_ERROR != ipc_ut_get_error()) {
+ utELOG("failed to deregister a valid filter!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Negative case for filter deregisteration:
+ * 2. filter unregistered.
+ */
+ UT_ASSERT(KAL_FALSE == ipc_dereg_filter(info->filter_id));
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_filter_registration(void *p_param,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 callback_with_info = {0};
+ kal_uint32 idx = 0;
+ ipc_ut_filter_info_t *info = NULL;
+ ipc_filter_rules_t *rules = NULL;
+ ipc_filter_rules_t invalid_rules = {0};
+ kal_int32 filter_id = 0;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ /* init before test */
+ ipc_ut_init();
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++) {
+ /*
+ * Negative cases for filter registration:
+ * 1. Register without callback function.
+ * 2. invalid rules.
+ */
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ rules->valid_fields = IPC_FILTER_BY_SRC_IPV4 | IPC_FILTER_BY_PDN_ID;
+ kal_mem_set(&ntfy_ctxt, 0, sizeof(ipc_filter_ntfy_ctxt_t));
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_NG != ipc_ut_get_error()) {
+ utELOG("register a filter without callback function shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->valid_fields = 0;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_dl_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_dl_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register an invalid DL filter is shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ rules->valid_fields = IPC_FILTER_BY_SRC_IPV6 | IPC_FILTER_BY_PDN_ID;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a IPv4 filter with invalid rules shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ rules->valid_fields = IPC_FILTER_BY_SRC_IPV4 | IPC_FILTER_BY_PDN_ID;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a IPv6 filter with invalid rules shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_MIXED;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a IPv4v6 filter with invalid rules shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ rules->valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_PDN_ID;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if (0 <= filter_id ||
+ IPC_UT_REGISTER_FILTER_VALIDATE_FAIL != ipc_ut_get_error()) {
+ utELOG("register a IPv4 filter with invalid protocol type shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Positive cases for filter registration:
+ */
+ kal_mem_set(ipc_ut_info_set, 0, sizeof(ipc_ut_info_set));
+ for (idx = 0; idx < IPC_MAX_FILTER_CNT; idx++) {
+ info = &ipc_ut_info_set[idx];
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID);
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 3344+idx;
+ rules->dst_port = 5566;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ if (idx < (IPC_MAX_FILTER_CNT / 2)) {
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+ } else {
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+ }
+ if (0 > info->filter_id || IPC_UT_NO_ERROR != ipc_ut_get_error()) {
+ utELOG("failed to register a valid filter!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /*
+ * Negative cases for filter registration:
+ * 3. all filters are busy.
+ */
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ rules = &invalid_rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT);
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 67;
+ rules->dst_port = 66;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ rules->valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_PDN_ID;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ if ((0 <= filter_id) ||
+ (IPC_UT_REGISTER_FILTER_NG != ipc_ut_get_error())) {
+ utELOG("register a filter while all filters are busy shall get a negetive filter_id in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Negative case for filter deregisteration:
+ * 1. invalid filter id in invalid range.
+ */
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ ipc_dereg_filter(IPC_MAX_FILTER_CNT);
+ if (IPC_UT_DEREGISTER_FILTER_WITH_INVALID_ID != ipc_ut_get_error()) {
+ utELOG("deregister a invalid filter shall get a fail resule!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ ipc_dereg_filter(-1);
+ if (IPC_UT_DEREGISTER_FILTER_WITH_INVALID_ID != ipc_ut_get_error()) {
+ utELOG("deregister a invalid filter shall get a fail resule!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Positive case for filter deregisteration.
+ */
+ for (idx = 0; idx < IPC_MAX_FILTER_CNT; idx++) {
+ info = &ipc_ut_info_set[idx];
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ ipc_dereg_filter(info->filter_id);
+ if (IPC_UT_NO_ERROR != ipc_ut_get_error()) {
+ utELOG("failed to deregister a valid filter!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Negative case for filter deregisteration:
+ * 2. filter unregistered.
+ */
+ UT_ASSERT(KAL_FALSE == ipc_dereg_filter(info->filter_id));
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ul_reload(void *context)
+{
+ ipc_ut_netif_t *net = (ipc_ut_netif_t *)context;
+
+ net->ul_reload_called = KAL_TRUE;
+ return net->need_retry;
+}
+
+void ipc_ut_reset_dl_callback_info(void)
+{
+ ipc_ut_dl_callback_gpd_cnt = 0;
+ ipc_ut_dl_callback_spd_payload_cnt = 0;
+ ipc_ut_dl_callback_did_cnt = 0;
+ ipc_ut_dl_callback_did_pkt_cnt = 0;
+ ipc_ut_dl_callback_did_dpfm_pkt_cnt = 0;
+ ipc_ut_dl_callback_did_dpfm_cnt = 0;
+ ipc_ut_dl_meta_buf_free_num_s = 0;
+}
+
+kal_bool ipc_ut_dl_callback(void *context, ipc_io_request_t *ior)
+{
+ UT_ASSERT(NULL != ior);
+
+ /*
+ * Calculate total GPD count put into callback function
+ */
+ {
+ ipc_io_request_t *ior_p = NULL;
+ ipc_io_request_t *next_ior = NULL;
+
+ for (ior_p = ior; ior_p; ior_p = next_ior) {
+ next_ior = ior_p->next_request;
+ if (ior_p->first_gpd && ior_p->last_gpd) {
+ ipc_ut_dl_callback_gpd_cnt += ipc_ut_gpd_list_count(ior_p->first_gpd, ior_p->last_gpd);
+ ipc_ut_dl_callback_spd_payload_cnt += ipc_ut_spd_payload_count(ior_p->first_gpd, ior_p->last_gpd);
+ }
+ }
+ }
+
+ /*
+ * Destroy whole IOR
+ */
+ ipc_dest_ior(ior);
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_callback_did(void *context, upcm_did *did)
+{
+ UT_ASSERT(NULL != did);
+
+ ipc_ut_dl_callback_did_cnt ++;
+ ipc_ut_dl_callback_did_pkt_cnt += UPCM_DID_GET_PKT_NUM(did);
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_callback_did_ra(void *context, upcm_did *did)
+{
+ kal_uint8 *p_data = NULL;
+ upcm_did_si *sit = NULL;
+ kal_uint32 i = 0;
+ kal_uint32 pkt_count = 0;
+ kal_int32 comp_result = 0;
+
+ UT_ASSERT(NULL != did);
+
+ ipc_ut_dl_callback_did_cnt ++;
+ ipc_ut_dl_callback_did_pkt_cnt += UPCM_DID_GET_PKT_NUM(did);
+ pkt_count = UPCM_DID_GET_PKT_NUM(did);
+ UT_ASSERT(1 == pkt_count);
+
+ /* Check if packet content is RA */
+ sit = UPCM_DID_GET_SIT_PTR(did);
+ p_data = UPCM_DID_SI_GET_DATAPTR(sit);
+ UT_ASSERT(sizeof(g_ipc_ut_icmpv6_ra_pkt) == UPCM_DID_SI_GET_LEN(sit));
+ comp_result = kal_mem_cmp(p_data, g_ipc_ut_icmpv6_ra_pkt, sizeof(g_ipc_ut_icmpv6_ra_pkt));
+ UT_ASSERT(0 == comp_result);
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_callback_did_dpfm(void *context, upcm_did *did)
+{
+ UT_ASSERT(NULL != did);
+
+ ipc_ut_dl_callback_did_dpfm_cnt ++;
+ ipc_ut_dl_callback_did_dpfm_pkt_cnt += UPCM_DID_GET_PKT_NUM(did);
+
+ return KAL_TRUE;
+}
+
+kal_int32 ipc_ut_check_netif(ipc_netif_t *netif, ipc_ut_netif_t *net)
+{
+ kal_uint32 error_code = 0;
+
+ if (netif) {
+ do {
+ if (net->handle != netif) {
+ error_code = -2;
+ break;
+ }
+
+ if (kal_mem_cmp(&net->conf, &netif->config, sizeof(ipc_conf_t))) {
+ error_code = -3;
+ break;
+ }
+ } while (0);
+ IPC_R_UNLOCK_OBJECT(netif, ipc_spinlock_g);
+ } else {
+ error_code = -1;
+ }
+
+ return error_code;
+}
+
+kal_int32 ipc_ut_check_session(ipc_session_t *session, ipc_ut_netif_t *net)
+{
+ kal_uint32 error_code = 0;
+ kal_uint32 ip_id = 0;
+ ipc_session_t *tmp_session = NULL;
+
+ if (session) {
+ do {
+ if (net->session[net->ip_type] != session) {
+ error_code = -2;
+ break;
+ }
+
+ if (net->pdn_id != session->context) {
+ error_code = -3;
+ break;
+ }
+
+ if (net->ip_type != session->type) {
+ error_code = -4;
+ break;
+ }
+
+ if (net->handle != session->netif) {
+ error_code = -5;
+ break;
+ }
+
+ ip_id = ipc_get_ip_id(net->handle);
+ if (session->ip_id != ip_id) {
+ error_code = -6;
+ break;
+ }
+
+ tmp_session = ipc_find_session_by_ip_id(ip_id,
+ ((IPC_IP_TYPE_MIXED == session->type) ? IPC_IP_TYPE_IPV4 : session->type));
+ if (tmp_session) {
+ if (ip_id != tmp_session->ip_id) {
+ error_code = -7;
+ IPC_R_UNLOCK_OBJECT(tmp_session, ipc_spinlock_g);
+ break;
+ }
+ if (session != tmp_session) {
+ error_code = -8;
+ IPC_R_UNLOCK_OBJECT(tmp_session, ipc_spinlock_g);
+ break;
+ }
+ IPC_R_UNLOCK_OBJECT(tmp_session, ipc_spinlock_g);
+ }
+ } while (0);
+
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ } else {
+ error_code = -1;
+ }
+
+ return error_code;
+}
+
+void ipc_ut_reset_ul_filter_info(void)
+{
+ kal_mem_set(&ipc_ut_ul_filter_info, 0, sizeof(ipc_filter_info_t));
+ ipc_ut_ul_filter_info.ip_id = -1;
+ ipc_ut_ul_filter_info.ebi = -1;
+ ipc_ut_ul_filter_id = -1;
+ ipc_ut_ul_filter_gpd_cnt = 0;
+}
+
+void ipc_ut_reset_dl_filter_info(void)
+{
+ kal_mem_set(&ipc_ut_dl_filter_info, 0, sizeof(ipc_filter_info_t));
+ ipc_ut_dl_filter_info.ip_id = -1;
+ ipc_ut_dl_filter_info.ebi = -1;
+ ipc_ut_dl_filter_id = -1;
+ ipc_ut_dl_filter_gpd_cnt = 0;
+ ipc_ut_dl_filter_expect_gpd_cnt = 0;
+ ipc_ut_dl_filter_spd_payload_cnt = 0;
+}
+
+void ipc_ut_reset_did(upcm_did *did)
+{
+ upcm_did_si *sit = UPCM_DID_GET_SIT_PTR(did);
+ kal_uint32 did_idx;
+
+ did_idx = did - ipc_ut_did_tbl_s;
+ kal_mem_set(&(did->sit), 0, sizeof(upcm_did_si) * UPCM_DID_MAX_SIT_ENT_NUM);
+}
+
+kal_uint32 ipc_ut_alloc_did(kal_uint32 request_num,
+ upcm_did **p_did_head,
+ upcm_did **p_did_tail) {
+#if 1
+ kal_uint32 alloc_num;
+ upcm_did *did;
+ upcm_did *prev_did = NULL;
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ alloc_num = upcm_did_alloc_q(request_num, p_did_head, p_did_tail);
+
+ end_of_list = KAL_FALSE;
+ for (did = *p_did_head; did && !end_of_list; did = next_did) {
+ next_did = UPCM_DID_GET_NEXT(did);
+ end_of_list = (did == *p_did_tail);
+ ipc_ut_reset_did(did);
+
+ if (prev_did) {
+ UPCM_DID_SET_NEXT(prev_did, did);
+ }
+ prev_did = did;
+ }
+
+ return alloc_num;
+#else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+}
+
+void ipc_ut_reset_meta(kal_uint32 start_idx,
+ kal_uint32 end_idx,
+ LHIF_QUEUE_TYPE q_type) {
+ kal_uint32 i = start_idx;
+
+
+ while (i != end_idx) {
+ switch (q_type) {
+ case IPC_UT_LHIF_META_AP0:
+ kal_mem_set(&ipc_ut_meta_tbl_s[i], 0, sizeof(lhif_meta_tbl_t));
+ ipc_ut_meta_tbl_s[i].vrb_addr = ipc_ut_meta_ring_buf_s[i];
+ break;
+ case IPC_UT_IPF_DL_0:
+ kal_mem_set(&ipc_ut_dl_meta_tbl_s[i], 0, sizeof(ipf_dl_meta));
+ ipc_ut_dl_meta_tbl_s[i].addr = (kal_uint32)ipc_ut_meta_ring_buf_s[i];
+ break;
+ default:
+ UT_ASSERT(0);
+ break;
+ }
+ i ++;
+ if (i == IPC_UT_META_TABLE_SIZE) {
+ i = 0;
+ }
+ }
+}
+
+kal_uint32 ipc_ut_alloc_meta(
+ ipc_ut_meta_type_e q_type,
+ kal_uint32 request_num,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx) {
+ kal_uint32 alloc_num, used_num, remain_num;
+
+ kal_uint8 write_idx, read_idx;
+
+ write_idx = ipc_ut_meta_queues[q_type].write_idx;
+ read_idx = ipc_ut_meta_queues[q_type].read_idx;
+
+ used_num = (write_idx >= read_idx)
+ ? (write_idx - read_idx) :
+ (IPC_UT_META_TABLE_SIZE - read_idx + write_idx);
+ remain_num = IPC_UT_META_TABLE_SIZE - used_num - 1;
+ alloc_num = (request_num > remain_num) ? remain_num : request_num;
+
+ *p_head_idx = write_idx;
+ write_idx += alloc_num;
+ if (write_idx >= IPC_UT_META_TABLE_SIZE) {
+ write_idx -= IPC_UT_META_TABLE_SIZE;
+ }
+ *p_tail_idx = write_idx;
+
+ ipc_ut_meta_queues[q_type].write_idx = write_idx;
+
+ ipc_ut_reset_meta(*p_head_idx, *p_tail_idx, q_type);
+
+ return alloc_num;
+}
+
+void ipc_ut_meta_read_done(kal_uint32 start_idx,
+ kal_uint32 end_idx,
+ LHIF_QUEUE_TYPE q_type) {
+ kal_uint32 used_num, free_num;
+ kal_uint8 write_idx, read_idx;
+
+ write_idx = ipc_ut_meta_queues[IPC_UT_LHIF_META_AP0].write_idx;
+ read_idx = ipc_ut_meta_queues[IPC_UT_LHIF_META_AP0].read_idx;
+
+ UT_ASSERT(LHIF_HWQ_AP_UL_Q0 == q_type);
+ UT_ASSERT(start_idx == read_idx);
+
+ used_num = (write_idx >= read_idx)
+ ? (write_idx - read_idx) :
+ (IPC_UT_META_TABLE_SIZE - read_idx + write_idx);
+ free_num = (end_idx > start_idx) ? (end_idx - start_idx) : (IPC_UT_META_TABLE_SIZE - start_idx + end_idx);
+
+ UT_ASSERT(free_num <= used_num);
+
+ ipc_ut_meta_queues[IPC_UT_LHIF_META_AP0].read_idx = end_idx;
+}
+
+void ipc_ut_release_ipf_meta_entry(kal_uint16 rel_num, kal_uint32 ipf_meta_q_type) {
+ kal_uint32 used_num;
+ kal_uint8 write_idx, read_idx;
+
+ write_idx = ipc_ut_meta_queues[IPC_UT_IPF_DL_0].write_idx;
+ read_idx = ipc_ut_meta_queues[IPC_UT_IPF_DL_0].read_idx;
+
+ used_num = (write_idx >= read_idx)
+ ? (write_idx - read_idx) :
+ (IPC_UT_META_TABLE_SIZE - read_idx + write_idx);
+
+ UT_ASSERT(rel_num <= used_num);
+
+ ipc_ut_meta_queues[IPC_UT_IPF_DL_0].read_idx = ((read_idx + rel_num)>=IPC_UT_META_TABLE_SIZE)
+ ?(read_idx+rel_num-IPC_UT_META_TABLE_SIZE):(read_idx+rel_num);
+}
+
+kal_bool ipc_ut_query_meta_table(kal_uint32 **base_addr, kal_uint16 *size, LHIF_QUEUE_TYPE queue_type) {
+ *base_addr = (kal_uint32 *)ipc_ut_meta_tbl_s;
+ *size = IPC_UT_META_TABLE_SIZE;
+
+ return KAL_TRUE;
+}
+
+void ipc_ut_fill_ipf_ul_meta_content(
+ lhif_meta_tbl_t *meta,
+ kal_uint8 idx,
+ kal_bool is_ipv6,
+ kal_uint8 proto_idx,
+ kal_uint8 test_stage,
+ kal_bool is_meta_mr,
+ kal_uint32 dhcp_idx) {
+ kal_bool is_pn_match;
+
+ if ( (IPC_UT_STAGE_BEFORE_BINDING == test_stage) || (IPC_UT_STAGE_UNBINDING == test_stage)) {
+ is_pn_match = KAL_FALSE;
+ }
+ else {
+ is_pn_match = KAL_TRUE;
+ }
+
+ if (is_pn_match && ((idx % 2) == 0)) {
+ meta->protocol_idx = proto_idx;
+ meta->pdn = IPC_UT_PDN_ID;
+ }
+
+ meta->ip = is_ipv6;
+
+ if(is_ipv6){
+ meta->match_index = IPC_UT_META_MATCH_IDX+1;
+ }
+ else{
+ meta->match_index = IPC_UT_META_MATCH_IDX;
+ }
+
+ if(KAL_FALSE == is_meta_mr){
+ if(dhcp_idx == idx){
+ meta->mr = IPC_HPC_MR_UNKNOWN;
+ meta->match_index = 0;
+ }else{
+ switch (idx % IPC_HPC_MR_MAX) {
+ case 0:
+ meta->mr = IPC_HPC_MR_UNKNOWN;
+ meta->match_index = 0;
+ break;
+ case 1:
+ meta->mr = IPC_HPC_MR_NEW;
+ break;
+ case 2:
+ /* MR_MATCH should be after MR_NEW*/
+ meta->mr = IPC_HPC_MR_MATCH;
+ break;
+ default:
+ // default is unknown
+ meta->mr = IPC_HPC_MR_UNKNOWN;
+ meta->match_index = 0;
+ break;
+ }
+ }
+ }else{
+ switch (idx % IPC_HPC_MR_MAX) {
+ case 0:
+ meta->mr = IPC_HPC_MR_UNKNOWN;
+ meta->match_index = 0;
+ break;
+ case 1:
+ meta->mr = IPC_HPC_MR_NEW;
+ break;
+ case 2:
+ /* MR_MATCH should be after MR_NEW*/
+ meta->mr = IPC_HPC_MR_MATCH;
+ break;
+ case 3:
+ meta->mr = IPC_HPC_MR_DPFM_MATCH;
+ break;
+ case 4:
+ meta->mr = IPC_HPC_MR_DPFM_MATCH_BUT_NO_NAT;
+ break;
+ case 5:
+ meta->mr = IPC_HPC_MR_DPFM_DEL_CMD_MATCH;
+ meta->match_index = 0;
+ break;
+ case 6:
+ meta->mr = IPC_HPC_MR_DPFM_DEL_CMD_MISS;
+ meta->match_index = 0;
+ break;
+ case 7:
+ meta->mr = IPC_HPC_MR_DPFM_ADD_CMD;
+ meta->match_index = 0;
+ break;
+ default:
+ // default is unknown
+ meta->mr = IPC_HPC_MR_UNKNOWN;
+ meta->match_index = 0;
+ break;
+ }
+ }
+}
+
+void ipc_ut_prepare_ul_meta_list_dpfm(
+ kal_bool allMatchIpPkt,
+ kal_uint32 ipv4_cnt,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ LHIF_QUEUE_TYPE *q_type,
+ kal_uint32 netif_id,
+ kal_uint8 proto_idx,
+ kal_uint8 test_stage) {
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ kal_uint32 curr_meta_idx;
+ lhif_meta_tbl_t *curr_meta;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+ kal_uint8 sequence = 0;
+
+ if (total_cnt != ipc_ut_alloc_meta(
+ IPC_UT_LHIF_META_AP0, //LHIF_HWQ_AP_UL_Q0,
+ total_cnt,
+ p_head_idx,
+ p_tail_idx)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+ *q_type = LHIF_HWQ_AP_UL_Q0;
+ curr_meta_idx = *p_head_idx;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ curr_meta = &ipc_ut_meta_tbl_s[curr_meta_idx];
+ curr_meta->net_type = ((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS;
+ curr_meta->channel_id = netif_id & 0x0000001F;
+
+ if(KAL_TRUE == allMatchIpPkt){
+ packet_buf = ipc_ut_ipv4_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_ul_packet);
+ } else {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ }
+
+ kal_mem_cpy(curr_meta->vrb_addr, packet_buf, packet_len);
+ curr_meta->length = packet_len;
+
+#if defined(__IPF_SUPPORT__)
+ // Fill IPF meta entry
+ ipc_ut_fill_ipf_ul_meta_content(curr_meta, idx, KAL_FALSE, proto_idx, test_stage, KAL_TRUE, 0);
+#endif
+
+ //assign sequence
+ curr_meta->psn = sequence;
+ sequence ++;
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ curr_meta = &ipc_ut_meta_tbl_s[curr_meta_idx];
+ curr_meta->net_type = ((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS;
+ curr_meta->channel_id = netif_id & 0x0000001F;
+
+ if(KAL_TRUE == allMatchIpPkt){
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_ul_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ }
+
+ kal_mem_cpy(curr_meta->vrb_addr, packet_buf, packet_len);
+ curr_meta->length = packet_len;
+
+#if defined(__IPF_SUPPORT__)
+ // Fill IPF meta entry
+ ipc_ut_fill_ipf_ul_meta_content(curr_meta, idx, KAL_TRUE, proto_idx, test_stage, KAL_TRUE, 0);
+#endif
+
+ //assign sequence
+ curr_meta->psn = sequence;
+ sequence ++;
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+}
+
+
+void ipc_ut_prepare_ul_meta_list(
+ kal_bool allValidIpPkt,
+ kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ LHIF_QUEUE_TYPE *q_type,
+ kal_uint32 netif_id,
+ kal_uint8 proto_idx,
+ kal_uint8 test_stage) {
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ kal_uint32 curr_meta_idx;
+ lhif_meta_tbl_t *curr_meta;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+ kal_uint8 sequence = 0;
+
+ if (total_cnt != ipc_ut_alloc_meta(
+ IPC_UT_LHIF_META_AP0, //LHIF_HWQ_AP_UL_Q0,
+ total_cnt,
+ p_head_idx,
+ p_tail_idx)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+ *q_type = LHIF_HWQ_AP_UL_Q0;
+ curr_meta_idx = *p_head_idx;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ curr_meta = &ipc_ut_meta_tbl_s[curr_meta_idx];
+ curr_meta->net_type = ((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS;
+ curr_meta->channel_id = netif_id & 0x0000001F;
+
+ if (idx == dhcpv4_idx) {
+ packet_buf = ipc_ut_ipv4_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_ul_packet);
+ } else {
+ /* Other packets */
+ switch (idx % 6) {
+ case 0:
+ if (KAL_TRUE == allValidIpPkt) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv4_incomplete_udp_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_udp_header_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag1_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ }
+ }
+
+ kal_mem_cpy(curr_meta->vrb_addr, packet_buf, packet_len);
+ curr_meta->length = packet_len;
+
+#if defined(__IPF_SUPPORT__)
+ // Fill IPF meta entry
+ ipc_ut_fill_ipf_ul_meta_content(curr_meta, idx, KAL_FALSE, proto_idx, test_stage, KAL_FALSE, dhcpv4_idx);
+#endif
+
+ //assign sequence
+ curr_meta->psn = sequence;
+ sequence ++;
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ curr_meta = &ipc_ut_meta_tbl_s[curr_meta_idx];
+ curr_meta->net_type = ((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS;
+ curr_meta->channel_id = netif_id & 0x0000001F;
+
+ if (idx == dhcpv6_idx) {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_ul_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_ext1_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext1_dhcp_ul_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_ul_packet);
+ }
+ } else {
+ /* Other packets */
+ switch (idx % 9) {
+ case 0:
+ if (KAL_TRUE == allValidIpPkt) {
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_incomplete_hop_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_hop_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_incomplete_ah_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ah_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+ }
+
+ kal_mem_cpy(curr_meta->vrb_addr, packet_buf, packet_len);
+ curr_meta->length = packet_len;
+
+#if defined(__IPF_SUPPORT__)
+ // Fill IPF meta entry
+ ipc_ut_fill_ipf_ul_meta_content(curr_meta, idx, KAL_TRUE, proto_idx, test_stage, KAL_FALSE, dhcpv6_idx);
+#endif
+
+ //assign sequence
+ curr_meta->psn = sequence;
+ sequence ++;
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+}
+
+
+void ipc_ut_prepare_dl_meta_list(kal_bool allValidIpPkt,
+ kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ ipfc_dl_filter_queue_type *q_type,
+ kal_uint32 netif_id,
+ kal_uint8 match_result)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ kal_uint32 curr_meta_idx;
+ ipf_dl_meta *curr_meta;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+
+ if (total_cnt != ipc_ut_alloc_meta(
+ IPC_UT_IPF_DL_0, //LHIF_HWQ_AP_UL_Q0,
+ total_cnt,
+ p_head_idx,
+ p_tail_idx)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+ *q_type = IPFC_META_QUEUE_DL;
+ curr_meta_idx = *p_head_idx;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ curr_meta->channel_id = ((((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS) <<8 )
+ |(netif_id & 0x000000FF) ;
+
+ if (idx == dhcpv4_idx) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ switch (idx) {
+ case 0:
+ if (ipv4_cnt > 4) {
+ if ((ipv4_cnt%2) == 0) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ }
+ else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv4_incomplete_udp_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_udp_header_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag1_packet);
+ break;
+ default:
+ if ((idx%3) == 0) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ }
+ break;
+ }
+ }
+
+ kal_mem_cpy((kal_uint8*)curr_meta->addr, packet_buf, packet_len);
+ curr_meta->len = packet_len;
+
+ // Fill IP type
+ curr_meta->ip = 0;
+
+ // Fill Match index (don't care value)
+ // we assgin the same value as ip type. it will be reused for querey filter id.
+ curr_meta->match_idx = 0;
+
+ curr_meta->mr = (match_result & 0x07);
+
+ curr_meta->pdn_sim_id = IPC_UT_PDN_ID;
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ curr_meta->channel_id = ((((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS) <<8 )
+ |(netif_id & 0x000000FF) ;
+
+
+ if (idx == dhcpv6_idx) {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_ext1_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext1_dhcp_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_packet);
+ }
+ } else {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_incomplete_hop_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_hop_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_incomplete_ah_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ah_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+ }
+
+ kal_mem_cpy((kal_uint8*)curr_meta->addr, packet_buf, packet_len);
+ curr_meta->len = packet_len;
+
+ // Fill IP type
+ curr_meta->ip = 1;
+
+ // Fill Match index (don't care value)
+ // we assgin the same value as ip type. it will be reused for querey filter id.
+ curr_meta->match_idx = 1;
+
+ curr_meta->mr = (match_result & 0x07);
+
+ curr_meta->pdn_sim_id = IPC_UT_PDN_ID;
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+}
+
+void ipc_ut_prepare_dl_did_list(
+ kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint16 *ipv4_invalid_packet_len,
+ kal_uint16 *ipv6_invalid_packet_len,
+ kal_uint32 did_cnt,
+ kal_bool did_igr_enable) {
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+
+ if (did_cnt != ipc_ut_alloc_did(
+ did_cnt,
+ did_head,
+ did_tail)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for ( curr_did = *did_head ;
+ curr_did && (end_of_list == KAL_FALSE) ;
+ curr_did = next_did) {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+
+
+ /* Set SIT to the first SIT in DID for data configuration */
+ curr_did = *did_head;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ if (KAL_TRUE == dnsv4_only) {
+ if (KAL_TRUE == v4hdr_exist) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ kal_uint32 offset;
+
+ /* Shift data pointer to reserve headroom */
+ offset = IPC_HDR_V4_GET_IHL(ipc_ut_ipv4_dns_packet) + IPC_HDR_UDP_HEADER_SIZE;
+
+ UPCM_DID_SI_SET_OFFSET(curr_si, UPCM_DID_SI_GET_OFFSET(curr_si) + offset);
+
+ packet_buf = ipc_ut_ipv4_dns_packet + offset;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet) - offset;
+ }
+ } else {
+ if (idx == dhcpv4_idx) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ switch (idx) {
+ case 0:
+ if (ipv4_cnt > 4) {
+ if ((ipv4_cnt%2) == 0) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ }
+ else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv4_incomplete_udp_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_udp_header_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag1_packet);
+ break;
+ default:
+ if ((idx%3) == 0) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ }
+ break;
+ }
+ }
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv4_invalid_packet_len) {
+ if (ipv4_invalid_packet_len[idx] > packet_len) {
+// kal_mem_cpy(ipc_ut_invalid_len_ip_packet, packet_buf, packet_len);
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv4_invalid_packet_len[idx]>IPC_INVALID_MAX_PKT_LEN)?IPC_INVALID_MAX_PKT_LEN:ipv4_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+#if 1
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt ++;
+ }
+ }
+#endif
+ if ( (did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx]) ) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num --;
+ }
+ } else {
+ pkt_num ++;
+ }
+ }
+
+ if (ipv4_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ if (KAL_TRUE == dnsv6_only) {
+ if (KAL_TRUE == v6hdr_exist) {
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ } else {
+ kal_uint32 offset;
+
+ /* Shift data pointer to reserve headroom */
+ offset = IPC_HDR_V6_HEADER_SIZE + IPC_HDR_UDP_HEADER_SIZE;
+
+ UPCM_DID_SI_SET_OFFSET(curr_si, UPCM_DID_SI_GET_OFFSET(curr_si) + offset);
+
+ packet_buf = ipc_ut_ipv6_mdns_packet + offset;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet) - offset;
+ }
+ } else {
+ if (idx == dhcpv6_idx) {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_ext1_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext1_dhcp_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_packet);
+ }
+ } else {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_incomplete_hop_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_hop_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_incomplete_ah_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ah_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+ }
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv6_invalid_packet_len) {
+ if (ipv6_invalid_packet_len[idx] > packet_len) {
+// kal_mem_cpy(ipc_ut_invalid_len_ip_packet, packet_buf, packet_len);
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv6_invalid_packet_len[idx]>IPC_INVALID_MAX_PKT_LEN)?IPC_INVALID_MAX_PKT_LEN:ipv6_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+#if 1
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt ++;
+ }
+ }
+#endif
+ if ( (did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx]) ) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num --;
+ }
+ } else {
+ pkt_num ++;
+ }
+ }
+
+ if (ipv6_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+}
+
+void ipc_ut_prepare_pfm_fin_ack_dl_did_list(kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint16 *ipv4_invalid_packet_len,
+ kal_uint16 *ipv6_invalid_packet_len,
+ kal_uint32 did_cnt,
+ kal_bool did_igr_enable) {
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+
+ if (did_cnt != ipc_ut_alloc_did(did_cnt, did_head, did_tail)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for (curr_did = *did_head; curr_did && (end_of_list == KAL_FALSE);
+ curr_did = next_did) {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+
+ /* Set SIT to the first SIT in DID for data configuration */
+ curr_did = *did_head;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ if (KAL_TRUE == dnsv4_only) {
+ if (KAL_TRUE == v4hdr_exist) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ kal_uint32 offset;
+
+ /* Shift data pointer to reserve headroom */
+ offset = IPC_HDR_V4_GET_IHL(ipc_ut_ipv4_dns_packet) + IPC_HDR_UDP_HEADER_SIZE;
+
+ UPCM_DID_SI_SET_OFFSET(curr_si, UPCM_DID_SI_GET_OFFSET(curr_si) + offset);
+
+ packet_buf = ipc_ut_ipv4_dns_packet + offset;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet) - offset;
+ }
+ } else {
+ if (idx == dhcpv4_idx) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ switch (idx) {
+ case 0:
+ if (ipv4_cnt > 4) {
+ if ((ipv4_cnt % 2) == 0) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ } else {
+ packet_buf = ipc_ut_ipv4_tcp_fin_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_fin_ack_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ }
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_tcp_fin_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_fin_ack_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv4_tcp_fin_ack_packet_2;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_fin_ack_packet_2);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_tcp_fin_ack_packet_2;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_fin_ack_packet_2);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ default:
+ if ((idx % 3) == 0) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ }
+ break;
+ }
+ }
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ if (ipv4_invalid_packet_len) {
+ if (ipv4_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv4_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv4_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+#if 1
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt++;
+ }
+ }
+#endif
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv4_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ if (KAL_TRUE == dnsv6_only) {
+ if (KAL_TRUE == v6hdr_exist) {
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ } else {
+ kal_uint32 offset;
+
+ /* Shift data pointer to reserve headroom */
+ offset = IPC_HDR_V6_HEADER_SIZE + IPC_HDR_UDP_HEADER_SIZE;
+
+ UPCM_DID_SI_SET_OFFSET(curr_si, UPCM_DID_SI_GET_OFFSET(curr_si) + offset);
+
+ packet_buf = ipc_ut_ipv6_mdns_packet + offset;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet) - offset;
+ }
+ } else {
+ if (idx == dhcpv6_idx) {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_ext1_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext1_dhcp_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_packet);
+ }
+ } else {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_tcp_fin_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_fin_ack_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_tcp_fin_ack_packet_2;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_fin_ack_packet_2);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_tcp_fin_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_fin_ack_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_tcp_fin_ack_packet_2;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_fin_ack_packet_2);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+ }
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv6_invalid_packet_len) {
+ if (ipv6_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv6_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv6_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt++;
+ }
+ }
+
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv6_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+}
+
+void ipc_ut_prepare_ul_gpd_list(kal_bool allValidIpPkt,
+ kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ qbm_gpd **head_gpd,
+ qbm_gpd **tail_gpd,
+ ipc_io_request_t **ior)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx = 0;
+ qbm_gpd *curr_gpd = NULL;
+ qbm_gpd *bd = NULL;
+ kal_uint8 *packet_buf = NULL;
+ kal_uint32 packet_len = 0;
+
+ ipc_ut_ul_head_gpd = ipc_ut_ul_tail_gpd = NULL;
+ if (ior) {*ior = NULL;}
+
+ if (total_cnt != qbmt_alloc_q(QBM_TYPE_NET_UL, total_cnt, (void **)(head_gpd), (void **)(tail_gpd))) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+ curr_gpd = *head_gpd;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ if (idx == dhcpv4_idx) {
+ packet_buf = ipc_ut_ipv4_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_ul_packet);
+ } else {
+ /* Other packets */
+ switch (idx % 6) {
+ case 0:
+ if (KAL_TRUE == allValidIpPkt) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv4_incomplete_udp_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_udp_header_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag1_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ }
+ }
+
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), packet_buf, packet_len);
+ QBM_DES_SET_DATALEN(bd, packet_len);
+ QBM_DES_SET_DATALEN(curr_gpd, packet_len);
+
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ if (idx == dhcpv6_idx) {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_ul_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_ext1_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext1_dhcp_ul_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_ul_packet);
+ }
+ } else {
+ /* Other packets */
+ switch (idx % 9) {
+ case 0:
+ if (KAL_TRUE == allValidIpPkt) {
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ case 1:
+ packet_buf = ipc_ut_ipv6_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_incomplete_hop_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_hop_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_incomplete_ah_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ah_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+ }
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), packet_buf, packet_len);
+ QBM_DES_SET_DATALEN(bd, packet_len);
+ QBM_DES_SET_DATALEN(curr_gpd, packet_len);
+
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+
+
+ if (ior && head_gpd && *head_gpd) {
+ *ior = (ipc_io_request_t *)QBM_DES_GET_SW_CTRL_FIELD(*head_gpd);
+ (*ior)->next_request = NULL;
+ (*ior)->first_gpd = *head_gpd;
+ (*ior)->last_gpd = *tail_gpd;
+ (*ior)->ip_type = (ipv4_cnt==0) ? IPC_IP_TYPE_IPV6:
+ (ipv6_cnt==0) ? IPC_IP_TYPE_IPV4:
+ IPC_IP_TYPE_MIXED;
+ (*ior)->qos_priority = 0;
+ (*ior)->data_path_type = 0;
+ (*ior)->reserved = 0;
+ }
+}
+
+void ipc_ut_prepare_dl_gpd_list(
+ kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ qbm_gpd **head_gpd,
+ qbm_gpd **tail_gpd,
+ kal_uint16 *ipv4_invalid_packet_len,
+ kal_uint16 *ipv6_invalid_packet_len,
+ /* Insert one SPD into the GPD list. Note that the total packet num should be less than 30. */
+ kal_bool spd_enable,
+ kal_bool spd_igr_bit_enable,
+ ipc_ut_spd_position_e spd_position) {
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx = 0;
+ qbm_gpd *curr_gpd = NULL;
+ qbm_gpd *bd = NULL;
+ qbm_gpd *head_bd = NULL;
+ qbm_gpd *tail_bd = NULL;
+ kal_uint8 *packet_buf = NULL;
+ kal_uint32 packet_len = 0;
+
+ /* SPD related */
+ qbm_spd *spd = NULL;
+ qbm_spd_pi *p_spd_pi = NULL;
+ qbm_spd_pie *p_spd_pie = NULL;
+ qbm_spd_pie *p_prev_spd_pie = NULL;
+ kal_uint8 *p_payload = NULL;
+ kal_uint32 payload_len = 0;
+ kal_uint32 total_data_len = 0;
+ kal_uint32 igr_payload_cnt = 0;
+ /* for setting spd position, which will be inserted after the last ipv4 packet. */
+ qbm_gpd *middle_gpd = NULL;
+
+ ipc_ut_dl_head_gpd = ipc_ut_dl_tail_gpd = NULL;
+
+ if (total_cnt != qbmt_alloc_q(
+ QBM_TYPE_NET_DL,
+ total_cnt,
+ (void **)(head_gpd),
+ (void **)(tail_gpd))) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ if (spd_enable) {
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ /* 1st packet should not be used! */
+ p_spd_pie = QBM_SPD_PI_GET_FIRST_PIE(p_spd_pi);
+ for (idx = 0; idx < QBM_SPD_MAX_PKTNUM; idx++) {
+ QBM_SPD_PIE_SET_PAYLOAD_LEN(p_spd_pie, 0);
+ QBM_SPD_PIE_SET_PAYLOAD_LEN(p_spd_pie, 0);
+ QBM_SPD_PIE_CLR_IGR(p_spd_pie);
+ QBM_SPD_PIE_CLR_EOL(p_spd_pie);
+ if (idx != (QBM_SPD_MAX_PKTNUM - 1)) {
+ p_spd_pie = QBM_SPD_PIE_NEXT(p_spd_pie);
+ }
+ }
+
+ /* Reset: point the SPD related ptrs to the second payload. */
+ p_spd_pie = QBM_SPD_PI_GET_FIRST_PIE(p_spd_pi);
+ p_prev_spd_pie = NULL;
+ p_payload = QBM_DES_GET_DATAPTR(spd);
+ payload_len = 0;
+ }
+
+
+ /* Append BD list */
+ if (additional_bd_cnt && total_cnt) {
+ qbm_gpd *next_gpd;
+ kal_bool end_of_gpd_list;
+ if ((total_cnt * additional_bd_cnt) != qbmt_alloc_q(
+ QBM_TYPE_TBD,
+ (total_cnt * additional_bd_cnt),
+ (void**)&head_bd,
+ (void**)&tail_bd)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ next_gpd = NULL;
+ end_of_gpd_list = KAL_FALSE;
+ for ( curr_gpd = *head_gpd ;
+ curr_gpd && (end_of_gpd_list == KAL_FALSE) ;
+ curr_gpd = next_gpd) {
+ kal_uint32 additional_bd_idx;
+
+ next_gpd = QBM_DES_GET_NEXT(curr_gpd);
+ end_of_gpd_list = (curr_gpd == *tail_gpd)?KAL_TRUE:KAL_FALSE;
+
+ bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ for ( additional_bd_idx = 0 ;
+ additional_bd_idx < additional_bd_cnt ;
+ additional_bd_idx ++) {
+ qbm_gpd *added_bd;
+
+ /* Remove BD from BD list */
+ UT_ASSERT(NULL != head_bd);
+ added_bd = head_bd;
+ head_bd = QBM_DES_GET_NEXT(head_bd);
+
+ /* Add BD to tail of curr_gpd BD list */
+ QBM_DES_SET_NEXT(bd, added_bd);
+ QBM_DES_CLR_EOL(bd);
+ QBM_DES_SET_NEXT(added_bd, NULL);
+ QBM_DES_SET_EOL(added_bd);
+ bd = added_bd; /* For next BD append */
+ }
+ }
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ qbm_gpd *next_gpd;
+ kal_bool end_of_gpd_list;
+
+ next_gpd = NULL;
+ end_of_gpd_list = KAL_FALSE;
+ for ( curr_gpd = *head_gpd ;
+ curr_gpd && (end_of_gpd_list == KAL_FALSE) ;
+ curr_gpd = next_gpd) {
+ bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ while (bd) {
+ QBM_DES_SET_DATAPTR(bd, ((kal_uint8*)QBM_DES_GET_DATAPTR(bd)) + (align_offset % 4));
+ qbm_cal_set_checksum((kal_uint8 *)bd);
+
+ if (QBM_DES_GET_EOL(bd)) {break;}
+ bd = QBM_DES_GET_NEXT(bd);
+ }
+ }
+ }
+
+
+ /* Set GPD to GPD list head for data configuration */
+ curr_gpd = *head_gpd;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ if (KAL_TRUE == dnsv4_only) {
+ if (KAL_TRUE == v4hdr_exist) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ kal_uint8 * data_ptr;
+ kal_uint32 offset;
+
+ /* Shift data pointer to reserve headroom */
+ offset = IPC_HDR_V4_GET_IHL(ipc_ut_ipv4_dns_packet) + IPC_HDR_UDP_HEADER_SIZE;
+
+ data_ptr = (kal_uint8*)QBM_DES_GET_DATAPTR(bd);
+ QBM_DES_SET_DATAPTR(bd, data_ptr+offset);
+
+ /* set bd checksum */
+ qbm_cal_set_checksum((kal_uint8 *)bd);
+
+ packet_buf = ipc_ut_ipv4_dns_packet + offset;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet) - offset;
+ }
+ } else {
+ if (idx == dhcpv4_idx) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ switch (idx) {
+ case 0:
+ if (ipv4_cnt > 4) {
+ if ((ipv4_cnt%2) == 0) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ }
+ else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv4_incomplete_udp_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_udp_header_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag1_packet);
+ break;
+ default:
+ if ((idx%3) == 0) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ }
+ break;
+ }
+ }
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv4_invalid_packet_len) {
+ if (ipv4_invalid_packet_len[idx] > packet_len) {
+ kal_mem_cpy(ipc_ut_invalid_len_ip_packet, packet_buf, packet_len);
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv4_invalid_packet_len[idx]>IPC_INVALID_MAX_PKT_LEN)?IPC_INVALID_MAX_PKT_LEN:ipv4_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (QBM_DES_GET_EOL(bd)) { /* Latest BD : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest BD : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ }
+
+ if (cont_loop_cnt == 0) {
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), packet_buf + copied_len, current_copy_len);
+ } else { /* For non-first BD, no buffer is allocated and we need to set its buffer to static template */
+ QBM_DES_SET_DATAPTR(bd, packet_buf + copied_len);
+ }
+ QBM_DES_SET_DATALEN(bd, current_copy_len);
+ copied_len += current_copy_len;
+
+ /* Get next BD in list */
+ bd = QBM_DES_GET_NEXT(bd);
+
+ cont_loop_cnt ++;
+ }
+
+ QBM_DES_SET_DATALEN(curr_gpd, packet_len);
+ }
+
+ if (spd_enable) {
+ kal_mem_cpy(p_payload, packet_buf, packet_len);
+ payload_len = packet_len;
+ UT_ASSERT(total_data_len < IPC_UT_SPD_RING_BUFFER_SIZE);
+
+ QBM_SPD_PIE_SET_PAYLOAD_LEN(p_spd_pie, payload_len);
+
+ if ( (spd_igr_bit_enable) && (1 == ipc_ut_spd_packet_igr_s[idx]) ) {
+ QBM_SPD_PIE_SET_IGR(p_spd_pie);
+ igr_payload_cnt++;
+ } else {
+ total_data_len += payload_len;
+ p_prev_spd_pie = p_spd_pie;
+ }
+ if (idx == (ipv4_cnt - 1)) {
+ /* The last packet of ipv4 */
+ middle_gpd = curr_gpd;
+ }
+ p_payload = QBM_SPD_PAYLOAD_NEXT(p_payload, payload_len);
+ p_spd_pie = QBM_SPD_PIE_NEXT(p_spd_pie);
+ }
+
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ if (KAL_TRUE == dnsv6_only) {
+ if (KAL_TRUE == v6hdr_exist) {
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ } else {
+ kal_uint8 * data_ptr;
+ kal_uint32 offset;
+
+ /* Shift data pointer to reserve headroom */
+ offset = IPC_HDR_V6_HEADER_SIZE + IPC_HDR_UDP_HEADER_SIZE;
+
+ data_ptr = (kal_uint8*)QBM_DES_GET_DATAPTR(bd);
+ QBM_DES_SET_DATAPTR(bd, data_ptr+offset);
+
+ /* set bd checksum */
+ qbm_cal_set_checksum((kal_uint8 *)bd);
+
+ packet_buf = ipc_ut_ipv6_mdns_packet + offset;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet) - offset;
+ }
+ } else {
+ if (idx == dhcpv6_idx) {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_ext1_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext1_dhcp_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_packet);
+ }
+ } else {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_incomplete_hop_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_hop_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_incomplete_ah_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ah_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+ }
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv6_invalid_packet_len) {
+ if (ipv6_invalid_packet_len[idx] > packet_len) {
+ kal_mem_cpy(ipc_ut_invalid_len_ip_packet, packet_buf, packet_len);
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv6_invalid_packet_len[idx]>IPC_INVALID_MAX_PKT_LEN)?IPC_INVALID_MAX_PKT_LEN:ipv6_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (QBM_DES_GET_EOL(bd)) { /* Latest BD : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest BD : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ }
+
+ if (cont_loop_cnt == 0) {
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), packet_buf + copied_len, current_copy_len);
+ } else { /* For non-first BD, no buffer is allocated and we need to set its buffer to static template */
+ QBM_DES_SET_DATAPTR(bd, packet_buf + copied_len);
+ }
+ QBM_DES_SET_DATALEN(bd, current_copy_len);
+ copied_len += current_copy_len;
+
+ /* Get next BD in list */
+ bd = QBM_DES_GET_NEXT(bd);
+
+ cont_loop_cnt ++;
+ }
+
+ QBM_DES_SET_DATALEN(curr_gpd, packet_len);
+ }
+
+ if (spd_enable) {
+ kal_mem_cpy(p_payload, packet_buf, packet_len);
+ payload_len = packet_len;
+ UT_ASSERT(total_data_len < IPC_UT_SPD_RING_BUFFER_SIZE);
+
+ QBM_SPD_PIE_SET_PAYLOAD_LEN(p_spd_pie, payload_len);
+
+ if ((spd_igr_bit_enable) && (1 == ipc_ut_spd_packet_igr_s[idx + ipv4_cnt])) {
+ QBM_SPD_PIE_SET_IGR(p_spd_pie);
+ igr_payload_cnt++;
+ } else {
+ total_data_len += payload_len;
+ p_prev_spd_pie = p_spd_pie;
+ }
+ if (idx != (ipv6_cnt - 1)) {
+ p_payload = QBM_SPD_PAYLOAD_NEXT(p_payload, payload_len);
+ p_spd_pie = QBM_SPD_PIE_NEXT(p_spd_pie);
+ }
+ }
+
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+
+ if (spd_enable) {
+ if (igr_payload_cnt == total_cnt) {
+ /* All SPD payloads has been ignored. */
+ qbmt_dest_q(spd, spd);
+ } else {
+ if (QBM_SPD_PIE_GET_IGR(p_spd_pie)) {
+ if (p_prev_spd_pie) {
+ QBM_SPD_PIE_SET_EOL(p_prev_spd_pie);
+ QBM_SPD_PI_SET_PKTNUM(p_spd_pi, total_cnt - 1);
+ } else {
+ UT_ASSERT(KAL_FALSE);
+ }
+ } else {
+ QBM_SPD_PIE_SET_EOL(p_spd_pie);
+ QBM_SPD_PI_SET_PKTNUM(p_spd_pi, total_cnt);
+ }
+ QBM_DES_SET_DATALEN(spd, total_data_len);
+
+ switch (spd_position) {
+ case IPC_UT_SPD_AT_THE_HEAD_OF_LIST:
+ QBM_DES_SET_NEXT(spd, *head_gpd);
+ *head_gpd = (qbm_gpd *)spd;
+ break;
+ case IPC_UT_SPD_AT_THE_END_OF_LIST:
+ QBM_DES_SET_NEXT(*tail_gpd, spd);
+ *tail_gpd = (qbm_gpd *)spd;
+ break;
+ case IPC_UT_SPD_IN_THE_MIDDLE_OF_LIST:
+ if (NULL == middle_gpd) {
+ middle_gpd = *head_gpd;
+ }
+ QBM_DES_SET_NEXT(spd, QBM_DES_GET_NEXT(middle_gpd));
+ QBM_DES_SET_NEXT(middle_gpd, spd);
+ if (*tail_gpd == middle_gpd) {
+ *tail_gpd = (qbm_gpd *)spd;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (head_gpd && *head_gpd) {
+ ((upcm_dlvr_dl_info_t *)QBM_DES_GET_SW_CTRL_FIELD(*head_gpd))->ebi = IPC_UT_DL_EBI;
+ }
+}
+
+void ipc_ut_prepare_garbage_filter_dl_gpd_list(
+ kal_uint32 ipv4_cnt,
+ kal_uint32 synv4_idx,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 synv6_idx,
+ qbm_gpd **head_gpd,
+ qbm_gpd **tail_gpd) {
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ qbm_gpd *curr_gpd;
+ qbm_gpd *bd;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+
+ ipc_ut_dl_head_gpd = ipc_ut_dl_tail_gpd = NULL;
+
+ if (total_cnt != qbmt_alloc_q(
+ QBM_TYPE_NET_DL,
+ total_cnt,
+ (void **)(head_gpd),
+ (void **)(tail_gpd))) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ if (head_gpd && *head_gpd) {
+ ((upcm_dlvr_dl_info_t *)QBM_DES_GET_SW_CTRL_FIELD(*head_gpd))->ebi = IPC_UT_DL_EBI;
+ }
+
+ /* Set GPD to GPD list head for data configuration */
+ curr_gpd = *head_gpd;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ if (idx == synv4_idx) {
+ packet_buf = ipc_ut_ipv4_tcp_syn_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_syn_packet);
+ } else {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv4_tcp_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_ack_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_tcp_syn_packet_2;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_syn_packet_2);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ default:
+ packet_buf = ipc_ut_ipv4_tcp_syn_packet_2;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_syn_packet_2);
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt++;
+ break;
+ }
+ }
+
+ {
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), packet_buf, packet_len);
+ QBM_DES_SET_DATALEN(bd, packet_len);
+ QBM_DES_SET_DATALEN(curr_gpd, packet_len);
+ }
+
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ if (idx == synv6_idx) {
+ packet_buf = ipc_ut_ipv6_tcp_syn_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_syn_packet);
+ } else {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_tcp_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_ack_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_tcp_syn_packet_2;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_syn_packet_2);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_tcp_syn_packet_2;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_syn_packet_2);
+ break;
+ }
+ }
+
+ {
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), packet_buf, packet_len);
+ QBM_DES_SET_DATALEN(bd, packet_len);
+ QBM_DES_SET_DATALEN(curr_gpd, packet_len);
+ }
+
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+}
+
+
+void ipc_fragment_ut_dl_filter_callback(void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length) {
+ qbmt_dest_q(head_gpd, tail_gpd);
+}
+
+
+void ipc_ut_prepare_fragments_and_send(kal_uint32 pdn_id, kal_uint8 proto_idx) {
+ upcm_did *did_p = NULL;
+ upcm_did_si *sit_p = NULL;
+ ipc_filter_rules_t rules = {0};
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+ kal_uint32 filter_id = IPC_INVALID_FILTER_ID;
+ kal_uint32 buff_count = 0, remain_count = 0;
+
+ buff_count = upcm_did_get_buff_remain_num() +
+ qbm_get_buff_remain_num(QBM_TYPE_TGPD) + qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+ rules.priority = 3;
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_PDN_ID | IPC_FILTER_BY_SPI;
+ rules.features = IPC_FILTER_FEATURE_FRAG;
+ rules.pdn_id = pdn_id;
+ rules.protocol = IPC_HDR_PROT_ESP;
+ rules.spi = 0x481fde70;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_fragment_ut_dl_filter_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ filter_id = ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt);
+
+ did_p = upcm_did_alloc_one();
+ sit_p = UPCM_DID_GET_SIT_PTR(did_p);
+ UPCM_DID_SET_NEXT(did_p, NULL);
+
+ kal_mem_set(sit_p, 0, sizeof(upcm_did_si));
+ UPCM_DID_SI_SET_LEN(sit_p, sizeof(pkt2508_1));
+ UPCM_DID_SI_SET_DATAPTR(sit_p, ((void*)pkt2508_1));
+ UPCM_DID_SI_SET_EOL(sit_p);
+ sit_p++;
+ kal_mem_set(sit_p, 0, sizeof(upcm_did_si));
+ UPCM_DID_SI_SET_LEN(sit_p, sizeof(pkt2509_1));
+ UPCM_DID_SI_SET_DATAPTR(sit_p, ((void*)pkt2509_1));
+ UPCM_DID_SI_SET_EOL(sit_p);
+ sit_p++;
+ kal_mem_set(sit_p, 0, sizeof(upcm_did_si));
+ UPCM_DID_SI_SET_LEN(sit_p, sizeof(pkt2510_1));
+ UPCM_DID_SI_SET_DATAPTR(sit_p, ((void*)pkt2510_1));
+ UPCM_DID_SI_SET_EOL(sit_p);
+
+ UPCM_DID_SET_PKT_NUM(did_p, 3);
+ UPCM_DID_SET_SEG_NUM(did_p, 3);
+
+ ipc_on_did_downlink_multiple_ps(pdn_id, did_p, did_p, proto_idx);
+ ipc_dereg_filter(filter_id);
+
+ remain_count = upcm_did_get_buff_remain_num() +
+ qbm_get_buff_remain_num(QBM_TYPE_TGPD) + qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+ ASSERT(remain_count == buff_count);
+}
+
+
+void ipc_ut_free_gpd_list(qbm_gpd *head_gpd, qbm_gpd *tail_gpd) {
+ if (head_gpd) {
+ qbmt_dest_q(head_gpd, tail_gpd);
+ }
+ if (ipc_ut_ul_tail_gpd) {
+ qbmt_dest_q(ipc_ut_ul_head_gpd, ipc_ut_ul_tail_gpd);
+ }
+ ipc_ut_ul_head_gpd = ipc_ut_ul_tail_gpd = NULL;
+
+ if (ipc_ut_dl_tail_gpd) {
+ qbmt_dest_q(ipc_ut_dl_head_gpd, ipc_ut_dl_tail_gpd);
+ }
+ ipc_ut_dl_head_gpd = ipc_ut_dl_tail_gpd = NULL;
+}
+
+kal_uint32 ipc_ut_gpd_list_count(qbm_gpd *head_gpd, qbm_gpd *tail_gpd) {
+ qbm_gpd *curr_gpd;
+ kal_uint32 cnt = 0;
+ kal_bool eol = (NULL == head_gpd || NULL == tail_gpd);
+
+ for (curr_gpd = head_gpd; !eol; curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd)) {
+ eol = (curr_gpd == tail_gpd);
+ cnt++;
+ }
+
+ return cnt;
+}
+
+kal_uint32 ipc_ut_non_igr_meta_count(kal_uint32 start_idx, kal_uint32 end_idx, LHIF_QUEUE_TYPE q_type) {
+ kal_uint32 curr_idx = start_idx;
+ kal_uint32 cnt = 0;
+ g_ipc_ut_igr_meta_cnt = 0;
+ g_ipc_ut_received_ignore_ea_cnt = 0;
+
+ UT_ASSERT(LHIF_HWQ_AP_UL_Q0 == q_type);
+
+ while (curr_idx != end_idx) {
+ if (!ipc_ut_meta_tbl_s[curr_idx].ignore) {
+ cnt ++;
+ }
+
+ if (ipc_ut_meta_tbl_s[curr_idx].ignore) {
+ g_ipc_ut_igr_meta_cnt++;
+ if (ipc_ut_meta_tbl_s[curr_idx].ea) {
+ g_ipc_ut_received_ignore_ea_cnt++;
+ }
+ }
+
+ curr_idx ++;
+ if (curr_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_idx = 0;
+ }
+ }
+
+ return cnt;
+}
+
+kal_uint32 ipc_ut_spd_payload_count(qbm_gpd *head_gpd, qbm_gpd *tail_gpd) {
+ qbm_gpd *curr_gpd;
+ kal_uint32 cnt = 0;
+ kal_bool eol = (NULL == head_gpd || NULL == tail_gpd);
+ qbm_spd *spd;
+ qbm_spd_pi *p_spd_pi;
+ qbm_spd_pie *p_spd_pie;
+ kal_uint8 i;
+ kal_uint16 packet_num = 0;
+
+ for (curr_gpd = head_gpd; !eol; curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd)) {
+ eol = (curr_gpd == tail_gpd);
+ if (0 != QBM_DES_GET_PDT(curr_gpd)) {
+ /* It's SPD! */
+ spd = QBM_GET_SPD_PTR(curr_gpd);
+ p_spd_pi = QBM_SPD_GET_PI(spd);
+ p_spd_pie = QBM_SPD_PI_GET_FIRST_PIE(p_spd_pi);
+ packet_num = QBM_SPD_PI_GET_PKTNUM(p_spd_pi);
+ for (i = 0; i < packet_num; i++) {
+ if ( QBM_SPD_PIE_GET_IGR(p_spd_pie) && QBM_SPD_PIE_GET_EOL(p_spd_pie) ) {
+ UT_ASSERT(KAL_FALSE);
+ }
+ if (!QBM_SPD_PIE_GET_IGR(p_spd_pie)) {
+ cnt++;
+ }
+ if (QBM_SPD_PIE_GET_EOL(p_spd_pie)) {
+ /* end of packet list */
+ break;
+ } else {
+ p_spd_pie = QBM_SPD_PIE_NEXT(p_spd_pie);
+ }
+ }
+ if (!QBM_SPD_PIE_GET_EOL(p_spd_pie)) {
+ UT_ASSERT(KAL_FALSE);
+ }
+ }
+ }
+
+ return cnt;
+}
+
+void ipc_ut_install_ul_filters(kal_bool callback_with_info,
+ kal_bool with_callback,
+ kal_uint32 ipv4_filter_cnt,
+ kal_uint32 ipv6_filter_cnt,
+ kal_bool with_wildcard,
+ kal_bool with_bwm,
+ kal_uint8 matched_filter_idx_v4,
+ kal_uint8 matched_filter_idx_v6,
+ kal_uint32 good_netif_id)
+{
+ kal_uint32 idx = 0;
+ ipc_ut_filter_info_t *info = NULL;
+ ipc_filter_rules_t *rules = NULL;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ if (ipv4_filter_cnt > (IPC_MAX_FILTER_CNT >> 1)) {
+ ipv4_filter_cnt = (IPC_MAX_FILTER_CNT >> 1);
+ }
+ if (ipv6_filter_cnt > (IPC_MAX_FILTER_CNT >> 1)) {
+ ipv6_filter_cnt = (IPC_MAX_FILTER_CNT >> 1);
+ }
+
+ for (idx = 0; idx < ipv4_filter_cnt; idx++) {
+ info = &ipc_ut_info_set[idx];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ if (matched_filter_idx_v4 == idx) {
+ /*
+ * IPv4 DHCP.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_SRC_IPV4 |
+ IPC_FILTER_BY_DST_IPV4 |
+ IPC_FILTER_BY_NETIF_ID);
+ rules->netif_id = good_netif_id;
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 68;
+ rules->dst_port = 67;
+ IPC_CP_V4_ADDR(rules->src_ipv4.addr8, ipc_ut_ipv4_dhcp_ul_packet + 12);
+ IPC_CP_V4_ADDR(rules->dst_ipv4.addr8, ipc_ut_ipv4_dhcp_ul_packet + 16);
+ } else if (0 == idx) {
+ /*
+ * IPv4 wrong Netif.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_NETIF_ID);
+ rules->netif_id = IPC_UT_BAD_NETIF_ID;
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 7890;
+ } else {
+ /*
+ * IPv4 non-DHCP.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT);
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 7890;
+ }
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+
+ if (with_callback) {
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+ } else {
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+ }
+
+ UT_ASSERT(idx == info->filter_id);
+ }
+
+ for (idx = 0; idx < ipv6_filter_cnt; idx++) {
+ info = &ipc_ut_info_set[ipv4_filter_cnt + idx];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ if (matched_filter_idx_v6 == idx) {
+ /*
+ * IPv6 DHCP.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_SRC_IPV6 |
+ IPC_FILTER_BY_DST_IPV6 |
+ IPC_FILTER_BY_NETIF_ID);
+ rules->netif_id = good_netif_id;
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 546;
+ rules->dst_port = 547;
+ IPC_CP_V6_ADDR(rules->src_ipv6.addr8, ipc_ut_ipv6_dhcp_ul_packet + 8);
+ IPC_CP_V6_ADDR(rules->dst_ipv6.addr8, ipc_ut_ipv6_dhcp_ul_packet + 24);
+ } else if (0 == idx) {
+ /*
+ * IPv6 wrong Netif.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_NETIF_ID);
+ rules->netif_id = IPC_UT_BAD_NETIF_ID;
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->dst_port = 9876;
+ } else {
+ /*
+ * IPv6 non-DHCP.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_DST_PORT);
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->dst_port = 9876;
+ }
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ UT_ASSERT(ipv4_filter_cnt + idx == info->filter_id);
+ }
+
+ if (with_wildcard) {
+ info = &ipc_ut_info_set[ipv4_filter_cnt + ipv6_filter_cnt];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+
+ rules->features = IPC_FILTER_FEATURE_WC;
+ rules->priority = IPC_UT_MID_PRIORITY;
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ UT_ASSERT(ipv4_filter_cnt + ipv6_filter_cnt == info->filter_id);
+ }
+
+ if (with_bwm) {
+ /*
+ * IPv4 DHCP Bypass When Matched filter.
+ */
+ info = &ipc_ut_info_set[
+ ipv4_filter_cnt + ipv6_filter_cnt + (with_wildcard) ? 1 : 0];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+
+ rules->features = IPC_FILTER_FEATURE_BWM;
+ rules->priority = IPC_UT_HIGH_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_SRC_IPV4 |
+ IPC_FILTER_BY_DST_IPV4 |
+ IPC_FILTER_BY_NETIF_ID);
+ rules->netif_id = good_netif_id;
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 68;
+ rules->dst_port = 67;
+ IPC_CP_V4_ADDR(rules->src_ipv4.addr8, ipc_ut_ipv4_dhcp_ul_packet + 12);
+ IPC_CP_V4_ADDR(rules->dst_ipv4.addr8, ipc_ut_ipv4_dhcp_ul_packet + 16);
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ UT_ASSERT(ipv4_filter_cnt + ipv6_filter_cnt + (with_wildcard)?1:0 == info->filter_id);
+
+ /*
+ * IPv6 DHCP Bypass When Matched filter.
+ */
+ info = &ipc_ut_info_set[
+ ipv4_filter_cnt + ipv6_filter_cnt + 1 + (with_wildcard) ? 1 : 0];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+
+ rules->features = IPC_FILTER_FEATURE_BWM;
+ rules->priority = IPC_UT_HIGH_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_SRC_IPV6 |
+ IPC_FILTER_BY_DST_IPV6 |
+ IPC_FILTER_BY_NETIF_ID);
+ rules->netif_id = good_netif_id;
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 546;
+ rules->dst_port = 547;
+ IPC_CP_V6_ADDR(rules->src_ipv6.addr8, ipc_ut_ipv6_dhcp_ul_packet + 8);
+ IPC_CP_V6_ADDR(rules->dst_ipv6.addr8, ipc_ut_ipv6_dhcp_ul_packet + 24);
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+
+ if (callback_with_info == 0) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ UT_ASSERT(ipv4_filter_cnt + ipv6_filter_cnt + 1 + (with_wildcard)?1:0 == info->filter_id);
+ }
+}
+
+void ipc_ut_uninstall_ul_filters(kal_uint32 ipv4_filter_cnt,
+ kal_uint32 ipv6_filter_cnt,
+ kal_bool with_wildcard,
+ kal_bool with_bwm)
+{
+ kal_uint32 idx = 0;
+ kal_uint32 filter_cnt = ipv4_filter_cnt + ipv6_filter_cnt + (
+ (with_wildcard) ? 1 : 0) + ((with_bwm) ? 2 : 0);
+
+ for (idx = 0; idx < filter_cnt; idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ ipc_dereg_filter(idx);
+
+ UT_ASSERT(IPC_UT_NO_ERROR == ipc_ut_get_error());
+ }
+}
+
+void ipc_ut_install_netif_filter(kal_uint32 netif_id) {
+ ipc_ut_filter_info_t *info = NULL;
+ ipc_filter_rules_t *rules = NULL;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ info = &ipc_ut_info_set[0];
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = IPC_FILTER_BY_NETIF_ID | IPC_FILTER_BY_PROTOCOL;
+ rules->netif_id = netif_id;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_dl_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_dl_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ ntfy_ctxt.p_ntfy_args = (void *)info;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+}
+
+void ipc_ut_uninstall_netif_filter(void) {
+ ipc_ut_filter_info_t *info = NULL;
+ info = &ipc_ut_info_set[0];
+ ipc_deregister_dl_filter(info->filter_id);
+}
+
+void ipc_ut_install_dl_filters(kal_bool callback_with_info,
+ kal_bool with_callback,
+ kal_uint32 ipv4_filter_cnt,
+ kal_uint32 ipv6_filter_cnt,
+ kal_uint8 matched_filter_idx_v4,
+ kal_uint8 matched_filter_idx_v6,
+ kal_uint32 netif_id)
+{
+ kal_uint32 idx = 0;
+ ipc_ut_filter_info_t *info = NULL;
+ ipc_filter_rules_t *rules = NULL;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ if (ipv4_filter_cnt > (IPC_MAX_FILTER_CNT >> 1)) {
+ ipv4_filter_cnt = (IPC_MAX_FILTER_CNT >> 1);
+ }
+ if (ipv6_filter_cnt > (IPC_MAX_FILTER_CNT >> 1)) {
+ ipv6_filter_cnt = (IPC_MAX_FILTER_CNT >> 1);
+ }
+
+ for (idx = 0; idx < ipv4_filter_cnt; idx++) {
+ info = &ipc_ut_info_set[idx];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ if (matched_filter_idx_v4 == idx) {
+ /*
+ * IPv4 DHCP.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_SRC_IPV4 |
+ IPC_FILTER_BY_DST_IPV4 |
+ IPC_FILTER_BY_PDN_ID |
+ IPC_FILTER_BY_EBI |
+ IPC_FILTER_BY_NETIF_ID);
+
+ rules->netif_id = netif_id;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ rules->ebi = IPC_UT_DL_EBI;
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 67;
+ rules->dst_port = 68;
+ IPC_CP_V4_ADDR(rules->src_ipv4.addr8, ipc_ut_ipv4_dhcp_packet + 12);
+ IPC_CP_V4_ADDR(rules->dst_ipv4.addr8, ipc_ut_ipv4_dhcp_packet + 16);
+ } else if (0 == idx) {
+ /*
+ * IPv4 wrong Netif.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_NETIF_ID |
+ IPC_FILTER_BY_PDN_ID);
+ rules->netif_id = IPC_UT_BAD_NETIF_ID;
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 7890;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ } else {
+ /*
+ * IPv4 non-DHCP.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_PDN_ID);
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 7890;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ }
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_dl_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_dl_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ ntfy_ctxt.p_ntfy_args = (void *)info;
+
+ if (with_callback) {
+ if (callback_with_info) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+ } else {
+ if (callback_with_info) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+ }
+ UT_ASSERT(idx == info->filter_id);
+ }
+
+ for (idx = 0; idx < ipv6_filter_cnt; idx++) {
+ info = &ipc_ut_info_set[ipv4_filter_cnt + idx];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ if (matched_filter_idx_v6 == idx) {
+ /*
+ * IPv6 DHCP.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_SRC_IPV6 |
+ IPC_FILTER_BY_DST_IPV6 |
+ IPC_FILTER_BY_PDN_ID |
+ IPC_FILTER_BY_EBI |
+ IPC_FILTER_BY_NETIF_ID);
+ rules->netif_id = netif_id;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ rules->ebi = IPC_UT_DL_EBI;
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->src_port = 546;
+ rules->dst_port = 547;
+ IPC_CP_V6_ADDR(rules->src_ipv6.addr8, ipc_ut_ipv6_dhcp_packet + 8);
+ IPC_CP_V6_ADDR(rules->dst_ipv6.addr8, ipc_ut_ipv6_dhcp_packet + 24);
+ } else if (0 == idx) {
+ /*
+ * IPv6 wrong Netif.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_NETIF_ID |
+ IPC_FILTER_BY_PDN_ID);
+ rules->netif_id = IPC_UT_BAD_NETIF_ID;
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->dst_port = 9876;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ } else {
+ /*
+ * IPv6 non-DHCP.
+ */
+ rules->priority = IPC_UT_LOW_PRIORITY;
+ rules->valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID);
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+ rules->protocol = IPC_HDR_PROT_UDP;
+ rules->dst_port = 9876;
+ rules->pdn_id = IPC_UT_PDN_ID;
+ }
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_dl_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_dl_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ ntfy_ctxt.p_ntfy_args = (void *)info;
+
+ if (callback_with_info) {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ } else {
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ info->filter_id = ipc_reg_filter(DL_DIRECT, rules, &ntfy_ctxt);
+ }
+
+ UT_ASSERT(ipv4_filter_cnt + idx == info->filter_id);
+ }
+}
+
+void ipc_ut_uninstall_dl_filters(kal_uint32 ipv4_filter_cnt, kal_uint32 ipv6_filter_cnt) {
+ kal_uint32 idx;
+ kal_uint32 filter_cnt = ipv4_filter_cnt + ipv6_filter_cnt;
+
+ for (idx = 0; idx < filter_cnt; idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ ipc_deregister_dl_filter(idx);
+
+ UT_ASSERT(IPC_UT_NO_ERROR == ipc_ut_get_error());
+ }
+}
+
+void ipc_ut_ntfy_callback(ipc_ntfy_param_t *param) {
+ kal_int32 ntfy_param_idx;
+ kal_int32 ntfy_info_idx;
+
+ /* Check for redundant parameter */
+ for ( ntfy_param_idx = 0 ; ntfy_param_idx < ipc_ut_ntfy_param.count ; ntfy_param_idx ++ ) {
+ if (0 == kal_mem_cmp(&(ipc_ut_ntfy_param.params[ntfy_param_idx]), param, sizeof(ipc_ntfy_param_t))) { /* Duplicated entry found : impossible */
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+ }
+
+ /* Validate the callback parameter */
+ for ( ntfy_info_idx = 0 ; ntfy_info_idx < IPC_MAX_NTFY_CNT ; ntfy_info_idx ++ ) {
+ if ( (KAL_TRUE == ipc_ut_ntfy_info.ntfy_valid[ntfy_info_idx]) &&
+ (param->context == (void*)(ipc_ut_ntfy_info.ntfy_context[ntfy_info_idx])) &&
+ (param->ntfy_id == ipc_ut_ntfy_info.ntfy_id[ntfy_info_idx]) ) { /* Record the notification */
+ UT_ASSERT(ipc_ut_ntfy_param.count < IPC_UT_NTFY_PARAM_MAX_COUNT);
+ kal_mem_cpy(&(ipc_ut_ntfy_param.params[ipc_ut_ntfy_param.count]), param, sizeof(ipc_ntfy_param_t));
+ ipc_ut_ntfy_param.count ++;
+
+ return;
+ }
+ }
+
+ /* No entry is found : fail case */
+ UT_ASSERT(KAL_FALSE);
+}
+
+void ipc_ut_ntfy_reset_param(void) {
+ kal_mem_set(&ipc_ut_ntfy_param, 0, sizeof(ipc_ut_ntfy_param));
+}
+
+void ipc_ut_ntfy_reset_info(void) {
+ kal_mem_set(&ipc_ut_ntfy_info, 0, sizeof(ipc_ut_ntfy_info));
+}
+
+kal_bool ipc_ut_ntfy_registration(kal_int32 register_cnt) {
+ kal_int32 idx;
+
+ for ( idx = 0 ; idx < register_cnt ; idx ++ ) {
+ kal_int32 ntfy_id;
+ kal_int32 ntfy_info_idx;
+
+ if (IPC_MAX_NTFY_CNT > ipc_ut_ntfy_info.count) {
+ kal_bool added;
+
+ added = KAL_FALSE;
+ for ( ntfy_info_idx = 0 ; ntfy_info_idx < IPC_MAX_NTFY_CNT ; ntfy_info_idx ++ ) {
+ if ((KAL_FALSE == added) &&
+ (KAL_FALSE == ipc_ut_ntfy_info.ntfy_valid[ntfy_info_idx]) /* Find invalid(NULL) entry to register */) {
+ ntfy_id = ipc_register_ntfy(ipc_ut_ntfy_callback, (void*)ntfy_info_idx);
+
+ /* Should success */
+ if ( 0 > ntfy_id ) {
+ goto err;
+ }
+
+ /* record the notification ID */
+ UT_ASSERT(ipc_ut_ntfy_info.count < IPC_MAX_NTFY_CNT);
+ ipc_ut_ntfy_info.ntfy_valid[ntfy_info_idx] = KAL_TRUE;
+ ipc_ut_ntfy_info.ntfy_context[ntfy_info_idx] = ntfy_info_idx;
+ ipc_ut_ntfy_info.ntfy_id[ntfy_info_idx] = ntfy_id;
+ ipc_ut_ntfy_info.count ++;
+
+ added = KAL_TRUE;
+ }
+ }
+ } else {
+ ntfy_id = ipc_register_ntfy(ipc_ut_ntfy_callback, (void*)0x12345678);
+
+ /* Should fail */
+ if ( 0 <= ntfy_id ) {
+ goto err;
+ }
+ }
+ }
+
+ return KAL_TRUE;
+
+err:
+ return KAL_FALSE;
+}
+
+kal_bool ipc_ut_ntfy_deregistration(kal_bool deregister_all, kal_int32 deregister_cnt, kal_int32 *remaining_cnt) {
+ kal_int32 total_deregister_cnt;
+ kal_int32 deregistered_cnt;
+ kal_int32 total_skip_count;
+ kal_int32 start_idx;
+
+ if (KAL_TRUE == deregister_all) { /* Deregister ALL entries */
+ total_deregister_cnt = ipc_ut_ntfy_info.count;
+ total_skip_count = 0;
+ } else { /* Deregister specific count entries */
+ total_deregister_cnt = deregister_cnt;
+ total_skip_count = 1;
+ }
+
+
+ deregistered_cnt = 0;
+ start_idx = 0;
+
+ while ((deregistered_cnt < total_deregister_cnt) && (ipc_ut_ntfy_info.count > 0)) {
+ kal_int32 ntfy_info_idx;
+ kal_bool deregistered;
+ kal_int32 skip_count;
+
+ deregistered = KAL_FALSE;
+ skip_count = total_skip_count;
+ ntfy_info_idx = start_idx;
+
+ while (KAL_FALSE == deregistered) {
+ /* Find valid entry to deregister */
+ if (KAL_TRUE == ipc_ut_ntfy_info.ntfy_valid[ntfy_info_idx]) {
+ if (0 < skip_count) /* Skip valid entry if skip count > 0 */ {
+ skip_count --;
+ } else { /* actually deregister entry */
+ ipc_deregister_ntfy(ipc_ut_ntfy_info.ntfy_id[ntfy_info_idx]);
+
+ ipc_ut_ntfy_info.ntfy_valid[ntfy_info_idx] = KAL_FALSE;
+ ipc_ut_ntfy_info.count --;
+ deregistered_cnt ++;
+ deregistered = KAL_TRUE;
+ }
+ }
+
+ /* Next entry */
+ if (ntfy_info_idx == IPC_MAX_NTFY_CNT) {
+ ntfy_info_idx = 0;
+ } else {
+ ntfy_info_idx ++;
+ }
+ }
+
+ start_idx = ntfy_info_idx;
+ }
+
+ if (remaining_cnt) {*remaining_cnt = ipc_ut_ntfy_info.count;}
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ntfy_chk_param(ipc_ntfy_type_e ntfy_type, kal_int32 netif_id, kal_int32 ip_id, kal_int32 ntfy_cnt) {
+ kal_int32 match_cnt;
+ kal_int32 idx;
+
+ match_cnt = 0;
+
+ for ( idx = 0 ; idx < ipc_ut_ntfy_param.count ; idx ++ ) {
+ if (ipc_ut_ntfy_param.params[idx].ntfy_type != ntfy_type) {continue;}
+ if (ipc_ut_ntfy_param.params[idx].netif_id != netif_id) {continue;}
+ if (ipc_ut_ntfy_param.params[idx].ip_id != ip_id) {continue;}
+ match_cnt ++;
+ }
+
+ return (match_cnt == ntfy_cnt)?KAL_TRUE:KAL_FALSE;
+}
+
+/*------------------------------------------------------------------------------
+ * public functions.
+ *----------------------------------------------------------------------------*/
+kal_bool ipc_ut_msg_chk(module_type _src_mod_id, module_type _dest_mod_id, sap_type _sap_id, msg_type _msg_id, kal_int32 _trigger_cnt);
+
+kal_bool ipc_ut_msg_chk(
+ module_type _src_mod_id,
+ module_type _dest_mod_id,
+ sap_type _sap_id,
+ msg_type _msg_id,
+ kal_int32 _trigger_cnt /* <0 means 'DONT CHECK' */) {
+
+ if ((_trigger_cnt >= 0) && (_trigger_cnt != ipc_ut_msg_sent._trigger_cnt)) {
+ goto err;
+ }
+
+ if (_trigger_cnt != 0) { /* Don't check trigger count and expected trigger count > 0 */
+ if (kal_mem_cmp(&(ipc_ut_msg_sent._src_mod_id),&(_src_mod_id), sizeof(module_type))) {
+ goto err;
+ }
+
+ if (kal_mem_cmp(&(ipc_ut_msg_sent._dest_mod_id),&(_dest_mod_id), sizeof(module_type))) {
+ goto err;
+ }
+
+ if (kal_mem_cmp(&(ipc_ut_msg_sent._sap_id),&(_sap_id), sizeof(sap_type))) {
+ goto err;
+ }
+
+ if (kal_mem_cmp(&(ipc_ut_msg_sent._msg_id),&(_msg_id), sizeof(msg_type))) {
+ goto err;
+ }
+ }
+
+ return KAL_TRUE;
+err:
+ return KAL_FALSE;
+}
+
+kal_bool ipc_ut_msg_send6(module_type _src_mod_id,
+ module_type _dest_mod_id,
+ sap_type _sap_id,
+ msg_type _msg_id,
+ local_para_struct *_local_para_ptr,
+ peer_buff_struct *_peer_buff_ptr)
+{
+ ipc_ut_msg_sent._trigger_cnt ++;
+
+ kal_mem_cpy(&(ipc_ut_msg_sent._src_mod_id),&(_src_mod_id), sizeof(module_type));
+ kal_mem_cpy(&(ipc_ut_msg_sent._dest_mod_id),&(_dest_mod_id), sizeof(module_type));
+
+ kal_mem_cpy(&(ipc_ut_msg_sent._sap_id),&(_sap_id), sizeof(sap_type));
+ kal_mem_cpy(&(ipc_ut_msg_sent._msg_id),&(_msg_id), sizeof(msg_type));
+
+ /* copy pointer only for UT verification and free local parameter and peer buffer */
+ kal_mem_cpy(&(ipc_ut_msg_sent._local_para_ptr), &(_local_para_ptr), sizeof(local_para_struct *));
+ kal_mem_cpy(&(ipc_ut_msg_sent._peer_buff_ptr), &(_peer_buff_ptr), sizeof(peer_buff_struct *));
+
+ if (_local_para_ptr) {
+ if (ipc_latest_local_param_p) {
+ kal_mem_cpy(ipc_latest_local_param_p, _local_para_ptr, ipc_latest_local_param_size);
+ }
+
+ free_local_para((local_para_struct *)_local_para_ptr);
+ }
+
+ if (_peer_buff_ptr) {
+ if (ipc_latest_peer_buff_p) {
+ kal_mem_cpy(ipc_latest_peer_buff_p, _peer_buff_ptr, ipc_latest_peer_buff_size);
+ }
+
+ free_peer_buff((peer_buff_struct *)_peer_buff_ptr);
+ }
+
+ return KAL_TRUE;
+}
+
+void ipc_ut_on_ul_packet_filtered_req(void *req_ptr) {
+ ipc_packet_filtered_req_t *req = (ipc_packet_filtered_req_t *)req_ptr;
+
+ ipc_ut_ul_filter_callback(
+ req->context,
+ req->filter_id,
+ (qbm_gpd *)req->head_gpd,
+ (qbm_gpd *)req->tail_gpd,
+ req->length);
+}
+
+void ipc_ut_on_dl_packet_filtered_req(void *req_ptr) {
+ ipc_packet_filtered_req_t *req = (ipc_packet_filtered_req_t *)req_ptr;
+
+ ipc_ut_dl_filter_callback(
+ req->context,
+ req->filter_id,
+ (qbm_gpd *)req->head_gpd,
+ (qbm_gpd *)req->tail_gpd,
+ req->length);
+}
+
+void ipc_ut_on_ul_packet_filtered_with_info_req(void *req_ptr) {
+ ipc_packet_filtered_with_info_req_t *req = (ipc_packet_filtered_with_info_req_t *)req_ptr;
+
+ ipc_ut_ul_filter_with_info_callback(
+ &(req->info),
+ req->context,
+ req->filter_id,
+ (qbm_gpd *)req->head_gpd,
+ (qbm_gpd *)req->tail_gpd,
+ req->length);
+}
+
+void ipc_ut_on_dl_packet_filtered_with_info_req(void *req_ptr) {
+ ipc_packet_filtered_with_info_req_t *req = (ipc_packet_filtered_with_info_req_t *)req_ptr;
+
+ ipc_ut_dl_filter_with_info_callback(
+ &(req->info),
+ req->context,
+ req->filter_id,
+ (qbm_gpd *)req->head_gpd,
+ (qbm_gpd *)req->tail_gpd,
+ req->length);
+}
+
+
+void ipc_ut_reset_ul_info(void) {
+ ipc_ut_ul_pdn_id = 0;
+ ipc_ut_ul_gpd_cnt = 0;
+ ipc_ut_ul_meta_cnt = 0;
+ ipc_ut_ul_meta_non_igr_cnt = 0;
+ ipc_ut_ul_proto_idx = IPC_UT_INVALID_UL_PROTO_IDX;
+}
+
+void ipc_ut_rcv_ul_sdu(ip_type_e ip_type, kal_uint32 pdn_id, qbm_gpd *p_head, qbm_gpd *p_tail, kal_uint8 proto_idx) {
+ UT_ASSERT(NULL != p_head);
+ UT_ASSERT(NULL != p_tail);
+
+ ipc_ut_ul_pdn_id = pdn_id;
+ ipc_ut_ul_gpd_cnt += ipc_ut_gpd_list_count(p_head, p_tail);
+
+ /* Drop GPD list */
+ qbmt_dest_q(p_head, p_tail);
+
+ if (proto_idx != ipc_ut_ul_proto_idx) {
+ if (IPC_UT_INVALID_UL_PROTO_IDX == ipc_ut_ul_proto_idx) {
+ ipc_ut_ul_proto_idx = proto_idx;
+ } else if (1 == proto_idx) {
+ /* Do nothing */
+ } else {
+ utDLOG("unexpected SIM idx\r\n");
+ UT_ASSERT(KAL_FALSE);
+ }
+ }
+}
+
+void ipc_ut_rcv_ul_sdu_by_ebi(kal_uint32 ebi, qbm_gpd *p_head, qbm_gpd *p_tail, kal_uint8 proto_idx) {
+ if (IPC_UT_UL_EBI == ebi) {
+ if (ipc_ut_ul_ebi_tail_gpd) {
+ QBM_DES_SET_NEXT(ipc_ut_ul_ebi_tail_gpd, p_head);
+ ipc_ut_ul_ebi_tail_gpd = p_tail;
+ } else {
+ ipc_ut_ul_ebi_head_gpd = p_head;
+ ipc_ut_ul_ebi_tail_gpd = p_tail;
+ }
+ } else {
+ qbmt_dest_q(p_head, p_tail);
+ utDLOG("unexpected EBI\r\n");
+ UT_ASSERT(KAL_FALSE);
+ }
+ if (proto_idx != ipc_ut_ul_proto_idx) {
+ if (IPC_UT_INVALID_UL_PROTO_IDX == ipc_ut_ul_proto_idx) {
+ ipc_ut_ul_proto_idx = proto_idx;
+ } else {
+ qbmt_dest_q(p_head, p_tail);
+ utDLOG("unexpected SIM idx\r\n");
+ UT_ASSERT(KAL_FALSE);
+ }
+ }
+ g_received_cnt += ipc_ut_gpd_list_count(p_head, p_tail);
+}
+
+void ipc_ut_reg_cbk_notify_tick_source(upcm_nofify_lte_tick_f pf_notify) {
+ /* Do nothing in UT */
+}
+
+void ipc_ut_reg_cbk_dlvr_dl_sdu(upcm_dlvr_dl_sdu_93_f pf_dlvr_sdu) {
+ /* Do nothing in UT */
+}
+
+void ipc_ut_rcv_ul_sdu_meta(kal_uint32 start_idx, kal_uint32 end_idx, LHIF_QUEUE_TYPE q_type) {
+ kal_uint32 i = start_idx;
+ kal_int16 proto_idx = IPC_UT_INVALID_UL_PROTO_IDX;
+
+ while (i != end_idx) {
+ if (!ipc_ut_meta_tbl_s[i].ignore ) {
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ if(ipc_ut_meta_tbl_s[i].mr != IPC_HPC_MR_DPFM_ADD_CMD){
+ proto_idx = ipc_ut_meta_tbl_s[i].protocol_idx;
+ ipc_ut_ul_pdn_id = ipc_ut_meta_tbl_s[i].pdn;
+ }
+#else
+ proto_idx = ipc_ut_meta_tbl_s[i].protocol_idx;
+ ipc_ut_ul_pdn_id = ipc_ut_meta_tbl_s[i].pdn;
+#endif
+ }
+
+ i ++;
+ if (i == IPC_UT_META_TABLE_SIZE) {
+ i = 0;
+ }
+ }
+ ipc_ut_ul_meta_cnt += (end_idx > start_idx) ? (end_idx - start_idx) : (IPC_UT_META_TABLE_SIZE - start_idx + end_idx);
+ ipc_ut_ul_meta_non_igr_cnt += ipc_ut_non_igr_meta_count(start_idx, end_idx, q_type);
+ UT_ASSERT(ipc_ut_ul_meta_cnt == (ipc_ut_ul_meta_non_igr_cnt + g_ipc_ut_igr_meta_cnt));
+
+ /* Free meta list */
+ ipc_ut_meta_read_done(start_idx, end_idx, q_type);
+
+ if (proto_idx != ipc_ut_ul_proto_idx) {
+ if (IPC_UT_INVALID_UL_PROTO_IDX == ipc_ut_ul_proto_idx) {
+ ipc_ut_ul_proto_idx = proto_idx;
+ } else {
+ utDLOG("unexpected SIM idx\r\n");
+ UT_ASSERT(KAL_FALSE);
+ }
+ }
+}
+
+kal_bool ipc_ut_dpfm_check_route(kal_bool uplink, kal_uint8 ip_type, ipc_pkt_des_t *pkt_des, kal_uint32 in_netif_id, kal_uint32 *out_netif_id) {
+ ipc_packet_info_t *packet_info;
+ kal_bool matched = KAL_TRUE;
+ lhif_meta_tbl_t *ul_meta;
+ ipf_dl_meta *dl_meta;
+
+ UT_ASSERT((NULL != pkt_des) && (NULL !=out_netif_id));
+
+ packet_info = pkt_des->packet_info;
+
+ if ( pkt_des->des_type == IPC_PKT_DES_TYPE_META)
+ {
+ if (uplink) {
+ ul_meta = pkt_des->meta;
+ if (IPC_HPC_MR_DPFM_MATCH == ul_meta->mr) {
+ goto _match;
+ }
+ } else {
+ dl_meta = pkt_des->ipf_meta;
+ if (IPC_IPF_MR_DPFM_MATCH == dl_meta->mr) {
+ goto _match;
+ }
+ }
+ }
+
+ matched &= (IPC_INVALID_NETIF_ID != in_netif_id);
+ matched &= (IPC_IP_TYPE_IPV4 == ip_type || IPC_IP_TYPE_IPV6 == ip_type);
+
+ if (IPC_IP_TYPE_IPV4 == ip_type) {
+ if (uplink) {
+ matched &= (IPC_PORT_BOOTPC == packet_info->src_port);
+ matched &= (IPC_PORT_BOOTPS == packet_info->dst_port);
+ } else {
+ matched &= (IPC_PORT_BOOTPS == packet_info->src_port);
+ matched &= (IPC_PORT_BOOTPC == packet_info->dst_port);
+ }
+ } else {
+ /* IPV6 */
+ if (uplink) {
+ matched &= (IPC_UT_IPV6_DPFM_SRC_PORT == packet_info->src_port);
+ matched &= (IPC_UT_IPV6_DPFM_DST_PORT == packet_info->dst_port);
+ } else {
+ matched &= (IPC_UT_IPV6_DPFM_SRC_PORT == packet_info->src_port);
+ matched &= (IPC_UT_IPV6_DPFM_DST_PORT == packet_info->dst_port);
+ }
+ }
+ matched &= (IPC_HDR_PROT_UDP == packet_info->protocol);
+
+_match:
+ if (matched) {
+ *out_netif_id = (uplink) ? IPC_UT_LHIF_NETID_START : IPC_UT_DPFM_NETID_START;
+ }
+
+ return matched;
+}
+
+kal_bool ipc_ut_dpfm_is_activated(void)
+{
+ return ipc_ut_dpfm_is_activated_g;
+}
+
+/*------------------------------------------------------------------------------
+ * test case functions.
+ *----------------------------------------------------------------------------*/
+
+#if defined(__MTK_TARGET__)
+kal_bool ipc_ut_struct(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ // init before test
+ ipc_ut_init();
+
+ if (sizeof(ipc_io_request_t) % 4 != 0) {
+ utELOG("ipc_io_request_t size is not multiple of 4-bte!\r\n");
+ return KAL_FALSE;
+ }
+ if (sizeof(ipc_conf_t) % 4 != 0) {
+ utELOG("ipc_conf_t size is not multiple of 4-bte!\r\n");
+ return KAL_FALSE;
+ }
+ if (sizeof(ipc_filter_rules_t) % 4 != 0) {
+ utELOG("ipc_filter_rules_t size is not multiple of 4-bte!\r\n");
+ return KAL_FALSE;
+ }
+ if (sizeof(ipc_link_req_t) % 4 != 0) {
+ utELOG("ipc_link_req_t size is not multiple of 4-bte!\r\n");
+ return KAL_FALSE;
+ }
+ if (sizeof(ipc_packet_filtered_req_t) % 4 != 0) {
+ utELOG("ipc_packet_filtered_req_t size is not multiple of 4-bte!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (sizeof(ipc_netif_t) % 4 != 0) {
+ utELOG("ipc_netif_t size is not multiple of 4-bte!\r\n");
+ return KAL_FALSE;
+ }
+ if (sizeof(ipc_session_t) % 4 != 0) {
+ utELOG("ipc_session_t size is not multiple of 4-bte!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+#endif
+
+kal_bool ipc_ut_helper_macro(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ static kal_uint8 in_buf[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
+ static kal_uint8 out_buf[40];
+
+ // init before test
+ ipc_ut_init();
+
+ if (IPC_NE_GET_2B(in_buf) != 0x1122 ||
+ IPC_NE_GET_2B(in_buf+1) != 0x2233 ) {
+ utELOG("IPC_NE_GET_2B() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ kal_mem_set(out_buf, 0, sizeof(out_buf));
+ IPC_NE_SET_2B(out_buf, 0x1122);
+ IPC_NE_SET_2B(out_buf+5, 0x6677);
+ if (kal_mem_cmp(in_buf, out_buf, 2) ||
+ kal_mem_cmp(in_buf+5, out_buf+5, 2)) {
+ utELOG("IPC_NE_SET_2B() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (IPC_NE_GET_4B(in_buf) != 0x11223344 ||
+ IPC_NE_GET_4B(in_buf+1) != 0x22334455 ||
+ IPC_NE_GET_4B(in_buf+2) != 0x33445566 ||
+ IPC_NE_GET_4B(in_buf+3) != 0x44556677) {
+ utELOG("IPC_NE_GET_4B() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ kal_mem_set(out_buf, 0, sizeof(out_buf));
+ IPC_NE_SET_4B(out_buf, 0x11223344);
+ if (kal_mem_cmp(in_buf, out_buf, 4)) {
+ utELOG("IPC_NE_SET_4B() offset 0 failed!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_set(out_buf, 0, sizeof(out_buf));
+ IPC_NE_SET_4B(out_buf+1, 0x22334455);
+ if (kal_mem_cmp(in_buf+1, out_buf+1, 4)) {
+ utELOG("IPC_NE_SET_4B() offset 1 failed!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_set(out_buf, 0, sizeof(out_buf));
+ IPC_NE_SET_4B(out_buf+2, 0x33445566);
+ if (kal_mem_cmp(in_buf+2, out_buf+2, 4)) {
+ utELOG("IPC_NE_SET_4B() offset 2 failed!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_set(out_buf, 0, sizeof(out_buf));
+ IPC_NE_SET_4B(out_buf+3, 0x44556677);
+ if (kal_mem_cmp(in_buf+3, out_buf+3, 4)) {
+ utELOG("IPC_NE_SET_4B() offset 3 failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * IPv4
+ */
+ if (!IPC_HDR_IS_V4(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_IS_V4() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (20 != IPC_HDR_V4_GET_IHL(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_IHL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x01 != IPC_HDR_V4_GET_DSCP(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_DSCP() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x015f != IPC_HDR_V4_GET_TOTAL_LENGTH(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_TOTAL_LENGTH() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x5f54 != IPC_HDR_V4_GET_IDENTITY(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_IDENTITY() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0 != IPC_HDR_V4_GET_FLAGS(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_FLAGS() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0 != IPC_HDR_V4_IS_MF(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_IS_MF() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0 != IPC_HDR_V4_GET_FRAG_OFFSET(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_FRAG_OFFSET() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0 != IPC_HDR_V4_IS_FRAG(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_IS_FRAG() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x40 != IPC_HDR_V4_GET_TTL(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_TTL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x11 != IPC_HDR_V4_GET_PROTOCOL(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_PROTOCOL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x92c3 != IPC_HDR_V4_GET_HEADER_CHECKSUM(ipc_ut_ipv4_dhcp_packet)) {
+ utELOG("IPC_HDR_V4_GET_HEADER_CHECKSUM() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0xac != *IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_ipv4_dhcp_packet) ||
+ 0x16 != *(IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_ipv4_dhcp_packet)+1)) {
+ utELOG("IPC_HDR_V4_GET_SRC_ADDR() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0xac != *IPC_HDR_V4_GET_DST_ADDR(ipc_ut_ipv4_dhcp_packet) ||
+ 0x16 != *(IPC_HDR_V4_GET_DST_ADDR(ipc_ut_ipv4_dhcp_packet)+1)) {
+ utELOG("IPC_HDR_V4_GET_DST_ADDR() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ kal_mem_set(out_buf, 0xff, sizeof(out_buf));
+ IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN(out_buf);
+ IPC_HDR_V4_SET_IHL(out_buf, 24);
+ IPC_HDR_V4_SET_DSCP(out_buf, 0x8);
+ IPC_HDR_V4_SET_TOTAL_LENGTH(out_buf, 0x0123);
+ IPC_HDR_V4_SET_IDENTITY(out_buf, 0x1234);
+ IPC_HDR_V4_SET_FLAGS(out_buf, 0x4);
+ IPC_HDR_V4_SET_FRAG_OFFSET(out_buf, 0x234);
+ IPC_HDR_V4_SET_TTL(out_buf, 0x45);
+ IPC_HDR_V4_SET_PROTOCOL(out_buf, 0x88);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(out_buf, 0x1234);
+ IPC_HDR_V4_SET_SRC_ADDR(out_buf, IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_ipv4_dhcp_packet));
+ IPC_HDR_V4_SET_DST_ADDR(out_buf, IPC_HDR_V4_GET_DST_ADDR(ipc_ut_ipv4_dhcp_packet));
+
+ if (!IPC_HDR_IS_V4(out_buf)) {
+ utELOG("IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (24 != IPC_HDR_V4_GET_IHL(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_IHL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x8 != IPC_HDR_V4_GET_DSCP(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_DSCP() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x0123 != IPC_HDR_V4_GET_TOTAL_LENGTH(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_TOTAL_LENGTH() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x1234 != IPC_HDR_V4_GET_IDENTITY(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_IDENTITY() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x4 != IPC_HDR_V4_GET_FLAGS(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_FLAGS() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x234 != IPC_HDR_V4_GET_FRAG_OFFSET(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_FRAG_OFFSET() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x45 != IPC_HDR_V4_GET_TTL(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_TTL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x88 != IPC_HDR_V4_GET_PROTOCOL(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_PROTOCOL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x1234 != IPC_HDR_V4_GET_HEADER_CHECKSUM(out_buf)) {
+ utELOG("IPC_HDR_V4_SET_HEADER_CHECKSUM() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (!IPC_EQ_V4_ADDR(IPC_HDR_V4_GET_SRC_ADDR(out_buf), IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_ipv4_dhcp_packet))) {
+ utELOG("IPC_HDR_V4_SET_SRC_ADDR() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (!IPC_EQ_V4_ADDR(IPC_HDR_V4_GET_DST_ADDR(out_buf), IPC_HDR_V4_GET_DST_ADDR(ipc_ut_ipv4_dhcp_packet))) {
+ utELOG("IPC_HDR_V4_SET_DST_ADDR() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * IPv6
+ */
+ if (!IPC_HDR_IS_V6(ipc_ut_ipv6_dhcp_packet)) {
+ utELOG("IPC_HDR_IS_V6() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0 != IPC_HDR_V6_GET_TC(ipc_ut_ipv6_dhcp_packet)) {
+ utELOG("IPC_HDR_V6_GET_TC() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0 != IPC_HDR_V6_GET_FLOW_LABEL(ipc_ut_ipv6_dhcp_packet)) {
+ utELOG("IPC_HDR_V6_GET_FLOW_LABEL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x0042 != IPC_HDR_V6_GET_LENGTH(ipc_ut_ipv6_dhcp_packet)) {
+ utELOG("IPC_HDR_V6_GET_LENGTH() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x11 != IPC_HDR_V6_GET_NH_TYPE(ipc_ut_ipv6_dhcp_packet)) {
+ utELOG("IPC_HDR_V6_GET_NH_TYPE() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x01 != IPC_HDR_V6_GET_HOP_LIMIT(ipc_ut_ipv6_dhcp_packet)) {
+ utELOG("IPC_HDR_V6_GET_HOP_LIMIT() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0xfe != *(IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_ipv6_dhcp_packet)) ||
+ 0x80 != *(IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_ipv6_dhcp_packet)+1)) {
+ utELOG("IPC_HDR_V6_GET_SRC_ADDR() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0xff != *(IPC_HDR_V6_GET_DST_ADDR(ipc_ut_ipv6_dhcp_packet)) ||
+ 0x02 != *(IPC_HDR_V6_GET_DST_ADDR(ipc_ut_ipv6_dhcp_packet)+1)) {
+ utELOG("IPC_HDR_V6_GET_DST_ADDR() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ kal_mem_set(out_buf, 0, sizeof(out_buf));
+ IPC_HDR_V6_RESET_VER_TC_FL(out_buf);
+ IPC_HDR_V6_SET_TC(out_buf, 0x12);
+ IPC_HDR_V6_SET_FLOW_LABEL(out_buf, 0x34567);
+ IPC_HDR_V6_SET_LENGTH(out_buf, 0x102);
+ IPC_HDR_V6_SET_NH_TYPE(out_buf, 0x06);
+ IPC_HDR_V6_SET_HOP_LIMIT(out_buf, 0xff);
+ IPC_HDR_V6_SET_SRC_ADDR(out_buf, IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_ipv6_dhcp_packet));
+ IPC_HDR_V6_SET_DST_ADDR(out_buf, IPC_HDR_V6_GET_DST_ADDR(ipc_ut_ipv6_dhcp_packet));
+
+ if (!IPC_HDR_IS_V6(out_buf)) {
+ utELOG("IPC_HDR_V6_RESET_VER_TC_FL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x12 != IPC_HDR_V6_GET_TC(out_buf)) {
+ utELOG("IPC_HDR_V6_SET_TC() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x34567 != IPC_HDR_V6_GET_FLOW_LABEL(out_buf)) {
+ utELOG("IPC_HDR_V6_SET_FLOW_LABEL() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x102 != IPC_HDR_V6_GET_LENGTH(out_buf)) {
+ utELOG("IPC_HDR_V6_SET_LENGTH() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x06 != IPC_HDR_V6_GET_NH_TYPE(out_buf)) {
+ utELOG("IPC_HDR_V6_SET_NH_TYPE() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0xff != IPC_HDR_V6_GET_HOP_LIMIT(out_buf)) {
+ utELOG("IPC_HDR_V6_SET_HOP_LIMIT() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (!IPC_EQ_V6_ADDR(IPC_HDR_V6_GET_SRC_ADDR(out_buf), IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_ipv6_dhcp_packet))) {
+ utELOG("IPC_HDR_V6_SET_SRC_ADDR() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (!IPC_EQ_V6_ADDR(IPC_HDR_V6_GET_DST_ADDR(out_buf), IPC_HDR_V6_GET_DST_ADDR(ipc_ut_ipv6_dhcp_packet))) {
+ utELOG("IPC_HDR_V6_SET_DST_ADDR() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * UDP
+ */
+ if (0x0043 != IPC_HDR_UDP_GET_SRC_PORT(IPC_HDR_V4_GET_NHPTR(ipc_ut_ipv4_dhcp_packet))) {
+ utELOG("IPC_HDR_UDP_GET_SRC_PORT() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x0044 != IPC_HDR_UDP_GET_DST_PORT(IPC_HDR_V4_GET_NHPTR(ipc_ut_ipv4_dhcp_packet))) {
+ utELOG("IPC_HDR_UDP_GET_DST_PORT() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x014b != IPC_HDR_UDP_GET_LENGTH(IPC_HDR_V4_GET_NHPTR(ipc_ut_ipv4_dhcp_packet))) {
+ utELOG("IPC_HDR_UDP_GET_LENGTH() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0xcf7d != IPC_HDR_UDP_GET_CHECKSUM(IPC_HDR_V4_GET_NHPTR(ipc_ut_ipv4_dhcp_packet))) {
+ utELOG("IPC_HDR_UDP_GET_CHECKSUM() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ kal_mem_set(out_buf, 0, sizeof(out_buf));
+ IPC_HDR_UDP_SET_SRC_PORT(out_buf, 0x1234);
+ IPC_HDR_UDP_SET_DST_PORT(out_buf, 0x5678);
+ IPC_HDR_UDP_SET_LENGTH(out_buf, 0x9abc);
+ IPC_HDR_UDP_SET_CHECKSUM(out_buf, 0xdef0);
+ if (0x1234 != IPC_HDR_UDP_GET_SRC_PORT(out_buf)) {
+ utELOG("IPC_HDR_UDP_SET_SRC_PORT() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x5678 != IPC_HDR_UDP_GET_DST_PORT(out_buf)) {
+ utELOG("IPC_HDR_UDP_SET_DST_PORT() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0x9abc != IPC_HDR_UDP_GET_LENGTH(out_buf)) {
+ utELOG("IPC_HDR_UDP_SET_LENGTH() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (0xdef0 != IPC_HDR_UDP_GET_CHECKSUM(out_buf)) {
+ utELOG("IPC_HDR_UDP_SET_CHECKSUM() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_checksum(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ kal_uint32 length;
+ kal_uint16 checksum;
+
+ // init before test
+ ipc_ut_init();
+
+ length = IPC_HDR_V4_GET_IHL(ipc_ut_ipv4_dns_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv4_dns_packet, length);
+
+ checksum = ipc_utils_calc_ipv4_checksum(ipc_ut_checksum_buf_s + idx);
+ if (0 != checksum) {
+ utELOG("ipc_utils_calc_ipv4_checksum(ipc_ut_ipv4_dns_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ length = sizeof(ipc_ut_ipv4_dns_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv4_dns_packet, length);
+
+ checksum = ipc_utils_calc_udp_checksum(
+ KAL_TRUE,
+ IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V4_GET_DST_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V4_GET_NHPTR(ipc_ut_checksum_buf_s + idx),
+ length - IPC_HDR_V4_GET_IHL(ipc_ut_checksum_buf_s + idx));
+ if (0xffff != checksum) {
+ utELOG("ipc_utils_calc_udp_checksum(ipc_ut_ipv4_dns_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ length = sizeof(ipc_ut_ipv4_dhcp_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv4_dhcp_packet, length);
+
+ checksum = ipc_utils_calc_udp_checksum(
+ KAL_TRUE,
+ IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V4_GET_DST_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V4_GET_NHPTR(ipc_ut_checksum_buf_s + idx),
+ length - IPC_HDR_V4_GET_IHL(ipc_ut_checksum_buf_s + idx));
+ if (0xffff != checksum) {
+ utELOG("ipc_utils_calc_udp_checksum(ipc_ut_ipv4_dhcp_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ length = sizeof(ipc_ut_ipv4_dhcp_ul_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv4_dhcp_ul_packet, length);
+
+ checksum = ipc_utils_calc_udp_checksum(
+ KAL_TRUE,
+ IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V4_GET_DST_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V4_GET_NHPTR(ipc_ut_checksum_buf_s + idx),
+ length - IPC_HDR_V4_GET_IHL(ipc_ut_checksum_buf_s + idx));
+ if (0xffff != checksum) {
+ utELOG("ipc_utils_calc_udp_checksum(ipc_ut_ipv4_dhcp_ul_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ length = sizeof(ipc_ut_ipv6_mdns_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv6_mdns_packet, length);
+
+ checksum = ipc_utils_calc_udp_checksum(
+ KAL_FALSE,
+ IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V6_GET_DST_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V6_GET_NHPTR(ipc_ut_checksum_buf_s + idx),
+ length - IPC_HDR_V6_HEADER_SIZE);
+ if (0xffff != checksum) {
+ utELOG("ipc_utils_calc_udp_checksum(ipc_ut_ipv6_mdns_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ length = sizeof(ipc_ut_ipv6_dhcp_ul_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv6_dhcp_ul_packet, length);
+
+ checksum = ipc_utils_calc_udp_checksum(
+ KAL_FALSE,
+ IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V6_GET_DST_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V6_GET_NHPTR(ipc_ut_checksum_buf_s + idx),
+ length - IPC_HDR_V6_HEADER_SIZE);
+ if (0xffff != checksum) {
+ utELOG("ipc_utils_calc_udp_checksum(ipc_ut_ipv6_dhcp_ul_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+
+ length = sizeof(ipc_ut_ipv6_dhcp_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv6_dhcp_packet, length);
+
+ checksum = ipc_utils_calc_udp_checksum(
+ KAL_FALSE,
+ IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V6_GET_DST_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V6_GET_NHPTR(ipc_ut_checksum_buf_s + idx),
+ length - IPC_HDR_V6_HEADER_SIZE);
+ if (0xffff != checksum) {
+ utELOG("ipc_utils_calc_udp_checksum(ipc_ut_ipv6_dhcp_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ length = sizeof(ipc_ut_ipv6_udp_zero_checksum_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv6_udp_zero_checksum_packet, length);
+
+ checksum = ipc_utils_calc_udp_checksum(
+ KAL_FALSE,
+ IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V6_GET_DST_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V6_GET_NHPTR(ipc_ut_checksum_buf_s + idx),
+ length - IPC_HDR_V6_HEADER_SIZE);
+ if (0xffff != checksum) {
+ utELOG("ipc_utils_calc_udp_checksum(ipc_ut_ipv6_udp_zero_checksum_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ length = sizeof(ipc_ut_ipv4_tcp_syn_packet);
+ for (idx = 0; idx < 4; idx++) {
+ kal_mem_set(ipc_ut_checksum_buf_s, 0, sizeof(ipc_ut_checksum_buf_s));
+ kal_mem_cpy(ipc_ut_checksum_buf_s + idx, ipc_ut_ipv4_tcp_syn_packet, length);
+
+ checksum = ipc_utils_calc_tcp_checksum(
+ KAL_TRUE,
+ IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V4_GET_DST_ADDR(ipc_ut_checksum_buf_s + idx),
+ IPC_HDR_V4_GET_NHPTR(ipc_ut_checksum_buf_s + idx),
+ length - IPC_HDR_V4_GET_IHL(ipc_ut_checksum_buf_s + idx));
+ if (0 != checksum) {
+ utELOG("ipc_utils_calc_tcp_checksum(ipc_ut_ipv4_tcp_syn_packet) failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_attach(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_bool result;
+ kal_uint32 idx;
+
+ utDLOG("net count: %d\r\n", IPC_UT_MAX_NET_CNT);
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_task_reset()) {
+ utELOG("ipc_task_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+
+ if ((idx & 0x1)) {
+ net->conf.features = IPC_F_DHCP4C;
+ }
+
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ if (!net->handle) {
+ utELOG("ipc_attach() returns NULL handle!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (((ipc_netif_t *)(net->handle))->config.features != net->conf.features) {
+ utELOG("ipc_attach() returns NULL handle!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_detach(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_bool result;
+ kal_uint32 idx;
+
+ // init before test
+ ipc_ut_init();
+
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_find_netif(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ ipc_netif_t *netif;
+ kal_uint32 idx;
+ kal_uint32 error_code = 0;
+
+ // init before test
+ ipc_ut_init();
+
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+
+ netif = ipc_find_netif(net->conf.netif_id);
+ error_code = ipc_ut_check_netif(netif, net);
+ if (error_code) {
+ utELOG("ipc_find_netif() failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_new_session(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_uint32 idx;
+
+ // init before test
+ ipc_ut_init();
+
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+
+ net->pdn_id = idx;
+ net->ip_type = IPC_IP_TYPE_MIXED + (idx % 3);
+ net->session[net->ip_type] = ipc_new_session(net->handle, net->pdn_id, net->ip_type, IPC_SESSION_STATE_BIND);
+ if (!net->session[net->ip_type]) {
+ utELOG("ipc_new_session() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (idx != net->session[net->ip_type]->ip_id) {
+ utELOG("ipc_new_session() ip_id mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_del_session(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_uint32 idx;
+
+ // init before test
+ ipc_ut_init();
+
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+
+ ipc_del_session(net->session[net->ip_type]);
+ net->session[net->ip_type] = NULL;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_find_session(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_uint32 idx;
+ ipc_session_t *session;
+ kal_uint32 error_code = 0;
+ ipc_session_t *tmp_session;
+
+ // init before test
+ ipc_ut_init();
+
+ tmp_session = ipc_find_session_by_ip_id(IPC_UT_INVALID_IP_ID, IPC_IP_TYPE_IPV4);
+ if (tmp_session) {
+ IPC_R_UNLOCK_OBJECT(tmp_session, ipc_spinlock_g);
+ utELOG("ipc_find_session_by_ip_id() with invalid ip_id shall get nothing in return!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+
+ session = ipc_find_session_by_context(net->pdn_id);
+ error_code = ipc_ut_check_session(session, net);
+ if (error_code) {
+ utELOG("ipc_find_session_by_context(): ip_id mismatched!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (IPC_IP_TYPE_MIXED != net->ip_type) {
+ session = ipc_find_session_by_netif(net->handle, net->ip_type);
+ error_code = ipc_ut_check_session(session, net);
+ if (error_code) {
+ utELOG("ipc_find_session_by_netif(): IPC_IP_TYPE_MIXED case mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ } else {
+ session = ipc_find_session_by_netif(net->handle, IPC_IP_TYPE_IPV4);
+ error_code = ipc_ut_check_session(session, net);
+ if (error_code) {
+ utELOG("ipc_find_session_by_netif(): IPC_IP_TYPE_MIXED case mismatched!\r\n");
+ return KAL_FALSE;
+ }
+
+ session = ipc_find_session_by_netif(net->handle, IPC_IP_TYPE_IPV6);
+ error_code = ipc_ut_check_session(session, net);
+ if (error_code) {
+ utELOG("ipc_find_session_by_netif(): IPC_IP_TYPE_MIXED case mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_query_info(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Before any netif attachment, 0 netif is attached */
+ {
+ ipc_query_info_t cnf_query_info;
+ ipc_query_info_t chk_query_info;
+
+ kal_mem_set(&cnf_query_info, 0, sizeof(ipc_query_info_t));
+ kal_mem_set(&chk_query_info, 0, sizeof(ipc_query_info_t));
+
+ ipc_ut_msg_reset(&cnf_query_info, sizeof(ipc_query_info_t), NULL, 0);
+
+ ipc_on_query_info(MOD_IPCORE, NULL);
+
+ if (ipc_ut_msg_chk(MOD_NIL,
+ MOD_IPCORE,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_QUERY_INFO_CNF,
+ 1) != KAL_TRUE) {
+ utELOG("IPCore query reply is failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Information to check */
+ chk_query_info.netif.netif_cnt = 0;
+
+ if (kal_mem_cmp(&(chk_query_info.netif), &(cnf_query_info.netif), sizeof(chk_query_info.netif))) {
+ utELOG("IPCore query reply content is failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* ipc_attach() */
+ {
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* Check status : 1 netif is attached */
+ {
+ ipc_query_info_t cnf_query_info;
+ ipc_query_info_t chk_query_info;
+
+ kal_mem_set(&cnf_query_info, 0, sizeof(ipc_query_info_t));
+ kal_mem_set(&chk_query_info, 0, sizeof(ipc_query_info_t));
+
+ ipc_ut_msg_reset(&cnf_query_info, sizeof(ipc_query_info_t), NULL, 0);
+
+ ipc_on_query_info(MOD_IPCORE, NULL);
+
+ if (ipc_ut_msg_chk(MOD_NIL,
+ MOD_IPCORE,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_QUERY_INFO_CNF,
+ 1) != KAL_TRUE) {
+ utELOG("IPCore query reply is failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Information to check */
+ chk_query_info.netif.netif_cnt = 1;
+ chk_query_info.netif.list[0].netif_id = net->conf.netif_id;
+
+ if (kal_mem_cmp(&(chk_query_info.netif), &(cnf_query_info.netif), sizeof(chk_query_info.netif))) {
+ utELOG("IPCore query reply content is failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Check status : 1 netif is attached */
+ {
+ ipc_query_info_t cnf_query_info;
+ ipc_query_info_t chk_query_info;
+
+ kal_mem_set(&cnf_query_info, 0, sizeof(ipc_query_info_t));
+ kal_mem_set(&chk_query_info, 0, sizeof(ipc_query_info_t));
+
+ ipc_ut_msg_reset(&cnf_query_info, sizeof(ipc_query_info_t), NULL, 0);
+
+ ipc_on_query_info(MOD_IPCORE, NULL);
+
+ if (ipc_ut_msg_chk(MOD_NIL,
+ MOD_IPCORE,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_QUERY_INFO_CNF,
+ 1) != KAL_TRUE) {
+ utELOG("IPCore query reply is failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Information to check */
+ chk_query_info.netif.netif_cnt = 1;
+ chk_query_info.netif.list[0].netif_id = net->conf.netif_id;
+
+ if (kal_mem_cmp(&(chk_query_info.netif), &(cnf_query_info.netif), sizeof(chk_query_info.netif))) {
+ utELOG("IPCore query reply content is failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Check status : 1 netif is attached */
+ {
+ ipc_query_info_t cnf_query_info;
+ ipc_query_info_t chk_query_info;
+
+ kal_mem_set(&cnf_query_info, 0, sizeof(ipc_query_info_t));
+ kal_mem_set(&chk_query_info, 0, sizeof(ipc_query_info_t));
+
+ ipc_ut_msg_reset(&cnf_query_info, sizeof(ipc_query_info_t), NULL, 0);
+
+ ipc_on_query_info(MOD_IPCORE, NULL);
+
+ if (ipc_ut_msg_chk(MOD_NIL,
+ MOD_IPCORE,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_QUERY_INFO_CNF,
+ 1) != KAL_TRUE) {
+ utELOG("IPCore query reply is failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Information to check */
+ chk_query_info.netif.netif_cnt = 1;
+ chk_query_info.netif.list[0].netif_id = net->conf.netif_id;
+
+ if (kal_mem_cmp(&(chk_query_info.netif), &(cnf_query_info.netif), sizeof(chk_query_info.netif))) {
+ utELOG("IPCore query reply content is failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* After all netif detach, 0 netif is attached */
+ {
+ ipc_query_info_t cnf_query_info;
+ ipc_query_info_t chk_query_info;
+
+ kal_mem_set(&cnf_query_info, 0, sizeof(ipc_query_info_t));
+ kal_mem_set(&chk_query_info, 0, sizeof(ipc_query_info_t));
+
+ ipc_ut_msg_reset(&cnf_query_info, sizeof(ipc_query_info_t), NULL, 0);
+
+ ipc_on_query_info(MOD_IPCORE, NULL);
+
+ if (ipc_ut_msg_chk(MOD_NIL,
+ MOD_IPCORE,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_QUERY_INFO_CNF,
+ 1) != KAL_TRUE) {
+ utELOG("IPCore query reply is failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Information to check */
+ chk_query_info.netif.netif_cnt = 0;
+
+ if (kal_mem_cmp(&(chk_query_info.netif), &(cnf_query_info.netif), sizeof(chk_query_info.netif))) {
+ utELOG("IPCore query reply content is failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+ }
+
+
+kal_bool ipc_ut_ul_reload_retry(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint64 netif_bit_ids;
+ ipc_ut_netif_t *net;
+ kal_uint32 idx;
+ kal_uint32 cnt;
+ ipc_netif_t *netif;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Init value test.
+ */
+ netif_bit_ids = ipc_get_all_netif_ul_reload_retry();
+ if (netif_bit_ids) {
+ utELOG("netif_bit_ids is expected to be zero before testing!\r\n");
+ return KAL_FALSE;
+ }
+ ipc_check_ul_reload_retry();
+
+ /*
+ * UL reload retry succeeded case.
+ */
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+ netif = (ipc_netif_t *)(net->handle);
+ net->ul_reload_called = KAL_FALSE;
+
+ ipc_set_netif_ul_reload_retry(net->handle, KAL_TRUE);
+ netif_bit_ids = ipc_get_all_netif_ul_reload_retry();
+ if (netif->bit_id != netif_bit_ids) {
+ utELOG("netif UL reload bit_id(%x) != netif_bit_ids(%x)\r\n", netif->bit_id, netif_bit_ids);
+ return KAL_FALSE;
+ }
+
+ ipc_on_retry_ul_reload();
+ if (KAL_FALSE == net->ul_reload_called) {
+ utELOG("netif UL is not called\r\n");
+ return KAL_FALSE;
+ }
+
+ net->ul_reload_called = KAL_FALSE;
+ ipc_set_netif_ul_reload_retry(net->handle, KAL_FALSE);
+ netif_bit_ids = ipc_get_all_netif_ul_reload_retry();
+ if (0 != netif_bit_ids) {
+ utELOG("netif_bit_ids is expected to be zero!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_on_retry_ul_reload();
+ if (KAL_FALSE != net->ul_reload_called) {
+ utELOG("netif UL shall not called\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /*
+ * UL reload retry failed case.
+ */
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+ netif = (ipc_netif_t *)(net->handle);
+ net->need_retry = KAL_TRUE;
+ net->ul_reload_called = KAL_FALSE;
+
+ ipc_set_netif_ul_reload_retry(net->handle, KAL_TRUE);
+ netif_bit_ids = ipc_get_all_netif_ul_reload_retry();
+ if (0 == (netif_bit_ids & netif->bit_id)) {
+ utELOG("netif_bit_ids(%x) doesn't include bit_id(%x)\r\n", netif_bit_ids, netif->bit_id);
+ return KAL_FALSE;
+ }
+ }
+
+ for (cnt = 0; cnt < 2; cnt++) {
+ ipc_on_retry_ul_reload();
+
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+
+ if (KAL_FALSE == net->ul_reload_called) {
+ utELOG("netif UL is not called\r\n");
+ return KAL_FALSE;
+ }
+ net->ul_reload_called = KAL_FALSE;
+ }
+ }
+
+ for (idx = 0; idx < IPC_UT_MAX_NET_CNT; idx++) {
+ net = &(ipc_ut_nets_s[idx]);
+ net->need_retry = KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_poll_source(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ // init before test
+ ipc_ut_init();
+
+ ipc_on_lte_tick_source(KAL_TRUE);
+ ipc_on_lte_tick_source(KAL_FALSE);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_pdn_bind_deact(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * IPv4 bind negative test.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = IPC_UT_BAD_NETIF_ID;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4_ADDR_TYPE;
+
+ /* Call PDN bind with bad network interface ID "with" source mod = MOD_IPCORE (To trigger Bind response reply) */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_on_pdn_bind_top(MOD_IPCORE, (local_para_struct *)bind_req);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_IPCORE, IPCORE_SAP ,MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 1) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Call PDN bind with bad network interface ID "without" source mod = MOD_IPCORE (To forbid Bind response reply) */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_NIL, IPCORE_SAP ,MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 0) != KAL_TRUE) {
+ utELOG("Bind response is received\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Free bind request */
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * IPv4 deact positive test.
+ */
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+ if (IPC_UT_SESSION_DEACTIVATE_NO_SESSION_FOUND != ipc_ut_get_error()) {
+ utELOG("IPv4 deact postive test returns error(%d)\r\n", ipc_ut_get_error());
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_pdn_ip_info(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_bool result;
+
+ kal_int32 net_ipid;
+
+ kal_uint8 ipv4_valid[4] = {192, 168, 0, 1};
+ kal_uint8 ipv4_invalid[4] = {0, 0, 0, 0};
+ kal_uint8 ipv4_dns_1[4] = {168, 95, 1, 1};
+ kal_uint8 ipv4_dns_2[4] = {140, 113, 1, 1};
+ kal_uint8 ipv6_valid[16] = {0x20, 0x01, 0x0d, 0xd8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+ kal_uint8 ipv6_invalid[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ kal_uint8 ipv6_dns_1[16] = {0x20, 0x01, 0x0d, 0xd8, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+ kal_uint8 ipv6_dns_2[16] = {0x20, 0x01, 0x0d, 0xd8, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
+
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+
+ kal_uint32 ip_type;
+ kal_uint32 ipv4_is_valid;
+ kal_uint32 ipv6_is_valid;
+ kal_uint32 ipv4_dns_cnt;
+ kal_uint32 ipv6_dns_cnt;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (ip_type = 0; ip_type < sizeof(ip_types)/sizeof(ip_types[0]); ip_type ++)
+ for (ipv4_is_valid = 0 ; ipv4_is_valid < 2 ; ipv4_is_valid ++)
+ for (ipv6_is_valid = 0 ; ipv6_is_valid < 2 ; ipv6_is_valid ++)
+ for (ipv4_dns_cnt = 0 ; ipv4_dns_cnt <= 2 ; ipv4_dns_cnt ++)
+ for (ipv6_dns_cnt = 0 ; ipv6_dns_cnt <= 2 ; ipv6_dns_cnt ++) {
+ kal_uint32 dns_idx;
+
+ utDLOG("iptype(%d) v4valid(%d) v6valid(%d) v4dns(%d) v6dns(%d)\r\n",
+ ip_type, ipv4_is_valid, ipv6_is_valid, ipv4_dns_cnt, ipv6_dns_cnt);
+ /*
+ * bind
+ */
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[ip_type];
+
+ kal_mem_cpy(bind_req->ip_addr.ipv4, (ipv4_is_valid)?ipv4_valid:ipv4_invalid, sizeof(bind_req->ip_addr.ipv4));
+ kal_mem_cpy(bind_req->ip_addr.ipv6, (ipv6_is_valid)?ipv6_valid:ipv6_invalid, sizeof(bind_req->ip_addr.ipv6));
+
+ for ( dns_idx = 0 ; dns_idx < ipv4_dns_cnt ; dns_idx ++ ) {
+ bind_req->dns.v4[dns_idx].is_dnsv4_present = KAL_TRUE;
+ kal_mem_cpy(bind_req->dns.v4[dns_idx].dnsv4, (dns_idx == 0)?ipv4_dns_1:ipv4_dns_2, sizeof(bind_req->dns.v4[dns_idx].dnsv4));
+ }
+
+ for ( dns_idx = 0 ; dns_idx < ipv6_dns_cnt ; dns_idx ++ ) {
+ bind_req->dns.v6[dns_idx].is_dnsv6_present = KAL_TRUE;
+ kal_mem_cpy(bind_req->dns.v6[dns_idx].dnsv6, (dns_idx == 0)?ipv6_dns_1:ipv6_dns_2, sizeof(bind_req->dns.v6[dns_idx].dnsv6));
+ }
+
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ net_ipid = ipc_get_ip_id(net->handle);
+
+ /* Check */
+ {
+ kal_uint8 ipv4_chk[4];
+ kal_uint8 ipv4_dns_1_chk[4];
+ kal_uint8 ipv4_dns_2_chk[4];
+ kal_uint8 ipv4_dns_cnt_chk;
+ kal_uint8 ipv6_chk[16];
+ kal_uint8 ipv6_iid_len_chk;
+ kal_uint8 ipv6_dns_1_chk[16];
+ kal_uint8 ipv6_dns_2_chk[16];
+ kal_uint8 ipv6_dns_cnt_chk;
+
+ nmu_get_ip4_ip(net_ipid, ipv4_chk);
+
+ nmu_get_ip4_dns_num(net_ipid, &ipv4_dns_cnt_chk);
+ nmu_get_ip4_dns(net_ipid, 0, ipv4_dns_1_chk);
+ nmu_get_ip4_dns(net_ipid, 1, ipv4_dns_2_chk);
+
+ nmu_get_ip6_iid(net_ipid, ipv6_chk);
+ nmu_get_ip6_iid_len(net_ipid, &ipv6_iid_len_chk);
+ nmu_get_ip6_dns_num(net_ipid, &ipv6_dns_cnt_chk);
+ nmu_get_ip6_dns(net_ipid, 0, ipv6_dns_1_chk);
+ nmu_get_ip6_dns(net_ipid, 1, ipv6_dns_2_chk);
+
+ if ((IPV6_ADDR_TYPE == ip_types[ip_type]) || (IPV4V6_ADDR_TYPE == ip_types[ip_type])) {
+ kal_uint32 idx;
+ if (ipv6_is_valid) {
+ if (kal_mem_cmp(ipv6_chk, ipv6_valid, sizeof(ipv6_chk))) {
+ utELOG("IPv6 IID check error!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ if (((ipv6_is_valid)?IPV6_VALID_IID_BITS:0) != ipv6_iid_len_chk) {
+ utELOG("IPv6 IID length check error!\r\n");
+ return KAL_FALSE;
+ }
+ if (ipv6_dns_cnt_chk != ipv6_dns_cnt) {
+ utELOG("IPv6 DNS count check error!\r\n");
+ return KAL_FALSE;
+ }
+
+ for ( idx = 0 ; idx < ipv6_dns_cnt_chk ; idx ++ ) {
+ if ((idx == 0) && kal_mem_cmp(ipv6_dns_1_chk, ipv6_dns_1, sizeof(ipv6_dns_1_chk))) {
+ utELOG("IPv6 DNS address 1 check error!\r\n");
+ return KAL_FALSE;
+ }
+ if ((idx == 1) && kal_mem_cmp(ipv6_dns_2_chk, ipv6_dns_2, sizeof(ipv6_dns_2_chk))) {
+ utELOG("IPv6 DNS address 2 check error!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ if (nmu_check_ip6_up(net_ipid) != ((ipv6_is_valid)?KAL_TRUE:KAL_FALSE)) {
+ utELOG("nmu_check_ip6_up() check error!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ if ((IPV4_ADDR_TYPE == ip_types[ip_type]) || (IPV4V6_ADDR_TYPE == ip_types[ip_type])) {
+ kal_uint32 idx;
+ if (kal_mem_cmp(ipv4_chk, (ipv4_is_valid)?ipv4_valid:ipv4_invalid, sizeof(ipv4_chk))) {
+ utELOG("IPv4 address check error!\r\n");
+ return KAL_FALSE;
+ }
+ if (ipv4_dns_cnt_chk != ipv4_dns_cnt) {
+ utELOG("IPv4 DNS count check error!\r\n");
+ return KAL_FALSE;
+ }
+
+ for ( idx = 0 ; idx < ipv4_dns_cnt_chk ; idx ++ ) {
+ if ((idx == 0) && kal_mem_cmp(ipv4_dns_1_chk, ipv4_dns_1, sizeof(ipv4_dns_1_chk))) {
+ utELOG("IPv4 DNS address 1 check error!\r\n");
+ return KAL_FALSE;
+ }
+ if ((idx == 1) && kal_mem_cmp(ipv4_dns_2_chk, ipv4_dns_2, sizeof(ipv4_dns_2_chk))) {
+ utELOG("IPv4 DNS address 2 check error!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ if (nmu_check_ip4_up(net_ipid) != ((ipv4_is_valid)?KAL_TRUE:KAL_FALSE)) {
+ utELOG("nmu_check_ip4_up() check error!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* Detach */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Check */
+ {
+ if ((IPV6_ADDR_TYPE == ip_types[ip_type]) || (IPV4V6_ADDR_TYPE == ip_types[ip_type])) {
+ if (nmu_check_ip6_up(net_ipid) != KAL_FALSE) {
+ utELOG("nmu_check_ip6_up() check error!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ if ((IPV4_ADDR_TYPE == ip_types[ip_type]) || (IPV4V6_ADDR_TYPE == ip_types[ip_type])) {
+ if (nmu_check_ip4_up(net_ipid) != KAL_FALSE) {
+ utELOG("nmu_check_ip4_up() check error!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+
+kal_bool ipc_ut_triggered_ul_reload(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ // init before test
+ ipc_ut_init();
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Request for UL GPD reload before PDN binding : It should success
+ */
+ net->need_retry = KAL_FALSE;
+ net->ul_reload_called = KAL_FALSE;
+ ipc_need_ul_reload(net->handle);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (KAL_TRUE != net->ul_reload_called) {
+ utELOG("ipc_need_ul_reload() does not call callback!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Request for UL GPD reload : It should success
+ */
+ net->need_retry = KAL_FALSE;
+ net->ul_reload_called = KAL_FALSE;
+ ipc_need_ul_reload(net->handle);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (KAL_TRUE != net->ul_reload_called) {
+ utELOG("ipc_need_ul_reload() does not call callback!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * Request for UL GPD reload after PDN deactivation : It should success
+ */
+ net->need_retry = KAL_FALSE;
+ net->ul_reload_called = KAL_FALSE;
+ ipc_need_ul_reload(net->handle);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (KAL_TRUE != net->ul_reload_called) {
+ utELOG("ipc_need_ul_reload() does not call callback!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_downlink_wo_dhcp4c(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink(IPC_UT_PDN_ID, head_gpd, tail_gpd);
+
+ if ( (0 != ipc_ut_dl_callback_gpd_cnt) ||
+ (0 != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is forwarded before PDN binding! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Simulate DL traffic to IPCore : All GPDs should be forward to DL callback regardless of IP types (IPv4/IPv6)
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+ kal_uint32 total_cnt;
+ kal_uint32 spd_payload_cnt;
+ kal_uint32 i;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink(IPC_UT_PDN_ID, head_gpd, tail_gpd);
+
+ if (1 == spd) {
+ total_cnt = ipv4_cnt + ipv6_cnt + 1/*spd*/;
+ spd_payload_cnt = ipv4_cnt + ipv6_cnt;
+ if (1 == spd_igr_bit) {
+ kal_uint32 igr_payload_cnt = 0;
+ for (i = 0; i < (ipv4_cnt + ipv6_cnt); i++) {
+ igr_payload_cnt += ipc_ut_spd_packet_igr_s[i];
+ }
+ if ((ipv4_cnt + ipv6_cnt) == igr_payload_cnt) {
+ /* All SPD's payloads has been ignored. */
+ total_cnt--;
+ spd_payload_cnt = 0;
+ } else {
+ spd_payload_cnt -= igr_payload_cnt;
+ }
+ }
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ spd_payload_cnt = 0;
+ }
+
+ if ( (total_cnt != ipc_ut_dl_callback_gpd_cnt) ||
+ (spd_payload_cnt != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is NOT forwarded to bound handler! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+
+ /* DL callback is correctly called : all GPDs are released */
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink(IPC_UT_PDN_ID, head_gpd, tail_gpd);
+
+ if ( (0 != ipc_ut_dl_callback_gpd_cnt) ||
+ (0 != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is forwarded after PDN deactivation! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_downlink_w_dhcp4c(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = IPC_F_DHCP4C;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ utDLOG("@ [Before Bind] uni(%d),align(%d),v4_cnt(%d),v6_cnt(%d)\r\n", unite, alignment, ipv4_cnt, ipv6_cnt);
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink(IPC_UT_PDN_ID, head_gpd, tail_gpd);
+
+ if ( (0 != ipc_ut_dl_callback_gpd_cnt) ||
+ (0 != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is forwarded before PDN binding! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Simulate DL traffic to IPCore
+ *
+ * - 1st IPv4 GPD is IPv4 DHCP packet and will be sent to DHCP4C module
+ * - All other GPDs should be forward to DL callback regardless of IP types (IPv4/IPv6)
+ *
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+ kal_uint32 total_cnt;
+ kal_uint32 spd_payload_cnt;
+ kal_uint32 i;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ utDLOG("@ [Binded] uni(%d),align(%d),v4_cnt(%d),v6_cnt(%d)\r\n", unite, alignment, ipv4_cnt, ipv6_cnt);
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink(IPC_UT_PDN_ID, head_gpd, tail_gpd);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (ipv4_cnt > 0) &&
+ /* DHCPv4 is only enabled for IPv4 related session */
+ ((ip_types[idx] == IPV4_ADDR_TYPE) ||
+ (ip_types[idx] == IPV4V6_ADDR_TYPE)) ) {
+ /* Least 1 IPv4 DHCP packet : this packet will be forwarded to DHCP4C module instead of sending to DL network interface */
+ if (1 == spd) {
+ if ((1 == ipv4_cnt) && (0 == ipv6_cnt)) {
+ total_cnt = 0;
+ spd_payload_cnt = 0;
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt + 1/*spd*/ - 1/*dhcp4c*/;
+ spd_payload_cnt = ipv4_cnt + ipv6_cnt - 1/*dhcp4c*/;
+ if (1 == spd_igr_bit) {
+ /* the first packet would be filtered out, so add the duplicate substration back. */
+ spd_payload_cnt++;
+
+ if (1 == spd_igr_bit) {
+ kal_uint32 igr_payload_cnt = 0;
+ for (i = 0; i < (ipv4_cnt + ipv6_cnt); i++) {
+ igr_payload_cnt += ipc_ut_spd_packet_igr_s[i];
+ }
+ if ((ipv4_cnt + ipv6_cnt) == igr_payload_cnt) {
+ /* All SPD's payloads has been ignored. */
+ total_cnt--;
+ spd_payload_cnt = 0;
+ } else {
+ spd_payload_cnt -= igr_payload_cnt;
+ }
+ }
+ }
+ }
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt - 1/*dhcp4c*/;
+ spd_payload_cnt = 0;
+ }
+ if ( (total_cnt != ipc_ut_dl_callback_gpd_cnt) ||
+ (spd_payload_cnt != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is NOT forwarded to bound handler or DHCP handling is failed! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+ } else {
+ /* All GPDs should be handled by DL network interface */
+ if (1 == spd) {
+ total_cnt = ipv4_cnt + ipv6_cnt + 1/*spd*/;
+ spd_payload_cnt = ipv4_cnt + ipv6_cnt;
+ if (1 == spd_igr_bit) {
+ kal_uint32 igr_payload_cnt = 0;
+ for (i = 0; i < (ipv4_cnt + ipv6_cnt); i++) {
+ igr_payload_cnt += ipc_ut_spd_packet_igr_s[i];
+ }
+ if ((ipv4_cnt + ipv6_cnt) == igr_payload_cnt) {
+ /* All SPD's payloads has been ignored. */
+ total_cnt--;
+ spd_payload_cnt = 0;
+ } else {
+ spd_payload_cnt -= igr_payload_cnt;
+ }
+ }
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ spd_payload_cnt = 0;
+ }
+ if ( (total_cnt != ipc_ut_dl_callback_gpd_cnt) ||
+ (spd_payload_cnt != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is NOT forwarded to bound handler! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+ }
+ /* DL callback or DHCP4C indication are correctly called : all GPDs should be released */
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ utDLOG("@ [Deactivated] uni(%d),align(%d),v4_cnt(%d),v6_cnt(%d)\r\n", unite, alignment, ipv4_cnt, ipv6_cnt);
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink(IPC_UT_PDN_ID, head_gpd, tail_gpd);
+
+ if ( (0 != ipc_ut_dl_callback_gpd_cnt) ||
+ (0 != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is forwarded after PDN deactivation! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+kal_bool ipc_ut_downlink_invalid_packet(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+ kal_uint16 ipv4_pkt_len[IPC_UT_INVALID_PKT_CASE][IPC_UT_INVALID_PKT_CNT] = {{IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, 0, 0, IPC_INVALID_PKT_LEN3},// first invalid & last invalid
+ {0, IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, 0, 0},// first valid & last valid
+ {IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3},// all invalid
+ {0, 0, 0, 0, 0},// all valid
+ {IPC_INVALID_PKT_LEN3, 0, 0, 0, 0}};// first valid
+ kal_uint16 ipv6_pkt_len[IPC_UT_INVALID_PKT_CASE][IPC_UT_INVALID_PKT_CNT] = {{IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, 0, 0, IPC_INVALID_PKT_LEN3},// first invalid & last invalid
+ {0, IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, 0, 0},// first valid & last valid
+ {IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3, IPC_INVALID_PKT_LEN3},// all invalid
+ {0, 0, 0, 0, IPC_INVALID_PKT_LEN3},// last invalid
+ {0, 0, 0, 0, 0}};// all valid
+ kal_uint8 case_cnt, valid_cnt, len_cnt;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Simulate DL traffic to IPCore : All GPDs should be forward to DL callback regardless of IP types (IPv4/IPv6)
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+
+ ipv4_cnt = ipv6_cnt = 5;
+
+ for (case_cnt = 0; case_cnt<IPC_UT_INVALID_PKT_CASE; case_cnt++) {
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,//(unite == 0)?0:10,
+ 0,//alignment,
+ &head_gpd,
+ &tail_gpd,
+ ipv4_pkt_len[case_cnt],
+ ipv6_pkt_len[case_cnt],
+ KAL_FALSE,
+ KAL_FALSE,
+ 0);
+
+ valid_cnt = 0;
+ for (len_cnt = 0; len_cnt<ipv4_cnt ; len_cnt++) {
+ if (ipv4_pkt_len[case_cnt][len_cnt] <= 1500) {
+ valid_cnt++;
+ }
+ }
+ for (len_cnt = 0; len_cnt<ipv6_cnt ; len_cnt++) {
+ if (ipv6_pkt_len[case_cnt][len_cnt] <= 1500) {
+ valid_cnt++;
+ }
+ }
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink(IPC_UT_PDN_ID, head_gpd, tail_gpd);
+
+ if ( (valid_cnt != ipc_ut_dl_callback_gpd_cnt) ) {
+ utELOG("DL GPD is NOT forwarded to bound handler!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+ /* DL callback is correctly called : all GPDs are released */
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+#endif
+
+kal_bool ipc_ut_uplink_filter(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 callback_with_info;
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 ipv4_filter_cnt;
+ kal_uint32 ipv6_filter_cnt;
+ kal_uint32 with_wildcard;
+ kal_uint32 with_bwm;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint8 matched_filter_idx_v6;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 4; ipv4_cnt+=2)
+ for (ipv6_cnt = 0; ipv6_cnt <= 4; ipv6_cnt+=2)
+ for (ipv4_filter_cnt = 0; ipv4_filter_cnt <= 4; ipv4_filter_cnt+=4)
+ for (ipv6_filter_cnt = 0; ipv6_filter_cnt <= 4; ipv6_filter_cnt+=4)
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++)
+ for (with_wildcard = 0; with_wildcard < 2; with_wildcard++)
+ for (with_bwm = 0; with_bwm < 2; with_bwm++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < ipv4_filter_cnt; matched_filter_idx_v4++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < ipv6_filter_cnt; matched_filter_idx_v6++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("ifo(%d) v4Cnt(%d) v6Cnt(%d) v4FltCnt(%d) v6FltCnt(%d) withWC(%d) withBWM(%d) IPType(%d) v4Idx(%d) v6Idx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, ipv4_filter_cnt , ipv6_filter_cnt, with_wildcard, with_bwm, idx, matched_filter_idx_v4, matched_filter_idx_v6);
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+
+ /* Install UL filter for each test loop */
+ ipc_ut_install_ul_filters(callback_with_info, KAL_TRUE, ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm, matched_filter_idx_v4, matched_filter_idx_v6, IPC_UT_NETID_START);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /*
+ * Before activate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN NOT be forwarded to UPCM
+ */
+ {
+ kal_uint32 dhcpv4_idx;
+ kal_uint32 dhcpv6_idx;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ ipc_io_request_t *ior;
+
+ for (dhcpv4_idx = 0 ; ((ipv4_cnt == 0 && dhcpv4_idx == 0) || (dhcpv4_idx < ipv4_cnt)) ; dhcpv4_idx+=2)
+ for (dhcpv6_idx = 0 ; ((ipv6_cnt == 0 && dhcpv6_idx == 0) || (dhcpv6_idx < ipv6_cnt)) ; dhcpv6_idx+=2) {
+ kal_uint32 expected_ul_v4_filter_out_cnt;
+ kal_uint32 expected_ul_v6_filter_out_cnt;
+ kal_uint32 expected_ul_filter_out_cnt;
+
+ utDLOG("@ Before activation : dhcpv4Idx(%d), dhcpv6Idx(%d)\r\n",
+ dhcpv4_idx, dhcpv6_idx);
+
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE,
+ ipv4_cnt, dhcpv4_idx,
+ ipv6_cnt, dhcpv6_idx,
+ &head_gpd, &tail_gpd, &ior);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ ipc_uplink(net->handle, ior);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * 1. If least 1 IPv4 filter rule & 1 IPv4 gpd -> least 1 packet (DHCPv4) will be filtered out
+ * 2. If least 1 IPv6 filter rule & 1 IPv6 gpd -> least 1 packet (DHCPv6) will be filtered out
+ * 3. NO any packet will been forwarded to network before PDN bind
+ */
+ if (with_wildcard) {
+ expected_ul_v4_filter_out_cnt = ipv4_cnt - (((ipv4_cnt > 0) && with_bwm)?1:0);
+ expected_ul_v6_filter_out_cnt = ipv6_cnt - (((ipv6_cnt > 0) && with_bwm)?1:0);
+ } else {
+ expected_ul_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (!with_bwm) )? 1:0;
+ expected_ul_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (!with_bwm) )?1:0;
+ }
+ expected_ul_filter_out_cnt = expected_ul_v4_filter_out_cnt + expected_ul_v6_filter_out_cnt;
+
+ if (callback_with_info && expected_ul_filter_out_cnt > 0) {
+ if (ipc_ut_ul_filter_info.netif_id != net->conf.netif_id) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != ipc_get_ip_id(net->handle)) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_gpd_cnt != expected_ul_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ul_gpd_cnt > 0) {
+ utELOG("GPD is forwarded to network before valid PDN binding!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN
+ *
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * After PDN binding activate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN be forwarded to UPCM
+ */
+ {
+ kal_uint32 dhcpv4_idx;
+ kal_uint32 dhcpv6_idx;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ ipc_io_request_t *ior;
+
+ for (dhcpv4_idx = 0 ; ((ipv4_cnt == 0 && dhcpv4_idx == 0) || (dhcpv4_idx < ipv4_cnt)) ; dhcpv4_idx+=2)
+ for (dhcpv6_idx = 0 ; ((ipv6_cnt == 0 && dhcpv6_idx == 0) || (dhcpv6_idx < ipv6_cnt)) ; dhcpv6_idx+=2) {
+ kal_uint32 expected_ul_v4_filter_out_cnt;
+ kal_uint32 expected_ul_v6_filter_out_cnt;
+ kal_uint32 expected_ul_filter_out_cnt;
+ kal_uint32 expected_ul_cnt;
+
+ utDLOG("@ PDN connected : dhcpv4Idx(%d), dhcpv6Idx(%d)\r\n",
+ dhcpv4_idx, dhcpv6_idx);
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE,
+ ipv4_cnt, dhcpv4_idx,
+ ipv6_cnt, dhcpv6_idx,
+ &head_gpd, &tail_gpd, &ior);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ ipc_uplink(net->handle, ior);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * 1. If least 1 IPv4 filter rule & 1 IPv4 gpd -> least 1 packet (DHCPv4) will be filtered out
+ * 2. If least 1 IPv6 filter rule & 1 IPv6 gpd -> least 1 packet (DHCPv6) will be filtered out
+ * 3. All non-filtered GPDs with matched IP type will been forwarded to network
+ */
+ if (with_wildcard) {
+ expected_ul_v4_filter_out_cnt = ipv4_cnt - (((ipv4_cnt > 0) && with_bwm)?1:0);
+ expected_ul_v6_filter_out_cnt = ipv6_cnt - (((ipv6_cnt > 0) && with_bwm)?1:0);
+ } else {
+ expected_ul_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (!with_bwm) )? 1:0;
+ expected_ul_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (!with_bwm) )?1:0;
+ }
+ expected_ul_filter_out_cnt = expected_ul_v4_filter_out_cnt + expected_ul_v6_filter_out_cnt;
+
+ if (callback_with_info && expected_ul_filter_out_cnt > 0) {
+ if (ipc_ut_ul_filter_info.netif_id != net->conf.netif_id) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != ipc_get_ip_id(net->handle)) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_gpd_cnt != expected_ul_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ expected_ul_cnt = (bind_req->ip_addr.ip_addr_type == IPV4_ADDR_TYPE)?(ipv4_cnt - expected_ul_v4_filter_out_cnt):
+ (bind_req->ip_addr.ip_addr_type == IPV6_ADDR_TYPE)?(ipv6_cnt - expected_ul_v6_filter_out_cnt):
+ ((ipv4_cnt + ipv6_cnt) - (expected_ul_filter_out_cnt));
+
+ if (ipc_ut_ul_gpd_cnt != expected_ul_cnt) {
+ utELOG("GPD is not forwarded to network correctly!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if ((expected_ul_cnt > 0) &&
+ (ipc_ut_ul_pdn_id != bind_req->pdn_id)) {
+ utELOG("GPD is not forwarded to correct network PDN!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * After deactivate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN NOT be forwarded to UPCM
+ */
+ {
+ kal_uint32 dhcpv4_idx;
+ kal_uint32 dhcpv6_idx;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ ipc_io_request_t *ior;
+
+ for (dhcpv4_idx = 0 ; ((ipv4_cnt == 0 && dhcpv4_idx == 0) || (dhcpv4_idx < ipv4_cnt)) ; dhcpv4_idx+=2)
+ for (dhcpv6_idx = 0 ; ((ipv6_cnt == 0 && dhcpv6_idx == 0) || (dhcpv6_idx < ipv6_cnt)) ; dhcpv6_idx+=2) {
+ kal_uint32 expected_ul_v4_filter_out_cnt;
+ kal_uint32 expected_ul_v6_filter_out_cnt;
+ kal_uint32 expected_ul_filter_out_cnt;
+
+ utDLOG("@ After deactivation : dhcpv4Idx(%d), dhcpv6Idx(%d)\r\n",
+ dhcpv4_idx, dhcpv6_idx);
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE,
+ ipv4_cnt, dhcpv4_idx,
+ ipv6_cnt, dhcpv6_idx,
+ &head_gpd, &tail_gpd, &ior);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ ipc_uplink(net->handle, ior);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * 1. If least 1 IPv4 filter rule & 1 IPv4 gpd -> least 1 packet (DHCPv4) will be filtered out
+ * 2. If least 1 IPv6 filter rule & 1 IPv6 gpd -> least 1 packet (DHCPv6) will be filtered out
+ * 3. NO any packet will been forwarded to network after PDN deactivation
+ */
+ if (with_wildcard) {
+ expected_ul_v4_filter_out_cnt = ipv4_cnt - (((ipv4_cnt > 0) && with_bwm)?1:0);
+ expected_ul_v6_filter_out_cnt = ipv6_cnt - (((ipv6_cnt > 0) && with_bwm)?1:0);
+ } else {
+ expected_ul_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (!with_bwm) )? 1:0;
+ expected_ul_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (!with_bwm) )?1:0;
+ }
+ expected_ul_filter_out_cnt = expected_ul_v4_filter_out_cnt + expected_ul_v6_filter_out_cnt;
+
+ if (callback_with_info && expected_ul_filter_out_cnt > 0) {
+ if (ipc_ut_ul_filter_info.netif_id != net->conf.netif_id) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != ipc_get_ip_id(net->handle)) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_gpd_cnt != expected_ul_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ul_gpd_cnt > 0) {
+ utELOG("GPD is forwarded to network before valid PDN binding!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+
+ /* Uninstall UL filters after test procedure */
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_link_notification(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ {
+ kal_uint32 link_update;
+ kal_uint32 is_up;
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Notifiy Link change for attached network interface : Trigger IPCORE to send ILM
+ */
+ for (link_update = 0 ; link_update < 2 ; link_update ++)
+ for (is_up = 0 ; is_up < 2 ; is_up ++)
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ msg_type message_type;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+
+ ipc_notify_link_change(net->conf.netif_id,
+ ip_types[idx],
+ link_update?KAL_TRUE:KAL_FALSE,
+ is_up?KAL_TRUE:KAL_FALSE);
+
+ if (link_update) { /* To update Link status */
+ message_type = is_up ? MSG_ID_IPCORE_LINK_UP_REQ : MSG_ID_IPCORE_LINK_DOWN_REQ;
+ } else { /* To update IP status */
+ message_type = is_up ? MSG_ID_IPCORE_IP_UP_REQ : MSG_ID_IPCORE_IP_DOWN_REQ;
+ }
+
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ message_type,
+ 1) != KAL_TRUE) {
+ utELOG("Link notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /*
+ * Notifiy Link change for non-attached network interface : Trigger nothing
+ */
+ for (link_update = 0 ; link_update < 2 ; link_update ++)
+ for (is_up = 0 ; is_up < 2 ; is_up ++)
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ msg_type message_type;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+
+ ipc_notify_link_change(net->conf.netif_id + 1 /* netif which is not attached to IPCORE */,
+ ip_types[idx],
+ link_update?KAL_TRUE:KAL_FALSE,
+ is_up?KAL_TRUE:KAL_FALSE);
+
+ if (link_update) { /* To update Link status */
+ message_type = is_up ? MSG_ID_IPCORE_LINK_UP_REQ : MSG_ID_IPCORE_LINK_DOWN_REQ;
+ } else { /* To update IP status */
+ message_type = is_up ? MSG_ID_IPCORE_IP_UP_REQ : MSG_ID_IPCORE_IP_DOWN_REQ;
+ }
+
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("Link notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+
+kal_bool ipc_ut_link_status_ind(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ kal_uint32 linkChangeTestIdx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+ kal_int32 orgIlmCnt;
+ kal_int32 ip_id;
+ kal_int32 set_ntfy_module;
+ kal_int32 ntfy_cnt;
+ kal_int32 ntfy_dereg_cnt;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (set_ntfy_module = 0 ; set_ntfy_module < 2 ; set_ntfy_module ++)
+ for (ntfy_cnt = 0 ; ntfy_cnt < IPC_MAX_NTFY_CNT + 2 ; ntfy_cnt ++)
+ for (ntfy_dereg_cnt = 0 ; ntfy_dereg_cnt <= ntfy_cnt ; ntfy_dereg_cnt ++)
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ kal_int32 ntfy_entry_cnt;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ utDLOG("set_ntfy_md %d ntfy_cnt %d ntfy_dereg_cnt %d idx %d\r\n", set_ntfy_module, ntfy_cnt, ntfy_dereg_cnt, idx);
+
+ /*
+ * Configure notification setting
+ */
+ if (set_ntfy_module) {
+ ipc_register_link_up_ind_handler(MOD_IPCORE);
+ } else {
+ ipc_deregister_link_up_ind_handler();
+ }
+
+ ipc_ut_ntfy_reset_info();
+ if (ipc_ut_ntfy_registration(ntfy_cnt) != KAL_TRUE) {
+ utELOG("ipc_ut_ntfy_registration() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ ipc_ut_ntfy_deregistration(KAL_FALSE, ntfy_dereg_cnt, &ntfy_entry_cnt);
+
+ /*
+ * Before any network interface attachment : trigger link change to test original ILM count
+ */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+ ipc_notify_all_netif_link_change(ip_types[idx], KAL_TRUE);
+ orgIlmCnt = ipc_ut_msg_sent._trigger_cnt;
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN
+ * - Link-UP should be called
+ *
+ */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ ip_id = ipc_get_ip_id(net->handle);
+
+ /* LINK-UP */
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_LINK_UP_REQ,
+ 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_LINK_UP_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_UP,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate ALL network interface link change
+ *
+ * 1. totally trigger count should be "orgIlmCnt+1"
+ * 2. totally notification count for specific network interface should same as registered count
+ *
+ */
+ for (linkChangeTestIdx = 0 ; linkChangeTestIdx < 16 ; linkChangeTestIdx ++) {
+ /* Link UP */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ ipc_notify_all_netif_link_change(ip_types[idx], KAL_TRUE);
+
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_LINK_UP_REQ,
+ orgIlmCnt + 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_LINK_UP_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_UP,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Link DOWN */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ ipc_notify_all_netif_link_change(ip_types[idx], KAL_FALSE);
+
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_LINK_DOWN_REQ,
+ orgIlmCnt + 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_LINK_DOWN_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_DOWN,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_DOWN notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* Notify Link UP */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ ipc_notify_all_netif_link_change(ip_types[idx], KAL_TRUE);
+
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_LINK_UP_REQ,
+ orgIlmCnt + 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_LINK_UP_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_UP,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* LINK-DOWN */
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_LINK_DOWN_REQ,
+ 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_LINK_DOWN_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_DOWN,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_DOWN notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Always deregister all notification entries */
+ ipc_ut_ntfy_deregistration(KAL_TRUE, 0, NULL);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ipv4_status_ind(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipc_session_t *session;
+ kal_int32 ip_id;
+ kal_uint8 dhcp4c_id;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+ kal_int32 set_ntfy_module;
+ kal_int32 ntfy_cnt;
+ kal_int32 ntfy_dereg_cnt;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (set_ntfy_module = 0 ; set_ntfy_module < 2 ; set_ntfy_module ++)
+ for (ntfy_cnt = 0 ; ntfy_cnt < IPC_MAX_NTFY_CNT + 2 ; ntfy_cnt ++)
+ for (ntfy_dereg_cnt = 0 ; ntfy_dereg_cnt <= ntfy_cnt ; ntfy_dereg_cnt ++)
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ kal_int32 ntfy_entry_cnt;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ utDLOG("set_ntfy_md %d ntfy_cnt %d ntfy_dereg_cnt: %d idx %d\r\n", set_ntfy_module, ntfy_cnt, ntfy_dereg_cnt, idx);
+
+ /*
+ * Configure notification setting
+ */
+ if (set_ntfy_module) {
+ ipc_register_ip_up_ind_handler(MOD_IPCORE);
+ } else {
+ ipc_deregister_ip_up_ind_handler();
+ }
+
+ ipc_ut_ntfy_reset_info();
+ if (ipc_ut_ntfy_registration(ntfy_cnt) != KAL_TRUE) {
+ utELOG("ipc_ut_ntfy_registration() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ ipc_ut_ntfy_deregistration(KAL_FALSE, ntfy_dereg_cnt, &ntfy_entry_cnt);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = IPC_F_DHCP4C;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Get session */
+ session = ipc_find_session_by_context(IPC_UT_PDN_ID);
+ if (!session) {
+ utELOG("no session found!\r\n");
+ return KAL_FALSE;
+ }
+ dhcp4c_id = session->dhcp4c_id;
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ ip_id = ipc_get_ip_id(net->handle);
+
+ if ( (ip_types[idx] == IPV4_ADDR_TYPE) ||
+ (ip_types[idx] == IPV4V6_ADDR_TYPE)) {
+ /* DHCP4c only activated in IPv4 related types */
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_LINK_UP_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_UP,
+ net->conf.netif_id,
+ ip_id,
+ 0) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ } else { /* For IPv6 only type, Link UP directly */
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_LINK_UP_REQ,
+ 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_LINK_UP_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_UP,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+
+ /*
+ * Simulate IP-up/down indication from DHCP4c are called
+ *
+ * 1. 1st IP-UP notification : trigger Link-up indication
+ * 2. IP-DOWN notification : trigger IP-down indication
+ * 3. IP-UP notification : trigger IP-UP indication
+ *
+ */
+ {
+ kal_uint32 cnt;
+ dhcp4c_ip_up_ind_struct ip_up_ind;
+ dhcp4c_ip_down_ind_struct ip_down_ind;
+
+ /* 1st IP-UP : Link UP */
+ {
+ ip_up_ind.ip_id = ip_id;
+ ip_up_ind.dhcp_id = dhcp4c_id;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ ipc_on_dhcp4c_ip_up_ind((void*)&ip_up_ind);
+
+
+ if ( (ip_types[idx] == IPV4_ADDR_TYPE) ||
+ (ip_types[idx] == IPV4V6_ADDR_TYPE)) {
+ /* DHCP4c only activated in IPv4 related types */
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_LINK_UP_REQ,
+ 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_LINK_UP_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_UP,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("DHCP4c still works in IPv6 PDN : check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_UP,
+ net->conf.netif_id,
+ ip_id,
+ 0) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* After 1st IP-UP: Link UP/DOWN will be forwarded to corresponding network interface */
+ for ( cnt = 0 ; cnt < 16 ; cnt ++ ) {
+ /* IP DOWN */
+ {
+ ip_down_ind.ip_id = ip_id;
+ ip_down_ind.dhcp_id = dhcp4c_id;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ ipc_on_dhcp4c_ip_down_ind((void*)&ip_down_ind);
+
+ if ( (ip_types[idx] == IPV4_ADDR_TYPE) ||
+ (ip_types[idx] == IPV4V6_ADDR_TYPE)) {
+ /* DHCP4c only activated in IPv4 related types */
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_IP_DOWN_REQ,
+ 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_IP_DOWN_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_IP_DOWN,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_IP_DOWN notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("DHCP4c still works in IPv6 PDN : check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_IP_DOWN,
+ net->conf.netif_id,
+ ip_id,
+ 0) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_IP_DOWN notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* IP UP */
+ {
+ ip_up_ind.ip_id = ip_id;
+ ip_up_ind.dhcp_id = dhcp4c_id;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_ntfy_reset_param();
+
+ ipc_on_dhcp4c_ip_up_ind((void*)&ip_up_ind);
+
+ if ( (ip_types[idx] == IPV4_ADDR_TYPE) ||
+ (ip_types[idx] == IPV4V6_ADDR_TYPE)) {
+ /* DHCP4c only activated in IPv4 related types */
+ if (ipc_ut_msg_chk( MOD_IPCORE,
+ net->conf.module_id,
+ IPCORE_SAP,
+ MSG_ID_IPCORE_IP_UP_REQ,
+ 1) != KAL_TRUE) {
+ utELOG("MSG_ID_IPCORE_IP_UP_REQ check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_IP_UP,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_IP_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("DHCP4c still works in IPv6 PDN : check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_IP_UP,
+ net->conf.netif_id,
+ ip_id,
+ 0) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_IP_UP notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ if (ipc_ut_ntfy_chk_param( IPC_NTFY_TYPE_LINK_DOWN,
+ net->conf.netif_id,
+ ip_id,
+ ntfy_entry_cnt) != KAL_TRUE) {
+ utELOG("IPC_NTFY_TYPE_LINK_DOWN notification check failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate IP-up/down indication from DHCP4c are called
+ *
+ * - After deactivation, No any notification should be triggered
+ *
+ */
+ {
+ dhcp4c_ip_up_ind_struct ip_up_ind;
+ dhcp4c_ip_down_ind_struct ip_down_ind;
+
+ /* IP DOWN */
+ {
+ ip_down_ind.ip_id = ip_id;
+ ip_down_ind.dhcp_id = dhcp4c_id;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_on_dhcp4c_ip_down_ind((void*)&ip_down_ind);
+
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("[IP DOWN notification handling after deactivation] check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* IP UP */
+ {
+ ip_up_ind.ip_id = ip_id;
+ ip_up_ind.dhcp_id = dhcp4c_id;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_on_dhcp4c_ip_up_ind((void*)&ip_up_ind);
+
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("[IP UP notification handling after deactivation] check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate IP-up/down indication from DHCP4c are called
+ *
+ * - After detach, No any notification should be triggered
+ *
+ */
+ {
+ dhcp4c_ip_up_ind_struct ip_up_ind;
+ dhcp4c_ip_down_ind_struct ip_down_ind;
+
+ /* IP DOWN */
+ {
+ ip_down_ind.ip_id = ip_id;
+ ip_down_ind.dhcp_id = dhcp4c_id;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_on_dhcp4c_ip_down_ind((void*)&ip_down_ind);
+
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("[IP DOWN notification handling after detach] check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* IP UP */
+ {
+ ip_up_ind.ip_id = ip_id;
+ ip_up_ind.dhcp_id = dhcp4c_id;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_on_dhcp4c_ip_up_ind((void*)&ip_up_ind);
+
+ if (ipc_ut_msg_chk( 0,
+ 0,
+ 0,
+ 0,
+ 0) != KAL_TRUE) {
+ utELOG("[IP UP notification handling after detach] check failed!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* Always deregister all notification entries */
+ ipc_ut_ntfy_deregistration(KAL_TRUE, 0, NULL);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_en_dhcp4c_unspecified_addr(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipc_session_t *session;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach() with IPC_F_DHCP4C
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = IPC_F_DHCP4C;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ session = ipc_find_session_by_context(IPC_UT_PDN_ID);
+ if (!session) {
+ utELOG("no session found!\r\n");
+ return KAL_FALSE;
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /*
+ * Check downlink filter and DHCPv4 client ID's.
+ */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (IPV4_ADDR_TYPE == ip_types[idx] || IPV4V6_ADDR_TYPE == ip_types[idx]) {
+ if (0 > session->dhcp4c_dl_filter_id) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ utELOG("Downlink filter for DHCPv4 is not installed!\r\n");
+ return KAL_FALSE;
+ }
+ if (!session->dhcp4c_running) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ utELOG("DHCPv4 client is not running!\r\n");
+ return KAL_FALSE;
+ }
+ } else {
+ if (0 <= session->dhcp4c_dl_filter_id) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ utELOG("Downlink filter for DHCPv4 shall not be installed!\r\n");
+ return KAL_FALSE;
+ }
+ if (session->dhcp4c_running) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ utELOG("DHCPv4 client shall not be running!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_en_dhcp4c_valid_addr(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipc_session_t *session;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE};
+ kal_bool result;
+ kal_uint8 valid_ipv4_addr[] = {192, 168, 0, 1};
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach() with IPC_F_DHCP4C
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = IPC_F_DHCP4C;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Activate IPv4/IPv4v6 PDN with valid IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ IPC_CP_V4_ADDR(bind_req->ip_addr.ipv4, valid_ipv4_addr);
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ session = ipc_find_session_by_context(IPC_UT_PDN_ID);
+ if (!session) {
+ utELOG("no session found!\r\n");
+ return KAL_FALSE;
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /*
+ * Check downlink filter and DHCPv4 client ID's.
+ */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (0 <= session->dhcp4c_dl_filter_id) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ utELOG("Downlink filter for DHCPv4 shall not be installed!\r\n");
+ return KAL_FALSE;
+ }
+ if (session->dhcp4c_running) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ utELOG("DHCPv4 client shall not be running!\r\n");
+ return KAL_FALSE;
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dis_dhcp4c_unspecified_addr(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipc_session_t *session;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach() without IPC_F_DHCP4C
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+ session = ipc_find_session_by_context(IPC_UT_PDN_ID);
+ if (!session) {
+ utELOG("no session found!\r\n");
+ return KAL_FALSE;
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /*
+ * Check downlink filter and DHCPv4 client ID's.
+ */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ IPC_R_LOCK_OBJECT(session, ipc_spinlock_g);
+ if (0 <= session->dhcp4c_dl_filter_id) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ utELOG("Downlink filter for DHCPv4 shall not be installed!\r\n");
+ return KAL_FALSE;
+ }
+ if (session->dhcp4c_running) {
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+ utELOG("DHCPv4 client shall not be running!\r\n");
+ return KAL_FALSE;
+ }
+ IPC_R_UNLOCK_OBJECT(session, ipc_spinlock_g);
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ul_filter_none(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 session_type;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ ipc_ut_reset_ul_filter_info();
+ ipc_ut_prepare_ul_gpd_list(KAL_FALSE, ipv4_cnt, 0, ipv6_cnt, 0, &head_gpd, &tail_gpd, NULL);
+
+ if (NULL == head_gpd || NULL == tail_gpd) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+ ipc_do_ul_filter(session_type, IPC_UT_NETID_START, &head_gpd, &tail_gpd);
+
+ if (ipc_ut_ul_filter_id >= 0) {
+ utELOG("No filter test case failed (Filter ID is configured)!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+
+ if (NULL != ipc_ut_ul_head_gpd ||
+ NULL != ipc_ut_ul_tail_gpd ||
+ ipc_ut_ul_filter_gpd_cnt != 0 ||
+ (ipv4_cnt + ipv6_cnt) != ipc_ut_gpd_list_count(head_gpd, tail_gpd)) {
+ utELOG("No filter test case failed!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_filter_none(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 session_type;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+ kal_uint32 total_cnt;
+ kal_uint32 spd_payload_cnt;
+ kal_uint32 i;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+ ipc_do_dl_filter(session_type, IPC_UT_NETID_START, IPC_UT_PDN_ID, &head_gpd, &tail_gpd);
+
+ if (ipc_ut_dl_filter_id >= 0) {
+ utELOG("No filter test case failed (Filter ID is configured)! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+
+ if (1 == spd) {
+ total_cnt = ipv4_cnt + ipv6_cnt + 1;
+ spd_payload_cnt = ipv4_cnt + ipv6_cnt;
+ if (1 == spd_igr_bit) {
+ kal_uint32 igr_payload_cnt = 0;
+ for (i = 0; i < (ipv4_cnt + ipv6_cnt); i++) {
+ igr_payload_cnt += ipc_ut_spd_packet_igr_s[i];
+ }
+ if ((ipv4_cnt + ipv6_cnt) == igr_payload_cnt) {
+ /* All SPD's payloads has been ignored. */
+ total_cnt--;
+ spd_payload_cnt = 0;
+ } else {
+ spd_payload_cnt -= igr_payload_cnt;
+ }
+ }
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ spd_payload_cnt = 0;
+ }
+
+ if (NULL != ipc_ut_dl_head_gpd ||
+ NULL != ipc_ut_dl_tail_gpd ||
+ (0 != ipc_ut_dl_filter_gpd_cnt) ||
+ (total_cnt != ipc_ut_gpd_list_count(head_gpd, tail_gpd)) ||
+ (spd_payload_cnt != ipc_ut_spd_payload_count(head_gpd, tail_gpd)) ) {
+ utELOG("No filter test case failed! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ul_filter_ipv4(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 callback_with_info;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 filter_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 session_type;
+ kal_uint8 matched_filter_idx_v4;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * (#ipv4 packets, #ipv6 packets, #ipv4 filters, #ipv6 filters)=(1-16, 0-3, 1-3, 0),
+ * where one of IPv4 GPD's is DHCP packet and one of IPv4 filters is DHCP
+ * => only one GPD matched.
+ */
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 1; ipv4_cnt <= 16; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (filter_cnt = 1; filter_cnt < 4; filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < filter_cnt; matched_filter_idx_v4++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ ipc_ut_install_ul_filters(callback_with_info, KAL_TRUE, filter_cnt, 0, KAL_FALSE, KAL_FALSE, matched_filter_idx_v4, 0, IPC_UT_NETID_START);
+
+ ipc_ut_reset_ul_filter_info();
+ ipc_ut_prepare_ul_gpd_list(KAL_FALSE, ipv4_cnt, ipv4_cnt-1, ipv6_cnt, 0, &head_gpd, &tail_gpd, NULL);
+
+ if (NULL == head_gpd || NULL == tail_gpd) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+ ipc_do_ul_filter(session_type, IPC_UT_NETID_START, &head_gpd, &tail_gpd);
+
+ if (callback_with_info) {
+ if (ipc_ut_ul_filter_info.netif_id != IPC_UT_NETID_START) {
+ utELOG("IPv4 filter test case failed! (netif_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("IPv4 filter test case failed! (ip_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("IPv4 filter test case failed! (netif_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("IPv4 filter test case failed! (ip_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_id != matched_filter_idx_v4) {
+ utELOG("IPv4 filter test case failed! (Filter ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ if (NULL == ipc_ut_ul_head_gpd ||
+ NULL == ipc_ut_ul_tail_gpd ||
+ ipc_ut_ul_head_gpd != ipc_ut_ul_tail_gpd ||
+ ipc_ut_ul_filter_gpd_cnt != 1 ||
+ (ipv4_cnt + ipv6_cnt - 1) != ipc_ut_gpd_list_count(head_gpd, tail_gpd)) {
+ utELOG("IPv4 filter test case failed!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_filter_ipv4(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 callback_with_info;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 filter_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 session_type;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint32 spd;
+ kal_uint32 spd_position;
+ kal_uint32 total_cnt;
+ kal_uint32 spd_payload_cnt;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * (#ipv4 packets, #ipv6 packets, #ipv4 filters, #ipv6 filters)=(1-16, 0-3, 1-3, 0),
+ * where one of IPv4 GPD's is DHCP packet and one of IPv4 filters is DHCP
+ * => only one GPD matched.
+ */
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 1; ipv4_cnt <= 16; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (filter_cnt = 1; filter_cnt < 4; filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < filter_cnt; matched_filter_idx_v4++)
+ for (spd = 0; spd < 1; spd++)
+// for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && 0 < spd_position) continue;
+
+ ipc_ut_install_dl_filters(callback_with_info, KAL_TRUE, filter_cnt, 0, matched_filter_idx_v4, 0, IPC_UT_NETID_START);
+
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ ipv4_cnt-1,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE, KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ KAL_FALSE,
+ spd_position);
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+ ipc_do_dl_filter(session_type, IPC_UT_NETID_START, IPC_UT_PDN_ID, &head_gpd, &tail_gpd);
+
+ if (callback_with_info) {
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_NETID_START) {
+ utELOG("IPv4 filter test case failed! (NetIF ID match fail) (SPD:%d)\r\n", spd);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_dl_filter_info.netif_id != 0) {
+ utELOG("IPv4 filter test case failed! (NetIF ID match fail) (SPD:%d)\r\n", spd);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_dl_filter_id != matched_filter_idx_v4) {
+ utELOG("IPv4 filter test case failed! (Filter ID match fail) (SPD:%d)\r\n", spd);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+
+ if (1 == spd) {
+ if ((1 == ipv4_cnt) && (0 == ipv6_cnt)) {
+ /* Only ipv4 DHCP packet left, so there is no SPD */
+ total_cnt = ipv4_cnt + ipv6_cnt - 1;
+ spd_payload_cnt = 0;
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt - ipc_ut_dl_filter_expect_gpd_cnt/*dhcp4c*/ + 1/*spd*/;
+ spd_payload_cnt = ipv4_cnt + ipv6_cnt - ipc_ut_dl_filter_expect_gpd_cnt/*dhcp4c*/;
+ }
+ if (NULL == ipc_ut_dl_head_gpd ||
+ NULL == ipc_ut_dl_tail_gpd ||
+ ipc_ut_dl_filter_expect_gpd_cnt*2 != ipc_ut_dl_filter_gpd_cnt ||
+ total_cnt != ipc_ut_gpd_list_count(head_gpd, tail_gpd) ||
+ spd_payload_cnt != ipc_ut_spd_payload_count(head_gpd, tail_gpd) ) {
+ utELOG("IPv4 filter test case failed! (with SPD)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ } else {
+ if (NULL == ipc_ut_dl_head_gpd ||
+ NULL == ipc_ut_dl_tail_gpd ||
+ //ipc_ut_dl_head_gpd != ipc_ut_dl_tail_gpd ||
+ ipc_ut_dl_filter_expect_gpd_cnt != ipc_ut_dl_filter_gpd_cnt ||
+ (ipv4_cnt + ipv6_cnt - ipc_ut_dl_filter_expect_gpd_cnt) != ipc_ut_gpd_list_count(head_gpd, tail_gpd) ||
+ 0 != ipc_ut_spd_payload_count(head_gpd, tail_gpd) ) {
+ utELOG("IPv4 filter test case failed!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ }
+ ipc_ut_install_netif_filter(IPC_UT_NETID_START);
+
+ for (ipv4_cnt = 1; ipv4_cnt <= 16; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ {
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ ipv4_cnt-1,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE, KAL_FALSE,
+ 0,
+ 0,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ 0,
+ KAL_FALSE,
+ 0);
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+
+ ipc_do_dl_filter(session_type, IPC_UT_NETID_START, IPC_UT_PDN_ID, &head_gpd, &tail_gpd);
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_NETID_START) {
+ utELOG("IPv4 filter test case failed! (NetIF ID match fail) (SPD:%d)\r\n", spd);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_id != 0) {
+ utELOG("IPv4 filter test case failed! (Filter ID match fail) (SPD:%d)\r\n", spd);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+
+ }
+
+ ipc_ut_uninstall_netif_filter();
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ul_filter_ipv6(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 callback_with_info;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 filter_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 session_type;
+ kal_uint8 matched_filter_idx_v6;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * (#ipv4 packets, #ipv6 packets, #ipv4 filters, #ipv6 filters)=(0-3, 1-16, 0, 1-3),
+ * where one of IPv4 GPD's is DHCP packet and one of IPv4 filters is DHCP
+ * => only one GPD matched.
+ */
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 1; ipv6_cnt <= 16; ipv6_cnt++)
+ for (filter_cnt = 1; filter_cnt < 4; filter_cnt++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < filter_cnt; matched_filter_idx_v6++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("if(%d) 4Ct(%d) 6Ct(%d) fCt(%d) fIdx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, filter_cnt, matched_filter_idx_v6);
+
+ ipc_ut_install_ul_filters(callback_with_info, KAL_TRUE, 0, filter_cnt, KAL_FALSE, KAL_FALSE, 0, matched_filter_idx_v6, IPC_UT_NETID_START);
+
+ ipc_ut_reset_ul_filter_info();
+ ipc_ut_prepare_ul_gpd_list(KAL_FALSE, ipv4_cnt, 0, ipv6_cnt, ipv6_cnt-1, &head_gpd, &tail_gpd, NULL);
+
+ if (NULL == head_gpd || NULL == tail_gpd) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+ ipc_do_ul_filter(session_type, IPC_UT_NETID_START, &head_gpd, &tail_gpd);
+
+ if (callback_with_info) {
+ if (ipc_ut_ul_filter_info.netif_id != IPC_UT_NETID_START) {
+ utELOG("IPv6 filter test case failed! (netif_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(0, filter_cnt, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("IPv6 filter test case failed! (ip_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(0, filter_cnt, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("IPv6 filter test case failed! (netif_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(0, filter_cnt, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("IPv6 filter test case failed! (ip_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(0, filter_cnt, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_id != matched_filter_idx_v6) {
+ utELOG("IPv6 filter test case failed! (Filter ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(0, filter_cnt, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ if (NULL == ipc_ut_ul_head_gpd ||
+ NULL == ipc_ut_ul_tail_gpd ||
+ ipc_ut_ul_head_gpd != ipc_ut_ul_tail_gpd ||
+ ipc_ut_ul_filter_gpd_cnt != 1 ||
+ (ipv4_cnt + ipv6_cnt - 1) != ipc_ut_gpd_list_count(head_gpd, tail_gpd)) {
+ utELOG("IPv6 filter test case failed!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(0, filter_cnt, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(0, filter_cnt, KAL_FALSE, KAL_FALSE);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_filter_ipv6(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 callback_with_info;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 filter_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 session_type;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint8 matched_filter_idx_v6;
+ kal_uint32 spd;
+ kal_uint32 spd_position;
+ kal_uint32 total_cnt;
+ kal_uint32 spd_payload_cnt;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * (#ipv4 packets, #ipv6 packets, #ipv4 filters, #ipv6 filters)=(0-3, 1-16, 0, 1-3),
+ * where one of IPv6 GPD's is DHCP packet and one of IPv6 filters is DHCP
+ * => only one GPD matched.
+ */
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (callback_with_info = 0 ; callback_with_info < 2; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 1; ipv6_cnt <= 16; ipv6_cnt++)
+ for (filter_cnt = 1; filter_cnt < 4; filter_cnt++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < filter_cnt; matched_filter_idx_v6++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && 0 < spd_position) continue;
+
+ utDLOG("un(%d) al(%d) if(%d) 4Ct(%d) 6Ct(%d) fCt(%d) fIdx(%d)\r\n",
+ unite, alignment, callback_with_info, ipv4_cnt, ipv6_cnt, filter_cnt, matched_filter_idx_v6);
+
+ ipc_ut_install_dl_filters(callback_with_info, KAL_TRUE, 0, filter_cnt, 0, matched_filter_idx_v6, IPC_UT_NETID_START);
+
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ ipv6_cnt-1,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,&tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ KAL_FALSE,
+ spd_position);
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+ ipc_do_dl_filter(session_type, IPC_UT_NETID_START, IPC_UT_PDN_ID, &head_gpd, &tail_gpd);
+
+ if (callback_with_info) {
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_NETID_START) {
+ utELOG("IPv6 filter test case failed! (NetIF ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(0, filter_cnt);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_dl_filter_info.netif_id != 0) {
+ utELOG("IPv6 filter test case failed! (NetIF ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(0, filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_dl_filter_id != matched_filter_idx_v6) {
+ utELOG("IPv6 filter test case failed! (Filter ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(0, filter_cnt);
+ return KAL_FALSE;
+ }
+
+ if (1 == spd) {
+ if ((0 == ipv4_cnt) && (1 == ipv6_cnt)) {
+ /* Only ipv6 DHCP packet left, so there is no SPD */
+ total_cnt = ipv4_cnt + ipv6_cnt - 1;
+ spd_payload_cnt = 0;
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt - 1/*dhcp*/ + 1/*spd*/;
+ spd_payload_cnt = ipv4_cnt + ipv6_cnt - 1/*dhcp*/;
+ }
+ if (NULL == ipc_ut_dl_head_gpd ||
+ NULL == ipc_ut_dl_tail_gpd ||
+ 2 != ipc_ut_dl_filter_gpd_cnt ||
+ total_cnt != ipc_ut_gpd_list_count(head_gpd, tail_gpd) ||
+ spd_payload_cnt != ipc_ut_spd_payload_count(head_gpd, tail_gpd) ) {
+ utELOG("IPv6 filter test case failed! (with SPD)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ } else {
+ if (NULL == ipc_ut_dl_head_gpd ||
+ NULL == ipc_ut_dl_tail_gpd ||
+ ipc_ut_dl_head_gpd != ipc_ut_dl_tail_gpd ||
+ 1 != ipc_ut_dl_filter_gpd_cnt ||
+ (ipv4_cnt + ipv6_cnt - 1) != ipc_ut_gpd_list_count(head_gpd, tail_gpd) ||
+ 0 != ipc_ut_spd_payload_count(head_gpd, tail_gpd) ) {
+ utELOG("IPv6 filter test case failed!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(0, filter_cnt);
+ }
+ ipc_ut_install_netif_filter(IPC_UT_NETID_START);
+
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 1; ipv6_cnt <= 16; ipv6_cnt++) {
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ ipv6_cnt-1,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ 0,
+ &head_gpd,&tail_gpd,
+ NULL,
+ NULL,
+ 0,
+ KAL_FALSE,
+ 0);
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+ ipc_do_dl_filter(session_type, IPC_UT_NETID_START, IPC_UT_PDN_ID, &head_gpd, &tail_gpd);
+
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_NETID_START) {
+ utELOG("IPv4 filter test case failed! (NetIF ID match fail) (SPD:%d)\r\n", spd);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_id != 0) {
+ utELOG("IPv4 filter test case failed! (Filter ID match fail) (SPD:%d)\r\n", spd);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+
+ }
+
+ ipc_ut_uninstall_netif_filter();
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ul_filter_and_forward_msg(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 callback_with_info;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 filter_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 session_type;
+ kal_uint8 matched_filter_idx_v4;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * (#ipv4 packets, #ipv6 packets, #ipv4 filters, #ipv6 filters)=(3, 0-3, 1-3, 0),
+ * where one of IPv4 GPD's is DHCP packet and one of IPv4 filters is DHCP
+ * => only one GPD matched.
+ */
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 1; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (filter_cnt = 1; filter_cnt < 4; filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < filter_cnt; matched_filter_idx_v4++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("if(%d) 4Cnt(%d) 6Cnt(%d) fCnt(%d) fIdx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, filter_cnt, matched_filter_idx_v4);
+
+ ipc_ut_install_ul_filters(callback_with_info, KAL_FALSE, filter_cnt, 0, KAL_FALSE, KAL_FALSE, matched_filter_idx_v4, 0, IPC_UT_NETID_START);
+
+ ipc_ut_reset_ul_filter_info();
+ ipc_ut_prepare_ul_gpd_list(KAL_FALSE,
+ ipv4_cnt,
+ ipv4_cnt-1,
+ ipv6_cnt,
+ 0,
+ &head_gpd,
+ &tail_gpd,
+ NULL);
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+ ipc_do_ul_filter(session_type, IPC_UT_NETID_START, &head_gpd, &tail_gpd);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (callback_with_info) {
+ if (ipc_ut_ul_filter_info.netif_id != IPC_UT_NETID_START) {
+ utELOG("IPv4 filter (MSG) test case failed! (netif_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("IPv4 filter (MSG) test case failed! (ip_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("IPv4 filter (MSG) test case failed! (netif_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("IPv4 filter (MSG) test case failed! (ip_id match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_id != matched_filter_idx_v4) {
+ utELOG("IPv4 filter (MSG) test case failed! (Filter ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ if (NULL == ipc_ut_ul_head_gpd ||
+ NULL == ipc_ut_ul_tail_gpd ||
+ ipc_ut_ul_head_gpd != ipc_ut_ul_tail_gpd ||
+ ipc_ut_ul_filter_gpd_cnt != 1 ||
+ (ipv4_cnt + ipv6_cnt - 1) != ipc_ut_gpd_list_count(head_gpd, tail_gpd)) {
+ utELOG("IPv4 filter (MSG) test case failed!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_ul_filters(filter_cnt, 0, KAL_FALSE, KAL_FALSE);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_filter_and_forward_msg(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 callback_with_info;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 filter_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 session_type;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint32 spd;
+ kal_uint32 spd_position;
+ kal_uint32 total_cnt;
+ kal_uint32 spd_payload_cnt;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * (#ipv4 packets, #ipv6 packets, #ipv4 filters, #ipv6 filters)=(3, 0-3, 1-3, 0),
+ * where one of IPv4 GPD's is DHCP packet and one of IPv4 filters is DHCP
+ * => only one GPD matched.
+ */
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 1; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (filter_cnt = 1; filter_cnt < 4; filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < filter_cnt; matched_filter_idx_v4++)
+ for (spd = 0; spd < 1; spd++)
+// for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && 0 < spd_position) continue;
+
+ utDLOG("ui(%d) if(%d) ai(%d) 4Cnt(%d) 6Cnt(%d) fCnt(%d) fIdx(%d)\r\n",
+ unite, callback_with_info, alignment, ipv4_cnt, ipv6_cnt, filter_cnt, matched_filter_idx_v4);
+
+ ipc_ut_install_dl_filters(callback_with_info, KAL_FALSE, filter_cnt, 0, matched_filter_idx_v4, 0, IPC_UT_NETID_START);
+
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ ipv4_cnt-1,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ KAL_FALSE,
+ spd_position);
+
+ session_type = ( (0 == ipv4_cnt) ? IPC_IP_TYPE_IPV6 :
+ ((0 == ipv6_cnt) ? IPC_IP_TYPE_IPV4 :
+ IPC_IP_TYPE_MIXED) );
+
+ ipc_do_dl_filter(session_type, IPC_UT_NETID_START, IPC_UT_PDN_ID, &head_gpd, &tail_gpd);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (callback_with_info) {
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_NETID_START) {
+ utELOG("IPv4 filter (MSG) test case failed! (NetIF ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_dl_filter_info.netif_id != 0) {
+ utELOG("IPv4 filter test (MSG) case failed! (NetIF ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_dl_filter_id != matched_filter_idx_v4) {
+ utELOG("IPv4 filter (MSG) test case failed! (Filter ID match fail)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+
+ if (1 == spd) {
+ if ((1 == ipv4_cnt) && (0 == ipv6_cnt)) {
+ /* Only ipv4 DHCP packet left, so there is no SPD */
+ total_cnt = ipv4_cnt + ipv6_cnt - 1;
+ spd_payload_cnt = 0;
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt - 1/*dhcp*/ + 1/*spd*/;
+ spd_payload_cnt = ipv4_cnt + ipv6_cnt - 1/*dhcp*/;
+ }
+ if (NULL == ipc_ut_dl_head_gpd ||
+ NULL == ipc_ut_dl_tail_gpd ||
+ 2 != ipc_ut_dl_filter_gpd_cnt ||
+ total_cnt != ipc_ut_gpd_list_count(head_gpd, tail_gpd) ||
+ spd_payload_cnt != ipc_ut_spd_payload_count(head_gpd, tail_gpd) ) {
+ utELOG("IPv4 filter (MSG) test case failed! (with SPD)\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ } else {
+ if (NULL == ipc_ut_dl_head_gpd ||
+ NULL == ipc_ut_dl_tail_gpd ||
+ ipc_ut_dl_head_gpd != ipc_ut_dl_tail_gpd ||
+ 1 != ipc_ut_dl_filter_gpd_cnt ||
+ (ipv4_cnt + ipv6_cnt - 1) != ipc_ut_gpd_list_count(head_gpd, tail_gpd) ||
+ 0 != ipc_ut_spd_payload_count(head_gpd, tail_gpd) ) {
+ utELOG("IPv4 filter (MSG) test case failed!\r\n");
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ return KAL_FALSE;
+ }
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ ipc_ut_uninstall_dl_filters(filter_cnt, 0);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_gpd_copy(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ qbm_gpd *bd;
+ kal_uint8 *dataptr;
+ kal_uint32 idx;
+ kal_uint32 total_len = 0;
+ kal_bool result;
+ static kal_uint8 _dst_buf[256];
+ static kal_uint32 _copied;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * GPD list.
+ */
+ if (2 != qbmt_alloc_q(
+ QBM_TYPE_NET_DL,
+ 2,
+ (void**)&head_gpd,
+ (void**)&tail_gpd)) {
+ UT_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ bd = (qbm_gpd *)QBM_DES_GET_DATAPTR(head_gpd);
+ dataptr = (kal_uint8 *)QBM_DES_GET_DATAPTR(bd);
+ for (idx = 0; idx < 100; idx++) {
+ *(dataptr + idx) = (kal_uint8)(total_len + idx);
+ }
+ total_len += idx;
+ QBM_DES_SET_DATALEN(bd, idx);
+ QBM_DES_SET_DATALEN(head_gpd, idx);
+
+ bd = (qbm_gpd *)QBM_DES_GET_DATAPTR(tail_gpd);
+ dataptr = (kal_uint8 *)QBM_DES_GET_DATAPTR(bd);
+ for (idx = 0; idx < 100; idx++) {
+ *(dataptr + idx) = (kal_uint8)(total_len + idx);
+ }
+ total_len += idx;
+ QBM_DES_SET_DATALEN(bd, idx);
+ QBM_DES_SET_DATALEN(tail_gpd, idx);
+
+ kal_mem_set(_dst_buf, 0, sizeof(_dst_buf));
+ result = ipc_gpd_copy(_dst_buf, sizeof(_dst_buf), &_copied, head_gpd, tail_gpd);
+ if (!result || _copied != total_len) {
+ utELOG("[G] ipc_gpd_copy() returns KAL_FALSE or wrong length copied!\r\n");
+ qbmt_dest_q(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+ for (idx = 0; idx < total_len; idx++) {
+ if (*(_dst_buf + idx) != (kal_uint8)idx) {
+ utELOG("[G] ipc_gpd_copy() buffer copied is wrong!\r\n");
+ qbmt_dest_q(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+ }
+
+ /*
+ * BD list.
+ */
+ bd = (qbm_gpd *)QBM_DES_GET_DATAPTR(head_gpd);
+ QBM_DES_SET_NEXT(bd, tail_gpd);
+ QBM_DES_CLR_EOL(bd);
+ bd = (qbm_gpd *)QBM_DES_GET_DATAPTR(tail_gpd);
+ kal_mem_cpy(tail_gpd, bd, sizeof(qbm_gpd));
+ QBM_DES_SET_DATALEN(head_gpd, total_len);
+
+ kal_mem_set(_dst_buf, 0, sizeof(_dst_buf));
+ result = ipc_gpd_copy(_dst_buf, sizeof(_dst_buf), &_copied, head_gpd, head_gpd);
+ if (!result || _copied != total_len) {
+ utELOG("[B] ipc_gpd_copy() returns KAL_FALSE or wrong length copied!\r\n");
+ qbmt_dest_q(head_gpd, head_gpd);
+ return KAL_FALSE;
+ }
+ for (idx = 0; idx < total_len; idx++) {
+ if (*(_dst_buf + idx) != (kal_uint8)idx) {
+ utELOG("[B] ipc_gpd_copy() buffer copied is wrong!\r\n");
+ qbmt_dest_q(head_gpd, head_gpd);
+ return KAL_FALSE;
+ }
+ }
+
+ qbmt_dest_q(head_gpd, head_gpd);
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_send_ul_pkt(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint8 *ip_header;
+ kal_uint32 total_length;
+ kal_uint8 *udp_header;
+ kal_uint32 udp_length;
+ kal_uint32 ul_total_length;
+ kal_bool result;
+
+ kal_uint32 to_generate_hdr;
+ ipc_pkt_t pkt;
+ ipc_hdr_t hdr;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for ( to_generate_hdr = 0 ; to_generate_hdr < 2 ; to_generate_hdr ++ ) {
+ qbm_gpd *curr_gpd;
+ kal_uint32 isGPD;
+ kal_uint32 pktcnt;
+ kal_uint32 alignment;
+
+ ip_header = ipc_ut_ipv4_dns_packet;
+ total_length = sizeof(ipc_ut_ipv4_dns_packet);
+ udp_header = IPC_HDR_V4_GET_NHPTR(ip_header);
+ udp_length = total_length - IPC_HDR_V4_GET_IHL(ip_header);
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (isGPD = 0 ; isGPD < 2 ; isGPD ++)
+ for (pktcnt = 1 ; pktcnt < 4 ; pktcnt ++) {
+ /* IP/UDP Header information */
+ hdr.ip_type = IPC_IP_TYPE_IPV4;
+ hdr.src_addr = IPC_HDR_V4_GET_SRC_ADDR(ip_header);
+ hdr.dst_addr = IPC_HDR_V4_GET_DST_ADDR(ip_header);
+ hdr.src_port = IPC_HDR_UDP_GET_SRC_PORT(udp_header);
+ hdr.dst_port = IPC_HDR_UDP_GET_DST_PORT(udp_header);
+ hdr.dscp_tc = 0;
+
+ /* Generate Packet */
+ if (0 == isGPD) {
+ pkt.isGPD = KAL_FALSE;
+ pkt.data = (0 == to_generate_hdr) ? ip_header : udp_header + IPC_HDR_UDP_HEADER_SIZE;
+ pkt.data_len = (0 == to_generate_hdr) ? total_length : udp_length - IPC_HDR_UDP_HEADER_SIZE;
+ } else {
+ pkt.isGPD = KAL_TRUE;
+ /* Using "dl_gpd_list" preparing to generate packet (which is more suitable for this case) */
+ ipc_ut_prepare_dl_gpd_list(pktcnt,
+ 0,
+ KAL_TRUE,
+ (0 == to_generate_hdr)?KAL_TRUE:KAL_FALSE,
+ 0,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0, /* We does NOT divide packet in pieces for following comparison */
+ alignment,
+ &(pkt.head),
+ &(pkt.tail),
+ NULL,
+ NULL,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0);
+ }
+
+ result = ipc_send_ul_pkt(
+ &pkt,
+ (0 == to_generate_hdr)?NULL:&hdr,
+ IPC_UT_UL_EBI);
+
+ if (!result) {
+ utELOG("[4] ipc_send_ul_pkt() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (NULL == ipc_ut_ul_ebi_head_gpd || NULL == ipc_ut_ul_ebi_tail_gpd) {
+ utELOG("[4] ipc_send_ul_pkt() failed! no UL SDU sent.\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Run GPD copy and content check */
+ curr_gpd = ipc_ut_ul_ebi_head_gpd;
+ do {
+ if (!ipc_gpd_copy(ipc_ut_checksum_buf_s,
+ sizeof(ipc_ut_checksum_buf_s),
+ &ul_total_length,
+ curr_gpd,
+ curr_gpd)) {
+ utELOG("[4] ipc_gpd_copy() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (ul_total_length != total_length) {
+ utELOG("[4] ipc_send_ul_pkt() IPv4 total_length mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ if ( !IPC_HDR_IS_V4(ipc_ut_checksum_buf_s) ||
+ total_length != IPC_HDR_V4_GET_TOTAL_LENGTH(ipc_ut_checksum_buf_s) ||
+ !IPC_EQ_V4_ADDR(IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_checksum_buf_s), IPC_HDR_V4_GET_SRC_ADDR(ip_header)) ||
+ !IPC_EQ_V4_ADDR(IPC_HDR_V4_GET_DST_ADDR(ipc_ut_checksum_buf_s), IPC_HDR_V4_GET_DST_ADDR(ip_header)) ||
+ IPC_HDR_PROT_UDP != IPC_HDR_V4_GET_PROTOCOL(ipc_ut_checksum_buf_s) ||
+ 0 != ipc_utils_calc_ipv4_checksum(ipc_ut_checksum_buf_s) ) {
+ utELOG("[4] ipc_send_ul_pkt() wrong IPv4 header!\r\n");
+ return KAL_FALSE;
+ }
+ if ( kal_mem_cmp(IPC_HDR_V4_GET_NHPTR(ipc_ut_checksum_buf_s), udp_header, udp_length) ) {
+ utELOG("[4] ipc_send_ul_pkt() UDP header or data mismatched!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check next GPD */
+ if (ipc_ut_ul_ebi_tail_gpd == curr_gpd) {
+ curr_gpd = NULL;
+ } else {
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+ } while (curr_gpd);
+
+ /* Free GPD list */
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ }
+
+ ip_header = ipc_ut_ipv6_mdns_packet;
+ total_length = sizeof(ipc_ut_ipv6_mdns_packet);
+ udp_header = IPC_HDR_V6_GET_NHPTR(ip_header);
+ udp_length = total_length - IPC_HDR_V6_HEADER_SIZE;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (isGPD = 0 ; isGPD < 2 ; isGPD ++)
+ for (pktcnt = 1 ; pktcnt < 4 ; pktcnt ++) {
+ /* IP/UDP Header information */
+ hdr.ip_type = IPC_IP_TYPE_IPV6;
+ hdr.src_addr = IPC_HDR_V6_GET_SRC_ADDR(ip_header);
+ hdr.dst_addr = IPC_HDR_V6_GET_DST_ADDR(ip_header);
+ hdr.src_port = IPC_HDR_UDP_GET_SRC_PORT(udp_header);
+ hdr.dst_port = IPC_HDR_UDP_GET_DST_PORT(udp_header);
+ hdr.dscp_tc = 0;
+
+ /* Generate Packet */
+ if (0 == isGPD) {
+ pkt.isGPD = KAL_FALSE;
+ pkt.data = (0 == to_generate_hdr) ? ip_header : (udp_header + IPC_HDR_UDP_HEADER_SIZE);
+ pkt.data_len = (0 == to_generate_hdr) ? total_length : udp_length - IPC_HDR_UDP_HEADER_SIZE;
+
+ } else {
+ pkt.isGPD = KAL_TRUE;
+ /* Using "dl_gpd_list" preparing to generate packet (which is more suitable for this case) */
+ ipc_ut_prepare_dl_gpd_list(0,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ pktcnt,
+ 0,
+ KAL_TRUE,
+ (0 == to_generate_hdr)?KAL_TRUE:KAL_FALSE,
+ 0, /* We does NOT divide packet in pieces for following comparison */
+ alignment,
+ &(pkt.head),
+ &(pkt.tail),
+ NULL,
+ NULL,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0);
+ }
+
+ result = ipc_send_ul_pkt(
+ &pkt,
+ (0 == to_generate_hdr)?NULL:&hdr,
+ IPC_UT_UL_EBI);
+
+ if (!result) {
+ utELOG("[6] ipc_send_ul_pkt() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (NULL == ipc_ut_ul_ebi_head_gpd || NULL == ipc_ut_ul_ebi_tail_gpd) {
+ utELOG("[6] ipc_send_ul_pkt() failed! no UL SDU sent.\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Run GPD copy and content check */
+ curr_gpd = ipc_ut_ul_ebi_head_gpd;
+ do {
+ if (!ipc_gpd_copy(ipc_ut_checksum_buf_s,
+ sizeof(ipc_ut_checksum_buf_s),
+ &ul_total_length,
+ curr_gpd,
+ curr_gpd)) {
+ utELOG("[6] ipc_gpd_copy() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (ul_total_length != total_length) {
+ utELOG("[6] ipc_send_ul_pkt() IPv6 total_length mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ if ( !IPC_HDR_IS_V6(ipc_ut_checksum_buf_s) ||
+ !IPC_EQ_V6_ADDR(IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_checksum_buf_s), IPC_HDR_V6_GET_SRC_ADDR(ip_header)) ||
+ !IPC_EQ_V6_ADDR(IPC_HDR_V6_GET_DST_ADDR(ipc_ut_checksum_buf_s), IPC_HDR_V6_GET_DST_ADDR(ip_header)) ||
+ IPC_HDR_PROT_UDP != IPC_HDR_V6_GET_NH_TYPE(ipc_ut_checksum_buf_s) ) {
+ utELOG("[6] ipc_send_ul_pkt() wrong IPv6 header!\r\n");
+ return KAL_FALSE;
+ }
+ if ( kal_mem_cmp(IPC_HDR_V6_GET_NHPTR(ipc_ut_checksum_buf_s), udp_header, udp_length) ) {
+ utELOG("[6] ipc_send_ul_pkt() UDP header or data mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_ebi_tail_gpd == curr_gpd) {
+ curr_gpd = NULL;
+ } else {
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+ } while (curr_gpd);
+
+ /* Free GPD list */
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_send_dl_pkt(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 netif_exist;
+ kal_uint32 idx;
+ kal_uint32 failNetifIdOffset;
+ kal_uint32 to_generate_hdr;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for ( netif_exist = 0 ; netif_exist < 2 ; netif_exist ++ )
+ for ( idx = 0 ; idx < 2 ; idx ++ )
+ for ( failNetifIdOffset = 0 ; failNetifIdOffset < 2 ; failNetifIdOffset ++ )
+ for ( to_generate_hdr = 0 ; to_generate_hdr < 2 ; to_generate_hdr ++ ) {
+ kal_bool result;
+ ipc_ut_netif_t *net;
+
+ if (netif_exist) {
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ /* For IPv4 */
+ {
+ kal_uint32 isGPD;
+ kal_uint32 pktcnt;
+ ipc_pkt_t pkt;
+ ipc_hdr_t hdr;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+
+ kal_uint8 *ip_header;
+ kal_uint32 total_length;
+ kal_uint8 *udp_header;
+ kal_uint32 udp_length;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (isGPD = 0 ; isGPD < 2 ; isGPD ++)
+ for (pktcnt = 1 ; pktcnt < 4 ; pktcnt ++) {
+ ip_header = ipc_ut_ipv4_dhcp_packet;
+ total_length = sizeof(ipc_ut_ipv4_dhcp_packet);
+ udp_header = IPC_HDR_V4_GET_NHPTR(ip_header);
+ udp_length = total_length - IPC_HDR_V4_GET_IHL(ip_header);
+
+ /* IP/UDP Header information */
+ hdr.ip_type = IPC_IP_TYPE_IPV4;
+ hdr.src_addr = IPC_HDR_V4_GET_SRC_ADDR(ip_header);
+ hdr.dst_addr = IPC_HDR_V4_GET_DST_ADDR(ip_header);
+ hdr.src_port = IPC_HDR_UDP_GET_SRC_PORT(udp_header);
+ hdr.dst_port = IPC_HDR_UDP_GET_DST_PORT(udp_header);
+ hdr.dscp_tc = 0;
+
+ /* Generate Packet */
+ if (0 == isGPD) {
+ pkt.isGPD = KAL_FALSE;
+ pkt.data = (0 == to_generate_hdr) ? ip_header : udp_header + IPC_HDR_UDP_HEADER_SIZE;
+ pkt.data_len = (0 == to_generate_hdr) ? total_length : udp_length - IPC_HDR_UDP_HEADER_SIZE;
+ } else {
+ pkt.isGPD = KAL_TRUE;
+ ipc_ut_prepare_dl_gpd_list(pktcnt,
+ 0,
+ KAL_TRUE,
+ (0 == to_generate_hdr)?KAL_TRUE:KAL_FALSE,
+ 0,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &(pkt.head),
+ &(pkt.tail),
+ NULL,
+ NULL,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0);
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ ipc_ut_reset_dl_callback_info();
+
+ result = ipc_send_dl_pkt(
+ &pkt,
+ (0 == to_generate_hdr)?NULL:&hdr,
+ (netif_exist)?(net->conf.netif_id + failNetifIdOffset):IPC_UT_NETID_START);
+
+ if ((!netif_exist) || failNetifIdOffset) { /* DL packet sending should be failed */
+ if (KAL_FALSE != result) {
+ utELOG("[4] ipc_send_dl_pkt() should be failed with error code [IPC_UT_DL_PKT_NETIF_NOT_FOUND]!\r\n");
+ return KAL_FALSE;
+ }
+ } else { /* DL packet sending should be success */
+ if (!result) {
+ utELOG("[4] ipc_send_dl_pkt() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if ( ((isGPD == 0) && (ipc_ut_dl_callback_gpd_cnt != 1)) ||
+ ((isGPD != 0) && (ipc_ut_dl_callback_gpd_cnt != pktcnt))) {
+ utELOG("[4] ipc_send_dl_pkt() failed! DL packet count is not correct!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* For IPv6 */
+ {
+ kal_uint32 isGPD;
+ kal_uint32 pktcnt;
+ ipc_pkt_t pkt;
+ ipc_hdr_t hdr;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+
+ kal_uint8 *ip_header;
+ kal_uint32 total_length;
+ kal_uint8 *udp_header;
+ kal_uint32 udp_length;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (isGPD = 0 ; isGPD < 2 ; isGPD ++)
+ for (pktcnt = 1 ; pktcnt < 4 ; pktcnt ++) {
+ ip_header = ipc_ut_ipv6_dhcp_packet;
+ total_length = sizeof(ipc_ut_ipv6_dhcp_packet);
+ udp_header = IPC_HDR_V4_GET_NHPTR(ip_header);
+ udp_length = total_length - IPC_HDR_V4_GET_IHL(ip_header);
+
+ /* IP/UDP Header information */
+ hdr.ip_type = IPC_IP_TYPE_IPV6;
+ hdr.src_addr = IPC_HDR_V6_GET_SRC_ADDR(ip_header);
+ hdr.dst_addr = IPC_HDR_V6_GET_DST_ADDR(ip_header);
+ hdr.src_port = IPC_HDR_UDP_GET_SRC_PORT(udp_header);
+ hdr.dst_port = IPC_HDR_UDP_GET_DST_PORT(udp_header);
+ hdr.dscp_tc = 0;
+
+ /* Generate Packet */
+ if (0 == isGPD) {
+ pkt.isGPD = KAL_FALSE;
+ pkt.data = (0 == to_generate_hdr) ? ip_header : udp_header + IPC_HDR_UDP_HEADER_SIZE;
+ pkt.data_len = (0 == to_generate_hdr) ? total_length : udp_length - IPC_HDR_UDP_HEADER_SIZE;
+ } else {
+ pkt.isGPD = KAL_TRUE;
+ ipc_ut_prepare_dl_gpd_list(0,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ pktcnt,
+ 0,
+ KAL_TRUE,
+ (0 == to_generate_hdr)?KAL_TRUE:KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &(pkt.head),
+ &(pkt.tail),
+ NULL,
+ NULL,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0);
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ ipc_ut_reset_dl_callback_info();
+
+ result = ipc_send_dl_pkt(
+ &pkt,
+ (0 == to_generate_hdr)?NULL:&hdr,
+ (netif_exist)?(net->conf.netif_id + failNetifIdOffset):IPC_UT_NETID_START);
+
+ if ((!netif_exist) || failNetifIdOffset) { /* DL packet sending should be failed */
+ if (KAL_FALSE != result) {
+ utELOG("[6] ipc_send_dl_pkt() should be failed with error code [IPC_UT_DL_PKT_NETIF_NOT_FOUND]!\r\n");
+ return KAL_FALSE;
+ }
+ } else { /* DL packet sending should be success */
+ if (!result) {
+ utELOG("[6] ipc_send_dl_pkt() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if ( ((isGPD == 0) && (ipc_ut_dl_callback_gpd_cnt != 1)) ||
+ ((isGPD != 0) && (ipc_ut_dl_callback_gpd_cnt != pktcnt))) {
+ utELOG("[6] ipc_send_dl_pkt() failed! DL packet count is not correct!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* For MIX */
+ {
+ kal_uint32 alignment;
+ kal_uint32 ipv4Pktcnt;
+ kal_uint32 ipv6Pktcnt;
+ ipc_pkt_t pkt;
+ kal_uint32 unite;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4Pktcnt = 0 ; ipv4Pktcnt <= 4 ; ipv4Pktcnt ++)
+ for (ipv6Pktcnt = 0 ; ipv6Pktcnt <= 4 ; ipv6Pktcnt ++) {
+ /*
+ For MIX case : it should be GPD list without generating header
+ */
+ if (to_generate_hdr) {continue;}
+
+ /* Generate Packet */
+ {
+ pkt.isGPD = KAL_TRUE;
+ ipc_ut_prepare_dl_gpd_list(ipv4Pktcnt,
+ 0,
+ KAL_TRUE,
+ KAL_TRUE,
+ ipv6Pktcnt,
+ 0,
+ KAL_TRUE,
+ KAL_TRUE,
+ (unite == 0)?0:10,
+ alignment,
+ &(pkt.head),
+ &(pkt.tail),
+ NULL,
+ NULL,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0);
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ ipc_ut_reset_dl_callback_info();
+
+ result = ipc_send_dl_pkt(
+ &pkt,
+ NULL,
+ (netif_exist)?(net->conf.netif_id + failNetifIdOffset):IPC_UT_NETID_START);
+
+ if ((!netif_exist) || failNetifIdOffset) { /* DL packet sending should be failed */
+ if (KAL_FALSE != result) {
+ utELOG("[MIX] ipc_send_dl_pkt() should be failed with error code [IPC_UT_DL_PKT_NETIF_NOT_FOUND]!\r\n");
+ return KAL_FALSE;
+ }
+ } else { /* DL packet sending should be success */
+ if (!result) {
+ utELOG("[MIX] ipc_send_dl_pkt() failed!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_dl_callback_gpd_cnt != (ipv4Pktcnt + ipv6Pktcnt)) {
+ utELOG("[MIX] ipc_send_dl_pkt() failed! DL packet count is not correct!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ if (netif_exist) {
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ul_throttle(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 blocked_cnt = 0;
+ qbm_gpd *head_gpd, *head_gpd_latency;
+ qbm_gpd *tail_gpd, *tail_gpd_latency;
+ ipc_io_request_t *ior, *ior_latency;
+ ipc_ut_netif_t *net, *net_latency;
+ kal_bool result;
+ kal_uint32 idx = 1;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ ipc_ul_throttle_conf_t conf = {0};
+ tmc_ctrl_config tmc_cfg = {0};
+ kal_uint32 conf_in_int = 0;
+ ipc_set_ul_throttle_param_t *p_ipc_ul_thrott_cfg = NULL;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ net_latency = &(ipc_ut_nets_s[1]);
+ kal_mem_set(net_latency, 0, sizeof(ipc_ut_netif_t));
+ net_latency->conf.module_id = MOD_IPCORE;
+ net_latency->conf.netif_id = IPC_UT_NETID_START + 1;
+ net_latency->conf.ul_reload_context = net_latency;
+ net_latency->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net_latency->conf.callback_context = net_latency;
+ net_latency->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net_latency->conf.features |= IPC_F_LATENCY_CONCERN;
+ result = ipc_attach(&net_latency->conf, &net_latency->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* PDN activation. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net_latency->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID_2;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Enable UL Throttle */
+#if defined(__MD93__)
+ kal_mem_set(&conf, 0, sizeof(ipc_ul_throttle_conf_t));
+ conf.enabled = 1;
+ conf.active_period_100ms = 10;
+ conf.suspend_period_100ms = 10;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_TRUE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 10;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 10;
+ p_ipc_ul_thrott_cfg->conf.features = 0;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * TEST CASE 1: Basic
+ * Throttle active mode.
+ * Both netifs should forward GPDs to network without blocking.
+ */
+ {
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ ipc_uplink(net_latency->handle, ior_latency);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (ipv4_cnt + ipv4_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("GPD is not forwarded to network correctly when active mode!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /* Throttling Mode: ACTIVE -> SUSPEND*/
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_TIMER_EXPIRY, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * TEST CASE 1: Basic
+ * Throttle suspend mode.
+ * Netif_1 should be throttled, while netif_2 should be able to forward GPDs.
+ */
+ {
+ blocked_cnt = 0;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ ipc_uplink(net_latency->handle, ior_latency);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (ipv4_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("GPD is not forwarded to network correctly when suspend mode!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ blocked_cnt += ipv4_cnt;
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * TEST CASE 1: Basic
+ * Throttle resume to active mode
+ * The blocked GPDs should be forwarded automatically.
+ */
+ {
+ ipc_ut_reset_ul_info();
+
+ /* Throttling Mode: SUSPEND -> ACTIVE*/
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_TIMER_EXPIRY, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (blocked_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("The blocked GPDs are not forwarded to network automatically when active mode.!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ /* Throttling Mode: ACTIVE -> SUSPEND*/
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_TIMER_EXPIRY, /* msg_id */
+ NULL, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * TEST CASE 1: Basic
+ * Throttle suspend mode case 2.
+ * When throttling is turning off, it should send ilm MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ to ipcore.
+ */
+ {
+ blocked_cnt = 0;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ ipc_uplink(net_latency->handle, ior_latency);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (ipv4_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("GPD is not forwarded to network correctly when suspend mode!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ blocked_cnt += ipv4_cnt;
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ ipc_ut_reset_ul_info();
+
+ /*
+ * Diable UL throttle
+ */
+#if defined(__MD93__)
+ conf.enabled = 0;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_FALSE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 10;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 10;
+ p_ipc_ul_thrott_cfg->conf.features = 0;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (blocked_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("The blocked GPDs are not forwarded to network automatically when throttling is turning off!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ /*
+ * TEST CASE 2: IMS Basic
+ * Throttling v2: IMS may be blocked.
+ * Enable UL Throttle (with blocking IMS)
+ */
+#if defined(__MD93__)
+ conf.enabled = 1;
+ conf.active_period_100ms = 1;
+ conf.suspend_period_100ms = 255;
+ conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_TRUE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * TEST CASE 2: IMS Basic
+ * Throttle SUSPEND-FOREVER mode.
+ * Both netifs should be throttled, and no packet is forwarded.
+ */
+ {
+ blocked_cnt = 0;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ ipc_uplink(net_latency->handle, ior_latency);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (0 != ipc_ut_ul_gpd_cnt) {
+ utELOG("(IMS) GPD is not forwarded to network correctly when suspend mode!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ blocked_cnt += ipv4_cnt + ipv4_cnt;
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * TEST CASE 2: IMS Basic
+ * Turn off throttling.
+ * The blocked GPDs should be forwarded automatically.
+ */
+ {
+ ipc_ut_reset_ul_info();
+
+ /*
+ * Diable UL throttle
+ */
+#if defined(__MD93__)
+ conf.enabled = 0;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_FALSE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (blocked_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("(IMS) The blocked GPDs are not forwarded to network automatically when active mode.!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ /*
+ * TEST CASE 2: IMS Basic
+ * Throttling v2: IMS may be blocked.
+ * Case 2: packets from ipc_send_ul_pkt should be blocked as well.
+ */
+
+#if defined(__MD93__)
+ conf.enabled = 1;
+ conf.active_period_100ms = 1;
+ conf.suspend_period_100ms = 255;
+ conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_TRUE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * TEST CASE 2: IMS Basic
+ * Throttle suspend mode case 2.
+ * Packets from ipc_send_ul_pkt should be blocked as well.
+ */
+ {
+ ipc_pkt_t pkt_ebi, pkt_pdn;
+
+ blocked_cnt = 0;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ /* Prepare ipc_pkt_t */
+ kal_mem_set(&pkt_ebi, 0, sizeof(ipc_pkt_t));
+ pkt_ebi.isGPD = KAL_TRUE;
+ pkt_ebi.head = head_gpd;
+ pkt_ebi.tail = tail_gpd;
+
+ kal_mem_set(&pkt_pdn, 0, sizeof(ipc_pkt_t));
+ pkt_pdn.isGPD = KAL_TRUE;
+ pkt_pdn.head = head_gpd_latency;
+ pkt_pdn.tail = tail_gpd_latency;
+
+ ipc_send_ul_pkt(&pkt_ebi, NULL, IPC_UT_UL_EBI);
+ ipc_send_ul_pkt_by_pdn(&pkt_pdn, NULL, IPC_UT_PDN_ID, IPC_IP_TYPE_IPV4);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (NULL != ipc_ut_ul_ebi_head_gpd) ||
+ (NULL != ipc_ut_ul_ebi_tail_gpd) ||
+ (0 != ipc_ut_ul_gpd_cnt) ) {
+ utELOG("(IMS send_ul_pkt) GPD is not forwarded to network correctly when suspend mode!\r\r");
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ blocked_cnt += ipv4_cnt;
+ }
+ }
+
+ /*
+ * TEST CASE 2: IMS Basic
+ * Turn off throttling
+ * The blocked GPDs should be forwarded automatically.
+ */
+ {
+ ipc_ut_reset_ul_info();
+
+ /* Diable UL throttle */
+#if defined(__MD93__)
+ conf.enabled = 0;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_FALSE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (blocked_cnt != ipc_ut_gpd_list_count(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd)) ||
+ (blocked_cnt != ipc_ut_ul_gpd_cnt) ) {
+ utELOG("(IMS send_ul_pkt) The blocked GPDs are not forwarded to network automatically when active mode.!\r\r");
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ if (ipc_ut_ul_ebi_head_gpd) {
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ }
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ul_throttle_ims_emergency(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 blocked_cnt = 0;
+ qbm_gpd *head_gpd, *head_gpd_latency = NULL;
+ qbm_gpd *tail_gpd, *tail_gpd_latency = NULL;
+ ipc_io_request_t *ior, *ior_latency = NULL;
+ ipc_ut_netif_t *net, *net_latency = NULL;
+ kal_bool result = KAL_FALSE;
+ kal_uint32 idx = 1;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ ipc_vdm_ims_emergency_call_ind_struct_t *local_para_ptr = NULL;
+ ipc_ul_throttle_conf_t conf = {0};
+ tmc_ctrl_config tmc_cfg = {0};
+ kal_uint32 conf_in_int = 0;
+ ipc_set_ul_throttle_param_t *p_ipc_ul_thrott_cfg = NULL;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ net_latency = &(ipc_ut_nets_s[1]);
+ kal_mem_set(net_latency, 0, sizeof(ipc_ut_netif_t));
+ net_latency->conf.module_id = MOD_IPCORE;
+ net_latency->conf.netif_id = IPC_UT_NETID_START + 1;
+ net_latency->conf.ul_reload_context = net_latency;
+ net_latency->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net_latency->conf.callback_context = net_latency;
+ net_latency->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net_latency->conf.features |= IPC_F_LATENCY_CONCERN;
+ result = ipc_attach(&net_latency->conf, &net_latency->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* PDN activation. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net_latency->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID_2;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * TEST CASE 1: Throttle IMS-blocking mode with IMS emergency flag.
+ * 1-1. IMS emergency = TRUE: Only latency packets could pass.
+ */
+
+ /* Enable UL Throttle with IMS blocking mode */
+#if defined(__MD93__)
+ conf.enabled = 1;
+ conf.active_period_100ms = 1;
+ conf.suspend_period_100ms = 255;
+ conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_TRUE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ {
+ /* Notify IMS emergency call */
+ local_para_ptr = (ipc_vdm_ims_emergency_call_ind_struct_t *)construct_local_para(sizeof(ipc_vdm_ims_emergency_call_ind_struct_t), TD_RESET);
+ UT_ASSERT(NULL != local_para_ptr);
+
+ local_para_ptr->is_calling = KAL_TRUE;
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_VDM_IMS_EMERGENCY_CALL_IND, /* msg_id */
+ (local_para_struct *)local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ blocked_cnt = 0;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ ipc_uplink(net_latency->handle, ior_latency);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (ipv4_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("1-1: GPD is not forwarded to network correctly when IMS emergency call!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ blocked_cnt += ipv4_cnt;
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ ipc_ut_reset_ul_info();
+
+ /* Diable UL throttle */
+#if defined(__MD93__)
+ conf.enabled = 0;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_FALSE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (blocked_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("1-1: The blocked GPDs are not forwarded to network automatically!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ /*
+ * TEST CASE 1: Throttle IMS-blocking mode with IMS emergency flag.
+ * 1-2. IMS emergency = FALSE: Both netifs should be throttled.
+ */
+
+ /* Enable UL Throttle with IMS blocking mode */
+#if defined(__MD93__)
+ conf.enabled = 1;
+ conf.active_period_100ms = 1;
+ conf.suspend_period_100ms = 255;
+ conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_TRUE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ {
+ /* Notify the end of IMS emergency call */
+ local_para_ptr = (ipc_vdm_ims_emergency_call_ind_struct_t *)construct_local_para(sizeof(ipc_vdm_ims_emergency_call_ind_struct_t), TD_RESET);
+ UT_ASSERT(NULL != local_para_ptr);
+
+ local_para_ptr->is_calling = KAL_FALSE;
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_VDM_IMS_EMERGENCY_CALL_IND, /* msg_id */
+ (local_para_struct *)local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ blocked_cnt = 0;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ ipc_uplink(net_latency->handle, ior_latency);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (0 != ipc_ut_ul_gpd_cnt) {
+ utELOG("1-2: GPD is not forwarded to network correctly when suspend mode!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ blocked_cnt += ipv4_cnt;
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * TEST CASE 1: Throttle IMS-blocking mode with IMS emergency flag.
+ * 1-3. Turn IMS emergency to TRUE: The blocked GPDs should be forwarded automatically.
+ */
+
+ {
+ ipc_ut_reset_ul_info();
+
+ /* Notify IMS emergency call */
+ local_para_ptr = (ipc_vdm_ims_emergency_call_ind_struct_t *)construct_local_para(sizeof(ipc_vdm_ims_emergency_call_ind_struct_t), TD_RESET);
+ UT_ASSERT(NULL != local_para_ptr);
+
+ local_para_ptr->is_calling = KAL_TRUE;
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_VDM_IMS_EMERGENCY_CALL_IND, /* msg_id */
+ (local_para_struct *)local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (blocked_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("1-3: The blocked GPDs are not forwarded to network automatically when IMS emergency call.!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+
+ ipc_ut_reset_ul_info();
+
+ /* Diable UL throttle */
+#if defined(__MD93__)
+ conf.enabled = 0;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_FALSE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (blocked_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("1-3: The blocked GPDs are not forwarded to network automatically when throttling is turning off!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ /*
+ * TEST CASE 2: IMS emergency call when throttling turned off
+ * When throttling is turning off, it should send ilm MSG_ID_IPCORE_PROCESS_UL_QUEUE_REQ to ipcore.
+ */
+
+ /* Enable UL Throttle with IMS blocking mode */
+#if defined(__MD93__)
+ conf.enabled = 1;
+ conf.active_period_100ms = 1;
+ conf.suspend_period_100ms = 255;
+ conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_TRUE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ {
+ /* Notify the end of IMS emergency call */
+ local_para_ptr = (ipc_vdm_ims_emergency_call_ind_struct_t *)construct_local_para(sizeof(ipc_vdm_ims_emergency_call_ind_struct_t), TD_RESET);
+ UT_ASSERT(NULL != local_para_ptr);
+
+ local_para_ptr->is_calling = KAL_FALSE;
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_VDM_IMS_EMERGENCY_CALL_IND, /* msg_id */
+ (local_para_struct *)local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ blocked_cnt = 0;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ ipc_uplink(net_latency->handle, ior_latency);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (0 != ipc_ut_ul_gpd_cnt) {
+ utELOG("2: GPD is not forwarded to network correctly when suspend mode!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ blocked_cnt += ipv4_cnt + ipv4_cnt;
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ ipc_ut_reset_ul_info();
+
+ /*
+ * Diable UL throttle
+ */
+#if defined(__MD93__)
+ conf.enabled = 0;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_FALSE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (blocked_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("2: The blocked GPDs are not forwarded to network automatically when throttling is turning off!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ /*
+ * TEST CASE 3: ipc_send_ul_pkt case
+ * 3-1. IMS emergency = TRUE: Packets from ipc_send_ul_pkt should be able to sent to the network.
+ */
+
+ /* Enable UL Throttle with IMS blocking mode */
+#if defined(__MD93__)
+ conf.enabled = 1;
+ conf.active_period_100ms = 1;
+ conf.suspend_period_100ms = 255;
+ conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_TRUE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ {
+ ipc_pkt_t pkt_ebi, pkt_pdn;
+
+ /* Notify IMS emergency call */
+ local_para_ptr = (ipc_vdm_ims_emergency_call_ind_struct_t *)construct_local_para(sizeof(ipc_vdm_ims_emergency_call_ind_struct_t), TD_RESET);
+ UT_ASSERT(NULL != local_para_ptr);
+
+ local_para_ptr->is_calling = KAL_TRUE;
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_VDM_IMS_EMERGENCY_CALL_IND, /* msg_id */
+ (local_para_struct *)local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ /* Prepare ipc_pkt_t */
+ kal_mem_set(&pkt_ebi, 0, sizeof(ipc_pkt_t));
+ pkt_ebi.isGPD = KAL_TRUE;
+ pkt_ebi.head = head_gpd;
+ pkt_ebi.tail = tail_gpd;
+
+ kal_mem_set(&pkt_pdn, 0, sizeof(ipc_pkt_t));
+ pkt_pdn.isGPD = KAL_TRUE;
+ pkt_pdn.head = head_gpd_latency;
+ pkt_pdn.tail = tail_gpd_latency;
+
+ ipc_send_ul_pkt(&pkt_ebi, NULL, IPC_UT_UL_EBI);
+ ipc_send_ul_pkt_by_pdn(&pkt_pdn, NULL, IPC_UT_PDN_ID, IPC_IP_TYPE_IPV4);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (NULL == ipc_ut_ul_ebi_head_gpd) ||
+ (NULL == ipc_ut_ul_ebi_tail_gpd) ||
+ (ipv4_cnt != ipc_ut_gpd_list_count(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd)) ||
+ (ipv4_cnt != ipc_ut_ul_gpd_cnt) ) {
+ utELOG("3-1: (IMS send_ul_pkt) GPD is not forwarded to network correctly!\r\r");
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ if (ipc_ut_ul_ebi_head_gpd) {
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ }
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * TEST CASE 3: ipc_send_ul_pkt case
+ * 3-2. IMS emergency = FALSE: Packets from ipc_send_ul_pkt should be blocked.
+ */
+ {
+ ipc_pkt_t pkt_ebi, pkt_pdn;
+
+ /* Notify the end of IMS emergency call */
+ local_para_ptr = (ipc_vdm_ims_emergency_call_ind_struct_t *)construct_local_para(sizeof(ipc_vdm_ims_emergency_call_ind_struct_t), TD_RESET);
+ UT_ASSERT(NULL != local_para_ptr);
+
+ local_para_ptr->is_calling = KAL_FALSE;
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_VDM_IMS_EMERGENCY_CALL_IND, /* msg_id */
+ (local_para_struct *)local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ blocked_cnt = 0;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++) {
+ if (0 == ipv4_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd, &tail_gpd, &ior);
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, 0, 0, &head_gpd_latency, &tail_gpd_latency, &ior_latency);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ /* Prepare ipc_pkt_t */
+ kal_mem_set(&pkt_ebi, 0, sizeof(ipc_pkt_t));
+ pkt_ebi.isGPD = KAL_TRUE;
+ pkt_ebi.head = head_gpd;
+ pkt_ebi.tail = tail_gpd;
+
+ kal_mem_set(&pkt_pdn, 0, sizeof(ipc_pkt_t));
+ pkt_pdn.isGPD = KAL_TRUE;
+ pkt_pdn.head = head_gpd_latency;
+ pkt_pdn.tail = tail_gpd_latency;
+
+ ipc_send_ul_pkt(&pkt_ebi, NULL, IPC_UT_UL_EBI);
+ ipc_send_ul_pkt_by_pdn(&pkt_pdn, NULL, IPC_UT_PDN_ID, IPC_IP_TYPE_IPV4);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (NULL != ipc_ut_ul_ebi_head_gpd) ||
+ (NULL != ipc_ut_ul_ebi_tail_gpd) ||
+ (0 != ipc_ut_ul_gpd_cnt) ) {
+ utELOG("3-2: (IMS send_ul_pkt) GPD is not forwarded to network correctly!\r\r");
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ blocked_cnt += ipv4_cnt;
+ }
+ }
+
+ /*
+ * TEST CASE 3: ipc_send_ul_pkt case
+ * 3-3. IMS emergency = TRUE: The blocked GPDs should be forwarded automatically.
+ */
+
+ {
+ ipc_ut_reset_ul_info();
+
+ /* Notify IMS emergency call */
+ local_para_ptr = (ipc_vdm_ims_emergency_call_ind_struct_t *)construct_local_para(sizeof(ipc_vdm_ims_emergency_call_ind_struct_t), TD_RESET);
+ UT_ASSERT(NULL != local_para_ptr);
+
+ local_para_ptr->is_calling = KAL_TRUE;
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_IPCORE_VDM_IMS_EMERGENCY_CALL_IND, /* msg_id */
+ (local_para_struct *)local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (blocked_cnt != ipc_ut_gpd_list_count(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd)) ||
+ (blocked_cnt != ipc_ut_ul_gpd_cnt) ) {
+ utELOG("3-3: (IMS send_ul_pkt) The blocked GPDs are not forwarded to network automatically when active mode.!\r\r");
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ if (ipc_ut_ul_ebi_head_gpd) {
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ }
+ ipc_ut_free_gpd_list(NULL, NULL);
+
+ /* Diable UL throttle */
+#if defined(__MD93__)
+ conf.enabled = 0;
+ kal_mem_cpy(&conf_in_int, &conf, sizeof(ipc_ul_throttle_conf_t));
+ tmc_md_thermal_feature_ctrl_sysmsgsrv_cbk_93(conf_in_int);
+#else
+ p_ipc_ul_thrott_cfg = (ipc_set_ul_throttle_param_t *)construct_local_para(sizeof(ipc_set_ul_throttle_param_t), TD_RESET);
+ UT_ASSERT(NULL != p_ipc_ul_thrott_cfg);
+ p_ipc_ul_thrott_cfg->conf.enabled = KAL_FALSE;
+ p_ipc_ul_thrott_cfg->conf.active_period_100ms = 1;
+ p_ipc_ul_thrott_cfg->conf.suspend_period_100ms = 255;
+ p_ipc_ul_thrott_cfg->conf.features = IPC_THROTTLE_FEATURE_BLOCK_LANTENCY_CONCERN;
+ ipc_set_ul_throttle((local_para_struct *)p_ipc_ul_thrott_cfg);
+ free_local_para((local_para_struct *)p_ipc_ul_thrott_cfg);
+#endif
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_prepare_dl_did_list_garbage(kal_uint32 ipv4_cnt,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 ipv4_idx,
+ kal_uint32 ipv6_idx,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint32 did_cnt)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+ kal_uint8 per_pkt_max_sit_num = 10; /* one DID max packet number will be 7. one DID has 62 SIT entries */
+
+ if (did_cnt != ipc_ut_alloc_did(
+ did_cnt,
+ did_head,
+ did_tail)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+ kal_uint32 i;
+ upcm_did_si *si;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for (curr_did = *did_head; curr_did && (end_of_list == KAL_FALSE); curr_did = next_did){
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ si = &curr_sit[i];
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ next_did = UPCM_DID_GET_NEXT(curr_did);
+ (*did_tail == curr_did)?(end_of_list = KAL_TRUE):(end_of_list = KAL_FALSE);
+ }
+ }
+
+ curr_did = *did_head;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ switch(idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv4_tcp_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_ack_packet);
+ ipc_ut_str_garbage_expect_host_cnt++;
+ break;
+ default:
+ packet_buf = ipc_ut_ipv4_tcp_syn_packet_2;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_syn_packet_2);
+ break;
+
+ }
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len)
+ {
+ kal_uint32 current_copy_len;
+
+ if ((curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) || (cont_loop_cnt == per_pkt_max_sit_num-1))
+ { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else
+ { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt ++;
+ }
+ }
+ pkt_num ++;
+
+ }
+
+ if(ipv4_cnt > 0){
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+ /*IPv6*/
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ switch(idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_udp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_udp_packet);
+ ipc_ut_str_garbage_expect_host_cnt++;
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_tcp_syn_packet_2;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_syn_packet_2);
+ break;
+
+ }
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len)
+ {
+ kal_uint32 current_copy_len;
+
+ if ((curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) || (cont_loop_cnt == per_pkt_max_sit_num-1))
+ { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else
+ { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt ++;
+ }
+ }
+ pkt_num ++;
+
+ }
+
+ if(ipv6_cnt > 0){
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+}
+
+kal_bool ipc_ut_str_garbage_filter(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ pfm_filter_set_t filter_set;
+ local_para_struct *local_para_ptr;
+ peer_buff_struct *peer_buff_ptr;
+ pfm_str_filter_t *filter_info;
+ kal_uint8 i;
+ kal_uint8 *pdu_ptr;
+ kal_uint16 peer_buf_len;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ static kal_uint8 ipv4_mask[192] = {0};
+ static kal_uint8 ipv6_mask[192] = {0};
+ kal_bool result;
+ kal_int32 *filter_id;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* PDN activation. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Register 0-7 IPv4 filter, 8-16 IPv6 filter
+ */
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_STR_FILTER_SET_ID;
+ filter_set.filter_cnt = 16;
+ filter_set.uplink = KAL_FALSE;
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ((kal_uint8*)&filter_set)+4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ /* Init mask */
+ ipv4_mask[0] = ipv6_mask[0] = 0xF0; /* IP version */
+ ipv4_mask[8] = ipv6_mask[6] = 0xFF; /* Protocol */
+ ipv4_mask[22] = ipv4_mask[23] = ipv6_mask[42] = ipv6_mask[43] = 0xFF; /* L4 dest port */
+
+ peer_buff_ptr = construct_peer_buff(sizeof(pfm_str_filter_t)*16, 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+
+ filter_info = (pfm_str_filter_t*)pdu_ptr;
+ for(i = 0; i < 16; i++){
+ filter_info->filter_id = i;
+ filter_info->magic_code = 0x1798; //PFM_STR_FILTER_MAGIC_CODE
+ filter_info->mask_len = 192;
+ filter_info->netif_id = IPC_UT_LHIF_NETID_START;
+ if( i < 8){
+ /* IPv4 filter pattern */
+ filter_info->filter_len = sizeof(ipc_ut_ipv4_tcp_ack_packet);
+
+ kal_mem_cpy(filter_info->mask, ipv4_mask, 192);
+ kal_mem_cpy(filter_info->filter, ipc_ut_ipv4_tcp_ack_packet, sizeof(ipc_ut_ipv4_tcp_ack_packet));
+
+ if(0 != i){
+ /* Not first pattern, increase dst port value (ipv4) */
+ filter_info->filter[23]++;
+ if(0 == filter_info->filter[23]){
+ filter_info->filter[22]++;
+ }
+ }
+ }else{
+ /* IPv6 filter pattern */
+ filter_info->filter_len = sizeof(ipc_ut_ipv6_udp_packet);
+
+ kal_mem_cpy(filter_info->mask, ipv6_mask, 192);
+ kal_mem_cpy(filter_info->filter, ipc_ut_ipv6_udp_packet, sizeof(ipc_ut_ipv6_udp_packet));
+ if(8 != i){
+ /* Not first pattern, increase dst port value (ipv4) */
+ filter_info->filter[42]++;
+ if(0 == filter_info->filter[42]){
+ filter_info->filter[43]++;
+ }
+ }
+ }
+ filter_info = filter_info+1;
+ }
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_REGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* Simulate DL traffic to IPCore : Only data matched garbage filter should be forward to DL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 total_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 ipv4_idx;
+ kal_uint32 ipv6_idx;
+ kal_uint32 did_remain_cnt, gpd_remain_cnt_dl;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (ipv4_idx = 0; ipv4_idx < ipv4_cnt; ipv4_idx++)
+ for (ipv6_idx = 0; ipv6_idx < ipv6_cnt; ipv6_idx++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("v4_cnt(%d),v6_cnt(%d),ipv4_idx(%d),ipv6_idx(%d),alignment(%d)\r\n", ipv4_cnt, ipv6_cnt, ipv4_idx, ipv6_idx, alignment);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ /*Store DID remain cnt */
+ did_remain_cnt = upcm_did_get_buff_remain_num();
+
+ /*Store GPD remain cnt */
+ gpd_remain_cnt_dl = qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+
+ ipc_ut_prepare_dl_did_list_garbage(ipv4_cnt,
+ ipv6_cnt,
+ ipv4_idx,
+ ipv6_idx,
+ alignment,
+ &did_head,
+ &did_tail,
+ did_cnt);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, 0);
+
+ if ( (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (ipc_ut_str_garbage_expect_host_cnt != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL PKT is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_str_garbage_expect_host_cnt = 0;
+ }
+ }
+
+ /*
+ * Deregister half of filters (0~7)
+ */
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_STR_FILTER_SET_ID;
+ filter_set.filter_cnt = 8;
+ filter_set.uplink = KAL_FALSE;
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ((kal_uint8*)&filter_set)+4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ peer_buff_ptr = construct_peer_buff(sizeof(kal_int32)*8, 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+
+ filter_id = (kal_int32*) pdu_ptr;
+ for (i = 0; i < 8; i++) {
+ *filter_id = (kal_int32) i;
+ filter_id++;
+ }
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_DEREGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * Register filter_id 0~7. Half of them should not be removed yet.
+ */
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_STR_FILTER_SET_ID;
+ filter_set.filter_cnt = 8;
+ filter_set.uplink = KAL_FALSE;
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ((kal_uint8*)&filter_set)+4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ peer_buff_ptr = construct_peer_buff(sizeof(pfm_str_filter_t)*8, 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+
+ filter_info = (pfm_str_filter_t*)pdu_ptr;
+ for(i = 0; i < 8; i++){
+ filter_info->filter_id = i;
+ filter_info->magic_code = 0x1798; //PFM_STR_FILTER_MAGIC_CODE
+ filter_info->mask_len = 192;
+ filter_info->netif_id = IPC_UT_LHIF_NETID_START;
+
+ /* IPv4 filter pattern */
+ filter_info->filter_len = sizeof(ipc_ut_ipv4_tcp_ack_packet);
+
+ kal_mem_cpy(filter_info->mask, ipv4_mask, 192);
+ kal_mem_cpy(filter_info->filter, ipc_ut_ipv4_tcp_ack_packet, sizeof(ipc_ut_ipv4_tcp_ack_packet));
+
+ if(0 != i){
+ /* Not first pattern, increase dst port value (ipv4) */
+ filter_info->filter[23]++;
+ if(0 == filter_info->filter[23]){
+ filter_info->filter[22]++;
+ }
+ }
+ filter_info = filter_info+1;
+ }
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_REGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * Deregister all filters
+ */
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_STR_FILTER_SET_ID;
+ filter_set.filter_cnt = -1;
+ filter_set.uplink = KAL_FALSE;
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ((kal_uint8*)&filter_set)+4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_DEREGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_garbage_filter(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ pfm_filter_set_t filter_set;
+ ipc_ut_garbage_filter_t filter;
+ kal_uint32 offset;
+ kal_uint32 i;
+ kal_int32 filter_id;
+ local_para_struct *local_para_ptr;
+ peer_buff_struct *peer_buff_ptr;
+ kal_uint8 *pdu_ptr;
+ kal_uint16 peer_buf_len;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ ipc_filter_rules_t rules;
+ kal_uint32 ipv4_cnt, ipv6_cnt, synv4_idx, synv6_idx;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Register
+ */
+ offset = 0;
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_FILTER_SET_ID;
+ filter_set.filter_cnt = 128;
+ filter_set.uplink = KAL_FALSE;
+
+ kal_mem_cpy(ipc_ut_garbage_filter_buf_s, &filter_set, sizeof(filter_set));
+ offset += sizeof(filter_set);
+
+ for (i = 0; i < 128; i++) {
+ kal_mem_set(&filter, 0,sizeof(filter));
+
+ filter.filter_id = i;
+ filter.ip_type = IPC_IP_TYPE_IPV4;
+ filter.protocol = IPC_HDR_PROT_TCP;
+ filter.dst_port = 443+i;
+ filter.magic_code = 168;
+
+ kal_mem_cpy(ipc_ut_garbage_filter_buf_s + offset, &filter, sizeof(filter));
+ offset += sizeof(filter);
+ }
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ipc_ut_garbage_filter_buf_s + 4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ peer_buff_ptr = construct_peer_buff(sizeof(kal_uint8)*(offset-sizeof(filter_set)), 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+ kal_mem_cpy(pdu_ptr, ipc_ut_garbage_filter_buf_s + sizeof(filter_set), offset - sizeof(filter_set));
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_REGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* Send DL packet */
+ for (ipv4_cnt = 1; ipv4_cnt <= 8; ipv4_cnt++)
+ for (ipv6_cnt = 1; ipv6_cnt <= 8; ipv6_cnt++)
+ for (synv4_idx = 0; synv4_idx < ipv4_cnt; synv4_idx++)
+ for (synv6_idx = 0; synv6_idx < ipv6_cnt; synv6_idx++) {
+ ipc_ut_prepare_garbage_filter_dl_gpd_list(ipv4_cnt, synv4_idx, ipv6_cnt, synv6_idx, &head_gpd, &tail_gpd);
+
+ ipc_do_dl_filter(IPC_IP_TYPE_IPV4, IPC_UT_NETID_START, IPC_UT_PDN_ID, &head_gpd, &tail_gpd);
+
+ if (NULL == head_gpd ||
+ NULL == tail_gpd ||
+ ipv4_cnt + ipv6_cnt - ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt
+ != ipc_ut_gpd_list_count(head_gpd, tail_gpd)) {
+ utELOG("Not trap Garbage packets!\r\n");
+ return KAL_FALSE;
+ }
+
+ if (ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt > 0 &&
+ (NULL == ipc_ut_ul_ebi_head_gpd ||
+ NULL == ipc_ut_ul_ebi_tail_gpd ||
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt
+ != ipc_ut_gpd_list_count(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd) )) {
+ utELOG("Responsing TCP RST packets has something wrong!!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+
+ if (NULL != ipc_ut_ul_ebi_head_gpd) {
+ UT_ASSERT(NULL != ipc_ut_ul_ebi_tail_gpd);
+
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ }
+
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt = 0;
+ }
+
+
+ /*
+ * Deregister half of filters
+ */
+ offset = 0;
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_FILTER_SET_ID;
+ filter_set.filter_cnt = 64;
+ filter_set.uplink = KAL_FALSE;
+
+ kal_mem_cpy(ipc_ut_garbage_filter_buf_s, &filter_set, sizeof(filter_set));
+ offset += sizeof(filter_set);
+
+ for (i = 0; i < 64; i++) {
+ filter_id = i << 1;
+
+ kal_mem_cpy(ipc_ut_garbage_filter_buf_s + offset, &filter_id, sizeof(filter_id));
+ offset += sizeof(filter_id);
+ }
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ipc_ut_garbage_filter_buf_s + 4, sizeof(filter_set) - 4);
+
+ peer_buff_ptr = construct_peer_buff(sizeof(kal_uint8)*(offset-sizeof(filter_set)), 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+ kal_mem_cpy(pdu_ptr, ipc_ut_garbage_filter_buf_s + sizeof(filter_set), offset - sizeof(filter_set));
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_DEREGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * Register filter_id 1~64. Half of them should not be removed yet.
+ */
+ offset = 0;
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_FILTER_SET_ID;
+ filter_set.filter_cnt = 64;
+ filter_set.uplink = KAL_FALSE;
+
+ kal_mem_cpy(ipc_ut_garbage_filter_buf_s, &filter_set, sizeof(filter_set));
+ offset += sizeof(filter_set);
+
+ for (i = 0; i < 64; i++) {
+ kal_mem_set(&filter, 0,sizeof(filter));
+
+ filter.filter_id = i;
+ filter.ip_type = IPC_IP_TYPE_IPV4;
+ filter.protocol = IPC_HDR_PROT_TCP;
+ filter.dst_port = i;
+ filter.magic_code = 168;
+
+ kal_mem_cpy(ipc_ut_garbage_filter_buf_s + offset, &filter, sizeof(filter));
+ offset += sizeof(filter);
+ }
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ipc_ut_garbage_filter_buf_s + 4, sizeof(filter_set) - 4);
+
+ peer_buff_ptr = construct_peer_buff(sizeof(kal_uint8)*(offset-sizeof(filter_set)), 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+ kal_mem_cpy(pdu_ptr, ipc_ut_garbage_filter_buf_s + sizeof(filter_set), offset - sizeof(filter_set));
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_REGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * Deregister all filters.
+ */
+ offset = 0;
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_FILTER_SET_ID;
+ filter_set.filter_cnt = -1;
+ filter_set.uplink = KAL_FALSE;
+
+ kal_mem_cpy(ipc_ut_garbage_filter_buf_s, &filter_set, sizeof(filter_set));
+ offset += sizeof(filter_set);
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ipc_ut_garbage_filter_buf_s + 4, sizeof(filter_set) - 4);
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_DEREGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * pfm_register_filter_msg & pfm_register_filter_with_info_msg
+ */
+ kal_mem_set(&rules, 0, sizeof(rules));
+ rules.features = IPC_FILTER_FEATURE_BWM;
+ rules.priority = IPC_UT_LOW_PRIORITY;
+ rules.valid_fields = (IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT);
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.src_port = 67;
+ pfm_register_filter_msg(0, 0, KAL_TRUE, &rules, MOD_NIL, NULL);
+ pfm_register_filter_with_info_msg(0, 0, KAL_TRUE, &rules, MOD_NIL, NULL);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_downlink_multiple_ps(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 proto_idx[] = {0, 1};
+ kal_bool result;
+ ilm_struct ilm;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Simulate DL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink_multiple_ps(IPC_UT_PDN_ID, head_gpd, tail_gpd, idx);
+
+ if ( (0 != ipc_ut_dl_callback_gpd_cnt) ||
+ (0 != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is forwarded before PDN binding! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Simulate DL traffic to IPCore : All GPDs should be forward to DL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+ kal_uint32 total_cnt;
+ kal_uint32 spd_payload_cnt;
+ kal_uint32 i;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink_multiple_ps(IPC_UT_PDN_ID, head_gpd, tail_gpd, idx);
+
+ if (1 == spd) {
+ total_cnt = ipv4_cnt + ipv6_cnt + 1/*spd*/;
+ spd_payload_cnt = ipv4_cnt + ipv6_cnt;
+ if (1 == spd_igr_bit) {
+ kal_uint32 igr_payload_cnt = 0;
+ for (i = 0; i < (ipv4_cnt + ipv6_cnt); i++) {
+ igr_payload_cnt += ipc_ut_spd_packet_igr_s[i];
+ }
+ if ((ipv4_cnt + ipv6_cnt) == igr_payload_cnt) {
+ /* All SPD's payloads has been ignored. */
+ total_cnt--;
+ spd_payload_cnt = 0;
+ } else {
+ spd_payload_cnt -= igr_payload_cnt;
+ }
+ }
+ } else {
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ spd_payload_cnt = 0;
+ }
+
+ if ( (total_cnt != ipc_ut_dl_callback_gpd_cnt) ||
+ (spd_payload_cnt != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is NOT forwarded to bound handler! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ ipc_ut_free_gpd_list(head_gpd, tail_gpd);
+ return KAL_FALSE;
+ }
+
+ /* DL callback is correctly called : all GPDs are released */
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Simulate DL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint32 alignment;
+ kal_uint32 unite;
+ kal_uint32 spd;
+ kal_uint32 spd_igr_bit;
+ kal_uint32 spd_position;
+
+ for (unite = 0 ; unite < 2 ; unite ++)
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (spd = 0; spd < 1; spd++)
+ for (spd_igr_bit = 0; spd_igr_bit < 2; spd_igr_bit++)
+ for (spd_position = 0; spd_position < 3; spd_position++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ if (0 == spd && ( 0 < spd_igr_bit || 0 < spd_position )) continue;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_gpd_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ (unite == 0)?0:10,
+ alignment,
+ &head_gpd,
+ &tail_gpd,
+ NULL,
+ NULL,
+ spd,
+ spd_igr_bit,
+ spd_position);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_downlink_multiple_ps(IPC_UT_PDN_ID, head_gpd, tail_gpd, idx);
+
+ if ( (0 != ipc_ut_dl_callback_gpd_cnt) ||
+ (0 != ipc_ut_dl_callback_spd_payload_cnt) ) {
+ utELOG("DL GPD is forwarded after PDN deactivation! (SPD:%d, IGR:%d)\r\n", spd, spd_igr_bit);
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_uplink_multiple_ps(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 blocked_cnt = 0;
+ ipc_io_request_t *ior;
+ ipc_ut_netif_t *net;
+ kal_bool result;
+ kal_uint32 idx;
+ kal_uint8 proto_idx[] = {0, 1};
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ ilm_struct ilm;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Simulate UL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_gpd, &tail_gpd, &ior);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (0 != ipc_ut_ul_gpd_cnt) {
+ utELOG("UL GPD is forwarded before PDN binding! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Simulate UL traffic to IPCore : All GPDs should be forward to UL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_gpd, &tail_gpd, &ior);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (ipv4_cnt + ipv6_cnt != ipc_ut_ul_gpd_cnt) {
+ utELOG("UL GPD is forwarded to bound handler! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Simulate UL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ ipc_ut_prepare_ul_gpd_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_gpd, &tail_gpd, &ior);
+
+ if (NULL == ior) {
+ utELOG("UL packet prepare failed!\r\r");
+ return KAL_FALSE;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_uplink(net->handle, ior);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (0 != ipc_ut_ul_gpd_cnt) {
+ utELOG("UL GPD is forwarded after PDN deactivation! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_free_gpd_list(NULL, NULL);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_send_ul_pkt_multiple_ps(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint8 *ip_header;
+ kal_uint32 total_length;
+ kal_uint8 *udp_header;
+ kal_uint32 udp_length;
+ kal_uint32 ul_total_length;
+ kal_bool result;
+ kal_uint32 idx;
+ kal_uint8 proto_idx[] = {0, 1};
+
+ kal_uint32 to_generate_hdr;
+ ipc_pkt_t pkt;
+ ipc_hdr_t hdr;
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for ( to_generate_hdr = 0 ; to_generate_hdr < 2 ; to_generate_hdr ++ ) {
+ qbm_gpd *curr_gpd;
+ kal_uint32 isGPD;
+ kal_uint32 pktcnt;
+ kal_uint32 alignment;
+
+ ip_header = ipc_ut_ipv4_dns_packet;
+ total_length = sizeof(ipc_ut_ipv4_dns_packet);
+ udp_header = IPC_HDR_V4_GET_NHPTR(ip_header);
+ udp_length = total_length - IPC_HDR_V4_GET_IHL(ip_header);
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (isGPD = 0 ; isGPD < 2 ; isGPD ++)
+ for (pktcnt = 1 ; pktcnt < 4 ; pktcnt ++) {
+ /* IP/UDP Header information */
+ hdr.ip_type = IPC_IP_TYPE_IPV4;
+ hdr.src_addr = IPC_HDR_V4_GET_SRC_ADDR(ip_header);
+ hdr.dst_addr = IPC_HDR_V4_GET_DST_ADDR(ip_header);
+ hdr.src_port = IPC_HDR_UDP_GET_SRC_PORT(udp_header);
+ hdr.dst_port = IPC_HDR_UDP_GET_DST_PORT(udp_header);
+ hdr.dscp_tc = 0;
+
+ /* Generate Packet */
+ if (0 == isGPD) {
+ pkt.isGPD = KAL_FALSE;
+ pkt.data = (0 == to_generate_hdr) ? ip_header : udp_header + IPC_HDR_UDP_HEADER_SIZE;
+ pkt.data_len = (0 == to_generate_hdr) ? total_length : udp_length - IPC_HDR_UDP_HEADER_SIZE;
+ } else {
+ pkt.isGPD = KAL_TRUE;
+ /* Using "dl_gpd_list" preparing to generate packet (which is more suitable for this case) */
+ ipc_ut_prepare_dl_gpd_list(pktcnt,
+ 0,
+ KAL_TRUE,
+ (0 == to_generate_hdr)?KAL_TRUE:KAL_FALSE,
+ 0,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0, /* We does NOT divide packet in pieces for following comparison */
+ alignment,
+ &(pkt.head),
+ &(pkt.tail),
+ NULL,
+ NULL,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0);
+ }
+
+ result = ipc_send_ul_pkt_multiple_ps(
+ &pkt,
+ (0 == to_generate_hdr)?NULL:&hdr,
+ IPC_UT_UL_EBI,
+ idx);
+
+ if (!result) {
+ utELOG("[4] ipc_send_ul_pkt() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (NULL == ipc_ut_ul_ebi_head_gpd || NULL == ipc_ut_ul_ebi_tail_gpd) {
+ utELOG("[4] ipc_send_ul_pkt() failed! no UL SDU sent.\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Run GPD copy and content check */
+ curr_gpd = ipc_ut_ul_ebi_head_gpd;
+ do {
+ if (!ipc_gpd_copy(ipc_ut_checksum_buf_s,
+ sizeof(ipc_ut_checksum_buf_s),
+ &ul_total_length,
+ curr_gpd,
+ curr_gpd)) {
+ utELOG("[4] ipc_gpd_copy() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (ul_total_length != total_length) {
+ utELOG("[4] ipc_send_ul_pkt() IPv4 total_length mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ if ( !IPC_HDR_IS_V4(ipc_ut_checksum_buf_s) ||
+ total_length != IPC_HDR_V4_GET_TOTAL_LENGTH(ipc_ut_checksum_buf_s) ||
+ !IPC_EQ_V4_ADDR(IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_checksum_buf_s), IPC_HDR_V4_GET_SRC_ADDR(ip_header)) ||
+ !IPC_EQ_V4_ADDR(IPC_HDR_V4_GET_DST_ADDR(ipc_ut_checksum_buf_s), IPC_HDR_V4_GET_DST_ADDR(ip_header)) ||
+ IPC_HDR_PROT_UDP != IPC_HDR_V4_GET_PROTOCOL(ipc_ut_checksum_buf_s) ||
+ 0 != ipc_utils_calc_ipv4_checksum(ipc_ut_checksum_buf_s) ) {
+ utELOG("[4] ipc_send_ul_pkt() wrong IPv4 header!\r\n");
+ return KAL_FALSE;
+ }
+ if ( kal_mem_cmp(IPC_HDR_V4_GET_NHPTR(ipc_ut_checksum_buf_s), udp_header, udp_length) ) {
+ utELOG("[4] ipc_send_ul_pkt() UDP header or data mismatched!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check next GPD */
+ if (ipc_ut_ul_ebi_tail_gpd == curr_gpd) {
+ curr_gpd = NULL;
+ } else {
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+ } while (curr_gpd);
+
+ /* Free GPD list */
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ ipc_ut_ul_proto_idx = IPC_UT_INVALID_UL_PROTO_IDX;
+ }
+
+ ip_header = ipc_ut_ipv6_mdns_packet;
+ total_length = sizeof(ipc_ut_ipv6_mdns_packet);
+ udp_header = IPC_HDR_V6_GET_NHPTR(ip_header);
+ udp_length = total_length - IPC_HDR_V6_HEADER_SIZE;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (isGPD = 0 ; isGPD < 2 ; isGPD ++)
+ for (pktcnt = 1 ; pktcnt < 4 ; pktcnt ++) {
+ /* IP/UDP Header information */
+ hdr.ip_type = IPC_IP_TYPE_IPV6;
+ hdr.src_addr = IPC_HDR_V6_GET_SRC_ADDR(ip_header);
+ hdr.dst_addr = IPC_HDR_V6_GET_DST_ADDR(ip_header);
+ hdr.src_port = IPC_HDR_UDP_GET_SRC_PORT(udp_header);
+ hdr.dst_port = IPC_HDR_UDP_GET_DST_PORT(udp_header);
+ hdr.dscp_tc = 0;
+
+ /* Generate Packet */
+ if (0 == isGPD) {
+ pkt.isGPD = KAL_FALSE;
+ pkt.data = (0 == to_generate_hdr) ? ip_header : (udp_header + IPC_HDR_UDP_HEADER_SIZE);
+ pkt.data_len = (0 == to_generate_hdr) ? total_length : udp_length - IPC_HDR_UDP_HEADER_SIZE;
+
+ } else {
+ pkt.isGPD = KAL_TRUE;
+ /* Using "dl_gpd_list" preparing to generate packet (which is more suitable for this case) */
+ ipc_ut_prepare_dl_gpd_list(0,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ pktcnt,
+ 0,
+ KAL_TRUE,
+ (0 == to_generate_hdr)?KAL_TRUE:KAL_FALSE,
+ 0, /* We does NOT divide packet in pieces for following comparison */
+ alignment,
+ &(pkt.head),
+ &(pkt.tail),
+ NULL,
+ NULL,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0);
+ }
+
+ result = ipc_send_ul_pkt_multiple_ps(
+ &pkt,
+ (0 == to_generate_hdr)?NULL:&hdr,
+ IPC_UT_UL_EBI,
+ idx);
+
+ if (!result) {
+ utELOG("[6] ipc_send_ul_pkt() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (NULL == ipc_ut_ul_ebi_head_gpd || NULL == ipc_ut_ul_ebi_tail_gpd) {
+ utELOG("[6] ipc_send_ul_pkt() failed! no UL SDU sent.\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Run GPD copy and content check */
+ curr_gpd = ipc_ut_ul_ebi_head_gpd;
+ do {
+ if (!ipc_gpd_copy(ipc_ut_checksum_buf_s,
+ sizeof(ipc_ut_checksum_buf_s),
+ &ul_total_length,
+ curr_gpd,
+ curr_gpd)) {
+ utELOG("[6] ipc_gpd_copy() failed!\r\n");
+ return KAL_FALSE;
+ }
+ if (ul_total_length != total_length) {
+ utELOG("[6] ipc_send_ul_pkt() IPv6 total_length mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ if ( !IPC_HDR_IS_V6(ipc_ut_checksum_buf_s) ||
+ !IPC_EQ_V6_ADDR(IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_checksum_buf_s), IPC_HDR_V6_GET_SRC_ADDR(ip_header)) ||
+ !IPC_EQ_V6_ADDR(IPC_HDR_V6_GET_DST_ADDR(ipc_ut_checksum_buf_s), IPC_HDR_V6_GET_DST_ADDR(ip_header)) ||
+ IPC_HDR_PROT_UDP != IPC_HDR_V6_GET_NH_TYPE(ipc_ut_checksum_buf_s) ) {
+ utELOG("[6] ipc_send_ul_pkt() wrong IPv6 header!\r\n");
+ return KAL_FALSE;
+ }
+ if ( kal_mem_cmp(IPC_HDR_V6_GET_NHPTR(ipc_ut_checksum_buf_s), udp_header, udp_length) ) {
+ utELOG("[6] ipc_send_ul_pkt() UDP header or data mismatched!\r\n");
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_ebi_tail_gpd == curr_gpd) {
+ curr_gpd = NULL;
+ } else {
+ curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(curr_gpd);
+ }
+ } while (curr_gpd);
+
+ /* Free GPD list */
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+ ipc_ut_ul_proto_idx = IPC_UT_INVALID_UL_PROTO_IDX;
+ }
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_meta_uplink(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 blocked_cnt = 0;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ kal_uint32 idx;
+ kal_uint8 proto_idx[] = {0, 1};
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ ilm_struct ilm;
+ kal_uint8 test_stage;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Simulate UL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_BEFORE_BINDING;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Before Bind] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_prepare_ul_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded before PDN binding! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Simulate UL traffic to IPCore : All GPDs should be forward to UL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_BINDING;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Binded] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_prepare_ul_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (total_cnt != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded to bound handler! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ if (IPC_UT_PDN_ID != ipc_ut_ul_pdn_id) {
+ utELOG("UL META is forwarded with wrong PDN ID! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ if (idx != ipc_ut_ul_proto_idx) {
+ utELOG("UL META is forwarded with wrong Protocol ID! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Simulate UL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_UNBINDING;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Deactivated] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_prepare_ul_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded after PDN deactivation! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_did_downlink(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 proto_idx[] = {0, 1};
+ kal_bool result;
+ ilm_struct ilm;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* IPCORE may send UL traffic in disconnected state */
+ ipc_ut_reset_ul_info();
+
+ /* Simulate DL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Before Bind] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ KAL_FALSE);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Simulate DL traffic to IPCore : All GPDs should be forward to DL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 total_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Binded] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ KAL_FALSE);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx);
+
+ if ( (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (total_cnt != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* DL callback is correctly called : all GPDs are released */
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Simulate DL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Deactivated] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ KAL_FALSE);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded after PDN deactivation!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_uplink_filter_meta(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 callback_with_info;
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 ipv4_filter_cnt;
+ kal_uint32 ipv6_filter_cnt;
+ kal_uint32 with_wildcard;
+ kal_uint32 with_bwm;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint8 matched_filter_idx_v6;
+ kal_uint8 test_stage;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 4; ipv4_cnt+=2)
+ for (ipv6_cnt = 2; ipv6_cnt <= 4; ipv6_cnt+=2)
+ for (ipv4_filter_cnt = 4; ipv4_filter_cnt <= 4; ipv4_filter_cnt+=4)
+ for (ipv6_filter_cnt = 4; ipv6_filter_cnt <= 4; ipv6_filter_cnt+=4)
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++)
+ for (with_wildcard = 0; with_wildcard < 2; with_wildcard++)
+ for (with_bwm = 0; with_bwm < 2; with_bwm++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < ipv4_filter_cnt; matched_filter_idx_v4++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < ipv6_filter_cnt; matched_filter_idx_v6++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("ifo(%d) v4Cnt(%d) v6Cnt(%d) v4FltCnt(%d) v6FltCnt(%d) withWC(%d) withBWM(%d) IPType(%d) v4Idx(%d) v6Idx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, ipv4_filter_cnt , ipv6_filter_cnt, with_wildcard, with_bwm, idx, matched_filter_idx_v4, matched_filter_idx_v6);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+
+ /* Install UL filter for each test loop */
+ ipc_ut_install_ul_filters(callback_with_info, KAL_TRUE, ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm, matched_filter_idx_v4, matched_filter_idx_v6, IPC_UT_LHIF_NETID_START);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /*
+ * Before activate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN NOT be forwarded to UPCM
+ */
+ {
+ kal_uint32 dhcpv4_idx;
+ kal_uint32 dhcpv6_idx;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_BEFORE_BINDING;
+
+ for (dhcpv4_idx = 0 ; ((ipv4_cnt == 0 && dhcpv4_idx == 0) || (dhcpv4_idx < ipv4_cnt)) ; dhcpv4_idx+=2)
+ for (dhcpv6_idx = 0 ; ((ipv6_cnt == 0 && dhcpv6_idx == 0) || (dhcpv6_idx < ipv6_cnt)) ; dhcpv6_idx+=2) {
+ kal_uint32 expected_ul_v4_filter_out_cnt;
+ kal_uint32 expected_ul_v6_filter_out_cnt;
+ kal_uint32 expected_ul_filter_out_cnt;
+
+ utDLOG("@ Before activation : dhcpv4Idx(%d), dhcpv6Idx(%d)\r\n",
+ dhcpv4_idx, dhcpv6_idx);
+
+
+ ipc_ut_prepare_ul_meta_list(KAL_TRUE, ipv4_cnt, dhcpv4_idx, ipv6_cnt, dhcpv6_idx, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * 1. If least 1 IPv4 filter rule & 1 IPv4 gpd -> least 1 packet (DHCPv4) will be filtered out
+ * 2. If least 1 IPv6 filter rule & 1 IPv6 gpd -> least 1 packet (DHCPv6) will be filtered out
+ * 3. NO any packet will been forwarded to network before PDN bind
+ */
+ if (with_wildcard) {
+ expected_ul_v4_filter_out_cnt = ipv4_cnt - (((ipv4_cnt > 0) && with_bwm)?1:0);
+ expected_ul_v6_filter_out_cnt = ipv6_cnt - (((ipv6_cnt > 0) && with_bwm)?1:0);
+ } else {
+ expected_ul_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (!with_bwm) )? 1:0;
+ expected_ul_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (!with_bwm) )?1:0;
+ }
+ expected_ul_filter_out_cnt = expected_ul_v4_filter_out_cnt + expected_ul_v6_filter_out_cnt;
+
+ if (callback_with_info && expected_ul_filter_out_cnt > 0) {
+ if (ipc_ut_ul_filter_info.netif_id != net->conf.netif_id) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != ipc_get_ip_id(net->handle)) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_gpd_cnt != expected_ul_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded to network before valid PDN binding!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN
+ *
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * After PDN binding activate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN be forwarded to UPCM
+ */
+ {
+ kal_uint32 dhcpv4_idx;
+ kal_uint32 dhcpv6_idx;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_BINDING;
+ for (dhcpv4_idx = 0 ; ((ipv4_cnt == 0 && dhcpv4_idx == 0) || (dhcpv4_idx < ipv4_cnt)) ; dhcpv4_idx+=2)
+ for (dhcpv6_idx = 0 ; ((ipv6_cnt == 0 && dhcpv6_idx == 0) || (dhcpv6_idx < ipv6_cnt)) ; dhcpv6_idx+=2) {
+ kal_uint32 expected_ul_v4_filter_out_cnt;
+ kal_uint32 expected_ul_v6_filter_out_cnt;
+ kal_uint32 expected_ul_filter_out_cnt;
+ kal_uint32 expected_ul_cnt;
+
+ utDLOG("@ PDN connected : dhcpv4Idx(%d), dhcpv6Idx(%d)\r\n",
+ dhcpv4_idx, dhcpv6_idx);
+
+ ipc_ut_prepare_ul_meta_list(KAL_TRUE, ipv4_cnt, dhcpv4_idx, ipv6_cnt, dhcpv6_idx, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * 1. If least 1 IPv4 filter rule & 1 IPv4 gpd -> least 1 packet (DHCPv4) will be filtered out
+ * 2. If least 1 IPv6 filter rule & 1 IPv6 gpd -> least 1 packet (DHCPv6) will be filtered out
+ * 3. All non-filtered GPDs with matched IP type will been forwarded to network
+ */
+ if (with_wildcard) {
+ expected_ul_v4_filter_out_cnt = ipv4_cnt - (((ipv4_cnt > 0) && with_bwm)?1:0);
+ expected_ul_v6_filter_out_cnt = ipv6_cnt - (((ipv6_cnt > 0) && with_bwm)?1:0);
+ } else {
+ expected_ul_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (!with_bwm) )? 1:0;
+ expected_ul_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (!with_bwm) )?1:0;
+ }
+ expected_ul_filter_out_cnt = expected_ul_v4_filter_out_cnt + expected_ul_v6_filter_out_cnt;
+
+ if (callback_with_info && expected_ul_filter_out_cnt > 0) {
+ if (ipc_ut_ul_filter_info.netif_id != net->conf.netif_id) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != ipc_get_ip_id(net->handle)) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_gpd_cnt != expected_ul_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ expected_ul_cnt = (bind_req->ip_addr.ip_addr_type == IPV4_ADDR_TYPE)?(ipv4_cnt - expected_ul_v4_filter_out_cnt):
+ (bind_req->ip_addr.ip_addr_type == IPV6_ADDR_TYPE)?(ipv6_cnt - expected_ul_v6_filter_out_cnt):
+ ((ipv4_cnt + ipv6_cnt) - (expected_ul_filter_out_cnt));
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (expected_ul_cnt != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is not forwarded to network correctly!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if ((expected_ul_cnt > 0) &&
+ (ipc_ut_ul_pdn_id != bind_req->pdn_id)) {
+ utELOG("UL META is not forwarded to correct network PDN!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * After deactivate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN NOT be forwarded to UPCM
+ */
+ {
+ kal_uint32 dhcpv4_idx;
+ kal_uint32 dhcpv6_idx;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_UNBINDING;
+ for (dhcpv4_idx = 0 ; ((ipv4_cnt == 0 && dhcpv4_idx == 0) || (dhcpv4_idx < ipv4_cnt)) ; dhcpv4_idx+=2)
+ for (dhcpv6_idx = 0 ; ((ipv6_cnt == 0 && dhcpv6_idx == 0) || (dhcpv6_idx < ipv6_cnt)) ; dhcpv6_idx+=2) {
+ kal_uint32 expected_ul_v4_filter_out_cnt;
+ kal_uint32 expected_ul_v6_filter_out_cnt;
+ kal_uint32 expected_ul_filter_out_cnt;
+
+ utDLOG("@ After deactivation : dhcpv4Idx(%d), dhcpv6Idx(%d)\r\n",
+ dhcpv4_idx, dhcpv6_idx);
+
+ ipc_ut_prepare_ul_meta_list(KAL_TRUE, ipv4_cnt, dhcpv4_idx, ipv6_cnt, dhcpv6_idx, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * 1. If least 1 IPv4 filter rule & 1 IPv4 gpd -> least 1 packet (DHCPv4) will be filtered out
+ * 2. If least 1 IPv6 filter rule & 1 IPv6 gpd -> least 1 packet (DHCPv6) will be filtered out
+ * 3. NO any packet will been forwarded to network after PDN deactivation
+ */
+ if (with_wildcard) {
+ expected_ul_v4_filter_out_cnt = ipv4_cnt - (((ipv4_cnt > 0) && with_bwm)?1:0);
+ expected_ul_v6_filter_out_cnt = ipv6_cnt - (((ipv6_cnt > 0) && with_bwm)?1:0);
+ } else {
+ expected_ul_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (!with_bwm) )? 1:0;
+ expected_ul_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (!with_bwm) )?1:0;
+ }
+ expected_ul_filter_out_cnt = expected_ul_v4_filter_out_cnt + expected_ul_v6_filter_out_cnt;
+
+ if (callback_with_info && expected_ul_filter_out_cnt > 0) {
+ if (ipc_ut_ul_filter_info.netif_id != net->conf.netif_id) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != ipc_get_ip_id(net->handle)) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ } else {
+ if (ipc_ut_ul_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+ }
+
+ if (ipc_ut_ul_filter_gpd_cnt != expected_ul_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded to network before valid PDN binding!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ return KAL_FALSE;
+ }
+
+
+ /* Uninstall UL filters after test procedure */
+ ipc_ut_uninstall_ul_filters(ipv4_filter_cnt, ipv6_filter_cnt, with_wildcard, with_bwm);
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_did_downlink_wo_dhcp4c(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic to IPCore : Before PDN binding, all DIDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Before Bind] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n", did_igr_bit);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Simulate DL traffic to IPCore : All DIDs should be forward to DL callback regardless of IP types (IPv4/IPv6)
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+ kal_uint32 total_cnt;
+ kal_uint32 i;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Binded] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+
+ if (1 == did_igr_bit) {
+ kal_uint32 ipv4_igr_cnt = 0;
+ kal_uint32 ipv6_igr_cnt = 0;
+
+ for (i = 0; i < ipv4_cnt; i++) {
+ ipv4_igr_cnt += ipc_ut_did_packet_igr_s[i];
+ }
+ for (i = 0; i < ipv6_cnt; i++) {
+ ipv6_igr_cnt += ipc_ut_did_packet_igr_s[i];
+ }
+ if ( (ipv4_igr_cnt) &&
+ (ipv4_cnt == ipv4_igr_cnt) ) {
+ /* All IPv4 DID pkt has been ignored. */
+ did_cnt --;
+ }
+ if ( (ipv6_igr_cnt) &&
+ (ipv6_cnt == ipv6_igr_cnt) ) {
+ /* All IPv6 DID pkt has been ignored. */
+ did_cnt --;
+ }
+
+ total_cnt -= (ipv4_igr_cnt + ipv6_igr_cnt);
+ if (!did_cnt) {
+ UT_ASSERT(total_cnt == 0);
+ }
+ }
+
+ if ( (total_cnt != ipc_ut_dl_callback_did_pkt_cnt) ||
+ (did_cnt != ipc_ut_dl_callback_did_cnt) ) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* DL callback is correctly called : all GPDs are released */
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all DIDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 total_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Deactivated] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded after PDN deactivation!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_did_downlink_w_dhcp4c(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+/* Note : This test case will trigger NMU to allocate NET_UL GPD,
+ Please be aware of that NET_UL GPD is only used in MD-only load.
+*/
+
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = IPC_F_DHCP4C;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic to IPCore : Before PDN binding, all DIDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Before Bind] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Simulate DL traffic to IPCore
+ *
+ * - 1st IPv4 DID is IPv4 DHCP packet and will be sent to DHCP4C module
+ * - All other DIDs should be forward to DL callback regardless of IP types (IPv4/IPv6)
+ *
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+ kal_uint32 total_cnt;
+ kal_uint32 i;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Binded] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+// (unite == 0)?0:10,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* In Gen97, we add session state in ipc_on_did_downlink() before forwarding data to bound interface.
+ * If session is not in link up state, then IPCore should not send any packets to bound interface.
+ * At this case, if there is no IPv4 packets, then the session will stay in bind state.
+ * So IPCore will drop all packets in this state.
+ */
+
+ if ((IPV4_ADDR_TYPE == ip_types[idx]) || (IPV4V6_ADDR_TYPE == ip_types[idx])) {
+ if ((0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt)) {
+ utELOG("DL DID is forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+ } else {
+ if ((total_cnt != ipc_ut_dl_callback_did_pkt_cnt) ||
+ (did_cnt != ipc_ut_dl_callback_did_cnt)) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 total_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Deactivated] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+// (unite == 0)?0:10,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded after PDN deactivation!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+static kal_bool ipc_ut_fin_ack_filter_netif_attach(void) {
+ ipc_conf_t config = {0};
+ ipc_handle_t p_handle = NULL;
+ kal_bool ret = KAL_TRUE;
+
+ config.module_id = MOD_IPCORE;
+ config.netif_id = IPC_UT_LHIF_NETID_START;
+ config.features = 0;
+ config.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ config.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ config.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+
+ UT_ASSERT(KAL_TRUE == ipc_attach(&config, &p_handle));
+ UT_ASSERT(NULL != p_handle);
+ utDLOG("netif id = %d attach successfully", config.netif_id);
+
+ return KAL_TRUE;
+}
+
+static void ipc_ut_fin_ack_filter_did_verification(void) {
+ kal_uint8 *p_packet = NULL;
+ qbm_gpd *p_bd = NULL;
+ qbm_gpd *p_current = ipc_ut_ul_ebi_head_gpd;
+ kal_uint8 i = 0;
+ kal_bool is_check = KAL_FALSE;
+ kal_bool is_ipv4 = KAL_FALSE;
+
+ for (i = 0; i < ipc_ut_gpd_list_count(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd); i++) {
+ if (!QBM_DES_GET_BDP(ipc_ut_ul_ebi_head_gpd)) {
+ p_packet = QBM_DES_GET_DATAPTR(ipc_ut_ul_ebi_head_gpd);
+
+ if (sizeof(ipc_ut_ipv4_tcp_fin_ack_packet) == QBM_DES_GET_DATALEN(ipc_ut_ul_ebi_head_gpd)) {
+ is_check = KAL_TRUE;
+ is_ipv4 = KAL_TRUE;
+ } else if (sizeof(ipc_ut_ipv6_tcp_fin_ack_packet) == QBM_DES_GET_DATALEN(ipc_ut_ul_ebi_head_gpd)) {
+ is_check = KAL_TRUE;
+ is_ipv4 = KAL_FALSE;
+ }
+ } else {
+ p_bd = QBM_DES_GET_DATAPTR(ipc_ut_ul_ebi_head_gpd);
+
+ while (p_bd && (QBM_DES_GET_DATALEN(p_bd) == 0)) {
+ p_bd = (QBM_DES_GET_EOL(p_bd)) ? (NULL) : ((qbm_gpd*) QBM_DES_GET_NEXT(p_bd));
+ }
+
+ if (NULL == p_bd) {
+ ipc_ut_free_gpd_list(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ }
+ p_packet = QBM_DES_GET_DATAPTR(p_bd);
+
+ if (sizeof(ipc_ut_ipv4_tcp_fin_ack_packet) == QBM_DES_GET_DATALEN(ipc_ut_ul_ebi_head_gpd)) {
+ is_check = KAL_TRUE;
+ is_ipv4 = KAL_TRUE;
+ } else if (sizeof(ipc_ut_ipv6_tcp_fin_ack_packet) == QBM_DES_GET_DATALEN(ipc_ut_ul_ebi_head_gpd)) {
+ is_check = KAL_TRUE;
+ is_ipv4 = KAL_FALSE;
+ }
+ p_packet = QBM_DES_GET_DATAPTR(p_bd);
+ }
+
+ if (is_check) {
+ kal_uint32 ip_header_len = is_ipv4 ? IPC_HDR_V4_HEADER_SIZE : IPC_HDR_V6_HEADER_SIZE;
+ kal_uint8 *src_addr = NULL;
+ kal_uint8 *dst_addr = NULL;
+ kal_uint32 tcp_header_len = 0;
+ kal_uint8 *p_src_tcp_header = NULL;
+ kal_uint8 *tcp_header = NULL;
+ kal_bool is_matched_packet = KAL_FALSE;
+
+ src_addr = IPC_HDR_V4_GET_SRC_ADDR(p_packet);
+ dst_addr = IPC_HDR_V4_GET_DST_ADDR(p_packet);
+
+ if (is_ipv4) {
+ if ((0 == kal_mem_cmp(IPC_HDR_V4_GET_SRC_ADDR(p_packet), IPC_HDR_V4_GET_DST_ADDR(ipc_ut_ipv4_tcp_fin_ack_packet), 4)) &&
+ (0 == kal_mem_cmp(IPC_HDR_V4_GET_DST_ADDR(p_packet), IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_ipv4_tcp_fin_ack_packet), 4))) {
+ is_matched_packet = KAL_TRUE;
+ p_src_tcp_header = ipc_ut_ipv4_tcp_fin_ack_packet + ip_header_len;
+ } else if ((0 == kal_mem_cmp(IPC_HDR_V4_GET_SRC_ADDR(p_packet), IPC_HDR_V4_GET_DST_ADDR(ipc_ut_ipv4_tcp_fin_ack_packet_2), 4)) &&
+ (0 == kal_mem_cmp(IPC_HDR_V4_GET_DST_ADDR(p_packet), IPC_HDR_V4_GET_SRC_ADDR(ipc_ut_ipv4_tcp_fin_ack_packet_2), 4))) {
+ is_matched_packet = KAL_TRUE;
+ p_src_tcp_header = ipc_ut_ipv4_tcp_fin_ack_packet_2 + ip_header_len;
+ }
+
+ if (is_matched_packet) {
+ tcp_header = p_packet + ip_header_len;
+ tcp_header_len = IPC_HDR_TCP_HEADER_SIZE;
+
+ UT_ASSERT((kal_uint8)(kal_uint8 *)IPC_HDR_V4_GET_PROTOCOL(p_packet) == (kal_uint8)IPC_HDR_PROT_TCP);
+ UT_ASSERT(IPC_HDR_TCP_GET_DST_PORT(tcp_header) == IPC_HDR_TCP_GET_SRC_PORT(p_src_tcp_header));
+ UT_ASSERT(IPC_HDR_TCP_GET_SRC_PORT(tcp_header) == IPC_HDR_TCP_GET_DST_PORT(p_src_tcp_header));
+ UT_ASSERT(IPC_HDR_TCP_GET_FLAGS(tcp_header) == (IPC_HDR_TCP_FLAG_RST | IPC_HDR_TCP_FLAG_ACK));
+ }
+ } else {
+ if ((0 == kal_mem_cmp(IPC_HDR_V6_GET_SRC_ADDR(p_packet), IPC_HDR_V6_GET_DST_ADDR(ipc_ut_ipv6_tcp_fin_ack_packet), 16)) &&
+ (0 == kal_mem_cmp(IPC_HDR_V6_GET_DST_ADDR(p_packet), IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_ipv6_tcp_fin_ack_packet), 16))) {
+ is_matched_packet = KAL_TRUE;
+ p_src_tcp_header = ipc_ut_ipv6_tcp_fin_ack_packet + ip_header_len;
+ } else if ((0 == kal_mem_cmp(IPC_HDR_V6_GET_SRC_ADDR(p_packet), IPC_HDR_V6_GET_DST_ADDR(ipc_ut_ipv6_tcp_fin_ack_packet_2), 16)) &&
+ (0 == kal_mem_cmp(IPC_HDR_V6_GET_DST_ADDR(p_packet), IPC_HDR_V6_GET_SRC_ADDR(ipc_ut_ipv6_tcp_fin_ack_packet_2), 16))) {
+ is_matched_packet = KAL_TRUE;
+ p_src_tcp_header = ipc_ut_ipv6_tcp_fin_ack_packet_2 + ip_header_len;
+ }
+
+ if (is_matched_packet) {
+ tcp_header = p_packet + ip_header_len;
+ tcp_header_len = IPC_HDR_TCP_HEADER_SIZE;
+ UT_ASSERT((kal_uint8)(kal_uint8 *)IPC_HDR_V6_GET_NH_TYPE(p_packet) == (kal_uint8)IPC_HDR_PROT_TCP);
+ UT_ASSERT(IPC_HDR_TCP_GET_DST_PORT(tcp_header) == IPC_HDR_TCP_GET_SRC_PORT(p_src_tcp_header));
+ UT_ASSERT(IPC_HDR_TCP_GET_SRC_PORT(tcp_header) == IPC_HDR_TCP_GET_DST_PORT(p_src_tcp_header));
+ UT_ASSERT(IPC_HDR_TCP_GET_FLAGS(tcp_header) == (IPC_HDR_TCP_FLAG_RST | IPC_HDR_TCP_FLAG_ACK));
+ }
+ }
+ }
+ p_current = p_current->p_next;
+ }
+ qbmt_dest_q(ipc_ut_ul_ebi_head_gpd, ipc_ut_ul_ebi_tail_gpd);
+ ipc_ut_ul_ebi_head_gpd = NULL;
+ ipc_ut_ul_ebi_tail_gpd = NULL;
+}
+
+kal_bool ipc_ut_fin_ack_filter_did(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 i = 0;
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ ipcore_upcm_pdn_bind_ind_struct *p_bind_req = NULL;
+ pfmApStatusInd *p_pfm_ap_ind_req = NULL;
+
+ /* initialize before test & reset IPCORE */
+ ipc_ut_init();
+ UT_ASSERT(KAL_TRUE == ipc_reset());
+ ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt = 0;
+ g_received_cnt = 0;
+
+ /* netif attach */
+ UT_ASSERT(KAL_TRUE == ipc_ut_fin_ack_filter_netif_attach());
+
+ /* IPv4 binding */
+ p_bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ p_bind_req->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_bind_req->pdn_id = IPC_UT_PDN_ID;
+ p_bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *) p_bind_req);
+ free_local_para((local_para_struct *)p_bind_req);
+
+ /* AP send suspend indication */
+ p_pfm_ap_ind_req = (pfmApStatusInd *)construct_local_para(sizeof(pfmApStatusInd), TD_RESET);
+ UT_ASSERT(NULL != p_pfm_ap_ind_req);
+ p_pfm_ap_ind_req->em_ap_status = PFM_AP_STATUS_SUSPEND;
+ p_pfm_ap_ind_req->bm_cmd = PFM_AP_CMD_FIN_ACK_REDUCTION;
+ UT_ASSERT(KAL_TRUE == msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_AP_STATUS_IND, (local_para_struct *)p_pfm_ap_ind_req, NULL));
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* Simulate DL traffic to IPCore : Before PDN binding, all DIDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 did_cnt = 0;
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+ kal_uint32 alignment = 0;
+ kal_uint32 did_igr_bit = 0;
+ kal_uint32 free_cnt = 0;
+
+ for (alignment = 0; alignment < 4; alignment++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@ [Before Bind] v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_pfm_fin_ack_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* verify filter result */
+ if (NULL != ipc_ut_ul_ebi_head_gpd) {
+ ipc_ut_fin_ack_filter_did_verification();
+ }
+ }
+ }
+
+ /* reset received count */
+ UT_ASSERT(g_received_cnt == ipc_ut_garbage_filter_expect_tcp_rst_gpd_cnt);
+ g_received_cnt = 0;
+
+ /* AP send wake up indication */
+ p_pfm_ap_ind_req = (pfmApStatusInd *)construct_local_para(sizeof(pfmApStatusInd), TD_RESET);
+ UT_ASSERT(NULL != p_pfm_ap_ind_req);
+ p_pfm_ap_ind_req->em_ap_status = PFM_AP_STATUS_WAKE_UP;
+ p_pfm_ap_ind_req->bm_cmd = PFM_AP_CMD_NONE;
+ msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_AP_STATUS_IND, (local_para_struct *)p_pfm_ap_ind_req, NULL);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* Simulate DL traffic to IPCore : Before PDN binding, all DIDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+ kal_uint32 free_cnt = 0;
+
+ for (alignment = 0; alignment < 4; alignment++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@ [Before Bind] v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_pfm_fin_ack_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (NULL != ipc_ut_ul_ebi_head_gpd) {
+ ipc_ut_fin_ack_filter_did_verification();
+ }
+ }
+ }
+ UT_ASSERT(0 == g_received_cnt);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+kal_bool ipc_ut_meta_uplink_dpfm(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 blocked_cnt = 0;
+ ipc_ut_netif_t *net;
+ ipc_ut_netif_t *net2;
+ ipc_ut_netif_t *net3;
+ kal_bool result;
+ kal_uint32 idx;
+ kal_uint8 proto_idx[] = {0, 1};
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ ilm_struct ilm;
+ kal_uint8 test_stage;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Activate DPFM */
+ ipc_ut_dpfm_is_activated_g = KAL_TRUE;
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() (DPFM device) */
+ net2 = &(ipc_ut_nets_s[1]);
+ kal_mem_set(net2, 0, sizeof(ipc_ut_netif_t));
+ net2->conf.module_id = MOD_IPCORE;
+ net2->conf.netif_id = IPC_UT_DPFM_NETID_START;
+ net2->conf.ul_reload_context = net2;
+ net2->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net2->conf.callback_context = net2;
+ net2->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net2->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did_dpfm;
+ net2->conf.features = IPC_F_LAN | IPC_F_TETHERING_ROUTE;
+ result = ipc_attach(&net2->conf, &net2->handle);
+ if (!result) {
+ utELOG("ipc_attach() (DPFM device) returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() (DPFM device 2) */
+ net3 = &(ipc_ut_nets_s[2]);
+ kal_mem_set(net3, 0, sizeof(ipc_ut_netif_t));
+ net3->conf.module_id = MOD_IPCORE;
+ net3->conf.netif_id = IPC_UT_DPFM_NETID_START + 1;
+ net3->conf.ul_reload_context = net3;
+ net3->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net3->conf.callback_context = net3;
+ net3->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net3->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did_dpfm;
+ net3->conf.features = IPC_F_LAN;
+ result = ipc_attach(&net3->conf, &net3->handle);
+ if (!result) {
+ utELOG("ipc_attach() (DPFM device 2) returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Simulate UL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 dpfm_device;
+ kal_uint32 netif_id;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ kal_uint8 non_ignore_cnt;
+ kal_uint8 allmatch;
+
+ test_stage = IPC_UT_STAGE_BEFORE_BINDING;
+ for (allmatch = 0; allmatch < 2; allmatch++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 8; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 8; ipv6_cnt++)
+ for (dpfm_device = 0; dpfm_device <= 1; dpfm_device++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ /* It should not generate DPFM related meta result which is comes from LAN NETIF without rounting fearue */
+ if (1 == dpfm_device && (ipv4_cnt >= 4 || ipv6_cnt >= 4)) continue;
+
+ utDLOG("@ [Before Bind] allmatch(%d), proto_idx(%d), v4_cnt(%d), v6_cnt(%d), dpfm_device(%d)\r\n", allmatch, idx, ipv4_cnt, ipv6_cnt, dpfm_device);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ netif_id = (dpfm_device == 0) ? IPC_UT_DPFM_NETID_START
+ : IPC_UT_DPFM_NETID_START + 1;
+
+ ipc_ut_prepare_ul_meta_list_dpfm(allmatch, ipv4_cnt, ipv6_cnt, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ non_ignore_cnt = 0;
+ /*
+ * if pkt_cnt is 8, then the last meta will be DPFM_ADD_CMD.
+ * And this command should be forwarded to UPCM.
+ */
+ if(ipv4_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+ if(ipv6_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_dl_callback_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (non_ignore_cnt != ipc_ut_ul_meta_non_igr_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_cnt) ) {
+ utELOG("Packet is forwarded before PDN binding! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Bind LAN netifs. */
+ ipc_bind_lan_netif(net2->conf.netif_id, net3->conf.netif_id);
+
+ /* Simulate UL traffic to IPCore : All GPDs should be forward to UL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 dpfm_pkt_cnt;
+ kal_uint32 lan_pkt_cnt;
+ kal_uint32 lan_did_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 dpfm_device;
+ kal_uint32 netif_id;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ kal_uint8 dpfm_cmd_cnt;
+ kal_uint8 dpfm_cmd_cnt_v4;
+ kal_uint8 dpfm_cmd_cnt_v6;
+ kal_uint8 non_ignore_cnt;
+ kal_uint8 allmatch;
+
+ test_stage = IPC_UT_STAGE_BINDING;
+ for (allmatch = 0; allmatch < 2; allmatch++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 8; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 8; ipv6_cnt++)
+ for (dpfm_device = 0; dpfm_device <= 1; dpfm_device++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ /* It should not generate DPFM related meta result which is comes from AP LAN NETIF(dpfm_device==1) without rounting fearue */
+ if (1 == dpfm_device && (ipv4_cnt >= 4 || ipv6_cnt >= 4)) continue;
+
+ utDLOG("@ [Binded] allmatch(%d), proto_idx(%d), v4_cnt(%d), v6_cnt(%d), dpfm_device(%d)\r\n", allmatch, idx, ipv4_cnt, ipv6_cnt, dpfm_device);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ netif_id = (dpfm_device == 0) ? IPC_UT_DPFM_NETID_START
+ : IPC_UT_DPFM_NETID_START + 1;
+
+ dpfm_cmd_cnt = 0;
+ dpfm_cmd_cnt_v4 = 0;
+ dpfm_cmd_cnt_v6 = 0;
+ if (ipv4_cnt > 5) {
+ dpfm_cmd_cnt_v4 += (ipv4_cnt-5);
+ }
+ if (ipv6_cnt > 5) {
+ dpfm_cmd_cnt_v6 += (ipv6_cnt-5);
+ }
+ dpfm_cmd_cnt = dpfm_cmd_cnt_v4 + dpfm_cmd_cnt_v6;
+
+ dpfm_pkt_cnt = 0;
+ if ((dpfm_device == 0) && (total_cnt > 0)) {
+ if ( allmatch == 1 ) {
+ if (ipv4_cnt > 4) {
+ dpfm_pkt_cnt += (ipv4_cnt - dpfm_cmd_cnt_v4 -1); /* minus 1 for DPFM_MATCH_BUT_NO_NAT MR */
+ } else {
+ dpfm_pkt_cnt += ipv4_cnt;
+ }
+ if (ipv6_cnt > 4) {
+ dpfm_pkt_cnt += (ipv6_cnt - dpfm_cmd_cnt_v6 -1); /* minus 1 for DPFM_MATCH_BUT_NO_NAT MR */
+ } else {
+ dpfm_pkt_cnt += ipv6_cnt;
+ }
+ } else if (allmatch == 0 ) {
+ if (ipv4_cnt >= 4) {
+ dpfm_pkt_cnt += 1; /*For DPFM_MATCH MR */
+ }
+ if (ipv6_cnt >= 4) {
+ dpfm_pkt_cnt += 1; /*For DPFM_MATCH MR */
+ }
+ }
+ }
+
+ non_ignore_cnt = 0;
+ /*
+ * if pkt_cnt is 8, then the last meta will be DPFM_ADD_CMD.
+ * And this command should be forwarded to UPCM.
+ */
+ if(ipv4_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+ if(ipv6_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+
+ lan_pkt_cnt = total_cnt - dpfm_pkt_cnt - dpfm_cmd_cnt;
+ lan_did_cnt = (lan_pkt_cnt == 0) ? 0 : 1;
+
+ ipc_ut_prepare_ul_meta_list_dpfm(allmatch, ipv4_cnt, ipv6_cnt, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_dl_callback_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ ((dpfm_pkt_cnt + non_ignore_cnt) != ipc_ut_ul_meta_non_igr_cnt) ||
+ (lan_pkt_cnt != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ||
+ (lan_did_cnt != ipc_ut_dl_callback_did_dpfm_cnt) ) {
+ utELOG("Packet is not forwarded correctly! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_meta_non_igr_cnt) {
+ if (dpfm_pkt_cnt != 0 && IPC_UT_PDN_ID != ipc_ut_ul_pdn_id) {
+ utELOG("UL META is forwarded with wrong PDN ID! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ if (dpfm_pkt_cnt != 0 && idx != ipc_ut_ul_proto_idx) {
+ utELOG("UL META is forwarded with wrong Protocol ID! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Unbind LAN netifs. */
+ ipc_unbind_lan_netif(net2->conf.netif_id, net3->conf.netif_id);
+
+ /* Simulate UL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 dpfm_device;
+ kal_uint32 netif_id;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ kal_uint8 allmatch;
+ kal_uint8 non_ignore_cnt;
+
+ test_stage = IPC_UT_STAGE_UNBINDING;
+ for (allmatch = 0; allmatch < 2; allmatch++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 8; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 8; ipv6_cnt++)
+ for (dpfm_device = 0; dpfm_device <= 1; dpfm_device++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ /* It should not generate DPFM related meta result which is comes from LAN NETIF without rounting fearue */
+ if (1 == dpfm_device && (ipv4_cnt >= 4 || ipv6_cnt >= 4)) continue;
+
+ utDLOG("@ [Deactivated] allmatch(%d), proto_idx(%d), v4_cnt(%d), v6_cnt(%d), dpfm_device(%d)\r\n", allmatch, idx, ipv4_cnt, ipv6_cnt, dpfm_device);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ netif_id = (dpfm_device == 0) ? IPC_UT_DPFM_NETID_START
+ : IPC_UT_DPFM_NETID_START + 1;
+
+ ipc_ut_prepare_ul_meta_list_dpfm(KAL_TRUE, ipv4_cnt, ipv6_cnt, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ non_ignore_cnt = 0;
+ /*
+ * if pkt_cnt is 8, then the last meta will be DPFM_ADD_CMD.
+ * And this command should be forwarded to UPCM.
+ */
+ if(ipv4_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+ if(ipv6_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_dl_callback_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (non_ignore_cnt != ipc_ut_ul_meta_non_igr_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_cnt) ) {
+ utELOG("Packet is forwarded after PDN deactivation! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_did_downlink_dpfm(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 idx;
+ ipc_ut_netif_t *net;
+ ipc_ut_netif_t *net2;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_bool result;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Activate DPFM
+ */
+ ipc_ut_dpfm_is_activated_g = KAL_TRUE;
+
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START + idx;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach() (DPFM device)
+ */
+ net2 = &(ipc_ut_nets_s[1]);
+ kal_mem_set(net2, 0, sizeof(ipc_ut_netif_t));
+ net2->conf.module_id = MOD_IPCORE;
+ net2->conf.netif_id = IPC_UT_DPFM_NETID_START;
+ net2->conf.ul_reload_context = net2;
+ net2->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net2->conf.callback_context = net2;
+ net2->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net2->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did_dpfm;
+ net2->conf.features = IPC_F_LAN | IPC_F_TETHERING_ROUTE;
+ result = ipc_attach(&net2->conf, &net2->handle);
+ if (!result) {
+ utELOG("ipc_attach() (DPFM device) returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic to IPCore : Before PDN binding, all DIDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Before Bind] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0, /* dhcpv4_idx */
+ KAL_FALSE, /* dnsv4_only */
+ KAL_FALSE, /* v4hdr_exist */
+ ipv6_cnt,
+ 0, /* dhcpv6_idx */
+ KAL_FALSE, /* dnsv6_only */
+ KAL_FALSE, /* v6hdr_exist */
+ 0, /* additional_bd_cnt */
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL, /* ipv4_invalid_packet_len */
+ NULL, /* ipv6_invalid_packet_len */
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n", did_igr_bit);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4/IPv4v6/IPv6 PDN with unspecified IP address.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Simulate DL traffic to IPCore
+ *
+ * - 1st IPv4 DID is IPv4 DHCP packet and will be sent to DPFM device
+ * - All other DIDs should be forward to DL callback regardless of IP types (IPv4/IPv6)
+ *
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+ kal_uint32 total_cnt;
+ kal_uint32 dpfm_pkt_cnt;
+ kal_uint32 dpfm_did_cnt;
+ kal_uint32 i;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Binded] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ dpfm_pkt_cnt = 0;
+ dpfm_did_cnt = 0;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0, /* dhcpv4_idx */
+ KAL_FALSE, /* dnsv4_only */
+ KAL_FALSE, /* v4hdr_exist */
+ ipv6_cnt,
+ 0, /* dhcpv6_idx */
+ KAL_FALSE, /* dnsv6_only */
+ KAL_FALSE, /* v6hdr_exist */
+ 0, /* additional_bd_cnt */
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL, /* ipv4_invalid_packet_len */
+ NULL, /* ipv6_invalid_packet_len */
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if (ipv4_cnt > 0) {
+ dpfm_did_cnt = 1;
+ dpfm_pkt_cnt = 1;
+
+ if(ipv6_cnt > 0){
+ dpfm_pkt_cnt++;
+ dpfm_did_cnt++; /* Because IPv4 and IPv6 are sent by two DIDs. */
+ }
+
+ if (1 == did_igr_bit) {
+ kal_uint32 ipv4_igr_cnt = 0;
+ kal_uint32 ipv6_igr_cnt = 0;
+
+ /* the first packet would be filtered out, so add the duplicate substration back. */
+ total_cnt ++;
+
+ for (i = 0; i < ipv4_cnt; i++) {
+ ipv4_igr_cnt += ipc_ut_did_packet_igr_s[i];
+ }
+ for (i = 0; i < ipv6_cnt; i++) {
+ ipv6_igr_cnt += ipc_ut_did_packet_igr_s[i];
+ }
+ if ( (ipv4_igr_cnt) &&
+ (ipv4_cnt == ipv4_igr_cnt) ) {
+ /* All IPv4 DID pkt has been ignored. */
+ did_cnt --;
+ }
+ if ( (ipv6_igr_cnt) &&
+ (ipv6_cnt == ipv6_igr_cnt) ) {
+ /* All IPv6 DID pkt has been ignored. */
+ did_cnt --;
+ }
+
+ total_cnt -= (ipv4_igr_cnt + ipv6_igr_cnt);
+ if (!did_cnt) {
+ UT_ASSERT(total_cnt == 0);
+ }
+ } else {
+ total_cnt -= dpfm_did_cnt;
+ if(ipv4_cnt == 1) {
+ /* All IPv4 DID pkt has been forward to LAN NETIF */
+ did_cnt --;
+ }
+ if(ipv6_cnt == 1) {
+ /* All IPv6 DID pkt has been forward to LAN NETIF */
+ did_cnt --;
+ }
+ if (!did_cnt) {
+ UT_ASSERT(total_cnt == 0);
+ }
+ }
+
+ if ( (total_cnt != ipc_ut_dl_callback_did_pkt_cnt) ||
+ (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (dpfm_pkt_cnt != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ||
+ (dpfm_did_cnt != ipc_ut_dl_callback_did_dpfm_cnt) ) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+ } else {
+ dpfm_did_cnt = 1;
+ dpfm_pkt_cnt = 1;
+ /* All DIDs should be handled by DL network interface */
+ if (1 == did_igr_bit) {
+ kal_uint32 ipv4_igr_cnt = 0;
+ kal_uint32 ipv6_igr_cnt = 0;
+
+ for (i = 0; i < ipv4_cnt; i++) {
+ ipv4_igr_cnt += ipc_ut_did_packet_igr_s[i];
+ }
+ for (i = 0; i < ipv6_cnt; i++) {
+ ipv6_igr_cnt += ipc_ut_did_packet_igr_s[i];
+ }
+ if ( (ipv4_igr_cnt) &&
+ (ipv4_cnt == ipv4_igr_cnt) ) {
+ /* All IPv4 DID pkt has been ignored. */
+ did_cnt --;
+ }
+ if ( (ipv6_igr_cnt) &&
+ (ipv6_cnt == ipv6_igr_cnt) ) {
+ /* All IPv6 DID pkt has been ignored. */
+ did_cnt --;
+ }
+
+ total_cnt -= (ipv4_igr_cnt + ipv6_igr_cnt);
+ if (!did_cnt) {
+ UT_ASSERT(total_cnt == 0);
+ }
+ } else {
+ total_cnt -= dpfm_did_cnt;
+ if(!total_cnt)
+ {
+ did_cnt--;
+ }
+ }
+
+ if ( (total_cnt != ipc_ut_dl_callback_did_pkt_cnt) ||
+ (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (dpfm_pkt_cnt != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ||
+ (dpfm_did_cnt != ipc_ut_dl_callback_did_dpfm_cnt) ) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ /* DL callback or DHCP4C indication are correctly called : all GPDs should be released */
+ }
+ }
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 total_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 did_igr_bit;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Deactivated] ip_type(%d),v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", idx, ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_dl_did_list(ipv4_cnt,
+ 0, /* dhcpv4_idx */
+ KAL_FALSE, /* dnsv4_only */
+ KAL_FALSE, /* v4hdr_exist */
+ ipv6_cnt,
+ 0, /* dhcpv6_idx */
+ KAL_FALSE, /* dnsv6_only */
+ KAL_FALSE, /* v6hdr_exist */
+ 0, /* additional_bd_cnt */
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL, /* ipv4_invalid_packet_len */
+ NULL, /* ipv6_invalid_packet_len */
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ) {
+ utELOG("DL DID is forwarded after PDN deactivation!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_detach() (DPFM device).
+ */
+ result = ipc_detach(net2->handle);
+ if (!result) {
+ utELOG("ipc_detach() (DPFM device) returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_meta_uplink_dpfm_cmd_after_detach(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 blocked_cnt = 0;
+ ipc_ut_netif_t *net;
+ ipc_ut_netif_t *net2;
+ ipc_ut_netif_t *net3;
+ kal_bool result;
+ kal_uint32 idx;
+ kal_uint8 proto_idx[] = {0, 1};
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ ilm_struct ilm;
+ kal_uint8 test_stage;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Activate DPFM */
+ ipc_ut_dpfm_is_activated_g = KAL_TRUE;
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Simulate UL traffic to IPCore : Before Netif attach, all Metas should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 dpfm_device;
+ kal_uint32 netif_id;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ kal_uint8 non_ignore_cnt;
+ kal_uint8 allmatch;
+
+ test_stage = IPC_UT_STAGE_BEFORE_BINDING;
+ for (allmatch = 0; allmatch < 2; allmatch++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 8; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 8; ipv6_cnt++)
+ for (dpfm_device = 0; dpfm_device <= 1; dpfm_device++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ /* It should not generate DPFM related meta result which is comes from LAN NETIF without rounting fearue */
+ if (1 == dpfm_device && (ipv4_cnt >= 4 || ipv6_cnt >= 4)) continue;
+
+ utDLOG("@ [Before Bind] allmatch(%d), proto_idx(%d), v4_cnt(%d), v6_cnt(%d), dpfm_device(%d)\r\n", allmatch, idx, ipv4_cnt, ipv6_cnt, dpfm_device);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ netif_id = (dpfm_device == 0) ? IPC_UT_DPFM_NETID_START
+ : IPC_UT_DPFM_NETID_START + 1;
+
+ ipc_ut_prepare_ul_meta_list_dpfm(allmatch, ipv4_cnt, ipv6_cnt, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ non_ignore_cnt = 0;
+ /*
+ * if pkt_cnt is 8, then the last meta will be DPFM_ADD_CMD.
+ * And this command should be forwarded to UPCM.
+ */
+ if(ipv4_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+ if(ipv6_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_dl_callback_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (non_ignore_cnt != ipc_ut_ul_meta_non_igr_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_cnt) ) {
+ utELOG("Packet is forwarded before PDN binding! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+
+ }
+ }
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() (DPFM device) */
+ net2 = &(ipc_ut_nets_s[1]);
+ kal_mem_set(net2, 0, sizeof(ipc_ut_netif_t));
+ net2->conf.module_id = MOD_IPCORE;
+ net2->conf.netif_id = IPC_UT_DPFM_NETID_START;
+ net2->conf.ul_reload_context = net2;
+ net2->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net2->conf.callback_context = net2;
+ net2->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net2->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did_dpfm;
+ net2->conf.features = IPC_F_LAN | IPC_F_TETHERING_ROUTE;
+ result = ipc_attach(&net2->conf, &net2->handle);
+ if (!result) {
+ utELOG("ipc_attach() (DPFM device) returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() (DPFM device 2) */
+ net3 = &(ipc_ut_nets_s[2]);
+ kal_mem_set(net3, 0, sizeof(ipc_ut_netif_t));
+ net3->conf.module_id = MOD_IPCORE;
+ net3->conf.netif_id = IPC_UT_DPFM_NETID_START + 1;
+ net3->conf.ul_reload_context = net3;
+ net3->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net3->conf.callback_context = net3;
+ net3->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net3->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did_dpfm;
+ net3->conf.features = IPC_F_LAN;
+ result = ipc_attach(&net3->conf, &net3->handle);
+ if (!result) {
+ utELOG("ipc_attach() (DPFM device 2) returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Bind LAN netifs. */
+ ipc_bind_lan_netif(net2->conf.netif_id, net3->conf.netif_id);
+
+ /* Simulate UL traffic to IPCore : All GPDs should be forward to UL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 dpfm_pkt_cnt;
+ kal_uint32 lan_pkt_cnt;
+ kal_uint32 lan_did_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 dpfm_device;
+ kal_uint32 netif_id;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ kal_uint8 dpfm_cmd_cnt;
+ kal_uint8 dpfm_cmd_cnt_v4;
+ kal_uint8 dpfm_cmd_cnt_v6;
+ kal_uint8 non_ignore_cnt;
+ kal_uint8 allmatch;
+
+ test_stage = IPC_UT_STAGE_BINDING;
+ for (allmatch = 0; allmatch < 2; allmatch++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 8; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 8; ipv6_cnt++)
+ for (dpfm_device = 0; dpfm_device <= 1; dpfm_device++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ /* It should not generate DPFM related meta result which is comes from AP LAN NETIF(dpfm_device==1) without rounting fearue */
+ if (1 == dpfm_device && (ipv4_cnt >= 4 || ipv6_cnt >= 4)) continue;
+
+ utDLOG("@ [Binded] allmatch(%d), proto_idx(%d), v4_cnt(%d), v6_cnt(%d), dpfm_device(%d)\r\n", allmatch, idx, ipv4_cnt, ipv6_cnt, dpfm_device);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ netif_id = (dpfm_device == 0) ? IPC_UT_DPFM_NETID_START
+ : IPC_UT_DPFM_NETID_START + 1;
+
+ dpfm_cmd_cnt = 0;
+ dpfm_cmd_cnt_v4 = 0;
+ dpfm_cmd_cnt_v6 = 0;
+ if (ipv4_cnt > 5) {
+ dpfm_cmd_cnt_v4 += (ipv4_cnt-5);
+ }
+ if (ipv6_cnt > 5) {
+ dpfm_cmd_cnt_v6 += (ipv6_cnt-5);
+ }
+ dpfm_cmd_cnt = dpfm_cmd_cnt_v4 + dpfm_cmd_cnt_v6;
+
+ dpfm_pkt_cnt = 0;
+ if ((dpfm_device == 0) && (total_cnt > 0)) {
+ if ( allmatch == 1 ) {
+ if (ipv4_cnt > 4) {
+ dpfm_pkt_cnt += (ipv4_cnt - dpfm_cmd_cnt_v4 -1); /* minus 1 for DPFM_MATCH_BUT_NO_NAT MR */
+ } else {
+ dpfm_pkt_cnt += ipv4_cnt;
+ }
+ if (ipv6_cnt > 4) {
+ dpfm_pkt_cnt += (ipv6_cnt - dpfm_cmd_cnt_v6 -1); /* minus 1 for DPFM_MATCH_BUT_NO_NAT MR */
+ } else {
+ dpfm_pkt_cnt += ipv6_cnt;
+ }
+ } else if (allmatch == 0 ) {
+ if (ipv4_cnt >= 4) {
+ dpfm_pkt_cnt += 1; /*For DPFM_MATCH MR */
+ }
+ if (ipv6_cnt >= 4) {
+ dpfm_pkt_cnt += 1; /*For DPFM_MATCH MR */
+ }
+ }
+ }
+
+ non_ignore_cnt = 0;
+ /*
+ * if pkt_cnt is 8, then the last meta will be DPFM_ADD_CMD.
+ * And this command should be forwarded to UPCM.
+ */
+ if(ipv4_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+ if(ipv6_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+
+ lan_pkt_cnt = total_cnt - dpfm_pkt_cnt - dpfm_cmd_cnt;
+ lan_did_cnt = (lan_pkt_cnt == 0) ? 0 : 1;
+
+ ipc_ut_prepare_ul_meta_list_dpfm(allmatch, ipv4_cnt, ipv6_cnt, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_dl_callback_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ ((dpfm_pkt_cnt + non_ignore_cnt) != ipc_ut_ul_meta_non_igr_cnt) ||
+ (lan_pkt_cnt != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ||
+ (lan_did_cnt != ipc_ut_dl_callback_did_dpfm_cnt) ) {
+ utELOG("Packet is not forwarded correctly! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_ul_meta_non_igr_cnt) {
+ if (dpfm_pkt_cnt != 0 && IPC_UT_PDN_ID != ipc_ut_ul_pdn_id) {
+ utELOG("UL META is forwarded with wrong PDN ID! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ if (dpfm_pkt_cnt != 0 && idx != ipc_ut_ul_proto_idx) {
+ utELOG("UL META is forwarded with wrong Protocol ID! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Unbind LAN netifs. */
+ ipc_unbind_lan_netif(net2->conf.netif_id, net3->conf.netif_id);
+
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Simulate UL traffic to IPCore : After Netif Dettach, all Metas should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 dpfm_device;
+ kal_uint32 netif_id;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ kal_uint8 non_ignore_cnt;
+ kal_uint8 allmatch;
+
+ test_stage = IPC_UT_STAGE_UNBINDING;
+ for (allmatch = 0; allmatch < 2; allmatch++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 8; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 8; ipv6_cnt++)
+ for (dpfm_device = 0; dpfm_device <= 1; dpfm_device++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+ /* It should not generate DPFM related meta result which is comes from LAN NETIF without rounting fearue */
+ if (1 == dpfm_device && (ipv4_cnt >= 4 || ipv6_cnt >= 4)) continue;
+
+ utDLOG("@ [After Unbind] allmatch(%d), proto_idx(%d), v4_cnt(%d), v6_cnt(%d), dpfm_device(%d)\r\n", allmatch, idx, ipv4_cnt, ipv6_cnt, dpfm_device);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ netif_id = (dpfm_device == 0) ? IPC_UT_DPFM_NETID_START
+ : IPC_UT_DPFM_NETID_START + 1;
+
+ ipc_ut_prepare_ul_meta_list_dpfm(allmatch, ipv4_cnt, ipv6_cnt, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ non_ignore_cnt = 0;
+ /*
+ * if pkt_cnt is 8, then the last meta will be DPFM_ADD_CMD.
+ * And this command should be forwarded to UPCM.
+ */
+ if(ipv4_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+ if(ipv6_cnt == 8)
+ {
+ non_ignore_cnt++;
+ }
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_dl_callback_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_pkt_cnt) ||
+ (0 != ipc_ut_dl_callback_did_dpfm_cnt) ) {
+ utELOG("Packet is forwarded after PDN Unbinding! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+
+ }
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+#endif
+
+kal_bool ipc_ut_meta_downlink(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ ilm_struct ilm;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 ipv4_filter_cnt;
+ kal_uint32 ipv6_filter_cnt;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint8 matched_filter_idx_v6;
+ kal_uint32 callback_with_info;
+ kal_uint32 total_cnt;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (ipv4_filter_cnt = 0; ipv4_filter_cnt <= 4; ipv4_filter_cnt++)
+ for (ipv6_filter_cnt = 0; ipv6_filter_cnt <= 4; ipv6_filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < ipv4_filter_cnt; matched_filter_idx_v4++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < ipv6_filter_cnt; matched_filter_idx_v6++) {
+ if ((0 == ipv4_cnt) && (0 == ipv6_cnt)) continue;
+
+ utDLOG("ifo(%d) v4Cnt(%d) v6Cnt(%d) v4FltCnt(%d) v6FltCnt(%d) v4Idx(%d) v6Idx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, ipv4_filter_cnt , ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Install DL filter for each test loop */
+ ipc_ut_install_dl_filters(callback_with_info, KAL_TRUE, ipv4_filter_cnt, ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6, IPC_UT_LHIF_NETID_START);
+
+ ipc_ut_dl_ipf_match_filter_id_v4_s = matched_filter_idx_v4;
+ ipc_ut_dl_ipf_match_filter_id_v6_s = ipv4_filter_cnt + matched_filter_idx_v6;
+
+ /* Before PDN Binding */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_pkt_cnt;
+
+ utDLOG("@ Before activation : match_result(%d)\r\n", match_result);
+
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_pkt_cnt = total_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) || (match_result == IPC_IPF_MR_PN_NO_MATCH)) {
+ expected_pkt_cnt = 0;
+ }
+
+ /* Make sure no DL callback to HIF */
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check if IPCore will release buffer when NETIF is invalid */
+ /* PN_NO_MATCH & DIRECT_TO_AP no need to free buffer */
+ if ( expected_pkt_cnt != ipc_ut_dl_meta_buf_free_num_s ) {
+ utELOG("DL buffer is not released before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic from IPCore : All meta should be forward to either DL callback or filter callback(IPv4/IPv6)
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_dl_v4_filter_out_cnt;
+ kal_uint32 expected_dl_v6_filter_out_cnt;
+ kal_uint32 expected_dl_filter_out_cnt;
+ kal_uint32 did_cnt;
+ kal_uint32 expected_dl_forwad_cnt;
+
+ utDLOG("@ PDN connected : match_result(%d)\r\n", match_result);
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_dl_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))? 1:0;
+ expected_dl_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))?1:0;
+
+ expected_dl_filter_out_cnt = expected_dl_v4_filter_out_cnt + expected_dl_v6_filter_out_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) ||
+ (match_result == IPC_IPF_MR_PN_NO_MATCH) ||
+ (match_result == IPC_IPF_MR_NET_INVALID)) {
+ did_cnt = expected_dl_forwad_cnt = 0;
+ }
+ else {
+ did_cnt = total_cnt-expected_dl_filter_out_cnt; //Supposed one DID only contains one packet
+ expected_dl_forwad_cnt = total_cnt-expected_dl_filter_out_cnt;
+ }
+
+ if (expected_dl_filter_out_cnt > 0) {
+ if (callback_with_info) {
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_LHIF_NETID_START) {
+ utELOG("Filtered-out netif ID is incorrect!\r\n");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+ else {
+ if (ipc_ut_dl_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\n");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+
+ if (ipc_ut_dl_filter_gpd_cnt != expected_dl_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+
+ if ( (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (expected_dl_forwad_cnt != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all meta should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_pkt_cnt;
+
+ utDLOG("@ PDN deactivated : dhcpv4Idx(%d), dhcpv6Idx(%d), match_result(%d)\r\n",
+ 0, 0, match_result);
+
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_pkt_cnt = total_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) || (match_result == IPC_IPF_MR_PN_NO_MATCH)) {
+ expected_pkt_cnt = 0;
+ }
+
+ /* Make sure no DL callback to HIF */
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded when PDN deactivated!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check if IPCore will release buffer when NETIF is invalid */
+ /* PN_NO_MATCH & DIRECT_TO_AP no need to free buffer */
+ if ( expected_pkt_cnt != ipc_ut_dl_meta_buf_free_num_s ) {
+ utELOG("DL buffer is not released when PDN deactivated!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_prepare_ul_empty_ack_meta_list(kal_bool allValidIpPkt,
+ kal_uint32 ipv4_cnt,
+ kal_uint8 ipv4_case_num,
+ kal_uint32 ipv6_cnt,
+ kal_uint8 ipv6_case_num,
+ kal_uint8 ip_type,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ LHIF_QUEUE_TYPE *q_type,
+ kal_uint32 netif_id,
+ kal_uint8 proto_idx,
+ kal_uint8 test_stage) {
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx = 0;
+ kal_uint32 curr_meta_idx = 0;
+ lhif_meta_tbl_t *curr_meta = NULL;
+ kal_uint8 *packet_buf = NULL;
+ kal_uint32 packet_len = 0;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+ kal_bool is_ea = KAL_FALSE;
+ kal_bool is_new_matched = KAL_FALSE;
+ kal_uint32 seq_base = 0;
+ kal_uint32 ack_base = 0;
+ kal_bool chk_mr_v4[IPC_UT_EA_MAX_CASE_NUM] = {KAL_FALSE};
+ kal_bool chk_mr_v6[IPC_UT_EA_MAX_CASE_NUM] = {KAL_FALSE};
+ kal_bool chk_mr_matched_v4[IPC_UT_EA_MAX_CASE_NUM] = {KAL_FALSE};
+ kal_bool chk_mr_matched_v6[IPC_UT_EA_MAX_CASE_NUM] = {KAL_FALSE};
+
+ UT_ASSERT(total_cnt == ipc_ut_alloc_meta(IPC_UT_LHIF_META_AP0, total_cnt, p_head_idx, p_tail_idx));
+ UT_ASSERT((ipv4_case_num >= 1) && (ipv4_case_num <= IPC_UT_EA_MAX_CASE_NUM));
+ UT_ASSERT((ipv6_case_num >= 1) && (ipv6_case_num <= IPC_UT_EA_MAX_CASE_NUM));
+
+ *q_type = LHIF_HWQ_AP_UL_Q0;
+ curr_meta_idx = *p_head_idx;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ curr_meta = &ipc_ut_meta_tbl_s[curr_meta_idx];
+ curr_meta->net_type = ((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS;
+ curr_meta->channel_id = netif_id & 0x0000001F;
+ is_ea = KAL_FALSE;
+ is_new_matched = KAL_FALSE;
+
+ seq_base = IPC_HDR_TCP_GET_SEQ_NUM(ipc_ut_ipv4_tcp_empty_ack_packet + IPC_HDR_V4_HEADER_SIZE);
+ ack_base = IPC_HDR_TCP_GET_ACK_NUM(ipc_ut_ipv4_tcp_empty_ack_packet + IPC_HDR_V4_HEADER_SIZE);
+ packet_buf = ipc_ut_ipv4_tcp_empty_ack_packet;
+
+ is_ea = KAL_TRUE;
+ g_ipc_ut_ea_cnt++;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_empty_ack_packet);
+ kal_mem_cpy(curr_meta->vrb_addr, packet_buf, packet_len);
+ curr_meta->length = packet_len;
+ curr_meta->ignore = KAL_FALSE;
+
+ if (1 < ipv4_case_num) {
+ switch (idx % ipv4_case_num) {
+ case 0:
+ curr_meta->match_index = IPC_UT_META_MATCH_IDX;
+ break;
+ case 1:
+ curr_meta->vrb_addr[15] += ipv4_case_num;
+ curr_meta->match_index = IPC_UT_META_MATCH_IDX + 1;
+ break;
+ case 2:
+ curr_meta->vrb_addr[15] += ipv4_case_num + 2;
+ curr_meta->match_index = IPC_UT_META_MATCH_IDX + 1;
+ break;
+ default:
+ /* invalid case */
+ UT_ASSERT(KAL_FALSE);
+ break;
+ }
+ } else {
+ curr_meta->match_index = IPC_UT_META_MATCH_IDX + 6;
+ }
+
+ if (KAL_FALSE == chk_mr_v4[(idx % ipv4_case_num)]) {
+ chk_mr_v4[(idx % ipv4_case_num)] = KAL_TRUE;
+ is_new_matched = KAL_TRUE;
+ } else {
+ if (KAL_FALSE == chk_mr_matched_v4[(idx % ipv4_case_num)]) {
+ chk_mr_matched_v4[(idx % ipv4_case_num)] = KAL_TRUE;
+ } else {
+ if (IPV6_ADDR_TYPE != ip_type) {
+ g_ipc_ut_ea_drop_cnt++;
+ }
+ }
+ }
+
+ if (is_ea) {
+ curr_meta->ea = KAL_TRUE;
+ IPC_HDR_TCP_SET_SEQ_NUM(curr_meta->vrb_addr + 20, seq_base + idx);
+ IPC_HDR_TCP_SET_ACK_NUM(curr_meta->vrb_addr + 20, ack_base + idx);
+ }
+
+#if defined(__IPF_SUPPORT__)
+ if (!((IPC_UT_STAGE_BEFORE_BINDING == test_stage) || (IPC_UT_STAGE_UNBINDING == test_stage))) {
+ curr_meta->protocol_idx = proto_idx;
+ curr_meta->pdn = IPC_UT_PDN_ID;
+ }
+
+ curr_meta->ip = KAL_FALSE;
+
+ if (is_new_matched) {
+ curr_meta->mr = IPC_HPC_MR_NEW;
+ } else {
+ curr_meta->mr = IPC_HPC_MR_MATCH;
+ }
+#endif
+ curr_meta_idx++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ curr_meta = &ipc_ut_meta_tbl_s[curr_meta_idx];
+ curr_meta->net_type = ((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS;
+ curr_meta->channel_id = netif_id & 0x0000001F;
+ is_ea = KAL_FALSE;
+ is_new_matched = KAL_FALSE;
+
+ seq_base = IPC_HDR_TCP_GET_SEQ_NUM(ipc_ut_ipv6_tcp_empty_ack_packet + IPC_HDR_V6_HEADER_SIZE);
+ ack_base = IPC_HDR_TCP_GET_ACK_NUM(ipc_ut_ipv6_tcp_empty_ack_packet + IPC_HDR_V6_HEADER_SIZE);
+ packet_buf = ipc_ut_ipv6_tcp_empty_ack_packet;
+
+ is_ea = KAL_TRUE;
+ g_ipc_ut_ea_cnt++;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_empty_ack_packet);
+ kal_mem_cpy(curr_meta->vrb_addr, packet_buf, packet_len);
+ curr_meta->length = packet_len;
+ curr_meta->ignore = KAL_FALSE;
+ curr_meta->ip = KAL_TRUE;
+
+ if (1 < ipv6_case_num) {
+ switch (idx % ipv6_case_num) {
+ case 0:
+ curr_meta->match_index = IPC_UT_META_MATCH_IDX + 3;
+ break;
+ case 1:
+ curr_meta->vrb_addr[15] += ipv6_case_num;
+ curr_meta->match_index = IPC_UT_META_MATCH_IDX + 4;
+ break;
+ case 2:
+ curr_meta->vrb_addr[15] += ipv6_case_num + 3;
+ curr_meta->match_index = IPC_UT_META_MATCH_IDX + 5;
+ break;
+ default:
+ /* invalid case */
+ UT_ASSERT(KAL_FALSE);
+ break;
+ }
+ } else {
+ curr_meta->match_index = IPC_UT_META_MATCH_IDX + 7;
+ }
+
+ if (KAL_FALSE == chk_mr_v6[(idx % ipv6_case_num)]) {
+ chk_mr_v6[(idx % ipv6_case_num)] = KAL_TRUE;
+ is_new_matched = KAL_TRUE;
+ } else {
+ if (KAL_FALSE == chk_mr_matched_v6[(idx % ipv6_case_num)]) {
+ chk_mr_matched_v6[(idx % ipv6_case_num)] = KAL_TRUE;
+ } else {
+ if (IPV4_ADDR_TYPE != ip_type) {
+ g_ipc_ut_ea_drop_cnt++;
+ }
+ }
+ }
+
+ if (is_ea) {
+ curr_meta->ea = KAL_TRUE;
+ IPC_HDR_TCP_SET_SEQ_NUM(curr_meta->vrb_addr + 20, seq_base + idx);
+ IPC_HDR_TCP_SET_ACK_NUM(curr_meta->vrb_addr + 20, ack_base + idx);
+ }
+
+ if (!((IPC_UT_STAGE_BEFORE_BINDING == test_stage) || (IPC_UT_STAGE_UNBINDING == test_stage))) {
+ curr_meta->protocol_idx = proto_idx;
+ curr_meta->pdn = IPC_UT_PDN_ID;
+ }
+
+ if (is_new_matched) {
+ curr_meta->mr = IPC_HPC_MR_NEW;
+ } else {
+ curr_meta->mr = IPC_HPC_MR_MATCH;
+ }
+
+ curr_meta_idx++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+ UT_ASSERT(g_ipc_ut_ea_cnt == ipv4_case_num + ipv6_case_num + g_ipc_ut_ea_drop_cnt);
+ return;
+}
+
+kal_bool ipc_ut_uplink_ack_reduction(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 idx = 0;
+ ipc_ut_netif_t *net = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ kal_uint8 ip_types[] = {IPV4_ADDR_TYPE, IPV4V6_ADDR_TYPE, IPV6_ADDR_TYPE};
+ kal_uint32 total_cnt = 0;
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ kal_uint32 ipv4_case_num = 0;
+ kal_uint32 ipv6_case_num = 0;
+ kal_uint32 with_wildcard = 0;
+ kal_uint32 with_bwm = 0;
+ kal_uint8 matched_filter_idx_v4 = 0;
+ kal_uint8 matched_filter_idx_v6 = 0;
+ kal_uint8 test_stage;
+ kal_uint32 expected_ul_v4_filter_out_cnt = 0;
+ kal_uint32 expected_ul_v6_filter_out_cnt = 0;
+ kal_uint32 expected_ul_filter_out_cnt = 0;
+
+ /* Init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ UT_ASSERT(KAL_TRUE == ipc_reset());
+
+ for (ipv4_cnt = 0; ipv4_cnt <= 4; ipv4_cnt+=2)
+ for (ipv6_cnt = 0; ipv6_cnt <= 4; ipv6_cnt+=2)
+ for (ipv4_case_num = 1; ipv4_case_num <= IPC_UT_EA_MAX_CASE_NUM; ipv4_case_num++)
+ for (ipv6_case_num = 1; ipv6_case_num <= IPC_UT_EA_MAX_CASE_NUM; ipv6_case_num++)
+ for (idx = 0; idx < sizeof(ip_types)/sizeof(ip_types[0]); idx++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("v4Cnt(%d) v6Cnt(%d) IPType(%d)",ipv4_cnt, ipv6_cnt, idx);
+ utDLOG("ipv4_case_num(%d) ipv6_case_num(%d)",ipv4_case_num, ipv6_case_num);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ UT_ASSERT(KAL_TRUE == ipc_attach(&net->conf, &net->handle));
+
+ /*
+ * Before activate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN NOT be forwarded to UPCM
+ */
+ {
+ kal_uint32 head_idx = 0;
+ kal_uint32 tail_idx = 0;
+ LHIF_QUEUE_TYPE q_type = LHIF_HWQ_AP_UL_Q0;
+
+ test_stage = IPC_UT_STAGE_BEFORE_BINDING;
+ expected_ul_v4_filter_out_cnt = 0;
+ expected_ul_v6_filter_out_cnt = 0;
+ expected_ul_filter_out_cnt = 0;
+ g_ipc_ut_ea_cnt = 0;
+ g_ipc_ut_ea_drop_cnt = 0;
+
+ ipc_ut_prepare_ul_empty_ack_meta_list(KAL_TRUE, ipv4_cnt, ipv4_case_num, ipv6_cnt, ipv6_case_num, ip_types[idx], &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IPCore */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ UT_ASSERT(ipc_meta_uplink(head_idx, tail_idx, q_type));
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ UT_ASSERT(0 == expected_ul_filter_out_cnt);
+ UT_ASSERT(ipc_ut_ul_filter_gpd_cnt == expected_ul_filter_out_cnt);
+ UT_ASSERT(total_cnt == (ipc_ut_ul_meta_cnt + ipc_ut_ul_meta_non_igr_cnt));
+ }
+
+ /* Activate IPv4/IPv4v6/IPv6 PDN */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = ip_types[idx];
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * After PDN binding activate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN be forwarded to UPCM
+ */
+ {
+ kal_uint32 head_idx = 0;
+ kal_uint32 tail_idx = 0;
+ LHIF_QUEUE_TYPE q_type = LHIF_HWQ_AP_UL_Q0;
+
+ test_stage = IPC_UT_STAGE_BINDING;
+ expected_ul_v4_filter_out_cnt = 0;
+ expected_ul_v6_filter_out_cnt = 0;
+ expected_ul_filter_out_cnt = 0;
+ g_ipc_ut_ea_cnt = 0;
+ g_ipc_ut_ea_drop_cnt = 0;
+
+ utDLOG("@ PDN connected : total_cnt(%u), ipv4(%d) ipv6(%d)\r\n", total_cnt, ipv4_cnt, ipv6_cnt);
+
+ ipc_ut_prepare_ul_empty_ack_meta_list(KAL_TRUE, ipv4_cnt, ipv4_case_num, ipv6_cnt, ipv6_case_num, ip_types[idx], &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IPCore */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ UT_ASSERT(ipc_meta_uplink(head_idx, tail_idx, q_type));
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ UT_ASSERT(0 == expected_ul_filter_out_cnt);
+ UT_ASSERT(ipc_ut_ul_filter_gpd_cnt == expected_ul_filter_out_cnt);
+ UT_ASSERT(total_cnt == ipc_ut_ul_meta_cnt);
+
+ if (IPV4_ADDR_TYPE == ip_types[idx]) {
+ if (2 >= ipv4_cnt) {
+ g_ipc_ut_ea_drop_cnt = ipv6_cnt;
+ } else {
+ g_ipc_ut_ea_drop_cnt += ipv6_cnt;
+ }
+ }
+
+ if (IPV6_ADDR_TYPE == ip_types[idx]) {
+ if (2 >= ipv6_cnt) {
+ g_ipc_ut_ea_drop_cnt = ipv4_cnt;
+ } else {
+ g_ipc_ut_ea_drop_cnt += ipv4_cnt;
+ }
+ }
+
+ UT_ASSERT(g_ipc_ut_received_ignore_ea_cnt == g_ipc_ut_ea_drop_cnt);
+ UT_ASSERT(ipc_ut_ul_meta_cnt == (ipc_ut_ul_meta_non_igr_cnt + g_ipc_ut_igr_meta_cnt));
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /*
+ * After deactivate, the UL packet from this network interface
+ * 1. CAN be filtered out
+ * 2. CAN NOT be forwarded to UPCM
+ */
+ {
+ kal_uint32 head_idx = 0;
+ kal_uint32 tail_idx = 0;
+ LHIF_QUEUE_TYPE q_type = LHIF_HWQ_AP_UL_Q0;
+
+ test_stage = IPC_UT_STAGE_UNBINDING;
+ expected_ul_v4_filter_out_cnt = 0;
+ expected_ul_v6_filter_out_cnt = 0;
+ expected_ul_filter_out_cnt = 0;
+
+ ipc_ut_prepare_ul_empty_ack_meta_list(KAL_TRUE, ipv4_cnt, 1, ipv6_cnt, 1, ip_types[idx], &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IPCore */
+ ipc_ut_reset_ul_info();
+ ipc_ut_reset_ul_filter_info();
+
+ UT_ASSERT(ipc_meta_uplink(head_idx, tail_idx, q_type));
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ UT_ASSERT(0 == expected_ul_filter_out_cnt);
+ UT_ASSERT(ipc_ut_ul_filter_gpd_cnt == expected_ul_filter_out_cnt);
+ UT_ASSERT(total_cnt == (ipc_ut_ul_meta_cnt + ipc_ut_ul_meta_non_igr_cnt));
+ }
+
+ /* ipc_detach(). */
+ UT_ASSERT(KAL_TRUE == ipc_detach(net->handle));
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_int32 ipc_ut_ipf_query_filter_id_by_index(kal_uint32 ipf_index) {
+ kal_int32 filter_id = -1;
+
+ if (0 == ipf_index) {
+ filter_id = ipc_ut_dl_ipf_match_filter_id_v4_s;
+ }
+ else {
+ filter_id = ipc_ut_dl_ipf_match_filter_id_v6_s;
+ }
+ return filter_id;
+}
+
+void ipc_ut_query_ipf_meta_info(void** base, kal_uint16* entry_num, kal_uint32 ipf_meta_q_type) {
+ *base = (void *)ipc_ut_dl_meta_tbl_s;
+ *entry_num = IPC_UT_META_TABLE_SIZE;
+
+ return;
+}
+
+void ipc_ut_ipf_pn_match_setting(kal_uint8 pdn_sim_id, kal_uint16 nc_id, kal_uint8 ipv4, kal_uint8 ipv6) {
+ return;
+}
+
+kal_bool ipc_ut_ipf_take_filter_tlb(void** buff_base, kal_uint32* max_entry_num) {
+ *buff_base = ipc_ut_hw_filter_buf_s;
+ *max_entry_num = IPC_UT_HW_FLTR_TOTAL_NUM;
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ipf_submit_filter_tlb(kal_uint32 filter_num, kal_uint32 v6_unknow_pro_ck) {
+ return KAL_TRUE;
+}
+
+void ipc_ut_free_ipf_meta_buf(void* meta, kal_uint32 len) {
+ ipc_ut_dl_meta_buf_free_num_s++;
+ return;
+}
+
+kal_bool ipc_ut_ul_throttle_plmn(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipc_ut_netif_t *net = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ilm_struct ilm = {0};
+ kal_bool result = KAL_FALSE;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Case 1 PLMN LIST is on-going, UL should be blocked; PLMN LIST is no action, UL should be resumed.*/
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ l4c_ipcore_ul_throttle_req_struct *p_ind;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Prepare UL meta */
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ v4_cnt(%d),v6_cnt(%d)\r\n", ipv4_cnt, ipv6_cnt);
+
+ /* Set PLMN LIST on-going */
+ p_ind = construct_local_para(sizeof(l4c_ipcore_ul_throttle_req_struct), TD_RESET);
+ p_ind->ul_throttle_action = UL_THROTTLE_ONGOING;
+ ilm.src_mod_id = MOD_L4C;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = L4C_IPCORE_SAP;
+ ilm.msg_id = MSG_ID_L4C_IPCORE_UL_THROTTLE_REQ;
+ ilm.local_para_ptr = (local_para_struct *)p_ind;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)p_ind);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_prepare_ul_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, 0, IPC_UT_STAGE_BINDING);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (0 != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded to UPCM when PLMN LIST is on-going! (ipv4:%d, ipv6:%d)\r\n", ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+
+ /* Set PLMN LIST no action */
+ p_ind = construct_local_para(sizeof(l4c_ipcore_ul_throttle_req_struct), TD_RESET);
+ p_ind->ul_throttle_action = UL_THROTTLE_NO_ACTION;
+ ilm.src_mod_id = MOD_L4C;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = L4C_IPCORE_SAP;
+ ilm.msg_id = MSG_ID_L4C_IPCORE_UL_THROTTLE_REQ;
+ ilm.local_para_ptr = (local_para_struct *)p_ind;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)p_ind);
+
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (total_cnt != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded to UPCM with wrong number! (ipv4:%d, ipv6:%d, ipc_ut_ul_meta_cnt:%d, ipc_ut_ul_meta_non_igr_cnt:%d)\r\n",
+ ipv4_cnt, ipv6_cnt, ipc_ut_ul_meta_cnt, ipc_ut_ul_meta_non_igr_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Case 2 if PDN is unbind when PLMN LIST is on-going, UL meta should be dropped */
+ {
+ l4c_ipcore_ul_throttle_req_struct *p_ind;
+ kal_uint32 ipv4_cnt = 3;
+ kal_uint32 ipv6_cnt = 3;
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ kal_uint32 idx;
+ kal_uint8 proto_idx[] = {0, 1};
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+
+ utDLOG("@ [after Bind] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Set PLMN LIST on-going */
+ p_ind = construct_local_para(sizeof(l4c_ipcore_ul_throttle_req_struct), TD_RESET);
+ p_ind->ul_throttle_action = UL_THROTTLE_ONGOING;
+ ilm.src_mod_id = MOD_L4C;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = L4C_IPCORE_SAP;
+ ilm.msg_id = MSG_ID_L4C_IPCORE_UL_THROTTLE_REQ;
+ ilm.local_para_ptr = (local_para_struct *)p_ind;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)p_ind);
+
+ ipc_ut_prepare_ul_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, idx, IPC_UT_STAGE_BINDING);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* Set PLMN LIST no action */
+ p_ind = construct_local_para(sizeof(l4c_ipcore_ul_throttle_req_struct), TD_RESET);
+ p_ind->ul_throttle_action = UL_THROTTLE_NO_ACTION;
+ ilm.src_mod_id = MOD_L4C;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = L4C_IPCORE_SAP;
+ ilm.msg_id = MSG_ID_L4C_IPCORE_UL_THROTTLE_REQ;
+ ilm.local_para_ptr = (local_para_struct *)p_ind;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)p_ind);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META should be dropped because of PDN deactivation! (ipv4:%d, ipv6:%d, ipc_ut_ul_meta_cnt:%d, ipc_ut_ul_meta_non_igr_cnt:%d)\r\n",
+ ipv4_cnt, ipv6_cnt, ipc_ut_ul_meta_cnt, ipc_ut_ul_meta_non_igr_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+#if defined(__MD97__)
+
+kal_bool ipc_ut_rq_info_verification(ipc_data_rq_info_list *p_pre_list, ipc_data_rq_info_list *p_rcv_list)
+{
+ return !kal_mem_cmp(p_pre_list, p_rcv_list, sizeof(ipc_data_rq_info_list));
+}
+
+void ipc_ut_rcv_rq_info(ipc_rq_info_t *p_rq_info)
+{
+ g_ipc_ut_sdap_pkt_received_cnt++;
+ ipc_data_saved_rq_info_list(&g_rq_info_list, p_rq_info);
+}
+
+void ipc_ut_set_prepare_rq_info_list(ipc_data_rq_info_list *p_list, kal_uint8 *p_pkt, kal_uint8 qfi)
+{
+ kal_uint32 idx = p_list->cnt;
+
+ UT_ASSERT(NULL != p_list);
+ UT_ASSERT(NULL != p_pkt);
+
+ if (IPC_HDR_IS_V4(p_pkt)) {
+ p_list->rq_info_list[idx].is_ipv4 = KAL_TRUE;
+ p_list->rq_info_list[idx].protocol = IPC_HDR_V4_GET_PROTOCOL(p_pkt);
+
+ kal_mem_cpy(&p_list->rq_info_list[idx].dst_ipv4.addr32, (kal_uint8 *)IPC_HDR_V4_GET_DST_ADDR(p_pkt), 4);
+ kal_mem_cpy(&p_list->rq_info_list[idx].src_ipv4.addr32, (kal_uint8 *)IPC_HDR_V4_GET_SRC_ADDR(p_pkt), 4);
+
+ p_list->rq_info_list[idx].valid_field = IPC_RQ_INFO_3_TUPLE;
+ if (IPC_HDR_PROT_TCP == p_list->rq_info_list[idx].protocol) {
+ p_list->rq_info_list[idx].dst_port = IPC_HDR_TCP_GET_DST_PORT(p_pkt + IPC_HDR_V4_HEADER_SIZE);
+ p_list->rq_info_list[idx].src_port = IPC_HDR_TCP_GET_SRC_PORT(p_pkt + IPC_HDR_V4_HEADER_SIZE);
+ p_list->rq_info_list[idx].valid_field = IPC_RQ_INFO_5_TUPLE;
+ } else if (IPC_HDR_PROT_UDP == p_list->rq_info_list[idx].protocol) {
+ p_list->rq_info_list[idx].dst_port = IPC_HDR_UDP_GET_DST_PORT(p_pkt + IPC_HDR_V4_HEADER_SIZE);
+ p_list->rq_info_list[idx].src_port = IPC_HDR_UDP_GET_SRC_PORT(p_pkt + IPC_HDR_V4_HEADER_SIZE);
+ p_list->rq_info_list[idx].valid_field = IPC_RQ_INFO_5_TUPLE;
+ }
+ } else if (IPC_HDR_IS_V6(p_pkt)) {
+ p_list->rq_info_list[idx].is_ipv4 = KAL_FALSE;
+ p_list->rq_info_list[idx].protocol = (kal_uint8)(kal_uint8 *)IPC_HDR_V6_GET_NH_TYPE(p_pkt);
+
+ kal_mem_cpy(p_list->rq_info_list[idx].dst_ipv6.addr32, (kal_uint8 *)IPC_HDR_V6_GET_DST_ADDR(p_pkt), 16);
+ kal_mem_cpy(p_list->rq_info_list[idx].src_ipv6.addr32, (kal_uint8 *)IPC_HDR_V6_GET_SRC_ADDR(p_pkt), 16);
+
+ p_list->rq_info_list[idx].valid_field = IPC_RQ_INFO_3_TUPLE;
+ if (IPC_HDR_PROT_TCP == p_list->rq_info_list[idx].protocol) {
+ p_list->rq_info_list[idx].dst_port = IPC_HDR_TCP_GET_DST_PORT(p_pkt + IPC_HDR_V6_HEADER_SIZE);
+ p_list->rq_info_list[idx].src_port = IPC_HDR_TCP_GET_SRC_PORT(p_pkt + IPC_HDR_V6_HEADER_SIZE);
+ p_list->rq_info_list[idx].valid_field = IPC_RQ_INFO_5_TUPLE;
+ } else if (IPC_HDR_PROT_UDP == p_list->rq_info_list[idx].protocol) {
+ p_list->rq_info_list[idx].dst_port = IPC_HDR_UDP_GET_DST_PORT(p_pkt + IPC_HDR_V6_HEADER_SIZE);
+ p_list->rq_info_list[idx].src_port = IPC_HDR_UDP_GET_SRC_PORT(p_pkt + IPC_HDR_V6_HEADER_SIZE);
+ p_list->rq_info_list[idx].valid_field = IPC_RQ_INFO_5_TUPLE;
+ }
+ } else {
+ utELOG("unsupported case");
+ }
+
+ p_list->rq_info_list[idx].qfi = qfi;
+ p_list->cnt++;
+ return;
+}
+
+void ipc_ut_prepare_dl_sdap_meta_list(kal_bool allValidIpPkt,
+ kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ ipfc_dl_filter_queue_type *q_type,
+ kal_uint32 netif_id,
+ kal_uint8 match_result)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx = 0;
+ kal_uint32 curr_meta_idx = 0;
+ ipf_dl_meta *curr_meta = NULL;
+ kal_uint8 *packet_buf = NULL;
+ kal_uint32 packet_len = 0;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+ kal_bool is_add = KAL_FALSE;
+
+ if (total_cnt != ipc_ut_alloc_meta(IPC_UT_IPF_DL_0, //LHIF_HWQ_AP_UL_Q0,
+ total_cnt,
+ p_head_idx,
+ p_tail_idx)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ *q_type = IPFC_META_QUEUE_DL;
+ curr_meta_idx = *p_head_idx;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ is_add = KAL_FALSE;
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ curr_meta->channel_id = ((((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS) <<8 )
+ |(netif_id & 0x000000FF) ;
+
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_ip_header_packet);
+ break;
+ case 2:
+ /* repeated the same 5-tuple packet */
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ is_add = KAL_FALSE;
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag1_packet);
+ is_add = KAL_TRUE;
+ break;
+ default:
+ UT_ASSERT(KAL_FALSE);
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ break;
+ }
+
+ if (IPC_IPF_MR_UNKNOWN_HEADER == match_result && is_add) {
+ /* 11011010 */
+ curr_meta->tcp_flag = 0xDA;
+ ipc_ut_set_prepare_rq_info_list(&g_prepare_rq_info_list, packet_buf, IPC_DATA_GET_QFI(curr_meta->tcp_flag));
+ g_ipc_ut_sdap_pkt_alloc_cnt++;
+ } else {
+ curr_meta->tcp_flag = 0;
+ }
+
+ kal_mem_cpy((kal_uint8*)curr_meta->addr, packet_buf, packet_len);
+ curr_meta->len = packet_len;
+ curr_meta->ip = 0;
+
+ /* Fill Match index (don't care value) */
+ /* we assgin the same value as ip type. it will be reused for querey filter id. */
+
+ curr_meta->match_idx = 0;
+ curr_meta->mr = (match_result & 0x07);
+ curr_meta->pdn_sim_id = IPC_UT_PDN_ID;
+ curr_meta_idx ++;
+
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ is_add = KAL_FALSE;
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ curr_meta->channel_id = ((((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS) <<8 )
+ |(netif_id & 0x000000FF) ;
+
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_ul_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_tcp_fin_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_fin_ack_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 3:
+ /* repeated 5-tuple packet */
+ packet_buf = ipc_ut_ipv6_tcp_empty_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_empty_ack_packet);
+ is_add = KAL_FALSE;
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ /* TODO : AH header case */
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ is_add = KAL_TRUE;
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 9:
+ packet_buf = ipc_ut_ipv6_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ip_header_packet);
+ break;
+ case 10:
+ packet_buf = ipc_ut_ipv6_incomplete_hop_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_hop_packet);
+ break;
+ case 11:
+ packet_buf = ipc_ut_ipv6_incomplete_ah_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ah_packet);
+ break;
+ default:
+ UT_ASSERT(KAL_FALSE);
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+
+ kal_mem_cpy((kal_uint8*)curr_meta->addr, packet_buf, packet_len);
+ curr_meta->len = packet_len;
+
+ if (IPC_IPF_MR_UNKNOWN_HEADER == match_result && is_add) {
+ /* 11011010 */
+ curr_meta->tcp_flag = 0xDB;
+ ipc_ut_set_prepare_rq_info_list(&g_prepare_rq_info_list, packet_buf, IPC_DATA_GET_QFI(curr_meta->tcp_flag));
+ g_ipc_ut_sdap_pkt_alloc_cnt++;
+ } else {
+ curr_meta->tcp_flag = 0;
+ }
+
+ curr_meta->ip = 1;
+
+ /* Fill Match index (don't care value) */
+ /* we assgin the same value as ip type. it will be reused for querey filter id. */
+
+ curr_meta->match_idx = 1;
+ curr_meta->mr = (match_result & 0x07);
+ curr_meta->pdn_sim_id = IPC_UT_PDN_ID;
+ curr_meta_idx ++;
+
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+}
+
+kal_bool ipc_ut_sdap_meta_downlink(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ipc_ut_netif_t *net = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result = KAL_FALSE;
+ ilm_struct ilm = {0};
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ kal_uint32 ipv4_filter_cnt = 0;
+ kal_uint32 ipv6_filter_cnt = 0;
+ kal_uint8 matched_filter_idx_v4 = 0;
+ kal_uint8 matched_filter_idx_v6 = 0;
+ kal_uint32 callback_with_info = 0;
+ kal_uint32 total_cnt = 0;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 4; ipv6_cnt++)
+ for (ipv4_filter_cnt = 0; ipv4_filter_cnt <= 4; ipv4_filter_cnt++)
+ for (ipv6_filter_cnt = 0; ipv6_filter_cnt <= 1; ipv6_filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < ipv4_filter_cnt; matched_filter_idx_v4++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < ipv6_filter_cnt; matched_filter_idx_v6++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("ifo(%d) v4Cnt(%d) v6Cnt(%d) v4FltCnt(%d) v6FltCnt(%d) v4Idx(%d) v6Idx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, ipv4_filter_cnt , ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Install DL filter for each test loop */
+ ipc_ut_install_dl_filters(callback_with_info, KAL_TRUE, ipv4_filter_cnt, ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6, IPC_UT_LHIF_NETID_START);
+
+ ipc_ut_dl_ipf_match_filter_id_v4_s = matched_filter_idx_v4;
+ ipc_ut_dl_ipf_match_filter_id_v6_s = ipv4_filter_cnt + matched_filter_idx_v6;
+
+ /* Before PDN Binding */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DIRECT_TO_AP ; match_result++) {
+ kal_uint32 expected_pkt_cnt;
+
+ utDLOG("@ Before activation : match_result(%d)\r\n", match_result);
+
+ ipc_ut_prepare_dl_sdap_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_pkt_cnt = total_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) || (match_result == IPC_IPF_MR_PN_NO_MATCH)) {
+ expected_pkt_cnt = 0;
+ }
+
+ /* Make sure no DL callback to HIF */
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check if IPCore will release buffer when NETIF is invalid */
+ /* PN_NO_MATCH & DIRECT_TO_AP no need to free buffer */
+ if ( expected_pkt_cnt != ipc_ut_dl_meta_buf_free_num_s ) {
+ utELOG("DL buffer is not released before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic from IPCore : All meta should be forward to either DL callback or filter callback(IPv4/IPv6)
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_dl_v4_filter_out_cnt;
+ kal_uint32 expected_dl_v6_filter_out_cnt;
+ kal_uint32 expected_dl_filter_out_cnt;
+ kal_uint32 did_cnt;
+ kal_uint32 expected_dl_forwad_cnt;
+
+ kal_mem_set(&g_prepare_rq_info_list, 0, sizeof(ipc_data_rq_info_list));
+ kal_mem_set(&g_rq_info_list, 0, sizeof(ipc_data_rq_info_list));
+ g_ipc_ut_sdap_pkt_alloc_cnt = 0;
+ g_ipc_ut_sdap_pkt_received_cnt = 0;
+ UT_ASSERT(0 == kal_mem_cmp(&g_prepare_rq_info_list, &g_rq_info_list, sizeof(ipc_data_rq_info_list)));
+
+ utDLOG("@ PDN connected : match_result(%d)\r\n", match_result);
+ ipc_ut_prepare_dl_sdap_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_dl_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))? 1:0;
+ expected_dl_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))?1:0;
+
+ expected_dl_filter_out_cnt = expected_dl_v4_filter_out_cnt + expected_dl_v6_filter_out_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) ||
+ (match_result == IPC_IPF_MR_PN_NO_MATCH) ||
+ (match_result == IPC_IPF_MR_NET_INVALID)) {
+ did_cnt = expected_dl_forwad_cnt = 0;
+ } else {
+ did_cnt = total_cnt-expected_dl_filter_out_cnt; //Supposed one DID only contains one packet
+ expected_dl_forwad_cnt = total_cnt-expected_dl_filter_out_cnt;
+ }
+
+ UT_ASSERT(0 == kal_mem_cmp(&g_prepare_rq_info_list, &g_rq_info_list, sizeof(ipc_data_rq_info_list)));
+ UT_ASSERT(ipc_ut_rq_info_verification(&g_prepare_rq_info_list, &g_rq_info_list));
+ UT_ASSERT(g_ipc_ut_sdap_pkt_alloc_cnt == g_ipc_ut_sdap_pkt_received_cnt);
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all meta should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_pkt_cnt;
+
+ utDLOG("@ PDN deactivated : dhcpv4Idx(%d), dhcpv6Idx(%d), match_result(%d)\r\n",
+ 0, 0, match_result);
+
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_pkt_cnt = total_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) || (match_result == IPC_IPF_MR_PN_NO_MATCH)) {
+ expected_pkt_cnt = 0;
+ }
+
+ /* Make sure no DL callback to HIF */
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded when PDN deactivated!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check if IPCore will release buffer when NETIF is invalid */
+ /* PN_NO_MATCH & DIRECT_TO_AP no need to free buffer */
+ if ( expected_pkt_cnt != ipc_ut_dl_meta_buf_free_num_s ) {
+ utELOG("DL buffer is not released when PDN deactivated!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+static LHIF_NET_TYPE ipc_ut_get_net_type_from_netif_id(kal_uint32 netif_id)
+{
+
+ UT_ASSERT(IPC_INVALID_NETIF_ID != netif_id);
+
+ switch (netif_id & 0xFFFFFF00) {
+ case IPC_NETIF_ID_LHIF_BEGIN:
+ return LHIF_NET_TYPE_LHIF;
+ case IPC_NETIF_ID_ETH_BEGIN:
+ return LHIF_NET_TYPE_RNDIS;
+ default:
+ /*can't reach here*/
+ UT_ASSERT(KAL_FALSE);
+ return LHIF_NET_TYPE_IGNORE;
+ }
+}
+
+void ipc_ut_prepare_send_did_by_ch_id_dl_list(kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint16 *ipv4_invalid_packet_len,
+ kal_uint16 *ipv6_invalid_packet_len,
+ kal_uint32 did_cnt,
+ kal_bool did_igr_enable)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+
+ if (did_cnt != ipc_ut_alloc_did(did_cnt, did_head, did_tail)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for (curr_did = *did_head; curr_did && (end_of_list == KAL_FALSE);
+ curr_did = next_did) {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+
+ /* Set SIT to the first SIT in DID for data configuration */
+ curr_did = *did_head;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ switch (idx % 3) {
+ case 0 :
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_3;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_3);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ case 1 :
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_1;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_1);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ case 2 :
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_2;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_2);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ default :
+ packet_buf = ipc_ut_ipv4_tcp_empty_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_empty_ack_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ if (ipv4_invalid_packet_len) {
+ if (ipv4_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv4_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv4_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt++;
+ }
+ }
+
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv4_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv6_invalid_packet_len) {
+ if (ipv6_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv6_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv6_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt++;
+ }
+ }
+
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv6_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+}
+
+kal_bool ipc_ut_send_did_by_ch_id(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 i = 0;
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ ipcore_upcm_pdn_bind_ind_struct *p_bind_req = NULL;
+ ipc_filter_rules_t rules = {0};
+ kal_int32 filter_id = 0;
+ kal_uint32 pdn_id = 0;
+ ipc_session_t *p_session = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_uint8 net_type = 0;
+ kal_uint8 nc_id = 0;
+ kal_bool result = KAL_FALSE;
+
+ /* initialize before test & reset IPCORE */
+ ipc_ut_init();
+ UT_ASSERT(KAL_TRUE == ipc_reset());
+ g_received_cnt = 0;
+
+ /* netif attach */
+ UT_ASSERT(KAL_TRUE == ipc_ut_fin_ack_filter_netif_attach());
+
+ /* IPv4 binding */
+ p_bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ p_bind_req->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_bind_req->pdn_id = IPC_UT_PDN_ID;
+ p_bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *) p_bind_req);
+ free_local_para((local_para_struct * )p_bind_req);
+
+ /* net_type and channel id test */
+ net_type = ipc_ut_get_net_type_from_netif_id(IPC_UT_LHIF_NETID_START);
+ nc_id = (net_type << 8) | ((0xFF) & IPC_UT_LHIF_NETID_START);
+
+ /* Simulate DL traffic to IPCore : PDN binding */
+ {
+ kal_uint32 did_cnt = 0;
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+ kal_uint32 alignment = 0;
+ kal_uint32 did_igr_bit = 0;
+ kal_uint32 free_cnt = 0;
+
+ for (alignment = 0; alignment < 4; alignment++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@[Binding] v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_send_did_by_ch_id_dl_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ UT_ASSERT(ipc_send_dl_did_by_ch_id(net_type, nc_id, did_head, did_tail));
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* verify filter result */
+ UT_ASSERT(ipc_ut_dl_callback_did_cnt == did_cnt);
+ UT_ASSERT(ipc_ut_dl_callback_did_pkt_cnt == ipv4_cnt + ipv6_cnt);
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_prepare_nr_dl_did_list(kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint16 *ipv4_invalid_packet_len,
+ kal_uint16 *ipv6_invalid_packet_len,
+ kal_uint32 did_cnt,
+ kal_bool did_igr_enable)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+ kal_bool is_add = KAL_FALSE;
+
+ if (did_cnt != ipc_ut_alloc_did(did_cnt, did_head, did_tail)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for (curr_did = *did_head; curr_did && (end_of_list == KAL_FALSE); curr_did = next_did) {
+ kal_uint32 i = 0;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+
+ /* Set SIT to the first SIT in DID for data configuration */
+ /* use did rsv2 instead of sit qfi */
+ /* use did rsv3 instead of sit nrqi */
+ curr_did = *did_head;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ is_add = KAL_FALSE;
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv4_tcp_syn_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_syn_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_tcp_syn_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_syn_packet);
+ is_add = KAL_FALSE;
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv4_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_ip_header_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag1_packet);
+ is_add = KAL_TRUE;
+ break;
+ default:
+ UT_ASSERT(KAL_FALSE);
+ break;
+ }
+
+ if (is_add) {
+ /* 11011010 */
+ curr_si->qfi = 0xDA;
+ curr_si->nrqi = KAL_TRUE;
+ ipc_ut_set_prepare_rq_info_list(&g_prepare_rq_info_list, packet_buf, curr_si->qfi);
+ g_ipc_ut_sdap_pkt_alloc_cnt++;
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ if (ipv4_invalid_packet_len) {
+ if (ipv4_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv4_invalid_packet_len[idx]>IPC_INVALID_MAX_PKT_LEN)?IPC_INVALID_MAX_PKT_LEN:ipv4_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len = 0;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+ cont_loop_cnt ++;
+ }
+ }
+
+ if ( (did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx]) ) {
+ kal_uint32 i = 0;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num --;
+ }
+ } else {
+ pkt_num ++;
+ }
+ }
+
+ if (ipv4_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ is_add = KAL_FALSE;
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_tcp_fin_ack_packet_2;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_fin_ack_packet_2);
+ is_add = KAL_TRUE;
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_ul_packet);
+ is_add = KAL_TRUE;
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_ul_packet);
+ is_add = KAL_FALSE;
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_incomplete_ah_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ah_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ break;
+ default:
+ UT_ASSERT(KAL_FALSE);
+ break;
+ }
+
+ if (is_add) {
+ /* 11011010 */
+ curr_si->qfi= 0xDA;
+ curr_si->nrqi= KAL_TRUE;
+ ipc_ut_set_prepare_rq_info_list(&g_prepare_rq_info_list, packet_buf, curr_si->qfi);
+ g_ipc_ut_sdap_pkt_alloc_cnt++;
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ if (ipv6_invalid_packet_len) {
+ if (ipv6_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv6_invalid_packet_len[idx]>IPC_INVALID_MAX_PKT_LEN)?IPC_INVALID_MAX_PKT_LEN:ipv6_invalid_packet_len[idx];
+ }
+ }
+#endif
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+ cont_loop_cnt ++;
+ }
+ }
+
+ if ( (did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx]) ) {
+ kal_uint32 i = 0;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num --;
+ }
+ } else {
+ pkt_num ++;
+ }
+ }
+
+ if (ipv6_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+}
+
+static void ipc_ut_nr_did_downlink_cbk(ipc_filter_info_t *p_filter_info,
+ void *p_args,
+ kal_int32 filter_id,
+ qbm_gpd *p_head,
+ qbm_gpd *p_tail,
+ kal_uint32 length)
+{
+ utDLOG("ipc_ut_nr_did_downlink_cbk !!!");
+ return;
+}
+
+kal_bool ipc_ut_nr_did_downlink(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 idx = 0;
+ ipc_ut_netif_t *net = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ kal_uint8 proto_idx[] = {0, 1};
+ kal_bool result = KAL_FALSE;
+ ilm_struct ilm = {0};
+ ipc_filter_rules_t rules = {0};
+ kal_int32 filter_id = 0;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* IPCORE may send UL traffic in disconnected state */
+ ipc_ut_reset_ul_info();
+
+ /* Simulate DL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Before Bind] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ kal_mem_set(&g_prepare_rq_info_list, 0, sizeof(ipc_data_rq_info_list));
+ kal_mem_set(&g_rq_info_list, 0, sizeof(ipc_data_rq_info_list));
+ g_ipc_ut_sdap_pkt_alloc_cnt = 0;
+ g_ipc_ut_sdap_pkt_received_cnt = 0;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_nr_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ KAL_FALSE);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ /* Registered DL filter to filter out TCP SYN packets*/
+ rules.valid_fields = IPC_FILTER_BY_PDN_ID |
+ IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_TCP_FLAGS;
+ rules.ip_type = IPC_IP_TYPE_IPV6;
+ rules.protocol = IPC_HDR_PROT_TCP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.tcp_flags = IPC_HDR_TCP_FLAG_SYN;
+
+ filter_id = ipc_register_dl_filter_with_info_cbk(&rules, ipc_ut_nr_did_downlink_cbk, NULL);
+ UT_ASSERT(0 == filter_id);
+
+ /* Simulate DL traffic to IPCore : All GPDs should be forward to DL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 total_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Binded] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_mem_set(&g_prepare_rq_info_list, 0, sizeof(ipc_data_rq_info_list));
+ kal_mem_set(&g_rq_info_list, 0, sizeof(ipc_data_rq_info_list));
+ g_ipc_ut_sdap_pkt_alloc_cnt = 0;
+ g_ipc_ut_sdap_pkt_received_cnt = 0;
+ UT_ASSERT(0 == kal_mem_cmp(&g_prepare_rq_info_list, &g_rq_info_list, sizeof(ipc_data_rq_info_list)));
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_nr_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ KAL_FALSE);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx);
+
+ if ( (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (total_cnt != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+
+ UT_ASSERT(0 == kal_mem_cmp(&g_prepare_rq_info_list, &g_rq_info_list, sizeof(ipc_data_rq_info_list)));
+ /* DL callback is correctly called : all GPDs are released */
+ }
+ }
+
+ ipc_deregister_dl_filter(filter_id);
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Simulate DL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("@ [Deactivated] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ kal_mem_set(&g_prepare_rq_info_list, 0, sizeof(ipc_data_rq_info_list));
+ kal_mem_set(&g_rq_info_list, 0, sizeof(ipc_data_rq_info_list));
+ g_ipc_ut_sdap_pkt_alloc_cnt = 0;
+ g_ipc_ut_sdap_pkt_received_cnt = 0;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_nr_dl_did_list(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ KAL_FALSE);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx);
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded after PDN deactivation!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+#endif
+
+static kal_bool ipc_ut_rebind_pdn_verification(ps_cause_enum result,
+ ipcore_upcm_pdn_rebind_ind_struct *p_rebind_req,
+ ipc_ut_msg_t *p_recv_ilm)
+{
+ ipcore_upcm_pdn_rebind_rsp_struct *p_rcv_rebind = NULL;
+ ipcore_upcm_pdn_rebind_rsp_struct *p_rebind_rsp = NULL;
+
+ UT_ASSERT(NULL != p_rebind_req);
+ UT_ASSERT(NULL != p_recv_ilm);
+
+ p_rebind_rsp = (ipcore_upcm_pdn_rebind_rsp_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_rebind_rsp_struct), TD_RESET);
+ p_rebind_rsp->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_rebind_rsp->old_pdn_id = p_rebind_req->old_pdn_id;
+ p_rebind_rsp->new_pdn_id = p_rebind_req->new_pdn_id;
+ kal_mem_cpy(&p_rebind_rsp->dns, &p_rebind_req->dns, sizeof(dns_struct));
+ kal_mem_cpy(&p_rebind_rsp->ip_addr, &p_rebind_req->ip_addr, sizeof(ip_addr_struct));
+ p_rebind_rsp->result = result;
+
+ p_rcv_rebind = (ipcore_upcm_pdn_rebind_rsp_struct *)p_recv_ilm->_local_para_ptr;
+ UT_ASSERT(MOD_IPCORE == ipc_ut_msg_sent._dest_mod_id);
+ UT_ASSERT(MOD_NIL == ipc_ut_msg_sent._src_mod_id);
+ UT_ASSERT(MSG_ID_IPCORE_UPCM_PDN_REBIND_RSP == ipc_ut_msg_sent._msg_id);
+ UT_ASSERT(IPCORE_SAP == ipc_ut_msg_sent._sap_id);
+ UT_ASSERT(p_rebind_rsp->network_interface_id == p_rcv_rebind->network_interface_id);
+ UT_ASSERT(p_rebind_rsp->new_pdn_id == p_rcv_rebind->new_pdn_id);
+ UT_ASSERT(p_rebind_rsp->old_pdn_id == p_rcv_rebind->old_pdn_id);
+ UT_ASSERT(p_rebind_rsp->result == p_rcv_rebind->result);
+ UT_ASSERT(0 == kal_mem_cmp(&p_rebind_rsp->dns, &p_rcv_rebind->dns, sizeof(dns_struct)));
+ UT_ASSERT(0 == kal_mem_cmp(&p_rebind_rsp->ip_addr, &p_rcv_rebind->ip_addr, sizeof(ip_addr_struct)));
+ UT_ASSERT(NULL == ipc_ut_msg_sent._peer_buff_ptr);
+
+ free_local_para((local_para_struct *)p_rebind_rsp);
+ return KAL_TRUE;
+}
+
+static kal_bool ipc_ut_unbind_pdn_req(kal_uint8 unbind_pdn)
+{
+ ilm_struct ilm = {0};
+ ipcore_upcm_pdn_unbind_ind_struct *p_unbind_req = NULL;
+
+ p_unbind_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ UT_ASSERT(NULL != p_unbind_req);
+ p_unbind_req->pdn_id = unbind_pdn;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)p_unbind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)p_unbind_req);
+
+ return KAL_TRUE;
+}
+
+static kal_bool ipc_ut_bind_pdn_req(pdp_addr_type_enum pdn_ip_type,
+ kal_uint8 pdn_id,
+ kal_uint32 netif_id)
+{
+ ilm_struct ilm = {0};
+ ipcore_upcm_pdn_bind_ind_struct *p_bind_req = NULL;
+
+ p_bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ p_bind_req->network_interface_id = netif_id;
+ p_bind_req->pdn_id = pdn_id;
+
+ switch (pdn_ip_type) {
+ case IPV4_ADDR_TYPE:
+ p_bind_req->dns.v4[0].is_dnsv4_present = KAL_TRUE;
+ p_bind_req->dns.v4[0].dnsv4[0] = 8;
+ p_bind_req->dns.v4[0].dnsv4[1] = 8;
+ p_bind_req->dns.v4[0].dnsv4[2] = 8;
+ p_bind_req->dns.v4[0].dnsv4[3] = 8;
+ p_bind_req->ip_addr.ip_addr_type = IPV4_ADDR_TYPE;
+ p_bind_req->ip_addr.ipv4[0] = 192;
+ p_bind_req->ip_addr.ipv4[1] = 168;
+ p_bind_req->ip_addr.ipv4[2] = 0;
+ p_bind_req->ip_addr.ipv4[3] = 2;
+ break;
+ case IPV6_ADDR_TYPE:
+ p_bind_req->dns.v6[0].is_dnsv6_present = KAL_TRUE;
+ p_bind_req->dns.v6[0].dnsv6[0] = 1;
+ p_bind_req->dns.v6[0].dnsv6[1] = 2;
+ p_bind_req->dns.v6[0].dnsv6[2] = 3;
+ p_bind_req->dns.v6[0].dnsv6[3] = 4;
+ p_bind_req->dns.v6[0].dnsv6[4] = 5;
+ p_bind_req->dns.v6[0].dnsv6[5] = 6;
+ p_bind_req->dns.v6[0].dnsv6[6] = 7;
+ p_bind_req->dns.v6[0].dnsv6[7] = 8;
+
+ p_bind_req->ip_addr.ip_addr_type = IPV6_ADDR_TYPE;
+ p_bind_req->ip_addr.ipv6[0] = 0xfd;
+ p_bind_req->ip_addr.ipv6[1] = 0xf1;
+ p_bind_req->ip_addr.ipv6[2] = 0x03;
+ p_bind_req->ip_addr.ipv6[3] = 0x04;
+ p_bind_req->ip_addr.ipv6[4] = 0x05;
+ p_bind_req->ip_addr.ipv6[5] = 0x06;
+ p_bind_req->ip_addr.ipv6[6] = 0x07;
+ p_bind_req->ip_addr.ipv6[7] = 0x08;
+ break;
+ case IPV4V6_ADDR_TYPE:
+ p_bind_req->dns.v4[0].is_dnsv4_present = KAL_TRUE;
+ p_bind_req->dns.v4[0].dnsv4[0] = 8;
+ p_bind_req->dns.v4[0].dnsv4[1] = 8;
+ p_bind_req->dns.v4[0].dnsv4[2] = 8;
+ p_bind_req->dns.v4[0].dnsv4[3] = 8;
+ p_bind_req->ip_addr.ip_addr_type = IPV4_ADDR_TYPE;
+ p_bind_req->ip_addr.ipv4[0] = 192;
+ p_bind_req->ip_addr.ipv4[1] = 168;
+ p_bind_req->ip_addr.ipv4[2] = 0;
+ p_bind_req->ip_addr.ipv4[3] = 2;
+ break;
+ default:
+ utELOG("unsupported pdn ip type");
+ return KAL_FALSE;
+ break;
+ }
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)p_bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)p_bind_req);
+
+ return KAL_TRUE;
+}
+
+static kal_bool ipc_ut_rebind_pdn_req(ipcore_upcm_pdn_rebind_ind_struct **p_rebind_req2,
+ pdp_addr_type_enum pdn_ip_type,
+ kal_uint8 old_pdn_id,
+ kal_uint8 new_pdn_id,
+ kal_uint32 netif_id)
+{
+ ilm_struct ilm = {0};
+ ipcore_upcm_pdn_rebind_ind_struct *p_rebind_req = NULL;
+
+ p_rebind_req = (ipcore_upcm_pdn_rebind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_rebind_ind_struct), TD_RESET);
+ p_rebind_req->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_rebind_req->old_pdn_id = old_pdn_id;
+ p_rebind_req->new_pdn_id = new_pdn_id;
+
+ switch (pdn_ip_type) {
+ case IPV4_ADDR_TYPE:
+ p_rebind_req->dns.v4[0].is_dnsv4_present = KAL_TRUE;
+ p_rebind_req->dns.v4[0].dnsv4[0] = 8;
+ p_rebind_req->dns.v4[0].dnsv4[1] = 8;
+ p_rebind_req->dns.v4[0].dnsv4[2] = 8;
+ p_rebind_req->dns.v4[0].dnsv4[3] = 8;
+ p_rebind_req->ip_addr.ip_addr_type = IPV4_ADDR_TYPE;
+ p_rebind_req->ip_addr.ipv4[0] = 192;
+ p_rebind_req->ip_addr.ipv4[1] = 168;
+ p_rebind_req->ip_addr.ipv4[2] = 0;
+ p_rebind_req->ip_addr.ipv4[3] = 1;
+ break;
+ case IPV6_ADDR_TYPE:
+ p_rebind_req->dns.v6[0].is_dnsv6_present = KAL_TRUE;
+ p_rebind_req->dns.v6[0].dnsv6[0] = 8;
+ p_rebind_req->dns.v6[0].dnsv6[1] = 7;
+ p_rebind_req->dns.v6[0].dnsv6[2] = 6;
+ p_rebind_req->dns.v6[0].dnsv6[3] = 5;
+ p_rebind_req->dns.v6[0].dnsv6[4] = 4;
+ p_rebind_req->dns.v6[0].dnsv6[5] = 3;
+ p_rebind_req->dns.v6[0].dnsv6[6] = 2;
+ p_rebind_req->dns.v6[0].dnsv6[7] = 1;
+
+ p_rebind_req->ip_addr.ip_addr_type = IPV6_ADDR_TYPE;
+ p_rebind_req->ip_addr.ipv6[0] = 0xfe;
+ p_rebind_req->ip_addr.ipv6[1] = 0xf0;
+ p_rebind_req->ip_addr.ipv6[2] = 0x01;
+ p_rebind_req->ip_addr.ipv6[3] = 0x02;
+ p_rebind_req->ip_addr.ipv6[4] = 0x03;
+ p_rebind_req->ip_addr.ipv6[5] = 0x04;
+ p_rebind_req->ip_addr.ipv6[6] = 0x05;
+ p_rebind_req->ip_addr.ipv6[7] = 0x06;
+ break;
+ case IPV4V6_ADDR_TYPE:
+ p_rebind_req->dns.v4[0].is_dnsv4_present = KAL_TRUE;
+ p_rebind_req->dns.v4[0].dnsv4[0] = 8;
+ p_rebind_req->dns.v4[0].dnsv4[1] = 8;
+ p_rebind_req->dns.v4[0].dnsv4[2] = 8;
+ p_rebind_req->dns.v4[0].dnsv4[3] = 8;
+ p_rebind_req->ip_addr.ip_addr_type = IPV4_ADDR_TYPE;
+ p_rebind_req->ip_addr.ipv4[0] = 192;
+ p_rebind_req->ip_addr.ipv4[1] = 168;
+ p_rebind_req->ip_addr.ipv4[2] = 0;
+ p_rebind_req->ip_addr.ipv4[3] = 1;
+ break;
+ default:
+ utELOG("unsupported pdn ip type");
+ return KAL_FALSE;
+ break;
+ }
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_REBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)p_rebind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+
+ *p_rebind_req2 = p_rebind_req;
+ return KAL_TRUE;
+}
+
+void ipc_ut_prepare_dl_did_list_tcprst(
+ kal_uint32 pkt_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint32 did_cnt)
+{
+ kal_uint32 total_cnt = pkt_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+ kal_uint8 per_pkt_max_sit_num = 10; /* one DID max packet number will be 7. one DID has 62 SIT entries */
+
+ if (did_cnt != ipc_ut_alloc_did(
+ did_cnt,
+ did_head,
+ did_tail)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for ( curr_did = *did_head ;
+ curr_did && (end_of_list == KAL_FALSE) ;
+ curr_did = next_did)
+ {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+ /*must have ra packet , test included to have other packets based upon ipv6 packet count*/
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+ for (idx = 0; idx < pkt_cnt; idx++) {
+ switch(idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv4_tcp_fin_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_fin_ack_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_tcp_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_ack_packet);
+ break;
+ case 2: // non tcp packet
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ break;
+ case 3:
+ // no-IP packet
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ break;
+ case 4:
+ // fragment non-1st packet
+ packet_buf = ipc_ut_ipv4_tcp_error_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_tcp_error_frag1_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_tcp_syn_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_syn_packet);
+ break;
+
+ }
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len)
+ {
+ kal_uint32 current_copy_len;
+
+ if ((curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) || (cont_loop_cnt == per_pkt_max_sit_num-1))
+ { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else
+ { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt ++;
+ }
+ }
+ pkt_num ++;
+
+ }
+
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+void ipc_ut_prepare_dl_did_list_udp(
+ kal_uint32 ipv4_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint32 did_cnt)
+{
+ kal_uint32 total_cnt = ipv4_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+ kal_uint8 per_pkt_max_sit_num = 10; /* one DID max packet number will be 7. one DID has 62 SIT entries */
+
+ if (did_cnt != ipc_ut_alloc_did(
+ did_cnt,
+ did_head,
+ did_tail)) {
+ IPC_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for ( curr_did = *did_head ;
+ curr_did && (end_of_list == KAL_FALSE) ;
+ curr_did = next_did)
+ {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ switch(idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv4_udp_packet_example;
+ packet_len = sizeof(ipc_ut_ipv4_udp_packet_example);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_udp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_udp_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_udp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_udp_packet);
+ break;
+ case 3:
+ packet_buf = g_ipc_ut_large_udp_pkt;
+ packet_len = sizeof(g_ipc_ut_large_udp_pkt);
+ break;
+ default:
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ break;
+ }
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len)
+ {
+ kal_uint32 current_copy_len;
+
+ if ((curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) || (cont_loop_cnt == per_pkt_max_sit_num-1))
+ { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else
+ { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt ++;
+ }
+ }
+ pkt_num ++;
+
+ }
+
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+
+kal_bool ipc_ut_downlink_test_udp_drop_packet(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ kal_uint8 proto_idx[] = {0, 1, 2, 3};
+ kal_uint32 idx;
+ kal_uint32 gpd_remain_cnt_ul, gpd_remain_cnt_dl, did_remain_cnt;
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++)
+ {
+ kal_uint32 cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint8 expected_pkt_cnt = 0;
+
+ for (alignment = 0 ; alignment < 1 ; alignment ++)
+ for (cnt = 1; cnt <= 5; cnt++) {
+
+ did_cnt = 1;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_reset_ul_info();
+
+ /*Store DID remain cnt */
+ did_remain_cnt = upcm_did_get_buff_remain_num();
+
+ /*prepare a DID of UDP ipv4 */
+ ipc_ut_prepare_dl_did_list_udp(cnt,
+ alignment,
+ &did_head,
+ &did_tail,
+ did_cnt);
+
+ /*Store GPD remain cnt */
+ gpd_remain_cnt_ul = qbm_get_buff_remain_num(QBM_TYPE_NET_UL);
+ gpd_remain_cnt_dl = qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx); //0 for SIM1
+
+ /*packet 1, 2, 3: udp packet
+ above 3 are non udp packet*/
+ if(cnt <= 3)
+ {
+ expected_pkt_cnt = cnt;
+ } else {
+ expected_pkt_cnt = 3;
+ }
+
+ if (ipc_ut_ul_gpd_cnt != expected_pkt_cnt) {
+ utELOG("wrong expected count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded on PDN unbind!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(gpd_remain_cnt_ul != qbm_get_buff_remain_num(QBM_TYPE_NET_UL)){
+ utELOG("wrong expected QBM_TYPE_NET_UL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+
+ }
+ }
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+
+}
+
+kal_bool ipc_ut_downlink_tcprst_packet(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ kal_uint8 proto_idx[] = {0, 1, 2, 3};
+ kal_uint32 idx;
+ kal_uint32 gpd_remain_cnt_ul, gpd_remain_cnt_dl, did_remain_cnt;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* no BINDING */
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++)
+ {
+ kal_uint32 pkt_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint8 expected_pkt_cnt = 0;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (pkt_cnt = 1; pkt_cnt <= 5; pkt_cnt++) {
+
+ did_cnt = 1;
+ expected_pkt_cnt = 0;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_reset_ul_info();
+
+ /*Store DID remain cnt */
+ did_remain_cnt = upcm_did_get_buff_remain_num();
+
+ /* prepare a DID of TCP RST */
+ ipc_ut_prepare_dl_did_list_tcprst(pkt_cnt,
+ alignment,
+ &did_head,
+ &did_tail,
+ did_cnt);
+
+ /*Store GPD remain cnt */
+ gpd_remain_cnt_ul = qbm_get_buff_remain_num(QBM_TYPE_NET_UL);
+ gpd_remain_cnt_dl = qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID on unbind condition*/
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx); //0 for SIM1
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded on PDN unbind!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* expected ul pkt cnt should be
+ * pkt 1 is of fin ack, generate 2 GPD
+ * pkt 2 is of ack pkt , generate 1 GPD
+ * pkt 3 is of ipv4 DNS packet(non tcp), generate 0 GPD
+ * pkt 4 is of non-IP packet, generate 0 GPD
+ * pkt 5 is of ipv4 non 1st fragment, generate 0 GPD
+ */
+ if ( pkt_cnt >= 1) {
+ expected_pkt_cnt += 2;
+ }
+ if ( pkt_cnt >= 2) {
+ expected_pkt_cnt += 1;
+ }
+ if ( pkt_cnt >= 3) {
+ expected_pkt_cnt += 0;
+ }
+ if ( pkt_cnt >= 4) {
+ expected_pkt_cnt += 0;
+ }
+ if ( pkt_cnt >= 5) {
+ expected_pkt_cnt += 0;
+ }
+
+ if (ipc_ut_ul_gpd_cnt != expected_pkt_cnt) {
+ utELOG("wrong expected count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(gpd_remain_cnt_ul != qbm_get_buff_remain_num(QBM_TYPE_NET_UL)){
+ utELOG("wrong expected QBM_TYPE_NET_UL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+static kal_bool ipc_ut_netif_attach(ipc_ut_netif_t *p_netif,
+ kal_uint32 netif_id)
+{
+ UT_ASSERT(NULL != p_netif);
+
+ kal_mem_set(p_netif, 0, sizeof(ipc_ut_netif_t));
+ p_netif->conf.module_id = MOD_IPCORE;
+ p_netif->conf.netif_id = netif_id;
+ p_netif->conf.ul_reload_context = p_netif;
+ p_netif->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ p_netif->conf.callback_context = p_netif;
+ p_netif->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ p_netif->conf.features = 0;
+ UT_ASSERT(ipc_attach(&p_netif->conf, &p_netif->handle));
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_rebind_pdn(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipc_ut_netif_t *p_netid_1 = &(ipc_ut_nets_s[0]);
+ ipc_ut_netif_t *p_netid_2 = &(ipc_ut_nets_s[1]);
+ ipcore_upcm_pdn_rebind_ind_struct *p_rebind_req = NULL;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ UT_ASSERT(ipc_reset());
+
+ /* Case 1 : no netif attach, no pdn binding, IPCore received rebind request from UPCM */
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_PDN_BIND_RSP_INVALID_NETIF, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+
+ /* Case 2 : netif attach, no pdn binding, IPCore received rebind request from UPCM */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_PDN_BIND_RSP_SESSION_RLOCK_FAIL, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 3 : netif attach, pdn IPv4 binding, IPCore received rebind request from UPCM */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ //UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID));
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 4 : netif attach, pdn IPv4 binding, IPCore received rebind request from UPCM with wrong old pdn */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4_ADDR_TYPE, IPC_UT_PDN_ID + 2, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_PDN_BIND_RSP_SESSION_RLOCK_FAIL, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 5 : netif attach, pdn IPv4 binding, IPCore received rebind request from UPCM with IPv4v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ //UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID));
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 6 : netif attach, pdn IPv4 binding, IPCore received rebind request from UPCM with v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV6_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 7 : netif attach, pdn IPv6 binding, IPCore received rebind request from UPCM with v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV6_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 7 : netif attach, pdn IPv6 binding, IPCore received rebind request from UPCM with v4 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 8 : netif attach, pdn IPv6 binding, IPCore received rebind request from UPCM with v4v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 9 : netif attach, pdn IPv4v6 binding, IPCore received rebind request from UPCM with v4v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 10 : netif attach, pdn IPv4v6 binding, IPCore received rebind request from UPCM with v4 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 11 : netif attach, pdn IPv4v6 binding, IPCore received rebind request from UPCM with v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV6_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 12 : netif attach, pdn IPv4 IPv6 binding, IPCore received rebind request from UPCM with v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV6_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_PDN_BIND_RSP_NEW_SESSION_FAIL, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID));
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID+1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 13 : netif attach, pdn IPv4 IPv6 binding, IPCore received rebind request from UPCM with v4 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_PDN_BIND_RSP_NEW_SESSION_FAIL, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 14 : netif attach, pdn IPv4 IPv6 binding, IPCore received rebind request from UPCM with v4 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 2, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 2));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 15 : netif attach, pdn IPv4 IPv6 binding, IPCore received rebind request from UPCM with v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV6_ADDR_TYPE, IPC_UT_PDN_ID + 1, IPC_UT_PDN_ID + 2, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID));
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 2));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 15 : netif attach, pdn IPv4 IPv6 binding, IPCore received rebind request from UPCM with v4v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID + 1, IPC_UT_PDN_ID + 2, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_PDN_BIND_RSP_NEW_SESSION_FAIL, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 16 : netif attach, pdn IPv4 IPv6 binding, IPCore received rebind request from UPCM with v4v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID + 1, IPC_UT_PDN_ID + 2, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 2));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ /* Case 17 : netif attach, pdn IPv4 IPv6 binding, IPCore received rebind request from UPCM with v4v6 pdn type */
+ UT_ASSERT(ipc_ut_netif_attach(p_netid_1, IPC_UT_LHIF_NETID_START));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV4_ADDR_TYPE, IPC_UT_PDN_ID, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_bind_pdn_req(IPV6_ADDR_TYPE, IPC_UT_PDN_ID + 1, p_netid_1->conf.netif_id));
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 1));
+ UT_ASSERT(ipc_ut_rebind_pdn_req(&p_rebind_req, IPV4V6_ADDR_TYPE, IPC_UT_PDN_ID, IPC_UT_PDN_ID + 2, p_netid_1->conf.netif_id));
+ UT_ASSERT(NULL != p_rebind_req);
+
+ /* verification */
+ UT_ASSERT(ipc_ut_rebind_pdn_verification(HIF_IPC_OK, p_rebind_req, &ipc_ut_msg_sent));
+ free_local_para((local_para_struct *)p_rebind_req);
+ UT_ASSERT(ipc_ut_unbind_pdn_req(IPC_UT_PDN_ID + 2));
+ UT_ASSERT(ipc_detach(p_netid_1->handle));
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ipc_fragment(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipc_fragment_test();
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_filter_info_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *p_head,
+ qbm_gpd *p_tail,
+ kal_uint32 length)
+{
+ g_normal_cbk_pkt_recv_cnt++;
+ qbmt_dest_q(p_head, p_tail);
+}
+
+void ipc_ut_filter_cbk(void *context,
+ kal_int32 filter_id,
+ qbm_gpd *p_head,
+ qbm_gpd *p_tail,
+ kal_uint32 length)
+{
+ g_normal_cbk_pkt_recv_cnt++;
+ qbmt_dest_q(p_head, p_tail);
+}
+
+kal_bool ipc_ut_cust_filter_cbk(const kal_uint8 *p_pkt,
+ kal_int32 pkt_len,
+ kal_int32 filter_id,
+ void *p_args)
+{
+ kal_bool ret = KAL_FALSE;
+ kal_uint32 win_size = 0;
+
+ if (IPC_HDR_IS_V4(p_pkt)) {
+ win_size = IPC_HDR_TCP_GET_WINDOW(p_pkt + IPC_HDR_V4_HEADER_SIZE);
+ if (0x2001 == win_size) {
+ g_cbk_pkt_recv_cnt++;
+ ret = KAL_TRUE;
+ }
+ } else if (IPC_HDR_IS_V6(p_pkt)) {
+ } else {
+ UT_ASSERT(KAL_FALSE);
+ }
+
+ return ret;
+}
+
+kal_bool ipc_ut_new_filter_verification(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipc_filter_rules_t rules = {0};
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+ kal_int32 filter_id = 0;
+
+ /* invalid data path */
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(2, &rules, &ntfy_ctxt));
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(3, &rules, &ntfy_ctxt));
+
+ /* invalid rules */
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(UL_DIRECT, &rules, &ntfy_ctxt));
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, NULL, &ntfy_ctxt));
+
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.pdn_id = 5;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+
+ /* invalid ntfy_ctxt */
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(UL_DIRECT, &rules, &ntfy_ctxt));
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, NULL));
+
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM;
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ UT_ASSERT(1 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+ ipc_dereg_filter(1);
+
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO;
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ UT_ASSERT(1 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+ ipc_dereg_filter(1);
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ UT_ASSERT(1 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+ ipc_dereg_filter(1);
+
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ UT_ASSERT(1 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+ ipc_dereg_filter(1);
+
+ rules.features |= IPC_FILTER_FEATURE_CUST_FILTER;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM;
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_ILM_WITH_FILTER_INFO;
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ rules.cust_cbk_func = ipc_ut_cust_filter_cbk;
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ UT_ASSERT(1 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+ ipc_dereg_filter(1);
+
+ /* invalid DL filter to filter out ESP packets : no set PROTOCOL in valid fields */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_SPI |
+ IPC_FILTER_BY_PDN_ID;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.spi = 0x0000000a;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+
+ /* invalid DL filter to filter out ESP packets : set wrong PROTOCOL in valid fields */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SPI |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.spi = 0x0000000a;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+
+ /* valid DL filter to filter out ESP packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SPI |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_ESP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.spi = 0x0000000a;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* invalid DL filter to filter out src port packets : wrong protocol */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_ESP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.src_port = 132;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+
+ /* invalid DL filter to filter out dst port packets : wrong protocol */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_ICMP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.src_port = 132;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+
+ /* invalid DL filter to filter out icmp v4 packets : wrong protocol */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV4_TYPE |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.src_port = 132;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+
+ /* invalid DL filter to filter out icmp v4 packets : wrong ip version */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV4_TYPE |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_ICMP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.src_port = 132;
+ rules.ip_type = IPC_IP_TYPE_IPV6;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+
+ /* invalid DL filter to filter out icmp v6 packets : wrong protocol */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV6_TYPE |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.src_port = 132;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+
+ /* invalid DL filter to filter out icmp v4 packets : wrong ip version */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV6_TYPE |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_ICMP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.src_port = 132;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(IPC_INVALID_FILTER_ID == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+
+ /* valid DL filter to filter out tcp port packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_TCP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.src_ipv4.addr32 = 3;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out tcp port packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_TCP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV6;
+ rules.src_ipv6.addr32[0] = 3;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out tcp port packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_TCP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.dst_ipv4.addr32 = 3;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out tcp port packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_TCP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV6;
+ rules.dst_ipv6.addr32[0] = 3;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out udp port packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.src_ipv4.addr32 = 3;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out udp port packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV6;
+ rules.src_ipv6.addr32[0] = 3;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out udp port packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.dst_ipv4.addr32 = 3;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out udp port packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_UDP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV6;
+ rules.dst_ipv6.addr32[0] = 3;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out icmp v4 packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV4_TYPE |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_ICMP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.icmpv4_type = 2;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ /* valid DL filter to filter out icmp v6 packets */
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV6_TYPE |
+ IPC_FILTER_BY_PDN_ID;
+ rules.protocol = IPC_HDR_PROT_ICMPV6;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.ip_type = IPC_IP_TYPE_IPV6;
+ rules.icmpv6_type = 2;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ UT_ASSERT(0 == ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt));
+ ipc_dereg_filter(0);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_esp_parser(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipc_packet_info_t p_info = {0};
+ kal_uint32 spi = 0;
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v4_esp_pkt_1, sizeof(g_ipc_ut_v4_esp_pkt_1), &p_info);
+ spi = 0x0000000a;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v4_ah_esp_pkt_1, sizeof(g_ipc_ut_v4_ah_esp_pkt_1), &p_info);
+ spi = 0x48dac2e4;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v6_esp_pkt_1, sizeof(g_ipc_ut_v6_esp_pkt_1), &p_info);
+ spi = 0x49507646;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v6_ah_esp_pkt_1, sizeof(g_ipc_ut_v6_ah_esp_pkt_1), &p_info);
+ spi = 0x49507656;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v6_routing_ah_esp_pkt_1, sizeof(g_ipc_ut_v6_routing_ah_esp_pkt_1), &p_info);
+ spi = 0x49507666;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v6_routing_esp_pkt_1, sizeof(g_ipc_ut_v6_routing_esp_pkt_1), &p_info);
+ spi = 0x49507676;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v6_hop_dst_route_esp_pkt_1, sizeof(g_ipc_ut_v6_hop_dst_route_esp_pkt_1), &p_info);
+ spi = 0x49508637;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v6_hop_dst_route_ah_esp_pkt_1, sizeof(g_ipc_ut_v6_hop_dst_route_ah_esp_pkt_1), &p_info);
+ spi = 0x49507637;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ kal_mem_set(&p_info, 0, sizeof(p_info));
+ ipc_get_packet_info(g_ipc_ut_v6_hop_dst_route_frag_ah_esp_pkt_1, sizeof(g_ipc_ut_v6_hop_dst_route_frag_ah_esp_pkt_1), &p_info);
+ spi = 0x49507737;
+ UT_ASSERT(spi == p_info.spi);
+ UT_ASSERT(IPC_HDR_PROT_ESP == p_info.protocol);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_prepare_esp_filter_pkt(kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint16 *ipv4_invalid_packet_len,
+ kal_uint16 *ipv6_invalid_packet_len,
+ kal_uint32 did_cnt,
+ kal_bool did_igr_enable)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+
+ if (did_cnt != ipc_ut_alloc_did(did_cnt, did_head, did_tail)) {
+ IPC_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for (curr_did = *did_head; curr_did && (end_of_list == KAL_FALSE);
+ curr_did = next_did) {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+
+ /* Set SIT to the first SIT in DID for data configuration */
+ curr_did = *did_head;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ switch (idx % 3) {
+ case 0 :
+ //packet_buf = ipc_ut_ipv4_tcp_empty_ack_packet;
+ //packet_len = sizeof(ipc_ut_ipv4_tcp_empty_ack_packet);
+ packet_buf = g_ipc_ut_v4_esp_pkt_1;
+ packet_len = sizeof(g_ipc_ut_v4_esp_pkt_1);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ g_cbk_pkt_send_cnt++;
+ break;
+ case 1 :
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ case 2 :
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_7;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_7);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ default :
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_6;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_6);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ if (ipv4_invalid_packet_len) {
+ if (ipv4_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv4_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv4_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+#if 1
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt++;
+ }
+ }
+#endif
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv4_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv6_invalid_packet_len) {
+ if (ipv6_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv6_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv6_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt++;
+ }
+ }
+
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv6_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+}
+
+
+void ipc_ut_prepare_ra_filter_pkt(kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint16 *ipv4_invalid_packet_len,
+ kal_uint16 *ipv6_invalid_packet_len,
+ kal_uint32 did_cnt,
+ kal_bool did_igr_enable)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+
+ if (did_cnt != ipc_ut_alloc_did(did_cnt, did_head, did_tail)) {
+ IPC_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for (curr_did = *did_head; curr_did && (end_of_list == KAL_FALSE);
+ curr_did = next_did) {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+
+ /* Set SIT to the first SIT in DID for data configuration */
+ curr_did = *did_head;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ switch (idx % 3) {
+ case 0 :
+ //packet_buf = ipc_ut_ipv4_tcp_empty_ack_packet;
+ //packet_len = sizeof(ipc_ut_ipv4_tcp_empty_ack_packet);
+ packet_buf = g_ipc_ut_icmp_ra_pkt;
+ packet_len = sizeof(g_ipc_ut_icmp_ra_pkt);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ g_cbk_pkt_send_cnt++;
+ break;
+ case 1 :
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ case 2 :
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_7;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_7);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ default :
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_6;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_6);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ if (ipv4_invalid_packet_len) {
+ if (ipv4_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv4_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv4_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+#if 1
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt++;
+ }
+ }
+#endif
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv4_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ packet_buf = g_ipc_ut_icmpv6_ra_pkt;
+ packet_len = sizeof(g_ipc_ut_icmpv6_ra_pkt);
+ g_cbk_pkt_send_cnt++;
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv6_invalid_packet_len) {
+ if (ipv6_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len = (ipv6_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv6_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt++;
+ }
+ }
+
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv6_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+}
+
+kal_bool ipc_ut_esp_filter(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 i = 0;
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ ipcore_upcm_pdn_bind_ind_struct *p_bind_req = NULL;
+ ipc_filter_rules_t rules = {0};
+ kal_int32 filter_id = 0;
+ kal_uint32 pdn_id = 0;
+ ipc_session_t *p_session = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ /* initialize before test & reset IPCORE */
+ ipc_ut_init();
+ ASSERT(KAL_TRUE == ipc_reset());
+
+ /* netif attach */
+ ASSERT(KAL_TRUE == ipc_ut_fin_ack_filter_netif_attach());
+
+ /* IPv4 binding */
+ p_bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ p_bind_req->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_bind_req->pdn_id = IPC_UT_PDN_ID;
+ p_bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)p_bind_req);
+ free_local_para((local_para_struct * )p_bind_req);
+
+ /* Registered DL filter to filter out ESP packets*/
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_PDN_ID |
+ IPC_FILTER_BY_SPI;
+ rules.protocol = IPC_HDR_PROT_ESP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.spi = 0x0000000a;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ filter_id= ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt);
+ ASSERT(0 == filter_id);
+
+ /* Simulate DL traffic to IPCore : PDN binding */
+ {
+ kal_uint32 did_cnt = 0;
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+ kal_uint32 alignment = 0;
+ kal_uint32 did_igr_bit = 0;
+ kal_uint32 free_cnt = 0;
+
+ for (alignment = 0; alignment < 4; alignment++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@[Binding] v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+ //g_cbk_pkt_recv_cnt = 0;
+ g_cbk_pkt_send_cnt = 0;
+ g_normal_cbk_pkt_recv_cnt = 0;
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_esp_filter_pkt(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ UT_ASSERT(g_cbk_pkt_send_cnt == g_normal_cbk_pkt_recv_cnt);
+ //UT_ASSERT(g_cbk_pkt_recv_cnt == g_cbk_pkt_send_cnt);
+ UT_ASSERT((ipc_ut_dl_callback_did_pkt_cnt + g_normal_cbk_pkt_recv_cnt) == (ipv4_cnt + ipv6_cnt));
+ }
+ }
+ ipc_dereg_filter(filter_id);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+
+}
+
+void ipc_ut_prepare_cust_filter_pkt(kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint16 *ipv4_invalid_packet_len,
+ kal_uint16 *ipv6_invalid_packet_len,
+ kal_uint32 did_cnt,
+ kal_bool did_igr_enable)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+
+ if (did_cnt != ipc_ut_alloc_did(did_cnt, did_head, did_tail)) {
+ IPC_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for (curr_did = *did_head; curr_did && (end_of_list == KAL_FALSE); curr_did = next_did) {
+ kal_uint32 i = 0;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+
+ /* Set SIT to the first SIT in DID for data configuration */
+ curr_did = *did_head;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ switch (idx % 3) {
+ case 0:
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_5;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_5);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ g_cbk_pkt_send_cnt++;
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI)
+ ;
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_7;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_7);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI)
+ ;
+ break;
+ default:
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_6;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_6);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI)
+ ;
+ break;
+ }
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ if (ipv4_invalid_packet_len) {
+ if (ipv4_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len =
+ (ipv4_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv4_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else { /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+ cont_loop_cnt++;
+ }
+ }
+
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv4_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+
+#if (IPC_UT_GEN_INVALID_LEN_PKT)
+ // invalid len packet
+ if (ipv6_invalid_packet_len) {
+ if (ipv6_invalid_packet_len[idx] > packet_len) {
+ packet_buf = ipc_ut_invalid_len_ip_packet;
+ packet_len =
+ (ipv6_invalid_packet_len[idx] > IPC_INVALID_MAX_PKT_LEN) ? IPC_INVALID_MAX_PKT_LEN : ipv6_invalid_packet_len[idx];
+ }
+ }
+#endif
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) {
+ /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else {
+ /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+ cont_loop_cnt++;
+ }
+ }
+
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+ }
+
+ if (ipv6_cnt) {
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+}
+
+kal_bool ipc_ut_cust_filter(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 i = 0;
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ ipcore_upcm_pdn_bind_ind_struct *p_bind_req = NULL;
+ ipc_filter_rules_t rules = {0};
+ kal_int32 filter_id = 0;
+ kal_uint32 pdn_id = 0;
+ ipc_session_t *p_session = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ /* initialize before test & reset IPCORE */
+ ipc_ut_init();
+ UT_ASSERT(KAL_TRUE == ipc_reset());
+
+ /* netif attach */
+ UT_ASSERT(KAL_TRUE == ipc_ut_fin_ack_filter_netif_attach());
+
+ /* IPv4 binding */
+ p_bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ p_bind_req->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_bind_req->pdn_id = IPC_UT_PDN_ID;
+ p_bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)p_bind_req);
+ free_local_para((local_para_struct * )p_bind_req);
+
+ /* Registered DL filter to filter out TCP SYN packets*/
+ rules.valid_fields = IPC_FILTER_BY_PDN_ID |
+ IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_TCP_FLAGS;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.protocol = IPC_HDR_PROT_TCP;
+ rules.pdn_id = IPC_UT_PDN_ID;
+ rules.tcp_flags = IPC_HDR_TCP_FLAG_SYN;
+ rules.features = IPC_FILTER_FEATURE_CUST_FILTER;
+ rules.cust_cbk_func = ipc_ut_cust_filter_cbk;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_filter_info_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+
+ filter_id= ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt);
+ UT_ASSERT(0 == filter_id);
+
+ /* Simulate DL traffic to IPCore : PDN binding */
+ {
+ kal_uint32 did_cnt = 0;
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+ kal_uint32 alignment = 0;
+ kal_uint32 did_igr_bit = 0;
+ kal_uint32 free_cnt = 0;
+
+ for (alignment = 0; alignment < 4; alignment++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@[Binding] v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+ g_cbk_pkt_recv_cnt = 0;
+ g_cbk_pkt_send_cnt = 0;
+ g_normal_cbk_pkt_recv_cnt = 0;
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_cust_filter_pkt(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ UT_ASSERT(g_cbk_pkt_recv_cnt == g_cbk_pkt_send_cnt);
+ UT_ASSERT((ipc_ut_dl_callback_did_pkt_cnt + g_normal_cbk_pkt_recv_cnt) == (ipv4_cnt + ipv6_cnt));
+ }
+ }
+ ipc_dereg_filter(filter_id);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_pdn_sim_macro(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint8 sim_idx = 0;
+ kal_uint8 pdn_id = 0;
+
+ /* (sim_idx, pdn_id) = (0, 5) => 0000 0101 */
+ sim_idx = 0;
+ pdn_id = 5;
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x05 == pdn_id);
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x00 == sim_idx);
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x05 == pdn_id);
+ IPC_UNMASK_PROTOID_FROM_PDNID(pdn_id);
+ UT_ASSERT(0x05 == pdn_id);
+
+ /* (sim_idx, pdn_id) = (1, 5) => 0100 0101 */
+ sim_idx = 1;
+ pdn_id = 5;
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x45 == pdn_id);
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x01 == sim_idx);
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x45 == pdn_id);
+ IPC_UNMASK_PROTOID_FROM_PDNID(pdn_id);
+ UT_ASSERT(0x05 == pdn_id);
+
+ /* (sim_idx, pdn_id) = (2, 5) => 1000 0101 */
+ sim_idx = 2;
+ pdn_id = 5;
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x85 == pdn_id);
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x02 == sim_idx);
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x85 == pdn_id);
+ IPC_UNMASK_PROTOID_FROM_PDNID(pdn_id);
+ UT_ASSERT(0x05 == pdn_id);
+
+ /* (sim_idx, pdn_id) = (3, 5) => 1100 0101 */
+ sim_idx = 3;
+ pdn_id = 5;
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0xC5 == pdn_id);
+ IPC_RETRIEVE_PROTOID_FROM_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0x03 == sim_idx);
+ IPC_MASK_PROTOID_ON_PDNID(pdn_id, sim_idx);
+ UT_ASSERT(0xC5 == pdn_id);
+ IPC_UNMASK_PROTOID_FROM_PDNID(pdn_id);
+ UT_ASSERT(0x05 == pdn_id);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+static void ipc_ut_prepare_retry_queue_list(kal_uint32 ipv4_cnt,
+ kal_bool dnsv4_only,
+ kal_bool v4hdr_exist,
+ kal_uint32 ipv6_cnt,
+ kal_bool dnsv6_only,
+ kal_bool v6hdr_exist,
+ kal_uint32 additional_bd_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint32 did_cnt,
+ kal_bool did_igr_enable,
+ kal_uint32 did_flow)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx = 0;
+ upcm_did *curr_did = NULL;
+ upcm_did_si *curr_sit = NULL;
+ upcm_did_si *curr_si = NULL;
+ kal_uint32 curr_si_idx = 0;
+ kal_uint32 pkt_start_si_idx = 0;
+ kal_uint8 *packet_buf = NULL;
+ kal_uint32 packet_len = 0;
+ kal_uint32 pkt_num = 0;
+ kal_uint32 seg_num = 0;
+ kal_uint32 flow = did_flow;
+
+ if (did_cnt != ipc_ut_alloc_did(did_cnt, did_head, did_tail)) {
+ IPC_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *p_next_did = NULL;
+ kal_bool end_of_list = KAL_FALSE;
+ kal_uint32 i = 0;
+
+ for (curr_did = *did_head; (end_of_list == KAL_FALSE); curr_did = p_next_did) {
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ p_next_did = UPCM_DID_GET_NEXT(curr_did);
+ end_of_list = (curr_did == *did_tail);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *p_sit = &curr_sit[i];
+ UPCM_DID_SI_SET_OFFSET(p_sit, UPCM_DID_SI_GET_OFFSET(p_sit) + (align_offset % 4));
+ }
+ UPCM_DID_SET_FLOW(curr_did, ++flow);
+ }
+ }
+
+ {
+ upcm_did *p_next_did = NULL;
+ kal_bool end_of_list = KAL_FALSE;
+ kal_uint32 i = 0;
+ kal_uint32 cur_flow = 0;
+
+ for (curr_did = *did_head; (end_of_list == KAL_FALSE); curr_did = p_next_did) {
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ p_next_did = UPCM_DID_GET_NEXT(curr_did);
+ end_of_list = (curr_did == *did_tail);
+ cur_flow = UPCM_DID_GET_FLOW(curr_did);
+
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+
+ switch (cur_flow % 2) {
+ case 0 :
+ packet_buf = g_ipc_ut_v4_esp_pkt_1;
+ packet_len = sizeof(g_ipc_ut_v4_esp_pkt_1);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ case 1 :
+ default :
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+ UPCM_DID_SET_SW_CTRL_FIELD(curr_did, IPC_UT_DL_EBI);
+ break;
+ }
+
+ {
+ kal_uint32 copied_len = 0;
+ kal_uint32 cont_loop_cnt = 0;
+ kal_uint32 si_offset = 0;
+
+ pkt_start_si_idx = curr_si_idx;
+ while (copied_len < packet_len) {
+ kal_uint32 current_copy_len = 0;
+
+ if (curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) {
+ /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else {
+ /* Non latest SIT : copy partial of data */
+ current_copy_len = (
+ ((align_offset > 0) || (cont_loop_cnt % 2)) ? (idx + cont_loop_cnt) : 0) % (packet_len - copied_len);
+ current_copy_len =
+ (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx++;
+ curr_si = &curr_sit[curr_si_idx];
+ cont_loop_cnt++;
+ }
+ }
+
+ if ((did_igr_enable) && (1 == ipc_ut_did_packet_igr_s[idx])) {
+ kal_uint32 i = 0;
+
+ for (i = pkt_start_si_idx; i < curr_si_idx; i++) {
+ upcm_did_si *tmp_si = &curr_sit[i];
+ UPCM_DID_SI_SET_HIF_TYPE(tmp_si, IPC_SI_HIF_TYPE_IGR);
+ seg_num--;
+ }
+ } else {
+ pkt_num++;
+ }
+
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+ }
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ return;
+}
+
+kal_bool ipc_ut_dl_cbk_retry_did(void *context, upcm_did *did)
+{
+ upcm_did *p_next_did = NULL;
+ upcm_did *p_curr_did = did;
+ kal_uint32 i = 0;
+
+ UT_ASSERT(NULL != did);
+
+ ipc_ut_dl_callback_did_cnt ++;
+ ipc_ut_dl_callback_did_pkt_cnt += UPCM_DID_GET_PKT_NUM(did);
+
+ if ((2 == UPCM_DID_GET_FLOW(p_curr_did)) && g_is_block) {
+ g_is_block = KAL_FALSE;
+
+ if (KAL_FALSE == g_is_insert) {
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+ ipc_ut_prepare_retry_queue_list(1, KAL_FALSE, KAL_FALSE, 1, KAL_FALSE, KAL_FALSE, 0, 0, &did_head, &did_tail, 2, KAL_FALSE, 6);
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ g_is_insert = KAL_TRUE;
+ }
+
+ return KAL_FALSE;
+ } else {
+ g_is_block = KAL_TRUE;
+ }
+
+ UT_ASSERT(g_current_flow < UPCM_DID_GET_FLOW(p_curr_did));
+ g_current_flow = UPCM_DID_GET_FLOW(p_curr_did);
+ return KAL_TRUE;
+}
+
+static kal_bool ipc_ut_retry_queue_netif_attach(void) {
+ ipc_conf_t config = {0};
+ ipc_handle_t p_handle = NULL;
+ kal_bool ret = KAL_TRUE;
+
+ config.module_id = MOD_IPCORE;
+ config.netif_id = IPC_UT_LHIF_NETID_START;
+ config.features = 0;
+ config.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ config.ipc_dlink_did_cb_t = ipc_ut_dl_cbk_retry_did;
+ config.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+
+ UT_ASSERT(KAL_TRUE == ipc_attach(&config, &p_handle));
+ UT_ASSERT(NULL != p_handle);
+ utDLOG("netif id = %d attach successfully", config.netif_id);
+
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_did_retry_put_head_queue(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 i = 0;
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ ipcore_upcm_pdn_bind_ind_struct *p_bind_req = NULL;
+ ipc_filter_rules_t rules = {0};
+ kal_int32 filter_id = 0;
+ kal_uint32 pdn_id = 0;
+ ipc_session_t *p_session = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ /* initialize before test & reset IPCORE */
+ ipc_ut_init();
+ ASSERT(KAL_TRUE == ipc_reset());
+
+ /* netif attach */
+ ASSERT(KAL_TRUE == ipc_ut_retry_queue_netif_attach());
+
+ /* IPv4 binding */
+ p_bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ p_bind_req->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_bind_req->pdn_id = IPC_UT_PDN_ID;
+ p_bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)p_bind_req);
+ free_local_para((local_para_struct * )p_bind_req);
+
+ /* Simulate DL traffic to IPCore : PDN binding */
+ {
+ kal_uint32 did_cnt = 0;
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+ kal_uint32 alignment = 0;
+ kal_uint32 did_igr_bit = 0;
+ kal_uint32 free_cnt = 0;
+
+ for (alignment = 0; alignment < 4; alignment++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@[Binding] v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+ g_cbk_pkt_send_cnt = 0;
+ g_normal_cbk_pkt_recv_cnt = 0;
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 2 : 3;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_ut_prepare_retry_queue_list(ipv4_cnt, KAL_FALSE, KAL_FALSE, ipv6_cnt, KAL_FALSE, KAL_FALSE, 0, alignment, &did_head, &did_tail, did_cnt, did_igr_bit, 0);
+ g_current_flow = 0;
+ g_is_insert = KAL_FALSE;
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ }
+ }
+ ipc_dereg_filter(filter_id);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_prepare_ipc_ut_ul_udp_igmp_filter(kal_bool allValidIpPkt,
+ kal_uint32 ipv4_tcp_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_uint32 ipv4_udp_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ LHIF_QUEUE_TYPE *q_type,
+ kal_uint32 netif_id,
+ kal_uint8 proto_idx,
+ kal_uint8 test_stage)
+{
+ kal_uint32 total_cnt = ipv4_tcp_cnt + ipv4_udp_cnt;
+ kal_uint32 idx = 0;
+ kal_uint32 curr_meta_idx = 0;
+ lhif_meta_tbl_t *curr_meta = NULL;
+ kal_uint8 *packet_buf = NULL;
+ kal_uint32 packet_len = 0;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+
+ if (total_cnt != ipc_ut_alloc_meta(IPC_UT_LHIF_META_AP0, total_cnt, p_head_idx, p_tail_idx)) {
+ IPC_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ *q_type = LHIF_HWQ_AP_UL_Q0;
+ curr_meta_idx = *p_head_idx;
+
+ for (idx = 0; idx < total_cnt; idx++) {
+ curr_meta = &ipc_ut_meta_tbl_s[curr_meta_idx];
+ curr_meta->net_type = ((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS;
+ curr_meta->channel_id = netif_id & 0x0000001F;
+ curr_meta->mr = IPC_HPC_MR_UNKNOWN;
+
+ switch (idx % 6) {
+ case 0:
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ g_chk_pkt_cnt++;
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_3;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_2);
+ break;
+ case 2:
+ packet_buf = g_ipc_ut_igmp_pkt_1;
+ packet_len = sizeof(g_ipc_ut_igmp_pkt_1);
+ g_chk_pkt_cnt++;
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_tcp_fin_ack_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_fin_ack_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_dhcp_ul_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_ul_packet);
+ g_chk_pkt_cnt++;
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_udp_zero_checksum_packet;
+ packet_len = sizeof(ipc_ut_ipv6_udp_zero_checksum_packet);
+ g_chk_pkt_cnt++;
+ break;
+ default:
+ packet_buf = ipc_ut_ipv4_ul_syn_window_scale_packets_3;
+ packet_len = sizeof(ipc_ut_ipv4_ul_syn_window_scale_packets_3);
+ break;
+ }
+
+ kal_mem_cpy(curr_meta->vrb_addr, packet_buf, packet_len);
+ curr_meta->length = packet_len;
+
+ curr_meta_idx++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+ return;
+}
+
+kal_bool ipc_ut_ul_udp_igmp_filter(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 blocked_cnt = 0;
+ ipc_ut_netif_t *net = NULL;
+ kal_uint32 netif_id = IPC_NETIF_ID_ETH_BEGIN;
+ kal_bool result = KAL_FALSE;
+ kal_uint32 idx = 0;
+ kal_uint8 proto_idx[] = {0, 1};
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ilm_struct ilm = {0};
+ kal_uint8 test_stage = 0;
+ ipc_session_t *p_session = NULL;
+ ipc_filter_rules_t rules = {0};
+ kal_int32 filter_id = 0;
+ kal_uint32 pdn_id = 0;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_NETIF_ID_ETH_BEGIN;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++) {
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Simulate UL traffic to IPCore : Before PDN binding, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_BEFORE_BINDING;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@ [Before Bind] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ ipc_ut_prepare_ipc_ut_ul_udp_igmp_filter(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded before PDN binding! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE)
+ {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ utDLOG("PDN binding successfull");
+
+ /* Registered uplink filter */
+ UT_ASSERT(KAL_TRUE == msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_IPCORE_UDP_IGMP_REG_FILTER_REQ, NULL, NULL));
+
+ /* Simulate UL traffic to IPCore : All GPDs should be forward to UL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt = 0;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_BINDING;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@ [Binded] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ g_chk_pkt_cnt = 0;
+ ipc_ut_prepare_ipc_ut_ul_udp_igmp_filter(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ UT_ASSERT(total_cnt == ipc_ut_ul_meta_cnt);
+ UT_ASSERT(g_chk_pkt_cnt == g_ipc_ut_igr_meta_cnt);
+ }
+ }
+
+ UT_ASSERT(KAL_TRUE == msg_send6(MOD_NIL, MOD_IPCORE, IPCORE_SAP, MSG_ID_IPCORE_UDP_IGMP_DEREG_FILTER_REQ, NULL, NULL));
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* Simulate UL traffic to IPCore : After PDN deactivation, all GPDs should be silently dropped by IPCore and NO callback is triggered */
+ {
+ kal_uint32 total_cnt;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+
+ test_stage = IPC_UT_STAGE_UNBINDING;
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@ [Deactivated] proto_idx(%d),v4_cnt(%d),v6_cnt(%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+ ipc_ut_prepare_ipc_ut_ul_udp_igmp_filter(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, idx, test_stage);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ if ( (total_cnt != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded after PDN deactivation! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, ipv4_cnt, ipv6_cnt);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_prepare_dl_did_list_ipv6ra(
+ kal_uint32 pkt_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint32 did_cnt)
+{
+ kal_uint32 total_cnt = pkt_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+ kal_uint8 per_pkt_max_sit_num = 10; /* one DID max packet number will be 7. one DID has 62 SIT entries */
+
+ if (did_cnt != ipc_ut_alloc_did(
+ did_cnt,
+ did_head,
+ did_tail)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for ( curr_did = *did_head ;
+ curr_did && (end_of_list == KAL_FALSE) ;
+ curr_did = next_did)
+ {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+ /*must have ra packet , test included to have other packets based upon ipv6 packet count*/
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+ for (idx = 0; idx < pkt_cnt; idx++) {
+ switch(idx) {
+ case 0:
+ packet_buf = g_ipc_ut_icmpv6_ra_pkt;
+ packet_len = sizeof(g_ipc_ut_icmpv6_ra_pkt);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_tcp_syn_packet;
+ packet_len = sizeof(ipc_ut_ipv6_tcp_syn_packet);
+ break;
+
+ }
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len)
+ {
+ kal_uint32 current_copy_len;
+
+ if ((curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) || (cont_loop_cnt == per_pkt_max_sit_num-1))
+ { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else
+ { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ UT_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt ++;
+ }
+ }
+ pkt_num ++;
+
+ }
+
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+}
+
+kal_bool ipc_ut_dl_filter_ra_pkt_did(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ kal_uint8 proto_idx[] = {0, 1};
+ kal_uint32 idx;
+ kal_uint32 gpd_remain_cnt_ul, gpd_remain_cnt_dl, did_remain_cnt;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ d2cm_ipcore_info_ind_struct *d2cm_ind = NULL;
+#endif
+ ilm_struct ilm = {0};
+
+ /* init before test */
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did_ra;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* no BINDING */
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++){
+ kal_uint32 pkt_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint8 expected_pkt_cnt = 0;
+
+ /*Store GPD remain cnt */
+ gpd_remain_cnt_dl = qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (pkt_cnt = 1; pkt_cnt <= 2; pkt_cnt++) {
+
+ did_cnt = 1;
+ expected_pkt_cnt = 0;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_reset_ul_info();
+
+ /*Store DID remain cnt */
+ did_remain_cnt = upcm_did_get_buff_remain_num();
+
+ /* prepare a DID of TCP RST */
+ ipc_ut_prepare_dl_did_list_ipv6ra(pkt_cnt, alignment, &did_head, &did_tail, did_cnt);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID on unbind condition*/
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx); //0 for SIM1
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded on PDN unbind!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)bind_req);
+
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ /* Send D2CM message to flush RA */
+ d2cm_ind = (d2cm_ipcore_info_ind_struct *)construct_local_para(sizeof(d2cm_ipcore_info_ind_struct), TD_RESET);
+ /* Be careful that D2CM only proivde NETIF ID from AP view (start from 0)
+ * IPCORE will translate netif ID by adding prefix IPC_NETIF_ID_LHIF_BEGIN
+ */
+ d2cm_ind->netif_id = IPC_UT_NETID_START;
+ d2cm_ind->keep_ra = KAL_TRUE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_NIL;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_D2CM_IPCORE_INFO_IND;
+ ilm.local_para_ptr = (local_para_struct *)d2cm_ind;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)d2cm_ind);
+
+#endif
+ /* expected DL pkt cnt should be
+ * pkt 1 is of ICMPv6 RA packet, generate 1 DL GPD
+ * pkt 2 is of TCP pkt , generate 0 DL GPD
+ */
+ if ( pkt_cnt >= 1) {
+ expected_pkt_cnt += 1;
+ }
+
+ if (ipc_ut_dl_callback_did_pkt_cnt != expected_pkt_cnt) {
+ utELOG("wrong expected count!\r\n");
+ return KAL_FALSE;
+ }
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ /* IPCORE should keep RA packet after flushing RA to AP */
+ if((gpd_remain_cnt_dl-1) != qbm_get_buff_remain_num(QBM_TYPE_NET_DL) ){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+#else
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+#endif
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ /* Reset DL counts */
+ ipc_ut_reset_dl_callback_info();
+
+ /* Send D2CM message to flush RA */
+ d2cm_ind = (d2cm_ipcore_info_ind_struct *)construct_local_para(sizeof(d2cm_ipcore_info_ind_struct), TD_RESET);
+ /* Be careful that D2CM only proivde NETIF ID from AP view (start from 0)
+ * IPCORE will translate netif ID by adding prefix IPC_NETIF_ID_LHIF_BEGIN
+ */
+ d2cm_ind->netif_id = IPC_UT_NETID_START;
+ d2cm_ind->keep_ra = KAL_FALSE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_NIL;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_D2CM_IPCORE_INFO_IND;
+ ilm.local_para_ptr = (local_para_struct *)d2cm_ind;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)d2cm_ind);
+
+ /* No RA packets should be stored in IPCORE */
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+ /* IPCORE should flush RA to NETIF */
+ if (ipc_ut_dl_callback_did_pkt_cnt != 1) {
+ utELOG("wrong expected count!\r\n");
+ return KAL_FALSE;
+ }
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+#endif
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_filter_ra_pkt_did_w_dynamic_q(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ kal_uint8 proto_idx[] = {0, 1};
+ kal_uint32 idx;
+ kal_uint32 gpd_remain_cnt_ul, gpd_remain_cnt_dl, did_remain_cnt;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ipc_lhifcore_q_mapping_msg_t *dynamic_q_rsp = NULL;
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ d2cm_ipcore_info_ind_struct *d2cm_ind = NULL;
+#endif
+ ilm_struct ilm = {0};
+
+ /* init before test */
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did_ra;
+ net->conf.features = IPC_F_DYNAMIC_Q_MAPPING;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* no BINDING */
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++){
+ kal_uint32 pkt_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint8 expected_pkt_cnt = 0;
+
+ /*Store GPD remain cnt */
+ gpd_remain_cnt_dl = qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (pkt_cnt = 1; pkt_cnt <= 2; pkt_cnt++) {
+
+ did_cnt = 1;
+ expected_pkt_cnt = 0;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_reset_ul_info();
+
+ /*Store DID remain cnt */
+ did_remain_cnt = upcm_did_get_buff_remain_num();
+
+ /* prepare a DID of TCP RST */
+ ipc_ut_prepare_dl_did_list_ipv6ra(pkt_cnt, alignment, &did_head, &did_tail, did_cnt);
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID on unbind condition*/
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx); //0 for SIM1
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded on PDN unbind!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Send dynamic queue mapping response to IPCore. */
+ dynamic_q_rsp = (ipc_lhifcore_q_mapping_msg_t *)construct_local_para(sizeof(ipc_lhifcore_q_mapping_msg_t), TD_RESET);
+ kal_mem_cpy(&(dynamic_q_rsp->bind_ind), bind_req, sizeof(ipcore_upcm_pdn_bind_ind_struct));
+ dynamic_q_rsp->netif_features = net->conf.features;
+ dynamic_q_rsp->callback_context = net->conf.callback_context;
+ dynamic_q_rsp->bind_src_mod_id = net->conf.module_id;
+ dynamic_q_rsp->netif_type = IPC_NETIF_TYPE_NORMAL;
+ dynamic_q_rsp->result = KAL_TRUE;
+
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_LHIFCORE;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_LHIFCORE_QUEUE_MAPPING_RSP;
+ ilm.local_para_ptr = (local_para_struct *)dynamic_q_rsp;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)dynamic_q_rsp);
+
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ /* Send D2CM message to flush RA */
+ d2cm_ind = (d2cm_ipcore_info_ind_struct *)construct_local_para(sizeof(d2cm_ipcore_info_ind_struct), TD_RESET);
+ /* Be careful that D2CM only proivde NETIF ID from AP view (start from 0)
+ * IPCORE will translate netif ID by adding prefix IPC_NETIF_ID_LHIF_BEGIN
+ */
+ d2cm_ind->netif_id = IPC_UT_NETID_START;
+ d2cm_ind->keep_ra = KAL_TRUE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_NIL;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_D2CM_IPCORE_INFO_IND;
+ ilm.local_para_ptr = (local_para_struct *)d2cm_ind;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)d2cm_ind);
+
+#endif
+
+ /* expected DL pkt cnt should be
+ * pkt 1 is of ICMPv6 RA packet, generate 1 DL GPD
+ * pkt 2 is of TCP pkt , generate 0 DL GPD
+ */
+ if ( pkt_cnt >= 1) {
+ expected_pkt_cnt += 1;
+ }
+
+ if (ipc_ut_dl_callback_did_pkt_cnt != expected_pkt_cnt) {
+ utELOG("wrong expected count!\r\n");
+ return KAL_FALSE;
+ }
+
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ /* IPCORE should keep RA packet after flushing RA to AP */
+ if((gpd_remain_cnt_dl-1) != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+#else
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+#endif
+
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+
+#if (IPC_IPV6_RA_WORKAROUND == 1)
+ /* Reset DL counts */
+ ipc_ut_reset_dl_callback_info();
+
+ /* Send D2CM message to flush RA */
+ d2cm_ind = (d2cm_ipcore_info_ind_struct *)construct_local_para(sizeof(d2cm_ipcore_info_ind_struct), TD_RESET);
+ /* Be careful that D2CM only proivde NETIF ID from AP view (start from 0)
+ * IPCORE will translate netif ID by adding prefix IPC_NETIF_ID_LHIF_BEGIN
+ */
+ d2cm_ind->netif_id = IPC_UT_NETID_START;
+ d2cm_ind->keep_ra = KAL_FALSE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_NIL;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_D2CM_IPCORE_INFO_IND;
+ ilm.local_para_ptr = (local_para_struct *)d2cm_ind;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)d2cm_ind);
+
+ /* No RA packets should be stored in IPCORE */
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+ /* IPCORE should flush RA to NETIF */
+ if (ipc_ut_dl_callback_did_pkt_cnt != 1) {
+ utELOG("wrong expected count!\r\n");
+ return KAL_FALSE;
+ }
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+#endif
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+ }
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_notify_l2(kal_uint32 unknown_header_num,
+ kal_uint16 begin_cntl,
+ kal_uint16 end_cntl,
+ kal_uint16 rb_idx,
+ kal_uint16 protocol_idx)
+{
+ g_ut_unk_hdr_stat_recv[protocol_idx][rb_idx].unk_hdr_cnt = unknown_header_num;
+ g_ut_unk_hdr_stat_recv[protocol_idx][rb_idx].begin_cntl = begin_cntl;
+ g_ut_unk_hdr_stat_recv[protocol_idx][rb_idx].end_cntl = end_cntl;
+ g_ut_unk_hdr_stat_recv[protocol_idx][rb_idx].is_valid = KAL_TRUE;
+}
+
+void ipc_ut_prepare_dl_meta_list_with_statistics(kal_bool allValidIpPkt,
+ kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ ipfc_dl_filter_queue_type *q_type,
+ kal_uint32 netif_id,
+ kal_uint8 match_result,
+ kal_uint8 sim_idx,
+ kal_uint8 *v4_cntl_begin,
+ kal_uint8 *v6_cntl_begin,
+ kal_uint8 *v4_cntl_end,
+ kal_uint8 *v6_cntl_end)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ kal_uint32 curr_meta_idx;
+ ipf_dl_meta *curr_meta;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+ kal_uint8 meta_cntl = 0;
+
+ if (total_cnt != ipc_ut_alloc_meta(IPC_UT_IPF_DL_0, total_cnt, p_head_idx, p_tail_idx)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ *q_type = IPFC_META_QUEUE_DL;
+ curr_meta_idx = *p_head_idx;
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ meta_cntl = 0;
+ curr_meta->count = 0;
+ *v4_cntl_begin = 0;
+ *v4_cntl_end = 0;
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ meta_cntl++;
+ curr_meta->count = meta_cntl;
+ curr_meta->rbid = 4;
+ curr_meta->channel_id = ((((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS) <<8 )
+ |(netif_id & 0x000000FF) ;
+
+ switch (idx) {
+ case 0:
+ case 1:
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ g_unk_pkt_v4_cnt ++;
+ if (0 == *v4_cntl_begin) {
+ *v4_cntl_begin = curr_meta->count;
+ }
+ *v4_cntl_end = curr_meta->count;
+ break;
+ default:
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ break;
+ }
+
+ kal_mem_cpy((kal_uint8*)curr_meta->addr, packet_buf, packet_len);
+ curr_meta->len = packet_len;
+ curr_meta->ip = 0;
+
+ /* Fill Match index (don't care value)
+ * we assgin the same value as ip type. it will be reused for querey filter id.
+ */
+ curr_meta->match_idx = 0;
+ curr_meta->mr = (match_result & 0x07);
+ curr_meta->pdn_sim_id = IPC_UT_PDN_ID;
+ IPC_MASK_PROTOID_ON_PDNID(curr_meta->pdn_sim_id, sim_idx);
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ meta_cntl = 0;
+ curr_meta->count = 0;
+ *v6_cntl_begin = 0;
+ *v6_cntl_end = 0;
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ meta_cntl++;
+ curr_meta->count = meta_cntl;
+ curr_meta->rbid = 6;
+ curr_meta->channel_id = ((((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS) <<8 )
+ |(netif_id & 0x000000FF) ;
+
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ g_unk_pkt_v6_cnt++;
+ if (0 == *v6_cntl_begin) {
+ *v6_cntl_begin = curr_meta->count;
+ }
+ *v6_cntl_end = curr_meta->count;
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+
+ kal_mem_cpy((kal_uint8*)curr_meta->addr, packet_buf, packet_len);
+ curr_meta->len = packet_len;
+ curr_meta->ip = 1;
+
+ /* Fill Match index (don't care value)
+ * we assgin the same value as ip type. it will be reused for querey filter id.
+ */
+ curr_meta->match_idx = 1;
+ curr_meta->mr = (match_result & 0x07);
+ curr_meta->pdn_sim_id = IPC_UT_PDN_ID;
+ IPC_MASK_PROTOID_ON_PDNID(curr_meta->pdn_sim_id, sim_idx);
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+}
+
+kal_bool ipc_ut_dl_filter_fragments(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint32 i = 0;
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ ipcore_upcm_pdn_bind_ind_struct *p_bind_req = NULL;
+ ipc_filter_rules_t rules = {0};
+ kal_int32 filter_id = 0;
+ kal_uint32 pdn_id = 0;
+ ipc_session_t *p_session = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+ ipc_conf_t config = {0};
+ ipc_handle_t p_handle = NULL;
+ kal_bool ret = KAL_TRUE;
+
+ /* initialize before test & reset IPCORE */
+ ipc_ut_init();
+ ASSERT(KAL_TRUE == ipc_reset());
+
+ /* netif attach */
+ config.module_id = MOD_IPCORE;
+ config.netif_id = IPC_UT_LHIF_NETID_START;
+ config.features = 0;
+ config.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ config.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ config.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+
+ UT_ASSERT(KAL_TRUE == ipc_attach(&config, &p_handle));
+ UT_ASSERT(NULL != p_handle);
+ utDLOG("netif id = %d attach successfully", config.netif_id);
+
+ /* IPv4 binding */
+ p_bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ p_bind_req->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_bind_req->pdn_id = IPC_UT_PDN_ID;
+ p_bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)p_bind_req);
+ free_local_para((local_para_struct * )p_bind_req);
+
+ ipc_ut_prepare_fragments_and_send(IPC_UT_PDN_ID, 0);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+
+kal_bool ipc_ut_meta_downlink_with_statistics(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ ilm_struct ilm;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 ipv4_filter_cnt;
+ kal_uint32 ipv6_filter_cnt;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint8 matched_filter_idx_v6;
+ kal_uint32 callback_with_info;
+ kal_uint32 total_cnt;
+ kal_uint32 sim_idx = 0;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (sim_idx = 0; sim_idx <= 1; sim_idx++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++) {
+ if ((0 == ipv4_cnt) && (0 == ipv6_cnt)) {
+ continue;
+ }
+
+ utDLOG("sim_idx(%d) v4Cnt(%d) v6Cnt(%d) \r\n", sim_idx, ipv4_cnt, ipv6_cnt);
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ /* Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_reset_ul_info();
+ ilm.src_mod_id = MOD_UPCM + sim_idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)bind_req);
+
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+ kal_uint8 v4_cntl_begin = 0;
+ kal_uint8 v6_cntl_begin = 0;
+ kal_uint8 v4_cntl_end = 0;
+ kal_uint8 v6_cntl_end = 0;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+
+ utDLOG("@ Before activation : match_result(%d)\r\n", match_result);
+
+ kal_mem_set(&g_ut_unk_hdr_stat_recv, 0, sizeof(g_ut_unk_hdr_stat_recv));
+ kal_mem_set(&g_ut_unk_hdr_stat_send, 0, sizeof(g_ut_unk_hdr_stat_send));
+ g_unk_pkt_v4_cnt = 0;
+ g_unk_pkt_v6_cnt = 0;
+
+ ipc_ut_prepare_dl_meta_list_with_statistics(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx,
+ &q_type, netif_id, match_result, sim_idx, &v4_cntl_begin,
+ &v6_cntl_begin, &v4_cntl_end, &v6_cntl_end);
+
+ if (IPC_IPF_MR_UNKNOWN_HEADER == match_result) {
+ if (0 != ipv4_cnt) {
+ g_ut_unk_hdr_stat_send[sim_idx][4].begin_cntl = v4_cntl_begin;
+ g_ut_unk_hdr_stat_send[sim_idx][4].end_cntl = v4_cntl_end;
+ g_ut_unk_hdr_stat_send[sim_idx][4].unk_hdr_cnt = g_unk_pkt_v4_cnt;
+ g_ut_unk_hdr_stat_send[sim_idx][4].is_valid = KAL_TRUE;
+ }
+
+ if (0 != ipv6_cnt) {
+ g_ut_unk_hdr_stat_send[sim_idx][6].begin_cntl = v6_cntl_begin;
+ g_ut_unk_hdr_stat_send[sim_idx][6].end_cntl = v6_cntl_end;
+ g_ut_unk_hdr_stat_send[sim_idx][6].unk_hdr_cnt = g_unk_pkt_v6_cnt;
+ g_ut_unk_hdr_stat_send[sim_idx][6].is_valid = KAL_TRUE;
+ }
+ }
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ UT_ASSERT(0 == kal_mem_cmp(g_ut_unk_hdr_stat_send, g_ut_unk_hdr_stat_recv, sizeof(g_ut_unk_hdr_stat_recv)));
+ }
+ }
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + sim_idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+ }
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+void ipc_ut_prepare_rs_ul_filter(kal_uint32 total_cnt,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ kal_uint32 netif_id,
+ LHIF_QUEUE_TYPE *q_type) {
+ kal_uint32 curr_meta_idx;
+ lhif_meta_tbl_t *curr_meta = NULL;
+ kal_uint8 *packet_buf = NULL;
+ kal_uint32 packet_len = 0;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+ kal_uint32 idx = 0;
+
+ if (total_cnt != ipc_ut_alloc_meta(IPC_UT_LHIF_META_AP0, total_cnt, p_head_idx, p_tail_idx)) {
+ IPC_ASSERT(KAL_FALSE);
+ return;
+ }
+ *q_type = LHIF_HWQ_AP_UL_Q0;
+ curr_meta_idx = *p_head_idx;
+ for (idx = 0; idx < total_cnt; idx++) {
+ curr_meta = &ipc_ut_meta_tbl_s[curr_meta_idx];
+ curr_meta->net_type = ((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS;
+ curr_meta->channel_id = netif_id & 0x0000001F;
+ curr_meta->mr = IPC_HPC_MR_UNKNOWN;
+ if ((idx % 2) == 0) {
+ packet_buf = g_ipc_ut_icmpv6_rs_pkt;
+ packet_len = sizeof(g_ipc_ut_icmpv6_rs_pkt);
+ } else {
+ packet_buf = g_ipc_ut_icmp_rs_pkt;
+ packet_len = sizeof(g_ipc_ut_icmp_rs_pkt);
+ }
+ g_chk_pkt_cnt++;
+
+ kal_mem_cpy(curr_meta->vrb_addr, packet_buf, packet_len);
+ curr_meta->length = packet_len;
+
+ curr_meta_idx++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+}
+
+kal_bool ipc_ut_rs_ul(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net = NULL;
+ kal_uint32 netif_id = IPC_NETIF_ID_ETH_BEGIN;
+ kal_bool result = KAL_FALSE;
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ LHIF_QUEUE_TYPE q_type;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ilm_struct ilm = {0};
+ ipc_filter_rules_t *rules = NULL;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+ ipc_ut_filter_info_t *info = NULL;
+ kal_uint32 idx = 0;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_NETIF_ID_ETH_BEGIN;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_callback_t = ipc_ut_dl_callback;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ ipc_ut_prepare_rs_ul_filter(2, &head_idx, &tail_idx, netif_id, &q_type);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ if ( (2 != ipc_ut_ul_meta_cnt) ||
+ (0 != ipc_ut_ul_meta_non_igr_cnt) ) {
+ utELOG("UL META is forwarded before PDN binding! (proto_idx:%d, ipv4:%d, ipv6:%d)\r\n", idx, 1, 1);
+ ipc_ut_meta_read_done(head_idx, tail_idx, q_type);
+ return KAL_FALSE;
+ }
+ /* Activate IPv6 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM + idx, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE)
+ {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ utDLOG("PDN binding successfull");
+
+ info = &ipc_ut_info_set[0];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->protocol = IPC_HDR_PROT_ICMP;
+ rules->valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV4_TYPE;
+ rules->icmpv4_type = IPC_HDR_ICMP_TYPE_RS;
+ rules->ip_type = IPC_IP_TYPE_IPV4;
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+
+ info = &ipc_ut_info_set[1];
+
+ rules = &info->rules;
+ kal_mem_set(rules, 0, sizeof(*rules));
+ rules->protocol = IPC_HDR_PROT_ICMPV6;
+ rules->valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV6_TYPE;
+ rules->icmpv6_type = IPC_HDR_ICMPV6_TYPE_RS;
+ rules->ip_type = IPC_IP_TYPE_IPV6;
+
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_ul_filter_callback;
+ ntfy_ctxt.ntfy_mod.with_info_cbk_func = ipc_ut_ul_filter_with_info_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ info->filter_id = ipc_reg_filter(UL_DIRECT, rules, &ntfy_ctxt);
+
+ g_chk_pkt_cnt = 0;
+
+ ipc_ut_prepare_rs_ul_filter(2, &head_idx, &tail_idx, netif_id, &q_type);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ UT_ASSERT(2 == ipc_ut_ul_meta_cnt);
+ UT_ASSERT(g_chk_pkt_cnt == g_ipc_ut_igr_meta_cnt);
+
+ ipc_dereg_filter(0);
+ ipc_dereg_filter(1);
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM + idx;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ ipc_ut_prepare_rs_ul_filter(2, &head_idx, &tail_idx, netif_id, &q_type);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_ul_info();
+
+ ipc_meta_uplink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+
+}
+
+kal_bool ipc_ut_dl_callback_did_2(void *context, upcm_did *did)
+{
+ UT_ASSERT(NULL != did);
+
+ ipc_ut_dl_callback_did_cnt ++;
+ ipc_ut_dl_callback_did_pkt_cnt += (UPCM_DID_GET_PKT_NUM(did) << 1);
+
+ return KAL_TRUE;
+}
+
+
+kal_bool ipc_ut_send_dl_pkt_force(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ typedef kal_bool (*ipc_dlink_callback_t)(void *context, ipc_io_request_t *ior);
+ ipc_ut_netif_t *netif;
+ kal_bool result;
+ kal_uint32 idx = 0, pkt_cnt = 0;
+ qbm_gpd *pkt, *tail;
+ ipc_dlink_callback_t did_cb[] = {ipc_ut_dl_callback_did, ipc_ut_dl_callback_did_2};
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ilm_struct ilm = {0};
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (pkt_cnt = 1; pkt_cnt < 3; pkt_cnt++) {
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ /* Test race condition */
+ ipc_data_set_dl_ilm_flag();
+
+ for (idx = 0; idx < pkt_cnt; idx++) {
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START, IPC_IP_TYPE_MIXED);
+
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START+1, IPC_IP_TYPE_MIXED);
+ }
+ ipc_data_clear_dl_ilm_flag();
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START+1,IPC_IP_TYPE_MIXED);
+
+ ASSERT(ipc_ut_dl_callback_did_pkt_cnt == 0); /* (2*1)+1 */
+ ASSERT(ipc_ut_dl_callback_did_cnt == 0); /* (2*1)+1 */
+ }
+
+ for (idx = 0; idx < 2; idx++) {
+ netif = &(ipc_ut_nets_s[idx]);
+ kal_mem_set(netif, 0, sizeof(ipc_ut_netif_t));
+ netif->conf.module_id = MOD_IPCORE;
+ netif->conf.netif_id = IPC_UT_LHIF_NETID_START + idx;
+ netif->conf.ul_reload_context = netif;
+ netif->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ netif->conf.callback_context = netif;
+ netif->conf.ipc_dlink_did_cb_t = did_cb[idx];
+ netif->conf.features = 0;
+ result = ipc_attach(&netif->conf, &netif->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ for (pkt_cnt = 1; pkt_cnt < 3; pkt_cnt++) {
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ /* Test race condition */
+ ipc_data_set_dl_ilm_flag();
+
+ for (idx = 0; idx < pkt_cnt; idx++) {
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START, IPC_IP_TYPE_MIXED);
+
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START+1, IPC_IP_TYPE_MIXED);
+ }
+ ipc_data_clear_dl_ilm_flag();
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START+1, IPC_IP_TYPE_MIXED);
+
+ ASSERT(ipc_ut_dl_callback_did_pkt_cnt == 0); /* (2*1)+1 */
+ ASSERT(ipc_ut_dl_callback_did_cnt == 0); /* (2*1)+1 */
+ }
+
+ for (idx = 0; idx < 2; idx++) {
+ /* Activate IPv6 PDN with unspecified IP address & from different MOD_UPCM_X. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = IPC_UT_LHIF_NETID_START + idx;
+ bind_req->pdn_id = IPC_UT_PDN_ID_2 + idx;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE)
+ {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+ free_local_para((local_para_struct *)bind_req);
+
+ for (pkt_cnt = 1; pkt_cnt < 3; pkt_cnt++) {
+ kal_uint32 expect_count;
+ kal_uint32 idx1;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ /* Test race condition */
+ ipc_data_set_dl_ilm_flag();
+ expect_count = 0;
+
+ for (idx1 = 0; idx1 < pkt_cnt; idx1++) {
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ expect_count++;
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START, IPC_IP_TYPE_MIXED);
+
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ if (idx > 0) {
+ expect_count += 2;
+ }
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START+1, IPC_IP_TYPE_MIXED);
+ }
+ ipc_data_clear_dl_ilm_flag();
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ if (idx > 0) {
+ expect_count += 2;
+ }
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START+1, IPC_IP_TYPE_MIXED);
+
+ ASSERT(ipc_ut_dl_callback_did_pkt_cnt == expect_count);
+ }
+
+ }
+ utDLOG("PDN binding successfull");
+
+ /* PDN deactivation. */
+ for (idx = 0; idx < 2; idx++) {
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID_2 + idx;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ for (pkt_cnt = 1; pkt_cnt < 3; pkt_cnt++) {
+ kal_uint32 idx1;
+ kal_uint32 expect_count;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+ /* Test race condition */
+ ipc_data_set_dl_ilm_flag();
+ expect_count = 0;
+
+ for (idx1 = 0; idx1 < pkt_cnt; idx1++) {
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START, IPC_IP_TYPE_MIXED);
+
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ if (idx == 0) {
+ expect_count += 2;
+ }
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START+1, IPC_IP_TYPE_MIXED);
+ }
+ ipc_data_clear_dl_ilm_flag();
+ ipc_ut_prepare_dl_gpd_list(0, 0, KAL_FALSE, KAL_FALSE, 1, 0, KAL_TRUE, KAL_FALSE,
+ 0, 0, &pkt, &tail, NULL, NULL, KAL_FALSE, KAL_FALSE, 0);
+ if (idx == 0) {
+ expect_count += 2;
+ }
+ ipc_send_dl_pkt_enqueue(pkt, IPC_UT_LHIF_NETID_START+1, IPC_IP_TYPE_MIXED);
+
+ ASSERT(ipc_ut_dl_callback_did_pkt_cnt == expect_count);
+ }
+ }
+
+ for (idx = 0; idx < 2; idx++) {
+ netif = &(ipc_ut_nets_s[idx]);
+ result = ipc_detach(netif->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_ra_dl(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint32 i = 0;
+ kal_uint32 ipv4_cnt = 0;
+ kal_uint32 ipv6_cnt = 0;
+ ipcore_upcm_pdn_bind_ind_struct *p_bind_req = NULL;
+ ipc_filter_rules_t rules = {0};
+ kal_int32 filter_id = 0, filter_idv6 = 0;
+ kal_uint32 pdn_id = 0;
+ ipc_session_t *p_session = NULL;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+
+ /* initialize before test & reset IPCORE */
+ ipc_ut_init();
+ ASSERT(KAL_TRUE == ipc_reset());
+
+ /* netif attach */
+ ASSERT(KAL_TRUE == ipc_ut_fin_ack_filter_netif_attach());
+ /* Before binding */
+ {
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+
+ ipc_ut_reset_dl_callback_info();
+
+ ipc_ut_prepare_ra_filter_pkt(0,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 1,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ 0,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ 1,
+ 0);
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ }
+ /* IPv6 binding */
+ p_bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ p_bind_req->network_interface_id = IPC_UT_LHIF_NETID_START;
+ p_bind_req->pdn_id = IPC_UT_PDN_ID;
+ p_bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)p_bind_req);
+ free_local_para((local_para_struct * )p_bind_req);
+
+// UT_ASSERT (ipc_ut_dl_callback_did_pkt_cnt == 1);
+
+ /* Registered DL filter to filter out v4 RA packets*/
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV4_TYPE;
+ rules.protocol = IPC_HDR_PROT_ICMP;
+ rules.icmpv4_type = IPC_HDR_ICMP_TYPE_RA;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.features = IPC_FILTER_FEATURE_IG_PN;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ filter_id= ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt);
+ ASSERT(0 == filter_id);
+
+ /* Registered DL filter to filter out v6 RA packets*/
+ kal_mem_set(&rules, 0, sizeof(ipc_filter_rules_t));
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_ICMPV6_TYPE;
+ rules.protocol = IPC_HDR_PROT_ICMPV6;
+ rules.icmpv6_type = IPC_HDR_ICMPV6_TYPE_RA;
+ rules.ip_type = IPC_IP_TYPE_IPV6;
+ rules.features = IPC_FILTER_FEATURE_IG_PN;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_ut_filter_cbk;
+ ntfy_ctxt.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC;
+
+ filter_idv6 = ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt);
+ ASSERT(1 == filter_idv6);
+
+ /* Simulate DL traffic to IPCore : PDN binding */
+ {
+ kal_uint32 did_cnt = 0;
+ upcm_did *did_head = NULL;
+ upcm_did *did_tail = NULL;
+ kal_uint32 alignment = 0;
+ kal_uint32 did_igr_bit = 0;
+ kal_uint32 free_cnt = 0;
+
+ for (alignment = 0; alignment < 4; alignment++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (did_igr_bit = 0; did_igr_bit < 1; did_igr_bit++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) {
+ continue;
+ }
+
+ utDLOG("@[Binding] v4_cnt(%d),v6_cnt(%d),alignment(%d),igr(%d)\r\n", ipv4_cnt, ipv6_cnt, alignment, did_igr_bit);
+ //g_cbk_pkt_recv_cnt = 0;
+ g_cbk_pkt_send_cnt = 0;
+ g_normal_cbk_pkt_recv_cnt = 0;
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_prepare_ra_filter_pkt(ipv4_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ ipv6_cnt,
+ 0,
+ KAL_FALSE,
+ KAL_FALSE,
+ 0,
+ alignment,
+ &did_head,
+ &did_tail,
+ NULL,
+ NULL,
+ did_cnt,
+ did_igr_bit);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_did_downlink_enqueue(IPC_UT_PDN_ID, did_head, did_tail);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+ UT_ASSERT(g_cbk_pkt_send_cnt == g_normal_cbk_pkt_recv_cnt);
+ //UT_ASSERT(g_cbk_pkt_recv_cnt == g_cbk_pkt_send_cnt);
+ UT_ASSERT((ipc_ut_dl_callback_did_pkt_cnt + g_normal_cbk_pkt_recv_cnt) == (ipv4_cnt + ipv6_cnt));
+ }
+ }
+ ipc_dereg_filter(filter_id);
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+
+}
+
+void ipc_ut_prepare_dl_did_large_udp_packets_list(
+ kal_uint32 ipv4_cnt,
+ kal_uint32 align_offset,
+ upcm_did **did_head,
+ upcm_did **did_tail,
+ kal_uint32 did_cnt)
+{
+ kal_uint32 total_cnt = ipv4_cnt;
+ kal_uint32 idx;
+ upcm_did *curr_did;
+ upcm_did_si *curr_sit;
+ upcm_did_si *curr_si;
+ kal_uint32 curr_si_idx;
+ kal_uint32 pkt_start_si_idx;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 pkt_num;
+ kal_uint32 seg_num;
+ kal_uint8 per_pkt_max_sit_num = 10; /* one DID max packet number will be 7. one DID has 62 SIT entries */
+
+ if (did_cnt != ipc_ut_alloc_did(
+ did_cnt,
+ did_head,
+ did_tail)) {
+ IPC_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ /* For un-alignment test : 4 byte align as maximum */
+ {
+ upcm_did *next_did;
+ kal_bool end_of_list;
+
+ next_did = NULL;
+ end_of_list = KAL_FALSE;
+ for ( curr_did = *did_head ;
+ curr_did && (end_of_list == KAL_FALSE) ;
+ curr_did = next_did)
+ {
+ kal_uint32 i;
+
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+
+ for (i = 0; i < IPC_UT_DID_MAX_SIT_NUM; i++) {
+ upcm_did_si *si = &curr_sit[i];
+
+ UPCM_DID_SI_SET_OFFSET(si, UPCM_DID_SI_GET_OFFSET(si) + (align_offset % 4));
+ }
+ }
+ }
+ curr_did = *did_tail;
+ curr_sit = UPCM_DID_GET_SIT_PTR(curr_did);
+ curr_si_idx = 0;
+ curr_si = &curr_sit[curr_si_idx];
+ pkt_num = 0;
+ seg_num = 0;
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ switch(idx) {
+ case 0:
+ packet_buf = g_ipc_ut_large_udp_pkt_s3632;
+ packet_len = sizeof(g_ipc_ut_large_udp_pkt_s3632);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_udp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_udp_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv4_udp_packet_example;
+ packet_len = sizeof(ipc_ut_ipv4_udp_packet_example);
+ break;
+ }
+
+ {
+ kal_uint32 copied_len;
+ kal_uint32 cont_loop_cnt;
+ kal_uint32 si_offset;
+
+ pkt_start_si_idx = curr_si_idx;
+ copied_len = 0;
+ cont_loop_cnt = 0;
+
+ while (copied_len < packet_len)
+ {
+ kal_uint32 current_copy_len;
+
+ if ((curr_si_idx == IPC_UT_DID_MAX_SIT_NUM - 1) || (cont_loop_cnt == per_pkt_max_sit_num-1))
+ { /* Latest SIT : copy all remaining data */
+ current_copy_len = packet_len - copied_len;
+ } else
+ { /* Non latest SIT : copy partial of data */
+ current_copy_len = (((align_offset > 0) || (cont_loop_cnt % 2))?(idx + cont_loop_cnt):0) % (packet_len - copied_len);
+ current_copy_len = (current_copy_len == 0) ? 1 : current_copy_len;
+ }
+
+ /* No buffer is allocated and we need to set its buffer to static template */
+ si_offset = UPCM_DID_SI_GET_OFFSET(curr_si);
+ UPCM_DID_SI_SET_DATAPTR(curr_si, packet_buf + copied_len - si_offset);
+ UPCM_DID_SI_SET_LEN(curr_si, current_copy_len);
+ copied_len += current_copy_len;
+ seg_num ++;
+
+ if (copied_len >= packet_len) {
+ IPC_ASSERT(copied_len == packet_len);
+ UPCM_DID_SI_SET_EOL(curr_si);
+ }
+
+ /* Get next SI in list */
+ curr_si_idx ++;
+ curr_si = &curr_sit[curr_si_idx];
+
+ cont_loop_cnt ++;
+ }
+ }
+ pkt_num ++;
+
+ }
+
+ UPCM_DID_SET_PKT_NUM(curr_did, pkt_num);
+ UPCM_DID_SET_SEG_NUM(curr_did, seg_num);
+ }
+
+kal_bool ipc_ut_downlink_test_udp_drop_large_packet(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ kal_uint8 proto_idx[] = {0, 1, 2, 3};
+ kal_uint32 idx;
+ kal_uint32 gpd_remain_cnt_ul, gpd_remain_cnt_dl, did_remain_cnt;
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+ for (idx = 0; idx < sizeof(proto_idx)/sizeof(proto_idx[0]); idx++)
+ {
+ kal_uint32 cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint8 expected_pkt_cnt = 0;
+
+ for (alignment = 0 ; alignment < 1 ; alignment ++)
+ for (cnt = 1; cnt <= 2; cnt++) {
+
+ did_cnt = 1;
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+ ipc_ut_reset_ul_info();
+
+ /*Store DID remain cnt */
+ did_remain_cnt = upcm_did_get_buff_remain_num();
+
+ /*prepare a DID of UDP ipv4 */
+ ipc_ut_prepare_dl_did_large_udp_packets_list(cnt,
+ alignment,
+ &did_head,
+ &did_tail,
+ did_cnt);
+
+ /*Store GPD remain cnt */
+ gpd_remain_cnt_ul = qbm_get_buff_remain_num(QBM_TYPE_NET_UL);
+ gpd_remain_cnt_dl = qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, idx); //0 for SIM1
+
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded on PDN unbind!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(gpd_remain_cnt_ul != qbm_get_buff_remain_num(QBM_TYPE_NET_UL)){
+ utELOG("wrong expected QBM_TYPE_NET_UL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+
+ }
+ }
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+
+}
+
+void ipc_ut_prepare_dl_meta_list_with_large_udp_pkt(kal_bool allValidIpPkt,
+ kal_uint32 ipv4_cnt,
+ kal_uint32 dhcpv4_idx,
+ kal_uint32 ipv6_cnt,
+ kal_uint32 dhcpv6_idx,
+ kal_uint32 *p_head_idx,
+ kal_uint32 *p_tail_idx,
+ ipfc_dl_filter_queue_type *q_type,
+ kal_uint32 netif_id,
+ kal_uint8 match_result)
+{
+ kal_uint32 total_cnt = ipv4_cnt + ipv6_cnt;
+ kal_uint32 idx;
+ kal_uint32 curr_meta_idx;
+ ipf_dl_meta *curr_meta;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint32 netif_id_prefix = (netif_id & 0xFFFFFF00);
+
+ if (total_cnt != ipc_ut_alloc_meta(
+ IPC_UT_IPF_DL_0, //LHIF_HWQ_AP_UL_Q0,
+ total_cnt,
+ p_head_idx,
+ p_tail_idx)) {
+ UT_ASSERT(KAL_FALSE);
+ return;
+ }
+ *q_type = IPFC_META_QUEUE_DL;
+ curr_meta_idx = *p_head_idx;
+
+ for (idx = 0; idx < ipv4_cnt; idx++) {
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ curr_meta->channel_id = ((((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS) <<8 )
+ |(netif_id & 0x000000FF) ;
+
+ if (idx == dhcpv4_idx) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ switch (idx) {
+ case 0:
+ if (ipv4_cnt > 4) {
+ if ((ipv4_cnt%2) == 0) {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ } else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ }
+ else {
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ }
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv4_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv4_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = g_ipc_ut_large_udp_pkt_s3632;
+ packet_len = sizeof(g_ipc_ut_large_udp_pkt_s3632);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv4_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag0_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv4_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv4_frag1_packet);
+ break;
+ default:
+ if ((idx%3) == 0) {
+ packet_buf = ipc_ut_ipv4_dns_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dns_packet);
+ } else {
+ packet_buf = ipc_ut_ipv4_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv4_dhcp_packet);
+ ipc_ut_dl_filter_expect_gpd_cnt++;
+ }
+ break;
+ }
+ }
+
+ kal_mem_cpy((kal_uint8*)curr_meta->addr, packet_buf, packet_len);
+ curr_meta->len = packet_len;
+
+ // Fill IP type
+ curr_meta->ip = 0;
+
+ // Fill Match index (don't care value)
+ // we assgin the same value as ip type. it will be reused for querey filter id.
+ curr_meta->match_idx = 0;
+
+ curr_meta->mr = (match_result & 0x07);
+
+ curr_meta->pdn_sim_id = IPC_UT_PDN_ID;
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+
+
+ for (idx = 0; idx < ipv6_cnt; idx++) {
+ curr_meta = &ipc_ut_dl_meta_tbl_s[curr_meta_idx];
+ curr_meta->channel_id = ((((netif_id & IPC_NETIF_ID_LHIF_BEGIN) == IPC_NETIF_ID_LHIF_BEGIN) ? LHIF_NET_TYPE_LHIF : LHIF_NET_TYPE_RNDIS) <<8 )
+ |(netif_id & 0x000000FF) ;
+
+
+ if (idx == dhcpv6_idx) {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_ipv6_ext0_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext0_dhcp_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_ext1_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ext1_dhcp_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_dhcp_packet;
+ packet_len = sizeof(ipc_ut_ipv6_dhcp_packet);
+ }
+ } else {
+ switch (idx) {
+ case 0:
+ packet_buf = ipc_ut_non_ip_packet;
+ packet_len = sizeof(ipc_ut_non_ip_packet);
+ break;
+ case 1:
+ packet_buf = ipc_ut_ipv6_incomplete_ip_header_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ip_header_packet);
+ break;
+ case 2:
+ packet_buf = ipc_ut_ipv6_incomplete_hop_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_hop_packet);
+ break;
+ case 3:
+ packet_buf = ipc_ut_ipv6_incomplete_ah_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ah_packet);
+ break;
+ case 4:
+ packet_buf = ipc_ut_ipv6_unknown_ext_packet;
+ packet_len = sizeof(ipc_ut_ipv6_unknown_ext_packet);
+ break;
+ case 5:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv4enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv4enc_packet);
+ break;
+ case 6:
+ packet_buf = ipc_ut_ipv6_incomplete_ipv6enc_packet;
+ packet_len = sizeof(ipc_ut_ipv6_incomplete_ipv6enc_packet);
+ break;
+ case 7:
+ if (ipv6_cnt <= 10) {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag0_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag0_packet);
+ } else {
+ packet_buf = ipc_ut_ipv6_ipv4enc_frag1_packet;
+ packet_len = sizeof(ipc_ut_ipv6_ipv4enc_frag1_packet);
+ }
+ break;
+ case 8:
+ packet_buf = ipc_ut_ipv6_frag_packet;
+ packet_len = sizeof(ipc_ut_ipv6_frag_packet);
+ break;
+ default:
+ packet_buf = ipc_ut_ipv6_mdns_packet;
+ packet_len = sizeof(ipc_ut_ipv6_mdns_packet);
+ break;
+ }
+ }
+
+ kal_mem_cpy((kal_uint8*)curr_meta->addr, packet_buf, packet_len);
+ curr_meta->len = packet_len;
+
+ // Fill IP type
+ curr_meta->ip = 1;
+
+ // Fill Match index (don't care value)
+ // we assgin the same value as ip type. it will be reused for querey filter id.
+ curr_meta->match_idx = 1;
+
+ curr_meta->mr = (match_result & 0x07);
+
+ curr_meta->pdn_sim_id = IPC_UT_PDN_ID;
+
+ curr_meta_idx ++;
+ if (curr_meta_idx == IPC_UT_META_TABLE_SIZE) {
+ curr_meta_idx = 0;
+ }
+ if (curr_meta_idx == *p_tail_idx) {
+ return;
+ }
+ }
+}
+
+kal_bool ipc_ut_meta_downlink_with_large_pkt(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ ilm_struct ilm;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 ipv4_filter_cnt;
+ kal_uint32 ipv6_filter_cnt;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint8 matched_filter_idx_v6;
+ kal_uint32 callback_with_info;
+ kal_uint32 total_cnt;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (ipv4_filter_cnt = 0; ipv4_filter_cnt <= 4; ipv4_filter_cnt++)
+ for (ipv6_filter_cnt = 0; ipv6_filter_cnt <= 4; ipv6_filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < ipv4_filter_cnt; matched_filter_idx_v4++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < ipv6_filter_cnt; matched_filter_idx_v6++) {
+ if ((0 == ipv4_cnt) && (0 == ipv6_cnt)) continue;
+
+ utDLOG("ifo(%d) v4Cnt(%d) v6Cnt(%d) v4FltCnt(%d) v6FltCnt(%d) v4Idx(%d) v6Idx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, ipv4_filter_cnt , ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Install DL filter for each test loop */
+ ipc_ut_install_dl_filters(callback_with_info, KAL_TRUE, ipv4_filter_cnt, ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6, IPC_UT_LHIF_NETID_START);
+
+ ipc_ut_dl_ipf_match_filter_id_v4_s = matched_filter_idx_v4;
+ ipc_ut_dl_ipf_match_filter_id_v6_s = ipv4_filter_cnt + matched_filter_idx_v6;
+
+ /*
+ * Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic from IPCore : All meta should be forward to either DL callback or filter callback(IPv4/IPv6)
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_dl_v4_filter_out_cnt;
+ kal_uint32 expected_dl_v6_filter_out_cnt;
+ kal_uint32 expected_dl_filter_out_cnt;
+ kal_uint32 did_cnt;
+ kal_uint32 expected_dl_forwad_cnt;
+
+ utDLOG("@ PDN connected : match_result(%d)\r\n", match_result);
+ ipc_ut_prepare_dl_meta_list_with_large_udp_pkt(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_dl_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))? 1:0;
+ expected_dl_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))?1:0;
+
+ expected_dl_filter_out_cnt = expected_dl_v4_filter_out_cnt + expected_dl_v6_filter_out_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) ||
+ (match_result == IPC_IPF_MR_PN_NO_MATCH) ||
+ (match_result == IPC_IPF_MR_NET_INVALID)) {
+ did_cnt = expected_dl_forwad_cnt = 0;
+ }
+ else {
+ did_cnt = total_cnt-expected_dl_filter_out_cnt; //Supposed one DID only contains one packet
+ expected_dl_forwad_cnt = total_cnt-expected_dl_filter_out_cnt;
+ }
+
+ if (expected_dl_filter_out_cnt > 0) {
+ if (callback_with_info) {
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_LHIF_NETID_START) {
+ utELOG("Filtered-out netif ID is incorrect!\r\n");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+ else {
+ if (ipc_ut_dl_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\n");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_fragment_ut_cust_filter_cbk(const kal_uint8 *p_pkt,
+ kal_int32 pkt_len,
+ kal_int32 filter_id,
+ void *p_args)
+{
+ kal_bool ret = KAL_FALSE;
+
+ if (IPC_HDR_IS_V4(p_pkt)) {
+ ret = KAL_TRUE;
+ } else if (IPC_HDR_IS_V6(p_pkt)) {
+ ret = KAL_TRUE;
+ } else {
+ UT_ASSERT(KAL_FALSE);
+ }
+
+ return ret;
+}
+
+void ipc_ut_reg_cust_filter_prepare_fragments_and_send(kal_uint32 pdn_id, kal_uint8 proto_idx) {
+ upcm_did *did_p = NULL;
+ upcm_did_si *sit_p = NULL;
+ ipc_filter_rules_t rules = {0};
+ ipc_filter_ntfy_ctxt_t ntfy_ctxt = {0};
+ kal_uint32 filter_id = IPC_INVALID_FILTER_ID;
+ kal_uint32 buff_count = 0, remain_count = 0;
+
+ buff_count = upcm_did_get_buff_remain_num() +
+ qbm_get_buff_remain_num(QBM_TYPE_TGPD) + qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+ rules.priority = 3;
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_PDN_ID | IPC_FILTER_BY_SPI;
+ rules.features = IPC_FILTER_FEATURE_FRAG | IPC_FILTER_FEATURE_CUST_FILTER;
+ rules.pdn_id = pdn_id;
+ rules.protocol = IPC_HDR_PROT_ESP;
+ rules.spi = 0x481fde70;
+ rules.cust_cbk_func = ipc_fragment_ut_cust_filter_cbk;
+ ntfy_ctxt.ntfy_mod.cbk_func = ipc_fragment_ut_dl_filter_callback;
+ ntfy_ctxt.ntfy_mod.cbk_mod = MOD_IPCORE;
+ filter_id = ipc_reg_filter(DL_DIRECT, &rules, &ntfy_ctxt);
+
+ did_p = upcm_did_alloc_one();
+ sit_p = UPCM_DID_GET_SIT_PTR(did_p);
+ UPCM_DID_SET_NEXT(did_p, NULL);
+
+ kal_mem_set(sit_p, 0, sizeof(upcm_did_si));
+ UPCM_DID_SI_SET_LEN(sit_p, sizeof(pkt2508_1));
+ UPCM_DID_SI_SET_DATAPTR(sit_p, ((void*)pkt2508_1));
+ UPCM_DID_SI_SET_EOL(sit_p);
+ sit_p++;
+ kal_mem_set(sit_p, 0, sizeof(upcm_did_si));
+ UPCM_DID_SI_SET_LEN(sit_p, sizeof(pkt2509_1));
+ UPCM_DID_SI_SET_DATAPTR(sit_p, ((void*)pkt2509_1));
+ UPCM_DID_SI_SET_EOL(sit_p);
+ sit_p++;
+ kal_mem_set(sit_p, 0, sizeof(upcm_did_si));
+ UPCM_DID_SI_SET_LEN(sit_p, sizeof(pkt2510_1));
+ UPCM_DID_SI_SET_DATAPTR(sit_p, ((void*)pkt2510_1));
+ UPCM_DID_SI_SET_EOL(sit_p);
+
+ UPCM_DID_SET_PKT_NUM(did_p, 3);
+ UPCM_DID_SET_SEG_NUM(did_p, 3);
+
+ ipc_on_did_downlink_multiple_ps(pdn_id, did_p, did_p, proto_idx);
+ ipc_dereg_filter(filter_id);
+
+ remain_count = upcm_did_get_buff_remain_num() +
+ qbm_get_buff_remain_num(QBM_TYPE_TGPD) + qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+ ASSERT(remain_count == buff_count);
+}
+
+kal_bool ipc_ut_dl_frag_refilter_with_cust_feature(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz)
+{
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ ilm_struct ilm;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /* Reset IPCore before test */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Activate IPv4 PDN */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ipc_ut_reset_ul_info();
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)bind_req);
+
+ ipc_ut_reg_cust_filter_prepare_fragments_and_send(IPC_UT_PDN_ID, 0);
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_dl_meta_table_threshold(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ ilm_struct ilm;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 ipv4_filter_cnt;
+ kal_uint32 ipv6_filter_cnt;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint8 matched_filter_idx_v6;
+ kal_uint32 callback_with_info;
+ kal_uint32 total_cnt;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 5; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 7; ipv6_cnt++)
+ for (ipv4_filter_cnt = 0; ipv4_filter_cnt <= 4; ipv4_filter_cnt++)
+ for (ipv6_filter_cnt = 0; ipv6_filter_cnt <= 4; ipv6_filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < ipv4_filter_cnt; matched_filter_idx_v4++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < ipv6_filter_cnt; matched_filter_idx_v6++) {
+ if ((0 == ipv4_cnt) && (0 == ipv6_cnt)) continue;
+
+ utDLOG("ifo(%d) v4Cnt(%d) v6Cnt(%d) v4FltCnt(%d) v6FltCnt(%d) v4Idx(%d) v6Idx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, ipv4_filter_cnt , ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Install DL filter for each test loop */
+ ipc_ut_install_dl_filters(callback_with_info, KAL_TRUE, ipv4_filter_cnt, ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6, IPC_UT_LHIF_NETID_START);
+
+ ipc_ut_dl_ipf_match_filter_id_v4_s = matched_filter_idx_v4;
+ ipc_ut_dl_ipf_match_filter_id_v6_s = ipv4_filter_cnt + matched_filter_idx_v6;
+
+ /* Before PDN Binding */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_pkt_cnt;
+
+ utDLOG("@ Before activation : match_result(%d)\r\n", match_result);
+
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_pkt_cnt = total_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) || (match_result == IPC_IPF_MR_PN_NO_MATCH)) {
+ expected_pkt_cnt = 0;
+ }
+
+ /* Make sure no DL callback to HIF */
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check if IPCore will release buffer when NETIF is invalid */
+ /* PN_NO_MATCH & DIRECT_TO_AP no need to free buffer */
+ if ( expected_pkt_cnt != ipc_ut_dl_meta_buf_free_num_s ) {
+ utELOG("DL buffer is not released before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4 PDN with unspecified IP address & from different MOD_UPCM_X.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic from IPCore : All meta should be forward to either DL callback or filter callback(IPv4/IPv6)
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_dl_v4_filter_out_cnt;
+ kal_uint32 expected_dl_v6_filter_out_cnt;
+ kal_uint32 expected_dl_filter_out_cnt;
+ kal_uint32 did_cnt;
+ kal_uint32 expected_dl_forwad_cnt;
+
+ utDLOG("@ PDN connected : match_result(%d)\r\n", match_result);
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_dl_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))? 1:0;
+ expected_dl_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))?1:0;
+
+ expected_dl_filter_out_cnt = expected_dl_v4_filter_out_cnt + expected_dl_v6_filter_out_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) ||
+ (match_result == IPC_IPF_MR_PN_NO_MATCH) ||
+ (match_result == IPC_IPF_MR_NET_INVALID)) {
+ did_cnt = expected_dl_forwad_cnt = 0;
+ }
+ else {
+ did_cnt = total_cnt-expected_dl_filter_out_cnt; //Supposed one DID only contains one packet
+ expected_dl_forwad_cnt = total_cnt-expected_dl_filter_out_cnt;
+ }
+
+ if (expected_dl_filter_out_cnt > 0) {
+ if (callback_with_info) {
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_LHIF_NETID_START) {
+ utELOG("Filtered-out netif ID is incorrect!\r\n");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+ else {
+ if (ipc_ut_dl_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\n");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+
+ if (ipc_ut_dl_filter_gpd_cnt != expected_dl_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+
+ if ( (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (expected_dl_forwad_cnt != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all meta should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_pkt_cnt;
+
+ utDLOG("@ PDN deactivated : dhcpv4Idx(%d), dhcpv6Idx(%d), match_result(%d)\r\n",
+ 0, 0, match_result);
+
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_pkt_cnt = total_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) || (match_result == IPC_IPF_MR_PN_NO_MATCH)) {
+ expected_pkt_cnt = 0;
+ }
+
+ /* Make sure no DL callback to HIF */
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded when PDN deactivated!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check if IPCore will release buffer when NETIF is invalid */
+ /* PN_NO_MATCH & DIRECT_TO_AP no need to free buffer */
+ if ( expected_pkt_cnt != ipc_ut_dl_meta_buf_free_num_s ) {
+ utELOG("DL buffer is not released when PDN deactivated!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+kal_bool ipc_ut_data_usage(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ ipcore_upcm_pdn_bind_ind_struct *bind_req = NULL;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req = NULL;
+ ipc_ut_netif_t *net;
+ kal_uint32 netif_id = IPC_UT_LHIF_NETID_START;
+ kal_bool result;
+ ilm_struct ilm;
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 ipv4_filter_cnt;
+ kal_uint32 ipv6_filter_cnt;
+ kal_uint8 matched_filter_idx_v4;
+ kal_uint8 matched_filter_idx_v6;
+ kal_uint32 callback_with_info;
+ kal_uint32 total_cnt;
+
+ /* init before test */
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * ipc_attach()
+ */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = netif_id;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ for (callback_with_info = 0 ; callback_with_info < 2 ; callback_with_info ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 5; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 7; ipv6_cnt++)
+ for (ipv4_filter_cnt = 0; ipv4_filter_cnt <= 4; ipv4_filter_cnt++)
+ for (ipv6_filter_cnt = 0; ipv6_filter_cnt <= 4; ipv6_filter_cnt++)
+ for (matched_filter_idx_v4 = 0; matched_filter_idx_v4 < ipv4_filter_cnt; matched_filter_idx_v4++)
+ for (matched_filter_idx_v6 = 0; matched_filter_idx_v6 < ipv6_filter_cnt; matched_filter_idx_v6++) {
+ if ((0 == ipv4_cnt) && (0 == ipv6_cnt)) continue;
+
+ utDLOG("ifo(%d) v4Cnt(%d) v6Cnt(%d) v4FltCnt(%d) v6FltCnt(%d) v4Idx(%d) v6Idx(%d)\r\n",
+ callback_with_info, ipv4_cnt, ipv6_cnt, ipv4_filter_cnt , ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6);
+
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_set_error(IPC_UT_NO_ERROR);
+
+ /* Install DL filter for each test loop */
+ ipc_ut_install_dl_filters(callback_with_info, KAL_TRUE, ipv4_filter_cnt, ipv6_filter_cnt, matched_filter_idx_v4, matched_filter_idx_v6, IPC_UT_LHIF_NETID_START);
+
+ ipc_ut_dl_ipf_match_filter_id_v4_s = matched_filter_idx_v4;
+ ipc_ut_dl_ipf_match_filter_id_v6_s = ipv4_filter_cnt + matched_filter_idx_v6;
+
+ /* Before PDN Binding */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* Before PDN Binding, IPF will only report PN not mtach case or NETIF invalid case */
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_pkt_cnt;
+
+ utDLOG("@ Before activation : match_result(%d)\r\n", match_result);
+
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_pkt_cnt = total_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) || (match_result == IPC_IPF_MR_PN_NO_MATCH)) {
+ expected_pkt_cnt = 0;
+ }
+
+ /* Make sure no DL callback to HIF */
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check if IPCore will release buffer when NETIF is invalid */
+ /* PN_NO_MATCH & DIRECT_TO_AP no need to free buffer */
+ if ( expected_pkt_cnt != ipc_ut_dl_meta_buf_free_num_s ) {
+ utELOG("DL buffer is not released before PDN binding!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Activate IPv4v6 PDN with unspecified IP address & from different MOD_UPCM_X.
+ */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_BIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)bind_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+ if (ipc_ut_msg_chk(MOD_IPCORE, MOD_UPCM, IPCORE_SAP, MSG_ID_IPCORE_UPCM_PDN_BIND_RSP, 2) != KAL_TRUE) {
+ utELOG("Bind response is not received\r\n");
+ return KAL_FALSE;
+ }
+
+ /*
+ * Simulate DL traffic from IPCore : All meta should be forward to either DL callback or filter callback(IPv4/IPv6)
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ /* After PDN Binding*/
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_dl_v4_filter_out_cnt;
+ kal_uint32 expected_dl_v6_filter_out_cnt;
+ kal_uint32 expected_dl_filter_out_cnt;
+ kal_uint32 did_cnt;
+ kal_uint32 expected_dl_forwad_cnt;
+
+ utDLOG("@ PDN connected : match_result(%d)\r\n", match_result);
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_dl_v4_filter_out_cnt = ( (ipv4_filter_cnt > 0) &&
+ (ipv4_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))? 1:0;
+ expected_dl_v6_filter_out_cnt = ( (ipv6_filter_cnt > 0) &&
+ (ipv6_cnt > 0) &&
+ (match_result != IPC_IPF_MR_DIRECT_TO_AP) &&
+ (match_result != IPC_IPF_MR_PN_NO_MATCH) &&
+ (match_result != IPC_IPF_MR_NET_INVALID))?1:0;
+
+ expected_dl_filter_out_cnt = expected_dl_v4_filter_out_cnt + expected_dl_v6_filter_out_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) ||
+ (match_result == IPC_IPF_MR_PN_NO_MATCH) ||
+ (match_result == IPC_IPF_MR_NET_INVALID)) {
+ did_cnt = expected_dl_forwad_cnt = 0;
+ }
+ else {
+ did_cnt = total_cnt-expected_dl_filter_out_cnt; //Supposed one DID only contains one packet
+ expected_dl_forwad_cnt = total_cnt-expected_dl_filter_out_cnt;
+ }
+
+ if (expected_dl_filter_out_cnt > 0) {
+ if (callback_with_info) {
+ if (ipc_ut_dl_filter_info.netif_id != IPC_UT_LHIF_NETID_START) {
+ utELOG("Filtered-out netif ID is incorrect!\r\n");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_info.ebi != -1) {
+ utELOG("Filtered-out EBI is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+ else {
+ if (ipc_ut_dl_filter_info.netif_id != 0) {
+ utELOG("Filtered-out netif ID is incorrect!\r\n");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ if (ipc_ut_dl_filter_info.ip_id != -1) {
+ utELOG("Filtered-out IP ID is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+ }
+ }
+
+
+ if (ipc_ut_dl_filter_gpd_cnt != expected_dl_filter_out_cnt) {
+ utELOG("Filtered-out gpd count is incorrect!\r\r");
+ ipc_ut_free_gpd_list(NULL, NULL);
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ return KAL_FALSE;
+ }
+
+ if ( (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (expected_dl_forwad_cnt != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+
+ /*Get Data usage*/
+ ipc_data_usage_info_t data_usage = {0};
+ ipc_get_data_usage_by_netif_id(net->conf.netif_id, &data_usage);
+
+ /* Free GPD after test */
+ ipc_ut_free_gpd_list(NULL, NULL);
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ /*
+ * PDN deactivation.
+ */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+
+ ipc_ut_msg_reset(NULL, 0, NULL, 0);
+ ilm.src_mod_id = MOD_UPCM;
+ ilm.dest_mod_id = MOD_IPCORE;
+ ilm.sap_id = IPCORE_SAP;
+ ilm.msg_id = MSG_ID_IPCORE_UPCM_PDN_UNBIND_IND;
+ ilm.local_para_ptr = (local_para_struct *)deact_req;
+ ilm.peer_buff_ptr = NULL;
+ ipc_on_ilm(&ilm);
+
+ /*
+ * Simulate DL traffic to IPCore : After PDN deactivation, all meta should be silently dropped by IPCore and NO callback is triggered
+ */
+ {
+ kal_uint32 head_idx;
+ kal_uint32 tail_idx;
+ ipfc_dl_filter_queue_type q_type;
+ kal_uint8 match_result;
+
+ for (match_result = IPC_IPF_MR_DIRECT_TO_AP ; match_result < IPC_IPF_MR_DPFM_MATCH ; match_result++) {
+ kal_uint32 expected_pkt_cnt;
+
+ utDLOG("@ PDN deactivated : dhcpv4Idx(%d), dhcpv6Idx(%d), match_result(%d)\r\n",
+ 0, 0, match_result);
+
+ ipc_ut_prepare_dl_meta_list(KAL_TRUE, ipv4_cnt, 0, ipv6_cnt, 0, &head_idx, &tail_idx, &q_type, netif_id, match_result);
+
+ /* Send IOR into IP Core */
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ ipc_meta_downlink(head_idx, tail_idx, q_type);
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ expected_pkt_cnt = total_cnt;
+
+ if ((match_result == IPC_IPF_MR_DIRECT_TO_AP) || (match_result == IPC_IPF_MR_PN_NO_MATCH)) {
+ expected_pkt_cnt = 0;
+ }
+
+ /* Make sure no DL callback to HIF */
+ if ( (0 != ipc_ut_dl_callback_did_cnt) ||
+ (0 != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL DID is forwarded when PDN deactivated!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* Check if IPCore will release buffer when NETIF is invalid */
+ /* PN_NO_MATCH & DIRECT_TO_AP no need to free buffer */
+ if ( expected_pkt_cnt != ipc_ut_dl_meta_buf_free_num_s ) {
+ utELOG("DL buffer is not released when PDN deactivated!\r\n");
+ return KAL_FALSE;
+ }
+ }
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(&ilm);
+
+ ipc_ut_uninstall_dl_filters(ipv4_filter_cnt, ipv6_filter_cnt);
+ }
+
+ /*
+ * ipc_detach().
+ */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+static void ipc_ut_pfm_garbage_str_wake_type_pkt_cbk(const kal_uint8 *packet, kal_int32 packet_len, kal_int32 pfm_filter_id, void* priv_data)
+{
+ utDLOG("Packet_buff(0x%x),len(%d),pfm_filter_id(%d),priv_data(0x%x),g_mbim_priv_data(0x%x)\r\n", packet, packet_len, pfm_filter_id, priv_data, &g_mbim_priv_data);
+ if(priv_data != &g_mbim_priv_data){
+ utELOG("wrong expected mbim priv_data!\r\n");
+ g_mbim_priv_data = IPC_UT_INAVLID_PRIV_DATA;
+ }
+ return;
+}
+
+kal_bool ipc_ut_str_garbage_filter_with_wakeup_pkt_cbk(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ pfm_filter_set_t filter_set;
+ local_para_struct *local_para_ptr;
+ peer_buff_struct *peer_buff_ptr;
+ pfm_str_filter_t *filter_info;
+ kal_uint8 i;
+ kal_uint8 *pdu_ptr;
+ kal_uint16 peer_buf_len;
+ ipc_ut_netif_t *net;
+ ipcore_upcm_pdn_bind_ind_struct *bind_req;
+ ipcore_upcm_pdn_unbind_ind_struct *deact_req;
+ static kal_uint8 ipv4_mask[192] = {0};
+ static kal_uint8 ipv6_mask[192] = {0};
+ kal_bool result;
+ kal_int32 *filter_id;
+
+ // init before test
+ ipc_ut_init();
+
+ /*
+ * Reset IPCore before test
+ */
+ if (KAL_TRUE != ipc_reset()) {
+ utELOG("ipc_reset() FAIL!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* ipc_attach() */
+ net = &(ipc_ut_nets_s[0]);
+ kal_mem_set(net, 0, sizeof(ipc_ut_netif_t));
+ net->conf.module_id = MOD_IPCORE;
+ net->conf.netif_id = IPC_UT_LHIF_NETID_START;
+ net->conf.ul_reload_context = net;
+ net->conf.ipc_ul_reload_callback_t = ipc_ut_ul_reload;
+ net->conf.callback_context = net;
+ net->conf.ipc_dlink_did_cb_t = ipc_ut_dl_callback_did;
+ net->conf.features = 0;
+ result = ipc_attach(&net->conf, &net->handle);
+ if (!result) {
+ utELOG("ipc_attach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ /* PDN activation. */
+ bind_req = (ipcore_upcm_pdn_bind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_bind_ind_struct), TD_RESET);
+ bind_req->network_interface_id = net->conf.netif_id;
+ bind_req->pdn_id = IPC_UT_PDN_ID;
+ bind_req->ip_addr.ip_addr_type = IPV4V6_ADDR_TYPE;
+ ipc_on_pdn_bind_top(MOD_NIL, (local_para_struct *)bind_req);
+ free_local_para((local_para_struct *)bind_req);
+
+ /*
+ * Register 0-7 IPv4 filter, 8-16 IPv6 filter
+ */
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_STR_FILTER_SET_ID;
+ filter_set.filter_cnt = 16;
+ filter_set.uplink = KAL_FALSE;
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ((kal_uint8*)&filter_set)+4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ /* Init mask */
+ ipv4_mask[0] = ipv6_mask[0] = 0xF0; /* IP version */
+ ipv4_mask[8] = ipv6_mask[6] = 0xFF; /* Protocol */
+ ipv4_mask[22] = ipv4_mask[23] = ipv6_mask[42] = ipv6_mask[43] = 0xFF; /* L4 dest port */
+
+ peer_buff_ptr = construct_peer_buff(sizeof(pfm_str_filter_t)*16, 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+
+ filter_info = (pfm_str_filter_t*)pdu_ptr;
+ for(i = 0; i < 16; i++){
+ filter_info->filter_id = i;
+ filter_info->magic_code = 0x1798; //PFM_STR_FILTER_MAGIC_CODE
+ filter_info->mask_len = 192;
+ filter_info->netif_id = IPC_UT_LHIF_NETID_START;
+ if( i < 8){
+ /* IPv4 filter pattern */
+ filter_info->filter_len = sizeof(ipc_ut_ipv4_tcp_ack_packet);
+
+ kal_mem_cpy(filter_info->mask, ipv4_mask, 192);
+ kal_mem_cpy(filter_info->filter, ipc_ut_ipv4_tcp_ack_packet, sizeof(ipc_ut_ipv4_tcp_ack_packet));
+
+ if(0 != i){
+ /* Not first pattern, increase dst port value (ipv4) */
+ filter_info->filter[23]++;
+ if(0 == filter_info->filter[23]){
+ filter_info->filter[22]++;
+ }
+ }
+ }else{
+ /* IPv6 filter pattern */
+ filter_info->filter_len = sizeof(ipc_ut_ipv6_udp_packet);
+
+ kal_mem_cpy(filter_info->mask, ipv6_mask, 192);
+ kal_mem_cpy(filter_info->filter, ipc_ut_ipv6_udp_packet, sizeof(ipc_ut_ipv6_udp_packet));
+ if(8 != i){
+ /* Not first pattern, increase dst port value (ipv4) */
+ filter_info->filter[42]++;
+ if(0 == filter_info->filter[42]){
+ filter_info->filter[43]++;
+ }
+ }
+ }
+ filter_info = filter_info+1;
+ }
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_REGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*register callback for pfm garbage str matched wake type packet*/
+ pfm_garbage_str_wake_type_pkt_f pf_wake_type_pkt = ipc_ut_pfm_garbage_str_wake_type_pkt_cbk;
+ pfm_reg_cbk_wake_type_pkt(pf_wake_type_pkt, &g_mbim_priv_data);
+
+ /* Simulate DL traffic to IPCore : Only data matched garbage filter should be forward to DL callback regardless of IP types (IPv4/IPv6) */
+ {
+ kal_uint32 ipv4_cnt;
+ kal_uint32 ipv6_cnt;
+ kal_uint32 total_cnt;
+ kal_uint32 did_cnt;
+ upcm_did *did_head;
+ upcm_did *did_tail;
+ kal_uint32 alignment;
+ kal_uint32 ipv4_idx;
+ kal_uint32 ipv6_idx;
+ kal_uint32 did_remain_cnt, gpd_remain_cnt_dl;
+
+ for (alignment = 0 ; alignment < 4 ; alignment ++)
+ for (ipv4_cnt = 0; ipv4_cnt <= 3; ipv4_cnt++)
+ for (ipv6_cnt = 0; ipv6_cnt <= 3; ipv6_cnt++)
+ for (ipv4_idx = 0; ipv4_idx < ipv4_cnt; ipv4_idx++)
+ for (ipv6_idx = 0; ipv6_idx < ipv6_cnt; ipv6_idx++) {
+ if (0 == ipv4_cnt && 0 == ipv6_cnt) continue;
+
+ utDLOG("v4_cnt(%d),v6_cnt(%d),ipv4_idx(%d),ipv6_idx(%d),alignment(%d)\r\n", ipv4_cnt, ipv6_cnt, ipv4_idx, ipv6_idx, alignment);
+
+ did_cnt = (ipv4_cnt == 0 || ipv6_cnt == 0) ? 1 : 2;
+ total_cnt = ipv4_cnt + ipv6_cnt;
+
+ ipc_ut_reset_dl_callback_info();
+ ipc_ut_reset_dl_filter_info();
+
+ /*Store DID remain cnt */
+ did_remain_cnt = upcm_did_get_buff_remain_num();
+
+ /*Store GPD remain cnt */
+ gpd_remain_cnt_dl = qbm_get_buff_remain_num(QBM_TYPE_NET_DL);
+
+ ipc_ut_prepare_dl_did_list_garbage(ipv4_cnt,
+ ipv6_cnt,
+ ipv4_idx,
+ ipv6_idx,
+ alignment,
+ &did_head,
+ &did_tail,
+ did_cnt);
+
+ /* simulate DL traffic from IPC_UT_PDN_ID */
+ ipc_on_did_downlink_multiple_ps(IPC_UT_PDN_ID, did_head, did_tail, 0);
+
+ if (g_mbim_priv_data == IPC_UT_INAVLID_PRIV_DATA) {
+ utELOG("Invalid mbim priv_data!\r\n");
+ return KAL_FALSE;
+ }
+
+ if ( (did_cnt != ipc_ut_dl_callback_did_cnt) ||
+ (ipc_ut_str_garbage_expect_host_cnt != ipc_ut_dl_callback_did_pkt_cnt) ) {
+ utELOG("DL PKT is NOT forwarded to bound handler!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(gpd_remain_cnt_dl != qbm_get_buff_remain_num(QBM_TYPE_NET_DL)){
+ utELOG("wrong expected QBM_TYPE_NET_DL GPD count!\r\n");
+ return KAL_FALSE;
+ }
+
+ if(did_remain_cnt != upcm_did_get_buff_remain_num()){
+ utELOG("wrong expected DID count!\r\n");
+ return KAL_FALSE;
+ }
+
+ ipc_ut_str_garbage_expect_host_cnt = 0;
+ }
+ }
+
+ /*
+ * Deregister half of filters (0~7)
+ */
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_STR_FILTER_SET_ID;
+ filter_set.filter_cnt = 8;
+ filter_set.uplink = KAL_FALSE;
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ((kal_uint8*)&filter_set)+4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ peer_buff_ptr = construct_peer_buff(sizeof(kal_int32)*8, 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+
+ filter_id = (kal_int32*) pdu_ptr;
+ for (i = 0; i < 8; i++) {
+ *filter_id = (kal_int32) i;
+ filter_id++;
+ }
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_DEREGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * Register filter_id 0~7. Half of them should not be removed yet.
+ */
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_STR_FILTER_SET_ID;
+ filter_set.filter_cnt = 8;
+ filter_set.uplink = KAL_FALSE;
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ((kal_uint8*)&filter_set)+4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ peer_buff_ptr = construct_peer_buff(sizeof(pfm_str_filter_t)*8, 0, 0, TD_RESET);
+ if (!peer_buff_ptr) {
+ utDLOG("peer_buff_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ pdu_ptr = get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+
+ filter_info = (pfm_str_filter_t*)pdu_ptr;
+ for(i = 0; i < 8; i++){
+ filter_info->filter_id = i;
+ filter_info->magic_code = 0x1798; //PFM_STR_FILTER_MAGIC_CODE
+ filter_info->mask_len = 192;
+ filter_info->netif_id = IPC_UT_LHIF_NETID_START;
+
+ /* IPv4 filter pattern */
+ filter_info->filter_len = sizeof(ipc_ut_ipv4_tcp_ack_packet);
+
+ kal_mem_cpy(filter_info->mask, ipv4_mask, 192);
+ kal_mem_cpy(filter_info->filter, ipc_ut_ipv4_tcp_ack_packet, sizeof(ipc_ut_ipv4_tcp_ack_packet));
+
+ if(0 != i){
+ /* Not first pattern, increase dst port value (ipv4) */
+ filter_info->filter[23]++;
+ if(0 == filter_info->filter[23]){
+ filter_info->filter[22]++;
+ }
+ }
+ filter_info = filter_info+1;
+ }
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_REGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ peer_buff_ptr); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*
+ * Deregister all filters
+ */
+ kal_mem_set(&filter_set, 0, sizeof(filter_set));
+ filter_set.filter_set_id = PFM_GARBAGE_STR_FILTER_SET_ID;
+ filter_set.filter_cnt = -1;
+ filter_set.uplink = KAL_FALSE;
+
+ local_para_ptr = construct_local_para(sizeof(filter_set), TD_RESET);
+ if (!local_para_ptr) {
+ utDLOG("local_para_ptr is NULL!\r\n");
+ return KAL_FALSE;
+ }
+ kal_mem_cpy(local_para_ptr + 1, ((kal_uint8*)&filter_set)+4, sizeof(filter_set) - 4); // shift local_para_ptr header
+
+ msg_send6(MOD_NIL, /* src_mod_id */
+ MOD_IPCORE, /* dest_mod_id */
+ IPCORE_SAP, /* sap_id */
+ MSG_ID_PFM_DEREGISTER_FILTER_REQ, /* msg_id */
+ local_para_ptr, /* local_para_ptr */
+ NULL); /* peer_buff_ptr */
+ kal_sleep_task(IPC_UT_MSG_LATENCY);
+
+ /*De-register callback for pfm garbage str matched wake type packet*/
+ pfm_dereg_cbk_wake_type_pkt();
+
+ /* PDN deactivation. */
+ deact_req = (ipcore_upcm_pdn_unbind_ind_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_unbind_ind_struct), TD_RESET);
+ deact_req->pdn_id = IPC_UT_PDN_ID;
+ ipc_on_pdn_unbind((local_para_struct *)deact_req);
+ free_local_para((local_para_struct *)deact_req);
+
+ /* ipc_detach(). */
+ result = ipc_detach(net->handle);
+ if (!result) {
+ utELOG("ipc_detach() returns KAL_FALSE!\r\n");
+ return KAL_FALSE;
+ }
+
+ IPC_UT_PASS();
+ return KAL_TRUE;
+}
+
+/*------------------------------------------------------------------------------
+ * Public functions.
+ *----------------------------------------------------------------------------*/
+#define IPC_UT_CASE(_func, _param) { #_func, _func, _param }
+
+kal_bool ipc_ut_st_create(void) {
+ static ST_TCASE_T ipc_ut_cases_s[] = {
+
+#if defined(__MTK_TARGET__)
+ IPC_UT_CASE(ipc_ut_struct, NULL),
+#endif
+ IPC_UT_CASE(ipc_ut_helper_macro, NULL),
+ IPC_UT_CASE(ipc_ut_checksum, NULL),
+ IPC_UT_CASE(ipc_ut_attach, NULL),
+ IPC_UT_CASE(ipc_ut_find_netif, NULL),
+ IPC_UT_CASE(ipc_ut_pdn_bind_deact, NULL),
+ IPC_UT_CASE(ipc_ut_new_session, NULL),
+ IPC_UT_CASE(ipc_ut_find_session, NULL),
+ IPC_UT_CASE(ipc_ut_poll_source, NULL),
+ IPC_UT_CASE(ipc_ut_ul_reload_retry, NULL),
+ IPC_UT_CASE(ipc_ut_del_session, NULL),
+ IPC_UT_CASE(ipc_ut_detach, NULL),
+ IPC_UT_CASE(ipc_ut_pdn_ip_info, NULL),
+ IPC_UT_CASE(ipc_ut_query_info, NULL),
+ IPC_UT_CASE(ipc_ut_rebind_pdn, NULL),
+ IPC_UT_CASE(ipc_ut_ipc_fragment, NULL),
+ IPC_UT_CASE(ipc_ut_ul_throttle, NULL),
+ IPC_UT_CASE(ipc_ut_ul_throttle_ims_emergency, NULL),
+ IPC_UT_CASE(ipc_ut_pdn_sim_macro, NULL),
+#if defined(__IPCORE_SUPPORT__) && !defined(IPCORE_NOT_PRESENT) && defined(__CCCICCMNI_SUPPORT__)
+ IPC_UT_CASE(ipc_ut_triggered_ul_reload, NULL),
+ #if (IPC_UT_GEN_INVALID_LEN_PKT)
+ IPC_UT_CASE(ipc_ut_downlink_invalid_packet, NULL),
+ #endif
+#endif
+ IPC_UT_CASE(ipc_ut_downlink_wo_dhcp4c, NULL),
+ IPC_UT_CASE(ipc_ut_uplink_filter, NULL),
+ IPC_UT_CASE(ipc_ut_link_notification, NULL),
+ IPC_UT_CASE(ipc_ut_link_status_ind, NULL),
+#if !defined(__SMART_PHONE_MODEM__)
+ IPC_UT_CASE(ipc_ut_downlink_w_dhcp4c, NULL),
+ IPC_UT_CASE(ipc_ut_ipv4_status_ind, NULL),
+ IPC_UT_CASE(ipc_ut_en_dhcp4c_unspecified_addr, NULL),
+ IPC_UT_CASE(ipc_ut_en_dhcp4c_valid_addr, NULL),
+ IPC_UT_CASE(ipc_ut_did_downlink_w_dhcp4c, NULL),
+#endif
+ IPC_UT_CASE(ipc_ut_dis_dhcp4c_unspecified_addr, NULL),
+ IPC_UT_CASE(ipc_ut_ul_filter_registration, NULL),
+ IPC_UT_CASE(ipc_ut_dl_filter_registration, NULL),
+ IPC_UT_CASE(ipc_ut_ul_filter_none, NULL),
+ IPC_UT_CASE(ipc_ut_dl_filter_none, NULL),
+ IPC_UT_CASE(ipc_ut_ul_filter_ipv4, NULL),
+ IPC_UT_CASE(ipc_ut_dl_filter_ipv4, NULL),
+ IPC_UT_CASE(ipc_ut_ul_filter_ipv6, NULL),
+ IPC_UT_CASE(ipc_ut_dl_filter_ipv6, NULL),
+ IPC_UT_CASE(ipc_ut_ul_filter_and_forward_msg, NULL),
+ IPC_UT_CASE(ipc_ut_dl_filter_and_forward_msg, NULL),
+ IPC_UT_CASE(ipc_ut_gpd_copy, NULL),
+ IPC_UT_CASE(ipc_ut_send_ul_pkt, NULL),
+ IPC_UT_CASE(ipc_ut_send_dl_pkt, NULL),
+ IPC_UT_CASE(ipc_ut_garbage_filter, NULL),
+ IPC_UT_CASE(ipc_ut_downlink_multiple_ps, NULL),
+ IPC_UT_CASE(ipc_ut_uplink_multiple_ps, NULL),
+ IPC_UT_CASE(ipc_ut_send_ul_pkt_multiple_ps, NULL),
+ IPC_UT_CASE(ipc_ut_meta_uplink, NULL),
+ IPC_UT_CASE(ipc_ut_did_downlink, NULL),
+ IPC_UT_CASE(ipc_ut_uplink_filter_meta, NULL),
+ IPC_UT_CASE(ipc_ut_did_downlink_wo_dhcp4c, NULL),
+ IPC_UT_CASE(ipc_ut_fin_ack_filter_did, NULL),
+ IPC_UT_CASE(ipc_ut_meta_downlink, NULL),
+ IPC_UT_CASE(ipc_ut_ul_throttle_plmn, NULL),
+ IPC_UT_CASE(ipc_ut_new_filter_verification, NULL),
+ IPC_UT_CASE(ipc_ut_esp_parser, NULL),
+ IPC_UT_CASE(ipc_ut_cust_filter, NULL),
+ IPC_UT_CASE(ipc_ut_esp_filter, NULL),
+ IPC_UT_CASE(ipc_ut_did_retry_put_head_queue, NULL),
+ IPC_UT_CASE(ipc_ut_ul_udp_igmp_filter, NULL),
+
+#if defined(__MD97__)
+ IPC_UT_CASE(ipc_ut_send_did_by_ch_id, NULL),
+ IPC_UT_CASE(ipc_ut_sdap_meta_downlink, NULL),
+ IPC_UT_CASE(ipc_ut_nr_did_downlink, NULL),
+#endif
+
+#ifdef __IPC_95_ACK_REDUCTION_SUPPORT__
+ IPC_UT_CASE(ipc_ut_uplink_ack_reduction, NULL),
+#endif
+
+#if defined(__MD_DIRECT_TETHERING_SUPPORT__)
+ IPC_UT_CASE(ipc_ut_meta_uplink_dpfm, NULL),
+ IPC_UT_CASE(ipc_ut_did_downlink_dpfm, NULL),
+ IPC_UT_CASE(ipc_ut_meta_uplink_dpfm_cmd_after_detach, NULL),
+#endif
+
+ IPC_UT_CASE(ipc_ut_downlink_tcprst_packet, NULL),
+ IPC_UT_CASE(ipc_ut_downlink_test_udp_drop_packet, NULL),
+ IPC_UT_CASE(ipc_ut_dl_filter_ra_pkt_did, NULL),
+ IPC_UT_CASE(ipc_ut_dl_filter_ra_pkt_did_w_dynamic_q, NULL),
+ IPC_UT_CASE(ipc_ut_str_garbage_filter, NULL),
+ IPC_UT_CASE(ipc_ut_meta_downlink_with_statistics, NULL),
+ IPC_UT_CASE(ipc_ut_dl_filter_fragments, NULL),
+ IPC_UT_CASE(ipc_ut_ra_dl, NULL),
+ IPC_UT_CASE(ipc_ut_rs_ul, NULL),
+ IPC_UT_CASE(ipc_ut_send_dl_pkt_force, NULL),
+ IPC_UT_CASE(ipc_ut_downlink_test_udp_drop_large_packet, NULL),
+ IPC_UT_CASE(ipc_ut_dl_frag_refilter_with_cust_feature, NULL),
+ IPC_UT_CASE(ipc_ut_dl_meta_table_threshold, NULL),
+ IPC_UT_CASE(ipc_ut_data_usage, NULL),
+ IPC_UT_CASE(ipc_ut_meta_downlink_with_large_pkt, NULL),
+ IPC_UT_CASE(ipc_ut_str_garbage_filter_with_wakeup_pkt_cbk, NULL),
+ };
+
+ return st_reg_test("IPCORE", &(ipc_ut_cases_s[0]), (sizeof(ipc_ut_cases_s)/sizeof(ST_TCASE_T)));
+}
+
+#endif /* ATEST_SYS_IPCORE */
diff --git a/mcu/middleware/hif/ipcore/src/ipc_ut_ilm.c b/mcu/middleware/hif/ipcore/src/ipc_ut_ilm.c
new file mode 100644
index 0000000..8eb7236
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_ut_ilm.c
@@ -0,0 +1,116 @@
+/*
+ * ipc_ut_ilm.c
+ *
+ * Created on: 2018/2/26
+ * Author: MTK15439
+ */
+
+#include "ipc_ut.h"
+#include "ipc_debug.h"
+#include "ipc_defs.h"
+#include "ipc_data.h"
+#include "upcm_msgid.h"
+
+#if defined(__MD97__)
+static kal_bool ipc_ut_rq_rule_ilm_handler(ilm_struct *p_ilm)
+{
+ ipc_rq_info_t rq_info_list = {0};
+ ipc_rq_info_t *p_rq_info = NULL;
+ ipc_rq_info_ind_t *p_rq_info_ind = NULL;
+ kal_uint32 info_cnt = 0;
+ kal_uint32 i = 0;
+ kal_uint16 peer_buf_len = 0;
+
+ ASSERT(NULL != p_ilm);
+ ASSERT(NULL == p_ilm->local_para_ptr);
+ ASSERT(NULL != p_ilm->peer_buff_ptr);
+
+ p_rq_info = (ipc_rq_info_t *)get_peer_buff_pdu(p_ilm->peer_buff_ptr, &peer_buf_len);
+ info_cnt = (peer_buf_len - 4) / sizeof(ipc_rq_info_t);
+
+ for (i = 0; i < info_cnt; i++) {
+ kal_mem_cpy(&rq_info_list, p_rq_info, sizeof(ipc_rq_info_t));
+ ipc_ut_rcv_rq_info(p_rq_info);
+ p_rq_info++;
+ }
+
+ return KAL_TRUE;
+}
+#endif
+
+static void ipc_ut_pdn_rebind_handler(ilm_struct *p_ilm)
+{
+ ipcore_upcm_pdn_rebind_rsp_struct *p_rebind_rsp = NULL;
+ p_rebind_rsp = (ipcore_upcm_pdn_rebind_rsp_struct *)construct_local_para(sizeof(ipcore_upcm_pdn_rebind_rsp_struct), TD_RESET);
+
+ ASSERT(NULL != p_ilm);
+ ASSERT(NULL != p_rebind_rsp);
+
+ kal_mem_cpy(p_rebind_rsp, p_ilm->local_para_ptr, sizeof(ipcore_upcm_pdn_rebind_rsp_struct));
+ ipc_ut_msg_send6(p_ilm->src_mod_id,
+ p_ilm->dest_mod_id,
+ p_ilm->sap_id,
+ p_ilm->msg_id,
+ (local_para_struct *)p_rebind_rsp,
+ p_ilm->peer_buff_ptr);
+
+ return;
+}
+
+static void ipc_ut_query_info_handler(ilm_struct *p_ilm)
+{
+ ipc_query_info_t *p_query_cnf = NULL;
+ p_query_cnf = (ipc_query_info_t *)construct_local_para(sizeof(ipc_query_info_t), TD_RESET);
+
+ ASSERT(NULL != p_ilm);
+ ASSERT(NULL != p_query_cnf);
+
+ kal_mem_cpy(p_query_cnf, p_ilm->local_para_ptr, sizeof(ipc_query_info_t));
+ ipc_ut_msg_send6(p_ilm->src_mod_id,
+ p_ilm->dest_mod_id,
+ p_ilm->sap_id,
+ p_ilm->msg_id,
+ (local_para_struct *)p_query_cnf,
+ p_ilm->peer_buff_ptr);
+
+ return;
+}
+
+kal_bool ipc_ut_on_ilm(ilm_struct *p_ilm)
+{
+ ASSERT(NULL != p_ilm);
+
+ switch(p_ilm->msg_id) {
+ case MSG_ID_IPCORE_UL_PACKET_FILTERED_REQ:
+ ipc_ut_on_ul_packet_filtered_req(p_ilm->local_para_ptr);
+ break;
+ case MSG_ID_IPCORE_DL_PACKET_FILTERED_REQ:
+ ipc_ut_on_dl_packet_filtered_req(p_ilm->local_para_ptr);
+ break;
+ case MSG_ID_IPCORE_UL_PACKET_FILTERED_WITH_INFO_REQ:
+ ipc_ut_on_ul_packet_filtered_with_info_req(p_ilm->local_para_ptr);
+ break;
+ case MSG_ID_IPCORE_DL_PACKET_FILTERED_WITH_INFO_REQ:
+ ipc_ut_on_dl_packet_filtered_with_info_req(p_ilm->local_para_ptr);
+ break;
+ case MSG_ID_IPCORE_UPCM_PDN_REBIND_RSP :
+ ipc_ut_pdn_rebind_handler(p_ilm);
+ break;
+ case MSG_ID_IPCORE_QUERY_INFO_CNF :
+ ipc_ut_query_info_handler(p_ilm);
+ break;
+#if defined(__MD97__)
+ case MSG_ID_IPCORE_NAS_RQ_INFO_IND:
+ ipc_ut_rq_rule_ilm_handler(p_ilm);
+ break;
+#endif
+ case MSG_ID_IPCORE_LHIFCORE_QUEUE_MAPPING_REQ:
+ /* do nothing */
+ break;
+ default :
+ ASSERT(KAL_FALSE);
+ break;
+ }
+
+ return KAL_TRUE;
+}
diff --git a/mcu/middleware/hif/ipcore/src/ipc_utils.c b/mcu/middleware/hif/ipcore/src/ipc_utils.c
new file mode 100644
index 0000000..90bc7e7
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/ipc_utils.c
@@ -0,0 +1,1195 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ipc_utils.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * IPCore internal utilities.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "upcm_did.h"
+#include "prbm.h"
+#include "qmu_bm_util.h"
+#include "mw_sap.h"
+#include "ipc_debug.h"
+#include "ipc_utils.h"
+
+#define IPC_UTILS_PKT_DUMP_DEFAULT_SIZE 3000
+
+static INLINE void ipc_utils_get_pkt_length(kal_uint8 *p_buf,
+ kal_uint32 buf_len,
+ kal_uint32 *p_pkt_len)
+{
+ ASSERT(NULL != p_buf);
+ ASSERT(NULL != p_pkt_len);
+
+ if (buf_len >= 6) {
+ /*
+ * check ip version and get ip packet length from header
+ * including ipv6 payload length
+ */
+ QBM_CACHE_INVALID((kal_uint8*)(p_buf), 6);
+
+ if (IPC_HDR_IS_V4(p_buf)) {
+ *p_pkt_len = IPC_HDR_V4_GET_TOTAL_LENGTH(p_buf);
+ } else if (IPC_HDR_IS_V6(p_buf)) {
+ *p_pkt_len = IPC_HDR_V6_GET_LENGTH(p_buf) + IPC_HDR_V6_HEADER_SIZE;
+ } else {
+ *p_pkt_len = 0;
+ }
+ } else {
+ *p_pkt_len = 0;
+ }
+}
+
+static void ipc_utils_pkt_dump_w_peerbuf(msg_type msg_id,
+ module_type src_mod,
+ peer_buff_struct *p_peer_buf)
+{
+ ilm_struct ilm = {0};
+
+ ASSERT(NULL != p_peer_buf);
+
+ /* fill ilm parameter */
+ ilm.src_mod_id = src_mod;
+ ilm.dest_mod_id = MOD_DHL;
+ ilm.sap_id = IPCORE_USER_SENSITIVE_SAP;
+ ilm.msg_id = msg_id;
+
+ ilm.local_para_ptr = NULL;
+ ilm.peer_buff_ptr = p_peer_buf;
+
+ /* send to DHL */
+ dhl_log_primitive(&ilm);
+ destroy_ilm(&ilm);
+}
+
+static kal_uint16 ipc_utils_calc_checksum16(kal_uint8 *data, kal_uint32 length)
+{
+ kal_uint32 odd = ((kal_uint32) data & 0x1);
+ kal_uint32 offset = 0;
+ kal_uint32 sum32 = 0;
+ kal_uint32 idx = 0;
+ kal_uint16 sum16 = 0;
+
+ if (!odd) {
+ sum32 = 0;
+ } else {
+ sum32 = ((kal_uint16)(*data) << 8);
+ data++;
+ length--;
+ }
+
+ offset = ((length >> 1) << 1);
+ for (idx = 0; idx < offset; idx += 2) {
+ sum32 += *((kal_uint16 *) (data + idx));
+ }
+ if ((length & 0x1)) {
+ sum32 += (kal_uint16)(*(data + length - 1));
+ }
+
+ /* add high word and low word. */
+ sum32 = (sum32 & 0xffff) + (sum32 >> 16);
+ /* add carry */
+ sum16 = (kal_uint16)((sum32 & 0xffff) + (sum32 >> 16));
+ if (odd) {
+ sum16 = (sum16 >> 8) | ((sum16 & 0xff) << 8);
+ }
+ return sum16;
+}
+
+kal_bool ipc_utils_gpd_copy(kal_uint8 *p_dst_buf,
+ kal_uint32 dst_max_len,
+ kal_uint32 *p_dst_len_copied,
+ qbm_gpd *p_head_gpd,
+ qbm_gpd *p_tail_gpd)
+{
+ qbm_gpd *p_curr_gpd = NULL;
+ qbm_gpd *p_curr_bd = NULL;
+ kal_bool is_end_of_gpd_list = KAL_FALSE;
+ kal_bool is_end_of_bd_list = KAL_FALSE;
+
+ if (NULL == p_dst_buf || 0 == dst_max_len || NULL == p_dst_len_copied ||
+ NULL == p_head_gpd || NULL == p_tail_gpd) {
+ return KAL_FALSE;
+ }
+
+ *p_dst_len_copied = 0;
+ is_end_of_gpd_list = KAL_FALSE;
+ for (p_curr_gpd = p_head_gpd; p_curr_gpd && !is_end_of_gpd_list; p_curr_gpd = (qbm_gpd *) QBM_DES_GET_NEXT(p_curr_gpd)) {
+ is_end_of_gpd_list = (p_curr_gpd == p_tail_gpd);
+ if (QBM_DES_GET_BDP(p_curr_gpd)) {
+
+ is_end_of_bd_list = KAL_FALSE;
+ for (p_curr_bd = (qbm_gpd *) QBM_DES_GET_DATAPTR(p_curr_gpd); p_curr_bd && !is_end_of_bd_list; p_curr_bd = (qbm_gpd *) QBM_DES_GET_NEXT(p_curr_bd)) {
+
+ is_end_of_bd_list = QBM_DES_GET_EOL(p_curr_bd);
+ if (QBM_DES_GET_DATALEN(p_curr_bd) > 0) {
+ if (*p_dst_len_copied + QBM_DES_GET_DATALEN(p_curr_bd) <= dst_max_len) {
+ /* Invalid source BD */
+ QBM_CACHE_INVALID(QBM_DES_GET_DATAPTR(p_curr_bd), QBM_DES_GET_DATALEN(p_curr_bd));
+
+ kal_mem_cpy(p_dst_buf + *p_dst_len_copied, QBM_DES_GET_DATAPTR(p_curr_bd), QBM_DES_GET_DATALEN(p_curr_bd));
+ *p_dst_len_copied += QBM_DES_GET_DATALEN(p_curr_bd);
+ } else {
+ return KAL_FALSE;
+ }
+ }
+ }
+ } else {
+ if (QBM_DES_GET_DATALEN(p_curr_gpd) > 0) {
+ if (*p_dst_len_copied + QBM_DES_GET_DATALEN(p_curr_gpd) <= dst_max_len) {
+ /* Invalid source GPD */
+ QBM_CACHE_INVALID(QBM_DES_GET_DATAPTR(p_curr_gpd), QBM_DES_GET_DATALEN(p_curr_gpd));
+
+ kal_mem_cpy(p_dst_buf + *p_dst_len_copied, QBM_DES_GET_DATAPTR(p_curr_gpd), QBM_DES_GET_DATALEN(p_curr_gpd));
+ *p_dst_len_copied += QBM_DES_GET_DATALEN(p_curr_gpd);
+ } else {
+ return KAL_FALSE;
+ }
+ }
+ }
+ }
+
+ /* Flush destination cache */
+ QBM_CACHE_FLUSH(p_dst_buf, *p_dst_len_copied);
+ return KAL_TRUE;
+}
+
+void ipc_utils_set_gpd_datalen(void *p_gpd, kal_uint32 datalen, void **p_payload)
+{
+ kal_uint8* p_data = NULL;
+
+ IPC_ASSERT(p_gpd && p_payload);
+
+ if (QBM_DES_GET_BDP(p_gpd)) {
+ void* p_bd = NULL;
+
+ /* set p_bd data ptr */
+ p_bd = QBM_DES_GET_DATAPTR(p_gpd);
+
+ p_data = (kal_uint8*) QBM_DES_GET_DATAPTR(p_bd);
+
+ /* set p_bd data len */
+ QBM_DES_SET_DATALEN(p_bd, datalen);
+
+ /* set p_bd checksum */
+ qbm_cal_set_checksum(p_bd);
+ } else {
+ p_data = (kal_uint8*) QBM_DES_GET_DATAPTR(p_gpd);
+ }
+
+ /* set p_gpd data len */
+ QBM_DES_SET_DATALEN(p_gpd, datalen);
+
+ /* set p_gpd checksum */
+ qbm_cal_set_checksum(p_gpd);
+
+ *p_payload = (void*)(p_data);
+}
+
+kal_bool ipc_utils_get_gpd_dataptr(void *p_gpd, void **p_payload)
+{
+ kal_uint8* p_data = NULL;
+
+ if(!p_gpd || !p_payload){
+ return KAL_FALSE;
+ }
+
+ if (QBM_DES_GET_BDP(p_gpd)) {
+ void* p_bd = NULL;
+
+ /* set p_bd data ptr */
+ p_bd = QBM_DES_GET_DATAPTR(p_gpd);
+
+ p_data = (kal_uint8*) QBM_DES_GET_DATAPTR(p_bd);
+
+ } else {
+ p_data = (kal_uint8*) QBM_DES_GET_DATAPTR(p_gpd);
+ }
+
+ *p_payload = (void*)(p_data);
+ return KAL_TRUE;
+}
+
+
+void ipc_utils_clarify_gpd(qbm_gpd *p_head_gpd,
+ qbm_gpd *p_tail_gpd,
+ qbm_gpd **p_ipv4_head_gpd,
+ qbm_gpd **p_ipv4_tail_gpd,
+ qbm_gpd **p_ipv6_head_gpd,
+ qbm_gpd **p_ipv6_tail_gpd)
+{
+ kal_bool is_end = KAL_FALSE;
+ qbm_gpd *p_curr_gpd = NULL;
+ qbm_gpd *p_next_gpd = NULL;
+ qbm_gpd *p_curr_bd = NULL;
+ kal_uint8 *p_first_buf = NULL;
+
+ IPC_ASSERT(p_ipv4_head_gpd);
+ IPC_ASSERT(p_ipv4_tail_gpd);
+ IPC_ASSERT(p_ipv6_head_gpd);
+ IPC_ASSERT(p_ipv6_tail_gpd);
+
+ *p_ipv4_head_gpd = *p_ipv4_tail_gpd = NULL;
+ *p_ipv6_head_gpd = *p_ipv6_tail_gpd = NULL;
+
+ is_end = KAL_FALSE;
+ for (p_curr_gpd = p_head_gpd; p_curr_gpd && !is_end; p_curr_gpd = p_next_gpd) {
+ IPC_ASSERT(QBM_DES_GET_DATAPTR(p_curr_gpd));
+
+ p_next_gpd = (qbm_gpd *) QBM_DES_GET_NEXT(p_curr_gpd);
+ is_end = (p_curr_gpd == p_tail_gpd) ? KAL_TRUE : KAL_FALSE;
+
+ if (QBM_DES_GET_DATALEN(p_curr_gpd) == 0) {
+ /* Zero length packet ! Drop this packet ! */
+ hif_trace_error(IPC_TR_CLARIFY_ZERO_LENGTH_PKT, p_curr_gpd, QBM_DES_GET_DATALEN(p_curr_gpd));
+ p_first_buf = NULL;
+ } else {
+ if (QBM_DES_GET_BDP(p_curr_gpd)) {
+ p_curr_bd = (qbm_gpd *) QBM_DES_GET_DATAPTR(p_curr_gpd);
+ /* Loop to trace 1st DL BD with data buffer */
+ while (p_curr_bd && (QBM_DES_GET_DATALEN(p_curr_bd) == 0)) {
+ p_curr_bd = (QBM_DES_GET_EOL(p_curr_bd)) ? (NULL) : ((qbm_gpd*)QBM_DES_GET_NEXT(p_curr_bd));
+ }
+
+ if (p_curr_bd) {
+ p_first_buf = (kal_uint8 *) QBM_DES_GET_DATAPTR(p_curr_bd);
+ } else {
+ hif_trace_error(IPC_TR_CLARIFY_ZERO_LENGTH_BD, p_curr_gpd, QBM_DES_GET_DATALEN(p_curr_gpd));
+ p_first_buf = NULL;
+ }
+ } else {
+ p_first_buf = (kal_uint8 *) QBM_DES_GET_DATAPTR(p_curr_gpd);
+ }
+ }
+
+ if (p_first_buf) {
+ if (IPC_HDR_IS_V4(p_first_buf)) {
+ if (*p_ipv4_tail_gpd) {
+ QBM_DES_SET_NEXT((*p_ipv4_tail_gpd), p_curr_gpd);
+ *p_ipv4_tail_gpd = p_curr_gpd;
+ } else {
+ *p_ipv4_head_gpd = p_curr_gpd;
+ *p_ipv4_tail_gpd = p_curr_gpd;
+ }
+ } else if (IPC_HDR_IS_V6(p_first_buf)) {
+ if (*p_ipv6_tail_gpd) {
+ QBM_DES_SET_NEXT((*p_ipv6_tail_gpd), p_curr_gpd);
+ *p_ipv6_tail_gpd = p_curr_gpd;
+ } else {
+ *p_ipv6_head_gpd = p_curr_gpd;
+ *p_ipv6_tail_gpd = p_curr_gpd;
+ }
+ } else {
+ hif_trace_error(IPC_TR_CLARIFY_NONE_IP_PKT, p_curr_gpd, QBM_DES_GET_DATALEN(p_curr_gpd));
+ qbmt_dest_q(p_curr_gpd, p_curr_gpd);
+ }
+ } else {
+ /* Always drop p_curr_gpd for parsing error case */
+ hif_trace_info(IPC_TR_CLARIFY_ZERO_LENGTH_PKT_DROP, p_curr_gpd, QBM_DES_GET_DATALEN(p_curr_gpd));
+ qbmt_dest_q(p_curr_gpd, p_curr_gpd);
+ }
+ }
+
+}
+
+ipc_si_hif_type_e ipc_utils_get_hif_type_by_netif_id(kal_uint32 netif_id)
+{
+ if (IPC_INVALID_NETIF_ID == netif_id) {
+ return IPC_SI_HIF_TYPE_IGR;
+ }
+
+ switch (netif_id & 0xFFFFFF00) {
+ case IPC_NETIF_ID_LHIF_BEGIN:
+ return IPC_SI_HIF_TYPE_LHIF;
+ case IPC_NETIF_ID_ETH_BEGIN:
+ case IPC_NETIF_ID_MBIM_BEGIN:
+ return IPC_SI_HIF_TYPE_USB;
+ case IPC_NETIF_ID_MCIF_BEGIN:
+ return IPC_SI_HIF_TYPE_MCIF;
+ case IPC_NETIF_ID_VNIF_BEGIN:
+ return IPC_SI_HIF_TYPE_VNIF;
+ default:
+ /* can't reach here */
+ IPC_ASSERT(KAL_FALSE);
+ return IPC_SI_HIF_TYPE_IGR;
+ }
+}
+
+void ipc_utils_pkt_set_si_hif_type(upcm_did *p_did,
+ ipc_si_hif_type_e hif_type,
+ kal_uint32 *p_curr_si_idx)
+{
+ upcm_did_si *p_sit = NULL;
+ kal_uint32 pkt_start_idx = 0;
+ kal_bool is_eol = KAL_FALSE;
+
+ IPC_ASSERT((p_did) && (p_curr_si_idx));
+
+ p_sit = UPCM_DID_GET_SIT_PTR(p_did);
+ pkt_start_idx = *p_curr_si_idx;
+
+ IPC_ASSERT( pkt_start_idx < UPCM_DID_MAX_SIT_ENT_NUM );
+
+ if (IPC_SI_HIF_TYPE_IGR == hif_type) {
+ ipc_utils_pkt_dump_did_one_pkt(p_did, &pkt_start_idx);
+ pkt_start_idx = *p_curr_si_idx;
+ }
+
+ is_eol = KAL_FALSE;
+ for (*p_curr_si_idx = pkt_start_idx; *p_curr_si_idx < UPCM_DID_MAX_SIT_ENT_NUM && !is_eol; (*p_curr_si_idx)++) {
+ upcm_did_si *p_curr_si = &p_sit[*p_curr_si_idx];
+
+ is_eol = UPCM_DID_SI_GET_EOL(p_curr_si);
+ UPCM_DID_SI_SET_HIF_TYPE(p_curr_si, hif_type);
+ if (IPC_SI_HIF_TYPE_IGR == hif_type) {
+ upcm_did_si_free_data_buf(p_curr_si);
+ /*
+ * We have to clear sit length if hif_type is IGNORE.
+ * Then, we can use this condition to skip these sit entries if the
+ * sit is already processed last time and HIF refuse to send.
+ */
+ UPCM_DID_SI_SET_LEN(p_curr_si, 0);
+ }
+ }
+}
+
+kal_bool ipc_utils_cpy_gpd_to_did(qbm_gpd *p_head_gpd,
+ qbm_gpd *p_tail_gpd,
+ upcm_did *p_did,
+ ipc_si_hif_type_e hif_type)
+{
+ qbm_gpd *p_curr_gpd = NULL;
+ qbm_gpd *p_curr_bd = NULL;
+ kal_bool end_of_gpd_list = KAL_FALSE;
+ kal_bool end_of_bd_list = KAL_FALSE;
+ upcm_did_si *p_sit = NULL;
+ upcm_did_si *p_curr_si = NULL;
+ kal_uint32 curr_si_idx;
+ kal_uint8 *p_dst_buf = NULL;
+ kal_uint8 pkt_cnt = 0;
+ kal_uint32 dst_len_copied = 0;
+ kal_uint32 dst_max_len = 0;
+
+ IPC_ASSERT(p_head_gpd && p_tail_gpd && p_did);
+
+ p_sit = UPCM_DID_GET_SIT_PTR(p_did);
+ curr_si_idx = 0;
+
+ end_of_gpd_list = KAL_FALSE;
+ for (p_curr_gpd = p_head_gpd;
+ p_curr_gpd && !end_of_gpd_list;
+ p_curr_gpd = (qbm_gpd *)QBM_DES_GET_NEXT(p_curr_gpd), curr_si_idx++) {
+
+ IPC_ASSERT(curr_si_idx < UPCM_DID_MAX_SIT_ENT_NUM);
+ p_curr_si = &p_sit[curr_si_idx];
+
+ dst_max_len = QBM_DES_GET_DATALEN(p_curr_gpd);
+ if (0 == dst_max_len) {
+ hif_trace_error(IPC_TR_COPY_GPD_TO_DID_ZERO_LENGTH_GPD, p_curr_gpd);
+ continue;
+ }
+
+ p_dst_buf = IPC_ALLOCATE_PRBM(dst_max_len, IPC_PRB_DL_ID);
+ dst_len_copied = 0;
+
+ if (!p_dst_buf) {
+ hif_trace_error(IPC_TR_COPY_GPD_TO_DID_ZERO_ALLOC_PRB_NG, p_curr_gpd, p_tail_gpd);
+ goto done;
+ }
+
+ end_of_gpd_list = (p_curr_gpd == p_tail_gpd);
+ if (QBM_DES_GET_BDP(p_curr_gpd)) {
+ end_of_bd_list = KAL_FALSE;
+ for (p_curr_bd = (qbm_gpd *)QBM_DES_GET_DATAPTR(p_curr_gpd);
+ p_curr_bd && !end_of_bd_list;
+ p_curr_bd = (qbm_gpd *)QBM_DES_GET_NEXT(p_curr_bd)) {
+
+ end_of_bd_list = QBM_DES_GET_EOL(p_curr_bd);
+ if (QBM_DES_GET_DATALEN(p_curr_bd) > 0) {
+ if (dst_len_copied + QBM_DES_GET_DATALEN(p_curr_bd) <= dst_max_len) {
+ /* Invalid source BD */
+ QBM_CACHE_INVALID(QBM_DES_GET_DATAPTR(p_curr_bd), QBM_DES_GET_DATALEN(p_curr_bd));
+ kal_mem_cpy(p_dst_buf + dst_len_copied, QBM_DES_GET_DATAPTR(p_curr_bd), QBM_DES_GET_DATALEN(p_curr_bd));
+ dst_len_copied += QBM_DES_GET_DATALEN(p_curr_bd);
+ } else {
+ hif_trace_error(IPC_TR_COPY_GPD_TO_DID_GPD_LENGTH_NG, p_curr_gpd);
+ IPC_FREE_PRBM(p_dst_buf, dst_max_len, IPC_PRB_DL_ID);
+ continue;
+ }
+ }
+ }
+ } else {
+ if (QBM_DES_GET_DATALEN(p_curr_gpd) > 0) {
+ if (dst_len_copied + QBM_DES_GET_DATALEN(p_curr_gpd) <= dst_max_len) {
+ /* Invalid source GPD */
+ QBM_CACHE_INVALID(QBM_DES_GET_DATAPTR(p_curr_gpd), QBM_DES_GET_DATALEN(p_curr_gpd));
+ kal_mem_cpy(p_dst_buf + dst_len_copied, QBM_DES_GET_DATAPTR(p_curr_gpd), QBM_DES_GET_DATALEN(p_curr_gpd));
+ dst_len_copied += QBM_DES_GET_DATALEN(p_curr_gpd);
+ } else {
+ hif_trace_error(IPC_TR_COPY_GPD_TO_DID_GPD_LENGTH_NG, p_curr_gpd);
+ IPC_FREE_PRBM(p_dst_buf, dst_max_len, IPC_PRB_DL_ID);
+ continue;
+ }
+ }
+ }
+
+ /* Flush destination cache */
+ QBM_CACHE_FLUSH(p_dst_buf, dst_len_copied);
+
+ kal_mem_set(p_curr_si, 0, sizeof(upcm_did_si));
+ UPCM_DID_SI_SET_EOL(p_curr_si);
+ UPCM_DID_SI_SET_F(p_curr_si);
+ UPCM_DID_SI_SET_LEN(p_curr_si, dst_max_len);
+ UPCM_DID_SI_SET_DATAPTR(p_curr_si, p_dst_buf);
+ UPCM_DID_SI_SET_HIF_TYPE(p_curr_si, hif_type);
+
+ pkt_cnt++;
+ }
+
+done :
+ if (pkt_cnt) {
+ UPCM_DID_SET_PKT_NUM(p_did, pkt_cnt);
+ UPCM_DID_SET_SEG_NUM(p_did, pkt_cnt);
+
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+}
+
+void ipc_utils_pkt_free_si_data_buf(upcm_did *p_did, kal_uint32 *p_curr_si_idx)
+{
+ upcm_did_si *p_sit = NULL;
+ kal_uint32 pkt_start_idx = 0;
+ kal_bool is_eol = KAL_FALSE;
+
+ IPC_ASSERT( (p_did) && (p_curr_si_idx) );
+
+ p_sit = UPCM_DID_GET_SIT_PTR(p_did);
+ pkt_start_idx = *p_curr_si_idx;
+
+ IPC_ASSERT( pkt_start_idx < UPCM_DID_MAX_SIT_ENT_NUM );
+
+ ipc_utils_pkt_dump_did_one_pkt(p_did, &pkt_start_idx);
+ pkt_start_idx = *p_curr_si_idx;
+
+ is_eol = KAL_FALSE;
+ for (*p_curr_si_idx = pkt_start_idx;
+ *p_curr_si_idx < UPCM_DID_MAX_SIT_ENT_NUM && !is_eol;
+ (*p_curr_si_idx)++) {
+
+ upcm_did_si *p_curr_si = &p_sit[*p_curr_si_idx];
+ is_eol = UPCM_DID_SI_GET_EOL(p_curr_si);
+ UPCM_DID_SI_SET_HIF_TYPE(p_curr_si, IPC_SI_HIF_TYPE_IGR);
+ upcm_did_si_free_data_buf(p_curr_si);
+ }
+}
+
+kal_bool ipc_utils_fill_did_si_from_meta(kal_bool is_need_adjust,
+ upcm_did *p_dst_did,
+ kal_uint32 *p_si_idx,
+ ipc_meta_info_des *p_pkt_info,
+ ipc_si_hif_type_e hif_type)
+{
+ upcm_did_si *p_sit = NULL;
+ upcm_did_si *p_si = NULL;
+ kal_uint16 base_psn = 0;
+ kal_uint16 psn = 0;
+ kal_uint32 num_igr_si = 0;
+ kal_uint32 i = 0;
+
+ IPC_ASSERT(p_dst_did && p_pkt_info && p_si_idx);
+
+ if(*p_si_idx >= UPCM_DID_MAX_SIT_ENT_NUM){
+ hif_trace_error(IPC_TR_FILL_DID_FROM_META_NG, *p_si_idx, is_need_adjust, p_dst_did);
+ return KAL_FALSE;
+ }
+
+ p_sit = UPCM_DID_GET_SIT_PTR(p_dst_did);
+
+ if (is_need_adjust) {
+ base_psn = UPCM_DID_GET_COUNT_L(p_dst_did);
+ psn = p_pkt_info->psn_countL;
+
+ /*
+ * DID PSN is continuous.
+ * if the coming PSN is smaller than previous, we need to allocate a new DID
+ */
+ if (psn < (base_psn + *p_si_idx)) {
+ return KAL_FALSE;
+ }
+
+ /* Calculate how many sit entry we need to skip */
+ num_igr_si = psn - (base_psn + *p_si_idx);
+ if ((*p_si_idx + num_igr_si) >= UPCM_DID_MAX_SIT_ENT_NUM) {
+ return KAL_FALSE;
+ }
+
+ /* Fill IGR packet to SIs for PSN correction */
+ for (i = 0; i < num_igr_si; i++) {
+ p_si = &(p_sit[*p_si_idx + i]);
+ UPCM_DID_SI_SET_EOL(p_si);
+ UPCM_DID_SI_CLR_F(p_si);
+ UPCM_DID_SI_SET_HIF_TYPE(p_si, IPC_SI_HIF_TYPE_IGR);
+ }
+ }
+
+ /* Fill the packet to the right position based on its PSN */
+ *p_si_idx += num_igr_si;
+ p_si = &(p_sit[*p_si_idx]);
+ UPCM_DID_SI_SET_EOL(p_si);
+ UPCM_DID_SI_SET_F(p_si);
+ UPCM_DID_SI_SET_LEN(p_si, p_pkt_info->len);
+ UPCM_DID_SI_SET_DATAPTR(p_si, p_pkt_info->addr);
+ UPCM_DID_SI_SET_HIF_TYPE(p_si, hif_type);
+ UPCM_DID_SI_SET_OFFSET(p_si, 0);
+
+ UPCM_DID_SET_PKT_NUM(p_dst_did, UPCM_DID_GET_PKT_NUM(p_dst_did) + 1);
+ UPCM_DID_SET_SEG_NUM(p_dst_did, UPCM_DID_GET_SEG_NUM(p_dst_did) + 1);
+ (*p_si_idx)++;
+
+ return KAL_TRUE;
+}
+
+void ipc_utils_pkt_dump_buf(msg_type msg_id,
+ module_type src_mod,
+ kal_uint8 *p_buf,
+ kal_uint32 pkt_len)
+{
+ ilm_struct ilm = {0};
+ kal_uint8 *p_dump_info = NULL;
+ peer_buff_struct *p_peer = NULL;
+ kal_uint16 peer_buf_len = 0;
+
+ /* fill ilm parameter */
+ ilm.src_mod_id = src_mod;
+ ilm.dest_mod_id = MOD_DHL;
+ ilm.sap_id = IPCORE_USER_SENSITIVE_SAP;
+ ilm.msg_id = msg_id;
+
+ if (0 == pkt_len) {
+ return;
+ }
+
+ if (pkt_len > IPC_UTILS_PKT_DUMP_DEFAULT_SIZE) {
+ pkt_len = IPC_UTILS_PKT_DUMP_DEFAULT_SIZE;
+ }
+
+ /* allocate peer buffer and reset to 0 */
+ p_peer = construct_peer_buff(sizeof(kal_uint8)*pkt_len, 0, 0, TD_RESET);
+ p_dump_info = (kal_uint8*) get_peer_buff_pdu(p_peer, &peer_buf_len);
+
+ /* copy packet content */
+ QBM_CACHE_INVALID((kal_uint8*)(p_buf), pkt_len);
+ kal_mem_cpy(p_dump_info, p_buf, peer_buf_len);
+
+ ilm.local_para_ptr = NULL;
+ ilm.peer_buff_ptr = p_peer;
+
+ /* send to DHL */
+ dhl_log_primitive(&ilm);
+ destroy_ilm(&ilm);
+}
+
+void ipc_utils_pkt_dump_buff_gpd_list(qbm_gpd *p_head_gpd,
+ qbm_gpd *p_tail_gpd,
+ kal_bool is_uplink)
+{
+ qbm_gpd *p_curr_gpd = NULL;
+ qbm_gpd *p_next_gpd = NULL;
+ qbm_gpd *p_bd = NULL;
+ kal_uint8 *p_pkt = NULL;
+ kal_uint32 pkt_len = 0;
+ kal_bool is_eol = KAL_FALSE;
+
+ IPC_ASSERT(p_head_gpd && p_tail_gpd);
+
+ is_eol = KAL_FALSE;
+ for (p_curr_gpd = p_head_gpd; p_curr_gpd && !is_eol; p_curr_gpd = p_next_gpd) {
+ p_next_gpd = QBM_DES_GET_NEXT(p_curr_gpd);
+ is_eol = (p_curr_gpd == p_tail_gpd);
+
+ pkt_len = QBM_DES_GET_DATALEN(p_curr_gpd);
+ p_bd = QBM_DES_GET_DATAPTR(p_curr_gpd);
+ if ((0 != pkt_len) && (pkt_len == QBM_DES_GET_DATALEN(p_bd))) {
+ p_pkt = QBM_DES_GET_DATAPTR(p_bd);
+ if (is_uplink) {
+ IPC_UL_PKT_DUMP(p_pkt, pkt_len);
+ } else {
+ IPC_DL_PKT_DUMP(p_pkt, pkt_len);
+ }
+ }
+ }
+}
+
+void ipc_utils_pkt_dump_did_one_pkt(upcm_did *p_did, kal_uint32 *p_curr_si_idx)
+{
+ upcm_did_si *p_sit = NULL;
+ upcm_did_si *p_curr_si = NULL;
+ kal_uint32 pkt_start_idx = 0;
+ kal_bool is_eol = KAL_FALSE;
+ kal_uint32 pkt_len = 0;
+ kal_uint32 pkt_offset = 0;
+ kal_uint32 si_len = 0;
+ kal_uint8 *p_buf = NULL;
+ kal_uint8 *p_dump_info = NULL;
+ peer_buff_struct *p_peer = NULL;
+ kal_uint16 peer_buf_len = 0;
+
+ IPC_ASSERT((p_did) && (p_curr_si_idx));
+
+ p_sit = UPCM_DID_GET_SIT_PTR(p_did);
+ p_curr_si = &p_sit[*p_curr_si_idx];
+ p_buf = (kal_uint8*) UPCM_DID_SI_GET_DATAPTR(p_curr_si) + UPCM_DID_SI_GET_OFFSET(p_curr_si);
+ si_len = UPCM_DID_SI_GET_LEN(p_curr_si);
+ pkt_start_idx = *p_curr_si_idx;
+
+ IPC_ASSERT( pkt_start_idx < UPCM_DID_MAX_SIT_ENT_NUM );
+
+ ipc_utils_get_pkt_length(p_buf, si_len, &pkt_len);
+ if (pkt_len == 0 || pkt_len > IPC_UTILS_PKT_DUMP_DEFAULT_SIZE) {
+ /* Invalid packet length, use default size instead */
+ pkt_len = IPC_UTILS_PKT_DUMP_DEFAULT_SIZE;
+ }
+
+ p_peer = construct_peer_buff(sizeof(kal_uint8) *pkt_len, 0, 0, TD_RESET);
+ p_dump_info = (kal_uint8*) get_peer_buff_pdu(p_peer, &peer_buf_len);
+ pkt_offset = 0;
+
+ is_eol = KAL_FALSE;
+ while (*p_curr_si_idx < UPCM_DID_MAX_SIT_ENT_NUM) {
+ p_curr_si = &p_sit[*p_curr_si_idx];
+ p_buf = (kal_uint8*) UPCM_DID_SI_GET_DATAPTR(p_curr_si) + UPCM_DID_SI_GET_OFFSET(p_curr_si);
+ si_len = UPCM_DID_SI_GET_LEN(p_curr_si);
+ is_eol = UPCM_DID_SI_GET_EOL(p_curr_si);
+
+ /* copy packet content */
+ if (si_len <= peer_buf_len) {
+ QBM_CACHE_INVALID((kal_uint8*)(p_buf), si_len);
+ kal_mem_cpy(p_dump_info + pkt_offset, p_buf, si_len);
+ pkt_offset += si_len;
+ peer_buf_len -= si_len;
+ }
+
+ if (!is_eol) {
+ (*p_curr_si_idx)++;
+ } else {
+ break;
+ }
+ }
+
+ /* send to DHL */
+ ipc_utils_pkt_dump_w_peerbuf(MSG_IPC_DL_RAW_DATA, MOD_IPCORE, p_peer);
+}
+
+void ipc_utils_pkt_dump_did(upcm_did *p_did_head,
+ upcm_did *p_did_tail,
+ ipc_si_hif_type_e hif_type)
+{
+ upcm_did *p_did = NULL;
+ upcm_did *p_next_did = NULL;
+ kal_bool is_eol = KAL_FALSE;
+ kal_uint32 seg_num = 0;
+ kal_uint32 cur_si_idx = 0;
+ upcm_did_si *p_did_si = NULL;
+ kal_bool free_all = KAL_FALSE;
+
+ /* chek if DID input is NULL */
+ ASSERT(p_did_head && p_did_tail);
+
+ free_all = (IPC_SI_HIF_TYPE_MAX == hif_type);
+
+ is_eol = KAL_FALSE;
+ for (p_did = p_did_head; p_did && !is_eol; p_did = p_next_did) {
+ p_next_did = UPCM_DID_GET_NEXT(p_did);
+ is_eol = (p_did == p_did_tail) ? KAL_TRUE : KAL_FALSE;
+ seg_num = UPCM_DID_GET_SEG_NUM(p_did);
+
+ for (cur_si_idx = 0; cur_si_idx < seg_num; cur_si_idx++) {
+ p_did_si = &p_did->sit[cur_si_idx];
+
+ /* skip si if hif_type is not equal to specified value*/
+ if ((hif_type != UPCM_DID_SI_GET_HIF_TYPE(p_did_si)) && !free_all) {
+ continue;
+ }
+
+ ipc_utils_pkt_dump_did_one_pkt(p_did, &cur_si_idx);
+ }
+ }
+}
+
+void ipc_utils_dump_data(void *p_data, kal_uint32 bytes)
+{
+ kal_uint32 i = 0;
+ /* 4bytes alignment */
+ kal_uint32 *p_d = (kal_uint32*)((int)p_data & (~0X3));
+
+ for (i = 0; i*4 < bytes; i = i + 4) {
+ hif_data_trace(MD_TRC_IPC_DATA_DUMP_TRACE,i*4 , p_d[i], p_d[i+1], p_d[i+2], p_d[i+3]);
+ }
+}
+
+void ipc_utils_gpd_list_del_entry(qbm_gpd **p_first_gpd,
+ qbm_gpd **p_last_gpd,
+ qbm_gpd **p_curr_gpd,
+ qbm_gpd **p_prev_gpd,
+ qbm_gpd **p_next_gpd)
+{
+ if (*p_curr_gpd == *p_first_gpd) {
+ if (*p_curr_gpd == *p_last_gpd) {
+ *p_first_gpd = NULL;
+ *p_last_gpd = NULL;
+ } else {
+ IPC_ASSERT(*p_next_gpd);
+ *p_first_gpd = *p_next_gpd;
+ }
+ *p_prev_gpd = NULL;
+ } else {
+ IPC_ASSERT(*p_prev_gpd);
+ if (*p_curr_gpd == *p_last_gpd) {
+ *p_last_gpd = *p_prev_gpd;
+ QBM_DES_SET_NEXT(*p_prev_gpd, NULL);
+ } else {
+ IPC_ASSERT(*p_next_gpd);
+ QBM_DES_SET_NEXT(*p_prev_gpd, *p_next_gpd);
+ }
+ }
+ QBM_DES_SET_NEXT(*p_curr_gpd, NULL);
+}
+
+void ipc_utils_unite_gpd(kal_bool is_uplink,
+ qbm_gpd *p_gpd_in,
+ qbm_gpd **pp_gpd_out)
+{
+ IPC_ASSERT(p_gpd_in);
+ IPC_ASSERT(pp_gpd_out);
+
+ /*
+ * Check if this GPD is needed to unite:
+ *
+ * 1. This GPD has BD list.
+ * 2. First BD (containing data) does not have full data within it.
+ */
+ {
+ qbm_gpd* p_bd = NULL;
+
+ if (!QBM_DES_GET_BDP(p_gpd_in)) {
+ goto no_change;
+ }
+
+ /* get 1st bd data ptr */
+ p_bd = QBM_DES_GET_DATAPTR(p_gpd_in);
+
+ /* Loop to trace 1st DL BD with data buffer */
+ while (p_bd && (QBM_DES_GET_DATALEN(p_bd) == 0)) {
+ p_bd = (QBM_DES_GET_EOL(p_bd)) ? (NULL) : ((qbm_gpd*) QBM_DES_GET_NEXT(p_bd));
+ }
+
+ /* No any BD have data */
+ if (NULL == p_bd) {
+ hif_trace_error(IPC_TR_GPD_UNITE_NULL_BD_LIST, is_uplink, p_gpd_in);
+ goto no_change;
+ }
+
+ if (QBM_DES_GET_DATALEN(p_gpd_in) == QBM_DES_GET_DATALEN(p_bd)) {
+ goto no_change;
+ }
+ }
+
+ /* This packet is divided into several pieces of data segment, unite them into single one. */
+ {
+ kal_uint32 total_len = 0;
+ kal_uint32 copied_len = 0;
+ kal_uint8 *p_buff = 0;
+
+ total_len = QBM_DES_GET_DATALEN(p_gpd_in);
+ if (0 == total_len) {
+ hif_trace_error(IPC_TR_GPD_UNITE_ZERO_LENGTH_GPD, is_uplink, p_gpd_in);
+ goto no_change;
+ }
+
+ if (1 != qbmt_alloc_q_no_tail(is_uplink ? QBM_TYPE_NET_UL_SHRD : QBM_TYPE_NET_DL,
+ 1,
+ (void**) pp_gpd_out,
+ (void**) pp_gpd_out)) {
+ hif_trace_error(IPC_TR_GPD_UNITE_ALLOC_GPD_NG, is_uplink, p_gpd_in, total_len);
+ goto unite_failed;
+ }
+
+ /* Copy data from input GPD to output GPD */
+ IPC_ASSERT(*pp_gpd_out);
+ ipc_utils_set_gpd_datalen(*pp_gpd_out, total_len, (void**) &p_buff);
+ IPC_ASSERT(p_buff);
+
+ if (KAL_TRUE != ipc_utils_gpd_copy(p_buff, total_len, &copied_len, p_gpd_in, p_gpd_in)) {
+ hif_trace_error(IPC_TR_GPD_UNITE_GPD_COPY_NG, is_uplink, p_buff, total_len, copied_len, p_gpd_in);
+ /* Free allocated new GPD */
+ qbmt_dest_q(*pp_gpd_out, *pp_gpd_out);
+ goto unite_failed;
+ }
+
+ /* Sync SW control field from UPCM for DL traffic */
+ if (KAL_FALSE == is_uplink) {
+ /* SW control field is from UPCM */
+ kal_mem_cpy((void*) QBM_DES_GET_SW_CTRL_FIELD(*pp_gpd_out), (void*) QBM_DES_GET_SW_CTRL_FIELD(p_gpd_in), sizeof(upcm_dlvr_dl_info_t));
+ }
+ }
+
+ /* Unite done : return new GPD. */
+ hif_data_trace(MD_TRC_IPC_GE_UNITED_GPD, is_uplink, p_gpd_in, *pp_gpd_out, QBM_DES_GET_DATALEN(*pp_gpd_out));
+ IPC_ASSERT(*pp_gpd_out);
+ return;
+
+no_change :
+ *pp_gpd_out = p_gpd_in;
+ return;
+
+unite_failed :
+ hif_trace_error(IPC_TR_GPD_UNITE_FAILED, is_uplink, p_gpd_in);
+ *pp_gpd_out = NULL;
+ return;
+}
+
+kal_bool ipc_utils_sit_to_gpd(qbm_type type,
+ upcm_did *p_did,
+ kal_uint32 curr_si_idx,
+ kal_uint32 pkt_len,
+ qbm_gpd **pp_gpd_out)
+{
+ kal_uint8 *p_gpd_data = NULL;
+ upcm_did_si *sit = UPCM_DID_GET_SIT_PTR(p_did);
+ kal_uint32 pkt_start_idx = curr_si_idx;
+ kal_uint8 *p_src_buf = NULL;
+ kal_uint32 dst_len_copied = 0;
+ kal_bool end_of_seg_list = KAL_FALSE;
+
+ IPC_ASSERT((p_did) && (pkt_start_idx < UPCM_DID_MAX_SIT_ENT_NUM));
+
+ if ((QBM_TYPE_NET_DL == type) && (QBM_NET_DL_DATA_LEN < pkt_len)) {
+ /* Packet len is more than gpd buffer memory*/
+ hif_trace_error(IPC_TR_SIT_TO_GPD_FAIL, __FUNCTION__, pkt_len, type, p_did, curr_si_idx);
+ *pp_gpd_out = NULL;
+ return KAL_FALSE;
+ }
+
+ if (1 != qbmt_alloc_q_no_tail(type,
+ 1,
+ (void**)pp_gpd_out,
+ (void**)pp_gpd_out)) {
+ hif_trace_error(IPC_TR_SI_UNITE_ALLOC_GPD_NG, type, p_did, curr_si_idx, pkt_len);
+ *pp_gpd_out = NULL;
+ return KAL_FALSE;
+ }
+
+ IPC_ASSERT(*pp_gpd_out);
+ ipc_utils_set_gpd_datalen(*pp_gpd_out, pkt_len, (void**)&p_gpd_data);
+ IPC_ASSERT(p_gpd_data);
+
+ dst_len_copied = 0;
+ end_of_seg_list = KAL_FALSE;
+ for (curr_si_idx = pkt_start_idx; curr_si_idx < UPCM_DID_MAX_SIT_ENT_NUM && !end_of_seg_list; curr_si_idx++) {
+ upcm_did_si *p_curr_si = &sit[curr_si_idx];
+ end_of_seg_list = UPCM_DID_SI_GET_EOL(p_curr_si);
+
+ if (UPCM_DID_SI_GET_LEN(p_curr_si)) {
+ p_src_buf = ((kal_uint8*) UPCM_DID_SI_GET_DATAPTR(p_curr_si)) + UPCM_DID_SI_GET_OFFSET(p_curr_si);
+ QBM_CACHE_INVALID(p_src_buf, UPCM_DID_SI_GET_LEN(p_curr_si));
+ kal_mem_cpy(p_gpd_data + dst_len_copied, p_src_buf, UPCM_DID_SI_GET_LEN(p_curr_si));
+ dst_len_copied += UPCM_DID_SI_GET_LEN(p_curr_si);
+ }
+ }
+
+ QBM_CACHE_FLUSH(p_gpd_data, dst_len_copied);
+ return KAL_TRUE;
+}
+
+kal_uint16 ipc_utils_calc_tcp_checksum(kal_bool is_ipv4,
+ kal_uint8 *src_addr,
+ kal_uint8 *dst_addr,
+ kal_uint8 *tcp_header,
+ kal_uint32 tcp_len)
+{
+ kal_uint32 sum32 = 0;
+ kal_uint32 length = 0;
+ kal_uint16 sum16 = 0;
+
+ /* It's designed for length < 2^16. */
+ IPC_ASSERT(tcp_len <= (kal_uint32)(is_ipv4 ? 65507 : 65487));
+
+ /* Pseudo-header. */
+ sum32 = IPC_H2N_2B(tcp_len); /* TCP length, assue it's less than 2^16. */
+ sum32 += IPC_H2N_2B(IPC_HDR_PROT_TCP); /* Next Header */
+ length = ((is_ipv4) ? IPC_HDR_V4_ADDR_SIZE : IPC_HDR_V6_ADDR_SIZE);
+ sum32 += ipc_utils_calc_checksum16(src_addr, length);
+ sum32 += ipc_utils_calc_checksum16(dst_addr, length);
+
+ /* TCP header and data. */
+ sum32 += ipc_utils_calc_checksum16(tcp_header, tcp_len);
+
+ sum32 = (sum32 & 0xffff) + (sum32 >> 16); /* add high word and low word. */
+ sum16 = (kal_uint16)((sum32 & 0xffff) + (sum32 >> 16)); /* add carry */
+ sum16 = ~sum16;
+
+ return IPC_H2N_2B(sum16);
+}
+
+kal_uint16 ipc_utils_calc_udp_checksum(kal_bool is_ipv4,
+ kal_uint8 *src_addr,
+ kal_uint8 *dst_addr,
+ kal_uint8 *udp_header,
+ kal_uint32 udp_len)
+{
+ kal_uint32 sum32 = 0;
+ kal_uint32 length = 0;
+ kal_uint16 sum16 = 0;
+
+ /* It's designed for length < 2^16. */
+ IPC_ASSERT(udp_len <= (kal_uint32)(is_ipv4 ? 65507 : 65487));
+
+ /* Pseudo-header. */
+ sum32 = IPC_H2N_2B(udp_len); /* UDP length, assue it's less than 2^16. */
+ sum32 += IPC_H2N_2B(IPC_HDR_PROT_UDP); /* Next Header */
+ length = ((is_ipv4) ? IPC_HDR_V4_ADDR_SIZE : IPC_HDR_V6_ADDR_SIZE);
+ sum32 += ipc_utils_calc_checksum16(src_addr, length);
+ sum32 += ipc_utils_calc_checksum16(dst_addr, length);
+
+ /* UDP header and data. */
+ sum32 += ipc_utils_calc_checksum16(udp_header, udp_len);
+
+ sum32 = (sum32 & 0xffff) + (sum32 >> 16); /* add high word and low word. */
+ sum16 = (kal_uint16)((sum32 & 0xffff) + (sum32 >> 16)); /* add carry */
+ sum16 = ~sum16;
+
+ /*
+ * 2015/07/07 Peter.Hsu
+ * IPv6 UDP with zero-checksum is invalid. (RFC 6935)
+ * If the checksum computation is 0, it should be replaced by 0xFFFF.
+ */
+ if (0 == sum16) {
+ sum16 = ~sum16;
+ }
+ return IPC_H2N_2B(sum16);
+}
+
+kal_uint16 ipc_utils_calc_ipv4_checksum(kal_uint8 *ip_header)
+{
+ kal_uint16 sum16 = 0;
+
+ sum16 = ipc_utils_calc_checksum16(ip_header, IPC_HDR_V4_GET_IHL(ip_header));
+ sum16 = ~sum16;
+ return IPC_H2N_2B(sum16);
+}
+
+kal_uint16 ipc_utils_calc_icmp_checksum(kal_uint8 *ip_header, kal_uint32 length)
+{
+ kal_uint16 sum16 = 0;
+
+ sum16 = ipc_utils_calc_checksum16(ip_header, length);
+ sum16 = ~sum16;
+ return IPC_H2N_2B(sum16);
+}
+
diff --git a/mcu/middleware/hif/ipcore/src/pfm_garbage_filter.c b/mcu/middleware/hif/ipcore/src/pfm_garbage_filter.c
new file mode 100644
index 0000000..5885d78
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/pfm_garbage_filter.c
@@ -0,0 +1,1556 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2014
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * pfm_garbage_filter.c
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * Packet Filter Manager customed functions for feature: Garbage Filter.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+#include "ipc_api.h"
+#include "ipc_enums.h"
+#include "ipc_filter_priority.h"
+#include "ipc_debug.h"
+#include "ipc_filter.h"
+#include "ipc_packet_parser.h"
+
+#include "pfm_defs.h"
+#include "pfm_enums.h"
+#include "pfm_object.h"
+
+#define PFM_GARBAGE_FILTER_MAX_FILTER 128
+#define PFM_INVALID_FILTER_ID -10
+#define PFM_STR_FILTER_NETIF_MAX_NUM 16
+#define PFM_STR_FILTER_MAGIC_CODE 0x1798
+#define PFM_UL_ICMP_PING_WHITELIST_LOW_PRIORITY 2
+#define PFM_UL_ICMP_PING_WHITELIST_HIGH_PRIORITY 1
+/*------------------------------------------------------------------------------
+ * Private data structure.
+ *----------------------------------------------------------------------------*/
+typedef struct _pfm_garbage_filter_t {
+ kal_int32 filter_id;
+ kal_uint8 ip_type;
+ kal_uint8 protocol;
+ kal_uint16 dst_port;
+ kal_uint32 magic_code;
+} pfm_garbage_filter_t;
+
+typedef struct _pfmStrFilterNetifInfo {
+ kal_uint32 index;
+ kal_uint32 netif_id;
+ kal_uint8 filter_num;
+ struct _pfmStrFilterInfo *p_head_filter;
+} pfmStrFilterNetifInfo;
+
+typedef struct _pfmStrFilterInfo {
+/* Following elements should be aligned with pfm_str_filter_t*/
+ kal_int32 filter_id; /* user defined index */
+ kal_uint32 netif_id;
+ kal_uint16 filter_len;
+ kal_uint16 mask_len;
+ kal_uint8 filter_str[PFM_STR_FILTER_MAX_SIZE];
+ kal_uint8 mask_str[PFM_STR_FILTER_MAX_SIZE];
+ kal_uint32 magic_code;
+/* end */
+ struct _pfmStrFilterInfo *p_next_filter;
+ struct _pfmStrFilterNetifInfo *p_netif;
+} pfmStrFilterInfo;
+
+/*------------------------------------------------------------------------------
+ * Private variables.
+ *----------------------------------------------------------------------------*/
+static kal_int32 g_fin_ack_filter_id_v4 = PFM_INVALID_FILTER_ID;
+static kal_int32 g_fin_ack_filter_id_v6 = PFM_INVALID_FILTER_ID;
+static kal_int32 g_igmp_filter_id_v4 = PFM_INVALID_FILTER_ID;
+static kal_int32 g_igmp_filter_id_v6 = PFM_INVALID_FILTER_ID;
+static kal_int32 g_udp_filter_id_v4 = PFM_INVALID_FILTER_ID;
+static kal_int32 g_udp_filter_id_v6 = PFM_INVALID_FILTER_ID;
+static pfmStrFilterInfo g_pfm_str_filter_pool[PFM_STR_FILTER_MAX_NUM];
+static pfmStrFilterNetifInfo g_pfm_str_filter_netif_pool[PFM_STR_FILTER_NETIF_MAX_NUM];
+static kal_uint32 g_pfm_str_filter_pool_mask = 0;
+static kal_uint32 g_pfm_str_filter_num = 0;
+static kal_uint32 g_pfm_str_filter_netif_pool_mask = 0;
+static kal_uint32 g_pfm_str_filter_netif_num = 0;
+static kal_int32 g_pfm_str_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_icmpv4_echo_req_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_icmpv4_echo_reply_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_icmpv6_echo_req_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_icmpv6_echo_reply_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_ul_disable_all_packets_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_ul_icmpv4_echo_req_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_ul_icmpv4_echo_reply_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_ul_icmpv6_echo_req_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_ul_icmpv6_echo_reply_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_ul_icmpv6_rs_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+static kal_int32 g_ul_non_ping_filter_id = PFM_INVALID_FILTER_ID;
+static pfm_garbage_str_wake_type_pkt_f g_funcptr_mbim_wake_type_pkt_cbk = NULL;
+static void* g_priv_data = NULL;
+
+/*
+* API to register PFM callback function for MBIM WAKE REASON wake type pkt
+*/
+void pfm_reg_cbk_wake_type_pkt(pfm_garbage_str_wake_type_pkt_f pf_wake_type_pkt, void* priv_data)
+{
+ hif_trace_info(PFM_TR_REG_CBK_WAKE_TYPE_PKT, __FUNCTION__, pf_wake_type_pkt);
+ PFM_SPIN_LOCK(pfm_spinlock_g);
+ g_funcptr_mbim_wake_type_pkt_cbk = pf_wake_type_pkt;
+ g_priv_data = priv_data;
+ PFM_SPIN_UNLOCK(pfm_spinlock_g);
+}
+
+/*
+* API to De-register PFM callback function for MBIM WAKE REASON wake type pkt
+*/
+void pfm_dereg_cbk_wake_type_pkt()
+{
+ hif_trace_info(PFM_TR_DEREG_CBK_WAKE_TYPE_PKT, __FUNCTION__);
+ PFM_SPIN_LOCK(pfm_spinlock_g);
+ g_funcptr_mbim_wake_type_pkt_cbk = NULL;
+ g_priv_data = NULL;
+ PFM_SPIN_UNLOCK(pfm_spinlock_g);
+}
+
+/*------------------------------------------------------------------------------
+ * Private functions.
+ *----------------------------------------------------------------------------*/
+
+/*!
+ * Callback function with packet information to process the IP datagram filtered.
+ * Reply TCP RST packet to the sender of the garbage TCP SYN packet.
+ *
+ * @param info_p [IN] Related information of filtered out GPDs.
+ * @param context [IN] A context specified while registering the filter.
+ * @param filter_id [IN] Corresponding registered filter ID.
+ * @param head_gpd [IN] Pointer head of the GPD list for the IP datagram filtered.
+ * @param tail_gpd [IN] Pointer tail of the GPD list for the IP datagram filtered.
+ * @param length [IN] Bytes of buffers used in the GPD list.
+ */
+void pfm_ipc_dl_filter_with_info_cb(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_pkt_t ipc_pkt;
+ qbm_gpd *ul_gpd;
+ qbm_gpd *bd;
+ kal_uint8 *p_data;
+ kal_uint8 *p_packet = NULL;
+ kal_uint8 *src_addr;
+ kal_uint8 *dst_addr;
+ kal_uint8 *p_tcp_header;
+ kal_uint32 ip_header_len;
+ kal_bool is_ipv4;
+
+ if (!QBM_DES_GET_BDP(head_gpd)) {
+ p_packet = QBM_DES_GET_DATAPTR(head_gpd);
+ } else {
+ /* get 1st bd data ptr */
+ bd = QBM_DES_GET_DATAPTR(head_gpd);
+
+ /* Loop to trace 1st DL BD with data buffer */
+ while (bd && (QBM_DES_GET_DATALEN(bd) == 0)) {
+ bd = (QBM_DES_GET_EOL(bd)) ? (NULL) : ((qbm_gpd*) QBM_DES_GET_NEXT(bd));
+ }
+
+ /* No any BD have data */
+ if (NULL == bd) {
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_ZERO_LENGTH_GPD, head_gpd);
+ goto free_gpd;
+ }
+
+ p_packet = QBM_DES_GET_DATAPTR(bd);
+ }
+
+ if (IPC_HDR_IS_V4(p_packet)) {
+ is_ipv4 = KAL_TRUE;
+
+ if (IPC_HDR_PROT_TCP != IPC_HDR_V4_GET_PROTOCOL(p_packet)) {
+ /* Only For TCP packet */
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_NON_TCP_PACKET, head_gpd, IPC_HDR_V4_GET_PROTOCOL(p_packet));
+ goto free_gpd;
+ }
+
+ /* Send IPv4 TCP RST */
+ ip_header_len = (kal_uint32) IPC_HDR_V4_GET_IHL(p_packet);
+ p_tcp_header = p_packet + ip_header_len;
+
+ src_addr = IPC_HDR_V4_GET_DST_ADDR(p_packet);
+ dst_addr = IPC_HDR_V4_GET_SRC_ADDR(p_packet);
+ } else {
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_NON_TCP_PACKET, head_gpd, IPC_HDR_V4_GET_PROTOCOL(p_packet));
+ goto free_gpd;
+ }
+
+ /* Allocate a UL GPD */
+ ul_gpd = QBM_ALLOC_ONE(QBM_TYPE_NET_UL);
+ if (!ul_gpd) {
+ hif_trace_info(PFM_TR_GARBAGE_FILTER_REPLY_RST_FAIL, 0, IPC_HDR_TCP_GET_DST_PORT(p_tcp_header));
+ return;
+ }
+
+ bd = QBM_DES_GET_DATAPTR(ul_gpd);
+ p_data = QBM_DES_GET_DATAPTR(bd);
+
+ /* Fill IP/TCP header */
+ {
+ kal_uint16 sum16;
+ kal_uint32 tcp_header_len;
+ kal_uint32 total_len;
+ kal_uint8 *ip_header; // ip_header for output packet
+ kal_uint8 *tcp_header; // tcp_header for output packet
+
+ ip_header_len = IPC_HDR_V4_HEADER_SIZE;
+ tcp_header_len = IPC_HDR_TCP_HEADER_SIZE;
+ total_len = ip_header_len + tcp_header_len;
+
+ ip_header = p_data;
+ tcp_header = ip_header + ip_header_len;
+
+ /* Fill TCP header */
+ IPC_HDR_TCP_SET_SRC_PORT(tcp_header, IPC_HDR_TCP_GET_DST_PORT(p_tcp_header));
+ IPC_HDR_TCP_SET_DST_PORT(tcp_header, IPC_HDR_TCP_GET_SRC_PORT(p_tcp_header));
+ IPC_HDR_TCP_SET_SEQ_NUM(tcp_header, IPC_HDR_TCP_GET_ACK_NUM(p_tcp_header));
+ IPC_HDR_TCP_SET_ACK_NUM(tcp_header, IPC_HDR_TCP_GET_SEQ_NUM(p_tcp_header) + 1);
+ IPC_HDR_TCP_SET_OFFSET(tcp_header, IPC_HDR_TCP_HEADER_SIZE);
+ IPC_HDR_TCP_SET_RESERVED(tcp_header, 0);
+ IPC_HDR_TCP_SET_FLAGS(tcp_header, IPC_HDR_TCP_FLAG_RST | IPC_HDR_TCP_FLAG_ACK);
+ IPC_HDR_TCP_SET_WINDOW(tcp_header, 0);
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, 0);
+ IPC_HDR_TCP_SET_URGENT_PTR(tcp_header, 0);
+ sum16 = ipc_calc_tcp_checksum(is_ipv4, src_addr, dst_addr, tcp_header, tcp_header_len);
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, sum16);
+
+ IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN(ip_header);
+ IPC_HDR_V4_SET_DSCP(ip_header, IPC_HDR_V4_GET_DSCP(p_packet));
+ IPC_HDR_V4_SET_TOTAL_LENGTH(ip_header, total_len);
+ IPC_HDR_V4_SET_IDENTITY(ip_header, 0);
+ IPC_HDR_V4_SET_FLAGS(ip_header, 0);
+ IPC_HDR_V4_SET_FRAG_OFFSET(ip_header, 0);
+ IPC_HDR_V4_SET_TTL(ip_header, IPC_DEF_TTL);
+ IPC_HDR_V4_SET_PROTOCOL(ip_header, IPC_HDR_PROT_TCP);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, 0);
+ IPC_HDR_V4_SET_SRC_ADDR(ip_header, src_addr);
+ IPC_HDR_V4_SET_DST_ADDR(ip_header, dst_addr);
+ sum16 = ipc_calc_ipv4_checksum(ip_header);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, sum16);
+
+ QBM_CACHE_FLUSH(ip_header, total_len);
+
+ QBM_DES_SET_DATALEN(bd, total_len);
+ qbm_cal_set_checksum(bd);
+
+ QBM_DES_SET_DATALEN(ul_gpd, total_len);
+ qbm_cal_set_checksum(ul_gpd);
+ }
+
+ kal_mem_set(&ipc_pkt, 0, sizeof(ipc_pkt));
+ ipc_pkt.isGPD = KAL_TRUE;
+ ipc_pkt.head = ul_gpd;
+ ipc_pkt.tail = ul_gpd;
+ ipc_send_ul_pkt_multiple_ps(&ipc_pkt, NULL, info_p->ebi, info_p->proto_idx);
+
+ hif_trace_info(PFM_TR_GARBAGE_FILTER_REPLY_RST, 0, IPC_HDR_TCP_GET_DST_PORT(p_tcp_header));
+
+free_gpd :
+ if (p_packet) {
+ pfm_matched_packet_trace(info_p->ebi, p_packet, PFM_MATCHED_PACKET_DUMP_SIZE);
+ }
+ qbmt_dest_q(head_gpd, tail_gpd);
+}
+
+void pfm_garbage_filter_register_parser(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ kal_uint32 idx;
+ pfm_garbage_filter_t *raw_filters = (pfm_garbage_filter_t *) buf;
+ ipc_filter_rules_t rules;
+
+ for (idx = 0; idx < filter_cnt; idx++) {
+ kal_mem_set(&rules, 0, sizeof(rules));
+
+ if (PFM_FILTER_STRUCT_MAGIC_CODE != raw_filters[idx].magic_code) {
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_WRONG_MAGIC_CODE, __FUNCTION__, idx);
+ PFM_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ if ((IPC_IP_TYPE_IPV4 != raw_filters[idx].ip_type) || (IPC_HDR_PROT_TCP != raw_filters[idx].protocol)) {
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_INVALID_PARAMS, raw_filters[idx].ip_type, raw_filters[idx].protocol);
+ PFM_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ hif_trace_info(PFM_TR_GARBAGE_FILTER_REG_PARSER, raw_filters[idx].filter_id, raw_filters[idx].ip_type, raw_filters[idx].protocol, raw_filters[idx].dst_port);
+
+ rules.features = IPC_FILTER_FEATURE_BWM;
+ rules.priority = raw_filters[idx].filter_id + IPC_DL_FILTER_PRIORITY_PFM_GARBAGE_FILTER_BEGIN;
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_DST_PORT | IPC_FILTER_BY_TCP_FLAGS;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.protocol = IPC_HDR_PROT_TCP;
+ rules.dst_port = raw_filters[idx].dst_port;
+ rules.tcp_flags = IPC_HDR_TCP_FLAG_SYN;
+
+ if (PFM_GARBAGE_FILTER_MAX_FILTER < raw_filters[idx].filter_id) {
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_INVALID_FILTER_ID, __FUNCTION__);
+ PFM_ASSERT(KAL_FALSE);
+ } else {
+ pfm_register_filter_cbk(PFM_GARBAGE_FILTER_SET_ID, raw_filters[idx].filter_id, KAL_FALSE, &rules, NULL, NULL);
+ }
+ }
+
+ /* Register filter to trap all left TCP SYN packets. */
+ kal_mem_set(&rules, 0, sizeof(rules));
+ rules.priority = IPC_DL_FILTER_PRIORITY_PFM_GARBAGE_FILTER_END;
+ rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_TCP_FLAGS;
+ rules.ip_type = IPC_IP_TYPE_IPV4;
+ rules.protocol = IPC_HDR_PROT_TCP;
+ rules.tcp_flags = IPC_HDR_TCP_FLAG_SYN;
+ pfm_register_filter_with_info_cbk(PFM_GARBAGE_FILTER_SET_ID,
+ PFM_GARBAGE_FILTER_MAX_FILTER, KAL_FALSE, &rules, pfm_ipc_dl_filter_with_info_cb, NULL);
+}
+
+void pfm_garbage_filter_deregister_callback(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ kal_int32 *filters_buf = buf;
+ pfm_internal_filter_set_t *filter_set = NULL;
+ pfm_internal_filter_set_t *filter_set_list = pfm_get_filter_set_list(uplink);
+ kal_int32 idx;
+
+ filter_set = pfm_get_filter_set_by_id(filter_set_list, NUM_OF_PFM_FILTER_SET_ID, PFM_GARBAGE_FILTER_SET_ID);
+ if (filter_set) {
+ hif_trace_info(PFM_TR_DEREG_FILTERS_INFO, uplink, PFM_GARBAGE_FILTER_SET_ID, filter_cnt);
+ if (-1 == filter_cnt) {
+ /* Deregister all filters. */
+ for (idx = 0; idx < PFM_FILTER_SET_MAX_SIZE; idx++) {
+ if (-1 != filter_set->filters[idx]) {
+ pfm_deregister_filter((uplink == 1) ? KAL_TRUE : KAL_FALSE, filter_set, idx);
+ if (0 == filter_set->filter_cnt) {
+ pfm_delete_filter_set(filter_set);
+ break;
+ }
+ }
+ }
+ } else {
+ /* Deregister the specified filters. */
+ if (filter_cnt <= filter_set->filter_cnt) {
+ for (idx = 0; idx < filter_cnt; idx++) {
+ pfm_deregister_filter((uplink == 1) ? KAL_TRUE : KAL_FALSE, filter_set, filters_buf[idx]);
+ if (0 == filter_set->filter_cnt) {
+ PFM_ASSERT(idx == (filter_cnt - 1));
+ pfm_delete_filter_set(filter_set);
+ }
+ }
+ } else {
+ PFM_ASSERT(KAL_FALSE);
+ }
+ }
+ } else {
+ hif_trace_error(PFM_TR_DEREG_FILTERS_FILTER_SET_NOT_FOUND, uplink, PFM_GARBAGE_FILTER_SET_ID);
+ }
+
+ return;
+}
+
+void pfm_fin_ack_filter_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ ipc_pkt_t ipc_pkt;
+ qbm_gpd *ul_gpd;
+ qbm_gpd *bd;
+ kal_uint8 *p_data;
+ kal_uint8 *p_packet = NULL;
+ kal_uint8 *src_addr;
+ kal_uint8 *dst_addr;
+ kal_uint8 *p_tcp_header;
+ kal_uint32 ip_header_len;
+ kal_bool is_ipv4;
+
+ hif_data_trace(MD_TRC_PFM_DL_RECEIVED_FILTER_PACKET, head_gpd, tail_gpd);
+
+ if (!QBM_DES_GET_BDP(head_gpd)) {
+ p_packet = QBM_DES_GET_DATAPTR(head_gpd);
+ } else {
+ /* get 1st bd data ptr */
+ bd = QBM_DES_GET_DATAPTR(head_gpd);
+
+ /* Loop to trace 1st DL BD with data buffer */
+ while (bd && (QBM_DES_GET_DATALEN(bd) == 0)) {
+ bd = (QBM_DES_GET_EOL(bd)) ? (NULL) : ((qbm_gpd*) QBM_DES_GET_NEXT(bd));
+ }
+
+ /* No any BD have data */
+ if (NULL == bd) {
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_ZERO_LENGTH_GPD, head_gpd);
+ goto free_gpd;
+ }
+
+ p_packet = QBM_DES_GET_DATAPTR(bd);
+ }
+
+ if (IPC_HDR_IS_V4(p_packet)) {
+ is_ipv4 = KAL_TRUE;
+
+ if (IPC_HDR_PROT_TCP != IPC_HDR_V4_GET_PROTOCOL(p_packet)) {
+ /* Only For TCP packet */
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_NON_TCP_PACKET, head_gpd, IPC_HDR_V4_GET_PROTOCOL(p_packet));
+ goto free_gpd;
+ }
+
+ /* Send IPv4 TCP RST */
+ ip_header_len = (kal_uint32) IPC_HDR_V4_GET_IHL(p_packet);
+ p_tcp_header = p_packet + ip_header_len;
+
+ src_addr = IPC_HDR_V4_GET_DST_ADDR(p_packet);
+ dst_addr = IPC_HDR_V4_GET_SRC_ADDR(p_packet);
+ } else if (IPC_HDR_IS_V6(p_packet)) {
+ is_ipv4 = KAL_FALSE;
+
+ if (IPC_HDR_PROT_TCP != IPC_HDR_V6_GET_NH_TYPE(p_packet)) {
+ /* Only For TCP packet */
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_NON_TCP_PACKET, head_gpd, IPC_HDR_V6_GET_NH_TYPE(p_packet));
+ goto free_gpd;
+ }
+
+ /* Send IPv6 TCP RST */
+ p_tcp_header = p_packet + IPC_HDR_V6_HEADER_SIZE;
+
+ src_addr = IPC_HDR_V6_GET_DST_ADDR(p_packet);
+ dst_addr = IPC_HDR_V6_GET_SRC_ADDR(p_packet);
+ } else {
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_NON_TCP_PACKET, head_gpd, IPC_HDR_V4_GET_PROTOCOL(p_packet));
+ goto free_gpd;
+ }
+
+ /* Allocate a UL GPD */
+ ul_gpd = QBM_ALLOC_ONE(QBM_TYPE_NET_UL);
+ if (!ul_gpd) {
+ hif_trace_info(PFM_TR_GARBAGE_FILTER_REPLY_RST_FAIL, 0, IPC_HDR_TCP_GET_DST_PORT(p_tcp_header));
+ return;
+ }
+
+ bd = QBM_DES_GET_DATAPTR(ul_gpd);
+ p_data = QBM_DES_GET_DATAPTR(bd);
+
+ /* Fill IP/TCP header */
+ {
+ kal_uint16 sum16;
+ kal_uint32 tcp_header_len;
+ kal_uint32 total_len;
+ kal_uint8 *ip_header; // ip_header for output packet
+ kal_uint8 *tcp_header; // tcp_header for output packet
+
+ ip_header_len = is_ipv4 ? IPC_HDR_V4_HEADER_SIZE : IPC_HDR_V6_HEADER_SIZE;
+ tcp_header_len = IPC_HDR_TCP_HEADER_SIZE;
+ total_len = ip_header_len + tcp_header_len;
+ ip_header = p_data;
+ tcp_header = ip_header + ip_header_len;
+
+ /* Fill TCP header */
+ IPC_HDR_TCP_SET_SRC_PORT(tcp_header, IPC_HDR_TCP_GET_DST_PORT(p_tcp_header));
+ IPC_HDR_TCP_SET_DST_PORT(tcp_header, IPC_HDR_TCP_GET_SRC_PORT(p_tcp_header));
+ IPC_HDR_TCP_SET_SEQ_NUM(tcp_header, IPC_HDR_TCP_GET_ACK_NUM(p_tcp_header));
+ IPC_HDR_TCP_SET_ACK_NUM(tcp_header, IPC_HDR_TCP_GET_SEQ_NUM(p_tcp_header) + 1);
+ IPC_HDR_TCP_SET_OFFSET(tcp_header, IPC_HDR_TCP_HEADER_SIZE);
+ IPC_HDR_TCP_SET_RESERVED(tcp_header, 0);
+ IPC_HDR_TCP_SET_FLAGS(tcp_header, IPC_HDR_TCP_FLAG_RST | IPC_HDR_TCP_FLAG_ACK);
+ IPC_HDR_TCP_SET_WINDOW(tcp_header, 0);
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, 0);
+ IPC_HDR_TCP_SET_URGENT_PTR(tcp_header, 0);
+ sum16 = ipc_calc_tcp_checksum(is_ipv4, src_addr, dst_addr, tcp_header, tcp_header_len);
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, sum16);
+
+ if (is_ipv4) {
+ IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN(ip_header);
+ IPC_HDR_V4_SET_DSCP(ip_header, IPC_HDR_V4_GET_DSCP(p_packet));
+ IPC_HDR_V4_SET_TOTAL_LENGTH(ip_header, total_len);
+ IPC_HDR_V4_SET_IDENTITY(ip_header, 0);
+ IPC_HDR_V4_SET_FLAGS(ip_header, 0);
+ IPC_HDR_V4_SET_FRAG_OFFSET(ip_header, 0);
+ IPC_HDR_V4_SET_TTL(ip_header, IPC_DEF_TTL);
+ IPC_HDR_V4_SET_PROTOCOL(ip_header, IPC_HDR_PROT_TCP);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, 0);
+ IPC_HDR_V4_SET_SRC_ADDR(ip_header, src_addr);
+ IPC_HDR_V4_SET_DST_ADDR(ip_header, dst_addr);
+ sum16 = ipc_calc_ipv4_checksum(ip_header);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, sum16);
+ } else {
+ IPC_HDR_V6_RESET_VER_TC_FL(ip_header);
+ IPC_HDR_V6_SET_TC(ip_header, IPC_HDR_V6_GET_TC(p_packet));
+ IPC_HDR_V6_SET_FLOW_LABEL(ip_header, IPC_HDR_V6_GET_FLOW_LABEL(p_packet));
+ IPC_HDR_V6_SET_LENGTH(ip_header, total_len);
+ IPC_HDR_V6_SET_NH_TYPE(ip_header, IPC_HDR_PROT_TCP);
+ IPC_HDR_V6_SET_HOP_LIMIT(ip_header, IPC_HDR_V6_GET_HOP_LIMIT(p_packet));
+ IPC_HDR_V6_SET_SRC_ADDR(ip_header, src_addr);
+ IPC_HDR_V6_SET_DST_ADDR(ip_header, dst_addr);
+ }
+
+ QBM_CACHE_FLUSH(ip_header, total_len);
+ QBM_DES_SET_DATALEN(bd, total_len);
+ qbm_cal_set_checksum(bd);
+ QBM_DES_SET_DATALEN(ul_gpd, total_len);
+ qbm_cal_set_checksum(ul_gpd);
+ }
+
+ kal_mem_set(&ipc_pkt, 0, sizeof(ipc_pkt));
+ ipc_pkt.isGPD = KAL_TRUE;
+ ipc_pkt.head = ul_gpd;
+ ipc_pkt.tail = ul_gpd;
+ ipc_send_ul_pkt_multiple_ps(&ipc_pkt, NULL, info_p->ebi, info_p->proto_idx);
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_REPLY_RST, ul_gpd, IPC_HDR_TCP_GET_DST_PORT(p_tcp_header));
+
+free_gpd :
+ if (p_packet) {
+ pfm_matched_packet_trace(info_p->ebi, p_packet, PFM_MATCHED_PACKET_DUMP_SIZE);
+ }
+ qbmt_dest_q(head_gpd, tail_gpd);
+}
+
+void pfm_fin_ack_filter_register_parser(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_filter_rules_t v4_rules = {0};
+ ipc_filter_rules_t v6_rules = {0};
+
+ v4_rules.features = IPC_FILTER_FEATURE_PFM_DL;
+ v4_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_TCP_FLAGS;
+ v4_rules.protocol = IPC_HDR_PROT_TCP;
+ v4_rules.tcp_flags = IPC_HDR_TCP_FLAG_ACK | IPC_HDR_TCP_FLAG_FIN;
+ v4_rules.features |= IPC_FILTER_FEATURE_CLONE;
+ v4_rules.ip_type = IPC_IP_TYPE_IPV4;
+
+ v6_rules.features = IPC_FILTER_FEATURE_PFM_DL;
+ v6_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_TCP_FLAGS;
+ v6_rules.protocol = IPC_HDR_PROT_TCP;
+ v6_rules.tcp_flags = IPC_HDR_TCP_FLAG_ACK | IPC_HDR_TCP_FLAG_FIN;
+ v6_rules.features |= IPC_FILTER_FEATURE_CLONE;
+ v6_rules.ip_type = IPC_IP_TYPE_IPV6;
+
+ if (PFM_INVALID_FILTER_ID == g_fin_ack_filter_id_v4) {
+ g_fin_ack_filter_id_v4 = ipc_register_dl_filter_with_info_cbk(&v4_rules, pfm_fin_ack_filter_cbk, NULL);
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_REGISTER_FILTER_ID_V4, g_fin_ack_filter_id_v4);
+ if (0 > g_fin_ack_filter_id_v4) {
+ hif_trace_error(PFM_TR_FIN_ACK_FILTER_REGISTER_FILTER_FAILED);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_NO_ACTION_V4, g_fin_ack_filter_id_v4);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_fin_ack_filter_id_v6) {
+ g_fin_ack_filter_id_v6 = ipc_register_dl_filter_with_info_cbk(&v6_rules, pfm_fin_ack_filter_cbk, NULL);
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_REGISTER_FILTER_ID_V6, g_fin_ack_filter_id_v6);
+ if (0 > g_fin_ack_filter_id_v6) {
+ hif_trace_error(PFM_TR_FIN_ACK_FILTER_REGISTER_FILTER_FAILED);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_NO_ACTION_V6, g_fin_ack_filter_id_v6);
+ }
+
+ return;
+}
+
+void pfm_fin_ack_filter_deregister_callback(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_deregister_dl_filter(g_fin_ack_filter_id_v4);
+ ipc_deregister_dl_filter(g_fin_ack_filter_id_v6);
+ g_fin_ack_filter_id_v4 = PFM_INVALID_FILTER_ID;
+ g_fin_ack_filter_id_v6 = PFM_INVALID_FILTER_ID;
+
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_DEREGISTER_FILTER, g_fin_ack_filter_id_v4, g_fin_ack_filter_id_v6);
+ return;
+}
+
+void pfm_udp_igmp_filter_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ hif_trace_info(PFM_TR_UDP_IGMP_FILTER_DROP, __FUNCTION__, filter_id);
+ qbmt_dest_q(head_gpd, tail_gpd);
+
+ return;
+}
+
+void pfm_udp_igmp_filter_register_parser(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_filter_rules_t igmp_v4_rules = {0};
+ ipc_filter_rules_t igmp_v6_rules = {0};
+ ipc_filter_rules_t udp_v4_rules = {0};
+ ipc_filter_rules_t udp_v6_rules = {0};
+
+ igmp_v4_rules.features = IPC_FILTER_FEATURE_PFM_DL;
+ igmp_v4_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_NETIF_ID;
+ igmp_v4_rules.protocol = IPC_HDR_PROT_IGMP;
+ igmp_v4_rules.netif_id = IPC_NETIF_ID_ETH_BEGIN;
+ igmp_v4_rules.ip_type = IPC_IP_TYPE_IPV4;
+
+ igmp_v6_rules.features = IPC_FILTER_FEATURE_PFM_DL;
+ igmp_v6_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_NETIF_ID;
+ igmp_v6_rules.protocol = IPC_HDR_PROT_IGMP;
+ igmp_v6_rules.netif_id = IPC_NETIF_ID_ETH_BEGIN;
+ igmp_v6_rules.ip_type = IPC_IP_TYPE_IPV6;
+
+ if (PFM_INVALID_FILTER_ID == g_igmp_filter_id_v4) {
+ g_igmp_filter_id_v4 = ipc_register_ul_filter_with_info_cbk(&igmp_v4_rules, pfm_udp_igmp_filter_cbk, NULL);
+ hif_trace_info(PFM_TR_IGMP_FILTER_REGISTER_FILTER_ID_V4, __FUNCTION__, g_igmp_filter_id_v4);
+ if (0 > g_igmp_filter_id_v4) {
+ hif_trace_error(PFM_TR_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_FILTER_REGISTER_NO_ACTION, __FUNCTION__, g_igmp_filter_id_v4);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_igmp_filter_id_v6) {
+ g_igmp_filter_id_v6 = ipc_register_ul_filter_with_info_cbk(&igmp_v6_rules, pfm_udp_igmp_filter_cbk, NULL);
+ hif_trace_info(PFM_TR_IGMP_FILTER_REGISTER_FILTER_ID_V6, __FUNCTION__, g_igmp_filter_id_v6);
+ if (0 > g_igmp_filter_id_v6) {
+ hif_trace_error(PFM_TR_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_FILTER_REGISTER_NO_ACTION, __FUNCTION__, g_igmp_filter_id_v6);
+ }
+
+ udp_v4_rules.features = IPC_FILTER_FEATURE_PFM_DL;
+ udp_v4_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_NETIF_ID;
+ udp_v4_rules.protocol = IPC_HDR_PROT_UDP;
+ udp_v4_rules.netif_id = IPC_NETIF_ID_ETH_BEGIN;
+ udp_v4_rules.ip_type = IPC_IP_TYPE_IPV4;
+
+ udp_v6_rules.features = IPC_FILTER_FEATURE_PFM_DL;
+ udp_v6_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_NETIF_ID;
+ udp_v6_rules.protocol = IPC_HDR_PROT_UDP;
+ udp_v6_rules.netif_id = IPC_NETIF_ID_ETH_BEGIN;
+ udp_v6_rules.ip_type = IPC_IP_TYPE_IPV6;
+
+ if (PFM_INVALID_FILTER_ID == g_udp_filter_id_v4) {
+ g_udp_filter_id_v4 = ipc_register_ul_filter_with_info_cbk(&udp_v4_rules, pfm_udp_igmp_filter_cbk, NULL);
+ hif_trace_info(PFM_TR_UDP_FILTER_REGISTER_FILTER_ID_V4, __FUNCTION__, g_udp_filter_id_v4);
+ if (0 > g_udp_filter_id_v4) {
+ hif_trace_error(PFM_TR_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_FILTER_REGISTER_NO_ACTION, __FUNCTION__, g_udp_filter_id_v4);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_udp_filter_id_v6) {
+ g_udp_filter_id_v6 = ipc_register_ul_filter_with_info_cbk(&udp_v6_rules, pfm_udp_igmp_filter_cbk, NULL);
+ hif_trace_info(PFM_TR_UDP_FILTER_REGISTER_FILTER_ID_V4, __FUNCTION__, g_udp_filter_id_v6);
+ if (0 > g_udp_filter_id_v6) {
+ hif_trace_error(PFM_TR_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_FILTER_REGISTER_NO_ACTION, __FUNCTION__, g_udp_filter_id_v6);
+ }
+
+ return;
+}
+
+void pfm_udp_igmp_filter_deregister_callback(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_deregister_dl_filter(g_igmp_filter_id_v4);
+ ipc_deregister_dl_filter(g_igmp_filter_id_v6);
+ ipc_deregister_dl_filter(g_udp_filter_id_v4);
+ ipc_deregister_dl_filter(g_udp_filter_id_v6);
+ g_igmp_filter_id_v4 = PFM_INVALID_FILTER_ID;
+ g_igmp_filter_id_v6 = PFM_INVALID_FILTER_ID;
+ g_udp_filter_id_v4 = PFM_INVALID_FILTER_ID;
+ g_udp_filter_id_v6 = PFM_INVALID_FILTER_ID;
+
+ hif_trace_info(PFM_TR_DEGISTER_IGMP_FILTER, __FUNCTION__, g_igmp_filter_id_v4, g_igmp_filter_id_v6);
+ hif_trace_info(PFM_TR_DEGISTER_UDP_FILTER, __FUNCTION__, g_udp_filter_id_v4, g_udp_filter_id_v6);
+
+ return;
+}
+
+static kal_int32 pfm_str_find_empty_object_idx(kal_uint32 *mask, kal_uint32 max_num, kal_uint32 *total_num)
+{
+ kal_uint32 i;
+
+ for(i = 0; i < max_num; i ++)
+ {
+ if( 0 == ((1 << i) & (*mask))){
+ *mask = (*mask) | (1 << i);
+ (*total_num)++;
+ return i;
+ }
+ }
+ return -1;
+}
+
+static void pfm_str_release_object_by_idx(kal_uint32 index, kal_uint32 *mask, kal_uint32 *total_num)
+{
+ *mask = (*mask) & ~(1 << index);
+ (*total_num)--;
+ return;
+}
+
+static pfmStrFilterNetifInfo* pfm_str_find_netif_by_id(kal_uint32 netif_id)
+{
+ kal_uint32 i = 0;
+
+ for(i = 0; i < PFM_STR_FILTER_NETIF_MAX_NUM; i++){
+ if(g_pfm_str_filter_netif_pool_mask & (1 << i)){
+ if( netif_id == g_pfm_str_filter_netif_pool[i].netif_id){
+ return &g_pfm_str_filter_netif_pool[i];
+ }
+ }
+ }
+ return NULL;
+}
+
+static void pfm_str_netif_remove_filter_by_id(pfmStrFilterNetifInfo *p_netif_info, kal_uint32 filter_id)
+{
+ pfmStrFilterInfo *filter = NULL;
+ pfmStrFilterInfo *prev_filter = NULL;
+
+ if((NULL == p_netif_info) || (0 == p_netif_info->filter_num)){
+ return;
+ }
+
+ filter = p_netif_info->p_head_filter;
+
+ while(NULL != filter){
+ if(filter_id == filter->filter_id){
+ if(NULL == prev_filter){
+ /* 1st filter */
+ p_netif_info->p_head_filter = filter->p_next_filter;
+ }else{
+ /* Non 1st filter */
+ prev_filter->p_next_filter = filter->p_next_filter;
+ }
+ p_netif_info->filter_num--;
+ break;
+ }
+ prev_filter = filter;
+ filter = filter->p_next_filter;
+ }
+ return;
+}
+
+static void pfm_garbage_str_forward_matched_pkt(const kal_uint8 *packet_buff, kal_int32 packet_len, kal_int32 pfm_filter_id)
+{
+ pfm_garbage_str_wake_type_pkt_f pf_wake_type_pkt_cbk = NULL;
+ void* priv_data = NULL;
+
+ PFM_SPIN_LOCK(pfm_spinlock_g);
+ pf_wake_type_pkt_cbk = g_funcptr_mbim_wake_type_pkt_cbk;
+ priv_data = g_priv_data;
+ PFM_SPIN_UNLOCK(pfm_spinlock_g);
+
+ if (pf_wake_type_pkt_cbk) {
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_PKT_FW, __FUNCTION__, pf_wake_type_pkt_cbk, packet_buff, packet_len, pfm_filter_id);
+ pf_wake_type_pkt_cbk(packet_buff, packet_len, pfm_filter_id, priv_data);
+ } else {
+ /*no callback registered for wake type packet*/
+ hif_trace_error(PFM_TR_GARBAGE_STR_FILTER_CBK_NULL, __FUNCTION__);
+ }
+ return;
+}
+
+static void pfm_garbage_str_filter_with_info_cb(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ qbmt_dest_q(head_gpd, tail_gpd);
+ return;
+}
+
+kal_bool pfm_garbage_str_cust_filter_cbk(const kal_uint8 *p_pkt,
+ kal_int32 pkt_len,
+ kal_int32 filter_id,
+ void *p_args)
+{
+ kal_uint32 j = 0;
+ kal_uint32 netif_id = 0;
+ kal_bool is_matched = KAL_FALSE;
+ pfmStrFilterInfo *p_filter_info = NULL;
+ pfmStrFilterNetifInfo *p_netif_info = NULL;
+ ipc_filter_info_t *p_ipc_info = NULL;
+ kal_uint8 *p_in_pkt = NULL;
+ upcm_did *p_did = NULL;
+ upcm_did_si *p_si = NULL;
+ kal_uint8 *p_tmp_buf = NULL;
+ kal_bool result = KAL_FALSE;
+
+ p_ipc_info = (ipc_filter_info_t *)p_args;
+ netif_id = p_ipc_info->netif_id;
+ p_netif_info = pfm_str_find_netif_by_id(netif_id);
+
+ /* if packet is not continueous, merge it */
+ if(IPC_FI_DESC_TYPE_DID == p_ipc_info->src_desc_type){
+ p_did = p_ipc_info->src_desc_ptr;
+ p_si = UPCM_DID_GET_SIT_ENTRY_PTR(p_did, p_ipc_info->src_desc_indx);
+ p_tmp_buf = get_ctrl_buffer(pkt_len);
+ if(NULL == p_tmp_buf){
+ goto _return;
+ }
+ result = ipc_get_continuous_content_did(p_si->p_data, UPCM_DID_SI_GET_OFFSET(p_si), p_did, p_ipc_info->src_desc_indx, pkt_len, &p_in_pkt, p_tmp_buf);
+ if(KAL_FALSE == result){
+ goto _return;
+ }
+ }
+
+ if(NULL != p_netif_info){
+ p_filter_info = p_netif_info->p_head_filter;
+ while ((NULL != p_filter_info) && (KAL_FALSE == is_matched)) {
+ if (pkt_len >= p_filter_info->filter_len) {
+ for (j = 0 ; j < p_filter_info->filter_len; j++) {
+ if (0 == p_filter_info->mask_str[j]) {
+ continue;
+ }
+ if(NULL != p_in_pkt){
+ if ((p_filter_info->mask_str[j] & p_in_pkt[j]) !=
+ (p_filter_info->mask_str[j] & p_filter_info->filter_str[j])) {
+ is_matched = KAL_FALSE;
+ break;
+ }
+ }else{
+ if ((p_filter_info->mask_str[j] & p_pkt[j]) !=
+ (p_filter_info->mask_str[j] & p_filter_info->filter_str[j])) {
+ is_matched = KAL_FALSE;
+ break;
+ }
+ }
+ is_matched = KAL_TRUE;
+ pfm_garbage_str_forward_matched_pkt(p_in_pkt ? p_in_pkt : p_pkt, pkt_len, p_filter_info->filter_id);
+ }
+ }
+ p_filter_info = p_filter_info->p_next_filter;
+ }
+ }
+
+_return:
+ if(NULL != p_tmp_buf){
+ free_ctrl_buffer(p_tmp_buf);
+ }
+
+ return !is_matched;
+}
+
+void pfm_garbage_str_filter_register_parser(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ kal_uint8 i = 0;
+ kal_uint32 index = 0;
+ pfm_str_filter_t *p_single_filter = (pfm_str_filter_t*)buf;
+ pfmStrFilterInfo *p_filter_info = NULL;
+ pfmStrFilterNetifInfo *p_netif = NULL;
+ ipc_filter_rules_t wildcard_rule = {0};
+ ipc_filter_ntfy_ctxt_t ntfy_context = {0};
+ pfm_internal_filter_set_t *p_filter_set = NULL;
+ pfm_internal_filter_set_t *p_filter_set_list = pfm_get_filter_set_list(uplink);
+
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_CMD_PARSER, __FUNCTION__, KAL_TRUE, buf, filter_cnt, uplink);
+ PFM_ASSERT(NULL != buf);
+ PFM_ASSERT(KAL_FALSE == uplink);
+
+ p_filter_set = pfm_get_filter_set_by_id(p_filter_set_list, NUM_OF_PFM_FILTER_SET_ID, PFM_GARBAGE_STR_FILTER_SET_ID);
+
+ PFM_ASSERT(NULL != p_filter_set);
+
+ /* Store string filter */
+ for(i = 0; i < filter_cnt; i++){
+ if(PFM_STR_FILTER_MAGIC_CODE != p_single_filter->magic_code) {
+ hif_trace_info(PFM_TR_GARBAGE_FILTER_WRONG_MAGIC_CODE, __FUNCTION__, i);
+ PFM_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ if (PFM_GARBAGE_FILTER_MAX_FILTER < p_single_filter->filter_id) {
+ hif_trace_error(PFM_TR_GARBAGE_FILTER_INVALID_FILTER_ID, __FUNCTION__);
+ PFM_ASSERT(KAL_FALSE);
+ }
+
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_REG_PARSER, __FUNCTION__, p_single_filter->filter_id, p_single_filter->netif_id, p_single_filter->filter_len, p_single_filter->mask_len);
+
+ /* Check if filter_id is already used */
+ if(-1 != p_filter_set->filters[p_single_filter->filter_id]){
+ /* remove previous first */
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_FLT_ID_EXIST, __FUNCTION__, p_single_filter->filter_id);
+ index = p_filter_set->filters[p_single_filter->filter_id];
+ p_filter_info = &g_pfm_str_filter_pool[index];
+ p_netif = pfm_str_find_netif_by_id(p_filter_info->netif_id);
+ PFM_ASSERT(NULL != p_netif);
+
+ pfm_str_netif_remove_filter_by_id(p_netif, p_single_filter->filter_id);
+ pfm_str_release_object_by_idx(index, &g_pfm_str_filter_pool_mask, &g_pfm_str_filter_num);
+ p_filter_set->filters[p_single_filter->filter_id] = -1;
+ p_filter_set->filter_cnt--;
+
+ if(0 == p_netif->filter_num){
+ pfm_str_release_object_by_idx(p_netif->index, &g_pfm_str_filter_netif_pool_mask, &g_pfm_str_filter_netif_num);
+ }
+ }
+
+ p_netif = pfm_str_find_netif_by_id(p_single_filter->netif_id);
+ if(NULL == p_netif)
+ {
+ /* Allocate new one */
+ index = pfm_str_find_empty_object_idx(&g_pfm_str_filter_netif_pool_mask, PFM_STR_FILTER_NETIF_MAX_NUM, &g_pfm_str_filter_netif_num);
+ if(-1 == index)
+ {
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_NETIF_ALLOC_NG, __FUNCTION__, g_pfm_str_filter_netif_pool_mask, g_pfm_str_filter_netif_num, p_single_filter->netif_id);
+ PFM_ASSERT(KAL_FALSE);
+ }
+ p_netif = &g_pfm_str_filter_netif_pool[index];
+ kal_mem_set(p_netif, 0, sizeof(pfmStrFilterNetifInfo));
+ p_netif->netif_id = p_single_filter->netif_id;
+ p_netif->index = index;
+ }
+
+ index = pfm_str_find_empty_object_idx(&g_pfm_str_filter_pool_mask, PFM_STR_FILTER_MAX_NUM, &g_pfm_str_filter_num);
+ if(-1 == index){
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_ALLOC_NG, __FUNCTION__, g_pfm_str_filter_pool_mask, g_pfm_str_filter_num, p_single_filter->filter_id);
+ PFM_ASSERT(KAL_FALSE);
+ return;
+ }
+ p_filter_info = &g_pfm_str_filter_pool[index];
+ kal_mem_set(p_filter_info, 0, sizeof(pfmStrFilterInfo));
+
+ kal_mem_cpy(p_filter_info, p_single_filter, sizeof(pfm_str_filter_t));
+ p_filter_info->p_netif = p_netif;
+ p_filter_info->p_next_filter = NULL;
+
+ if(NULL == p_netif->p_head_filter){
+ p_netif->p_head_filter = p_filter_info;
+ }else{
+ p_filter_info->p_next_filter = p_netif->p_head_filter;
+ p_netif->p_head_filter = p_filter_info;
+ }
+ p_netif->filter_num++;
+
+ p_filter_set->filter_cnt++;
+ p_filter_set->filters[p_single_filter->filter_id] = index;
+ p_single_filter++;
+ }
+ if(PFM_INVALID_FILTER_ID == g_pfm_str_filter_id){
+ /* Switch IPCORE DL mode to SW mode*/
+ ipc_filter_switch_dl_mode(IPC_SW_DL_MODE_STR);
+
+ /* Register filter to IPCORE */
+ wildcard_rule.features = IPC_FILTER_FEATURE_PFM_DL | IPC_FILTER_FEATURE_CUST_FILTER_W_INFO | IPC_FILTER_FEATURE_WC;
+ wildcard_rule.cust_cbk_func = pfm_garbage_str_cust_filter_cbk;
+ wildcard_rule.priority = IPC_DL_FILTER_PRIORITY_PFM_GARBAGE_FILTER_END;
+ ntfy_context.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ ntfy_context.ntfy_mod.with_info_cbk_func = pfm_garbage_str_filter_with_info_cb;
+
+ g_pfm_str_filter_id = ipc_reg_filter(DL_DIRECT, &wildcard_rule, &ntfy_context);
+
+ hif_trace_error(PFM_TR_GARBAGE_STR_FILTER_IPC_FILTER_ID, __FUNCTION__, g_pfm_str_filter_id);
+
+ PFM_ASSERT(-1 != g_pfm_str_filter_id);
+ }
+
+ return;
+}
+
+void pfm_garbage_str_filter_deregister_callback(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ kal_uint32 i = 0;
+ kal_uint32 netif_id = 0;
+ kal_int32 *filter_ids = (kal_int32*) buf;
+ pfm_internal_filter_set_t *p_filter_set = NULL;
+ pfm_internal_filter_set_t *p_filter_set_list = pfm_get_filter_set_list(uplink);
+ pfmStrFilterInfo *p_filter_info = NULL;
+ kal_uint32 filter_idx_internal = 0;
+ pfmStrFilterNetifInfo* p_netif_info = NULL;
+
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_CMD_PARSER, __FUNCTION__, KAL_FALSE, buf, filter_cnt, uplink);
+
+ p_filter_set = pfm_get_filter_set_by_id(p_filter_set_list, NUM_OF_PFM_FILTER_SET_ID, PFM_GARBAGE_STR_FILTER_SET_ID);
+
+ PFM_ASSERT(NULL != p_filter_set);
+
+ if(-1 == filter_cnt){
+ /* Deregister all filters */
+ for(i = 0; i < PFM_STR_FILTER_MAX_NUM; i++){
+ if(g_pfm_str_filter_pool_mask & (1 << i)){
+ pfm_str_release_object_by_idx(i, &g_pfm_str_filter_pool_mask, &g_pfm_str_filter_num);
+ p_filter_info = &g_pfm_str_filter_pool[i];
+ p_filter_set->filters[p_filter_info->filter_id] = -1;
+ p_filter_set->filter_cnt--;
+ }
+ }
+ for(i = 0; i < PFM_STR_FILTER_NETIF_MAX_NUM; i++){
+ if(g_pfm_str_filter_netif_pool_mask & (1 << i)){
+ pfm_str_release_object_by_idx(i, &g_pfm_str_filter_netif_pool_mask, &g_pfm_str_filter_netif_num);
+ }
+ }
+ PFM_ASSERT(!g_pfm_str_filter_num && !g_pfm_str_filter_netif_num && !p_filter_set->filter_cnt);
+ }else{
+ /* Deregister specific filters */
+ PFM_ASSERT(NULL != buf);
+ if(filter_cnt <= g_pfm_str_filter_num){
+ for(i = 0; i < filter_cnt; i++){
+ if((filter_ids[i] < 0) || (filter_ids[i] > PFM_FILTER_SET_MAX_SIZE)){
+ PFM_ASSERT(KAL_FALSE);
+ return;
+ }
+ filter_idx_internal = (kal_uint32)p_filter_set->filters[filter_ids[i]];
+ PFM_ASSERT(g_pfm_str_filter_pool_mask & (1 << filter_idx_internal));
+ p_filter_info = &g_pfm_str_filter_pool[filter_idx_internal];
+ netif_id = p_filter_info->netif_id;
+ p_netif_info = pfm_str_find_netif_by_id(netif_id);
+ PFM_ASSERT(NULL != p_netif_info);
+
+ pfm_str_netif_remove_filter_by_id(p_netif_info, filter_ids[i]);
+ pfm_str_release_object_by_idx(filter_idx_internal, &g_pfm_str_filter_pool_mask, &g_pfm_str_filter_num);
+ p_filter_set->filters[filter_ids[i]] = -1;
+ p_filter_set->filter_cnt--;
+
+ if(0 == p_netif_info->filter_num){
+ pfm_str_release_object_by_idx(p_netif_info->index, &g_pfm_str_filter_netif_pool_mask, &g_pfm_str_filter_netif_num);
+ }
+ }
+ }else{
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_DEREG_CNT_NG, __FUNCTION__);
+ PFM_ASSERT(KAL_FALSE);
+ }
+ }
+
+ if(0 == p_filter_set->filter_cnt){
+ hif_trace_info(PFM_TR_GARBAGE_STR_FILTER_DEREG_DEL, __FUNCTION__, g_pfm_str_filter_id);
+ pfm_delete_filter_set(p_filter_set);
+
+ if(PFM_INVALID_FILTER_ID != g_pfm_str_filter_id){
+ ipc_dereg_filter(g_pfm_str_filter_id);
+ g_pfm_str_filter_id = PFM_INVALID_FILTER_ID;
+ }
+ /* Switch IPCORE DL mode to HW mode*/
+ ipc_filter_switch_dl_mode(IPC_HW_DL_MODE_STR);
+ }
+
+ return;
+}
+
+void pfm_icmp_ping_filter_with_info_cb(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ qbmt_dest_q(head_gpd, tail_gpd);
+ return;
+}
+
+kal_bool pfm_icmp_ping_filter_cust_cbk(const kal_uint8 *p_pkt,
+ kal_int32 pkt_len,
+ kal_int32 filter_id,
+ void *p_args)
+{
+ /* Do nothing */
+ return KAL_FALSE;
+}
+
+void pfm_icmp_ping_filter_register_parser(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_filter_rules_t icmpv4_req_rules = {0};
+ ipc_filter_rules_t icmpv4_reply_rules = {0};
+ ipc_filter_rules_t icmpv6_req_rules = {0};
+ ipc_filter_rules_t icmpv6_reply_rules = {0};
+ ipc_filter_ntfy_ctxt_t ntfy_context = {0};
+
+ ntfy_context.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ ntfy_context.ntfy_mod.with_info_cbk_func = pfm_icmp_ping_filter_with_info_cb;
+
+ if (PFM_INVALID_FILTER_ID == g_icmpv4_echo_req_filter_id) {
+ /* Register ICMPV4 Echo Request filter to IPCORE */
+ icmpv4_req_rules.features = IPC_FILTER_FEATURE_PFM_DL | IPC_FILTER_FEATURE_CUST_FILTER_W_INFO;
+ icmpv4_req_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV4_TYPE;
+ icmpv4_req_rules.protocol = IPC_HDR_PROT_ICMP;
+ icmpv4_req_rules.ip_type = IPC_IP_TYPE_IPV4;
+ icmpv4_req_rules.icmpv4_type = IPC_HDR_ICMP_TYPE_ECHO_REQUEST;
+ icmpv4_req_rules.cust_cbk_func = pfm_icmp_ping_filter_cust_cbk;
+
+ g_icmpv4_echo_req_filter_id = ipc_reg_filter(DL_DIRECT, &icmpv4_req_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV4_PING_REQ_FILTER_IPC_FILTER_ID, __FUNCTION__, g_icmpv4_echo_req_filter_id);
+ if (0 > g_icmpv4_echo_req_filter_id) {
+ hif_trace_error(PFM_TR_ICMP_PING_FILTER_REGISTER_FAILED, __FUNCTION__, __LINE__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMP_PING_FILTER_NO_ACTION, __FUNCTION__, __LINE__, g_icmpv4_echo_req_filter_id);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_icmpv4_echo_reply_filter_id) {
+ /* Register ICMPV4 Echo Reply filter to IPCORE */
+ icmpv4_reply_rules.features = IPC_FILTER_FEATURE_PFM_DL | IPC_FILTER_FEATURE_CUST_FILTER_W_INFO;
+ icmpv4_reply_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV4_TYPE;
+ icmpv4_reply_rules.protocol = IPC_HDR_PROT_ICMP;
+ icmpv4_reply_rules.ip_type = IPC_IP_TYPE_IPV4;
+ icmpv4_reply_rules.icmpv4_type = IPC_HDR_ICMP_TYPE_ECHO_REPLY;
+ icmpv4_reply_rules.cust_cbk_func = pfm_icmp_ping_filter_cust_cbk;
+
+ g_icmpv4_echo_reply_filter_id = ipc_reg_filter(DL_DIRECT, &icmpv4_reply_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV4_PING_REPLY_FILTER_IPC_FILTER_ID, __FUNCTION__, g_icmpv4_echo_reply_filter_id);
+ if (0 > g_icmpv4_echo_reply_filter_id) {
+ hif_trace_error(PFM_TR_ICMP_PING_FILTER_REGISTER_FAILED, __FUNCTION__, __LINE__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMP_PING_FILTER_NO_ACTION, __FUNCTION__, __LINE__, g_icmpv4_echo_reply_filter_id);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_icmpv6_echo_req_filter_id) {
+ /* Register ICMPV6 Echo Request filter to IPCORE */
+ icmpv6_req_rules.features = IPC_FILTER_FEATURE_PFM_DL | IPC_FILTER_FEATURE_CUST_FILTER_W_INFO;
+ icmpv6_req_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV6_TYPE;
+ icmpv6_req_rules.protocol = IPC_HDR_PROT_ICMPV6;
+ icmpv6_req_rules.ip_type = IPC_IP_TYPE_IPV6;
+ icmpv6_req_rules.icmpv6_type = IPC_HDR_ICMPV6_TYPE_ECHO_REQUEST;
+ icmpv6_req_rules.cust_cbk_func = pfm_icmp_ping_filter_cust_cbk;
+
+ g_icmpv6_echo_req_filter_id = ipc_reg_filter(DL_DIRECT, &icmpv6_req_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV6_PING_REQ_FILTER_IPC_FILTER_ID, __FUNCTION__, g_icmpv6_echo_req_filter_id);
+ if (0 > g_icmpv6_echo_req_filter_id) {
+ hif_trace_error(PFM_TR_ICMP_PING_FILTER_REGISTER_FAILED, __FUNCTION__, __LINE__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMP_PING_FILTER_NO_ACTION, __FUNCTION__, __LINE__, g_icmpv6_echo_req_filter_id);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_icmpv6_echo_reply_filter_id) {
+ /* Register ICMPV6 Echo Reply filter to IPCORE */
+ icmpv6_reply_rules.features = IPC_FILTER_FEATURE_PFM_DL | IPC_FILTER_FEATURE_CUST_FILTER_W_INFO;
+ icmpv6_reply_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV6_TYPE;
+ icmpv6_reply_rules.protocol = IPC_HDR_PROT_ICMPV6;
+ icmpv6_reply_rules.ip_type = IPC_IP_TYPE_IPV6;
+ icmpv6_reply_rules.icmpv6_type = IPC_HDR_ICMPV6_TYPE_ECHO_REPLY;
+ icmpv6_reply_rules.cust_cbk_func = pfm_icmp_ping_filter_cust_cbk;
+
+ g_icmpv6_echo_reply_filter_id = ipc_reg_filter(DL_DIRECT, &icmpv6_reply_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV6_PING_REPLY_FILTER_IPC_FILTER_ID, __FUNCTION__, g_icmpv6_echo_reply_filter_id);
+ if (0 > g_icmpv6_echo_reply_filter_id) {
+ hif_trace_error(PFM_TR_ICMP_PING_FILTER_REGISTER_FAILED, __FUNCTION__, __LINE__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMP_PING_FILTER_NO_ACTION, __FUNCTION__, __LINE__, g_icmpv6_echo_reply_filter_id);
+ }
+
+ return;
+}
+
+void pfm_icmp_ping_filter_deregister_callback(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_deregister_dl_filter(g_icmpv4_echo_req_filter_id);
+ ipc_deregister_dl_filter(g_icmpv4_echo_reply_filter_id);
+ ipc_deregister_dl_filter(g_icmpv6_echo_req_filter_id);
+ ipc_deregister_dl_filter(g_icmpv6_echo_reply_filter_id);
+ g_icmpv4_echo_req_filter_id = PFM_INVALID_FILTER_ID;
+ g_icmpv4_echo_reply_filter_id = PFM_INVALID_FILTER_ID;
+ g_icmpv6_echo_req_filter_id = PFM_INVALID_FILTER_ID;
+ g_icmpv6_echo_reply_filter_id = PFM_INVALID_FILTER_ID;
+
+ hif_trace_info(PFM_TR_DEGISTER_ICMPV4_PING_FILTER, __FUNCTION__, g_icmpv4_echo_req_filter_id, g_icmpv4_echo_reply_filter_id);
+ hif_trace_info(PFM_TR_DEGISTER_ICMPV6_PING_FILTER, __FUNCTION__, g_icmpv6_echo_req_filter_id, g_icmpv6_echo_reply_filter_id);
+
+ return;
+}
+
+void pfm_ul_disable_all_packets_filter_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ hif_trace_info(PFM_TR_DISABLE_ALL_PACKETS_FILTER_DROP, __FUNCTION__, filter_id);
+ qbmt_dest_q(head_gpd, tail_gpd);
+
+ return;
+}
+
+void pfm_ul_disable_all_packets_filter_register_parser(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_filter_rules_t wc_rules = {0};
+
+ wc_rules.features = IPC_FILTER_FEATURE_WC;
+ wc_rules.priority = PFM_UL_ICMP_PING_WHITELIST_HIGH_PRIORITY;
+
+ if (PFM_INVALID_FILTER_ID == g_ul_disable_all_packets_filter_id) {
+ g_ul_disable_all_packets_filter_id = ipc_register_ul_filter_with_info_cbk(&wc_rules, pfm_ul_disable_all_packets_filter_cbk, NULL);
+ hif_trace_info(PFM_TR_DISABLE_ALL_PACKETS_FILTER_REGISTER_FILTER_ID, __FUNCTION__, g_ul_disable_all_packets_filter_id);
+ if (0 > g_ul_disable_all_packets_filter_id) {
+ hif_trace_error(PFM_TR_DISABLE_ALL_PACKETS_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_DISABLE_ALL_PACKETS_FILTER_NO_ACTION, __FUNCTION__, g_ul_disable_all_packets_filter_id);
+ }
+ return;
+}
+
+void pfm_ul_disable_all_packets_filter_deregister_callback(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_deregister_ul_filter(g_ul_disable_all_packets_filter_id);
+ g_ul_disable_all_packets_filter_id = PFM_INVALID_FILTER_ID;
+
+ hif_trace_info(PFM_TR_DEREG_DISABLE_ALL_PACKETS_FILTER, __FUNCTION__, g_ul_disable_all_packets_filter_id);
+
+ return;
+}
+
+
+kal_bool pfm_ul_icmp_ping_whitelist_filter_cust_cbk(const kal_uint8 *p_pkt,
+ kal_int32 pkt_len,
+ kal_int32 filter_id,
+ void *p_args)
+{
+ /* Do nothing */
+ return KAL_FALSE;
+}
+
+void pfm_ul_icmp_ping_whitelist_filter_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+ hif_trace_info(PFM_TR_ICMP_PING_WHITELIST_FILTER_DROP, __FUNCTION__, filter_id);
+ qbmt_dest_q(head_gpd, tail_gpd);
+
+ return;
+}
+
+void pfm_ul_icmp_ping_whitelist_filter_register_parser(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_filter_rules_t icmpv4_req_rules = {0};
+ ipc_filter_rules_t icmpv4_reply_rules = {0};
+ ipc_filter_rules_t icmpv6_req_rules = {0};
+ ipc_filter_rules_t icmpv6_reply_rules = {0};
+ ipc_filter_rules_t wc_rules = {0};
+ ipc_filter_ntfy_ctxt_t ntfy_context = {0};
+
+ ntfy_context.ntfy_type = IPC_FILTER_NTFY_CBK_FUNC_WITH_FILTER_INFO;
+ ntfy_context.ntfy_mod.with_info_cbk_func = pfm_ul_icmp_ping_whitelist_filter_cbk;
+
+ if (PFM_INVALID_FILTER_ID == g_ul_icmpv4_echo_req_whitelist_filter_id) {
+ /* Register ICMPV4 Echo Request filter to IPCORE */
+ icmpv4_req_rules.features = IPC_FILTER_FEATURE_BWM;
+ icmpv4_req_rules.priority = PFM_UL_ICMP_PING_WHITELIST_HIGH_PRIORITY;
+ icmpv4_req_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV4_TYPE;
+ icmpv4_req_rules.protocol = IPC_HDR_PROT_ICMP;
+ icmpv4_req_rules.ip_type = IPC_IP_TYPE_IPV4;
+ icmpv4_req_rules.icmpv4_type = IPC_HDR_ICMP_TYPE_ECHO_REQUEST;
+ icmpv4_req_rules.cust_cbk_func = pfm_ul_icmp_ping_whitelist_filter_cust_cbk;
+
+ g_ul_icmpv4_echo_req_whitelist_filter_id = ipc_reg_filter(UL_DIRECT, &icmpv4_req_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV4_PING_REQ_BYPASS_FILTER_IPC_FILTER_ID, __FUNCTION__, g_ul_icmpv4_echo_req_whitelist_filter_id);
+ if (0 > g_ul_icmpv4_echo_req_whitelist_filter_id) {
+ hif_trace_error(PFM_TR_ICMPV4_PING_REQ_BYPASS_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMPV4_PING_REQ_BYPASS_FILTER_NO_ACTION, __FUNCTION__, g_ul_icmpv4_echo_req_whitelist_filter_id);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_ul_icmpv4_echo_reply_whitelist_filter_id) {
+ /* Register ICMPV4 Echo Reply filter to IPCORE */
+ icmpv4_reply_rules.features = IPC_FILTER_FEATURE_BWM;
+ icmpv4_reply_rules.priority = PFM_UL_ICMP_PING_WHITELIST_HIGH_PRIORITY;
+ icmpv4_reply_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV4_TYPE;
+ icmpv4_reply_rules.protocol = IPC_HDR_PROT_ICMP;
+ icmpv4_reply_rules.ip_type = IPC_IP_TYPE_IPV4;
+ icmpv4_reply_rules.icmpv4_type = IPC_HDR_ICMP_TYPE_ECHO_REPLY;
+ icmpv4_reply_rules.cust_cbk_func = pfm_ul_icmp_ping_whitelist_filter_cust_cbk;
+
+ g_ul_icmpv4_echo_reply_whitelist_filter_id = ipc_reg_filter(UL_DIRECT, &icmpv4_reply_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV4_PING_REPLY_BYPASS_FILTER_IPC_FILTER_ID, __FUNCTION__, g_ul_icmpv4_echo_reply_whitelist_filter_id);
+ if (0 > g_ul_icmpv4_echo_reply_whitelist_filter_id) {
+ hif_trace_error(PFM_TR_ICMPV4_PING_REPLY_BYPASS_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMPV4_PING_REPLY_BYPASS_FILTER_NO_ACTION, __FUNCTION__, g_ul_icmpv4_echo_reply_whitelist_filter_id);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_ul_icmpv6_echo_req_whitelist_filter_id) {
+ /* Register ICMPV6 Echo Request filter to IPCORE */
+ icmpv6_req_rules.features = IPC_FILTER_FEATURE_BWM;
+ icmpv6_req_rules.priority = PFM_UL_ICMP_PING_WHITELIST_HIGH_PRIORITY;
+ icmpv6_req_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV6_TYPE;
+ icmpv6_req_rules.protocol = IPC_HDR_PROT_ICMPV6;
+ icmpv6_req_rules.ip_type = IPC_IP_TYPE_IPV6;
+ icmpv6_req_rules.icmpv6_type = IPC_HDR_ICMPV6_TYPE_ECHO_REQUEST;
+ icmpv6_req_rules.cust_cbk_func = pfm_ul_icmp_ping_whitelist_filter_cust_cbk;
+
+ g_ul_icmpv6_echo_req_whitelist_filter_id = ipc_reg_filter(UL_DIRECT, &icmpv6_req_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV6_PING_REQ_BYPASS_FILTER_IPC_FILTER_ID, __FUNCTION__, g_ul_icmpv6_echo_req_whitelist_filter_id);
+ if (0 > g_ul_icmpv6_echo_req_whitelist_filter_id) {
+ hif_trace_error(PFM_TR_ICMPV6_PING_REQ_BYPASS_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMPV6_PING_REQ_BYPASS_FILTER_NO_ACTION, __FUNCTION__, g_ul_icmpv6_echo_req_whitelist_filter_id);
+ }
+
+ if (PFM_INVALID_FILTER_ID ==g_ul_icmpv6_echo_reply_whitelist_filter_id) {
+ /* Register ICMPV6 Echo Reply filter to IPCORE */
+ icmpv6_reply_rules.features = IPC_FILTER_FEATURE_BWM;
+ icmpv6_reply_rules.priority = PFM_UL_ICMP_PING_WHITELIST_HIGH_PRIORITY;
+ icmpv6_reply_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV6_TYPE;
+ icmpv6_reply_rules.protocol = IPC_HDR_PROT_ICMPV6;
+ icmpv6_reply_rules.ip_type = IPC_IP_TYPE_IPV6;
+ icmpv6_reply_rules.icmpv6_type = IPC_HDR_ICMPV6_TYPE_ECHO_REPLY;
+ icmpv6_reply_rules.cust_cbk_func = pfm_ul_icmp_ping_whitelist_filter_cust_cbk;
+
+ g_ul_icmpv6_echo_reply_whitelist_filter_id = ipc_reg_filter(UL_DIRECT, &icmpv6_reply_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV6_PING_REPLY_BYPASS_FILTER_IPC_FILTER_ID, __FUNCTION__, g_ul_icmpv6_echo_reply_whitelist_filter_id);
+ if (0 > g_ul_icmpv6_echo_reply_whitelist_filter_id) {
+ hif_trace_error(PFM_TR_ICMPV6_PING_REPLY_BYPASS_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMPV6_PING_REPLY_BYPASS_FILTER_NO_ACTION, __FUNCTION__, g_ul_icmpv6_echo_reply_whitelist_filter_id);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_ul_icmpv6_rs_whitelist_filter_id) {
+ /* Register ICMPV6 RS filter to IPCORE */
+ icmpv6_req_rules.features = IPC_FILTER_FEATURE_BWM;
+ icmpv6_req_rules.priority = PFM_UL_ICMP_PING_WHITELIST_HIGH_PRIORITY;
+ icmpv6_req_rules.valid_fields = IPC_FILTER_BY_PROTOCOL | IPC_FILTER_BY_ICMPV6_TYPE;
+ icmpv6_req_rules.protocol = IPC_HDR_PROT_ICMPV6;
+ icmpv6_req_rules.ip_type = IPC_IP_TYPE_IPV6;
+ icmpv6_req_rules.icmpv6_type = IPC_HDR_ICMPV6_TYPE_RS;
+ icmpv6_req_rules.cust_cbk_func = pfm_ul_icmp_ping_whitelist_filter_cust_cbk;
+
+ g_ul_icmpv6_rs_whitelist_filter_id = ipc_reg_filter(UL_DIRECT, &icmpv6_req_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_ICMPV6_RS_BYPASS_FILTER_IPC_FILTER_ID, __FUNCTION__, g_ul_icmpv6_rs_whitelist_filter_id);
+ if (0 > g_ul_icmpv6_rs_whitelist_filter_id) {
+ hif_trace_error(PFM_TR_ICMPV6_RS_BYPASS_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_ICMPV6_RS_BYPASS_FILTER_NO_ACTION, __FUNCTION__, g_ul_icmpv6_rs_whitelist_filter_id);
+ }
+
+ if (PFM_INVALID_FILTER_ID == g_ul_non_ping_filter_id) {
+ /* Register wild card filter to IPCORE to filter out all packets left*/
+ wc_rules.features = IPC_FILTER_FEATURE_WC;
+ wc_rules.priority = PFM_UL_ICMP_PING_WHITELIST_LOW_PRIORITY;
+
+ g_ul_non_ping_filter_id = ipc_reg_filter(UL_DIRECT, &wc_rules, &ntfy_context);
+ hif_trace_info(PFM_TR_NON_PING_FILTER_REGISTER_FILTER_ID, __FUNCTION__, g_ul_non_ping_filter_id);
+ if (0 > g_ul_non_ping_filter_id) {
+ hif_trace_error(PFM_TR_NON_PING_FILTER_REGISTER_FAILED, __FUNCTION__);
+ return;
+ }
+ } else {
+ hif_trace_info(PFM_TR_NON_PING_FILTER_NO_ACTION, __FUNCTION__, g_ul_non_ping_filter_id);
+ }
+ return;
+}
+
+void pfm_ul_icmp_ping_whitelist_filter_deregister_callback(void *buf,
+ kal_uint32 filter_cnt,
+ kal_bool uplink)
+{
+ ipc_deregister_ul_filter(g_ul_icmpv4_echo_req_whitelist_filter_id);
+ ipc_deregister_ul_filter(g_ul_icmpv4_echo_reply_whitelist_filter_id);
+ ipc_deregister_ul_filter(g_ul_icmpv6_echo_req_whitelist_filter_id);
+ ipc_deregister_ul_filter(g_ul_icmpv6_echo_reply_whitelist_filter_id);
+ ipc_deregister_ul_filter(g_ul_icmpv6_rs_whitelist_filter_id);
+
+ ipc_deregister_ul_filter(g_ul_non_ping_filter_id);
+
+ g_ul_icmpv4_echo_req_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+ g_ul_icmpv4_echo_reply_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+ g_ul_icmpv6_echo_req_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+ g_ul_icmpv6_echo_reply_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+ g_ul_icmpv6_rs_whitelist_filter_id = PFM_INVALID_FILTER_ID;
+
+ g_ul_non_ping_filter_id = PFM_INVALID_FILTER_ID;
+
+ hif_trace_info(PFM_TR_DEREG_ICMPV4_PING_REQ_BYPASS_FILTER, __FUNCTION__, g_ul_icmpv4_echo_req_whitelist_filter_id);
+ hif_trace_info(PFM_TR_DEREG_ICMPV4_PING_REPLY_BYPASS_FILTER, __FUNCTION__, g_ul_icmpv4_echo_reply_whitelist_filter_id);
+ hif_trace_info(PFM_TR_DEREG_ICMPV6_PING_REQ_BYPASS_FILTER, __FUNCTION__, g_ul_icmpv6_echo_req_whitelist_filter_id);
+ hif_trace_info(PFM_TR_DEREG_ICMPV6_PING_REPLY_BYPASS_FILTER, __FUNCTION__, g_ul_icmpv6_echo_reply_whitelist_filter_id);
+ hif_trace_info(PFM_TR_DEREG_ICMPV6_RS_BYPASS_FILTER, __FUNCTION__, g_ul_icmpv6_echo_req_whitelist_filter_id);
+ hif_trace_info(PFM_TR_DEREG_NON_PING_FILTER, __FUNCTION__, g_ul_non_ping_filter_id);
+
+ return;
+}
+
+
diff --git a/mcu/middleware/hif/ipcore/src/pfm_if.c b/mcu/middleware/hif/ipcore/src/pfm_if.c
new file mode 100644
index 0000000..9cffd05
--- /dev/null
+++ b/mcu/middleware/hif/ipcore/src/pfm_if.c
@@ -0,0 +1,847 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2014
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * pfm_if.c
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * Packet Filter Manager public interface implementation.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "ipc_api.h"
+#include "ipc_filter.h"
+#include "intrCtrl.h"
+#include "ccci_ipc_msgid.h"
+
+#include "mw_sap.h"
+#include "ipc_debug.h"
+
+#include "pfm_struct.h"
+#include "pfm_defs.h"
+#include "pfm_enums.h"
+#include "pfm_object.h"
+
+#if defined(__HIF_PCIE_SUPPORT__)
+#include "hif_dpmaifdev.h"
+#endif
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+kal_spinlockid pfm_spinlock_g = NULL;
+/*------------------------------------------------------------------------------
+ * Helper macro.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Private data structure.
+ *----------------------------------------------------------------------------*/
+typedef void (*pfm_register_parser_func_t)(void *, kal_uint32, kal_bool);
+typedef void (*pfm_deregister_callback_func_t)(void *, kal_uint32, kal_bool);
+
+/*------------------------------------------------------------------------------
+ * Private variables.
+ *----------------------------------------------------------------------------*/
+const static pfm_register_parser_func_t pfm_register_parser_func_list_s[] = {
+ #undef PFM_FILTER_SET_FEATURE_NAME
+ #undef PFM_FILTER_SET_PREFIX
+ #define PFM_FILTER_SET_FEATURE_NAME(_name)
+ #define PFM_FILTER_SET_PREFIX(_prefix) pfm_ ## _prefix ## _register_parser,
+ #include "pfm_config.h"
+
+};
+
+const static pfm_deregister_callback_func_t pfm_deregister_callback_func_list_s[] = {
+ #undef PFM_FILTER_SET_FEATURE_NAME
+ #undef PFM_FILTER_SET_PREFIX
+ #define PFM_FILTER_SET_FEATURE_NAME(_name)
+ #define PFM_FILTER_SET_PREFIX(_prefix) pfm_ ## _prefix ## _deregister_callback,
+ #include "pfm_config.h"
+
+};
+
+static pfm_internal_filter_set_t pfm_ul_filter_set_list_s[NUM_OF_PFM_FILTER_SET_ID];
+static pfm_internal_filter_set_t pfm_dl_filter_set_list_s[NUM_OF_PFM_FILTER_SET_ID];
+pfm_internal_filter_set_t *pfm_fsl_set_s[] = {pfm_dl_filter_set_list_s, pfm_ul_filter_set_list_s};
+
+/*------------------------------------------------------------------------------
+ * Private fucntions.
+ *----------------------------------------------------------------------------*/
+pfm_internal_filter_set_t *
+pfm_get_filter_set_by_id(
+ pfm_internal_filter_set_t *filter_set_list,
+ kal_uint32 list_size,
+ kal_uint32 filter_set_id)
+{
+ pfm_internal_filter_set_t *filter_set;
+
+ if ( (NULL == filter_set_list) ||
+ (filter_set_id >= list_size) ) {
+ hif_trace_error(PFM_TR_GET_FILTER_SET_INVALID_PARAMS, filter_set_list, list_size, filter_set_id);
+ return NULL;
+ }
+
+ filter_set = &filter_set_list[filter_set_id];
+
+ if (!PFM_IS_VALID_OBJECT(filter_set)) {
+ hif_trace_info(PFM_TR_GET_FILTER_SET_NEW_FILTER_SET, filter_set_list, filter_set_id, filter_set);
+ PFM_INIT_OBJECT_BEGIN(filter_set, pfm_spinlock_g);
+
+ filter_set->filter_set_id = filter_set_id;
+ filter_set->filter_cnt = 0;
+ kal_mem_set(filter_set->filters, -1, sizeof(filter_set->filters));
+
+ PFM_INIT_OBJECT_END(filter_set, pfm_spinlock_g);
+ return filter_set;
+ }
+ return filter_set;
+}
+
+void pfm_delete_filter_set(
+ pfm_internal_filter_set_t *filter_set)
+{
+ hif_trace_info(PFM_TR_DEL_FILTER_SET_BEGIN, filter_set);
+ PFM_DEINIT_OBJECT_BEGIN(filter_set, pfm_spinlock_g);
+ if (filter_set) {
+ PFM_DEINIT_OBJECT_END(filter_set, pfm_spinlock_g);
+ } else {
+ PFM_ASSERT(KAL_FALSE);
+ }
+}
+
+void pfm_dispatch_cmd(ilm_struct *ilm, kal_bool is_register)
+{
+ pfm_filter_set_t *fs;
+ kal_uint8 *filters_buf;
+ kal_bool uplink;
+ local_para_struct *local_para_ptr = ilm->local_para_ptr; /* local_para pointer */
+ peer_buff_struct *peer_buff_ptr = ilm->peer_buff_ptr; /* peer_buff pointer */
+ kal_uint16 peer_buf_len;
+
+ if (!local_para_ptr) {
+ if(is_register){
+ hif_trace_error(PFM_TR_DISPATCH_REGISTER_CMD_NULL_PARAMS);
+ }else{
+ hif_trace_error(PFM_TR_DEREG_FILTERS_NULL_PARAMS);
+ }
+ return;
+ }
+
+ fs = (pfm_filter_set_t *)local_para_ptr;
+
+ /* Register parameter check */
+ if(is_register) {
+ if ( (fs->filter_set_id >= NUM_OF_PFM_FILTER_SET_ID) ||
+ (fs->filter_cnt == 0) ||
+ ((fs->filter_cnt > 0) && (NULL == peer_buff_ptr))) {
+ hif_trace_error(PFM_TR_DISPATCH_REGISTER_CMD_INVALID_PARAMS, peer_buff_ptr, fs->filter_set_id, fs->filter_cnt);
+ return;
+ }
+ } else {
+ /* De-register parameter check */
+ if ( (fs->filter_set_id >= NUM_OF_PFM_FILTER_SET_ID) ||
+ (fs->filter_cnt == 0) ||
+ ((fs->filter_cnt > 0) && (NULL == peer_buff_ptr))) {
+ hif_trace_error(PFM_TR_DEREG_FILTERS_INVALID_PARAMS, peer_buff_ptr, fs->filter_set_id, fs->filter_cnt);
+ PFM_ASSERT(KAL_FALSE);
+ return;
+ }
+ }
+
+ if (NULL != peer_buff_ptr) {
+ filters_buf = (kal_uint8 *)get_peer_buff_pdu(peer_buff_ptr, &peer_buf_len);
+ } else {
+ filters_buf = NULL;
+ }
+ uplink = (fs->uplink == 1)? KAL_TRUE:KAL_FALSE;
+
+ if(is_register) {
+ hif_trace_info(PFM_TR_DISPATCH_REGISTER_CMD_BEGIN, fs->filter_set_id, fs->filter_cnt);
+ /* Dispatch to pfm_xxx_register_parser() */
+ pfm_register_parser_func_list_s[fs->filter_set_id](filters_buf, fs->filter_cnt, uplink);
+ } else {
+ hif_trace_info(PFM_TR_DEREG_FILTERS_INFO, fs->uplink, fs->filter_set_id, fs->filter_cnt);
+ /* De-register command dispatch */
+ pfm_deregister_callback_func_list_s[fs->filter_set_id](filters_buf, fs->filter_cnt, uplink);
+ }
+}
+
+void pfm_deregister_filter(
+ kal_bool uplink,
+ pfm_internal_filter_set_t *filter_set,
+ kal_int32 filter_id)
+{
+ kal_int32 ipc_filter_id;
+
+ if ( !filter_set || (filter_id < 0) || (filter_id >= PFM_FILTER_SET_MAX_SIZE)|| (filter_set->filter_cnt == 0) ) {
+ hif_trace_error(PFM_TR_DEREG_FILTER_WITH_INVALID_PARAMS, uplink, filter_set, filter_id);
+ PFM_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ ipc_filter_id = filter_set->filters[filter_id];
+ hif_trace_info(PFM_TR_DEREG_FILTER_BEGIN, uplink, filter_set, filter_id, ipc_filter_id);
+ if (-1 != ipc_filter_id) {
+ if (uplink) {
+ ipc_deregister_ul_filter(ipc_filter_id);
+ } else {
+ ipc_deregister_dl_filter(ipc_filter_id);
+ }
+ filter_set->filters[filter_id] = -1;
+ filter_set->filter_cnt--;
+ } else {
+ PFM_ASSERT(KAL_FALSE);
+ }
+}
+
+void pfm_deregister_filters(local_para_struct *local_para_ptr)
+{
+ pfm_filter_set_t *fs;
+ kal_int32 *filters_buf;
+
+ pfm_internal_filter_set_t *filter_set;
+ kal_int32 idx;
+
+ if (!local_para_ptr) {
+ hif_trace_error(PFM_TR_DEREG_FILTERS_NULL_PARAMS);
+ return;
+ }
+
+ fs = (pfm_filter_set_t *)local_para_ptr;
+ filters_buf = (kal_int32 *)(fs + 1);
+
+ if ( (fs->filter_set_id >= NUM_OF_PFM_FILTER_SET_ID) ||
+ (fs->filter_cnt == 0) ) {
+ hif_trace_error(PFM_TR_DEREG_FILTERS_INVALID_PARAMS, local_para_ptr, fs->filter_set_id, fs->filter_cnt);
+ PFM_ASSERT(KAL_FALSE);
+ return;
+ }
+
+ filter_set = pfm_get_filter_set_by_id(pfm_fsl_set_s[fs->uplink], NUM_OF_PFM_FILTER_SET_ID, fs->filter_set_id);
+ if (filter_set) {
+ hif_trace_info(PFM_TR_DEREG_FILTERS_INFO, fs->uplink, fs->filter_set_id, fs->filter_cnt);
+ if (-1 == fs->filter_cnt) {
+ /* Deregister all filters. */
+ for (idx = 0; idx < PFM_FILTER_SET_MAX_SIZE; idx++) {
+ if (-1 != filter_set->filters[idx]) {
+ pfm_deregister_filter((fs->uplink == 1)?KAL_TRUE:KAL_FALSE, filter_set, idx);
+ pfm_deregister_callback_func_list_s[fs->filter_set_id](filters_buf, fs->filter_cnt, fs->uplink);
+ if (0 == filter_set->filter_cnt) {
+ pfm_delete_filter_set(filter_set);
+ break;
+ }
+ }
+ }
+ } else {
+ /* Deregister the specified filters. */
+ if (fs->filter_cnt <= filter_set->filter_cnt) {
+ for (idx = 0; idx < fs->filter_cnt; idx++) {
+ pfm_deregister_filter((fs->uplink == 1)?KAL_TRUE:KAL_FALSE, filter_set, filters_buf[idx]);
+ pfm_deregister_callback_func_list_s[fs->filter_set_id](filters_buf, fs->filter_cnt, fs->uplink);
+ if (0 == filter_set->filter_cnt) {
+ PFM_ASSERT(idx == (fs->filter_cnt - 1));
+ pfm_delete_filter_set(filter_set);
+ }
+ }
+ } else {
+ PFM_ASSERT(KAL_FALSE);
+ }
+ }
+ } else {
+ hif_trace_error(PFM_TR_DEREG_FILTERS_FILTER_SET_NOT_FOUND, fs->uplink, fs->filter_set_id);
+ }
+}
+
+kal_bool pfm_register_filter(kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ kal_bool callback,
+ kal_bool with_info,
+ ipc_filter_rules_t *rules,
+ void *callback_func,
+ void *callback_context,
+ module_type callback_module)
+{
+ pfm_internal_filter_set_t *filter_set = NULL;
+ kal_int32 ret = 0;
+ kal_uint8 idx = (KAL_TRUE == uplink) ? 1 : 0;
+
+ if ( (filter_set_id < 0) || (filter_set_id >= NUM_OF_PFM_FILTER_SET_ID) ||
+ (filter_id < 0) || (filter_id >= PFM_FILTER_SET_MAX_SIZE) ||
+ (!rules) ) {
+ hif_trace_error(PFM_TR_REG_FILTER_INVALID_PARAMS, filter_set_id, filter_id, rules);
+ PFM_ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ filter_set = pfm_get_filter_set_by_id(pfm_fsl_set_s[idx], NUM_OF_PFM_FILTER_SET_ID, filter_set_id);
+ if (filter_set) {
+ /* Deregister the filter if the filter_id has been used. */
+ if (-1 != filter_set->filters[filter_id]) {
+ pfm_deregister_filter(uplink, filter_set, filter_id);
+ }
+
+ if (KAL_FALSE == uplink) {
+ rules->features |= IPC_FILTER_FEATURE_PFM_DL;
+ }
+
+ /* Call corresponding register API */
+ if (uplink) {
+ if (callback) {
+ if (with_info) {
+ ret = ipc_register_ul_filter_with_info_cbk(rules, callback_func, callback_context);
+ } else {
+ ret = ipc_register_ul_filter_cbk(rules, callback_func, callback_context);
+ }
+ } else {
+ if (with_info) {
+ ret = ipc_register_ul_filter_with_info_msg(rules, callback_module, callback_context);
+ } else {
+ ret = ipc_register_ul_filter_msg(rules, callback_module, callback_context);
+ }
+ }
+ } else {
+ if (callback) {
+ if (with_info) {
+ ret = ipc_register_dl_filter_with_info_cbk(rules, callback_func, callback_context);
+ } else {
+ ret = ipc_register_dl_filter_cbk(rules, callback_func, callback_context);
+ }
+ } else {
+ if (with_info) {
+ ret = ipc_register_dl_filter_with_info_msg(rules, callback_module, callback_context);
+ } else {
+ ret = ipc_register_dl_filter_msg(rules, callback_module, callback_context);
+ }
+ }
+ }
+
+ /* Check if registering is succeeded or not. */
+ if (PFM_IPC_REGISTER_FILTER_FAIL != ret) {
+ filter_set->filters[filter_id] = ret;
+ filter_set->filter_cnt++;
+ } else {
+ hif_trace_error(PFM_TR_REG_FILTER_FAILED);
+ return KAL_FALSE;
+ }
+ } else {
+ hif_trace_error(PFM_TR_REG_FILTER_FILTER_SET_NOT_FOUND, uplink, filter_set_id);
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool pfm_register_filter_cbk(
+ kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ ipc_filter_callback_t callback_func,
+ void *callback_context)
+{
+ hif_trace_info(PFM_TR_REG_FILTER_CBK_BEGIN, filter_set_id, filter_id, uplink, rules, callback_func, callback_context);
+ return pfm_register_filter(filter_set_id, filter_id, uplink, KAL_TRUE, KAL_FALSE, rules, callback_func, callback_context, MOD_NIL);
+}
+
+kal_bool pfm_register_filter_msg(
+ kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ module_type callback_module,
+ void *callback_context)
+{
+ hif_trace_info(PFM_TR_REG_FILTER_MSG_BEGIN, filter_set_id, filter_id, uplink, rules, callback_module, callback_context);
+ return pfm_register_filter(filter_set_id, filter_id, uplink, KAL_FALSE, KAL_FALSE, rules, NULL, callback_context, callback_module);
+}
+
+kal_bool pfm_register_filter_with_info_cbk(
+ kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ ipc_filter_with_info_callback_t callback_func,
+ void *callback_context)
+{
+ hif_trace_info(PFM_TR_REG_FILTER_WITH_INFO_CBK_BEGIN, filter_set_id, filter_id, uplink, rules, callback_func, callback_context);
+ return pfm_register_filter(filter_set_id, filter_id, uplink, KAL_TRUE, KAL_TRUE, rules, callback_func, callback_context, MOD_NIL);
+}
+
+kal_bool pfm_register_filter_with_info_msg(
+ kal_uint32 filter_set_id,
+ kal_int32 filter_id,
+ kal_bool uplink,
+ ipc_filter_rules_t *rules,
+ module_type callback_module,
+ void *callback_context)
+{
+ hif_trace_info(PFM_TR_REG_FILTER_WITH_INFO_MSG_BEGIN, filter_set_id, filter_id, uplink, rules, callback_module, callback_context);
+ return pfm_register_filter(filter_set_id, filter_id, uplink, KAL_FALSE, KAL_TRUE, rules, NULL, callback_context, callback_module);
+}
+
+void pfm_matched_packet_trace(kal_int16 ebi, kal_uint8 *p_data, kal_uint32 bytes){
+ kal_uint32 i = 0;
+ kal_uint32 *p_dump = (kal_uint32 *)((int)p_data & (~0x3)); //4-bytes alignment
+
+ hif_data_trace(MD_TRC_PFM_GE_MATCHED_PACKET_INFO, ebi, (p_data[4]<<8|p_data[5]), (p_data[10]<<8|p_data[11]));
+ for (i = 0; i*4 < bytes; i = i+4 ){
+ hif_data_trace(MD_TRC_PFM_GE_MATCHED_PACKET_DUMP, i*4, p_dump[i], p_dump[i+1], p_dump[i+2], p_dump[i+3]);
+ }
+}
+
+void pfm_spinlock_init()
+{
+ PFM_ASSERT(!pfm_spinlock_g);
+ pfm_spinlock_g = kal_create_spinlock(PFM_LOCK_NAME);
+}
+
+static kal_bool pfm_ap_fin_ack_reduction_handler(void)
+{
+ pfm_filter_set_t *p_filter_set = NULL;
+
+ p_filter_set = (pfm_filter_set_t *)construct_local_para(sizeof(pfm_filter_set_t), TD_RESET);
+ if (NULL == p_filter_set) {
+ hif_trace_error(PFM_TR_FIN_ACK_FILTER_ALLOCATE_FAILED);
+ return KAL_FALSE;
+ }
+
+ p_filter_set->filter_set_id = PFM_FIN_ACK_FILTER_SET_ID;
+ p_filter_set->filter_cnt = -1; // No filter info in peer buf
+ p_filter_set->uplink = KAL_FALSE;
+
+ if (KAL_FALSE == msg_send6(kal_get_active_module_id(), MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_REGISTER_FILTER_REQ, (local_para_struct *)p_filter_set, NULL)) {
+ hif_trace_error(PFM_TR_FIN_ACK_FILTER_SEND_ILM_FAILED);\
+ return KAL_FALSE;
+ }
+
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_FIN_ACK_FILTER_REQ, p_filter_set->filter_set_id);
+ return KAL_TRUE;
+}
+
+static void pfm_ap_suspend_handler(kal_uint32 bm_cmd)
+{
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_RECEIVED_AP_SUSPEND_CMD, bm_cmd);
+
+ if (bm_cmd == PFM_AP_CMD_NONE) {
+ /* no additional action */
+ return;
+ }
+
+ if (bm_cmd & PFM_AP_CMD_FIN_ACK_REDUCTION) {
+ if (KAL_FALSE == pfm_ap_fin_ack_reduction_handler()) {
+ /* pfm_ap_fin_ack_reduction_handler failed */
+ return;
+ }
+ }
+
+ return;
+}
+
+static void pfm_ap_wakeup_handler()
+{
+ pfm_deregister_callback_func_list_s[PFM_FIN_ACK_FILTER_SET_ID](NULL, 0, 0);
+ return;
+}
+
+static void pfm_ap_status_parser(local_para_struct *p_local_param)
+{
+ pfmApStatusInd *p_ap_status = (pfmApStatusInd *)p_local_param;
+
+ ASSERT(NULL != p_ap_status);
+
+ hif_trace_info(PFM_TR_FIN_ACK_FILTER_RECEIVED_AP_STATUS,
+ (p_ap_status->em_ap_status == PFM_AP_STATUS_SUSPEND) ? "suspend":"resume");
+ switch(p_ap_status->em_ap_status) {
+ case PFM_AP_STATUS_SUSPEND :
+ pfm_ap_suspend_handler(p_ap_status->bm_cmd);
+ break;
+ case PFM_AP_STATUS_WAKE_UP :
+ pfm_ap_wakeup_handler();
+ break;
+ default :
+ /* unsupported status */
+ hif_trace_error(PFM_TR_FIN_ACK_FILTER_RECEIVED_AP_INVALID_STATUS);
+ break;
+ }
+
+ return;
+}
+
+static void pfm_udp_igmp_reg_filter_handler(local_para_struct *p_local_param)
+{
+ pfm_filter_set_t *p_filter_set = NULL;
+
+ p_filter_set = (pfm_filter_set_t *)construct_local_para(sizeof(pfm_filter_set_t), TD_RESET);
+ if (NULL == p_filter_set) {
+ hif_trace_error(PFM_TR_FIN_ACK_FILTER_ALLOCATE_FAILED);
+ return;
+ }
+
+ p_filter_set->filter_set_id = PFM_UDP_IGMP_FILTER_SET_ID;
+ p_filter_set->filter_cnt = -1; // No filter info in peer buf
+ p_filter_set->uplink = KAL_TRUE;
+
+ if (KAL_FALSE == msg_send6(kal_get_active_module_id(), MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_REGISTER_FILTER_REQ, (local_para_struct *)p_filter_set, NULL)) {
+ hif_trace_error(PFM_TR_FIN_ACK_FILTER_SEND_ILM_FAILED);
+ return;
+ }
+
+ return;
+}
+
+static void pfm_udp_igmp_dereg_filter_handler(local_para_struct *p_local_param)
+{
+ pfm_deregister_callback_func_list_s[PFM_UDP_IGMP_FILTER_SET_ID](NULL, 0, 0);
+ return;
+}
+
+static void pfm_icmp_ping_reg_filter_handler(local_para_struct *p_local_param)
+{
+ pfm_filter_set_t *p_filter_set = NULL;
+
+ p_filter_set = (pfm_filter_set_t *)construct_local_para(sizeof(pfm_filter_set_t), TD_RESET);
+ if (NULL == p_filter_set) {
+ hif_trace_error(PFM_TR_ICMP_PING_FILTER_ALLOCATE_FAILED, __FUNCTION__);
+ return;
+ }
+
+ p_filter_set->filter_set_id = PFM_ICMP_PING_FILTER_SET_ID;
+ p_filter_set->filter_cnt = -1; // No filter info in peer buf
+ p_filter_set->uplink = KAL_FALSE;
+
+ if (KAL_FALSE == msg_send6(kal_get_active_module_id(), MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_REGISTER_FILTER_REQ, (local_para_struct *)p_filter_set, NULL)) {
+ hif_trace_error(PFM_TR_ICMP_PING_FILTER_SEND_ILM_FAILED, __FUNCTION__);
+ return;
+ }
+
+ return;
+}
+
+static void pfm_icmp_ping_dereg_filter_handler(local_para_struct *p_local_param)
+{
+ pfm_deregister_callback_func_list_s[PFM_ICMP_PING_FILTER_SET_ID](NULL, 0, 0);
+ return;
+}
+
+static void pfm_ul_disable_all_packets_reg_filter_handler(local_para_struct *p_local_param)
+{
+ pfm_filter_set_t *p_filter_set = NULL;
+
+ p_filter_set = (pfm_filter_set_t *)construct_local_para(sizeof(pfm_filter_set_t), TD_RESET);
+ if (NULL == p_filter_set) {
+ hif_trace_error(PFM_TR_UL_DISABLE_ALL_PACKETS_FILTER_ALLOCATE_FAILED, __FUNCTION__);
+ return;
+ }
+
+ p_filter_set->filter_set_id = PFM_UL_DISABLE_ALL_PACKETS_FILTER_SET_ID;
+ p_filter_set->filter_cnt = -1; // No filter info in peer buf
+ p_filter_set->uplink = KAL_TRUE;
+
+ if (KAL_FALSE == msg_send6(kal_get_active_module_id(), MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_REGISTER_FILTER_REQ, (local_para_struct *)p_filter_set, NULL)) {
+ hif_trace_error(PFM_UL_DISABLE_ALL_PACKETS_FILTER_SEND_ILM_FAILED, __FUNCTION__);
+ return;
+ }
+
+ return;
+}
+
+static void pfm_ul_disable_all_packets_dereg_filter_handler(local_para_struct *p_local_param)
+{
+ pfm_deregister_callback_func_list_s[PFM_UL_DISABLE_ALL_PACKETS_FILTER_SET_ID](NULL, 0, 0);
+ return;
+}
+
+static void pfm_ul_icmp_ping_whitelist_reg_filter_handler(local_para_struct *p_local_param)
+{
+ pfm_filter_set_t *p_filter_set = NULL;
+
+ p_filter_set = (pfm_filter_set_t *)construct_local_para(sizeof(pfm_filter_set_t), TD_RESET);
+ if (NULL == p_filter_set) {
+ hif_trace_error(PFM_TR_UL_ICMP_PING_WHITELIST_FILTER_ALLOCATE_FAILED, __FUNCTION__);
+ return;
+ }
+
+ p_filter_set->filter_set_id = PFM_UL_ICMP_PING_WHITELIST_FILTER_SET_ID;
+ p_filter_set->filter_cnt = -1; // No filter info in peer buf
+ p_filter_set->uplink = KAL_TRUE;
+
+ if (KAL_FALSE == msg_send6(kal_get_active_module_id(), MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_REGISTER_FILTER_REQ, (local_para_struct *)p_filter_set, NULL)) {
+ hif_trace_error(PFM_UL_ICMP_PING_WHITELIST_FILTER_SEND_ILM_FAILED, __FUNCTION__);
+ return;
+ }
+
+ return;
+}
+
+static void pfm_ul_icmp_ping_whitelist_dereg_filter_handler(local_para_struct *p_local_param)
+{
+ pfm_deregister_callback_func_list_s[PFM_UL_ICMP_PING_WHITELIST_FILTER_SET_ID](NULL, 0, 0);
+ return;
+}
+
+
+#if defined(__HIF_DPMAIF_PCIE_SUPPORT__)
+int pfm_pcie_hifdpmaif_callback(void *param, void *user_param)
+{
+ pfm_pcie_state_change_ind_struct *ind_p;
+ ind_p = (pfm_pcie_state_change_ind_struct *)construct_local_para(sizeof(pfm_pcie_state_change_ind_struct), TD_RESET);
+ ind_p->is_suspend = (kal_uint32)user_param;
+ msg_send5(kal_get_active_module_id(), MOD_IPCORE, IPCORE_SAP, MSG_ID_PFM_PCIE_STATE_CHANGE_IND, (local_para_struct*) ind_p);
+
+ return 0;
+}
+
+static void pfm_pcie_state_change_hdlr(local_para_struct *p_local_param)
+{
+ pfm_pcie_state_change_ind_struct *p_suspend_ind;
+ p_suspend_ind = (pfm_pcie_state_change_ind_struct *)p_local_param;
+
+ if (p_suspend_ind->is_suspend == PFM_STATE_SUSPEND) {
+ ipc_filter_switch_dl_mode(IPC_SW_DL_MODE_PCI);
+ hifdpmaif_suspend_user_ack(DPMAIF_PCIE_NPU_IPCORE);
+ } else {
+ ipc_filter_switch_dl_mode(IPC_HW_DL_MODE_PCI);
+ hifdpmaif_resume_user_ack(DPMAIF_PCIE_NPU_IPCORE);
+ }
+}
+
+#endif
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+void pfm_on_ilm(ilm_struct *ilm)
+{
+ ASSERT(NULL != ilm);
+
+ switch (ilm->msg_id) {
+ case MSG_ID_PFM_REGISTER_FILTER_REQ:
+ pfm_dispatch_cmd(ilm, KAL_TRUE);
+ break;
+ case MSG_ID_PFM_DEREGISTER_FILTER_REQ:
+ pfm_dispatch_cmd(ilm, KAL_FALSE);
+ break;
+ case MSG_ID_AP_STATUS_IND:
+ pfm_ap_status_parser(ilm->local_para_ptr);
+ break;
+ case MSG_ID_IPCORE_UDP_IGMP_REG_FILTER_REQ:
+ pfm_udp_igmp_reg_filter_handler(ilm->local_para_ptr);
+ break;
+ case MSG_ID_IPCORE_UDP_IGMP_DEREG_FILTER_REQ:
+ pfm_udp_igmp_dereg_filter_handler(ilm->local_para_ptr);
+ break;
+ case MSG_ID_PFM_ICMP_PING_REG_FILTER_REQ:
+ pfm_icmp_ping_reg_filter_handler(ilm->local_para_ptr);
+ break;
+ case MSG_ID_PFM_ICMP_PING_DEREG_FILTER_REQ:
+ pfm_icmp_ping_dereg_filter_handler(ilm->local_para_ptr);
+ break;
+ case MSG_ID_PFM_UL_DISABLE_ALL_PACKETS_REG_FILTER_REQ:
+ pfm_ul_disable_all_packets_reg_filter_handler(ilm->local_para_ptr);
+ break;
+ case MSG_ID_PFM_UL_DISABLE_ALL_PACKETS_DEREG_FILTER_REQ:
+ pfm_ul_disable_all_packets_dereg_filter_handler(ilm->local_para_ptr);
+ break;
+ case MSG_ID_PFM_UL_ICMP_PING_WHITELIST_REG_FILTER_REQ:
+ pfm_ul_icmp_ping_whitelist_reg_filter_handler(ilm->local_para_ptr);
+ break;
+ case MSG_ID_PFM_UL_ICMP_PING_WHITELIST_DEREG_FILTER_REQ:
+ pfm_ul_icmp_ping_whitelist_dereg_filter_handler(ilm->local_para_ptr);
+ break;
+ #if defined(__HIF_DPMAIF_PCIE_SUPPORT__)
+ case MSG_ID_PFM_PCIE_STATE_CHANGE_IND:
+ pfm_pcie_state_change_hdlr(ilm->local_para_ptr);
+ break;
+ #endif
+ default:
+ break;
+ }
+}
+
+kal_bool pfm_init(void)
+{
+ kal_uint32 i = 0;
+
+ /* Init the static structure */
+ kal_mem_set(pfm_ul_filter_set_list_s, 0, sizeof(pfm_ul_filter_set_list_s));
+ kal_mem_set(pfm_dl_filter_set_list_s, 0, sizeof(pfm_dl_filter_set_list_s));
+
+ for (i = 0; i < NUM_OF_PFM_FILTER_SET_ID; i++) {
+ kal_mem_set(pfm_ul_filter_set_list_s[i].filters, -1, sizeof(kal_int32) * PFM_FILTER_SET_MAX_SIZE);
+ kal_mem_set(pfm_dl_filter_set_list_s[i].filters, -1, sizeof(kal_int32) * PFM_FILTER_SET_MAX_SIZE);
+ }
+
+ pfm_spinlock_init();
+#if defined(__HIF_DPMAIF_PCIE_SUPPORT__)
+ hifdpmaif_register_suspend_non_post_callback(
+ DPMAIF_PCIE_NPU_IPCORE,
+ pfm_pcie_hifdpmaif_callback,
+ (void*)PFM_STATE_SUSPEND);
+ hifdpmaif_register_resume_non_post_callback(
+ DPMAIF_PCIE_NPU_IPCORE,
+ pfm_pcie_hifdpmaif_callback,
+ (void*)PFM_STATE_RESUME);
+#endif
+
+ return KAL_TRUE;
+}
+
+kal_bool pfm_reset(void)
+{
+ kal_uint32 i = 0;
+
+ /* Init the static structure */
+ kal_mem_set(pfm_ul_filter_set_list_s, 0, sizeof(pfm_ul_filter_set_list_s));
+ kal_mem_set(pfm_dl_filter_set_list_s, 0, sizeof(pfm_dl_filter_set_list_s));
+
+ for (i = 0; i < NUM_OF_PFM_FILTER_SET_ID; i++) {
+ kal_mem_set(pfm_ul_filter_set_list_s[i].filters, -1, sizeof(kal_int32) * PFM_FILTER_SET_MAX_SIZE);
+ kal_mem_set(pfm_dl_filter_set_list_s[i].filters, -1, sizeof(kal_int32) * PFM_FILTER_SET_MAX_SIZE);
+ }
+
+ return KAL_TRUE;
+}
+
+pfm_internal_filter_set_t* pfm_get_filter_set_list(kal_bool is_uplink)
+{
+ return (is_uplink)?pfm_fsl_set_s[1]:pfm_fsl_set_s[0];
+}
diff --git a/mcu/middleware/hif/uartcore/src/uartcore_task.c b/mcu/middleware/hif/uartcore/src/uartcore_task.c
new file mode 100644
index 0000000..92e4335
--- /dev/null
+++ b/mcu/middleware/hif/uartcore/src/uartcore_task.c
@@ -0,0 +1,171 @@
+/*!
+ * @file uartcore_task.c
+ * @author Ansel Liao <ansel.liao@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main functions of uartcore
+ */
+
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "hmu.h"
+#include "hmu_conf_data.h"
+
+typedef enum{
+ UART_EN_Q = 0,
+ UART_DE_Q = 1,
+ UART_EN_Q_LIGHT = 2,
+ UART_DE_Q_ALL = 3,
+} drv_uart_en_q_or_de_q;
+
+extern void *uart_tgpd_head[3];
+extern void *uart_rgpd_head[3];
+extern void *uart_tgpd_tail[3];
+extern void *uart_rgpd_tail[3];
+extern kal_uint32 uart_open_event;
+extern void uart_en_q_de_q_with_mutex(UART_PORT port, kal_bool tx_or_rx, kal_bool en_q_or_de_q, void *p_ior_head, void *p_ior_tail);
+extern void dbg_print(kal_char *fmt, ...);
+
+static void uart_core_task_main(task_entry_struct* task_entry_ptr)
+{
+ ilm_struct current_ilm;
+ kal_uint32 rt_event, uart_event=0;
+ kal_uint32 count = 0;
+
+ kal_set_active_module_id(MOD_UARTCORE);
+ kal_mem_set(¤t_ilm, 0, sizeof(ilm_struct));
+
+ while(1)
+ {
+ //dbg_print("=========>uartcore_task_main\r\n");
+
+ // msg_receive_extq will block, therefore we poll if any message exist first
+ while(msg_get_extq_messages() > 0)
+ {
+ if(msg_receive_extq(¤t_ilm) != KAL_TRUE)
+ {
+ break;
+ }
+
+ switch (current_ilm.msg_id)
+ {
+ default:
+ break;
+ }
+
+ destroy_ilm(¤t_ilm);
+ }
+ // wait some open uart port first time;
+ if(uart_open_event <= 0){
+ uart_event = hmu_hifeg_wait(HIF_DRV_EG_UART_IND_EVENT);
+ }
+ if((HIF_DRV_EG_UART_IND_EVENT & uart_event) || uart_open_event>0){
+ // Wait someone notify HMU to wake up HIF.
+ rt_event = hmu_hifeg_wait(HIF_DRV_EG_HIF_TICK_EVENT_UART);
+ if((HIF_DRV_EG_HIF_TICK_EVENT_UART & rt_event))
+ {
+ count++;
+ if(0 == (count % 1) )
+ {
+ if(uart_tgpd_head[uart_port1] != uart_tgpd_tail[uart_port1])
+ uart_en_q_de_q_with_mutex(uart_port1, UART_TX, UART_DE_Q, NULL, NULL);
+
+ if(uart_rgpd_head[uart_port1] != uart_rgpd_tail[uart_port1])
+ uart_en_q_de_q_with_mutex(uart_port1, UART_RX, UART_DE_Q, NULL, NULL);
+#if defined(__FLAVOR_MULTI_MODE_ROUTER__) || defined(__FLAVOR_SINGLE_MODE_ROUTER__)
+ //in Router product. SUART0 is AP own, so it should not be init here.
+#else
+ if(uart_tgpd_head[uart_port2] != uart_tgpd_tail[uart_port2])
+ uart_en_q_de_q_with_mutex(uart_port2, UART_TX, UART_DE_Q, NULL, NULL);
+
+ if(uart_rgpd_head[uart_port2] != uart_rgpd_tail[uart_port2])
+ uart_en_q_de_q_with_mutex(uart_port2, UART_RX, UART_DE_Q, NULL, NULL);
+#endif
+ }
+ }
+ }
+}
+}
+
+
+static kal_bool uart_core_task_init(void)
+{
+ dbg_print("=========>uartcore_task_init\r\n");
+
+ return KAL_TRUE;
+}
+
+
+static kal_bool uart_core_task_reset(void)
+{
+ dbg_print("=========>uartcore_task_reset\r\n");
+
+ // Do task's reset here.
+ // Notice that: shouldn't execute modules reset handler since
+ // stack_task_reset() will do.
+ return KAL_TRUE;
+}
+
+
+static kal_bool uart_core_task_end(void)
+{
+ dbg_print("=========>uartcore_task_end\r\n");
+
+ // Do task's termination here.
+ // Notice that: shouldn't execute modules reset handler since
+ // stack_task_end() will do.
+ return KAL_TRUE;
+}
+
+
+kal_bool uart_core_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct uart_core_handler_info =
+ {
+ uart_core_task_main, /* task entry function */
+ uart_core_task_init, /* task initialization function */
+// NULL, /* task configuration function */
+ uart_core_task_reset, /* task reset handler */
+// uart_core_task_end /* task termination handler */
+ };
+
+ uart_open_event = 0;
+ dbg_print("=========>uartcore_create\r\n");
+
+ *handle = (comptask_handler_struct *) &uart_core_handler_info;
+
+ return KAL_TRUE;
+}
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_bm.h b/mcu/middleware/hif/usbclass/msd/include/ms_bm.h
new file mode 100644
index 0000000..d05c711
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_bm.h
@@ -0,0 +1,148 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ms_bm.h
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * MS buffer management header file.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_MS_BM_H
+#define __INC_MS_BM_H
+
+/*------------------------------------------------------------------------------
+ * Configuration.
+ *----------------------------------------------------------------------------*/
+#define QBM_NUM_MSD 300 /* Number of MSD GPD */
+
+/*------------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+extern kal_int32 free_gpd_cnt;
+extern kal_bool bm_need_init;
+
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+
+kal_uint32 ms_bm_get_gpd_list_cnt(qbm_gpd *head, qbm_gpd *tail);
+
+
+/*
+ * === FUNCTION =====================================================
+* Name: ms_bm_init
+* Description: Before use ms bm to allocate/free gpd queue, should init it first.
+* Return: Success: KAL_TRUE.
+* Failed: KAL_FALSE
+* =================================================================
+*/
+kal_bool ms_bm_init(void);
+
+/*
+ * === FUNCTION =====================================================
+* Name: ms_bm_de_init
+* Description: Dummy function just check gpds is all free or not, when bm_de_init require all gpds free
+* Return: Success: KAL_TRUE
+* Failed: KAL_FALSE
+* =================================================================
+*/
+kal_bool ms_bm_de_init(void);
+
+/*!
+* === FUNCTION =====================================================
+* Name: ms_bm_alloc_gpd
+* Description: allcate the gpd queue
+* @param cnt: [IN] the request of allocate gpd number, if the cnt more than free gpds just allocate all free count
+* @param head: [IN] Pointer to the gpd list head which you allocated
+* @param tail: [IN] Pointer to the gpd list tail which you allocated
+* Return: Success: The allocate GPD number
+* Failed: 0
+* =================================================================
+*/
+kal_int32 ms_bm_alloc(kal_int32 cnt , qbm_gpd **head, qbm_gpd **tail);
+
+/*!
+* === FUNCTION =====================================================
+* Name: ms_bm_free_gpd
+* Description: free the whole queue from head to tail.
+* @param head: [IN] Pointer to the gpd list head which you want to free
+* @param tail: [IN] Pointer to the gpd list tail which you want to free
+* Return: Success: The freed GPD number
+* Failed: 0
+* =================================================================
+*/
+kal_int32 ms_bm_free(qbm_gpd *head, qbm_gpd *tail);
+
+
+#endif
+
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_core.h b/mcu/middleware/hif/usbclass/msd/include/ms_core.h
new file mode 100644
index 0000000..5739fc1
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_core.h
@@ -0,0 +1,235 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ms_core.h
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * MSD core header file.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __INC_MS_CORE_H
+#define __INC_MS_CORE_H
+
+/*------------------------------------------------------------------------------
+ * Configuration.
+ *----------------------------------------------------------------------------*/
+#define MS_UL_RELOAD_MIN_THRESH 128
+#define MS_UL_RELOAD_GPD_CNT 132
+
+#define MS_CACHE_GPD_NUM 128
+#define MS_MAX_GPD_FOR_READ 32
+
+#define MS_FAST_WRITE_FEATURE 1
+
+/*------------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+#define USBMS_VENDOR_CMD 0xF0
+#define USBMS_VENDOR_CMD_SUB_SET 0x01
+#define USBMS_VENDOR_CMD_SUB_GET 0x02
+#define USBMS_VENDOR_CMD_SUB_META 0x03
+#define USBMS_VENDOR_CMD_SUB_SET_WIN 0x01
+#define USBMS_VENDOR_CMD_SUB_SET_MAC 0x02
+#define USBMS_VENDOR_CMD_SUB_SET_LINUX 0x03
+
+#define USBMS_VENDOR_CMD_OS_XP 0x01
+#define USBMS_VENDOR_CMD_OS_VISTA 0x02
+#define USBMS_VENDOR_CMD_OS_WIN7 0x03
+#define USBMS_VENDOR_CMD_OS_WIN8 0x04
+
+#define USB11_MAX_PACKET_SIZE 64
+#define USB20_MAX_PACKET_SIZE 512
+#define USB30_MAX_PACKET_SIZE 1024
+
+
+
+
+
+#define USB_BULK_CB_WRAP_LEN 31
+#define USB_BULK_CB_SIG 0x43425355 /*little endian: Spells out USBC */
+#define USB_BULK_IN_FLAG 0x80
+
+#define USB_BULK_CS_WRAP_LEN 13
+#define USB_BULK_CS_SIG 0x53425355 /*little endian: Spells out 'USBS' */
+#define USB_STATUS_PASS 0
+#define USB_STATUS_FAIL 1
+#define USB_STATUS_PHASE_ERROR 2
+
+/* Bulk-only class specific requests */
+#define USB_BULK_RESET_REQUEST 0xff
+#define USB_BULK_GET_MAX_LUN_REQUEST 0xfe
+
+
+/* Length of a SCSI Command Data Block */
+#define SS_MAX_COMMAND_SIZE 16
+
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+#define MS_CORE_LOCK(_stack_var) _stack_var = SaveAndSetIRQMask()
+#define MS_CORE_UNLOCK(_stack_var) RestoreIRQMask(_stack_var)
+
+#define MS_INC_CTRL_DROPS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.ctrl_drops += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+#define MS_INC_CTRL_ERRORS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.ctrl_errors += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+
+#define MS_INC_CTRL_PACKETS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.ctrl_packets += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+#define MS_INC_RX_DROPS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.rx_drops += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+#define MS_INC_RX_ERRORS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.rx_errors += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+
+#define MS_INC_RX_PACKETS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.rx_packets += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+#define MS_INC_TX_DROPS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.tx_drops += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+#define MS_INC_TX_ERRORS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.tx_errors += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+
+#define MS_INC_TX_PACKETS(_dev, _packets) \
+ { \
+ kal_uint32 _tmp_stack_var; \
+ MS_CORE_LOCK(_tmp_stack_var); \
+ (_dev)->statistics.tx_packets += (_packets); \
+ MS_CORE_UNLOCK(_tmp_stack_var); \
+ }
+
+
+void ms_core_handle_ilm(ilm_struct *ilm);
+kal_int32 ms_core_ul_reload(void);
+kal_int32 ms_core_init();
+kal_int32 ms_core_deinit(void);
+kal_int32 ms_core_send_tx_gpd_list(qbm_gpd *head, qbm_gpd *tail, kal_uint32 gpd_cnt);
+kal_uint32 ms_core_get_ior_gpd_cnt(usbc_io_request_t *ior);
+kal_int32 ms_core_init_luns(ms_dev_t *dev);
+kal_int32 ms_core_usb_speed(kal_uint32 speed);
+kal_int32 ms_usbc_init(kal_uint8 class_device_id, usb_mode_e mode, kal_uint32 config_num, void *context,kal_uint32 flag);
+kal_int32 ms_usbc_set_config(kal_uint8 class_device_id, kal_uint32 config_num, void *context);
+void ms_usbc_reinit(kal_bool need_check_in);
+kal_uint16 ms_usbc_query_func_wk_capability(void);
+#endif
+
+
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_ctrl.h b/mcu/middleware/hif/usbclass/msd/include/ms_ctrl.h
new file mode 100644
index 0000000..e2bd032
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_ctrl.h
@@ -0,0 +1,117 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ms_ctrl.h
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * MSD control header file.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __INC_MS_CTRL_H
+#define __INC_MS_CTRL_H
+
+/*------------------------------------------------------------------------------
+ * Configuration.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+#define MS_MSG_LEN sizeof(kal_int32)
+
+#define MS_MSG_TYPE_KAL_INT32 0
+#define MS_MSG_TYPE_USB_STATE 1
+#define MS_MSG_TYPE_USB_SPEED 2
+#define MS_MSG_TYPE_USB_SETUP_PKT 3
+#define MS_MSG_TYPE_USB_IO_REQUEST 4
+#define MS_MSG_TYPE_USB_EP_STALL 5
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+typedef struct
+{
+ LOCAL_PARA_HDR
+ kal_uint32 msg_type;
+ kal_uint32 msg_length;
+ void *msg_value;
+}ms_ilm_param_t;
+
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+void ms_ctrl_on_usb_state(kal_uint8 class_device_id, usbc_usb_state_e state);
+void ms_ctrl_on_usb_speed(kal_uint8 class_device_id, usbc_usb_speed_e speed);
+void ms_ctrl_on_setup_packet(kal_uint8 class_device_id, usbc_setup_packet_t *packet);
+void ms_ctrl_on_control_complete(kal_uint8 class_device_id);
+void ms_ctrl_on_bulk_in_complete(kal_uint8 class_device_id, usbc_io_request_t *io_request);
+void ms_ctrl_on_bulk_out_complete(kal_uint8 class_device_id, usbc_io_request_t *io_request);
+void ms_ctrl_on_bulk_in_stall(kal_uint8 class_device_id, kal_bool stall);
+void ms_ctrl_on_bulk_out_stall(kal_uint8 class_device_id, kal_bool stall);
+
+#define MS_CONSTRUCT_LOCAL_PARA(local_para_ptr, local_para_struct) \
+ local_para_ptr = (local_para_struct *) \
+ construct_local_para((kal_uint16)sizeof(local_para_struct),0);
+
+
+#endif
+
+
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_custom.h b/mcu/middleware/hif/usbclass/msd/include/ms_custom.h
new file mode 100644
index 0000000..c365ced
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_custom.h
@@ -0,0 +1,90 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ms_custom.h
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * MSD customization parameter head file.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __INC_MS_CUSTOM_H
+#define __INC_MS_CUSTOM_H
+
+
+/*------------------------------------------------------------------------------
+ * Configuration.
+ *----------------------------------------------------------------------------*/
+#define MS_INTERFACE_STRING_MAX_SIZE 64
+/*------------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+extern kal_bool ms_custom_init(usb_mode_e mode,kal_uint32 config_num);
+extern kal_bool ms_custom_deinit(void);
+
+#endif
+
+
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_debug.h b/mcu/middleware/hif/usbclass/msd/include/ms_debug.h
new file mode 100644
index 0000000..c199e2e
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_debug.h
@@ -0,0 +1,14 @@
+#ifndef __INC_MS_DEBUG_H
+#define __INC_MS_DEBUG_H
+
+#if defined(__MTK_TARGET__)
+ #define HIF_CONSOLE_TRACE_ENABLED 0 /* TODO: set it to 0 once DHL log is done on target. */
+#else
+ #define HIF_CONSOLE_TRACE_ENABLED 0
+#endif
+
+#include "hif_trace.h"
+#include "ms_trace.h"
+
+#endif /* __INC_UCD_DEBUG_H */
+
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_defs.h b/mcu/middleware/hif/usbclass/msd/include/ms_defs.h
new file mode 100644
index 0000000..6fda398
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_defs.h
@@ -0,0 +1,298 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ms_defs.h
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * MS device related defines and configurations.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __INC_MS_DEFS_H
+#define __INC_MS_DEFS_H
+
+#include "usbcore_class_device.h"
+#include "hif_ior.h"
+
+
+/*------------------------------------------------------------------------------
+ * Configuration.
+ *----------------------------------------------------------------------------*/
+#define MS_HWO_BM_RECYCLE_TICKS KAL_TICKS_10_MSEC /* KAL ticks of start bm recycle timer. */
+#define MS_UL_RELOAD_TICKS KAL_TICKS_10_MSEC /* KAL ticks of start ul reload timer*/
+#define MS_INF_STRING_MAX_SIZE 32
+
+
+/*------------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+
+#define MSD_BULK_IN_MAX_SIZE 512
+#define MSD_BULK_OUT_MAX_SIZE 512
+
+#define MS_ES_INDEX_HWO_BM_RECYCLE 1
+#define MS_ES_INDEX_UL_GPD_RELOAD 2
+
+#define MS_PIPE_TYPE_BULK_IN 0
+#define MS_PIPE_TYPE_BULK_OUT 1
+#define MS_TOTAL_PIPE_NUM 2
+
+#define USB_DIR_OUT 0
+#define USB_DIR_IN 0x80
+
+#define USB_TYPE_CLASS (0x01 << 5)
+#define USB_RECIP_INTERFACE 0x01
+
+#define MS_FUNC_WAKEUP_CAPABLE 1
+
+
+/*
+ * DEVICE TYPES
+ */
+#define TYPE_DISK 0x00
+#define TYPE_ROM 0x05
+
+#define MS_SUCCESS 1
+#define MS_ERROR_BM_RECYCLING -1
+#define MS_ERROR_REGISTER_USBC_DEV_FAIL -2
+#define MS_ERROR_SETUP_REQ_ERRORINFO -3
+#define MS_ERROR_SETUP_UNSUPPORTED -4
+#define MS_ERROR_NOT_CBW_CMD_GPD -5
+#define MS_ERROR_CBW_CMD_ERROR -6
+#define MS_ERROR_ALLOC_GPD_FAILED -7
+#define MS_ERROR_DO_SCSI_FAILED -8
+#define MS_ERROR_NOT_ENOUGH_BM -9
+#define MS_ERROR_MORE_DATA_REQ -10
+#define MS_ERROR_QUEUE_NO_FULL -11
+
+#define MS_INFO_SEND_CSW -500
+#define MS_INFO_CBW_DATA_COMPLETED -550
+#define MS_INFO_FAST_WRITE_STATUS_GOOD -600
+
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+typedef enum {
+ MS_STATE_INVALID, /*Invalid device. */
+ MS_STATE_INIT,
+ MS_STATE_DEINIT, /*ms device is deinit*/
+ MS_STATE_IDLE, /*idle state. */
+ MS_STATE_CBW, /*CBW state, Transition state from MS idle state. */
+ MS_STATE_DATA_TRANSING, /*Data translating state,Transition state from CBW state. */
+ MS_STATE_DATA_COMPLETED,/*Data translation completed state,Transition state from translating state.*/
+ MS_STATE_CSW, /*CBW state,Transition state from data completed state or no data required of CBW state. */
+
+ MS_STATE_DUMMY = 0x7fffffff /* Make it a 4-byte enum */
+} ms_dev_state_e;
+
+typedef enum {
+ MS_BULK_START, /*bulk start, data is handled in MS*/
+ MS_BULK_STOP, /*bulk stop, no data is handled in MS*/
+
+ MS_BULK_DUMMY = 0x7fffffff /* Make it a 4-byte enum */
+}ms_bulk_state_e;
+
+typedef enum {
+ MS_DATA_TRANS_NONE, /*data trans default state*/
+ MS_DATA_TRANS_LOOP_CNT, /*loop cnt more than threshold*/
+ MS_DATA_TRANS_NO_DATA, /*no data transfer*/
+ MS_DATA_TRANS_NO_BM, /*no enought bm to allocate*/
+ MS_DATA_TRANS_BULK_STALL, /*bulk stall*/
+ MS_DATA_TRANS_MAX_STATE = 0xffff,
+
+ MS_DATA_TRANS_DUMMY = 0x7fffffff /* Make it a 4-byte enum */
+}ms_data_trans_state_e;
+
+typedef enum {
+ MS_CSW_STATUS_GOOD = 0, /*command good*/
+ MS_CSW_STATUS_FAILED = 1, /*command failed*/
+ MS_CSW_STATUS_PHASE_ERROR = 2 /*phase error*/
+}ms_csw_status_e;
+
+/* Command Block Wrapper */
+typedef struct
+{
+ kal_uint32 Signature; /* Contains 'USBC' */
+ kal_uint32 Tag; /* Unique per command id */
+ kal_uint32 DataTransferLength; /* Size of the data */
+ kal_uint8 Flags; /* Direction in bit 7 */
+ kal_uint8 Lun; /* LUN (normally 0) */
+ kal_uint8 Length; /* Of the CDB, <= MAX_COMMAND_SIZE */
+ kal_uint8 CDB[16]; /* Command Data Block */
+}ms_bulk_cb_wrap_t;
+
+/* Command Status Wrapper */
+typedef struct
+{
+ kal_uint32 Signature; /* Should = 'USBS' */
+ kal_uint32 Tag; /* Same as original command */
+ kal_uint32 Residue; /* Amount not transferred */
+ kal_uint8 Status; /* success/fail/phase error */
+ kal_uint8 padding[3]; /* 4 byte alignment*/
+}ms_bulk_cs_wrap_t;
+
+typedef struct
+{
+ ms_data_trans_state_e state_code;
+ kal_int32 (*state_code_callback)(void *);
+}ms_data_trans_err_handle_t;
+
+typedef struct
+{
+ kal_uint32 num_sectors;
+ kal_uint32 sector_len;
+
+ kal_uint32 cdrom:1;
+ kal_uint32 readonly:1;
+ kal_uint32 removable:1;
+ kal_uint32 prevent_medium_removal:1;
+ kal_uint32 stop_by_host:1;
+ kal_uint32 info_invalid:1;
+ kal_uint32 last_write_error:1;
+
+ kal_uint32 sense_data;
+ kal_uint32 sense_info;
+ kal_uint16 max_driver_bd_num;
+}ms_lun_t;
+
+/* maintain read/write status */
+typedef struct
+{
+ kal_uint32 LBA; /*Logical block address*/
+ kal_uint32 blkcnt; /*transfer logical blocks count*/
+ kal_uint8 rw_case; /*read /write case*/
+} ms_rw_cmd;
+
+typedef struct
+{
+ /*
+ * States.
+ */
+ ms_dev_state_e dev_state; /**< MS device global state. */
+ ms_bulk_state_e bulkin_state; /**< MS bulk in state.*/
+ ms_bulk_state_e bulkout_state; /**< MS bulk out state.*/
+
+ /*
+ * Handles.
+ */
+ usbc_class_device_instance_t *usbc_inst; /**< Instance acquired in usbc_class_device_register(), which keeps valid until usbc_class_device_deregister(). */
+
+ kal_uint8 lun_num; /**< total lun num(disk num -1): lun 0 mean the first disk,...*/
+ kal_uint8 cur_mode; /*recorde last mode which from SCSI vendor command*/
+ kal_uint16 rx_allow_data_len; /**< max usb allow data length*/
+
+ kal_int32 bulk_out_hwo_cnt; /**< Number of GPD owned by USB for bulk OUT EP. */
+ kal_int32 bulk_in_hwo_cnt; /**< Number of GPD owned by USB for bulk IN EP. */
+ eventid hwo_bm_recycle_eventid; /**< Event id for recycling hwo GPD. */
+ eventid ul_reload_eventid; /**< Event id for ul reload. */
+
+ const usb_class_ms_param_t *cus_param; /**< parameter customization*/
+ ms_lun_t luns[8]; /**< ms lun struct.*/
+ kal_uint32 csw_data_residue; /**< Amount not transferred */
+ kal_uint8 csw_error_status; /**< success/fail/phase error */
+ ms_data_trans_err_handle_t data_trans_err_handle; /**<data trans handle error*/
+ ms_rw_cmd rw_cmd; /**< maintain read/write status */
+ ms_bulk_cb_wrap_t cur_cbw; /**< cbw */
+ kal_bool ior_is_handle;
+ kal_bool need_check_in;
+ kal_bool usbc_reinit;
+ kal_bool usbc_reinit_done;
+} ms_dev_t;
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+extern ms_dev_t ms_dev_g; /* ms device context, please use ms_get_dev() to access it outside this file. */
+extern event_scheduler *ms_es_recycle_hwo_gpd_g; /* Timer to retry recycling hwo gpd. */
+extern event_scheduler *ms_es_ul_reload_gpd_g; /* Timer to retry ul reload gpd*/
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+
+/*Only one instance */
+#define ms_get_dev() &ms_dev_g
+
+#ifdef ATEST_SYS_MSD
+ #define MS_ASSERT(x) if(!(x)) \
+ { \
+ printf("MSD ASSERT ERROR! %s(%d)\n",__FUNCTION__,__LINE__); \
+ }
+#else
+ #define MS_ASSERT ASSERT
+#endif
+
+#endif
+
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_scsi.h b/mcu/middleware/hif/usbclass/msd/include/ms_scsi.h
new file mode 100644
index 0000000..b427fc5
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_scsi.h
@@ -0,0 +1,159 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ms_scsi.h
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * MSD core header file.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __INC_MS_SCSI_H
+#define __INC_MS_SCSI_H
+
+/*------------------------------------------------------------------------------
+ * Configuration.
+ *----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+
+
+/* SCSI commands that we recognize */
+#define SC_TEST_UNIT_READY 0x00
+#define SC_REQUEST_SENSE 0x03
+#define SC_READ_6 0x08
+#define SC_WRITE_6 0x0a
+#define SC_INQUIRY 0x12
+#define SC_MODE_SELECT 0x15
+#define SC_MODE_SENSE 0x1a
+#define SC_START_STOP 0x1b
+#define SC_ALLOW_MEDIUM_REMOVAL 0x1e
+#define SC_READ_FORMAT_CAPACITIES 0x23
+#define SC_READ_CAPACITY 0x25
+#define SC_READ_10 0x28
+#define SC_WRITE_10 0x2a
+#define SC_VERIFY 0x2f
+#define SC_SYNCHRONIZE_CACHE 0x35
+#define SC_WRITE_BUFFER 0x3b
+#define SC_READ_TOC 0x43
+#define SC_READ_HEADER 0x44
+#define SC_GET_CONFIGURATION 0x46
+#define SC_GET_EVENT_STATUS_NOTIFICATION 0x4a
+#define SC_READ_DISKINFO 0x51
+#define SC_READ_TRACKINFO 0x52
+#define SC_MODE_SELECT_10 0x55
+#define SC_MODE_SENSE_10 0x5a
+#define SC_READ_12 0xa8
+#define SC_WRITE_12 0xaa
+#define SC_ERASE_12 0xac
+#define SC_SET_CD_SPEED 0xbb
+#define SC_READ_CD 0xbe
+
+/*Vendor command*/
+#define SC_VENDOR_CMD 0xF0
+#define SC_UNKONW_CMD 0xFF
+
+
+/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
+#define SS_NO_SENSE 0
+#define SS_COMMUNICATION_FAILURE 0x040800
+#define SS_INVALID_COMMAND 0x052000
+#define SS_INVALID_FIELD_IN_CDB 0x052400
+#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
+#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500
+#define SS_MEDIUM_NOT_PRESENT 0x023a00
+#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302
+#define SS_NOT_READY_TO_READY_TRANSITION 0x062800
+#define SS_RESET_OCCURRED 0x062900
+#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900
+#define SS_UNRECOVERED_READ_ERROR 0x031100
+#define SS_WRITE_ERROR 0x030c02
+#define SS_WRITE_PROTECTED 0x072700
+
+#define SK(x) ((kal_uint8)((x) >> 16)) /* Sense Key byte, etc. */
+#define ASC(x) ((kal_uint8)((x) >> 8))
+#define ASCQ(x) ((kal_uint8)(x))
+
+/*------------------------------------------------------------------------------
+ * Data structure defintion.
+ *----------------------------------------------------------------------------*/
+
+
+/*------------------------------------------------------------------------------
+ * Global variables.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+#define MS_SCSI_LOCK(_stack_var) _stack_var = SaveAndSetIRQMask()
+#define MS_SCSI_UNLOCK(_stack_var) RestoreIRQMask(_stack_var)
+
+kal_int32 ms_scsi_do_scsi_cmd(qbm_gpd *gpd_cbw,usbc_io_request_t *ior);
+kal_int32 ms_scsi_handle_received_data(usbc_io_request_t *ior);
+kal_int32 ms_scsi_tx_csw(void *dev_t);
+kal_int32 ms_scsi_handle_read(void *dev_t);
+#endif
+
+
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_trace.h b/mcu/middleware/hif/usbclass/msd/include/ms_trace.h
new file mode 100644
index 0000000..51f1685
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_trace.h
@@ -0,0 +1,17 @@
+#ifndef __INC_MS_TRACE_H
+#define __INC_MS_TRACE_H
+#if HIF_CONSOLE_TRACE_ENABLED != 1
+#ifndef GEN_FOR_PC
+ #include "kal_public_defs.h"
+#endif /* GEN_FOR_PC */
+#include "dhl_trace.h"
+#include "dhl_def.h"
+#if !defined(GEN_FOR_PC)
+#if defined(__DHL_MODULE__) || defined(__CUSTOM_RELEASE__)
+#endif /* TST Trace Defintion */
+#endif
+#endif /* HIF_CONSOLE_TRACE_ENABLED != 1 */
+#if !defined(GEN_FOR_PC)
+#include"ms_trace_mod_usbmsd_utmd.h"
+#endif
+#endif /* __INC_UCD_TRACE_H */
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_trace_mod_usbmsd_utmd.json b/mcu/middleware/hif/usbclass/msd/include/ms_trace_mod_usbmsd_utmd.json
new file mode 100644
index 0000000..4284198
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_trace_mod_usbmsd_utmd.json
@@ -0,0 +1,1370 @@
+{
+ "legacyParameters": {},
+ "module": "MOD_USBMSD",
+ "startGen": "Legacy",
+ "endGen": "Legacy",
+ "traceClassDefs": [
+ {
+ "TRACE_INFO": {
+ "debugLevel": "Medium",
+ "tag": [
+ "Baseline",
+ "TRACE_INFO"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_WARNING": {
+ "debugLevel": "High",
+ "tag": [
+ "Baseline",
+ "TRACE_WARNING"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_ERROR": {
+ "debugLevel": "High",
+ "tag": [
+ "Baseline",
+ "TRACE_ERROR"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_FUNC": {
+ "debugLevel": "Medium",
+ "tag": [
+ "Baseline",
+ "TRACE_FUNC"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_STATE": {
+ "debugLevel": "Medium",
+ "tag": [
+ "Baseline",
+ "TRACE_STATE"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_1": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_2": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_3": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_4": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_5": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_6": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_7": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_8": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_9": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ },
+ {
+ "TRACE_GROUP_10": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "Public"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_INIT_BEGIN": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init start...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_INIT_FINISHED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init finished!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_INIT_FAILED": {
+ "apiType": "index",
+ "format": "[MSD] MS adapter custom init failed!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_DEINIT_BEGIN": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom DeInit begin...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_DEINIT_FINISHED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom deinit finished!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_DEINIT_CDROM_HANDLE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter: cdrom driver handler(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_DEINIT_CDROM_FS_LOCK": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter: FS lock(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_DEINIT_CDROM_FREE_FS_LOCK": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter: after free lock,fs_lock(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_NO_CUS_PARAM": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init fail, no custom parameter!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_NO_DISK_CONFIG": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init fail, no disk configured!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_DISK_CONFIG_TOO_MANY": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init fail, configured too many disk!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_NO_SD_MMC_SUPPORT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init fail, No SD MMC support, please check the feature option __MSDC_SD_MMC__ !!!!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_NO_SD_MMC_DUAL_CARD_SUPPORT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init fail, No SD MMC dual card support, please check the feature option __MSDC_SD_MMC__ and __MSDC_DUAL_CARD_SWITCH__ !!!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_NO_NAND_SUPPORT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init fail, No NAND support, please check feature option NAND_SUPPORT",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_NO_RAMDISK_SUPPORT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init fail, No RAMDISK support, please check the feature option __USB_RAMDISK__",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_CDROM_REGISTERED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init,CDROM driver registered!!!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_RAMDISK_REGISTERED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init,RAMDISK driver registered!!!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_NO_DISK_REGISTERED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init,No disk is registered,please check disk config!!!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_CUSTOM_REGISTERED_DISK": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter custom init,Registered %d disks!!!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter usbms_read_write_failed sub_head:(0x%x),sub_tail:(0x%x),lba:(%d),lba_num:(%d),data_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_OUT_OF_RANGE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter rw LBA out of range,lastLBA:(%d),rw LBA:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_RESIDUE_GPD": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter rw residue gpd,write seq(%d),write gpd(%d),residue gpd:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_LBA_LEN_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter rw lba len error,lba_len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_LBA_NUM_MISS_MATCH": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter rw lba len/num miss match,wrote:(%d),want to wrote:(%d),addr:(0x%x),data len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_DATA_PTR_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter rw data ptr is NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_DIR_WRITE_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter direct write failed,data_ptr:(0x%x),lba:(%d),lba_sec_num:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_DIR_READ_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter direct read failed,data_ptr:(0x%x),lba:(%d),lba_sec_num:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_DATA_LEN_INVALID": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter invalid write data len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_RW_CACHE_OUT_OF_RANGE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter rw cache out of range:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_INIT_NORMAL_MODE_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter init normal mode failed,result:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_FS_GET_DEVSTATUS_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter get dev status failed,result:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_ADAPTER_INIT_CDROM_ISO_NOT_FOUND": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS adapter init cdrom iso not found,result:(%d),DeRegister driver!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_FREE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm free(%d)gpds,all free gpds(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_FREE_IN_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm free Input Error!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_DE_INIT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm deinit finished!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_DE_INIT_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm deinit failed - not all gpd free!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_ALLOC": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm alloc(%d)gpds,all free gpds(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_ALLOC_MORE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm allocate need cnt(%d)is more than now free gpd(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_ALLOC_NO_FREE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm allocate failed - No free GPD!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_ALLOC_REQUIRE_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm allocate failed - Require cnt error(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_INIT_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm init failed - Qbm_init_queue Error code:(%d)!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_BM_REINIT_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS bm reinit failed - not all gpd free!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_ON_USB_STATE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] USB state notify, usbc device id:%d,state:%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_ON_USB_SPEED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] USB speed changed,usbc device id:%d,speed:%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_ON_USB_SETUP_PKT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] USB setup pkt recevied",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_ON_USB_CTRL_COMPLETED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] USB send ctrl pkt completed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_ON_USB_BULKIN_COMPLETED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] USB bulk in completed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_ON_USB_BULKOUT_COMPLETED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] USB bulk out completed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_ON_USB_BULKIN_STALL": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] USB bulk in stall state(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_ON_USB_BULKOUT_STALL": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] USB bulk out stall state(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_SETUP_PKT_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] received setup pkt, reqType=0x%x, req=0x%x, wVal=%d, wIdx=%d, wLen=%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_SETUP_PKT_ERROR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] setup pkt info error,reqType=0x%x, req=0x%x, wVal=%d, wIdx=%d, wLen=%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CTRL_SETUP_PKT_REQUEST_UNSUPPORTED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] setup pkt unsupported!,reqType=0x%x, req=0x%x, wVal=%d, wIdx=%d, wLen=%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_START_BM_RECYCLE_TIMER": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] start recycle HWO GPD timer,timer(%d)...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_SET_BM_RECYCLE_TIMER_ERROR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] start recycle HWO GPD timer error!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_BM_RECYCLE_TIME_OUT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] recycle HWO GPD time out!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_BM_RECYCLE_RESTART": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] recycle HWO GPD time out and recycle is needed, restart...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_BM_RECYCLE_START": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] try to start BM recycling now...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_BM_RECYCLE_FINISHED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] BM recycling completed, send reinit ILM to MSD",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_INIT_BEGIN": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS core init begin...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_INIT_FINISHED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS core init completed...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_DEINIT_NEED_BM_RECYCLE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] MS core deinit, bm recycle is needed...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_MALLOC_BM": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] malloc bm buffer, to_alloc(%d),num_alloc(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_UL_GPD_ALLOW_LEN": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] UL submitted GPD, update allow length(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_UL_GPD_SUBMITTED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] UL submitted GPD, total number(%d) in HIF",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_UL_RELOAD_TIMER": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] start UL reload timer, timer(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_UL_RELOAD_TIMEOUT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] UL reload time out!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_UL_RELOAD_RESTART_ILM": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] send ILM to MSD for restart UL reload!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_SEND_SUBMIT_GPD_LIST": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] TX GPD count(%d) to usb core",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_SEND_BACK_GPD_LIST": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] TX GPD count back(%d) from usb core",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_DATA_TRANS_STATE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Data translate state(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_DATA_START_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Data start failed for dev->usbc_inst is NULL",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_BULK_IN_STATE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]BULK IN STALL?(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_BULK_OUT_HWO_CNT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]BULK OUT HWO cnt(%d),RX GPD cnt(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_BULK_IN_HWO_CNT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] BULK IN HWO cnt(%d),TX GPD cnt(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_BULK_IN_HWO_CNT_IN_FALSE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]BULK IN HWO in failed cnt(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_HANDLE_USB_MODE_SWITCH": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]=============USB MODE SWITCH,switch to mode(%d)===============",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_HANDLE_USB_RESET_DEVICE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]******RESET DEVICE REQUEST...******",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_IF_USBC_INIT_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]MS IF USBC INIT INFO:if_id(%d),bulkin_ep(%d),bulkou_ep(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_IF_USBC_SET_CONF_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]MS IF set config...mode(%d),conf_num(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_IF_USBC_SET_CONF": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]MS IF set config retval(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_IF_USBC_REINIT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]MS IF USBC REINIT,need_check_in(%d)...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_IF_USBC_WAIT_REINIT_DONE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]MS IF USBC REINIT,wait reinit done(%d)...",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_IF_USBC_REINIT_DONE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]MS IF USBC REINIT DONE,reinit done, total wait time(%d)(ms)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_IF_USBC_SET_FUNC_WK_ABILITY": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD]MS IF USBC set func wake ability(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_INQUIRY": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - INQUIRY, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_REQUEST_SENSE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - REQUEST_SENSE, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_TEST_UNIT_READY": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - TEST_UNIT_READY, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_READ": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - READ, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_READ_6": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - READ_6",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_READ_10": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - READ_10",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_READ_12": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - READ_12",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_WRITE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - WRITE, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_WRITE_6": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - WRITE_6",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_WRITE_10": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - WRITE_10",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_WRITE_12": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - WRITE_12",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_MODE_SELECT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - MODE_SELECT, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_MODE_SELECT_10": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - MODE_SELECT_10, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_MODE_SENSE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - MODE_SENSE, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_START_STOP": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - START_STOP, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_ALLOW_MEDIUM_REMOVAL": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - ALLOW_MEDIUM_REMOVAL, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_READ_FORMAT_CAPACITIES": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - READ_FORMAT_CAPACITIES, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_READ_CAPACITY": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - READ_CAPACITY, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_VERIFY": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - VERIFY, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_MODE_SENSE_10": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - MODE_SENSE_10, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_READ_TOC": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - READ_TOC, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_GET_CONFIGURATION": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - GET_CONFIGURATION, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_READ_DISKINFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - READ_DISKINFO, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_UNKNOWN_CMD": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI command - UNKNOWN_CMD, LUN(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_TX_GPG_LIST_ERROR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Tx gpd list to usb core ERROR!!",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_ATTEMPT_STOP_PREVENT": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] attempt stop prevent lun(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_VENDOR_CMD": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] handle vendor cmd(0x%x),CDB1=0x%x,CDB2=0x%x,CDB3=0x%x",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_TX_CSW": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] <=== Do SCSI TX CSW",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_TX_CSW_SUCCESS": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI tx csw success",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_TX_CSW_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI tx csw failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_ALLOC_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI alloc gpd failed cnt:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_GEN_SENSEKEY": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI gen sensekey sd:(%d),sdinfo:(%d),valid:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_GEN_INQUIRY_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI gen inquiry failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_GEN_INQUIRY_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI gen inquiry info -- vendor:(%s),product:(%s),revision:(%s)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_STATUS_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI hand write status:(%d),csw status:(%d) failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_FAST_WRITE_TX_CSW_STATUS": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write,FAST WRITE TX CSW status(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_FAST_WRITE_TX_CSW_AGAIN_STATUS": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write,WRITE TX CSW again for no BM, status(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_LAST_WRITE_ERROR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write,LUN(%d),last write error(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_MORE_GPD": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI gpd list more than data tansfer",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_LBA_NUM": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write: cur(%d) of total(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_TX_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write tx failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_MORE_TO_WRITE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write more data to write residue:(%d),blk cnt:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write failed LBA:(%d),residue:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_NO_IOR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write No ior to write",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_SEC_LEN_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write lba len is 0",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_WRITE_RESIDUE_LEN_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle write residue len err,blk cnt(%d),lba len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_DUMMY_TX_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI do dummy tx failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_DUMMY_ERROR_DIR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI do dummy unknow direction",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read info -- residue:(%d),need_gpd:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_STATE_ERROR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read status error:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_ALLOC_GPD": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read alloc gpd:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_LBA_NUM": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read lba index:(%d),lba num:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_FAILED_FREE_BUF": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read failed -- free buffer",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_ALLOC_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read alloc failed gpd cnt:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_FINISH": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read finish",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_FINISH_5": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read case 5 finish",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_FINISH_7": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read case 7 finish",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_STATUS_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI hand read status:(%d),csw status:(%d),lba_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_RESIDUE_LEN_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI hand read residue len err,blk cnt(%d),lba len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_SEND_SHORT_PACKET_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI send short packet failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_TX_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read tx failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_HANDLE_READ_MORE_LOOP": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI handle read loop cnt(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_IQ_TX_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI do inquire tx failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_CAP_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read capacity failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_CAP_STATUS_ERROR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read capacity status error:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_CAP_ALLOC_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read capacity alloc failed cnt:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_CAP_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read capacity info -- LBA:(%d),len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_CAP_TX_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read capacity tx failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_FMT_CAP_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read fmt capacity info -- blk no:(%x),blk len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_FMT_TX_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read fmt capacity tx failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_FMT_ALLOC_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read fmt alloc failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_LBA_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read lba info -- lba len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_CASE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read case:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_CSW_STATUS_ERROR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read csw status error,status:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_MEDIA_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read media error,sense_data:(%d),lba_len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_WRITE_INFO": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI write info -- lba len:(%d),blk cnt(%d),data(%d) byte",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_WRITE_CASE": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI write case:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_WRITE_MEDIA_ERR_DROP_DATA": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI write media err drop data sense_data:(%d),ior addr:(%d),lba_len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_WRITE_MEDIA_ERR": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI write media error,sense_data(%d),lba_len:(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_REQ_SENSE_TX_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI req sense tx failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_REQ_SENSE_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI req sense failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_GET_CONFIG_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI get configuration failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_DO_READ_DISKINFO_FAILED": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI read diskinfo failed",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_LOG_DATA_ADDR_LEN": {
+ "_comment": "Trace reference not found",
+ "format": "[MSD] Do SCSI log data addr:(%x),len(%d),print(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_LOG_DATA": {
+ "_comment": "Trace reference not found",
+ "format": "%02x ",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_SCSI_LOG_DROP_DATA": {
+ "_comment": "Trace reference not found",
+ "format": "****************DROP DATA***************",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_LOG_IOR": {
+ "_comment": "Trace reference not found",
+ "format": "****IOR(0x%x)****",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_LOG_EQUAL": {
+ "_comment": "Trace reference not found",
+ "format": "=================",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "MSD_TR_MS_CORE_LOG_GPD_ADDRESS": {
+ "_comment": "Trace reference not found",
+ "format": "gpd(0x%x)",
+ "traceClass": "TRACE_INFO"
+ }
+ }
+ ],
+ "traceFamily": "PS",
+ "userModule": "MOD_USBMSD"
+}
\ No newline at end of file
diff --git a/mcu/middleware/hif/usbclass/msd/include/ms_ut.h b/mcu/middleware/hif/usbclass/msd/include/ms_ut.h
new file mode 100644
index 0000000..46d8ef4
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/ms_ut.h
@@ -0,0 +1,134 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ms_ut.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * MSD unit test defines.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __INC_MS_UT_H
+#define __INC_MS_UT_H
+
+/*------------------------------------------------------------------------------
+ * Configurations.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Data structure.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * Helper macros for UT and normal modes.
+ *----------------------------------------------------------------------------*/
+#define _msd_ut_printf printf
+
+#define msd_ut_printf(_fmts, ...) \
+ _msd_ut_printf("%s(): " _fmts, __FUNCTION__, ##__VA_ARGS__)
+
+#define msd_ut_format_err_str(_fmts, ...) \
+ kal_sprintf(p_ret_err_str, "%s:%d: " _fmts, __FILE__, __LINE__, ##__VA_ARGS__); \
+ msd_ut_printf("[FAILED] " _fmts, ##__VA_ARGS__)
+
+
+#ifdef ATEST_SYS_MSD
+
+ #define msd_hif_register msd_ut_hif_register
+
+ #define msd_hif_deregister msd_ut_hif_deregister
+
+ #define msd_hif_submit_control_request msd_ut_hif_submit_control_request
+
+ #define msd_hif_submit_io_request msd_ut_hif_submit_io_request
+
+ #define msd_hif_flush_io_request msd_ut_hif_flush_io_request
+#else
+
+ #define msd_hif_register usbc_class_device_register
+
+ #define msd_hif_deregister usbc_class_device_deregister
+
+ #define msd_hif_submit_control_request usbc_class_device_submit_control_request
+
+ #define msd_hif_submit_io_request usbc_class_device_submit_io_request
+
+ #define msd_hif_flush_io_request usbc_class_device_flush_io_request
+#endif
+
+#ifdef ATEST_SYS_MSD
+/*------------------------------------------------------------------------------
+ * UT specific helper macros.
+ *----------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ * UT specific public fucntions.
+ *----------------------------------------------------------------------------*/
+usbc_class_device_instance_t *msd_ut_hif_register(kal_uint8 class_device_id,usbc_class_device_info_t *device_info);
+
+kal_bool msd_ut_hif_deregister(kal_uint8 class_device_id);
+
+kal_bool msd_ut_hif_submit_control_request(kal_uint8 class_device_id, kal_uint8 *buffer, kal_uint32 length, usbc_control_request_type_e type);
+
+kal_bool msd_ut_hif_submit_io_request(kal_uint8 class_device_id, kal_uint8 queue_no, usbc_io_request_t *io_request);
+kal_bool msd_ut_hif_flush_io_request(kal_uint8 class_device_id, kal_uint8 queue_no);
+
+#endif /* ATEST_SYS_MSD */
+#endif /* __INC_MBIM_UT_H */
+
diff --git a/mcu/middleware/hif/usbclass/msd/include/mse_common.h b/mcu/middleware/hif/usbclass/msd/include/mse_common.h
new file mode 100644
index 0000000..2291649
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/mse_common.h
@@ -0,0 +1,81 @@
+/*!
+ * @file adb_common.h
+ * @author TJ Chang <tj.chang@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ *
+ */
+
+#ifndef _MSE_COMMON_H
+#define _MSE_COMMON_H
+
+#include "kal_general_types.h"
+
+/* USB_CORE */
+#include "usbcore_class_device.h"
+
+
+// ==========================================================
+// Macro Definition
+// ==========================================================
+
+
+// ==========================================================
+// Data Structure Definition
+// ==========================================================
+typedef enum _MSE_PIPE_TYPE_E {
+ MSE_PIPE_TYPE_DATA_IN = 0,
+ MSE_PIPE_TYPE_DATA_OUT = 1,
+ MSE_PIPE_MAX_NUM,
+} MSE_PIPE_TYPE_E;
+
+typedef struct _mse_device_instance_t
+{
+ /* COMMON */
+ kal_bool is_used; /**< KAL_TRUE if this cdcacm instance is used, KAL_FALSE otherwise. */
+
+ /* USB_CORE */
+ kal_bool usb_ready; /**< USB read state. */
+ kal_bool usb_pipe_ready[MSE_PIPE_MAX_NUM]; /**< USB pipe state. */
+ usbc_class_device_instance_t *usb_handler; /**< USB handler is acquired when registering usb_core, and used to communicate with usb_core. */
+ usbc_usb_state_e usb_state; /**< USB state. */
+ usbc_usb_speed_e usb_speed; /**< USB speed. */
+ kal_uint8 usb_class_id; /**< USB class id. */
+ usb_class_type_e if_type; /**< USB MSE interface type.which is defined in usbc_custom.h. */
+ kal_uint8 func_wakeup_enabled; /**< 1 if function remote wakeup is enabled. */
+ kal_uint8 is_usb_state_suspend; /**< 1 if in usb suspend state */
+} mse_device_instance_t;
+
+#endif /* _MSE_COMMON_H */
diff --git a/mcu/middleware/hif/usbclass/msd/include/mse_core.h b/mcu/middleware/hif/usbclass/msd/include/mse_core.h
new file mode 100644
index 0000000..858d2d5
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/mse_core.h
@@ -0,0 +1,67 @@
+/*!
+ * @file mse_core.h
+ * @author TJ Chang <tj.chang@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ *
+ */
+
+#ifndef _MSE_CORE_H
+#define _MSE_CORE_H
+
+#include "mse_common.h"
+#include "usbcore_debug.h"
+
+#define mse_trace_info usbc_trace_info
+// ==========================================================
+// Macro Definition
+// ==========================================================
+#define MSE_FUNC_WAKEUP_CAPABLE 1 /* 1 to enable USB function remote wakeup capable; 0 to disable. */
+#define MSE_MAX_REMOTE_WAKEUP_SLEEP_TICKS KAL_TICKS_10_MSEC /* Interval to check if remote wakeup is completed. */
+#define MSE_MAX_REMOTE_WAKEUP_WAIT_TICKS KAL_TICKS_1_SEC /* Maximal time to wait for the completion of remote wakeup. */
+
+/* MSE-related USB Protocol Definition */
+#define MSE_EP_BULK_MAXP 0x0200
+#define MSE_DATA_CLASS 0x08
+#define MSE_DATA_SUBCLASS 0x06
+#define MSE_DATA_PROTOCOL 0x50
+
+mse_device_instance_t* mse_core_get_instance();
+kal_int32 mse_core_set_config(kal_uint8 class_device_id, kal_uint32 config_num);
+void mse_core_deinit(mse_device_instance_t *p_dev_inst);
+void mse_core_reinit(kal_bool need_checkin);
+kal_bool mse_task_init(void);
+
+#endif /* _MSE_CORE_H */
diff --git a/mcu/middleware/hif/usbclass/msd/include/mse_usbhdr.h b/mcu/middleware/hif/usbclass/msd/include/mse_usbhdr.h
new file mode 100644
index 0000000..5bf205f
--- /dev/null
+++ b/mcu/middleware/hif/usbclass/msd/include/mse_usbhdr.h
@@ -0,0 +1,110 @@
+/*!
+ * @file mse_usbhdr.h
+ * @author TJ Chang <tj.chang@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ *
+ */
+
+#ifndef _MSE_USBHDR_H
+#define _MSE_USBHDR_H
+
+#include "kal_general_types.h"
+#include "usbcore_class_device.h"
+#include "mse_common.h"
+
+
+// ==========================================================
+// Data Structure Definition
+// ==========================================================
+
+
+// ==========================================================
+// USBHDR Public Function
+// ==========================================================
+/**
+ * mse_usbhdr_checkin
+ *
+ * CDCACM USB Handler - Checkin CDCACM callback function into USB stack.
+ *
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail.
+ */
+kal_bool mse_usbhdr_checkin();
+
+/**
+ * mse_usbhdr_reg_usbcore
+ *
+ * CDCACM USB Handler - Register to USB_CORE
+ *
+ * @param [IN] p_dev_inst mse device instance
+ *
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail.
+ */
+kal_bool mse_usbhdr_reg_usbcore(mse_device_instance_t *p_dev_inst);
+
+/**
+ * mse_usbhdr_expt_reg_usbcore
+ *
+ * CDCACM USB Handler - Register exception handling to USB_CORE
+ *
+ * @param [IN] p_dev_inst mse exception device instance
+ *
+ * @return KAL_TRUE if success, otherwise KAL_FALSE if fail.
+ */
+kal_bool mse_usbhdr_expt_reg_usbcore(mse_device_instance_t *p_dev_inst);
+
+/*!
+ * usbcore reports USB remote wakeup ability
+ *
+ * @param class_device_id [IN] Identifier of the RNDIS device.
+ * @param ability [IN] KAL_TRUE if remote wakeup ability is enabled, otherwise is KAL_FALSE.
+ */
+void mse_usbhdr_set_func_wk_ability(kal_uint8 class_device_id, kal_bool ability);
+
+/*!
+ * usbcore queries USB remote status.
+ *
+ * @param class_device_id [IN] Identifier of the RNDIS device.
+ */
+kal_uint16 mse_usbhdr_query_func_wk_status(kal_uint8 class_device_id);
+
+kal_int32 mse_usbhdr_init(kal_uint8 class_device_id, usb_mode_e mode, kal_uint32 config_num, void *context, kal_uint8 flag);
+kal_int32 mse_usbhdr_set_config(kal_uint8 class_device_id, kal_uint32 config_num, void *context);
+void mse_usbhdr_reinit(kal_bool need_checkin);
+kal_uint16 mse_usbhdr_query_func_wk_capability();
+
+
+#endif /* _MSE_USBHDR_H */
+
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_cosim.h b/mcu/middleware/hif/usbcore/include/usbcore_cosim.h
new file mode 100644
index 0000000..be4da46
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_cosim.h
@@ -0,0 +1,27 @@
+#ifndef _USBCORE_COSIM_H
+#define _USBCORE_COSIM_H
+
+#include "hif_usb.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#include "dhl_trace.h"
+
+#define USBC_ESL_DEBUG 0
+
+#if USBC_ESL_DEBUG
+ #define usbc_esl_printf(...) hsl_printf(__VA_ARGS__)
+#else
+ #define usbc_esl_printf(...)
+#endif
+
+/*!
+ * @brief usbcore initial for ESL COSIM
+ */
+kal_bool usbc_cosim_core_task_init(void);
+
+/*!
+ * @brief usbcore main function for ESL COSIM
+ */
+void usbc_cosim_core_task_main(task_entry_struct*);
+
+#endif // _USBCORE_HIF_H
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_data_path_trace_utmd.json b/mcu/middleware/hif/usbcore/include/usbcore_data_path_trace_utmd.json
new file mode 100644
index 0000000..837f7a8
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_data_path_trace_utmd.json
@@ -0,0 +1,250 @@
+{
+ "legacyParameters": {
+ "codeSection": "TCMFORCE",
+ "l2BufferSetting": "L2_BUFFER_HIF",
+ "l2MaxArg": 7,
+ "modemType": "Generic"
+ },
+ "module": "USBCORE_L2",
+ "stringTranslationDefs": [],
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "USBCORE_POLL_QUEUE_UL": {
+ "debugLevel": "Ultra-Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_L": {
+ "debugLevel": "Low",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "USBCORE_CLASS_REQUEST_UH": {
+ "debugLevel": "Ultra-High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "USBCORE_CLASS_REQUEST_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "USBCORE_CLASS_REQUEST_M": {
+ "debugLevel": "Medium",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_H": {
+ "debugLevel": "High",
+ "filterDefaultValue": "ON",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "USBCORE_POLL_QUEUE_E": {
+ "format": "[USBCORE] checked E_txq[%xd], E_rxq[%xl]",
+ "traceClass": "USBCORE_POLL_QUEUE_H"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_TX": {
+ "format": "[USBCORE] polling Tx_q[%d], returns %l GPD(s), first gpd %xl, last gpd %xl",
+ "traceClass": "USBCORE_POLL_QUEUE_M"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_TX_ONE": {
+ "format": "[USBCORE] polling Tx_q[%d], returns gpd %xl",
+ "traceClass": "USBCORE_POLL_QUEUE_M"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_TX_NOTIFY_END": {
+ "format": "[USBCORE] finishing notifing poll Tx queue complete: class id = %d",
+ "traceClass": "USBCORE_POLL_QUEUE_L"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_RX": {
+ "format": "[USBCORE] polling Rx_q[%d], returns %l GPD(s), first gpd %xl, last gpd %xl",
+ "traceClass": "USBCORE_POLL_QUEUE_M"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_RX_ONE": {
+ "format": "[USBCORE] polling Rx_q[%d], returns gpd %xl",
+ "traceClass": "USBCORE_POLL_QUEUE_M"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_RX_NOTIFY_END": {
+ "format": "[USBCORE] finishing notifing poll Rx queue complete: class id = %d",
+ "traceClass": "USBCORE_POLL_QUEUE_L"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_LEN_TX": {
+ "format": "[USBCORE] polling Tx_q[%d], GPD length = %xl, BD_length = %xl, SPD length = %xl",
+ "traceClass": "USBCORE_POLL_QUEUE_L"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_LEN_RX": {
+ "format": "[USBCORE] polling Rx_q[%d], GPD length = %xl, BD_length = %xl, SPD length = %xl",
+ "traceClass": "USBCORE_POLL_QUEUE_L"
+ }
+ },
+ {
+ "USBCORE_CLASS_SUBMIT_IO_REQUEST_HWQ": {
+ "format": "[USBCORE] submit hw_q type/q_no = %xd, first gpd %xl, last gpd %xl",
+ "traceClass": "USBCORE_CLASS_REQUEST_M"
+ }
+ },
+ {
+ "USBCORE_CLASS_SUBMIT_IO_REQUEST_HWQ_ONE": {
+ "format": "[USBCORE] submit hw_q type/q_no = %xd, gpd %xl",
+ "traceClass": "USBCORE_CLASS_REQUEST_M"
+ }
+ },
+ {
+ "USBCORE_CLASS_SUBMIT_IO_REQUEST_SWQ": {
+ "format": "[USBCORE] submit sw_q type/q_no = %xd, first gpd %xl, last gpd %xl",
+ "traceClass": "USBCORE_CLASS_REQUEST_M"
+ }
+ },
+ {
+ "USBCORE_CLASS_SUBMIT_IO_REQUEST_SWQ_ONE": {
+ "format": "[USBCORE] submit sw_q type/q_no = %xd, gpd %xl",
+ "traceClass": "USBCORE_CLASS_REQUEST_M"
+ }
+ },
+ {
+ "USBCORE_CLASS_FLUSH_HW_QUEUE": {
+ "format": "[USBCORE] flush HW_q[%xd], returns %l GPD(s), first gpd %xl, last gpd %xl",
+ "traceClass": "USBCORE_CLASS_REQUEST_H"
+ }
+ },
+ {
+ "USBCORE_CLASS_FLUSH_SW_QUEUE": {
+ "format": "[USBCORE] flush SW_q[%xd], returns %l GPD(s), first gpd %xl, last gpd %xl",
+ "traceClass": "USBCORE_CLASS_REQUEST_H"
+ }
+ },
+ {
+ "USBCORE_RESTORE_RX_GPD_SWQ2HWQ": {
+ "format": "[USBCORE] restore Rx GPDs from sw_q to hw_q: type/q_no = %xd",
+ "traceClass": "USBCORE_CLASS_REQUEST_H"
+ }
+ },
+ {
+ "USBCORE_RESTORE_TX_GPD_SWQ2HWQ": {
+ "format": "[USBCORE] restore Tx GPDs from sw_q to hw_q: type/q_no = %xd",
+ "traceClass": "USBCORE_CLASS_REQUEST_H"
+ }
+ },
+ {
+ "USBCORE_DIRECT_POLL_QUEUE": {
+ "format": "[USBCORE] direct polling dir = %d, md_q = %l, ap_q = %l",
+ "traceClass": "USBCORE_POLL_QUEUE_M"
+ }
+ },
+ {
+ "USBCORE_DIRECT_SUBMIT_IO_REQUEST": {
+ "format": "[USBCORE] direct submitIO dir = %d, md_q = %l, ap_q = %l",
+ "traceClass": "USBCORE_CLASS_REQUEST_M"
+ }
+ },
+ {
+ "USBCORE_DIRECT_FLUSH_HW_QUEUE": {
+ "format": "[USBCORE] direct flush_hw_q dir = %d, md_q = %l, ap_q = %l",
+ "traceClass": "USBCORE_CLASS_REQUEST_H"
+ }
+ },
+ {
+ "USBCORE_DIRECT_FLUSH_SW_QUEUE": {
+ "format": "[USBCORE] direct flush_sw_q dir = %d, md_q = %l, ap_q = %l",
+ "traceClass": "USBCORE_CLASS_REQUEST_H"
+ }
+ },
+ {
+ "USBCORE_DIRECT_CHK_QUEUE_EMPTY": {
+ "format": "[USBCORE] direct check queue empty isTx = %d, md_q = %l, ap_q = %l, isEmpty = %l",
+ "traceClass": "USBCORE_CLASS_REQUEST_UH"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_DRB": {
+ "format": "[USBCORE] polling drb_q[%d], returns %l field(s), startIdx %l, endIdx %l",
+ "traceClass": "USBCORE_POLL_QUEUE_M"
+ }
+ },
+ {
+ "USBCORE_POLL_QUEUE_XIT": {
+ "format": "[USBCORE] polling xit_q[%d], returns %l field(s), startIdx %l, endIdx %l",
+ "traceClass": "USBCORE_POLL_QUEUE_M"
+ }
+ },
+ {
+ "USBCORE_CHK_UL_META": {
+ "format": "[USBCORE] CHK UL META: type = %d, startIdx %l, endIdx %l",
+ "traceClass": "USBCORE_POLL_QUEUE_UL"
+ }
+ },
+ {
+ "USBCORE_DEBUG_XIT_ENQ1": {
+ "format": "[USBCORE] DBG XIT: index = %d, len = %l, data_addr = %l",
+ "traceClass": "USBCORE_POLL_QUEUE_UL"
+ }
+ },
+ {
+ "USBCORE_DEBUG_XIT_ENQ2": {
+ "format": "[USBCORE] DBG_XIT: dump: %d, %l, %l, %l",
+ "traceClass": "USBCORE_POLL_QUEUE_UL"
+ }
+ }
+ ],
+ "traceFamily": "L2",
+ "userModule": "MOD_USBCORE"
+}
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_debug.h b/mcu/middleware/hif/usbcore/include/usbcore_debug.h
new file mode 100644
index 0000000..09e1f08
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_debug.h
@@ -0,0 +1,129 @@
+#ifndef _USBCORE_DEBUG_H
+#define _USBCORE_DEBUG_H
+
+#define HIF_DATA_TRACE_ENABLED 1
+#define USBCORE_CONSOLE_TRACE_ENABLED 0
+
+#include "hif_trace.h"
+#include "TrcMod.h"
+#include <ex_public.h>
+
+extern void dbg_print(char *fmt,...);
+
+
+#if USBCORE_CONSOLE_TRACE_ENABLED
+ /*
+ * Print indexed trace to console.
+ */
+ #if defined(__MTK_TARGET__)
+ #define usbc_console_print dbg_print
+ #else
+ #define usbc_console_print
+ #endif
+
+ #define usbc_trace_error(...) usbc_console_print(__VA_ARGS__)
+ #define usbc_trace_warn(...) usbc_console_print(__VA_ARGS__)
+ #define usbc_trace_info(...) usbc_console_print(__VA_ARGS__)
+ #define usbc_data_trace hif_data_trace
+#else
+
+ /*
+ * Use DHL logging.
+ */
+ #define usbc_trace_error(trc_name, ...) \
+ do{ \
+ if(INT_QueryExceptionStatus() == KAL_FALSE) \
+ { \
+ MD_TRC_##trc_name(__VA_ARGS__); \
+ } \
+ }while(0)
+
+ #define usbc_trace_warn(trc_name, ...) \
+ do{ \
+ if(INT_QueryExceptionStatus() == KAL_FALSE) \
+ { \
+ MD_TRC_##trc_name(__VA_ARGS__); \
+ } \
+ }while(0)
+
+ #define usbc_trace_info(trc_name, ...) \
+ do{ \
+ if(INT_QueryExceptionStatus() == KAL_FALSE) \
+ { \
+ MD_TRC_##trc_name(__VA_ARGS__); \
+ } \
+ }while(0)
+
+ #define usbc_trace_func(trc_name, ...) \
+ do{ \
+ if(INT_QueryExceptionStatus() == KAL_FALSE) \
+ { \
+ MD_TRC_##trc_name(__VA_ARGS__); \
+ } \
+ }while(0)
+
+ #define usbc_data_trace hif_data_trace
+#endif /* USBCORE_CONSOLE_TRACE_ENABLED */
+
+
+#include "usbcore_trace.h"
+#include "dhl_trace.h"
+
+typedef enum
+{
+ USBCORE_UNIQUE_CODE_CLASS_START = 0,
+ USBCORE_UNIQUE_CODE_CLASS_RNDIS,
+ USBCORE_UNIQUE_CODE_CLASS_CDCACM,
+ USBCORE_UNIQUE_CODE_CLASS_ADB,
+ USBCORE_UNIQUE_CODE_CLASS_MSE,
+ USBCORE_UNIQUE_CODE_CLASS_ECM,
+ USBCORE_UNIQUE_CODE_CLASS_MBIM,
+ USBCORE_UNIQUE_CODE_CLASS_NUM
+}usbcore_unique_code_class_module;
+
+#define USBCORE_LOC_ASSERT_UNIQUE_CODE_BASE 0xA5200000
+typedef enum
+{
+ USBCORE_LOC_UNQIUE_CODE_START = USBCORE_LOC_ASSERT_UNIQUE_CODE_BASE,
+ USBCORE_LOC_SEND_OVER_CCCI_FAIL,
+ USBCORE_LOC_SEND_OVER_CCCI_TIMEOUT,
+ USBCORE_LOC_READ_OVER_CCCI_FAIL,
+ USBCORE_LOC_AP_RESPONSE_TIMEOUT,
+ USBCORE_LOC_AP_SET_STALL_INVALID_EP,
+ USBCORE_LOC_DUAL_OWNER_TIMER_INIT_FAIL,
+ USBCORE_LOC_INIT_CCCI_CHANNEL_FAIL_1,
+ USBCORE_LOC_INIT_CCCI_CHANNEL_FAIL_2,
+ USBCORE_LOC_INIT_CCCI_CHANNEL_FAIL_3,
+ USBCORE_LOC_DUALIPC_INVALID_PARAMETER,
+ USBCORE_LOC_CCCI_NO_SUPPORT_RUNTIME_FEATURE,
+ USBCORE_LOC_DRV_NOTIFY_INVALID_EVENT,
+ USBCORE_LOC_POLLED_RX_NULL_GPD,
+ USBCORE_LOC_QUERY_QUE_DEVICE_NOT_REGISTER,
+ USBCORE_LOC_QUERY_QUE_OVERSIZE_QUE_NUMBER,
+ USBCORE_LOC_QUERY_QUE_CLASS_ID_NOT_MATCH, //0xA5200010
+ USBCORE_LOC_REGISTER_CLASS_NOT_INITIALIZE,
+ USBCORE_LOC_DEREGISTER_CLASS_NOT_REGISTERED,
+ USBCORE_LOC_SUBMIT_CTRL_REQ_CLASS_NOT_REGISTERED,
+ USBCORE_LOC_NO_ABILITY_TO_REMOTE_WK,
+ USBCORE_LOC_DEVICE_SET_CONFIG_FUNC_NULL,
+ USBCORE_LOC_DEVICE_RX_COMPLETE_FUNC_NULL,
+ USBCORE_LOC_TASK_INVALID_ITEM,
+ USBCORE_LOC_TASK_QUE_FULL,
+ USBCORE_LOC_GET_MODE_LID_INFO_FOR_ENUM_FAIL,
+ USBCORE_LOC_GET_MODE_LID_INFO_FOR_SET_FAIL,
+ USBCORE_LOC_GET_MODE_LID_INFO_FOR_AT_GET_FAIL,
+ USBCORE_LOC_GET_MODE_LID_VALUE_FAIL,
+ USBCORE_LOC_GET_EMEI_LID_INFO_FAIL,
+ USBCORE_LOC_GET_EMEI_LID_VALUE_FAIL,
+ USBCORE_LOC_GET_SN_LID_INFO_FOR_ENUM_FAIL,
+ USBCORE_LOC_GET_SN_LID_INFO_FOR_SET_FAIL, //0xA5200020
+ USBCORE_LOC_GET_SN_LID_INFO_FOR_AT_GET_FAIL,
+ USBCORE_LOC_GET_STATUS_EP_STATUS_INVALID,
+ USBCORE_LOC_GET_STATUS_INVALID_RECIP,
+ USBCORE_LOC_MODIFY_CONFIG_DESC_OVERSIZE_FOR_U3_EP_COMP,
+ USBCORE_LOC_MODIFY_CONFIG_DESC_OVERSIZE,
+ USBCORE_LOC_ITEMS_NUM
+}usbcore_assert_loc_e;
+
+#endif /* _USBCORE_DEBUG_H */
+
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_dual_owner.h b/mcu/middleware/hif/usbcore/include/usbcore_dual_owner.h
new file mode 100644
index 0000000..f84b29d
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_dual_owner.h
@@ -0,0 +1,152 @@
+/*!
+ * @file usbcore_dual_owner.h
+ * @author Yuhao Ye <yuhao.ye@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE TYPE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main definitions of usbcore
+ */
+
+#ifndef _DUAL_USB_OWNER_H
+#define _DUAL_USB_OWNER_H
+
+#include "kal_public_api.h"
+#include "usbc_custom.h"
+#include "usbcore_common.h"
+#include "nccci_if.h"
+
+#define USB_CLASS_MAX_IF_NUM 4
+#define USB_IF_MAX_EP_NUM 4
+#define USB_DEVICE_MAX_IF_NUM 16
+#define USB_MAX_AP_CLASS_DEVICE 8
+#define MSG_ID_USB_DUAL_OWNER_MSG_RECEIVE 1
+#define USB_DUAL_OWNER_WRITE_DONE_MAX_TICK 2000
+
+typedef enum{
+ APUBS_SETUP_RSP_IDLE = 0,
+ APUBS_SETUP_RSP_INIT,
+ APUSB_SETUP_RSP_SUCCESS,
+ APUSB_SETUP_RSP_FAIL,
+ APUSB_SETUP_RSP_DATA,
+ APUSB_SETUP_RSP_STALL,
+ APUSB_SETUP_RSP_TIMEOUT,
+ APUSB_SETUP_RSP_NUM,
+}apusb_setup_rsp_e;
+
+typedef enum{
+ APUSB_MSG_ID_UNKNOWN = 0,
+ APUSB_RSP_STATUS_SUCCESS,
+ APUSB_RSP_STATUS_STALL,
+ APUSB_RSP_SEND_DATA,
+ APUSB_NOTIFY_EVT_REMOTE_WAKEUP,
+ APUSB_NOTIFY_EVT_EP_HALT,
+ APUSB_NOTIFY_EVT_RESET_DONE,
+ APUSB_NOTIFY_EVT_SUSPEND_DONE,
+ APUSB_NOTIFY_EVT_ATTACHED_DONE,
+ APUSB_MSG_ID_NUM
+}apusb_msg_id_e;
+
+typedef enum {
+ NOTIFY_MSG_ID_UNKNOWN = 0,
+ NOTIFY_EVT_ATTACHED,
+ NOTIFY_EVT_DETACHED,
+ NOTIFY_EVT_SUSPEND,
+ NOTIFY_EVT_RESUME,
+ NOTIFY_EVT_RESET,
+ NOTIFY_EVT_CLASS_CTRL_REQ,
+ NOTIFY_EVT_FEATURE_SC,
+ NOTIFY_EVT_CTRL_DATA,
+ NOTIFY_EVT_FUNCTION_RESUME,
+ NOTIFY_EVT_SUSPENDED,
+ NOTIFY_EVT_IP_PWRDOWN,
+ NOTIFY_MSG_ID_NUM
+} mdusb_msg_id_e;
+
+typedef enum{
+ USB_CLASS_TYPE_UNKNOWN = 0,
+ USB_CLASS_TYPE_CDC_ACM1,
+ USB_CLASS_TYPE_CDC_ACM2,
+ USB_CLASS_TYPE_CDC_ACM3,
+ USB_CLASS_TYPE_ADB,
+ USB_CLASS_TYPE_MS,
+ USB_CLASS_TYPE_NUM
+}dual_usb_owner_class_type_e;
+
+typedef struct
+{
+ kal_uint8 endpoint_num;
+ kal_uint8 endpoint_direct;
+}apusb_ep_info_s;
+
+/*msg struct send to AP over CCCI*/
+typedef struct{
+ mdusb_msg_id_e msg_type;
+ kal_uint32 msg_length;
+}dual_usb_owner_msg_hdr_s;
+
+typedef struct{
+ dual_usb_owner_msg_hdr_s msg_hdr;
+ char msg_data[CCCI_PAYLOAD_SIZE];
+}dual_usb_owner_msg_s;
+
+typedef struct{
+ kal_uint32 class_device_id;
+ kal_uint32 endpoint_address;
+ hifusb_usb_xfer_type_e ep_type;
+ kal_uint32 maxpacketsize;
+}endpoint_info_s;
+
+typedef struct{
+ kal_uint32 interface_id;
+ usbc_interface_type_e interface_type;
+}interface_info_s;
+
+typedef struct{
+ kal_uint32 class_device_id;
+ dual_usb_owner_class_type_e class_device_type;
+ kal_uint32 total_interface_num;
+ interface_info_s if_info[USB_CLASS_MAX_IF_NUM];
+ endpoint_info_s ep_info[USB_IF_MAX_EP_NUM];
+}class_device_info_s;
+
+typedef struct{
+ kal_uint32 total_class_device;
+ class_device_info_s class_device_info[USB_MAX_AP_CLASS_DEVICE];
+}usb_deivce_info_s;
+
+void dual_owner_funciton_register();
+void dual_usb_owner_set_ap_rsp_timer();
+kal_bool dual_usb_owner_send_device_state(kal_uint32 type, kal_uint8 ext);
+#endif // _DUAL_USB_OWNER_H
+
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_hif.h b/mcu/middleware/hif/usbcore/include/usbcore_hif.h
new file mode 100644
index 0000000..4c5d5e2
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_hif.h
@@ -0,0 +1,442 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * usbcore_hif.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * USB Core HIF interface shared between normal and exception modes.
+ * One can tell the type of HIF interface from function name prefix:
+ * (1) usbc_normal_hif_xxx(): implementation for normal mode HIF.
+ * (2) usbc_core_xxx(): shared between normal mode and exception mode HIF.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef _USBCORE_HIF_H
+#define _USBCORE_HIF_H
+
+#include "hif_usb.h"
+#include "usbcore_main.h"
+#include "usbcore_debug.h"
+
+typedef kal_bool (*USBC_INDICATE_CONTROL_SETUP_PACKET)(kal_uint8 intf_idx, usbc_setup_packet_t *packet);
+typedef void (*USBC_INDICATE_CONTROL_COMPLETE)(kal_uint8 intf_idx);
+typedef void (*USBC_INDICATE_ALTERNATE_SETTING)(kal_uint8 intf_idx, kal_uint8 alternate_setting);
+typedef void (*USBC_INDICATE_STALL)(kal_bool is_tx, kal_uint8 queue_idx, kal_bool stall);
+typedef kal_bool (*USBC_SET_CONTROL_REQUEST)(kal_uint8* buffer, kal_uint32 length, usbc_control_request_type_e type);
+typedef kal_bool (*USBC_SET_PROPERTY)(hifusb_property_t *p_property);
+typedef kal_bool (*USBC_SET_USB_ADDRESS)(kal_uint8 address);
+typedef kal_bool (*USBC_SET_USB_CONFIGURATION)(kal_uint8 configuration);
+typedef void (*USBC_SET_STALL)(kal_bool is_tx, kal_uint8 nEnd);
+typedef void (*USBC_RST_EP)(kal_bool is_tx, kal_uint8 nEnd);
+typedef void (*USBC_CLEAR_STALL)(kal_bool is_tx, kal_uint8 nEnd);
+typedef kal_bool (*USBC_SET_USB_TESTMODE)(hifusb_test_mode_e testmode);
+typedef void (*USBC_SET_SS_DEV_INIT_U1_EN)(kal_bool);
+typedef void (*USBC_SET_SS_DEV_INIT_U2_EN)(kal_bool);
+typedef void (*USBC_SET_USBHIF_ADDRESS)(kal_uint8);
+typedef void (*USBC_SET_UFBHIF_CONFIGURATION)(kal_uint8);
+typedef kal_bool (*USBC_SET_USBHIF_CONNECT)(void);
+typedef kal_bool (*USBC_SET_USBHIF_DISCONNECT)(void);
+typedef kal_bool (*USBC_SET_USBHIFQ_GPD)(hif_queue_type_e, kal_uint8, qbm_gpd*, qbm_gpd*);
+typedef kal_uint32 (*USBC_POLL_USBHIFQ_GPD)(hif_deq_info_t deq_info, void **first_gpd, void **last_gpd);
+typedef kal_bool (*USBC_CHECK_USBHIFQ_EMPTY)(hif_queue_type_e core_queue_hif_type, kal_uint8 q_num);
+typedef kal_uint32 (*USBC_FLUSH_USBHIFQ_GPD)(hif_queue_type_e, kal_uint8, hif_flush_type_e, void**, void**);
+typedef kal_uint32 (*USBC_FLUSH_SW_USBHIFQ_GPD)(hif_queue_type_e, kal_uint8, hif_flush_type_e, void**, void**);
+typedef kal_bool (*USBC_CHK_NEWPKT)(kal_bool, kal_uint8);
+typedef void (*USBC_START_DATAQ)(kal_bool, kal_uint8);
+typedef void (*USBC_POWER_DOWN)(void);
+typedef void (*USBC_SET_CLOCK_CG)(kal_bool);
+typedef void (*USBC_MASK_WAKEUP_EVENT)(kal_bool);
+typedef void (*USBC_MASK_INTR)(kal_bool);
+
+typedef void (*USBC_DUAL_OWNER_OPERATION)(void);
+typedef kal_bool (*USBC_DUAL_OWNER_NOTIFY_EVENT)(kal_uint32 type, kal_uint8 ext);
+
+/*------------------------------------------------------------------------------
+ * USB Core HIF interface shared between normal mode and exception mode.
+ *----------------------------------------------------------------------------*/
+/*!
+ * @brief indicate the setup packet up to specified USB CLASS interface.
+ */
+extern USBC_INDICATE_CONTROL_SETUP_PACKET usbc_core_indicate_control_setup_packet;
+
+/*!
+ * @brief indicate the complete complete to specified USB CLASS interface.
+ */
+extern USBC_INDICATE_CONTROL_COMPLETE usbc_core_indicate_control_complete;
+
+/*!
+ * @brief indicate the alternate setting set by host to specified interface.
+ */
+extern USBC_INDICATE_ALTERNATE_SETTING usbc_core_indicate_alternate_setting;
+
+/*!
+ * @brief indicate the alternate setting set by host to specified interface.
+ */
+extern USBC_INDICATE_STALL usbc_core_indicate_stall;
+
+/*!
+ * @brief write or read control transfer data buffer and status to hif driver
+ */
+extern USBC_SET_CONTROL_REQUEST usbc_core_set_control_request;
+
+/*!
+ * @brief set USB device and endpoint related settings to hif driver
+ */
+extern USBC_SET_PROPERTY usbc_core_set_property;
+
+/*!
+ * @brief update USB address to hif driver
+ */
+extern USBC_SET_USB_ADDRESS usbc_core_set_usb_address;
+
+/*!
+ * @brief set usb configuration to hif driver
+ */
+extern USBC_SET_USB_CONFIGURATION usbc_core_set_usb_configuration;
+
+/*!
+ * @brief set endpoint stall to hif driver
+ */
+extern USBC_SET_STALL usbc_core_set_stall;
+
+/*!
+ * @brief reset endpoint to hif driver
+ */
+extern USBC_RST_EP usbc_core_rst_ep;
+/*!
+ * @brief clear endpoint stall to hif driver
+ */
+extern USBC_CLEAR_STALL usbc_core_clear_stall;
+
+/*!
+ * @brief set test mode to hif driver
+ */
+extern USBC_SET_USB_TESTMODE usbc_core_set_usb_testmode;
+
+/*!
+ * @brief enable U1 to hif driver
+ */
+extern USBC_SET_SS_DEV_INIT_U1_EN usbc_core_set_ss_dev_init_u1_en;
+
+/*!
+ * @brief enable U2 to hif driver
+ */
+extern USBC_SET_SS_DEV_INIT_U2_EN usbc_core_set_ss_dev_init_u2_en;
+
+/*!
+ * @brief HIF API for setting address
+ */
+extern USBC_SET_USBHIF_ADDRESS usbc_core_set_usbhif_address;
+
+/*!
+ * @brief HIF API for setting configuration
+ */
+extern USBC_SET_UFBHIF_CONFIGURATION usbc_core_set_usbhif_configuration;
+
+/*!
+ * @brief HIF API for attaching to USB IP driver
+ */
+extern USBC_SET_USBHIF_CONNECT usbc_core_set_usbhif_connect;
+
+/*!
+ * @brief HIF API for deattaching to USB IP driver
+ */
+extern USBC_SET_USBHIF_DISCONNECT usbc_core_set_usbhif_disconnect;
+
+
+/*!
+ * @brief HIF QBM API for submit GPDs to USB QMU
+ */
+extern USBC_SET_USBHIFQ_GPD usbc_core_set_usbhifq_gpd;
+
+/*!
+ * @breif HIF QMU API for polling GPDs
+ */
+extern USBC_POLL_USBHIFQ_GPD usbc_core_poll_hifusbq_qpd;
+
+extern USBC_CHECK_USBHIFQ_EMPTY usbc_core_check_hifusbq_empty;
+
+extern USBC_FLUSH_USBHIFQ_GPD usbc_core_flush_hifusbq_gpd;
+
+extern USBC_FLUSH_SW_USBHIFQ_GPD usbc_core_flush_sw_hifusbq_gpd;
+
+extern USBC_CHK_NEWPKT usbc_core_check_new_packet;
+
+/*!
+ * @brief Start ULQ/DLQ to hif driver
+ */
+extern USBC_START_DATAQ usbc_core_start_dataq;
+
+extern USBC_POWER_DOWN usbc_core_power_down;
+
+extern USBC_MASK_WAKEUP_EVENT usbc_core_mask_wakeup_event;
+
+extern USBC_SET_CLOCK_CG usbc_core_set_clock_cg;
+
+extern USBC_MASK_INTR usbc_core_mask_intr;
+
+/*!
+ * @brief for USB dual owner function point
+ */
+extern USBC_DUAL_OWNER_OPERATION usbc_dual_owner_init;
+extern USBC_DUAL_OWNER_OPERATION usbc_dual_owner_ilm_handle;
+extern USBC_DUAL_OWNER_OPERATION usbc_dual_owner_class_ctrl_request;
+extern USBC_DUAL_OWNER_OPERATION usbc_dual_owner_class_ctrl_complete;
+extern USBC_DUAL_OWNER_OPERATION usbc_dual_owner_send_feature_request;
+extern USBC_DUAL_OWNER_NOTIFY_EVENT usbc_dual_owner_notify_event;
+
+#ifdef __USBCORE_DEBUG__
+/*!
+ * @brief dump gpd content for debug purpose
+ */
+void usbc_core_dump_gpd_list(void* first_gpd, void* last_gpd);
+#endif
+
+/*!
+ * @brief fill up HIF IP dependent settings to hif driver
+ */
+kal_bool usbc_core_set_hif_configuration(void);
+
+/*!
+ * @brief USB Core internal implementation to dispatch setup packet
+ * @param pUsbCore USB Core context
+ * @param p_setup setup packet to parse
+ * @return KAL_TRUE if it has been handled in this function;
+ * KAL_FALSE if it will be handled in task context later.
+ */
+kal_bool usbc_core_dispatch_control_setup_packet(usbc_core_t *pUsbCore, hifusb_setup_packet_t *p_setup);
+
+/*!
+ * @brief USB Core internal implementation for control transfer complete post-processing
+ * @param pUsbCore USB Core context
+ */
+void usbc_core_notify_control_complete(usbc_core_t *pUsbCore);
+
+/*!
+ * @brief Change USB speed and related descriptors.
+ * @param pUsbCore USB Core context
+ */
+void usbc_core_speed_change(usbc_core_t *pUsbCore, usbc_usb_speed_e speed);
+
+
+/*------------------------------------------------------------------------------
+ * USB Core internal implementation for HIF normal mode.
+ *----------------------------------------------------------------------------*/
+/*!
+ * @brief ask hif driver to initiate
+ */
+kal_bool usbc_normal_hif_init(void);
+
+/*!
+ * @brief ask hif driver to shutdown
+ */
+kal_bool usbc_normal_hif_shutdown(void);
+
+/*!
+ * @brief ask hif driver to connect
+ */
+kal_bool usbc_normal_hif_connect(void);
+
+/*!
+ * @brief ask hif driver to disconnect
+ */
+kal_bool usbc_normal_hif_disconnect(void);
+
+/*!
+ * @brief ask hif driver to remote wakeup
+ */
+kal_bool usbc_normal_hif_remote_wakeup(void);
+/*!
+ * @brief ask hif driver to send function wakeup notification
+ */
+kal_bool usbc_normal_hif_ss_wk_notify(kal_uint8 nInterface);
+
+/*!
+ * @brief poll hif each queue to see if any data available
+ */
+void usbc_normal_hif_poll_queue(void);
+
+/*!
+ * @brief Process indications queued in USBCORE task context
+ */
+void usbc_normal_hif_process_indications(void);
+
+/*!
+ * @brief Fill up HIF function pointers with nomral mode HIF implementation
+ */
+void usbc_normal_hif_factory(void);
+
+/*!
+ * @brief Fill up HIF function pointers with meta mode HIF implementation
+ */
+void usbc_meta_hif_factory(void);
+
+/*!
+ * @breif Fill up HIF function pointers with USB suspended HIF implementation
+ */
+void usbc_suspended_hif_factory(void);
+
+#ifdef ATEST_SYS_USBCORE
+/*!
+ * @brief Fill up HIF function pointers with dummy HIF implementation
+ */
+void usbc_fake_hif_factory(void);
+#endif
+
+void usbc_direct_hif_factory(void);
+
+/*!
+ * @brief Emulate HIFUSB_NOTIFY_EVT_RESET, SetAddress, and SetConfiguration in META mode
+ */
+void usbc_normal_hif_meta_attach(void);
+
+/*!
+ * @brief Check for reusing META COM
+ */
+kal_bool usbc_normal_hif_is_meta_reused(void);
+
+/*!
+ * @brief Restore Buffered GPDs to hardware
+ */
+kal_bool usbc_normal_hif_restore_gpd_pwrsave(void);
+
+/*!
+ * @brief set pwr flag
+ */
+void usbc_normal_hif_set_pwr_flag(kal_bool flag);
+
+/*!
+ * @brief print GPD length info
+ */
+void usbc_core_trace_gpd_info(qbm_gpd* first_gpd, qbm_gpd* last_gpd, kal_uint8 q_no, kal_bool isTx, kal_bool flag);
+
+/*!
+ * @brief clear enum request record
+ */
+void usbc_core_clear_enum_record();
+
+usbcore_unique_code_class_module usbcore_classid_to_module(kal_uint8 class_device_id);
+#endif // _USBCORE_HIF_H
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_ind_q.h b/mcu/middleware/hif/usbcore/include/usbcore_ind_q.h
new file mode 100644
index 0000000..2b6aeab
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_ind_q.h
@@ -0,0 +1,142 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * usbcore_ind_q.h
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * USB Core indication queue operations.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef _USBCORE_IND_Q_H
+#define _USBCORE_IND_Q_H
+
+#define USBC_IND_CTRL_SETUP 0 /**< Control transfer setup packet indication. */
+#define USBC_IND_CTRL_CMPLT 1 /**< Control transfer data phase complete. */
+#define USBC_IND_DEV_EVENT 2 /**< USB device event indication. */
+#define USBC_IND_SPEED_CHANGE 3 /**< USB speed changed notification. */
+#define USBC_IND_ALT_SETTING 4 /**< USB interface alternate setting set by host. */
+#define USBC_IND_PIPE_STALL 5 /**< USB pipe HALT state is set or cleared by host. */
+#define USBC_IND_MODE_SWITCH 6 /**< USB mode switch indication */
+#define USBC_IND_FUNC_EVENT 7 /**< USB function event indication. */
+#define USBC_IND_SET_CONFIG 8 /**< USB Set configuration */
+#define USBC_IND_UFPM_POLL 9 /**< USB direct poll queue */
+#define USBC_IND_IP_PWRDOWN 10 /**< USB direct poll queue */
+
+
+/*!
+ * @brief Information to indication up to USB Class.
+ */
+typedef struct _usbc_ind {
+ kal_uint8 ext:4; /**< Extended data specific to each type of indication. */
+ kal_uint8 type:4; /**< Type of indication, see USBC_IND_XXX for details. */
+ kal_uint8 data; /**< Data specific to each type of indication. */
+} usbc_ind_t;
+
+
+/*!
+ * @brief Empty the USB queue of indication
+ */
+void usbc_empty_ind_queue(void);
+
+/*!
+ * @brief Copy and enqueue an indication object.
+ * @param indication [IN] Pointer to the indication object to enqueue.
+ */
+void usbc_enqueue_ind(usbc_ind_t *indication);
+
+/*!
+ * @brief Dequeue an indication object if available.
+ * @param indication [OUT] Caller allocated space for the indication object dequeued.
+ * @return KAL_TURE if there's an indicaiton object dequeue; KAL_FALSE otherwise.
+ */
+kal_bool usbc_dequeue_ind(usbc_ind_t *indication);
+
+void usbc_empty_ind_queue();
+
+kal_bool usbc_ind_queue_spinlock_init();
+
+kal_bool usbc_queue_empty_check();
+#endif
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_main.h b/mcu/middleware/hif/usbcore/include/usbcore_main.h
new file mode 100644
index 0000000..98d0de4
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_main.h
@@ -0,0 +1,666 @@
+/*!
+ * @file usbcore_main.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main definitions of usbcore
+ */
+
+#ifndef _USBCORE_MAIN_H
+#define _USBCORE_MAIN_H
+
+#include "usbcore_common.h"
+#include "hif_usb.h"
+#include "usbcore_usbstd.h"
+#include "usbcore_class_device.h"
+#include "hifusb_qmu.h"
+#include "ubm_export.h"
+
+//#define __USBCORE_DEBUG__
+
+#ifdef __USBCORE_DEBUG__
+#define usbc_core_printf kal_printf
+#else
+#if defined(__MTK_TARGET__)
+#define usbc_core_printf(fmt, args...)
+#else
+#define usbc_core_printf(fmt, ...)
+#endif
+#endif
+
+#define __USBCORE_CHECK__
+#ifdef __USBCORE_CHECK__
+ #define USBC_IS_IN_EXCEPTION_MODE() \
+ ( USBC_OP_MODE_EXCEPTION == usbc_get_op_mode() )
+
+ #define USBC_EXCEPTION_MODE_CHECK() \
+ ASSERT( USBC_IS_IN_EXCEPTION_MODE() )
+
+ #define USBC_NON_EXCEPTION_MODE_CHECK() \
+ ASSERT( !USBC_IS_IN_EXCEPTION_MODE() )
+
+ #define USBC_CORE_INSTANCE_CHECK(_inst) \
+ ASSERT( NULL != (_inst))
+#else
+ #define USBC_IS_IN_EXCEPTION_MODE()
+
+ #define USBC_EXCEPTION_MODE_CHECK()
+
+ #define USBC_NON_EXCEPTION_MODE_CHECK()
+
+ #define USBC_CORE_INSTANCE_CHECK(_inst)
+#endif
+
+#define USBC_CLASS_DEVICE_CONTEXT_CHECK() \
+ ASSERT(!kal_if_hisr())
+
+#define USBC_QUEUE_GPD_TAKE_MUTEX(_s) \
+ kal_take_enh_mutex(_s)
+
+#define USBC_QUEUE_GPD_GIVE_MUTEX(_s) \
+ kal_give_enh_mutex(_s)
+
+/*!
+ * @brief MAX_USBCORE_DEVICE_NUM defines the maximum value of class
+ * devices usbcore can handle
+ */
+#define MAX_USBCORE_DEVICE_NUM 16
+
+/*!
+ * @brief KAL interval for resending function remote wakeup notification
+ * The min. interval is 2500ms to notify the host.
+ */
+#ifdef __HAPS_FPGA_CLK_ADJUST__
+#define USBC_WK_NOTIFY_CHECK_MS (25 * KAL_TICKS_100_MSEC_REAL)
+#else
+#define USBC_WK_NOTIFY_CHECK_MS (25 * KAL_TICKS_100_MSEC)
+#endif
+
+/*!
+ * @brief KAL ticks duration for checking device resuming
+ */
+#define USBC_DEV_RESUME_DURATION_TICK 2
+
+/*!
+ * @brief KAL ticks duration for checking AP response
+ */
+#define USBC_DEV_DURATION_AP_RSP_TICK 1
+
+/*!
+ * @brief KAL ticks duration for checking CCCI DL done
+ */
+#define USBC_DEV_DURATION_CCCI_DL_DONE_TICK 1
+
+/*!
+ * @brief KAL event scheduler for function wakreup notification tiemout
+ */
+#define USBC_WK_NOTIFY_INDEX 1
+
+/*!
+ * @breif Warpper for KAL enhanced mutex
+ */
+#define USBC_CLASS_REMOTE_WK_LOCK(_s) kal_take_enh_mutex(_s)
+#define USBC_CLASS_REMOTE_WK_UNLOCK(_s) kal_give_enh_mutex(_s)
+
+#define USBC_CLASS_COMMON_LOCK(_s) kal_take_enh_mutex(_s)
+#define USBC_CLASS_COMMON_UNLOCK(_s) kal_give_enh_mutex(_s)
+
+#define USBC_CLASS_COMMON_SPIN_LOCK(_s) kal_take_spinlock(_s, KAL_INFINITE_WAIT)
+#define USBC_CLASS_COMMON_SPIN_UNLOCK(_s) kal_give_spinlock(_s)
+
+#define USBC_POLLED_CHECK_DURATION 25
+#define USBC_POLLED_CHECK_SHOW_ONLY_NO_DATA 1
+
+#define USBC_POLLED_CHECK_DURATION_TIME_MAX 10000 //10ms
+/*!
+ * @brief timeout time for AP rsp request.
+ */
+#define USBC_AP_RSP_CHECK_MS (50 * KAL_TICKS_100_MSEC_REAL)
+#define USBC_AP_SUSPEND_DISABLE_CG_TIMEOUT 5000000
+#define USBC_AP_EVT_DONE_TIMEOUT 1500000
+
+#define USBC_READ_FILE_PATH_MAX_LENGTH 128
+#define USBC_READ_FILE_DATA_MAX_LENGTH 128
+typedef enum{
+ MSD_DISABLE = 0,
+ MSD_ENABLE,
+ MSD_INVALID,
+}usbc_ms_enable_e;
+
+
+/*!
+ * @brief USBCORE ATCMD handle function table sturture
+ */
+typedef kal_bool (*USBC_HANDLE_ATCMD_FUNC)(void *data_in, void *data_out);
+typedef struct
+{
+ char cmd_type[32];
+ USBC_HANDLE_ATCMD_FUNC handle_set_func;
+ USBC_HANDLE_ATCMD_FUNC handle_get_func;
+}usbc_atcmd_hd_t;
+/*!
+ * @brief configruation read from HMU.
+ */
+typedef struct _usbc_hmu_info {
+ /*!
+ * @brief USB enumeration tiemout in unit of ms.
+ */
+ kal_uint32 enum_timeout;
+ /*!
+ * @brief Tx transfer tiemout in unit of ms.
+ */
+ kal_uint32 tx_timeout;
+} usbc_hmu_info_t;
+
+/*
+ * @brief USB descriptors compiled.
+ */
+typedef struct _usbc_descriptors_t {
+ kal_uint8 device[USBC_DEVICE_DESC_SIZE];
+ kal_uint8 configuration[MAX_USBCORE_CONFIG_NUM][USBC_MAX_CONF_SIZE];
+} usbc_descriptors_t;
+
+
+/*!
+ * @brief usbc_core_class_device_t describe class device information maintain
+ * within usbcore
+ */
+typedef struct _usbc_core_class_device_t {
+ /*!
+ * @brief class type of this device
+ */
+ usb_class_type_e class_type;
+ /*!
+ * @brief current state of this device
+ */
+ usbc_core_class_device_state_e state;
+ /*!
+ * @brief current class device owner
+ */
+ usb_class_owner_e owner;
+ /*!
+ * @brief total pipes of this device
+ */
+ kal_uint8 total_pipes;
+ kal_uint8 rsvd[1];
+ /*!
+ * @brief returning device instance to class driver
+ */
+ usbc_class_device_instance_t device_instance;
+ /*!
+ * @brief callback function while usb state changed
+ */
+ void (*notify_usb_state)(kal_uint8 class_device_id, usbc_usb_state_e state);
+ /*!
+ * @brief callback function while usb speed changed
+ */
+ void (*notify_usb_speed)(kal_uint8 class_device, usbc_usb_speed_e speed);
+ /*!
+ * @brief the status of the class device
+ */
+ kal_bool is_func_suspend;
+ /*!
+ * @brief callback function while set or clear function remote wakeup ability
+ */
+ void (*notify_func_wk_ability)(kal_uint8 class_device_id, kal_bool ability);
+ /*!
+ * @brief callback function to known the class device status
+ */
+ kal_uint16 (*query_func_wk_status)(kal_uint8 class_device_id);
+} usbc_core_class_device_t;
+
+typedef struct _usbc_core_xit_meta_t {
+ kal_bool xit2meta_retry;
+ kal_uint32 remain_num;
+ kal_uint32 startIdx;
+ kal_uint32 endIdx;
+} usbc_core_xit_meta_t;
+
+/*!
+ * @brief usbc_core_t describe main structure of usbcore
+ */
+typedef struct _usbc_core {
+ /*!
+ * @brief HMU events indication that USBCORE task is going to wait
+ */
+ kal_uint32 hmu_indication;
+
+ usb_mode_e mode;
+ kal_bool is_mode_switch;
+
+ /*!
+ * @brief current usb speed
+ */
+ usbc_usb_speed_e speed;
+ /*!
+ * @brief current usb state
+ */
+ usbc_usb_state_e state;
+ usbc_usb_state_e state_in_hisr;
+ /*!
+ * @brief KAL_TRUE if the setup_packet will be handled by USBCLASS; KAL_FALSE if it has been handled by USBCORE.
+ */
+ kal_bool setup_indicated;
+ kal_uint8 rsvd0[1];
+ /*!
+ * @brief current setup packet
+ */
+ usbc_setup_packet_t setup_packet;
+ /*!
+ * @brief the state machine of setup handle
+ */
+ usbc_setup_packet_sm_e setup_status;
+ /*!
+ * @brief the spinlock for setup pakcet protect
+ */
+ kal_spinlockid setup_packet_spinlock;
+ /*!
+ * @brief control request buffer to send or receive
+ */
+ kal_uint8 control_request_buffer[MAX_USBCORE_CONTROL_REQUEST_BUFFER_SIZE];
+
+ /*!
+ * @brief current device qualifier descriptor
+ */
+ usbc_device_qualifier_descriptor_t device_qualifier_descriptor;
+
+ /* device parameter got from usb custom */
+ usb_dev_param_t* dev_param;
+
+ /* get the ability of morhping from NVRAM */
+ kal_bool morphing_enable;
+
+ /* Resource */
+ kal_uint8 resource_interface_number[MAX_USBCORE_CONFIG_NUM];
+ kal_uint8 resource_string_number;
+ kal_uint8 resource_iad_number[MAX_USBCORE_CONFIG_NUM];
+ kal_uint8 resource_ep_tx_number[MAX_USBCORE_CONFIG_NUM];
+ kal_uint8 resource_ep_rx_number[MAX_USBCORE_CONFIG_NUM];
+ usbc_interface_info_t if_info[MAX_USBCORE_CONFIG_NUM][MAX_USBCORE_INTERFACE_NUM];
+ usbc_interface_association_descriptor_t iad_descriptor[MAX_USBCORE_CONFIG_NUM][MAX_USBCORE_IAD_NUM];
+ usbc_endpoint_info_t ep_tx_info[MAX_USBCORE_CONFIG_NUM][MAX_USBCORE_QUEUE_NUM];
+ usbc_endpoint_info_t ep_rx_info[MAX_USBCORE_CONFIG_NUM][MAX_USBCORE_QUEUE_NUM];
+
+ /*!
+ * @brief current string descriptor
+ */
+ usbc_string_descriptor_t* string_descriptor[MAX_USBCORE_STRING_DESCRIPTOR_NUM];
+
+ /*!
+ * @brief current usb address in Set Address Request
+ */
+ kal_uint8 usb_address;
+ /*!
+ * @brief current selected configuration in Set Configuration Request
+ */
+ kal_uint8 usb_configuration;
+
+ /*!
+ * @brief total configurated class devices
+ */
+ kal_uint8 total_class_devices;
+ /*!
+ * @brief total configurated class interfaces
+ */
+ kal_uint8 total_class_interfaces;
+ /*!
+ * @brief total configurated transmit queues
+ */
+ kal_uint8 total_tx_queues;
+ /*!
+ * @brief total configurated receive queues
+ */
+ kal_uint8 total_rx_queues;
+
+ /*!
+ * @brief class device information
+ */
+ usbc_core_class_device_t class_device[MAX_USBCORE_DEVICE_NUM];
+
+ /*!
+ * @brief class interface information
+ */
+ usbc_core_class_interface_t class_interface[MAX_USBCORE_INTERFACE_NUM];
+ /*!
+ * @brief transmit queue information
+ */
+ usbc_core_queue_t tx_queue[MAX_USBCORE_QUEUE_NUM];
+ /*!
+ * @brief receive queue information
+ */
+ usbc_core_queue_t rx_queue[MAX_USBCORE_QUEUE_NUM];
+
+ /*!
+ * @brief USB descriptors compiled.
+ */
+ usbc_descriptors_t descriptors;
+
+ kal_bool morph_active;
+
+ /*!
+ * @brief current status of device
+ */
+ kal_bool is_device_u1_enable;
+ kal_bool is_device_u2_enable;
+ kal_bool is_device_ltm_enable;
+
+ /*!
+ * @brief MUTEX for remote wakeup
+ */
+ kal_enhmutexid usbc_class_remote_wk_mutex;
+
+ /*!
+ * @brief keep the information for device suspend after function suspend
+ */
+ event_scheduler* usbc_es_wk_notify_g;
+ kal_bool func_notify_list[MAX_USBCORE_DEVICE_NUM];
+ eventid wk_eventid;
+ kal_enhmutexid usbc_class_renotify_mutex;
+ kal_bool is_func_be_accessed[MAX_USBCORE_DEVICE_NUM];
+ kal_enhmutexid usbc_class_func_access_mutex;
+
+ /*!
+ * @brief MUTEX for resume
+ */
+ kal_enhmutexid usbc_class_resume_mutex;
+
+ /*!
+ * @brief Check for META mode
+ */
+ kal_bool is_mode_meta;
+ kal_bool is_mode_meta_reused;
+
+ /*!
+ * @brief bMaxPower for USB 3.0 configuratyion
+ */
+ kal_uint8 u3ConfMaxPower;
+
+ /*!
+ * @brief USB XIT queue status for META translation
+ */
+ usbc_core_xit_meta_t rx_xit_meta[MAX_USBCORE_QUEUE_NUM];
+
+ kal_uint16 usbc_txq_polled_mask;
+ kal_uint16 usbc_rxq_polled_mask;
+ kal_uint16 usbc_q_polled_duration;
+
+ /*!
+ * @brief setup buffer for OUT request in AP owner port, send to AP over CCCI
+ */
+ kal_uint8 ap_setup_buf[MAX_USBCORE_CONTROL_REQUEST_BUFFER_SIZE];
+ kal_uint32 ap_setup_buf_rx_expected_len;
+
+ kal_timerid usbc_es_ap_rsp_timerid;
+ /*!
+ * @brief flag for waiting AP echo
+ */
+ kal_bool ap_response_reset_evt_done;
+ kal_uint32 ap_response_evt_time;
+ kal_bool waiting_ap_clk_disable_flag;
+ /*!
+ * @brief rx flush operation and submit spinlock
+ */
+ kal_enhmutexid rx_submit_enhmuexid[MAX_USBCORE_QUEUE_NUM];
+
+ /*!
+ * @brief flag for enable USB lowpower feature
+ */
+ kal_bool config_has_ap_port;
+ kal_bool usb_low_power_enable;
+ kal_bool usbc_wait_wakeup_event;
+ kal_timerid usbc_ap_rsp_suspend_done_timerid;
+ kal_timerid usbc_ap_rsp_attached_done_timerid;
+} usbc_core_t;
+
+
+/*!
+ * @brief switch USBCORE operation mode.
+ * @return current USBCORE operation mode, see usbc_op_mode_e for more information.
+ */
+usbc_op_mode_e usbc_get_op_mode(void);
+
+
+/*!
+ * @brief set USBCORE operation mode.
+ * @param op_mode USBCORE operation mode to set, see usbc_op_mode_e for more information.
+ */
+void usbc_set_op_mode(usbc_op_mode_e op_mode);
+
+
+/*!
+ * @brief get instance of USBCORE module
+ * @return pointer to usbc_core_t* instance if success, NULL if fail
+ */
+usbc_core_t *usbc_core_get_instance(void);
+
+
+/*!
+ * @brief get settings read from HMU
+ * @return pointer the usbc_hmu_info_t object for these setting.
+ */
+usbc_hmu_info_t *usbc_core_get_hmu_info(void);
+
+
+/*!
+ * @brief force returning to non-register state
+ */
+void usbc_core_clear_register(void);
+
+
+/*!
+ * @brief notify all existed class drivers that usb state is changed to
+ * attaching
+ */
+void usbc_core_notify_state_attaching(void);
+
+
+/*!
+ * @brief notify all existed class drivers that usb state is changed to
+ * attached
+ */
+void usbc_core_notify_state_attached(void);
+
+
+/*!
+ * @brief notify all existed class drivers that usb state is changed to
+ * detaching
+ */
+void usbc_core_notify_state_detaching(void);
+
+
+/*!
+ * @brief notify all existed class drivers that usb state is changed to
+ * suspending
+ */
+void usbc_core_notify_state_suspending(void);
+
+
+/*!
+ * @brief notify all existed class drivers that usb state is changed to
+ * resume
+ */
+void usbc_core_notify_state_resume(void);
+
+
+/*!
+ * @brief notify all existed class drivers that usb state is changed to
+ * reset
+ */
+void usbc_core_notify_state_reset(void);
+
+
+/*!
+ * @brief notify all existed class drivers that usb speed is changed
+ * @param speed new USB link speed
+ */
+void usbc_core_notify_speed_change(usbc_usb_speed_e speed);
+
+
+/*!
+ * @brief notify the interface that its alternate setting is set by host
+ * @param intf_idx indext to the interface
+ * @param alternate_setting alternate setting set by host
+ */
+void usbc_core_notify_alternate_setting(kal_uint8 intf_idx, kal_uint8 alternate_setting);
+
+
+/*!
+ * @brief notify the endpoint that its HALT state is changed by host
+ * @param is_tx KAL_TURE for OUT endpoint; KAL_FALSE for IN endpoint
+ * @param queue_idx internal queue index of the endpoint
+ * @param stall KAL_TRUE if it's been set STALL; KAL_FALSE if it's been cleared STALL
+ */
+void usbc_core_notify_stall(kal_bool is_tx, kal_uint8 queue_idx, kal_bool stall);
+
+
+/*!
+ * @brief handle usb standard request
+ */
+kal_bool usbc_core_handle_standard_request(void);
+
+/*!
+ * @brief handle usb vendor request
+ */
+void usbc_core_handle_vendor_request(void);
+
+
+/*!
+ * @brief Modify descriptors according to current USB speed.
+ * @param pUsbCore USB Core context
+ * @param speed Current USB speed
+ */
+void usbc_core_descriptors_speed_change(usbc_core_t *pUsbCore, usbc_usb_speed_e speed);
+
+
+/*!
+ * @brief Internal implementaion of usb class device registration
+ * @param class_device_id [IN] USB class device instance id
+ * @param pUsbCore USB Core context
+ * @param device_info class device information used to register
+ * @return new instance of usb class device if success, NULL if fail
+ */
+usbc_class_device_instance_t *usbc_core_device_register(kal_uint8 class_device_id, usbc_core_t *pUsbCore, usbc_class_device_info_t *device_info);
+
+
+/*!
+ * @brief Query information about the queue of an USB calss device instance.
+ * @param class_device_id [IN] USB class device instance id
+ * @param queue_no [IN] Queue number to query
+ * @param queue [OUT] Caller allocated space for a pointer to the queue object. Its value is invalid if no matched queue found.
+ * @param queue_type [OUT] Type of the queue. Its value is invalid if no matched queue found.
+ * @return KAL_TURE if matched queue found; KAL_FALSE otherwise.
+ */
+kal_bool usbc_core_get_queue_info(kal_uint8 class_device_id, kal_uint8 queue_no, usbc_core_queue_t **queue, hif_queue_type_e *queue_type);
+
+
+/*!
+ * @brief clear device status and function status to default setting
+ */
+void usbc_core_clear_status(void);
+
+
+/*!
+ * @brief check if the given interface is the first one of any functions
+ */
+kal_bool usbc_core_is_1st_interface(kal_uint8 idx);
+
+
+/*!
+ * @brief get the first interface of the given function
+ */
+kal_uint8 usbc_class_device_get_1st_interface(kal_uint8 class_device_id);
+
+/*!
+ * @brief Notify the USB state to specific USB classes
+ */
+void usbc_core_indicate_function_state(kal_uint8 class_device_id, usbc_usb_state_e state);
+
+/*!
+ * @brief Notify the requested class driver that usb state is changed to suspending
+ * @param idx [IN] USB class_device_id
+ */
+void usbc_core_notify_function_state_suspending(kal_uint8 class_device_id);
+
+
+/*!
+ * @brief notify the requested class driver that usb state is changed to resume
+ * @param idx [IN] USB class_device_id
+ */
+void usbc_core_notify_function_state_resume(kal_uint8 class_device_id);
+
+
+/*!
+ * @brief notify the requested class driver to enable or disable function remote wakeup
+ * @param idx [IN] USB class_device_id
+ * @param ability [IN] Enable or disable the function remote wakeup capability. KAL_TRUE for enable, and KAL_FALSE for disable.
+ */
+void usbc_core_notify_func_wk_ability(kal_uint8 class_device_id, kal_bool ability);
+
+
+/*!
+ * @brief get the bitmap of functions that enable remote wakeup
+ * @return the bit map of funtions that enable remote wakeup
+ */
+kal_uint16 usbc_core_get_function_remote_wk_list(void);
+
+/*!
+ * @brief get the bitmap of functions that are suspended
+ * @return the bit map of funtions that are suspended
+ */
+kal_uint16 usbc_core_get_function_suspend_list(void);
+
+/*!
+ * @brief set IMEI as the serial number of USB device descriptor
+ */
+kal_bool usbc_core_set_serial_number(void);
+
+/*!
+ * @brief set USB serial number from NVRAM
+ */
+kal_uint8 usbc_set_serial_number_for_internal();
+
+/*!
+ * @brief USBCORE ATCMD handle fucntion
+ */
+kal_bool usbc_core_handle_set_serialnumber_atcmd(void *data_req, void *data_cnf);
+kal_bool usbc_core_handle_set_usb_mode_atcmd(void *data_req, void *data_cnf);
+kal_bool usbc_core_handle_get_serialnumber_atcmd(void *data_req, void *data_cnf);
+kal_bool usbc_core_handle_get_usb_mode_atcmd(void *data_req, void *data_cnf);
+kal_bool usbc_core_handle_powerdown_usb_atcmd(void *req, void *cnf);
+void usbc_core_check_low_power_enable();
+void usbc_core_check_mass_strorage_onoff();
+
+#endif // _USBCORE_MAIN_H
+
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_mode.h b/mcu/middleware/hif/usbcore/include/usbcore_mode.h
new file mode 100644
index 0000000..5f8cef0
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_mode.h
@@ -0,0 +1,245 @@
+/*!
+ * @file usbcore_mode.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides mode related definitions of usbcore
+ */
+
+#ifndef _USBCORE_MODE_H
+#define _USBCORE_MODE_H
+
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+
+/*!
+ * @brief USBC_DEF_BCDDEV defines default bcd device
+ */
+#define USBC_DEF_BCDDEV 0x0001
+
+
+/*!
+ * @brief USBC_DEF_STR_IDX_LANGUAGE defines default language string index
+ */
+#define USBC_DEF_STR_IDX_LANGUAGE 0x00
+
+
+/*!
+ * @brief USBC_DEF_IDX_MANUFACTURER defines default manufacturer string index
+ */
+#define USBC_DEF_STR_IDX_MANUFACTURER 0x01
+
+
+/*!
+ * @brief USBC_DEF_IDX_PRODUCT defines default product string index
+ */
+#define USBC_DEF_STR_IDX_PRODUCT 0x02
+
+
+/*!
+ * @brief USBC_DEF_IDX_SERIALNUM defines default serial number string index
+ */
+#define USBC_DEF_STR_IDX_SERIALNUM 0x03
+
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+
+/*!
+ * @brief USBC_USB11_MAX_PACKET_SIZE define maximum packet size in USB SPEED 1.1
+ */
+#define USBC_USB11_MAX_PACKET_SIZE 64
+
+
+/*!
+ * @brief USBC_USB20_MAX_PACKET_SIZE define maximum packet size in USB SPEED 2.0
+ */
+#define USBC_USB20_MAX_PACKET_SIZE 512
+
+
+/*!
+ * @brief USBC_USB30_MAX_PACKET_SIZE define maximum packet size in USB SPEED 3.0
+ */
+#define USBC_USB30_MAX_PACKET_SIZE 1024
+
+
+/*!
+ * @brief usbc_core_mode_e enumerate all possible modes of USBCORE module
+ * @param USBC_CORE_MODE_MIN pseudo mode
+ * @param USBC_CORE_MODE_ACM 1 CDC-ACM COM
+ * @param USBC_CORE_MODE_ECM 1 CDC-ECM
+ * @param USBC_CORE_MODE_RNDIS 1 RNDIS
+ * @param USBC_CORE_MODE_CDROM 1 Mass Storage CDROM
+ * @param USBC_CORE_MODE_DISK 1 Mass Storage Disk
+ * @param USBC_CORE_MODE_MBIM 1 MBIM
+ * @param USBC_CORE_MODE_1RNDIS_1ACM 1 RNDIS 1 CDC-ACM
+ * @param USBC_CORE_MODE_1RNDIS_2ACM 1 RNDIS 2 CDC-ACM
+ * @param USBC_CORE_MODE_1ECM_1ACM 1 CDC-ECM 1 CDC-ACM
+ * @param USBC_CORE_MODE_2ACM 2 CDC-ACM
+ * @param USBC_CORE_MODE_3ACM 3 CDC-ACM
+ * @param USBC_CORE_MODE_1RNDIS_1ACM_1CDROM 1 RNDIS 1 CDC-ACM 1 CDROM
+ * @param USBC_CORE_MODE_1ECM_1ACM_1CDROM 1 CDC-ECM 1 CDC-ACM 1 CDROM
+ * @param USBC_CORE_MODE_MAX pseudo mode
+ */
+typedef enum _usbc_core_mode {
+ USBC_CORE_MODE_MIN = 0,
+ USBC_CORE_MODE_ACM = 1,
+ USBC_CORE_MODE_ECM = 2,
+ USBC_CORE_MODE_RNDIS = 3,
+ USBC_CORE_MODE_CDROM = 4,
+ USBC_CORE_MODE_DISK = 5,
+ USBC_CORE_MODE_MBIM = 6,
+ USBC_CORE_MODE_1RNDIS_1ACM = 7,
+ USBC_CORE_MODE_1RNDIS_2ACM = 8,
+ USBC_CORE_MODE_1ECM_1ACM = 9,
+ USBC_CORE_MODE_2ACM = 10,
+ USBC_CORE_MODE_3ACM = 11,
+ USBC_CORE_MODE_1RNDIS_1ACM_1CDROM = 12,
+ USBC_CORE_MODE_1ECM_1ACM_1CDROM = 13,
+#ifdef __USB_MSD_SUPPORT__
+ USBC_CORE_MODE_MSD =14,
+ USBC_CORE_MODE_1ACM_1MSD =15,
+#endif
+ USBC_CORE_MODE_1MBIM_1ACM = 16,
+ USBC_CORE_MODE_MAX = 99,
+} usbc_core_mode_e;
+
+
+/*!
+ * @brief set the mode usbcore will run at
+ */
+void usbc_core_set_mode(usbc_core_mode_e mode);
+
+
+/*!
+ * @brief SetUp all things for MODE CDC_ACM
+ */
+void usbc_core_set_mode_acm(void);
+
+
+/*!
+ * @brief SetUp all things for MODE RNDIS
+ */
+void usbc_core_set_mode_rndis(void);
+
+
+/*!
+ * @brief SetUp all things for MODE 1MBIM_1ACM
+ */
+void usbc_core_set_mode_1mbim_1acm(void);
+
+
+/*!
+ * @brief SetUp all things for MODE 1RNDIS_1ACM
+ */
+void usbc_core_set_mode_1rndis_1acm(void);
+
+
+/*!
+ * @brief SetUp all things for MODE 1RNDIS_2ACM
+ */
+void usbc_core_set_mode_1rndis_2acm(void);
+
+/*!
+ * @brief SetUp all things for MODE 1RNDIS_3ACM
+ */
+void usbc_core_set_mode_3acm(void);
+
+/*!
+ * @brief Set up an USB device with one MBIM function.
+ */
+void usbc_core_set_mode_mbim(void);
+/*!
+ * @brief Set up an USB device with one MSD function.
+ */
+void usbc_core_set_mode_msd(void);
+
+void usbc_core_set_mode_1acm_1msd();
+
+#endif // _USBCORE_MODE_H
+
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_trace.h b/mcu/middleware/hif/usbcore/include/usbcore_trace.h
new file mode 100644
index 0000000..5eb4764
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_trace.h
@@ -0,0 +1,17 @@
+#ifndef _USBCORE_TRACE_H_
+#define _USBCORE_TRACE_H_
+#if HIF_CONSOLE_TRACE_ENABLED != 1
+#ifndef GEN_FOR_PC
+ #include "stack_config.h"
+#endif /* GEN_FOR_PC */
+#include "dhl_trace.h"
+#include "dhl_def.h"
+#if !defined(GEN_FOR_PC)
+#if defined(__DHL_MODULE__) || defined(__CUSTOM_RELEASE__)
+#endif /* TST Trace Defintion */
+#endif
+#endif /* HIF_CONSOLE_TRACE_ENABLED != 1 */
+#if !defined(GEN_FOR_PC)
+#include"usbcore_trace_mod_usbcore_utmd.h"
+#endif
+#endif /* _USBCORE_TRACE_H_ */
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_trace_mod_usbcore_utmd.json b/mcu/middleware/hif/usbcore/include/usbcore_trace_mod_usbcore_utmd.json
new file mode 100644
index 0000000..530d996
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_trace_mod_usbcore_utmd.json
@@ -0,0 +1,606 @@
+{
+ "legacyParameters": {},
+ "module": "MOD_USBCORE",
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "TRACE_ERROR": {
+ "debugLevel": "Ultra-High",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "TRACE_WARNING": {
+ "debugLevel": "High",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "TRACE_INFO": {
+ "debugLevel": "Medium",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "TRACE_STATE": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline"
+ ],
+ "traceType": "CoreDesign"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "USBCORE_TASK_INIT": {
+ "format": "[USBCORE] usbcore task initialization",
+ "traceClass": "TRACE_STATE"
+ }
+ },
+ {
+ "USBCORE_TASK_RESET": {
+ "format": "[USBCORE] usbcore task reset",
+ "traceClass": "TRACE_STATE"
+ }
+ },
+ {
+ "USBCORE_TASK_CREATE": {
+ "format": "[USBCORE] usbcore task create",
+ "traceClass": "TRACE_STATE"
+ }
+ },
+ {
+ "USBCORE_TASK_MAIN": {
+ "format": "[USBCORE] usbcore task main",
+ "traceClass": "TRACE_STATE"
+ }
+ },
+ {
+ "USBCORE_ALL_NODE_CHECKIN": {
+ "format": "[USBCORE] all nodes have been checked in",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_ALL_NODE_CHECKIN_INIT_CLASS_START": {
+ "format": "[USBCORE] start initialing classes after all nodes checked in: class type = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_ALL_NODE_CHECKIN_INIT_CLASS_END": {
+ "format": "[USBCORE] finish initialing classes after all nodes checked in: class type = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_ALL_NODE_CHECKIN_REINIT_CLASS_START": {
+ "format": "[USBCORE] start re-initialing classes after all nodes checked in: class index = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_ALL_NODE_CHECKIN_REINIT_CLASS_END": {
+ "format": "[USBCORE] finish re-initialing classes after all nodes checked in: class index = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_DISPATCH_REQUEST": {
+ "format": "[USBCORE] usbcore dispatches requests: bmRequestType = 0x%x",
+ "traceClass": "TRACE_STATE"
+ }
+ },
+ {
+ "USBCORE_SET_ADDRESS": {
+ "format": "[USBCORE] usbcore handles set_address: addr = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_GET_STATUS": {
+ "format": "[USBCORE] usbcore handles get_status: bRecip = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_SET_FEATURE": {
+ "format": "[USBCORE] usbcore handles set_feature: bRecip = 0x%x, wIndex = 0x%x, wValue = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_CLEAR_FEATURE": {
+ "format": "[USBCORE] usbcore handles clear_feature: bRecip = 0x%x, wIndex = 0x%x, wValue = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_GET_DESCRIPTOR": {
+ "format": "[USBCORE] usbcore handles get_descriptor: bRecip = 0x%x, type = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_SET_CONFIG": {
+ "format": "[USBCORE] usbcore handles set_configuration: wValue = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_GET_CONFIG": {
+ "format": "[USBCORE] usbcore handles get_configuration: wValue = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_SET_INFX": {
+ "format": "[USBCORE] usbcore handles set_interface: bInterface = 0x%x, wValue = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_GET_INFX": {
+ "format": "[USBCORE] usbcore handles get_interface: bInterface = 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_EVENT_ATTACH": {
+ "format": "[USBCORE] usbcore receives ATTACH events from HIF driver",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_EVENT_DETACH": {
+ "format": "[USBCORE] usbcore receives DETACH events from HIF driver",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_EVENT_SUSPEND": {
+ "format": "[USBCORE] usbcore receives SUSPEND events from HIF driver",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_EVENT_RESUME": {
+ "format": "[USBCORE] usbcore receives RESUME events from HIF driver",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_EVENT_RESET": {
+ "format": "[USBCORE] usbcore receives RESET events from HIF driver",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_EVENT_SPEED_CHANGE": {
+ "format": "[USBCORE] usbcore changes speed in HIF driver reset: original speed 0x%x to new speed 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_EVENT_UNKNOWN": {
+ "format": "[USBCORE] usbcore receives unknown events from HIF driver",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_HIF_SET_CONFIG": {
+ "format": "[USBCORE] usbcore is setting config: %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_SET_CONFIG_UNCHANGED": {
+ "format": "[USBCORE] usbcore doesn't set config (config unchaged)",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_HIF_SET_CONFIG_REINIT_START": {
+ "format": "[USBCORE] usbcore starts usbclass reinit in HIF SET CONF",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_HIF_SET_CONFIG_REINIT_END": {
+ "format": "[USBCORE] usbcore finishes usbclass reinit in HIF SET CONF",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_HIF_SET_CONFIG_USBCLASS": {
+ "format": "[USBCORE] usbcore calls set config callback usbclass type %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_HIF_SET_CONFIG_HIF": {
+ "format": "[USBCORE] usbcore calls HIF driver to set config: %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_HIF_SET_CONFIG_ADDR_STATE": {
+ "format": "[USBCORE] usbcore goes to address state after setting config",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_HIF_SET_CONFIG_CONF_STATE": {
+ "format": "[USBCORE] usbcore goes to configuration state after setting config",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_CONF_INVALID": {
+ "format": "[USBCORE] usbcore receives an invalid configuration: %d",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_REMOTE_WK_START": {
+ "format": "[USBCORE] usb class id %d starts calling function remote wk",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_REMOTE_WK_INVALID": {
+ "format": "[USBCORE] the class id %d doesn't enable function remote wk: status 0x%x",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_REMOTE_WK_DEVICE": {
+ "format": "[USBCORE] the class id %d asks the USB device to remote wakeup",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_REMOTE_WK_DEVICE_WAIT": {
+ "format": "[USBCORE] the class id %d waits for device resuming",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_REMOTE_WK_FUNC": {
+ "format": "[USBCORE] the class id %d asks USBCORE to wakeup its function",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_REMOTE_WK_SET_NOTIFY_TIMER": {
+ "format": "[USBCORE] usbcore sets remote wk notify timer for the class id %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_REMOTE_WK_HIF_NOTIFY": {
+ "format": "[USBCORE] usbcore asks HIF driver to send wk notification for interface %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_NOTIFY_CLASS_START": {
+ "format": "[USBCORE] usbcore calls usbclass's notify state: class type = %d, state = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_NOTIFY_CLASS_END": {
+ "format": "[USBCORE] usbcore finishs usbclass's notify state: class type = %d, state = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_NOTIFY_WK_ABILITY_START": {
+ "format": "[USBCORE] usbcore starts notifing wk ability to usbclass: class type = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_NOTIFY_WK_ABILITY_END": {
+ "format": "[USBCORE] usbcore finishs notifing wk ability to usbclass: class type = %d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_NOTIFY_WK_ABILITY_INVALID": {
+ "format": "[USBCORE] invalid notifing wk ability to usbclass: class type = %d",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_DEV_SUSPEND_CLOCK": {
+ "format": "[USBCORE] usbcore sets clock gating = %d, notifies usbidle = %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DEV_SUSPEND_L4": {
+ "format": "[USBCORE] usbcore sets l4 power saving = %d, notifies ILM = %d, suspend = %d, remote wk =%d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_SUSPEND_STOP_POLL": {
+ "format": "[USBCORE] usbcore stop polling GPDs",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_SUSPEND_START_POLL": {
+ "format": "[USBCORE] usbcore start polling GPDs",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_RESTORE_BFF_GPD": {
+ "format": "[USBCORE] usbcore restore buffered GPDs in queue %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_FLUSH_BFF_GPD": {
+ "format": "[USBCORE] usbcore flushes buffered GPDs in queue %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_UPDATE_API_BUFF_GPD": {
+ "format": "[USBCORE] usbcore updates API for buffering GPDs: %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_CLASS_OP_INACTIVATE_QUE": {
+ "format": "[USBCORE] the class id %d uses inactivated queue %d",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_MODE_NVRAM_SELECT": {
+ "format": "[USBCORE] usbcore mode NVRAM select vendor:%d, index%d, mode:%d ret:%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_MODE_DEFAULT_CFG_SELECT": {
+ "format": "[USBCORE] usbcore mode default select mode:%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_DEBUG_CONFIGURATION_PORT_INFO": {
+ "format": "[USBCORE] usbcore port_info class idx:%d, type:%s, owner:%d, uart_port%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_DEBUG_CONFIGURATION_PORT_EP_INFO": {
+ "format": "[USBCORE] usbcore port_info class idx:%d, tx_ep start:%d, num:%d, rx_ep start:%d, num:%d",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_NOTIFY_USB_STATE": {
+ "format": "[USBCORE] usbcore dual_owner notify USB state %d length: %d ret :%d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_NOTIFY_FEATURE_SC": {
+ "format": "[USBCORE] usbcore dual_owner feature set/clear, request:%d value:%d index:%d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_NOTIFY_SEND_CLASS_REQUEST": {
+ "format": "[USBCORE] usbcore dual_owner send class req, request:%d value:%d index:%d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_SEND_CLASS_REQUEST_NO_RSP": {
+ "format": "[USBCORE] usbcore dual_owner send class request no rsp request:%d value:%d index:%d",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_RECEIVE_CCCI_DL_DONE_TIMEOUT": {
+ "format": "[USBCORE] usbcore dual_owner CCCI write done callback timeout.",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_SEND_CTRL_OUT_DATA": {
+ "format": "[USBCORE] usbcore dual_owner send EP0 out data length:%d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_CCCI_WRITE": {
+ "format": "[USBCORE] usbcore dual_owner write ccci fail ret:%d",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_CCCI_READ": {
+ "format": "[USBCORE] usbcore dual_owner read ccci fail ret:%d",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_IN_DATA_LEN_ERROR": {
+ "format": "[USBCORE] usbcore dual_owner IN request data expect length:%d actual length:%d ",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_RECEIVE_ILM_MSG": {
+ "format": "[USBCORE] usbcore dual_owner receive ILM MSG msg_id %d, length %d.",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_RECEIVE_REMOTE_WAKEUP": {
+ "format": "[USBCORE] usbcore dual_owner send function resume after remote wakeup from device%d.",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DUAL_OWNER_DEBUG_ATTACHED_INFO": {
+ "format": "[USBCORE] usbcore dual_owner attached info %s:%d, %s:%d.",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_RECEIVE_ATCMD_MSG": {
+ "format": "[USBCORE] usbcore receive ATCMD msg data:%s, handle result:%d.",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_DUALIPC_INFO": {
+ "format": "[USBCORE] usbcore dualipc dipcmode:%d, port_mode:%d, pcie_state:%d.",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "USBCORE_FACTORY_MODE_INFO": {
+ "format": "[USBCORE] usbcore get META mode from CCCI start_id:%d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_POLL_TICK_TIMEOUT": {
+ "format": "[USBCORE] usbcore get polling tick timeout duration : %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_POLL_ALL_QUEUE_EMPTY": {
+ "format": "[USBCORE] polling all queue %d times empty, tx 0x%x, rx 0x%x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_CLASS_FLUSH_HW_QUEUE_PS": {
+ "format": "[USBCORE] flush HW_q[0x%x], returns %d GPD(s), first gpd %x, last gpd %x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_CLASS_FLUSH_SW_QUEUE_PS": {
+ "format": "[USBCORE] flush SW_q[0x%x], returns %d GPD(s), first gpd %x, last gpd %x",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_CLASS_CHECK_SUBMIT_TX_GPD_KPI": {
+ "format": "[USBCORE] submit tx_q %d gpd %x length %d, bd number %d bypass %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_CLASS_CHECK_POLL_TX_GPD_KPI": {
+ "format": "[USBCORE] polled tx_q %d gpd %x length %d, bd number %d bypass %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_CLASS_CHECK_SUBMIT_RX_GPD_KPI": {
+ "format": "[USBCORE] submit rx_q %d gpd %x length %d, bd number %d bypass %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_CLASS_CHECK_POLL_RX_GPD_KPI": {
+ "format": "[USBCORE] polled rx_q %d gpd %x length %d, bd number %d bypass %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_FLUSH_RX_HW_GPD_WITH_SUBMIT": {
+ "format": "[USBCORE] flush HW queue %d, returns gpd %x length %d, and submit",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_FLUSH_RX_SW_GPD_WITH_SUBMIT": {
+ "format": "[USBCORE] flush SW queue %d, returns gpd %x length %d, and submit",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_RECEIVE_MULTI_SETUP_PACKET": {
+ "format": "[USBCORE] receive multi-setup , state machine: %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_MULTI_SETUP_PACKET_RETURN_STALL": {
+ "format": "[USBCORE] return STALL after multi-setup packet",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_GET_NETWORK_TYPE": {
+ "format": "[USBCORE] current network type is %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_SET_USB_WAKEUP_EVENT": {
+ "format": "[USBCORE] set usb wakeup event from eint",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_WAIT_AP_SUSPEND_DOWN_TIMEOUT": {
+ "format": "[USBCORE] ap suspend done timeout",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_WAIT_AP_RESET_DOWN_TIMEOUT": {
+ "format": "[USBCORE] ap reset done timeout",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_WAIT_AP_ATTACH_DOWN_TIMEOUT": {
+ "format": "[USBCORE] ap attach done timeout",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_SET_CG_ON": {
+ "format": "[USBCORE] USBCORE set USB cg on",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "USBCORE_GET_LOW_POWER_ENABLE_VALUE": {
+ "format": "[USBCORE] USBCORE get low power value: %d",
+ "traceClass": "TRACE_WARNING"
+ }
+ }
+ ],
+ "traceFamily": "PS",
+ "userModule": "MOD_USBCORE"
+}
diff --git a/mcu/middleware/hif/usbcore/include/usbcore_ut.h b/mcu/middleware/hif/usbcore/include/usbcore_ut.h
new file mode 100644
index 0000000..a393f33
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/include/usbcore_ut.h
@@ -0,0 +1,34 @@
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_usbstd.h"
+#include "hif_common.h"
+#include "hif_usb.h"
+#include "usbcore_main.h"
+#include "usbcore_class_device.h"
+
+#define USBC_UT_FAKE_CLASS_CALLBACK 0
+
+#define usbc_core_set_ss_dev_init_u1_en(...)
+#define usbc_core_set_ss_dev_init_u2_en(...)
+#define hifusb_ss_func_wk_notify usbc_ut_fake_notify_retry
+#define hifusb_remote_wakeup usbc_ut_fake_hif_remote_wakeup
+
+#define USBC_UT_BLOCK_TICK_T 2
+
+typedef kal_uint16 usbc_ut_fake_infx_status;
+
+typedef struct usbc_ut_fake_class_func_info {
+ usbc_ut_fake_infx_status infx_status;
+ kal_uint8 nRetry;
+} usbc_ut_fake_class_func_info_t;
+
+kal_uint16 usbc_ut_fake_query_func_wk_status(kal_uint8 class_device_id);
+
+void usbc_ut_fake_notify_func_wk_ability(kal_uint8 class_device_id, kal_bool ability);
+
+kal_bool usbc_ut_fake_notify_retry(kal_uint8 nInterface);
+
+kal_bool usbc_ut_fake_hif_remote_wakeup();
+
+kal_bool usbc_ut_fake_set_control_request(kal_uint8 *buffer, kal_uint32 length, usbc_control_request_type_e type);
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_class_device.c b/mcu/middleware/hif/usbcore/src/usbcore_class_device.c
new file mode 100644
index 0000000..bc4a784
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_class_device.c
@@ -0,0 +1,1118 @@
+/*!
+ * @file usbcore_class_device.c
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides functions of usbcore class device interface
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_main.h"
+#include "usbcore_class_device.h"
+#include "usbcore_hif.h"
+#include "hifusb_qmu.h"
+#include "hif_ior.h"
+#include "usbcore_ind_q.h"
+#include "hmu.h"
+#include "usbcore_debug.h"
+#include "usbidle_if.h"
+#include "hif_swla.h"
+#include "usbidle_if.h"
+#include "hif_mw_msgid.h"
+#include "usbc_custom.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+
+#ifdef ATEST_SYS_USBCORE
+#include "usbcore_ut.h"
+#endif
+#include "us_timer.h"
+
+#define INVALID_CLASS_DEVICE_ID 0xff
+#define INVALID_PIPE_QUEUE_ID 0xff
+#define PIPE_QUEUE_RX_MASK 0x80
+
+usbcore_unique_code_class_module usbcore_classid_to_module(kal_uint8 class_device_id)
+{
+ usb_class_type_e type;
+ usbcore_unique_code_class_module module;
+ type = usbc_core_get_instance()->class_device[class_device_id].class_type;
+
+ switch(type)
+ {
+#ifdef __USB_ACM_SUPPORT__
+ case USB_CLASS_ACM1:
+ case USB_CLASS_ACM2:
+ case USB_CLASS_ACM3:
+ module = USBCORE_UNIQUE_CODE_CLASS_CDCACM;
+ break;
+#endif
+#ifdef __USB_RNDIS_SUPPORT__
+ case USB_CLASS_RNDIS:
+ module = USBCORE_UNIQUE_CODE_CLASS_RNDIS;
+ break;
+#endif
+#ifdef __USB_ADB_SUPPORT__
+ case USB_CLASS_ADB:
+ module = USBCORE_UNIQUE_CODE_CLASS_ADB;
+ break;
+#endif
+#ifdef __USB_MBIM_SUPPORT__
+ case USB_CLASS_MBIM:
+ module = USBCORE_UNIQUE_CODE_CLASS_MBIM;
+ break;
+#endif
+#ifdef __USB_ECM_SUPPORT__
+ case USB_CLASS_ECM:
+ module = USBCORE_UNIQUE_CODE_CLASS_ECM;
+ break;
+#endif
+//#ifdef __USB_MSD_SUPPORT__
+ case USB_CLASS_MS:
+ module = USBCORE_UNIQUE_CODE_CLASS_MSE;
+ break;
+//#endif
+ default:
+ module = USBCORE_UNIQUE_CODE_CLASS_START;
+ break;
+ }
+ return module;
+}
+
+static void release_class_device(kal_uint8 class_device_id)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 i = 0;
+
+ pUsbCore->class_device[class_device_id].state = USBC_CORE_CLASS_DEVICE_STATE_INITIATED;
+
+ for ( i=0; i<pUsbCore->total_class_interfaces; i++ )
+ {
+ if (pUsbCore->class_interface[i].class_device_id == class_device_id)
+ {
+ pUsbCore->class_interface[i].state = USBC_CORE_CLASS_INTERFACE_STATE_INITIATED;
+ }
+ }
+}
+
+
+static kal_uint8 acquire_pipe_queue(kal_uint8 class_device_id, usbc_pipe_type_e type)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 pipe_queue = INVALID_PIPE_QUEUE_ID;
+ kal_uint8 i = 0;
+
+ for ( i=0; i< MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->tx_queue[i].class_device_id == class_device_id) &&
+ (pUsbCore->tx_queue[i].pipe_type == type) &&
+ (pUsbCore->tx_queue[i].state == USBC_CORE_QUEUE_STATE_INITIATED))
+ {
+ pipe_queue = i;
+ break;
+ }
+ }
+
+ if ( pipe_queue != INVALID_PIPE_QUEUE_ID )
+ {
+ return pipe_queue;
+ }
+
+ for ( i=0; i< MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->rx_queue[i].class_device_id == class_device_id) &&
+ (pUsbCore->rx_queue[i].pipe_type == type) &&
+ (pUsbCore->rx_queue[i].state == USBC_CORE_QUEUE_STATE_INITIATED))
+ {
+ pipe_queue = (i | PIPE_QUEUE_RX_MASK);
+ break;
+ }
+ }
+
+ return pipe_queue;
+}
+
+
+static void release_pipe_queue(kal_uint8 class_device_id)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 i = 0;
+
+ for ( i=0; i< MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if (pUsbCore->tx_queue[i].class_device_id == class_device_id)
+ {
+ pUsbCore->tx_queue[i].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ }
+ if (pUsbCore->rx_queue[i].class_device_id == class_device_id)
+ {
+ pUsbCore->rx_queue[i].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ }
+ }
+}
+
+static kal_bool usbc_class_device_submit_io_request_priv(hif_queue_type_e core_queue_hif_type, usbc_core_queue_t *pQueue, usbc_io_request_t *io_request, kal_uint8 queue_no)
+{
+ usbc_io_request_t *current_request = io_request;
+ usbc_io_request_t *next_request;
+ qbm_gpd *first_gpd = NULL;
+ qbm_gpd *last_gpd = NULL;
+ qbm_gpd *current_gpd = NULL;
+ kal_bool isTx = KAL_FALSE;
+
+ while ( current_request != NULL )
+ {
+ next_request = current_request->next_request;
+
+ first_gpd = current_request->first_gpd;
+ last_gpd = current_request->last_gpd;
+ current_gpd = first_gpd;
+ /* try to traverse gpd list if last_gpd is not filled */
+ if (last_gpd == NULL)
+ {
+ while ( current_gpd->p_next != NULL )
+ {
+ current_gpd = current_gpd->p_next;
+ }
+ last_gpd = current_gpd;
+ }
+
+#ifdef __USBCORE_DEBUG__
+ usbc_core_printf("[USBCORE] submit type %d queue no %d first gpd %x last gpd %x\r\n", core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd);
+ //usbc_core_dump_gpd_list(first_gpd, last_gpd);
+#endif
+ isTx = ((queue_no & PIPE_QUEUE_RX_MASK) != PIPE_QUEUE_RX_MASK)?KAL_TRUE:KAL_FALSE;
+ usbc_core_trace_gpd_info(first_gpd, last_gpd, HIFUSB_EPNO_2_QNO(pQueue->ep_no), isTx, 1);
+
+ usbc_core_set_usbhifq_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd);
+
+ current_request = next_request;
+ }
+
+ return KAL_TRUE;
+}
+
+
+
+kal_bool
+usbc_core_get_queue_info(
+ kal_uint8 class_device_id,
+ kal_uint8 queue_no,
+ usbc_core_queue_t **queue,
+ hif_queue_type_e *queue_type)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint8 core_queue_no;
+
+ if ((class_device_id >= pUsbCore->total_class_devices) ||
+ (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED)) {
+ EXT_ASSERT(0, USBCORE_LOC_QUERY_QUE_DEVICE_NOT_REGISTER, (kal_uint32)class_device_id, (kal_uint32)pUsbCore->class_device[class_device_id].state);
+ return KAL_FALSE;
+ }
+
+ if ((queue_no & ~PIPE_QUEUE_RX_MASK) > MAX_USBCORE_QUEUE_NUM) {
+ EXT_ASSERT(0, USBCORE_LOC_QUERY_QUE_OVERSIZE_QUE_NUMBER, (kal_uint32)class_device_id, (kal_uint32)queue_no);
+ return KAL_FALSE;
+ }
+
+ if ((queue_no & PIPE_QUEUE_RX_MASK) != PIPE_QUEUE_RX_MASK) {
+ core_queue_no = queue_no;
+ *queue_type = HIFQ_TYPE_TX;
+ *queue = &(pUsbCore->tx_queue[core_queue_no]);
+ } else {
+ core_queue_no = queue_no & ~PIPE_QUEUE_RX_MASK;
+ *queue_type = HIFQ_TYPE_RX;
+ *queue = &(pUsbCore->rx_queue[core_queue_no]);
+ }
+
+ if ((*queue)->class_device_id != class_device_id) {
+ EXT_ASSERT(0, USBCORE_LOC_QUERY_QUE_CLASS_ID_NOT_MATCH, (kal_uint32)class_device_id, (kal_uint32)((*queue)->class_device_id));
+ return KAL_FALSE;
+ }
+
+ if ((*queue)->state != USBC_CORE_QUEUE_STATE_ACTIVE) {
+ usbc_trace_info(USBCORE_CLASS_OP_INACTIVATE_QUE, class_device_id, queue_no);
+ }
+
+ return KAL_TRUE;
+}
+
+usbc_class_device_instance_t* usbc_class_device_register(
+ kal_uint8 class_device_id,
+ usbc_class_device_info_t *device_info)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ if (pUsbCore == NULL) {
+ ASSERT(0);
+ return NULL;
+ }
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ return usbc_core_device_register(class_device_id, pUsbCore, device_info);
+}
+
+usbc_class_device_instance_t* usbc_core_device_register(
+ kal_uint8 class_device_id,
+ usbc_core_t *pUsbCore,
+ usbc_class_device_info_t *device_info)
+{
+ usbc_core_class_device_t* pClassDevice = NULL;
+ usbc_class_device_instance_t* pClassDeviceInstance = NULL;
+ usbc_core_queue_t* pQueue = NULL;
+ kal_uint8 acquire_queue = 0;
+ kal_uint8 i = 0;
+
+ if (device_info == NULL) {
+ ASSERT(0);
+ return NULL;
+ }
+
+ /* Check state of class device -> it should be initiated state */
+ if (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_INITIATED) {
+ EXT_ASSERT(0, USBCORE_LOC_REGISTER_CLASS_NOT_INITIALIZE, (kal_uint32)class_device_id, (kal_uint32)(pUsbCore->class_device[class_device_id].state));
+ return NULL;
+ }
+
+ /* found available device instance, use it and apply register infromation */
+ pClassDevice = &(pUsbCore->class_device[class_device_id]);
+ if (device_info->total_pipes != pClassDevice->total_pipes) {
+ // pipe number not match, return NULL
+ ASSERT(0);
+ return NULL;
+ }
+
+ pClassDeviceInstance = &(pClassDevice->device_instance);
+ pClassDeviceInstance->id = class_device_id;
+ pClassDeviceInstance->speed = pUsbCore->speed;
+ pClassDeviceInstance->total_interfaces = 0;
+ pClassDeviceInstance->context = device_info->class_device_context;
+ pClassDevice->state = USBC_CORE_CLASS_DEVICE_STATE_REGISTERED;
+ pClassDevice->notify_usb_state = device_info->notify_usb_state;
+ pClassDevice->notify_usb_speed = device_info->notify_usb_speed;
+#ifdef ATEST_SYS_USBCORE
+ #if USBC_UT_FAKE_CLASS_CALLBACK
+ pClassDevice->notify_func_wk_ability = usbc_ut_fake_notify_func_wk_ability;
+ pClassDevice->query_func_wk_status = usbc_ut_fake_query_func_wk_status;
+ #else
+ pClassDevice->notify_func_wk_ability = device_info->notify_func_wk_ability;
+ pClassDevice->query_func_wk_status = device_info->query_func_wk_status;
+ #endif
+#else
+ pClassDevice->notify_func_wk_ability = device_info->notify_func_wk_ability;
+ pClassDevice->query_func_wk_status = device_info->query_func_wk_status;
+#endif
+
+ for ( i=0; i<pUsbCore->total_class_interfaces; i++ )
+ {
+ if ( (pUsbCore->class_interface[i].state == USBC_CORE_CLASS_INTERFACE_STATE_INITIATED) &&
+ (pUsbCore->class_interface[i].class_device_id == class_device_id) )
+ {
+ /* fill Device Instance interface information */
+ pClassDeviceInstance->interface_type[pClassDeviceInstance->total_interfaces] = pUsbCore->class_interface[i].interface_type;
+ pClassDeviceInstance->interface_no[pClassDeviceInstance->total_interfaces] = pUsbCore->class_interface[i].interface_no;
+ pClassDeviceInstance->total_interfaces++;
+
+ /* fill USB Core interface information */
+ pUsbCore->class_interface[i].state = USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE;
+ pUsbCore->class_interface[i].notify_control_setup_packet = device_info->notify_control_setup_packet;
+ pUsbCore->class_interface[i].notify_control_complete = device_info->notify_control_complete;
+ pUsbCore->class_interface[i].notify_alternate_setting = device_info->notify_alternate_setting;
+ }
+ }
+
+ for ( i=0; i<device_info->total_pipes; i++ )
+ {
+ acquire_queue = acquire_pipe_queue(class_device_id, device_info->pipe_type[i]);
+ if ( acquire_queue == INVALID_PIPE_QUEUE_ID )
+ {
+ //can't satisfy, release acquired resource if any
+ release_pipe_queue(class_device_id);
+ release_class_device(class_device_id);
+ ASSERT(0);
+ return NULL;
+ }
+
+ /* fill Device Instance Queue information */
+ pClassDeviceInstance->queue_no_for_pipe[i] = acquire_queue;
+
+ /* fill USB Core Queue information */
+ if ( (acquire_queue & PIPE_QUEUE_RX_MASK) != PIPE_QUEUE_RX_MASK )
+ {
+ pQueue = &(pUsbCore->tx_queue[acquire_queue]);
+ } else {
+ pQueue = &(pUsbCore->rx_queue[acquire_queue & ~PIPE_QUEUE_RX_MASK]);
+ }
+ pQueue->state = USBC_CORE_QUEUE_STATE_ACTIVE;
+ pQueue->notify_complete = device_info->notify_pipe_complete[i];
+ pQueue->notify_rb_complete = device_info->notify_rb_pipe_complete[i];
+ pQueue->notify_stall = device_info->notify_pipe_stall[i];
+ }
+
+ return pClassDeviceInstance;
+}
+
+
+kal_bool usbc_class_device_deregister(kal_uint8 class_device_id)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ if ( (class_device_id >= pUsbCore->total_class_devices) ||
+ (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_DEREGISTER_CLASS_NOT_REGISTERED, (kal_uint32)class_device_id, (kal_uint32)(pUsbCore->class_device[class_device_id].state));
+ return KAL_FALSE;
+ }
+
+ release_pipe_queue(class_device_id);
+ release_class_device(class_device_id);
+
+ return KAL_TRUE;
+}
+
+
+void* usbc_class_device_get_context(kal_uint8 class_device_id)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_core_class_device_t *pClassDevice = &(pUsbCore->class_device[class_device_id]);
+ usbc_class_device_instance_t *pClassDeviceInstance = &(pClassDevice->device_instance);
+
+ return pClassDeviceInstance->context;
+}
+
+
+kal_bool usbc_class_device_submit_control_request(
+ kal_uint8 class_device_id, kal_uint8* buffer, kal_uint32 length,
+ usbc_control_request_type_e type)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ if (!USBC_IS_IN_EXCEPTION_MODE())
+ {
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+ }
+
+ if ( (class_device_id >= pUsbCore->total_class_devices) ||
+ (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_SUBMIT_CTRL_REQ_CLASS_NOT_REGISTERED, (kal_uint32)class_device_id, (kal_uint32)(pUsbCore->class_device[class_device_id].state));
+ return KAL_FALSE;
+ }
+
+ return usbc_core_set_control_request(buffer, length, type);
+}
+
+
+kal_bool usbc_class_device_submit_io_request(
+ kal_uint8 class_device_id, kal_uint8 queue_no,
+ usbc_io_request_t* io_request)
+{
+ usbc_core_queue_t *pQueue = NULL;
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ hif_queue_type_e core_queue_hif_type;
+ kal_bool ret;
+
+ HIF_SWLA_START("UD1");
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if ((queue_no & PIPE_QUEUE_RX_MASK) == PIPE_QUEUE_RX_MASK)
+ USBC_QUEUE_GPD_TAKE_MUTEX(pUsbCore->rx_submit_enhmuexid[queue_no & ~PIPE_QUEUE_RX_MASK]);
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ HIF_SWLA_STOP("UD1");
+ return KAL_FALSE;
+ }
+
+ ret = usbc_class_device_submit_io_request_priv(core_queue_hif_type, pQueue, io_request, queue_no);
+ HIF_SWLA_STOP("UD1");
+
+ if ((queue_no & PIPE_QUEUE_RX_MASK) == PIPE_QUEUE_RX_MASK)
+ USBC_QUEUE_GPD_GIVE_MUTEX(pUsbCore->rx_submit_enhmuexid[queue_no & ~PIPE_QUEUE_RX_MASK]);
+ return ret;
+}
+
+kal_bool usbc_class_device_restore_gpd_pwrsave(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t *pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ kal_bool ret;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ // Restore GPDs
+ if (core_queue_hif_type == HIFQ_TYPE_TX) {
+ usbc_data_trace(MD_TRC_USBCORE_RESTORE_TX_GPD_SWQ2HWQ, (core_queue_hif_type << 8) | (queue_no & 0xFF) );
+ }
+ else if (core_queue_hif_type == HIFQ_TYPE_RX) {
+ usbc_data_trace(MD_TRC_USBCORE_RESTORE_RX_GPD_SWQ2HWQ, (core_queue_hif_type << 8) | (queue_no & 0xFF) );
+ }
+ ret = hifusbq_pwrsave_restore_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no));
+
+ return ret;
+}
+
+kal_bool usbc_class_device_submit_io_request_ext(
+ kal_uint8 class_device_id, kal_uint8 queue_no,
+ usbc_io_request_t *io_request,
+ usbc_io_ext_info_t *info)
+{
+ usbc_core_queue_t *pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ switch (info->type) {
+ case USBC_IO_TX_NO_FLUSH:
+ core_queue_hif_type = HIFQ_TYPE_TX_NO_FLUSH;
+ break;
+
+ default:
+ ASSERT(KAL_FALSE);
+ return KAL_FALSE;
+ }
+
+ return usbc_class_device_submit_io_request_priv(core_queue_hif_type, pQueue, io_request, queue_no);
+}
+
+
+kal_bool usbc_class_device_submit_drb(kal_uint8 class_device_id, kal_uint8 queue_no,kal_uint32 submit_drb_count)
+{
+ kal_bool ret;
+ usbc_core_queue_t *pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+
+ HIF_SWLA_START("UD1");
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ ret = ubm_drb_submit(HIFUSB_EPNO_2_QNO(pQueue->ep_no), submit_drb_count);
+
+ HIF_SWLA_STOP("UD1");
+ return ret;
+}
+
+kal_bool usbc_class_device_flush_rb(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ usbc_core_queue_t* pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ //hif_flush_type_e core_queue_flush_type = HIFQ_FLUSH_FREE; // USBCLASS owner requests RB queue flushing is done USB driver;
+ kal_uint32 startIdx, endIdx;
+ kal_uint32 num = 0;
+ kal_bool result;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ if(core_queue_hif_type == HIFQ_TYPE_TX)
+ {
+ result = ubm_drb_flush(HIFUSB_EPNO_2_QNO(pQueue->ep_no), &startIdx, &endIdx, &num); // Flush DRB and NFHB by USB driver
+ } else {
+ queue_no &= ~PIPE_QUEUE_RX_MASK;
+ (pUsbCore->rx_xit_meta)[queue_no].xit2meta_retry = KAL_FALSE;
+ (pUsbCore->rx_xit_meta)[queue_no].remain_num = (pUsbCore->rx_xit_meta)[queue_no].startIdx = (pUsbCore->rx_xit_meta)[queue_no].endIdx = 0;
+ result = ubm_xit_flush(HIFUSB_EPNO_2_QNO(pQueue->ep_no), &startIdx, &endIdx, &num); // Flush XIT and PRB by USB driver
+ }
+
+ return result;
+}
+
+kal_bool usbc_class_device_rst_ep_pipe(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t *pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ kal_bool is_tx;
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+ if(pQueue->owner == USB_CLASS_OWNER_MD){
+ is_tx = core_queue_hif_type == HIFQ_TYPE_TX ? KAL_TRUE : KAL_FALSE;
+ usbc_core_rst_ep(is_tx, pQueue->ep_no);
+ }
+
+ return KAL_TRUE;
+
+}
+kal_bool usbc_class_device_flush_io_request(
+ kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t* pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ hif_flush_type_e core_queue_flush_type;
+ qbm_gpd* first_gpd = NULL;
+ qbm_gpd* last_gpd = NULL;
+ kal_uint32 num = 0;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ if ( pQueue->notify_complete == NULL )
+ {
+ core_queue_flush_type = HIFQ_FLUSH_FREE;
+ } else {
+ core_queue_flush_type = HIFQ_FLUSH_DEQ;
+ }
+
+ // Flush GPDs that are configured in hardware, and give GPDs back to uppoer layers
+ num = usbc_core_flush_hifusbq_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), core_queue_flush_type, (void**)&first_gpd, (void**)&last_gpd);
+ if ( num != 0 )
+ {
+#ifdef __USBCORE_DEBUG__
+ usbc_core_printf("[USBCORE] flush type %d queue no %d first gpd %x last gpd %x\r\n", core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd);
+ //usbc_core_dump_gpd_list(first_gpd, last_gpd);
+#endif
+ if ( pQueue->notify_complete != NULL )
+ {
+ if ( first_gpd == NULL )
+ {
+ /* just indicate a notification */
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_FLUSH_HW_QUEUE, queue_no, num, 0x00, 0x00);
+ usbc_trace_warn(USBCORE_CLASS_FLUSH_HW_QUEUE_PS, queue_no, num, 0x00, 0x00);
+ pQueue->notify_complete(pQueue->class_device_id, NULL);
+ } else {
+ usbc_io_request_t* request = NULL;
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_FLUSH_HW_QUEUE, queue_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ usbc_trace_warn(USBCORE_CLASS_FLUSH_HW_QUEUE_PS, queue_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd);
+ request->next_request = NULL;
+ request->first_gpd = first_gpd;
+ request->last_gpd = last_gpd;
+ pQueue->notify_complete(pQueue->class_device_id, request);
+ }
+ }
+ }
+ else
+ {
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_FLUSH_HW_QUEUE, queue_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ usbc_trace_warn(USBCORE_CLASS_FLUSH_HW_QUEUE_PS, queue_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ }
+
+ // Flush GPDs that are buffered in DRAM, and give GPDs back to uppoer layers
+ num = usbc_core_flush_sw_hifusbq_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), core_queue_flush_type, (void**)&first_gpd, (void**)&last_gpd);
+ if ( num != 0 )
+ {
+#ifdef __USBCORE_DEBUG__
+ usbc_core_printf("[USBCORE] flush type %d queue no %d first gpd %x last gpd %x\r\n", core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd);
+ //usbc_core_dump_gpd_list(first_gpd, last_gpd);
+#endif
+ if ( pQueue->notify_complete != NULL )
+ {
+ if ( first_gpd == NULL )
+ {
+ /* just indicate a notification */
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_FLUSH_SW_QUEUE, queue_no, num, 0x00, 0x00);
+ usbc_trace_warn(USBCORE_CLASS_FLUSH_SW_QUEUE_PS, queue_no, num, 0x00, 0x00);
+ pQueue->notify_complete(pQueue->class_device_id, NULL);
+ } else {
+ usbc_io_request_t* request = NULL;
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_FLUSH_SW_QUEUE, queue_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ usbc_trace_warn(USBCORE_CLASS_FLUSH_SW_QUEUE_PS, queue_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd);
+ request->next_request = NULL;
+ request->first_gpd = first_gpd;
+ request->last_gpd = last_gpd;
+ pQueue->notify_complete(pQueue->class_device_id, request);
+ }
+ }
+ }
+ else
+ {
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_FLUSH_SW_QUEUE, queue_no, num, 0x00, 0x00);
+ usbc_trace_warn(USBCORE_CLASS_FLUSH_SW_QUEUE_PS, queue_no, num, 0x00, 0x00);
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool usbc_class_device_flush_rx_io_with_submit(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t* pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ hif_flush_type_e core_queue_flush_type;
+ qbm_gpd* first_gpd = NULL;
+ qbm_gpd* last_gpd = NULL;
+ kal_uint32 num = 0;
+ qbm_gpd* curr_gpd = NULL;
+ usbc_io_request_t* request = NULL;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ ASSERT(core_queue_hif_type == HIFQ_TYPE_RX);
+ USBC_QUEUE_GPD_TAKE_MUTEX(pUsbCore->rx_submit_enhmuexid[queue_no & ~PIPE_QUEUE_RX_MASK]);
+
+ core_queue_flush_type = HIFQ_FLUSH_DEQ;
+ // Flush GPDs that are configured in hardware, and submit to USB driver
+ num = usbc_core_flush_hifusbq_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), core_queue_flush_type, (void**)&first_gpd, (void**)&last_gpd);
+ if ( num != 0 )
+ {
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_FLUSH_HW_QUEUE, queue_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ curr_gpd = first_gpd;
+ while(curr_gpd)
+ {
+ usbc_trace_info(USBCORE_FLUSH_RX_HW_GPD_WITH_SUBMIT, queue_no & ~PIPE_QUEUE_RX_MASK, curr_gpd, QBM_DES_GET_DATALEN(curr_gpd));
+
+ QBM_DES_SET_DATALEN(curr_gpd, 0);
+ QBM_DES_SET_HWO(curr_gpd);
+ qbm_cal_set_checksum(curr_gpd);
+ QBM_CACHE_FLUSH(curr_gpd, sizeof(qbm_gpd));
+
+ if(curr_gpd == last_gpd) break;
+ curr_gpd = QBM_DES_GET_NEXT(curr_gpd);
+ }
+ request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd);
+ request->next_request = NULL;
+ request->first_gpd = first_gpd;
+ request->last_gpd = last_gpd;
+ usbc_class_device_submit_io_request_priv(core_queue_hif_type, pQueue, request, queue_no);
+ }
+
+ // Flush GPDs that are buffered in DRAM, and submit to USB driver
+ num = usbc_core_flush_sw_hifusbq_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), core_queue_flush_type, (void**)&first_gpd, (void**)&last_gpd);
+ if ( num != 0 )
+ {
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_FLUSH_SW_QUEUE, queue_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ curr_gpd = first_gpd;
+ while(curr_gpd)
+ {
+ usbc_trace_info(USBCORE_FLUSH_RX_SW_GPD_WITH_SUBMIT, queue_no & ~PIPE_QUEUE_RX_MASK, curr_gpd, QBM_DES_GET_DATALEN(curr_gpd));
+
+ QBM_DES_SET_DATALEN(curr_gpd, 0);
+ QBM_DES_SET_HWO(curr_gpd);
+ qbm_cal_set_checksum(curr_gpd);
+ QBM_CACHE_FLUSH(curr_gpd, sizeof(qbm_gpd));
+
+ if(curr_gpd == last_gpd) break;
+ curr_gpd = QBM_DES_GET_NEXT(curr_gpd);
+ }
+ request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd);
+ request->next_request = NULL;
+ request->first_gpd = first_gpd;
+ request->last_gpd = last_gpd;
+ usbc_class_device_submit_io_request_priv(core_queue_hif_type, pQueue, request, queue_no);
+ }
+ USBC_QUEUE_GPD_GIVE_MUTEX(pUsbCore->rx_submit_enhmuexid[queue_no & ~PIPE_QUEUE_RX_MASK]);
+ return KAL_TRUE;
+}
+
+
+kal_bool usbc_class_device_change_notify_complete(
+ kal_uint8 class_device_id, kal_uint8 queue_no,
+ void (*notify_complete)(kal_uint8 class_device_id, usbc_io_request_t* io_request))
+{
+ usbc_core_queue_t* pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ pQueue->notify_complete = notify_complete;
+
+ return KAL_TRUE;
+}
+
+
+kal_bool usbc_class_device_set_hif_disconnect(kal_uint8 class_device_id)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if ( (class_device_id >= pUsbCore->total_class_devices) ||
+ (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED) )
+ {
+ ASSERT(0);
+ return KAL_FALSE;
+ }
+
+ usbc_normal_hif_disconnect();
+
+ return KAL_TRUE;
+}
+
+
+void usbc_wk_notify_timeout()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_device_id = 0;
+ kal_uint8 i;
+
+ USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_renotify_mutex);
+ for(i=0; i<pUsbCore->total_class_devices; i++)
+ {
+ if(pUsbCore->func_notify_list[i] == KAL_TRUE)
+ {
+ class_device_id = i;
+ pUsbCore->func_notify_list[i] = KAL_FALSE;
+ break;
+ }
+ }
+
+ if (i == pUsbCore->total_class_devices)
+ {
+ pUsbCore->wk_eventid = NULL;
+ USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_renotify_mutex);
+ return;
+ }
+ USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_renotify_mutex);
+
+ // check the access of the function
+ if ( !pUsbCore->is_func_be_accessed[class_device_id] )
+ {
+ usbc_set_wk_notify_timer(class_device_id);
+ }
+}
+
+
+void usbc_set_wk_notify_timer(kal_uint8 class_device_id)
+{
+ eventid eid;
+ kal_uint8 nInterface;
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ /*
+ * To prevent race condition of event cancelling and set,
+ * there shall be only one such event for simplicity.
+ */
+ ASSERT(NULL != pUsbCore->usbc_es_wk_notify_g);
+
+ usbc_trace_info(USBCORE_REMOTE_WK_SET_NOTIFY_TIMER, class_device_id);
+
+ USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_renotify_mutex);
+
+ // usb a bitmap to maintain the list of function wakeup notification
+ pUsbCore->func_notify_list[class_device_id] = KAL_TRUE;
+
+ // get the firtst interface ot the function
+ nInterface = usbc_class_device_get_1st_interface(class_device_id);
+ // send function remote wakeup notification via HIF driver
+ usbc_normal_hif_ss_wk_notify(nInterface);
+
+ if (NULL == pUsbCore->wk_eventid)
+ {
+ eid = evshed_set_event(
+ pUsbCore->usbc_es_wk_notify_g,
+ usbc_wk_notify_timeout, // timeout handler
+ NULL, /* event_hf_param */
+ USBC_WK_NOTIFY_CHECK_MS); /* elapse_time */
+ ASSERT(eid);
+ }
+
+ USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_renotify_mutex);
+}
+
+
+kal_bool usbc_class_device_func_remote_wk(kal_uint8 class_device_id)
+{
+
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_bool isDeviceSuspend;
+ usbc_ind_t ind_to_enqueue;
+ usbc_func_state_e state;
+
+ usbc_trace_info(USBCORE_REMOTE_WK_START, class_device_id);
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ /* Check whether the requested function is capable to wakeup the host and remote wakeup is enabled.
+ Return KAL_FALSE if the function is not valid to wakeup host
+ */
+ if ( pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id) != 0x03 )
+ {
+ usbc_trace_error(USBCORE_REMOTE_WK_INVALID, class_device_id, pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id));
+ EXT_ASSERT(0, USBCORE_LOC_NO_ABILITY_TO_REMOTE_WK, (kal_uint32)usbcore_classid_to_module(class_device_id),
+ (kal_uint32)(pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id)));
+ return KAL_FALSE;
+ }
+
+ // check for the remote wakeup once a function at the same time
+ USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_remote_wk_mutex);
+
+ // reset the status of function accessing of class device id
+ USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_func_access_mutex);
+ pUsbCore->is_func_be_accessed[class_device_id] = KAL_FALSE;
+ USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_func_access_mutex);
+
+ isDeviceSuspend = (pUsbCore->state == USBC_USB_STATE_SUSPENDED)? KAL_TRUE:KAL_FALSE;
+
+ /* If it is resumed from device suspend,
+ then send hifusb_remote_wakeup first and wait for the resume callback to know LPM state to U0.
+ If it is resumed from function suspend,
+ then send notification to resume the suspended function in USB Core context.
+ */
+ if ( isDeviceSuspend )
+ {
+ usbc_trace_info(USBCORE_REMOTE_WK_DEVICE, class_device_id);
+ if(pUsbCore->usb_low_power_enable)
+ {
+ while(pUsbCore->waiting_ap_clk_disable_flag ){
+ kal_sleep_task(USBC_DEV_RESUME_DURATION_TICK);
+ }
+ usbc_core_mask_wakeup_event(KAL_TRUE);
+ usbc_core_set_clock_cg(KAL_TRUE);
+ usbc_core_mask_intr(KAL_FALSE);
+ }
+ usb_idle_set_clockGating(KAL_FALSE); // nofity USBIDLE that it does not have to gate the clock of USB IP
+ usbc_normal_hif_remote_wakeup();
+ }
+
+ //else if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ // block until device resume
+ while ( isDeviceSuspend )
+ {
+ kal_sleep_task(USBC_DEV_RESUME_DURATION_TICK);
+ isDeviceSuspend = (pUsbCore->state_in_hisr == USBC_USB_STATE_SUSPENDING)? KAL_TRUE:KAL_FALSE;
+ usbc_trace_warn(USBCORE_REMOTE_WK_DEVICE_WAIT, class_device_id);
+ }
+
+ usbc_trace_info(USBCORE_REMOTE_WK_FUNC, class_device_id);
+ // call HIF driver API to send function wakeup notification, and resend if needed
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ usbc_set_wk_notify_timer(class_device_id);
+ }
+
+ /*if class_device is AP owner, do not notify MD class in task ,because setup packet will be send to AP
+ , so notify MD class here.*/
+ if(USB_CLASS_OWNER_MD != pUsbCore->class_device[class_device_id].owner)
+ {
+ usbc_core_notify_function_state_resume(class_device_id);
+ }
+ else
+ {
+ // send callback to notify class device of resuming
+ state = USBC_FUNC_STATE_RESUME;
+ // Enqueue USB function state which will be handled in USB context later.
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = class_device_id;
+ ind_to_enqueue.data = (kal_uint8)state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ // Wake up USBCORE task to process indications.
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ }
+
+ }
+
+ // release for the remote wakeup of a function
+ USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_remote_wk_mutex);
+
+ return KAL_TRUE;
+}
+
+void usbc_class_device_netifx_suspend_notify(kal_uint8 class_device_id, kal_bool suspend, kal_bool remote_wakeup)
+{
+ usbcore_usbidle_l4_power_saving_req_struct *rsp_msg_p;
+
+ if ( 1
+#ifdef __USB_RNDIS_SUPPORT__
+ && (usbc_core_get_instance()->class_device[class_device_id].class_type != USB_CLASS_RNDIS)
+#endif
+#ifdef __USB_MBIM_SUPPORT__
+ && (usbc_core_get_instance()->class_device[class_device_id].class_type != USB_CLASS_MBIM)
+#endif
+#ifdef __USB_ECM_SUPPORT__
+ && (usbc_core_get_instance()->class_device[class_device_id].class_type != USB_CLASS_ECM)
+#endif
+ )
+ {
+ ASSERT(0);
+ return;
+ }
+
+ // In current implemnntation, only notifying L4 of USB suspended/resuming with remote wakeup is allowed
+ ASSERT(remote_wakeup);
+ if( suspend )
+ {
+ rsp_msg_p = (usbcore_usbidle_l4_power_saving_req_struct*)construct_local_para(sizeof(usbcore_usbidle_l4_power_saving_req_struct), TD_RESET);
+ ASSERT(rsp_msg_p);
+ rsp_msg_p->notify_suspend = suspend;
+ rsp_msg_p->notify_suspend_with_remote_wk = remote_wakeup;
+ usb_idle_set_l4_power_saving(KAL_TRUE);
+ msg_send6(MOD_USBCORE, // src module
+ MOD_USBIDLE, // dst module
+ 0, // sap id
+ MSG_ID_USBCORE_IDLE_NOTIFY_TO_L4,
+ (local_para_struct*)rsp_msg_p,
+ 0);
+ }
+ else
+ {
+ usb_idle_set_l4_power_saving(KAL_FALSE);
+ usb_idle_event_notify_to_l4(suspend, remote_wakeup);
+ }
+}
+
+kal_bool usbc_class_device_check_ep_empty(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t* pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ return usbc_core_check_hifusbq_empty(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no));
+}
+
+kal_uint8 usbc_class_device_get_phy_queue_num(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t* pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ return HIFUSB_EPNO_2_QNO(pQueue->ep_no);
+}
+
+kal_bool usbc_class_device_set_header_rule(kal_uint32 header_rule, void *ph_addr, void *xh_addr, kal_uint16 ph_length, kal_uint16 xh_length)
+{
+ usb_header_rule_data_t rule_data = {.ph_start_ptr = ph_addr, .xh_start_ptr = xh_addr, .ph_size = ph_length, .xh_size = xh_length};
+
+ return hifusbq_set_header_rule((usb_header_rule_enum)header_rule, &rule_data);
+}
+
+kal_bool usbc_class_device_set_stall(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t *pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ kal_bool is_tx;
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ pQueue->state = USBC_CORE_QUEUE_STATE_STALL;
+ if(pQueue->owner == USB_CLASS_OWNER_MD){
+ is_tx = core_queue_hif_type == HIFQ_TYPE_TX ? KAL_TRUE : KAL_FALSE;
+ usbc_core_set_stall(is_tx, pQueue->ep_no);
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool usbc_class_device_clear_stall(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t *pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ kal_bool is_tx;
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ pQueue->state = USBC_CORE_QUEUE_STATE_ACTIVE;
+ if(pQueue->owner == USB_CLASS_OWNER_MD){
+ is_tx = core_queue_hif_type == HIFQ_TYPE_TX ? KAL_TRUE : KAL_FALSE;
+ usbc_core_clear_stall(is_tx, pQueue->ep_no);
+ }
+ return KAL_TRUE;
+}
+
+kal_bool usbc_class_device_start_data_q(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t *pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ kal_bool is_tx;
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
+ return KAL_FALSE;
+ }
+
+ is_tx = core_queue_hif_type == HIFQ_TYPE_TX ? KAL_TRUE : KAL_FALSE;
+ usbc_core_start_dataq(is_tx, HIFUSB_EPNO_2_QNO(pQueue->ep_no));
+
+ return KAL_TRUE;
+}
+
+void usbc_class_device_stall_ep0(void)
+{
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+}
+
+usb_class_owner_e usbc_class_get_class_device_owner(kal_uint8 class_device)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ return pUsbCore->class_device[class_device].owner;
+}
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_cosim.c b/mcu/middleware/hif/usbcore/src/usbcore_cosim.c
new file mode 100644
index 0000000..f12d3d2
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_cosim.c
@@ -0,0 +1,246 @@
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "hif_usb.h"
+#include "usbcore_main.h"
+#include "usbcore_ind_q.h"
+#include "usbcore_hif.h"
+#include "hifusb_qmu.h"
+#include "usbcore_class_device.h"
+#include "hif_ior.h"
+#include "qmu_bm_util.h"
+#include "qmu_bm.h"
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#include "sysservice_msgid.h"
+#include "hif_mw_msgid.h"
+#include "usbcore_cosim.h"
+
+/************************************************
+ * USBHIF driver APIs for ESL COSIM
+ ************************************************/
+static kal_bool usbc_cosim_hif_connect(void)
+{
+ /* emulate driver connection */
+ usbc_core_notify_state_attaching();
+
+ return KAL_TRUE;
+}
+
+static kal_bool usbc_cosim_hif_disconnect(void)
+{
+ usbc_core_notify_state_detaching();
+
+ return KAL_TRUE;
+}
+
+/************************************************
+ * USBCORE HIF APIs for ESL COSIM
+ ************************************************/
+
+static void usbc_cosim_hif_factory(void)
+{
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ usbc_esl_printf("Use DRVHIF ESL APIs...\n");
+ usbc_core_set_property = hifusb_set_property_emulate;
+ usbc_core_set_usbhif_address = hifusb_set_usb_address_emulate;
+ usbc_core_set_usbhif_configuration = hifusb_set_usb_configuration_emulate;
+ usbc_core_set_usbhif_connect = usbc_cosim_hif_connect;
+ usbc_core_set_usbhif_disconnect = usbc_cosim_hif_disconnect;
+}
+
+static void usbc_cosim_hif_attach(void)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ usbc_esl_printf("Emulare USB enumeration...\n");
+
+ /* emulate reset and speed change */
+ usbc_esl_printf("Emulare USB speed change and reset...\n");
+ usbc_core_speed_change(pUsbCore, USBC_USB_SPEED_USB30);
+ usbc_core_notify_speed_change(USBC_USB_SPEED_USB30);
+ usbc_core_set_hif_configuration(); // emulate reset notify
+ usbc_core_notify_state_reset();
+ usbc_cosim_hif_factory();
+
+ /* emulate SetAddress */
+ usbc_esl_printf("Emulare HIF USB set address...\n");
+ usbc_core_set_usb_address(1); // set USB address
+
+ /* emulate SetConfig */
+ usbc_esl_printf("Emulare USB set configuration...\n");
+ usbc_core_set_usb_configuration(1); //set USB configuration, assume there is only one configuration in META mode
+ usbc_core_notify_state_attached();
+
+ // Clean USB indication queue
+ usbc_cosim_hif_factory();
+ usbc_empty_ind_queue();
+}
+
+static void usbc_cosim_notify_data_connect(void)
+{
+ module_type dest_mod;
+ msg_type msg_id;
+ usbc_class_device_esl_connect_parm *rsp_msg_p;
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ usbc_esl_printf("Set USB class to connected state...\n");
+
+ // change USB classes state to transfer data
+ rsp_msg_p = (usbc_class_device_esl_connect_parm*)construct_local_para(sizeof(usbc_class_device_esl_connect_parm), TD_RESET);
+ ASSERT(rsp_msg_p);
+ rsp_msg_p->class_device_id = 0;
+ msg_id = MSG_ID_USBCLASS_USBCORE_ESL_ENTER_CONNECTED_STATE_REQ;
+
+ switch ((pUsbCore->class_device[0]).class_type)
+ {
+#ifdef __USB_MBIM_SUPPORT__
+ case USB_CLASS_MBIM:
+ dest_mod = MOD_MBIM;
+ break;
+#endif
+#ifdef __USB_ECM_SUPPORT__
+ case USB_CLASS_ECM:
+ dest_mod = MOD_ECM;
+ break;
+#endif
+#ifdef __USB_RNDIS_SUPPORT__
+ case USB_CLASS_RNDIS:
+ dest_mod = MOD_RNDIS;
+ break;
+#endif
+ default:
+ // We assume the first class device must be a NIC for ESL CO-SIM
+ ASSERT(0);
+ return;
+ break;
+ }
+
+ msg_send6(MOD_USBCORE, // src module
+ dest_mod, // dst module
+ 0, // sap id
+ msg_id,
+ (local_para_struct*)rsp_msg_p,
+ 0); //msg id
+}
+
+/************************************************
+ * USBCORE task APIs for ESL COSIM
+ ************************************************/
+
+kal_bool usbc_cosim_core_task_init(void)
+{
+ usbc_core_t* pUsbCore;
+ kal_char usbc_class_mutex_name[50];
+
+#ifdef IPCORE_NOT_PRESENT
+ hmu_boot_init();
+#endif
+
+ usbc_set_op_mode(USBC_OP_MODE_NORMAL);
+ kal_mem_set(usbc_core_get_instance(), 0, sizeof(usbc_core_t));
+
+ usbc_core_clear_register();
+ usbc_core_clear_status();
+
+ pUsbCore = usbc_core_get_instance();
+ // create enhance mutex
+ sprintf(usbc_class_mutex_name, "USBC_CLASS_REMOTE_WK_MUTEX");
+ pUsbCore->usbc_class_remote_wk_mutex = kal_create_enh_mutex(usbc_class_mutex_name);
+ sprintf(usbc_class_mutex_name, "USBC_CLASS_RENOTIFY_MUTEX");
+ pUsbCore->usbc_class_renotify_mutex = kal_create_enh_mutex(usbc_class_mutex_name);
+ sprintf(usbc_class_mutex_name, "USBC_CLASS_FUNC_ACCESS_MUTEX");
+ pUsbCore->usbc_class_func_access_mutex = kal_create_enh_mutex(usbc_class_mutex_name);
+ if ( NULL == pUsbCore->usbc_class_remote_wk_mutex ||
+ NULL == pUsbCore->usbc_class_renotify_mutex ||
+ NULL == pUsbCore->usbc_class_func_access_mutex )
+ {
+ ASSERT(0);
+ }
+
+ // initial an evnet scheduler
+ pUsbCore->usbc_es_wk_notify_g = evshed_create(
+ "USBC_WK_NOTIFY", /* timer_name: event scheduler name */
+ MOD_USBCORE, /* dest_mod_id: system sends timeout message to this module when event scheduler timeout happens */
+ 0, /* fuzz */
+ (KAL_TICKS_10_MSEC * 255 / 2)); /* max_delay_ticks */
+ if (pUsbCore->usbc_es_wk_notify_g) {
+ evshed_set_index(pUsbCore->usbc_es_wk_notify_g, USBC_WK_NOTIFY_INDEX);
+ } else {
+ ASSERT(0);
+ }
+
+ usbc_normal_hif_factory();
+ usbc_cosim_hif_factory();
+
+ usbc_stack_checkin(USB_CLASS_NUM, NULL);
+
+ return KAL_TRUE;
+}
+
+void usbc_cosim_core_task_main(task_entry_struct* task_entry_ptr)
+{
+ ilm_struct current_ilm;
+ kal_uint32 rt_event;
+ kal_uint16 timer_index;
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ kal_set_active_module_id(MOD_USBCORE);
+ kal_mem_set(¤t_ilm, 0, sizeof(ilm_struct));
+
+ // Emulate USB plug-in for ESL COSIM
+ usbc_cosim_hif_attach();
+ // Emulate USB classes' requests
+ usbc_cosim_notify_data_connect();
+
+ usbc_esl_printf("Start USBCORE task loop...\n");
+ while(1)
+ {
+ while ( msg_get_extq_messages() > 0 )
+ {
+ if ( msg_receive_extq(¤t_ilm) != KAL_TRUE )
+ {
+ break;
+ }
+
+ switch (current_ilm.msg_id)
+ {
+ case MSG_ID_TIMER_EXPIRY:
+ timer_index = evshed_get_index(¤t_ilm);
+ switch (timer_index)
+ {
+ case USBC_WK_NOTIFY_INDEX:
+ ASSERT(0);
+ evshed_timer_handler(pUsbCore->usbc_es_wk_notify_g);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ destroy_ilm(¤t_ilm);
+ }
+
+ /* Wait someone notify HMU to wake up HIF. */
+ rt_event = hmu_hifeg_wait(HIF_DRV_EG_HIF_TICK_EVENT | HIF_DRV_EG_USBC_IND_EVENT);
+ if ((HIF_DRV_EG_HIF_TICK_EVENT & rt_event) &&
+ (pUsbCore->state != USBC_USB_STATE_SUSPENDED))
+ {
+ /* poll HIF queue data */
+ usbc_esl_printf("Start HIF USB poll queue...\n");
+ usbc_normal_hif_poll_queue();
+ usbc_esl_printf("End HIF USB poll queue...\n");
+ }
+ if ((HIF_DRV_EG_USBC_IND_EVENT & rt_event))
+ {
+ /* Handle indications */
+ usbc_normal_hif_process_indications();
+ }
+ }
+}
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_direct.c b/mcu/middleware/hif/usbcore/src/usbcore_direct.c
new file mode 100644
index 0000000..ca0c146
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_direct.c
@@ -0,0 +1,372 @@
+/*!
+ * @file usbcore_direct.c
+ * @author Roger Huang <bo-kai.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main functions of usbcore
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_hif.h"
+#include "usbcore_usbstd.h"
+#include "usbcore_main.h"
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#include "sysservice_msgid.h"
+#include "nvram_interface.h"
+#include "nvram_data_items.h"
+#include "usbcore_debug.h"
+
+#include "hif_usb.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#include "hifusb_qmu.h"
+#include "hif_ior.h"
+#include "qmu_bm_util.h"
+#include "qmu_bm.h"
+#include "usbcore_ind_q.h"
+#include "usbcore_direct.h"
+#include "ufpm_if.h"
+
+void usbc_direct_hif_usbcore_send_indication()
+{
+ usbc_ind_t ind_to_enqueue;
+
+ ind_to_enqueue.type = USBC_IND_UFPM_POLL;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = 0;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+}
+
+void usbc_direct_hif_enable_poll_queue(kal_bool enable)
+{
+ usbc_core_get_instance()->hmu_indication = enable? (HIF_DRV_EG_HIF_TICK_EVENT | HIF_DRV_EG_USBC_IND_EVENT):HIF_DRV_EG_USBC_IND_EVENT;
+
+ if(enable) {
+ usbc_direct_hif_usbcore_send_indication();
+ }
+}
+
+// Notify USB classes for USB evnets
+void usbc_direct_hif_notify_usb_func_event(kal_uint8 class_device_id, usbc_usb_state_e state)
+{
+ usbc_core_indicate_function_state(class_device_id, state);
+
+ return;
+}
+
+// notify USBCORE for USB events
+void usbc_direct_hif_notify_usb_core_event(usbc_usb_state_e state)
+{
+ usbc_core_get_instance()->state = state;
+}
+
+// Notify USBCORE for configuration state, but do not broadcast ATTACHED notification for USB class
+void usbc_direct_hif_attach(usbc_usb_speed_e speed, kal_uint8 address, kal_uint8 configuration)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ // Emulate speed change for USBCORE only
+ pUsbCore->speed = speed; // emulate speed change notify: We do not need to re-compose configuration descriptors in MDT, so do NOT use usbc_core_speed_change
+ usbc_core_notify_speed_change(speed);
+ usbc_direct_hif_factory();
+
+ // Emulate SetAddress for USBCORE only
+ usbc_core_set_usb_address(address); // set USB address
+
+ // Emulate SetConfig for USBCORE only
+ usbc_direct_core_set_config(configuration);
+
+ // Update USBCORE callbacks
+ usbc_direct_hif_factory();
+}
+
+// Notify USBCORE for RESET, but do NOT broadcast RESET notifucation for USB class
+void usbc_direct_hif_detach()
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ // Clean USB indication queue
+ usbc_empty_ind_queue();
+
+ usbc_core_set_hif_configuration();
+ pUsbCore->usb_configuration = 0;
+ pUsbCore->state = USBC_USB_STATE_RESET;
+ usbc_core_clear_status();
+}
+
+void usbc_direct_set_config_class_device(kal_uint8 class_device_id, kal_uint8 configuration)
+{
+ #define CFG_TO_INDEX(config) (config-1)
+
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_class_set_config_func_t class_set_config_func;
+ usb_class_type_e type;
+ usb_cfg_param_t cfg_param;
+
+ cfg_param = pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_param[CFG_TO_INDEX(configuration)];
+ type = cfg_param.class_type[class_device_id];
+ class_set_config_func = usbc_get_class_set_config_func(type);
+
+ if (class_set_config_func) {
+ class_set_config_func(class_device_id, CFG_TO_INDEX(configuration), cfg_param.class_ctxt[class_device_id]);
+ }
+}
+
+void usbc_direct_core_set_config(kal_uint8 configuration)
+{
+ #define CFG_TO_INDEX(config) (config-1)
+
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ //kal_bool result = KAL_TRUE;
+ kal_uint32 idx_class;
+ usb_class_type_e type;
+ kal_uint32 idx_if;
+ kal_uint32 idx_ep;
+
+ /* Check if configuration is changed */
+ if (pUsbCore->usb_configuration == configuration) {
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_UNCHANGED);
+ return;
+ }
+ pUsbCore->usb_configuration = configuration;
+
+ /* Reinit usb classes of old configuration */
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_REINIT_START);
+ usbc_reinit_class();
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_REINIT_END);
+
+ if (configuration == 0)
+ { /* Clear all class device / interface / tx_queue / rx_queue number */
+ pUsbCore->total_class_devices = 0;
+ pUsbCore->total_class_interfaces = 0;
+ pUsbCore->total_tx_queues = 0;
+ pUsbCore->total_rx_queues = 0;
+ } else
+ {
+ /* Fill class_device / interface / tx_queue / rx_queue */
+ pUsbCore->total_class_devices = pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_param[CFG_TO_INDEX(configuration)].class_num;
+ for (idx_class = 0; idx_class < pUsbCore->total_class_devices; idx_class ++)
+ {
+ type = pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_param[CFG_TO_INDEX(configuration)].class_type[idx_class];
+ pUsbCore->class_device[idx_class].state = USBC_CORE_CLASS_DEVICE_STATE_INITIATED;
+ pUsbCore->class_device[idx_class].class_type = type;
+ pUsbCore->class_device[idx_class].total_pipes = 0;
+ }
+
+ pUsbCore->total_class_interfaces = pUsbCore->resource_interface_number[CFG_TO_INDEX(configuration)];
+ for (idx_if = 0; idx_if < pUsbCore->total_class_interfaces; idx_if ++)
+ {
+ kal_mem_cpy(&pUsbCore->class_interface[idx_if],
+ &pUsbCore->if_info[CFG_TO_INDEX(configuration)][idx_if].class_interface,
+ sizeof(usbc_core_class_interface_t));
+ pUsbCore->class_interface[idx_if].state = USBC_CORE_CLASS_INTERFACE_STATE_INITIATED;
+ }
+
+ pUsbCore->total_tx_queues = pUsbCore->resource_ep_tx_number[CFG_TO_INDEX(configuration)];
+ for (idx_ep = 0; idx_ep < pUsbCore->total_tx_queues; idx_ep ++)
+ {
+ kal_mem_cpy(&pUsbCore->tx_queue[idx_ep],
+ &pUsbCore->ep_tx_info[CFG_TO_INDEX(configuration)][idx_ep].queue_info,
+ sizeof(usbc_core_queue_t));
+ pUsbCore->tx_queue[idx_ep].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ pUsbCore->class_device[pUsbCore->tx_queue[idx_ep].class_device_id].total_pipes ++;
+ }
+
+ pUsbCore->total_rx_queues = pUsbCore->resource_ep_rx_number[CFG_TO_INDEX(configuration)];
+ for (idx_ep = 0; idx_ep < pUsbCore->total_rx_queues; idx_ep ++)
+ {
+ kal_mem_cpy(&pUsbCore->rx_queue[idx_ep],
+ &pUsbCore->ep_rx_info[CFG_TO_INDEX(configuration)][idx_ep].queue_info,
+ sizeof(usbc_core_queue_t));
+ pUsbCore->rx_queue[idx_ep].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ pUsbCore->class_device[pUsbCore->rx_queue[idx_ep].class_device_id].total_pipes ++;
+ }
+ }
+
+ /* According to Ming's comment in 2013/4/24, we can still set old property to hif if usb_configuration is changed to 0 */
+ //usbc_core_set_hif_configuration();
+
+ //usbc_trace_info(USBCORE_HIF_SET_CONFIG_HIF, pUsbCore->usb_configuration);
+ //usbc_core_set_usbhif_configuration(pUsbCore->usb_configuration);
+
+ if (pUsbCore->usb_configuration > 0) {
+ pUsbCore->state = USBC_USB_STATE_ATTACHED;
+ } else {
+ pUsbCore->state = USBC_USB_STATE_ATTACHING;
+ }
+
+
+ return;
+}
+
+
+kal_bool usbc_direct_dispatch_control_setup_packet(kal_uint8 class_device_id, void* pkt_ptr)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_bool handled = KAL_TRUE;
+ hifusb_setup_packet_t *p_setup = (hifusb_setup_packet_t*)pkt_ptr;
+ kal_uint8 infx;
+
+ pUsbCore->setup_packet.bmRequestType = p_setup->bmRequestType;
+ pUsbCore->setup_packet.bRequest = p_setup->bRequest;
+ pUsbCore->setup_packet.wValue = USBC_EF16P((kal_uint8*)&p_setup->wValue);
+ pUsbCore->setup_packet.wIndex = USBC_EF16P((kal_uint8*)&p_setup->wIndex);
+ pUsbCore->setup_packet.wLength = USBC_EF16P((kal_uint8*)&p_setup->wLength);
+
+ infx = usbc_class_device_get_1st_interface(class_device_id);
+
+ if ( (pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_TYPE_MASK) == USBC_REQUEST_TYPE_CLASS &&
+ (pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK) == USBC_REQUEST_RECIP_INTERFACE &&
+ (infx < pUsbCore->total_class_interfaces) ) {
+
+ (pUsbCore->class_interface[infx]).notify_control_setup_packet(class_device_id, pkt_ptr);
+ }
+ else {
+ /* unknown reqeuset */
+ //ASSERT(0);
+ handled = KAL_FALSE;
+ }
+
+ return handled;
+}
+
+void usbc_direct_class_device_submit_control_request(ufpm_send_ap_ep0_msg_t* ep0_rsp_ptr, kal_bool isIndication)
+{
+ // Send control results vai UFPM
+ ufpm_set_control_request(ep0_rsp_ptr, isIndication);
+}
+
+kal_bool usbc_direct_hif_usbq_chk_empty(hif_queue_type_e core_queue_hif_type, kal_uint8 logic_queue_no)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_bool isEmpty;
+ kal_bool isTx = ((core_queue_hif_type == HIFQ_TYPE_RX) || (core_queue_hif_type == HIFQ_TYPE_RX_W_BPS))? KAL_FALSE:KAL_TRUE;
+ kal_uint8 phy_queue_no = (isTx)? HIFUSB_EPNO_2_QNO(pUsbCore->tx_queue[logic_queue_no].ep_no):HIFUSB_EPNO_2_QNO(pUsbCore->rx_queue[logic_queue_no].ep_no);
+
+ isEmpty = hifusb_chk_que_empty(isTx, phy_queue_no);
+
+ usbc_data_trace(MD_TRC_USBCORE_DIRECT_CHK_QUEUE_EMPTY, isTx, logic_queue_no, phy_queue_no, isEmpty);
+
+ return isEmpty;
+}
+
+void usbc_direct_hifusb_set_usb_address_emulate(kal_uint8 address)
+{
+ // Do nothing because USB driver does not have to be notified for speed in USB fast path
+ return;
+}
+
+kal_bool usbc_direct_hifusb_set_usbhif_connect_disconnect()
+{
+ // Do nothing because USB driver does not have to be connect/disconnect USB
+ return KAL_TRUE;
+}
+
+void usbc_direct_init_ufpm_mapping_table(kal_uint8 config_no, kal_uint8 class_device_id, ufpm_usb_mapping_t* perClassMapTlb)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_endpoint_info_t *tx_ep, *rx_ep;
+ usbc_core_queue_t *tx_q, *rx_q;
+ kal_uint8 idx, mapTlbIdx = 0;
+
+ // Fill Tx EP/queue info into perClassMapTlb
+ for(idx = 0; idx < pUsbCore->resource_ep_tx_number[config_no]; idx++) {
+ tx_ep = &(pUsbCore->ep_tx_info[config_no][idx]);
+ tx_q = &(tx_ep->queue_info);
+
+ if(0 == tx_ep->epdscr_size) {
+ break;
+ }
+ else {
+ if(tx_q->class_device_id == class_device_id) {
+ perClassMapTlb[mapTlbIdx].type = 0x40 | ((tx_q->xfer_type - 1) << 2) | 0x00;
+ perClassMapTlb[mapTlbIdx].map = tx_q->ep_no;
+ perClassMapTlb[mapTlbIdx].maxPktSize = tx_q->max_packet_size;
+ perClassMapTlb[mapTlbIdx].queue_config = tx_q->config;
+ perClassMapTlb[mapTlbIdx].fifo_n = tx_q->fifo_n;
+ mapTlbIdx++;
+ }
+ }
+ }
+
+ // Fill Rx EP/queue info into perClassMapTlb
+ for(idx = 0; idx < pUsbCore->resource_ep_rx_number[config_no]; idx++) {
+ rx_ep = &(pUsbCore->ep_rx_info[config_no][idx]);
+ rx_q = &(rx_ep->queue_info);
+
+ if(0 == rx_ep->epdscr_size) {
+ break;
+ }
+ else {
+ if(rx_q->class_device_id == class_device_id) {
+ perClassMapTlb[mapTlbIdx].type = 0x40 | ((rx_q->xfer_type - 1) << 2) | 0x01;
+ perClassMapTlb[mapTlbIdx].map = rx_q->ep_no;
+ perClassMapTlb[mapTlbIdx].maxPktSize = rx_q->max_packet_size;
+ perClassMapTlb[mapTlbIdx].queue_config = rx_q->config;
+ perClassMapTlb[mapTlbIdx].fifo_n = rx_q->fifo_n;
+ mapTlbIdx++;
+ }
+ }
+ }
+
+ return;
+}
+
+kal_bool usbc_direct_hif_init(void)
+{
+ kal_bool result = KAL_FALSE;
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ result = hifusb_init_ufp();
+ ASSERT(result);
+ return result;
+}
+
+
+void usbc_direct_set_usb_mapping(kal_bool isTx, kal_uint8 md_q_no, kal_uint8 ap_ep_no)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ if(isTx) {
+ pUsbCore->tx_queue[md_q_no].ep_no = ap_ep_no;
+
+ } else {
+ pUsbCore->rx_queue[md_q_no].ep_no = ap_ep_no;
+ }
+}
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_direct_ut.c b/mcu/middleware/hif/usbcore/src/usbcore_direct_ut.c
new file mode 100644
index 0000000..4ff1011
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_direct_ut.c
@@ -0,0 +1,99 @@
+/*!
+ * @file usbcore_direct_ut.c
+ * @author Roger Huang <bo-kai.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main functions of usbcore
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_hif.h"
+#include "usbcore_usbstd.h"
+#include "usbcore_main.h"
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#include "sysservice_msgid.h"
+#include "nvram_interface.h"
+#include "nvram_data_items.h"
+#include "usbcore_debug.h"
+
+#include "hif_usb.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#include "hifusb_qmu.h"
+#include "hif_ior.h"
+#include "qmu_bm_util.h"
+#include "qmu_bm.h"
+#include "usbcore_ind_q.h"
+#include "usbcore_direct.h"
+#include "ufpm_if.h"
+
+usbc_usb_speed_e usbc_direct_ut_get_speed()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ return pUsbCore->speed;
+}
+
+kal_uint8 usbc_direct_ut_get_address()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ return pUsbCore->usb_address;
+}
+
+kal_uint8 usbc_direct_ut_get_config()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ return pUsbCore->usb_configuration;
+}
+
+usbc_usb_state_e usbc_direct_ut_get_state()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ return pUsbCore->state;
+}
+
+kal_uint8 usbc_direct_ut_get_total_device()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ return pUsbCore->total_class_devices;
+}
+
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_dual_owner.c b/mcu/middleware/hif/usbcore/src/usbcore_dual_owner.c
new file mode 100644
index 0000000..6f4d349
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_dual_owner.c
@@ -0,0 +1,616 @@
+/*!
+ * @file usbcore_dual_owner.c
+ * @author Yuhao.Ye <yuhao.ye@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides functions of usbcore dual owner handle
+ */
+
+#include "kal_public_api.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#include "usbcore_common.h"
+#include "usbcore_dual_owner.h"
+#include "usbcore_usbstd.h"
+#include "usbcore_debug.h"
+#include "hif_mw_msgid.h"
+#include "us_timer.h"
+#include "sleepdrv_interface.h"
+
+dual_usb_owner_msg_s g_dual_usb_owner_msg = {0};
+char apusb_ctrl_data_buffer[1024] = {0};
+kal_bool g_write_done_flag;
+kal_uint32 g_apusb_rsp_flag = APUBS_SETUP_RSP_IDLE;
+
+void dual_usb_owner_write_done_callback()
+{
+ g_write_done_flag = KAL_TRUE;
+}
+kal_bool dual_usb_owner_send_msg_over_ccci()
+{
+ kal_int32 write_ret = 0;
+ kal_uint32 tick_count = 0;
+ g_write_done_flag = KAL_FALSE;
+
+ write_ret = nccci_write(CCCI_USB_FWD_CHANNEL, &g_dual_usb_owner_msg, g_dual_usb_owner_msg.msg_hdr.msg_length);
+ if(write_ret < 0){
+ /*error handle*/
+ usbc_trace_error(USBCORE_DUAL_OWNER_CCCI_WRITE, write_ret);
+ EXT_ASSERT(0, USBCORE_LOC_SEND_OVER_CCCI_FAIL, (kal_uint32)g_dual_usb_owner_msg.msg_hdr.msg_type, (kal_uint32)g_dual_usb_owner_msg.msg_hdr.msg_length);
+ return KAL_FALSE;
+ }
+ else if(write_ret == 0)
+ {
+ /*wait for callback function*/
+ while(1)
+ {
+ kal_sleep_task(USBC_DEV_DURATION_CCCI_DL_DONE_TICK);
+ /*sleep, wait for AP response, then break*/
+ if(g_write_done_flag == KAL_TRUE)
+ {
+ write_ret = nccci_write(CCCI_USB_FWD_CHANNEL, &g_dual_usb_owner_msg, g_dual_usb_owner_msg.msg_hdr.msg_length);
+ break;
+ }
+
+ if((++tick_count) > USB_DUAL_OWNER_WRITE_DONE_MAX_TICK)
+ {
+ /*error log*/
+ usbc_trace_error(USBCORE_DUAL_OWNER_RECEIVE_CCCI_DL_DONE_TIMEOUT);
+ //EXT_ASSERT(0, USBCORE_LOC_SEND_OVER_CCCI_TIMEOUT, (kal_uint32)g_dual_usb_owner_msg.msg_hdr.msg_type, (kal_uint32)g_dual_usb_owner_msg.msg_hdr.msg_length);
+ return KAL_FALSE;
+ }
+ }
+ }
+ else if(write_ret < g_dual_usb_owner_msg.msg_hdr.msg_length){
+ /*error handle*/
+ usbc_trace_error(USBCORE_DUAL_OWNER_CCCI_WRITE, write_ret);
+ return KAL_FALSE;
+ }
+
+ /*write OK*/
+ return KAL_TRUE;
+
+}
+
+kal_bool dual_usb_owner_read_data_over_ccci(char * buffer, kal_uint32 size)
+{
+ kal_uint32 read_ret;
+
+ read_ret = nccci_read(CCCI_USB_FWD_CHANNEL, buffer, size);
+ if(read_ret != size)
+ {
+ /*error handle*/
+ usbc_trace_error(USBCORE_DUAL_OWNER_CCCI_READ, read_ret);
+ EXT_ASSERT(0, USBCORE_LOC_READ_OVER_CCCI_FAIL, 0, 0);
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+dual_usb_owner_class_type_e class_device_type_to_dual_class_type(usb_class_type_e type)
+{
+ dual_usb_owner_class_type_e transfer_type;
+ switch(type)
+ {
+#ifdef __USB_ACM_SUPPORT__
+ case USB_CLASS_ACM1:
+ transfer_type = USB_CLASS_TYPE_CDC_ACM1;
+ break;
+ case USB_CLASS_ACM2:
+ transfer_type = USB_CLASS_TYPE_CDC_ACM2;
+ break;
+ case USB_CLASS_ACM3:
+ transfer_type = USB_CLASS_TYPE_CDC_ACM3;
+ break;
+#endif
+#ifdef __USB_ADB_SUPPORT__
+ case USB_CLASS_ADB:
+ transfer_type = USB_CLASS_TYPE_ADB;
+ break;
+#endif
+//#ifdef __USB_MSD_SUPPORT__
+ case USB_CLASS_MS:
+ transfer_type = USB_CLASS_TYPE_MS;
+ break;
+//#endif
+ default:
+ transfer_type = USB_CLASS_TYPE_CDC_ACM1;
+ break;
+ }
+ return transfer_type;
+}
+
+
+void dual_usb_owner_load_device_info()
+{
+ usb_deivce_info_s device_info = {0};
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint32 device_class_idx, interface_idx, ep_idx;
+ kal_uint32 total_ep_num, total_if_num;
+ kal_uint32 if_num;
+ class_device_info_s *class_device_info;
+ interface_info_s *interface_info;
+ endpoint_info_s *endpont_info;
+ kal_uint32 ap_class_device_num = 0;
+
+ for(device_class_idx = 0; device_class_idx < pUsbCore->total_class_devices; device_class_idx++)
+ {
+ total_ep_num = 0;
+ if(pUsbCore->class_device[device_class_idx].owner == USB_CLASS_OWNER_MD)
+ continue;
+ pUsbCore->config_has_ap_port = KAL_TRUE;
+ class_device_info = &device_info.class_device_info[ap_class_device_num];
+ class_device_info->class_device_id = device_class_idx;
+ class_device_info->class_device_type = class_device_type_to_dual_class_type(pUsbCore->class_device[device_class_idx].class_type);
+ total_if_num = pUsbCore->class_device[device_class_idx].device_instance.total_interfaces;
+ class_device_info->total_interface_num = total_if_num;
+ usbc_trace_info(USBCORE_DUAL_OWNER_DEBUG_ATTACHED_INFO, "device_id", device_class_idx, "class_type", class_device_info->class_device_type );
+
+ for(interface_idx = 0; interface_idx < total_if_num; interface_idx++)
+ {
+ interface_info = &class_device_info->if_info[interface_idx];
+
+ if_num = pUsbCore->class_device[device_class_idx].device_instance.interface_no[interface_idx];
+ interface_info->interface_id = if_num;
+ interface_info->interface_type = pUsbCore->class_interface[if_num].interface_type;
+ usbc_trace_info(USBCORE_DUAL_OWNER_DEBUG_ATTACHED_INFO, "if_num", if_num, "if_type", interface_info->interface_type );
+ }
+ for ( ep_idx = 0; ep_idx < MAX_USBCORE_QUEUE_NUM; ep_idx++ )
+ {
+ if(pUsbCore->tx_queue[ep_idx].class_device_id == device_class_idx)
+ {
+ endpont_info = &class_device_info->ep_info[total_ep_num++];
+ endpont_info->class_device_id = device_class_idx;
+ endpont_info->maxpacketsize = pUsbCore->tx_queue[ep_idx].max_packet_size;
+ endpont_info->ep_type = pUsbCore->tx_queue[ep_idx].xfer_type;
+ endpont_info->endpoint_address = pUsbCore->tx_queue[ep_idx].ep_no | USBC_REQUEST_DIR_IN;
+ usbc_trace_info(USBCORE_DUAL_OWNER_DEBUG_ATTACHED_INFO, "ep_num", endpont_info->endpoint_address, "ep_class", device_class_idx );
+ }
+
+ if(pUsbCore->rx_queue[ep_idx].class_device_id == device_class_idx)
+ {
+ endpont_info = &class_device_info->ep_info[total_ep_num++];
+ endpont_info->class_device_id = device_class_idx;
+ endpont_info->maxpacketsize = pUsbCore->rx_queue[ep_idx].max_packet_size;
+ endpont_info->ep_type = pUsbCore->rx_queue[ep_idx].xfer_type;
+ endpont_info->endpoint_address = pUsbCore->rx_queue[ep_idx].ep_no | USBC_REQUEST_DIR_OUT;
+ usbc_trace_info(USBCORE_DUAL_OWNER_DEBUG_ATTACHED_INFO, "ep_num", endpont_info->endpoint_address, "ep_class", device_class_idx );
+ }
+ }
+ ap_class_device_num++;
+ }
+ device_info.total_class_device = ap_class_device_num;
+
+ kal_mem_cpy(&(g_dual_usb_owner_msg.msg_data), &device_info, sizeof(usb_deivce_info_s));
+ return ;
+}
+
+void dual_usb_wait_ap_suspend_done_timeout()
+{
+ usbc_trace_warn(USBCORE_WAIT_AP_SUSPEND_DOWN_TIMEOUT);
+ usbc_core_get_instance()->waiting_ap_clk_disable_flag = KAL_FALSE;
+ usbc_core_mask_intr(KAL_FALSE);
+ SleepDrv_UnlockSleep(SLEEP_CTL_USBCORE, SMP);
+}
+
+void dual_usb_wait_ap_attach_done_timeout()
+{
+ usbc_trace_warn(USBCORE_WAIT_AP_ATTACH_DOWN_TIMEOUT);
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_RECEIVE);
+}
+
+kal_bool dual_usb_owner_send_device_state(kal_uint32 type, kal_uint8 ext)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint32 msg_type = NOTIFY_MSG_ID_NUM;
+ kal_bool ret;
+ kal_uint32 length = sizeof(dual_usb_owner_msg_hdr_s);
+ kal_mem_set(&g_dual_usb_owner_msg, 0, sizeof(dual_usb_owner_msg_s));
+
+ switch(type)
+ {
+ case USBC_USB_STATE_ATTACHING:
+ case USBC_USB_STATE_DETACHED:
+ return KAL_TRUE;
+ case USBC_USB_STATE_ATTACHED:
+ msg_type = NOTIFY_EVT_ATTACHED;
+ length += sizeof(usb_deivce_info_s);
+ /*load data*/
+ dual_usb_owner_load_device_info();
+ if(pUsbCore->config_has_ap_port)
+ kal_set_timer(pUsbCore->usbc_ap_rsp_attached_done_timerid, dual_usb_wait_ap_attach_done_timeout, NULL, 20 * KAL_TICKS_100_MSEC_REAL, 0);
+ break;
+ case USBC_USB_STATE_DETACHING:
+ return KAL_TRUE;
+ case USBC_USB_STATE_SUSPENDING:
+ if(pUsbCore->state_in_hisr != USBC_USB_STATE_SUSPENDING)
+ return KAL_TRUE;
+ msg_type = NOTIFY_EVT_SUSPEND;
+ g_dual_usb_owner_msg.msg_hdr.msg_type = msg_type;
+ g_dual_usb_owner_msg.msg_hdr.msg_length = length;
+ ret = dual_usb_owner_send_msg_over_ccci();
+ usbc_trace_warn(USBCORE_DUAL_OWNER_NOTIFY_USB_STATE, msg_type, length, ret);
+
+ if(pUsbCore->usb_low_power_enable)
+ {
+ pUsbCore->waiting_ap_clk_disable_flag = KAL_TRUE;
+ msg_type = NOTIFY_EVT_SUSPENDED;
+ g_dual_usb_owner_msg.msg_hdr.msg_type = msg_type;
+ g_dual_usb_owner_msg.msg_hdr.msg_length = length;
+ ret = dual_usb_owner_send_msg_over_ccci();
+ kal_set_timer(pUsbCore->usbc_ap_rsp_suspend_done_timerid, dual_usb_wait_ap_suspend_done_timeout, NULL, USBC_AP_RSP_CHECK_MS, 0);
+ usbc_trace_warn(USBCORE_DUAL_OWNER_NOTIFY_USB_STATE, msg_type, length, ret);
+ }
+ return ret;
+ case USBC_USB_STATE_SUSPENDED:
+ return KAL_TRUE;
+ case USBC_USB_STATE_RESUME:
+ msg_type = NOTIFY_EVT_RESUME;
+ break;
+ case USBC_USB_STATE_RESET:
+ msg_type = NOTIFY_EVT_RESET;
+ length += sizeof(kal_uint32);
+ *(kal_uint32*)(g_dual_usb_owner_msg.msg_data) = (kal_uint32)ext;
+ usbc_core_get_instance()->ap_response_reset_evt_done = KAL_FALSE;
+ usbc_core_get_instance()->ap_response_evt_time = ust_get_current_time();
+ break;
+ case USBC_USB_STATE_PWRDOWN:
+ msg_type = NOTIFY_EVT_IP_PWRDOWN;
+ break;
+ default:
+ msg_type = type;
+ break;
+ }
+ g_dual_usb_owner_msg.msg_hdr.msg_type = msg_type;
+ g_dual_usb_owner_msg.msg_hdr.msg_length = length;
+
+ ret = dual_usb_owner_send_msg_over_ccci();
+ usbc_trace_warn(USBCORE_DUAL_OWNER_NOTIFY_USB_STATE, msg_type, length, ret);
+
+ return ret;
+}
+
+kal_bool dual_usb_owner_send_request( mdusb_msg_id_e msg_type)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_mem_set(&g_dual_usb_owner_msg, 0, sizeof(dual_usb_owner_msg_s));
+
+ g_dual_usb_owner_msg.msg_hdr.msg_type = msg_type;
+ g_dual_usb_owner_msg.msg_hdr.msg_length = sizeof(dual_usb_owner_msg_hdr_s) + sizeof(usbc_setup_packet_t);
+ kal_mem_cpy(&(g_dual_usb_owner_msg.msg_data), &(pUsbCore->setup_packet), sizeof(usbc_setup_packet_t));
+
+ if(msg_type == NOTIFY_EVT_FEATURE_SC)
+ usbc_trace_warn(USBCORE_DUAL_OWNER_NOTIFY_FEATURE_SC, pUsbCore->setup_packet.bRequest, pUsbCore->setup_packet.wValue, pUsbCore->setup_packet.wIndex);
+ else
+ usbc_trace_warn(USBCORE_DUAL_OWNER_NOTIFY_SEND_CLASS_REQUEST, pUsbCore->setup_packet.bRequest, pUsbCore->setup_packet.wValue, pUsbCore->setup_packet.wIndex);
+
+ return dual_usb_owner_send_msg_over_ccci();
+}
+
+void dual_usb_owner_send_feature_request()
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK;
+ kal_bool ret = 0;
+ ret = dual_usb_owner_send_request(NOTIFY_EVT_FEATURE_SC);
+
+ /*Set/clear STALL will not response host ACK directly, response host after AP handle done*/
+ if(bRecip == USBC_REQUEST_RECIP_ENDPOINT)
+ {
+ if(ret == KAL_TRUE)
+ {
+ g_apusb_rsp_flag = APUBS_SETUP_RSP_INIT;
+ dual_usb_owner_set_ap_rsp_timer();
+ }
+ else
+ {
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+ }
+ return;
+}
+
+kal_bool dual_usb_owner_send_req_data( )
+{
+ kal_bool ret = 0;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_mem_set(&g_dual_usb_owner_msg, 0, sizeof(dual_usb_owner_msg_s));
+
+ g_dual_usb_owner_msg.msg_hdr.msg_type = NOTIFY_EVT_CTRL_DATA;
+ g_dual_usb_owner_msg.msg_hdr.msg_length = sizeof(dual_usb_owner_msg_hdr_s) + pUsbCore->ap_setup_buf_rx_expected_len;
+ kal_mem_cpy(&(g_dual_usb_owner_msg.msg_data), &(pUsbCore->ap_setup_buf), pUsbCore->ap_setup_buf_rx_expected_len);
+ usbc_trace_warn(USBCORE_DUAL_OWNER_SEND_CTRL_OUT_DATA, g_dual_usb_owner_msg.msg_hdr.msg_length);
+ ret = dual_usb_owner_send_msg_over_ccci();
+ return ret;
+}
+
+void dual_usb_owner_ap_rsp_timeout()
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ /*MD do not receive rsp from AP*/
+ usbc_trace_error(USBCORE_DUAL_OWNER_SEND_CLASS_REQUEST_NO_RSP, pUsbCore->setup_packet.bRequest, pUsbCore->setup_packet.wValue, pUsbCore->setup_packet.wIndex);
+ //EXT_ASSERT(0, USBCORE_LOC_AP_RESPONSE_TIMEOUT, (kal_uint32)pUsbCore->setup_packet.bRequest, 0);
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ g_apusb_rsp_flag = APUSB_SETUP_RSP_TIMEOUT;
+}
+
+void dual_usb_owner_set_ap_rsp_timer()
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ kal_set_timer(pUsbCore->usbc_es_ap_rsp_timerid, dual_usb_owner_ap_rsp_timeout, NULL, USBC_AP_RSP_CHECK_MS, 0);
+ return;
+}
+
+void dual_usb_owner_class_control_request()
+{
+ kal_bool ret;
+ ret = dual_usb_owner_send_request(NOTIFY_EVT_CLASS_CTRL_REQ);
+ if(ret != KAL_TRUE)
+ return;
+
+ g_apusb_rsp_flag = APUBS_SETUP_RSP_INIT;
+ dual_usb_owner_set_ap_rsp_timer();
+
+ return ;
+}
+
+void dual_usb_owner_class_control_complete()
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ if(!(pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_DIR_IN))
+ {
+ (void)dual_usb_owner_send_req_data();
+ }
+ return;
+}
+
+void dual_usb_owner_apusb_remote_wakeup()
+{
+ kal_uint32 class_device_id = 0;
+
+ dual_usb_owner_read_data_over_ccci((char*)&class_device_id, sizeof(kal_uint32));
+ usbc_class_device_func_remote_wk((kal_uint8)class_device_id);
+
+ kal_mem_set(&g_dual_usb_owner_msg, 0, sizeof(dual_usb_owner_msg_s));
+
+ g_dual_usb_owner_msg.msg_hdr.msg_type = NOTIFY_EVT_FUNCTION_RESUME;
+ g_dual_usb_owner_msg.msg_hdr.msg_length = sizeof(dual_usb_owner_msg_hdr_s) + sizeof(kal_uint32);
+ *(kal_uint32*)g_dual_usb_owner_msg.msg_data = class_device_id;
+ usbc_trace_warn(USBCORE_DUAL_OWNER_RECEIVE_REMOTE_WAKEUP, class_device_id);
+ dual_usb_owner_send_msg_over_ccci();
+
+ return ;
+}
+
+void dual_usb_owner_apusb_ep_halt()
+{
+ apusb_ep_info_s ep_info = {0};
+ kal_uint32 i;
+ kal_bool ret;
+ usbc_core_queue_t* pQueue = NULL;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ ret = dual_usb_owner_read_data_over_ccci((char*)&ep_info, sizeof(apusb_ep_info_s));
+
+ /*TX*/
+ if (ep_info.endpoint_direct)
+ {
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->tx_queue[i].ep_no == ep_info.endpoint_num) &&
+ (pUsbCore->tx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
+ {
+ pQueue = &pUsbCore->tx_queue[i];
+ break;
+ }
+ }
+ } else {
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->rx_queue[i].ep_no == ep_info.endpoint_num) &&
+ (pUsbCore->rx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
+ {
+ pQueue = &pUsbCore->rx_queue[i];
+ break;
+ }
+ }
+ }
+
+ if(ret != KAL_TRUE || pQueue == NULL)
+ {
+ EXT_ASSERT(0, USBCORE_LOC_AP_SET_STALL_INVALID_EP, (kal_uint32)ep_info.endpoint_num, (kal_uint32)ep_info.endpoint_direct);
+ return ;
+ }
+
+ pQueue->state = USBC_CORE_QUEUE_STATE_STALL;
+ return;
+}
+
+void dual_usb_owner_ilm_handle()
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ dual_usb_owner_msg_hdr_s msg_hdr = {0};
+
+ if(KAL_TRUE != dual_usb_owner_read_data_over_ccci((char*)&msg_hdr, sizeof(dual_usb_owner_msg_hdr_s)))
+ {
+ g_apusb_rsp_flag = APUSB_SETUP_RSP_FAIL;
+ return ;
+ }
+
+ if((msg_hdr.msg_length - sizeof(dual_usb_owner_msg_hdr_s)) > 0)
+ {
+ kal_mem_set(&apusb_ctrl_data_buffer, 0 , sizeof(apusb_ctrl_data_buffer));
+ dual_usb_owner_read_data_over_ccci((char*)&apusb_ctrl_data_buffer, msg_hdr.msg_length - sizeof(dual_usb_owner_msg_hdr_s));
+ }
+
+ usbc_trace_warn(USBCORE_DUAL_OWNER_RECEIVE_ILM_MSG, msg_hdr.msg_type, msg_hdr.msg_length);
+
+ switch(msg_hdr.msg_type)
+ {
+ case APUSB_RSP_STATUS_SUCCESS:
+ /*if g_apusb_rsp_flag != APUBS_SETUP_RSP_INIT, the class request has handled,ignore this msg*/
+ if(g_apusb_rsp_flag != APUBS_SETUP_RSP_INIT)
+ break;
+
+ kal_cancel_timer(pUsbCore->usbc_es_ap_rsp_timerid);
+ g_apusb_rsp_flag = APUSB_SETUP_RSP_SUCCESS;
+ pUsbCore->ap_setup_buf_rx_expected_len = pUsbCore->setup_packet.wLength;
+
+ if(pUsbCore->setup_packet.wLength > 0)
+ {
+ /*OUT requset*/
+ kal_mem_set(&(pUsbCore->ap_setup_buf), 0, MAX_USBCORE_CONTROL_REQUEST_BUFFER_SIZE);
+ usbc_core_set_control_request(pUsbCore->ap_setup_buf, pUsbCore->setup_packet.wLength, HIFUSB_CONTROL_REQUEST_TYPE_RECEIVE);
+ }
+ else
+ {
+ /*No data stage requset*/
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_RECEIVE);
+ }
+ break;
+ case APUSB_RSP_STATUS_STALL:
+ /*if g_apusb_rsp_flag != APUBS_SETUP_RSP_INIT, the class request has handled,ignore this msg*/
+ if(g_apusb_rsp_flag != APUBS_SETUP_RSP_INIT)
+ break;
+
+ kal_cancel_timer(pUsbCore->usbc_es_ap_rsp_timerid);
+ g_apusb_rsp_flag = APUSB_SETUP_RSP_STALL;
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ break;
+ case APUSB_RSP_SEND_DATA:
+ /*if g_apusb_rsp_flag != APUBS_SETUP_RSP_INIT, the class request has handled,ignore this msg*/
+ if(g_apusb_rsp_flag != APUBS_SETUP_RSP_INIT)
+ break;
+
+ kal_cancel_timer(pUsbCore->usbc_es_ap_rsp_timerid);
+ g_apusb_rsp_flag = APUSB_SETUP_RSP_DATA;
+ /*copy data to buffer*/
+ if((msg_hdr.msg_length - sizeof(dual_usb_owner_msg_hdr_s)) != pUsbCore->setup_packet.wLength){
+ /*warning*/
+ usbc_trace_warn(USBCORE_DUAL_OWNER_IN_DATA_LEN_ERROR, pUsbCore->setup_packet.wLength, (msg_hdr.msg_length - sizeof(dual_usb_owner_msg_hdr_s)));
+ }
+ usbc_core_set_control_request((kal_uint8 *)&apusb_ctrl_data_buffer, pUsbCore->setup_packet.wLength, HIFUSB_CONTROL_REQUEST_TYPE_SEND);
+ break;
+ case APUSB_NOTIFY_EVT_REMOTE_WAKEUP:
+ dual_usb_owner_apusb_remote_wakeup();
+ break;
+ case APUSB_NOTIFY_EVT_EP_HALT:
+ dual_usb_owner_apusb_ep_halt();
+ break;
+ case APUSB_NOTIFY_EVT_RESET_DONE:
+ pUsbCore->ap_response_reset_evt_done = KAL_TRUE;
+ break;
+ case APUSB_NOTIFY_EVT_SUSPEND_DONE:
+ kal_cancel_timer(pUsbCore->usbc_ap_rsp_suspend_done_timerid);
+ pUsbCore->usbc_wait_wakeup_event = KAL_TRUE;
+ usbc_core_mask_wakeup_event(KAL_FALSE);
+ pUsbCore->waiting_ap_clk_disable_flag = KAL_FALSE;
+ SleepDrv_UnlockSleep(SLEEP_CTL_USBCORE,SMP);
+ break;
+ case APUSB_NOTIFY_EVT_ATTACHED_DONE:
+ kal_cancel_timer(pUsbCore->usbc_ap_rsp_attached_done_timerid);
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_RECEIVE);
+ break;
+ default:
+ g_apusb_rsp_flag = APUSB_SETUP_RSP_FAIL;
+ break;
+ }
+}
+
+void dual_usb_owner_init()
+{
+ kal_int32 ret = 0;
+ NCCCI_ILM_REGISTRATION_STRUCT nccci_ilm_reg;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ /*init dual usb owner ap rsp timer*/
+ pUsbCore->usbc_es_ap_rsp_timerid = kal_create_timer("USBC_AP_RSP");
+ if (pUsbCore->usbc_es_ap_rsp_timerid == NULL)
+ {
+ EXT_ASSERT(0, USBCORE_LOC_DUAL_OWNER_TIMER_INIT_FAIL, 0, 0);
+ return;
+ }
+
+ pUsbCore->usbc_ap_rsp_suspend_done_timerid = kal_create_timer("USBC_SUSPEND_RSP");
+ if (pUsbCore->usbc_ap_rsp_suspend_done_timerid == NULL)
+ {
+ EXT_ASSERT(0, USBCORE_LOC_DUAL_OWNER_TIMER_INIT_FAIL, 0, 1);
+ return;
+ }
+
+ pUsbCore->usbc_ap_rsp_attached_done_timerid = kal_create_timer("USBC_ATTACHED_RSP");
+ if (pUsbCore->usbc_ap_rsp_attached_done_timerid == NULL)
+ {
+ EXT_ASSERT(0, USBCORE_LOC_DUAL_OWNER_TIMER_INIT_FAIL, 0, 2);
+ return;
+ }
+
+ ret = nccci_open(CCCI_USB_FWD_CHANNEL);
+ if(ret < 0)
+ {
+ EXT_ASSERT(0, USBCORE_LOC_INIT_CCCI_CHANNEL_FAIL_1, 0, 0);
+ return;
+ }
+
+ ret = nccci_ioctl(CCCI_USB_FWD_CHANNEL, NCCCI_IOCTL_SET_DL_CALLBACK, &dual_usb_owner_write_done_callback);
+ if(ret < 0)
+ {
+ EXT_ASSERT(0, USBCORE_LOC_INIT_CCCI_CHANNEL_FAIL_2, 0, 0);
+ return;
+ }
+
+ nccci_ilm_reg.module_id = MOD_USBCORE;
+ nccci_ilm_reg.msg_id = MSG_ID_USBCORE_DUAL_OWNER_MSG_RECEIVE;
+ nccci_ilm_reg.sap = 0;
+ ret = nccci_ioctl(CCCI_USB_FWD_CHANNEL, NCCCI_IOCTL_SET_UL_DONE_ILM, nccci_ilm_reg);
+ if(ret < 0)
+ {
+ EXT_ASSERT(0, USBCORE_LOC_INIT_CCCI_CHANNEL_FAIL_3, 0, 0);
+ return;
+ }
+ return ;
+}
+
+void dual_owner_funciton_register()
+{
+ usbc_dual_owner_init = dual_usb_owner_init;
+ usbc_dual_owner_ilm_handle = dual_usb_owner_ilm_handle;
+ usbc_dual_owner_class_ctrl_request = dual_usb_owner_class_control_request;
+ usbc_dual_owner_class_ctrl_complete = dual_usb_owner_class_control_complete;
+ usbc_dual_owner_send_feature_request = dual_usb_owner_send_feature_request;
+ usbc_dual_owner_notify_event = dual_usb_owner_send_device_state;
+}
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_except.c b/mcu/middleware/hif/usbcore/src/usbcore_except.c
new file mode 100644
index 0000000..928b64f
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_except.c
@@ -0,0 +1,1427 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * usbcore_except.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * USB Core exception mode wrapper.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+
+#include "usbcore_common.h"
+#include "usbcore_main.h"
+#include "usbcore_class_device.h"
+#include "usbcore_hif.h"
+#include "usbcore_except.h"
+
+#include "hifusb_qmu.h"
+#include "hifusb_qmu_except.h"
+#include "hif_usb_except.h"
+
+#if (defined(__MTK_TARGET__) && defined(__PRODUCTION_RELEASE__))
+#include "dcl.h"
+#endif
+
+#define CPU_PMU_CNT_WRAP (0xFFFFFFFFUL)
+#define CPU_GET_DURATION(_start, _end) \
+ ((_end) >= (_start)) ? ((_end) - (_start)) : (CPU_PMU_CNT_WRAP - (_start) + (_end) + 1))
+
+#ifdef __MTK_TARGET__
+ #ifdef USE_US_TIMER
+ #error "TODO: USE_US_TIMER"
+ #else /*use CPU performance counter, it might be not compatible for MAUI platform*/
+ //#include "cpu.h"
+
+ #define GET_CURR_TICK(_curr_tick) \
+ (_curr_tick) = kal_get_systicks()
+ //cpu_event_counter_get_cycle(_curr_tick)
+
+ #define GET_DURATION_MS(_start_tick, _end_tick) \
+ kal_ticks_to_milli_secs((CPU_GET_DURATION(_start_tick, _end_tick))
+ //CPU_PMUTICK2MS(cpu_event_get_duration(_start_tick, _end_tick))
+ #endif
+#else
+ #define GET_CURR_TICK(_curr_tick) (_curr_tick) = 0
+
+ #define GET_DURATION_MS(_start_tick, _end_tick) 0
+#endif
+
+/*------------------------------------------------------------------------------
+ * Constant definition.
+ *----------------------------------------------------------------------------*/
+#define USBC_EXCEPT_INFINITE_TIMEOUT 0xffffffff /* No timeout. */
+
+#define USBC_EXCEPT_MIN_ENUM_TIMEOUT 100 /* Minmal USB enumeration timeout in ms. */
+#define USBC_EXCEPT_DEF_ENUM_TIMEOUT 20000 /* Minmal USB enumeration timeout in ms. */
+
+#define USBC_EXCEPT_MIN_TX_TIMEOUT 100 /* Minmal USB tx transfer timeout in ms. */
+#define USBC_EXCEPT_DEF_TX_TIMEOUT 5000 /* Minmal USB tx transfer timeout in ms. */
+
+#define USBC_EXCEPT_CALL_EXCEPT_INIT 0x00000001
+#define USBC_EXCEPT_CALL_CLEAR_CH 0x00000002
+#define USBC_EXCEPT_CALL_RESET_CH 0x00000004
+#define USBC_EXCEPT_CALL_ENUM_LOOP 0x00000008
+#define USBC_EXCEPT_CALL_SUBMIT_GPD 0x00000010
+#define USBC_EXCEPT_CALL_POLL_QUEUE 0x00000020
+#define USBC_EXCEPT_CALL_HIF_STATE 0x00000040
+#define USBC_EXCEPT_CALL_HIF_POLL 0x00000080
+
+#define USBC_EXCEPT_NOTIFY_RESET 0x00000100
+#define USBC_EXCEPT_NOTIFY_SPEED_CHANGE 0x00000200
+
+#define USBC_EXCEPT_CALL_FLUSH 0x00001000
+
+#define USBC_EXCEPT_CLEAR_CH_NG 0x00010000
+#define USBC_EXCEPT_ENUM_LOOP_OK 0x00020000
+#define USBC_EXCEPT_ENUM_LOOP_TO 0x00040000
+#define USBC_EXCEPT_SUBMIT_GPD_NG 0x00080000
+#define USBC_EXCEPT_POLL_QUEUE_NG 0x00100000
+#define USBC_EXCEPT_HIF_STATE_NG 0x00200000
+#define USBC_EXCEPT_HIF_STATE_TO 0x00400000
+#define USBC_EXCEPT_FLUSH_NG 0x01000000
+
+
+#define INVALID_CLASS_DEVICE_ID 0xff
+#define INVALID_PIPE_QUEUE_ID 0xff
+#define PIPE_QUEUE_RX_MASK 0x80
+
+
+/*!
+ * @brief USB Core control transfer state in exception mode.
+ */
+typedef enum _usbc_except_ct_state {
+ USBC_EXCEPT_CT_READY = 0,
+ USBC_EXCEPT_CT_SETUP = 1,
+ USBC_EXCEPT_CT_DATA = 2,
+} usbc_except_ct_state_e;
+
+/*!
+ * @brief USB Core exception mode data path information for troubleshooting.
+ */
+typedef struct _usbc_except_data_log {
+ kal_uint32 tx_submit_called;
+ kal_uint32 tx_poll_called;
+ kal_uint32 tx_completed;
+ qbm_gpd *tx_last_gpd_submitted;
+ qbm_gpd *tx_last_gpd_polled;
+ kal_uint32 rx_submit_called;
+ kal_uint32 rx_poll_called;
+ kal_uint32 rx_completed;
+ qbm_gpd *rx_last_gpd_submitted;
+ qbm_gpd *rx_last_gpd_polled;
+} usbc_except_data_log;
+
+/*!
+ * @brief USB Core exception mode context.
+ */
+typedef struct _usbc_except_doc {
+ /*!
+ * @brief HIF driver allocated buffer for IN/OUT data of a control transfer in exception mode
+ */
+ kal_uint8 *ct_data_ptr;
+ /*!
+ * @brief Bytes used in except_ct_data_ptr
+ */
+ kal_uint32 ct_data_len;
+ /*!
+ * @brief Result of the control transfer.
+ */
+ hifusb_control_request_type_e ct_result;
+ /*!
+ * @brief Control transfer state.
+ */
+ usbc_except_ct_state_e ct_state;
+ kal_uint8 rsvd[2];
+ /*!
+ * @brief USB enumeration tiemout in unit of ms.
+ */
+ kal_uint32 enum_timeout;
+ /*!
+ * @brief Tx transfer tiemout in unit of ms.
+ */
+ kal_uint32 tx_timeout;
+} usbc_except_doc_t;
+
+static usbc_except_doc_t usbc_except_doc_s;
+#define usbc_except_get_doc() (&usbc_except_doc_s)
+
+static volatile kal_uint32 usbc_except_flags_s = 0; /* For troubleshooting USBCORE exception mode API.*/
+#define usbc_set_flag(_flag) usbc_except_flags_s |= (_flag)
+
+static usbc_except_data_log usbc_except_dlog_s; /* For USBCORE exception mode data path troubleshooting.*/
+#define usbc_dlog_reset() \
+ kal_mem_set( &usbc_except_dlog_s, 0, sizeof(usbc_except_data_log) )
+#define usbc_dlog_submit_gpd(_queue_type, _gpd) \
+ do { \
+ if (HIFQ_TYPE_TX == _queue_type) { \
+ usbc_except_dlog_s.tx_submit_called++; \
+ usbc_except_dlog_s.tx_last_gpd_submitted = (qbm_gpd *)(_gpd); \
+ } else { \
+ usbc_except_dlog_s.rx_submit_called++; \
+ usbc_except_dlog_s.rx_last_gpd_submitted = (qbm_gpd *)(_gpd); \
+ } \
+ } while (0)
+#define usbc_dlog_poll_queue(_queue_type, _gpd_cnt, _gpd) \
+ do { \
+ if (HIFQ_TYPE_TX == _queue_type) { \
+ usbc_except_dlog_s.tx_poll_called++; \
+ if (0 < (_gpd_cnt)) { \
+ usbc_except_dlog_s.tx_completed += (_gpd_cnt); \
+ usbc_except_dlog_s.tx_last_gpd_polled = (_gpd); \
+ } \
+ } else { \
+ usbc_except_dlog_s.rx_poll_called++; \
+ if (0 < (_gpd_cnt)) { \
+ usbc_except_dlog_s.rx_completed += (_gpd_cnt); \
+ usbc_except_dlog_s.rx_last_gpd_polled = (_gpd); \
+ } \
+ } \
+ } while (0)
+
+/*------------------------------------------------------------------------------
+ * Device/configuration/interface/endpoint Descriptors
+ *----------------------------------------------------------------------------*/
+#define USBC_DEF_VID 0x0E8D
+#define USBC_DEF_PID 0x7101
+#define USBC_TOTAL_INTERFACE_NUM 2
+#define USBC_INTERFACE_MTK_COM_0 0
+#define USBC_INTERFACE_MTK_COM_1 1
+
+#define USBC_DEF_STR_IDX_MANUFACTURER 0x01
+#define USBC_DEF_STR_IDX_PRODUCT 0x02
+#define USBC_DEF_STR_IDX_SERIALNUM 0x03
+
+#define __CDC_ACM_REPORT_IAD__
+
+/* MODE CDC_ACM Device Descriptors */
+static usbc_device_descriptor_t usbc_device_descriptor_cdc_acm =
+{
+ /* Device Descriptor */
+ 0x12, /* bLength */
+ USBC_DT_DEVICE, /* DEVICE */
+ 0x0200, /* USB 2.0 */
+#ifdef __CDC_ACM_REPORT_IAD__
+ 0xEF, /* CLASS */
+ 0x02, /* Subclass */
+ 0x01, /* Protocol */
+#else
+ 0x02, /* CLASS */
+ 0x00, /* Subclass */
+ 0x00, /* Protocol */
+#endif
+ 0x40, /* bMaxPktSize0 */
+ USBC_DEF_VID, /* idVendor */
+ USBC_DEF_PID, /* idProduct */
+ 0x0001, /* bcdDevice */
+ USBC_DEF_STR_IDX_MANUFACTURER, /* iManufacturer */
+ USBC_DEF_STR_IDX_PRODUCT, /* iProduct */
+#ifdef __PRODUCTION_RELEASE__
+ 0x00,
+#else
+/* under construction !*/
+#endif
+ 0x01 /* One configuration */
+};
+
+
+/* MODE CDC_ACM Configuration Descriptors */
+static struct _usbc_configuration_descriptor_cdc_acm {
+ usbc_configuration_descriptor_t configuration_descriptor;
+#ifdef __CDC_ACM_REPORT_IAD__
+ usbc_interface_association_descriptor_t interface_association_descriptor;
+#endif
+ usbc_interface_descriptor_t control_interface_descriptor;
+ usbc_cs_header_descriptor_t cs_header_descriptor;
+ usbc_cs_call_manage_descriptor_t cs_call_manage_descriptor;
+ usbc_cs_abstract_control_manage_descriptor_t cs_abstrac_control_manage_descriptor;
+ usbc_cs_union_function_descriptor_t cs_union_function_descriptor;
+ usbc_endpoint_descriptor_t commin_endpoint_descriptor;
+ usbc_interface_descriptor_t data_interface_descriptor;
+ usbc_endpoint_descriptor_t datain_endpoint_descriptor;
+ usbc_endpoint_descriptor_t dataout_endpoint_descriptor;
+} usbc_configuration_descriptor_cdc_acm = {
+{
+ /* Configuration Descriptor */
+ 0x09, /* bLength */
+ 0x02, /* CONFIGURATION */
+#ifdef __CDC_ACM_REPORT_IAD__
+ 0x004B, /* length */
+#else
+ 0x0043, /* length */
+#endif
+ USBC_TOTAL_INTERFACE_NUM, /* bNumInterfaces */
+ 0x01, /* bConfigurationValue */
+ 0x00, /* iConfiguration */
+ 0x80, /* bmAttributes (required + self-powered) */
+ 0xFA /* power */
+},
+#ifdef __CDC_ACM_REPORT_IAD__
+{
+ /* Interface Association Descriptor */
+ 0x08, /* bLength */
+ USBC_DT_IAD, /* bDescriptorType */
+ USBC_INTERFACE_MTK_COM_0, /* bFristInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00 /* iFunction */
+},
+#endif
+{
+ /* Comm Interface Descriptor */
+ 0x09, /* bLength */
+ USBC_DT_INTERFACE, /* INTERFACE */
+ USBC_INTERFACE_MTK_COM_0, /* bInterfaceNumber */
+ 0x00, /* bAlternatSetting */
+ 0x01, /* bNumberEnpoints */
+ 0x02, /* bInterface Class */
+ 0x02, /* SubClass */
+ 0x01, /* Protocol */
+ 0x00 /* Index of String */
+},
+{
+ /* CS Header Descriptor */
+ 0x05, /* bLength; */
+ 0x24, /* bDescriptorType; */
+ 0x00, /* bDescriptorSubType; */
+ 0x0110 /* bcdCDC; */
+},
+{
+ /* CS Call Manage Descriptor */
+ 0x05, /* bLength */
+ 0x24, /* bDescriptorType */
+ 0x01, /* bDescriptorSubType */
+ 0x03, /* bmCapabilities */
+ USBC_INTERFACE_MTK_COM_1 /* bDataInterface */
+},
+{
+ /* CS Abstract Control Manage Descriptor */
+ 0x04, /* bLength */
+ 0x24, /* bDescriptorType */
+ 0x02, /* bDescriptorSubType */
+ 0x0F /* bmCapabilities */
+},
+{
+ /* CS Union Function Descriptor */
+ 0x05, /* bLength; */
+ 0x24, /* bDescriptorType; */
+ 0x06, /* bDescriptorSubType; */
+ USBC_INTERFACE_MTK_COM_0, /* bMasterInterface; */
+ USBC_INTERFACE_MTK_COM_1 /* bSlaveInterface; */
+},
+{
+ /* Comm EndpointDescriptor */
+ 0x07, /* bLength */
+ 0x05, /* bDescriptorType */
+ 0x82, /* bEndpointAddress */
+ 0x03, /* bmAttributes */
+ 0x0040, /* wMaxPacketSize */
+ 0x01 /* bInterval */
+},
+{
+ /* Data Interface Descriptor */
+ 0x09, /* bLength */
+ USBC_DT_INTERFACE, /* INTERFACE */
+ USBC_INTERFACE_MTK_COM_1, /* bInterfaceNumber */
+ 0x00, /* bAlternatSetting */
+ 0x02, /* bNumberEnpoints */
+ 0x0A, /* bInterface Class */
+ 0x00, /* SubClass */
+ 0x00, /* Protocol */
+ 0x00 /* Index of String */
+},
+{
+ /* Data In Endpoint Descriptor */
+ 0x07, /* bLength */
+ 0x05, /* bDescriptorType */
+ 0x81, /* bEndpointAddress */
+ 0x02, /* bmAttributes */
+ 0x0200, /* wMaxPacketSize */
+ 0x00 /* bInterval */
+},
+{
+ /* Data Out EndpointDescriptor */
+ 0x07, /* bLength */
+ 0x05, /* bDescriptorType */
+ 0x01, /* bEndpointAddress */
+ 0x02, /* bmAttributes */
+ 0x0200, /* wMaxPacketSize */
+ 0x00 /* bInterval */
+}
+};
+
+/* MODE CDC_ACM Device Qualifier Descriptors */
+static usbc_device_qualifier_descriptor_t usbc_device_qualifier_descriptor_cdc_acm =
+{
+ /* Device Qualifier Descriptor */
+ 0x0A, /* bLength */
+ USBC_DT_DEVICE_QUALIFIER, /* Device Qualifier */
+ 0x0200, /* USB Version */
+#ifdef __CDC_ACM_REPORT_IAD__
+ 0xEF, /* CLASS */
+ 0x02, /* Subclass */
+ 0x01, /* Protocol */
+#else
+ 0x02, /* CLASS */
+ 0x00, /* Subclass */
+ 0x00, /* Protocol */
+#endif
+ 0x40, /* Max Packet Length */
+ 0x01, /* Number of other speed config */
+ 0x00 /* Reserved */
+};
+
+/* Default String Descriptor Language ID */
+static kal_uint8 usbc_string_descriptor_language_default[] =
+{
+ /* String Descriptor */
+ 0x04, /* bLength */
+ 0x03, /* bDescriptorType */
+ 0x09,0x04
+};
+
+
+/* Default String Descriptor Manufacturer */
+static kal_uint8 usbc_string_descriptor_manufacturer_default[] =
+{
+ /* String Descriptor */
+ 0x1c, /* bLength */
+ 0x03, /* bDescriptorType */
+ 'M',0x00,'e',0x00,'d',0x00,'i',0x00,
+ 'a',0x00,'T',0x00,'e',0x00,'k',0x00,
+ ' ',0x00,'I',0x00,'n',0x00,'c',0x00,
+ '.',0x00
+};
+
+
+/* Default String Descriptor Product */
+static kal_uint8 usbc_string_descriptor_product_default[] =
+{
+ /* String Descriptor */
+ 0x1a, /* bLength */
+ 0x03, /* bDescriptorType */
+ 'L',0x00,'T',0x00,'E',0x00,' ',0x00,
+ 'U',0x00,'S',0x00,'B',0x00,' ',0x00,
+ 'C',0x00,'A',0x00,'R',0x00,'D',0x00,
+};
+
+
+/* Default String Descriptor SerialNum */
+static kal_uint8 usbc_string_descriptor_serialnum_default[] =
+{
+ /* String Descriptor Serial Number */
+ 0x1a, /* bLength */
+ 0x03, /* bDescriptorType */
+ '6',0x00,'6',0x00,'5',0x00,'5',0x00,
+ '4',0x00,'4',0x00,'3',0x00,'3',0x00,
+ '2',0x00,'2',0x00,'1',0x00,'1',0x00
+};
+
+/*------------------------------------------------------------------------------
+ * Private implementation.
+ *----------------------------------------------------------------------------*/
+#define USBC_EXCEPT_MAX_TRACE_NUM 30
+#define USBC_EXCEPT_TRACE_SIG 0xBA000000
+
+kal_uint32 usbc_except_trace[USBC_EXCEPT_MAX_TRACE_NUM];
+kal_uint32 usbc_except_trace_idx = 0;
+void usbc_excpet_log_trace (kal_uint16 func_flag, kal_uint8 ret)
+{
+ usbc_except_trace_idx %= USBC_EXCEPT_MAX_TRACE_NUM;
+
+ usbc_except_trace[usbc_except_trace_idx] = USBC_EXCEPT_TRACE_SIG;
+ usbc_except_trace[usbc_except_trace_idx] |= ((func_flag & 0xFFFF) << 8);
+ usbc_except_trace[usbc_except_trace_idx] |= ret;
+
+ usbc_except_trace_idx ++;
+}
+
+static kal_bool usbc_except_hif_indicate_control_setup_packet(kal_uint8 intf_idx, usbc_setup_packet_t *packet)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_core_class_interface_t *intf = &pUsbCore->class_interface[intf_idx];
+
+ intf->notify_control_setup_packet(intf->class_device_id, packet);
+ return KAL_TRUE;
+}
+
+static void usbc_except_hif_indicate_control_complete(kal_uint8 intf_idx)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_core_class_interface_t *intf = &pUsbCore->class_interface[intf_idx];
+
+ intf->notify_control_complete(intf->class_device_id);
+}
+
+static kal_bool usbc_except_hif_set_control_request(kal_uint8 *buffer, kal_uint32 length, usbc_control_request_type_e type)
+{
+ ASSERT(USBC_EXCEPT_CT_SETUP == usbc_except_get_doc()->ct_state);
+ usbc_except_get_doc()->ct_state = USBC_EXCEPT_CT_DATA;
+
+ switch (type) {
+ case USBC_CONTROL_REQUEST_TYPE_SEND:
+ /*
+ * Control IN.
+ */
+ ASSERT(HIFUSB_CONTROL_REQUEST_TYPE_SEND == usbc_except_get_doc()->ct_result);
+ if (length > usbc_except_get_doc()->ct_data_len) {
+ length = usbc_except_get_doc()->ct_data_len;
+ }
+ kal_mem_cpy(usbc_except_get_doc()->ct_data_ptr, buffer, length);
+ usbc_except_get_doc()->ct_data_len = length;
+ usbc_except_get_doc()->ct_result = HIFUSB_CONTROL_REQUEST_TYPE_SEND;
+ break;
+
+ case USBC_CONTROL_REQUEST_TYPE_RECEIVE:
+ /*
+ * Control OUT.
+ */
+ ASSERT(HIFUSB_CONTROL_REQUEST_TYPE_RECEIVE == usbc_except_get_doc()->ct_result);
+ if (usbc_except_get_doc()->ct_data_len > length) {
+ usbc_except_get_doc()->ct_data_len = length;
+ }
+ kal_mem_cpy(buffer, usbc_except_get_doc()->ct_data_ptr, usbc_except_get_doc()->ct_data_len);
+ usbc_except_get_doc()->ct_result = HIFUSB_CONTROL_REQUEST_TYPE_RECEIVE;
+ break;
+
+ case USBC_CONTROL_REQUEST_TYPE_STALL:
+ /*
+ * HIF driver only allows control IN to return STALL
+ */
+ if (HIFUSB_CONTROL_REQUEST_TYPE_SEND == usbc_except_get_doc()->ct_result) {
+ usbc_except_get_doc()->ct_result = HIFUSB_CONTROL_REQUEST_TYPE_STALL;
+ } else {
+ usbc_except_get_doc()->ct_data_len = 0;
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ usbc_except_get_doc()->ct_data_len = 0;
+ break;
+ }
+ return KAL_TRUE;
+}
+
+static kal_bool usbc_except_hif_set_usb_address(kal_uint8 address)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ pUsbCore->usb_address = address;
+ hifusb_except_set_usb_address(pUsbCore->usb_address);
+
+ return KAL_TRUE;
+}
+
+static kal_bool usbc_except_hif_set_usb_configuration(kal_uint8 configuration)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ pUsbCore->usb_configuration = configuration;
+ hifusb_except_set_usb_configuration(pUsbCore->usb_configuration);
+
+ if ( pUsbCore->usb_configuration > 0 ) {
+ pUsbCore->state = USBC_USB_STATE_ATTACHED;
+ } else {
+ pUsbCore->state = USBC_USB_STATE_ATTACHING;
+ }
+
+ return KAL_TRUE;
+}
+
+static void usbc_except_hif_set_stall(kal_bool is_tx, kal_uint8 nEnd)
+{
+}
+
+static void usbc_except_hif_clear_stall(kal_bool is_tx, kal_uint8 nEnd)
+{
+}
+
+static kal_bool usbc_except_hif_set_usb_testmode(hifusb_test_mode_e testmode)
+{
+ return KAL_FALSE;
+}
+
+static void usbc_except_hif_start_dataq(kal_bool isTx, kal_uint8 q_no)
+{
+}
+
+static void usbc_except_hif_factory(void)
+{
+ usbc_core_indicate_control_setup_packet = usbc_except_hif_indicate_control_setup_packet;
+ usbc_core_indicate_control_complete = usbc_except_hif_indicate_control_complete;
+ usbc_core_indicate_alternate_setting = usbc_core_notify_alternate_setting;
+ usbc_core_indicate_stall = usbc_core_notify_stall;
+ usbc_core_set_control_request = usbc_except_hif_set_control_request;
+ usbc_core_set_property = hifusb_except_set_property;
+ usbc_core_set_usb_address = usbc_except_hif_set_usb_address;
+ usbc_core_set_usb_configuration = usbc_except_hif_set_usb_configuration;
+ usbc_core_set_stall = usbc_except_hif_set_stall;
+ usbc_core_clear_stall = usbc_except_hif_clear_stall;
+ usbc_core_set_usb_testmode = usbc_except_hif_set_usb_testmode;
+ usbc_core_start_dataq = usbc_except_hif_start_dataq;
+}
+
+static void usbc_except_load_settings(void)
+{
+ if (usbc_core_get_hmu_info()->enum_timeout >= USBC_EXCEPT_MIN_ENUM_TIMEOUT) {
+ usbc_except_get_doc()->enum_timeout = usbc_core_get_hmu_info()->enum_timeout;
+ } else {
+ usbc_except_get_doc()->enum_timeout = USBC_EXCEPT_DEF_ENUM_TIMEOUT;
+ }
+ if (usbc_core_get_hmu_info()->tx_timeout >= USBC_EXCEPT_MIN_TX_TIMEOUT) {
+ usbc_except_get_doc()->tx_timeout = usbc_core_get_hmu_info()->tx_timeout;
+ } else {
+ usbc_except_get_doc()->tx_timeout = USBC_EXCEPT_DEF_TX_TIMEOUT;
+ }
+}
+
+static void usbc_except_init_context(void)
+{
+ /*if project suppot factory mode, use factory PID*/
+ if(USBC_OP_MODE_FACTORY == usbc_get_op_mode())
+ usbc_device_descriptor_cdc_acm.idProduct = usb_get_factory_mode_pid();
+
+ /*
+ * Initialize USB Core context for exception mode.
+ */
+ kal_mem_set(usbc_except_get_doc(), 0, sizeof(usbc_except_doc_t));
+ usbc_except_load_settings();
+
+ usbc_set_op_mode(USBC_OP_MODE_EXCEPTION);
+ kal_mem_set(usbc_core_get_instance(), 0, sizeof(usbc_core_t));
+
+ usbc_except_hif_factory();
+ usbc_resource_reset();
+ usbc_core_clear_register();
+ usbc_core_clear_status();
+}
+
+static void usbc_except_read_configuration(void)
+{
+ /*
+ * Currently, we assume exception mode only uses 1 CDC/ACM COM port configuration.
+ */
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ /* configure descriptor */
+ kal_mem_cpy(pUsbCore->descriptors.device, &usbc_device_descriptor_cdc_acm, USBC_DEVICE_DESC_SIZE);
+ kal_mem_cpy(pUsbCore->descriptors.configuration[0], &usbc_configuration_descriptor_cdc_acm, sizeof(usbc_configuration_descriptor_cdc_acm));
+ kal_mem_cpy(&pUsbCore->device_qualifier_descriptor , &usbc_device_qualifier_descriptor_cdc_acm, sizeof(usbc_device_qualifier_descriptor_t));
+
+ pUsbCore->total_class_devices = 1;
+ /* configure 1st class device */
+ pUsbCore->class_device[0].class_type = USB_CLASS_ACM2;
+ pUsbCore->class_device[0].state = USBC_CORE_CLASS_DEVICE_STATE_INITIATED;
+ pUsbCore->class_device[0].total_pipes = 3;
+
+ pUsbCore->total_class_interfaces = 2;
+ /* configure 1st class interface */
+ pUsbCore->class_interface[0].class_device_id = 0;
+ pUsbCore->class_interface[0].interface_no = usbc_configuration_descriptor_cdc_acm.control_interface_descriptor.bInterfaceNumber;
+ pUsbCore->class_interface[0].interface_type = USBC_INTERFACE_TYPE_CDC_ACM_CONTROL;
+ pUsbCore->class_interface[0].state = USBC_CORE_CLASS_INTERFACE_STATE_INITIATED;
+ pUsbCore->class_interface[0].alternate_setting = 0;
+
+ /* configure 2nd class interface */
+ pUsbCore->class_interface[1].class_device_id = 0;
+ pUsbCore->class_interface[1].interface_no = usbc_configuration_descriptor_cdc_acm.data_interface_descriptor.bInterfaceNumber;
+ pUsbCore->class_interface[1].interface_type = USBC_INTERFACE_TYPE_CDC_ACM_DATA;
+ pUsbCore->class_interface[1].state = USBC_CORE_CLASS_INTERFACE_STATE_INITIATED;
+ pUsbCore->class_interface[1].alternate_setting = 0;
+
+ pUsbCore->total_tx_queues = 2;
+ /* configure 1st transmit queue */
+ pUsbCore->tx_queue[0].class_device_id = 0;
+ pUsbCore->tx_queue[0].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ pUsbCore->tx_queue[0].pipe_type = USBC_PIPE_TYPE_CDC_ACM_DATA_IN;
+ pUsbCore->tx_queue[0].xfer_type = HIFUSB_EP_XFER_TYPE_BULK;
+ pUsbCore->tx_queue[0].ep_no = usbc_configuration_descriptor_cdc_acm.datain_endpoint_descriptor.bEndpointAddress & ~0x80;
+ pUsbCore->tx_queue[0].max_packet_size = usbc_configuration_descriptor_cdc_acm.datain_endpoint_descriptor.wMaxPacketSize;
+ pUsbCore->tx_queue[0].fifo_n = 2;
+#ifdef ENABLE_QMU_CHECKSUM
+ pUsbCore->tx_queue[0].config = HIFUSB_QMU_EN | HIFUSB_QMU_CS_EN | HIFUSB_QMU_TXQ_ZLP | HIFUSB_QMU_TXQ_EMPTY_ENQ | HIFUSB_QMU_TXQ_SPD_EN;
+#else
+ pUsbCore->tx_queue[0].config = HIFUSB_QMU_EN | HIFUSB_QMU_TXQ_ZLP | HIFUSB_QMU_TXQ_EMPTY_ENQ | HIFUSB_QMU_TXQ_SPD_EN;
+#endif
+
+ /* configure 2nd transmit queue */
+ pUsbCore->tx_queue[1].class_device_id = 0;
+ pUsbCore->tx_queue[1].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ pUsbCore->tx_queue[1].pipe_type = USBC_PIPE_TYPE_CDC_ACM_COMM_IN;
+ pUsbCore->tx_queue[1].xfer_type = HIFUSB_EP_XFER_TYPE_INT;
+ pUsbCore->tx_queue[1].ep_no = usbc_configuration_descriptor_cdc_acm.commin_endpoint_descriptor.bEndpointAddress & ~0x80;
+ pUsbCore->tx_queue[1].max_packet_size = usbc_configuration_descriptor_cdc_acm.commin_endpoint_descriptor.wMaxPacketSize;
+ pUsbCore->tx_queue[1].fifo_n = 1;
+#ifdef ENABLE_QMU_CHECKSUM
+ pUsbCore->tx_queue[1].config = HIFUSB_QMU_EN | HIFUSB_QMU_CS_EN;
+#else
+ pUsbCore->tx_queue[1].config = HIFUSB_QMU_EN;
+#endif
+
+ pUsbCore->total_rx_queues = 1;
+ /* configure 1st receive queue */
+ pUsbCore->rx_queue[0].class_device_id = 0;
+ pUsbCore->rx_queue[0].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ pUsbCore->rx_queue[0].pipe_type = USBC_PIPE_TYPE_CDC_ACM_DATA_OUT;
+ pUsbCore->rx_queue[0].xfer_type = HIFUSB_EP_XFER_TYPE_BULK;
+ pUsbCore->rx_queue[0].ep_no = usbc_configuration_descriptor_cdc_acm.dataout_endpoint_descriptor.bEndpointAddress & ~0x80;
+ pUsbCore->rx_queue[0].max_packet_size = usbc_configuration_descriptor_cdc_acm.dataout_endpoint_descriptor.wMaxPacketSize;
+ pUsbCore->rx_queue[0].fifo_n = 2;
+#ifdef ENABLE_QMU_CHECKSUM
+ pUsbCore->rx_queue[0].config = HIFUSB_QMU_EN | HIFUSB_QMU_CS_EN;
+#else
+ pUsbCore->rx_queue[0].config = HIFUSB_QMU_EN;
+#endif
+
+ /* String descriptor */
+ pUsbCore->string_descriptor[0] = (usbc_string_descriptor_t*)usbc_string_descriptor_language_default;
+ pUsbCore->string_descriptor[USBC_DEF_STR_IDX_MANUFACTURER] = (usbc_string_descriptor_t*)usbc_string_descriptor_manufacturer_default;
+ pUsbCore->string_descriptor[USBC_DEF_STR_IDX_PRODUCT] = (usbc_string_descriptor_t*)usbc_string_descriptor_product_default;
+ pUsbCore->string_descriptor[USBC_DEF_STR_IDX_SERIALNUM] = (usbc_string_descriptor_t*)usbc_string_descriptor_serialnum_default;
+ pUsbCore->resource_string_number = 4;
+
+ /* Reset speed */
+ pUsbCore->speed = USBC_USB_SPEED_MIN;
+}
+
+static void usbc_except_restart_watchdog(void)
+{
+#if (defined(__MTK_TARGET__) && defined(__PRODUCTION_RELEASE__))
+ DCL_HANDLE dcl_wdt_handle;
+
+ dcl_wdt_handle = DclWDT_Open(DCL_WDT, 0);
+ DclWDT_Control(dcl_wdt_handle,WDT_CMD_RESTART, 0);
+ DclWDT_Close(dcl_wdt_handle);
+
+#endif // #if (defined(__MTK_TARGET__) && defined(__PRODUCTION_RELEASE__))
+}
+
+/*------------------------------------------------------------------------------
+ * HIF callback functions.
+ *----------------------------------------------------------------------------*/
+static void usbc_except_compile_ep_companion(kal_uint8 *dst_desc, kal_uint8 transfer_type)
+{
+ USBC_SET_DESC_LENGTH(dst_desc, USBC_ENDPOINT_COMPANION_DESC_SIZE);
+ USBC_SET_DESC_TYPE(dst_desc, USBC_DT_ENDPOINT_COMPANION);
+ USBC_SET_EPC_ATTRIBUTES(dst_desc, 0);
+
+ if (USBC_BULK_TRANSFER == transfer_type) {
+ USBC_SET_EPC_MAX_BURST(dst_desc, 1);
+ USBC_SET_EPC_BYTES_PER_INTERVAL(dst_desc, 0);
+ } else {
+ USBC_SET_EPC_MAX_BURST(dst_desc, 0);
+ USBC_SET_EPC_BYTES_PER_INTERVAL(dst_desc, 0x40);
+ }
+}
+
+static void usbc_except_configuration_speed_change(usbc_core_t *pUsbCore, usbc_usb_speed_e speed)
+{
+ kal_uint32 total_len;
+ kal_uint32 bytes_read;
+ kal_uint32 bytes_written;
+ kal_uint8 *desc_read;
+ kal_uint8 *desc_to_write;
+ kal_uint32 desc_len;
+ kal_uint32 idx_ep;
+ kal_uint8 conf[USBC_MAX_CONF_SIZE];
+
+ kal_mem_cpy(conf, pUsbCore->descriptors.configuration[0], USBC_MAX_CONF_SIZE);
+ bytes_read = 0;
+ bytes_written = 0;
+ total_len = USBC_GET_CONF_TOTAL_LENGTH(conf);
+
+ while (bytes_read < total_len)
+ {
+ desc_read = conf + bytes_read;
+ desc_to_write = pUsbCore->descriptors.configuration[0] + bytes_written;
+ desc_len = USBC_GET_DESC_LENGTH(desc_read);
+
+ kal_mem_cpy(desc_to_write, desc_read, desc_len);
+ bytes_written += desc_len;
+
+ switch (USBC_GET_DESC_TYPE(desc_read))
+ {
+ case USBC_DT_ENDPOINT:
+ {
+ if (USBC_BULK_TRANSFER == USBC_GET_EP_TRANSFER_TYPE(desc_to_write))
+ {
+ switch (speed) {
+ case USBC_USB_SPEED_USB11:
+ {
+ USBC_SET_EP_MAX_PACKET_SIZE(desc_to_write, USBC_USB11_MAX_PACKET_SIZE);
+ break;
+ }
+ case USBC_USB_SPEED_USB20:
+ {
+ USBC_SET_EP_MAX_PACKET_SIZE(desc_to_write, USBC_USB20_MAX_PACKET_SIZE);
+ break;
+ }
+ case USBC_USB_SPEED_USB30:
+ {
+ USBC_SET_EP_MAX_PACKET_SIZE(desc_to_write, USBC_USB30_MAX_PACKET_SIZE);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ if (speed == USBC_USB_SPEED_USB30) {
+ if (bytes_written + USBC_ENDPOINT_COMPANION_DESC_SIZE <= USBC_MAX_CONF_SIZE) {
+ usbc_except_compile_ep_companion(desc_to_write + desc_len, USBC_GET_EP_TRANSFER_TYPE(desc_to_write));
+ bytes_written += USBC_ENDPOINT_COMPANION_DESC_SIZE;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ bytes_read += desc_len;
+ }
+
+ /*
+ * Patch configuration descriptor.
+ */
+ if (speed == USBC_USB_SPEED_USB30) {
+ USBC_SET_CONF_MAX_POWER(pUsbCore->descriptors.configuration[0], (896 / USBC_USB30_POWER_DESC_UINT));
+ }
+ USBC_SET_CONF_TOTAL_LENGTH(pUsbCore->descriptors.configuration[0], bytes_written);
+
+ /*
+ * Modify max packet size in tx/rx endpoint queue info
+ */
+ for (idx_ep = 0; idx_ep < pUsbCore->total_tx_queues; idx_ep ++)
+ {
+ if (pUsbCore->tx_queue[idx_ep].xfer_type == HIFUSB_EP_XFER_TYPE_BULK)
+ {
+ switch (speed) {
+ case USBC_USB_SPEED_USB11:
+ {
+ pUsbCore->tx_queue[idx_ep].max_packet_size = USBC_USB11_MAX_PACKET_SIZE;
+ break;
+ }
+ case USBC_USB_SPEED_USB20:
+ {
+ pUsbCore->tx_queue[idx_ep].max_packet_size = USBC_USB20_MAX_PACKET_SIZE;
+ break;
+ }
+ case USBC_USB_SPEED_USB30:
+ {
+ pUsbCore->tx_queue[idx_ep].max_packet_size = USBC_USB30_MAX_PACKET_SIZE;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ }
+ for (idx_ep = 0; idx_ep < pUsbCore->total_rx_queues; idx_ep ++)
+ {
+ if (pUsbCore->rx_queue[idx_ep].xfer_type == HIFUSB_EP_XFER_TYPE_BULK)
+ {
+ switch (speed) {
+ case USBC_USB_SPEED_USB11:
+ {
+ pUsbCore->rx_queue[idx_ep].max_packet_size = USBC_USB11_MAX_PACKET_SIZE;
+ break;
+ }
+ case USBC_USB_SPEED_USB20:
+ {
+ pUsbCore->rx_queue[idx_ep].max_packet_size = USBC_USB20_MAX_PACKET_SIZE;
+ break;
+ }
+ case USBC_USB_SPEED_USB30:
+ {
+ pUsbCore->rx_queue[idx_ep].max_packet_size = USBC_USB30_MAX_PACKET_SIZE;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ }
+}
+static void usbc_except_speed_change(usbc_core_t *pUsbCore, usbc_usb_speed_e speed)
+{
+ usbc_device_descriptor_t *dev_desc;
+
+ pUsbCore->speed = speed;
+ dev_desc = (usbc_device_descriptor_t *)pUsbCore->descriptors.device;
+
+ /*
+ * Device descriptor speed change
+ */
+ switch (speed) {
+ case USBC_USB_SPEED_USB30:
+ dev_desc->bcdUSB = 0x0300;
+ dev_desc->bMaxPacketSize0 = USBC_USB30_EP0_PACKET_SIZE;
+ break;
+
+ default:
+ dev_desc->bcdUSB = 0x0210;
+ dev_desc->bMaxPacketSize0 = 64;
+ break;
+ }
+
+ /*
+ * Configuration descriptor speed change
+ */
+ usbc_except_configuration_speed_change(pUsbCore, speed);
+}
+
+static void usbc_core_notify_usb_event(hifusb_notify_evt_e event, void *data)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_usb_speed_e speed;
+
+ USBC_EXCEPTION_MODE_CHECK();
+
+ /*
+ * In exception mode:
+ *
+ * 1. For simplicity, we don't indicate any USB event to USB Class.
+ * 2. When HIF driver indicates RESET event to USBCORE,
+ * we will notify USB Class about the current USB speed and then
+ * set HIF IP related configruation.
+ *
+ */
+ switch (event) {
+ case HIFUSB_NOTIFY_EVT_RESET:
+ usbc_set_flag(USBC_EXCEPT_NOTIFY_RESET);
+ speed = *(usbc_usb_speed_e*)data;
+ usbc_excpet_log_trace(USBC_EXCEPT_NOTIFY_RESET, 0);
+ if (speed != pUsbCore->speed) {
+ /*
+ * Change USB link speed and related settings.
+ */
+ usbc_set_flag(USBC_EXCEPT_NOTIFY_SPEED_CHANGE);
+ usbc_except_speed_change(pUsbCore, speed);
+ usbc_core_notify_speed_change(speed);
+ usbc_excpet_log_trace(USBC_EXCEPT_NOTIFY_SPEED_CHANGE, 0);
+ }
+ pUsbCore->state = USBC_USB_STATE_RESET;
+ usbc_core_set_hif_configuration();
+ usbc_core_notify_state_reset();
+ pUsbCore->usb_configuration = 0;
+ usbc_except_get_doc()->ct_state = USBC_EXCEPT_CT_READY;
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+static hifusb_control_request_type_e usbc_except_notify_usb_except_control_in(hifusb_setup_packet_t *p_setup, void *p_buf, kal_uint32 *p_len)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ hifusb_control_request_type_e result;
+
+ USBC_EXCEPTION_MODE_CHECK();
+
+ ASSERT(USBC_EXCEPT_CT_READY == usbc_except_get_doc()->ct_state);
+ usbc_except_get_doc()->ct_data_ptr = (kal_uint8 *)p_buf;
+ usbc_except_get_doc()->ct_data_len = HIFUSB_EXCEPT_EP_BUF_SZ;
+ usbc_except_get_doc()->ct_result = HIFUSB_CONTROL_REQUEST_TYPE_SEND;
+ usbc_except_get_doc()->ct_state = USBC_EXCEPT_CT_SETUP;
+
+ usbc_core_dispatch_control_setup_packet(pUsbCore, p_setup);
+ ASSERT(USBC_EXCEPT_CT_DATA == usbc_except_get_doc()->ct_state);
+
+ *p_len = usbc_except_get_doc()->ct_data_len;
+ result = usbc_except_get_doc()->ct_result;
+ usbc_core_notify_control_complete(pUsbCore);
+ usbc_except_get_doc()->ct_state = USBC_EXCEPT_CT_READY;
+
+ return result;
+}
+
+static hifusb_control_request_type_e usbc_except_notify_usb_except_control_out(hifusb_setup_packet_t *p_setup, void *p_buf, kal_uint32 len)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ hifusb_control_request_type_e result;
+
+ USBC_EXCEPTION_MODE_CHECK();
+
+ ASSERT(USBC_EXCEPT_CT_READY == usbc_except_get_doc()->ct_state);
+ usbc_except_get_doc()->ct_data_ptr = (kal_uint8 *)p_buf;
+ usbc_except_get_doc()->ct_data_len = len;
+ usbc_except_get_doc()->ct_result = HIFUSB_CONTROL_REQUEST_TYPE_RECEIVE;
+ usbc_except_get_doc()->ct_state = USBC_EXCEPT_CT_SETUP;
+
+ usbc_core_dispatch_control_setup_packet(pUsbCore, p_setup);
+ ASSERT(USBC_EXCEPT_CT_DATA == usbc_except_get_doc()->ct_state);
+
+ result = usbc_except_get_doc()->ct_result;
+ usbc_core_notify_control_complete(pUsbCore);
+ usbc_except_get_doc()->ct_state = USBC_EXCEPT_CT_READY;
+
+ return result;
+}
+
+/*------------------------------------------------------------------------------
+ * Public interface.
+ *----------------------------------------------------------------------------*/
+
+kal_bool usbc_except_init(void)
+{
+ usbc_set_flag(USBC_EXCEPT_CALL_EXCEPT_INIT);
+
+ usbc_except_load_settings();
+ hifusbq_except_initial();
+
+ usbc_excpet_log_trace(USBC_EXCEPT_CALL_EXCEPT_INIT, 1);
+ return KAL_TRUE;
+}
+
+kal_bool usbc_except_clear_ch(kal_uint8 class_device_id, kal_uint8 queue_no)
+{
+ usbc_core_queue_t *queue;
+ hif_queue_type_e queue_type;
+
+ usbc_set_flag(USBC_EXCEPT_CALL_CLEAR_CH);
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &queue, &queue_type)) {
+ usbc_set_flag(USBC_EXCEPT_CLEAR_CH_NG);
+ usbc_excpet_log_trace(USBC_EXCEPT_CALL_CLEAR_CH, 0);
+ return KAL_FALSE;
+ }
+
+ hifusbq_except_clear_q(queue_type, HIFUSB_EPNO_2_QNO(queue->ep_no));
+ usbc_excpet_log_trace(USBC_EXCEPT_CALL_CLEAR_CH, 1);
+ return KAL_TRUE;
+}
+
+static kal_uint8 usbc_except_acquire_pipe_queue(kal_uint8 class_device_id, usbc_pipe_type_e type)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 pipe_queue = INVALID_PIPE_QUEUE_ID;
+ kal_uint8 i = 0;
+
+ for ( i=0; i< MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->tx_queue[i].class_device_id == class_device_id) &&
+ (pUsbCore->tx_queue[i].pipe_type == type) &&
+ (pUsbCore->tx_queue[i].state == USBC_CORE_QUEUE_STATE_INITIATED))
+ {
+ pipe_queue = i;
+ break;
+ }
+ }
+
+ if ( pipe_queue != INVALID_PIPE_QUEUE_ID )
+ {
+ return pipe_queue;
+ }
+
+ for ( i=0; i< MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->rx_queue[i].class_device_id == class_device_id) &&
+ (pUsbCore->rx_queue[i].pipe_type == type) &&
+ (pUsbCore->rx_queue[i].state == USBC_CORE_QUEUE_STATE_INITIATED))
+ {
+ pipe_queue = (i | PIPE_QUEUE_RX_MASK);
+ break;
+ }
+ }
+
+ return pipe_queue;
+}
+
+static usbc_class_device_instance_t*
+usbc_except_device_register(
+ usbc_core_t *pUsbCore,
+ usbc_class_device_info_t *device_info)
+{
+ usbc_core_class_device_t* pClassDevice = NULL;
+ usbc_class_device_instance_t* pClassDeviceInstance = NULL;
+ usbc_core_queue_t* pQueue = NULL;
+ kal_uint8 acquire_queue = 0;
+ kal_uint8 i = 0;
+
+ if (device_info == NULL) {
+ return NULL;
+ }
+
+ /* found available device instance, use it and apply register infromation */
+ pClassDevice = &(pUsbCore->class_device[0]);
+ if (device_info->total_pipes != pClassDevice->total_pipes) {
+ // pipe number not match, return NULL
+ return NULL;
+ }
+
+ pClassDeviceInstance = &(pClassDevice->device_instance);
+ pClassDeviceInstance->id = 0;
+ pClassDeviceInstance->speed = pUsbCore->speed;
+ pClassDeviceInstance->total_interfaces = 0;
+ pClassDeviceInstance->context = device_info->class_device_context;
+ pClassDevice->state = USBC_CORE_CLASS_DEVICE_STATE_REGISTERED;
+ pClassDevice->notify_usb_state = device_info->notify_usb_state;
+ pClassDevice->notify_usb_speed = device_info->notify_usb_speed;
+ for ( i=0; i<pUsbCore->total_class_interfaces; i++ )
+ {
+ if ( (pUsbCore->class_interface[i].state == USBC_CORE_CLASS_INTERFACE_STATE_INITIATED) &&
+ (pUsbCore->class_interface[i].class_device_id == 0) )
+ {
+ /* fill Device Instance interface information */
+ pClassDeviceInstance->interface_type[pClassDeviceInstance->total_interfaces] = pUsbCore->class_interface[i].interface_type;
+ pClassDeviceInstance->interface_no[pClassDeviceInstance->total_interfaces] = pUsbCore->class_interface[i].interface_no;
+ pClassDeviceInstance->total_interfaces++;
+
+ /* fill USB Core interface information */
+ pUsbCore->class_interface[i].state = USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE;
+ pUsbCore->class_interface[i].notify_control_setup_packet = device_info->notify_control_setup_packet;
+ pUsbCore->class_interface[i].notify_control_complete = device_info->notify_control_complete;
+ pUsbCore->class_interface[i].notify_alternate_setting = device_info->notify_alternate_setting;
+ }
+ }
+
+ for ( i=0; i<device_info->total_pipes; i++ )
+ {
+ acquire_queue = usbc_except_acquire_pipe_queue(0, device_info->pipe_type[i]);
+ if ( acquire_queue == INVALID_PIPE_QUEUE_ID )
+ {
+ return NULL;
+ }
+
+ /* fill Device Instance Queue information */
+ pClassDeviceInstance->queue_no_for_pipe[i] = acquire_queue;
+
+ /* fill USB Core Queue information */
+ if ( (acquire_queue & PIPE_QUEUE_RX_MASK) != PIPE_QUEUE_RX_MASK )
+ {
+ pQueue = &(pUsbCore->tx_queue[acquire_queue]);
+ } else {
+ pQueue = &(pUsbCore->rx_queue[acquire_queue & ~PIPE_QUEUE_RX_MASK]);
+ }
+ pQueue->state = USBC_CORE_QUEUE_STATE_ACTIVE;
+ pQueue->notify_complete = device_info->notify_pipe_complete[i];
+ pQueue->notify_stall = device_info->notify_pipe_stall[i];
+ }
+
+ return pClassDeviceInstance;
+}
+
+
+usbc_class_device_instance_t *usbc_except_reset_ch(usbc_class_device_info_t *device_info)
+{
+ usbc_class_device_instance_t *dev_inst;
+ static hifusb_except_cb_t except_cb;
+
+ usbc_set_flag(USBC_EXCEPT_CALL_RESET_CH);
+ usbc_dlog_reset();
+
+ usbc_except_init_context();
+ usbc_except_read_configuration();
+
+ /*
+ * Register exception mode callback function to HIF driver and
+ * disconnect and then connect to USB to trigger USB re-enumeration.
+ */
+ except_cb.notify_usb_except_evt = usbc_core_notify_usb_event;
+ except_cb.notify_usb_except_control_in = usbc_except_notify_usb_except_control_in;
+ except_cb.notify_usb_except_control_out = usbc_except_notify_usb_except_control_out;
+ hifusb_except_change_ch(&except_cb);
+
+ /*
+ * Find the device instance for the USB CLASS in exception.
+ */
+ dev_inst = usbc_except_device_register(usbc_core_get_instance(), device_info);
+ usbc_excpet_log_trace(USBC_EXCEPT_CALL_RESET_CH, 2);
+ return dev_inst;
+}
+
+kal_bool usbc_except_enum_loop(void)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ usbc_set_flag(USBC_EXCEPT_CALL_ENUM_LOOP);
+ USBC_EXCEPTION_MODE_CHECK();
+
+ /*
+ * Wait untill SET_CONFIGURATION or timeout to make sure
+ * host side driver is ready.
+ */
+#if (defined(__MTK_TARGET__) && defined(__PRODUCTION_RELEASE__))
+ kal_uint32 begin_tick;
+ GET_CURR_TICK(begin_tick);
+#endif // #if (defined(__MTK_TARGET__) && defined(__PRODUCTION_RELEASE__))
+ do {
+ usbc_except_restart_watchdog(); // Restart watchdog timer to avoid silient reboot
+
+ hifusb_except_poll_isr();
+
+#if (defined(__MTK_TARGET__) && defined(__PRODUCTION_RELEASE__))
+ kal_uint32 curr_tick;
+ kal_uint64 ms_passed;
+ GET_CURR_TICK(curr_tick);
+ ms_passed = GET_DURATION_MS(begin_tick, curr_tick);
+
+ if (USBC_EXCEPT_INFINITE_TIMEOUT != usbc_except_get_doc()->enum_timeout &&
+ ms_passed > usbc_except_get_doc()->enum_timeout) {
+ usbc_set_flag(USBC_EXCEPT_ENUM_LOOP_TO);
+ usbc_excpet_log_trace(USBC_EXCEPT_CALL_ENUM_LOOP, 0);
+ return KAL_FALSE;
+ }
+#endif // #if (defined(__MTK_TARGET__) && defined(__PRODUCTION_RELEASE__))
+ } while (USBC_USB_STATE_ATTACHED != pUsbCore->state);
+ usbc_set_flag(USBC_EXCEPT_ENUM_LOOP_OK);
+
+ usbc_excpet_log_trace(USBC_EXCEPT_CALL_ENUM_LOOP, 1);
+ return KAL_TRUE;
+}
+
+kal_bool usbc_except_hif_poll(kal_uint8 class_device_id)
+{
+ usbc_set_flag(USBC_EXCEPT_CALL_HIF_POLL);
+ USBC_EXCEPTION_MODE_CHECK();
+
+ hifusb_except_poll_isr();
+// usbc_excpet_log_trace(USBC_EXCEPT_CALL_HIF_POLL, 1);
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_except_submit_gpd(
+ kal_uint8 class_device_id,
+ kal_uint8 queue_no,
+ void *p_first_gpd,
+ void *p_last_gpd)
+{
+ usbc_core_queue_t *queue;
+ hif_queue_type_e queue_type;
+
+ usbc_set_flag(USBC_EXCEPT_CALL_SUBMIT_GPD);
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &queue, &queue_type)) {
+ usbc_set_flag(USBC_EXCEPT_SUBMIT_GPD_NG);
+// usbc_excpet_log_trace(USBC_EXCEPT_CALL_SUBMIT_GPD, 0);
+ return KAL_FALSE;
+ }
+ usbc_dlog_submit_gpd(queue_type, p_last_gpd);
+
+// usbc_excpet_log_trace(USBC_EXCEPT_CALL_SUBMIT_GPD, 2);
+ return hifusbq_except_set_gpd(queue_type, HIFUSB_EPNO_2_QNO(queue->ep_no), p_first_gpd, p_last_gpd);
+}
+
+kal_bool
+usbc_except_poll_queue(
+ kal_uint8 class_device_id,
+ kal_uint8 queue_no,
+ void **pp_first_gpd,
+ void **pp_last_gpd,
+ kal_uint32 *gpd_num)
+{
+ usbc_core_queue_t *queue;
+ hif_queue_type_e queue_type;
+ hif_deq_info_t deq_info;
+
+ usbc_set_flag(USBC_EXCEPT_CALL_POLL_QUEUE);
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &queue, &queue_type)) {
+ usbc_set_flag(USBC_EXCEPT_POLL_QUEUE_NG);
+// usbc_excpet_log_trace(USBC_EXCEPT_CALL_POLL_QUEUE, 0);
+ return KAL_FALSE;
+ }
+
+ kal_mem_set(&deq_info, 0, sizeof(hif_deq_info_t));
+ deq_info.q_type = queue_type;
+ deq_info.que_no = HIFUSB_EPNO_2_QNO(queue->ep_no);
+ deq_info.deq_type = HIFQ_DEQ;
+
+ *gpd_num = hifusbq_except_poll_queue(deq_info, pp_first_gpd, pp_last_gpd);
+ usbc_dlog_poll_queue(queue_type, *gpd_num, *pp_last_gpd);
+
+// usbc_excpet_log_trace(USBC_EXCEPT_CALL_POLL_QUEUE, 1);
+ return KAL_TRUE;
+}
+
+
+kal_bool
+usbc_except_hif_state(
+ kal_uint8 class_device_id,
+ kal_uint8 queue_no,
+ usbc_except_link_st_e *link_state)
+{
+ usbc_core_queue_t *queue;
+ hif_queue_type_e queue_type;
+ kal_uint32 inactive_interval;
+
+ usbc_set_flag(USBC_EXCEPT_CALL_HIF_STATE);
+
+ if (!usbc_core_get_queue_info(class_device_id, queue_no, &queue, &queue_type)) {
+ usbc_set_flag(USBC_EXCEPT_HIF_STATE_NG);
+// usbc_excpet_log_trace(USBC_EXCEPT_CALL_HIF_STATE, 0);
+ return KAL_FALSE;
+ }
+
+ inactive_interval = hifusbq_except_get_txq_timeout(HIFUSB_EPNO_2_QNO(queue->ep_no));
+ if (inactive_interval > usbc_except_get_doc()->tx_timeout) {
+ usbc_set_flag(USBC_EXCEPT_HIF_STATE_TO);
+ *link_state = USBC_LINK_TX_TIMEOUT;
+ } else {
+ *link_state = USBC_LINK_NO_ERROR;
+ }
+// usbc_excpet_log_trace(USBC_EXCEPT_CALL_HIF_STATE, 1);
+ return KAL_TRUE;
+}
+
+kal_bool usbc_except_reset_flush(
+ kal_uint8 class_device_id, kal_uint8 queue_no, void** first_gpd, void** last_gpd, kal_uint32* gpd_num)
+{
+ usbc_core_queue_t* pQueue = NULL;
+ hif_queue_type_e core_queue_hif_type;
+ hif_flush_type_e core_queue_flush_type = HIFQ_FLUSH_DEQ;
+
+ usbc_set_flag(USBC_EXCEPT_CALL_FLUSH);
+ usbc_except_restart_watchdog(); // Restart watchdog timer to avoid silient reboot
+
+ if (usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type))
+ {
+ *gpd_num = hifusbq_except_flush_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no),
+ core_queue_flush_type, first_gpd, last_gpd);
+ }
+ else
+ {
+ usbc_set_flag(USBC_EXCEPT_FLUSH_NG);
+ usbc_excpet_log_trace(USBC_EXCEPT_CALL_FLUSH, 0xFF);
+ return KAL_FALSE;
+ }
+
+ usbc_excpet_log_trace(USBC_EXCEPT_CALL_FLUSH, (kal_uint8)*gpd_num);
+ return KAL_TRUE;
+}
+
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_hif.c b/mcu/middleware/hif/usbcore/src/usbcore_hif.c
new file mode 100644
index 0000000..d8753c7
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_hif.c
@@ -0,0 +1,2179 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * usbcore_hif.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * USB Core HIF interface and normal mode implementation.
+ * One can tell the type of HIF interface from function name prefix:
+ * (1) usbc_normal_hif_xxx(): implementation for normal mode HIF.
+ * (2) usbc_core_xxx(): shared between normal mode and exception mode HIF.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "hif_usb.h"
+#include "usbcore_main.h"
+#include "usbcore_ind_q.h"
+#include "usbcore_hif.h"
+#include "usbc_custom.h"
+#include "hifusb_qmu.h"
+#include "hif_ior.h"
+#include "qmu_bm_util.h"
+#include "qmu_bm.h"
+#include "hif_spd_ext.h"
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#include "usbidle_if.h"
+#include "usbcore_debug.h"
+#include "hif_swla.h"
+#include "usbcore_dual_owner.h"
+#include "usbc_custom.h"
+#include "dcl.h"
+#include "us_timer.h"
+#include "sleepdrv_interface.h"
+
+#ifdef __MULTI_BOOT__
+#include "multiboot_config.h"
+#endif /* __MULTI_BOOT__ */
+#ifdef __USB_OSD_SUPPORT__
+#include "usbosd.h"
+#endif /* __USB_OSD_SUPPORT__ */
+
+#ifdef ATEST_SYS_USBCORE
+#include "usbcore_ut.h"
+#endif
+
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+#include "usbcore_direct.h"
+#endif
+
+extern kal_uint32 dipc_mode, port_mode, pcie_status;
+/*
+ * Set up max capable speed by project makefile configuration, HIF_USB30_SUPPORT.
+ * See also usbcore.mak.
+ */
+#if __USBC_USB30_SUPPORT__
+ #define USBC_MAX_SPEED HIFUSB_USB_SPEED_USB30
+#else
+ #define USBC_MAX_SPEED HIFUSB_USB_SPEED_USB20
+#endif
+
+extern kal_uint16 INT_BootMode(void);
+
+#if __USBC_TARGET_HIF_DRIVER_SUPPORT__
+#define __USBCORE_TARGET_DEBUG__
+#endif
+
+/* switch to control OSD enable state */
+extern kal_bool osd_enable;
+
+usb_current_cfg_param_t usbc_current_param[USB_MAX_CLASS_NUM] = {0};
+
+/*trace for setup packet*/
+#define USBC_REQ_RECORD_MAX_NUM 20
+usbc_setup_packet_t usbc_request_record[USBC_REQ_RECORD_MAX_NUM] = {0};
+hifusb_control_request_type_e usbc_set_request_record[USBC_REQ_RECORD_MAX_NUM] = {0};
+kal_uint8 usbc_request_record_index = 0;
+kal_uint8 usbc_set_control_index = 0;
+/*exception setup packet trace*/
+usbc_setup_packet_t usbc_except_request_record[USBC_REQ_RECORD_MAX_NUM] = {0};
+kal_uint8 usbc_except_request_record_index = 0;
+
+kal_bool usbc_set_connect_flag = KAL_FALSE;
+
+/*record last polling tick time from HMU*/
+kal_uint32 usbc_last_polling_time = 0;
+
+/*
+ * HIF function pointers, actural mapping is defined in
+ * usbc_normal_hif_factory() and usbc_except_hif_factor() for
+ * normal mode and exception mode respectively.
+ */
+USBC_INDICATE_CONTROL_SETUP_PACKET usbc_core_indicate_control_setup_packet = NULL;
+USBC_INDICATE_CONTROL_COMPLETE usbc_core_indicate_control_complete = NULL;
+USBC_INDICATE_ALTERNATE_SETTING usbc_core_indicate_alternate_setting = NULL;
+USBC_INDICATE_STALL usbc_core_indicate_stall = NULL;
+USBC_SET_CONTROL_REQUEST usbc_core_set_control_request = NULL;
+USBC_SET_PROPERTY usbc_core_set_property = NULL;
+USBC_SET_USB_ADDRESS usbc_core_set_usb_address = NULL;
+USBC_SET_USB_CONFIGURATION usbc_core_set_usb_configuration = NULL;
+USBC_SET_STALL usbc_core_set_stall = NULL;
+USBC_CLEAR_STALL usbc_core_clear_stall = NULL;
+USBC_RST_EP usbc_core_rst_ep = NULL;
+USBC_SET_USB_TESTMODE usbc_core_set_usb_testmode = NULL;
+USBC_SET_SS_DEV_INIT_U1_EN usbc_core_set_ss_dev_init_u1_en = NULL;
+USBC_SET_SS_DEV_INIT_U2_EN usbc_core_set_ss_dev_init_u2_en = NULL;
+USBC_SET_USBHIF_ADDRESS usbc_core_set_usbhif_address = NULL;
+USBC_SET_UFBHIF_CONFIGURATION usbc_core_set_usbhif_configuration = NULL;
+USBC_SET_USBHIF_CONNECT usbc_core_set_usbhif_connect = NULL;
+USBC_SET_USBHIF_DISCONNECT usbc_core_set_usbhif_disconnect = NULL;
+USBC_SET_USBHIFQ_GPD usbc_core_set_usbhifq_gpd = NULL;
+USBC_POLL_USBHIFQ_GPD usbc_core_poll_hifusbq_gpd = NULL;
+USBC_CHECK_USBHIFQ_EMPTY usbc_core_check_hifusbq_empty = NULL;
+USBC_FLUSH_USBHIFQ_GPD usbc_core_flush_hifusbq_gpd = NULL;
+USBC_FLUSH_SW_USBHIFQ_GPD usbc_core_flush_sw_hifusbq_gpd = NULL;
+USBC_CHK_NEWPKT usbc_core_check_new_packet = NULL;
+USBC_START_DATAQ usbc_core_start_dataq = NULL;
+USBC_POWER_DOWN usbc_core_power_down = NULL;
+USBC_SET_CLOCK_CG usbc_core_set_clock_cg = NULL;
+USBC_MASK_WAKEUP_EVENT usbc_core_mask_wakeup_event = NULL;
+USBC_MASK_INTR usbc_core_mask_intr = NULL;
+
+USBC_DUAL_OWNER_OPERATION usbc_dual_owner_init = NULL;
+USBC_DUAL_OWNER_OPERATION usbc_dual_owner_ilm_handle = NULL;
+USBC_DUAL_OWNER_OPERATION usbc_dual_owner_class_ctrl_request = NULL;
+USBC_DUAL_OWNER_OPERATION usbc_dual_owner_class_ctrl_complete = NULL;
+USBC_DUAL_OWNER_OPERATION usbc_dual_owner_send_feature_request = NULL;
+USBC_DUAL_OWNER_NOTIFY_EVENT usbc_dual_owner_notify_event = NULL;
+
+/*------------------------------------------------------------------------------
+ * Private implementation for normal mode HIF.
+ *----------------------------------------------------------------------------*/
+static void usbc_normal_hif_notify_usb_event(hifusb_notify_evt_e event, void *data)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_usb_state_e state;
+ usbc_ind_t ind_to_enqueue = {0};
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ switch ( event )
+ {
+ case HIFUSB_NOTIFY_EVT_ATTACH:
+ {
+ state = USBC_USB_STATE_ATTACHING;
+ usbc_trace_info(USBCORE_HIF_EVENT_ATTACH);
+ break;
+ }
+ case HIFUSB_NOTIFY_EVT_DETACH:
+ {
+ state = USBC_USB_STATE_DETACHING;
+ usbc_trace_info(USBCORE_HIF_EVENT_DETACH);
+ break;
+ }
+ case HIFUSB_NOTIFY_EVT_SUSPEND:
+ {
+ state = USBC_USB_STATE_SUSPENDING;
+ if (pUsbCore->usb_low_power_enable)
+ {
+ usbc_core_mask_intr(KAL_TRUE);
+ SleepDrv_LockSleep(SLEEP_CTL_USBCORE,SMP);
+ }
+ usbc_normal_hif_set_pwr_flag(KAL_TRUE);
+ usbc_trace_info(USBCORE_HIF_EVENT_SUSPEND);
+ break;
+ }
+ case HIFUSB_NOTIFY_EVT_RESUME:
+ {
+ state = USBC_USB_STATE_RESUME;
+ usbc_trace_info(USBCORE_HIF_EVENT_RESUME);
+ break;
+ }
+ case HIFUSB_NOTIFY_EVT_RESET:
+ {
+ usbc_usb_speed_e speed = *(usbc_usb_speed_e*)data;
+ pUsbCore->setup_status = USBC_CORE_SETUP_SM_INITIALIZE;
+
+ usbc_trace_info(USBCORE_HIF_EVENT_RESET);
+ usbc_trace_info(USBCORE_DUALIPC_INFO, dipc_mode, port_mode, pcie_status);
+
+ // Clean USB indication queue
+ usbc_empty_ind_queue();
+ /*clean USB enum request record*/
+ usbc_core_clear_enum_record();
+
+ if ((speed != pUsbCore->speed) || (pUsbCore->is_mode_switch)) {
+ usbc_trace_info(USBCORE_HIF_EVENT_SPEED_CHANGE, pUsbCore->speed, speed);
+
+ /*
+ * Change USB link speed and related settings.
+ */
+ usbc_core_speed_change(pUsbCore, speed);
+
+ /*
+ * Enqueue USB speed change before USB reset event.
+ * Note that, we assume underlying HIF driver has already configured itself
+ * for new USB link speed.
+ */
+ ind_to_enqueue.type = USBC_IND_SPEED_CHANGE;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)speed;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ }
+ usbc_core_set_hif_configuration();
+
+ ind_to_enqueue.ext = (kal_uint8)speed;
+ state = USBC_USB_STATE_RESET;
+ break;
+ }
+ case HIFUSB_NOTIFY_EVT_WAKEUP:
+ usbc_trace_warn(USBCORE_SET_USB_WAKEUP_EVENT);
+ if (!pUsbCore->usb_low_power_enable)
+ return;
+ if(pUsbCore->usbc_wait_wakeup_event == KAL_TRUE)
+ {
+ SleepDrv_LockSleep(SLEEP_CTL_USBCORE,SMP);
+ pUsbCore->usbc_wait_wakeup_event = KAL_FALSE;
+
+ usbc_core_set_clock_cg(KAL_TRUE);
+ usbc_core_mask_intr(KAL_FALSE);
+ usbc_trace_warn(USBCORE_SET_CG_ON);
+ SleepDrv_UnlockSleep(SLEEP_CTL_USBCORE,SMP);
+ }
+ return;
+ default:
+ {
+ usbc_trace_error(USBCORE_HIF_EVENT_UNKNOWN);
+ EXT_ASSERT(0, USBCORE_LOC_DRV_NOTIFY_INVALID_EVENT, (kal_uint32)event, 0);
+ return;
+ }
+ }
+ pUsbCore->state_in_hisr = state;
+ /*
+ * Enqueue USB device state which will be handled in USB context later.
+ */
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ //ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ /*
+ * Wake up USBCORE task to process indications.
+ */
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+}
+
+static kal_bool usbc_normal_hif_indicate_control_setup_packet(kal_uint8 intf_idx, usbc_setup_packet_t *packet)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_ind_t ind_to_enqueue;
+
+ pUsbCore->setup_indicated = KAL_TRUE; /* Indicate to USBCLASS */
+
+ ind_to_enqueue.type = USBC_IND_CTRL_SETUP;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = intf_idx;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ /*
+ * Wake up USBCORE task to process indications.
+ */
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ return KAL_FALSE;
+}
+
+static void usbc_normal_hif_indicate_control_complete(kal_uint8 intf_idx)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_ind_t ind_to_enqueue;
+
+ ASSERT(pUsbCore->setup_indicated); /* Only setup packet indicated case shall enqueue a control complet indication. */
+
+ ind_to_enqueue.type = USBC_IND_CTRL_CMPLT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = intf_idx;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ /*
+ * Wake up USBCORE task to process indications.
+ */
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+}
+
+static void usbc_normal_hif_indicate_alternate_setting(kal_uint8 intf_idx, kal_uint8 alternate_setting)
+{
+ usbc_ind_t ind_to_enqueue;
+
+ ind_to_enqueue.type = USBC_IND_ALT_SETTING;
+ ind_to_enqueue.ext = intf_idx;
+ ind_to_enqueue.data = alternate_setting;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ /*
+ * Wake up USBCORE task to process indications.
+ */
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+}
+
+static void usbc_normal_hif_indicate_stall(kal_bool is_tx, kal_uint8 queue_idx, kal_bool stall)
+{
+ usbc_ind_t ind_to_enqueue;
+
+ ind_to_enqueue.type = USBC_IND_PIPE_STALL;
+ ind_to_enqueue.ext = ((KAL_TRUE == stall) ? 1 : 0);
+ ind_to_enqueue.data = ((KAL_TRUE == is_tx) ? 0x80 : 0x00) | (queue_idx & 0x7f);
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ /*
+ * Wake up USBCORE task to process indications.
+ */
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+}
+
+static kal_bool usbc_normal_hif_notify_control_setup_packet(hifusb_setup_packet_t *p_setup)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ USBC_CLASS_COMMON_SPIN_LOCK(pUsbCore->setup_packet_spinlock);
+ if(pUsbCore->setup_status != USBC_CORE_SETUP_SM_INITIALIZE)
+ {
+ usbc_trace_warn(USBCORE_RECEIVE_MULTI_SETUP_PACKET, pUsbCore->setup_status);
+ pUsbCore->setup_status = USBC_CORE_SETUP_SM_MULTI_SETUP;
+ USBC_CLASS_COMMON_SPIN_UNLOCK(pUsbCore->setup_packet_spinlock);
+ return KAL_FALSE;
+ }
+ pUsbCore->setup_status = USBC_CORE_SETUP_SM_RECEIVED;
+ USBC_CLASS_COMMON_SPIN_UNLOCK(pUsbCore->setup_packet_spinlock);
+
+ return usbc_core_dispatch_control_setup_packet(pUsbCore, p_setup);
+}
+
+static void usbc_normal_hif_notify_control_complete(void)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ usbc_core_notify_control_complete(pUsbCore);
+}
+
+static kal_bool usbc_normal_hif_set_usb_address(kal_uint8 address)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_bool result = KAL_TRUE;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ pUsbCore->usb_address = address;
+ usbc_core_set_usbhif_address(pUsbCore->usb_address);
+
+ return result;
+}
+
+void usbc_core_transfer_class_type_to_string(usb_class_type_e type, char *class_type)
+{
+ switch(type)
+ {
+#ifdef __USB_ACM_SUPPORT__
+ case USB_CLASS_ACM1:
+ sprintf(class_type, "CDC_ACM1");
+ break;
+ case USB_CLASS_ACM2:
+ sprintf(class_type, "CDC_ACM2");
+ break;
+ case USB_CLASS_ACM3:
+ sprintf(class_type, "CDC_ACM3");
+ break;
+#endif
+#ifdef __USB_RNDIS_SUPPORT__
+ case USB_CLASS_RNDIS:
+ sprintf(class_type, "RNDIS");
+ break;
+#endif
+#ifdef __USB_MBIM_SUPPORT__
+ case USB_CLASS_MBIM:
+ sprintf(class_type, "MBIM");
+ break;
+#endif
+#ifdef __USB_ECM_SUPPORT__
+ case USB_CLASS_ECM:
+ sprintf(class_type, "CDC_ECM");
+ break;
+#endif
+#ifdef __USB_ADB_SUPPORT__
+ case USB_CLASS_ADB:
+ sprintf(class_type, "ADB");
+ break;
+#endif
+//#ifdef __USB_MSD_SUPPORT__
+ case USB_CLASS_MS:
+ sprintf(class_type, "MS");
+ break;
+//#endif
+ default:
+ sprintf(class_type, "UNKNOWN");
+ break;
+ }
+ return;
+}
+
+static void usbc_core_trace_configuration_port_info()
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_idx, q_idx, txep_start, txep_num, rxep_start, rxep_num;
+ char class_type[16] = {0};
+ kal_uint32 tx_q = 0;
+ kal_uint32 rx_q = 0;
+ kal_uint32 uartport_num;
+ usb_cfg_param_t *cfg = &(pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_param[pUsbCore->usb_configuration-1]);
+
+ for(class_idx = 0; class_idx < cfg->class_num; class_idx++)
+ {
+ usbc_current_param[class_idx].class_type = cfg->class_type[class_idx];
+ usbc_current_param[class_idx].bulk_fifo_n = (kal_uint32)(cfg->bulk_fifo_n[class_idx]);
+ usbc_current_param[class_idx].uart_port = (kal_uint32)(cfg->class_ctxt[class_idx] -uart_port_usb + 1);
+ usbc_current_param[class_idx].class_owner = cfg->class_owner[class_idx];
+ }
+
+ for(class_idx = 0; class_idx < pUsbCore->total_class_devices; class_idx++)
+ {
+ kal_mem_set(class_type, 0, sizeof(class_type));
+ usbc_core_transfer_class_type_to_string(pUsbCore->class_device[class_idx].class_type, class_type);
+ uartport_num = ((kal_uint32)(cfg->class_ctxt[class_idx]) - (kal_uint32)uart_port_usb) + 1;
+
+ usbc_trace_info(USBCORE_DEBUG_CONFIGURATION_PORT_INFO, class_idx, class_type, pUsbCore->class_device[class_idx].owner, uartport_num);
+
+ txep_start = 0;
+ txep_num = 0;
+ for(q_idx = tx_q; q_idx < pUsbCore->total_tx_queues; q_idx++)
+ {
+ if(pUsbCore->tx_queue[q_idx].class_device_id == class_idx)
+ {
+ if(!txep_start)
+ txep_start = q_idx+1;
+ txep_num++;
+ }
+ else
+ {
+ tx_q = q_idx;
+ break;
+ }
+ }
+ rxep_start = 0;
+ rxep_num = 0;
+ for(q_idx = rx_q; q_idx < pUsbCore->total_rx_queues; q_idx++)
+ {
+ if(pUsbCore->rx_queue[q_idx].class_device_id == class_idx)
+ {
+ if(!rxep_start)
+ rxep_start = q_idx+1;
+ rxep_num++;
+ }
+ else
+ {
+ rx_q = q_idx;
+ break;
+ }
+ }
+
+ usbc_trace_info(USBCORE_DEBUG_CONFIGURATION_PORT_EP_INFO, class_idx, txep_start, txep_num,rxep_start, rxep_num);
+ }
+}
+
+static kal_bool usbc_normal_hif_set_usb_configuration(kal_uint8 configuration)
+{
+ #define CFG_TO_INDEX(config) (config-1)
+
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_bool result = KAL_TRUE;
+ kal_uint32 idx_class;
+ kal_uint32 idx_if;
+ kal_uint32 idx_ep;
+ usbc_class_set_config_func_t class_set_config_func;
+ usb_class_type_e type;
+ usb_class_owner_e owner;
+ usb_cfg_param_t cfg_param;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG, configuration);
+
+ /* Check if configuration is changed */
+ if (pUsbCore->usb_configuration == configuration) {
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_UNCHANGED);
+ }
+ pUsbCore->usb_configuration = configuration;
+
+ /* Reinit usb classes of old configuration */
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_REINIT_START);
+ usbc_reinit_class();
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_REINIT_END);
+
+ if (configuration == 0)
+ { /* Clear all class device / interface / tx_queue / rx_queue number */
+ pUsbCore->total_class_devices = 0;
+ pUsbCore->total_class_interfaces = 0;
+ pUsbCore->total_tx_queues = 0;
+ pUsbCore->total_rx_queues = 0;
+ } else
+ {
+ /* Fill class_device / interface / tx_queue / rx_queue */
+ pUsbCore->total_class_devices = pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_param[CFG_TO_INDEX(configuration)].class_num;
+ for (idx_class = 0; idx_class < pUsbCore->total_class_devices; idx_class ++)
+ {
+ type = pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_param[CFG_TO_INDEX(configuration)].class_type[idx_class];
+ owner = pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_param[CFG_TO_INDEX(configuration)].class_owner[idx_class];
+ pUsbCore->class_device[idx_class].state = USBC_CORE_CLASS_DEVICE_STATE_INITIATED;
+ pUsbCore->class_device[idx_class].class_type = type;
+ pUsbCore->class_device[idx_class].owner = owner;
+ pUsbCore->class_device[idx_class].total_pipes = 0;
+ }
+
+ pUsbCore->total_class_interfaces = pUsbCore->resource_interface_number[CFG_TO_INDEX(configuration)];
+ for (idx_if = 0; idx_if < pUsbCore->total_class_interfaces; idx_if ++)
+ {
+ kal_mem_cpy(&pUsbCore->class_interface[idx_if],
+ &pUsbCore->if_info[CFG_TO_INDEX(configuration)][idx_if].class_interface,
+ sizeof(usbc_core_class_interface_t));
+ pUsbCore->class_interface[idx_if].state = USBC_CORE_CLASS_INTERFACE_STATE_INITIATED;
+ }
+
+ pUsbCore->total_tx_queues = pUsbCore->resource_ep_tx_number[CFG_TO_INDEX(configuration)];
+ for (idx_ep = 0; idx_ep < pUsbCore->total_tx_queues; idx_ep ++)
+ {
+ kal_mem_cpy(&pUsbCore->tx_queue[idx_ep],
+ &pUsbCore->ep_tx_info[CFG_TO_INDEX(configuration)][idx_ep].queue_info,
+ sizeof(usbc_core_queue_t));
+ pUsbCore->tx_queue[idx_ep].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ pUsbCore->class_device[pUsbCore->tx_queue[idx_ep].class_device_id].total_pipes ++;
+ }
+
+ pUsbCore->total_rx_queues = pUsbCore->resource_ep_rx_number[CFG_TO_INDEX(configuration)];
+ for (idx_ep = 0; idx_ep < pUsbCore->total_rx_queues; idx_ep ++)
+ {
+ kal_mem_cpy(&pUsbCore->rx_queue[idx_ep],
+ &pUsbCore->ep_rx_info[CFG_TO_INDEX(configuration)][idx_ep].queue_info,
+ sizeof(usbc_core_queue_t));
+ pUsbCore->rx_queue[idx_ep].state = USBC_CORE_QUEUE_STATE_INITIATED;
+ pUsbCore->class_device[pUsbCore->rx_queue[idx_ep].class_device_id].total_pipes ++;
+ }
+
+
+ /* Call Set config callback function to all usb class modules */
+ for (idx_class = 0; idx_class < pUsbCore->total_class_devices; idx_class ++)
+ {
+ cfg_param = pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_param[CFG_TO_INDEX(configuration)];
+ type = cfg_param.class_type[idx_class];
+ class_set_config_func = usbc_get_class_set_config_func(type);
+ if (class_set_config_func) {
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_USBCLASS, type);
+ class_set_config_func(idx_class,
+ CFG_TO_INDEX(configuration),
+ cfg_param.class_ctxt[idx_class]);
+ } else {
+ EXT_ASSERT(0, USBCORE_LOC_DEVICE_SET_CONFIG_FUNC_NULL, (kal_uint32)usbcore_classid_to_module(idx_class), (kal_uint32)idx_class);
+ }
+ }
+ }
+
+ /* According to Ming's comment in 2013/4/24, we can still set old property to hif if usb_configuration is changed to 0 */
+ usbc_core_set_hif_configuration();
+
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_HIF, pUsbCore->usb_configuration);
+ usbc_core_set_usbhif_configuration(pUsbCore->usb_configuration);
+
+ if (pUsbCore->usb_configuration > 0) {
+ /* notify class driver that HOST enable this device */
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_CONF_STATE);
+ usbc_core_notify_state_attached();
+
+ usbc_core_trace_configuration_port_info();
+
+ if(usbc_dual_owner_notify_event != NULL)
+ usbc_dual_owner_notify_event(USBC_USB_STATE_ATTACHED, 0);
+ } else {
+ /* notify class driver that HOST disable this device */
+ usbc_trace_info(USBCORE_HIF_SET_CONFIG_ADDR_STATE);
+ usbc_core_notify_state_attaching(); /* According to usb spec, configuration 0 means device enter addressed state */
+ }
+
+ return result;
+}
+
+static void usbc_normal_hif_set_stall(kal_bool is_tx, kal_uint8 nEnd)
+{
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ hifusb_set_stall(is_tx, nEnd);
+}
+
+static void usbc_normal_hif_clear_stall(kal_bool is_tx, kal_uint8 nEnd)
+{
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ hifusb_clear_stall(is_tx, nEnd);
+}
+
+static void usbc_normal_hif_rst_ep(kal_bool is_tx, kal_uint8 nEnd)
+{
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ hifusb_rst_ep(is_tx, nEnd);
+}
+
+static kal_bool usbc_normal_hif_set_control_request(kal_uint8 *buffer, kal_uint32 length, usbc_control_request_type_e type)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ hifusb_control_request_type_e hif_type = HIFUSB_CONTROL_REQUEST_TYPE_SEND;
+ kal_bool ret = KAL_FALSE;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ /*record set control requests */
+ usbc_set_request_record[usbc_set_control_index] = type;
+ usbc_set_control_index = (usbc_set_control_index + 1) % USBC_REQ_RECORD_MAX_NUM;
+
+ switch ( type ) {
+ case USBC_CONTROL_REQUEST_TYPE_SEND:
+ hif_type = HIFUSB_CONTROL_REQUEST_TYPE_SEND;
+ break;
+ case USBC_CONTROL_REQUEST_TYPE_RECEIVE:
+ hif_type = HIFUSB_CONTROL_REQUEST_TYPE_RECEIVE;
+ break;
+ case USBC_CONTROL_REQUEST_TYPE_STALL:
+ hif_type = HIFUSB_CONTROL_REQUEST_TYPE_STALL;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ if(pUsbCore->setup_status == USBC_CORE_SETUP_SM_RECEIVED)
+ {
+ USBC_CLASS_COMMON_SPIN_LOCK(pUsbCore->setup_packet_spinlock);
+ pUsbCore->setup_status = USBC_CORE_SETUP_SM_INITIALIZE;
+ USBC_CLASS_COMMON_SPIN_UNLOCK(pUsbCore->setup_packet_spinlock);
+ if (pUsbCore->setup_indicated) {
+ hifusb_set_control_request_in_task(buffer, length, hif_type);
+ } else {
+ hifusb_set_control_request_in_hisr(buffer, length, hif_type);
+ }
+ ret = KAL_TRUE;
+ }
+ else if(pUsbCore->setup_status == USBC_CORE_SETUP_SM_MULTI_SETUP)
+ {
+ USBC_CLASS_COMMON_SPIN_LOCK(pUsbCore->setup_packet_spinlock);
+ pUsbCore->setup_status = USBC_CORE_SETUP_SM_INITIALIZE;
+ USBC_CLASS_COMMON_SPIN_UNLOCK(pUsbCore->setup_packet_spinlock);
+ usbc_trace_warn(USBCORE_MULTI_SETUP_PACKET_RETURN_STALL);
+ hifusb_set_control_request_in_task(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+ return ret;
+}
+
+static kal_bool usbc_normal_hif_chk_newpkt(kal_bool isTx, kal_uint8 q_no)
+{
+ kal_uint8 flag;
+
+ if (isTx) {
+ flag = (hifusbq_check_dl_newpkt() >> q_no) & 0x01;
+ }
+ else {
+ flag = (hifusbq_check_ul_newpkt() >> q_no) & 0x01;
+ }
+
+ return (flag == 0)? KAL_FALSE:KAL_TRUE;
+}
+
+static void usbc_normal_hif_start_dataq(kal_bool isTx, kal_uint8 q_no)
+{
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ if (isTx) {
+ hifusb_start_dlq(q_no);
+ } else {
+ hifusb_start_ulq(q_no);
+ }
+}
+
+void usbc_normal_hif_set_pwr_flag(kal_bool flag)
+{
+ usb_idle_set_clockGating(flag);
+}
+
+void usbc_core_clear_enum_record()
+{
+ usbc_request_record_index = 0;
+ usbc_set_control_index = 0;
+ kal_mem_set(usbc_request_record, 0, sizeof(usbc_setup_packet_t)*USBC_REQ_RECORD_MAX_NUM);
+ kal_mem_set(usbc_set_request_record, 0, sizeof(hifusb_control_request_type_e)*USBC_REQ_RECORD_MAX_NUM);
+}
+
+void usbc_core_trace_gpd_info(qbm_gpd* first_gpd, qbm_gpd* last_gpd, kal_uint8 q_no, kal_bool isTx, kal_bool flag)
+{
+ qbm_gpd* curr_gpd = NULL;
+ kal_uint32 data_length, bd_num;
+ void* curr_bd = NULL;
+
+ curr_gpd = first_gpd;
+ do {
+ data_length = 0;
+ bd_num = 0;
+
+ if ( curr_gpd == NULL ) break;
+
+ if (QBM_DES_GET_BDP(curr_gpd))
+ {
+ curr_bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ while(curr_bd)
+ {
+ data_length += QBM_DES_GET_DATALEN(curr_bd) + QBM_DES_GET_EXTLEN(curr_bd);
+ bd_num++;
+ if ( QBM_DES_GET_EOL(curr_bd) ) break;
+ curr_bd = QBM_DES_GET_NEXT(curr_bd);
+ }
+ }
+ else
+ data_length = QBM_DES_GET_EXTLEN(curr_gpd) + QBM_DES_GET_DATALEN(curr_gpd);
+
+ if(flag)
+ {
+ if(isTx)
+ {
+ usbc_trace_warn(USBCORE_CLASS_CHECK_SUBMIT_TX_GPD_KPI, q_no, (kal_uint32)curr_gpd, data_length, bd_num, QBM_DES_GET_BPS(curr_gpd));
+ }
+ else
+ {
+ usbc_trace_warn(USBCORE_CLASS_CHECK_SUBMIT_RX_GPD_KPI, q_no, (kal_uint32)curr_gpd, data_length, bd_num, QBM_DES_GET_BPS(curr_gpd));
+ }
+ }
+ else
+ {
+ if(isTx)
+ {
+ usbc_trace_warn(USBCORE_CLASS_CHECK_POLL_TX_GPD_KPI, q_no, (kal_uint32)curr_gpd, data_length, bd_num, QBM_DES_GET_BPS(curr_gpd));
+ }
+ else
+ {
+ usbc_trace_warn(USBCORE_CLASS_CHECK_POLL_RX_GPD_KPI, q_no, (kal_uint32)curr_gpd, data_length, bd_num, QBM_DES_GET_BPS(curr_gpd));
+ }
+ }
+ if ( curr_gpd == last_gpd ) break;
+ curr_gpd = QBM_DES_GET_NEXT(curr_gpd);
+
+ } while (1);
+}
+
+/*------------------------------------------------------------------------------
+ * USB Core HIF interface shared between normal mode and exception mode.
+ *----------------------------------------------------------------------------*/
+#ifdef __USBCORE_DEBUG__
+void usbc_core_dump_gpd_list(void* first_gpd, void* last_gpd)
+{
+ void* curr_gpd = NULL;
+
+ curr_gpd = first_gpd;
+ do {
+ void* curr_bd = NULL;
+
+ if ( curr_gpd == NULL ) break;
+
+ usbc_core_printf("[USBCORE] gpd[%x].CHKSUM : %x \r\n", curr_gpd, QBM_DES_GET_CHKSUM(curr_gpd));
+ usbc_core_printf("[USBCORE] gpd[%x].IOC : %d \r\n", curr_gpd, QBM_DES_GET_IOC(curr_gpd)?1:0);
+ usbc_core_printf("[USBCORE] gpd[%x].BDP : %d \r\n", curr_gpd, QBM_DES_GET_BDP(curr_gpd)?1:0);
+ usbc_core_printf("[USBCORE] gpd[%x].HWO : %d \r\n", curr_gpd, QBM_DES_GET_HWO(curr_gpd)?1:0);
+ usbc_core_printf("[USBCORE] gpd[%x].BPS : %d \r\n", curr_gpd, QBM_DES_GET_BPS(curr_gpd)?1:0);
+ usbc_core_printf("[USBCORE] gpd[%x].NEXT : %x \r\n", curr_gpd, QBM_DES_GET_NEXT(curr_gpd));
+ usbc_core_printf("[USBCORE] gpd[%x].DATAPTR : %x \r\n", curr_gpd, QBM_DES_GET_DATAPTR(curr_gpd));
+ usbc_core_printf("[USBCORE] gpd[%x].DATALEN : %d \r\n", curr_gpd, QBM_DES_GET_DATALEN(curr_gpd));
+ usbc_core_printf("[USBCORE] gpd[%x].ALLOWLEN : %d \r\n", curr_gpd, QBM_DES_GET_ALLOW_LEN(curr_gpd));
+ usbc_core_printf("[USBCORE] gpd[%x].EXTLEN : %d \r\n", curr_gpd, QBM_DES_GET_EXTLEN(curr_gpd));
+ curr_bd = QBM_DES_GET_DATAPTR(curr_gpd);
+ do {
+ if ( !QBM_DES_GET_BDP(curr_gpd) )
+ {
+ break;
+ }
+
+ usbc_core_printf("[USBCORE] bd[%x].CHKSUM : %x \r\n", curr_bd, QBM_DES_GET_CHKSUM(curr_bd));
+ usbc_core_printf("[USBCORE] bd[%x].EOL : %d \r\n", curr_bd, QBM_DES_GET_EOL(curr_bd));
+ usbc_core_printf("[USBCORE] bd[%x].NEXT : %x \r\n", curr_bd, QBM_DES_GET_NEXT(curr_bd));
+ usbc_core_printf("[USBCORE] bd[%x].DATAPTR : %x \r\n", curr_bd, QBM_DES_GET_DATAPTR(curr_bd));
+ usbc_core_printf("[USBCORE] bd[%x].DATALEN : %d \r\n", curr_bd, QBM_DES_GET_DATALEN(curr_bd));
+ usbc_core_printf("[USBCORE] bd[%x].ALLOWLEN : %d \r\n", curr_bd, QBM_DES_GET_ALLOW_LEN(curr_bd));
+ usbc_core_printf("[USBCORE] bd[%x].EXTLEN : %d \r\n", curr_bd, QBM_DES_GET_EXTLEN(curr_bd));
+
+ if ( QBM_DES_GET_EOL(curr_bd) ) break;
+
+ curr_bd = QBM_DES_GET_NEXT(curr_bd);
+
+ } while (curr_bd != NULL);
+
+ if ( curr_gpd == last_gpd ) break;
+
+ curr_gpd = QBM_DES_GET_NEXT(curr_gpd);
+
+ } while (1);
+}
+#endif
+
+static void usbc_core_getGpdLength(void* first_gpd, void* last_gpd, kal_uint32* gpd_len, kal_uint32* bd_len, kal_uint32* spd_len)
+{
+ void* curr_gpd = first_gpd;
+ void* curr_bd = NULL;
+ qbm_spd_ext* p_spdext;
+ kal_uint16 ph_len, packet_num;
+ hif_spd_packet_header* p_spdph;
+
+ *gpd_len = *bd_len = *spd_len = 0;
+
+ while(curr_gpd)
+ {
+ // Onlu process non-bypass GPDs
+ if(0 == QBM_DES_GET_BPS(curr_gpd))
+ {
+ // Accumulate EXTLEN, BD/SPD data length, and packet header length
+ switch(QBM_DES_GET_PDT(curr_gpd))
+ {
+ case DES_FLAG_BIT_GPD:
+ // Accumulate length of GPDs
+ *gpd_len += QBM_DES_GET_DATALEN(curr_gpd) + QBM_DES_GET_EXTLEN(curr_gpd);
+
+ // Accumulate extnesion length of BDs
+ if (QBM_DES_GET_BDP(curr_gpd))
+ {
+ curr_bd = QBM_DES_GET_DATAPTR(curr_gpd);
+
+ while(curr_bd)
+ {
+ *bd_len += QBM_DES_GET_DATALEN(curr_bd) + QBM_DES_GET_EXTLEN(curr_bd);
+
+ if ( QBM_DES_GET_EOL(curr_bd) ) break;
+ curr_bd = QBM_DES_GET_NEXT(curr_bd);
+ }
+ }
+ break;
+
+ case DES_FLAG_BIT_SPD1:
+ p_spdext = (qbm_spd_ext*)QBM_SPD_GET_EXT((qbm_spd*)curr_gpd);
+ packet_num = HIF_SPD_EXT_GET_PKTNUM((hif_spd_ext_header*)p_spdext);
+ ph_len = HIF_SPD_EXT_GET_SPD1_HEADERLEN((hif_spd_ext_header*)p_spdext);
+
+ // Accumulate SPD data and header size
+ *spd_len += QBM_DES_GET_DATALEN(curr_gpd) + ph_len * packet_num;
+ break;
+
+ case DES_FLAG_BIT_SPD2:
+ // Accumulate SPD data size
+ *spd_len += QBM_DES_GET_DATALEN(curr_gpd);
+
+ // Accumulate header size of each available packet
+ p_spdext = (qbm_spd_ext*)QBM_SPD_GET_EXT((qbm_spd*)curr_gpd);
+ p_spdph = HIF_SPD_EXT_GET_FIRST_PH(p_spdext);
+ ph_len = 0;
+ while(p_spdph)
+ {
+ if( 0 == HIF_SPD_PH_GET_IGR(p_spdph) )
+ {
+ ph_len = HIF_SPD_PH_GET_SPD2_HEADERLEN(p_spdph);
+ *spd_len += ph_len;
+ }
+
+ if( 0 != HIF_SPD_PH_GET_EOL(p_spdph) )
+ break;
+
+ p_spdph = HIF_SPD_PH_NEXT(p_spdph, ph_len);
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+
+ if(curr_gpd == last_gpd) break;
+ curr_gpd = QBM_DES_GET_NEXT(curr_gpd);
+ }
+
+ return;
+}
+
+kal_bool usbc_core_set_hif_configuration(void)
+{
+ static hifusb_property_t property;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_bool result = KAL_FALSE;
+ kal_uint8 i = 0;
+
+ kal_mem_set(&property, 0, sizeof(hifusb_property_t));
+ property.speed = USBC_MAX_SPEED; /* set desired speed as max capable speed */
+ property.qmu_config = 0;
+ property.txq_num = pUsbCore->total_tx_queues;
+ property.rxq_num = pUsbCore->total_rx_queues;
+ for ( i=0; i<property.txq_num; i++) {
+ property.tx_que[i].ep_no = pUsbCore->tx_queue[i].ep_no;
+ property.tx_que[i].que_no = HIFUSB_EPNO_2_QNO(pUsbCore->tx_queue[i].ep_no);
+ property.tx_que[i].type = pUsbCore->tx_queue[i].xfer_type;
+ property.tx_que[i].max_packet_size = pUsbCore->tx_queue[i].max_packet_size;
+ property.tx_que[i].u2_fifo_u3_burst = pUsbCore->tx_queue[i].fifo_n;
+ /* set config to 0 when queue is AP side, USBdriver will not enable this queue */
+ if(pUsbCore->tx_queue[i].owner != USB_CLASS_OWNER_MD){
+ property.tx_que[i].config = 0;
+ }
+ else{
+ property.tx_que[i].config = pUsbCore->tx_queue[i].config;
+ }
+ }
+ for ( i=0; i<property.rxq_num; i++) {
+ property.rx_que[i].ep_no = pUsbCore->rx_queue[i].ep_no;
+ property.rx_que[i].que_no = HIFUSB_EPNO_2_QNO(pUsbCore->rx_queue[i].ep_no);
+ property.rx_que[i].type = pUsbCore->rx_queue[i].xfer_type;
+ property.rx_que[i].max_packet_size = pUsbCore->rx_queue[i].max_packet_size;
+ property.rx_que[i].u2_fifo_u3_burst = pUsbCore->rx_queue[i].fifo_n;
+ /* set config to 0 when queue is AP side, USBdriver will not enable this queue */
+ if(pUsbCore->rx_queue[i].owner != USB_CLASS_OWNER_MD){
+ property.rx_que[i].config = 0;
+ }
+ else{
+ property.rx_que[i].config = pUsbCore->rx_queue[i].config;
+ }
+ }
+
+ property.notify_usb_evt = usbc_normal_hif_notify_usb_event;
+ property.notify_control_setup_packet = usbc_normal_hif_notify_control_setup_packet;
+ property.notify_control_complete = usbc_normal_hif_notify_control_complete;
+ property.notify_clock_gate_flag = usbc_normal_hif_set_pwr_flag;
+
+ result = usbc_core_set_property(&property);
+ ASSERT(result);
+
+ return result;
+}
+
+void usbc_core_trace_setup_packet(usbc_setup_packet_t *packet)
+{
+ if (USBC_IS_IN_EXCEPTION_MODE())
+ {
+ kal_mem_cpy(&(usbc_except_request_record[usbc_except_request_record_index]), packet, sizeof(usbc_setup_packet_t));
+ usbc_except_request_record_index = (usbc_except_request_record_index + 1) % USBC_REQ_RECORD_MAX_NUM;
+ }
+ else
+ {
+ kal_mem_cpy(&(usbc_request_record[usbc_request_record_index]), packet, sizeof(usbc_setup_packet_t));
+ usbc_request_record_index = (usbc_request_record_index + 1) % USBC_REQ_RECORD_MAX_NUM;
+ }
+}
+
+kal_bool usbc_core_dispatch_control_setup_packet(usbc_core_t *pUsbCore, hifusb_setup_packet_t *p_setup)
+{
+ kal_bool handled = KAL_TRUE;
+
+ pUsbCore->setup_packet.bmRequestType = p_setup->bmRequestType;
+ pUsbCore->setup_packet.bRequest = p_setup->bRequest;
+ pUsbCore->setup_packet.wValue = USBC_EF16P((kal_uint8*)&p_setup->wValue);
+ pUsbCore->setup_packet.wIndex = USBC_EF16P((kal_uint8*)&p_setup->wIndex);
+ pUsbCore->setup_packet.wLength = USBC_EF16P((kal_uint8*)&p_setup->wLength);
+
+ pUsbCore->setup_indicated = KAL_FALSE; /* Default is handled in USBCORE. */
+
+ usbc_trace_info(USBCORE_DISPATCH_REQUEST, pUsbCore->setup_packet.bmRequestType);
+
+ usbc_core_trace_setup_packet(&pUsbCore->setup_packet);
+
+ /* host detection filter before USB request handling */
+#ifdef __USB_OSD_SUPPORT__
+ if (osd_enable)
+ {
+ if (osd_setup())
+ {
+ return handled;
+ }
+ }
+#endif
+
+ if ((pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_TYPE_MASK) == USBC_REQUEST_TYPE_STANDARD) {
+ //usbc_core_printf("=========>usbcore_handle_standard_request\r\n");
+ handled = usbc_core_handle_standard_request();
+
+#ifdef __USB_OSD_SUPPORT__
+ /* Do OSD retry after set configuration finished */
+ osd_retry_require_check();
+#endif
+ } else if ((pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_TYPE_MASK) == USBC_REQUEST_TYPE_CLASS) {
+ if ((pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK) == USBC_REQUEST_RECIP_INTERFACE) {
+ kal_uint8 bInterface = pUsbCore->setup_packet.wIndex & 0xff;
+ kal_uint8 i;
+
+ usbc_core_printf("=========>usbcore_handle_class_request\r\n");
+
+ /* notify class driver by interface if exist */
+ for ( i=0; i<pUsbCore->total_class_interfaces; i++) {
+ if ( (pUsbCore->class_interface[i].interface_no == bInterface) &&
+ (pUsbCore->class_interface[i].state == USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE) &&
+ (pUsbCore->class_interface[i].notify_control_setup_packet != NULL)) {
+ break;
+ }
+ }
+
+ if ( i == pUsbCore->total_class_interfaces ) {
+ /* incorrect reqeuset */
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ } else {
+ handled = usbc_core_indicate_control_setup_packet(i, &pUsbCore->setup_packet);
+ }
+ } else {
+ /* incorrect reqeuset */
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+ } else if ((p_setup->bmRequestType & USBC_REQUEST_TYPE_MASK) == USBC_REQUEST_TYPE_VENDOR) {
+ usbc_core_printf("=========>usbcore_handle_vendor_request\r\n");
+ usbc_core_handle_vendor_request();
+ } else {
+ /* unknown reqeuset */
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+
+ return handled;
+}
+
+void usbc_core_notify_control_complete(usbc_core_t *pUsbCore)
+{
+ if (((pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_TYPE_MASK) == USBC_REQUEST_TYPE_CLASS) ||
+ ((pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_TYPE_MASK) == USBC_REQUEST_TYPE_VENDOR)) {
+ if ((pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK) == USBC_REQUEST_RECIP_INTERFACE) {
+ kal_uint8 bInterface = pUsbCore->setup_packet.wIndex & 0xff;
+ kal_uint8 i;
+
+ /* notify class driver by interface if exist */
+ for ( i=0; i<pUsbCore->total_class_interfaces; i++) {
+ if ( (pUsbCore->class_interface[i].interface_no == bInterface) &&
+ (pUsbCore->class_interface[i].state == USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE) &&
+ (pUsbCore->class_interface[i].notify_control_complete != NULL) ) {
+ break;
+ }
+ }
+
+ if ( i < pUsbCore->total_class_interfaces ) {
+ usbc_core_indicate_control_complete(i);
+ }
+ }
+ }
+}
+
+void usbc_core_speed_change(usbc_core_t *pUsbCore, usbc_usb_speed_e speed)
+{
+ pUsbCore->speed = speed;
+
+ usbc_core_descriptors_speed_change(pUsbCore, speed);
+}
+
+/*------------------------------------------------------------------------------
+ * USB Core internal implementation for HIF normal mode.
+ *----------------------------------------------------------------------------*/
+kal_bool usbc_normal_hif_init(void)
+{
+ kal_bool result = KAL_FALSE;
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ result = hifusb_init(USBC_MAX_SPEED);
+ ASSERT(result);
+ return result;
+}
+
+kal_bool usbc_normal_hif_shutdown(void)
+{
+ kal_bool result = KAL_FALSE;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ hifusb_shutdown();
+
+ return result;
+}
+
+kal_bool usbc_normal_hif_connect(void)
+{
+ kal_bool result = KAL_FALSE;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ usbc_set_connect_flag = KAL_TRUE;
+ result = usbc_core_set_usbhif_connect();
+
+ return result;
+}
+
+kal_bool usbc_normal_hif_disconnect(void)
+{
+ kal_bool result = KAL_FALSE;
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+ usbc_set_connect_flag = KAL_FALSE;
+ result = usbc_core_set_usbhif_disconnect();
+
+ return result;
+}
+
+kal_bool usbc_normal_hif_remote_wakeup(void)
+{
+ kal_bool result = KAL_FALSE;
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+#if __USBC_TARGET_HIF_DRIVER_SUPPORT__ || ATEST_SYS_USBCORE
+ result = hifusb_remote_wakeup();
+ ASSERT(result);
+#endif
+
+ return result;
+}
+
+kal_bool usbc_normal_hif_ss_wk_notify(kal_uint8 nInterface)
+{
+ kal_bool result = KAL_FALSE;
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+#if __USBC_TARGET_HIF_DRIVER_SUPPORT__ || ATEST_SYS_USBCORE
+ usbc_trace_info(USBCORE_REMOTE_WK_HIF_NOTIFY, nInterface);
+ result = hifusb_ss_func_wk_notify(nInterface);
+ ASSERT(result);
+#endif
+
+ return result;
+}
+
+void usbc_normal_hif_sc_stall(kal_uint8 queue_no, kal_bool stall, usb_class_owner_e* owner)
+{
+ kal_bool is_tx = (queue_no & 0x80)? KAL_TRUE : KAL_FALSE;
+ kal_uint8 queue_idx = queue_no & 0x7f;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_core_queue_t *pQueue;
+
+ if (is_tx) {
+ pQueue = &pUsbCore->tx_queue[queue_idx];
+ } else {
+ pQueue = &pUsbCore->rx_queue[queue_idx];
+ }
+
+ *owner = pQueue->owner;
+ if(pQueue->owner == USB_CLASS_OWNER_MD){
+ if(stall)
+ usbc_core_set_stall(is_tx, pQueue->ep_no);
+ else
+ usbc_core_clear_stall(is_tx, pQueue->ep_no);
+ }
+
+ pQueue->state = (stall == KAL_TRUE)? USBC_CORE_QUEUE_STATE_STALL:USBC_CORE_QUEUE_STATE_ACTIVE;
+}
+
+void usbc_normal_hif_poll_queue_tx_gpd(kal_uint8 q_no)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ qbm_gpd *first_gpd = NULL;
+ qbm_gpd *last_gpd = NULL;
+ kal_uint32 num = 0;
+ hif_deq_info_t deq_info;
+ usbc_io_request_t *request;
+
+ // check Tx bitmap of the endpoint
+ if ( !usbc_core_check_new_packet(KAL_TRUE, HIFUSB_EPNO_2_QNO(pUsbCore->tx_queue[q_no].ep_no)) ) {
+ return;
+ }
+
+ kal_mem_set(&deq_info, 0, sizeof(hif_deq_info_t));
+ deq_info.q_type = HIFQ_TYPE_TX;
+ deq_info.que_no = HIFUSB_EPNO_2_QNO(pUsbCore->tx_queue[q_no].ep_no);
+ if ( pUsbCore->tx_queue[q_no].notify_complete == NULL ) {
+ deq_info.deq_type = HIFQ_FREEQ;
+ } else {
+ deq_info.deq_type = HIFQ_DEQ;
+ }
+
+ num = usbc_core_poll_hifusbq_gpd(deq_info, (void**)&first_gpd, (void**)&last_gpd);
+
+ if( num > 0 ) {
+#ifdef __USBCORE_DEBUG__
+ usbc_core_printf("[USBCORE] poll tx[%d] return %d first gpd %x last gpd %x\r\n", q_no, num, first_gpd, last_gpd);
+ //usbc_core_dump_gpd_list(first_gpd, last_gpd);
+#endif
+ if( num > 1 ) {
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_TX, q_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ } else {
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_TX_ONE, q_no, (kal_uint32)first_gpd);
+ }
+#ifdef __USBCORE_TARGET_DEBUG__
+ kal_uint32 gpd_len, bd_len, spd_len;
+ usbc_core_getGpdLength(first_gpd, last_gpd, &gpd_len, &bd_len, &spd_len);
+ usbc_core_trace_gpd_info(first_gpd, last_gpd, q_no, KAL_TRUE, 0);
+#endif
+ if( pUsbCore->tx_queue[q_no].notify_complete != NULL ) {
+ if ( first_gpd == NULL ) {
+ /* just indicate a notification */
+ pUsbCore->tx_queue[q_no].notify_complete(pUsbCore->tx_queue[q_no].class_device_id, NULL);
+ } else {
+ if(!pUsbCore->is_func_be_accessed[pUsbCore->tx_queue[q_no].class_device_id]) {
+ USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_func_access_mutex);
+ pUsbCore->is_func_be_accessed[pUsbCore->tx_queue[q_no].class_device_id] = KAL_TRUE;
+ USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_func_access_mutex);
+ }
+
+ request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd);
+ request->next_request = NULL;
+ request->first_gpd = first_gpd;
+ request->last_gpd = last_gpd;
+ pUsbCore->tx_queue[q_no].notify_complete(pUsbCore->tx_queue[q_no].class_device_id, request);
+ }
+ }
+
+#ifdef __USBCORE_TARGET_DEBUG__
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_LEN_TX, q_no, gpd_len, bd_len, spd_len);
+#endif
+ pUsbCore->usbc_q_polled_duration += USBC_POLLED_CHECK_DURATION * USBC_POLLED_CHECK_SHOW_ONLY_NO_DATA;
+ }
+}
+
+
+void usbc_normal_hif_poll_queue_rx_gpd(kal_uint8 q_no)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ qbm_gpd *first_gpd = NULL;
+ qbm_gpd *last_gpd = NULL;
+ kal_uint32 num = 0;
+ hif_deq_info_t deq_info;
+ usbc_io_request_t *request;
+
+ // check Rx bitmap of the endpoint
+ if ( !usbc_core_check_new_packet(KAL_FALSE, HIFUSB_EPNO_2_QNO(pUsbCore->rx_queue[q_no].ep_no)) ) {
+ return;
+ }
+
+ kal_mem_set(&deq_info, 0, sizeof( deq_info));
+ deq_info.q_type = HIFQ_TYPE_RX;
+ deq_info.que_no = HIFUSB_EPNO_2_QNO(pUsbCore->rx_queue[q_no].ep_no);
+ deq_info.deq_type = HIFQ_DEQ;
+
+ num = usbc_core_poll_hifusbq_gpd(deq_info, (void**)&first_gpd, (void**)&last_gpd);
+
+ if(num > 0) {
+#ifdef __USBCORE_DEBUG__
+ usbc_core_printf("[USBCORE] poll rx[%d] return %d first gpd %x last gpd %x\r\n", q_no, num, first_gpd, last_gpd);
+ //usbc_core_dump_gpd_list(first_gpd, last_gpd);
+#endif
+ if(num > 1 ) {
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_RX, q_no, num, (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ } else {
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_RX_ONE, q_no, (kal_uint32)first_gpd);
+ }
+#ifdef __USBCORE_TARGET_DEBUG__
+ kal_uint32 gpd_len, bd_len, spd_len;
+ usbc_core_getGpdLength(first_gpd, last_gpd, &gpd_len, &bd_len, &spd_len);
+ usbc_core_trace_gpd_info(first_gpd, last_gpd, q_no, KAL_FALSE, 0);
+#endif
+
+ if ( pUsbCore->rx_queue[q_no].notify_complete != NULL ) {
+ if ( first_gpd == NULL ) {
+ /* has return number, but no return GPD */
+ EXT_ASSERT(0, USBCORE_LOC_POLLED_RX_NULL_GPD, (kal_uint32)num, (kal_uint32)q_no);
+ } else {
+ if(!pUsbCore->is_func_be_accessed[pUsbCore->rx_queue[q_no].class_device_id]) {
+ USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_func_access_mutex);
+ pUsbCore->is_func_be_accessed[pUsbCore->rx_queue[q_no].class_device_id] = KAL_TRUE;
+ USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_func_access_mutex);
+ }
+
+ request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd);
+ request->next_request = NULL;
+ request->first_gpd = first_gpd;
+ request->last_gpd = last_gpd;
+ pUsbCore->rx_queue[q_no].notify_complete(pUsbCore->rx_queue[q_no].class_device_id, request);
+ }
+ } else {
+ EXT_ASSERT(0, USBCORE_LOC_DEVICE_RX_COMPLETE_FUNC_NULL, (kal_uint32)usbcore_classid_to_module(pUsbCore->rx_queue[q_no].class_device_id), (kal_uint32)q_no);
+ }
+
+#ifdef __USBCORE_TARGET_DEBUG__
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_LEN_RX, q_no, gpd_len, bd_len, spd_len);
+#endif
+ pUsbCore->usbc_q_polled_duration += USBC_POLLED_CHECK_DURATION * USBC_POLLED_CHECK_SHOW_ONLY_NO_DATA;
+ }
+}
+
+void usbc_normal_hif_poll_queue_drb(kal_uint8 q_no)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint32 num = 0;
+ kal_uint32 startIdx, endIdx;
+
+ // check Rx bitmap of the endpoint
+ if ( !usbc_core_check_new_packet(KAL_TRUE, HIFUSB_EPNO_2_QNO(pUsbCore->tx_queue[q_no].ep_no)) ) {
+ return;
+ }
+
+ num = ubm_drb_poll(HIFUSB_EPNO_2_QNO(pUsbCore->tx_queue[q_no].ep_no), &startIdx, &endIdx);
+
+ if(num > 0) {
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_DRB, q_no, num, startIdx, endIdx);
+
+ if( pUsbCore->tx_queue[q_no].notify_rb_complete != NULL ) {
+ if(!pUsbCore->is_func_be_accessed[pUsbCore->tx_queue[q_no].class_device_id]) {
+ USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_func_access_mutex);
+ pUsbCore->is_func_be_accessed[pUsbCore->tx_queue[q_no].class_device_id] = KAL_TRUE;
+ USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_func_access_mutex);
+ }
+
+ pUsbCore->tx_queue[q_no].notify_rb_complete(pUsbCore->tx_queue[q_no].class_device_id, startIdx, endIdx, 0);
+ }
+
+ ubm_drb_repay(HIFUSB_EPNO_2_QNO(pUsbCore->tx_queue[q_no].ep_no)); // check, copy stock DRB to common DRB, and re-submit
+ pUsbCore->usbc_q_polled_duration += USBC_POLLED_CHECK_DURATION * USBC_POLLED_CHECK_SHOW_ONLY_NO_DATA;
+ }
+}
+
+void usbc_normal_hif_poll_queue_xit(kal_uint8 q_no)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint32 num = 0;
+ kal_uint16 startIdx = 0, endIdx = 0, relIdx = 0;
+
+ // check Rx bitmap of the endpoint
+ if ( usbc_core_check_new_packet(KAL_FALSE, HIFUSB_EPNO_2_QNO(pUsbCore->rx_queue[q_no].ep_no)) ) {
+ /*
+ * Poll XIT
+ */
+ num = ubm_xit_poll(HIFUSB_EPNO_2_QNO(pUsbCore->rx_queue[q_no].ep_no), &startIdx, &endIdx, &relIdx);
+ }
+
+ /*
+ * Enqueue to LHIF UL queue
+ */
+ if (num > 0) {
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_XIT, q_no, num, startIdx, endIdx);
+ pUsbCore->usbc_q_polled_duration += USBC_POLLED_CHECK_DURATION * USBC_POLLED_CHECK_SHOW_ONLY_NO_DATA;
+ }
+
+ if (pUsbCore->rx_queue[q_no].notify_rb_complete) {
+ pUsbCore->rx_queue[q_no].notify_rb_complete(pUsbCore->rx_queue[q_no].class_device_id, startIdx, endIdx, relIdx);
+ } else {
+ EXT_ASSERT(0, USBCORE_LOC_DEVICE_RX_COMPLETE_FUNC_NULL, (kal_uint32)usbcore_classid_to_module(pUsbCore->rx_queue[q_no].class_device_id), (kal_uint32)q_no);
+ }
+}
+
+void usbc_normal_hif_poll_queue()
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_int8 i = 0;
+ kal_uint32 current_time;
+
+ current_time = ust_get_current_time();
+ if((usbc_last_polling_time != 0) && (current_time - usbc_last_polling_time > USBC_POLLED_CHECK_DURATION_TIME_MAX))
+ {
+ usbc_trace_warn(USBCORE_POLL_TICK_TIMEOUT, (current_time - usbc_last_polling_time));
+ }
+ usbc_last_polling_time = current_time;
+
+ /*
+ * USB Rx queue
+ */
+ HIF_SWLA_START("UUP");
+ for ( i=0; i<pUsbCore->total_rx_queues; i++ ) {
+ if ( pUsbCore->rx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED ) {
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+ if(pUsbCore->rx_queue[i].xfer_type != HIFUSB_EP_XFER_TYPE_BULK) {
+ continue;
+ }
+#endif
+ if(pUsbCore->rx_queue[i].owner != USB_CLASS_OWNER_MD){
+ continue;
+ }
+
+ if(pUsbCore->rx_queue[i].config & HIFUSB_QMU_RXQ_UL_PRB_XIT_EN) {
+ usbc_normal_hif_poll_queue_xit(i); // Poll Rx XIT
+ } else {
+ usbc_normal_hif_poll_queue_rx_gpd(i); // Poll Rx GPD
+ }
+
+ pUsbCore->usbc_rxq_polled_mask |= 0x1 << i;
+ }
+ }
+ HIF_SWLA_STOP("UUP");
+
+ /*
+ * USB Tx queue
+ */
+ HIF_SWLA_START("UDP");
+ for ( i=0; i<pUsbCore->total_tx_queues; i++ ) {
+ if ( pUsbCore->tx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED ) {
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+ if(pUsbCore->tx_queue[i].xfer_type != HIFUSB_EP_XFER_TYPE_BULK) {
+ continue;
+ }
+#endif
+ if(pUsbCore->tx_queue[i].owner != USB_CLASS_OWNER_MD){
+ continue;
+ }
+
+ if(pUsbCore->tx_queue[i].config & HIFUSB_QMU_TXQ_DL_DRB_EN) {
+ usbc_normal_hif_poll_queue_drb(i); // Poll Tx DRB
+ } else {
+ usbc_normal_hif_poll_queue_tx_gpd(i); // Poll Tx GPD/SPD
+ }
+
+ pUsbCore->usbc_txq_polled_mask |= 0x1 << i;
+ }
+ }
+ HIF_SWLA_STOP("UDP");
+
+ if (++pUsbCore->usbc_q_polled_duration == USBC_POLLED_CHECK_DURATION) {
+ usbc_data_trace(MD_TRC_USBCORE_POLL_QUEUE_E, pUsbCore->usbc_txq_polled_mask, pUsbCore->usbc_rxq_polled_mask);
+ usbc_trace_warn(USBCORE_POLL_ALL_QUEUE_EMPTY, USBC_POLLED_CHECK_DURATION, pUsbCore->usbc_txq_polled_mask, pUsbCore->usbc_rxq_polled_mask);
+ }
+ if (pUsbCore->usbc_q_polled_duration >= USBC_POLLED_CHECK_DURATION) {
+ pUsbCore->usbc_q_polled_duration = pUsbCore->usbc_txq_polled_mask = pUsbCore->usbc_rxq_polled_mask = 0;
+ }
+}
+
+static kal_bool usbc_core_isConfigValid(kal_uint8 iConfig)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8* pDevConf = pUsbCore->descriptors.device;
+
+ if(iConfig <= pDevConf[17])
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ usbc_trace_warn(USBCORE_CONF_INVALID, iConfig);
+ return KAL_FALSE;
+ }
+}
+void usbc_core_handle_device_wk_feature(usbc_func_state_e state)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint32 i;
+ kal_bool send_flag = KAL_FALSE;
+ kal_uint32 remote_wk_state;
+
+ for( i=0; i<pUsbCore->total_class_devices; i++)
+ {
+ if ( NULL != pUsbCore->class_device[i].query_func_wk_status &&
+ pUsbCore->class_device[i].query_func_wk_status(i) & ((kal_uint8)0x01) )
+ {
+ remote_wk_state = (pUsbCore->class_device[i].query_func_wk_status(i))>>1;
+ if(pUsbCore->class_device[i].owner == USB_CLASS_OWNER_AP)
+ {
+ if((remote_wk_state == 1 && state == USBC_FUNC_WK_DISABLE) ||(remote_wk_state == 0 && state == USBC_FUNC_WK_ENABLE))
+ {
+ /*only send request to AP when AP port wk state change*/
+ send_flag = KAL_TRUE;
+ }
+ }
+ usbc_core_notify_func_wk_ability(i, (state == USBC_FUNC_WK_DISABLE? KAL_FALSE:KAL_TRUE));
+ }
+ }
+ if(send_flag == KAL_TRUE && usbc_dual_owner_send_feature_request != NULL)
+ usbc_dual_owner_send_feature_request();
+
+ return;
+}
+
+
+void usbc_normal_hif_process_indications(void)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_core_class_interface_t *intf;
+ usbc_ind_t ind_dequeued;
+ kal_uint8 class_device_id;
+ usb_class_owner_e owner;
+
+ USBC_CLASS_DEVICE_CONTEXT_CHECK();
+
+ while (!usbc_queue_empty_check()) {
+ if (pUsbCore->usb_low_power_enable && (pUsbCore->waiting_ap_clk_disable_flag == KAL_TRUE))
+ {
+ kal_sleep_task(1);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ break;
+ }
+
+ if (pUsbCore->ap_response_reset_evt_done == KAL_FALSE)
+ {
+ if((ust_get_current_time() - pUsbCore->ap_response_evt_time) > USBC_AP_EVT_DONE_TIMEOUT)
+ {
+ usbc_trace_warn(USBCORE_WAIT_AP_RESET_DOWN_TIMEOUT);
+ pUsbCore->ap_response_reset_evt_done = KAL_TRUE;
+ }
+ else
+ {
+ kal_sleep_task(1);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ break;
+ }
+ }
+
+ if(!usbc_dequeue_ind(&ind_dequeued))
+ break;
+ switch (ind_dequeued.type) {
+ case USBC_IND_CTRL_SETUP:
+ ASSERT(pUsbCore->setup_indicated);
+ intf = &pUsbCore->class_interface[ind_dequeued.data];
+ class_device_id = pUsbCore->class_interface[ind_dequeued.data].class_device_id;
+
+ if (USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE == intf->state &&
+ NULL != intf->notify_control_setup_packet) {
+ if(pUsbCore->class_device[class_device_id].owner != USB_CLASS_OWNER_MD)
+ {
+ /*send setup packet to AP over CCCI if interface is AP owner. block function*/
+ if(usbc_dual_owner_class_ctrl_request != NULL)
+ usbc_dual_owner_class_ctrl_request();
+ break;
+ }
+ intf->notify_control_setup_packet(intf->class_device_id, &pUsbCore->setup_packet);
+ } else {
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+ break;
+
+ case USBC_IND_CTRL_CMPLT:
+ intf = &pUsbCore->class_interface[ind_dequeued.data];
+ class_device_id = pUsbCore->class_interface[ind_dequeued.data].class_device_id;
+
+ if (USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE == intf->state &&
+ NULL != intf->notify_control_complete) {
+ /*send data to AP over CCCI, if interface is AP owner and direction is OUT.*/
+ /*do nothing when IN*/
+ if(pUsbCore->class_device[class_device_id].owner != USB_CLASS_OWNER_MD){
+ if(usbc_dual_owner_class_ctrl_complete != NULL)
+ usbc_dual_owner_class_ctrl_complete();
+ break;
+ }
+ intf->notify_control_complete(intf->class_device_id);
+ }
+ break;
+
+ case USBC_IND_DEV_EVENT:
+ switch ((usbc_usb_state_e)ind_dequeued.data) {
+ case USBC_USB_STATE_ATTACHING:
+ usbc_core_notify_state_attaching();
+ break;
+ case USBC_USB_STATE_ATTACHED:
+ usbc_core_notify_state_attached();
+ break;
+ case USBC_USB_STATE_DETACHING:
+ usbc_core_notify_state_detaching();
+ break;
+ case USBC_USB_STATE_SUSPENDING:
+ usbc_core_notify_state_suspending();
+ break;
+ case USBC_USB_STATE_RESUME:
+ usbc_core_notify_state_resume();
+ break;
+ case USBC_USB_STATE_RESET:
+ usbc_core_notify_state_reset();
+ pUsbCore->usb_configuration = 0;
+#ifndef __PRODUCTION_RELEASE__
+/* under construction !*/
+/* under construction !*/
+#endif
+ break;
+ default:
+ ASSERT(KAL_FALSE);
+ break;
+ }
+ /*send state to AP over CCCI, if state is attached, send all port infomation to AP in addition.*/
+ if(usbc_dual_owner_notify_event != NULL)
+ usbc_dual_owner_notify_event((usbc_usb_state_e)ind_dequeued.data, ind_dequeued.ext);
+
+ break;
+
+ case USBC_IND_SPEED_CHANGE:
+ usbc_core_notify_speed_change((usbc_usb_speed_e)ind_dequeued.data);
+ break;
+
+ case USBC_IND_ALT_SETTING:
+ usbc_core_notify_alternate_setting(ind_dequeued.ext, ind_dequeued.data);
+ break;
+
+ case USBC_IND_PIPE_STALL:
+ usbc_normal_hif_sc_stall(ind_dequeued.data, (1 == ind_dequeued.ext) ? KAL_TRUE : KAL_FALSE, &owner);
+ usbc_core_notify_stall(
+ ((ind_dequeued.data & 0x80) ? KAL_TRUE : KAL_FALSE), /* is_tx */
+ (ind_dequeued.data & 0x7f), /* queue_idx */
+ ((1 == ind_dequeued.ext) ? KAL_TRUE : KAL_FALSE)); /* stall */
+
+ if(owner == USB_CLASS_OWNER_MD)
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ break;
+ case USBC_IND_MODE_SWITCH:
+ if (ind_dequeued.data < USB_MODE_NUM) {
+ usbc_mode_switch(ind_dequeued.data);
+ } else {
+ ASSERT(KAL_FALSE);
+ }
+ break;
+
+ case USBC_IND_FUNC_EVENT:
+ class_device_id = ind_dequeued.ext;
+
+ if((usbc_func_state_e)ind_dequeued.data == USBC_FUNC_WK_ENABLE ||(usbc_func_state_e)ind_dequeued.data == USBC_FUNC_WK_DISABLE )
+ {
+ usbc_core_handle_device_wk_feature((usbc_func_state_e)ind_dequeued.data);
+ }
+ else if(pUsbCore->class_device[class_device_id].owner != USB_CLASS_OWNER_MD)
+ {
+ /*If is not device remote wakeup enable setting, send request to AP*/
+ if(usbc_dual_owner_send_feature_request != NULL)
+ usbc_dual_owner_send_feature_request();
+ }
+ switch((usbc_func_state_e)ind_dequeued.data)
+ {
+ case USBC_FUNC_WK_ENABLE:
+ //usbc_core_notify_func_wk_ability(class_device_id, KAL_TRUE);
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ break;
+ case USBC_FUNC_WK_DISABLE:
+ //usbc_core_notify_func_wk_ability(class_device_id, KAL_FALSE);
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ break;
+ case USBC_FUNC_STATE_SUSPENDING:
+ usbc_core_notify_function_state_suspending(class_device_id);
+ break;
+ case USBC_FUNC_STATE_RESUME:
+ usbc_core_notify_function_state_resume(class_device_id);
+ break;
+ case USBC_FUNC_WK_ENABLE_STATE_SUSPENDING:
+ usbc_core_notify_func_wk_ability(class_device_id, KAL_TRUE);
+ usbc_core_notify_function_state_suspending(class_device_id);
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ break;
+ case USBC_FUNC_WK_ENABLE_STATE_RESUME:
+ usbc_core_notify_function_state_resume(class_device_id);
+ usbc_core_notify_func_wk_ability(class_device_id, KAL_TRUE);
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ break;
+ case USBC_FUNC_WK_DISABLE_STATE_SUSPENDING:
+ usbc_core_notify_func_wk_ability(class_device_id, KAL_FALSE);
+ usbc_core_notify_function_state_suspending(class_device_id);
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ break;
+ case USBC_FUNC_WK_DISABLE_STATE_RESUME:
+ usbc_core_notify_function_state_resume(class_device_id);
+ usbc_core_notify_func_wk_ability(class_device_id, KAL_FALSE);
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ break;
+ case USBC_FUNC_SET_FEATURE_ERROR:
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_STALL);
+ break;
+ default:
+ ASSERT(KAL_FALSE);
+ break;
+ }
+ break;
+ case USBC_IND_SET_CONFIG:
+ if(usbc_core_isConfigValid(ind_dequeued.data))
+ {
+ usbc_core_set_usb_configuration(ind_dequeued.data);
+ if(!pUsbCore->config_has_ap_port)
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ }
+ else
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_STALL);
+ }
+ break;
+
+ case USBC_IND_UFPM_POLL:
+ break;
+ case USBC_IND_IP_PWRDOWN:
+ //set USB powerdown for lowpower
+ usbc_core_power_down();
+ if(usbc_dual_owner_notify_event != NULL)
+ usbc_dual_owner_notify_event(USBC_USB_STATE_PWRDOWN, 0);
+ pUsbCore->state = USBC_USB_STATE_PWRDOWN;
+ break;
+ default:
+ EXT_ASSERT(0, USBCORE_LOC_TASK_INVALID_ITEM, (kal_uint32)ind_dequeued.type, 0);
+ break;
+ }
+ }
+}
+
+
+static kal_bool usbc_normal_hif_hw_usbq_set_gpd(hif_queue_type_e q_type, kal_uint8 queue_no, qbm_gpd* first_gpd, qbm_gpd* last_gpd)
+{
+ kal_bool result = KAL_FALSE;
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ if (first_gpd != last_gpd) {
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_SUBMIT_IO_REQUEST_HWQ, ((q_type << 8) | (queue_no & 0xFF)), (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ } else {
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_SUBMIT_IO_REQUEST_HWQ_ONE, ((q_type << 8) | (queue_no & 0xFF)), (kal_uint32)first_gpd);
+ }
+ result = hifusbq_set_gpd(q_type, queue_no, first_gpd, last_gpd);
+
+ return result;
+}
+
+static kal_bool usbc_normal_hif_sw_usbq_set_gpd(hif_queue_type_e q_type, kal_uint8 queue_no, qbm_gpd* first_gpd, qbm_gpd* last_gpd)
+{
+ kal_bool result = KAL_FALSE;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ USBC_CLASS_COMMON_LOCK(pUsbCore->usbc_class_resume_mutex);
+ if (first_gpd != last_gpd) {
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_SUBMIT_IO_REQUEST_SWQ, ((q_type << 8) | (queue_no & 0xFF)), (kal_uint32)first_gpd, (kal_uint32)last_gpd);
+ } else {
+ usbc_data_trace(MD_TRC_USBCORE_CLASS_SUBMIT_IO_REQUEST_SWQ_ONE, ((q_type << 8) | (queue_no & 0xFF)), (kal_uint32)first_gpd);
+ }
+ result = hifusbq_pwrsave_buffer_gpd(q_type, queue_no, first_gpd, last_gpd);
+
+ if (result == KAL_TRUE && usbc_core_get_instance()->state != USBC_USB_STATE_SUSPENDED) {
+ if (q_type == HIFQ_TYPE_TX) {
+ usbc_data_trace(MD_TRC_USBCORE_RESTORE_TX_GPD_SWQ2HWQ, (HIFQ_TYPE_TX << 8) | (queue_no & 0xFF) );
+ }
+ else if (q_type == HIFQ_TYPE_RX) {
+ usbc_data_trace(MD_TRC_USBCORE_RESTORE_RX_GPD_SWQ2HWQ, (HIFQ_TYPE_RX << 8) | (queue_no & 0xFF) );
+ }
+
+ result = hifusbq_pwrsave_restore_gpd(q_type, queue_no);
+ }
+ USBC_CLASS_COMMON_UNLOCK(pUsbCore->usbc_class_resume_mutex);
+
+ return result;
+}
+
+static kal_bool usbc_normal_hif_usbq_chk_empty(hif_queue_type_e core_queue_hif_type, kal_uint8 q_num)
+{
+ kal_bool isTx = ((core_queue_hif_type == HIFQ_TYPE_RX) || (core_queue_hif_type == HIFQ_TYPE_RX_W_BPS))? KAL_FALSE:KAL_TRUE;
+ return hifusb_chk_que_empty(isTx, q_num);
+}
+
+void usbc_normal_hif_factory(void)
+{
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ usbc_core_indicate_control_setup_packet = usbc_normal_hif_indicate_control_setup_packet;
+ usbc_core_indicate_control_complete = usbc_normal_hif_indicate_control_complete;
+ usbc_core_indicate_alternate_setting = usbc_normal_hif_indicate_alternate_setting;
+ usbc_core_indicate_stall = usbc_normal_hif_indicate_stall;
+ usbc_core_set_control_request = usbc_normal_hif_set_control_request;
+ usbc_core_set_property = hifusb_set_property;
+ usbc_core_set_usb_address = usbc_normal_hif_set_usb_address;
+ usbc_core_set_usb_configuration = usbc_normal_hif_set_usb_configuration;
+ usbc_core_set_stall = usbc_normal_hif_set_stall;
+ usbc_core_clear_stall = usbc_normal_hif_clear_stall;
+ usbc_core_rst_ep = usbc_normal_hif_rst_ep;
+ usbc_core_set_usb_testmode = hifusb_set_usb_testmode;
+#if __USBC_TARGET_HIF_DRIVER_SUPPORT__
+ usbc_core_set_ss_dev_init_u1_en = hifusb_ss_dev_init_u1_en;
+ usbc_core_set_ss_dev_init_u2_en = hifusb_ss_dev_init_u2_en;
+#endif
+ usbc_core_set_usbhif_address = hifusb_set_usb_address;
+ usbc_core_set_usbhif_configuration = hifusb_set_usb_configuration;
+ usbc_core_set_usbhif_connect = hifusb_set_connect;
+ usbc_core_set_usbhif_disconnect = hifusb_set_disconnect;
+ usbc_core_set_usbhifq_gpd = usbc_normal_hif_hw_usbq_set_gpd;
+ usbc_core_poll_hifusbq_gpd = hifusbq_poll_queue;
+ usbc_core_check_hifusbq_empty = usbc_normal_hif_usbq_chk_empty;
+ usbc_core_flush_hifusbq_gpd = hifusbq_flush_gpd;
+ usbc_core_flush_sw_hifusbq_gpd = hifusbq_pwrsave_flush_gpd;
+ usbc_core_check_new_packet = usbc_normal_hif_chk_newpkt;
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+ usbc_core_check_hifusbq_empty = usbc_direct_hif_usbq_chk_empty;
+ usbc_core_set_usbhif_address = usbc_direct_hifusb_set_usb_address_emulate;
+ usbc_core_set_usbhif_connect = usbc_direct_hifusb_set_usbhif_connect_disconnect;
+ usbc_core_set_usbhif_disconnect = usbc_direct_hifusb_set_usbhif_connect_disconnect;
+#endif
+ usbc_core_start_dataq = usbc_normal_hif_start_dataq;
+ usbc_core_power_down = hifusb_ip_pwrdn;
+ usbc_core_set_clock_cg = hifusb_set_clock_cg;
+ usbc_core_mask_wakeup_event = hifusb_mask_usb_wakeup_event;
+ usbc_core_mask_intr = hifusb_mask_mac_intr;
+}
+
+void usbc_meta_hif_factory(void)
+{
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ usbc_core_set_property = hifusb_set_property_emulate;
+ usbc_core_set_usbhif_address = hifusb_set_usb_address_emulate;
+ usbc_core_set_usbhif_configuration = hifusb_set_usb_configuration_emulate;
+}
+
+void usbc_suspended_hif_factory(void)
+{
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ // Update function pointer for buffering GPDs in DRAM
+ usbc_core_set_usbhifq_gpd = usbc_normal_hif_sw_usbq_set_gpd;
+}
+
+
+#ifdef ATEST_SYS_USBCORE
+void usbc_fake_hif_factory(void)
+{
+ usbc_core_set_control_request = usbc_ut_fake_set_control_request;
+}
+#endif
+
+void usbc_normal_hif_meta_attach(void)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ hifusb_boot_info_t usb_boot_info;
+
+ /* get USB HW info */
+ hifusb_get_boot_info(&usb_boot_info);
+
+ /* emulate driver connection */
+ usbc_core_notify_state_attaching();
+
+ /* emulate HIFUSB_NOTIFY_EVT_RESET */
+ hifusb_reset_isr_emulate();
+ usbc_core_speed_change(pUsbCore, (usbc_usb_speed_e)usb_boot_info.usb_speed); // emulate speed change notify
+ usbc_meta_hif_factory();
+
+ /* emulate SetAddress */
+ usbc_core_set_usb_address(usb_boot_info.usb_addr & 0x7f); // set USB address
+
+ /* emulate SetConfig */
+ usbc_core_set_usb_configuration(1); //set USB configuration, assume there is only one configuration in META mode
+ usbc_core_notify_state_attached();
+
+ /* restore function pointers of USB driver to normal state*/
+ usbc_normal_hif_factory();
+
+ // Clean USB indication queue
+ usbc_empty_ind_queue();
+}
+
+kal_bool usbc_normal_hif_is_meta_reused(void)
+{
+ hifusb_boot_info_t usb_boot_info;
+
+ /* get USB HW info */
+ hifusb_get_boot_info(&usb_boot_info);
+
+#if defined(__MTK_TARGET__) && defined(__MULTI_BOOT__)
+ return ((INT_BootMode() == MTK_FACTORY_MODE) && (usb_boot_info.boot_type == HIFUSB_BOOT_SUSPEND))? KAL_TRUE:KAL_FALSE;
+#else
+ return KAL_FALSE;
+#endif
+}
+
+kal_bool usbc_normal_hif_restore_gpd_pwrsave()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 queue_no;
+ kal_bool result;
+
+
+ USBC_NON_EXCEPTION_MODE_CHECK();
+
+ // Restore Tx GPDs
+ for(queue_no = 0; queue_no < pUsbCore->total_tx_queues; queue_no++)
+ {
+ if(pUsbCore->tx_queue[queue_no].owner != USB_CLASS_OWNER_MD){
+ continue;
+ }
+ usbc_data_trace(MD_TRC_USBCORE_RESTORE_TX_GPD_SWQ2HWQ, (HIFQ_TYPE_TX << 8) | (queue_no & 0xFF) );
+ result = hifusbq_pwrsave_restore_gpd(HIFQ_TYPE_TX, queue_no);
+ ASSERT(result);
+ }
+
+ // Restore Rx GPDs
+ for(queue_no = 0; queue_no < pUsbCore->total_rx_queues; queue_no++)
+ {
+ if(pUsbCore->rx_queue[queue_no].owner != USB_CLASS_OWNER_MD){
+ continue;
+ }
+ usbc_data_trace(MD_TRC_USBCORE_RESTORE_RX_GPD_SWQ2HWQ, (HIFQ_TYPE_RX << 8) | (queue_no & 0xFF) );
+ result = hifusbq_pwrsave_restore_gpd(HIFQ_TYPE_RX, queue_no);
+ ASSERT(result);
+ }
+
+ return KAL_TRUE;
+}
+
+/*------------------------------------------------------------------------------
+ * USB Core internal implementation for HIF direct mode.
+ *----------------------------------------------------------------------------*/
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+void usbc_direct_hif_factory(void)
+{
+ usbc_normal_hif_factory();
+ usbc_core_check_hifusbq_empty = usbc_direct_hif_usbq_chk_empty;
+ usbc_core_set_usbhif_address = usbc_direct_hifusb_set_usb_address_emulate;
+ usbc_core_set_usbhif_connect = usbc_direct_hifusb_set_usbhif_connect_disconnect;
+ usbc_core_set_usbhif_disconnect = usbc_direct_hifusb_set_usbhif_connect_disconnect;
+}
+#endif
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_ind_q.c b/mcu/middleware/hif/usbcore/src/usbcore_ind_q.c
new file mode 100644
index 0000000..cfe6193
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_ind_q.c
@@ -0,0 +1,434 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * usbcore_ind_q.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * USB Core indication queue operations.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#include "kal_public_api.h"
+#include "intrCtrl.h"
+#include "usbcore_debug.h"
+#include "usbcore_ind_q.h"
+
+#define USBC_UT_IND 0
+
+#define USBC_MAX_IND_QUEUE_LEN 128 /* Maximal number of indication in queue. It got to be 2's power and must larger than 6. */
+#define USBC_MAX_IND_QUEUE_LEN_MASK (USBC_MAX_IND_QUEUE_LEN - 1)
+
+
+static kal_uint32 usbc_ind_queue_head_s = 0;
+static kal_uint32 usbc_ind_queue_len_s = 0;
+static usbc_ind_t usbc_ind_queue_s[USBC_MAX_IND_QUEUE_LEN];
+static kal_spinlockid usbc_ind_q_spinlock = NULL;
+
+/*------------------------------------------------------------------------------
+ * Private implementation
+ *----------------------------------------------------------------------------*/
+#define USBC_IND_QUEUE_LOCK(_stack_var) \
+ _stack_var = SaveAndSetIRQMask()
+
+#define USBC_IND_QUEUE_UNLOCK(_stack_var) \
+ RestoreIRQMask(_stack_var)
+
+#define USBC_IND_QUEUE_TAKE_SPINLOCK() \
+ kal_take_spinlock(usbc_ind_q_spinlock, KAL_INFINITE_WAIT)
+
+#define USBC_IND_QUEUE_GIVE_SPINLOCK() \
+ kal_give_spinlock(usbc_ind_q_spinlock)
+
+#define USBC_IS_IND_QUEUE_FULL() \
+ (USBC_MAX_IND_QUEUE_LEN == usbc_ind_queue_len_s)
+
+#define USBC_IS_IND_QUEUE_EMPTY() \
+ (0 == usbc_ind_queue_len_s)
+
+#define USBC_GET_IND_QUEUE_INDEX(_index) \
+ ((_index) & USBC_MAX_IND_QUEUE_LEN_MASK)
+
+#define USBC_COPY_IND(_dst_ind, _src_ind) \
+ kal_mem_cpy((_dst_ind), (_src_ind), sizeof(usbc_ind_t))
+
+#if !USBC_UT_IND
+ #define USBC_IND_QUEUE_FULL_ASSERT(expr, e1, e2, e3) EXT_ASSERT(expr, e1, e2, e3)
+#else
+ #define USBC_IND_QUEUE_FULL_ASSERT(expr, e1, e2, e3)
+#endif
+/*------------------------------------------------------------------------------
+ * Public interface
+ *----------------------------------------------------------------------------*/
+kal_bool usbc_ind_queue_spinlock_init()
+{
+ kal_char usbc_class_mutex_name[50];
+
+ sprintf(usbc_class_mutex_name, "USBC_IND_Q_SPINLOCK");
+ usbc_ind_q_spinlock = kal_create_spinlock(usbc_class_mutex_name);
+
+ return (NULL != usbc_ind_q_spinlock)? KAL_TRUE:KAL_FALSE;
+}
+
+void usbc_empty_ind_queue()
+{
+ USBC_IND_QUEUE_TAKE_SPINLOCK();
+
+ if (!USBC_IS_IND_QUEUE_EMPTY())
+ {
+ usbc_ind_queue_head_s = usbc_ind_queue_len_s = 0;
+ }
+
+ USBC_IND_QUEUE_GIVE_SPINLOCK();
+
+ return;
+}
+
+void usbc_enqueue_ind(usbc_ind_t *indication)
+{
+ kal_uint32 new_tail;
+ kal_uint32 next_one;
+
+ USBC_IND_QUEUE_TAKE_SPINLOCK();
+
+ if (!USBC_IS_IND_QUEUE_FULL()) {
+ new_tail = USBC_GET_IND_QUEUE_INDEX(usbc_ind_queue_head_s + usbc_ind_queue_len_s);
+ usbc_ind_queue_len_s++;
+ } else {
+ /*
+ * If queue is full, we discard OLDEST NON-control request indication.
+ * Since HIF driver guarantees at most one control transfer is on-going,
+ * there are at most 1 CTRL_CMPLT and 1 SETUP_CMPLT in queue.
+ */
+ new_tail = usbc_ind_queue_head_s;
+ usbc_ind_queue_head_s = USBC_GET_IND_QUEUE_INDEX(usbc_ind_queue_head_s + 1);
+ if (USBC_IND_CTRL_SETUP == usbc_ind_queue_s[new_tail].type ||
+ USBC_IND_CTRL_CMPLT == usbc_ind_queue_s[new_tail].type) {
+
+ USBC_IND_QUEUE_FULL_ASSERT(0, USBCORE_LOC_TASK_QUE_FULL, 0, 0);
+ if (USBC_IND_CTRL_SETUP == usbc_ind_queue_s[usbc_ind_queue_head_s].type ||
+ USBC_IND_CTRL_CMPLT == usbc_ind_queue_s[usbc_ind_queue_head_s].type) {
+
+ next_one = USBC_GET_IND_QUEUE_INDEX(usbc_ind_queue_head_s + 1);
+ USBC_COPY_IND(&usbc_ind_queue_s[next_one], &usbc_ind_queue_s[usbc_ind_queue_head_s]);
+ }
+ USBC_COPY_IND(&usbc_ind_queue_s[usbc_ind_queue_head_s], &usbc_ind_queue_s[new_tail]);
+ }
+ }
+
+ USBC_COPY_IND(&usbc_ind_queue_s[new_tail], indication);
+
+ USBC_IND_QUEUE_GIVE_SPINLOCK();
+}
+
+kal_bool usbc_dequeue_ind(usbc_ind_t *indication)
+{
+ kal_bool succeeded;
+
+ USBC_IND_QUEUE_TAKE_SPINLOCK();
+
+ if (USBC_IS_IND_QUEUE_EMPTY()) {
+ succeeded = KAL_FALSE;
+ } else {
+ succeeded = KAL_TRUE;
+ USBC_COPY_IND(indication, &usbc_ind_queue_s[usbc_ind_queue_head_s]);
+ usbc_ind_queue_head_s = USBC_GET_IND_QUEUE_INDEX(usbc_ind_queue_head_s + 1);
+ usbc_ind_queue_len_s--;
+ }
+
+ USBC_IND_QUEUE_GIVE_SPINLOCK();
+
+ return succeeded;
+}
+
+kal_bool usbc_queue_empty_check()
+{
+ return USBC_IS_IND_QUEUE_EMPTY();
+}
+
+#if USBC_UT_IND
+
+#define USBC_IND_UT_TYPE_MASK 0x3
+#define USBC_IND_UT_DATA_MASK 0x3f
+
+void usbc_ut_ind(void)
+{
+ kal_uint32 burst_len;
+ kal_uint32 idx;
+ kal_uint32 start_pos;
+ usbc_ind_t ind_to_enqueue;
+ usbc_ind_t ind_dequeued;
+
+ for (burst_len = 1; burst_len <= USBC_MAX_IND_QUEUE_LEN; burst_len++) {
+ for (start_pos = 0; start_pos < USBC_MAX_IND_QUEUE_LEN; start_pos++) {
+ /*
+ * Change queue head index.
+ */
+ USBC_IND_QUEUE_TAKE_SPINLOCK();
+ ASSERT(USBC_IS_IND_QUEUE_EMPTY());
+ usbc_ind_queue_head_s = start_pos;
+ USBC_IND_QUEUE_TAKE_SPINLOCK();
+
+ /*
+ * Enqueue burst of indications.
+ */
+ for (idx = 0; idx < burst_len; idx++) {
+ ind_to_enqueue.type = (idx & USBC_IND_UT_TYPE_MASK);
+ ind_to_enqueue.data = (idx & USBC_IND_UT_DATA_MASK);
+
+ usbc_enqueue_ind(&ind_to_enqueue);
+ }
+
+ /*
+ * Dequeue burst of indications and check the correctness.
+ */
+ for (idx = 0; idx < burst_len; idx++) {
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if ((idx & USBC_IND_UT_TYPE_MASK) != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if ((idx & USBC_IND_UT_DATA_MASK) != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+ }
+
+ /*
+ * Check dequeue at empty queue condition.
+ */
+ if (usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ }
+ }
+
+ /*
+ * Check enqueue at queue full with last indication is a device event.
+ */
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.data = 0x23;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ for (idx = 1; idx < USBC_MAX_IND_QUEUE_LEN; idx++) {
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.data = (idx & USBC_IND_UT_DATA_MASK);
+ usbc_enqueue_ind(&ind_to_enqueue);
+ }
+
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.data = 0x18;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ for (idx = 1; idx < USBC_MAX_IND_QUEUE_LEN; idx++) {
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_DEV_EVENT != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if ((idx & USBC_IND_UT_DATA_MASK) != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+ }
+
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_DEV_EVENT != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if (0x18 != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+
+ /*
+ * Check enqueue at queue full with last indication is a control transfer.
+ */
+ ind_to_enqueue.type = USBC_IND_CTRL_SETUP;
+ ind_to_enqueue.data = 0x23;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ for (idx = 1; idx < USBC_MAX_IND_QUEUE_LEN; idx++) {
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.data = (idx & USBC_IND_UT_DATA_MASK);
+ usbc_enqueue_ind(&ind_to_enqueue);
+ }
+
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.data = 0x18;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_CTRL_SETUP != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if (0x23 != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+
+ for (idx = 2; idx < USBC_MAX_IND_QUEUE_LEN; idx++) {
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_DEV_EVENT != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if ((idx & USBC_IND_UT_DATA_MASK) != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+ }
+
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_DEV_EVENT != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if (0x18 != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+
+ /*
+ * Check enqueue at queue full with last two indications are control transfer related.
+ */
+ ind_to_enqueue.type = USBC_IND_CTRL_SETUP;
+ ind_to_enqueue.data = 0x23;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ ind_to_enqueue.type = USBC_IND_CTRL_SETUP;
+ ind_to_enqueue.data = 0x33;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+
+ for (idx = 2; idx < USBC_MAX_IND_QUEUE_LEN; idx++) {
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.data = (idx & USBC_IND_UT_DATA_MASK);
+ usbc_enqueue_ind(&ind_to_enqueue);
+ }
+
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.data = 0x18;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_CTRL_SETUP != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if (0x23 != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_CTRL_SETUP != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if (0x33 != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+
+ for (idx = 3; idx < USBC_MAX_IND_QUEUE_LEN; idx++) {
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_DEV_EVENT != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if ((idx & USBC_IND_UT_DATA_MASK) != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+ }
+
+ if (!usbc_dequeue_ind(&ind_dequeued)) {
+ ASSERT(KAL_FALSE);
+ }
+ if (USBC_IND_DEV_EVENT != ind_dequeued.type) {
+ ASSERT(KAL_FALSE);
+ }
+ if (0x18 != ind_dequeued.data) {
+ ASSERT(KAL_FALSE);
+ }
+}
+#endif
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_notify_event.c b/mcu/middleware/hif/usbcore/src/usbcore_notify_event.c
new file mode 100644
index 0000000..724157a
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_notify_event.c
@@ -0,0 +1,466 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * usbcore_notify_event.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * Helper routine to notify USBCLASS changes.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#include "usbcore_class_device.h"
+#include "usbc_custom.h"
+#include "hif_ior.h"
+#include "hif_mw_msgid.h"
+#include "usbidle_if.h"
+#include "usbcore_debug.h"
+#include "hmu_conf_data.h"
+#include "usbcore_dual_owner.h"
+/*------------------------------------------------------------------------------
+ * Private implementation.
+ *----------------------------------------------------------------------------*/
+static void usbc_core_indicate_state(usbc_usb_state_e state)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint8 idx;
+
+ pUsbCore->state = state;
+
+ for (idx = 0; idx < pUsbCore->total_class_devices; idx++) {
+ if ( USBC_CORE_CLASS_DEVICE_STATE_REGISTERED == pUsbCore->class_device[idx].state &&
+ NULL != pUsbCore->class_device[idx].notify_usb_state )
+ {
+ if ( (state == USBC_USB_STATE_SUSPENDING || state == USBC_USB_STATE_SUSPENDED) &&
+ pUsbCore->class_device[idx].is_func_suspend )
+ {
+ // do not suspend the class device again if it has been in function suspend state
+ }
+ else if ( state == USBC_USB_STATE_RESUME && pUsbCore->class_device[idx].is_func_suspend )
+ {
+ // do not resume the class device which was function suspended while device resuming
+ // the class device will be resumed later while function resuming
+ }
+ else
+ {
+ usbc_trace_info(USBCORE_NOTIFY_CLASS_START, pUsbCore->class_device[idx].class_type, state);
+ pUsbCore->class_device[idx].notify_usb_state(idx,state);
+ usbc_trace_info(USBCORE_NOTIFY_CLASS_END, pUsbCore->class_device[idx].class_type, state);
+ }
+ }
+ }
+}
+
+
+/*!
+ * @brief This function is used to notify function suspend or function resume to a specific class device
+ */
+void usbc_core_indicate_function_state(kal_uint8 class_device_id, usbc_usb_state_e state)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ if ( USBC_CORE_CLASS_DEVICE_STATE_REGISTERED == pUsbCore->class_device[class_device_id].state &&
+ NULL != pUsbCore->class_device[class_device_id].notify_usb_state )
+ {
+ usbc_trace_info(USBCORE_NOTIFY_CLASS_START, pUsbCore->class_device[class_device_id].class_type, state);
+ pUsbCore->class_device[class_device_id].notify_usb_state(class_device_id, state);
+ usbc_trace_info(USBCORE_NOTIFY_CLASS_END, pUsbCore->class_device[class_device_id].class_type, state);
+
+ }
+}
+
+/*------------------------------------------------------------------------------
+ * Public interface.
+ *----------------------------------------------------------------------------*/
+void usbc_core_notify_state_attaching()
+{
+ usbc_core_indicate_state(USBC_USB_STATE_ATTACHING);
+}
+
+
+void usbc_core_notify_state_attached()
+{
+ usbc_core_indicate_state(USBC_USB_STATE_ATTACHED);
+}
+
+
+void usbc_core_notify_state_detaching()
+{
+ usbc_core_indicate_state(USBC_USB_STATE_DETACHING);
+ usbc_core_indicate_state(USBC_USB_STATE_DETACHED);
+}
+
+
+void usbc_core_notify_state_suspending()
+{
+ kal_uint16 func_list;
+ usbcore_usbidle_l4_power_saving_req_struct *rsp_msg_p;
+
+ // notify USBCLASS of USB suspended
+ usbc_core_indicate_state(USBC_USB_STATE_SUSPENDING);
+ usbc_core_indicate_state(USBC_USB_STATE_SUSPENDED);
+
+ if( USBC_IS_IN_EXCEPTION_MODE() )
+ {
+ return;
+ }
+
+ // Updatea function pointer for setting GPDs in DRAM buffer
+ usbc_trace_info(USBCORE_UPDATE_API_BUFF_GPD, 1);
+ usbc_suspended_hif_factory();
+
+ // Ask USBIDLE to notify L4 to turn RF power off or go to fast dormancy
+ func_list = usbc_core_get_function_remote_wk_list();
+ rsp_msg_p = (usbcore_usbidle_l4_power_saving_req_struct*)construct_local_para(sizeof(usbcore_usbidle_l4_power_saving_req_struct), TD_RESET);
+ ASSERT(rsp_msg_p);
+ rsp_msg_p->notify_suspend = KAL_TRUE;
+ rsp_msg_p->notify_suspend_with_remote_wk = (func_list==0)? KAL_FALSE:KAL_TRUE;
+ usbc_trace_info(USBCORE_DEV_SUSPEND_L4, 1, 1, 1, (rsp_msg_p->notify_suspend_with_remote_wk? 1:0));
+ usb_idle_set_l4_power_saving(KAL_TRUE);
+ msg_send6(MOD_USBCORE, // src module
+ MOD_USBIDLE, // dst module
+ 0, // sap id
+ MSG_ID_USBCORE_IDLE_NOTIFY_TO_L4,
+ (local_para_struct*)rsp_msg_p,
+ 0); //msg id
+}
+
+
+void usbc_core_notify_state_resume()
+{
+ kal_bool remote_wakeup_enabled = (usbc_core_get_function_remote_wk_list()==0)? KAL_FALSE:KAL_TRUE;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ if( USBC_IS_IN_EXCEPTION_MODE() )
+ {
+ usbc_core_indicate_state(USBC_USB_STATE_RESUME);
+ return;
+ }
+
+
+ // nofity USBIDLE that it does not have to gate the clock of USB IP
+ usbc_trace_info(USBCORE_DEV_SUSPEND_CLOCK, 0, 0);
+ usb_idle_set_clockGating(KAL_FALSE);
+
+ USBC_CLASS_COMMON_LOCK(pUsbCore->usbc_class_resume_mutex);
+ // Notify USB resume event to USB classes
+ usbc_core_indicate_state(USBC_USB_STATE_RESUME);
+
+ // Set GPDs that are buffered in DRAM to hardware
+ usbc_normal_hif_restore_gpd_pwrsave();
+
+ // Update function pointer for set GPDs to hardware normally
+ usbc_trace_info(USBCORE_UPDATE_API_BUFF_GPD, 0);
+ usbc_normal_hif_factory();
+ USBC_CLASS_COMMON_UNLOCK(pUsbCore->usbc_class_resume_mutex);
+
+ // Set USBCORE task to wait for both indication events and tick events
+ usbc_trace_info(USBCORE_SUSPEND_START_POLL);
+ usbc_core_get_instance()->hmu_indication = HIF_DRV_EG_HIF_TICK_EVENT | HIF_DRV_EG_USBC_IND_EVENT;
+
+ // Ask USBIDLE to notify L4 to turn RF power on or go back to normal operation state
+ usbc_trace_info(USBCORE_DEV_SUSPEND_L4, 0, 0, 0, (remote_wakeup_enabled? 1:0));
+ usb_idle_set_l4_power_saving(KAL_FALSE);
+ usb_idle_event_notify_to_l4(KAL_FALSE, remote_wakeup_enabled);
+}
+
+
+void usbc_core_notify_state_reset()
+{
+ kal_bool remote_wakeup_enabled = (usbc_core_get_function_remote_wk_list()==0)? KAL_FALSE:KAL_TRUE;
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ if( USBC_IS_IN_EXCEPTION_MODE() )
+ {
+ usbc_core_indicate_state(USBC_USB_STATE_RESET);
+ usbc_core_clear_status();
+ return;
+ }
+
+ // nofity USBIDLE that it does not have to gate the clock of USB IP
+ usbc_trace_info(USBCORE_DEV_SUSPEND_CLOCK, 0, 0);
+ usb_idle_set_clockGating(KAL_FALSE);
+
+ USBC_CLASS_COMMON_LOCK(pUsbCore->usbc_class_resume_mutex);
+
+ // Set GPDs that are buffered in DRAM to hardware
+ usbc_normal_hif_restore_gpd_pwrsave();
+
+ usbc_trace_info(USBCORE_UPDATE_API_BUFF_GPD, 0);
+ // Update function pointer for set GPDs to hardware normally
+ usbc_normal_hif_factory();
+
+ pUsbCore->state = USBC_USB_STATE_RESET;
+ USBC_CLASS_COMMON_UNLOCK(pUsbCore->usbc_class_resume_mutex);
+
+ // Notify USB reset event to USB classes
+ usbc_core_indicate_state(USBC_USB_STATE_RESET);
+
+ // Clear USB status
+ usbc_core_clear_status();
+
+ // Ask USBIDLE to notify L4 to turn RF power on or go back to normal operation state
+ usbc_trace_info(USBCORE_DEV_SUSPEND_L4, 0, 0, 0, (remote_wakeup_enabled? 1:0));
+ usb_idle_set_l4_power_saving(KAL_FALSE);
+ usb_idle_event_notify_to_l4(KAL_FALSE, remote_wakeup_enabled);
+}
+
+
+void usbc_core_notify_speed_change(usbc_usb_speed_e speed)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint8 idx = 0;
+
+ for (idx = 0; idx < pUsbCore->total_class_devices; idx++) {
+ if (USBC_CORE_CLASS_DEVICE_STATE_REGISTERED == pUsbCore->class_device[idx].state &&
+ NULL != pUsbCore->class_device[idx].notify_usb_speed) {
+ pUsbCore->class_device[idx].notify_usb_speed(idx, speed);
+ }
+ }
+}
+
+void usbc_core_notify_alternate_setting(kal_uint8 intf_idx, kal_uint8 alternate_setting)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_core_class_interface_t *intf = &pUsbCore->class_interface[intf_idx];
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+ if (USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE == intf->state &&
+ NULL != intf->notify_alternate_setting) {
+ intf->notify_alternate_setting(
+ intf->class_device_id,
+ intf->interface_type,
+ intf->alternate_setting);
+ }
+}
+
+void usbc_core_notify_stall(kal_bool is_tx, kal_uint8 queue_idx, kal_bool stall)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbc_core_queue_t *pQueue;
+
+ if (is_tx) {
+ pQueue = &pUsbCore->tx_queue[queue_idx];
+ } else {
+ pQueue = &pUsbCore->rx_queue[queue_idx];
+ }
+
+ /*send stall info to AP over CCCI if this endpoint is AP owner, return after send.*/
+ if(pQueue->owner != USB_CLASS_OWNER_MD && usbc_dual_owner_send_feature_request != NULL)
+ {
+ usbc_dual_owner_send_feature_request();
+ }
+ if (pQueue->state > USBC_CORE_QUEUE_STATE_INITIATED &&
+ NULL != pQueue->notify_stall) {
+ pQueue->notify_stall(pQueue->class_device_id, stall);
+ }
+}
+
+void usbc_core_notify_function_state_suspending(kal_uint8 class_device_id)
+{
+ kal_uint16 func_suspend_list;
+ kal_uint16 func_wk_list = usbc_core_get_function_remote_wk_list();
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ usbcore_usbidle_l4_power_saving_req_struct *rsp_msg_p;
+
+ // Notify the specific function of USB suspended
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ usbc_core_indicate_function_state(class_device_id, USBC_USB_STATE_SUSPENDING);
+ usbc_core_indicate_function_state(class_device_id, USBC_USB_STATE_SUSPENDED);
+ pUsbCore->class_device[class_device_id].is_func_suspend = KAL_TRUE;
+ }
+
+ // If all functions of the device are suspended, we notify L4 to do power saving
+ func_suspend_list = usbc_core_get_function_suspend_list();
+ if( !USBC_IS_IN_EXCEPTION_MODE() &&
+ func_suspend_list == ((0x01 << pUsbCore->total_class_devices)-1) )
+ {
+ rsp_msg_p = (usbcore_usbidle_l4_power_saving_req_struct*)construct_local_para(sizeof(usbcore_usbidle_l4_power_saving_req_struct), TD_RESET);
+ ASSERT(rsp_msg_p);
+ rsp_msg_p->notify_suspend = KAL_TRUE;
+ rsp_msg_p->notify_suspend_with_remote_wk = (func_wk_list==0)? KAL_FALSE:KAL_TRUE;
+ usbc_trace_info(USBCORE_DEV_SUSPEND_L4, 1, 1, 1, (rsp_msg_p->notify_suspend_with_remote_wk? 0:1));
+ usb_idle_set_l4_power_saving(KAL_TRUE);
+ msg_send6(MOD_USBCORE, // src module
+ MOD_USBIDLE, // dst module
+ 0, // sap id
+ MSG_ID_USBCORE_IDLE_NOTIFY_TO_L4,
+ (local_para_struct*)rsp_msg_p,
+ 0); //msg id
+ }
+}
+
+void usbc_core_notify_function_state_resume(kal_uint8 class_device_id)
+{
+ kal_uint16 func_suspend_list = usbc_core_get_function_suspend_list();
+ kal_bool remote_wakeup_enabled = (usbc_core_get_function_remote_wk_list()==0)? KAL_FALSE:KAL_TRUE;
+
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+
+ // Notify the specific function of USB resuming
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ usbc_core_indicate_function_state(class_device_id, USBC_USB_STATE_RESUME);
+ pUsbCore->class_device[class_device_id].is_func_suspend = KAL_FALSE;
+ }
+
+ // Notify L4 to go back to normal operation states if function resumes from the status that all functions are suspended before
+ if( !USBC_IS_IN_EXCEPTION_MODE() &&
+ func_suspend_list == ((0x01 << pUsbCore->total_class_devices)-1) )
+ {
+ usbc_trace_info(USBCORE_DEV_SUSPEND_L4, 0, 0, 0, (remote_wakeup_enabled? 0:1));
+ usb_idle_set_l4_power_saving(KAL_FALSE);
+ usb_idle_event_notify_to_l4(KAL_FALSE, remote_wakeup_enabled);
+ }
+}
+
+void usbc_core_notify_func_wk_ability(kal_uint8 class_device_id, kal_bool ability)
+{
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_bool isCapableWk = KAL_FALSE;
+
+ // check the capability of the class device
+ if ( NULL != pUsbCore->class_device[class_device_id].query_func_wk_status)
+ {
+ isCapableWk = ((pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id) & (kal_uint8)0x01) == 0x01)? KAL_TRUE:KAL_FALSE;
+ }
+ if( ability && !isCapableWk )
+ {
+ usbc_trace_error(USBCORE_NOTIFY_WK_ABILITY_INVALID, pUsbCore->class_device[class_device_id].class_type);
+ ASSERT(0);
+ return;
+ }
+
+ if ( USBC_CORE_CLASS_DEVICE_STATE_REGISTERED == pUsbCore->class_device[class_device_id].state &&
+ NULL != pUsbCore->class_device[class_device_id].notify_func_wk_ability )
+ {
+ usbc_trace_info(USBCORE_NOTIFY_WK_ABILITY_START, pUsbCore->class_device[class_device_id].class_type);
+ pUsbCore->class_device[class_device_id].notify_func_wk_ability(class_device_id, ability);
+ usbc_trace_info(USBCORE_NOTIFY_WK_ABILITY_END, pUsbCore->class_device[class_device_id].class_type);
+ }
+}
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_resource.c b/mcu/middleware/hif/usbcore/src/usbcore_resource.c
new file mode 100644
index 0000000..d1755d1
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_resource.c
@@ -0,0 +1,136 @@
+/*!
+ * @file usbcore_resource.c
+ * @author HaoRen Kao
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides usb resource management function
+ */
+
+#include <stdlib.h>
+#include "usbcore_main.h"
+
+void
+usbc_resource_reset(void)
+{
+ usbc_core_t* usbc_inst = usbc_core_get_instance();
+ kal_uint8 idx;
+
+ for (idx = 0; idx < MAX_USBCORE_CONFIG_NUM; idx++)
+ {
+ usbc_inst->resource_interface_number[idx] = 0;
+ usbc_inst->resource_iad_number[idx] = 0;
+ usbc_inst->resource_ep_tx_number[idx] = 0;
+ usbc_inst->resource_ep_rx_number[idx] = 0;
+ }
+ usbc_inst->resource_string_number = 0;
+}
+
+usbc_interface_info_t*
+usbc_get_interface_number(kal_uint8 config_num, kal_uint8 *if_num_p)
+{
+ usbc_core_t* usbc_inst = usbc_core_get_instance();
+
+ ASSERT(config_num < MAX_USBCORE_CONFIG_NUM);
+ ASSERT(usbc_inst->resource_interface_number[config_num] < MAX_USBCORE_INTERFACE_NUM);
+
+ usbc_inst->resource_interface_number[config_num]++;
+ if (if_num_p) {
+ *if_num_p = usbc_inst->resource_interface_number[config_num] - 1;
+ }
+ return (&usbc_inst->if_info[config_num][usbc_inst->resource_interface_number[config_num] - 1]);
+}
+
+kal_uint8
+usbc_get_string_number(void *string)
+{
+ usbc_core_t* usbc_inst = usbc_core_get_instance();
+ usbc_string_descriptor_t* string_dscr;
+
+ ASSERT(string);
+ ASSERT(usbc_inst->resource_string_number < MAX_USBCORE_STRING_DESCRIPTOR_NUM);
+
+ string_dscr = (usbc_string_descriptor_t*)string;
+
+ usbc_inst->resource_string_number++;
+ usbc_inst->string_descriptor[usbc_inst->resource_string_number - 1] = string_dscr;
+ return (usbc_inst->resource_string_number - 1);
+}
+
+usbc_interface_association_descriptor_t*
+usbc_get_iad_number(kal_uint8 config_num, kal_uint8 *iad_num_p)
+{
+ usbc_core_t* usbc_inst = usbc_core_get_instance();
+
+ ASSERT(config_num < MAX_USBCORE_CONFIG_NUM);
+ ASSERT(usbc_inst->resource_iad_number[config_num] < MAX_USBCORE_IAD_NUM);
+
+ usbc_inst->resource_iad_number[config_num]++;
+ if (iad_num_p) {
+ *iad_num_p = usbc_inst->resource_iad_number[config_num] - 1;
+ }
+ return (&usbc_inst->iad_descriptor[config_num][usbc_inst->resource_iad_number[config_num] - 1]);
+}
+
+usbc_endpoint_info_t*
+usbc_get_endpoint_tx_number(kal_uint8 config_num, kal_uint8 *tx_ep_num_p)
+{
+ usbc_core_t* usbc_inst = usbc_core_get_instance();
+
+ ASSERT(config_num < MAX_USBCORE_CONFIG_NUM);
+ ASSERT(usbc_inst->resource_ep_tx_number[config_num] < MAX_USBCORE_QUEUE_NUM);
+
+ usbc_inst->resource_ep_tx_number[config_num]++;
+ if (tx_ep_num_p) {
+ *tx_ep_num_p = usbc_inst->resource_ep_tx_number[config_num];
+ }
+ return (&usbc_inst->ep_tx_info[config_num][usbc_inst->resource_ep_tx_number[config_num] - 1]);
+}
+
+usbc_endpoint_info_t*
+usbc_get_endpoint_rx_number(kal_uint8 config_num, kal_uint8 *rx_ep_num_p)
+{
+ usbc_core_t* usbc_inst = usbc_core_get_instance();
+
+ ASSERT(config_num < MAX_USBCORE_CONFIG_NUM);
+ ASSERT(usbc_inst->resource_ep_rx_number[config_num] < MAX_USBCORE_QUEUE_NUM);
+
+ usbc_inst->resource_ep_rx_number[config_num]++;
+ if (rx_ep_num_p) {
+ *rx_ep_num_p = usbc_inst->resource_ep_rx_number[config_num];
+ }
+ return (&usbc_inst->ep_rx_info[config_num][usbc_inst->resource_ep_rx_number[config_num] - 1]);
+}
+
+
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_stack.c b/mcu/middleware/hif/usbcore/src/usbcore_stack.c
new file mode 100644
index 0000000..42b2054
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_stack.c
@@ -0,0 +1,747 @@
+/*!
+ * @file usbcore_stack.c
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides interactive functions of usbcore and HMU
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#include "usbc_custom.h"
+#include "usbcore_debug.h"
+#ifdef __MULTI_BOOT__
+#include "multiboot_config.h"
+#endif /* __MULTI_BOOT__ */
+#include "usbcore_ind_q.h"
+#include "hmu_conf_data.h"
+#include "hmu.h"
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+#include "usbcore_direct.h"
+#endif
+#include "usb_nvram_def.h"
+#include "dcl.h"
+#ifdef __HIF_CCCI_SUPPORT__
+#include "ccci_if.h"
+#endif
+
+#ifndef __MAUI_BASIC__
+extern kal_uint8 custom_em_get_usb_cdrom_config(void);
+#else
+ #define custom_em_get_usb_cdrom_config(...) 0x00
+#endif
+extern kal_uint16 INT_BootMode(void);
+extern kal_uint32 usb_mode_register_index;
+
+/*------------------------------------------------------------------------------
+ * USB stack initialization.
+ *----------------------------------------------------------------------------*/
+/*
+ * USB stack configuration.
+ */
+
+/*
+ * Bitmap of check-in nodes.
+ */
+static kal_uint32 usbc_stack_nodes_s = 0;
+
+/*
+ * Node registration information.
+ * 0 ~ (USB_FUNC_NUM-1) : USB function node
+ * USB_FUNC_NUM : USB Core node
+ */
+#define USBC_NODE_COUNT USB_CLASS_NUM+1
+static usbc_node_reg_entry_t *usbc_stack_nodes_reg_table_s[USBC_NODE_COUNT];
+
+/*
+ * USB stack helper routines.
+ */
+#define _NODE_TO_BIT(_node) \
+ ( (kal_uint32)1 << (kal_uint32)(_node) )
+
+#define _GET_NODE_VALUE() \
+ usbc_stack_nodes_s
+
+#define _SET_NODE_VALUE(_val) \
+ usbc_stack_nodes_s = (_val)
+
+#define _GET_NODE_REG_TABLE(_node) \
+ usbc_stack_nodes_reg_table_s[(_node)]
+
+#define _SET_NODE_REG_TABLE(_node, _reg_table) \
+ usbc_stack_nodes_reg_table_s[(_node)] = (_reg_table)
+
+#define _CHECKIN_NODE(_node, _reg_table) \
+ (usbc_stack_nodes_s) |= _NODE_TO_BIT(_node); \
+ _SET_NODE_REG_TABLE(_node, _reg_table)
+
+#define _ALL_NODES_CHECKIN() \
+ ( (usbc_stack_nodes_s) == (_NODE_TO_BIT(USBC_NODE_COUNT) - 1) )
+
+
+#define INDEX_TO_CFG(index) (index+1)
+
+/*
+ * USB language string
+ */
+static const kal_uint16 usb_language_string[] =
+{
+ 0x0304,
+ 0x0409
+};
+
+/*
+ * Default device descriptor
+ */
+static usbc_device_descriptor_t usbc_default_device_descriptor =
+{
+ /* Device Descriptor */
+ 0x12, /* bLength */
+ USBC_DT_DEVICE, /* DEVICE */
+ 0x0200, /* bcdUSB: USB 2.0 */
+ 0xEF, /* CLASS */
+ 0x02, /* Subclass */
+ 0x01, /* Protocol */
+ 0x40, /* bMaxPktSize0 */
+ 0x0E8D, /* idVendor */
+ 0x1234, /* idProduct */
+ 0x0001, /* bcdDevice */
+ 0x00, /* iManufacturer */
+ 0x00, /* iProduct */
+ 0x00, /* iSerial Number */
+ 0x01 /* One configuration */
+};
+
+/*
+ * Default configuration descriptor
+ */
+static usbc_configuration_descriptor_t usbc_default_configuration_descriptor =
+{
+ 0x09, /* bLength */
+ 0x02, /* CONFIGURATION */
+ 0x0000, /* length */
+ 0x00, /* bNumInterfaces */
+ 0x00, /* bConfigurationValue */
+ 0x00, /* iConfiguration */
+ 0x80, /* bmAttributes (required + self-powered) */
+ 0xFA /* power */
+};
+
+void usbc_stack_reset()
+{
+ usbc_stack_nodes_s = 0;
+ kal_mem_set(usbc_stack_nodes_reg_table_s, 0, sizeof(usbc_stack_nodes_reg_table_s));
+}
+
+static usbc_class_init_func_t _get_class_init_func(usb_class_type_e type)
+{
+ usbc_node_reg_entry_t *curr_entry;
+
+ curr_entry = _GET_NODE_REG_TABLE(type);
+
+ if (curr_entry && curr_entry->init_func) {
+ return (usbc_class_init_func_t)(curr_entry->init_func);
+ } else {
+ return NULL;
+ }
+}
+
+static usbc_class_reinit_func_t _get_class_reinit_func(usb_class_type_e type)
+{
+ usbc_node_reg_entry_t *curr_entry;
+
+ curr_entry = _GET_NODE_REG_TABLE(type);
+
+ if (curr_entry && curr_entry->reinit_func) {
+ return (usbc_class_reinit_func_t)(curr_entry->reinit_func);
+ } else {
+ return NULL;
+ }
+}
+
+usbc_class_set_config_func_t usbc_get_class_set_config_func(usb_class_type_e type)
+{
+ usbc_node_reg_entry_t *curr_entry;
+
+ curr_entry = _GET_NODE_REG_TABLE(type);
+
+ if (curr_entry && curr_entry->set_config_func) {
+ return (usbc_class_set_config_func_t)(curr_entry->set_config_func);
+ } else {
+ return NULL;
+ }
+}
+
+static usbc_class_query_func_wk_capability_func_t usbc_get_class_query_func_wk_capability_func(usb_class_type_e type)
+{
+ usbc_node_reg_entry_t *curr_entry;
+
+ curr_entry = _GET_NODE_REG_TABLE(type);
+
+ if (curr_entry && curr_entry->query_func_wk_capability)
+ {
+ return (usbc_class_query_func_wk_capability_func_t)(curr_entry->query_func_wk_capability);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static void _usbc_construct_config_descriptor(usbc_core_t *usbc_p)
+{
+ kal_uint32 idx_cfg, idx_if, idx_ep, idx_iad, idx_class;
+ kal_uint32 config_index;
+ usb_cfg_param_t *cfg_param;
+ kal_uint8 *conf;
+ usbc_configuration_descriptor_t *config_desc_p;
+ usbc_class_query_func_wk_capability_func_t class_query;
+
+ // check for valid USB mode
+ if (usbc_p->mode >= USB_MODE_NUM)
+ {
+ ASSERT(0);
+ return;
+ }
+
+ // assign bMaxPower for USB 3.0 configurations
+ usbc_p->u3ConfMaxPower = (U3_CONF_BMAXPOWER / USBC_USB30_POWER_DESC_UINT);
+
+ // construct configuration descriptors
+ for (idx_cfg = 0; idx_cfg < usbc_p->dev_param->mode_param[usbc_p->mode].cfg_num; idx_cfg ++)
+ {
+ config_index = 0;
+ conf = usbc_p->descriptors.configuration[idx_cfg];
+
+ /* configuration descriptor */
+ kal_mem_cpy(conf + config_index,
+ &usbc_default_configuration_descriptor,
+ USBC_CONFIGURATION_DESC_SIZE);
+ config_index += USBC_CONFIGURATION_DESC_SIZE;
+
+ /* interface/iad/endpoint descriptors */
+ for (idx_if = 0; idx_if < usbc_p->resource_interface_number[idx_cfg]; idx_if ++)
+ {
+ /* IAD */
+ for (idx_iad = 0; idx_iad < usbc_p->resource_iad_number[idx_cfg]; idx_iad ++) {
+ if (idx_if == usbc_p->iad_descriptor[idx_cfg][idx_iad].bFirstInterface) {
+ break;
+ }
+ }
+ if (idx_iad != usbc_p->resource_iad_number[idx_cfg])
+ { /* This interface is the first interface of the IAD */
+ kal_mem_cpy(conf + config_index,
+ &usbc_p->iad_descriptor[idx_cfg][idx_iad],
+ sizeof(usbc_interface_association_descriptor_t));
+ config_index += sizeof(usbc_interface_association_descriptor_t);
+ }
+
+ /* Interface */
+ kal_mem_cpy(conf + config_index,
+ &usbc_p->if_info[idx_cfg][idx_if].ifdscr.stdif,
+ usbc_p->if_info[idx_cfg][idx_if].ifdscr_size);
+ config_index += usbc_p->if_info[idx_cfg][idx_if].ifdscr_size;
+
+ /* Endpoints */
+ for (idx_ep = 0; idx_ep < usbc_p->if_info[idx_cfg][idx_if].ifdscr.stdif.bNumEndpoints; idx_ep ++)
+ {
+ kal_mem_cpy(conf + config_index,
+ &usbc_p->if_info[idx_cfg][idx_if].ep_info[idx_ep]->epdscr.stdep,
+ usbc_p->if_info[idx_cfg][idx_if].ep_info[idx_ep]->epdscr_size);
+ config_index += usbc_p->if_info[idx_cfg][idx_if].ep_info[idx_ep]->epdscr_size;
+ }
+
+ /* alternate setting */
+ if (usbc_p->if_info[idx_cfg][idx_if].altn_surpport)
+ {
+ kal_mem_cpy(conf + config_index,
+ &usbc_p->if_info[idx_cfg][idx_if].altn_if_info.ifdscr.stdif,
+ usbc_p->if_info[idx_cfg][idx_if].altn_if_info.ifdscr_size);
+ config_index += usbc_p->if_info[idx_cfg][idx_if].altn_if_info.ifdscr_size;
+ for (idx_ep = 0; idx_ep < usbc_p->if_info[idx_cfg][idx_if].altn_if_info.ifdscr.stdif.bNumEndpoints; idx_ep ++)
+ {
+ kal_mem_cpy(conf + config_index,
+ &usbc_p->if_info[idx_cfg][idx_if].altn_if_info.ep_info[idx_ep]->epdscr.stdep,
+ usbc_p->if_info[idx_cfg][idx_if].altn_if_info.ep_info[idx_ep]->epdscr_size);
+ config_index += usbc_p->if_info[idx_cfg][idx_if].altn_if_info.ep_info[idx_ep]->epdscr_size;
+ }
+ }
+ }
+
+ ASSERT(config_index <= USBC_MAX_CONF_SIZE);
+
+ /* Fill in some members of configuration descriptor */
+ config_desc_p = (usbc_configuration_descriptor_t*)conf;
+ config_desc_p->wTotalLength = config_index;
+ config_desc_p->bNumInterfaces = usbc_p->resource_interface_number[idx_cfg];
+ config_desc_p->bConfigurationValue = INDEX_TO_CFG(idx_cfg); // configuration value must start with 1
+
+ // update remote wakeup attribute in configuration descriptor by qeuring each class in this config
+ cfg_param = &usbc_p->dev_param->mode_param[usbc_p->mode].cfg_param[idx_cfg];
+ for (idx_class = 0; idx_class < cfg_param->class_num; idx_class++)
+ {
+ class_query = usbc_get_class_query_func_wk_capability_func(cfg_param->class_type[idx_class]);
+ if ( class_query &&
+ (class_query() & 0x0001) )
+ {
+ config_desc_p->bmAttributes |= 0x20;
+ break;
+ }
+ }
+ }
+
+}
+
+void usbc_set_ep_owner(kal_uint8 cfg, kal_uint8 class_device_id, kal_uint8 owner)
+{
+ kal_uint32 idx_ep;
+ usbc_core_t *usbc_inst;
+
+ usbc_inst = usbc_core_get_instance();
+ for(idx_ep = 0; idx_ep < (usbc_inst->resource_ep_tx_number[cfg]); idx_ep++){
+ if(usbc_inst->ep_tx_info[cfg][idx_ep].queue_info.class_device_id == class_device_id){
+ usbc_inst->ep_tx_info[cfg][idx_ep].queue_info.owner = owner;
+ }
+ }
+ for(idx_ep = 0; idx_ep < (usbc_inst->resource_ep_rx_number[cfg]); idx_ep++){
+ if(usbc_inst->ep_rx_info[cfg][idx_ep].queue_info.class_device_id == class_device_id){
+ usbc_inst->ep_rx_info[cfg][idx_ep].queue_info.owner = owner;
+ }
+ }
+ return ;
+}
+
+kal_bool usbc_get_boot_factory_mode()
+{
+ kal_bool factory_mode = KAL_FALSE;
+
+ /*if project do not support factory mode, return FALSE*/
+ if(!usb_get_factory_mode_support())
+ return KAL_FALSE;
+
+#ifdef __HIF_CCCI_SUPPORT__
+ /*get factory mode*/
+ CCCI_RUNTIME_BOOT_INFO_FORMAT_T boot_info;
+ CCCI_RUNTIME_FEATURE_SUPPORT_T feature_support;
+
+ feature_support = ccci_runtime_data_query(AP_CCCI_RUNTIME_BOOT_INFO, &boot_info, sizeof(CCCI_RUNTIME_BOOT_INFO_FORMAT_T));
+ if(feature_support.support_mask != CCCI_RUNTIME_FEATURE_MUST_SUPPORT)
+ EXT_ASSERT(0, USBCORE_LOC_CCCI_NO_SUPPORT_RUNTIME_FEATURE, (kal_uint32)feature_support.support_mask, (kal_uint32)boot_info.BootingStartID);
+ usbc_trace_warn(USBCORE_FACTORY_MODE_INFO, boot_info.BootingStartID);
+
+ if(CCCI_META_BOOT == (boot_info.BootingStartID & 0x000000FF))
+ {
+ factory_mode = KAL_TRUE;
+ usbc_set_op_mode(USBC_OP_MODE_FACTORY);
+ }
+#endif
+
+ return factory_mode;
+}
+
+kal_bool usbc_core_get_mode_from_nvram()
+{
+ kal_uint8 *pBuffer = NULL;
+ kal_uint16 record, size;
+ kal_uint8 owner = 0;
+ kal_uint8 index = 0;
+ usbc_core_t *usbc_inst = usbc_core_get_instance();
+ kal_uint8 mode_idx;
+ kal_bool ret = KAL_FALSE;
+
+ /* check for valid ID for NVRAM */
+ if( NVRAM_ERRNO_SUCCESS != nvram_get_info(NVRAM_EF_USB_MODE_LID, &record, &size) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_MODE_LID_INFO_FOR_ENUM_FAIL, (kal_uint32)NVRAM_EF_USB_MODE_LID, 0);
+ return 0;
+ }
+ pBuffer = (kal_uint8*)get_ctrl_buffer(size * record);
+
+ if ( nvram_external_read_data(NVRAM_EF_USB_MODE_LID, 1, pBuffer, (kal_uint32)size) )
+ {
+ owner = *((kal_uint8*)pBuffer);
+ index = *((kal_uint8*)(pBuffer + sizeof(kal_uint8)));
+
+ for(mode_idx = 0; mode_idx < usb_mode_register_index; mode_idx++)
+ {
+
+ if(usbc_inst->dev_param->mode_param[mode_idx].mode_owner == owner && usbc_inst->dev_param->mode_param[mode_idx].mode_index == index)
+ {
+ usbc_inst->mode = mode_idx;
+ break;
+ }
+ }
+ if(mode_idx >= usb_mode_register_index)
+ {
+ /*mode or index invalid*/
+ usbc_inst->mode = 0;
+ }
+ else
+ ret = KAL_TRUE;
+ }
+ else
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_MODE_LID_VALUE_FAIL, (kal_uint32)NVRAM_EF_USB_MODE_LID, (kal_uint32)size);
+ }
+
+ free_ctrl_buffer(pBuffer);
+ usbc_trace_info(USBCORE_MODE_NVRAM_SELECT, owner, index, usbc_inst->mode, ret);
+ return ret;
+}
+
+usb_network_class_type_e usbc_get_network_type()
+{
+ usbc_core_t *usbc_inst = usbc_core_get_instance();
+ usb_mode_e mode = usbc_inst->mode;
+ kal_int8 idx_cfg, idx_class;
+ usb_cfg_param_t *cfg_param;
+ kal_uint8 cfg_num = usbc_inst->dev_param->mode_param[mode].cfg_num;
+ usb_network_class_type_e net_type = USB_NETWORK_CLASS_RNDIS;
+ for (idx_cfg = 0; idx_cfg < cfg_num; idx_cfg++)
+ {
+ cfg_param = &usbc_inst->dev_param->mode_param[mode].cfg_param[idx_cfg];
+ for(idx_class = 0; idx_class < cfg_param->class_num; idx_class++)
+ {
+#ifdef __USB_RNDIS_SUPPORT__
+ if(cfg_param->class_type[idx_class] == USB_CLASS_RNDIS)
+ net_type = USB_NETWORK_CLASS_RNDIS;
+#endif
+#ifdef __USB_MBIM_SUPPORT__
+ if(cfg_param->class_type[idx_class] == USB_CLASS_MBIM)
+ net_type = USB_NETWORK_CLASS_MBIM;
+#endif
+#ifdef __USB_ECM_SUPPORT__
+ if(cfg_param->class_type[idx_class] == USB_CLASS_ECM)
+ net_type = USB_NETWORK_CLASS_ECM;
+#endif
+ }
+ }
+
+ usbc_trace_warn(USBCORE_GET_NETWORK_TYPE, net_type);
+ return net_type;
+}
+
+
+void usbc_core_modify_custom_port()
+{
+ usbc_core_t *usbc_inst = usbc_core_get_instance();
+ usbc_op_mode_e op_mode = usbc_get_op_mode();
+ usb_mode_e mode = usbc_inst->mode;
+ kal_int8 idx_cfg, idx_class;
+ usb_cfg_param_t *cfg_param;
+ usb_cfg_param_t temp_param = {0};
+ kal_uint8 cfg_num = usbc_inst->dev_param->mode_param[mode].cfg_num;
+
+ usbc_inst = usbc_core_get_instance();
+
+ if(op_mode == USBC_OP_MODE_NORMAL)
+ return;
+ else if(op_mode == USBC_OP_MODE_UNUSED)
+ {
+ ASSERT(0);
+ return;
+ }
+ else if(op_mode == USBC_OP_MODE_METADEBUG)
+ {
+ usb_mode_replace_metadbg_mode(mode);
+ return ;
+ }
+
+ for (idx_cfg = 0; idx_cfg < cfg_num; idx_cfg++)
+ {
+ kal_mem_set(&temp_param, 0, sizeof(usb_cfg_param_t));
+ cfg_param = &usbc_inst->dev_param->mode_param[mode].cfg_param[idx_cfg];
+ for(idx_class = 0; idx_class < cfg_param->class_num; idx_class++)
+ {
+ if((op_mode == USBC_OP_MODE_MDONLY) && (cfg_param->class_owner[idx_class] == USB_CLASS_OWNER_AP))
+ {
+ continue;
+ }
+ else if((op_mode == USBC_OP_MODE_NOLOGGING) && (cfg_param->class_ctxt[idx_class] == (void*)uart_port_usb2))
+ {
+ continue;
+ }
+
+ temp_param.class_type[temp_param.class_num] = cfg_param->class_type[idx_class];
+ temp_param.class_ctxt[temp_param.class_num] = cfg_param->class_ctxt[idx_class];
+ temp_param.bulk_fifo_n[temp_param.class_num] = cfg_param->bulk_fifo_n[idx_class];
+ temp_param.class_owner[temp_param.class_num] = cfg_param->class_owner[idx_class];
+ temp_param.class_num++;
+ }
+ kal_mem_cpy(cfg_param, &temp_param, sizeof(usb_cfg_param_t));
+ }
+ return;
+}
+
+/*
+ usbcore: usbc_stack_checkin(USB_CLASS_NUM, NULL);
+ usbclass: ex. usbc_stack_checkin(USB_CLASS_ACM1, XXX);
+ */
+void usbc_stack_checkin(usb_class_type_e class_type, usbc_node_reg_entry_t *reg_table)
+{
+ usbc_class_init_func_t class_init;
+ kal_uint32 idx_cfg, idx_class;
+ kal_uint32 cfg_num;
+ usb_cfg_param_t *cfg_param;
+ usbc_device_descriptor_t *dev_desc;
+ usbc_device_qualifier_descriptor_t *dev_qual_desc;
+ usbc_configuration_descriptor_t *config_desc_p;
+ usbc_core_t *usbc_inst;
+
+ _CHECKIN_NODE(class_type, reg_table);
+
+ if (_ALL_NODES_CHECKIN())
+ {
+ usbc_trace_info(USBCORE_ALL_NODE_CHECKIN);
+
+ usbc_inst = usbc_core_get_instance();
+
+ /* 1. hif init */
+ #ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+ usbc_direct_hif_factory();
+ usbc_direct_hif_init();
+ #else
+ usbc_normal_hif_init();
+ #endif
+ ubm_init(); // UBM init
+
+ // Check for META mode
+ usbc_inst->is_mode_meta = usbc_inst->is_mode_meta_reused = KAL_FALSE;
+
+ /* 2. Reset usbcore resources/structures */
+ usbc_resource_reset();
+ usbc_core_clear_register();
+ usbc_core_clear_status();
+
+ /*
+ 3. Select a mode for MD USB enumeration.
+ */
+ usbc_inst->dev_param = (usb_dev_param_t*)usb_get_custom_func()->get_device_param_func();
+
+ /*Get whether current boot is factory mode*/
+ if(usbc_get_boot_factory_mode())
+ {
+ usb_mode_factory_register();
+ usbc_inst->mode = 0;
+ }
+
+ if(usbc_get_op_mode() != USBC_OP_MODE_FACTORY)
+ {
+#ifdef __USB_PORT_CUSTOMIZATION__
+ /*Register customized mode and set a mode which is read from NVRAM*/
+ usb_mode_customization_register();
+ usbc_core_get_mode_from_nvram();
+#else
+ /*Register all normal mode*/
+ usb_mode_base_register();
+ usb_mode_ufpm_register();
+ usb_mode_inusj_register();
+ usb_mode_qeznk_register();
+
+ #if defined (BTT_STANDALONE_MODE)
+ usbc_inst->mode = USB_MODE_BTT_STANDALONE;
+ #elif defined(__MODIS_USB_TAP_ACCESS__)
+ usbc_inst->mode = USB_MODE_1R3C;
+ #elif defined(__MTK_MD_DIRECT_USB_SUPPORT__)
+ usbc_inst->mode = USB_MODE_UFPM;
+ #elif defined(__DUMMY_L1_ON_TARGET_4G5G__)
+ usbc_inst->mode = USBMODE_KS_IODT_1R3C_ENUM;
+ #else
+ usbc_inst->mode = USB_MODE_DEFAULT;
+ #endif
+
+ usbc_trace_info(USBCORE_MODE_DEFAULT_CFG_SELECT, usbc_inst->mode);
+#endif
+ /*Change port for DUALIPC*/
+ usbc_core_modify_custom_port();
+ usbc_core_check_mass_strorage_onoff();
+ }
+ cfg_num = usbc_inst->dev_param->mode_param[usbc_inst->mode].cfg_num;
+ usbc_core_check_low_power_enable();
+
+ /* 4. Set device_descriptor */
+ dev_desc = (usbc_device_descriptor_t *)usbc_inst->descriptors.device;
+ kal_mem_cpy(dev_desc, &usbc_default_device_descriptor, USBC_DEVICE_DESC_SIZE);
+ dev_desc->bDeviceClass = usbc_inst->dev_param->mode_param[usbc_inst->mode].device_class;
+ dev_desc->bDeviceSubClass = usbc_inst->dev_param->mode_param[usbc_inst->mode].device_sub_class;
+ dev_desc->bDeviceProtocol = usbc_inst->dev_param->mode_param[usbc_inst->mode].device_protocol;
+ dev_desc->idVendor = usbc_inst->dev_param->mode_param[usbc_inst->mode].vendor_id;
+ dev_desc->idProduct = usbc_inst->dev_param->mode_param[usbc_inst->mode].product_id;
+ dev_desc->bcdDevice = usbc_inst->dev_param->bcd_device;
+ dev_desc->bNumConfigurations = usbc_inst->dev_param->mode_param[usbc_inst->mode].cfg_num;
+
+ dev_qual_desc = &usbc_inst->device_qualifier_descriptor;
+ dev_qual_desc->bLength = 0x0A;
+ dev_qual_desc->bDescriptorType = USBC_DT_DEVICE_QUALIFIER;
+ dev_qual_desc->bcdUSB = dev_desc->bcdUSB;
+ dev_qual_desc->bDeviceClass = dev_desc->bDeviceClass;
+ dev_qual_desc->bDeviceSubClass = dev_desc->bDeviceSubClass;
+ dev_qual_desc->bDeviceProtocol = dev_desc->bDeviceProtocol;
+ dev_qual_desc->bMaxPacketSize0 = dev_desc->bMaxPacketSize0;
+ dev_qual_desc->bNumConfigurations = dev_desc->bNumConfigurations;
+
+ /* 5. Store device string - language/manufacturere/product/serialnum */
+ usbc_get_string_number((void*)usb_language_string);
+ dev_desc->iManufacturer = usbc_get_string_number((void*)usbc_inst->dev_param->manufacture_string);
+ dev_desc->iProduct = usbc_get_string_number((void*)usbc_inst->dev_param->product_string);
+ // Update serial number by reading the IMEI from NVRAM
+#ifdef __PRODUCTION_RELEASE__
+ dev_desc->iSerialNumber = usbc_core_set_serial_number()? usbc_get_string_number((void*)usbc_inst->dev_param->serial_number):0x00;
+#else
+/* under construction !*/
+#endif
+
+ /* 6. Call init function of each usb class for all configurations */
+ for (idx_cfg = 0; idx_cfg < cfg_num; idx_cfg++)
+ {
+ cfg_param = &usbc_inst->dev_param->mode_param[usbc_inst->mode].cfg_param[idx_cfg];
+ for (idx_class = 0; idx_class < cfg_param->class_num; idx_class++)
+ {
+ class_init = _get_class_init_func(cfg_param->class_type[idx_class]);
+ if (class_init) {
+ usbc_trace_info(USBCORE_ALL_NODE_CHECKIN_INIT_CLASS_START, cfg_param->class_type[idx_class]);
+ class_init( idx_class,
+ usbc_inst->mode,
+ idx_cfg,
+ cfg_param->class_ctxt[idx_class],
+ cfg_param->bulk_fifo_n[idx_class]);
+ usbc_trace_info(USBCORE_ALL_NODE_CHECKIN_INIT_CLASS_END, cfg_param->class_type[idx_class]);
+ /* Set EP owner*/
+ usbc_set_ep_owner(idx_cfg, idx_class, cfg_param->class_owner[idx_class]);
+ } else {
+ EXT_ASSERT(KAL_FALSE, 1, 0, 0);
+ }
+ }
+ }
+
+
+ if( !usbc_inst->is_mode_meta_reused )
+ {
+ /* 7. Construct configuration descriptor */
+ _usbc_construct_config_descriptor(usbc_inst);
+
+ #ifndef __MTK_MD_DIRECT_USB_SUPPORT__
+ /* 8. Set hif configuration, and connect to hif later in task main */
+ usbc_normal_hif_disconnect();
+ usbc_core_set_hif_configuration();
+ #else
+ /* Init UFPM global variables */
+ ufpm_init();
+ #endif
+ }
+ else
+ {
+ /* 7. Construct configuration descriptor */
+ usbc_inst->resource_iad_number[0] = 0; // Discard IAD if it is in META mode
+ _usbc_construct_config_descriptor(usbc_inst); // construct configuration descriptor
+
+ /* 8. Update descriptors for META */
+ dev_desc->iSerialNumber = 0x00; // no serial number in BootROM/pre-loader's COM
+ config_desc_p = (usbc_configuration_descriptor_t*)usbc_inst->descriptors.configuration[0]; // only one configuration in META mode
+ config_desc_p->bmAttributes &= 0xdf; // the remote wakeup is not capable in BootROM/Pre-loader COM
+ config_desc_p->bMaxPower = 0xc8; // the max power of BootROM/Preloader COM's confiuration is 400mA
+ usbc_inst->u3ConfMaxPower = (U3_CONF_BMAXPOWER_META / USBC_USB30_POWER_DESC_UINT); // the max power is 400mA in USB 3.0
+
+ /* 9. Enqueue and prepare for fake enumeration */
+ usbc_meta_hif_factory(); // set function pointers of USB driver to META state
+ usbc_core_set_hif_configuration();
+ usbc_normal_hif_meta_attach();
+ }
+ }
+}
+
+void usbc_reinit_class(void)
+{
+ kal_uint32 idx;
+ usbc_class_reinit_func_t class_reinit;
+
+ for (idx = 0; idx < USB_CLASS_NUM; idx++) {
+ class_reinit = _get_class_reinit_func(idx);
+ if (class_reinit) {
+ usbc_trace_info(USBCORE_ALL_NODE_CHECKIN_REINIT_CLASS_START, idx);
+ class_reinit(KAL_FALSE);
+ usbc_trace_info(USBCORE_ALL_NODE_CHECKIN_REINIT_CLASS_END, idx);
+ } else {
+ //EXT_ASSERT(KAL_FALSE, 2, 0, 0);
+ continue;
+ }
+ }
+}
+
+void usbc_mode_switch(usb_mode_e mode){
+ kal_uint32 idx;
+ usbc_core_t* usbc_inst = usbc_core_get_instance();
+ usbc_class_reinit_func_t class_reinit;
+ usbc_ind_t ind_to_enqueue; // Do mode switch immediately if it is not in HISR, or enqueue a mode switch event for USBCORE task
+ if (!kal_if_hisr()) {
+#if 1
+ if (mode == USB_MODE_MSD_OSDRTY){
+ /* wait 3 second for OSD known issue */
+ kal_sleep_task(600);
+ }
+#endif
+ /* 1. set disconnect */
+ hifusb_set_disconnect();
+ usbc_empty_ind_queue();
+
+ /* 2. Set switch mode */
+ usbc_inst->is_mode_switch = KAL_TRUE;
+ usbc_inst->mode = mode;
+
+ /* 3. Send re-init callback to all usb class */
+ _SET_NODE_VALUE(0);
+ usbc_stack_checkin(USB_CLASS_NUM, NULL);
+ for (idx = 0; idx < USB_CLASS_NUM; idx++) {
+ class_reinit = _get_class_reinit_func(idx);
+ _SET_NODE_REG_TABLE(idx, NULL);
+ if (class_reinit) {
+ usbc_trace_info(USBCORE_ALL_NODE_CHECKIN_REINIT_CLASS_START, idx);
+ class_reinit(KAL_TRUE);
+ usbc_trace_info(USBCORE_ALL_NODE_CHECKIN_REINIT_CLASS_END, idx);
+ } else {
+ EXT_ASSERT(KAL_FALSE, 2, 0, 0);
+ }
+ }
+ } else {
+ ind_to_enqueue.type = USBC_IND_MODE_SWITCH;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)mode;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ }
+}
+
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_stdreq.c b/mcu/middleware/hif/usbcore/src/usbcore_stdreq.c
new file mode 100644
index 0000000..b7046ae
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_stdreq.c
@@ -0,0 +1,1305 @@
+/*!
+ * @file usbcore_usbstd.c
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides usb standard request handler function
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_usbstd.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#include "usbcore_ind_q.h"
+#include "usbcore_debug.h"
+#ifdef __USB_OSD_SUPPORT__
+#include "usbosd.h"
+#endif /* __USB_OSD_SUPPORT__ */
+
+#ifdef ATEST_SYS_USBCORE
+#include "usbcore_ut.h"
+#endif
+
+#define _USB30_DEVICE_REMOTE_WK_SUPPORT_ 1
+
+static kal_uint8 usbc_bos_s[USBC_MAX_BOS_SIZE] = {
+ /*BOS standard descriptor*/
+ 0x05, /*bLength*/
+ 0x0F, /*bDescriptorType*/
+ 0x16, 0x00, //0x0016, /*wTotalLength*/
+ 0x02, /*bNumDeviceCaps*/
+
+ /*USB2.0 Extension Device Capability Descriptor*/
+ 0x07, /*bLength*/
+ 0x10, /*bDescriptorType*/
+ 0x02, /*bDevCapabilityType*/
+ /*Link Power Management : YES*/
+ 0x02, 0x00, 0x00, 0x00, //0x00000002 /*bmAttributes*/
+
+ /*SuperSpeed Device Capability Descriptor*/
+ 0x0A, /*bLength*/
+ 0x10, /*bDescritorType*/
+ 0x03, /*bDevCapabilityType*/
+ 0x00, /*bmAttributes*/
+ /*bit-map : support FS/HS/5Gbs*/
+ 0x0E, 0x00, //0x000E, /*wSpeedsSupport*/ /* 3: 5Gbps, 2: high 1: full, 0: low */
+ 0x01, /*bFunctionalitySupport*/ /* lowest speed supported */
+ 0x0A, /*bU1DevExitLat*/ /* Less than 0x0a us */
+ 0x20, 0x00 //0x0020, /*bU2DevExitLat*/ /* Less than 0x20 us */
+};
+
+/*
+ * Define Microsoft OS string descriptor
+ */
+#define USBC_MS_OS_STRING_INDEX 0xEE
+#define USBC_MAX_OS_STRING_LENGTH 18
+static const kal_uint16 usbc_os_string[] = {'M', 'S', 'F', 'T', '1', '0', '0'};
+static usbc_os_string_descriptor_t usbc_os_string_desc;
+static kal_uint8 pOtherSpeedDescript[256];
+
+static kal_bool usbc_core_handle_set_address()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+
+ usbc_core_printf("=========>usbcore_handle_set_address\r\n");
+ usbc_trace_info(USBCORE_SET_ADDRESS, (wValue & 0x7f));
+
+ usbc_core_set_usb_address(wValue & 0x7f);
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+}
+
+
+static kal_bool usbc_core_handle_get_status()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK;
+ //kal_uint16 wIndex = pUsbCore->setup_packet.wIndex;
+ kal_uint8* pBuffer = pUsbCore->control_request_buffer;
+ kal_uint32 length = 0;
+
+ usbc_core_printf("=========>usbcore_handle_get_status\r\n");
+ usbc_trace_info(USBCORE_GET_STATUS, bRecip);
+
+ if ( bRecip == USBC_REQUEST_RECIP_DEVICE )
+ {
+ kal_uint8 i;
+
+ /* D0: Self Powered, D1: Remote Wakeup */
+ pBuffer[0] = 0; //Bus Power
+ pBuffer[1] = 0; //No Remote Wakeup
+ length = 2;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+
+ // report remote wakeup status in USB 1.1 and USB 2.0 (0 in USB 3.0)
+ if( pUsbCore->speed != USBC_USB_SPEED_USB30 )
+ {
+ for( i=0; i<pUsbCore->total_class_devices; i++)
+ {
+ if ( NULL != pUsbCore->class_device[i].query_func_wk_status &&
+ pUsbCore->class_device[i].query_func_wk_status(i) & 0x0002 )
+ {
+ pBuffer[0] |= ((kal_uint8)0x01 << 1);
+ break;
+ }
+ }
+ }
+ else
+ {
+ // USB 3.0 U1 enable status (0 in USB 2.0)
+ if ( pUsbCore->is_device_u1_enable )
+ {
+ pBuffer[0] |= ((kal_uint8)0x01 << 2);
+ }
+
+ // USB 3.0 U2 enable status ( 0 in USB 3.0)
+ if( pUsbCore->is_device_u2_enable )
+ {
+ pBuffer[0] |= ((kal_uint8)0x01 << 3);
+ }
+
+ // USB 3.0 LTM enable status ( 0 in USB 3.0)
+ if( pUsbCore->is_device_ltm_enable )
+ {
+ pBuffer[0] |= ((kal_uint8)0x01 << 4);
+ }
+ }
+
+ } else
+ if ( bRecip == USBC_REQUEST_RECIP_INTERFACE )
+ {
+ kal_uint8 nInterface = (kal_uint8)pUsbCore->setup_packet.wIndex;
+ kal_uint8 class_device_id = pUsbCore->class_interface[nInterface].class_device_id;
+
+ /* return two bytes of 0x00, 0x00.
+ Both bytes are reserved for future use
+ */
+ pBuffer[0] = 0;
+ pBuffer[1] = 0;
+ length = 2;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 &&
+ usbc_core_is_1st_interface(nInterface) &&
+ NULL != pUsbCore->class_device[class_device_id].query_func_wk_status )
+ {
+ /* if the requested interface is the first one of a function,
+ report the function remote wakeup capability and state
+ */
+ pBuffer[0] = pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id) & ((kal_uint8)0xFF);
+ }
+
+ } else
+ if ( bRecip == USBC_REQUEST_RECIP_ENDPOINT )
+ {
+ /* D0: HALT, D1: Reserve */
+ kal_uint8 nEnd = pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_NUM_MASK; /* TODO: It's error-prone to use en_no instead of endpoint address. */
+ usbc_core_queue_t* pQueue = NULL;
+ kal_uint8 i = 0;
+
+ if ( (pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_DIR_IN) )
+ {
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->tx_queue[i].ep_no == nEnd) &&
+ (pUsbCore->tx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
+ {
+ pQueue = &pUsbCore->tx_queue[i];
+ break;
+ }
+ }
+ } else {
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->rx_queue[i].ep_no == nEnd) &&
+ (pUsbCore->rx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
+ {
+ pQueue = &pUsbCore->rx_queue[i];
+ break;
+ }
+ }
+ }
+
+ /* D0: HALT, D1: Reserve */
+ if ( pQueue == NULL )
+ {
+ length = 0;
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+
+ if( nEnd == 0)
+ {
+ pBuffer[0] = 0;
+ pBuffer[1] = 0;
+ length = 2;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ }
+
+ } else {
+ switch (pQueue->state)
+ {
+ case USBC_CORE_QUEUE_STATE_ACTIVE:
+ {
+ pBuffer[0] = 0;
+ pBuffer[1] = 0;
+ length = 2;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ break;
+ }
+ case USBC_CORE_QUEUE_STATE_STALL:
+ {
+ pBuffer[0] = 1;
+ pBuffer[1] = 0;
+ length = 2;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ break;
+ }
+ default:
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_STATUS_EP_STATUS_INVALID, (kal_uint32)pQueue->state, (kal_uint32)nEnd);
+ length = 0;
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ break;
+ }
+ }
+ }
+ } else {
+ EXT_ASSERT(0, USBCORE_LOC_GET_STATUS_INVALID_RECIP, (kal_uint32)bRecip, 0);
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+
+ usbc_core_set_control_request(pBuffer, length, type);
+ return KAL_TRUE;
+}
+
+
+static kal_bool usbc_core_handle_set_feature()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK;
+ kal_uint16 wIndex = pUsbCore->setup_packet.wIndex;
+ kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+ kal_bool is_tx = KAL_TRUE;
+
+ usbc_core_printf("=========>usbcore_handle_set_feature\r\n");
+ usbc_trace_info(USBCORE_SET_FEATURE, bRecip, wIndex, wValue);
+
+ if ( bRecip == USBC_REQUEST_RECIP_DEVICE )
+ {
+ usbc_ind_t ind_to_enqueue;
+ usbc_func_state_e state;
+
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ if ( pUsbCore->state <= USBC_USB_STATE_ATTACHING )
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ } else
+ if ( wValue == USBC_FEATURE_U1_ENABLE )
+ {
+ pUsbCore->is_device_u1_enable = KAL_TRUE;
+ usbc_core_set_ss_dev_init_u1_en(KAL_TRUE);
+ type = USBC_CONTROL_REQUEST_TYPE_RECEIVE;
+ } else
+ if ( wValue == USBC_FEATURE_U2_ENABLE )
+ {
+ pUsbCore->is_device_u2_enable = KAL_TRUE;
+ usbc_core_set_ss_dev_init_u2_en(KAL_TRUE);
+ type = USBC_CONTROL_REQUEST_TYPE_RECEIVE;
+ } else
+ if ( wValue == USBC_FEATURE_LTM_ENABLE )
+ {
+ pUsbCore->is_device_ltm_enable = KAL_TRUE;
+ // TODO: set LTM enabled if support
+ type = USBC_CONTROL_REQUEST_TYPE_RECEIVE;
+ }
+#if _USB30_DEVICE_REMOTE_WK_SUPPORT_
+ else if ( wValue == USBC_FEATURE_DEVICE_REMOTE_WAKEUP )
+ {
+ // enable function remote wakeup for capable functions in enabling device remote wakeup
+ state = USBC_FUNC_WK_ENABLE;
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ }
+
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+#endif
+ else
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+ }
+ else
+ {
+ if ( wValue == USBC_FEATURE_DEVICE_REMOTE_WAKEUP )
+ {
+ // enable function remote wakeup for capable functions in enabling device remote wakeup
+ state = USBC_FUNC_WK_ENABLE;
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ }
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ } else
+ if ( wValue == USBC_FEATURE_TEST_MODE )
+ {
+ usbc_core_set_usb_testmode((hifusb_test_mode_e)(wIndex >> 8));
+ type = USBC_CONTROL_REQUEST_TYPE_RECEIVE;
+ }
+ else
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+ }
+
+ } else
+ if ( bRecip == USBC_REQUEST_RECIP_INTERFACE )
+ {
+ kal_uint8 nInterface = (kal_uint8)wIndex & 0xFF;
+ kal_uint8 suspendOpt = wIndex >> 8;
+ usbc_ind_t ind_to_enqueue;
+ kal_uint8 class_device_id = pUsbCore->class_interface[nInterface].class_device_id;
+ usbc_func_state_e state;
+
+ //specifies no interface features
+ type = USBC_CONTROL_REQUEST_TYPE_RECEIVE;
+
+ if( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ if ( pUsbCore->state > USBC_USB_STATE_ATTACHING &&
+ wValue == USBC_FEATURE_FUNCTION_SUSPEND &&
+ usbc_core_is_1st_interface(nInterface) )
+ {
+ if ( suspendOpt & 0x02 )
+ {
+ state = (suspendOpt & 0x01)? USBC_FUNC_WK_ENABLE_STATE_SUSPENDING:USBC_FUNC_WK_ENABLE_STATE_RESUME;
+ }
+ else
+ {
+ state = (suspendOpt & 0x01)? USBC_FUNC_WK_DISABLE_STATE_SUSPENDING:USBC_FUNC_WK_DISABLE_STATE_RESUME;
+ }
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = class_device_id;
+ ind_to_enqueue.data = (kal_uint8)state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ // Wake up USBCORE task to process indications.
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ }
+ }
+ else
+ {
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = class_device_id;
+ ind_to_enqueue.data = (kal_uint8)USBC_FUNC_SET_FEATURE_ERROR;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ // Wake up USBCORE task to process indications.
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_STALL);
+ return KAL_TRUE;
+ }
+ }
+ // Return USB 3.0 SetFeature of interfaces here, because the state is reported after finishing indications.
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+
+ } else
+ if ( bRecip == USBC_REQUEST_RECIP_ENDPOINT )
+ {
+ kal_uint8 nEnd = pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_NUM_MASK; /* TODO: It's error-prone to use en_no instead of endpoint address. */
+ usbc_core_queue_t* pQueue = NULL;
+ kal_uint8 i = 0;
+
+ if ( (pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_DIR_IN) )
+ {
+ is_tx = KAL_TRUE;
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->tx_queue[i].ep_no == nEnd) &&
+ (pUsbCore->tx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
+ {
+ pQueue = &pUsbCore->tx_queue[i];
+ break;
+ }
+ }
+ } else {
+ is_tx = KAL_FALSE;
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->rx_queue[i].ep_no == nEnd) &&
+ (pUsbCore->rx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
+ {
+ pQueue = &pUsbCore->rx_queue[i];
+ break;
+ }
+ }
+ }
+
+ if ( pQueue == NULL )
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ } else {
+ /* notify class driver that this queue is set stall, class has to set EP stall to driver */
+ usbc_core_indicate_stall(is_tx, i, KAL_TRUE);
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ pQueue->state = USBC_CORE_QUEUE_STATE_STALL;
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ }
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+ } else {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+
+ usbc_core_set_control_request(NULL, 0, type);
+ return KAL_TRUE;
+}
+
+
+static kal_bool usbc_core_handle_clear_feature()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK;
+ kal_uint16 wIndex = pUsbCore->setup_packet.wIndex;
+ kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+ kal_bool is_tx = KAL_TRUE;
+
+ usbc_core_printf("=========>usbcore_handle_clear_feature\r\n");
+ usbc_trace_info(USBCORE_CLEAR_FEATURE, bRecip, wIndex, wValue);
+
+ if ( bRecip == USBC_REQUEST_RECIP_DEVICE )
+ {
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_RECEIVE;
+
+ if ( wValue == USBC_FEATURE_U1_ENABLE )
+ {
+ pUsbCore->is_device_u1_enable = KAL_FALSE;
+ usbc_core_set_ss_dev_init_u1_en(KAL_FALSE);
+ } else
+ if ( wValue == USBC_FEATURE_U2_ENABLE )
+ {
+ pUsbCore->is_device_u2_enable = KAL_FALSE;
+ usbc_core_set_ss_dev_init_u2_en(KAL_FALSE);
+ } else
+ if ( wValue == USBC_FEATURE_LTM_ENABLE )
+ {
+ pUsbCore->is_device_ltm_enable = KAL_FALSE;
+ //TODO: clear LTM capability if support
+ }
+#if _USB30_DEVICE_REMOTE_WK_SUPPORT_
+ else if ( wValue == USBC_FEATURE_DEVICE_REMOTE_WAKEUP )
+ {
+ usbc_func_state_e state;
+ usbc_ind_t ind_to_enqueue;
+
+ // disable function remote wakeup for capable functions while disabling device remote wakeup
+ state = USBC_FUNC_WK_DISABLE;
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ }
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+#endif
+ else {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+ }
+ else
+ {
+ if ( wValue == USBC_FEATURE_DEVICE_REMOTE_WAKEUP )
+ {
+ usbc_func_state_e state;
+ usbc_ind_t ind_to_enqueue;
+
+ // disable function remote wakeup for capable functions while disabling device remote wakeup
+ state = USBC_FUNC_WK_DISABLE;
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ }
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+ else {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+ }
+
+ } else
+ if ( bRecip == USBC_REQUEST_RECIP_INTERFACE )
+ {
+ kal_uint8 nInterface = (kal_uint8)pUsbCore->setup_packet.wIndex;
+ usbc_ind_t ind_to_enqueue;
+ kal_uint8 class_device_id = pUsbCore->class_interface[nInterface].class_device_id;
+ usbc_func_state_e state;
+
+ //specifies no interface features
+ type = USBC_CONTROL_REQUEST_TYPE_RECEIVE;
+
+ if( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ if ( wValue == USBC_FEATURE_FUNCTION_SUSPEND && usbc_core_is_1st_interface(nInterface) )
+ {
+ state = USBC_FUNC_WK_DISABLE_STATE_RESUME;
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = class_device_id;
+ ind_to_enqueue.data = (kal_uint8)state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ // Wake up USBCORE task to process indications.
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ }
+ }
+ else
+ {
+ ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
+ ind_to_enqueue.ext = class_device_id;
+ ind_to_enqueue.data = (kal_uint8)USBC_FUNC_SET_FEATURE_ERROR;
+ usbc_enqueue_ind(&ind_to_enqueue);
+
+ // Wake up USBCORE task to process indications.
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_STALL);
+ return KAL_TRUE;
+ }
+ }
+ // Return USB 3.0 SetFeature of interfaces here, because the state is reported after finishing indications.
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+
+ } else
+ if ( bRecip == USBC_REQUEST_RECIP_ENDPOINT )
+ {
+ kal_uint8 nEnd = pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_NUM_MASK; /* TODO: It's error-prone to use en_no instead of endpoint address. */
+ usbc_core_queue_t* pQueue = NULL;
+ kal_uint8 i = 0;
+
+ if ( (pUsbCore->setup_packet.wIndex & USBC_EP_ADDR_DIR_IN) )
+ {
+ is_tx = KAL_TRUE;
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->tx_queue[i].ep_no == nEnd) &&
+ (pUsbCore->tx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
+ {
+ pQueue = &pUsbCore->tx_queue[i];
+ break;
+ }
+ }
+ } else {
+ is_tx = KAL_FALSE;
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ if ( (pUsbCore->rx_queue[i].ep_no == nEnd) &&
+ (pUsbCore->rx_queue[i].state > USBC_CORE_QUEUE_STATE_INITIATED) )
+ {
+ pQueue = &pUsbCore->rx_queue[i];
+ break;
+ }
+ }
+ }
+
+ if ( pQueue == NULL )
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ } else {
+ /* notify class driver that this queue is clear stall, class has to clr stall to driver */
+ usbc_core_indicate_stall(is_tx, i, KAL_FALSE);
+ if(USBC_IS_IN_EXCEPTION_MODE())
+ {
+ pQueue->state = USBC_CORE_QUEUE_STATE_ACTIVE;
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ }
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+ } else {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+
+ usbc_core_set_control_request(NULL, 0, type);
+ return KAL_TRUE;
+}
+
+static kal_bool usbc_core_update_dt_other_speed(kal_uint8 *pDescript, kal_uint8 idx_config)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8* pConfig = (kal_uint8*)pUsbCore->descriptors.configuration[idx_config];
+ kal_uint16 totalLength = pConfig[2] + (pConfig[3] << 8);
+ kal_uint8 *ptr = NULL;
+ kal_uint16 i = 0;
+ kal_uint8 currLength, type;
+
+ // copy the configuration descriptor as the default other speeed descriptor
+ kal_mem_cpy(pDescript, pConfig, totalLength);
+
+ // set the descriptor type as other speed configuration;
+ pDescript[1] = USBC_DT_OTHER_SPEED;
+
+ // update the maximum packet size of each bulk endpoint descriptor
+ ptr = pDescript;
+ while(i < totalLength)
+ {
+ currLength = ptr[0];
+ type = ptr[1];
+
+ if( USBC_DT_ENDPOINT == type &&
+ USBC_BULK_TRANSFER == (ptr[3] & 0x03))
+ {
+ if (USBC_USB_SPEED_USB20 == pUsbCore->speed)
+ {
+ ptr[4] = USBC_USB11_MAX_PACKET_SIZE & 0x00FF;
+ ptr[5] = (USBC_USB11_MAX_PACKET_SIZE >> 8) & 0x07;
+ }
+ else if(USBC_USB_SPEED_USB11 == pUsbCore->speed)
+ {
+ ptr[4] = USBC_USB20_MAX_PACKET_SIZE & 0x00FF;
+ ptr[5] = (USBC_USB20_MAX_PACKET_SIZE >> 8) & 0x07;
+ }
+ }
+
+ ptr += currLength;
+ i += currLength;
+ }
+
+ return KAL_TRUE;
+}
+
+static kal_bool usbc_core_handle_get_descriptor()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK;
+ //kal_uint16 wIndex = pUsbCore->setup_packet.wIndex;
+ kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+ kal_uint16 wLength = pUsbCore->setup_packet.wLength;
+ kal_uint8* pBuffer = NULL;
+ kal_uint32 length = 0;
+
+ usbc_trace_info(USBCORE_GET_DESCRIPTOR, bRecip, (wValue >> 8));
+
+ if ( bRecip == USBC_REQUEST_RECIP_DEVICE )
+ {
+ kal_uint8 bDscrType = wValue >> 8;
+
+ switch ( bDscrType )
+ {
+ case USBC_DT_DEVICE:
+ {
+ usbc_core_printf("=========>usbcore_handle_get_descriptor: Device\r\n");
+ /* Device Descriptor Type */
+ if ( USBC_GET_DESC_LENGTH(pUsbCore->descriptors.device) > wLength )
+ {
+ length = wLength;
+ } else {
+ length = USBC_GET_DESC_LENGTH(pUsbCore->descriptors.device);
+ }
+ pBuffer = pUsbCore->descriptors.device;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ break;
+ }
+ case USBC_DT_CONFIG:
+ {
+ kal_uint8 config_idx = wValue & 0xff; /* configuration index */
+
+ usbc_core_printf("=========>usbcore_handle_get_descriptor: Configuration\r\n");
+ /* Configuration Descriptor Type */
+ if ( USBC_GET_CONF_TOTAL_LENGTH(pUsbCore->descriptors.configuration[config_idx]) > wLength )
+ {
+ length = wLength;
+ } else {
+ length = USBC_GET_CONF_TOTAL_LENGTH(pUsbCore->descriptors.configuration[config_idx]);
+ }
+ pBuffer = pUsbCore->descriptors.configuration[config_idx];
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ break;
+ }
+ case USBC_DT_DEVICE_QUALIFIER:
+ {
+ usbc_core_printf("=========>usbcore_handle_get_descriptor: Qualifier\r\n");
+
+ if ( USBC_USB_SPEED_USB30 == pUsbCore->speed ) {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ break;
+ }
+
+ /* Device Qualifier Type */
+ if ( pUsbCore->device_qualifier_descriptor.bLength > wLength )
+ {
+ length = wLength;
+ } else {
+ length = pUsbCore->device_qualifier_descriptor.bLength;
+ }
+ pBuffer = (kal_uint8*)&pUsbCore->device_qualifier_descriptor;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ break;
+ }
+ case USBC_DT_STRING:
+ {
+ kal_uint8 bStrIdx = wValue & 0xff; /* String Type */
+
+ usbc_core_printf("=========>usbcore_handle_get_descriptor: String\r\n");
+
+ if (bStrIdx == USBC_MS_OS_STRING_INDEX)
+ { /* MOD string descriptor */
+ if ( !pUsbCore->morphing_enable || pUsbCore->state == USBC_USB_STATE_ATTACHED )
+ {
+ pBuffer = NULL;
+ length = 0;
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+// dbg_print("[OSD] MOD 0xEE not handled by standard handler.\r\n");
+ break;
+ }
+ usbc_os_string_desc.bLength = USBC_MAX_OS_STRING_LENGTH;
+ usbc_os_string_desc.bDescriptorType = USBC_DT_STRING;
+ kal_mem_cpy(usbc_os_string_desc.qwSignature, (kal_uint8*)usbc_os_string, 14);
+ usbc_os_string_desc.bMS_VendorCode = USBC_REQ_GET_MS_DESCRIPTOR;
+ usbc_os_string_desc.bPad = 0x00;
+
+ if (USBC_MAX_OS_STRING_LENGTH > wLength) {
+ length = wLength;
+ } else {
+ length = USBC_MAX_OS_STRING_LENGTH;
+ }
+ pBuffer = (kal_uint8*)&usbc_os_string_desc;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ } else
+ {
+ if (bStrIdx < pUsbCore->resource_string_number && pUsbCore->string_descriptor[bStrIdx] != NULL)
+ {
+ if (pUsbCore->string_descriptor[bStrIdx]->bLength > wLength) {
+ length = wLength;
+ } else {
+ length = pUsbCore->string_descriptor[bStrIdx]->bLength;
+ }
+ pBuffer = (kal_uint8*)pUsbCore->string_descriptor[bStrIdx];
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ } else
+ {
+ pBuffer = NULL;
+ length = 0;
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+ }
+ break;
+ }
+ case USBC_DT_BOS:
+ {
+ usbc_core_printf("=========>usbcore_handle_get_descriptor: BOS\r\n");
+
+ /*if ( USBC_USB_SPEED_USB30 != pUsbCore->speed ) {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ break;
+ }*/
+
+ /* Binary Device Object Store (BOS) Type */
+ pBuffer = usbc_bos_s;
+ if ( USBC_GET_BOS_TOTAL_LENGTH(pBuffer) > wLength ) {
+ length = wLength;
+ } else {
+ length = USBC_GET_BOS_TOTAL_LENGTH(pBuffer);
+ }
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ break;
+ }
+ case USBC_DT_OTHER_SPEED:
+ {
+ kal_uint8 config_idx = wValue & 0xff; /* configuration index */
+
+ usbc_core_printf("=========>usbcore_handle_get_descriptor: Other_Speed_Configuration\r\n");
+ /* Configuration Descriptor Type */
+
+ if ( USBC_USB_SPEED_USB30 == pUsbCore->speed ) {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ break;
+ }
+
+ if ( USBC_GET_CONF_TOTAL_LENGTH(pUsbCore->descriptors.configuration[config_idx]) > wLength )
+ {
+ length = wLength;
+ }
+ else
+ {
+ length = USBC_GET_CONF_TOTAL_LENGTH(pUsbCore->descriptors.configuration[config_idx]);
+ }
+
+ // struct other speed configuration
+ usbc_core_update_dt_other_speed(pOtherSpeedDescript, config_idx);
+
+ pBuffer = pOtherSpeedDescript;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+ break;
+ }
+ default:
+ {
+ pBuffer = NULL;
+ length = 0;
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ break;
+ }
+ }
+ } else {
+ pBuffer = NULL;
+ length = 0;
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+
+ usbc_core_set_control_request(pBuffer, length, type);
+ return KAL_TRUE;
+}
+
+
+static kal_bool usbc_core_handle_set_configuration()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+ usbc_ind_t ind_to_enqueue;
+
+#ifdef __USB_OSD_SUPPORT__
+ /* Quentin Li:
+ * Win 8 always set 2 configuration if morphing enabled
+ */
+ if ((wValue & 0xff) == pUsbCore->dev_param->morphing_sub_id) {
+ update_host_os_type(OSD_WIN_8);
+ }
+#endif
+
+ usbc_core_printf("=========>usbcore_handle_set_configuration\r\n");
+ usbc_trace_info(USBCORE_SET_CONFIG, wValue & 0xff);
+
+ if (USBC_IS_IN_EXCEPTION_MODE()) {
+ usbc_core_set_usb_configuration(wValue & 0xff);
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+ return KAL_TRUE;
+ } else {
+ ind_to_enqueue.type = USBC_IND_SET_CONFIG;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)(wValue & 0xff);
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+}
+
+
+static kal_bool usbc_core_handle_get_configuration()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8* pBuffer = pUsbCore->control_request_buffer;
+ kal_uint32 length = 0;
+
+ usbc_core_printf("=========>usbcore_handle_get_configuration\r\n");
+ usbc_trace_info(USBCORE_GET_CONFIG, pUsbCore->usb_configuration);
+
+ pBuffer[0] = pUsbCore->usb_configuration;
+ length = 1;
+
+ usbc_core_set_control_request(pBuffer, length, USBC_CONTROL_REQUEST_TYPE_SEND);
+ return KAL_TRUE;
+}
+
+
+static kal_bool usbc_core_handle_set_interface()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ kal_uint8 bInterface = pUsbCore->setup_packet.wIndex & 0xff;
+ kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+ kal_uint8 i;
+
+ usbc_core_printf("=========>usbcore_handle_set_interface\r\n");
+ usbc_trace_info(USBCORE_SET_INFX, bInterface, wValue);
+
+ do {
+ for ( i=0; i<pUsbCore->total_class_interfaces; i++ )
+ {
+ if ( (pUsbCore->class_interface[i].interface_no == bInterface) &&
+ (pUsbCore->class_interface[i].state == USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE) )
+ {
+ break;
+ }
+ }
+
+ if ( i == pUsbCore->total_class_interfaces )
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ break;
+ }
+
+ pUsbCore->class_interface[i].alternate_setting = wValue & 0xff;
+
+ if ( pUsbCore->class_interface[i].notify_alternate_setting != NULL )
+ {
+ //type = USBC_CONTROL_REQUEST_TYPE_RECEIVE;
+ usbc_core_indicate_alternate_setting(i, pUsbCore->class_interface[i].alternate_setting);
+ pUsbCore->setup_indicated = KAL_TRUE; // set control request in task
+ return KAL_FALSE;
+ }
+ else
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ }
+ } while (0);
+
+ usbc_core_set_control_request(NULL, 0, type);
+ return KAL_TRUE;
+
+}
+
+
+static kal_bool usbc_core_handle_get_interface()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ usbc_control_request_type_e type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ kal_uint8 bInterface = pUsbCore->setup_packet.wIndex & 0xff;
+ //kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+ kal_uint8* pBuffer = pUsbCore->control_request_buffer;
+ kal_uint32 length = 0;
+ kal_uint8 i;
+
+ usbc_core_printf("=========>usbcore_handle_get_interface\r\n");
+ usbc_trace_info(USBCORE_GET_INFX, bInterface);
+
+ do {
+ for ( i=0; i<pUsbCore->total_class_interfaces; i++ )
+ {
+ if ( (pUsbCore->class_interface[i].interface_no == bInterface) &&
+ (pUsbCore->class_interface[i].state == USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE) )
+ {
+ break;
+ }
+ }
+
+ if ( i == pUsbCore->total_class_interfaces )
+ {
+ type = USBC_CONTROL_REQUEST_TYPE_STALL;
+ length = 0;
+ break;
+ }
+
+ pBuffer[0] = pUsbCore->class_interface[i].alternate_setting;
+ length = 1;
+ type = USBC_CONTROL_REQUEST_TYPE_SEND;
+
+ } while (0);
+
+ usbc_core_set_control_request(pBuffer, length, type);
+ return KAL_TRUE;
+}
+
+static kal_bool usbc_core_handle_set_sel()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8* pBuffer = pUsbCore->control_request_buffer;
+ kal_uint32 length = 6;
+
+ usbc_core_printf("=========>usbcore_handle_set_sel\r\n");
+ // TODO: set exit latency value if support, do nothing currently
+ usbc_core_set_control_request(pBuffer, length, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+
+ return KAL_TRUE;
+}
+
+static kal_bool usbc_core_handle_set_isochro_delay()
+{
+ usbc_core_printf("=========>usbcore_handle_isochro_delay\r\n");
+ // TODO: set isochronous delay value if support, do nothing currently
+ usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE);
+
+ return KAL_TRUE;
+}
+
+static void usbc_core_device_descriptor_speed_change(usbc_device_descriptor_t *desc, usbc_usb_speed_e speed)
+{
+ switch (speed) {
+ case USBC_USB_SPEED_USB30:
+ desc->bcdUSB = 0x0300;
+ desc->bMaxPacketSize0 = USBC_USB30_EP0_PACKET_SIZE;
+ break;
+
+ default:
+#ifdef __MTK_TARGET__
+ desc->bcdUSB = 0x0210;
+#else
+ desc->bcdUSB = 0x0200;
+#endif
+ desc->bMaxPacketSize0 = 64;
+ break;
+ }
+}
+
+static void usbc_core_compile_ep_companion(usbc_core_t *pUsbCore, kal_uint32 idx_cfg, kal_uint8 *dst_desc, kal_uint8 transfer_type, kal_uint8 ep_addr)
+{
+ kal_uint8 fifo_n = 1;
+
+ USBC_SET_DESC_LENGTH(dst_desc, USBC_ENDPOINT_COMPANION_DESC_SIZE);
+ USBC_SET_DESC_TYPE(dst_desc, USBC_DT_ENDPOINT_COMPANION);
+ USBC_SET_EPC_ATTRIBUTES(dst_desc, 0);
+ if (ep_addr & 0x80) {
+ fifo_n = pUsbCore->ep_tx_info[idx_cfg][HIFUSB_EPNO_2_QNO((ep_addr & 0xf))].queue_info.fifo_n;
+ }
+ else {
+ fifo_n = pUsbCore->ep_rx_info[idx_cfg][HIFUSB_EPNO_2_QNO((ep_addr & 0xf))].queue_info.fifo_n;
+ }
+
+ if (USBC_BULK_TRANSFER == transfer_type) {
+ USBC_SET_EPC_MAX_BURST(dst_desc, fifo_n - 1);
+ USBC_SET_EPC_BYTES_PER_INTERVAL(dst_desc, 0);
+ } else {
+ USBC_SET_EPC_MAX_BURST(dst_desc, 0);
+ USBC_SET_EPC_BYTES_PER_INTERVAL(dst_desc, 0x40);
+ }
+}
+
+static void usbc_core_configuration_speed_change(usbc_core_t *pUsbCore, usbc_usb_speed_e speed)
+{
+ kal_uint32 total_len;
+ kal_uint32 bytes_read;
+ kal_uint32 bytes_written;
+ kal_uint8 *desc_read;
+ kal_uint8 *desc_to_write;
+ kal_uint32 desc_len;
+ kal_uint32 idx_cfg;
+ kal_uint32 idx_ep;
+ kal_uint8 conf[USBC_MAX_CONF_SIZE];
+
+ for (idx_cfg = 0; idx_cfg < pUsbCore->dev_param->mode_param[pUsbCore->mode].cfg_num; idx_cfg++)
+ {
+ kal_mem_cpy(conf, pUsbCore->descriptors.configuration[idx_cfg], USBC_MAX_CONF_SIZE);
+ bytes_read = 0;
+ bytes_written = 0;
+ total_len = USBC_GET_CONF_TOTAL_LENGTH(conf);
+
+ while (bytes_read < total_len)
+ {
+ desc_read = conf + bytes_read;
+ desc_to_write = pUsbCore->descriptors.configuration[idx_cfg] + bytes_written;
+ desc_len = USBC_GET_DESC_LENGTH(desc_read);
+
+ kal_mem_cpy(desc_to_write, desc_read, desc_len);
+ bytes_written += desc_len;
+
+ switch (USBC_GET_DESC_TYPE(desc_read))
+ {
+ case USBC_DT_ENDPOINT:
+ {
+ if (USBC_BULK_TRANSFER == USBC_GET_EP_TRANSFER_TYPE(desc_to_write))
+ {
+ switch (speed) {
+ case USBC_USB_SPEED_USB11:
+ {
+ USBC_SET_EP_MAX_PACKET_SIZE(desc_to_write, USBC_USB11_MAX_PACKET_SIZE);
+ break;
+ }
+ case USBC_USB_SPEED_USB20:
+ {
+ USBC_SET_EP_MAX_PACKET_SIZE(desc_to_write, USBC_USB20_MAX_PACKET_SIZE);
+ break;
+ }
+ case USBC_USB_SPEED_USB30:
+ {
+ USBC_SET_EP_MAX_PACKET_SIZE(desc_to_write, USBC_USB30_MAX_PACKET_SIZE);
+ break;
+ }
+ default:
+ {
+ ASSERT(0);
+ break;
+ }
+ }
+ }
+ if (speed == USBC_USB_SPEED_USB30) {
+ if (bytes_written + USBC_ENDPOINT_COMPANION_DESC_SIZE <= USBC_MAX_CONF_SIZE) {
+ usbc_core_compile_ep_companion(pUsbCore, idx_cfg, desc_to_write + desc_len, USBC_GET_EP_TRANSFER_TYPE(desc_to_write), USBC_GET_EP_ADDR(desc_to_write));
+ bytes_written += USBC_ENDPOINT_COMPANION_DESC_SIZE;
+ /*if EP companion descriptors exsit, just update value, do not insert new one .*/
+ if(USBC_GET_DESC_TYPE(desc_read + desc_len) == USBC_DT_ENDPOINT_COMPANION) {
+ bytes_read += USBC_ENDPOINT_COMPANION_DESC_SIZE;
+ }
+ } else {
+ EXT_ASSERT(0, USBCORE_LOC_MODIFY_CONFIG_DESC_OVERSIZE_FOR_U3_EP_COMP, (kal_uint32)speed, 0);
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ bytes_read += desc_len;
+ }
+
+ /*
+ * Patch configuration descriptor.
+ */
+ EXT_ASSERT(bytes_written <= USBC_MAX_CONF_SIZE, USBCORE_LOC_MODIFY_CONFIG_DESC_OVERSIZE, (kal_uint32)bytes_written, 0);
+ if (speed == USBC_USB_SPEED_USB30) {
+ USBC_SET_CONF_MAX_POWER(pUsbCore->descriptors.configuration[idx_cfg], pUsbCore->u3ConfMaxPower);
+ }
+ USBC_SET_CONF_TOTAL_LENGTH(pUsbCore->descriptors.configuration[idx_cfg], bytes_written);
+
+ /*
+ * Modify max packet size in tx/rx endpoint queue info
+ */
+ for (idx_ep = 0; idx_ep < pUsbCore->resource_ep_tx_number[idx_cfg]; idx_ep ++)
+ {
+ if (pUsbCore->ep_tx_info[idx_cfg][idx_ep].queue_info.xfer_type == HIFUSB_EP_XFER_TYPE_BULK)
+ {
+ switch (speed) {
+ case USBC_USB_SPEED_USB11:
+ {
+ pUsbCore->ep_tx_info[idx_cfg][idx_ep].queue_info.max_packet_size = USBC_USB11_MAX_PACKET_SIZE;
+ break;
+ }
+ case USBC_USB_SPEED_USB20:
+ {
+ pUsbCore->ep_tx_info[idx_cfg][idx_ep].queue_info.max_packet_size = USBC_USB20_MAX_PACKET_SIZE;
+ break;
+ }
+ case USBC_USB_SPEED_USB30:
+ {
+ pUsbCore->ep_tx_info[idx_cfg][idx_ep].queue_info.max_packet_size = USBC_USB30_MAX_PACKET_SIZE;
+ break;
+ }
+ default:
+ {
+ ASSERT(0);
+ break;
+ }
+ }
+ }
+ }
+ for (idx_ep = 0; idx_ep < pUsbCore->resource_ep_rx_number[idx_cfg]; idx_ep ++)
+ {
+ if (pUsbCore->ep_rx_info[idx_cfg][idx_ep].queue_info.xfer_type == HIFUSB_EP_XFER_TYPE_BULK)
+ {
+ switch (speed) {
+ case USBC_USB_SPEED_USB11:
+ {
+ pUsbCore->ep_rx_info[idx_cfg][idx_ep].queue_info.max_packet_size = USBC_USB11_MAX_PACKET_SIZE;
+ break;
+ }
+ case USBC_USB_SPEED_USB20:
+ {
+ pUsbCore->ep_rx_info[idx_cfg][idx_ep].queue_info.max_packet_size = USBC_USB20_MAX_PACKET_SIZE;
+ break;
+ }
+ case USBC_USB_SPEED_USB30:
+ {
+ pUsbCore->ep_rx_info[idx_cfg][idx_ep].queue_info.max_packet_size = USBC_USB30_MAX_PACKET_SIZE;
+ break;
+ }
+ default:
+ {
+ ASSERT(0);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+kal_bool usbc_core_handle_standard_request()
+{
+ static struct _usbc_request_entry {
+ kal_uint32 request;
+ kal_bool (*request_handler)();
+ } request_entry_table[] = {
+ {USBC_REQ_SET_ADDRESS, usbc_core_handle_set_address},
+ {USBC_REQ_GET_STATUS, usbc_core_handle_get_status},
+ {USBC_REQ_SET_FEATURE, usbc_core_handle_set_feature},
+ {USBC_REQ_CLEAR_FEATURE, usbc_core_handle_clear_feature},
+ {USBC_REQ_GET_DESCRIPTOR, usbc_core_handle_get_descriptor},
+ {USBC_REQ_SET_CONFIGURATION, usbc_core_handle_set_configuration},
+ {USBC_REQ_GET_CONFIGURATION, usbc_core_handle_get_configuration},
+ {USBC_REQ_SET_INTERFACE, usbc_core_handle_set_interface},
+ {USBC_REQ_GET_INTERFACE, usbc_core_handle_get_interface},
+ {USBC_REQ_SET_SEL, usbc_core_handle_set_sel},
+ {USBC_REQ_SET_ISOCHRONOUS_DELAY, usbc_core_handle_set_isochro_delay},
+ };
+
+ kal_uint32 request_entry_table_num = sizeof(request_entry_table)/sizeof(struct _usbc_request_entry);
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint32 idx = 0;
+ kal_bool handled = KAL_TRUE;
+
+ for (idx = 0; idx < request_entry_table_num; idx++) {
+ if (pUsbCore->setup_packet.bRequest == request_entry_table[idx].request) break;
+ }
+
+ if (idx < request_entry_table_num) {
+ handled = request_entry_table[idx].request_handler();
+ } else {
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+
+ return handled;
+}
+
+
+void usbc_core_descriptors_speed_change(usbc_core_t *pUsbCore, usbc_usb_speed_e speed)
+{
+ usbc_core_device_descriptor_speed_change(
+ (usbc_device_descriptor_t *)pUsbCore->descriptors.device,
+ speed);
+
+ usbc_core_configuration_speed_change(pUsbCore, speed);
+}
+
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_task.c b/mcu/middleware/hif/usbcore/src/usbcore_task.c
new file mode 100644
index 0000000..c123e1c
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_task.c
@@ -0,0 +1,1000 @@
+/*!
+ * @file usbcore_task.c
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main functions of usbcore
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_hif.h"
+#include "usbcore_usbstd.h"
+#include "usbcore_main.h"
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#include "sysservice_msgid.h"
+#include "nvram_interface.h"
+#include "nvram_data_items.h"
+#include "usbcore_debug.h"
+#include "usbcore_ind_q.h"
+#include "usbcore_dual_owner.h"
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+#include "usbcore_direct.h"
+#endif
+#ifdef __ESL_COSIM_HIF__
+#include "usbcore_cosim.h"
+#endif
+#include "usb_nvram_def.h"
+#include "l4_nvram_def.h"
+#include "hif_mw_msgid.h"
+#include "custom_port.h"
+#include "usb_nvram_def.h"
+#include "ps_public_l4_msgid.h"
+#include "ps_public_struct.h"
+#include "fs_general_types.h"
+#include "fs_general_api.h"
+#include "sleepdrv_interface.h"
+
+#define UNI_ID NVRAM_EF_IMEI_IMEISV_LID
+extern ltable_entry_struct logical_data_item_table_usb[];
+extern kal_uint32 usb_mode_register_index;
+
+/*
+ * Current operation mode.
+ */
+static usbc_op_mode_e usbc_op_mode_s = USBC_OP_MODE_UNKNOWN;
+
+/*
+ * USBCORE settings read from HMU.
+ */
+static usbc_hmu_info_t usbc_hmu_info_s;
+
+/*
+ * Pointer to current USBCORE global context.
+ */
+static usbc_core_t *usbc_inst_s = NULL;
+
+/*
+ * USBCORE global context for exception mode.
+ */
+static usbc_core_t usbc_except_inst_s;
+
+/*
+ * USBCORE global context for normal mode.
+ */
+static usbc_core_t usbc_normal_inst_s;
+
+/*
+ * USBCORE global context for DUALIPC parameters.
+ */
+kal_uint32 dipc_mode, port_mode, pcie_status;
+
+/*
+ * USBCORE global context for mode record.
+ */
+usbc_op_mode_e usbc_op_mode_record = USBC_OP_MODE_UNKNOWN;
+
+usbc_op_mode_e usbc_get_op_mode(void)
+{
+ return usbc_op_mode_s;
+}
+
+
+void usbc_set_op_mode(usbc_op_mode_e op_mode)
+{
+ if (USBC_OP_MODE_EXCEPTION == op_mode) {
+ usbc_inst_s = &usbc_except_inst_s;
+ } else {
+ usbc_inst_s = &usbc_normal_inst_s;
+ }
+ usbc_op_mode_s = op_mode;
+}
+
+
+usbc_core_t* usbc_core_get_instance()
+{
+ USBC_CORE_INSTANCE_CHECK(usbc_inst_s);
+ return usbc_inst_s;
+}
+
+
+usbc_hmu_info_t *usbc_core_get_hmu_info(void)
+{
+ return &usbc_hmu_info_s;
+}
+
+
+void usbc_core_clear_register()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 i = 0;
+
+ /* Clear USB Core Register information */
+ for ( i=0; i<MAX_USBCORE_QUEUE_NUM; i++ )
+ {
+ pUsbCore->tx_queue[i].state = USBC_CORE_QUEUE_STATE_DISABLE;
+ pUsbCore->rx_queue[i].state = USBC_CORE_QUEUE_STATE_DISABLE;
+ }
+ for ( i=0; i<MAX_USBCORE_INTERFACE_NUM; i++ )
+ {
+ pUsbCore->class_interface[i].state = USBC_CORE_CLASS_INTERFACE_STATE_DISABLE;
+ }
+ for ( i=0; i<MAX_USBCORE_DEVICE_NUM; i++ )
+ {
+ pUsbCore->class_device[i].state = USBC_CORE_CLASS_DEVICE_STATE_NOTEXIST;
+ }
+
+ pUsbCore->total_class_devices = 0;
+ pUsbCore->total_class_interfaces = 0;
+ pUsbCore->total_tx_queues = 0;
+ pUsbCore->total_rx_queues = 0;
+}
+
+void usbc_core_clear_status()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 i;
+
+ /* Clear USBCORE task to wait for both indication events and tick events */
+ usbc_trace_info(USBCORE_SUSPEND_START_POLL);
+ pUsbCore->hmu_indication = HIF_DRV_EG_HIF_TICK_EVENT | HIF_DRV_EG_USBC_IND_EVENT;
+
+ /* Clear USB device status */
+ pUsbCore->usb_configuration = 0;
+ pUsbCore->is_device_u1_enable = KAL_FALSE;
+ pUsbCore->is_device_u2_enable = KAL_FALSE;
+ pUsbCore->is_device_ltm_enable = KAL_FALSE;
+
+ /* Clear USB class status */
+ for( i=0; i<MAX_USBCORE_DEVICE_NUM; i++ )
+ {
+ pUsbCore->class_device[i].is_func_suspend = KAL_FALSE;
+ pUsbCore->func_notify_list[i] = KAL_FALSE;
+ }
+
+ /* Clear USB XIT queue status */
+ for( i = 0; i < MAX_USBCORE_QUEUE_NUM; ++i) {
+ (pUsbCore->rx_xit_meta)[i].xit2meta_retry = KAL_FALSE;
+ (pUsbCore->rx_xit_meta)[i].remain_num = (pUsbCore->rx_xit_meta)[i].startIdx = (pUsbCore->rx_xit_meta)[i].endIdx = 0;
+ }
+
+ pUsbCore->usbc_txq_polled_mask = 0;
+ pUsbCore->usbc_rxq_polled_mask = 0;
+ pUsbCore->usbc_q_polled_duration = 0;
+}
+
+void usbc_core_queue_mutexlock_init()
+{
+ kal_uint8 i = 0;
+ kal_char usbc_queue_mutexlock_name[50];
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ for(i = 0 ; i < MAX_USBCORE_QUEUE_NUM; i++)
+ {
+ usbc_queue_mutexlock_name[0] = '\0';
+ sprintf(usbc_queue_mutexlock_name, "USBC_RXQ%d_MUTEX", i);
+ pUsbCore->rx_submit_enhmuexid[i] = kal_create_enh_mutex(usbc_queue_mutexlock_name);
+ ASSERT(pUsbCore->rx_submit_enhmuexid[i]);
+ }
+ return;
+}
+
+kal_bool usbc_core_is_1st_interface(kal_uint8 idx)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 i = 0;
+
+ for(i = 0; i < pUsbCore->total_class_devices; i++)
+ {
+ if( pUsbCore->class_device[i].device_instance.interface_no[0] == idx )
+ {
+ return KAL_TRUE;
+ }
+ }
+
+ return KAL_FALSE;
+}
+
+kal_uint8 usbc_class_device_get_1st_interface(kal_uint8 class_device_id)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ return pUsbCore->class_device[class_device_id].device_instance.interface_no[0];
+}
+
+#define VAL_TO_STRING(uInt4Val) (((uInt4Val) < 0x0a)? ((uInt4Val) + 0x30):((uInt4Val) - 0x0a + 0x61))
+kal_bool usbc_core_set_serial_number(void)
+{
+ kal_bool result = KAL_FALSE;
+
+#if USB_UNIQUE_SERIAL_NUM_ENABLE
+
+ #define NO_IMEI_SERIAL_NUM 0xffffffffffffffff
+
+ kal_uint16* pSerialNumber = usbc_core_get_instance()->dev_param->serial_number;
+ kal_uint8 *pBuffer = NULL;
+ kal_uint16 record, size, sVal;
+ kal_uint8 i = 0;
+
+ /* check for valid ID for NVRAM */
+ if( NVRAM_ERRNO_SUCCESS != nvram_get_info(UNI_ID, &record, &size) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_EMEI_LID_INFO_FAIL, (kal_uint32)UNI_ID, 0);
+ return result;
+ }
+
+ pBuffer = (kal_uint8*)get_ctrl_buffer(size);
+
+ /* store IMEI to pBuffer, and store the length of IMEI to size */
+ if ( nvram_external_read_data(UNI_ID, 1, pBuffer, (kal_uint32)size) )
+ {
+ if(NO_IMEI_SERIAL_NUM != *((kal_uint64*)pBuffer)) // update serial number if IEMI has been set
+ {
+ /*
+ * Assume the maximum length of IEMI is 0x0F, and we also define the length of serial number as 0x0F.
+ * Then the length of parsed IMEI must be smaller or equal to the length of serial number
+ */
+ size = (size <= (0x0f >> 1))? size:(0x0f >> 1);
+ while( i < size )
+ {
+ sVal = pBuffer[i] & 0x0f; // the lower part of pBuffer[i] is the odd part of the serail number
+ pSerialNumber[(i<<1)+1] = VAL_TO_STRING(sVal);
+ sVal = (pBuffer[i] & 0xf0) >> 4; // the higher part of pBuffer[i] is the even part of the serail number
+ pSerialNumber[(i<<1)+2] = VAL_TO_STRING(sVal);
+ i++;
+ }
+ sVal = pBuffer[i] & 0x0f; // pBuffer[15] is the last field of the serail number
+ pSerialNumber[0x0f] = VAL_TO_STRING(sVal);
+
+ free_ctrl_buffer(pBuffer);
+ result = KAL_TRUE;
+ }
+ }
+ else
+ {
+ free_ctrl_buffer(pBuffer);
+ EXT_ASSERT(0, USBCORE_LOC_GET_EMEI_LID_VALUE_FAIL, (kal_uint32)UNI_ID, 0);
+ }
+#endif
+
+ return result;
+}
+
+kal_uint8 usbc_set_serial_number_for_internal()
+{
+ kal_bool result = KAL_FALSE;
+ kal_uint16* pSerialNumber = usbc_core_get_instance()->dev_param->serial_number;
+ kal_uint8 *pBuffer = NULL;
+ kal_uint16 record, size;
+ kal_uint8 i = 0;
+ kal_bool sn_valid_flag = KAL_TRUE;
+ kal_uint16 usb_serial_num[] = {0x031a,'6','6','5','5','4','4','3','3','2','2','1','1' };
+
+ /* check for valid ID for NVRAM */
+ if( NVRAM_ERRNO_SUCCESS != nvram_get_info(NVRAM_EF_USB_SN_LID, &record, &size) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_SN_LID_INFO_FOR_ENUM_FAIL, (kal_uint32)NVRAM_EF_USB_SN_LID, 0);
+ return result;
+ }
+
+ pBuffer = (kal_uint8*)get_ctrl_buffer(size);
+
+ /* store SN to pBuffer, and store the length of SN to size */
+ if ( nvram_external_read_data(NVRAM_EF_USB_SN_LID, 1, pBuffer, (kal_uint32)size) )
+ {
+ for(i = 0; i < size; i++)
+ {
+ if((pBuffer[i] >= '0' && pBuffer[i] <= '9') || (pBuffer[i] >= 'a' && pBuffer[i] <= 'z') || (pBuffer[i]>= 'A' && pBuffer[i] <= 'Z') || pBuffer[i] == '-' || pBuffer[i] == '_' || pBuffer[i] == '#')
+ pSerialNumber[i + 1] = pBuffer[i];
+ else
+ {
+ sn_valid_flag = KAL_FALSE;
+ break;
+ }
+ }
+ /*invalid SN*/
+ if(sn_valid_flag == KAL_FALSE)
+ {
+ kal_mem_cpy(pSerialNumber, usb_serial_num, sizeof(usb_serial_num));
+ }
+
+ free_ctrl_buffer(pBuffer);
+ result = KAL_TRUE;
+ }
+ return result;
+}
+
+void usbc_core_check_low_power_enable()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ if(dipc_mode == PORT_DIPC_MODE_USB_ONLY)
+ pUsbCore->usb_low_power_enable = KAL_TRUE;
+ else
+ pUsbCore->usb_low_power_enable = KAL_FALSE;
+ usbc_trace_warn(USBCORE_GET_LOW_POWER_ENABLE_VALUE, pUsbCore->usb_low_power_enable);
+}
+
+kal_uint16 usbc_core_get_function_remote_wk_list(void)
+{
+ kal_uint8 i, total_class_device;
+ kal_uint16 result = 0;
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ total_class_device = pUsbCore->total_class_devices;
+
+ for(i=0; i<total_class_device; i++)
+ {
+ if ( pUsbCore->class_device[i].query_func_wk_status &&
+ pUsbCore->class_device[i].query_func_wk_status(i) == 0x03 )
+ {
+ result |= (0x01 << i);
+ }
+ }
+
+ return result;
+}
+
+kal_uint16 usbc_core_get_function_suspend_list(void)
+{
+ kal_uint8 i, total_class_device;
+ kal_uint16 result = 0;
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ total_class_device = pUsbCore->total_class_devices;
+
+ for(i=0; i<total_class_device; i++)
+ {
+ /*if class_device is AP owner, its suspend state should not effect MD lowpower flow,
+ so set its state to suspended state when get suspend list*/
+ if (pUsbCore->class_device[i].owner != USB_CLASS_OWNER_MD)
+ {
+ result |= (0x01 << i);
+ continue;
+ }
+
+ if ( pUsbCore->class_device[i].is_func_suspend &&
+ pUsbCore->class_device[i].is_func_suspend == KAL_TRUE )
+ {
+ result |= (0x01 << i);
+ }
+ }
+
+ return result;
+}
+
+void usbc_core_check_mass_strorage_onoff()
+{
+ kal_wchar *filepath = NULL;
+ filepath = (kal_wchar *)get_ctrl_buffer(USBC_READ_FILE_PATH_MAX_LENGTH);
+ kal_wsprintf(filepath, "%s", "V:\\usb_config");
+ char *buffer = NULL;
+ FS_HANDLE file_handle;
+ usbc_ms_enable_e ms_enable = MSD_INVALID;
+ kal_uint8 idx_cfg = 0;
+ char *value = NULL;
+ char pattern[] = "mass_storage_mode:";
+
+ usbc_core_t *usbc_inst = usbc_core_get_instance();
+ usb_mode_e mode = usbc_inst->mode;
+ kal_uint8 cfg_num = usbc_inst->dev_param->mode_param[mode].cfg_num;
+ usb_cfg_param_t *cfg_param;
+
+ buffer = (char *)get_ctrl_buffer(USBC_READ_FILE_DATA_MAX_LENGTH);
+ kal_mem_set((kal_uint8*)buffer, 0, USBC_READ_FILE_DATA_MAX_LENGTH);
+ if ((file_handle = FS_Open(filepath, FS_READ_ONLY | FS_OPEN_NO_DIR)) >= FS_NO_ERROR) {
+ kal_uint32 read_size;
+ if (FS_Read(file_handle, (kal_uint8*)buffer, USBC_READ_FILE_DATA_MAX_LENGTH - 1, &read_size) >= FS_NO_ERROR) {
+ buffer[read_size] = '\0';
+ value = strstr(buffer, pattern);
+ if(value != NULL && buffer[strlen(pattern)] >= '0' && buffer[strlen(pattern)] <= '9')
+ {
+ ms_enable = buffer[strlen(pattern)] - '0';
+ if(ms_enable == MSD_ENABLE)
+ {
+ /*msd is enable, change config*/
+ for (idx_cfg = 0; idx_cfg < cfg_num; idx_cfg++)
+ {
+ cfg_param = &usbc_inst->dev_param->mode_param[mode].cfg_param[idx_cfg];
+ if(cfg_param->class_num >= USB_MAX_CLASS_NUM)
+ continue;
+
+ cfg_param->class_type[cfg_param->class_num] = USB_CLASS_MS;
+ cfg_param->class_owner[cfg_param->class_num] = USB_CLASS_OWNER_AP;
+ cfg_param->class_ctxt[cfg_param->class_num] = (void*)0;
+ cfg_param->bulk_fifo_n[cfg_param->class_num] = 0x11;
+ cfg_param->class_num++;
+ }
+ }
+ else
+ {
+ /*msd is disable, do nothing*/
+ }
+ }
+ }
+ }
+ free_ctrl_buffer(buffer);
+ free_ctrl_buffer(filepath);
+}
+
+void usbc_ut_dualipc_op_mode_select(kal_uint32 *dipc_mode, kal_uint32 *port_mode, kal_uint32 *pcie_status)
+{
+ kal_uint8 *pBuffer = NULL;
+ kal_uint16 record, size;
+
+ nvram_get_info(NVRAM_EF_USB_VIDPID_LID, &record, &size);
+ pBuffer = (kal_uint8*)get_ctrl_buffer(size);
+ nvram_external_read_data(NVRAM_EF_USB_VIDPID_LID, 1, pBuffer, (kal_uint32)size);
+ *dipc_mode = (*((kal_uint16*)pBuffer)) & 0xf;
+ *pcie_status = (*((kal_uint16*)pBuffer)) & 0xf0;
+ nvram_external_read_data(NVRAM_EF_USB_VIDPID_LID, 2, pBuffer, (kal_uint32)size);
+ *port_mode = (*((kal_uint16*)pBuffer)) & 0xf;
+}
+
+kal_bool usbc_core_get_dipc_status()
+{
+#ifndef __USBC_DIPC_UT_TEST__
+ dipc_mode = CUSTOM_PORT_GET_DIPC_MODE(0);
+ pcie_status = CUSTOM_PORT_GET_PCIE_STATUS(0);
+ port_mode = CUSTOM_PORT_GET_MODE(CUSTOM_PORT_USER_LOG);
+#else
+ usbc_ut_dualipc_op_mode_select(&dipc_mode, &port_mode, &pcie_status);
+#endif
+
+ switch(dipc_mode)
+ {
+ case PORT_DIPC_MODE_NOT_SUPPORT:
+ #ifdef __HIF_PCIE_SUPPORT__
+ usbc_set_op_mode(USBC_OP_MODE_METADEBUG);
+ #else
+ usbc_set_op_mode(USBC_OP_MODE_NORMAL);
+ #endif
+ break;
+ case PORT_DIPC_MODE_DUAL_IPC:
+ if((pcie_status == PORT_PCIE_STATUS_LINK_UP)&&(port_mode != PORT_MODE_USB && port_mode != PORT_MODE_USB_AND_PCIE))
+ {
+ usbc_set_op_mode(USBC_OP_MODE_NOLOGGING);
+ }
+ else
+ {
+ usbc_set_op_mode(USBC_OP_MODE_NORMAL);
+ }
+ break;
+ case PORT_DIPC_MODE_PCIE_ADVANCE:
+ if(pcie_status == PORT_PCIE_STATUS_LINK_UP)
+ {
+ usbc_set_op_mode(USBC_OP_MODE_UNUSED);
+ return KAL_FALSE;
+ }
+ else
+ {
+ usbc_set_op_mode(USBC_OP_MODE_NORMAL);
+ }
+ break;
+ case PORT_DIPC_MODE_PCIE_ONLY:
+ usbc_set_op_mode(USBC_OP_MODE_UNUSED);
+ return KAL_FALSE;
+ case PORT_DIPC_MODE_USB_ONLY:
+ usbc_set_op_mode(USBC_OP_MODE_NORMAL);
+ break;
+ default:
+ EXT_ASSERT(0, USBCORE_LOC_DUALIPC_INVALID_PARAMETER, dipc_mode, 0);
+ }
+ return KAL_TRUE;
+}
+
+
+usbc_atcmd_hd_t usbc_atcmd_handle_table[] =
+{
+#ifndef __PRODUCTION_RELEASE__
+/* under construction !*/
+#endif
+ {"usb_mode", usbc_core_handle_set_usb_mode_atcmd, usbc_core_handle_get_usb_mode_atcmd},
+ {"usb_pwrdown", usbc_core_handle_powerdown_usb_atcmd, NULL},
+};
+
+kal_bool usbc_core_handle_powerdown_usb_atcmd(void *req, void *cnf)
+{
+ usbc_ind_t ind_to_enqueue;
+ usbc_normal_hif_disconnect();
+ ind_to_enqueue.type = USBC_IND_IP_PWRDOWN;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = 0;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+
+ return KAL_TRUE;
+}
+kal_bool usbc_core_handle_set_usb_mode_atcmd(void *req, void *cnf)
+{
+ kal_uint16 record, size;
+ kal_uint8 mode_idx;
+ kal_uint8 *pBuffer = NULL;
+ kal_bool result = KAL_FALSE;
+ usbc_core_t* usbc_inst = usbc_core_get_instance();
+ l4c_general_modem_configure_struct *at_data = &(((l4c_general_modem_configure_set_req_struct*)req)->data);
+
+ if(at_data->param_num != 2 || at_data->type[0] != L4C_AT_CMD_PARAM_INTEGER || at_data->type[1] != L4C_AT_CMD_PARAM_INTEGER)
+ return KAL_FALSE;
+
+ /* check for valid ID for NVRAM */
+ if( NVRAM_ERRNO_SUCCESS != nvram_get_info(NVRAM_EF_USB_MODE_LID, &record, &size) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_MODE_LID_INFO_FOR_SET_FAIL, (kal_uint32)NVRAM_EF_USB_MODE_LID, 0);
+ return KAL_FALSE;
+ }
+ ASSERT(size == 2);
+
+ pBuffer = (kal_uint8*)get_ctrl_buffer(size * record);
+ pBuffer[0] = at_data->param[0].integer_num;
+ pBuffer[1] = at_data->param[1].integer_num;
+
+ for(mode_idx = 0; mode_idx < usb_mode_register_index; mode_idx++)
+ {
+
+ if(usbc_inst->dev_param->mode_param[mode_idx].mode_owner == pBuffer[0] && usbc_inst->dev_param->mode_param[mode_idx].mode_index == pBuffer[1])
+ {
+ break;
+ }
+ }
+ if(mode_idx >= usb_mode_register_index)
+ {
+ /*mode or index invalid*/
+ return KAL_FALSE;
+ }
+
+ result = nvram_external_write_data(NVRAM_EF_USB_MODE_LID, 1, pBuffer, size);
+ free_ctrl_buffer(pBuffer);
+ return result;
+}
+
+kal_bool usbc_core_handle_get_usb_mode_atcmd(void *req, void *cnf)
+{
+ kal_uint16 record, size;
+ kal_uint8 *pBuffer = NULL;
+ kal_bool result = KAL_FALSE;
+ l4c_general_modem_configure_struct *at_data = &(((l4c_general_modem_configure_query_cnf_struct*)cnf)->data);
+
+ /* check for valid ID for NVRAM */
+ if( NVRAM_ERRNO_SUCCESS != nvram_get_info(NVRAM_EF_USB_MODE_LID, &record, &size) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_MODE_LID_INFO_FOR_AT_GET_FAIL, (kal_uint32)NVRAM_EF_USB_MODE_LID, 0);
+ return KAL_FALSE;
+ }
+ ASSERT(size == 2);
+
+ pBuffer = (kal_uint8*)get_ctrl_buffer(size * record);
+
+ if ( nvram_external_read_data(NVRAM_EF_USB_MODE_LID, 1, pBuffer, (kal_uint32)size) )
+ {
+ at_data->param_num = 2;
+ at_data->type[0] = L4C_AT_CMD_PARAM_INTEGER;
+ at_data->type[1] = L4C_AT_CMD_PARAM_INTEGER;
+ at_data->param[0].integer_num = *((kal_uint8*)pBuffer);
+ at_data->param[1].integer_num = *((kal_uint8*)(pBuffer + sizeof(kal_uint8)));
+ result = KAL_TRUE;
+ }
+
+ free_ctrl_buffer(pBuffer);
+ return result;
+}
+
+kal_bool usbc_core_handle_set_serialnumber_atcmd(void *req, void *cnf)
+{
+ kal_uint16 record, size, i;
+ kal_bool result = KAL_FALSE;
+ kal_uint8 *pBuffer = NULL;
+ l4c_general_modem_configure_struct *at_data = &(((l4c_general_modem_configure_set_req_struct*)req)->data);
+ kal_uint8 length;
+ char c;
+
+ if(at_data->param_num != 1 || at_data->type[0] != L4C_AT_CMD_PARAM_STRING_S)
+ return KAL_FALSE;
+
+ length = strlen((char*)at_data->param[0].string_s);
+ if( NVRAM_ERRNO_SUCCESS != nvram_get_info(NVRAM_EF_USB_SN_LID, &record, &size) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_SN_LID_INFO_FOR_SET_FAIL, (kal_uint32)NVRAM_EF_USB_SN_LID, 0);
+ return KAL_FALSE;
+ }
+ pBuffer = (kal_uint8*)get_ctrl_buffer(size);
+ if(pBuffer == NULL)
+ {
+ return KAL_FALSE;
+ }
+
+ for(i = 0; i < size; i++)
+ {
+ if(i < length)
+ {
+ c = at_data->param[0].string_s[i];
+ if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c>= 'A' && c <= 'Z') || c == '-' || c == '_' || c == '#')
+ pBuffer[i] = c;
+ else
+ {
+ free_ctrl_buffer(pBuffer);
+ return KAL_FALSE;
+ }
+ }
+ else
+ pBuffer[i] = '0';
+ }
+
+ result = nvram_external_write_data(NVRAM_EF_USB_SN_LID, 1, pBuffer, size);
+ free_ctrl_buffer(pBuffer);
+ return result;
+}
+
+kal_bool usbc_core_handle_get_serialnumber_atcmd(void *req, void *cnf)
+{
+ kal_uint16 record, size, i;
+ kal_bool result = KAL_FALSE;
+ kal_uint8 *pBuffer = NULL;
+ l4c_general_modem_configure_struct *at_data = &(((l4c_general_modem_configure_query_cnf_struct*)cnf)->data);
+ kal_bool sn_valid_flag = KAL_TRUE;
+
+ /* check for valid ID for NVRAM */
+ if( NVRAM_ERRNO_SUCCESS != nvram_get_info(NVRAM_EF_USB_SN_LID, &record, &size) )
+ {
+ EXT_ASSERT(0, USBCORE_LOC_GET_SN_LID_INFO_FOR_AT_GET_FAIL, (kal_uint32)NVRAM_EF_USB_SN_LID, 0);
+ return result;
+ }
+
+ pBuffer = (kal_uint8*)get_ctrl_buffer(size);
+
+ /* store SN to pBuffer, and store the length of SN to size */
+ if ( nvram_external_read_data(NVRAM_EF_USB_SN_LID, 1, pBuffer, (kal_uint32)size) )
+ {
+ for(i = 0; i < size; i++)
+ {
+ if((pBuffer[i] >= '0' && pBuffer[i] <= '9') || (pBuffer[i] >= 'a' && pBuffer[i] <= 'z') || (pBuffer[i] >= 'A' && pBuffer[i] <= 'Z') || pBuffer[i] == '-' || pBuffer[i] == '_'|| pBuffer[i] == '#')
+ {
+ at_data->param[0].string_s[i] = pBuffer[i];
+ }
+ else
+ {
+ sn_valid_flag = KAL_FALSE;
+ break;
+ }
+ }
+ /*invalid SN*/
+ if(sn_valid_flag == KAL_FALSE)
+ {
+ kal_mem_set(at_data->param[0].string_s, 0, MAX_ATCMD_EGMC_SHORT_STR_LEN);
+ return KAL_FALSE;
+ }
+
+ at_data->param_num = 1;
+ at_data->type[0] = L4C_AT_CMD_PARAM_STRING_S;
+ free_ctrl_buffer(pBuffer);
+ result = KAL_TRUE;
+ }
+ return result;
+}
+
+static void usbc_core_handle_atcmd(ilm_struct *current_ilm)
+{
+ l4c_general_modem_configure_set_req_struct *set_req_ptr = NULL;
+ l4c_general_modem_configure_set_cnf_struct *set_cnf_ptr = NULL;
+ l4c_general_modem_configure_query_req_struct *query_req_ptr = NULL;
+ l4c_general_modem_configure_query_cnf_struct *query_cnf_ptr = NULL;
+ char *cmd_type = NULL;
+ kal_bool is_set;
+ kal_bool ret = KAL_FALSE;
+ kal_uint16 param_len;
+ kal_uint8 i = 0;
+
+ if(current_ilm->msg_id == MSG_ID_L4C_GENERAL_MODEM_CONFIGURE_SET_REQ)
+ {
+ set_req_ptr = (l4c_general_modem_configure_set_req_struct*)get_local_para_ptr(current_ilm->local_para_ptr, ¶m_len);
+ set_cnf_ptr = (l4c_general_modem_configure_set_cnf_struct*)construct_local_para(sizeof(l4c_general_modem_configure_set_cnf_struct), TD_RESET);
+ cmd_type = (char*)set_req_ptr->configure_string;
+ is_set = KAL_TRUE;
+ }
+ else
+ {
+ query_req_ptr = (l4c_general_modem_configure_query_req_struct*)get_local_para_ptr(current_ilm->local_para_ptr, ¶m_len);
+ query_cnf_ptr = (l4c_general_modem_configure_query_cnf_struct*)construct_local_para(sizeof(l4c_general_modem_configure_query_cnf_struct), TD_RESET);
+ cmd_type = (char*)query_req_ptr->configure_string;
+ is_set = KAL_FALSE;
+ }
+
+ for(i = 0 ; i < sizeof(usbc_atcmd_handle_table)/sizeof(usbc_atcmd_hd_t) ; i++)
+ {
+ if(0 == strcmp(cmd_type, usbc_atcmd_handle_table[i].cmd_type))
+ break;
+ }
+
+ if(i < sizeof(usbc_atcmd_handle_table)/sizeof(usbc_atcmd_hd_t))
+ {
+ if(is_set && usbc_atcmd_handle_table[i].handle_set_func != NULL)
+ ret = usbc_atcmd_handle_table[i].handle_set_func((void*)set_req_ptr, (void*)set_cnf_ptr);
+ else if(!is_set && usbc_atcmd_handle_table[i].handle_get_func != NULL)
+ ret = usbc_atcmd_handle_table[i].handle_get_func((void*)query_req_ptr, (void*)query_cnf_ptr);
+ }
+
+ usbc_trace_warn(USBCORE_RECEIVE_ATCMD_MSG, cmd_type, ret);
+ if(is_set)
+ {
+ set_cnf_ptr->src_id = set_req_ptr->src_id;
+ set_cnf_ptr->result = ret;
+ set_cnf_ptr->data.param_num = 0;
+ kal_mem_cpy(set_cnf_ptr->configure_string, cmd_type, sizeof(set_cnf_ptr->configure_string));
+ msg_send6( kal_get_active_module_id(), /* src_mod_id */
+ MOD_L4C, /* dst_mod_id */
+ 0, /* sap_id */
+ MSG_ID_L4C_GENERAL_MODEM_CONFIGURE_SET_CNF, /* msg_id */
+ (local_para_struct*)set_cnf_ptr, /* local_para_ptr */
+ NULL);
+ }
+ else
+ {
+ query_cnf_ptr->src_id = query_req_ptr->src_id;
+ kal_mem_cpy(query_cnf_ptr->configure_string, cmd_type, sizeof(query_cnf_ptr->configure_string));
+ msg_send6( kal_get_active_module_id(), /* src_mod_id */
+ MOD_L4C, /* dst_mod_id */
+ 0, /* sap_id */
+ MSG_ID_L4C_GENERAL_MODEM_CONFIGURE_QUERY_CNF, /* msg_id */
+ (local_para_struct*)query_cnf_ptr, /* local_para_ptr */
+ NULL);
+ }
+
+ return;
+}
+
+static void usbc_core_task_main(task_entry_struct* task_entry_ptr)
+{
+ ilm_struct current_ilm;
+ kal_uint32 rt_event;
+ kal_uint16 timer_index;
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ kal_set_active_module_id(MOD_USBCORE);
+ kal_mem_set(¤t_ilm, 0, sizeof(ilm_struct));
+
+ usbc_trace_info(USBCORE_TASK_MAIN);
+
+ if(usbc_get_op_mode() == USBC_OP_MODE_UNUSED)
+ {
+ return;
+ }
+
+ if( !pUsbCore->is_mode_meta_reused )
+ {
+ ubm_drb_init_properties();
+ ubm_ul_meta_init_properties();
+
+#ifndef __MTK_MD_DIRECT_USB_SUPPORT__
+ usbc_normal_hif_connect();
+#else
+ usbc_direct_hif_enable_poll_queue(KAL_FALSE);
+#endif
+ }
+
+#ifdef __UBM_UT__
+ ubm_ut_test_cases();
+#endif
+
+#ifdef __UFPM_UT__
+ ufpm_ut_func_test_series1();
+#endif
+
+ while (1)
+ {
+ //usbc_core_printf("=========>usbcore_task_main\r\n");
+
+ /* msg_receive_extq will block, therefore we poll if any message
+ exist first */
+ while ( msg_get_extq_messages() > 0 )
+ {
+ if ( msg_receive_extq(¤t_ilm) != KAL_TRUE )
+ {
+ break;
+ }
+
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+ if(MOD_UFPM == current_ilm.dest_mod_id) {
+ ufpm_on_ilm(¤t_ilm);
+ }
+ else
+#endif
+ {
+ switch (current_ilm.msg_id)
+ {
+ case MSG_ID_TIMER_EXPIRY:
+ timer_index = evshed_get_index(¤t_ilm);
+ switch (timer_index)
+ {
+ case USBC_WK_NOTIFY_INDEX:
+ evshed_timer_handler(pUsbCore->usbc_es_wk_notify_g);
+ break;
+
+ default:
+ break;
+ }
+ break;
+ /*msgid for AP msg receive in dual usb owner, read CCCI buffer and handle when receive msgid*/
+ case MSG_ID_USBCORE_DUAL_OWNER_MSG_RECEIVE:
+ if(usbc_dual_owner_ilm_handle != NULL)
+ usbc_dual_owner_ilm_handle();
+ break;
+ case MSG_ID_L4C_GENERAL_MODEM_CONFIGURE_SET_REQ:
+ case MSG_ID_L4C_GENERAL_MODEM_CONFIGURE_QUERY_REQ:
+ usbc_core_handle_atcmd(¤t_ilm);
+ break;
+ default:
+ break;
+ }
+ }
+
+ destroy_ilm(¤t_ilm);
+ }
+
+ /* Wait someone notify HMU to wake up HIF. */
+ rt_event = hmu_hifeg_wait(pUsbCore->hmu_indication) & pUsbCore->hmu_indication;
+ if ((HIF_DRV_EG_HIF_TICK_EVENT & rt_event) &&
+ (pUsbCore->state != USBC_USB_STATE_SUSPENDED) && (pUsbCore->state != USBC_USB_STATE_DETACHED))
+ {
+ /* poll HIF queue data */
+ usbc_normal_hif_poll_queue();
+ }
+ if ((HIF_DRV_EG_USBC_IND_EVENT & rt_event))
+ {
+ /* Handle indications */
+ usbc_normal_hif_process_indications();
+ }
+ }
+}
+
+
+static kal_bool usbc_core_task_init(void)
+{
+ usbc_core_t* pUsbCore;
+ kal_char usbc_class_mutex_name[50];
+ kal_bool ind_q_spinlock_init;
+ usbc_core_printf("=========>usbcore_task_init\r\n");
+ usbc_trace_info(USBCORE_TASK_INIT);
+
+#if defined(IPCORE_NOT_PRESENT) || !defined(__IPCORE_SUPPORT__) || defined(__IPCORE_TASK_DISABLE__)
+ hmu_boot_init();
+#endif
+
+ usbc_set_op_mode(USBC_OP_MODE_NORMAL);
+ kal_mem_set(usbc_core_get_instance(), 0, sizeof(usbc_core_t));
+
+ usbc_core_clear_register();
+ usbc_core_clear_status();
+
+ pUsbCore = usbc_core_get_instance();
+ nvram_ltable_register(logical_data_item_table_usb);
+ if(KAL_FALSE == usbc_core_get_dipc_status())
+ {
+ return KAL_TRUE;
+ }
+ usbc_op_mode_record = usbc_get_op_mode();
+
+ // create enhance mutex
+ sprintf(usbc_class_mutex_name, "USBC_CLASS_REMOTE_WK_MUTEX");
+ pUsbCore->usbc_class_remote_wk_mutex = kal_create_enh_mutex(usbc_class_mutex_name);
+ sprintf(usbc_class_mutex_name, "USBC_CLASS_RENOTIFY_MUTEX");
+ pUsbCore->usbc_class_renotify_mutex = kal_create_enh_mutex(usbc_class_mutex_name);
+ sprintf(usbc_class_mutex_name, "USBC_CLASS_FUNC_ACCESS_MUTEX");
+ pUsbCore->usbc_class_func_access_mutex = kal_create_enh_mutex(usbc_class_mutex_name);
+ sprintf(usbc_class_mutex_name, "USBC_RESUME_MUTEX");
+ pUsbCore->usbc_class_resume_mutex = kal_create_enh_mutex(usbc_class_mutex_name);
+ sprintf(usbc_class_mutex_name, "USBC_SETUP_SPINLOCK");
+ pUsbCore->setup_packet_spinlock= kal_create_spinlock(usbc_class_mutex_name);
+ ind_q_spinlock_init = usbc_ind_queue_spinlock_init();
+ usbc_core_queue_mutexlock_init();
+
+ if ( NULL == pUsbCore->usbc_class_remote_wk_mutex ||
+ NULL == pUsbCore->usbc_class_renotify_mutex ||
+ NULL == pUsbCore->usbc_class_func_access_mutex ||
+ NULL == pUsbCore->usbc_class_resume_mutex ||
+ NULL == pUsbCore->setup_packet_spinlock ||
+ KAL_FALSE == ind_q_spinlock_init)
+ {
+ ASSERT(0);
+ }
+
+ // initial an evnet scheduler
+ pUsbCore->usbc_es_wk_notify_g = evshed_create(
+ "USBC_WK_NOTIFY", /* timer_name: event scheduler name */
+ MOD_USBCORE, /* dest_mod_id: system sends timeout message to this module when event scheduler timeout happens */
+ 0, /* fuzz */
+ (KAL_TICKS_10_MSEC * 255 / 2)); /* max_delay_ticks */
+ if (pUsbCore->usbc_es_wk_notify_g) {
+ evshed_set_index(pUsbCore->usbc_es_wk_notify_g, USBC_WK_NOTIFY_INDEX);
+ } else {
+ ASSERT(0);
+ }
+
+ usbc_normal_hif_factory();
+
+#if defined(__HIF_USB_ENUM_PORT_FOR_AP__) && defined(__HIF_CCCI_SUPPORT__)
+ dual_owner_funciton_register();
+#endif
+ if(usbc_dual_owner_init != NULL)
+ usbc_dual_owner_init();
+
+ usbc_stack_checkin(USB_CLASS_NUM, NULL);
+ return KAL_TRUE;
+}
+
+
+static kal_bool usbc_core_task_reset(void)
+{
+ usbc_core_printf("=========>usbcore_task_reset\r\n");
+ usbc_trace_info(USBCORE_TASK_RESET);
+
+ /* Do task's reset here.
+ * Notice that: shouldn't execute modules reset handler since
+ * stack_task_reset() will do. */
+ return KAL_TRUE;
+}
+
+#ifdef __MODIS_USB_TAP_ACCESS__
+extern kal_bool uta_usbcore_task_init(void);
+extern void uta_usbcore_task_main(task_entry_struct*);
+#endif
+
+extern void usbc_stack_reset(); /* Simply reset USB stack before task init, so, no need to be public. */
+
+kal_bool usbc_core_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct usbc_core_handler_info =
+ {
+#if defined(__ESL_COSIM_HIF__)
+ usbc_cosim_core_task_main, /* task entry function for ESL COSIM */
+ usbc_cosim_core_task_init, /* task initialization function for ESL_COSIM */
+#elif defined(__MODIS_USB_TAP_ACCESS__)
+ uta_usbcore_task_main, /* task entry function for MoDIS TAP Access */
+ uta_usbcore_task_init, /* task initialization function for MoDIS TAP Access */
+#else
+ usbc_core_task_main, /* task entry function */
+ usbc_core_task_init, /* task initialization function */
+#endif
+ usbc_core_task_reset /* task reset handler */
+ };
+
+ usbc_core_printf("=========>usbcore_create\r\n");
+ usbc_trace_info(USBCORE_TASK_CREATE);
+
+ *handle = (comptask_handler_struct *)&usbc_core_handler_info;
+
+ usbc_stack_reset();
+ return KAL_TRUE;
+}
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_ut.c b/mcu/middleware/hif/usbcore/src/usbcore_ut.c
new file mode 100644
index 0000000..d5a1b04
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_ut.c
@@ -0,0 +1,871 @@
+//#include "kal_release.h"
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "task_config.h"
+//#include "kal_debug.h"
+#include "sys_test.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#include "usbcore_common.h"
+#include "usbcore_ind_q.h"
+#include "hifusb_qmu.h"
+#include "hmu.h"
+#include "usbcore_ut.h"
+
+/****************************************************************************
+ Macro Declaration
+ ***************************************************************************/
+#define ST_MOD_NAME "USBCORE"
+
+/****************************************************************************
+ Global Variables
+***************************************************************************/
+static usbc_ut_fake_class_func_info_t fake_class_func;
+
+hifusb_setup_packet_t getDevStatusPkt =
+{
+ 0x80, // bmRequestType
+ 0x00, // bRequest
+ 0x00, // wValue
+ 0x00, // wIndex
+ 0x02, // wLength
+};
+
+hifusb_setup_packet_t getNon1stInfxStatusPkt =
+{
+ 0x81, // bmRequestType
+ 0x00, // bRequest
+ 0x00, // wValue
+ 0x01, // wIndex
+ 0x02, // wLength
+};
+
+hifusb_setup_packet_t get1stInfxStatusPkt =
+{
+ 0x81, // bmRequestType
+ 0x00, // bRequest
+ 0x00, // wValue
+ 0x00, // wIndex
+ 0x02, // wLength
+};
+
+hifusb_setup_packet_t setDevFeatureRemoteWkPkt =
+{
+ 0x00, // bmRequestType
+ 0x03, // bRequest
+ 0x01, // wValue
+ 0x00, // wIndex
+ 0x00, // wLength
+};
+
+hifusb_setup_packet_t setDevFeatureU1Pkt =
+{
+ 0x00, // bmRequestType
+ 0x03, // bRequest
+ 0x30, // wValue
+ 0x00, // wIndex
+ 0x00, // wLength
+};
+
+hifusb_setup_packet_t setDevFeatureU2Pkt =
+{
+ 0x00, // bmRequestType
+ 0x03, // bRequest
+ 0x31, // wValue
+ 0x00, // wIndex
+ 0x00, // wLength
+};
+
+hifusb_setup_packet_t setDevFeatureLtmPkt =
+{
+ 0x00, // bmRequestType
+ 0x03, // bReques: set featuret
+ 0x32, // wValue: feature selector LTM_ENABLE
+ 0x00, // wIndex
+ 0x00, // wLength
+};
+
+hifusb_setup_packet_t setInfxFeatureWkPkt =
+{
+ 0x01, // bmRequestType
+ 0x03, // bRequest: set feature
+ 0x00, // wValue: function suspend feature selector
+ 0x0200, // wIndex: suspend option + nInterface
+ 0x00,
+};
+
+hifusb_setup_packet_t setInfxFeatureSuspendPkt =
+{
+ 0x01, // bmRequestType
+ 0x03, // bRequest: set feature
+ 0x00, // wValue: function suspend feature selector
+ 0x0300, // wIndex: suspend option + nInterface
+ 0x00,
+};
+
+hifusb_setup_packet_t setInfxFeatureResumePkt =
+{
+ 0x01, // bmRequestType
+ 0x03, // bRequest: set feature
+ 0x00, // wValue: function suspend feature selector
+ 0x00, // wIndex: suspend option + nInterface
+ 0x00,
+};
+
+hifusb_setup_packet_t clsDevFeatureRemoteWkPkt =
+{
+ 0x00, // bmRequestType
+ 0x01, // bRequest
+ 0x01, // wValue
+ 0x00, // wIndex
+ 0x00, // wLength
+};
+
+hifusb_setup_packet_t clsDevFeatureU1Pkt =
+{
+ 0x00, // bmRequestType
+ 0x01, // bRequest
+ 0x30, // wValue
+ 0x00, // wIndex
+ 0x00, // wLength
+};
+
+hifusb_setup_packet_t clsDevFeatureU2Pkt =
+{
+ 0x00, // bmRequestType
+ 0x01, // bRequest
+ 0x31, // wValue
+ 0x00, // wIndex
+ 0x00, // wLength
+};
+
+hifusb_setup_packet_t clsDevFeatureLtmPkt =
+{
+ 0x00, // bmRequestType
+ 0x01, // bRequest
+ 0x32, // wValue
+ 0x00, // wIndex
+ 0x00, // wLength
+};
+
+hifusb_setup_packet_t clsInfxFeatureWkPkt =
+{
+ 0x01, // bmRequestType
+ 0x01, // bRequest: clear feature
+ 0x00, // wValue: function suspend feature selector
+ 0x00, // wIndex: nInterface
+ 0x00, // wLength
+};
+
+/****************************************************************************
+ Private Function
+***************************************************************************/
+static void usbc_ut_std_req(void *p_param)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ // set control setup packet
+ usbc_core_dispatch_control_setup_packet(pUsbCore, p_param);
+}
+
+static kal_uint16 usbc_ut_get_status(void *p_param)
+{
+ usbc_core_t* pUsbCore;
+ kal_uint16* pStatus;
+
+ usbc_ut_std_req(p_param);
+
+ pUsbCore = usbc_core_get_instance();
+ pStatus = (kal_uint16*)pUsbCore->control_request_buffer;
+
+ return *pStatus;
+}
+
+
+/****************************************************************************
+ Public Fake Function
+***************************************************************************/
+kal_uint16 usbc_ut_fake_query_func_wk_status(kal_uint8 class_device_id)
+{
+ return fake_class_func.infx_status;
+}
+
+void usbc_ut_fake_notify_func_wk_ability(kal_uint8 class_device_id, kal_bool ability)
+{
+ if (ability)
+ {
+ fake_class_func.infx_status |= 0x0002;
+ }
+ else
+ {
+ fake_class_func.infx_status &= 0xFFFD;
+ }
+}
+
+kal_bool usbc_ut_fake_notify_retry(kal_uint8 nInterface)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_device_id = 0;
+
+ fake_class_func.nRetry++;
+ if( fake_class_func.nRetry >= 5)
+ {
+ pUsbCore->is_func_be_accessed[class_device_id] = KAL_TRUE;
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool usbc_ut_fake_hif_remote_wakeup()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_device_id = pUsbCore->class_interface[0].class_device_id;
+ kal_uint16 status;
+ usbc_usb_state_e dev_state;
+ usbc_ind_t ind_to_enqueue;
+
+ // device resume
+ dev_state = USBC_USB_STATE_RESUME;
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)dev_state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+
+ return KAL_TRUE;
+}
+
+kal_bool usbc_ut_fake_set_control_request(kal_uint8 *buffer, kal_uint32 length, usbc_control_request_type_e type)
+{
+ return KAL_TRUE;
+}
+/****************************************************************************
+ Test Function
+ ***************************************************************************/
+kal_bool
+usbc_ut_is_dev_attached(void *p_parm,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_str_sz)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ usbc_fake_hif_factory();
+
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_ut_check_1st_infx(void *p_param,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_str_sz)
+{
+ kal_uint8 total_interface_number;
+ kal_bool ans[6] = {KAL_TRUE, KAL_FALSE, KAL_TRUE, KAL_FALSE, KAL_TRUE, KAL_FALSE};
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ kal_uint8 i;
+ kal_bool isFirstInfx;
+
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ total_interface_number = 6;
+ }
+ else
+ {
+ total_interface_number = 3;
+ }
+
+ for( i=0; i<total_interface_number; i++)
+ {
+ isFirstInfx = usbc_core_is_1st_interface(i);
+ if (isFirstInfx != ans[i])
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_ut_get_1st_infx(void *p_param,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_str_sz)
+{
+ // set test parameters
+ kal_uint8 total_dev_num = 3;
+ kal_uint8 ans[3] = {0, 2, 4};
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ kal_uint8 i;
+ kal_uint8 nFirstInfx;
+
+ for( i=0; i<total_dev_num; i++)
+ {
+ nFirstInfx = usbc_class_device_get_1st_interface(i);
+ if (nFirstInfx != ans[i])
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_ut_set_dev_feature(void *p_parm,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_st_ss)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint16 status = usbc_ut_get_status(&getDevStatusPkt);
+
+ if( 0x0000 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ // set LTM enable
+ usbc_ut_std_req(&setDevFeatureLtmPkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0010 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+
+ // set U2 enable
+ usbc_ut_std_req(&setDevFeatureU2Pkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0018 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+
+ // set U1 enable
+ usbc_ut_std_req(&setDevFeatureU1Pkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x001C != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+
+ // clear U1 enable
+ usbc_ut_std_req(&clsDevFeatureU1Pkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0018 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+
+ // clear U2 enable
+ usbc_ut_std_req(&clsDevFeatureU2Pkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0010 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+
+ // clear LTM enable
+ usbc_ut_std_req(&clsDevFeatureLtmPkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0000 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+ }
+ else
+ {
+ // set remote wakeup
+ usbc_ut_std_req(&setDevFeatureRemoteWkPkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0002 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+
+ // clear remote wakeup
+ usbc_ut_std_req(&clsDevFeatureRemoteWkPkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0000 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+
+kal_bool
+usbc_ut_set_infx_feature(void *p_parm,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_st_ss)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint16 status;
+
+ // non 1st interface of any function, the reported status is 0
+ status = usbc_ut_get_status(&getNon1stInfxStatusPkt);
+ if( 0x0000 != (status & 0xFFFF))
+ {
+ return KAL_FALSE;
+ }
+
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ // 1st interface of a super-speed function
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ if ( 0x0001 != (status & 0xFFFF))
+ {
+ return KAL_FALSE;
+ }
+ }
+ // 1st interface of a non super-speed function
+ else
+ {
+ if( 0x0000 != (status & 0xFFFF))
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ // set feature to enable function remote wakeup
+ usbc_ut_std_req(&setInfxFeatureWkPkt);
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( 0x0003 != (status & 0xFFFF))
+ {
+ return KAL_FALSE;
+ }
+
+ // clear feature to disable function remote wakeup
+ usbc_ut_std_req(&clsInfxFeatureWkPkt);
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( 0x0001 != (status & 0xFFFF))
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_ut_func_suspend_resume(void *p_parm,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_st_ss)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_device_id = pUsbCore->class_interface[0].class_device_id;
+ kal_uint16 status;
+
+ // function suspend is supported in super-speed device only
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ // set feature to enable function remote wakeup and set function to suspend
+ usbc_ut_std_req(&setInfxFeatureSuspendPkt);
+ while( !pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend ||
+ 0x0003 != (status & 0xFFFF) )
+ {
+ return KAL_FALSE;
+ }
+ // set feature to disable function remote wakeu and resume function
+ usbc_ut_std_req(&setInfxFeatureResumePkt);
+ while( pUsbCore->class_device[class_device_id].is_func_suspend)
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend ||
+ 0x0001 != (status & 0xFFFF) )
+ {
+ return KAL_FALSE;
+ }
+
+ // set feature to enable function remote wakeup and set function to suspend
+ usbc_ut_std_req(&setInfxFeatureSuspendPkt);
+ while( !pUsbCore->class_device[class_device_id].is_func_suspend)
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend ||
+ 0x0003 != (status & 0xFFFF) )
+ {
+ return KAL_FALSE;
+ }
+ // clear feature to disable function remote wakeu and resume function
+ usbc_ut_std_req(&clsInfxFeatureWkPkt);
+ while( pUsbCore->class_device[class_device_id].is_func_suspend)
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend ||
+ 0x0001 != (status & 0xFFFF) )
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_ut_func_suspend_remote_wk(void *p_parm,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_st_ss)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_device_id = pUsbCore->class_interface[0].class_device_id;
+ kal_uint16 status;
+ fake_class_func.nRetry = 0;
+
+ // function suspend is supported in super-speed device only
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ // set feature to enable function remote wakeup and set function to suspend
+ usbc_ut_std_req(&setInfxFeatureSuspendPkt);
+ while( !pUsbCore->class_device[class_device_id].is_func_suspend)
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend ||
+ 0x0003 != (status & 0xFFFF) )
+ {
+ return KAL_FALSE;
+ }
+ // remote wakeup to resume the function
+ usbc_class_device_func_remote_wk(class_device_id);
+ while( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend ||
+ 0x0003 != (status & 0xFFFF) )
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_ut_dev_suspend_resume(void *p_parm,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_st_ss)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_device_id = pUsbCore->class_interface[0].class_device_id;
+ kal_uint16 status;
+ usbc_usb_state_e dev_state;
+ usbc_ind_t ind_to_enqueue;
+
+
+ /* test for USB non super-speed devices and supoer-speed devices without function suspend */
+ // device suspend
+ dev_state = USBC_USB_STATE_SUSPENDING;
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)dev_state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ while ( USBC_USB_STATE_SUSPENDED!= pUsbCore->state )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // device resume
+ dev_state = USBC_USB_STATE_RESUME;
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)dev_state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ while ( USBC_USB_STATE_RESUME != pUsbCore->state )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // test for USB super-speed device with function suspend
+ if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
+ {
+ // set function to be suspended
+ usbc_ut_std_req(&setInfxFeatureSuspendPkt);
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // device suspend
+ dev_state = USBC_USB_STATE_SUSPENDING;
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)dev_state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ while ( USBC_USB_STATE_SUSPENDED != pUsbCore->state )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // device resume
+ dev_state = USBC_USB_STATE_RESUME;
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)dev_state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ while ( USBC_USB_STATE_RESUME != pUsbCore->state )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // set the function to be resumed
+ usbc_ut_std_req(&setInfxFeatureResumePkt);
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_ut_dev_suspend_remote_wk(void *p_parm,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_st_ss)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_device_id = pUsbCore->class_interface[0].class_device_id;
+ kal_uint16 status;
+ usbc_usb_state_e dev_state;
+ usbc_ind_t ind_to_enqueue;
+
+ // for non super-speed device, use device remote wakeup
+ if ( pUsbCore->speed != USBC_USB_SPEED_USB30 )
+ {
+ // set feature to enable device remote wakeup
+ usbc_ut_std_req(&setDevFeatureRemoteWkPkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0002 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+
+ // device suspend
+ dev_state = USBC_USB_STATE_SUSPENDING;
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)dev_state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ while ( USBC_USB_STATE_SUSPENDED!= pUsbCore->state )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // device remote wakeup
+ usbc_class_device_func_remote_wk(class_device_id);
+ while ( USBC_USB_STATE_RESUME != pUsbCore->state )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // clear remote wakeup
+ usbc_ut_std_req(&clsDevFeatureRemoteWkPkt);
+ status = usbc_ut_get_status(&getDevStatusPkt);
+ if( 0x0000 != (status & 0xFFFE))
+ {
+ return KAL_FALSE;
+ }
+ }
+ else
+ {
+ // set feature to enable function remote wakeup and set function to suspend
+ usbc_ut_std_req(&setInfxFeatureSuspendPkt);
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend ||
+ 0x0003 != (status & 0xFFFF) )
+ {
+ return KAL_FALSE;
+ }
+
+ // device suspend
+ dev_state = USBC_USB_STATE_SUSPENDING;
+ ind_to_enqueue.type = USBC_IND_DEV_EVENT;
+ ind_to_enqueue.ext = 0;
+ ind_to_enqueue.data = (kal_uint8)dev_state;
+ usbc_enqueue_ind(&ind_to_enqueue);
+ hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
+ while ( USBC_USB_STATE_SUSPENDED!= pUsbCore->state )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ if ( !pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // device resume and function remote wakeup
+ usbc_class_device_func_remote_wk(class_device_id);
+ while ( USBC_USB_STATE_RESUME != pUsbCore->state ||
+ pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+ if ( pUsbCore->class_device[class_device_id].is_func_suspend )
+ {
+ return KAL_FALSE;
+ }
+
+ // clear feature to disable function remote wakeup
+ usbc_ut_std_req(&clsInfxFeatureWkPkt);
+ status = usbc_ut_get_status(&get1stInfxStatusPkt);
+ if ( 0x0001 != (status & 0xFFFF))
+ {
+ return KAL_FALSE;
+ }
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool
+usbc_ut_notification_timeout(void *p_parm,
+ kal_char *p_ret_err_str,
+ kal_uint32 *p_ret_err_st_ss)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 class_device_id = 0;
+ fake_class_func.nRetry = 0;
+
+ usbc_set_wk_notify_timer((class_device_id));
+ while ( !pUsbCore->is_func_be_accessed[class_device_id] )
+ {
+ kal_sleep_task(USBC_UT_BLOCK_TICK_T);
+ }
+
+ if( fake_class_func.nRetry >=5 )
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+
+//#define ERR_STR "This is a sample error case"
+//kal_bool
+//usbc_ut_get_1st_infx(void *p_param,
+// kal_char *p_ret_err_str,
+// kal_uint32 *p_ret_err_str_sz)
+//{
+ /* Test case is FAILED */
+// strncpy(p_ret_err_str, ERR_STR, MIN(strlen(ERR_STR), *p_ret_err_str_sz));
+// *p_ret_err_str_sz = MIN(strlen(ERR_STR), *p_ret_err_str_sz);
+
+// return KAL_FALSE;
+//}
+
+
+/****************************************************************************
+ USBCORE Task Init Function
+ ***************************************************************************/
+
+ST_TCASE_T st_tcase_g[] = {
+ { "Check the attachment of the device",
+ usbc_ut_is_dev_attached,
+ NULL
+ },
+ { "Check 1st interface",
+ usbc_ut_check_1st_infx,
+ NULL
+ },
+ { "Get 1st interface",
+ usbc_ut_get_1st_infx,
+ NULL
+ },
+ { "Set/clear features of device",
+ usbc_ut_set_dev_feature,
+ NULL
+ },
+ { "Set/clear feature of interface",
+ usbc_ut_set_infx_feature,
+ NULL
+ },
+ { "Function wakeup notification timeout and retry",
+ usbc_ut_notification_timeout,
+ NULL
+ },
+ { "Function suspend and resume by host",
+ usbc_ut_func_suspend_resume,
+ NULL
+ },
+ { "Function suspend and remote wakeup by class devices",
+ usbc_ut_func_suspend_remote_wk,
+ NULL
+ },
+ { "Device suspend and resume by host",
+ usbc_ut_dev_suspend_resume,
+ NULL
+ },
+ { "Device suspend and remote wakeup by class devices",
+ usbc_ut_dev_suspend_remote_wk,
+ NULL
+ }
+};
+
+kal_uint32 st_tcase_count_g = sizeof(st_tcase_g) / sizeof(ST_TCASE_T);
+
+kal_bool usbcore_ut_st_create (void)
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+
+ // set fefault fake class device value
+ fake_class_func.infx_status = 0x0001;
+ fake_class_func.nRetry = 0;
+
+ pUsbCore->speed = USBC_USB_SPEED_USB30;
+
+ return st_reg_test(ST_MOD_NAME, /* p_mod_name */
+ st_tcase_g, /* p_tcase */
+ st_tcase_count_g /* tcase_num */
+ );
+}
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_ut_except.c b/mcu/middleware/hif/usbcore/src/usbcore_ut_except.c
new file mode 100644
index 0000000..ce60403
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_ut_except.c
@@ -0,0 +1,129 @@
+#include "kal_public_api.h"
+#include "intrCtrl.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+
+#include "usbcore_except.h"
+
+static usbc_class_device_info_t dev_info_s;
+static usbc_class_device_instance_t *dev_inst_s = NULL;
+static kal_uint8 ct_data_buf[2048];
+
+#define MIN(_a, _b) (((_a) <= (_b)) ? (_a) : (_b))
+
+void usbc_at_notify_usb_state(kal_uint8 class_device_id, usbc_usb_state_e state)
+{
+ ASSERT(0);
+}
+
+void usbc_at_notify_usb_speed(kal_uint8 class_device_id, usbc_usb_speed_e speed)
+{
+ ASSERT(dev_inst_s);
+ ASSERT(class_device_id == dev_inst_s->id);
+}
+
+void usbc_at_notify_control_setup_packet(kal_uint8 class_device_id, usbc_setup_packet_t *packet)
+{
+ kal_bool result;
+
+ ASSERT(dev_inst_s);
+ ASSERT(class_device_id == dev_inst_s->id);
+
+ if (packet->bmRequestType & 0x80) { // IN
+ ASSERT(packet->wLength > 0);
+ result = usbc_class_device_submit_control_request(
+ class_device_id, /* kal_uint8 class_device_id */
+ NULL, /* kal_uint8 *buffer */
+ 0, /* kal_uint32 length */
+ USBC_CONTROL_REQUEST_TYPE_SEND); /* usbc_control_request_type_e */
+ } else { // OUT
+ result = usbc_class_device_submit_control_request(
+ class_device_id, /* kal_uint8 class_device_id */
+ ct_data_buf, /* kal_uint8 *buffer */
+ MIN(packet->wLength, sizeof(ct_data_buf)), /* kal_uint32 length */
+ USBC_CONTROL_REQUEST_TYPE_RECEIVE); /* usbc_control_request_type_e */
+ }
+ ASSERT(result);
+}
+
+void usbc_at_notify_control_complete(kal_uint8 class_device_id)
+{
+ ASSERT(dev_inst_s);
+ ASSERT(class_device_id == dev_inst_s->id);
+ return;
+}
+
+void usbc_at_exception(void)
+{
+ static kal_uint32 cnt = 0;
+ kal_uint32 mask;
+ kal_uint32 num_gpd;
+ void *head_gpd;
+ void *tail_gpd;
+ void *rx_gpd;
+ void *next_gpd;
+ usbc_except_link_st_e link_state;
+
+ if (cnt++ < 5000) {
+ return;
+ }
+
+ ASSERT(2 == qbmt_alloc_q_no_tail(QBM_TYPE_HIF_DL, 2, &head_gpd, &tail_gpd));
+ for (rx_gpd = head_gpd; rx_gpd; rx_gpd = next_gpd) {
+ next_gpd = QBM_DES_GET_NEXT(rx_gpd);
+
+ QBM_DES_SET_ALLOW_LEN(rx_gpd, 512);
+ qbm_cal_set_checksum((kal_uint8*)rx_gpd);
+ QBM_CACHE_FLUSH(rx_gpd, sizeof(qbm_gpd));
+ rx_gpd = QBM_DES_GET_NEXT(rx_gpd);
+
+ if (rx_gpd == tail_gpd) break;
+ }
+
+ mask = SaveAndSetIRQMask();
+
+ dev_info_s.class_type = USBC_CLASS_TYPE_CDC_ACM;
+ dev_info_s.total_pipes = 3;
+ dev_info_s.pipe_type[0] = USBC_PIPE_TYPE_CDC_ACM_COMM_IN;
+ dev_info_s.pipe_type[1] = USBC_PIPE_TYPE_CDC_ACM_DATA_IN;
+ dev_info_s.pipe_type[2] = USBC_PIPE_TYPE_CDC_ACM_DATA_OUT;
+ dev_info_s.notify_usb_state = usbc_at_notify_usb_state;
+ dev_info_s.notify_usb_speed = usbc_at_notify_usb_speed;
+ dev_info_s.notify_control_setup_packet = usbc_at_notify_control_setup_packet;
+ dev_info_s.notify_control_complete = usbc_at_notify_control_complete;
+ dev_info_s.notify_alternate_setting = NULL;
+ dev_info_s.notify_pipe_complete[0] = NULL;
+ dev_info_s.notify_pipe_complete[1] = NULL;
+ dev_info_s.notify_pipe_complete[2] = NULL;
+ dev_info_s.notify_pipe_stall[0] = NULL;
+ dev_info_s.notify_pipe_stall[1] = NULL;
+ dev_info_s.notify_pipe_stall[2] = NULL;
+
+ dev_inst_s = usbc_except_reset_ch(&dev_info_s);
+ ASSERT(dev_inst_s);
+ ASSERT(usbc_except_enum_loop());
+
+ ASSERT(usbc_except_init());
+ ASSERT(usbc_except_submit_gpd(dev_inst_s->id, dev_inst_s->queue_no_for_pipe[1], head_gpd, tail_gpd));
+
+ do {
+ usbc_except_hif_poll(dev_inst_s->id);
+
+ ASSERT(usbc_except_poll_queue(dev_inst_s->id, dev_inst_s->queue_no_for_pipe[1], &head_gpd, &tail_gpd, &num_gpd));
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ ASSERT(usbc_except_hif_state(dev_inst_s->id, dev_inst_s->queue_no_for_pipe[1], &link_state));
+#if 0
+/* under construction !*/
+#endif
+
+ } while(1);
+
+ RestoreIRQMask(mask);
+}
diff --git a/mcu/middleware/hif/usbcore/src/usbcore_vendreq.c b/mcu/middleware/hif/usbcore/src/usbcore_vendreq.c
new file mode 100644
index 0000000..92aeb15
--- /dev/null
+++ b/mcu/middleware/hif/usbcore/src/usbcore_vendreq.c
@@ -0,0 +1,209 @@
+/*!
+ * @file usbcore_usbstd.c
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides usb standard request handler function
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "usbcore_common.h"
+#include "usbcore_usbstd.h"
+#include "usbcore_main.h"
+#include "usbcore_hif.h"
+#ifdef __USB_OSD_SUPPORT__
+#include "usbosd.h"
+#endif /* __USB_OSD_SUPPORT__ */
+
+
+#define MIN(_a, _b) (((_a) <= (_b)) ? (_a) : (_b))
+
+/*
+ * Define Microsoft OS feature descriptor
+ */
+#define USBC_FEATURE_EXT_COMPAT_ID 0x0004
+#define USBC_MAX_OS_FEATURE_DESC_LENGTH 40
+static usbc_ext_compat_id_os_feature_descriptor_t usbc_os_descriptor =
+{
+ USBC_MAX_OS_FEATURE_DESC_LENGTH, /* dwLength */
+ 0x0100, /* bcdVersion */
+ USBC_FEATURE_EXT_COMPAT_ID, /* wIndex */
+ 0x01, /* bCount */
+ {0,0,0,0,0,0,0}, /* bPads_1 */
+ 0x00, /* bFirstInterfaceNumber */
+ 0x01, /* bInterfaceCount */
+ {0x41, 0x4C, 0x54, 0x52, 0x43, 0x46, 0x47, 0x00}, /* compatibleID (ALTRCFG) */
+ {0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* subcompatibleID (default:2) */
+ {0,0,0,0,0,0} /* bPads_2 */
+};
+
+#ifdef __USB_OSD_SUPPORT__
+static usbc_ext_compat_id_os_feature_descriptor_t usbc_mod_str_descriptor =
+{
+ USBC_MAX_OS_FEATURE_DESC_LENGTH, /* dwLength */
+ 0x0100, /* bcdVersion */
+ USBC_FEATURE_EXT_COMPAT_ID, /* wIndex */
+ 0x01, /* bCount */
+ {0,0,0,0,0,0,0}, /* bPads_1 */
+ 0x00, /* bFirstInterfaceNumber */
+ 0x01, /* bInterfaceCount */
+ {0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00}, /* compatibleID (WINUSB) */
+ {0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* subcompatibleID (default:2) */
+ {0,0,0,0,0,0} /* bPads_2 */
+};
+#endif
+
+static void usbc_core_handle_get_ms_descriptor()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK;
+ kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+ kal_uint16 wIndex = pUsbCore->setup_packet.wIndex;
+ kal_uint16 wLength = pUsbCore->setup_packet.wLength;
+ kal_uint8* pBuffer = NULL;
+ kal_uint32 length = 0;
+
+ if ( bRecip == USBC_REQUEST_RECIP_DEVICE &&
+ pUsbCore->morphing_enable )
+ {
+ if (wValue == 0x00 && wIndex == USBC_FEATURE_EXT_COMPAT_ID)
+ {
+ /* Morphing device must not report the compatible and subcompatible ID after a configuration is selected */
+ if (pUsbCore->state == USBC_USB_STATE_ATTACHED) {
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ return;
+ }
+ pUsbCore->morph_active = KAL_TRUE;
+ if (pUsbCore->dev_param->morphing_sub_id >= 2 && pUsbCore->dev_param->morphing_sub_id <= 4)
+ { /*
+ * 0x32 -> '2', 0x33 -> '3', 0x34 -> '4'
+ */
+ usbc_os_descriptor.subcompatibleID[0] = 0x30 + pUsbCore->dev_param->morphing_sub_id;
+ }
+
+ length = MIN(USBC_MAX_OS_FEATURE_DESC_LENGTH, wLength);
+ pBuffer = (kal_uint8*)&usbc_os_descriptor;
+ usbc_core_set_control_request(pBuffer, length, USBC_CONTROL_REQUEST_TYPE_SEND);
+ }
+ } else
+ {
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+}
+
+#ifdef __USB_OSD_SUPPORT__
+/* Debug for Win8 U3 enumeration failed issue */
+static void usbc_core_handle_get_mod_str_descriptor()
+{
+ usbc_core_t* pUsbCore = usbc_core_get_instance();
+ kal_uint8 bRecip = pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK;
+ kal_uint16 wValue = pUsbCore->setup_packet.wValue;
+ kal_uint16 wIndex = pUsbCore->setup_packet.wIndex;
+ kal_uint16 wLength = pUsbCore->setup_packet.wLength;
+ kal_uint8* pBuffer = NULL;
+ kal_uint32 length = 0;
+
+ if ( bRecip == USBC_REQUEST_RECIP_DEVICE )
+ {
+ if (wValue == 0x00 && wIndex == USBC_FEATURE_EXT_COMPAT_ID)
+ {
+
+ length = MIN(USBC_MAX_OS_FEATURE_DESC_LENGTH, wLength);
+ pBuffer = (kal_uint8*)&usbc_mod_str_descriptor;
+ usbc_core_set_control_request(pBuffer, length, USBC_CONTROL_REQUEST_TYPE_SEND);
+ }
+ } else
+ {
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+}
+#endif
+
+void usbc_core_handle_vendor_request()
+{
+ static struct _usbc_request_entry {
+ kal_uint32 request;
+ void (*request_handler)();
+ } request_entry_table[] = {
+ {USBC_REQ_GET_MS_DESCRIPTOR, usbc_core_handle_get_ms_descriptor},
+#ifdef __USB_OSD_SUPPORT__
+ {VENDOR_CODE_1, usbc_core_handle_get_mod_str_descriptor},
+ {VENDOR_CODE_2, usbc_core_handle_get_mod_str_descriptor},
+#endif
+ };
+
+ kal_uint32 request_entry_table_num = sizeof(request_entry_table)/sizeof(struct _usbc_request_entry);
+ usbc_core_t *pUsbCore = usbc_core_get_instance();
+ kal_uint32 idx;
+ kal_uint8 bInterface;
+
+ for (idx = 0; idx < request_entry_table_num; idx++) {
+ if (pUsbCore->setup_packet.bRequest == request_entry_table[idx].request) break;
+ }
+
+ if (idx < request_entry_table_num)
+ {
+ request_entry_table[idx].request_handler();
+ } else
+ { /* If request handler can't be found, search all interface and notify class driver if existed */
+ if ((pUsbCore->setup_packet.bmRequestType & USBC_REQUEST_RECIP_MASK) == USBC_REQUEST_RECIP_INTERFACE)
+ {
+ kal_uint8 i;
+ bInterface = pUsbCore->setup_packet.wIndex & 0xff;
+
+ /* notify class driver by interface if exist */
+ for ( i=0 ; i< pUsbCore->total_class_interfaces; i++ ) {
+ if ( (pUsbCore->class_interface[i].interface_no == bInterface) &&
+ (pUsbCore->class_interface[i].state == USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE) &&
+ (pUsbCore->class_interface[i].notify_control_setup_packet != NULL)) {
+ break;
+ }
+ }
+
+ if ( i == pUsbCore->total_class_interfaces ) {
+ /* incorrect request */
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ } else {
+ usbc_core_indicate_control_setup_packet(i, &pUsbCore->setup_packet);
+ }
+ } else
+ { // not support
+ usbc_core_set_control_request(NULL, 0, HIFUSB_CONTROL_REQUEST_TYPE_STALL);
+ }
+ }
+}
+
+
diff --git a/mcu/middleware/hif/usbidle/include/usbidle_hif.h b/mcu/middleware/hif/usbidle/include/usbidle_hif.h
new file mode 100644
index 0000000..a837730
--- /dev/null
+++ b/mcu/middleware/hif/usbidle/include/usbidle_hif.h
@@ -0,0 +1,47 @@
+/*!
+ * @file usbidle_main.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main definitions of usbcore
+ */
+
+#ifndef _USBIDLE_HIF_H
+#define _USBIDLE_HIF_H
+
+void usb_idle_suspend_done_handle(void);
+
+#endif // _USBIDLE_MAIN_H
+
diff --git a/mcu/middleware/hif/usbidle/include/usbidle_main.h b/mcu/middleware/hif/usbidle/include/usbidle_main.h
new file mode 100644
index 0000000..10d06dc
--- /dev/null
+++ b/mcu/middleware/hif/usbidle/include/usbidle_main.h
@@ -0,0 +1,84 @@
+/*!
+ * @file usbidle_main.h
+ * @author Roger Huang <chaomin.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main definitions of usbcore
+ */
+
+#ifndef _USBIDLE_MAIN_H
+#define _USBIDLE_MAIN_H
+
+#include "hif_mw_msgid.h"
+#include "kal_public_api.h"
+
+#define USBIDLE_MUTEX_LOCK(_s) kal_take_enh_mutex(_s)
+#define USBIDLE_MUTEX_UNLOCK(_s) kal_give_enh_mutex(_s)
+
+typedef struct _usbidle_t{
+
+ /*!
+ * @brife use to notify whether USBIDLE has to gate the clock of USB IP or not
+ */
+ kal_bool usbidle_clock_off;
+
+ /*!
+ * @brife use to notify whether USBIDLE has to ask L4 to do power saving
+ */
+ kal_bool usbidle_l4_power_saving;
+
+ /*!
+ * @brief mutex for setting usbidle_clock_off
+ */
+ //kal_enhmutexid usbidle_clock_gating_mutex;
+
+ /*!
+ * @brief mutex for setting usbidle_L4 power saving
+ */
+ kal_enhmutexid usbidle_l4_power_saving_mutex;
+
+ kal_spinlockid usbidle_notify_driver_spinlock;
+
+} usbidle_t;
+
+
+/*!
+ * @brief get the instance of USBIDLE module
+ * @return pointer to usbidle_t* instance if success, NULL if fail
+ */
+usbidle_t* usbidle_get_instance(void);
+
+#endif // _USBIDLE_MAIN_H
+
diff --git a/mcu/middleware/hif/usbidle/src/usbidle_hif.c b/mcu/middleware/hif/usbidle/src/usbidle_hif.c
new file mode 100644
index 0000000..68af3dc
--- /dev/null
+++ b/mcu/middleware/hif/usbidle/src/usbidle_hif.c
@@ -0,0 +1,59 @@
+/*!
+ * @file usbidle_hif.c
+ * @author Bo-Kai Huang <bo-kai.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main functions of usbidle
+ */
+
+#include "kal_public_api.h"
+#include "intrCtrl.h"
+#include "usbidle_hif.h"
+#include "usbidle_main.h"
+#include "hif_usb.h"
+
+void usb_idle_suspend_done_handle(void)
+{
+ usbidle_t* pUsbIdle = usbidle_get_instance();
+
+ kal_take_spinlock(pUsbIdle->usbidle_notify_driver_spinlock, KAL_INFINITE_WAIT);
+
+ if(pUsbIdle->usbidle_clock_off)
+ {
+ hifusb_suspend_done_handle(); // notification to HIF driver for the completion of USB suspending
+ }
+
+ kal_give_spinlock(pUsbIdle->usbidle_notify_driver_spinlock);
+}
diff --git a/mcu/middleware/hif/usbidle/src/usbidle_if.c b/mcu/middleware/hif/usbidle/src/usbidle_if.c
new file mode 100644
index 0000000..5853943
--- /dev/null
+++ b/mcu/middleware/hif/usbidle/src/usbidle_if.c
@@ -0,0 +1,96 @@
+/*!
+ * @file usbidle_task.c
+ * @author Bo-Kai Huang <bo-kai.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main functions of usbidle
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "sysservice_msgid.h"
+#include "usbidle_main.h"
+#include "usbidle_if.h"
+#include "ps_public_l4_msgid.h"
+#include "ps_public_struct.h"
+
+void usb_idle_set_clockGating(kal_bool gatingValue)
+{
+ usbidle_t* pUsbIdle = usbidle_get_instance();
+
+ //USBIDLE_MUTEX_LOCK(pUsbIdle->usbidle_clock_gating_mutex);
+ kal_take_spinlock(pUsbIdle->usbidle_notify_driver_spinlock, KAL_INFINITE_WAIT);
+ pUsbIdle->usbidle_clock_off = gatingValue;
+ kal_give_spinlock(pUsbIdle->usbidle_notify_driver_spinlock);
+ //USBIDLE_MUTEX_UNLOCK(pUsbIdle->usbidle_clock_gating_mutex);
+}
+
+void usb_idle_set_l4_power_saving(kal_bool gatingValue)
+{
+ usbidle_t* pUsbIdle = usbidle_get_instance();
+
+ USBIDLE_MUTEX_LOCK(pUsbIdle->usbidle_l4_power_saving_mutex);
+ pUsbIdle->usbidle_l4_power_saving = gatingValue;
+ USBIDLE_MUTEX_UNLOCK(pUsbIdle->usbidle_l4_power_saving_mutex);
+}
+
+void usb_idle_event_notify_to_l4(kal_bool usb_suspend, kal_bool remote_wk)
+{
+#if !defined(L4_NOT_PRESENT) && !defined(__L4_TASK_DISABLE__)
+ l4c_usb_suspend_req_struct *rsp_msg_p;
+ msg_type msg_id;
+ usbidle_t* pUsbIdle = usbidle_get_instance();
+
+ msg_id = usb_suspend? MSG_ID_L4C_USB_SUSPEND_REQ:MSG_ID_L4C_USB_RESUME_REQ;
+ rsp_msg_p = (l4c_usb_suspend_req_struct*)construct_local_para(sizeof(l4c_usb_suspend_req_struct), TD_RESET);
+ ASSERT(rsp_msg_p);
+ rsp_msg_p->remote_wakeup_enable = remote_wk;
+
+ if(usb_suspend && !pUsbIdle->usbidle_l4_power_saving)
+ {
+ return;
+ }
+
+ /*
+ * Send ILM to L4 to notify power saving
+ */
+ msg_send6(MOD_USBIDLE, // src module
+ MOD_L4C, // dst module
+ 0, // sap id
+ msg_id,
+ (local_para_struct*)rsp_msg_p,
+ 0); //msg id
+#endif
+}
diff --git a/mcu/middleware/hif/usbidle/src/usbidle_task.c b/mcu/middleware/hif/usbidle/src/usbidle_task.c
new file mode 100644
index 0000000..84e329e
--- /dev/null
+++ b/mcu/middleware/hif/usbidle/src/usbidle_task.c
@@ -0,0 +1,152 @@
+/*!
+ * @file usbidle_task.c
+ * @author Bo-Kai Huang <bo-kai.haung@mediatek.com>
+ * @version 1.0
+ * @section LICENSE
+ *
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ * @section DESCRIPTION
+ * This file provides main functions of usbidle
+ */
+
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "sysservice_msgid.h"
+#include "usbidle_main.h"
+#include "usbidle_hif.h"
+#include "usbidle_if.h"
+#include "hif_usb.h"
+#ifdef __MTK_MD_DIRECT_USB_SUPPORT__
+#include "ufpm_usbcore.h"
+#include "ps_public_l4_msgid.h"
+#endif
+
+static usbidle_t usbidle_inst_s;
+
+usbidle_t* usbidle_get_instance()
+{
+ return &usbidle_inst_s;
+}
+
+static void usb_idle_task_main(task_entry_struct* task_entry_ptr)
+{
+ ilm_struct current_ilm;
+ kal_set_active_module_id(MOD_USBIDLE);
+ kal_mem_set(¤t_ilm, 0, sizeof(ilm_struct));
+
+ while (1)
+ {
+ /* msg_receive_extq will block, therefore we poll if any message
+ exist first */
+ if ( KAL_TRUE == msg_receive_extq(¤t_ilm) )
+ {
+ kal_set_active_module_id(current_ilm.dest_mod_id);
+
+ switch (current_ilm.msg_id)
+ {
+#ifndef __MTK_MD_DIRECT_USB_SUPPORT__
+ case MSG_ID_USBCORE_SUSPEND_TO_IDLE:
+ usb_idle_suspend_done_handle(); // notification to HIF driver for the completion of USB suspending
+ break;
+
+ case MSG_ID_USBCORE_IDLE_NOTIFY_TO_L4:
+ {
+ usbcore_usbidle_l4_power_saving_req_struct *rsp_msg_l4_power_p = (usbcore_usbidle_l4_power_saving_req_struct*)current_ilm.local_para_ptr;
+ usb_idle_event_notify_to_l4(rsp_msg_l4_power_p->notify_suspend, rsp_msg_l4_power_p->notify_suspend_with_remote_wk);
+ break;
+ }
+#else
+#ifdef __UFPM_AT_COMMAND_SUPPORT__
+ case MSG_ID_L4C_UFPM_ENABLE_MD_FAST_PATH_REQ:
+ case MSG_ID_L4C_UFPM_DISABLE_MD_FAST_PATH_REQ:
+ case MSG_ID_L4C_UFPM_ACTIVATE_MD_FAST_PATH_REQ:
+ case MSG_ID_L4C_UFPM_DEACTIVATE_MD_FAST_PATH_REQ:
+ ufpm_redirect_l4_ilm(¤t_ilm);
+ break;
+#endif
+#endif
+ default:
+ break;
+ }
+
+ destroy_ilm(¤t_ilm);
+ }
+ }
+}
+
+
+static kal_bool usb_idle_task_init(void)
+{
+ usbidle_t *pUsbIdle;
+ kal_char usbidle_mutex_name[50];
+
+ kal_mem_set(usbidle_get_instance(), 0, sizeof(usbidle_t));
+
+ pUsbIdle = usbidle_get_instance();
+
+ pUsbIdle->usbidle_clock_off = KAL_FALSE;
+ pUsbIdle->usbidle_l4_power_saving = KAL_FALSE;
+
+ //sprintf(usbidle_mutex_name, "USBIDLE_CLOCK_GATE_MUTEX");
+ //pUsbIdle->usbidle_clock_gating_mutex = kal_create_enh_mutex(usbidle_mutex_name);
+ sprintf(usbidle_mutex_name, "USBIDLE_L4_POWER_SAVING_MUTEX");
+ pUsbIdle->usbidle_l4_power_saving_mutex = kal_create_enh_mutex(usbidle_mutex_name);
+ sprintf(usbidle_mutex_name, "USBIDLE_NOTIFY_DRIVER_SPINLOCK");
+ pUsbIdle->usbidle_notify_driver_spinlock = kal_create_spinlock(usbidle_mutex_name);
+
+ return KAL_TRUE;
+}
+
+
+static kal_bool usb_idle_task_reset(void)
+{
+ /* Do task's reset here.
+ * Notice that: shouldn't execute modules reset handler since
+ * stack_task_reset() will do. */
+ return KAL_TRUE;
+}
+
+
+kal_bool usb_idle_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct usb_idle_handler_info =
+ {
+ usb_idle_task_main, /* task entry function */
+ usb_idle_task_init, /* task initialization function */
+ usb_idle_task_reset /* task reset handler */
+ };
+
+ *handle = (comptask_handler_struct *)&usb_idle_handler_info;
+
+ return KAL_TRUE;
+}
+
diff --git a/mcu/middleware/kpalv/include/kpalv.h b/mcu/middleware/kpalv/include/kpalv.h
new file mode 100644
index 0000000..7f147a1
--- /dev/null
+++ b/mcu/middleware/kpalv/include/kpalv.h
@@ -0,0 +1,120 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2012
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ *****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * kpalv.h
+ *
+ * Project:
+ * --------
+ *
+ *
+ * Description:
+ * ------------
+ * keepalive internal function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ *
+ *
+ ****************************************************************************/
+
+#ifndef __INC_KPALV_H
+#define __INC_KPALV_H
+
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+#include "kpalv_struct.h"
+#include "kpalv_data.h"
+#include "ipc_struct.h"
+
+void kpalv_dispatch_ilm(ilm_struct *ilm);
+void kpalv_ilm_handler(ilm_struct *ilm);
+
+void kpalv_timer_init(void);
+void kpalv_init(void);
+void kpalv_reset(void);
+
+void kpalv_stop_reset_all_connections(void);
+
+void kpalv_receive_keep_alive_enable_cmd(ilm_struct *ilm);
+void kpalv_receive_keep_alive_disable_cmd(ilm_struct *ilm);
+void kpalv_receive_keep_alive_query_cmd(ilm_struct *ilm);
+void kpalv_receive_keep_alive_invalid_cmd(ilm_struct *ilm);
+kal_bool kpalv_receive_keep_alive_query_result(ilm_struct *ilm, kal_uint8 *conn_id, kal_uint8 *conn_status);
+void kpalv_idle_poll_tmout_hndlr(void *event_hf_param);
+void kpalv_interval_poll_tmout_hndlr(void *event_hf_param);
+void kpalv_register_ul_filter_at_ipc(kal_uint8 conn_id, kpalv_req_ip_type_e ip_type);
+void kpalv_register_dl_filter_at_ipc(kal_uint8 conn_id, kpalv_req_ip_type_e ip_type);
+void kpalv_start_retry_timer(kal_uint8 conn_id);
+void kpalv_start_idle_timer(kal_uint8 conn_id);
+void kpalv_idle_poll_tmout_hndlr(void *event_hf_param);
+void kpalv_unregister_ul_dl_filter_at_ipc(kal_uint8 conn_id);
+void kpalv_stop_keep_alive_for_connection(kal_uint8 conn_id);
+void kpalv_stop_idle_timer(kal_uint8 conn_id);
+void kpalv_send_keep_alive_notify(kal_bool ok, kal_uint8 conn_handle, kpalv_md_kpalive_state_e state, kal_bool ap_disable_rsp, kal_uint8 rsp_ps_idx);
+void kpalv_send_keep_alive_notify_urc(kal_uint8 conn_handle, kpalv_md_kpalive_state_e state, kal_uint8 rsp_ps_idx);
+
+
+void kpalv_ul_filter_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length);
+
+void kpalv_dl_filter_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length);
+
+void kpalv_prepare_udp_keep_alive_packet_buffer(kal_uint8 conn_id);
+void kpalv_send_udp_keep_alive_packet(kal_uint8 conn_id);
+
+#ifdef ATEST_SYS_KPALV
+void* kpalv_get_connection_address(kal_uint8 conn_id);
+kal_int32 kpalv_get_connection_ul_filter_id(kal_uint8 conn_id);
+kal_int32 kpalv_get_connection_dl_filter_id(kal_uint8 conn_id);
+#endif
+#endif /* __INC_KPALV_H */
diff --git a/mcu/middleware/kpalv/include/kpalv_data.h b/mcu/middleware/kpalv/include/kpalv_data.h
new file mode 100644
index 0000000..f7445f9
--- /dev/null
+++ b/mcu/middleware/kpalv/include/kpalv_data.h
@@ -0,0 +1,140 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2012
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ *****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * kpalv_data.h
+ *
+ * Project:
+ * --------
+ *
+ *
+ * Description:
+ * ------------
+ * Keep alive context structure definitions
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ *
+ *
+ ****************************************************************************/
+#ifndef __INC_KPALV_DATA_H
+#define __INC_KPALV_DATA_H
+
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+#include "kpalv_struct.h"
+#include "kpalv_ut.h"
+
+#ifdef ATEST_SYS_KPALV
+#define KPALV_SEND_KEEP_ALIVE_NOTIFY_CNF kpalv_ut_send_keep_alive_notify
+#define KPALV_SEND_KEEP_ALIVE_NOTIFY_URC kpalv_ut_send_keep_alive_notify_urc
+#else
+#define KPALV_SEND_KEEP_ALIVE_NOTIFY_CNF kpalv_send_keep_alive_notify
+#define KPALV_SEND_KEEP_ALIVE_NOTIFY_URC kpalv_send_keep_alive_notify_urc
+#endif
+
+
+#define KPALV_KEEP_ALIVE_DATA_LENGTH 1
+#define KPALV_KEEP_ALIVE_IPV4_PACKET 40 /* ipv4:20 + tcp:20 */
+#define KPALV_KEEP_ALIVE_IPV6_PACKET 60 /* ipv6:40 + tcp:20 */
+
+#define KPALV_KEEP_ALIVE_IPV4_UDP_PACKET 28 /* ipv4:20 + udp:8 */
+#define KPALV_KEEP_ALIVE_IPV6_UDP_PACKET 48 /* ipv6:40 + udp:8 */
+
+#define KPALV_KEEP_ALIVE_V4_PACKET_LENGTH (KPALV_KEEP_ALIVE_IPV4_PACKET + KPALV_KEEP_ALIVE_DATA_LENGTH)
+#define KPALV_KEEP_ALIVE_V6_PACKET_LENGTH (KPALV_KEEP_ALIVE_IPV6_PACKET + KPALV_KEEP_ALIVE_DATA_LENGTH)
+
+#define KPALV_KEEP_ALIVE_V4_UDP_PACKET_LENGTH (KPALV_KEEP_ALIVE_IPV4_UDP_PACKET + KPALV_KEEP_ALIVE_DATA_LENGTH)
+#define KPALV_KEEP_ALIVE_V6_UDP_PACKET_LENGTH (KPALV_KEEP_ALIVE_IPV6_UDP_PACKET + KPALV_KEEP_ALIVE_DATA_LENGTH)
+
+/** this is the index value for idle timer for connection 0 */
+#define IDLE_TIMER_INDEX_VALUE_START 5
+
+/** this is the index value for retry timer for connection 0 */
+#define RETRY_TIMER_INDEX_VALUE_START 10
+
+typedef struct {
+ kal_bool is_enable; /**< keep-alive enabled or disabled */
+ kpalv_req_ip_type_e ip_type; /**< ipv4/v6 tcp udp type */
+ kal_uint32 netif_id; /**< ap module attached to nw_interface_id */
+ kal_uint8 src_ipv4_addr[KPALV_IPV4_ADDR_LEN]; /**< IPV4 src addr */
+ kal_uint8 dst_ipv4_addr[KPALV_IPV4_ADDR_LEN]; /**< IPV4 dst addr */
+ kal_uint8 src_ipv6_addr[KPALV_IPV6_ADDR_LEN]; /**< IPV6 src addr */
+ kal_uint8 dst_ipv6_addr[KPALV_IPV6_ADDR_LEN]; /**< IPV6 dst addr */
+ kal_uint16 src_port; /**< src port */
+ kal_uint16 dst_port; /**< dst port */
+ kal_uint16 idle_time; /**< idle time in sec */
+ kal_uint16 probe_interval; /**< retry time in sec */
+ kal_uint8 max_retry_cnt; /**< number of retries */
+} kpalv_keep_alive_at_cmd_info_struct;
+
+typedef struct {
+ kal_uint32 pdn_id; /**< get ipc_find_pdn_id_by_netif_id */
+ kal_uint8 ps_id; /**< get ipc_find_pdn_id_by_netif_id */
+ kal_uint8 curr_retry_attempt; /**< curr retry count */
+ kal_int32 ul_filter_id; /**< UL filter id */
+ kal_int32 dl_filter_id; /**< DL filter id */
+ event_scheduler *idle_timer_scheduler; /**< T1 event schduler */
+ event_scheduler *retry_timer_scheduler; /**< T2 event scheduler */
+ eventid eid_idle_timer; /**< T1 event id */
+ eventid eid_retry_timer; /**< T2 event id */
+} kpalv_keep_alive_control_struct;
+
+typedef struct {
+ kal_bool is_already_updated; /**< received first UL packet from AP or not */
+ kal_uint8 ipv4_tcp_keep_alive_packet[KPALV_KEEP_ALIVE_V4_PACKET_LENGTH]; /**< ipv4 keep-alive ready buffer */
+ kal_uint8 ipv6_tcp_keep_alive_packet[KPALV_KEEP_ALIVE_V6_PACKET_LENGTH]; /**< ipv6 keep-alive ready buffer */
+ kal_uint8 ipv4_udp_keep_alive_packet[KPALV_KEEP_ALIVE_V4_UDP_PACKET_LENGTH]; /**< ipv4 udp keep-alive ready buffer */
+ kal_uint8 ipv6_udp_keep_alive_packet[KPALV_KEEP_ALIVE_V6_UDP_PACKET_LENGTH]; /**< ipv6 udp keep-alive ready buffer */
+} kpalv_keep_alive_data_struct;
+
+typedef struct {
+ kpalv_keep_alive_at_cmd_info_struct at_info;
+ kpalv_keep_alive_control_struct control_info;
+ kal_bool is_cntx_valid;
+ kpalv_md_kpalive_state_e status;
+ kpalv_keep_alive_data_struct data_info;
+} kpalv_keep_alive_struct;
+
+
+#endif /* __INC_KPALV_DATA_H */
diff --git a/mcu/middleware/kpalv/include/kpalv_debug.h b/mcu/middleware/kpalv/include/kpalv_debug.h
new file mode 100644
index 0000000..c6de6ed
--- /dev/null
+++ b/mcu/middleware/kpalv/include/kpalv_debug.h
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2012
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ *****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * kpalv_debug.h
+ *
+ * Project:
+ * --------
+ *
+ *
+ * Description:
+ * ------------
+ * keepalive debug functions
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ *
+ *
+ ****************************************************************************/
+#ifndef __INC_KPALV_DEBUG_H
+#define __INC_KPALV_DEBUG_H
+
+#include "kpalv_trace.h"
+
+#define KPALV_LOG dhl_trace
+
+#endif /* __INC_KPALV_DEBUG_H */
diff --git a/mcu/middleware/kpalv/include/kpalv_trace.h b/mcu/middleware/kpalv/include/kpalv_trace.h
new file mode 100644
index 0000000..c73dfa4
--- /dev/null
+++ b/mcu/middleware/kpalv/include/kpalv_trace.h
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2012
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ *****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * kpalv_debug.h
+ *
+ * Project:
+ * --------
+ *
+ *
+ * Description:
+ * ------------
+ * keepalive debug traces
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ *
+ *
+ ****************************************************************************/
+
+#ifndef __INC_KPALV_TRACE_H
+#define __INC_KPALV_TRACE_H
+
+#ifndef GEN_FOR_PC
+ #include "kal_public_defs.h"
+#endif /* GEN_FOR_PC */
+
+#include "dhl_trace.h"
+
+#if !defined(GEN_FOR_PC)
+#if defined(__DHL_MODULE__) || defined(__CUSTOM_RELEASE__)
+#endif
+#endif
+#if !defined(GEN_FOR_PC)
+#include "kpalv_trace_mod_kpalv_utmd.h"
+#endif
+
+#endif /* __INC_KPALV_TRACE_H */
+
diff --git a/mcu/middleware/kpalv/include/kpalv_trace_mod_kpalv_utmd.json b/mcu/middleware/kpalv/include/kpalv_trace_mod_kpalv_utmd.json
new file mode 100644
index 0000000..b4ff25a
--- /dev/null
+++ b/mcu/middleware/kpalv/include/kpalv_trace_mod_kpalv_utmd.json
@@ -0,0 +1,278 @@
+{
+ "endGen": "-",
+ "LegacyParameters": {},
+ "module": "MOD_KPALV",
+ "startGen": "93",
+ "traceClassDefs": [
+ {
+ "TRACE_INFO": {
+ "debugLevel": "High",
+ "tag": [
+ "Baseline",
+ "TRACE_INFO"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "TRACE_ERROR": {
+ "debugLevel": "Ultra-High",
+ "tag": [
+ "Baseline",
+ "TRACE_ERROR"
+ ],
+ "traceType": "CoreDesign"
+ }
+ },
+ {
+ "TRACE_WARNING": {
+ "debugLevel": "Medium",
+ "tag": [
+ "Baseline",
+ "TRACE_WARNING"
+ ],
+ "traceType": "InternalDesign"
+ }
+ },
+ {
+ "TRACE_FUNC": {
+ "debugLevel": "Low",
+ "tag": [
+ "Baseline",
+ "TRACE_FUNC"
+ ],
+ "traceType": "CoreDesign"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "KPALV_TR_ILM_WRONG_MSG_ID": {
+ "apiType": "index",
+ "format": "[kpalv] dispatcher_on_ilm(): wrong msg_id(%d)!",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "KPALV_TR_INIT_ENTRY": {
+ "apiType": "index",
+ "format": "[[kpalv] dispatcher_init()",
+ "traceClass": "TRACE_FUNC"
+ }
+ },
+
+ {
+ "KPALV_TR_RESET_ENTRY": {
+ "apiType": "index",
+ "format": "[kpalv] dispatcher_reset()",
+ "traceClass": "TRACE_FUNC"
+ }
+ },
+ {
+ "KPALV_TR_ENABLE_REQ_DUPLICATE": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_receive_keep_alive_enable_cmd ERROR: duplicate req!!!",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "KPALV_TR_ENABLE_REQ_MAX_CONN": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_receive_keep_alive_enable_cmd ERROR: max conn reached!!!",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+
+ {
+ "KPALV_TR_ENABLE_REQ_NETIF_FAILED": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_receive_keep_alive_enable_cmd ERROR: ipc query netif failed!!!",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "KPALV_TR_ENABLE_REQ_SIM_MISMATCH": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_receive_keep_alive_enable_cmd ERROR: atp sim and ps_id different!!!",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "KPALV_TR_NOTIFY_RSP_TO_ATP": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_send_keep_alive_notify: result:(%d), conn_id(%d), status(%d), ap_dis_req(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_NOTIFY_FOR_URC_TO_ATP": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_send_keep_alive_notify_urc: conn_id(%d), status(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_START_IDLE_TIMER": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_start_idle_timer: conn_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_START_RETRY_TIMER": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_start_retry_timer: conn_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_STOP_IDLE_TIMER": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_stop_idle_timer: conn_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_STOP_RETRY_TIMER": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_stop_retry_timer: conn_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_TIMEOUT_IDLE_TIMER": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_idle_poll_tmout_hndlr: conn_id(%d), conn_status(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_TIMEOUT_RETRY_TIMER": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_interval_poll_tmout_hndlr: conn_id(%d), retry_attempt(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_MAX_RETRY_ATTEMPTED": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv max retries exhausted INACTIVE for conn_id(%d) , notify URC to AP",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "KPALV_TR_STOP_KEEP_ALIVE_CONN": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_stop_keep_alive_for_connection: conn_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_UL_FILTER_CBK": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_ul_filter_cbk: conn_id(%d) , head_gpd(0x%X) tail_gpd(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_UL_FILTER_DETAILS": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_ul_filter_cbk, 1st UL packet captured ACTIVE state : conn_id(%d), notify URC to AP",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_UPDATE_KEEP_ALIVE_BUFF": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_update_keep_alive_packet_by_ul_flow: conn_id(%d) is_ipv6(%d) seq_num(%u), ack_num(%u)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_DL_FILTER_CBK": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_dl_filter_cbk: conn_id(%d) , head_gpd(0x%X) tail_gpd(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_DL_PACKET_INFO": {
+ "apiType": "index",
+ "format": "[kpalv] recvd DL pkt: DL tcp seg len(%d) ack_num(%u) seq_num(%u) tcp_flag (%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_DL_PACKET_INFO_UPDATE_UL": {
+ "apiType": "index",
+ "format": "[kpalv] recvd DL pkt: update KPLAV buffer by non-keepalive ack pkt with ack_num(%u) seq_num(%u)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_DL_KEEP_ALIVE_ACK": {
+ "apiType": "index",
+ "format": "[kpalv] recvd DL pkt: TCP keep-alive ack recvd from server, return",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_DL_PACKET_FORWARD": {
+ "apiType": "index",
+ "format": "[kpalv] recvd DL pkt: non keep-alive ack: forward head_gpd(0x%X) tail_gpd(0x%X) to netif(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_GPD_ALLOC_FAIL": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_send_keep_alive_packet() : GPD alloc failed at line:(%d)",
+ "traceClass": "TRACE_ERROR"
+ }
+ },
+ {
+ "KPALV_TR_SEND_KEEP_ALIVE_PKT": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_send_keep_alive_packet: conn_id(%d) , pdn_id(%d), head_gpd(0x%X)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_PKT_SEND_FAILED": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_send_keep_alive_packet() failed: %d : ipcore return false",
+ "traceClass": "TRACE_WARNING"
+ }
+ },
+ {
+ "KPALV_TR_SEND_KEEP_ALIVE_PKT_ENTRY": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_send_keep_alive_packet() entry for conn_id(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_SEND_KEEP_ALIVE_PKT_UPDATE": {
+ "apiType": "index",
+ "format": "[kpalv] keep alive update pkt before send DONE",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_PREPARE_UDP_KEEP_ALIVE_PKT": {
+ "apiType": "index",
+ "format": "[kpalv] UDP enabled, kpalv_prepare_udp_packet: conn_id(%d) , total_len(%d), ip_hdr_len(%d)",
+ "traceClass": "TRACE_INFO"
+ }
+ },
+ {
+ "KPALV_TR_SEND_UDP_KEEP_ALIVE_PKT": {
+ "apiType": "index",
+ "format": "[kpalv] kpalv_send_udp_keep_alive_packet: conn_id(%d) , pdn_id(%d), head_gpd(0x%X)",
+ "traceClass": "TRACE_FUNC"
+ }
+ }
+ ],
+ "traceFamily": "PS",
+ "userModule": "MOD_KPALV"
+}
diff --git a/mcu/middleware/kpalv/include/kpalv_ut.h b/mcu/middleware/kpalv/include/kpalv_ut.h
new file mode 100644
index 0000000..13ef181
--- /dev/null
+++ b/mcu/middleware/kpalv/include/kpalv_ut.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * kpalv_ut.h
+ *
+ * Project:
+ * --------
+ * UMOLY
+ *
+ * Description:
+ * ------------
+ * UT Api.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *******************************************************************************/
+
+#ifndef __INC_KPALV_UT_H
+#define __INC_KPALV_UT_H
+
+#ifdef ATEST_SYS_KPALV
+void kpalv_ut_send_keep_alive_notify(kal_bool ok, kal_uint8 conn_handle, kpalv_md_kpalive_state_e state, kal_bool ap_dis_flow, kal_uint8 rsp_ps_idx);
+void kpalv_ut_send_keep_alive_notify_urc(kal_uint8 conn_handle, kpalv_md_kpalive_state_e state, kal_uint8 rsp_ps_idx);
+
+
+#endif/* ATEST_SYS_KPALV */
+
+#endif /* __INC_KPALV_UT_H */
diff --git a/mcu/middleware/kpalv/src/kpalv_data.c b/mcu/middleware/kpalv/src/kpalv_data.c
new file mode 100644
index 0000000..968dadf
--- /dev/null
+++ b/mcu/middleware/kpalv/src/kpalv_data.c
@@ -0,0 +1,1266 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2012
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ *****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * kpalv_data.c
+ *
+ * Project:
+ * --------
+ *
+ *
+ * Description:
+ * ------------
+ * keepalive handling for connection
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 09 18 2019 amit.singh
+ * [MOLY00440693] [KPALV] clean task info in VMOLY
+ *
+ * USIR KPALV task.
+ *
+ *
+ *
+ ****************************************************************************/
+#include "ipc_api.h"
+#include "qmu_bm_util.h"
+#include "kpalv.h"
+#include "kpalv_data.h"
+#include "kpalv_msgid.h"
+#include "atp_msgid.h"
+#include "kpalv_debug.h"
+#include "kpalv_struct.h"
+#include "mw_sap.h"
+
+
+extern kal_uint16 ipc_calc_tcp_checksum(kal_bool is_ipv4, kal_uint8 *src_addr, kal_uint8 *dst_addr, kal_uint8 *tcp_header, kal_uint32 tcp_len);
+extern kal_uint16 ipc_calc_ipv4_checksum(kal_uint8 *ip_header);
+extern kal_uint16 ipc_calc_udp_checksum(kal_bool is_ipv4, kal_uint8 *src_addr, kal_uint8 *dst_addr, kal_uint8 *udp_header, kal_uint32 udp_len);
+
+
+/* context structure of keep-aive*/
+static kpalv_keep_alive_struct keep_alive_cntx[KPALV_MAX_KEEP_ALIVE_CONN];
+
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+
+void kpalv_init(void)
+{
+ int conn_id = 0;
+ kal_mem_set(&keep_alive_cntx, 0, sizeof(kpalv_keep_alive_struct)*KPALV_MAX_KEEP_ALIVE_CONN);
+
+ for (conn_id = 0; conn_id < KPALV_MAX_KEEP_ALIVE_CONN; conn_id++) {
+ keep_alive_cntx[conn_id].control_info.ul_filter_id = -1;
+ keep_alive_cntx[conn_id].control_info.dl_filter_id = -1;
+ keep_alive_cntx[conn_id].status = KPALV_MD_KEEPALIVE_STATE_INACTIVE;
+ }
+
+ kpalv_timer_init();
+ MD_TRC_KPALV_TR_INIT_ENTRY();
+}
+
+void kpalv_reset(void)
+{
+ kpalv_stop_reset_all_connections();
+ MD_TRC_KPALV_TR_RESET_ENTRY();
+}
+
+void kpalv_timer_init(void)
+{
+ kal_uint8 i = 0;
+ for (i= 0; i< KPALV_MAX_KEEP_ALIVE_CONN; i++) {
+ keep_alive_cntx[i].control_info.idle_timer_scheduler = evshed_create(
+ "KPALV_IDEL_TIMER",
+ MOD_KPALV,
+ 0,
+ 0);
+
+ if (keep_alive_cntx[i].control_info.idle_timer_scheduler) {
+ evshed_set_index(keep_alive_cntx[i].control_info.idle_timer_scheduler, (IDLE_TIMER_INDEX_VALUE_START + i));
+ } else {
+ ASSERT(KAL_FALSE);
+ }
+
+ keep_alive_cntx[i].control_info.retry_timer_scheduler = evshed_create(
+ "KPALV_RETRY_TIMER",
+ MOD_KPALV,
+ 0,
+ 0);
+
+ if (keep_alive_cntx[i].control_info.retry_timer_scheduler) {
+ evshed_set_index(keep_alive_cntx[i].control_info.retry_timer_scheduler, (RETRY_TIMER_INDEX_VALUE_START + i));
+ } else {
+ ASSERT(KAL_FALSE);
+ }
+ }
+}
+
+void kpalv_update_data_before_sending_keepalive_packet(kal_uint8 *stored_buffer, kal_uint8 ip_type) {
+
+ kal_uint16 sum16 = 0;
+ kal_uint16 ipid = 0;
+ kal_uint32 ip_header_len = 0;
+ kal_uint8 *ip_header = NULL;
+ kal_uint8 *tcp_header = NULL;
+ kal_uint8 *src_addr = NULL;
+ kal_uint8 *dst_addr = NULL;
+ kal_uint32 tcp_header_len = 0;
+
+ ip_header = stored_buffer;
+ tcp_header_len = IPC_HDR_TCP_HEADER_SIZE;
+
+ ip_header_len = (ip_type == IPC_IP_TYPE_IPV4) ? IPC_HDR_V4_HEADER_SIZE : IPC_HDR_V6_HEADER_SIZE;
+
+ tcp_header = ip_header + ip_header_len;
+
+ if (ip_type == IPC_IP_TYPE_IPV4) {
+ ipid = IPC_HDR_V4_GET_IDENTITY(ip_header);
+ src_addr = IPC_HDR_V4_GET_SRC_ADDR(ip_header);
+ dst_addr = IPC_HDR_V4_GET_DST_ADDR(ip_header);
+ IPC_HDR_V4_SET_IDENTITY(ip_header, ipid + 1);//last UL IPID + 1;
+
+ //calc tcp chekcsum
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, 0);
+ sum16 = ipc_calc_tcp_checksum(KAL_TRUE, src_addr, dst_addr, tcp_header, (tcp_header_len+KPALV_KEEP_ALIVE_DATA_LENGTH)); //1 byte nil data
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, sum16);
+
+ //update the checksum too
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(stored_buffer, 0);
+ sum16 = ipc_calc_ipv4_checksum(stored_buffer);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(stored_buffer, sum16);
+ } else {
+ //calc tcp chekcsum
+ dst_addr = IPC_HDR_V6_GET_DST_ADDR(ip_header);
+ src_addr = IPC_HDR_V6_GET_SRC_ADDR(ip_header);
+
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, 0);
+ sum16 = ipc_calc_tcp_checksum(KAL_TRUE, src_addr, dst_addr, tcp_header, tcp_header_len);
+ IPC_HDR_TCP_SET_CHECKSUM(tcp_header, sum16);
+
+ /*ipv6 dont have checksum*/
+ }
+ MD_TRC_KPALV_TR_SEND_KEEP_ALIVE_PKT_UPDATE();
+}
+
+void kpalv_send_udp_keep_alive_packet(kal_uint8 conn_id) {
+ ipc_pkt_t ipc_pkt;
+ qbm_gpd *ul_gpd;
+ qbm_gpd *bd;
+ kal_bool result;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint8 ip_type;
+ kpalv_keep_alive_at_cmd_info_struct *at_info = NULL;
+
+
+ at_info = &keep_alive_cntx[conn_id].at_info;
+ ip_type = (at_info->ip_type == KPALV_REQ_IPTYPE_IPV4UDP) ? IPC_IP_TYPE_IPV4 : IPC_IP_TYPE_IPV6;
+
+ if(ip_type == IPC_IP_TYPE_IPV4) {
+ packet_buf = keep_alive_cntx[conn_id].data_info.ipv4_udp_keep_alive_packet;
+ packet_len = sizeof(keep_alive_cntx[conn_id].data_info.ipv4_udp_keep_alive_packet);
+ } else {
+ packet_buf = keep_alive_cntx[conn_id].data_info.ipv6_udp_keep_alive_packet;
+ packet_len = sizeof(keep_alive_cntx[conn_id].data_info.ipv6_udp_keep_alive_packet);
+ }
+ ul_gpd = QBM_ALLOC_ONE(QBM_TYPE_NET_UL_SHRD);
+ if (ul_gpd == NULL)
+ {
+ //log cant send keep-aive as of now
+ MD_TRC_KPALV_TR_GPD_ALLOC_FAIL(__LINE__);
+ return;
+ }
+
+ bd = QBM_DES_GET_DATAPTR(ul_gpd);
+
+ /*fill GPD for keep-alive packet buffer, this is a ready buffer, no need to update anythig, just copy*/
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), packet_buf, packet_len);
+ QBM_CACHE_FLUSH(QBM_DES_GET_DATAPTR(bd), packet_len);
+ QBM_DES_SET_DATALEN(bd, packet_len);
+ qbm_cal_set_checksum(bd);
+ QBM_DES_SET_DATALEN(ul_gpd, packet_len);
+ qbm_cal_set_checksum(ul_gpd);
+
+ /*Send keep-alive packet to IPCORE */
+ kal_mem_set(&ipc_pkt, 0, sizeof(ipc_pkt));
+ ipc_pkt.isGPD = KAL_TRUE;
+ ipc_pkt.head = ul_gpd;
+ ipc_pkt.tail = ul_gpd;
+ MD_TRC_KPALV_TR_SEND_UDP_KEEP_ALIVE_PKT(conn_id, keep_alive_cntx[conn_id].control_info.pdn_id, ipc_pkt.head);
+ result = ipc_send_ul_pkt_by_pdn_multiple_ps(&ipc_pkt, NULL, keep_alive_cntx[conn_id].control_info.pdn_id, ip_type, keep_alive_cntx[conn_id].control_info.ps_id);
+ if (KAL_FALSE == result) {
+ MD_TRC_KPALV_TR_PKT_SEND_FAILED(__LINE__);
+ qbmt_dest_q(ul_gpd, ul_gpd);
+ }
+}
+
+void kpalv_send_keep_alive_packet(kal_uint8 conn_id)
+{
+
+ /* in our buffer always keep-alive updated, ready to send same packet*/
+ ipc_pkt_t ipc_pkt;
+ qbm_gpd *ul_gpd;
+ qbm_gpd *bd;
+ kal_uint8 *packet_buf;
+ kal_uint32 packet_len;
+ kal_uint8 ip_type;
+ kal_uint8 *ipv4_keep_alive_buffer = keep_alive_cntx[conn_id].data_info.ipv4_tcp_keep_alive_packet;
+ kal_uint8 *ipv6_keep_alive_buffer = keep_alive_cntx[conn_id].data_info.ipv6_tcp_keep_alive_packet;
+ kal_bool result;
+
+ MD_TRC_KPALV_TR_SEND_KEEP_ALIVE_PKT_ENTRY(conn_id);
+ ul_gpd = QBM_ALLOC_ONE(QBM_TYPE_NET_UL_SHRD);
+ if (ul_gpd == NULL)
+ {
+ //log cant send keep-aive as of now
+ MD_TRC_KPALV_TR_GPD_ALLOC_FAIL(__LINE__);
+ return;
+ }
+
+ bd = QBM_DES_GET_DATAPTR(ul_gpd);
+ packet_buf = keep_alive_cntx[conn_id].at_info.ip_type == KPALV_REQ_IPTYPE_IPV6TCP ? ipv6_keep_alive_buffer : ipv4_keep_alive_buffer;
+ packet_len = keep_alive_cntx[conn_id].at_info.ip_type == KPALV_REQ_IPTYPE_IPV6TCP ? KPALV_KEEP_ALIVE_V6_PACKET_LENGTH : KPALV_KEEP_ALIVE_V4_PACKET_LENGTH;
+ ip_type = keep_alive_cntx[conn_id].at_info.ip_type == KPALV_REQ_IPTYPE_IPV6TCP ? IPC_IP_TYPE_IPV6 : IPC_IP_TYPE_IPV4;
+
+ /*get the keep-alive ready buffer, but need to update the ID field in IPv4 header , nedd to increment on every UL even for kpalv too*/
+
+ kpalv_update_data_before_sending_keepalive_packet(packet_buf, ip_type);
+
+ /*fill GPD for keep-alive packet buffer, this is a ready buffer, no need to update anythig, just copy*/
+ kal_mem_cpy(QBM_DES_GET_DATAPTR(bd), packet_buf, packet_len);
+ QBM_CACHE_FLUSH(QBM_DES_GET_DATAPTR(bd), packet_len);
+ QBM_DES_SET_DATALEN(bd, packet_len);
+ qbm_cal_set_checksum(bd);
+ QBM_DES_SET_DATALEN(ul_gpd, packet_len);
+ qbm_cal_set_checksum(ul_gpd);
+
+
+ /*Send keep-alive packet to IPCORE */
+ kal_mem_set(&ipc_pkt, 0, sizeof(ipc_pkt));
+ ipc_pkt.isGPD = KAL_TRUE;
+ ipc_pkt.head = ul_gpd;
+ ipc_pkt.tail = ul_gpd;
+ MD_TRC_KPALV_TR_SEND_KEEP_ALIVE_PKT(conn_id, keep_alive_cntx[conn_id].control_info.pdn_id, ipc_pkt.head);
+ result = ipc_send_ul_pkt_by_pdn_multiple_ps(&ipc_pkt, NULL, keep_alive_cntx[conn_id].control_info.pdn_id, ip_type, keep_alive_cntx[conn_id].control_info.ps_id);
+ if (KAL_FALSE == result) {
+ MD_TRC_KPALV_TR_PKT_SEND_FAILED(__LINE__);
+ qbmt_dest_q(ul_gpd, ul_gpd);
+ }
+}
+
+
+void kpalv_close_connection_notify_urc(kal_uint8 conn_id)
+{
+ kpalv_keep_alive_struct* connection_context = &keep_alive_cntx[conn_id];
+ /*notify to AP via URC for dead connection*/
+ KPALV_SEND_KEEP_ALIVE_NOTIFY_URC(conn_id, KPALV_MD_KEEPALIVE_STATE_INACTIVE, connection_context->control_info.ps_id);
+ kpalv_stop_keep_alive_for_connection(conn_id);
+
+}
+
+void kpalv_idle_poll_tmout_hndlr(void *event_hf_param)
+{
+ kpalv_keep_alive_struct* connection_context = (kpalv_keep_alive_struct*)event_hf_param;
+ kal_uint8 conn_id = connection_context - &keep_alive_cntx[0];
+
+ ASSERT(connection_context->control_info.eid_idle_timer);
+ connection_context->control_info.eid_idle_timer = NULL;
+
+ MD_TRC_KPALV_TR_TIMEOUT_IDLE_TIMER(conn_id, connection_context->status);
+ if ((connection_context->at_info.ip_type == KPALV_REQ_IPTYPE_IPV6TCP) ||
+ (connection_context->at_info.ip_type == KPALV_REQ_IPTYPE_IPV4TCP)) {
+ if (connection_context->status == KPALV_MD_KEEPALIVE_STATE_ACTIVE) {
+ kpalv_send_keep_alive_packet(conn_id);
+ kpalv_start_retry_timer(conn_id);
+ } else if (connection_context->status == KPALV_MD_KEEPALIVE_STATE_PENDING){
+ //can restart idle timer again to wait for active state
+ kpalv_start_idle_timer(conn_id);
+ } else {
+ ASSERT(0);
+ }
+ } else {
+ /* UPD case falls here*/
+ kpalv_send_udp_keep_alive_packet(conn_id);
+ kpalv_start_idle_timer(conn_id);
+ }
+}
+
+
+void kpalv_interval_poll_tmout_hndlr(void *event_hf_param)
+{
+ kpalv_keep_alive_struct* connection_context = (kpalv_keep_alive_struct*)event_hf_param;
+ kal_uint8 conn_id = connection_context - &keep_alive_cntx[0];
+
+ ASSERT(connection_context->control_info.eid_retry_timer);
+ connection_context->control_info.eid_retry_timer = NULL;
+
+ if (connection_context->control_info.curr_retry_attempt < connection_context->at_info.max_retry_cnt) {
+ connection_context->control_info.curr_retry_attempt++;
+ MD_TRC_KPALV_TR_TIMEOUT_RETRY_TIMER(conn_id, connection_context->control_info.curr_retry_attempt);
+ kpalv_send_keep_alive_packet(conn_id);
+ kpalv_start_retry_timer(conn_id);
+ return;
+ }
+
+ /*max retry reached for retry attempt, notify AP via URC & reset this conection info*/
+ MD_TRC_KPALV_TR_MAX_RETRY_ATTEMPTED(conn_id);
+ kpalv_close_connection_notify_urc(conn_id);
+}
+
+void kpalv_start_idle_timer(kal_uint8 conn_id)
+{
+
+ kpalv_keep_alive_struct *kpalv_cntx = &keep_alive_cntx[conn_id];
+ kpalv_cntx->control_info.eid_idle_timer = evshed_set_event(kpalv_cntx->control_info.idle_timer_scheduler,
+ (kal_timer_func_ptr)kpalv_idle_poll_tmout_hndlr,
+ kpalv_cntx,
+ kpalv_cntx->at_info.idle_time*1000
+ );
+ MD_TRC_KPALV_TR_START_IDLE_TIMER(conn_id);
+
+}
+
+void kpalv_start_retry_timer(kal_uint8 conn_id)
+{
+ kpalv_keep_alive_struct *kpalv_cntx = &keep_alive_cntx[conn_id];
+ kpalv_cntx->control_info.eid_retry_timer = evshed_set_event(kpalv_cntx->control_info.retry_timer_scheduler,
+ (kal_timer_func_ptr)kpalv_interval_poll_tmout_hndlr,
+ kpalv_cntx,
+ kpalv_cntx->at_info.probe_interval*1000
+ );
+ MD_TRC_KPALV_TR_START_RETRY_TIMER(conn_id);
+}
+
+
+void kpalv_stop_idle_timer(kal_uint8 conn_id)
+{
+ if (keep_alive_cntx[conn_id].control_info.eid_idle_timer != NULL) {
+ evshed_cancel_event(keep_alive_cntx[conn_id].control_info.idle_timer_scheduler,
+ &keep_alive_cntx[conn_id].control_info.eid_idle_timer);
+ keep_alive_cntx[conn_id].control_info.eid_idle_timer = NULL;
+ MD_TRC_KPALV_TR_STOP_IDLE_TIMER(conn_id);
+ }
+}
+
+void kpalv_stop_retry_timer(kal_uint8 conn_id)
+{
+ if (keep_alive_cntx[conn_id].control_info.eid_retry_timer != NULL) {
+ evshed_cancel_event(keep_alive_cntx[conn_id].control_info.retry_timer_scheduler,
+ &keep_alive_cntx[conn_id].control_info.eid_retry_timer);
+ keep_alive_cntx[conn_id].control_info.eid_retry_timer = NULL;
+ keep_alive_cntx[conn_id].control_info.curr_retry_attempt = 0;
+ MD_TRC_KPALV_TR_STOP_RETRY_TIMER(conn_id);
+ }
+}
+
+void kpalv_receive_keep_alive_req_cmd(ilm_struct *ilm)
+{
+ atp_kpalv_keepalive_req_struct *at_cmd = (atp_kpalv_keepalive_req_struct *)(ilm->local_para_ptr);
+
+ if (KPALV_REQ_ENABLE == at_cmd->req_type) {
+ kpalv_receive_keep_alive_enable_cmd(ilm);
+ } else if (KPALV_REQ_DISABLE == at_cmd->req_type) {
+ kpalv_receive_keep_alive_disable_cmd(ilm);
+ } else if (KPALV_REQ_QUERY == at_cmd->req_type) {
+ kpalv_receive_keep_alive_query_cmd(ilm);
+ } else {
+ kpalv_receive_keep_alive_invalid_cmd(ilm);
+ }
+}
+
+
+
+
+void kpalv_ilm_handler(ilm_struct *ilm)
+{
+ switch (ilm->msg_id) {
+ case MSG_ID_ATP_KPALV_KEEPALIVE_REQ:
+ kpalv_receive_keep_alive_req_cmd(ilm);
+ break;
+
+ /*timer expiry*/
+ case MSG_ID_TIMER_EXPIRY:
+ switch (evshed_get_index(ilm)) {
+ case 5:
+ evshed_timer_handler(keep_alive_cntx[0].control_info.idle_timer_scheduler);
+ break;
+ case 6:
+ evshed_timer_handler(keep_alive_cntx[1].control_info.idle_timer_scheduler);
+ break;
+ case 10:
+ evshed_timer_handler(keep_alive_cntx[0].control_info.retry_timer_scheduler);
+ break;
+ case 11:
+ evshed_timer_handler(keep_alive_cntx[1].control_info.retry_timer_scheduler);
+ break;
+ }
+ break;
+
+ default:
+ MD_TRC_KPALV_TR_ILM_WRONG_MSG_ID(ilm->msg_id);
+ break;
+ }
+}
+
+void kpalv_update_keep_alive_packet_by_ul_flow(kal_bool is_ul, kal_uint8 *ip_packet, kal_uint8 conn_id, kal_bool is_ipv6)
+{
+ kal_uint8 *stored_tcp_header = NULL;
+ kal_uint8 *in_tcp_header = NULL;
+ kal_uint32 in_tcp_seq_num =0;
+ kal_uint32 in_tcp_ack_num =0;
+
+ if (KAL_FALSE == is_ipv6) {
+ kal_uint16 ipid = 0;
+ kal_uint8 *stored_full_buffer = keep_alive_cntx[conn_id].data_info.ipv4_tcp_keep_alive_packet;
+ stored_tcp_header = stored_full_buffer + IPC_HDR_V4_HEADER_SIZE;
+ in_tcp_header = ip_packet + IPC_HDR_V4_HEADER_SIZE;
+
+ /*update the recvd ipid */
+ ipid = IPC_HDR_V4_GET_IDENTITY(ip_packet);
+ IPC_HDR_V4_SET_IDENTITY(stored_full_buffer, ipid); //saved last IPID +1 when sending a new keep-alive packet
+
+ /** for ipv4 header just update totallength */
+ IPC_HDR_V4_SET_TOTAL_LENGTH(stored_full_buffer, KPALV_KEEP_ALIVE_V4_PACKET_LENGTH);
+
+ } else {
+ kal_uint8 *stored_full_buffer = keep_alive_cntx[conn_id].data_info.ipv6_tcp_keep_alive_packet;
+ stored_tcp_header = stored_full_buffer + IPC_HDR_V6_HEADER_SIZE;
+ in_tcp_header = ip_packet + IPC_HDR_V6_HEADER_SIZE;
+
+ /** for ipv6 header just update payload length */
+ IPC_HDR_V6_SET_LENGTH(stored_full_buffer, (KPALV_KEEP_ALIVE_V6_PACKET_LENGTH - IPC_HDR_V6_HEADER_SIZE));
+
+ }
+
+ /*update tcp part: FLAG, PTR, CHECKSUM at later*/
+ in_tcp_seq_num = IPC_HDR_TCP_GET_SEQ_NUM(in_tcp_header);
+ IPC_HDR_TCP_SET_SEQ_NUM(stored_tcp_header, (in_tcp_seq_num -1));
+
+ in_tcp_ack_num = IPC_HDR_TCP_GET_ACK_NUM(in_tcp_header);
+ IPC_HDR_TCP_SET_ACK_NUM(stored_tcp_header, in_tcp_ack_num);
+
+ MD_TRC_KPALV_TR_UPDATE_KEEP_ALIVE_BUFF(conn_id, is_ipv6, (in_tcp_seq_num-1), in_tcp_ack_num);
+
+ IPC_HDR_TCP_SET_FLAGS(stored_tcp_header, 0);
+ IPC_HDR_TCP_SET_FLAGS(stored_tcp_header, IPC_HDR_TCP_FLAG_ACK);
+ IPC_HDR_TCP_SET_URGENT_PTR(stored_tcp_header, 0);
+ IPC_HDR_TCP_SET_OFFSET(stored_tcp_header, IPC_HDR_TCP_HEADER_SIZE);
+ IPC_HDR_TCP_SET_RESERVED(stored_tcp_header, 0);
+}
+
+/*ipv4 or ipv6 +tcp ul packet matched filter cbk*/
+void kpalv_ul_filter_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+
+ kal_uint8 *p_packet = NULL;
+ qbm_gpd *bd;
+ kal_uint8 conn_id;
+ kpalv_keep_alive_struct* connection_context = (kpalv_keep_alive_struct*)context;
+ conn_id = connection_context - &keep_alive_cntx[0];
+
+ /*this is uplink filter matched packet so we can take full snapshot here*/
+ ASSERT(filter_id == keep_alive_cntx[conn_id].control_info.ul_filter_id);
+
+ MD_TRC_KPALV_TR_UL_FILTER_CBK(conn_id, head_gpd, tail_gpd);
+
+ if (!QBM_DES_GET_BDP(head_gpd)) {
+ p_packet = QBM_DES_GET_DATAPTR(head_gpd);
+ } else {
+ /* get 1st bd data ptr */
+ bd = QBM_DES_GET_DATAPTR(head_gpd);
+
+ /* Loop to trace 1st DL BD with data buffer */
+ while (bd && (QBM_DES_GET_DATALEN(bd) == 0)) {
+ bd = (QBM_DES_GET_EOL(bd))?(NULL):((qbm_gpd*)QBM_DES_GET_NEXT(bd));
+ }
+
+ /* No any BD have data */
+ if (NULL == bd) {
+ qbmt_dest_q(head_gpd, tail_gpd);
+ return;
+ }
+
+ p_packet = QBM_DES_GET_DATAPTR(bd);
+ }
+ if (IPC_HDR_IS_V4(p_packet)) {
+
+ if (keep_alive_cntx[conn_id].data_info.is_already_updated == KAL_FALSE) {
+
+ kal_mem_set(keep_alive_cntx[conn_id].data_info.ipv4_tcp_keep_alive_packet, 0, sizeof(keep_alive_cntx[conn_id].data_info.ipv4_tcp_keep_alive_packet));
+ /*take full snapshot here for 1st dummy UL req from AP*/
+ kal_mem_cpy(keep_alive_cntx[conn_id].data_info.ipv4_tcp_keep_alive_packet, p_packet, KPALV_KEEP_ALIVE_IPV4_PACKET);//1 data byte will remain 00
+ /** always keep the ready buffer non fragmented */
+ IPC_HDR_V4_SET_FLAGS(keep_alive_cntx[conn_id].data_info.ipv4_tcp_keep_alive_packet, 0x2); /* Set Do Not Fragment */
+ IPC_HDR_V4_SET_FRAG_OFFSET(keep_alive_cntx[conn_id].data_info.ipv4_tcp_keep_alive_packet, 0);
+ keep_alive_cntx[conn_id].data_info.is_already_updated = KAL_TRUE;
+ keep_alive_cntx[conn_id].status = KPALV_MD_KEEPALIVE_STATE_ACTIVE;
+ MD_TRC_KPALV_TR_UL_FILTER_DETAILS(conn_id);
+ KPALV_SEND_KEEP_ALIVE_NOTIFY_URC(conn_id, KPALV_MD_KEEPALIVE_STATE_ACTIVE, keep_alive_cntx[conn_id].control_info.ps_id);
+ }
+ /** any pther UL paket sent by AP ,update this buffer for ready keep-alive message */
+ kpalv_update_keep_alive_packet_by_ul_flow(KAL_TRUE, p_packet, conn_id, KAL_FALSE);
+
+ }
+
+ if (IPC_HDR_IS_V6(p_packet)) {
+
+ //ipv6 handling here
+ if(keep_alive_cntx[conn_id].data_info.is_already_updated == KAL_FALSE) {
+ kal_mem_set(keep_alive_cntx[conn_id].data_info.ipv6_tcp_keep_alive_packet, 0, sizeof(keep_alive_cntx[conn_id].data_info.ipv6_tcp_keep_alive_packet));
+ kal_mem_cpy(keep_alive_cntx[conn_id].data_info.ipv6_tcp_keep_alive_packet, p_packet, KPALV_KEEP_ALIVE_IPV6_PACKET);//IPv6+TCP 1 data byte will remain 00
+ keep_alive_cntx[conn_id].data_info.is_already_updated = KAL_TRUE;
+ keep_alive_cntx[conn_id].status = KPALV_MD_KEEPALIVE_STATE_ACTIVE;
+ MD_TRC_KPALV_TR_UL_FILTER_DETAILS(conn_id);
+ KPALV_SEND_KEEP_ALIVE_NOTIFY_URC(conn_id, KPALV_MD_KEEPALIVE_STATE_ACTIVE, keep_alive_cntx[conn_id].control_info.ps_id);
+ }
+ //any pther UL paket sent by AP ,update this buffer for ready keep-alive message
+ kpalv_update_keep_alive_packet_by_ul_flow(KAL_TRUE, p_packet, conn_id, KAL_TRUE);
+ }
+ qbmt_dest_q(head_gpd, tail_gpd);
+}
+
+
+
+void kpalv_register_ul_filter_at_ipc(kal_uint8 conn_id, kpalv_req_ip_type_e ip_type)
+{
+ ipc_filter_rules_t ul_filter_rules;
+ kal_mem_set(&ul_filter_rules, 0, sizeof(ipc_filter_rules_t));
+
+ ul_filter_rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT;
+
+ ul_filter_rules.protocol = IPC_HDR_PROT_TCP;
+ ul_filter_rules.src_port = keep_alive_cntx[conn_id].at_info.src_port;
+ ul_filter_rules.dst_port = keep_alive_cntx[conn_id].at_info.dst_port;
+
+ /*pass the packet to UPCM as callback to filter to update keep-alive packet content*/
+ ul_filter_rules.features |= IPC_FILTER_FEATURE_CLONE;
+
+ if (ip_type == KPALV_REQ_IPTYPE_IPV6TCP) {
+ ul_filter_rules.valid_fields |= IPC_FILTER_BY_SRC_IPV6 |
+ IPC_FILTER_BY_DST_IPV6;
+ ul_filter_rules.ip_type = IPC_IP_TYPE_IPV6;
+ IPC_CP_V6_ADDR(&ul_filter_rules.src_ipv6.addr8, &keep_alive_cntx[conn_id].at_info.src_ipv6_addr);
+ IPC_CP_V6_ADDR(&ul_filter_rules.dst_ipv6.addr8, &keep_alive_cntx[conn_id].at_info.dst_ipv6_addr);
+
+ } else {
+ ul_filter_rules.valid_fields |= IPC_FILTER_BY_SRC_IPV4 |
+ IPC_FILTER_BY_DST_IPV4;
+ ul_filter_rules.ip_type = IPC_IP_TYPE_IPV4;
+ IPC_CP_V4_ADDR(&ul_filter_rules.src_ipv4.addr8, &keep_alive_cntx[conn_id].at_info.src_ipv4_addr);
+ IPC_CP_V4_ADDR(&ul_filter_rules.dst_ipv4.addr8, &keep_alive_cntx[conn_id].at_info.dst_ipv4_addr);
+ }
+ keep_alive_cntx[conn_id].control_info.ul_filter_id = ipc_register_ul_filter_with_info_cbk(
+ &ul_filter_rules, kpalv_ul_filter_cbk, &keep_alive_cntx[conn_id]);
+
+}
+
+void kpalv_keep_alive_rsp_received(kal_uint8 conn_id)
+{
+ //Stop idle timer if running
+ kpalv_stop_idle_timer(conn_id);
+ //stop probe timer if running, along with reset retry count
+ kpalv_stop_retry_timer(conn_id);
+ //start idle timer again
+ kpalv_start_idle_timer(conn_id);
+}
+
+void kpalv_dl_filter_cbk(ipc_filter_info_t *info_p,
+ void *context,
+ kal_int32 filter_id,
+ qbm_gpd *head_gpd,
+ qbm_gpd *tail_gpd,
+ kal_uint32 length)
+{
+
+ /*downlink filter matched for set filter*/
+ /*there could be two case 1. keep-alive ack 2. others*/
+ /* need update to keepalive packet seq & ack number based upon DL recvd from server*/
+ kal_uint8 *p_packet = NULL;
+ qbm_gpd *bd;
+ kal_bool is_ipv4 = KAL_FALSE;
+ kal_uint8 *p_tcp_header;
+ kal_uint32 dl_ack_num;
+ kal_uint32 dl_seq_num;
+ kal_uint16 tcp_flags;
+ kal_uint32 data_seg_len = 0;
+ kal_uint8 conn_id;
+ kal_uint8 *stored_full_buffer;
+ kal_uint8 *stored_tcp_header;
+ kal_uint8 tcp_total_header_len = 0;
+
+ kpalv_keep_alive_struct* connection_context = (kpalv_keep_alive_struct*)context;
+ conn_id = connection_context - &keep_alive_cntx[0];
+
+ ASSERT(filter_id == keep_alive_cntx[conn_id].control_info.dl_filter_id);
+
+ MD_TRC_KPALV_TR_DL_FILTER_CBK(conn_id, head_gpd, tail_gpd);
+ if (head_gpd == NULL || tail_gpd == NULL) {
+ return;
+ }
+
+ if (!QBM_DES_GET_BDP(head_gpd)) {
+ p_packet = QBM_DES_GET_DATAPTR(head_gpd);
+ } else {
+ /* get 1st bd data ptr */
+ bd = QBM_DES_GET_DATAPTR(head_gpd);
+
+ /* Loop to trace 1st DL BD with data buffer */
+ while (bd && (QBM_DES_GET_DATALEN(bd) == 0)) {
+ bd = (QBM_DES_GET_EOL(bd))?(NULL):((qbm_gpd*)QBM_DES_GET_NEXT(bd));
+ }
+
+ /* No any BD have data */
+ if (NULL == bd) {
+ /*zero length gpd*/
+ qbmt_dest_q(head_gpd, tail_gpd);
+ return;
+ }
+
+ p_packet = QBM_DES_GET_DATAPTR(bd);
+ }
+
+ //got the IP packet start address
+
+ if (IPC_HDR_IS_V4(p_packet)) {
+ is_ipv4 = KAL_TRUE;
+ p_tcp_header = p_packet + IPC_HDR_V4_HEADER_SIZE;//move to TCP header
+ tcp_total_header_len = IPC_HDR_TCP_GET_OFFSET(p_tcp_header);
+ data_seg_len = IPC_HDR_V4_GET_TOTAL_LENGTH(p_packet) - IPC_HDR_V4_HEADER_SIZE - tcp_total_header_len; // total length - ipv4-total tcp header
+ } else if (IPC_HDR_IS_V6(p_packet)) {
+ is_ipv4 = KAL_FALSE;
+ p_tcp_header = p_packet + IPC_HDR_V6_HEADER_SIZE;
+ tcp_total_header_len = IPC_HDR_TCP_GET_OFFSET(p_tcp_header);
+ data_seg_len = IPC_HDR_V6_GET_LENGTH(p_packet) - tcp_total_header_len; //payload length - total tcp header
+ } else {
+ qbmt_dest_q(head_gpd, tail_gpd);
+ return;
+ }
+
+ dl_ack_num = IPC_HDR_TCP_GET_ACK_NUM(p_tcp_header);
+ dl_seq_num = IPC_HDR_TCP_GET_SEQ_NUM(p_tcp_header);
+ tcp_flags = IPC_HDR_TCP_GET_FLAGS(p_tcp_header);
+
+ if (is_ipv4) {
+ stored_full_buffer = keep_alive_cntx[conn_id].data_info.ipv4_tcp_keep_alive_packet;
+ stored_tcp_header = stored_full_buffer + IPC_HDR_V4_HEADER_SIZE;
+ } else {
+ stored_full_buffer = keep_alive_cntx[conn_id].data_info.ipv6_tcp_keep_alive_packet;
+ stored_tcp_header = stored_full_buffer + IPC_HDR_V6_HEADER_SIZE;
+ }
+
+ MD_TRC_KPALV_TR_DL_PACKET_INFO(data_seg_len, dl_ack_num, dl_seq_num, tcp_flags);
+
+ /*this is only TCP ACK packet, could be Keep-aive ack so just check*/
+ if (tcp_flags == IPC_HDR_TCP_FLAG_ACK) {
+
+ kal_uint32 saved_ul_ack_num;
+ kal_uint32 saved_ul_seq_num;
+
+ saved_ul_ack_num = IPC_HDR_TCP_GET_ACK_NUM(stored_tcp_header);
+ saved_ul_seq_num = IPC_HDR_TCP_GET_SEQ_NUM(stored_tcp_header);
+
+ if ((saved_ul_seq_num == (dl_ack_num-1)) && (saved_ul_ack_num == dl_seq_num)) {
+ //this is the response of TCP keep-alive
+ kpalv_keep_alive_rsp_received(conn_id);
+ qbmt_dest_q(head_gpd, tail_gpd);
+ MD_TRC_KPALV_TR_DL_KEEP_ALIVE_ACK();
+ return;
+ }
+ }
+
+ /*pkt received from server so restart idle timer*/
+ kpalv_stop_idle_timer(conn_id);
+ //start idle timer again
+ kpalv_start_idle_timer(conn_id);
+ /*could be the case that retry probe is sent But before that server send some packet*/
+ /*we can assume server conn is active, so can stop retry timer if running*/
+ kpalv_stop_retry_timer(conn_id);
+
+ /** update tcp header fields for stored keep-alive packet */
+ /** update the TCP fileds when keep-alive Buffer updated by UL(ACTIVE_STATE) */
+ if ((connection_context->data_info.is_already_updated == KAL_TRUE) &&
+ (connection_context->status == KPALV_MD_KEEPALIVE_STATE_ACTIVE)) {
+ IPC_HDR_TCP_SET_SEQ_NUM(stored_tcp_header, dl_ack_num -1);
+ IPC_HDR_TCP_SET_ACK_NUM(stored_tcp_header, dl_seq_num + data_seg_len);
+ MD_TRC_KPALV_TR_DL_PACKET_INFO_UPDATE_UL((dl_seq_num + data_seg_len), (dl_ack_num -1));
+ }
+
+ /*not a keep-alive ack => update last DL ack & seq to keep-alive buffer & forward to AP*/
+ /* pass to AP via IPCORE*/
+ {
+ ipc_pkt_t pkt;
+ kal_uint32 netif_id = 0;
+
+ pkt.buf_type = IPC_PKT_DES_TYPE_GPD;
+ pkt.head = head_gpd;
+ pkt.tail = tail_gpd;
+
+ netif_id = keep_alive_cntx[conn_id].at_info.netif_id | IPC_NETIF_ID_LHIF_BEGIN;
+ MD_TRC_KPALV_TR_DL_PACKET_FORWARD(head_gpd, tail_gpd, netif_id);
+
+ if (KAL_FALSE == ipc_send_dl_pkt_in_did(&pkt, NULL, netif_id)) {
+ if(qbm_get_used(head_gpd)) {
+ qbmt_dest_q(head_gpd, tail_gpd);
+ }
+ }
+ }
+
+}
+
+
+
+void kpalv_register_dl_filter_at_ipc(kal_uint8 conn_id, kpalv_req_ip_type_e ip_type)
+{
+ ipc_filter_rules_t dl_filter_rules;
+ kal_mem_set(&dl_filter_rules, 0, sizeof(ipc_filter_rules_t));
+ dl_filter_rules.valid_fields = IPC_FILTER_BY_PROTOCOL |
+ IPC_FILTER_BY_SRC_PORT |
+ IPC_FILTER_BY_DST_PORT |
+ IPC_FILTER_BY_PDN_ID;
+
+
+ dl_filter_rules.protocol = IPC_HDR_PROT_TCP;
+ /*reverse port for DL filter*/
+ dl_filter_rules.src_port = keep_alive_cntx[conn_id].at_info.dst_port;
+ dl_filter_rules.dst_port = keep_alive_cntx[conn_id].at_info.src_port;
+
+ dl_filter_rules.pdn_id = keep_alive_cntx[conn_id].control_info.pdn_id;
+
+ if (ip_type == KPALV_REQ_IPTYPE_IPV6TCP) {
+ dl_filter_rules.valid_fields |= IPC_FILTER_BY_SRC_IPV6 |
+ IPC_FILTER_BY_DST_IPV6;
+ dl_filter_rules.ip_type = IPC_IP_TYPE_IPV6;
+
+ IPC_CP_V6_ADDR(&dl_filter_rules.src_ipv6.addr8, &keep_alive_cntx[conn_id].at_info.dst_ipv6_addr);
+ IPC_CP_V6_ADDR(&dl_filter_rules.dst_ipv6.addr8, &keep_alive_cntx[conn_id].at_info.src_ipv6_addr);
+
+ } else {
+ dl_filter_rules.valid_fields |= IPC_FILTER_BY_SRC_IPV4 |
+ IPC_FILTER_BY_DST_IPV4;
+ dl_filter_rules.ip_type = IPC_IP_TYPE_IPV4;
+
+ IPC_CP_V4_ADDR(&dl_filter_rules.src_ipv4.addr8, &keep_alive_cntx[conn_id].at_info.dst_ipv4_addr);
+ IPC_CP_V4_ADDR(&dl_filter_rules.dst_ipv4.addr8, &keep_alive_cntx[conn_id].at_info.src_ipv4_addr);
+ }
+
+ keep_alive_cntx[conn_id].control_info.dl_filter_id = ipc_register_dl_filter_with_info_cbk(
+ &dl_filter_rules, kpalv_dl_filter_cbk , &keep_alive_cntx[conn_id]);
+}
+
+kal_bool kpalv_get_conn_number(kal_uint8* conn_id)
+{
+ int i = 0;
+ for (i= 0; i< KPALV_MAX_KEEP_ALIVE_CONN; i++) {
+ if(keep_alive_cntx[i].is_cntx_valid == KAL_FALSE) {
+ *conn_id = i;
+ return KAL_TRUE;
+ }
+ }
+ return KAL_FALSE;
+}
+
+void kpalv_send_keep_alive_notify_urc(kal_uint8 conn_handle, kpalv_md_kpalive_state_e state, kal_uint8 rsp_ps_idx)
+{
+ //MSG_ID_ATP_KPALV_CONNECTION_STATUS_IND
+ atp_kpalv_connection_status_ind_struct *p_ind = NULL;
+ kal_uint16 sap_id = KPALV_SAP;
+
+ p_ind = (atp_kpalv_connection_status_ind_struct *)construct_local_para
+ (sizeof(atp_kpalv_connection_status_ind_struct), TD_RESET);
+
+ p_ind->conn_id = conn_handle;
+ p_ind->status = state;
+
+ MD_TRC_KPALV_TR_NOTIFY_FOR_URC_TO_ATP(conn_handle, state);
+
+ msg_send6(MOD_KPALV, MOD_ATP + rsp_ps_idx, sap_id, MSG_ID_ATP_KPALV_CONNECTION_STATUS_IND,
+ (local_para_struct *)p_ind, NULL);
+}
+
+
+void kpalv_send_keep_alive_notify(kal_bool ok, kal_uint8 conn_handle, kpalv_md_kpalive_state_e state, kal_bool ap_dis_flow, kal_uint8 rsp_ps_idx)
+{
+
+ //MSG_ID_ATP_KPALV_KEEPALIVE_CNF
+ atp_kpalv_keepalive_cnf_struct *p_ind = NULL;
+ kal_uint16 sap_id = KPALV_SAP;
+
+ p_ind = (atp_kpalv_keepalive_cnf_struct *)construct_local_para
+ (sizeof(atp_kpalv_keepalive_cnf_struct), TD_RESET);
+
+ p_ind->result = ok;
+ p_ind->conn_id = conn_handle;
+ p_ind->status = state;
+ p_ind->is_ap_disable_rsp = ap_dis_flow;
+
+ MD_TRC_KPALV_TR_NOTIFY_RSP_TO_ATP(ok, conn_handle, state, ap_dis_flow);
+
+ msg_send6(MOD_KPALV, MOD_ATP + rsp_ps_idx, sap_id, MSG_ID_ATP_KPALV_KEEPALIVE_CNF,
+ (local_para_struct *)p_ind, NULL);
+}
+
+
+kal_bool kpalv_check_is_duplicate_req(local_para_struct *local_para_ptr)
+{
+ kal_uint8 i = 0;
+ kal_uint32 result = 0;
+
+ kpalv_keep_alive_at_cmd_info_struct *recvd_at_info = (kpalv_keep_alive_at_cmd_info_struct *)(local_para_ptr + 1);
+ kpalv_keep_alive_at_cmd_info_struct *stored_at_info = NULL;
+ for (i= 0; i<KPALV_MAX_KEEP_ALIVE_CONN; i++)
+ {
+ stored_at_info = &keep_alive_cntx[i].at_info;
+ result = kal_mem_cmp(stored_at_info, recvd_at_info, sizeof(kpalv_keep_alive_at_cmd_info_struct));
+ if (result == 0) {
+ return KAL_TRUE;
+ }
+ }
+ return KAL_FALSE;
+}
+
+/*
+1. Check duplicate req or not, if yes, return ERROR for this.
+2. get conn_id from pool, if not get return ERROR
+3. get PDNID & SIMID from netif , if FALSE return from IPC API, return ERROR to AP
+4. if SIMID from AP & IPC API are different , return ERROR
+*/
+void kpalv_receive_keep_alive_enable_cmd(ilm_struct *ilm)
+{
+ kal_uint8 ip_type = 0;
+ kal_uint32 pdn_id = 0;
+ kal_uint32 netif_id = 0;
+ kal_uint8 ps_id = 0;
+ kal_uint8 conn_id = 0;
+ kal_bool cnf_result = KAL_FALSE;
+ kpalv_md_kpalive_state_e conn_status = KPALV_MD_KEEPALIVE_STATE_INACTIVE;
+
+ kal_uint8 atp_idx = ilm->src_mod_id - MOD_ATP;
+ atp_kpalv_keepalive_req_struct *at_cmd = (atp_kpalv_keepalive_req_struct *)(ilm->local_para_ptr);
+
+ if (at_cmd->parsing_result == KAL_TRUE) {
+ /** 1. check for only TCP handling for UDP return directly with error*/
+
+ /** 2.check for duplicate req*/
+ if (kpalv_check_is_duplicate_req(ilm->local_para_ptr)) {
+ MD_TRC_KPALV_TR_ENABLE_REQ_DUPLICATE();
+ goto final_cnf;
+ }
+
+ /** 3.check max conn reached or not*/
+ if (KAL_FALSE == kpalv_get_conn_number(&conn_id)) {
+ MD_TRC_KPALV_TR_ENABLE_REQ_MAX_CONN();
+ goto final_cnf;
+ }
+
+ ip_type = ((at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV6TCP) || (at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV6UDP)) ? IPC_IP_TYPE_IPV6 : IPC_IP_TYPE_IPV4;
+ //cant set DL filter as failed for pdnid
+ /** 4..get PDNID from NETIFID*/
+ netif_id = at_cmd->netif_id | IPC_NETIF_ID_LHIF_BEGIN;
+ if (ipc_find_pdn_id_by_netif_id(netif_id, ip_type, &pdn_id, &ps_id) == KAL_FALSE) {
+ //temp assign for internal testing , return ERROR
+ //pdn_id = 15;
+ //ps_id = 0;
+ MD_TRC_KPALV_TR_ENABLE_REQ_NETIF_FAILED();
+ goto final_cnf;
+ }
+ else
+ {
+ if (ps_id != atp_idx)
+ {
+ MD_TRC_KPALV_TR_ENABLE_REQ_SIM_MISMATCH();
+ goto final_cnf;
+ }
+ }
+ if ((at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV4TCP) || (at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV6TCP)) {
+ kal_mem_set(&keep_alive_cntx[conn_id].at_info, 0, sizeof(kpalv_keep_alive_at_cmd_info_struct));
+ //reset the data part for new keep-alive ind
+ kal_mem_set(&keep_alive_cntx[conn_id].data_info, 0, sizeof(kpalv_keep_alive_data_struct));
+
+ /*update current control info all fields*/
+ keep_alive_cntx[conn_id].control_info.pdn_id = pdn_id;
+ keep_alive_cntx[conn_id].control_info.ps_id = ps_id;
+ keep_alive_cntx[conn_id].control_info.curr_retry_attempt = 0;
+ keep_alive_cntx[conn_id].control_info.ul_filter_id = -1;
+ keep_alive_cntx[conn_id].control_info.dl_filter_id = -1;
+
+ keep_alive_cntx[conn_id].at_info.is_enable = KAL_TRUE;
+ keep_alive_cntx[conn_id].at_info.ip_type = at_cmd->ip_type;
+ keep_alive_cntx[conn_id].at_info.netif_id = at_cmd->netif_id;
+ keep_alive_cntx[conn_id].at_info.src_port = at_cmd->src_port;
+ keep_alive_cntx[conn_id].at_info.dst_port = at_cmd->dst_port;
+
+ /*keep-alive parameters*/
+ keep_alive_cntx[conn_id].at_info.idle_time = at_cmd->idle_time;
+ keep_alive_cntx[conn_id].at_info.probe_interval = at_cmd->probe_interval;
+ keep_alive_cntx[conn_id].at_info.max_retry_cnt = at_cmd->retry_cnt;
+ if (at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV6TCP) {
+ kal_mem_cpy(keep_alive_cntx[conn_id].at_info.src_ipv6_addr, at_cmd->src_ipv6_addr, 16);
+ kal_mem_cpy(keep_alive_cntx[conn_id].at_info.dst_ipv6_addr, at_cmd->dst_ipv6_addr, 16);
+ } else {
+ kal_mem_cpy(keep_alive_cntx[conn_id].at_info.src_ipv4_addr, at_cmd->src_ipv4_addr, 4);
+ kal_mem_cpy(keep_alive_cntx[conn_id].at_info.dst_ipv4_addr, at_cmd->dst_ipv4_addr, 4);
+ }
+
+ //register UL/DL filter
+ kpalv_register_ul_filter_at_ipc(conn_id, at_cmd->ip_type);
+ kpalv_register_dl_filter_at_ipc(conn_id, at_cmd->ip_type);
+
+ keep_alive_cntx[conn_id].is_cntx_valid = KAL_TRUE;
+ keep_alive_cntx[conn_id].status = KPALV_MD_KEEPALIVE_STATE_PENDING;
+
+ //start Idle timer
+ kpalv_start_idle_timer(conn_id);
+ conn_status = keep_alive_cntx[conn_id].status;
+ cnf_result = KAL_TRUE;
+ } else if ((at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV4UDP) || (at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV6UDP)) {
+ kal_mem_set(&keep_alive_cntx[conn_id].at_info, 0, sizeof(kpalv_keep_alive_at_cmd_info_struct));
+ //reset the data part for new keep-alive ind
+ kal_mem_set(&keep_alive_cntx[conn_id].data_info, 0, sizeof(kpalv_keep_alive_data_struct));
+ /*update current control info all fields*/
+ keep_alive_cntx[conn_id].control_info.pdn_id = pdn_id;
+ keep_alive_cntx[conn_id].control_info.ps_id = ps_id;
+ keep_alive_cntx[conn_id].control_info.curr_retry_attempt = 0;
+ keep_alive_cntx[conn_id].control_info.ul_filter_id = -1;
+ keep_alive_cntx[conn_id].control_info.dl_filter_id = -1;
+
+ keep_alive_cntx[conn_id].at_info.is_enable = KAL_TRUE;
+ keep_alive_cntx[conn_id].at_info.ip_type = at_cmd->ip_type;
+ keep_alive_cntx[conn_id].at_info.netif_id = at_cmd->netif_id;
+ keep_alive_cntx[conn_id].at_info.src_port = at_cmd->src_port;
+ keep_alive_cntx[conn_id].at_info.dst_port = at_cmd->dst_port;
+
+ /*keep-alive parameters only T1 in UDP*/
+ keep_alive_cntx[conn_id].at_info.idle_time = at_cmd->idle_time;
+
+ if (at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV6UDP) {
+ kal_mem_cpy(keep_alive_cntx[conn_id].at_info.src_ipv6_addr, at_cmd->src_ipv6_addr, 16);
+ kal_mem_cpy(keep_alive_cntx[conn_id].at_info.dst_ipv6_addr, at_cmd->dst_ipv6_addr, 16);
+ } else {
+ kal_mem_cpy(keep_alive_cntx[conn_id].at_info.src_ipv4_addr, at_cmd->src_ipv4_addr, 4);
+ kal_mem_cpy(keep_alive_cntx[conn_id].at_info.dst_ipv4_addr, at_cmd->dst_ipv4_addr, 4);
+ }
+ keep_alive_cntx[conn_id].is_cntx_valid = KAL_TRUE;
+ keep_alive_cntx[conn_id].status = KPALV_MD_KEEPALIVE_STATE_ACTIVE;
+ kpalv_start_idle_timer(conn_id);
+ conn_status = keep_alive_cntx[conn_id].status;
+ cnf_result = KAL_TRUE;
+ kpalv_prepare_udp_keep_alive_packet_buffer(conn_id);
+ } else {
+ cnf_result = KAL_FALSE;
+ conn_id = 0;
+ conn_status = KPALV_MD_KEEPALIVE_STATE_INACTIVE;
+ }
+ }
+
+final_cnf:
+ KPALV_SEND_KEEP_ALIVE_NOTIFY_CNF(cnf_result, conn_id, conn_status, KAL_FALSE, atp_idx);
+
+
+}
+
+void kpalv_prepare_udp_keep_alive_packet_buffer(kal_uint8 conn_id) {
+ kal_uint8 *ip_header = NULL;
+ kal_uint32 total_len = 0;
+ kal_uint8 *udp_header = NULL;
+ kal_uint8 *udp_data = NULL;
+ kal_uint16 sum16 = 0;
+ kal_uint8 *src_addr = NULL;
+ kal_uint8 *dst_addr = NULL;
+ kal_uint16 src_port = 0;
+ kal_uint16 dst_port = 0;
+ kal_uint32 ip_header_len = 0;
+ kpalv_keep_alive_at_cmd_info_struct *at_info = NULL;
+
+
+ at_info = &keep_alive_cntx[conn_id].at_info;
+ if (KPALV_REQ_IPTYPE_IPV4UDP == at_info->ip_type) {
+ ip_header = keep_alive_cntx[conn_id].data_info.ipv4_udp_keep_alive_packet;
+ src_addr = at_info->src_ipv4_addr;
+ dst_addr = at_info->dst_ipv4_addr;
+ ip_header_len = IPC_HDR_V4_HEADER_SIZE;
+ } else {
+ ip_header = keep_alive_cntx[conn_id].data_info.ipv6_udp_keep_alive_packet;
+ src_addr = at_info->src_ipv6_addr;
+ dst_addr = at_info->dst_ipv6_addr;
+ ip_header_len = IPC_HDR_V6_HEADER_SIZE;
+ }
+
+ src_port = at_info->src_port;
+ dst_port = at_info->dst_port;
+
+ total_len = ip_header_len + IPC_HDR_UDP_HEADER_SIZE + 1;
+ udp_header = ip_header + ip_header_len;
+ udp_data = udp_header + IPC_HDR_UDP_HEADER_SIZE;
+
+ MD_TRC_KPALV_TR_PREPARE_UDP_KEEP_ALIVE_PKT(conn_id, total_len, ip_header_len);
+
+ IPC_HDR_UDP_SET_SRC_PORT(udp_header, src_port);
+ IPC_HDR_UDP_SET_DST_PORT(udp_header, dst_port);
+ IPC_HDR_UDP_SET_LENGTH(udp_header, total_len - ip_header_len);
+ IPC_HDR_UDP_SET_CHECKSUM(udp_header, 0);
+ kal_mem_set(udp_data, 0xff, 1);
+ sum16 = ipc_calc_udp_checksum((KPALV_REQ_IPTYPE_IPV4UDP == at_info->ip_type)?KAL_TRUE:KAL_FALSE,
+ src_addr,
+ dst_addr,
+ udp_header,
+ total_len - ip_header_len);
+ IPC_HDR_UDP_SET_CHECKSUM(udp_header, sum16);
+
+ if (KPALV_REQ_IPTYPE_IPV4UDP == at_info->ip_type) {
+ IPC_HDR_V4_RESET_VER_IHL_DSCP_ECN(ip_header);
+
+ IPC_HDR_V4_SET_TOTAL_LENGTH(ip_header, total_len);
+ IPC_HDR_V4_SET_IDENTITY(ip_header, 0);
+ IPC_HDR_V4_SET_FLAGS(ip_header, 0); /* Set Do Not Fragment */
+ IPC_HDR_V4_SET_FRAG_OFFSET(ip_header, 0);
+ IPC_HDR_V4_SET_TTL(ip_header, IPC_DEF_TTL);
+ IPC_HDR_V4_SET_PROTOCOL(ip_header, IPC_HDR_PROT_UDP);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, 0);
+ IPC_HDR_V4_SET_SRC_ADDR(ip_header, src_addr);
+ IPC_HDR_V4_SET_DST_ADDR(ip_header, dst_addr);
+ sum16 = ipc_calc_ipv4_checksum(ip_header);
+ IPC_HDR_V4_SET_HEADER_CHECKSUM(ip_header, sum16);
+ } else {
+ //currently no need
+ IPC_HDR_V6_RESET_VER_TC_FL(ip_header);
+ IPC_HDR_V6_SET_TC(ip_header, 0);
+ IPC_HDR_V6_SET_FLOW_LABEL(ip_header, 0);
+ IPC_HDR_V6_SET_LENGTH(ip_header, (total_len-ip_header_len));
+ IPC_HDR_V6_SET_NH_TYPE(ip_header, IPC_HDR_PROT_UDP);
+ IPC_HDR_V6_SET_HOP_LIMIT(ip_header, IPC_DEF_TTL);
+ IPC_HDR_V6_SET_SRC_ADDR(ip_header, src_addr);
+ IPC_HDR_V6_SET_DST_ADDR(ip_header, dst_addr);
+ }
+
+}
+
+void kpalv_stop_reset_all_connections(void)
+{
+ kal_uint8 i = 0;
+
+ for (i= 0; i<KPALV_MAX_KEEP_ALIVE_CONN; i++)
+ {
+ if (keep_alive_cntx[i].is_cntx_valid) {
+ kpalv_stop_keep_alive_for_connection(i);
+ }
+ }
+}
+
+/** invalid req for keepalive msgid, return ERROR*/
+void kpalv_receive_keep_alive_invalid_cmd(ilm_struct *ilm)
+{
+ kal_uint8 atp_idx = ilm->src_mod_id - MOD_ATP;
+ KPALV_SEND_KEEP_ALIVE_NOTIFY_CNF(KAL_FALSE, 0, KPALV_MD_KEEPALIVE_STATE_INACTIVE, KAL_FALSE, atp_idx);
+}
+
+/** query result for a connection_status*/
+void kpalv_receive_keep_alive_query_cmd(ilm_struct *ilm) {
+ kal_uint8 conn_id = 0xFF;
+ kal_uint8 conn_status = KPALV_MD_KEEPALIVE_STATE_INACTIVE;
+ kal_uint8 atp_idx = ilm->src_mod_id - MOD_ATP;
+ if(KAL_TRUE == kpalv_receive_keep_alive_query_result(ilm, &conn_id, &conn_status)) {
+ /** found a conection with given at paramers, return status */
+ KPALV_SEND_KEEP_ALIVE_NOTIFY_CNF(KAL_TRUE, conn_id, conn_status, KAL_FALSE, atp_idx);
+ } else {
+ /** no such connection found return ERROR */
+ KPALV_SEND_KEEP_ALIVE_NOTIFY_CNF(KAL_FALSE, conn_id, conn_status, KAL_FALSE, atp_idx);
+ }
+
+}
+kal_bool kpalv_receive_keep_alive_query_result(ilm_struct *ilm, kal_uint8 *conn_id, kal_uint8 *conn_status)
+{
+ kal_uint8 i= 0;
+ kal_uint32 cmp;
+ kal_uint32 cmp1;
+ kal_bool result = KAL_FALSE;
+ /** find a conn based upon input parameters*/
+ atp_kpalv_keepalive_req_struct *at_cmd = (atp_kpalv_keepalive_req_struct *)(ilm->local_para_ptr);
+
+ for(i=0; i < KPALV_MAX_KEEP_ALIVE_CONN; i++)
+ {
+ if((keep_alive_cntx[i].is_cntx_valid == KAL_TRUE) &&
+ (keep_alive_cntx[i].at_info.netif_id == at_cmd->netif_id) &&
+ (keep_alive_cntx[i].at_info.src_port == at_cmd->src_port) &&
+ (keep_alive_cntx[i].at_info.dst_port == at_cmd->dst_port) &&
+ (keep_alive_cntx[i].at_info.ip_type == at_cmd->ip_type))
+ {
+ result = KAL_TRUE;
+ }
+ else
+ {
+ result = KAL_FALSE;
+ continue;
+ }
+
+ if ((at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV6TCP) || (at_cmd->ip_type == KPALV_REQ_IPTYPE_IPV6UDP)) {
+ cmp = kal_mem_cmp(keep_alive_cntx[i].at_info.src_ipv6_addr, at_cmd->src_ipv6_addr, 16);
+ cmp1 = kal_mem_cmp(keep_alive_cntx[i].at_info.dst_ipv6_addr, at_cmd->dst_ipv6_addr, 16);
+ if ((cmp == 0) && (cmp1 == 0)) {
+ result = KAL_TRUE;
+ } else {
+ result = KAL_FALSE;
+ continue;
+ }
+ } else {
+ cmp = (keep_alive_cntx[i].at_info.src_ipv4_addr == at_cmd->src_ipv4_addr);
+ cmp1 = (keep_alive_cntx[i].at_info.dst_ipv4_addr == at_cmd->dst_ipv4_addr);
+ if ((cmp == 0) && (cmp1 == 0)) {
+ result = KAL_TRUE;
+ } else {
+ result = KAL_FALSE;
+ continue;
+ }
+ }
+
+ if(result == KAL_TRUE) {
+ *conn_id = i;
+ *conn_status = keep_alive_cntx[i].status;
+ return result;
+ }
+ }
+ return result;
+}
+
+void kpalv_receive_keep_alive_disable_cmd(ilm_struct *ilm)
+{
+ kal_uint8 conn_id = 0;
+ kal_uint8 atp_idx = ilm->src_mod_id - MOD_ATP;
+ kal_bool result = KAL_TRUE;
+ kal_bool is_ap_disable_req = KAL_TRUE;
+
+ atp_kpalv_keepalive_req_struct *at_cmd = (atp_kpalv_keepalive_req_struct *)(ilm->local_para_ptr);
+ if(at_cmd->parsing_result == KAL_TRUE) {
+ conn_id = at_cmd->conn_id;
+ /** single conection reset */
+ if (conn_id < 0xFF) {
+ if ((conn_id < KPALV_MAX_KEEP_ALIVE_CONN) && (keep_alive_cntx[conn_id].is_cntx_valid)) {
+ kpalv_stop_keep_alive_for_connection(conn_id);
+ } else {
+ result = KAL_FALSE;
+ }
+ }
+ /** for all conn reset */
+ if (conn_id == 0xFF) {
+ kpalv_stop_reset_all_connections();
+ }
+ } else {
+ result = KAL_FALSE;
+ }
+ KPALV_SEND_KEEP_ALIVE_NOTIFY_CNF(result, conn_id, KPALV_MD_KEEPALIVE_STATE_INACTIVE, is_ap_disable_req, atp_idx);
+}
+
+
+void kpalv_unregister_ul_dl_filter_at_ipc(kal_uint8 conn_id)
+{
+ if (keep_alive_cntx[conn_id].control_info.dl_filter_id >= 0) {
+ ipc_deregister_dl_filter(keep_alive_cntx[conn_id].control_info.dl_filter_id);
+ keep_alive_cntx[conn_id].control_info.dl_filter_id = -1;
+ }
+ if (keep_alive_cntx[conn_id].control_info.ul_filter_id >= 0) {
+ ipc_deregister_ul_filter(keep_alive_cntx[conn_id].control_info.ul_filter_id);
+ keep_alive_cntx[conn_id].control_info.ul_filter_id = -1;
+ }
+}
+
+void kpalv_stop_keep_alive_for_connection(kal_uint8 conn_id)
+{
+ MD_TRC_KPALV_TR_STOP_KEEP_ALIVE_CONN(conn_id);
+ /*reset at info*/
+ kal_mem_set(&keep_alive_cntx[conn_id].at_info, 0, sizeof(kpalv_keep_alive_at_cmd_info_struct));
+
+ /*stop all the running timers for this connection*/
+ kpalv_stop_idle_timer(conn_id);
+ kpalv_stop_retry_timer(conn_id);
+
+ kpalv_unregister_ul_dl_filter_at_ipc(conn_id);
+ keep_alive_cntx[conn_id].control_info.pdn_id = 0;
+ keep_alive_cntx[conn_id].control_info.ps_id = 0;
+ keep_alive_cntx[conn_id].control_info.curr_retry_attempt = 0;
+
+ keep_alive_cntx[conn_id].is_cntx_valid = KAL_FALSE;
+ keep_alive_cntx[conn_id].status = KPALV_MD_KEEPALIVE_STATE_INACTIVE;
+ //reset the data part for new keep-alive ind
+ kal_mem_set(&keep_alive_cntx[conn_id].data_info, 0, sizeof(kpalv_keep_alive_data_struct));
+}
+
+
+void kpalv_module_clean(void)
+{
+ kal_uint8 i = 0;
+ for (i= 0; i<KPALV_MAX_KEEP_ALIVE_CONN; i++)
+ {
+ if (keep_alive_cntx[i].is_cntx_valid) {
+ /*reset at info*/
+ kal_mem_set(&keep_alive_cntx[i].at_info, 0, sizeof(kpalv_keep_alive_at_cmd_info_struct));
+ kal_mem_set(&keep_alive_cntx[i].data_info, 0, sizeof(kpalv_keep_alive_data_struct));
+ }
+ }
+}
+
+void kpalv_task_clean_handler(void)
+{
+ kpalv_module_clean();
+}
+
+
+#ifdef ATEST_SYS_KPALV
+void* kpalv_get_connection_address(kal_uint8 conn_id)
+{
+ return (&keep_alive_cntx[conn_id]);
+}
+
+kal_int32 kpalv_get_connection_ul_filter_id(kal_uint8 conn_id) {
+ return keep_alive_cntx[conn_id].control_info.ul_filter_id;
+}
+
+kal_int32 kpalv_get_connection_dl_filter_id(kal_uint8 conn_id) {
+ return keep_alive_cntx[conn_id].control_info.dl_filter_id;
+}
+#endif
diff --git a/mcu/middleware/kpalv/src/kpalv_task.c b/mcu/middleware/kpalv/src/kpalv_task.c
new file mode 100644
index 0000000..3c4279f
--- /dev/null
+++ b/mcu/middleware/kpalv/src/kpalv_task.c
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2012
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ *****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * kpalv.h
+ *
+ * Project:
+ * --------
+ *
+ *
+ * Description:
+ * ------------
+ * keepalive task handling function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ *
+ *
+ ****************************************************************************/
+#include "kal_public_api.h"
+#include "syscomp_config.h"
+#include "kpalv.h"
+#include "kpalv_debug.h"
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+
+kal_bool kpalv_task_init(void)
+{
+ kal_bool result = KAL_TRUE;
+ kpalv_init();
+ return result;
+}
+
+
+kal_bool kpalv_task_reset(void)
+{
+ kal_bool result = KAL_TRUE;
+ kpalv_reset();
+
+ return result;
+}
+
+
+void kpalv_dispatch_ilm(ilm_struct *ilm)
+{
+ if (MOD_KPALV == ilm->dest_mod_id) {
+ kal_set_active_module_id(MOD_KPALV);
+ kpalv_ilm_handler(ilm);
+ }
+
+ /*
+ * Free the ILM.
+ */
+ destroy_ilm(ilm);
+}
+
+
+static void kpalv_task_main(task_entry_struct *task_entry_ptr)
+{
+ ilm_struct current_ilm;
+
+ while (1) {
+ if (KAL_TRUE == msg_receive_extq(¤t_ilm)) {
+ kpalv_dispatch_ilm(¤t_ilm);
+ }
+ }
+}
+
+kal_bool kpalv_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct handler_info =
+ {
+ kpalv_task_main, /* task entry function */
+ kpalv_task_init, /* task initialization function */
+ kpalv_task_reset, /* task reset handler */
+ };
+
+ *handle = (comptask_handler_struct *)&handler_info;
+
+ return KAL_TRUE;
+}
+
diff --git a/mcu/middleware/kpalv/src/kpalv_ut.c b/mcu/middleware/kpalv/src/kpalv_ut.c
new file mode 100644
index 0000000..bfa3ee2
--- /dev/null
+++ b/mcu/middleware/kpalv/src/kpalv_ut.c
@@ -0,0 +1,1028 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2012
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+ * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+ *
+ *****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * kpalv_data.c
+ *
+ * Project:
+ * --------
+ *
+ *
+ * Description:
+ * ------------
+ * keepalive handling for connection
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ *
+ *
+ ****************************************************************************/
+#ifdef ATEST_SYS_KPALV
+#include "kal_public_api.h"
+#include "sys_test.h"
+#include "kpalv.h"
+#include "kpalv_msgid.h"
+#include "mw_sap.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+#include "atp_kpalv_msgs.h"
+/*------------------------------------------------------------------------------
+ * Public fucntions.
+ *----------------------------------------------------------------------------*/
+static kal_uint8 kpalv_ut_ul_packet_1[] = {
+0x45,0x00,0x00,0x4d,
+0x07,0xda,0x40,0x00,
+0x80,0x06,0x00,0x00,
+0xc0,0xa8,0x00,0x02,
+0xdf,0x68,0xd2,0xa3,
+0x1d,0xe6,0x21,0xb9,
+0x9f,0x4b,0x17,0x11,
+0x70,0x15,0x80,0xd6,
+0x50,0x18,0x02,0x02,
+0x72,0xf6,0x00,0x00,
+0x7e,0x00,0x20,0x00,
+0x02,0x5a,0x16,0x49,
+0xa0,0x54,0x42,0x4f,0x58,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
+0x30,0x30,0x30,0x30,0x30,0x35,0x00,0x00,0x03,0x02,0x00,0x04,
+0x00,0x01,0x00,0xc9,0x7e};
+
+
+static kal_uint8 kpalv_ut_ul_packet_2[] = {
+0x45,0x00,
+0x00,0x4d,0x07,0xdb,0x40,0x00,0x80,0x06,0x00,0x00,0xc0,0xa8,0x00,0x02,0xdf,0x68,
+0xd2,0xa3,0x1d,0xe6,0x21,0xb9,0x9f,0x4b,0x17,0x36,0x70,0x15,0x81,0x20,0x50,0x18,
+0x02,0x02,0x72,0xf6,0x00,0x00,0x7e,0x00,0x20,0x00,0x03,0x5a,0x16,0x49,0xa6,0x54,
+0x42,0x4f,0x58,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x35,
+0x00,0x00,0x03,0x02,0x00,0x04,0x00,0x01,0x00,0xce,0x7e
+};
+
+
+static kal_uint8 kpalv_ut_dl_packet_1[] = {
+0x45,0x00,
+0x00,0x28,0x00,0x3e,0x00,0x00,0xed,0x06,0x5a,0xdb,0xdf,0x68,0xd2,0xa3,0xc0,0xa8,
+0x00,0x02,0x21,0xb9,0x1d,0xe6,0x70,0x15,0x80,0xd6,0x9f,0x4b,0x17,0x36,0x50,0x10,
+0xb3,0xdb,0xa2,0x35,0x00,0x00
+};
+
+//for test tcp seg len
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+static kal_uint8 kpalv_ut_dl_packet_2[] = {
+0x45,0x00,
+0x00,0x72,0x00,0x3f,0x00,0x00,0xed,0x06,0x5a,0x90,0xdf,0x68,0xd2,0xa3,0xc0,0xa8,
+0x00,0x02,0x21,0xb9,0x1d,0xe6,0x70,0x15,0x80,0xd6,0x9f,0x4b,0x17,0x36,0x50,0x18,
+0xb4,0x00,0xce,0xa0,0x00,0x00,0x7e,0x00,0x45,0x00,0x2a,0x58,0x68,0x64,0xaa,0x54,
+0x42,0x4f,0x58,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x35,
+0x00,0x00,0x03,0x02,0x00,0x03,0x00,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x68,0x64,0xa9,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x7e
+};
+
+static kal_uint8 kpalv_ut_dl_packet_3[] = {
+0x45,0x00,0x00,0x28,0x00,0x40,0x00,0x00,0xed,0x06,0x5a,0xd9,0xdf,0x68,0xd2,0xa3,0xc0,0xa8,
+0x00,0x02,0x21,0xb9,0x1d,0xe6,0x70,0x15,0x81,0x20,0x9f,0x4b,0x17,0x5b,0x50,0x10,
+0xb3,0xdb,0xa1,0xc6,0x00,0x00
+};
+
+
+//customer logs:
+static kal_uint8 kpalv_ut_ul_packet_3[] = {
+0x45,0x00,0x00,0x29,
+0x07,0xdc,0x40,0x00,
+0x80,0x06,0x00,0x00,
+0xc0,0xa8,0x00,0x02, /*src addr = 0200a8c0 = 33597632*/
+0xdf,0x68,0xd2,0xa3, /*dst addr = a3d268df = 2748475615*/
+0x1d,0xe6,0x21,0xb9,
+0x9f,0x4b,0x17,0x5a,
+0x70,0x15,0x81,0x20,
+0x50,0x10,0x02,0x02,
+0x72,0xd2,0x00,0x00,0x00};
+
+
+//customer logs:
+static kal_uint8 kpalv_ut_dl_packet_4[] = {
+0x45,0x00,0x00,0x28,
+0x00,0x42,0x00,0x00,
+0xed,0x06,0x5a,0xd7,
+0xdf,0x68,0xd2,0xa3,
+0xc0,0xa8,0x00,0x02,
+0x21,0xb9,0x1d,0xe6,
+0x70,0x15,0x81,0x20,
+0x9f,0x4b,0x17,0x5b,
+0x50,0x10,0xb4,0x00,
+0xa1,0xa1,0x00,0x00};
+
+#define KPALV_UT_CASE(_func, _param) { #_func, _func, _param }
+typedef struct {
+ kal_bool result;
+ kal_bool is_ap_disable_rsp; /**< ap requested to disable keep-alive */
+ kal_uint8 conn_id;
+ kal_uint8 status;
+ kal_uint8 ps_idx;
+} kpalv_ut_latest_at_cmd_result_struct;
+
+typedef struct {
+ kal_uint8 conn_id;
+ kal_uint8 status;
+ kal_uint8 ps_idx;
+} kpalv_ut_latest_urc_notify_struct;
+
+kpalv_ut_latest_at_cmd_result_struct at_result;
+kpalv_ut_latest_urc_notify_struct urc_result;
+
+void kpalv_ut_send_keep_alive_notify(kal_bool ok, kal_uint8 conn_handle, kpalv_md_kpalive_state_e state, kal_bool ap_dis_flow, kal_uint8 rsp_ps_idx)
+{
+ at_result.result = ok;
+ at_result.is_ap_disable_rsp = ap_dis_flow;
+ at_result.status = state;
+ at_result.conn_id = conn_handle;
+ at_result.ps_idx = rsp_ps_idx;
+}
+
+void kpalv_ut_send_keep_alive_notify_urc(kal_uint8 conn_handle, kpalv_md_kpalive_state_e state, kal_uint8 rsp_ps_idx)
+{
+ urc_result.conn_id = conn_handle;
+ urc_result.status = state;
+ urc_result.ps_idx = rsp_ps_idx;
+}
+
+
+kal_bool kpalv_ut_test_first(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ /*temp test case*/
+ return KAL_TRUE;
+}
+
+void kpalv_ut_setup_ipv4_connection_3(atp_kpalv_keepalive_req_struct *req_ptr, kal_bool parsing_result, kal_bool is_tcp) {
+
+ kal_uint8 src_ipv4_addr[4] = {192,168,0,4};
+ kal_uint8 dst_ipv4_addr[4] = {223,104,201,165};
+ req_ptr->req_type = KPALV_REQ_ENABLE;
+ if(is_tcp == KAL_TRUE) {
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV4TCP;
+ req_ptr->idle_time = 900;
+ req_ptr->probe_interval = 10;
+ req_ptr->retry_cnt = 3;
+ } else {
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV4UDP;
+ req_ptr->idle_time = 900;
+ }
+ req_ptr->netif_id = 0;
+ kal_mem_cpy(req_ptr->src_ipv4_addr, src_ipv4_addr, 4);
+
+ kal_mem_cpy(req_ptr->dst_ipv4_addr, dst_ipv4_addr, 4);
+ req_ptr->src_port = 7656;
+ req_ptr->dst_port = 8667;
+
+ req_ptr->parsing_result = parsing_result;
+}
+
+void kpalv_ut_setup_ipv4_connection_2(atp_kpalv_keepalive_req_struct *req_ptr, kal_bool parsing_result, kal_bool is_tcp) {
+
+ kal_uint8 src_ipv4_addr[4] = {192,168,0,3};
+ kal_uint8 dst_ipv4_addr[4] = {223,104,201,164};
+ req_ptr->req_type = KPALV_REQ_ENABLE;
+ if(is_tcp == KAL_TRUE) {
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV4TCP;
+ req_ptr->idle_time = 900;
+ req_ptr->probe_interval = 10;
+ req_ptr->retry_cnt = 3;
+ } else {
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV4UDP;
+ req_ptr->idle_time = 900;
+ }
+ req_ptr->netif_id = 0;
+ kal_mem_cpy(req_ptr->src_ipv4_addr, src_ipv4_addr, 4);
+
+ kal_mem_cpy(req_ptr->dst_ipv4_addr, dst_ipv4_addr, 4);
+ req_ptr->src_port = 7655;
+ req_ptr->dst_port = 8666;
+
+ req_ptr->parsing_result = parsing_result;
+}
+
+void kpalv_ut_setup_ipv4_connection(atp_kpalv_keepalive_req_struct *req_ptr, kal_bool parsing_result, kal_bool is_tcp) {
+
+ kal_uint8 src_ipv4_addr[4] = {192,168,0,2};
+ kal_uint8 dst_ipv4_addr[4] = {223,104,201,163};
+ req_ptr->req_type = KPALV_REQ_ENABLE;
+ if(is_tcp == KAL_TRUE) {
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV4TCP;
+ req_ptr->idle_time = 900;
+ req_ptr->probe_interval = 10;
+ req_ptr->retry_cnt = 3;
+ } else {
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV4UDP;
+ req_ptr->idle_time = 900;
+ }
+ req_ptr->netif_id = 0;
+ kal_mem_cpy(req_ptr->src_ipv4_addr, src_ipv4_addr, 4);
+
+ kal_mem_cpy(req_ptr->dst_ipv4_addr, dst_ipv4_addr, 4);
+ req_ptr->src_port = 7654;
+ req_ptr->dst_port = 8663;
+
+ req_ptr->parsing_result = parsing_result;
+}
+
+void kpalv_ut_setup_ipv6_connection(atp_kpalv_keepalive_req_struct *req_ptr, kal_bool parsing_result, kal_bool is_tcp) {
+
+ kal_uint8 src_ip_address[] = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
+ kal_uint8 dst_ip_address[] = "2001:0db8:85a3:0000:0000:8a2e:0370:7335";
+
+ req_ptr->req_type = KPALV_REQ_ENABLE;
+ if(is_tcp == KAL_TRUE) {
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV6TCP;
+ req_ptr->idle_time = 900;
+ req_ptr->probe_interval = 10;
+ req_ptr->retry_cnt = 3;
+ } else {
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV6UDP;
+ req_ptr->idle_time = 900;
+ }
+ req_ptr->netif_id = 0;
+
+ req_ptr->src_port = 1000;
+ req_ptr->dst_port = 2000;
+ ipv6addr_convert_string_to_bin((kal_char *)src_ip_address, req_ptr->src_ipv6_addr);
+ ipv6addr_convert_string_to_bin((kal_char *)dst_ip_address, req_ptr->dst_ipv6_addr);
+
+ req_ptr->parsing_result = parsing_result;
+}
+
+void kpalv_ut_setup_ipv6_query(atp_kpalv_keepalive_req_struct *req_ptr, kal_bool parsing_result) {
+
+ kal_uint8 src_ip_address[] = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
+ kal_uint8 dst_ip_address[] = "2001:0db8:85a3:0000:0000:8a2e:0370:7335";
+
+ req_ptr->req_type = KPALV_REQ_QUERY;
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV6TCP;
+ req_ptr->netif_id = 0;
+
+ req_ptr->src_port = 1000;
+ req_ptr->dst_port = 2000;
+ ipv6addr_convert_string_to_bin((kal_char *)src_ip_address, req_ptr->src_ipv6_addr);
+ ipv6addr_convert_string_to_bin((kal_char *)dst_ip_address, req_ptr->dst_ipv6_addr);
+
+ req_ptr->parsing_result = parsing_result;
+}
+
+void kpalv_ut_setup_ipv4_query(atp_kpalv_keepalive_req_struct *req_ptr, kal_bool parsing_result) {
+ kal_uint8 src_ipv4_addr[4] = {192,168,0,2};
+ kal_uint8 dst_ipv4_addr[4] = {223,104,201,163};
+ req_ptr->req_type = KPALV_REQ_QUERY;
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV4TCP;
+ req_ptr->netif_id = 0;
+ kal_mem_cpy(req_ptr->src_ipv4_addr, src_ipv4_addr, 4);
+
+ kal_mem_cpy(req_ptr->dst_ipv4_addr, dst_ipv4_addr, 4);
+ req_ptr->src_port = 7654;
+ req_ptr->dst_port = 8663;
+ req_ptr->parsing_result = parsing_result;
+}
+
+void kpalv_ut_setup_ipv4_query_udp(atp_kpalv_keepalive_req_struct *req_ptr, kal_bool parsing_result) {
+ kal_uint8 src_ipv4_addr[4] = {192,168,0,2};
+ kal_uint8 dst_ipv4_addr[4] = {223,104,201,163};
+ req_ptr->req_type = KPALV_REQ_QUERY;
+ req_ptr->ip_type = KPALV_REQ_IPTYPE_IPV4UDP;
+ req_ptr->netif_id = 0;
+ kal_mem_cpy(req_ptr->src_ipv4_addr, src_ipv4_addr, 4);
+
+ kal_mem_cpy(req_ptr->dst_ipv4_addr, dst_ipv4_addr, 4);
+ req_ptr->src_port = 7654;
+ req_ptr->dst_port = 8663;
+ req_ptr->parsing_result = parsing_result;
+}
+
+void kpalv_ut_disable_keep_alive(atp_kpalv_keepalive_req_struct *req_ptr, kal_uint8 conn_id, kal_bool parsing_result) {
+
+ req_ptr->req_type = KPALV_REQ_DISABLE;
+ req_ptr->conn_id = conn_id;
+ req_ptr->parsing_result = parsing_result;
+}
+
+void kpalv_ut_send_ilm_to_kpalv(kal_uint8 ps_idx, atp_kpalv_keepalive_req_struct *req_ptr)
+{
+ ilm_struct ilm;
+
+ ilm.src_mod_id = MOD_ATP + ps_idx; //0 for SIM1
+ ilm.dest_mod_id = MOD_KPALV;
+ ilm.sap_id = KPALV_SAP;
+ ilm.msg_id = MSG_ID_ATP_KPALV_KEEPALIVE_REQ;
+ ilm.local_para_ptr = (local_para_struct *)req_ptr;
+ ilm.peer_buff_ptr = NULL;
+
+ kpalv_dispatch_ilm(&ilm);
+}
+
+void kpalv_ut_connections_reset(void) {
+ atp_kpalv_keepalive_req_struct *disable_req_ptr;
+ kal_uint8 proto_idx = 0;
+ disable_req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_disable_keep_alive(disable_req_ptr, 255, KAL_TRUE);
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, disable_req_ptr);
+}
+
+void kpalv_ut_reset(void) {
+ kpalv_ut_connections_reset();
+}
+
+void kpalv_ut_enable_conection_3(void)
+{
+ atp_kpalv_keepalive_req_struct *enable_req_ptr;
+ kal_uint8 proto_idx =0;
+ /*it mus be first connection*/
+ enable_req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv4_connection_3(enable_req_ptr, KAL_TRUE, KAL_TRUE); //Parsing OK, for TCP
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, enable_req_ptr);
+}
+
+void kpalv_ut_enable_conection_2(void)
+{
+ atp_kpalv_keepalive_req_struct *enable_req_ptr;
+ kal_uint8 proto_idx =0;
+ /*it mus be first connection*/
+ enable_req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv4_connection_2(enable_req_ptr, KAL_TRUE, KAL_TRUE); //Parsing OK, for TCP
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, enable_req_ptr);
+}
+
+void kpalv_ut_enable_conection(void)
+{
+ atp_kpalv_keepalive_req_struct *enable_req_ptr;
+ kal_uint8 proto_idx =0;
+ /*it mus be first connection*/
+ enable_req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv4_connection(enable_req_ptr, KAL_TRUE, KAL_TRUE); //Parsing OK, for TCP
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, enable_req_ptr);
+}
+
+void kpalv_ut_enable_udp_conection(void)
+{
+ atp_kpalv_keepalive_req_struct *enable_req_ptr;
+ kal_uint8 proto_idx =0;
+ /*it mus be first connection*/
+ enable_req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv4_connection(enable_req_ptr, KAL_TRUE, KAL_FALSE); //Parsing OK, for TCP
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, enable_req_ptr);
+}
+
+void kpalv_ut_enable_conection_ipv6(void)
+{
+ atp_kpalv_keepalive_req_struct *enable_req_ptr;
+ kal_uint8 proto_idx =0;
+ /*it mus be first connection*/
+ enable_req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv6_connection(enable_req_ptr, KAL_TRUE, KAL_TRUE); //Parsing OK, for TCP
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, enable_req_ptr);
+}
+
+kal_bool kpalv_ut_keep_alive_enable_setup(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ /*prepare ilm to send KPALV module*/
+
+ kal_uint8 i = 0;
+ kpalv_ut_reset();
+
+ kpalv_ut_enable_conection();
+
+
+ /*chekc enable req rsp*/
+ if ((at_result.is_ap_disable_rsp == KAL_FALSE) &&
+ (at_result.result == KAL_TRUE) &&
+ (at_result.conn_id == 0) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING))
+ {
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+}
+
+
+
+kal_bool kpalv_ut_keep_alive_enable_setup_ipv6(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint8 i = 0;
+
+ kpalv_ut_reset();
+ kpalv_ut_enable_conection_ipv6();
+
+ /*chekc enable req rsp*/
+ if ((at_result.is_ap_disable_rsp == KAL_FALSE) &&
+ (at_result.result == KAL_TRUE) &&
+ (at_result.conn_id == 0) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING))
+ {
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+
+}
+
+void kpalv_ut_query_connection(kal_bool parse_result) {
+ kal_uint8 proto_idx =0;
+ atp_kpalv_keepalive_req_struct *req_ptr;
+ req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv4_query(req_ptr, parse_result);
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, req_ptr);
+}
+
+void kpalv_ut_query_connection_udp_ipv4(kal_bool parse_result) {
+ kal_uint8 proto_idx =0;
+ atp_kpalv_keepalive_req_struct *req_ptr;
+ req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv4_query_udp(req_ptr, parse_result);
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, req_ptr);
+}
+
+void kpalv_ut_query_connection_ipv6(kal_bool parse_result) {
+ kal_uint8 proto_idx =0;
+ atp_kpalv_keepalive_req_struct *req_ptr;
+ req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv6_query(req_ptr, parse_result);
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, req_ptr);
+}
+
+kal_bool kpalv_ut_keep_alive_query(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kpalv_ut_reset();
+ kpalv_ut_enable_conection();
+
+ kpalv_ut_query_connection(KAL_TRUE);
+ if ((at_result.conn_id == 0) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING)) {
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+}
+
+void kpalv_ut_disable_connection(kal_uint8 conn_id, kal_bool parse_result)
+{
+ kal_uint8 proto_idx =0;
+ kal_bool result = KAL_TRUE;
+
+ atp_kpalv_keepalive_req_struct *req_ptr;
+ req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_disable_keep_alive(req_ptr, conn_id, parse_result);
+
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, req_ptr);
+}
+
+kal_bool kpalv_ut_keep_alive_disable(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+
+ kpalv_ut_reset();
+ kpalv_ut_enable_conection();//get conn_id
+ if(at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING) {
+ kpalv_ut_disable_connection(at_result.conn_id, KAL_TRUE);
+ } else {
+ return KAL_FALSE;
+ }
+
+ //disable req sent , check disable AT rsp
+ if ((at_result.is_ap_disable_rsp == KAL_TRUE) &&
+ (at_result.result == KAL_TRUE))
+ {
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+
+}
+
+kal_bool kpalv_ut_keep_alive_disable_ipv6(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+
+ kpalv_ut_reset();
+ kpalv_ut_enable_conection_ipv6();//get conn_id
+ if(at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING) {
+ kpalv_ut_disable_connection(at_result.conn_id, KAL_TRUE);
+ } else {
+ return KAL_FALSE;
+ }
+
+ //disable req sent , check disable AT rsp
+ if ((at_result.is_ap_disable_rsp == KAL_TRUE) &&
+ (at_result.result == KAL_TRUE))
+ {
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+
+}
+
+void kpalv_ut_send_ul_packet(kal_uint8 index) {
+
+ //simulate the packet from filter cbk
+ void* p_bd = NULL;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 *ip_header = NULL;
+ kal_uint32 length = 0;
+
+ qbmt_alloc_q(QBM_TYPE_NET_UL_SHRD, 1, (void**)&head_gpd, (void**)&tail_gpd);
+
+ p_bd = QBM_DES_GET_DATAPTR(head_gpd);
+
+ ip_header = QBM_DES_GET_DATAPTR(p_bd);
+ if(index == 1) {
+ length = sizeof(kpalv_ut_ul_packet_1);
+ kal_mem_cpy(ip_header, kpalv_ut_ul_packet_1, length);
+ }
+ if(index == 2) {
+ length = sizeof(kpalv_ut_ul_packet_2);
+ kal_mem_cpy(ip_header, kpalv_ut_ul_packet_2, length);
+ }
+ /*keep-alive packet*/
+ if(index == 3) {
+ length = sizeof(kpalv_ut_ul_packet_3);
+ kal_mem_cpy(ip_header, kpalv_ut_ul_packet_3, length);
+ }
+
+ QBM_CACHE_FLUSH(ip_header, length);
+ QBM_DES_SET_DATALEN(p_bd, length);
+ qbm_cal_set_checksum(p_bd);
+ QBM_DES_SET_DATALEN(head_gpd, length);
+ qbm_cal_set_checksum(head_gpd);
+
+ kpalv_ul_filter_cbk(NULL, kpalv_get_connection_address(0), kpalv_get_connection_ul_filter_id(0), head_gpd, tail_gpd, length);
+
+}
+
+
+void kpalv_ut_send_dl_packet(kal_uint8 index) {
+
+ //simulate the packet from filter cbk
+ void* p_bd = NULL;
+ qbm_gpd *head_gpd;
+ qbm_gpd *tail_gpd;
+ kal_uint8 *ip_header = NULL;
+ kal_uint32 length = 0;
+
+ qbmt_alloc_q(QBM_TYPE_NET_DL, 1, (void**)&head_gpd, (void**)&tail_gpd);
+
+ p_bd = QBM_DES_GET_DATAPTR(head_gpd);
+
+ ip_header = QBM_DES_GET_DATAPTR(p_bd);
+ if(index == 1) {
+ length = sizeof(kpalv_ut_dl_packet_1);
+ kal_mem_cpy(ip_header, kpalv_ut_dl_packet_1, length);
+ }
+ if(index == 2) {
+ length = sizeof(kpalv_ut_dl_packet_2);
+ kal_mem_cpy(ip_header, kpalv_ut_dl_packet_2, length);
+ }
+ if(index == 3) {
+ length = sizeof(kpalv_ut_dl_packet_3);
+ kal_mem_cpy(ip_header, kpalv_ut_dl_packet_3, length);
+ }
+ /*keep-alive rsp*/
+ if(index == 4) {
+ length = sizeof(kpalv_ut_dl_packet_4);
+ kal_mem_cpy(ip_header, kpalv_ut_dl_packet_4, length);
+ }
+
+ QBM_CACHE_FLUSH(ip_header, length);
+ QBM_DES_SET_DATALEN(p_bd, length);
+ qbm_cal_set_checksum(p_bd);
+ QBM_DES_SET_DATALEN(head_gpd, length);
+ qbm_cal_set_checksum(head_gpd);
+
+ kpalv_dl_filter_cbk(NULL, kpalv_get_connection_address(0), kpalv_get_connection_dl_filter_id(0), head_gpd, tail_gpd, length);
+
+}
+
+//to chekc State & send keep-alive packet
+void kpalv_ut_idle_poll_tmout_hndlr(kal_uint8 conn_id) {
+ kpalv_idle_poll_tmout_hndlr((void*)kpalv_get_connection_address(conn_id));
+}
+
+//to chekc State & send keep-alive packet
+void kpalv_ut_retry_poll_tmout_hndlr(kal_uint8 conn_id) {
+ kpalv_interval_poll_tmout_hndlr((void*)kpalv_get_connection_address(conn_id));
+}
+
+//get keep-alive ack from server by idle timeout hdlr
+kal_bool kpalv_ut_keep_alive_full_run_idle_tmout(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+
+ kpalv_ut_reset();
+ kpalv_ut_enable_conection(); //get conn_id
+ if ((at_result.conn_id != 0) &&
+ (at_result.status != KPALV_MD_KEEPALIVE_STATE_PENDING)) {
+ return KAL_FALSE;
+ }
+
+ //after this check the conn_status == ACTIVE
+ kpalv_ut_send_ul_packet(1);
+ if ((urc_result.conn_id != 0) &&
+ (urc_result.status != KPALV_MD_KEEPALIVE_STATE_ACTIVE)) {
+ return KAL_FALSE;
+ }
+ kpalv_ut_send_dl_packet(1);
+
+ kpalv_ut_send_dl_packet(2);
+ kpalv_ut_send_ul_packet(2);
+
+ kpalv_ut_send_dl_packet(3);
+
+ //simulat keepa-live sending
+ //simulate keep-alive ack from server
+ kpalv_ut_idle_poll_tmout_hndlr(0);
+ //kpalv_ut_send_ul_packet(3);
+
+ kpalv_ut_send_dl_packet(4);
+
+ //after this we can make a query to check the connection status
+ kpalv_ut_query_connection(KAL_TRUE);
+ if ((at_result.conn_id != 0) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_ACTIVE)) {
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+//get keep-alive ack from server by Retry timeout hdlr
+kal_bool kpalv_ut_keep_alive_full_run_retry_tmout(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint8 conn_id = 255;
+
+ kpalv_ut_reset();
+ kpalv_ut_enable_conection(); //get conn_id
+ if ((at_result.conn_id != 0) &&
+ (at_result.status != KPALV_MD_KEEPALIVE_STATE_PENDING)) {
+ return KAL_FALSE;
+ } else {
+ conn_id = at_result.conn_id;
+ }
+
+ kpalv_ut_send_ul_packet(1);
+ if ((urc_result.conn_id != conn_id) &&
+ (urc_result.status != KPALV_MD_KEEPALIVE_STATE_ACTIVE)) {
+ return KAL_FALSE;
+ }
+
+ kpalv_ut_send_dl_packet(1);
+
+ kpalv_ut_send_dl_packet(2);
+ kpalv_ut_send_ul_packet(2);
+
+ kpalv_ut_send_dl_packet(3);
+
+ //simulat keepa-live sending
+ //simulate keep-alive ack from server
+ kpalv_ut_idle_poll_tmout_hndlr(conn_id);
+
+ kpalv_ut_retry_poll_tmout_hndlr(conn_id);
+ kpalv_ut_retry_poll_tmout_hndlr(conn_id);
+ kpalv_ut_retry_poll_tmout_hndlr(conn_id);
+ //send DL packet before last retry timer expire
+ kpalv_ut_send_dl_packet(4);
+
+ //after this we can make a query to check the connection status
+ kpalv_ut_query_connection(KAL_TRUE);
+ if ((at_result.conn_id != 0) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_ACTIVE)) {
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
+
+
+
+kal_bool kpalv_ut_keep_alive_full_run_conn_inactive(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kal_uint8 conn_id = 255;
+
+ kpalv_ut_reset();
+ kpalv_ut_enable_conection();
+ if((at_result.result == KAL_TRUE) && (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING)) {
+ conn_id = at_result.conn_id;
+ } else {
+ return KAL_FALSE;
+ }
+
+ kpalv_ut_send_ul_packet(1);
+
+ if ((urc_result.conn_id != 0) &&
+ (urc_result.status != KPALV_MD_KEEPALIVE_STATE_ACTIVE)) {
+ return KAL_FALSE;
+ }
+
+ kpalv_ut_send_dl_packet(1);
+
+ kpalv_ut_send_dl_packet(2);
+ kpalv_ut_send_ul_packet(2);
+
+ kpalv_ut_send_dl_packet(3);
+
+ //simulate keepa-live sending by idle timeout
+ //simulate keep-alive ack from server
+ kpalv_ut_idle_poll_tmout_hndlr(conn_id);
+
+ kpalv_ut_retry_poll_tmout_hndlr(conn_id); //Idle timer expire, try 1
+ kpalv_ut_retry_poll_tmout_hndlr(conn_id); //try 1 timer expire , try 2
+ kpalv_ut_retry_poll_tmout_hndlr(conn_id); //try 2 timer expire , try 3
+ kpalv_ut_retry_poll_tmout_hndlr(conn_id); //try 3 timer expire, no respone from server
+
+ //all retries exhausted, so state must be inactive, get from last urc response
+ if ((urc_result.conn_id != conn_id) &&
+ (urc_result.status != KPALV_MD_KEEPALIVE_STATE_INACTIVE)) {
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+kal_bool kpalv_enable_req_with_parsing_result_and_ip_type(kal_bool parse_result, kal_bool is_tcp) {
+ //test wrong cases here
+ atp_kpalv_keepalive_req_struct *req_ptr = NULL;
+ kal_uint8 proto_idx = 0;
+ /*it mus be first connection*/
+ req_ptr = (atp_kpalv_keepalive_req_struct *)construct_local_para(sizeof(atp_kpalv_keepalive_req_struct), TD_RESET);
+ kpalv_ut_setup_ipv4_connection(req_ptr, parse_result, is_tcp);
+ kpalv_ut_send_ilm_to_kpalv(proto_idx, req_ptr);
+ return KAL_TRUE;
+
+}
+
+
+kal_bool kaplav_enable_req_max_conn_reached_error(void) {
+
+ kal_uint8 max_conn = KPALV_MAX_KEEP_ALIVE_CONN;
+ kal_uint8 success_conn = 0;
+
+ kpalv_ut_reset(); //delete all connection before
+
+ //setup connection parsing success +TCP ipv4: different conn
+ kpalv_ut_enable_conection();
+ //check latest at result
+ if ((at_result.conn_id == success_conn) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING)) {
+ success_conn++;
+ } else {
+ return KAL_FALSE;
+ }
+
+
+ //set up connection 2 ipv4 tcp + parsing success : different conn
+ kpalv_ut_enable_conection_2();
+ if ((at_result.conn_id == success_conn) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING)) {
+ success_conn++;
+ } else {
+ return KAL_FALSE;
+ }
+
+ //try to setup connection 3 ipv4 tcp + parsing success : different conn, must be ERROR
+
+ kpalv_ut_enable_conection_3();
+ if (max_conn == success_conn) {
+ if (at_result.result == KAL_TRUE) {
+ return KAL_FALSE;
+ }
+ }
+
+ kpalv_ut_reset(); //delete all connection after
+ return KAL_TRUE;
+
+}
+
+//check NON TCP
+//check parsing fail
+//max conn reach error
+kal_bool kpalv_ut_keep_alive_enable_fail_setup(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+
+ kal_uint8 success_conn_id = 255;
+
+ kpalv_ut_reset();
+
+ kpalv_enable_req_with_parsing_result_and_ip_type(KAL_FALSE, KAL_TRUE); //parse fail + TCP
+ if (at_result.result != KAL_FALSE) {
+ return KAL_FALSE;
+ }
+ kpalv_enable_req_with_parsing_result_and_ip_type(KAL_FALSE, KAL_FALSE); //parse fail + UDP
+ if (at_result.result != KAL_FALSE) {
+ return KAL_FALSE;
+ }
+
+ /*this mus be sucess as parsing SUCCESS + TCP */
+ kpalv_enable_req_with_parsing_result_and_ip_type(KAL_TRUE, KAL_TRUE); //parse success + TCP
+ if (!((at_result.result == KAL_TRUE) ||
+ (at_result.conn_id == 0) ||
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING))) {
+ return KAL_FALSE;
+ }
+ success_conn_id = at_result.conn_id;
+ /*Duplicate req, result must be ERROR*/
+ kpalv_enable_req_with_parsing_result_and_ip_type(KAL_TRUE, KAL_TRUE); //parse success + TCP
+ if (at_result.result != KAL_FALSE) {
+ return KAL_FALSE;
+ }
+ //double confirm by query or disable cmd
+ {
+ kpalv_ut_query_connection(KAL_TRUE);
+ if ((at_result.conn_id == 0) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING)) {
+
+ } else {
+ return KAL_FALSE;
+ }
+
+ kpalv_ut_disable_connection(at_result.conn_id, KAL_TRUE);
+ if ((at_result.is_ap_disable_rsp == KAL_TRUE) &&
+ (at_result.result == KAL_TRUE))
+ {
+
+ } else {
+ return KAL_FALSE;
+ }
+ }
+
+ /*MAX CONN REACH ERROR */
+ if (KAL_TRUE != kaplav_enable_req_max_conn_reached_error()) {
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+
+
+kal_bool kpalv_ut_keep_alive_query_fail_rsp(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+
+ kpalv_ut_reset();
+
+ //case 1 parsing result is failed, result must be ERROR
+ kpalv_ut_query_connection(KAL_FALSE);
+ if ((at_result.result == KAL_TRUE)) {
+ return KAL_FALSE;
+ }
+
+ //case 2 parsing success but no such connection, result must be ERROR
+ kpalv_ut_query_connection(KAL_TRUE);
+ if ((at_result.result == KAL_TRUE)) {
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+
+
+kal_bool kpalv_ut_keep_alive_disable_fail_rsp(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+
+ kal_uint8 conn_id = 255;
+ //reset all connections
+ kpalv_ut_reset();
+
+ //parsing result failed, result must be ERROR
+ kpalv_ut_disable_connection(0, KAL_FALSE);
+ if(at_result.result == KAL_TRUE) {
+ return KAL_FALSE;
+ }
+
+ //no such conection exist(not enabled), result must be ERROR
+ kpalv_ut_disable_connection(0, KAL_TRUE);
+ if(at_result.result == KAL_TRUE) {
+ return KAL_FALSE;
+ }
+
+ //connection_id >max conn, result must be ERROR
+ kpalv_ut_disable_connection(KPALV_MAX_KEEP_ALIVE_CONN, KAL_TRUE);
+ if(at_result.result == KAL_TRUE) {
+ return KAL_FALSE;
+ }
+
+ //now enable a connection & run the test case again for parsing fail or max conn cases.
+ kpalv_ut_enable_conection(); //setup valid connection.
+ if((at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING) &&
+ (at_result.result == KAL_TRUE)) {
+ conn_id = at_result.conn_id;
+ } else {
+ return KAL_FALSE;
+ }
+ kpalv_ut_disable_connection(conn_id, KAL_FALSE); //parsing result failed
+ if(at_result.result == KAL_TRUE) {
+ return KAL_FALSE;
+ }
+
+ //try to disable some unknown conn_id
+ kpalv_ut_disable_connection((conn_id+1), KAL_TRUE); //invalid conn_id
+ if(at_result.result == KAL_TRUE) {
+ return KAL_FALSE;
+ }
+
+ kpalv_ut_disable_connection(KPALV_MAX_KEEP_ALIVE_CONN, KAL_TRUE); //max conn_id
+ if(at_result.result == KAL_TRUE) {
+ return KAL_FALSE;
+ }
+
+ //finally disbale in correct way, result must be success
+ kpalv_ut_disable_connection(conn_id, KAL_TRUE); //max conn_id
+ if(at_result.result == KAL_FALSE) {
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool kpalv_ut_keep_alive_query_ipv6(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kpalv_ut_reset();
+ kpalv_ut_enable_conection_ipv6();
+
+ kpalv_ut_query_connection_ipv6(KAL_TRUE);
+ if ((at_result.conn_id == 0) &&
+ (at_result.status == KPALV_MD_KEEPALIVE_STATE_PENDING)) {
+ return KAL_TRUE;
+ } else {
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool kpalv_ut_keep_alive_udp_setup_query_disable(void *p_param, kal_char *p_ret_err_str, kal_uint32 *p_ret_err_str_sz) {
+ kpalv_ut_reset();
+ kpalv_ut_enable_udp_conection();
+ if ((at_result.conn_id != 0) ||
+ (at_result.status != KPALV_MD_KEEPALIVE_STATE_ACTIVE)) {
+ return KAL_FALSE;
+ }
+
+ kpalv_ut_query_connection_udp_ipv4(KAL_TRUE);
+ if ((at_result.conn_id != 0) ||
+ (at_result.status != KPALV_MD_KEEPALIVE_STATE_ACTIVE)) {
+ return KAL_FALSE;
+ }
+
+ kpalv_ut_disable_connection(at_result.conn_id, KAL_TRUE);
+ if ((at_result.is_ap_disable_rsp != KAL_TRUE) ||
+ (at_result.result != KAL_TRUE))
+ {
+ return KAL_FALSE;
+ }
+
+ return KAL_TRUE;
+}
+
+kal_bool kpalv_ut_st_create(void) {
+ static ST_TCASE_T kpalv_ut_cases_s[] = {
+ KPALV_UT_CASE(kpalv_ut_test_first, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_enable_fail_setup, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_enable_setup, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_query_fail_rsp, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_query, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_disable_fail_rsp, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_disable, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_full_run_idle_tmout, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_full_run_retry_tmout, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_full_run_conn_inactive, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_enable_setup_ipv6, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_query_ipv6, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_disable_ipv6, NULL),
+ KPALV_UT_CASE(kpalv_ut_keep_alive_udp_setup_query_disable, NULL),
+ };
+ return st_reg_test("KPALV", &(kpalv_ut_cases_s[0]), (sizeof(kpalv_ut_cases_s)/sizeof(ST_TCASE_T)));
+}
+
+#endif /*ATEST_SYS_KPALV*/
\ No newline at end of file
diff --git a/mcu/middleware/media/audio/src/aud_ilm.c b/mcu/middleware/media/audio/src/aud_ilm.c
new file mode 100644
index 0000000..581ee32
--- /dev/null
+++ b/mcu/middleware/media/audio/src/aud_ilm.c
@@ -0,0 +1,662 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * aud_ilm.c
+ *
+ * Project:
+ * --------
+ * Maui
+ *
+ * Description:
+ * ------------
+ * This file includes send-ilm related funcions of audio manager task.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef MED_NOT_PRESENT
+
+/*==== INCLUDES ===========*/
+
+/* system includes */
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+#include "mw_sap.h"
+#include "svc_sap.h"
+#include "drv_sap.h"
+#include "med_msgid.h"
+#include "nvram_msgid.h"
+
+/* global includes */
+#include "l1audio.h"
+#include "nvram_struct.h"
+#include "audio_nvram_def.h"
+
+/* local includes */
+#include "med_global.h"
+#include "aud_defs.h"
+#include "med_struct.h"
+#include "med_context.h"
+#include "aud_main.h"
+
+
+#include "string.h"
+
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_ilm
+ * DESCRIPTION
+ * This function is used to send ilm.
+ * PARAMETERS
+ * dest_id [IN]
+ * msg_id [IN]
+ * local_param_ptr [?]
+ * peer_buf_ptr [?]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_ilm(module_type dest_id, kal_uint16 msg_id, void *local_param_ptr, void *peer_buf_ptr)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ module_type src_id;
+ sap_type sap_id;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+
+ /* Check destination module ID */
+ if (dest_id == MOD_NIL)
+ {
+ return;
+ }
+
+ /* Get source module ID */
+ if (kal_if_hisr())
+ {
+// src_id = MOD_VISUAL_HISR;
+ return;
+ }
+ else
+ {
+ src_id = kal_get_active_module_id();
+ }
+
+ switch (dest_id)
+ {
+ case MOD_MED:
+ sap_id = MED_SAP;
+ break;
+ case MOD_UEM:
+ sap_id = MED_SAP;
+ break;
+ case MOD_NVRAM:
+ sap_id = PS_NVRAM_SAP;
+ break;
+ default:
+ sap_id = MED_SAP;
+ break;
+ }
+
+ msg_send6(src_id,dest_id,sap_id,msg_id,(local_para_struct*)local_param_ptr,(peer_buff_struct*)peer_buf_ptr);
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_msg_to_nvram
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * msg_name [IN]
+ * ef_id [IN]
+ * data_ptr [?]
+ * length [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_msg_to_nvram(msg_type msg_name, kal_uint16 ef_id, void *data_ptr, kal_uint16 length)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ peer_buff_struct *data_stream;
+ local_para_struct *parm_stream;
+ kal_uint16 pdu_len;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ switch (msg_name)
+ {
+ case MSG_ID_NVRAM_WRITE_REQ:
+ switch (ef_id)
+ {
+ case NVRAM_EF_CUST_ACOUSTIC_DATA_LID:
+ case NVRAM_EF_AUDIO_PARAM_LID:
+ case NVRAM_EF_AUDIO_DC_CALIBRATION_LID:
+ #ifdef __AMRWB_LINK_SUPPORT__
+ case NVRAM_EF_AUDIO_WB_SPEECH_INPUT_FIR_LID:
+ case NVRAM_EF_AUDIO_WB_SPEECH_OUTPUT_FIR_LID:
+ case NVRAM_EF_AUDIO_WB_SPEECH_MODE_PARAM_LID:
+ #endif /* __AMRWB_LINK_SUPPORT__ */
+ parm_stream = construct_local_para(sizeof(nvram_write_req_struct), TD_CTRL);
+ data_stream = construct_peer_buff(length, 0, 0, TD_CTRL);
+
+ ((nvram_write_req_struct*) parm_stream)->file_idx = (kal_uint16) ef_id;
+ ((nvram_write_req_struct*) parm_stream)->para = 1;
+ ((nvram_write_req_struct*) parm_stream)->access_id = 0;
+
+ pdu_len = length;
+ kal_mem_cpy(get_peer_buff_pdu(data_stream, &pdu_len), data_ptr, length);
+
+ aud_send_ilm(MOD_NVRAM, MSG_ID_NVRAM_WRITE_REQ, parm_stream, data_stream);
+ break;
+ default:
+ /* error write */
+ break;
+ }
+ break;
+ case MSG_ID_NVRAM_READ_REQ:
+ switch (ef_id)
+ {
+ case NVRAM_EF_CUST_ACOUSTIC_DATA_LID:
+ case NVRAM_EF_AUDIO_PARAM_LID:
+ case NVRAM_EF_AUDIO_DC_CALIBRATION_LID:
+ #ifdef __GAIN_TABLE_SUPPORT__
+ case NVRAM_EF_AUDIO_GAIN_TABLE_LID:
+ #endif /* __GAIN_TABLE_SUPPORT__ */
+ #ifdef __SPEECH_MODE_TABLE_SUPPORT__
+ case NVRAM_EF_AUDIO_SPEECH_MODE_TABLE_LID:
+ #endif /* __SPEECH_MODE_TABLE_SUPPORT__ */
+ #ifdef __AMRWB_LINK_SUPPORT__
+ case NVRAM_EF_AUDIO_WB_SPEECH_INPUT_FIR_LID:
+ case NVRAM_EF_AUDIO_WB_SPEECH_OUTPUT_FIR_LID:
+ case NVRAM_EF_AUDIO_WB_SPEECH_MODE_PARAM_LID:
+ #endif /* __AMRWB_LINK_SUPPORT__ */
+ #ifdef __DUAL_MIC_SUPPORT__
+ case NVRAM_EF_AUDIO_DUAL_MIC_PARAM_LID:
+ #endif
+ parm_stream = construct_local_para(sizeof(nvram_read_req_struct), TD_CTRL);
+
+ ((nvram_read_req_struct*) parm_stream)->file_idx = (kal_uint16) ef_id;
+ ((nvram_read_req_struct*) parm_stream)->para = 1;
+
+ aud_send_ilm(MOD_NVRAM, MSG_ID_NVRAM_READ_REQ, parm_stream, NULL);
+ break;
+ default:
+ /* error read */
+ break;
+ }
+ break;
+ default:
+ break;
+ } /* End Switch */
+
+ return;
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_startup_cnf
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * result [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_startup_cnf(kal_uint8 result)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ med_startup_cnf_struct *cnf_p = NULL;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ cnf_p = (med_startup_cnf_struct*) construct_local_para(sizeof(med_startup_cnf_struct), TD_CTRL);
+
+ /* send confirm message to L4 */
+ cnf_p->result = result;
+
+ aud_send_ilm(aud_context_p->src_mod, MSG_ID_MED_STARTUP_CNF, cnf_p, NULL);
+
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_set_audio_profile_cnf
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * result [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_set_audio_profile_cnf(kal_uint8 result)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ media_aud_set_audio_profile_cnf_struct *cnf_p = NULL;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ cnf_p = (media_aud_set_audio_profile_cnf_struct*)
+ construct_local_para(sizeof(media_aud_set_audio_profile_cnf_struct), TD_CTRL);
+
+ /* send confirm message to L4 */
+ cnf_p->src_id = aud_context_p->src_id;
+ if(result == 0) /* MED_RES_OK */
+ {
+ cnf_p->result = KAL_TRUE;
+ }
+ else
+ {
+ cnf_p->result = KAL_FALSE;
+ }
+ cnf_p->cause = result;
+
+ aud_send_ilm(aud_context_p->src_mod, MSG_ID_MEDIA_AUD_SET_AUDIO_PROFILE_CNF, cnf_p, NULL);
+
+}
+
+void aud_send_in_proc_call_req(
+ module_type src_mod_id,
+ media_in_proc_call_type func,
+ kal_uint32 func_arg1,
+ void *func_arg2)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ media_in_proc_call_req_struct *msg_p = (media_in_proc_call_req_struct*)
+ construct_local_para(sizeof(media_in_proc_call_req_struct), TD_CTRL);
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ msg_p->func = func;
+ msg_p->func_arg1 = func_arg1;
+ msg_p->func_arg2 = func_arg2;
+
+ //aud_send_msg_to_med((module_type)src_mod_id, (kal_uint16) MSG_ID_MEDIA_IN_PROC_CALL_REQ, (void *)msg_p);
+ aud_send_ilm(MOD_MED, (kal_uint16) MSG_ID_MEDIA_IN_PROC_CALL_REQ, (void *)msg_p, NULL);
+}
+
+#ifdef __AMRWB_LINK_SUPPORT__
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_set_audio_wb_input_fir_cnf
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * result [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_set_audio_wb_input_fir_cnf(kal_uint8 result)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ media_aud_set_audio_wb_input_fir_param_cnf_struct *cnf_p = NULL;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ cnf_p = (media_aud_set_audio_wb_input_fir_param_cnf_struct*)
+ construct_local_para(sizeof(media_aud_set_audio_wb_input_fir_param_cnf_struct), TD_CTRL);
+
+ /* send confirm message to L4 */
+ cnf_p->src_id = aud_context_p->src_id;
+
+ if(result == 0) /* MED_RES_OK */
+ {
+ cnf_p->result = KAL_TRUE;
+ }
+ else
+ {
+ cnf_p->result = KAL_FALSE;
+ }
+ cnf_p->cause = result;
+
+ aud_send_ilm(aud_context_p->src_mod, MSG_ID_MEDIA_AUD_SET_AUDIO_WB_INPUT_FIR_PARAM_CNF, cnf_p, NULL);
+
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_set_audio_wb_output_fir_cnf
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * input [IN]
+ * result [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_set_audio_wb_output_fir_cnf(kal_uint8 result)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ media_aud_set_audio_wb_output_fir_param_cnf_struct *cnf_p = NULL;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ cnf_p = (media_aud_set_audio_wb_output_fir_param_cnf_struct*)
+ construct_local_para(sizeof(media_aud_set_audio_wb_output_fir_param_cnf_struct), TD_CTRL);
+
+ /* send confirm message to L4 */
+ cnf_p->src_id = aud_context_p->src_id;
+
+ if(result == 0) /* MED_RES_OK */
+ {
+ cnf_p->result = KAL_TRUE;
+ }
+ else
+ {
+ cnf_p->result = KAL_FALSE;
+ }
+ cnf_p->cause = result;
+
+ aud_send_ilm(aud_context_p->src_mod, MSG_ID_MEDIA_AUD_SET_AUDIO_WB_OUTPUT_FIR_PARAM_CNF, cnf_p, NULL);
+
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_set_audio_wb_mode_cnf
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * result [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_set_audio_wb_mode_cnf(kal_uint8 result)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ media_aud_set_audio_wb_mode_param_cnf_struct *cnf_p = NULL;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ cnf_p = (media_aud_set_audio_wb_mode_param_cnf_struct*)
+ construct_local_para(sizeof(media_aud_set_audio_wb_mode_param_cnf_struct), TD_CTRL);
+
+ /* send confirm message to L4 */
+ cnf_p->src_id = aud_context_p->src_id;
+
+ if(result == 0) /* MED_RES_OK */
+ {
+ cnf_p->result = KAL_TRUE;
+ }
+ else
+ {
+ cnf_p->result = KAL_FALSE;
+ }
+ cnf_p->cause = result;
+
+ aud_send_ilm(aud_context_p->src_mod, MSG_ID_MEDIA_AUD_SET_AUDIO_WB_MODE_PARAM_CNF, cnf_p, NULL);
+
+}
+
+#endif /*__AMRWB_LINK_SUPPORT__*/
+
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_set_audio_param_cnf
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * result [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_set_audio_param_cnf(kal_uint8 result)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ media_aud_set_audio_param_cnf_struct *cnf_p = NULL;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ cnf_p = (media_aud_set_audio_param_cnf_struct*)
+ construct_local_para(sizeof(media_aud_set_audio_param_cnf_struct), TD_CTRL);
+
+ /* send confirm message to L4 */
+ cnf_p->src_id = aud_context_p->src_id;
+ if(result == 0) /* MED_RES_OK */
+ {
+ cnf_p->result = KAL_TRUE;
+ }
+ else
+ {
+ cnf_p->result = KAL_FALSE;
+ }
+ cnf_p->cause = result;
+
+ aud_send_ilm(aud_context_p->src_mod, MSG_ID_MEDIA_AUD_SET_AUDIO_PARAM_CNF, cnf_p, NULL);
+
+}
+
+#else /* MED_NOT_PRESENT */
+
+/*==== INCLUDES ===========*/
+
+/* system includes */
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+#include "mw_sap.h"
+#include "svc_sap.h"
+#include "drv_sap.h"
+#include "med_msgid.h"
+#include "nvram_msgid.h"
+
+/* global includes */
+#include "l1audio.h"
+#include "nvram_struct.h"
+#include "audio_nvram_def.h"
+
+/* local includes */
+#include "med_global.h"
+#include "aud_defs.h"
+#include "med_struct.h"
+#include "med_context.h"
+#include "aud_main.h"
+
+
+#include "string.h"
+
+/*****************************************************************************
+ * FUNCTION
+ * aud_send_ilm
+ * DESCRIPTION
+ * This function is used to send ilm.
+ * PARAMETERS
+ * dest_id [IN]
+ * msg_id [IN]
+ * local_param_ptr [?]
+ * peer_buf_ptr [?]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void aud_send_ilm(module_type dest_id, kal_uint16 msg_id, void *local_param_ptr, void *peer_buf_ptr)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ module_type src_id;
+ sap_type sap_id;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+
+ /* Check destination module ID */
+ if (dest_id == MOD_NIL)
+ {
+ return;
+ }
+
+ /* Get source module ID */
+ if (kal_if_hisr())
+ {
+ src_id = MOD_VISUAL_HISR;//MOD_VISUAL_HISR;//MOD_TIMER_HISR �٬O MOD_GPT_TIMER
+
+ // return;
+ }
+ else
+ {
+ src_id = kal_get_active_module_id();
+ }
+
+ switch (dest_id)
+ {
+ case MOD_MED:
+ sap_id = MED_SAP;
+ break;
+ case MOD_UEM:
+ sap_id = MED_SAP;
+ break;
+ case MOD_NVRAM:
+ sap_id = PS_NVRAM_SAP;
+ break;
+ default:
+ sap_id = MED_SAP;
+ break;
+ }
+
+ msg_send6(src_id,dest_id,sap_id,msg_id,(local_para_struct*)local_param_ptr,(peer_buff_struct*)peer_buf_ptr);
+}
+
+void aud_send_in_proc_call_req(
+ module_type src_mod_id,
+ media_in_proc_call_type func,
+ kal_uint32 func_arg1,
+ void *func_arg2)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ media_in_proc_call_req_struct *msg_p = (media_in_proc_call_req_struct*)
+ construct_local_para(sizeof(media_in_proc_call_req_struct), TD_CTRL);
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ msg_p->func = func;
+ msg_p->func_arg1 = func_arg1;
+ msg_p->func_arg2 = func_arg2;
+
+ //aud_send_msg_to_med((module_type)src_mod_id, (kal_uint16) MSG_ID_MEDIA_IN_PROC_CALL_REQ, (void *)msg_p);
+ aud_send_ilm(MOD_MED, (kal_uint16) MSG_ID_MEDIA_IN_PROC_CALL_REQ, (void *)msg_p, NULL);
+
+}
+
+
+#endif /* MED_NOT_PRESENT */
+
+
+
diff --git a/mcu/middleware/media/common/src/med_ext_smalloc.c b/mcu/middleware/media/common/src/med_ext_smalloc.c
new file mode 100644
index 0000000..d75afff
--- /dev/null
+++ b/mcu/middleware/media/common/src/med_ext_smalloc.c
@@ -0,0 +1,247 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * med_ext_smalloc.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ *
+ *
+ * Author:
+ * -------
+ *
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#include "kal_public_defs.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_trace.h"
+
+#include "med_trc.h"
+#include "med_global.h"
+#include "med_mem.h"
+#include "med_smalloc.h"
+#include "init.h"
+
+
+typedef struct{
+ KAL_ADM_ID aud_mem_pool_id;
+ kal_uint32 aud_mem_alloc_count;
+ kal_uint32 aud_mem_left_size;
+}med_ext_mem_struct;
+
+med_ext_mem_struct g_med_ext_mem_cntx;
+
+#if defined(__MED_MEM_CACHEABLE_SUPPORT__)
+#define MED_MEM_CACHEABLE_ALIGN_SIZE 32
+#else
+#define MED_MEM_CACHEABLE_ALIGN_SIZE 4
+#endif
+
+#if defined(__MED_MEM_DEBUG_ON__)
+ #define MED_MEM_ALLOC(adm_id,size,f,l) kal_adm_alloc_dbg(adm_id,size,f,l)
+ #define MED_MEM_ALLOC_TOPMOST_CACHEABLE(adm_id, size, a, f, l) kal_adm_alloc_c_topmost_dbg(adm_id, size, a, f, l)
+ #define MED_MEM_ALLOC_TOPMOST(adm_id, size, a, f, l) kal_adm_alloc_topmost_dbg(adm_id, size, a, f, l)
+ #define MED_MEM_ALLOC_CACHEABLE(adm_id, size, option, f, l) kal_adm_alloc_cacheable_dbg(adm_id, size, option, f, l)
+ #define MED_MEM_ALLOC_FRAMEBUFFER(adm_id, size, a, f, l) kal_adm_alloc_align_dbg(adm_id, size, a, f, l)
+#else
+ #define MED_MEM_ALLOC(adm_id,size,f,l) kal_adm_alloc(adm_id,size)
+ #define MED_MEM_ALLOC_TOPMOST(adm_id, size, a, f, l) kal_adm_alloc_topmost(adm_id, size, a)
+ #define MED_MEM_ALLOC_TOPMOST_CACHEABLE(adm_id, size, a, f, l) kal_adm_alloc_c_topmost(adm_id, size, a)
+ #define MED_MEM_ALLOC_CACHEABLE(adm_id, size, option, f, l) kal_adm_alloc_cacheable(adm_id, size, option)
+ #define MED_MEM_ALLOC_FRAMEBUFFER(adm_id, size, a, f, l) kal_adm_alloc_align(adm_id, size, a)
+#endif
+
+/*****************************************************************************
+ * FUNCTION
+ * med_ext_smalloc_ext
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * size [IN]
+ * RETURNS
+ *
+ *****************************************************************************/
+address_t med_ext_smalloc_ext(size_type size, unsigned short location, const char *file, int line)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ void *ptr;
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ if (size == 0)
+ {
+ return NULL;
+ }
+
+ switch(location)
+ {
+ case MED_EXT_MEMORY_TYPE_AUDIO_NONCACHEABLE:
+ case MED_EXT_MEMORY_TYPE_AUDIO_CACHEABLE:
+ if (g_med_ext_mem_cntx.aud_mem_pool_id == 0)
+ return NULL;
+ break;
+ default:
+ return NULL;
+ }
+
+ if (location == MED_EXT_MEMORY_TYPE_AUDIO_NONCACHEABLE)
+ {
+ ptr = MED_MEM_ALLOC(g_med_ext_mem_cntx.aud_mem_pool_id, size,basename((char *)file), line);
+ }
+ else if (location == MED_EXT_MEMORY_TYPE_AUDIO_CACHEABLE)
+ {
+ ptr = MED_MEM_ALLOC_CACHEABLE(g_med_ext_mem_cntx.aud_mem_pool_id, size, MED_MEM_CACHEABLE_ALIGN_SIZE, basename((char *)file), line);
+ }
+
+ if (ptr!=NULL)
+ {
+ g_med_ext_mem_cntx.aud_mem_alloc_count++;
+ g_med_ext_mem_cntx.aud_mem_left_size = kal_adm_get_total_left_size(g_med_ext_mem_cntx.aud_mem_pool_id);
+ MED_MEM_INFO_AUD(MED_AUD_MEM_SIZE, size, g_med_ext_mem_cntx.aud_mem_left_size, ptr, g_med_ext_mem_cntx.aud_mem_alloc_count);
+ }
+ else
+ {
+
+ if (size < kal_adm_get_total_left_size(g_med_ext_mem_cntx.aud_mem_pool_id))
+ {
+ /* fragmentation */
+ MED_MEM_FRAGMENTATION_AUD(MED_AUD_MEM_SIZE, size, g_med_ext_mem_cntx.aud_mem_left_size,g_med_ext_mem_cntx.aud_mem_alloc_count);
+ }
+ else
+ {
+ /* concurrent */
+ MED_MEM_CONCURRENT_AUD(MED_AUD_MEM_SIZE, size, g_med_ext_mem_cntx.aud_mem_left_size,g_med_ext_mem_cntx.aud_mem_alloc_count);
+ }
+ }
+ return (address_t) ptr;
+} /* malloc */
+
+/*****************************************************************************
+ * FUNCTION
+ * med_aud_sfree
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * ptr [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void med_aud_sfree(address_t ptr)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ if (ptr!=NULL)
+ {
+ kal_adm_free(g_med_ext_mem_cntx.aud_mem_pool_id, ptr);
+ g_med_ext_mem_cntx.aud_mem_alloc_count--;
+ g_med_ext_mem_cntx.aud_mem_left_size = kal_adm_get_total_left_size(g_med_ext_mem_cntx.aud_mem_pool_id);
+ MED_FREE_MEM_INFO_AUD(g_med_ext_mem_cntx.aud_mem_left_size, ptr, g_med_ext_mem_cntx.aud_mem_alloc_count );
+ }
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * med_set_aud_memory_pool
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * memory [IN]
+ * size [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void med_set_aud_memory_pool(address_t memory, size_type size)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ g_med_ext_mem_cntx.aud_mem_pool_id = kal_adm_create(
+ memory,
+ size,
+ NULL,
+ #if defined(__MED_MEM_DEBUG_ON__)
+ KAL_TRUE
+ #else
+ KAL_FALSE
+ #endif
+ );
+ g_med_ext_mem_cntx.aud_mem_alloc_count = 0;
+ g_med_ext_mem_cntx.aud_mem_left_size = size;
+}
+
diff --git a/mcu/middleware/media/common/src/med_main.c b/mcu/middleware/media/common/src/med_main.c
new file mode 100644
index 0000000..87b4610
--- /dev/null
+++ b/mcu/middleware/media/common/src/med_main.c
@@ -0,0 +1,892 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * med_main.c
+ *
+ * Project:
+ * --------
+ * Maui
+ *
+ * Description:
+ * ------------
+ * This file includes primary functions of media task.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+/*==== INCLUDES =========*/
+
+/* system includes */
+
+#include "kal_public_defs.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_trace.h"
+#include "syscomp_config.h"
+#include "task_config.h"
+#include "nvram_msgid.h"
+#include "sysservice_msgid.h"
+#include "tst_msgid.h"
+#include "med_msgid.h"
+#include "drv_msgid.h"
+#include "cmux_msgid.h"
+#include "audio_msgid.h"
+#include "em_msgid.h"
+
+#include "tst_sap.h"
+#include "drv_sap.h"
+
+
+/* global includes */
+#include "l1audio.h"
+#include "nvram_struct.h"
+#include "audio_nvram_def.h"
+#include "nvram_editor_data_item.h"
+// #include "aud_common_config.h"
+
+/* local include */
+#include "med_global.h"
+#include "med_mem.h"
+#include "med_struct.h"
+#include "med_context.h"
+#include "med_utility.h"
+
+#include "aud_main.h"
+#include "med_main.h"
+
+#ifdef __SPEECH_MODE_TABLE_SUPPORT__
+#include "speech_mode_table.h"
+#endif
+
+//Only for AUDIO_DEVICE_MICROPHONE
+#include "device.h"
+
+#include "em_struct.h"
+
+#if defined(__VOLTE_SUPPORT__)
+#include "ltecsr_msgid.h"
+#endif //#if defined(__VOLTE_SUPPORT__)
+
+
+/* global variables */
+med_context_struct med_context;
+med_context_struct *med_context_p = &med_context;
+
+#ifdef __MTK_TARGET__
+ #if defined(__DYNAMIC_SWITCH_CACHEABILITY__)
+ __attribute__ ((section ("DYNAMICCACHEABLEZI_NC_MMIPOOL")))
+ __attribute__((aligned(4)))
+ kal_uint8 med_aud_mem[MED_AUD_MEM_SIZE];
+ #else
+ __attribute__ ((section ("LARGEPOOL_ZI")))
+ __attribute__((aligned(4)))
+ kal_uint8 med_aud_mem[MED_AUD_MEM_SIZE];
+ #endif
+#else
+ kal_uint8 med_aud_mem[MED_AUD_MEM_SIZE];
+#endif
+
+
+#if !defined(MED_NOT_PRESENT)
+
+/*==== FUNCTIONS ===========*/
+extern void med_timer_expiry_hdlr(ilm_struct *ilm_ptr);
+
+/*****************************************************************************
+ * FUNCTION
+ * med_nvram_read_data_cnf_hdlr
+ * DESCRIPTION
+ * This function is to handle nvram read data confirm.
+ * PARAMETERS
+ * local_para_ptr [?]
+ * peer_buff_ptr [?]
+ * RETURNS
+ * void
+ *****************************************************************************/
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #if defined(__SPEECH_MODE_TABLE_SUPPORT__)
+/* under construction !*/
+ #elif defined(__AMRWB_LINK_SUPPORT__)
+/* under construction !*/
+ #elif defined(__DUAL_MIC_SUPPORT__)
+/* under construction !*/
+ #else
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #ifdef __SPEECH_MODE_TABLE_SUPPORT__
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #if defined(__AMRWB_LINK_SUPPORT__)
+/* under construction !*/
+ #elif defined( __DUAL_MIC_SUPPORT__)
+/* under construction !*/
+ #else
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+ #endif /* __SPEECH_MODE_TABLE_SUPPORT__ */
+/* under construction !*/
+ #ifdef __AMRWB_LINK_SUPPORT__
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #if defined(__DUAL_MIC_SUPPORT__)
+/* under construction !*/
+ #else
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+ #endif /* __AMRWB_LINK_SUPPORT__ */
+/* under construction !*/
+ #ifdef __DUAL_MIC_SUPPORT__
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #ifdef __AMRWB_LINK_SUPPORT__
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #ifdef __AMRWB_LINK_SUPPORT__
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #ifdef __AMRWB_LINK_SUPPORT__
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif // #if 0
+#endif // #if !defined(MED_NOT_PRESENT)
+
+//#if !defined(MED_NOT_PRESENT)
+//extern void l1audio_console_handler(kal_char *string);
+//#endif //
+/*****************************************************************************
+ * FUNCTION
+ * med_main
+ * DESCRIPTION
+ * This function is main message dispatching function of media task.
+ * PARAMETERS
+ * ilm_ptr [?]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void med_main(ilm_struct *ilm_ptr)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+
+#if defined(__VOLTE_SUPPORT__)
+ if (ilm_ptr->msg_id == MSG_ID_LTECSR_VOICE_UL_DATA_NOTIFY)
+ {
+#ifndef __MTK_TARGET__
+ return;
+#else //#ifndef __MTK_TARGET__
+ void sp4g_fake_loopback(void);
+ sp4g_fake_loopback();
+#endif //#ifndef __MTK_TARGET__
+ }
+ if (ilm_ptr->msg_id == MSG_ID_LTECSR_VOICE_UL_MUTE_NOTIFY)
+ {
+ return;
+ }
+#endif //#if defined(__VOLTE_SUPPORT__)
+
+#if !defined(MED_NOT_PRESENT)
+ if (ilm_ptr->msg_id == MSG_ID_TIMER_EXPIRY)
+ {
+ ASSERT(0);
+ //med_timer_expiry_hdlr(ilm_ptr);
+ }
+ /*else if (ilm_ptr->msg_id == MSG_ID_MED_STARTUP_REQ)
+ {
+ med_startup_hdlr(ilm_ptr);
+ }
+ else if (ilm_ptr->msg_id == MSG_ID_NVRAM_READ_CNF)
+ {
+ med_nvram_read_data_cnf_hdlr(ilm_ptr->local_para_ptr, ilm_ptr->peer_buff_ptr);
+ }
+ else if (ilm_ptr->msg_id == MSG_ID_NVRAM_WRITE_CNF)
+ {
+ med_nvram_write_data_cnf_hdlr(ilm_ptr->local_para_ptr, ilm_ptr->peer_buff_ptr);
+ }
+ else if ( (ilm_ptr->msg_id >= MSG_ID_MED_CODE_BEGIN) && (ilm_ptr->msg_id <= MSG_ID_MED_CODE_TAIL) )
+ {
+ aud_main(ilm_ptr);
+ }*/
+ else if(ilm_ptr->msg_id == MSG_ID_MEDIA_AUD_SP_SET_MODE_REQ)
+ {
+ meida_aud_sp_set_mode_req_struct *req_p;
+ req_p = (meida_aud_sp_set_mode_req_struct*) ilm_ptr->local_para_ptr;
+ if (req_p->speech_on)
+ {
+ L1SP_Speech_On(req_p->rat_mode);
+ }
+ else
+ {
+ L1SP_Speech_Off();
+ }
+ }
+
+ else
+#endif
+ if (ilm_ptr->msg_id == MSG_ID_TST_INJECT_STRING) {
+ tst_module_string_inject_struct *tstInj = (tst_module_string_inject_struct *)ilm_ptr->local_para_ptr;
+ if(tstInj->index == 99 ) {
+ void l1audio_console_handler(kal_char *string);
+ l1audio_console_handler((kal_char *)(tstInj->string));
+ } else {
+ kal_prompt_trace(MOD_MED, "unused inject string index = %d ", tstInj->index);
+ }
+ } else if(ilm_ptr->msg_id == MSG_ID_L4CPS_EM_UPDATE_REQ ) {
+ l4cps_em_update_req_struct * em_update_ptr = (l4cps_em_update_req_struct *) ilm_ptr->local_para_ptr;
+ if(em_update_ptr->em_src == EM_FROM_ELT) {
+ void SP_setEmCodecNotifyOff(kal_bool isOff);
+ if(EM_OFF == em_update_ptr->info_request[EM_SPEECH_INFO_SPH_CODEC]) {
+ SP_setEmCodecNotifyOff(KAL_TRUE);
+ } else if(EM_ON == em_update_ptr->info_request[EM_SPEECH_INFO_SPH_CODEC]) {
+ SP_setEmCodecNotifyOff(KAL_FALSE);
+ } // EM_NC, no change do nothing
+ } // else from AT do nothing
+ }
+
+ if (ilm_ptr->msg_id == MSG_ID_AUDIO_L4C_EPOF_NOTIFY) {
+#if defined( __SMART_PHONE_MODEM__ )
+ kal_prompt_trace(MOD_L1SP, "[EPOF]med_main receive L4C EPOF notify");
+ set_spcGetEpofTimes(ENUM_EPOF_MD1_L4C_NOTIFY, 1);
+ if( 0 == get_spcGetEpofTimes(ENUM_EPOF_DO_FORCEENDALLAPP) )
+ {
+ void Spc_ForceEndAllApp(void);
+ Spc_ForceEndAllApp();
+ }
+ if(get_spcGetEpofTimes(ENUM_EPOF_AP_ACK_NOTIFY))
+ {
+ //Notify L4C: speech driver enter EPOF done
+ msg_send6(MOD_MED, MOD_L4C, AUDIO_SAP, MSG_ID_AUDIO_L4C_EPOF_ACK, (local_para_struct *)NULL, NULL);
+ kal_prompt_trace(MOD_L1SP, "[EPOF]med_main notify L4C done");
+ }
+#else // #if defined( __SMART_PHONE_MODEM__ )
+ //Notify L4C: speech driver enter EPOF done
+ msg_send6(MOD_MED, MOD_L4C, AUDIO_SAP, MSG_ID_AUDIO_L4C_EPOF_ACK, (local_para_struct *)NULL, NULL);
+ kal_prompt_trace(MOD_L1SP, "[EPOF]med_main notify L4C done 2");
+#endif // #if defined( __SMART_PHONE_MODEM__ )
+ }
+
+#if defined(SHASTA_L)
+ if (ilm_ptr->msg_id == MSG_ID_AUDIO_C2K_EPOF_NOTIFY) {
+#if defined( __SMART_PHONE_MODEM__ )
+ kal_prompt_trace(MOD_L1SP, "[EPOF]med_main receive C2K EPOF notify");
+ set_spcGetEpofTimes(ENUM_EPOF_C2K_NOTIFY, 1);
+ if( 0 == get_spcGetEpofTimes(ENUM_EPOF_DO_FORCEENDALLAPP) )
+ {
+ Spc_ForceEndAllApp();
+ }
+#endif // #if defined( __SMART_PHONE_MODEM__ )
+ }
+#endif //#if defined(SHASTA_L)
+
+ if(ilm_ptr->msg_id == MSG_ID_AUDIO_CUST_DUMP_REQ) {
+#if defined( __SMART_PHONE_MODEM__ )
+ void spc_sendCustomDump(void *ilm);
+ spc_sendCustomDump(ilm_ptr->local_para_ptr);
+#endif
+ }
+#if !defined(L1_NOT_PRESENT) && !defined(__UE_SIMULATOR__)
+ #if defined( __DATA_CARD_SPEECH__ )
+ if ( ( (ilm_ptr->msg_id >= CMUX_MSG_CODE_BEGIN) && (ilm_ptr->msg_id <= MSG_ID_CMUX_CODE_TAIL) )
+ || ( (ilm_ptr->msg_id >= MSG_ID_SPEECH_ON_ACK) && (ilm_ptr->msg_id <= MSG_ID_STRM_SPEECH_UL_DATA_REQUEST ) )
+ || ( (ilm_ptr->msg_id >= DRIVER_MSG_CODE_BEGIN) && (ilm_ptr->msg_id <= MSG_ID_DRIVER_CODE_TAIL) ) )
+ {
+ SP_Strm_Audl_Handler(ilm_ptr);
+ }
+ #endif
+ #if defined( __SMART_PHONE_MODEM__ )
+ if (ilm_ptr->msg_id == MSG_ID_AUDIO_A2M_CCCI)
+ {
+ SpcIO_Msg_Handler_inAudL(ilm_ptr);
+ } else if (ilm_ptr->msg_id == MSG_ID_MEDIA_AUD_MUTE_REQ) {
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ kal_uint16 cnf_msg_id;
+ void *cnf_p = NULL;
+
+ media_aud_mute_req_struct *req_p;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ req_p = (media_aud_mute_req_struct*) ilm_ptr->local_para_ptr;
+
+ switch (req_p->device)
+ {
+ case AUDIO_DEVICE_MICROPHONE:
+ /* call L1AUD to set microphone mute */
+ L1SP_MuteMicrophone(req_p->mute);
+ // aud_context_p->audio_mute = req_p->mute;
+ break;
+ default:
+ break;
+ }
+
+ cnf_p = (media_aud_mute_cnf_struct*) construct_local_para(sizeof(media_aud_mute_cnf_struct), TD_CTRL);
+
+ cnf_msg_id = MSG_ID_MEDIA_AUD_MUTE_CNF;
+
+ // aud_send_ilm(ilm_ptr->src_mod_id, cnf_msg_id, cnf_p, NULL);
+ msg_send6(kal_get_active_module_id(),ilm_ptr->src_mod_id,AUDIO_SAP,cnf_msg_id,cnf_p, NULL);
+ }
+ #endif
+#endif
+
+ if ((ilm_ptr->msg_id > MSG_ID_AUDIO_M2M_BEGIN) && (ilm_ptr->msg_id < MSG_ID_AUDIO_M2M_TAIL))
+ {
+ #ifdef __MTK_TARGET__
+ void SP_M2M_Handler(ilm_struct *ilm_ptr);
+ SP_M2M_Handler(ilm_ptr);
+ #endif //#ifdef __MTK_TARGET__
+ }
+#if !defined(__L1_STANDALONE__)
+ if ((ilm_ptr->msg_id > MSG_ID_AUDIO_L2P_BEGIN) && (ilm_ptr->msg_id < MSG_ID_AUDIO_L2P_TAIL))
+ {
+ #ifdef __MTK_TARGET__
+ void SP_L2P_Handler(ilm_struct *ilm_ptr);
+ SP_L2P_Handler(ilm_ptr);
+ #endif //#ifdef __MTK_TARGET__
+ }
+#endif
+#if defined(__VOLTE_SUPPORT__)
+ if ( ilm_ptr->msg_id == MSG_ID_MEDIA_IN_PROC_CALL_REQ )
+ {
+ #ifdef __MTK_TARGET__
+ void aud_util_in_proc_call_req_hdlr(ilm_struct *ilm_ptr);
+ kal_prompt_trace(MOD_L1SP, "[TONEDEBUG]MSG_ID_MEDIA_IN_PROC_CALL_REQ1");
+ aud_util_in_proc_call_req_hdlr(ilm_ptr);
+ #endif //#ifdef __MTK_TARGET__
+ }
+#endif
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * med_task_main
+ * DESCRIPTION
+ * This function is main function of media task.
+ * PARAMETERS
+ * task_entry_ptr [?]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void med_task_main(task_entry_struct *task_entry_ptr)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ ilm_struct current_ilm;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+
+#if !defined(L1_NOT_PRESENT) && !defined(__UE_SIMULATOR__)
+ SP_Drv_Init_Task();
+#endif
+
+ while (1)
+ {
+ msg_receive_extq(¤t_ilm);
+
+ kal_set_active_module_id(current_ilm.dest_mod_id);
+
+ med_main((void*)¤t_ilm);
+
+ destroy_ilm(¤t_ilm);
+ }
+
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * med_init
+ * DESCRIPTION
+ * This function is used to init media task.
+ * PARAMETERS
+ * task_indx [IN]
+ * RETURNS
+ *
+ *****************************************************************************/
+kal_bool med_init(void)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+#if !defined(MED_NOT_PRESENT)
+ med_context_p->aud_mem_p = med_aud_mem;
+
+ /*if (!aud_init())
+ {
+ return KAL_FALSE;
+ }*/
+#else //#if !defined(MED_NOT_PRESENT)
+ #if defined(__MCU_DTMF_SUPPORT__)
+ med_context_p->aud_mem_p = med_aud_mem;
+ #endif //#if defined(__MCU_DTMF_SUPPORT__)
+#endif //#if !defined(MED_NOT_PRESENT)
+
+ if (!med_utility_init())
+ {
+ return KAL_FALSE;
+ }
+
+#if !defined(L1_NOT_PRESENT) && !defined(__UE_SIMULATOR__)
+ if (!SP_Drv_Init_Bootup())
+ {
+ return KAL_FALSE;
+ }
+#endif
+
+ return KAL_TRUE;
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * med_reset
+ * DESCRIPTION
+ * This function is used to reset media task.
+ * PARAMETERS
+ * task_indx [IN]
+ * RETURNS
+ *
+ *****************************************************************************/
+kal_bool med_reset(void)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ return KAL_TRUE;
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * med_create
+ * DESCRIPTION
+ * This function is used to create media task configuration info.
+ * PARAMETERS
+ * handle [IN]
+ * RETURNS
+ *
+ *****************************************************************************/
+kal_bool med_create(comptask_handler_struct **handle)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ static const comptask_handler_struct med_handler_info =
+ {
+ med_task_main, /* task entry function */
+ med_init, /* task initialization function */
+ med_reset /* task reset handler */
+ };
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ *handle = (comptask_handler_struct*) & med_handler_info;
+
+ return KAL_TRUE;
+}
+
diff --git a/mcu/middleware/media/common/src/med_utility.c b/mcu/middleware/media/common/src/med_utility.c
new file mode 100644
index 0000000..f85efd1
--- /dev/null
+++ b/mcu/middleware/media/common/src/med_utility.c
@@ -0,0 +1,288 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * med_utility.c
+ *
+ * Project:
+ * --------
+ * Maui
+ *
+ * Description:
+ * ------------
+ * This file includes common used functions of media task.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+/*==== INCLUDES =========*/
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+#include "kal_general_types.h"
+#include "kal_trace.h"
+
+/* global includes */
+#include "l1audio.h"
+
+/* local includes */
+#include "med_main.h"
+#include "med_global.h"
+#include "med_mem.h"
+#include "med_struct.h"
+#include "med_context.h"
+#include "med_smalloc.h"
+#include "med_utility.h"
+#include "med_trc.h"
+#include "aud_main.h"
+
+kal_mutexid med_mem_mutex;
+
+/*****************************************************************************
+ * FUNCTION
+ * med_alloc_ext_mem
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * size [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void *med_alloc_ext_mem_ext(kal_int32 size, kal_uint8 location, char* file_p, long line_p)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ void *p = NULL;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ kal_take_mutex(med_mem_mutex);
+ p = (void*)med_ext_smalloc_ext((size_type) size, location, file_p, line_p);
+ kal_give_mutex(med_mem_mutex);
+
+ return p;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * med_free_aud_mem_ext
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * pointer [IN]
+ * RETURNS
+ * void
+ *****************************************************************************/
+void med_free_aud_mem_ext(void **pointer,char* file_p, long line_p)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ kal_take_mutex(med_mem_mutex);
+ med_aud_sfree((address_t) * pointer);
+ kal_give_mutex(med_mem_mutex);
+ *pointer = NULL;
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * med_util_alloc_aud_mem
+ * DESCRIPTION
+ * This function is to allocate memory from audio memory pool.
+ * PARAMETERS
+ * size [IN] Memory size to be allocated.
+ * file_p [IN] File name.
+ * line [IN] Line number in the file.
+ * RETURNS
+ * Allocated memory address
+ *****************************************************************************/
+static void* med_util_alloc_aud_mem(kal_uint32 size, char* file_p, long line)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ return med_alloc_ext_mem_ext(size, MED_EXT_MEMORY_TYPE_AUDIO_NONCACHEABLE, file_p, line);
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * med_util_alloc_aud_cacheable_mem
+ * DESCRIPTION
+ * This function is to allocate cacheable memory from audio memory pool.
+ * PARAMETERS
+ * void
+ * RETURNS
+ * Allocated memory address
+ *****************************************************************************/
+static void* med_util_alloc_aud_cacheable_mem(kal_uint32 size, char* file_p, long line)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ return med_alloc_ext_mem_ext(size, MED_EXT_MEMORY_TYPE_AUDIO_CACHEABLE, file_p, line);
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * med_util_free_aud_mem
+ * DESCRIPTION
+ * This function is to free audio memory.
+ * PARAMETERS
+ * void
+ * RETURNS
+ * Allocated memory address
+ *****************************************************************************/
+static void med_util_free_aud_mem(void** mem_p, char* file_p, long line)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ med_free_aud_mem_ext(mem_p, file_p, line);
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * med_utility_init
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ * void
+ * RETURNS
+ *
+ *****************************************************************************/
+kal_bool med_utility_init(void)
+{
+
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ Media_Func_Reg_Type media_func;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+
+ med_mem_mutex = kal_create_mutex("MED MEM");
+
+ /* Register callback functions to L1audio */
+ media_func.alloc_mem = med_util_alloc_aud_mem;
+ media_func.alloc_mem_cacheable = med_util_alloc_aud_cacheable_mem;
+ media_func.free_mem = med_util_free_aud_mem;
+ media_func.set_path_volume = NULL;
+ media_func.get_active_mode = NULL;
+#if defined(__VOLTE_SUPPORT__)
+ media_func.send_proc_call = aud_send_in_proc_call_req; // is only used in VoLTE DTMF MCU destroy functions
+#else
+ media_func.send_proc_call = NULL;
+#endif
+ media_func.send_proc_call2 = NULL;
+ media_func.get_meta_file = NULL;
+ media_func.get_meta_array = NULL;
+
+#if !defined(L1_NOT_PRESENT)
+ Audio_MedFuncReg(&media_func);
+#endif
+
+ /* init audio memory */
+ med_set_aud_memory_pool((unsigned char*)med_context_p->aud_mem_p, MED_AUD_MEM_SIZE);
+
+ return KAL_TRUE;
+}
+
+
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_aux.h b/mcu/middleware/meta/ft/inc/ft_fnc_aux.h
new file mode 100644
index 0000000..b8f1aa9
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_aux.h
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_aux.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Auxiliary Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+#ifndef _FT_FNC_AUX_H_
+#define _FT_FNC_AUX_H_
+// added in RHR first round
+#include "kal_public_api.h"
+
+void FT_Aux_Operation(ilm_struct *ptrMsg);
+void FT_Handle_FTA_CNF(ilm_struct *ptrMsg);
+
+
+#endif //#ifndef _FT_FNC_MISC_H_
+
+#endif // end of #if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_c2krf.h b/mcu/middleware/meta/ft/inc/ft_fnc_c2krf.h
new file mode 100644
index 0000000..8a3220e
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_c2krf.h
@@ -0,0 +1,83 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2016
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2016
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_c2krf.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT private API definition (Category: C2KRF)
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __FT_FNC_C2KRF_H__
+#define __FT_FNC_C2KRF_H__
+#if defined(__C2K_RAT__)
+#include "ft_msg.h"
+void FT_Crf_Operation(ilm_struct *ptrMsg);
+void FT_Crf_ConfirmHandler(ilm_struct* crfMessage);
+#endif // #if defined(__C2K_RAT__)
+#endif // #ifndef __FT_FNC_C2KRF_H__
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_custom.h b/mcu/middleware/meta/ft/inc/ft_fnc_custom.h
new file mode 100644
index 0000000..1d41569
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_custom.h
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_custom.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Customer Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef _FT_FNC_CUSTOM_H_
+#define _FT_FNC_CUSTOM_H_
+// added in RHR first round
+#include "kal_public_api.h"
+
+void FT_Custom_Operation(ilm_struct *ptrMsg);
+void FT_Handle_FTC_CNF(ilm_struct *ptrMsg);
+
+
+#endif //#ifndef _FT_FNC_MISC_H_
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_fat.h b/mcu/middleware/meta/ft/inc/ft_fnc_fat.h
new file mode 100644
index 0000000..7f81341
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_fat.h
@@ -0,0 +1,123 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_fat.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT FAT operation header file
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef _FT_FNC_FAT_H_
+#define _FT_FNC_FAT_H_
+#include "ft_msg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+*
+* FAT directory structure traverse
+*
+*******************************************************************************/
+#define FT_FAT_FIND_NOT_FOUND 0xFF
+
+typedef enum {
+ FT_FAT_FIND_FILE = 0,
+ FT_FAT_FIND_FILE_RECURSIVE,
+ FT_FAT_FIND_DIR_RECURSIVE
+}FT_FAT_FIND_MODE;
+
+typedef kal_int8 (*FT_FAT_FIND_CALLBACK)(const WCHAR *fullpath, const FS_DOSDirEntry *dos_info, void *usr_arg);
+
+extern kal_uint8 ft_fat_find(const WCHAR *base_path, const WCHAR *find_pattern, FT_FAT_FIND_MODE mode, FT_FAT_FIND_CALLBACK cb, void *usr_arg);
+
+/* FAT */
+#define FT_FAT_ASSERT_UNKNOWN_OP 0
+#define FT_FAT_MAX_FULLPATH FS_MAX_PATH
+#define FT_FAT_MAX_FILENAME (FS_MAX_PATH-20)
+#define FT_FAT_MAX_DIR_DEPTH 300
+
+typedef struct {
+ FS_HANDLE fs_handle;
+}ft_fat_dir_info;
+
+extern void FT_FAT_Operation(FT_FAT_OPERATION *ft_fat_op, peer_buff_struct *peer_buff_in);
+kal_int32 FT_GetDiskFreeSpace(const WCHAR* pathname);
+kal_int32 ft_CreateFullDirectory(const WCHAR *pathname);
+kal_int16 FT_GetAvailableDrive(kal_int32 size);
+
+#ifdef __cplusplus
+}
+#endif // #ifdef __cplusplus
+
+#endif // #ifndef _FT_FNC_FAT_H_
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_l1rf.h b/mcu/middleware/meta/ft/inc/ft_fnc_l1rf.h
new file mode 100644
index 0000000..8ba7b0c
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_l1rf.h
@@ -0,0 +1,154 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_l1rf.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT private API definition (Category: L1RF)
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __FT_FNC_L1RF_H__
+#define __FT_FNC_L1RF_H__
+#if defined(__MTK_GL1_GSM__) || defined(__L1SIM_NR_SM__) || defined(__NR_L1SIM__)
+#include "ft_msg.h"
+extern kal_uint8 FT_UTIL_SendCnf(const FT_UTILITY_COMMAND_CNF *cnf, peer_buff_struct *p_peer_buff);
+void FT_Rf_Operation(ilm_struct *ptrMsg);
+void FT_Rf_ConfirmHandler(ilm_struct* rfMessage);
+void FT_RfCheckFunctionSupported(kal_uint32 query_op_code);
+#endif // #if defined(__MTK_GL1_GSM__)
+#endif // #ifndef __FT_FNC_L1RF_H__
+
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_l4.h b/mcu/middleware/meta/ft/inc/ft_fnc_l4.h
new file mode 100644
index 0000000..42bb645
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_l4.h
@@ -0,0 +1,6 @@
+
+#ifndef __FT_FNC_L4_H__
+#define __FT_FNC_L4_H__
+#include "ft_msg.h"
+void FT_L4_Operation(ilm_struct *ptrMsg);
+#endif // #ifndef __FT_FNC_L4_H__
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_lterf.h b/mcu/middleware/meta/ft/inc/ft_fnc_lterf.h
new file mode 100644
index 0000000..2dd04ee
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_lterf.h
@@ -0,0 +1,108 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_lterf.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT private API definition (Category: LTERF)
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __FT_FNC_LTERF_H__
+#define __FT_FNC_LTERF_H__
+#include "ft_msg.h"
+extern kal_uint8 FT_UTIL_SendCnf(const FT_UTILITY_COMMAND_CNF *cnf, peer_buff_struct *p_peer_buff);
+void FT_Erf_Operation(ilm_struct *ptrMsg);
+void FT_PhyTool_Operation(ilm_struct *ptrMsg);
+void FT_Erf_ConfirmHandler(ilm_struct* erfMessage);
+void FT_ErfCheckFunctionSupported(kal_uint32 query_op_code);
+#endif // #ifndef __FT_FNC_LTERF_H__
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_misc.h b/mcu/middleware/meta/ft/inc/ft_fnc_misc.h
new file mode 100644
index 0000000..7b7cc2e
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_misc.h
@@ -0,0 +1,113 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_misc.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Misc Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef _FT_FNC_MISC_H_
+#define _FT_FNC_MISC_H_
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+#include "nvram_struct.h"
+
+#define FT_SML_VALID 0x00
+#define FT_SML_INVALID 0x01
+#define FT_SML_NO_FILENAME 0x02
+
+kal_uint32 FT_MiscCheckFunctionSupported(kal_uint32 query_op_code);
+void FT_MISC_Operation(ilm_struct *ptrMsg);
+kal_uint8 FT_MISC_SendCnf(FT_MISC_CNF *ft_misc_ret, peer_buff_struct *peer_buff);
+
+extern kal_uint16 ft_gl_misc_token;
+
+void FT_Misc_CalDataInTargetAddOneRequestHandler(ilm_struct *ptrMsg);
+kal_bool FT_Misc_CalDataRecordItemProcess(kal_uint16 fileIdx, kal_uint16 recordId);
+
+#endif // end of #ifndef _FT_FNC_MISC_H_
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_misc_ex.h b/mcu/middleware/meta/ft/inc/ft_fnc_misc_ex.h
new file mode 100644
index 0000000..496766f
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_misc_ex.h
@@ -0,0 +1,111 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_misc.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Misc Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef _FT_FNC_MISC_EX_H_
+#define _FT_FNC_MISC_EX_H_
+#include "kal_public_api.h"
+
+#define FT_MISC_EX_DATA_FRAME_SIZE 1800
+
+kal_uint32 FT_MiscExCheckFunctionSupported(kal_uint32 query_op_code);
+void FT_MISC_EX_Operation(ilm_struct *ptrMsg);
+void FT_MiscEx_NvramConfirmHandler(ilm_struct* ptrMsgCnf);
+extern kal_uint16 ft_gl_misc_ex_token;
+
+enum META_BP_AREA_STATUS_E
+{
+ META_BP_AREA_STATUS_OK = 0
+ ,META_BP_AREA_STATUS_EMPTY
+ ,META_BP_AREA_STATUS_BROKEN
+ ,META_BP_AREA_STATUS_NO_SYNC
+ ,META_BP_AREA_STATUS_UNKNOWN
+
+};
+
+#endif // end of #ifndef _FT_FNC_MISC_H_
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_mmrf.h b/mcu/middleware/meta/ft/inc/ft_fnc_mmrf.h
new file mode 100644
index 0000000..1ebf256
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_mmrf.h
@@ -0,0 +1,101 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_mmrf.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT private API definition (Category: MMRF)
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __FT_FNC_MMRF_H__
+#define __FT_FNC_MMRF_H__
+#include "kal_public_defs.h"
+extern kal_uint8 FT_UTIL_SendCnf(const FT_UTILITY_COMMAND_CNF *cnf, peer_buff_struct *p_peer_buff);
+void FT_Mmrf_Operation(ilm_struct* ptrMsg);
+void FT_Mmrf_ConfirmHandler(ilm_struct* mmrfMessage);
+void FT_MmrfCheckFunctionSupported(kal_uint32 query_op_code);
+void FT_Mmrf_UpdateRuntimeConfirmHandler(ilm_struct *ptrMsg);
+void FT_Mmrf_UpdateRuntimeHandler(peer_buff_struct* peer_buff, kal_uint16 lid, kal_uint16 rid);
+kal_bool FT_Mmrf_PollUpdateRuntimeReady();
+#endif // #ifndef __FT_FNC_MMRF_H__
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_nrf.h b/mcu/middleware/meta/ft/inc/ft_fnc_nrf.h
new file mode 100644
index 0000000..e2ea164
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_nrf.h
@@ -0,0 +1,70 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_nr.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT private API definition (Category: NR)
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __FT_FNC_NRF_H__
+#define __FT_FNC_NRF_H__
+#include "kal_public_defs.h"
+void FT_Nrf_Operation(ilm_struct* ptrMsg);
+void FT_Nrf_ConfirmHandler(ilm_struct* nrMessage);
+#endif // #ifndef __FT_FNC_NRF_H__
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_nvram.h b/mcu/middleware/meta/ft/inc/ft_fnc_nvram.h
new file mode 100644
index 0000000..641b1f9
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_nvram.h
@@ -0,0 +1,128 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_nvram.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT NVRAM operation header file
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef _FT_FNC_NVRAM_H_
+#define _FT_FNC_NVRAM_H_
+#include "ft_msg.h"
+#include "nvram_struct.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*fp_nvram_read_handler_t)(ft_nvram_read_req_struct_T* req, kal_uint8 ftAccessId);
+typedef void (*fp_nvram_read_confirm_handler_t)(nvram_read_cnf_struct*, peer_buff_struct*);
+typedef void (*fp_nvram_write_handler_t)(ft_nvram_write_req_struct_T* req, peer_buff_struct* peer_buff, kal_uint8 ftAccessId);
+typedef void (*fp_nvram_write_confirm_handler_t)(nvram_write_cnf_struct*);
+
+extern fp_nvram_read_handler_t FT_ReadFrom_NVRAM;
+extern fp_nvram_read_confirm_handler_t FT_ReadFrom_NVRAM_CNF;
+extern fp_nvram_write_handler_t FT_WriteTo_NVRAM;
+extern fp_nvram_write_confirm_handler_t FT_WriteTo_NVRAM_CNF;
+void FT_Nvram_SendReadRequestToNvram(kal_uint16, kal_uint16, kal_uint8 accessId);
+void FT_Nvram_ReadNvramHandler(ft_nvram_read_req_struct_T* req, kal_uint8 accessId);
+void FT_NvramSec_ReadNvramHandler(ft_nvram_read_req_struct_T* req, kal_uint8 accessId);
+void FT_Nvram_ReadNvramConfirmHandler(nvram_read_cnf_struct*, peer_buff_struct*);
+void FT_Nvram_WriteNvramHandler(ft_nvram_write_req_struct_T* req, peer_buff_struct* peer_buff, kal_uint8 accessId);
+void FT_NvramSec_WriteNvramHandler(ft_nvram_write_req_struct_T* req, peer_buff_struct* peer_buff, kal_uint8 accessId);
+void FT_Nvram_WriteNvramConfirmHandler(nvram_write_cnf_struct*);
+
+void FT_Nvram_SendReadResponseToHost(nvram_read_cnf_struct* nvramReadCnf, peer_buff_struct* nvramReadCnfPeerBuf, kal_bool holdBufferForRelay);
+void FT_Nvram_SendWriteResponseToHost(nvram_write_cnf_struct* nvramWriteCnf);
+kal_bool FT_Nvram_IsModNvramRespnose(ilm_struct* ilm_ptr);
+void FT_Nvram_SendWriteCommandToNvram(peer_buff_struct* peer_buff, kal_uint16 lid, kal_uint16 rid, kal_uint8 ftAccessId, kal_bool holdBufferForRelay);
+void FT_Nvram_SendReadCommandToNvram(kal_uint16 lid, kal_uint16 rid, kal_uint8 ftAccessId);
+
+#define FT_NVRAM_ACCESS_ID_CAL_INTEGRITY_OP 0x1
+#ifdef __cplusplus
+}
+#endif // #ifdef __cplusplus
+
+#endif // #ifndef _FT_FNC_NVRAM_H_
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_tdscdma.h b/mcu/middleware/meta/ft/inc/ft_fnc_tdscdma.h
new file mode 100644
index 0000000..93c1f61
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_tdscdma.h
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_tdscdma.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * TD-SCDMA Function header
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef _FT_FNC_TDSCDMA_H_
+#define _FT_FNC_TDSCDMA_H_
+#if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+
+//20130206
+/*************************************************************************
+ * Include Statements for MAUI
+ *************************************************************************/
+#include "tl1_struct.h"
+#include "tl1_cc_public.h"
+
+#endif // #if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+#endif // #ifndef _FT_FNC_TDSCDMA_H_
diff --git a/mcu/middleware/meta/ft/inc/ft_fnc_wcdma.h b/mcu/middleware/meta/ft/inc/ft_fnc_wcdma.h
new file mode 100644
index 0000000..4f80bbb
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_fnc_wcdma.h
@@ -0,0 +1,137 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_wcdma.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * WCDMA Function header
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef _FT_FNC_WCDMA_H_
+#define _FT_FNC_WCDMA_H_
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#include "ft_msg.h"
+/*************************************************************************
+ * Include Statements for MAUI
+ *************************************************************************/
+extern kal_uint8 FT_UTIL_SendCnf(const FT_UTILITY_COMMAND_CNF *cnf, peer_buff_struct *p_peer_buff);
+void FT_UL1RfCheckFunctionSuppported(kal_uint32 query_op_code);
+void FT_FtURfTestReq(ilm_struct *ptrMsg);
+void FT_UL1TST_SEND_CNF_BACK(ilm_struct *ptrMsg_ul1tst);
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#endif // #ifndef _FT_FNC_WCDMA_H_
diff --git a/mcu/middleware/meta/ft/inc/ft_mem.h b/mcu/middleware/meta/ft/inc/ft_mem.h
new file mode 100644
index 0000000..32afadd
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_mem.h
@@ -0,0 +1,84 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_mem.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT memory management functions
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef __FT_MEM_H__
+#define __FT_MEM_H__
+void FtInitMemoryPool(void);
+void* FtAllocExtMemory(kal_uint32 size);
+void FtFreeExtMemory(void* ptr);
+kal_uint32 FtGetLeftExtMemory(void);
+#endif // #ifndef __FT_MEM_H__
diff --git a/mcu/middleware/meta/ft/inc/ft_private.h b/mcu/middleware/meta/ft/inc/ft_private.h
new file mode 100644
index 0000000..3a9f9c6
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_private.h
@@ -0,0 +1,302 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_private.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT private stuff
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef FT_PRIVATE_H
+#define FT_PRIVATE_H
+
+#include "ft_msg.h"
+#include "kal_public_api.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#ifndef L1_SIM
+#include "nvram_struct.h"
+#include "fs_type.h"
+#endif // #ifndef L1_SIM
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#include "ul1cal.h"
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+/***********************
+ * TST module APIs
+ **********************/
+#include "kal_trace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern kal_uint16 ft_gl_token;
+extern kal_uint16 ft_gl_rf_token;
+extern kal_uint16 ft_gl_l4aud_token;
+extern kal_uint16 ft_gl_l4aud_ind_token;
+extern kal_uint16 ft_gl_l4aud_current_volume;
+extern peer_buff_struct *ft_gl_l4aud_peer_buf;
+extern kal_uint16 ft_gl_nvram_token;
+
+//extern kal_bool g_META_DLL_Version_Incorrect;
+extern kal_bool g_b_ft_assert_check_enable;
+extern kal_bool g_b_ver_Incorrect;
+extern kal_uint8 g_u1_msg_recv_times;
+
+#ifndef L1_SIM
+/* for build warning */
+extern void FT_FtPMICRegisterRead(ft_PMICRegisterRead_req_T* req, unsigned char RegType);
+extern void FT_FtPMICRegisterWrite(ft_PMICRegisterWrite_req_T* req, unsigned char RegType);
+#endif // #ifndef L1_SIM
+
+/* for backup and restore calibration data */
+extern kal_uint8 ft_gl_path_check_flag;
+/* for ft event group pointer */
+#define FT_EVENT_TIMEOUT 5000 // 10 sec
+extern kal_uint32 ft_event_group_ptr; // event bit map in ft_public.h
+/* ------------------------------------------------------------------------- */
+/*******************************************************************************
+*
+* ft_fnc.c
+*
+*******************************************************************************/
+void FT_DispatchMessage(ilm_struct* ptrMsg);
+void FT_InitCalibrationData(task_entry_struct *task_entry_ptr);
+void FT_InitFtData(void);
+#ifndef L1_SIM
+/* BaseBand Testing */
+void FT_FtRegisterRead (ft_RegisterRead_req_T *req, unsigned char RegType);
+void FT_FtRegisterWrite (ft_RegisterWrite_req_T *req, unsigned char RegType);
+void FT_FtADC_GetMeaData (ft_FtADC_GetMeaData_req_T *req);
+#endif // #ifndef L1_SIM
+/* Version Info */
+extern void FT_GetVersionInfo(void);
+
+/* FT task test alive */
+extern void FT_TestAlive(void);
+
+#ifndef L1_SIM
+/* FT task Power Off */
+extern void FT_PowerOff(void);
+
+/* SLA */
+extern void FT_GetSlaStatus(void);
+extern void FT_CheckSlaVer(FT_CHECK_SLA_VER_REQ *ft_check_sla_ver_op);
+extern void FT_GetSlaPara(void);
+extern void FT_VerifySla(FT_VERIFY_SLA_RND_REQ *ft_verify_sla_op);
+extern kal_bool FT_MetaSLA_Is_Enabled(void);
+
+#endif // #ifndef L1_SIM
+
+
+/* FT task utility command */
+extern void FT_UtilityCommand(ilm_struct *ptrMsg);
+
+/*******************************************************************************
+*
+* other module's api
+*
+*******************************************************************************/
+extern kal_uint32 SaveAndSetIRQMask(void);
+/***************************
+ * FT task self message API
+ **************************/
+typedef void (*ft_in_proc_call_type) (kal_uint32 arg1, void *arg2);
+typedef struct
+{
+ LOCAL_PARA_HDR
+ ft_in_proc_call_type func;
+ kal_uint32 func_arg1;
+ void *func_arg2;
+} ft_in_proc_call_req_struct;
+typedef enum
+{
+ MSG_ID_FT_IN_PROC_CALL_REQ,
+ MSG_ID_FT_IN_PROC_CALL_CNF
+}FT_TASK_MESSAGE_TYPE;
+void ft_send_in_proc_call_req(ft_in_proc_call_type func, kal_uint32 func_arg1, void *func_arg2);
+void ft_in_proc_call_handler(ilm_struct *ilm_ptr);
+extern kal_char g_FT_debug_buf[128];
+#ifndef L1_SIM
+/***********************
+ * NVRAM module APIs
+ **********************/
+extern kal_bool nvram_get_disk_file_info(kal_uint32 *diskfilesize, kal_uint32 *freespace, kal_uint32 *overhead);
+/***********************
+ * CCT module APIs
+ **********************/
+kal_uint8 ft_cct_check_op_is_support(kal_uint32 query_op_code);
+#endif // #ifndef L1_SIM
+
+#ifdef __cplusplus
+}
+#endif // #ifdef __cplusplus
+
+#endif // #ifndef FT_PRIVATE_H
+
diff --git a/mcu/middleware/meta/ft/inc/ft_report.h b/mcu/middleware/meta/ft/inc/ft_report.h
new file mode 100644
index 0000000..e549d6f
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_report.h
@@ -0,0 +1,82 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_report.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT report API definition (Category: L1RF)
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef __FT_REPORT_H__
+#define __FT_REPORT_H__
+
+#endif // #ifndef __FT_REPORT_H__
diff --git a/mcu/middleware/meta/ft/inc/ft_trace_def.h b/mcu/middleware/meta/ft/inc/ft_trace_def.h
new file mode 100644
index 0000000..78ea7f2
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_trace_def.h
@@ -0,0 +1,71 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_trace_def.h
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * FT trace definition
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 08 18 2015 jenny.lin
+ * [MOLY00137504] [Jade][Security] Phase-in secure NVRAM interface
+ * [New Feature]NVRAM read/write by NVRAM secure API not by ILM message
+ *
+ ****************************************************************************/
+#ifndef _FT_TRACE_DEF_H
+#define _FT_TRACE_DEF_H
+#ifndef GEN_FOR_PC
+ #include "kal_public_defs.h"
+#endif /* GEN_FOR_PC */
+#include "kal_trace.h"
+#if !defined(GEN_FOR_PC)
+#endif
+#if !defined(GEN_FOR_PC)
+#include"ft_trace_def_mod_ft_utmd.h"
+#endif
+#endif /* _FT_TRACE_DEF_H */
diff --git a/mcu/middleware/meta/ft/inc/ft_trace_def_mod_ft_utmd.json b/mcu/middleware/meta/ft/inc/ft_trace_def_mod_ft_utmd.json
new file mode 100644
index 0000000..4af67ed
--- /dev/null
+++ b/mcu/middleware/meta/ft/inc/ft_trace_def_mod_ft_utmd.json
@@ -0,0 +1,221 @@
+{
+ "legacyParameters": {},
+ "module": "MOD_FT",
+ "startGen": "Legacy",
+ "endGen": "-",
+ "traceClassDefs": [
+ {
+ "FT_OP_INFO": {
+ "debugLevel": "Medium",
+ "tag": [
+ "FT_OP"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "FT_OP_FUNC": {
+ "debugLevel": "High",
+ "tag": [
+ "FT_OP"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "FT_CAL_INFO": {
+ "debugLevel": "Medium",
+ "tag": [
+ "FT_CAL"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "FT_CAL_FUNC": {
+ "debugLevel": "High",
+ "tag": [
+ "FT_CAL"
+ ],
+ "traceType": "DesignInfo"
+ }
+ },
+ {
+ "FT_NVRAM_INFO": {
+ "debugLevel": "High",
+ "tag": [
+ "FT_NVRAM"
+ ],
+ "traceType": "Public"
+ }
+ }
+ ],
+ "traceDefs": [
+ {
+ "FT_MISC_OP_CHECK_SIM_HW_TEST_ENTER_DRV": {
+ "apiType": "index",
+ "format": "[FT] Calling usim_iftest_for_smt",
+ "traceClass": "FT_OP_INFO"
+ }
+ },
+ {
+ "FT_MISC_OP_CHECK_SIM_HW_TEST_LEAVE_DRV": {
+ "apiType": "index",
+ "format": "[FT] Exit usim_iftest_for_smt: status (%d)",
+ "traceClass": "FT_OP_INFO"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_INIT_PROCESS": {
+ "apiType": "index",
+ "format": "[FT] Init Cal Data Integrity Check recording procedure",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_GET_NVRAM_ITEM_CHECKSUM": {
+ "apiType": "index",
+ "format": "[FT] Get Nvram item checksum file_idx(%d), rec_idx(%d) checksum(%d) valid(%d)",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_RECORD_NVRAM_ITEM_PROCESS": {
+ "apiType": "index",
+ "format": "[FT] Process NVRAM item with Cal Data Check Flow file_idx(%d), rec_idx(%d) enabled(%d)",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_ALLOCATE_BUFFER": {
+ "apiType": "index",
+ "format": "[FT] Allocate Cal Data Integrity Check internal buffer",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_FREE_BUFFER": {
+ "apiType": "index",
+ "format": "[FT] Free Cal Data Integrity Check internal buffer",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_ADD_RECORD": {
+ "apiType": "index",
+ "format": "[FT] Add Cal Data Integrity Check internal buffer file_idx(%d), rec_idx(%d), checksum(%d)",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_ADD_RECORD_BUFFER_EMPTY": {
+ "apiType": "index",
+ "format": "[FT] Cal Data Integrity internal buffer is NULL",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_ADD_RECORD_INSERT_ONE": {
+ "apiType": "index",
+ "format": "[FT] Add Cal Data Integrity to specific index (%d) current valid num after inserttion (%d)",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_ADD_RECORD_OUT_OF_BOUND": {
+ "apiType": "index",
+ "format": "[FT] Exceeds the Cal Data Integrity internal buffer boundary (%d)",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_ADD_RECORD_UPDATE_EXISTING_ONE": {
+ "format": "[FT] Add Cal Data Integrity to existing record in index (%d)",
+ "traceClass": "FT_CAL_INFO"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_ADD_RECORD_INSERT_FLOW_START": {
+ "apiType": "index",
+ "format": "[FT] Insert the Cal Data Integrity",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_DEL_RECORD": {
+ "apiType": "index",
+ "format": "[FT] Remove Cal Data Integrity Check internal buffer file_idx(%d), rec_idx(%d), is one record(%d)",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_CHECK_RECORD": {
+ "apiType": "index",
+ "format": "[FT] Check Cal Data Integrity Check internal buffer file_idx(%d), rec_idx(%d), is one record(%d)",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_SYNC_BUFFER": {
+ "apiType": "index",
+ "format": "[FT] Sync Cal Data Integrity Check buffer",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_CAL_DATA_SYNC_BUFFER_RESPONSE_HANDLER": {
+ "apiType": "index",
+ "format": "[FT] Cal Data Integrity Check sync buffer response handler current op(%d)",
+ "traceClass": "FT_CAL_FUNC"
+ }
+ },
+ {
+ "FT_MISC_OP_FUNC": {
+ "apiType": "index",
+ "format": "[FT] FT_MISC_Operation type(%d)",
+ "traceClass": "FT_OP_FUNC"
+ }
+ },
+ {
+ "FT_NVRAM_SEND_WRITE_CMD_TO_NVRAM": {
+ "format": "[FT][NVRAM] Send Write Request to NVRAM holdBufferForRelay(%d)",
+ "traceClass": "FT_NVRAM_INFO"
+ }
+ },
+ {
+ "FT_NVRAM_SEND_READ_CMD_TO_NVRAM": {
+ "format": "[FT][NVRAM] Send Read Request to NVRAM",
+ "traceClass": "FT_NVRAM_INFO"
+ }
+ },
+ {
+ "FT_NVRAM_SEND_WRITE_RESPONSE_TO_HOST": {
+ "apiType": "index",
+ "format": "[FT][NVRAM] Send Write Response to Host",
+ "traceClass": "FT_NVRAM_INFO"
+ }
+ },
+ {
+ "FT_NVRAM_SEND_READ_RESPONSE_TO_HOST": {
+ "apiType": "index",
+ "format": "[FT][NVRAM] Send Read Response to Host holdBufferForRelay(%d)",
+ "traceClass": "FT_NVRAM_INFO"
+ }
+ },
+ {
+ "FT_NVRAM_CALL_READ_NVRAM_API": {
+ "apiType": "index",
+ "format": "[FT][NVRAM] NVRAM API read data result = [%d] (result = 0 --> NVRAM_ERRNO_SUCCESS)",
+ "traceClass": "FT_NVRAM_INFO"
+ }
+ },
+ {
+ "FT_NVRAM_CALL_WRITE_NVRAM_API": {
+ "apiType": "index",
+ "format": "[FT][NVRAM] NVRAM API write data result = [%d] (result = 0 --> NVRAM_ERRNO_SUCCESS)",
+ "traceClass": "FT_NVRAM_INFO"
+ }
+ }
+ ],
+ "traceFamily": "PS"
+}
\ No newline at end of file
diff --git a/mcu/middleware/meta/ft/src/ft_dummy.c b/mcu/middleware/meta/ft/src/ft_dummy.c
new file mode 100644
index 0000000..095cb91
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_dummy.c
@@ -0,0 +1,160 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_dummy.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * Dummy function for ft lib in MAUI only configuration
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+/*************************************************************************
+ * Include Statements for task config
+ *************************************************************************/
+#include "syscomp_config.h"
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_public_defs.h"
+/*************************************************************************
+ * Include Statements for L1
+ *************************************************************************/
+#include "l1_types_public.h"
+/*************************************************************************
+ * FUNCTION
+ * ft_create
+ *
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ *
+ *************************************************************************/
+kal_bool
+ft_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct ft_handler_info =
+ {
+ NULL, /* task entry function */
+ NULL, /* task initialization function */
+ NULL, /* task configuration function */
+ NULL, /* task reset handler */
+ NULL, /* task termination handler */
+ };
+
+ *handle = (comptask_handler_struct *)&ft_handler_info;
+ return KAL_TRUE;
+}
+/*******************************************************************************
+* FUNCTION
+* FT_DispatchReports
+*
+* DESCRIPTION
+* Dispatch report
+*
+* CALLS
+* FT_ReportPowerScanDone
+* FT_ReportFCB
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* None
+*
+* GLOBALS AFFECTED
+* None
+*******************************************************************************/
+void FT_DispatchReports( Report_FT *report )
+{
+}
+/*******************************************************************************
+ * FUNCTION
+ * FT_META_IsBasicOperation
+ *
+ * DESCRIPTION
+ * Check the message ID belongs to one of the basic META mode operation
+ *
+ * CALLS
+ * none
+ *
+ * PARAMETERS
+ * msg_id the message ID of the request message
+ *
+ * RETURNS
+ * The indicator of the operation is basic META mode operation cross any state (MODE_ENTRY_SRC)
+ *
+ *******************************************************************************/
+kal_bool FT_META_IsBasicOperation(kal_uint16 msg_id)
+{
+ return KAL_FALSE;
+}
diff --git a/mcu/middleware/meta/ft/src/ft_fnc.c b/mcu/middleware/meta/ft/src/ft_fnc.c
new file mode 100644
index 0000000..a75aac4
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc.c
@@ -0,0 +1,2505 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_r.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Factory testing function library
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+/*************************************************************************
+* Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#ifndef L1_SIM
+#include "task_config.h"
+#endif // #ifndef L1_SIM
+#include "svc_sap.h"
+#include "ft_msgid.h"
+/*************************************************************************
+* Include Statements for MAUI
+ *************************************************************************/
+/**************************************************************************
+ * System Service header
+ *************************************************************************/
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_public_defs.h"
+#include "string.h"
+#ifndef L1_SIM
+#include "fs_type.h"
+#include "fs_func.h"
+#include "fs_errcode.h"
+#endif // #ifndef L1_SIM
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#ifndef L1_SIM
+#include "init.h"
+#endif // #ifndef L1_SIM
+/**************************************************************************
+ * HAL header
+ *************************************************************************/
+#ifndef L1_SIM
+#include "dcl.h"
+#include "drv_comm.h"
+#include "l1audio.h"
+// include the device.h for the GPIO_DEV_LED_KEY definition
+// (Baseband tool LED, vibrator definitions)
+#include "device.h"
+#endif // #ifndef L1_SIM
+#include "tst_hal_internal_wrapper_defs.h"
+/**************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_public.h"
+#include "ft_private.h"
+#ifndef L1_SIM
+#include "ft_fnc_misc.h"
+#endif //#ifndef L1_SIM
+#include "ft_fnc_l1rf.h"
+#include "ft_fnc_wcdma.h"
+/**************************************************************************
+ * custom header
+ *************************************************************************/
+#ifndef L1_SIM
+#include "meta_customize.h"
+#include "custom_em.h"
+//#include "usb_custom.h"
+#include "custom_equipment.h"
+#endif // #ifndef L1_SIM
+/**************************************************************************
+ * UL1 RF header
+ *************************************************************************/
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#include "ul1cal.h"
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+//MSBB remove #include "fctycomp_config.h"
+/**************************************************************************
+ * NVRAM header
+ *************************************************************************/
+#ifndef L1_SIM
+#include "nvram_data_items.h"
+#include "ft_nvram_def.h"
+#endif // #ifndef L1_SIM
+/**************************************************************************
+ * audio (MED) header
+ *************************************************************************/
+#ifndef MED_NOT_PRESENT
+#include "aud_defs.h"
+#include "med_struct.h"
+#endif // MED_NOT_PRESENT
+#include "tst_def.h"
+/**************************************************************************
+ * SLA header
+ *************************************************************************/
+#include "meta_sec_support.h"
+/*************************************************************************
+ * Non-MODEM BSP
+ *************************************************************************/
+kal_uint32 ft_event_group_ptr; /**< \brief ft event group pointer */
+
+extern kal_bool Drv_ReadReg(kal_uint32 addr, kal_uint16 *data);
+extern kal_bool Drv_WriteReg(kal_uint32 addr, kal_uint16 data);
+extern void tst_log_primitive_without_filter_check(ilm_struct*,
+ kal_uint8,
+ kal_uint32);
+extern void dhl_FT_log_primitive(ilm_struct *ilm);
+/*******************************************************************************
+ *
+ * Utility Functions
+ *
+ *******************************************************************************/
+void _FT_ALLOC_MSG(ilm_struct* ilm_ptr, kal_uint16 size, kal_bool IsFtMsg, kal_bool IsCcMsg)
+{
+ if( ilm_ptr == NULL )
+ {
+ ASSERT(0); // assert it!
+ }
+
+ ilm_ptr->local_para_ptr = NULL;
+ ilm_ptr->peer_buff_ptr = NULL;
+ if( 0 < size ) {
+ if( KAL_TRUE == IsCcMsg ) {
+ if( NULL == (ilm_ptr->local_para_ptr=construct_cc_non_cached_local_para(size, TD_RESET)) ) {
+ ASSERT(0); // assert it!
+ }
+ }
+ else {
+ if( NULL == (ilm_ptr->local_para_ptr=construct_local_para(size, TD_RESET)) ) {
+ ASSERT(0); // assert it!
+ }
+ }
+ }
+ if( KAL_TRUE == IsFtMsg ) {
+ // reset content of FT primitive first
+ if(size > sizeof(FT_H) && NULL != ((char *)ilm_ptr->local_para_ptr)+sizeof(FT_H))
+ {
+ kal_mem_set(((char *)ilm_ptr->local_para_ptr)+sizeof(FT_H), 0, size-sizeof(FT_H));
+ }
+ }
+}
+
+void _FT_CONSTRUCT_CC_MSG(const ilm_struct* ilm_ptr, ilm_struct* ilm_cc_ptr)
+{
+ if(ilm_ptr == NULL || ilm_cc_ptr == NULL)
+ {
+ ASSERT(0);
+ }
+ _FT_ALLOC_MSG(ilm_cc_ptr, ilm_ptr->local_para_ptr->msg_len, KAL_FALSE, KAL_TRUE);
+ kal_mem_cpy(ilm_cc_ptr->local_para_ptr, ilm_ptr->local_para_ptr, ilm_ptr->local_para_ptr->msg_len);
+ if( ilm_ptr->peer_buff_ptr != NULL )
+ {
+ kal_uint8 *pdu_ptr, *pdu_cc_ptr;
+ kal_uint16 size;
+ if( NULL == (ilm_cc_ptr->peer_buff_ptr=construct_cc_non_cached_peer_buff(ilm_ptr->peer_buff_ptr->pdu_len,
+ 0,
+ 0,
+ TD_RESET)) ) {
+ ASSERT(0); // assert it!
+ }
+ pdu_ptr = (kal_uint8*) get_peer_buff_pdu(ilm_ptr->peer_buff_ptr, &size);
+ pdu_cc_ptr = (kal_uint8*) get_peer_buff_pdu(ilm_cc_ptr->peer_buff_ptr, &size);
+ kal_mem_cpy(pdu_cc_ptr, pdu_ptr, size);
+ }
+}
+
+void _FT_SendFtMsgToPcByToken(ilm_struct *ilm_ptr, kal_uint16 token)
+{
+#if !defined(__DHL_MODULE__)
+ _FT_SendFtMsgByToken(MOD_FT, MOD_TST, FT_TST_SAP, MSG_ID_FT_TO_TST, ilm_ptr, token);
+#else
+ _FT_SendFtMsgByToken(MOD_FT, MOD_DHL, FT_TST_SAP, MSG_ID_FT_TO_TST, ilm_ptr, token);
+#endif // #if !defined(__DHL_MODULE__)
+}
+
+void _FT_SendFtMsgByToken(module_type src_mod, module_type dest_mod, sap_type sap, msg_type msg, ilm_struct *ilm_ptr, kal_uint16 token)
+{
+ ilm_ptr->src_mod_id = src_mod;
+ ilm_ptr->dest_mod_id = dest_mod;
+ ilm_ptr->msg_id = msg;
+ ilm_ptr->sap_id = sap;
+#if !defined(__DHL_MODULE__)
+ if (dest_mod == MOD_TST) {
+#else
+ if (dest_mod == MOD_DHL) {
+#endif // #if !defined(__DHL_MODULE__)
+ ((FT_H *)(ilm_ptr->local_para_ptr))->token=token;
+ tst_log_primitive(ilm_ptr);
+ ilm_ptr->src_mod_id = (module_type)0xA1;
+ ilm_ptr->dest_mod_id = (module_type)0;
+ ilm_ptr->sap_id = (sap_type)0xA3;
+ ilm_ptr->msg_id = (msg_type)2;
+#if !defined(__DHL_MODULE__)
+ // directly copy primitive to TST ring buffer
+ tst_log_primitive_without_filter_check(
+ ilm_ptr,
+ RS232_LOGGED_PRIMITIVE_TYPE,
+ MSG_ID_LOGGED_PRIMITIVE);
+#else
+ dhl_FT_log_primitive(ilm_ptr);
+#endif // #if !defined(__DHL_MODULE__)
+ // cancel ilm, because we directly access TST ring buffer, no need to send primitive to TST
+ destroy_ilm(ilm_ptr);
+ return;
+ }
+ msg_send6(src_mod, dest_mod, sap, msg, ilm_ptr->local_para_ptr, ilm_ptr->peer_buff_ptr);
+}
+
+void FT_SendDeniedMsgIdCnf(kal_uint16 deniedMsgId, kal_uint32 status)
+{
+ ilm_struct ilm_ptr;
+ FT_DENIED_MSG_ID_CNF *ft_cnf;
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_DENIED_MSG_ID_CNF));
+ ft_cnf = (FT_DENIED_MSG_ID_CNF *)ilm_ptr.local_para_ptr;
+ ft_cnf->header.ft_msg_id = FT_CMD_DENIED_CNF_ID;
+ ft_cnf->deniedMsgId = deniedMsgId;
+ ft_cnf->status = status;
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+/*******************************************************************************
+ *
+ * FT Module Initialization Functions
+ *
+ *******************************************************************************/
+/*******************************************************************************
+ * FUNCTION
+ * FT_InitFtData
+ *
+ * DESCRIPTION
+ *
+ * CALLS
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ *******************************************************************************/
+#ifndef L1_SIM
+extern kal_int8 FT_FAT_Handle_Clear(void);
+#endif //#ifndef L1_SIM
+void FT_InitFtData()
+{
+#ifndef L1_SIM
+ FT_FAT_Handle_Clear();
+#endif //#ifndef L1_SIM
+ // init event group
+ ft_event_group_ptr = (kal_uint32) kal_create_event_group("FtEvent");
+}
+#ifndef L1_SIM
+/**
+ * This function calls Dcl PMU interface to read PMIC register
+ * @register_index the index of the register to be written
+ */
+kal_bool ft_pmic_reg_read(kal_uint16 *data, kal_uint16 register_index)
+{
+ kal_bool status;
+ DCL_HANDLE handle;
+ PMU_CTRL_MISC_GET_REGISTER_VALUE val;
+ val.offset=register_index;
+ handle=DclPMU_Open(DCL_PMU, FLAGS_NONE);
+ if(DclPMU_Control(handle, MISC_GET_REGISTER_VALUE, (DCL_CTRL_DATA_T *)&val) != STATUS_OK)
+ {
+ // in this case, there might be not supported (if the driver did not support yet, usually in development phase)
+ status = KAL_FALSE;
+ }
+ else
+ {
+ status = KAL_TRUE;
+ }
+ DclPMU_Close(handle);
+ *data = val.value;
+ return status;
+}
+/**
+ * This function calls Dcl PMU interface to read PMIC register
+ * @param data the register value to be written to PMIC
+ * @param register_index the index of the register to be written
+ */
+kal_bool ft_pmic_reg_write(kal_uint16 data, kal_uint16 register_index)
+{
+ kal_bool status;
+ DCL_HANDLE handle;
+ PMU_CTRL_MISC_SET_REGISTER_VALUE val;
+ val.offset=register_index;
+ val.value=data;
+ handle=DclPMU_Open(DCL_PMU, FLAGS_NONE);
+ if(DclPMU_Control(handle, MISC_SET_REGISTER_VALUE, (DCL_CTRL_DATA_T *)&val) != STATUS_OK)
+ {
+ // in this case, there might be not supported (if the driver did not support yet, usually in development phase)
+ status = KAL_FALSE;
+ }
+ else
+ {
+ status = KAL_TRUE;
+ }
+ DclPMU_Close(handle);
+ return status;
+}
+/**
+ * This function handles the PMIC register read operation
+ * @param req FT task PMIC register read request
+ * @param Regtype register type
+ */
+void FT_FtPMICRegisterRead(ft_PMICRegisterRead_req_T* req,unsigned char RegType) // for build warning
+{
+ ilm_struct ilm_ptr;
+ ft_PMICRegisterRead_cnf_T* ptrMsg;
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_PMICRegisterRead_cnf_T));
+ ptrMsg = (ft_PMICRegisterRead_cnf_T *)ilm_ptr.local_para_ptr;
+ ptrMsg->status = KAL_FALSE;
+ if(RegType ==FT_PMICReg)
+ {
+ ptrMsg->header.ft_msg_id = FT_PMIC_REG_READ_CNF_ID;
+ /*
+ * Note: The custom_pmic_reg_read interface is changed due to HAL,
+ * the reference is changed to ft_pmic_reg_read
+ */
+ ptrMsg->status = ft_pmic_reg_read(&(ptrMsg->value), (kal_uint16)req->addr);
+ }
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+/**
+ * This function handles the PMIC register write operation
+ * @param req FT task PMIC register write request
+ * @param Regtype register type
+ */
+void FT_FtPMICRegisterWrite(ft_PMICRegisterWrite_req_T* req,unsigned char RegType)
+{
+ ilm_struct ilm_ptr;
+ ft_PMICRegisterWrite_cnf_T *ptrMsg ;
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_PMICRegisterWrite_cnf_T));
+ ptrMsg = (ft_PMICRegisterWrite_cnf_T *)ilm_ptr.local_para_ptr;
+ ptrMsg->status = KAL_FALSE;
+ if(RegType ==FT_PMICReg)
+ {
+ ptrMsg->header.ft_msg_id = FT_PMIC_REG_WRITE_CNF_ID;
+ /*
+ * Note: The custom_pmic_reg_write interface is changed due to HAL,
+ * the reference is changed to ft_pmic_reg_write
+ */
+ ptrMsg->status = ft_pmic_reg_write(req->value, (kal_uint16)req->addr);
+ }
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+/*******************************************************************************
+ * FUNCTION
+ * FT_FtRegisterRead()
+ *
+ * DESCRIPTION
+ * Handle the request of reading Register Req
+ *
+ * CALLS
+ * Drv_ReadReg(.)
+ *
+ * PARAMETERS
+ * *req
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_FtRegisterRead(ft_RegisterRead_req_T* req,unsigned char RegType)
+{
+ kal_uint8 status;
+ ilm_struct ilm_ptr;
+ ft_RegisterRead_cnf_T* ptrMsg;
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_RegisterRead_cnf_T));
+ /* if ptrMsg != NULL*/
+ ptrMsg = (ft_RegisterRead_cnf_T *)ilm_ptr.local_para_ptr;
+ status = KAL_FALSE; // for build warning
+ if(RegType ==FT_BaseBandReg)
+ {
+ ptrMsg->header.ft_msg_id = FT_REG_READ_CNF_ID;
+ status=Drv_ReadReg(req->addr,&ptrMsg->value);
+ }
+ if(status==KAL_TRUE)
+ { status=FT_CNF_OK; }
+ else
+ { status=FT_CNF_FAIL; }
+ ptrMsg->status = status;
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+
+/*******************************************************************************
+ * FUNCTION
+ * FT_FtRegisterWrite()
+ *
+ * DESCRIPTION
+ * Handle the request of Writing Register Req
+ *
+ * CALLS
+ * Drv_WriteReg(.)
+ *
+ * PARAMETERS
+ * *req
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_FtRegisterWrite(ft_RegisterWrite_req_T* req,unsigned char RegType)
+{
+ kal_uint8 status;
+ ilm_struct ilm_ptr;
+ ft_RegisterWrite_cnf_T *ptrMsg ;
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_RegisterWrite_cnf_T));
+ status = KAL_FALSE; // for build warning
+ /* if ptrMsg != NULL*/
+ ptrMsg = (ft_RegisterWrite_cnf_T *)ilm_ptr.local_para_ptr;
+ if(RegType ==FT_BaseBandReg)
+ {
+ ptrMsg->header.ft_msg_id = FT_REG_WRITE_CNF_ID;
+ status=Drv_WriteReg(req->addr,req->value);
+ }
+ if(status==KAL_TRUE)
+ { status=FT_CNF_OK; }
+ else
+ { status=FT_CNF_FAIL; }
+ ptrMsg->status = status;
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+/*******************************************************************************
+ * FUNCTION
+ * FT_FtADC_GetMeaData()
+ *
+ * DESCRIPTION
+ * Handle the request of Getting MeaData
+ *
+ * CALLS
+ * ADC_GetData2Meta(.)
+ *
+ * PARAMETERS
+ * *req
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_FtADC_GetMeaData(ft_FtADC_GetMeaData_req_T* req)
+{
+ ilm_struct ilm_ptr;
+ ft_FtADC_GetMeaData_cnf_T *ptrMsg ;
+ ADC_CTRL_GET_DATA_2_META_T data2meta;
+ DCL_HANDLE adc_handle;
+ memset(&data2meta, 0, sizeof(ADC_CTRL_GET_DATA_2_META_T));
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_FtADC_GetMeaData_cnf_T));
+ ptrMsg = (ft_FtADC_GetMeaData_cnf_T *)ilm_ptr.local_para_ptr;
+ ptrMsg->status=FT_CNF_OK;
+ ptrMsg->header.ft_msg_id = FT_ADC_GETMEADATA_CNF_ID;
+ adc_handle = DclHADC_Open(DCL_ADC, FLAGS_NONE);
+ data2meta.u1Channel = req->Sel;
+ data2meta.u2MeaCount = req->Meacount;
+ if(DclHADC_Control(adc_handle, ADC_CMD_GET_DATA_2_META, (DCL_CTRL_DATA_T *)& data2meta) != STATUS_OK)
+ {
+ ptrMsg->status = FT_CNF_FAIL;
+ }
+ ptrMsg->value = data2meta.u4ADCData;
+ if(DclHADC_Close(adc_handle) != STATUS_OK)
+ {
+ ptrMsg->status = FT_CNF_FAIL;
+ }
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+#endif // #ifndef L1_SIM
+/*******************************************************************************
+ *
+ * Version Info functionality
+ *
+ *******************************************************************************/
+void FT_GetVersionInfo(void) {
+
+ ilm_struct ilm_ptr;
+ FT_VER_INFO_CNF *ptrMsg;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_VER_INFO_CNF));
+ // if ptrMsg != NULL
+ ptrMsg = (FT_VER_INFO_CNF *)ilm_ptr.local_para_ptr;
+ // assign primitive id
+ ptrMsg->header.ft_msg_id = FT_VER_INFO_CNF_ID;
+
+ #ifndef L1_SIM
+ version_struct ver_struct;
+ memset(&ver_struct, 0, sizeof(version_struct));
+
+ // get version info
+ INT_VersionNumbers(&ver_struct);
+ // check
+ if( NULL == ver_struct.bb_chip ) {
+ ver_struct.bb_chip = "Unknown";
+ }
+ if( NULL == ver_struct.dsp_fw ) {
+ ver_struct.dsp_fw = "Unknown";
+ }
+ if( NULL == ver_struct.dsp_ptch ) {
+ ver_struct.dsp_ptch = "Unknown";
+ }
+ if( NULL == ver_struct.mcu_sw ) {
+ ver_struct.mcu_sw = "Unknown";
+ }
+ if( NULL == ver_struct.bb_board ) {
+ ver_struct.bb_board = "Unknown";
+ }
+ if( NULL == ver_struct.mcu_sw_flavor ) {
+ ver_struct.mcu_sw_flavor = "Unknown";
+ }
+ // assign BaseBand chip version string
+ strncpy((kal_char *)ptrMsg->bb_chip, ver_struct.bb_chip, 64);
+ // assign ECO version
+ kal_mem_set(ptrMsg->eco_ver, 0, 4);
+ // assign DSP firmware version string
+ strncpy((kal_char *)ptrMsg->dsp_fw, ver_struct.dsp_fw, 64);
+ // assign DSP patch version string
+ strncpy((kal_char *)ptrMsg->dsp_patch, ver_struct.dsp_ptch, 64);
+ // assign S/W version string
+ strncpy((kal_char *)ptrMsg->sw_ver, ver_struct.mcu_sw, 64);
+ // assign H/W version string
+ strncpy((kal_char *)ptrMsg->hw_ver, ver_struct.bb_board, 64);
+ // assign Melody version string
+ strncpy((kal_char *)ptrMsg->melody_ver, "Unknown", 64);
+ // assign S/W flavor version string
+ strncpy((kal_char *)ptrMsg->sw_flavor, ver_struct.mcu_sw_flavor, 64);
+#else // #ifndef L1_SIM
+ strcpy((kal_char *)ptrMsg->bb_chip, "Unknown");
+ kal_mem_set(ptrMsg->eco_ver, 0, 4);
+ kal_mem_set(ptrMsg->dsp_fw, 0, 64);
+ kal_mem_set(ptrMsg->dsp_patch, 0, 64);
+ strcpy((kal_char *)ptrMsg->sw_ver, "xl1 Sim");
+ kal_mem_set(ptrMsg->hw_ver, 0, 64);
+ kal_mem_set(ptrMsg->melody_ver, 0, 64);
+ strcpy((kal_char *)ptrMsg->sw_flavor, "Unknown");
+#endif // #ifdef L1_SIM
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+/*******************************************************************************
+ *
+ * FT task test alive
+ *
+ *******************************************************************************/
+void FT_TestAlive(void) {
+
+ FT_IS_ALIVE_CNF *pMsg;
+ ilm_struct ilm_ptr;
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_IS_ALIVE_CNF));
+ pMsg=(FT_IS_ALIVE_CNF *)ilm_ptr.local_para_ptr;
+ pMsg->header.ft_msg_id = FT_IS_ALIVE_CNF_ID;
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+#ifndef L1_SIM
+/**
+ * This api calls the DCL interface to check and clear the PDN1 bit 7 set by flashtool
+ * and scrambles theh powerkey1
+ */
+ #if (!defined(__SMART_PHONE_MODEM__))
+static kal_bool FT_ClearPowerKey(void)
+{
+ /// Driver RTC FT Power Off request
+ RTC_CTRL_FT_POWEROFF_T ft_cmd_data;
+ DCL_HANDLE rtc_handle = DclRTC_Open(DCL_RTC, FLAGS_NONE);
+ memset(&ft_cmd_data, 0, sizeof(RTC_CTRL_FT_POWEROFF_T));
+ DclRTC_Control(rtc_handle, RTC_CMD_FT_POWEROFF, (DCL_CTRL_DATA_T *) &ft_cmd_data);
+ DclRTC_Close(rtc_handle);
+ return (kal_bool)ft_cmd_data.fgMetaReset;
+}
+ #endif
+/*******************************************************************************
+ *
+ * FUNCTION
+ * FT_PowerOff
+ *
+ * DESCRIPTION
+ * Power off sequence in META mode
+ *
+ * CALLS
+ * custom_ft_util_check_if_usb_enable_support for check the USB_ENABLE compile option
+ * USB_PowerControl
+ * DclRTC_Open/DclRTC_Control (RTC_CMD_FT_POWEROFF command)/DclRTC_Close for RTC power off sequence (scramble PDN1 bit 7 for flashtool entering META mode)
+ * DclPW_Open/DclPW_Control (PW_CMD_POWEROFF command)/DclPW_Close for Driver power off sequence
+ * DclWDT_Open/DclWDT_Control (WDT_CMD_DRV_RESET command)/DclWDT_Close for Driver reset sequence
+ *
+ * PARAMETERS
+ * void
+ *
+ * RETURNS
+ * void
+ *
+ * GLOBALS AFFECTED
+ * N/A
+ *
+ *******************************************************************************/
+void FT_PowerOff(void)
+{
+#if (!defined(__SMART_PHONE_MODEM__))
+ if(KAL_TRUE == custom_ft_util_check_if_usb_enable_support())
+ {
+ // shutdown USB module
+ /**
+ * USB_PowerControl(KAL_FALSE) is no longer
+ * to disable the usb power anymore.
+ **/
+ }
+ Custom_META_USBVirtualComDisconnect();
+ FT_ClearPowerKey();
+#endif // #if (!defined(__SMART_PHONE_MODEM__))
+}
+#endif // #ifndef L1_SIM
+#ifndef L1_SIM
+/***********************************************
+ * FT task self message API
+ * This API is called in other task context
+ * or HISR conext!
+ **********************************************/
+void ft_send_in_proc_call_req(ft_in_proc_call_type func, kal_uint32 func_arg1, void *func_arg2)
+{
+ ft_in_proc_call_req_struct *ptrMsg;
+ ptrMsg = (ft_in_proc_call_req_struct *)construct_local_para(sizeof(ft_in_proc_call_req_struct), TD_RESET);
+ if(NULL == ptrMsg)
+ {
+ ASSERT(0);
+ }
+ ptrMsg->func = func;
+ ptrMsg->func_arg1 = func_arg1;
+ ptrMsg->func_arg2 = func_arg2;
+ msg_send5(kal_get_active_module_id(), MOD_FT, FT_TST_SAP, (msg_type)MSG_ID_FT_IN_PROC_CALL_REQ, (local_para_struct*)ptrMsg);
+}
+/***********************************************
+ * FT task self message (In Proc Call handler)
+ **********************************************/
+void ft_in_proc_call_handler(ilm_struct *ilm_ptr)
+{
+ /*----------------------------------------------------------------*/
+ /* Local Variables */
+ /*----------------------------------------------------------------*/
+ ft_in_proc_call_req_struct *ptrMsg = (ft_in_proc_call_req_struct*) ilm_ptr->local_para_ptr;
+
+ /*----------------------------------------------------------------*/
+ /* Code Body */
+ /*----------------------------------------------------------------*/
+ ASSERT(ptrMsg->func != NULL);
+ ptrMsg->func(ptrMsg->func_arg1, ptrMsg->func_arg2);
+}
+
+
+/*******************************************************************************
+ *
+ * SLA functionality
+ *
+ *******************************************************************************/
+kal_bool FT_MetaSLA_Is_Enabled(void)
+{
+ return MetaSLA_Is_Enabled();
+}
+
+void FT_GetSlaStatus(void)
+{
+ ilm_struct ilm_ptr;
+ FT_GET_SLA_STATUS_CNF *ptrMsg;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_GET_SLA_STATUS_CNF));
+ // if ptrMsg != NULL
+ ptrMsg = (FT_GET_SLA_STATUS_CNF *)ilm_ptr.local_para_ptr;
+ // assign primitive id
+ ptrMsg->header.ft_msg_id = FT_GET_SLA_STATUS_CNF_ID;
+ ptrMsg->sla_config = (kal_uint16) FT_MetaSLA_Is_Enabled();
+ ptrMsg->sla_verified= (kal_uint16) MetaSLA_Is_Verified();
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+extern kal_uint16 Custom_META_CheckSlaVer(kal_uint32 sla_ver_from_pc);
+void FT_CheckSlaVer(FT_CHECK_SLA_VER_REQ *ft_check_sla_ver_op)
+{
+ ilm_struct ilm_ptr;
+ FT_CHECK_SLA_VER_CNF *ptrMsg;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_CHECK_SLA_VER_CNF));
+ // if ptrMsg != NULL
+ ptrMsg = (FT_CHECK_SLA_VER_CNF *)ilm_ptr.local_para_ptr;
+ // assign primitive id
+ ptrMsg->header.ft_msg_id = FT_CHECK_SLA_VER_CNF_ID;
+ ptrMsg->status = Custom_META_CheckSlaVer(ft_check_sla_ver_op->sla_ver_from_pc);
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+extern kal_bool Custom_META_GetSlaPara(kal_uint8* para, kal_uint32 para_len);
+void FT_GetSlaPara(void)
+{
+ ilm_struct ilm_ptr;
+ FT_GET_SLA_PARA_CNF *ptrMsg;
+ kal_uint8 para[META_SLA_RND_LEN];
+ kal_uint32 ret = 0;
+ kal_uint8 cust_para[256];
+ kal_bool bRet = 0;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_GET_SLA_PARA_CNF));
+
+ ptrMsg = (FT_GET_SLA_PARA_CNF *)ilm_ptr.local_para_ptr;
+ ptrMsg->header.ft_msg_id = FT_GET_SLA_PARA_CNF_ID;
+
+ if (META_SLA_RND_LEN > RND_BUF_LEN)
+ {
+ // ft message buffer is not enough
+ ptrMsg->status = FT_CNF_FAIL;
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+ return;
+ }
+
+ kal_mem_set(para, 0, META_SLA_RND_LEN);
+
+ ret = MetaSLA_Rnd_Gen(para, RND_BUF_LEN);
+ if (0 == ret)
+ {
+ kal_mem_cpy(ptrMsg->rand_num, para, META_SLA_RND_LEN);
+ ptrMsg->rand_num_len = META_SLA_RND_LEN;
+ }
+ else
+ {
+ ptrMsg->status = ret;
+ ptrMsg->rand_num_len = 0;
+ }
+
+ bRet = Custom_META_GetSlaPara(cust_para, 256);
+ if (true == bRet)
+ {
+ kal_mem_cpy(ptrMsg->cust_para, cust_para, 256);
+ }
+ else
+ {
+ ptrMsg->status = -1;
+ }
+
+ if (ret == 0 && bRet == true)
+ {
+ ptrMsg->status = FT_CNF_OK;
+ }
+
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+void FT_VerifySla(FT_VERIFY_SLA_RND_REQ *ft_verify_sla_op)
+{
+ ilm_struct ilm_ptr;
+ FT_VERIFY_SLA_RND_CNF *ptrMsg;
+ kal_uint32 ret = 0;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_VERIFY_SLA_RND_CNF));
+
+ ptrMsg = (FT_VERIFY_SLA_RND_CNF *)ilm_ptr.local_para_ptr;
+ ptrMsg->header.ft_msg_id = FT_VERIFY_SLA_RND_CNF_ID;
+
+ ret = MetaSLA_Rnd_Verify(ft_verify_sla_op->encrypted, ft_verify_sla_op->encrypted_len);
+ if (ret == 0)
+ {
+ if (FT_MetaSLA_Is_Enabled())
+ {
+ ptrMsg->status = FT_CNF_OK;
+ }
+ else
+ {
+ ptrMsg->status = -1;
+ }
+ }
+ else
+ {
+ ptrMsg->status = ret;
+ }
+
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+#endif // #ifndef L1_SIM
+
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_aux.c b/mcu/middleware/meta/ft/src/ft_fnc_aux.c
new file mode 100644
index 0000000..dca6dad
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_aux.c
@@ -0,0 +1,200 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_aux.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Auxiliary Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+
+#include "md_mw_sap.h"
+#include "svc_sap.h"
+#include "ft_msgid.h"
+
+#ifdef __MTK_TARGET__
+#include <stdio.h>
+
+#endif
+
+/*************************************************************************
+ * Include Statements for MAUI
+ *************************************************************************/
+
+#include "fta_msg.h"
+#include "ft_private.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_public_defs.h"
+
+void FT_Aux_Operation(ilm_struct *ptrMsg)
+{
+ ilm_struct ilm_ptr;
+ kal_uint16 pdu_length;
+ kal_uint8 *pdu_ptr = NULL;
+ //peer_buff_struct *p_peer_buff_ptr;
+ // for debug
+
+ kal_uint16 pdu_length_new;
+ kal_uint8 *pdu_ptr_new;
+ peer_buff_struct *peer_buff_new;
+
+ FT_AUX_REQ *p_req = (FT_AUX_REQ *)ptrMsg->local_para_ptr;
+
+ if(ptrMsg->peer_buff_ptr == NULL) // do nothing
+ return;
+
+ switch(p_req->type)
+ {
+ case FT_AUX_OP_BASIC:
+ {
+
+ pdu_ptr = get_peer_buff_pdu( ptrMsg->peer_buff_ptr, &pdu_length );
+
+ // construct a peer buffer to send to NVRAM
+ if( NULL != (peer_buff_new=construct_peer_buff(pdu_length, 0, 0, TD_CTRL)) )
+ {
+ pdu_ptr_new = get_peer_buff_pdu( peer_buff_new, &pdu_length_new );
+ kal_mem_cpy(pdu_ptr_new, pdu_ptr, pdu_length);
+ peer_buff_new->pdu_len = pdu_length;
+ }
+ FT_ALLOC_OTHER_MSG(&ilm_ptr, sizeof(fta_basic_req_struct) );
+ ilm_ptr.peer_buff_ptr = peer_buff_new;
+
+ FT_SEND_MSG(MOD_FT, MOD_FTA, FT_FTA_SAP , (msg_type)MSG_ID_FTA_BASIC_REQ, &ilm_ptr);
+
+ peer_buff_new=NULL;/* make sure FTA will release the mem*/
+
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void FT_Handle_FTA_CNF(ilm_struct *ptrMsg)
+{
+ ilm_struct ilm_ptr;
+ FT_AUX_CNF *ptrMsg2; // send back to PC
+
+ switch (ptrMsg->msg_id)
+ {
+ case MSG_ID_FTA_BASIC_CNF:
+ {
+ fta_basic_cnf_struct *tmp_local_para = NULL; // from FTA Task
+ tmp_local_para = (fta_basic_cnf_struct*)ptrMsg->local_para_ptr;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_AUX_CNF) );
+
+ ilm_ptr.peer_buff_ptr = ptrMsg->peer_buff_ptr;
+ ptrMsg2 = (FT_AUX_CNF*)ilm_ptr.local_para_ptr;
+
+ ptrMsg2->header.ft_msg_id = FT_AUX_CNF_ID;
+ ptrMsg2->type = FT_AUX_OP_BASIC;
+ ptrMsg2->status = tmp_local_para->status; //FTA_CNF_OK;
+ break;
+ }
+ default:
+ return;
+
+ }
+ // send confirm to PC
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+
+#endif // end of #if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_c2krf.c b/mcu/middleware/meta/ft/src/ft_fnc_c2krf.c
new file mode 100644
index 0000000..5a911ff
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_c2krf.c
@@ -0,0 +1,109 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2016
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2016
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_c2krf.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Factory testing function for C2K
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#if defined(__C2K_RAT__)
+/*************************************************************************
+* Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h"
+#include "svc_sap.h"
+#include "tst_msgid.h"
+#include "ft_msgid.h"
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_c2krf.h"
+
+/**
+ * @param metaMessage the input message from META tool for CRF test command processing
+ */
+void FT_Crf_Operation(ilm_struct* ptrMsg)
+{
+ ilm_struct crfMessage;
+ FT_CONSTRUCT_CC_MSG(ptrMsg, &crfMessage);
+ FT_SEND_MSG(MOD_FT, MOD_CL1TST, DHL_CL1TST_SAP, MSG_ID_DHL_TO_CL1TST, &crfMessage);
+}
+
+/**
+ * Confirm message handler for MOD_CL1TST
+ */
+void FT_Crf_ConfirmHandler(ilm_struct* crfMessage)
+{
+ FT_SEND_MSG_TO_PC(crfMessage);
+}
+
+#endif // #if defined(__C2K_RAT__)
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_custom.c b/mcu/middleware/meta/ft/src/ft_fnc_custom.c
new file mode 100644
index 0000000..0f5d054
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_custom.c
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_custom.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Misc Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "md_mw_sap.h"
+#include "svc_sap.h"
+#include "ft_msgid.h"
+#include "nvram_msgid.h"
+#ifdef __MTK_TARGET__
+#include <stdio.h>
+#endif
+/*************************************************************************
+ * Include Statements for MAUI
+ *************************************************************************/
+#include "ftc_msg.h"
+#include "ft_private.h"
+#include "kal_public_api.h"
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+void FT_Custom_Operation(ilm_struct *ptrMsg)
+{
+ ilm_struct ilm_ptr;
+ FT_CUSTOMER_REQ *p_req = (FT_CUSTOMER_REQ *)ptrMsg->local_para_ptr;
+ if(ptrMsg->peer_buff_ptr == NULL)
+ {
+ return;
+ }
+ switch(p_req->type)
+ {
+ case FT_CUSTOMER_OP_BASIC:
+ {
+ FT_ALLOC_OTHER_MSG(&ilm_ptr, sizeof(ftc_basic_req_struct));
+ ilm_ptr.peer_buff_ptr = ptrMsg->peer_buff_ptr;
+ /* hold this peer buffer so that we don't need to duplicate the buffer */
+ hold_peer_buff(ptrMsg->peer_buff_ptr);
+ FT_SEND_MSG(MOD_FT, MOD_FTC, FT_FTC_SAP , (msg_type)MSG_ID_FTC_BASIC_REQ, &ilm_ptr);
+ break;
+ }
+ default:
+ break;
+ }
+}
+void FT_Handle_FTC_CNF(ilm_struct *ptrMsg)
+{
+ ilm_struct ilm_ptr;
+ FT_CUSTOMER_CNF *ptrMsg2;
+ switch (ptrMsg->msg_id)
+ {
+ case MSG_ID_FTC_BASIC_CNF:
+ {
+ ftc_basic_cnf_struct *tmp_local_para = NULL;
+ tmp_local_para = (ftc_basic_cnf_struct*)ptrMsg->local_para_ptr;
+
+ FT_ALLOC_MSG(&ilm_ptr ,sizeof(FT_CUSTOMER_CNF));
+
+ ilm_ptr.peer_buff_ptr = ptrMsg->peer_buff_ptr;
+ ptrMsg2 = (FT_CUSTOMER_CNF*)ilm_ptr.local_para_ptr;
+
+ ptrMsg2->header.ft_msg_id = FT_CUSTOM_CNF_ID;
+ ptrMsg2->type = FT_CUSTOMER_OP_BASIC;
+ ptrMsg2->status = tmp_local_para->status;
+ break;
+ }
+ default:
+ return;
+ }
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_fat.c b/mcu/middleware/meta/ft/src/ft_fnc_fat.c
new file mode 100644
index 0000000..5b0e9d5
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_fat.c
@@ -0,0 +1,1400 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_fat.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT FAT operations
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_fat.h"
+#include "svc_sap.h"
+#include "ft_msgid.h"
+/*************************************************************************
+ * NVRAM header
+ *************************************************************************/
+#include "nvram_interface.h"
+#include "fs_gprot.h"
+/*******************************************************************************
+ *
+ * Dynamic allocated stack
+ *
+ *******************************************************************************/
+#define FT_STACK_MAGIC 12345
+
+typedef void (*FT_STACK_RELEASE_CALLBACK)(void *data, void *usr_arg);
+
+typedef struct {
+ kal_uint8 *stack; // used to remember the FindNext calling times,not FS_HANDLE
+
+ kal_uint16 max_node_size;
+ kal_uint16 max_depth;
+ kal_uint16 depth; // 1 ~ N , 0 -> empty
+
+ kal_uint16 magic; // used to mark if the stack is created or not.
+
+}ft_stack_handle;
+
+kal_uint8 ft_stack_destroy(ft_stack_handle *p_ft_stack_hdl)
+{
+
+ if( NULL==p_ft_stack_hdl)
+ {
+ return 1;
+ }
+
+ // free buffer
+ free_ctrl_buffer(p_ft_stack_hdl->stack);
+ // reset
+ kal_mem_set(p_ft_stack_hdl, 0, sizeof(ft_stack_handle));
+
+ return 0;
+}
+
+kal_uint8 ft_stack_create(ft_stack_handle *p_ft_stack_hdl, kal_uint16 max_node_size, kal_uint16 max_depth) {
+
+ if( NULL==p_ft_stack_hdl || 0==max_node_size || 0==max_depth ) {
+ return 1;
+ }
+
+ // if un-release handle, destroy first
+ if( FT_STACK_MAGIC == p_ft_stack_hdl->magic ) {
+ if(ft_stack_destroy(p_ft_stack_hdl))
+ {
+ return 2;
+ }
+ }
+
+ // allocate memory
+ if( NULL == (p_ft_stack_hdl->stack=(kal_uint8 *)get_ctrl_buffer(max_node_size*max_depth)) ) {
+ return 2;
+ }
+
+ // initialize
+ p_ft_stack_hdl->max_node_size = max_node_size;
+ p_ft_stack_hdl->max_depth = max_depth;
+ p_ft_stack_hdl->depth = 0;
+ p_ft_stack_hdl->magic = FT_STACK_MAGIC;
+
+ return 0;
+}
+
+kal_uint8 ft_stack_push(ft_stack_handle *p_ft_stack_hdl, kal_uint16 cur_width) {
+
+ if( NULL==p_ft_stack_hdl || FT_STACK_MAGIC!=p_ft_stack_hdl->magic)
+ {
+ return 1;
+ }
+
+ /*
+ if( data_size > p_ft_stack_hdl->max_node_size ) {
+ return 2;
+ }
+ */
+ if( (p_ft_stack_hdl->depth+1) > p_ft_stack_hdl->max_depth ) {
+ return 3;
+ }
+
+ p_ft_stack_hdl->depth++;
+
+ //kal_mem_cpy(p_ft_stack_hdl->stack+p_ft_stack_hdl->max_node_size*(p_ft_stack_hdl->depth-1), data, data_size);
+
+ (*(p_ft_stack_hdl->stack+p_ft_stack_hdl->max_node_size*(p_ft_stack_hdl->depth-1))) = cur_width;
+ return 0;
+}
+
+kal_uint8 ft_stack_pop(ft_stack_handle *p_ft_stack_hdl, kal_uint16 *pWidth) {
+
+ if( NULL==p_ft_stack_hdl || FT_STACK_MAGIC!=p_ft_stack_hdl->magic || NULL == pWidth)
+ {
+ return 1;
+ }
+ /*
+ if( data_size > p_ft_stack_hdl->max_node_size ) {
+ return 2;
+ }
+ */
+ if( 1 > p_ft_stack_hdl->depth ) {
+ return 3;
+ }
+
+ //kal_mem_cpy(data, p_ft_stack_hdl->stack+p_ft_stack_hdl->max_node_size*(p_ft_stack_hdl->depth-1), data_size);
+ (*pWidth) = (*(p_ft_stack_hdl->stack+p_ft_stack_hdl->max_node_size*(p_ft_stack_hdl->depth-1)));
+
+ p_ft_stack_hdl->depth--;
+
+ return 0;
+}
+
+kal_uint16 ft_stack_get_cur_depth(ft_stack_handle *p_ft_stack_hdl) {
+ if( NULL==p_ft_stack_hdl || FT_STACK_MAGIC!=p_ft_stack_hdl->magic ) {
+ return 0;
+ }
+
+ return p_ft_stack_hdl->depth;
+}
+/*******************************************************************************
+ *
+ * FAT functionality
+ *
+ *******************************************************************************/
+#define FT_FAT_MAX_PEER_SIZE 2048
+#define FT_FAT_MAX_FRAME_SIZE FT_FAT_MAX_PEER_SIZE/64*56
+
+/**
+ * Get Disk free space
+ */
+kal_int32 FT_GetDiskFreeSpace(const WCHAR* pathname)
+{
+ FS_DiskInfo fs_diskinfo;
+ kal_int32 status;
+ kal_int32 cluster_size = FS_GetClusterSize(pathname[0]);
+ if(FS_DRIVE_NOT_FOUND == cluster_size)
+ {
+ return cluster_size;
+ }
+ if( (status=FS_GetDiskInfo(pathname, &fs_diskinfo, FS_DI_BASIC_INFO|FS_DI_FREE_SPACE)) < 0 )
+ {
+ return status;
+ }
+ return cluster_size * fs_diskinfo.FreeClusters;
+}
+kal_uint8 FT_FAT_SendCnf(FT_FAT_OPERATION *ft_fat_ret, peer_buff_struct *peer_buff) {
+
+ ilm_struct ilm_ptr;
+ FT_FAT_OPERATION *ptrMsg;
+
+ FT_ALLOC_MSG(&ilm_ptr,sizeof(FT_FAT_OPERATION));
+
+ /* if ptrMsg != NULL*/
+ ptrMsg = (FT_FAT_OPERATION *)ilm_ptr.local_para_ptr;
+
+ // assign primitive id
+ ptrMsg->header.ft_msg_id = FT_FAT_OPERATION_ID;
+
+ // assign return structure
+ ptrMsg->fs_handle = ft_fat_ret->fs_handle;
+ ptrMsg->fat_op = ft_fat_ret->fat_op;
+ ptrMsg->offset = ft_fat_ret->offset;
+ ptrMsg->last_frame = ft_fat_ret->last_frame;
+ ptrMsg->status = ft_fat_ret->status;
+
+ // assign peer buffer
+ if( NULL != peer_buff ) {
+ ilm_ptr.peer_buff_ptr = peer_buff;
+ }
+
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+ return 0;
+}
+
+WCHAR * ft_wstrnpbrk(const WCHAR *s, const WCHAR *char_set) {
+ const WCHAR *p;
+ kal_int32 char_set_len;
+ kal_int32 i;
+
+ if( NULL == s || NULL == char_set ) {
+ return NULL;
+ }
+
+ char_set_len = kal_wstrlen(char_set);
+ p = s;
+
+ while( 0 != *p ) {
+ for(i=0; i<char_set_len; i++) {
+ if( *p == char_set[i] ) {
+ break;
+ }
+ }
+ // if no char match in char_set
+ if( i == char_set_len ) {
+ return (WCHAR *)p;
+ }
+ p++;
+ }
+
+ return NULL;
+}
+
+WCHAR *ft_wstrichr(const WCHAR *s, int c)
+{
+ WCHAR tmp;
+
+ // to upper case
+ if( 0x61<=c && 0x7a>=c ) {
+ // a(0x61)~z(0x7a) --> A(0x41)~Z(0x5a)
+ c -= 0x20;
+ }
+
+ do
+ {
+ tmp = *s;
+
+ // to upper case
+ if( 0x61<=tmp && 0x7a>=tmp ) {
+ // a(0x61)~z(0x7a) --> A(0x41)~Z(0x5a)
+ tmp -= 0x20;
+ }
+
+ if (tmp == c)
+ return (WCHAR*)s;
+
+ } while (*s++);
+
+ return (0);
+}
+
+/*-----------------------------------*/
+/* Return : 0 s1 = s2 */
+/* <0 s1 is less than s2 */
+/* >0 s1 is greater than s2 */
+/*-----------------------------------*/
+int ft_wstrnicmp(const WCHAR *s1, const WCHAR *s2, int n)
+{
+ WCHAR c1, c2;
+
+ for(; 0!=*s1 && 0!=*s2 && n>0; s1++, s2++, n--) {
+
+ c1 = *s1;
+ c2 = *s2;
+
+ // to upper case
+ if( 0x61<=c1 && 0x7a>=c1 ) {
+ // a(0x61)~z(0x7a) --> A(0x41)~Z(0x5a)
+ c1 -= 0x20;
+ }
+
+ // to upper case
+ if( 0x61<=c2 && 0x7a>=c2 ) {
+ // a(0x61)~z(0x7a) --> A(0x41)~Z(0x5a)
+ c2 -= 0x20;
+ }
+
+ if( c1 != c2 ) {
+ // not match
+ break;
+ }
+ }
+
+ return (0>=n ? 0 : (*s1 - *s2));
+}
+
+const WCHAR * ft_wstristr(const WCHAR *s, const WCHAR *ptn) {
+
+ if( NULL == s || NULL == ptn ) {
+ return NULL;
+ }
+
+ while( NULL != (s=ft_wstrichr(s, ptn[0])) ) {
+ if(!ft_wstrnicmp(s, ptn, kal_wstrlen(ptn))) {
+ return s;
+ }
+ s++;
+ }
+
+ return NULL;
+}
+
+kal_bool ft_IsDirectoryExist(const WCHAR *dir) {
+
+ kal_int32 ret;
+
+ if( NULL == dir ) {
+ return KAL_FALSE;
+ }
+
+#if defined(__LOW_COST_SUPPORT_ULC__)
+ if( 0 > (ret = FS_Open(dir, FS_OPEN_DIR|FS_READ_ONLY))){
+ return KAL_FALSE;
+ }else{
+ if( FS_NO_ERROR != FS_Close(ret)){
+ ASSERT(0);
+ }
+ }
+#else
+ if( 0 >= (ret=FS_GetAttributes(dir)) ) {
+ return KAL_FALSE;
+ }
+
+ if(!(FS_ATTR_DIR&((kal_uint32)ret))) {
+ return KAL_FALSE;
+ }
+#endif
+
+ return KAL_TRUE;
+}
+
+kal_int32 ft_CreateFullDirectory(const WCHAR *pathname) {
+
+ kal_int32 ret;
+ WCHAR *buf, *p, ch;
+
+ if( NULL == pathname ) {
+ return 1;
+ }
+
+ if( NULL == (buf=(WCHAR *)get_ctrl_buffer(sizeof(WCHAR)*(kal_wstrlen(pathname)+1))) ) {
+ return 2;
+ }
+ kal_wstrcpy(buf, pathname);
+ p = buf;
+
+ if( KAL_TRUE != ft_IsDirectoryExist(p) ) {
+
+ // skip drive letter
+ if(!kal_wstrncmp(p+1, L":\\", 2)) {
+ p += 3; // skip "C:\"
+ }
+
+ // skip '\' and '.' to find the first directory name
+ while( NULL != (p=ft_wstrnpbrk(p, L"\\.")) ) {
+
+ // find the first '\' after directory name
+ if( NULL == (p=kal_wstrchr(p, L'\\')) ) {
+ // no more '\' all sub directories are created.
+ break;
+ }
+
+ // temporarily replace with 0
+ ch = *p;
+ *p = 0;
+
+ // create directory
+ if(!ft_IsDirectoryExist(buf)) {
+ if( FS_NO_ERROR != (ret=FS_CreateDir(buf)) ) {
+ free_ctrl_buffer(buf);
+ return ret;
+ }
+ }
+
+ // restore char
+ *p = ch;
+ }
+ }
+
+ free_ctrl_buffer(buf);
+
+ return 0;
+}
+
+kal_uint8 ft_fat_fullpath_concatenate(WCHAR *fullpath, kal_uint32 fullpath_len_of_bytes, const WCHAR *subname) {
+
+ kal_uint32 total_length;
+ kal_bool end_with_backslash;
+
+ // get base_path length first
+ total_length = kal_wstrlen(fullpath);
+
+ // check if end with backslash
+ if( L'\\' == fullpath[total_length-1] ) {
+ end_with_backslash = KAL_TRUE;
+ }
+ else {
+ end_with_backslash = KAL_FALSE;
+ total_length += 1; // add '\' length
+ }
+
+ // calculate total length
+ total_length += kal_wstrlen(subname) + 1; // including 0 terminator char
+
+ if( (fullpath_len_of_bytes/sizeof(WCHAR)) < total_length ) {
+ return 1;
+ }
+
+ if(!end_with_backslash) {
+ kal_wstrcat(fullpath, L"\\");
+ }
+ kal_wstrcat(fullpath, subname);
+
+ return 0;
+}
+
+kal_uint8 ft_fat_fullpath_extract(WCHAR *fullpath, WCHAR **pp_subname) {
+
+ WCHAR *p;
+
+ if( NULL == (p=kal_wstrrchr(fullpath, L'\\')) ) {
+ return 1;
+ }
+
+ *p = 0;
+
+ if( NULL != pp_subname ) {
+ *pp_subname = p+1;
+ }
+
+ return 0;
+}
+/* for build warning
+ static void ft_fat_find_close_handle(ft_fat_dir_info *dir_info, void *arg) {
+ FS_FindClose(dir_info->fs_handle);
+ }
+ */
+void ft_fat_free_buffer(ft_stack_handle *p_stack,WCHAR *fullpath, WCHAR *found)
+{
+ if(NULL != p_stack)
+ ft_stack_destroy(p_stack);//, (FT_STACK_RELEASE_CALLBACK)ft_fat_find_close_handle, NULL);
+ p_stack = NULL;
+
+ // free fullpath
+ if( NULL != fullpath ) {
+ free_ctrl_buffer(fullpath);
+ fullpath = NULL;
+ }
+
+ // free found
+ if( NULL != found ) {
+ free_ctrl_buffer(found);
+ found = NULL;
+ }
+}
+
+kal_uint8 ft_fat_find_file_only(ft_stack_handle *p_stack,
+ const WCHAR *find_pattern,
+ WCHAR *fullpath,
+ WCHAR *found,
+ FT_FAT_FIND_CALLBACK cb, void *usr_arg)
+{
+ FS_HANDLE fs_handle;
+ FS_DOSDirEntry fileinfo;
+ kal_uint8 ret = FT_FAT_FIND_NOT_FOUND;
+
+
+ // concatenate fullpath with file search pattern
+ if(ft_fat_fullpath_concatenate(fullpath, FT_FAT_MAX_FULLPATH, find_pattern)) {
+ ret = 10;
+ ft_fat_free_buffer(p_stack,fullpath,found);
+ return ret;
+ }
+
+ // find first file
+ fs_handle = FS_FindFirst(fullpath, 0, FS_ATTR_DIR, &fileinfo, found, FT_FAT_MAX_FILENAME);
+
+ // remove find_pattern from fullpath
+ if(ft_fat_fullpath_extract(fullpath, NULL)) {
+ ret = 11;
+ ft_fat_free_buffer(p_stack,fullpath,found);
+ return ret;
+ }
+
+ // keep finding file
+ if( 0 <= fs_handle ) {
+
+ do {
+ // file found!
+ ret = 0;
+
+ // concatenate fullpath with found filename
+ if(ft_fat_fullpath_concatenate(fullpath, FT_FAT_MAX_FULLPATH, found)) {
+ ret = 12;
+ ft_fat_free_buffer(p_stack,fullpath,found);
+ return ret;
+ }
+
+ // callback
+ if( 0 != cb(fullpath, &fileinfo, usr_arg) ) {
+ ret = 13;
+ ft_fat_free_buffer(p_stack,fullpath,found);
+ return ret;
+ }
+
+ // extract path
+ if(ft_fat_fullpath_extract(fullpath, NULL)) {
+ ret = 14;
+ ft_fat_free_buffer(p_stack,fullpath,found);
+ return ret;
+ }
+ }while( FS_NO_ERROR == FS_FindNext(fs_handle, &fileinfo, found, FT_FAT_MAX_FILENAME) );
+
+ // close find handle
+ FS_FindClose(fs_handle);
+ }
+
+ return ret;
+
+}
+kal_uint8 ft_fat_find_first_dir(ft_stack_handle *p_stack,
+ ft_fat_dir_info *p_dir_info,
+ WCHAR *fullpath,
+ WCHAR *found,
+ FS_DOSDirEntry *p_fileinfo,
+ kal_bool *p_IsDirSearchGoOn)
+{
+ kal_uint8 ret = FT_FAT_FIND_NOT_FOUND; // default value
+
+ (*p_IsDirSearchGoOn) = KAL_FALSE;
+
+ // concatenate fullpath with dir search pattern "*"
+ if(ft_fat_fullpath_concatenate(fullpath, FT_FAT_MAX_FULLPATH, L"*")) {
+ ret = 5;
+ ft_fat_free_buffer(p_stack,fullpath,found);
+ return ret;
+ }
+ // find first dir
+ p_dir_info->fs_handle = FS_FindFirst(fullpath, FS_ATTR_DIR, FS_ATTR_HIDDEN, p_fileinfo, found, FT_FAT_MAX_FILENAME);//update by wayne
+
+ // p_dir_info->fs_handle = FS_FindFirst(fullpath, FS_ATTR_DIR, 0, p_fileinfo, found, FT_FAT_MAX_FILENAME);
+
+
+ //cur_width=0;
+
+
+ // remove dir search pattern "*" from fullpath
+ if(ft_fat_fullpath_extract(fullpath, NULL)) {
+ ret = 6;
+ ft_fat_free_buffer(p_stack,fullpath,found);
+ return ret;
+ }
+
+ return ret;
+}
+
+kal_uint8 ft_fat_find(const WCHAR *base_path, const WCHAR *find_pattern, FT_FAT_FIND_MODE mode, FT_FAT_FIND_CALLBACK cb, void *usr_arg) {
+
+ ft_stack_handle stack;
+ ft_fat_dir_info dir_info;
+ // FS_HANDLE fs_handle; // for build warning
+ FS_DOSDirEntry fileinfo;
+
+ kal_uint16 cur_width;
+ kal_uint16 get_width;
+ kal_uint16 i;
+
+ kal_uint8 ret = FT_FAT_FIND_NOT_FOUND;
+ kal_bool IsDirSearchGoOn;
+ kal_bool IsSearchSubDirGoOn;
+ WCHAR *fullpath = NULL;
+ WCHAR *found = NULL;
+
+ kal_uint8 test_ret = 0;
+
+
+ if( NULL==base_path || 0==base_path[0] || NULL==find_pattern || 0==find_pattern[0] || NULL==cb ) {
+ return 1;
+ }
+
+ // create fullpath buffer
+ if( NULL == (fullpath=(WCHAR *)get_ctrl_buffer(FT_FAT_MAX_FULLPATH)) ) {
+ ret = 2;
+ goto free_buffer;
+ }
+
+ // create found buffer
+ if( NULL == (found=(WCHAR *)get_ctrl_buffer(FT_FAT_MAX_FILENAME)) ) {
+ ret = 3;
+ goto free_buffer;
+ }
+
+ // create stack for depth first dir search
+ //if(ft_stack_create(&stack, sizeof(ft_fat_dir_info), FT_FAT_MAX_DIR_DEPTH)) { //FT_FAT_MAX_DIR_DEPTH
+ memset(&stack, 0, sizeof(ft_stack_handle));
+ if(ft_stack_create(&stack,sizeof(kal_uint16), FT_FAT_MAX_DIR_DEPTH)) { //FT_FAT_MAX_DIR_DEPTH
+ ret = 4;
+ goto free_buffer;
+ }
+
+ // copy base_path to fullpath
+ kal_wstrcpy(fullpath, base_path);
+
+ // check find mode
+ if( FT_FAT_FIND_FILE == mode ) {
+ //goto file_search;
+ ret = ft_fat_find_file_only(&stack,find_pattern,fullpath,found,cb,usr_arg);
+ }
+ else // FT_FAT_FIND_FILE_RECURSIVE or FT_FAT_FIND_DIR_RECURSIVE
+ {
+ // search the first directory in the base_path == lable: dir_search
+ ret = ft_fat_find_first_dir(&stack, &dir_info, fullpath, found, &fileinfo, &IsDirSearchGoOn);
+ cur_width=0;
+ if(ret != FT_FAT_FIND_NOT_FOUND) goto free_buffer;
+
+ IsSearchSubDirGoOn = KAL_FALSE;
+ for(; ;)
+ {
+
+ if( 0 <= dir_info.fs_handle )
+ {
+ do{
+ cur_width++;
+
+ // if dir search go on, FindNext() again first
+ if(IsDirSearchGoOn) {
+ IsDirSearchGoOn = KAL_FALSE;
+ continue;
+ }
+ // if found is "." or ".." , skip it
+ if( !kal_wstrcmp(found, L".") || !kal_wstrcmp(found, L"..") ) {
+ continue;
+ }
+ if( FT_FAT_FIND_DIR_RECURSIVE == mode ) {
+ // dir found!
+ ret = 0;
+ }
+ //close the file handler before we push it!
+ FS_FindClose(dir_info.fs_handle);
+
+ // push current dir
+ cur_width--;
+ //test_ret = ft_stack_push(&stack, &dir_info, sizeof(dir_info), cur_width);
+ test_ret = ft_stack_push(&stack, cur_width);
+ if(test_ret>0)
+ {
+ if(test_ret == 1) ret = 60;
+ else if(test_ret ==2) ret = 61;
+ else if(test_ret ==3) ret = 62;
+
+ goto free_buffer;
+ }
+
+ // concatenate with the found sub dir
+ if(ft_fat_fullpath_concatenate(fullpath, FT_FAT_MAX_FULLPATH, found)) {
+ ret = 8;
+ goto free_buffer;
+ }
+
+ // callback
+ if( 0 != cb(fullpath, &fileinfo, usr_arg) ) {
+ ret = 9;
+ goto free_buffer;
+ }
+
+ // find from sub dir
+ //goto dir_search;
+ if(ret != 0)
+ ret = ft_fat_find_first_dir(&stack, &dir_info, fullpath, found, &fileinfo, &IsDirSearchGoOn);
+ else
+ ft_fat_find_first_dir(&stack, &dir_info, fullpath, found, &fileinfo, &IsDirSearchGoOn);
+
+ cur_width=0;
+ if(ret != 0 && ret != FT_FAT_FIND_NOT_FOUND) goto free_buffer;
+
+ IsSearchSubDirGoOn = KAL_TRUE;
+ break; // break the while loop
+ //goto dir_search_go_on;
+
+ }while( FS_NO_ERROR == FS_FindNext(dir_info.fs_handle, &fileinfo, found, FT_FAT_MAX_FILENAME) );
+
+ if(IsSearchSubDirGoOn == KAL_TRUE)
+ {
+ IsSearchSubDirGoOn = KAL_FALSE;
+ continue; // start from the for loop again
+
+ }
+ // close find handle
+ FS_FindClose(dir_info.fs_handle);
+
+
+
+ }// end of if( 0 <= dir_info.fs_handle )
+
+
+ // file_search: find file
+ if(FT_FAT_FIND_FILE_RECURSIVE == mode)
+ {
+ if(ret!= 0)
+ ret = ft_fat_find_file_only(&stack,find_pattern,fullpath,found,cb,usr_arg);
+ else
+ ft_fat_find_file_only(&stack,find_pattern,fullpath,found,cb,usr_arg);
+
+ if(ret != 0 && ret != FT_FAT_FIND_NOT_FOUND) goto free_buffer; // error
+ }
+
+
+ // pop to parent dir
+ if(!ft_stack_pop(&stack, &get_width)) {
+ // extract fullpath to parent dir
+ if(ft_fat_fullpath_extract(fullpath, NULL)) {
+ ret = 15;
+ goto free_buffer;
+ }
+
+
+ // open the directory after we pop it =========================
+ // concatenate fullpath with dir search pattern "*"
+ if(ft_fat_fullpath_concatenate(fullpath, FT_FAT_MAX_FULLPATH, L"*")) {
+ ret = 70;
+ goto free_buffer;
+ }
+
+ //dir_info.fs_handle = FS_FindFirst(fullpath, FS_ATTR_DIR, 0, &fileinfo, found, FT_FAT_MAX_FILENAME);
+ dir_info.fs_handle = FS_FindFirst(fullpath, FS_ATTR_DIR, FS_ATTR_HIDDEN , &fileinfo, found, FT_FAT_MAX_FILENAME);
+ for(i=0;i<get_width;i++)
+ {
+ if(FS_FindNext(dir_info.fs_handle, &fileinfo, found, FT_FAT_MAX_FILENAME) !=FS_NO_ERROR)
+ {
+ ret = 73;
+ goto free_buffer;
+ }
+ }
+
+ cur_width = get_width;
+
+ // remove dir search pattern "*" from fullpath
+ if(ft_fat_fullpath_extract(fullpath, NULL)) {
+ ret = 71;
+ goto free_buffer;
+ }
+ //===========================================================
+
+ // dir search go on
+ IsDirSearchGoOn = KAL_TRUE;
+ //goto dir_search_go_on;
+ }// end of pop up the parent dir
+ else
+ {
+ break; // exit the for(; ;) loop
+ }
+ } // end of for(; ;)
+
+
+ } // end of else
+free_buffer:
+
+ ft_fat_free_buffer(&stack,fullpath,found);
+ return ret;
+}
+
+static kal_bool ft_fat_check_if_path_restricted(const WCHAR *path)
+{
+ return nvram_check_hidden_file(path, (ft_gl_path_check_flag) ? KAL_FALSE : KAL_TRUE );
+}
+
+typedef struct {
+ FT_FAT_OPERATION *p_fat_ret;
+ peer_buff_struct **pp_peer_buff_ret;
+ FT_FAT_FIND_MODE find_mode;
+}ft_fat_find_cb_arg;
+
+static kal_int8 ft_fat_update_peer_buf(const WCHAR *fullpath, const FS_DOSDirEntry *dos_info, ft_fat_find_cb_arg *arg) {
+
+ kal_uint32 filesize;
+ kal_uint16 pdu_length;
+ kal_char *pdu_ptr;
+
+ // check find mode
+ if( FT_FAT_FIND_DIR_RECURSIVE == arg->find_mode ) {
+ // find dir mode, skip all non-dir found items
+ if(!(FS_ATTR_DIR&(dos_info->Attributes))) {
+ return 0;
+ }
+ }
+ else {
+ // find file mode, skip all non-file found items
+ if((FS_ATTR_DIR&(dos_info->Attributes))) {
+ return 0;
+ }
+ }
+
+ // check path restriction
+ if(ft_fat_check_if_path_restricted(fullpath)) {
+ return 0;
+ }
+
+allocate_peer_buf:
+ // if peer buffer is not allocated, allocate it now.
+ if( NULL == *(arg->pp_peer_buff_ret) ) {
+ if( NULL == (*(arg->pp_peer_buff_ret)=construct_peer_buff(FT_FAT_MAX_FRAME_SIZE, 0, 0, TD_CTRL)) ) {
+ return 1;
+ }
+ (*(arg->pp_peer_buff_ret))->pdu_len = 0;
+ }
+
+ // data format: filesize(4bytes) + filepath(string) + '\0'
+
+ // if data exceed limit, flush out.
+ if( FT_FAT_MAX_FRAME_SIZE < ((*(arg->pp_peer_buff_ret))->pdu_len+4+((kal_wstrlen(fullpath)+1)*2)) ) {
+ // set last_frame = 0
+ arg->p_fat_ret->last_frame = 0;
+ arg->p_fat_ret->status = FT_CNF_OK;
+ // send confirm
+ FT_FAT_SendCnf(arg->p_fat_ret, *(arg->pp_peer_buff_ret));
+
+ // sleep to wait for tst flush out data
+ kal_sleep_task(50);
+
+ // allocate peer buffer again
+ *(arg->pp_peer_buff_ret) = NULL;
+ goto allocate_peer_buf;
+ }
+
+ pdu_ptr = get_peer_buff_pdu( *(arg->pp_peer_buff_ret), &pdu_length );
+
+ // store filesize
+ filesize = dos_info->FileSize;
+ kal_mem_cpy(pdu_ptr+pdu_length, &filesize, sizeof(filesize));
+ // copy filepath
+ kal_mem_cpy(pdu_ptr+pdu_length+sizeof(filesize), (void *)fullpath, (kal_wstrlen(fullpath)+1)*2);
+ // update pdu_len
+ (*(arg->pp_peer_buff_ret))->pdu_len += ( sizeof(filesize) + (kal_wstrlen(fullpath)+1)*2 );
+
+ return 0;
+}
+
+#define MAX_OPENED_HANDLE 32
+static FS_HANDLE g_FAT_HandleArrary[MAX_OPENED_HANDLE];
+
+kal_int8 FT_FAT_Handle_Clear(void) {
+ kal_uint16 i;
+ for(i=0; i<MAX_OPENED_HANDLE; i++) {
+ g_FAT_HandleArrary[i] = -1;
+ }
+ return 0;
+}
+
+kal_int8 FT_FAT_Handle_Add(FS_HANDLE handle) {
+ kal_uint16 i;
+ for(i=0; i<MAX_OPENED_HANDLE; i++) {
+ if( -1 == g_FAT_HandleArrary[i] ) {
+ g_FAT_HandleArrary[i] = handle;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+kal_int8 FT_FAT_Handle_Del(FS_HANDLE handle) {
+ kal_uint16 i;
+ for(i=0; i<MAX_OPENED_HANDLE; i++) {
+ if( handle == g_FAT_HandleArrary[i] ) {
+ g_FAT_HandleArrary[i] = -1;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+kal_bool FT_FAT_Handle_IsAvailable(void) {
+ kal_uint16 i;
+ for(i=0; i<MAX_OPENED_HANDLE; i++) {
+ if( -1 == g_FAT_HandleArrary[i] ) {
+ return KAL_TRUE;
+ }
+ }
+ return KAL_FALSE;
+}
+
+#if !defined(__LOW_COST_SUPPORT_ULC__)
+kal_bool FT_FAT_IsFileAlreadyOpened(const WCHAR *filename, FS_HANDLE *handle) {
+ kal_uint16 i;
+ FS_FileInfo file_info;
+ for(i=0; i<MAX_OPENED_HANDLE; i++) {
+ if( -1 != g_FAT_HandleArrary[i] ) {
+ // get file handel info
+ if( 0 <= FS_GetFileInfo(g_FAT_HandleArrary[i], &file_info) ) {
+
+ // compare full filename
+ if(!ft_wstrnicmp(filename, (WCHAR *)file_info.FullName, kal_wstrlen(filename))) {
+ // filename is the same, this file is already opened!
+ if( NULL != handle ) {
+ *handle = g_FAT_HandleArrary[i];
+ }
+ return KAL_TRUE;
+ }
+
+ }
+ }
+ }
+ return KAL_FALSE;
+}
+
+kal_int8 FT_FAT_CloseFileIfAlreadyOpened(const WCHAR *filename) {
+ FS_HANDLE handle;
+ // check if handle is already opened
+ if( KAL_TRUE == FT_FAT_IsFileAlreadyOpened(filename, &handle) ) {
+ if( FS_NO_ERROR != FS_Close(handle) ) {
+ return 1;
+ }
+ // delete this handle from opened handle arrary
+ if( 0 != FT_FAT_Handle_Del(handle) ) {
+ return 2;
+ }
+ }
+ return 0;
+}
+#endif
+
+void FT_FAT_Operation(FT_FAT_OPERATION *ft_fat_op, peer_buff_struct *peer_buff_in) {
+
+ kal_uint32 mode;
+ kal_uint16 pdu_length;
+ kal_char *pdu_ptr;
+ peer_buff_struct *peer_buff_ret;
+ kal_uint32 finish_bytes;
+ FT_FAT_OPERATION ft_fat_ret;
+ ft_fat_find_cb_arg ft_fat_update_peer_buf_arg;
+ kal_uint32 filesize;
+ WCHAR *w_filepath_1;
+ WCHAR *w_filepath_2;
+ FT_FAT_DiskInfo_T DiskInfo;
+ FS_DiskInfo fs_diskinfo;
+ //kal_uint8 folder_total_amount;
+ //kal_uint8 folder_idx;
+
+ // initialize
+ pdu_length = 0;
+ pdu_ptr = NULL;
+ peer_buff_ret = NULL;
+ kal_mem_set(&ft_fat_ret, '\0', sizeof(FT_FAT_OPERATION));
+
+ if( NULL != peer_buff_in ) {
+ pdu_ptr = get_peer_buff_pdu( peer_buff_in, &pdu_length );
+ }
+
+ ft_fat_ret.fat_op = ft_fat_op->fat_op;
+ ft_fat_ret.status = FT_CNF_FAIL;
+ switch((int)ft_fat_op->fat_op) {
+ case FT_FAT_OP_OPEN|FT_FAT_OP_READ:
+ case FT_FAT_OP_OPEN|FT_FAT_OP_WRITE:
+ if( NULL != peer_buff_in && 0 < pdu_length ) {
+
+ // check if filepath too long
+ if( FT_FAT_MAX_FULLPATH < pdu_length ) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_TOO_LONG;
+ break;
+ }
+
+ // cast to WCHAR
+ w_filepath_1 = (WCHAR *)pdu_ptr;
+
+ // check path restriction
+ if(ft_fat_check_if_path_restricted(w_filepath_1)) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_RESTRICTION;
+ break;
+ }
+
+ // create dir
+ if( 0 != (ft_fat_ret.status=ft_CreateFullDirectory(w_filepath_1)) ) {
+ break;
+ }
+
+ if( (FT_FAT_OP_OPEN+FT_FAT_OP_WRITE) == ft_fat_ret.fat_op ) {
+ mode = FS_CREATE_ALWAYS;
+ }
+ else {
+ mode = FS_READ_ONLY;
+ }
+
+#if !defined(__LOW_COST_SUPPORT_ULC__)
+ // close file if it is already opened
+ FT_FAT_CloseFileIfAlreadyOpened(w_filepath_1);
+#endif
+
+ // check if file handle available
+ if( KAL_TRUE != FT_FAT_Handle_IsAvailable() ) {
+ ft_fat_ret.status = FS_TOO_MANY_FILES;
+ break;
+ }
+
+ if( 0 <= (ft_fat_ret.status=FS_Open(w_filepath_1, mode)) ) {
+ // assign file handle
+ ft_fat_ret.fs_handle = ft_fat_ret.status;
+ // ok
+ ft_fat_ret.status = FT_CNF_OK;
+ // add this handle into opened handle arrary
+ FT_FAT_Handle_Add(ft_fat_ret.fs_handle);
+ // send confirm
+ break;
+ }
+ }
+ break;
+ case FT_FAT_OP_READ:
+ ft_fat_ret.fs_handle = ft_fat_op->fs_handle;
+ ft_fat_ret.offset = ft_fat_op->offset;
+ ft_fat_ret.last_frame = 0;
+ if( 0 <= (ft_fat_ret.status=FS_Seek(ft_fat_ret.fs_handle, ft_fat_ret.offset, FS_FILE_BEGIN))) {
+ finish_bytes = 0;
+ if( NULL != (peer_buff_ret=construct_peer_buff(FT_FAT_MAX_FRAME_SIZE, 0, 0, TD_CTRL)) ) {
+
+ pdu_ptr = get_peer_buff_pdu( peer_buff_ret, &pdu_length );
+
+ if( FS_NO_ERROR == (ft_fat_ret.status=FS_GetFileSize(ft_fat_ret.fs_handle, &filesize)) ) {
+
+ if( FS_NO_ERROR == (ft_fat_ret.status=FS_Read(ft_fat_ret.fs_handle, pdu_ptr, FT_FAT_MAX_FRAME_SIZE, &finish_bytes)) ) {
+ if( (finish_bytes+ft_fat_ret.offset) >= filesize ) {
+ ft_fat_ret.last_frame = 1;
+ }
+ ft_fat_ret.status = FT_CNF_OK;
+ peer_buff_ret->pdu_len = finish_bytes;
+ // send confirm
+ break;
+ }
+
+ }
+
+ // error, free buffer
+ free_peer_buff(peer_buff_ret);
+ peer_buff_ret = NULL;
+ }
+ }
+ break;
+ case FT_FAT_OP_WRITE:
+ ft_fat_ret.fs_handle = ft_fat_op->fs_handle;
+ ft_fat_ret.offset = ft_fat_op->offset;
+ if( NULL != peer_buff_in && 0 < pdu_length ) {
+ if( 0 <= (ft_fat_ret.status=FS_Seek(ft_fat_ret.fs_handle, ft_fat_ret.offset, FS_FILE_BEGIN))) {
+ finish_bytes = 0;
+ if( FS_NO_ERROR==(ft_fat_ret.status=FS_Write(ft_fat_ret.fs_handle, pdu_ptr, pdu_length, &finish_bytes)) && pdu_length==finish_bytes ) {
+ ft_fat_ret.status = FT_CNF_OK;
+ // send confirm
+ break;
+ }
+ }
+ }
+ break;
+ case FT_FAT_OP_CLOSE:
+ ft_fat_ret.fs_handle = ft_fat_op->fs_handle;
+ if( FS_NO_ERROR == (ft_fat_ret.status=FS_Close(ft_fat_ret.fs_handle)) ) {
+ // ok
+ ft_fat_ret.status = FT_CNF_OK;
+ // delete this handle from opened handle arrary
+ FT_FAT_Handle_Del(ft_fat_ret.fs_handle);
+ // send confirm
+ break;
+ }
+ break;
+ case FT_FAT_OP_FILESIZE:
+ ft_fat_ret.fs_handle = ft_fat_op->fs_handle;
+ if( FS_NO_ERROR == (ft_fat_ret.status=FS_GetFileSize(ft_fat_ret.fs_handle, (kal_uint32 *)&(ft_fat_ret.offset))) ) {
+ // ok
+ ft_fat_ret.status = FT_CNF_OK;
+ // send confirm
+ break;
+ }
+ break;
+ case FT_FAT_OP_DELETE:
+ if( NULL != peer_buff_in && 0 < pdu_length ) {
+
+ // check if filepath too long
+ if( FT_FAT_MAX_FULLPATH < pdu_length ) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_TOO_LONG;
+ break;
+ }
+
+ // cast to WCHAR
+ w_filepath_1 = (WCHAR *)pdu_ptr;
+
+ // check path restriction
+ if(ft_fat_check_if_path_restricted(w_filepath_1)) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_RESTRICTION;
+ break;
+ }
+
+#if !defined(__LOW_COST_SUPPORT_ULC__)
+ // close file if it is already opened
+ FT_FAT_CloseFileIfAlreadyOpened(w_filepath_1);
+#endif
+ if( FS_NO_ERROR == (ft_fat_ret.status=FS_Delete(w_filepath_1)) ) {
+ // ok
+ ft_fat_ret.status = FT_CNF_OK;
+ // send confirm
+ break;
+ }
+ }
+ break;
+ case FT_FAT_OP_MOVE:
+#if defined(__LOW_COST_SUPPORT_ULC__)
+ ft_fat_ret.status = FT_FAT_ERR_ACTION_NOT_SUPPORT;
+#else // non __LOW_COST_SUPPORT_LC__
+ if( NULL != peer_buff_in && 0 < pdu_length ) {
+
+ w_filepath_1 = (WCHAR *)pdu_ptr;
+ w_filepath_2 = w_filepath_1+kal_wstrlen(w_filepath_1)+1;
+
+ // check if src path too long
+ if( FT_FAT_MAX_FULLPATH < (kal_wstrlen(w_filepath_1)+1)*2 ) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_TOO_LONG;
+ break;
+ }
+
+ // check if dest path too long
+ if( FT_FAT_MAX_FULLPATH < (kal_wstrlen(w_filepath_2)+1)*2 ) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_TOO_LONG;
+ break;
+ }
+
+ // check path restriction
+ if(ft_fat_check_if_path_restricted(w_filepath_1)) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_RESTRICTION;
+ break;
+ }
+
+ // check path restriction
+ if(ft_fat_check_if_path_restricted(w_filepath_2)) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_RESTRICTION;
+ break;
+ }
+
+ // close file if it is already opened
+ FT_FAT_CloseFileIfAlreadyOpened(w_filepath_1);
+ FT_FAT_CloseFileIfAlreadyOpened(w_filepath_2);
+
+ if( FS_NO_ERROR == (ft_fat_ret.status=FS_Rename(w_filepath_1, w_filepath_2)) ) {
+ // ok
+ ft_fat_ret.status = FT_CNF_OK;
+ // send confirm
+ break;
+ }
+ }
+#endif // non __LOW_COST_SUPPORT_LC__
+ break;
+ case FT_FAT_OP_FIND_FILE:
+ case FT_FAT_OP_FIND_FILE_RECURSIVE:
+ case FT_FAT_OP_FIND_DIR_RECURSIVE:
+ if( NULL != peer_buff_in && 0 < pdu_length ) {
+
+ w_filepath_1 = (WCHAR *)pdu_ptr;
+ w_filepath_2 = w_filepath_1+kal_wstrlen(w_filepath_1)+1;
+
+ // check if base_dir too long
+ if( FT_FAT_MAX_FULLPATH < (kal_wstrlen(w_filepath_1)+1)*2 ) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_TOO_LONG;
+ break;
+ }
+
+ // check if find_pattern path too long
+ if( FT_FAT_MAX_FULLPATH < (kal_wstrlen(w_filepath_2)+1)*2 ) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_TOO_LONG;
+ break;
+ }
+
+ // check path restriction in file search case
+ if( (FT_FAT_OP_FIND_DIR_RECURSIVE != ft_fat_op->fat_op) &&
+ ft_fat_check_if_path_restricted(w_filepath_1) ) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_RESTRICTION;
+ break;
+ }
+
+ // find
+ peer_buff_ret = NULL;
+ ft_fat_update_peer_buf_arg.p_fat_ret = &ft_fat_ret;
+ ft_fat_update_peer_buf_arg.pp_peer_buff_ret = &peer_buff_ret;
+ switch(ft_fat_op->fat_op) {
+ case FT_FAT_OP_FIND_FILE:
+ ft_fat_update_peer_buf_arg.find_mode = FT_FAT_FIND_FILE;
+ break;
+ case FT_FAT_OP_FIND_DIR_RECURSIVE:
+ ft_fat_update_peer_buf_arg.find_mode = FT_FAT_FIND_DIR_RECURSIVE;
+ break;
+ case FT_FAT_OP_FIND_FILE_RECURSIVE:
+ default:
+ ft_fat_update_peer_buf_arg.find_mode = FT_FAT_FIND_FILE_RECURSIVE;
+ break;
+ }
+ if( 0 == (ft_fat_ret.status=ft_fat_find(
+ w_filepath_1,
+ w_filepath_2,
+ ft_fat_update_peer_buf_arg.find_mode,
+ (FT_FAT_FIND_CALLBACK)ft_fat_update_peer_buf,
+ &ft_fat_update_peer_buf_arg)) )
+ {
+ // found
+ ft_fat_ret.last_frame = 1;
+ ft_fat_ret.status = FT_CNF_OK;
+ }
+ }
+ break;
+ case FT_FAT_OP_GET_DISK_INFO:
+ if( NULL != peer_buff_in && 0 < pdu_length ) {
+
+ // cast to WCHAR
+ w_filepath_1 = (WCHAR *)pdu_ptr;
+
+ /* // check path restriction
+ if(ft_fat_check_if_path_restricted(w_filepath_1)) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_RESTRICTION;
+ break;
+ }*/
+
+ if( NULL != (peer_buff_ret=construct_peer_buff(sizeof(FT_FAT_DiskInfo_T), 0, 0, TD_CTRL)) ) {
+
+ pdu_ptr = get_peer_buff_pdu( peer_buff_ret, &pdu_length );
+
+ kal_mem_set(&fs_diskinfo, 0, sizeof(fs_diskinfo));
+ if( 0 <= (ft_fat_ret.status=FS_GetDiskInfo(w_filepath_1, &fs_diskinfo, FS_DI_BASIC_INFO|FS_DI_FREE_SPACE)) ) {
+ // ok
+ ft_fat_ret.status = FT_CNF_OK;
+ // fill FT_FAT_DiskInfo_T
+ DiskInfo.Type = fs_diskinfo.FATType;
+ DiskInfo.SectorsPerCluster = fs_diskinfo.SectorsPerCluster;
+ DiskInfo.TotalClusters = fs_diskinfo.TotalClusters;
+ DiskInfo.FreeClusters = fs_diskinfo.FreeClusters;
+ kal_mem_cpy(pdu_ptr, &DiskInfo, sizeof(FT_FAT_DiskInfo_T));
+ // send confirm
+ break;
+ }
+
+ // error, free buffer
+ free_peer_buff(peer_buff_ret);
+ peer_buff_ret = NULL;
+ }
+ }
+ break;
+ case FT_FAT_OP_RMDIR:
+#if defined(__LOW_COST_SUPPORT_ULC__)
+ ft_fat_ret.status = FT_FAT_ERR_ACTION_NOT_SUPPORT;
+#else // non __LOW_COST_SUPPORT_ULC__
+ if( NULL != peer_buff_in && 0 < pdu_length ) {
+
+ // check if filepath too long
+ if( FT_FAT_MAX_FULLPATH < pdu_length ) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_TOO_LONG;
+ break;
+ }
+
+ // cast to WCHAR
+ w_filepath_1 = (WCHAR *)pdu_ptr;
+
+ // check path restriction
+ if(ft_fat_check_if_path_restricted(w_filepath_1)) {
+ ft_fat_ret.status = FT_FAT_ERR_PATH_RESTRICTION;
+ break;
+ }
+
+ // check if directory
+ if(!ft_IsDirectoryExist(w_filepath_1)) {
+ ft_fat_ret.status = FT_FAT_ERR_DIR_NOT_EXIST;
+ break;
+ }
+
+ // call FS_XDelete
+ if( 0 <= (ft_fat_ret.status=FS_XDelete(w_filepath_1, FS_FILE_TYPE|FS_DIR_TYPE|FS_RECURSIVE_TYPE, NULL, 0)) ) {
+ ft_fat_ret.status = FT_CNF_OK;
+ }
+ }
+#endif // end non __LOW_COST_SUPPORT_ULC__
+ break;
+ case FT_FAT_OP_GET_DRIVE_TYPE:
+ {
+ // Since FS_GetDevType is not supported
+ ft_fat_ret.status = FT_FAT_ERR_ACTION_NOT_SUPPORT;
+ break;
+ }
+ default:
+ break;
+ }
+
+ // send confirm
+ ft_gl_path_check_flag = KAL_TRUE; // re-enable the path restriction!
+ FT_FAT_SendCnf(&ft_fat_ret, peer_buff_ret);
+}
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_l1rf.c b/mcu/middleware/meta/ft/src/ft_fnc_l1rf.c
new file mode 100644
index 0000000..cce84e4
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_l1rf.c
@@ -0,0 +1,252 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_l1rf.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Factory testing function for GSM/GPRS/EDGE
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+/*************************************************************************
+* Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h"
+#include "task_config.h"
+#include "svc_sap.h"
+#include "md_sap.h"
+#include "ft_msgid.h"
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_l1rf.h"
+/**
+ * @param metaMessage the input message from META tool for RF test command processing
+ */
+void FT_Rf_Operation(ilm_struct *ptrMsg)
+{
+ ilm_struct rfMessage;
+ FT_CONSTRUCT_CC_MSG(ptrMsg, &rfMessage);
+ FT_SEND_MSG(MOD_FT, MOD_L1, FT_GL1TST_SAP, MSG_ID_FT_TO_GL1TST, &rfMessage);
+}
+/**
+ * Confirm message handler for MOD_L1
+ */
+void FT_Rf_ConfirmHandler(ilm_struct* rfMessage)
+{
+ ft_rf_test_cnf_T *ptrMsg;
+ ptrMsg = (ft_rf_test_cnf_T *)rfMessage->local_para_ptr;
+ if(ptrMsg->type == RF_TEST_CMD_CHECK_IF_FUNC_EXIST)
+ {
+ FT_UTILITY_COMMAND_CNF cnf;
+ kal_mem_set(&cnf, '\0', sizeof(cnf));
+ cnf.status = (ptrMsg->param.CheckIfFuncExist.result==1)?FT_CNF_OK:FT_CNF_FAIL;
+ cnf.result.CheckIfFuncExist.query_ft_msg_id = ptrMsg->header.ft_msg_id;
+ cnf.result.CheckIfFuncExist.query_op_code = ptrMsg->param.CheckIfFuncExist.query_op_code;
+ FT_UTIL_SendCnf(&cnf, NULL);
+ return;
+ }
+ FT_SEND_MSG_TO_PC(rfMessage);
+}
+void FT_RfCheckFunctionSupported(kal_uint32 query_op_code)
+{
+ ilm_struct ilm_ptr;
+ ft_rf_test_req_T *ptrMsg;
+ FT_ALLOC_OTHER_CC_MSG( &ilm_ptr, sizeof(ft_rf_test_req_T) );
+ // local parameter
+ ptrMsg = (ft_rf_test_req_T *)ilm_ptr.local_para_ptr;
+ ptrMsg->header.ft_msg_id = FT_RF_TEST_REQ_ID;
+ ptrMsg->type = RF_TEST_CMD_CHECK_IF_FUNC_EXIST;
+ ptrMsg->param.query_op_code = (RfTestCmdType)query_op_code;
+ FT_SEND_MSG(MOD_FT, MOD_L1, FT_GL1TST_SAP, MSG_ID_FT_TO_GL1TST, &ilm_ptr);
+}
+#endif //#if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_l4.c b/mcu/middleware/meta/ft/src/ft_fnc_l4.c
new file mode 100644
index 0000000..bff3c45
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_l4.c
@@ -0,0 +1,105 @@
+#if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT) || defined(DUMMY_PROTOCOL)
+/*************************************************************************
+* Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h"
+#include "md_sap.h"
+#include "tst_msgid.h"
+#include "ft_msgid.h"
+#include "ps_public_l4_msgid.h"
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_l4.h"
+#include "ft_msg_l4.h"
+/**
+ * @param metaMessage and MOD_L4C the input message for L4 AT test command processing
+ */
+void FT_L4_Operation(ilm_struct* ptrMsg)
+{
+ ilm_struct l4Message;
+
+ if(MOD_L4C == ptrMsg->src_mod_id)
+ {
+ switch (ptrMsg->msg_id)
+ {
+ case MSG_ID_FT_ENTER_FACTORY_MODE_CNF:
+ {
+ ft_enter_factory_mode_cnf_struct *l4CnfMsg;
+ FT_L4_ATCMD_CNF *ptrCnfMsg;
+ l4CnfMsg = (ft_enter_factory_mode_cnf_struct*)ptrMsg->local_para_ptr;
+ FT_ALLOC_MSG(&l4Message, sizeof(FT_L4_ATCMD_CNF));
+ ptrCnfMsg = (FT_L4_ATCMD_CNF *)l4Message.local_para_ptr;
+ ptrCnfMsg->header.ft_msg_id = FT_L4_ATCMD_CNF_ID;
+ ptrCnfMsg->type = 1;
+ if(l4CnfMsg->result == FT_MODE_SWITCH_SUCCESS)
+ {
+ ptrCnfMsg->status = FT_CNF_OK;
+ }
+ else if(l4CnfMsg->result == FT_MODE_SWITCH_RETRY)
+ {
+ ptrCnfMsg->status = FT_CNF_RETRY;
+ }
+ else
+ {
+ ptrCnfMsg->status = FT_CNF_FAIL;
+ }
+ FT_SEND_MSG_TO_PC(&l4Message);
+ break;
+ }
+ case MSG_ID_FT_ENTER_NORMAL_MODE_CNF:
+ {
+ ft_enter_normal_mode_cnf_struct *l4CnfMsg;
+ FT_L4_ATCMD_CNF *ptrCnfMsg;
+ l4CnfMsg = (ft_enter_normal_mode_cnf_struct*)ptrMsg->local_para_ptr;
+ FT_ALLOC_MSG(&l4Message, sizeof(FT_L4_ATCMD_CNF));
+ ptrCnfMsg = (FT_L4_ATCMD_CNF *)l4Message.local_para_ptr;
+ ptrCnfMsg->header.ft_msg_id = FT_L4_ATCMD_CNF_ID;
+ ptrCnfMsg->type = 0;
+ if(l4CnfMsg->result == FT_MODE_SWITCH_SUCCESS)
+ {
+ ptrCnfMsg->status = FT_CNF_OK;
+ }
+ else if(l4CnfMsg->result == FT_MODE_SWITCH_RETRY)
+ {
+ ptrCnfMsg->status = FT_CNF_RETRY;
+ }
+ else
+ {
+ ptrCnfMsg->status = FT_CNF_FAIL;
+ }
+ FT_SEND_MSG_TO_PC(&l4Message);
+ break;
+ }
+ /* FT not in switch mode broadcast list
+ case MSG_ID_L4C_ENTER_FACTORY_MODE_REQ:
+ {
+ l4Message.local_para_ptr = NULL;
+ l4Message.peer_buff_ptr = NULL;
+ FT_SEND_MSG(MOD_FT, MOD_L4C, L4C_META_SAP, MSG_ID_L4C_ENTER_FACTORY_MODE_CNF, &l4Message);
+ break;
+ }*/
+ }
+ }
+ else
+ {
+ FT_L4_ATCMD_REQ *ptrLocalMsg;
+ ptrLocalMsg = (FT_L4_ATCMD_REQ *)ptrMsg->local_para_ptr;
+ if(FT_L4_ATCMD_REQ_ID == ptrLocalMsg->header.ft_msg_id)
+ {
+ l4Message.local_para_ptr = NULL;
+ l4Message.peer_buff_ptr = NULL;
+ if(ptrLocalMsg->type == 1)
+ {
+ FT_SEND_MSG(MOD_FT, MOD_L4C, L4C_META_SAP, MSG_ID_FT_ENTER_FACTORY_MODE_REQ, &l4Message);
+ }
+ else if(ptrLocalMsg->type == 0)
+ {
+ FT_SEND_MSG(MOD_FT, MOD_L4C, L4C_META_SAP, MSG_ID_FT_ENTER_NORMAL_MODE_REQ, &l4Message);
+ }
+ }
+ }
+}
+#endif // #if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT) || defined(DUMMY_PROTOCOL)
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_lterf.c b/mcu/middleware/meta/ft/src/ft_fnc_lterf.c
new file mode 100644
index 0000000..bb54a6a
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_lterf.c
@@ -0,0 +1,194 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_lterf.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Factory testing function for LTE
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#if defined(__LTE_RAT__)
+/*************************************************************************
+* Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h"
+#include "svc_sap.h"
+#include "tst_msgid.h"
+#include "ft_msgid.h"
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_lterf.h"
+/**
+ * @param metaMessage the input message from META tool for ERF test command processing
+ */
+void FT_Erf_Operation(ilm_struct* ptrMsg)
+{
+ ilm_struct erfMessage;
+ FT_CONSTRUCT_CC_MSG(ptrMsg, &erfMessage);
+ FT_SEND_MSG(MOD_FT, MOD_EL1, DHL_EL1TST_SAP, MSG_ID_DHL_TO_EL1TST, &erfMessage);
+}
+/**
+ * @param metaMessage the input message from META tool for ERF test command processing
+ */
+void FT_PhyTool_Operation(ilm_struct* ptrMsg)
+{
+ ilm_struct erfMessage;
+ FT_CONSTRUCT_CC_MSG(ptrMsg, &erfMessage);
+ FT_SEND_MSG(MOD_FT, MOD_EL1, DHL_ETSTM_SAP, MSG_ID_DHL_TO_ETSTM, &erfMessage);
+}
+/**
+ * Confirm message handler for MOD_ETSTM
+ */
+void FT_Erf_ConfirmHandler(ilm_struct* erfMessage)
+{
+ FT_ERF_TEST_CNF *ptrMsg;
+ ptrMsg = (FT_ERF_TEST_CNF *)erfMessage->local_para_ptr;
+ if(ptrMsg->type == ERF_TEST_CMD_CHECK_IF_FUNC_EXIST)
+ {
+ FT_UTILITY_COMMAND_CNF cnf;
+ kal_mem_set(&cnf, '\0', sizeof(cnf));
+ cnf.status = (ptrMsg->param.CheckIfFuncExist.result==1)?FT_CNF_OK:FT_CNF_FAIL;
+ cnf.result.CheckIfFuncExist.query_ft_msg_id = ptrMsg->header.ft_msg_id;
+ cnf.result.CheckIfFuncExist.query_op_code = ptrMsg->param.CheckIfFuncExist.query_op_code;
+ FT_UTIL_SendCnf(&cnf, NULL);
+ return;
+ }
+ FT_SEND_MSG_TO_PC(erfMessage);
+}
+void FT_ErfCheckFunctionSupported(kal_uint32 query_op_code)
+{
+ ilm_struct ilm_ptr;
+ FT_ERF_TEST_REQ *ptrMsg;
+ FT_ALLOC_OTHER_CC_MSG( &ilm_ptr, sizeof(FT_ERF_TEST_REQ) );
+ // local parameter
+ ptrMsg = (FT_ERF_TEST_REQ *)ilm_ptr.local_para_ptr;
+ ptrMsg->header.ft_msg_id = FT_ERF_TEST_REQ_ID;
+ ptrMsg->type = ERF_TEST_CMD_CHECK_IF_FUNC_EXIST;
+ ptrMsg->param.CheckIfFuncExist.cmd_tpye = (ERfTestCmdType)query_op_code;
+ FT_SEND_MSG(MOD_FT, MOD_EL1, DHL_EL1TST_SAP, MSG_ID_DHL_TO_EL1TST, &ilm_ptr);
+}
+#endif // #if defined(__LTE_RAT__)
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_misc.c b/mcu/middleware/meta/ft/src/ft_fnc_misc.c
new file mode 100644
index 0000000..f948081
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_misc.c
@@ -0,0 +1,1058 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_misc.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Misc Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_trace.h"
+#include "string.h"
+#include "sst_interface.h"
+#include "svc_sap.h"
+#include "md_sap.h"
+#include "mw_sap.h"
+#include "ft_msgid.h"
+#include "nvram_msgid.h"
+#include "sim_public_msgid.h"
+/**************************************************************************
+ * HAL header
+ *************************************************************************/
+#include "dcl.h"
+/**************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_misc.h"
+#include "ft_mem.h"
+#include "ft_fnc_nvram.h"
+#include "ft_trace_def.h"
+/**************************************************************************
+ * NVRAM header
+ *************************************************************************/
+#include "nvram_enums.h"
+#include "nvram_data_items.h"
+#include "ft_nvram_def.h"
+#include "l4_nvram_def.h"
+#include "mml1_nvram_def.h"
+#include "nvram_struct.h"
+#include "nvram_interface.h"
+#include "nvram_editor_data_item.h"
+#include "ft_nvram_editor.h"
+/* NVRAM private header for data item iterator */
+//#include "nvram_util.h" -> "nvram_interface.h"
+/**************************************************************************
+ * SIM header
+ *************************************************************************/
+#include "ps2sim_struct.h"
+/**************************************************************************
+ * Custom header
+ *************************************************************************/
+#include "meta_customize.h"
+kal_uint8 ft_gl_path_check_flag = KAL_TRUE;
+kal_uint8 *p_ft_misc_buf = NULL; // a pointer point to : nvram_cal_data_check_struct
+kal_bool b_ft_misc_buf_from_med = KAL_TRUE; // KAL_TRUE: from MED task, KAL_FALSE: from control buffer
+kal_uint16 ft_gl_misc_token = 0;
+kal_uint8 ft_gl_sim_cmd_type = 0; // store sim cmd type
+
+//=============== local buffer process =========================
+kal_uint8 FT_MISC_SendCnf(FT_MISC_CNF *ft_misc_ret, peer_buff_struct *peer_buff) {
+
+ ilm_struct ilm_ptr;
+ FT_MISC_CNF *ptrMsg;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_MISC_CNF));
+
+ /* if ptrMsg != NULL*/
+ ptrMsg = (FT_MISC_CNF *)ilm_ptr.local_para_ptr;
+
+ // assign primitive id
+ ptrMsg->header.ft_msg_id = FT_MISC_CMD_CNF_ID;
+
+ // assign return structure
+ ptrMsg->type = ft_misc_ret->type;
+
+ // copy the result directly without checking its cmd type
+ kal_mem_cpy(&(ptrMsg->result), &(ft_misc_ret->result), sizeof(FT_MISC_CNF_U));
+
+ ptrMsg->status = ft_misc_ret->status;
+
+ // assign peer buffer
+ if( NULL != peer_buff ) {
+ ilm_ptr.peer_buff_ptr = peer_buff;
+ }
+
+ /* FT_SEND_MSG(src_mod, dest_mod, sap_id, msg_id, ilm_ptr) */
+ FT_SEND_MSG_TO_PC_BY_TOKEN(&ilm_ptr, ft_gl_misc_token);
+ return 0;
+}
+#define FT_MISC_MAX_PEER_SIZE 2048
+#define FT_MISC_MAX_FRAME_SIZE FT_MISC_MAX_PEER_SIZE/64*56
+#define FT_OTHER_INFO_FLAG 0
+#define FT_IMEI_INFO_FLAG 1
+#define FT_SML_INFO_FLAG 2
+kal_uint8 ft_misc_op_collect_cal_info(FT_MISC_CNF *misc_cnf)
+{
+ kal_char *pcStrPrefix;
+ kal_char *pcStrVerNo;
+ kal_uint8 flag;
+ peer_buff_struct *peer_buff_ret = NULL;
+ kal_char *pdu_ptr = NULL;
+ kal_uint16 pdu_length = 0;
+ kal_uint16 cur_pos = 0;
+ nvram_ltable_entry_struct *entry = NULL;
+ // find the first enrty when the input pointer is NULL pointer
+ while(nvram_util_next_data_item(&entry) == KAL_TRUE)
+ {
+ if(NVRAM_IO_ERRNO_OK != nvram_check_backup(entry->LID, &pcStrPrefix, &pcStrVerNo))
+ {
+ continue;
+ }
+ flag = FT_OTHER_INFO_FLAG;
+ if(entry->LID == NVRAM_EF_IMEI_IMEISV_LID)
+ {
+ flag = FT_IMEI_INFO_FLAG;
+ }
+ else if(entry->LID==NVRAM_EF_SML_LID)
+ {
+ flag = FT_SML_INFO_FLAG;
+ }
+allocate_peer_buf:
+ if(NULL == peer_buff_ret) // allocate peer buffer
+ {
+ peer_buff_ret=construct_peer_buff(FT_MISC_MAX_FRAME_SIZE, 0, 0, TD_CTRL);
+ if(NULL == peer_buff_ret)
+ {
+ return 1;
+ }
+ /* Set the pdu_len to 0 to keep track of the current position and updated at each iteration */
+ peer_buff_ret->pdu_len = 0 ;
+ }
+ if( FT_MISC_MAX_FRAME_SIZE < (peer_buff_ret->pdu_len+3+strlen(pcStrPrefix)+strlen(pcStrVerNo)+1) )
+ {
+ misc_cnf->result.m_u1LastFrame = 0; // set last_frame = 0
+ misc_cnf->status = FT_CNF_OK;
+ // send confirm
+ FT_MISC_SendCnf(misc_cnf, peer_buff_ret);
+ // sleep to wait for tst flush out data
+ kal_sleep_task(50);
+ // allocate peer buffer again
+ peer_buff_ret = NULL;
+ cur_pos = 0;
+ goto allocate_peer_buf;
+ }
+ pdu_ptr = get_peer_buff_pdu( peer_buff_ret, &pdu_length );
+ // copy to peer buffer
+ cur_pos = 0;
+ // copy lid_value (Assertion check to guarantee that the protocol stays unchange)
+ {
+ ASSERT(sizeof(kal_uint16) == sizeof(nvram_lid_enum));
+ kal_mem_cpy(pdu_ptr+pdu_length, &(entry->LID), sizeof(kal_uint16));
+ cur_pos += sizeof(kal_uint16);
+ }
+ // copy file flag
+ {
+ kal_mem_cpy(pdu_ptr+pdu_length+cur_pos, &flag, sizeof(kal_uint8));
+ cur_pos += sizeof(kal_uint8);
+ }
+ // copy file prefix (Assertion check to guarantee that the protocol stays unchange)
+ {
+ ASSERT(strlen(pcStrPrefix) == 4);
+ kal_mem_cpy(pdu_ptr+pdu_length+cur_pos, pcStrPrefix, strlen(pcStrPrefix));
+ cur_pos +=(strlen(pcStrPrefix));
+ }
+ // copy lid Ver No (Assertion check to guarantee that the protocol stays unchange)
+ {
+ ASSERT(strlen(pcStrVerNo) == 3);
+ kal_mem_cpy(pdu_ptr+pdu_length+cur_pos, pcStrVerNo, strlen(pcStrVerNo)+1);
+ cur_pos += (strlen(pcStrVerNo)+1);
+ }
+ // update pdu_len
+ peer_buff_ret->pdu_len += cur_pos;
+ }
+ misc_cnf->result.m_u1LastFrame = 1;
+ misc_cnf->status = FT_CNF_OK;
+ FT_MISC_SendCnf(misc_cnf, peer_buff_ret);
+ return 0;
+}
+/**
+ * Get Number of ADC channels
+ * \return the number of ADC channels
+ */
+kal_uint8 FT_GetAdcMaxChannel(void)
+{
+ // HAL modification
+ DCL_HANDLE adc_handle;
+ ADC_CTRL_GET_MAX_PHYSICAL_CH_T prGetMaxPhyCh;
+ kal_uint8 adc_max_channel;
+ adc_handle = DclSADC_Open(DCL_ADC, FLAGS_NONE);
+ if(DclHADC_Control(adc_handle, ADC_CMD_GET_MAX_PHYSICAL_CH, (DCL_CTRL_DATA_T *)&prGetMaxPhyCh) != STATUS_OK)
+ {
+ // error handling (prevent from access out-of bound)
+ adc_max_channel = 1;
+ return adc_max_channel;
+ }
+ adc_max_channel = prGetMaxPhyCh.u4Adc_max_ch;
+ if(DclSADC_Close(adc_handle) != STATUS_OK)
+ {
+ // error handling (prevent from access out-of bound)
+ adc_max_channel = 1;
+ }
+ return adc_max_channel;
+}
+
+void FT_MISC_Operation(ilm_struct *ptrMsg)
+{
+ kal_wchar wpath[128];
+ FT_MISC_REQ *p_req = (FT_MISC_REQ *)ptrMsg->local_para_ptr;
+ FT_MISC_CNF misc_cnf;
+ memset(&misc_cnf, 0x0, sizeof(misc_cnf));
+ peer_buff_struct *peer_buff_ret = NULL; // default value
+ kal_char *pdu_ptr = NULL;
+ kal_uint16 pdu_length = 0;
+ misc_cnf.type = p_req->type;
+ misc_cnf.status = FT_CNF_FAIL; // default value
+ ft_gl_misc_token = p_req->header.token;
+ MD_TRC_FT_MISC_OP_FUNC(p_req->type);
+
+ switch(p_req->type)
+ {
+ case FT_MISC_OP_GET_IMEI_LOC:
+ {
+ misc_cnf.result.m_u1IMEILoc = nvram_get_imei_type();
+ misc_cnf.status = FT_CNF_OK;
+ break;
+ }
+ case FT_MISC_OP_GET_IMEI_VALUE:
+ {
+ // check the record index (because tools before 0912 causes assertion)
+ kal_uint16 rec_num = nvram_get_imei_record_num();
+ if(p_req->cmd.m_u1RecordIndex < 1 || p_req->cmd.m_u1RecordIndex > rec_num)
+ {
+ // set the record index to 1 (the behavior will be confrom to that of target load before 0909)
+ p_req->cmd.m_u1RecordIndex = 1;
+ }
+ if(KAL_TRUE == nvram_get_imei_value(NVRAM_EF_IMEI_IMEISV_SIZE,
+ misc_cnf.result.m_rIMEIData.buf, p_req->cmd.m_u1RecordIndex))
+ {
+ misc_cnf.result.m_rIMEIData.buf_len = NVRAM_EF_IMEI_IMEISV_SIZE;
+ misc_cnf.status = FT_CNF_OK;
+ }
+ else
+ misc_cnf.status = FT_CNF_FAIL;
+ break;
+
+ }
+#if defined(__MTK_INTERNAL__)
+ case FT_MISC_OP_SET_IMEI_VALUE:
+ {
+ FT_MISC_CNF misc_cnf;
+ misc_cnf.type = FT_MISC_OP_SET_IMEI_VALUE;
+ misc_cnf.result.m_u2RecordIndex = p_req->cmd.m_rIMEIData.record_index;
+ misc_cnf.status = FT_CNF_FAIL;
+
+ kal_uint8 *buffer = (kal_uint8*)get_ctrl_buffer(NVRAM_EF_IMEI_IMEISV_SIZE);
+ memcpy(buffer, p_req->cmd.m_rIMEIData.imei, 8);
+ buffer[8] = p_req->cmd.m_rIMEIData.svn;
+ if( NVRAM_ERRNO_SUCCESS == nvram_external_secure_write_data (NVRAM_EF_IMEI_IMEISV_LID, p_req->cmd.m_rIMEIData.record_index, buffer, NVRAM_EF_IMEI_IMEISV_SIZE, NULL) )
+ {
+ misc_cnf.status = FT_CNF_OK;
+ }
+ free_ctrl_buffer(buffer);
+ FT_MISC_SendCnf(&misc_cnf, NULL);
+ return;
+ }
+#endif //#if defined(__MTK_INTERNAL__)
+ case FT_MISC_OP_GET_IMEI_REC_NUM:
+ {
+ misc_cnf.result.m_u2IMEIRecords = nvram_get_imei_record_num();
+ misc_cnf.status = FT_CNF_OK;
+ break;
+ }
+ case FT_MISC_OP_VERIFY_TEMP_SML_FILE:
+ {
+ //kal_char *pdu_ptr;
+ //kal_uint16 pdu_length;
+ kal_wchar *w_filepath;
+ // get the file path from peer_buffer
+ if(ptrMsg->peer_buff_ptr != NULL)
+ {
+ pdu_ptr = get_peer_buff_pdu( ptrMsg->peer_buff_ptr, &pdu_length );
+
+ // cast to kal_wchar
+ w_filepath = (kal_wchar *)pdu_ptr;
+
+ misc_cnf.status = FT_CNF_OK;
+
+ // ask nvram task to check the SML file
+ if(NVRAM_IO_ERRNO_OK == nvram_validate_file(NVRAM_EF_SML_LID, w_filepath))
+ misc_cnf.result.m_u1VerifyResult = FT_SML_VALID;
+ else
+ misc_cnf.result.m_u1VerifyResult = FT_SML_INVALID;
+
+ }
+ else // peer buffer is null
+ {
+ misc_cnf.status = FT_CNF_FAIL;
+ misc_cnf.result.m_u1VerifyResult = FT_SML_NO_FILENAME;
+ }
+
+ break;
+ }
+ case FT_MISC_OP_GET_CAL_INFO:
+ {
+ ft_misc_op_collect_cal_info(&misc_cnf);
+ return;
+ }
+ case FT_MISC_OP_QUERY_NVRAM_FOLDER:
+ {
+ kal_uint16 length;
+ kal_char* buf;
+ kal_uint8 folder_total_amount = nvram_get_folder_total_amount();
+ kal_int16 total_length = 0;
+ kal_int8 i;
+ misc_cnf.status = FT_CNF_OK;
+
+ // allocate peer buffer
+ if(NULL == peer_buff_ret)
+ {//FT_MISC_MAX_FRAME_SIZE
+ peer_buff_ret = construct_peer_buff(FT_MISC_MAX_FRAME_SIZE, 0, 0, TD_CTRL);
+ if(NULL == peer_buff_ret) return;
+
+ peer_buff_ret->pdu_len = 0 ;
+ }
+ pdu_ptr = get_peer_buff_pdu( peer_buff_ret, &pdu_length );
+ for(i = 0;i<folder_total_amount;i++)
+ {
+ buf = nvram_get_work_path(i);
+ kal_wsprintf(wpath, "%s", buf);
+ if(nvram_check_hidden_file(wpath, KAL_TRUE))
+ {
+ continue;
+ }
+ length = (strlen(buf)+1);
+ kal_mem_cpy(pdu_ptr+pdu_length+total_length, (buf), length );
+ *(pdu_ptr+pdu_length+total_length+length-1) = '?';
+ total_length += length;
+ }
+ // update pdu_len
+ peer_buff_ret->pdu_len += (total_length);
+
+
+ break;
+ }
+ case FT_MISC_OP_VERIFY_NVRAM_ATTR_SETTING_COMPLETE:
+ {
+ kal_uint16 stop_index = custom_meta_check_must_backup_lid_array(p_req->cmd.m_bcheckImeiFlag);
+ if(stop_index == custom_meta_get_check_lid_num()) // check successfully!
+ {
+ misc_cnf.status = FT_CNF_OK;
+ misc_cnf.result.m_rNvramVerifyResult.m_stop_enum_value = custom_meta_get_enum_by_index(stop_index-1); // pass the imei_enum
+ misc_cnf.result.m_rNvramVerifyResult.m_total_lid_num = custom_meta_get_check_lid_num();
+ misc_cnf.result.m_rNvramVerifyResult.m_stop_index = stop_index;
+ }
+ else
+ {
+ misc_cnf.status = FT_CNF_FAIL;
+ misc_cnf.result.m_rNvramVerifyResult.m_stop_enum_value = custom_meta_get_enum_by_index(stop_index);
+ misc_cnf.result.m_rNvramVerifyResult.m_total_lid_num = custom_meta_get_check_lid_num();
+ misc_cnf.result.m_rNvramVerifyResult.m_stop_index = stop_index;
+ }
+ break;
+ }
+ case FT_MISC_OP_ENABLE_PATH_LIMITION:
+ case FT_MISC_OP_DISABLE_PATH_LIMITION:
+ {
+ ft_gl_path_check_flag = (p_req->type == FT_MISC_OP_ENABLE_PATH_LIMITION)?KAL_TRUE:KAL_FALSE;
+ misc_cnf.status = FT_CNF_OK;
+ break;
+ }
+ case FT_MISC_OP_GET_NVRAM_FOLDER_AMOUNT:
+ {
+ kal_uint8 i;
+ misc_cnf.result.m_u1NVRAMFolderAmount = nvram_get_folder_total_amount();
+ for(i = 0;i<nvram_get_folder_total_amount();i++)
+ {
+ kal_wsprintf(wpath, "%s", nvram_get_work_path(i));
+ if(nvram_check_hidden_file(wpath, KAL_TRUE))
+ {
+ misc_cnf.result.m_u1NVRAMFolderAmount--;
+ }
+ }
+ misc_cnf.status = FT_CNF_OK;
+
+ }
+ break;
+#ifndef SIM_NOT_PRESENT
+ case FT_MISC_OP_CHECK_SIM1_INSERTED:
+ {
+ // Send reset request to MOD_SIM
+ ilm_struct ilm_ptr;
+ sim_reset_req_struct* ptr_loc_para;
+ FT_ALLOC_OTHER_MSG(&ilm_ptr, sizeof(sim_reset_req_struct));
+ ptr_loc_para = (sim_reset_req_struct*) (ilm_ptr.local_para_ptr);
+ ptr_loc_para->src_id = 0xff;
+ // set sim cmd type to global variable
+ ft_gl_sim_cmd_type = FT_MISC_OP_CHECK_SIM1_INSERTED;
+ FT_SEND_MSG(MOD_FT, MOD_SIM, PS_SIM_SAP, MSG_ID_SIM_RESET_REQ, &ilm_ptr);
+ // wait for SIM task CNF message
+ return;
+ }
+#ifdef __GEMINI__
+ case FT_MISC_OP_CHECK_SIM2_INSERTED:
+ {
+ // Send reset request to MOD_SIM_2
+ ilm_struct ilm_ptr;
+ sim_reset_req_struct* ptr_loc_para;
+ FT_ALLOC_OTHER_MSG(&ilm_ptr, sizeof(sim_reset_req_struct));
+ ptr_loc_para = (sim_reset_req_struct*) (ilm_ptr.local_para_ptr);
+ ptr_loc_para->src_id = 0xff;
+ // set sim cmd type to global variable
+ ft_gl_sim_cmd_type =FT_MISC_OP_CHECK_SIM2_INSERTED;
+ FT_SEND_MSG(MOD_FT, MOD_SIM_2, PS_SIM_SAP, MSG_ID_SIM_RESET_REQ, &ilm_ptr);
+ // wait for SIM task CNF message
+ return;
+ }
+#endif // __GEMINI__
+#ifdef GEMINI_PLUS
+ case FT_MISC_OP_CHECK_GEMINI_PLUS_SIM_INSERTED:
+ {
+ // Send reset request to MOD_SIM_N
+ ilm_struct ilm_ptr;
+ sim_reset_req_struct* ptr_loc_para;
+ // if index out of range, break and then send error status CNF
+ if(p_req->cmd.m_u1SimIndex >= GEMINI_PLUS)
+ {
+ break;
+ }
+ FT_ALLOC_OTHER_MSG(&ilm_ptr, sizeof(sim_reset_req_struct));
+ ptr_loc_para = (sim_reset_req_struct*) (ilm_ptr.local_para_ptr);
+ ptr_loc_para->src_id = 0xff;
+ // set sim cmd type to global variable
+ ft_gl_sim_cmd_type = FT_MISC_OP_CHECK_GEMINI_PLUS_SIM_INSERTED;
+ FT_SEND_MSG(MOD_FT, (module_type)(MOD_SIM + p_req->cmd.m_u1SimIndex), PS_SIM_SAP, MSG_ID_SIM_RESET_REQ, &ilm_ptr);
+ // wait for SIM task CNF message
+ return;
+ }
+#endif // GEMINI_PLUS
+#endif // SIM_NOT_PRESENT
+ case FT_MISC_OP_SET_MUIC_CHARGER_MODE:
+ {
+#ifdef __DRV_EXT_CHARGER_DETECTION__
+ MU_BQ25040_Charger_Mode(p_req->cmd.m_u1ChargerMode);
+ misc_cnf.status = FT_CNF_OK;
+#else
+ misc_cnf.status = FT_CNF_FAIL;
+
+#endif
+ break;
+ }
+ case FT_MISC_OP_GET_ADC_FROM_EFUSE:
+ {
+ kal_bool b_ret_code;
+ kal_uint8 i;
+ kal_uint8 adc_max_channel;
+ DCL_HANDLE adc_handle;
+ ADC_CTRL_READ_CALIBRATION_DATA_T prReadCalibrationData;
+ adc_handle = DclSADC_Open(DCL_ADC, FLAGS_NONE);
+ adc_max_channel = FT_GetAdcMaxChannel();
+ b_ret_code = (STATUS_OK == DclSADC_Control(adc_handle, ADC_CMD_READ_CALIBRATION_DATA, (DCL_CTRL_DATA_T*)&prReadCalibrationData)) ?
+ KAL_TRUE : KAL_FALSE;
+ misc_cnf.status = FT_CNF_OK;
+ misc_cnf.result.m_rGetAdcFromEfuse.bADCStoredInEfuse = b_ret_code;
+ misc_cnf.result.m_rGetAdcFromEfuse.u2ADCChnNum = b_ret_code ? adc_max_channel : 0;
+
+ // if channel number > 0, construct peer buffer
+ if(misc_cnf.result.m_rGetAdcFromEfuse.u2ADCChnNum > 0) // i.e. FT_GetAdcMaxChannel()
+ {
+ if( NULL != (peer_buff_ret=construct_peer_buff(adc_max_channel*8, 0, 0, TD_CTRL)) )
+ {
+ pdu_ptr = get_peer_buff_pdu( peer_buff_ret, &pdu_length );
+ peer_buff_ret->pdu_len = adc_max_channel *8;
+
+ for(i =0; i< adc_max_channel; i++) // append slope first
+ {
+ kal_mem_cpy(pdu_ptr+(i*4), &(prReadCalibrationData.i4ADCSlope[i]), sizeof(kal_int32));
+ }
+ for(i =0; i<adc_max_channel; i++) // append offset second
+ {
+ kal_mem_cpy(pdu_ptr+((adc_max_channel+i)*4), &(prReadCalibrationData.i4ADCOffset[i]), sizeof(kal_int32));
+ }
+ }
+ }
+ break;
+ }
+ case FT_MISC_OP_GET_CALFLAG_ENUM:
+ {
+ misc_cnf.result.m_u2CalFlagEnum = custom_ft_get_calflag_enum();
+ misc_cnf.status = FT_CNF_OK;
+ }
+ break;
+ case FT_MISC_OP_GET_ADC_MAX_CHANNEL:
+ {
+ // HAL modification
+ misc_cnf.status = FT_CNF_OK;
+ misc_cnf.result.m_u1ADCMaxChannel = FT_GetAdcMaxChannel();
+ break;
+ }
+ case FT_MISC_OP_GET_TADC_INDEX:
+ {
+ // HAL modification
+ //misc_cnf.result.m_u1TADCChannelIndex = custom_adc_get_channel(rftmp_adc_channel);
+ DCL_HANDLE adc_handle;
+ ADC_CTRL_GET_PHYSICAL_CHANNEL_T adc_ch;
+ misc_cnf.status = FT_CNF_OK;
+ adc_handle = DclSADC_Open(DCL_ADC, FLAGS_NONE);
+ adc_ch.u2AdcName = DCL_RFTMP_ADC_CHANNEL;
+ if(DclSADC_Control( adc_handle, ADC_CMD_GET_CHANNEL, (DCL_CTRL_DATA_T *)& adc_ch) != STATUS_OK)
+ {
+ misc_cnf.status = FT_CNF_FAIL;
+ }
+ misc_cnf.result.m_u1TADCChannelIndex = adc_ch.u1AdcPhyCh;
+ if(DclSADC_Close(adc_handle) != STATUS_OK)
+ {
+ misc_cnf.status = FT_CNF_FAIL;
+ }
+ break;
+ }
+ case FT_MISC_OP_GET_RF_CAL_ENV_ENUM:
+ misc_cnf.result.m_u2Enum = custom_ft_get_rf_cal_env_enum();
+ misc_cnf.status = FT_CNF_OK;
+ break;
+ case FT_MISC_OP_GET_RF_CAL_LOSS_SETTING_ENUM:
+ misc_cnf.result.m_u2Enum = custom_ft_get_rf_loss_setting_enum();
+ misc_cnf.status = FT_CNF_OK;
+ break;
+ case FT_MISC_OP_GET_RF_TEST_POWER_RESULT_ENUM:
+ misc_cnf.result.m_u2Enum = custom_ft_get_rf_test_power_result_enum();
+ misc_cnf.status = FT_CNF_OK;
+ break;
+ case FT_MISC_OP_GET_RID:
+ {
+ if(KAL_TRUE == SST_Get_ChipRID((kal_char*)misc_cnf.result.m_rRIDData.buf, (p_req->cmd.m_RIDLength*8)))
+ {
+ misc_cnf.result.m_rRIDData.buf_len = p_req->cmd.m_RIDLength; // return RID length in bytes
+ }
+ else
+ {
+ misc_cnf.result.m_rRIDData.buf_len = 0; // return length = 0 for error check
+ }
+ misc_cnf.status = FT_CNF_OK;
+ break;
+ }
+ case FT_MISC_OP_GET_BARCODE_VALUE:
+ {
+ if(p_req->cmd.m_u1RecordIndex < 1 || p_req->cmd.m_u1RecordIndex > NVRAM_EF_BARCODE_NUM_TOTAL)
+ {
+ p_req->cmd.m_u1RecordIndex = 1;
+ }
+ if( NULL != (peer_buff_ret=construct_peer_buff(NVRAM_EF_BARCODE_NUM_SIZE, 0, 0, TD_CTRL)))
+ {
+ peer_buff_ret->pdu_len = NVRAM_EF_BARCODE_NUM_SIZE;
+ pdu_ptr = get_peer_buff_pdu( peer_buff_ret, &pdu_length );
+ if(KAL_TRUE == nvram_external_read_data(NVRAM_EF_BARCODE_NUM_LID, p_req->cmd.m_u1RecordIndex, (kal_uint8*)pdu_ptr, NVRAM_EF_BARCODE_NUM_SIZE))
+ {
+ misc_cnf.status = FT_CNF_OK;
+ }
+ }
+ break;
+ }
+ case FT_MISC_OP_CHECK_SIM_HW_TEST:
+ {
+#if !defined(SIM_NOT_PRESENT)
+ extern int usim_iftest_for_smt(kal_uint32 SIM_index);
+ kal_int32 status;
+ MD_TRC_FT_MISC_OP_CHECK_SIM_HW_TEST_ENTER_DRV();
+ status = usim_iftest_for_smt(p_req->cmd.m_u1SimIndex);
+ MD_TRC_FT_MISC_OP_CHECK_SIM_HW_TEST_LEAVE_DRV(status);
+ kal_mem_cpy(&(misc_cnf.result.m_i4SimHwStatus), &status, sizeof(kal_int32));
+ misc_cnf.status = FT_CNF_OK;
+#else // #if !defined(SIM_NOT_PRESENT)
+ kal_uint32* pStatus = (kal_uint32*) &(misc_cnf.result.m_i4SimHwStatus);
+ *pStatus = 0;
+ misc_cnf.status = FT_CNF_FAIL;
+#endif // #if defined(SIM_NOT_PRESENT)
+ break;
+ }
+ default:
+ return;
+ }
+ // send confirm to PC side
+ FT_MISC_SendCnf(&misc_cnf, peer_buff_ret);
+}
+
+/**
+ * Check if the function supported
+ * \param query_op_code the OP code to be checked if supported
+ * \retval FT_CNF_FAIL not supported
+ * \retval FT_CNF_OK supported
+ */
+kal_uint32 FT_MiscCheckFunctionSupported(kal_uint32 query_op_code)
+{
+ kal_uint32 cnf_code;
+ if(FT_MISC_OP_END> query_op_code)
+ {
+ if(FT_MISC_OP_SET_IMEI_VALUE == query_op_code)
+ {
+#if defined(__MTK_INTERNAL__)
+ cnf_code = FT_CNF_OK;
+#else
+ cnf_code = FT_CNF_FAIL;
+#endif //#if defined(__MTK_INTERNAL__)
+ }
+ else if(FT_MISC_OP_SET_WIFI_MAC_ADDR == query_op_code)
+ {
+ cnf_code = FT_CNF_FAIL;
+ }
+ else if(FT_MISC_OP_SET_MUIC_CHARGER_MODE == query_op_code)
+ {
+#ifdef __DRV_EXT_CHARGER_DETECTION__
+ cnf_code = FT_CNF_OK;
+#else
+ cnf_code = FT_CNF_FAIL;
+
+#endif
+ }
+ else if(
+ (FT_MISC_OP_GET_RF_CAL_ENV_ENUM == query_op_code) ||
+ (FT_MISC_OP_GET_RF_CAL_LOSS_SETTING_ENUM == query_op_code) ||
+ (FT_MISC_OP_GET_RF_TEST_POWER_RESULT_ENUM == query_op_code)
+ )
+ {
+#ifdef __TC01__
+ cnf_code = FT_CNF_OK;
+#else
+ cnf_code = FT_CNF_FAIL;
+#endif
+ }
+ else if(FT_MISC_OP_GET_MMI_CACHE_ENUM_INDEX == query_op_code)
+ {
+ cnf_code = FT_CNF_FAIL;
+ }
+ else if(FT_MISC_OP_CHECK_SIM_HW_TEST == query_op_code)
+ {
+#if !defined(SIM_NOT_PRESENT)
+ cnf_code = FT_CNF_OK;
+#else // #if !defined(SIM_NOT_PRESENT)
+ cnf_code = FT_CNF_FAIL;
+#endif // #if defined(SIM_NOT_PRESENT)
+ }
+ else if (
+ (FT_MISC_OP_CALDATA_INTEGRITY_START_REC == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_STOP_REC == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_ADD_ONE == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_DEL_ONE == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_DEL_ALL == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_CHECK_ONE == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_CHECK_ALL == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_START_REC_EX == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_STOP_REC_EX == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_ADD_ONE_EX == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_DEL_ONE_EX == query_op_code) ||
+ (FT_MISC_OP_CALDATA_INTEGRITY_DEL_ALL_EX == query_op_code)
+ )
+ {
+ cnf_code = FT_CNF_FAIL;
+ }
+ else
+ {
+ cnf_code = FT_CNF_OK;
+ }
+ }
+ else
+ {
+ cnf_code = FT_CNF_FAIL;
+ }
+ return cnf_code;
+}
+
+/**
+ * Handles the Add on record for other SW modules in target
+ * \param ptrMsg the ILM request message from other module
+ */
+void FT_Misc_CalDataInTargetAddOneRequestHandler(ilm_struct *ptrMsg)
+{
+ ilm_struct ilm_ptr;
+ kal_uint8 uRet = 0;
+ ft_cal_data_add_one_cnf_struct* cnf = NULL;
+
+ FT_ALLOC_OTHER_MSG( &ilm_ptr, sizeof(ft_cal_data_add_one_cnf_struct) );
+ // local parameter
+ cnf = (ft_cal_data_add_one_cnf_struct*)ilm_ptr.local_para_ptr;
+ cnf->status = uRet;
+ FT_SEND_MSG(MOD_FT, ptrMsg->src_mod_id, ptrMsg->sap_id, MSG_ID_FT_CAL_DATA_ADD_ONE_CNF, &ilm_ptr);
+}
+
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_misc_ex.c b/mcu/middleware/meta/ft/src/ft_fnc_misc_ex.c
new file mode 100644
index 0000000..20d7bb8
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_misc_ex.c
@@ -0,0 +1,615 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_misc_ex.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Misc Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "svc_sap.h"
+#include "ft_msgid.h"
+#include "nvram_msgid.h"
+/**************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_misc_ex.h"
+/**************************************************************************
+ * Custom header
+ *************************************************************************/
+#include "meta_customize.h"
+#if defined(__TC01_ERS_SUPPORT__)
+// FIXME: remove the compile option wrapping after GOLF QM
+#include "ers_type.h"
+#include "ers_api.h"
+#endif // #if defined(__TC01_ERS_SUPPORT__)
+
+#if defined(__FS_RAMDISK__)
+// added for ram disk dump
+#include "ramdisk_gprot.h"
+#endif //#if defined(__FS_RAMDISK__)
+
+// INT_SetCmdToSys
+#include "init.h"
+
+kal_uint16 ft_gl_misc_ex_token = 0;
+kal_uint8 *ft_gl_misc_ex_buf = NULL;
+kal_uint8 FT_MISC_EX_SendCnf(FT_MISC_EX_CNF *ft_misc_ret, peer_buff_struct *peer_buff)
+{
+
+ ilm_struct ilm_ptr;
+ FT_MISC_EX_CNF *ptrMsg;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_MISC_EX_CNF));
+
+ /* if ptrMsg != NULL*/
+ ptrMsg = (FT_MISC_EX_CNF *)ilm_ptr.local_para_ptr;
+
+ // assign primitive id
+ ptrMsg->header.ft_msg_id = FT_MISC_EX_CMD_CNF_ID;
+
+ // assign return structure
+ ptrMsg->type = ft_misc_ret->type;
+
+ // copy the result directly without checking its cmd type
+ kal_mem_cpy(&(ptrMsg->result), &(ft_misc_ret->result), sizeof(FT_MISC_EX_CNF_U));
+
+ ptrMsg->status = ft_misc_ret->status;
+
+ // assign peer buffer
+ if( NULL != peer_buff )
+ {
+ ilm_ptr.peer_buff_ptr = peer_buff;
+ }
+
+ FT_SEND_MSG_TO_PC_BY_TOKEN(&ilm_ptr, ft_gl_misc_ex_token);
+ return 0;
+}
+
+#if defined(__TC01_ERS_SUPPORT__)
+void FT_ReadERS_Data(ilm_struct *ptrMsg)
+{
+ kal_uint16 pdu_length_in;
+ kal_char *pdu_ptr_in;
+ FT_MISC_EX_CNF misc_ex_cnf;
+ kal_int32 ers_data_size;
+ kal_uint8 *p_ers_data ;
+ kal_int32 ers_data_idx;
+ kal_uint32 u4CurOffset = 0;
+
+
+
+
+ misc_ex_cnf.type = FT_MISC_EX_OP_GET_ERS_DATA;
+ misc_ex_cnf.status = FT_CNF_FAIL; // default value
+ ers_data_size = ERS_query_size(); //wise_query_ERS_size();
+
+ if( NULL != ptrMsg->peer_buff_ptr )
+ {
+ pdu_ptr_in = get_peer_buff_pdu( ptrMsg->peer_buff_ptr, &pdu_length_in );
+ }
+ kal_mem_cpy(&ers_data_idx, pdu_ptr_in, 4);
+ p_ers_data = (kal_uint8*)ERS_query_content_by_idx(ers_data_idx);//wise_query_ERS_content((WCHAR *)pdu_ptr_in);
+
+ // organize the buffer, and send it sequentially to PC side
+ if(p_ers_data != NULL)
+ {
+ // allocate the peer buffer to send to PC-side
+ while(u4CurOffset < ers_data_size)
+ {
+
+ peer_buff_struct *peer_buff = NULL;
+ kal_char *pdu_ptr = NULL;
+ kal_uint16 pdu_length = 0;
+ kal_uint16 u2_cur_len = FT_MISC_EX_DATA_FRAME_SIZE; // default: 1800 bytes to send
+
+ misc_ex_cnf.result.m_rErsDataFrm.m_u4TotalSize = ers_data_size;
+ misc_ex_cnf.result.m_rErsDataFrm.m_u4CurOffset = u4CurOffset;
+ if(u4CurOffset+FT_MISC_EX_DATA_FRAME_SIZE >= ers_data_size)
+ {
+ misc_ex_cnf.result.m_rErsDataFrm.m_bLastFrm = KAL_TRUE;
+ u2_cur_len = ers_data_size - u4CurOffset;
+ }
+ else
+ misc_ex_cnf.result.m_rErsDataFrm.m_bLastFrm = KAL_FALSE;
+
+ // allocate a peer buffer
+ if( NULL != (peer_buff=construct_peer_buff(u2_cur_len, 0, 0, TD_CTRL)) )
+ {
+ pdu_ptr = get_peer_buff_pdu( peer_buff, &pdu_length );
+ kal_mem_cpy(pdu_ptr, p_ers_data+u4CurOffset , u2_cur_len);
+ peer_buff->pdu_len = u2_cur_len;
+ }
+ misc_ex_cnf.status = FT_CNF_OK;
+ FT_MISC_EX_SendCnf(&misc_ex_cnf, peer_buff);
+ kal_sleep_task(50);
+
+ peer_buff = NULL;// the mem will be released by FT task when copy to TST buffer
+ u4CurOffset += u2_cur_len;
+
+
+ }
+
+ }
+ else
+ {
+ misc_ex_cnf.status = 0xFF;
+ FT_MISC_EX_SendCnf(&misc_ex_cnf, NULL);
+ }
+
+}
+#endif // #if defined(__TC01_ERS_SUPPORT__)
+
+void FT_MiscEx_NvramConfirmHandler(ilm_struct* ptrMsgCnf)
+{
+ FT_MISC_EX_CNF misc_ex_cnf;
+ memset(&misc_ex_cnf,0x0,sizeof(misc_ex_cnf));
+ peer_buff_struct *peer_buff_ret = NULL; // default value
+ misc_ex_cnf.status = FT_CNF_FAIL; // default value
+ switch (ptrMsgCnf->msg_id)
+ {
+ case MSG_ID_NVRAM_SDS_CNF:
+ case MSG_ID_NVRAM_BIN_REGION_CNF:
+ {
+#if !defined(__MODEM_CCCI_EXIST__) || !defined(__MODEM_CARD__)
+ if(!Custom_META_SdsSupported())
+ {
+ misc_ex_cnf.type = FT_MISC_EX_OP_BACKUP_TO_SDS;
+ misc_ex_cnf.status = FT_CNF_FAIL;
+ misc_ex_cnf.result.m_u4SDSStatus = 0;
+ }
+ else
+#endif
+ {
+#if !defined(__MODEM_CCCI_EXIST__) || !defined(__MODEM_CARD__)
+ nvram_sds_cnf_struct* cnf = (nvram_sds_cnf_struct*)ptrMsgCnf->local_para_ptr;
+#else
+ nvram_bin_region_cnf_struct* cnf = (nvram_bin_region_cnf_struct*)ptrMsgCnf->local_para_ptr;
+#endif
+ misc_ex_cnf.type = (FT_MISC_EX_CMD_TYPE)cnf->access_id;
+ misc_ex_cnf.status = FT_CNF_OK;
+ misc_ex_cnf.result.m_u4SDSStatus = cnf->result;
+ }
+ break;
+ }
+ default:
+ return;
+ }
+ FT_MISC_EX_SendCnf(&misc_ex_cnf,peer_buff_ret);
+}
+
+#if defined(__FS_RAMDISK__)
+void FT_Read_RamDisk_Data(ilm_struct *ptrMsg)
+{
+ FT_MISC_EX_CNF misc_ex_cnf;
+ FT_MISC_EX_REQ* p_req = (FT_MISC_EX_REQ *)ptrMsg->local_para_ptr;
+ kal_uint32 u4CurOffset = p_req->cmd.m_u4RamDiskReqOffset;
+ kal_uint32 u4TotalSize = ramdisk_get_raw_length();
+ // allocate the peer buffer to send to PC-side
+ peer_buff_struct *peer_buff = NULL;
+ kal_char *pdu_ptr = NULL;
+ kal_uint16 pdu_length = 0;
+ kal_uint16 u2_cur_len = FT_MISC_EX_DATA_FRAME_SIZE; // default: 1800 bytes to send
+
+ misc_ex_cnf.type = FT_MISC_EX_OP_RAMDISK_READ;
+ misc_ex_cnf.status = FT_CNF_FAIL; // default value
+
+ misc_ex_cnf.result.m_rRamDiskFrm.m_u4TotalSize = u4TotalSize;
+ misc_ex_cnf.result.m_rRamDiskFrm.m_u4CurOffset = u4CurOffset;
+ if(u4CurOffset+FT_MISC_EX_DATA_FRAME_SIZE >= u4TotalSize)
+ {
+ misc_ex_cnf.result.m_rErsDataFrm.m_bLastFrm = KAL_TRUE;
+ u2_cur_len = u4TotalSize - u4CurOffset;
+ }
+ else
+ misc_ex_cnf.result.m_rErsDataFrm.m_bLastFrm = KAL_FALSE;
+
+ // allocate a peer buffer
+ if( NULL != (peer_buff=construct_peer_buff(u2_cur_len, 0, 0, TD_CTRL)) )
+ {
+ pdu_ptr = get_peer_buff_pdu( peer_buff, &pdu_length );
+ peer_buff->pdu_len = u2_cur_len;
+ // read from ram disk
+ if(ramdisk_get_raw_data(pdu_ptr, u4CurOffset, u2_cur_len) > 0 || u2_cur_len == 0)
+ {
+ misc_ex_cnf.status = FT_CNF_OK;
+ }
+ FT_MISC_EX_SendCnf(&misc_ex_cnf, peer_buff);
+ peer_buff = NULL;// the mem will be released by FT task when copy to TST buffer
+ }
+ else
+ {
+ // return fail;
+ FT_MISC_EX_SendCnf(&misc_ex_cnf, NULL);
+ }
+}
+#endif //#if defined(__FS_RAMDISK__)
+void FT_MISC_EX_Operation(ilm_struct *ptrMsg)
+{
+#if defined(__TC01_ERS_SUPPORT__)
+ kal_char* pdu_ptr;
+ kal_uint16 pdu_length;
+#endif // #if defined(__TC01_ERS_SUPPORT__)
+ ilm_struct ptr_ilm;
+ FT_MISC_EX_CNF misc_ex_cnf;
+ memset(&misc_ex_cnf,0x0,sizeof(misc_ex_cnf));
+ FT_MISC_EX_REQ* p_req = (FT_MISC_EX_REQ *)ptrMsg->local_para_ptr;
+ peer_buff_struct* peer_buff_ret = NULL; // default value
+
+ misc_ex_cnf.type = p_req->type;
+ misc_ex_cnf.status = FT_CNF_FAIL;
+ ft_gl_misc_ex_token = p_req->header.token;
+ switch(p_req->type)
+ {
+ case FT_MISC_EX_OP_GET_ERS_COUNT:
+ {
+#if defined(__TC01_ERS_SUPPORT__)
+ misc_ex_cnf.result.m_i4ErsDataCount = ERS_query_count(); //wise_query_ERS_count();
+#else // #if defined(__TC01_ERS_SUPPORT__)
+ misc_ex_cnf.result.m_i4ErsDataCount = 0;
+#endif // #if !defined(__TC01_ERS_SUPPORT__)
+ misc_ex_cnf.status = FT_CNF_OK;
+ break;
+ }
+ case FT_MISC_EX_OP_GET_ERS_DATA_INFO_BY_INDEX:
+ {
+#if defined(__TC01_ERS_SUPPORT__)
+ ers_info_struct ers_info;
+ ERS_query_info(p_req->cmd.m_i4ErsDataIndex, &ers_info);
+ misc_ex_cnf.result.m_rErsDataTime.sec = ers_info.ers_ctime.sec;
+ misc_ex_cnf.result.m_rErsDataTime.min = ers_info.ers_ctime.min;
+ misc_ex_cnf.result.m_rErsDataTime.hour = ers_info.ers_ctime.hour;
+ misc_ex_cnf.result.m_rErsDataTime.day = ers_info.ers_ctime.day;
+ misc_ex_cnf.result.m_rErsDataTime.mon = ers_info.ers_ctime.mon;
+ misc_ex_cnf.result.m_rErsDataTime.wday = ers_info.ers_ctime.wday;
+ misc_ex_cnf.result.m_rErsDataTime.year = ers_info.ers_ctime.year;
+
+ if( NULL != (peer_buff_ret=construct_peer_buff((2+1)*2, 0, 0, TD_CTRL)) ) // defined in mcu\external_mmi\wise\bal\sys\include\ws_dbg_type.h
+ {
+ pdu_ptr = get_peer_buff_pdu( peer_buff_ret, &pdu_length );
+ // copy filename
+ //kal_mem_cpy(pdu_ptr, (void *)ers_info.ers_filename, (kal_wstrlen(ers_info.ers_filename)+1)*2);
+ kal_mem_cpy(pdu_ptr, (void*)&(p_req->cmd.m_i4ErsDataIndex), sizeof(kal_int32));
+ kal_mem_set(pdu_ptr+4, 0x0, 2);
+ peer_buff_ret->pdu_len = 6; //(kal_wstrlen(ers_info.ers_filename)+1)*2;
+ }
+ misc_ex_cnf.status = FT_CNF_OK;
+#else // #if defined(__TC01_ERS_SUPPORT__)
+ misc_ex_cnf.status = FT_CNF_FAIL;
+#endif // #if !defined(__TC01_ERS_SUPPORT__)
+ break;
+ }
+ case FT_MISC_EX_OP_GET_ERS_SIZE:
+ {
+#if defined(__TC01_ERS_SUPPORT__)
+ misc_ex_cnf.result.m_u4ErsDataSize = ERS_query_size(); //wise_query_ERS_size();
+#else // #if defined(__TC01_ERS_SUPPORT__)
+ misc_ex_cnf.result.m_u4ErsDataSize = 0;
+#endif // #if !defined(__TC01_ERS_SUPPORT__)
+ misc_ex_cnf.status = FT_CNF_OK;
+ break;
+ }
+ case FT_MISC_EX_OP_GET_ERS_DATA: // send message to NVRAM task to read ERS data
+ {
+#if defined(__TC01_ERS_SUPPORT__)
+ FT_ReadERS_Data(ptrMsg);
+ return;
+#else // #if defined(__TC01_ERS_SUPPORT__)
+ misc_ex_cnf.status = FT_CNF_FAIL;
+#endif // #if !defined(__TC01_ERS_SUPPORT__)
+ break;
+ }
+
+ case FT_MISC_EX_OP_BACKUP_TO_SDS:
+ {
+#if !defined(__MODEM_CCCI_EXIST__) || !defined(__MODEM_CARD__)
+ if(!Custom_META_SdsSupported())
+ {
+ misc_ex_cnf.status = FT_CNF_FAIL;
+ break;
+ }
+ else
+#endif
+ {
+ nvram_sds_req_struct* ptrMsg;
+ FT_ALLOC_OTHER_MSG(&ptr_ilm,sizeof(nvram_sds_req_struct));
+ ptrMsg = (nvram_sds_req_struct *)ptr_ilm.local_para_ptr;
+ ptrMsg->access_id = (kal_uint8)FT_MISC_EX_OP_BACKUP_TO_SDS;
+ // the access mode is defined in nvram_enums.h (nvram_sds_access_enum)
+ ptrMsg->access_mode = (nvram_sds_access_enum)p_req->cmd.mode;
+#if !defined(__MODEM_CCCI_EXIST__) || !defined(__MODEM_CARD__)
+ FT_SEND_MSG(MOD_FT, MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_SDS_REQ, &ptr_ilm);
+#else
+ FT_SEND_MSG(MOD_FT, MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_BIN_REGION_REQ, &ptr_ilm);
+#endif
+ return;
+ }
+ }
+ /* ram disk dump */
+#if defined(__FS_RAMDISK__)
+ case FT_MISC_EX_OP_RAMDISK_CHECK_EXIST: /**< \brief check ram disk is existing or not */
+ {
+ if(ramdisk_is_existed())
+ {
+ misc_ex_cnf.result.m_cRamDiskExist = 1;
+ }
+ else
+ {
+ misc_ex_cnf.result.m_cRamDiskExist = 0;
+ }
+ misc_ex_cnf.status = FT_CNF_OK;
+ break;
+ }
+ case FT_MISC_EX_OP_RAMDISK_GET_SIZE: /**< \brief get ram disk size */
+ {
+ misc_ex_cnf.result.m_u4RamDiskSize = ramdisk_get_raw_length();
+ if(misc_ex_cnf.result.m_u4RamDiskSize != 0)
+ {
+ misc_ex_cnf.status = FT_CNF_OK;
+ }
+ else
+ {
+ misc_ex_cnf.status = FT_CNF_FAIL;
+ }
+ break;
+ }
+ case FT_MISC_EX_OP_RAMDISK_READ: /**< \brief read from ram disk */
+ {
+ FT_Read_RamDisk_Data(ptrMsg);
+ return;
+ }
+#endif //#if defined(__FS_RAMDISK__)
+ case FT_MISC_EX_OP_SET_COMMAND_TO_SYSTEM: /**< \brief set/clr download flag */
+ {
+ misc_ex_cnf.status = FT_CNF_OK;
+ if(p_req->cmd.m_u4SetCmd2System == 0) // SET_DL_FLAG = 0 set BROM download flag
+ {
+ INT_SetCmdToSys(SYS_CMD_SET_BROM_DL);
+ }
+ else if(p_req->cmd.m_u4SetCmd2System == 1) // CLR_DL_FLAG = 1 clear download flag
+ {
+ INT_SetCmdToSys(SYS_CMD_CLR_DL_FLAG);
+ }
+ else if(p_req->cmd.m_u4SetCmd2System == 2) //SET_DL_FLAG_BL = 2 set Bootloader download flag
+ {
+ INT_SetCmdToSys(SYS_CMD_SET_BROM_DL);
+ }
+ else
+ {
+ misc_ex_cnf.status = FT_CNF_FAIL;
+ }
+ break;
+ }
+ default:
+ return;
+ }
+ FT_MISC_EX_SendCnf(&misc_ex_cnf, peer_buff_ret);
+}
+kal_uint32 FT_MiscExCheckFunctionSupported(kal_uint32 query_op_code)
+{
+ kal_uint32 cnf_code;
+ if(FT_MISC_EX_OP_END> query_op_code)
+ {
+ if( query_op_code == FT_MISC_EX_OP_GET_ERS_SIZE ||
+ query_op_code == FT_MISC_EX_OP_GET_ERS_DATA
+ )
+ {
+#ifdef WISDOM_MMI
+ cnf_code = FT_CNF_OK;
+#else
+ cnf_code = FT_CNF_FAIL;
+#endif
+
+ }
+ else if(query_op_code == FT_MISC_EX_OP_COPY_NVRAM_TO_BP_AREA ||
+ query_op_code == FT_MISC_EX_OP_VERIFY_BP_AREA
+ )
+ {
+ cnf_code = FT_CNF_FAIL;
+
+ }
+ else if(query_op_code == FT_MISC_EX_OP_BACKUP_TO_SDS)
+ {
+#if !defined(__MODEM_CCCI_EXIST__) || !defined(__MODEM_CARD__)
+ if(Custom_META_SdsSupported() != KAL_TRUE)
+ {
+ cnf_code = FT_CNF_FAIL;
+ }
+ else
+#endif
+ {
+ cnf_code = FT_CNF_OK;
+ }
+ }
+ else if(query_op_code == FT_MISC_EX_OP_RAMDISK_CHECK_EXIST ||
+ query_op_code == FT_MISC_EX_OP_RAMDISK_GET_SIZE ||
+ query_op_code == FT_MISC_EX_OP_RAMDISK_READ)
+ {
+#if defined(__FS_RAMDISK__)
+ cnf_code = FT_CNF_OK;
+#else
+ cnf_code = FT_CNF_FAIL;
+#endif
+ }
+ /*******************************
+ * obsoleted op codes
+ ******************************/
+ else if(query_op_code == FT_MISC_EX_OP_OBSOLETED1 ||
+ query_op_code == FT_MISC_EX_OP_OBSOLETED2)
+ {
+ cnf_code = FT_CNF_FAIL;
+ }
+ else if(query_op_code == FT_MISC_EX_OP_SET_COMMAND_TO_SYSTEM)
+ {
+ cnf_code = FT_CNF_OK;
+ }
+ else
+ {
+ cnf_code = FT_CNF_OK;
+ }
+
+ }
+ else
+ {
+ cnf_code = FT_CNF_FAIL;
+ }
+ return cnf_code;
+}
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_mmrf.c b/mcu/middleware/meta/ft/src/ft_fnc_mmrf.c
new file mode 100644
index 0000000..7e39932
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_mmrf.c
@@ -0,0 +1,224 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+ * Modification Notice:
+ * --------------------------
+ * This software is modified by MediaTek Inc. and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2001
+ *
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_mmrf.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Factory testing function for MMRF
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h"
+#include "kal_trace.h"
+#include "svc_sap.h"
+#include "md_mw_sap.h"
+#include "mmrf_msgid.h"
+#include "mmrf_msg_interface.h"
+#include "ft_msgid.h"
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#ifndef L1_SIM
+#include "ft_fnc_nvram.h"
+#include "nvram_defs.h"
+#include "nvram_enums.h"
+#include "nvram_interface.h"
+#include "nvram_data_items.h"
+#include "ft_nvram_def.h"
+#include "nvram_struct.h"
+#endif // #ifndef L1_SIM
+#include "ft_fnc_mmrf.h"
+extern kal_eventgrpid MMRF_UPDATE_RUNTIME_EVENT;
+/**
+ * @param metaMessage the input message from META tool for MMRF test command processing
+ */
+void FT_Mmrf_Operation(ilm_struct* ptrMsg)
+{
+ ilm_struct mmrfMessage;
+ FT_CONSTRUCT_CC_MSG(ptrMsg, &mmrfMessage);
+ FT_SEND_MSG(MOD_FT, MOD_MMRF_XL1TST, FT_MMRF_SAP, MSG_ID_FT_TO_MMRF, &mmrfMessage);
+}
+/**
+ * Confirm message handler for MOD_ETSTM
+ */
+void FT_Mmrf_ConfirmHandler(ilm_struct* mmrfMessage)
+{
+ mmrftst_cnf_struct *ptrMsg;
+ ptrMsg = (mmrftst_cnf_struct *)mmrfMessage->local_para_ptr;
+ if(ptrMsg->type == MMRF_TEST_CMD_CHECK_IF_FUNC_EXIST)
+ {
+ FT_UTILITY_COMMAND_CNF cnf;
+ kal_mem_set(&cnf, '\0', sizeof(cnf));
+ cnf.status = (ptrMsg->result==1)?FT_CNF_OK:FT_CNF_FAIL;
+ cnf.result.CheckIfFuncExist.query_ft_msg_id = ptrMsg->header.ft_msg_id;
+ cnf.result.CheckIfFuncExist.query_op_code = ptrMsg->param.checkIfFuncExist.query_op_code;
+ FT_UTIL_SendCnf(&cnf, NULL);
+ return;
+ }
+ FT_SEND_MSG_TO_PC(mmrfMessage);
+}
+void FT_MmrfCheckFunctionSupported(kal_uint32 query_op_code)
+{
+ ilm_struct ilm_ptr;
+ mmrftst_req_struct *ptrMsg;
+ FT_ALLOC_OTHER_CC_MSG( &ilm_ptr, sizeof(mmrftst_req_struct) );
+ // local parameter
+ ptrMsg = (mmrftst_req_struct *)ilm_ptr.local_para_ptr;
+ ptrMsg->header.ft_msg_id = FT_MMRF_TEST_REQ_ID;
+ ptrMsg->type = MMRF_TEST_CMD_CHECK_IF_FUNC_EXIST;
+ ptrMsg->param.checkIfFuncExist.query_op_code = (MMRfTestCmdType)query_op_code;
+ FT_SEND_MSG(MOD_FT, MOD_MMRF_XL1TST, FT_MMRF_SAP, MSG_ID_FT_TO_MMRF, &ilm_ptr);
+}
+/**
+ * Update Runtime Confirm message handler for MOD_MMRF_XL1TST
+ */
+void FT_Mmrf_UpdateRuntimeHandler(peer_buff_struct* peer_buff, kal_uint16 lid, kal_uint16 rid)
+{
+ ilm_struct ilm_ptr;
+ kal_char* pduToMmrf;
+ kal_char* pduInput;
+ peer_buff_struct* peerToMmrf;
+ mmrf_update_runtime_req_struct* mmrf_update_runtime_req;
+
+ FT_ALLOC_OTHER_CC_MSG(&ilm_ptr, sizeof(mmrf_update_runtime_req_struct));
+ /* set local parameter */
+ mmrf_update_runtime_req = (mmrf_update_runtime_req_struct*)ilm_ptr.local_para_ptr;
+ mmrf_update_runtime_req->nvramLid = lid;
+ mmrf_update_runtime_req->record = rid;
+ /* copy peer buffer */
+ pduInput = get_peer_buff_pdu(peer_buff, NULL);
+ peerToMmrf = construct_cc_non_cached_peer_buff(peer_buff->pdu_len, 0, 0, TD_RESET);
+ pduToMmrf = get_peer_buff_pdu(peerToMmrf, NULL);
+ kal_mem_cpy(pduToMmrf, pduInput, peer_buff->pdu_len);
+ ilm_ptr.peer_buff_ptr = peerToMmrf;
+ FT_SEND_MSG(MOD_FT, MOD_MMRF_XL1TST, FT_MMRF_SAP, MSG_ID_MMRF_UPDATE_RUNTIME_REQ, &ilm_ptr);
+}
+/**
+ * Update Runtime Confirm message handler for MOD_MMRF_XL1TST
+ */
+void FT_Mmrf_UpdateRuntimeConfirmHandler(ilm_struct* _ilm)
+{
+ kal_set_eg_events(MMRF_UPDATE_RUNTIME_EVENT, 0x1, KAL_OR);
+}
+kal_bool FT_Mmrf_PollUpdateRuntimeReady()
+{
+ kal_uint32 ev;
+ kal_sleep_task(1);
+ if(kal_retrieve_eg_events(MMRF_UPDATE_RUNTIME_EVENT, 0x1, KAL_AND_CONSUME, &ev, 0) == KAL_NOT_PRESENT)
+ {
+ return KAL_FALSE;
+ }
+ return KAL_TRUE;
+}
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_nrf.c b/mcu/middleware/meta/ft/src/ft_fnc_nrf.c
new file mode 100644
index 0000000..cbdccf5
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_nrf.c
@@ -0,0 +1,95 @@
+/*****************************************************************************
+ * Copyright Statement:
+ * --------------------
+ * This software is protected by Copyright and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2005
+ *
+ * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+ * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+ * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+ *
+ * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+ * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+ * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+ * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+ * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+ * Modification Notice:
+ * --------------------------
+ * This software is modified by MediaTek Inc. and the information contained
+ * herein is confidential. The software may not be copied and the information
+ * contained herein may not be used or disclosed except with the written
+ * permission of MediaTek Inc. (C) 2001
+ *
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_nr.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Factory testing function for NR
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ *************************************************************************/
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h"
+#include "kal_trace.h"
+#include "ft_msgid.h"
+#include "svc_sap.h"
+#include "md_mw_sap.h"
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_nrf.h"
+/**
+ * @param metaMessage the input message from META tool for NR test command processing
+ */
+void FT_Nrf_Operation(ilm_struct* ptrMsg)
+{
+ #if defined(__MD97__)
+ ilm_struct nrfMessage;
+ FT_CONSTRUCT_CC_MSG(ptrMsg, &nrfMessage);
+ FT_SEND_MSG(MOD_FT, MOD_NL1, NL1_FT_SAP, MSG_ID_FT_TO_NL1, &nrfMessage);
+ #endif //!defined(__MD97__)
+}
+/**
+ * Confirm message handler for MOD_NL
+ */
+void FT_Nrf_ConfirmHandler(ilm_struct* nrfMessage)
+{
+ FT_SEND_MSG_TO_PC(nrfMessage);
+}
\ No newline at end of file
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_nvram.c b/mcu/middleware/meta/ft/src/ft_fnc_nvram.c
new file mode 100644
index 0000000..312fd55
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_nvram.c
@@ -0,0 +1,428 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_nvram.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT NVRAM operations
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#if defined(__MOD_NVRAM__) && !defined(NVRAM_NOT_PRESENT)
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_nvram.h"
+#include "ft_fnc_misc.h"
+#include "svc_sap.h"
+#include "nvram_msgid.h"
+#include "ft_msgid.h"
+#include "ft_trace_def.h"
+#include "ft_fnc_mmrf.h"
+/**************************************************************************
+ * NVRAM header
+ *************************************************************************/
+#include "nvram_defs.h"
+#include "nvram_enums.h"
+#include "nvram_interface.h"
+#include "nvram_data_items.h"
+#include "ft_nvram_def.h"
+#include "l4_nvram_def.h"
+#include "nvram_struct.h"
+void FT_Nvram_SendWriteCommandToNvram(peer_buff_struct* peer_buff, kal_uint16 lid, kal_uint16 rid, kal_uint8 ftAccessId, kal_bool holdBufferForRelay)
+{
+ kal_uint8 *pdu_ptr;
+ kal_uint16 pdu_length;
+ ilm_struct ilm_ptr;
+ nvram_write_cnf_struct *cnf_result_ptr;
+
+ FT_ALLOC_OTHER_MSG(&ilm_ptr, sizeof( nvram_write_cnf_struct ));
+ cnf_result_ptr = (nvram_write_cnf_struct *)ilm_ptr.local_para_ptr;
+ pdu_ptr = get_peer_buff_pdu(peer_buff, &pdu_length);
+ cnf_result_ptr->file_idx = lid;
+ cnf_result_ptr->para = rid;
+ cnf_result_ptr->access_id = ftAccessId;
+
+ /* call secure API to access nvram item */
+ cnf_result_ptr->result = nvram_external_secure_write_data(lid, rid, pdu_ptr, pdu_length, NULL);
+ MD_TRC_FT_NVRAM_CALL_WRITE_NVRAM_API(cnf_result_ptr->result);
+
+ if( holdBufferForRelay != KAL_TRUE)
+ {
+ free_peer_buff(peer_buff);
+ }
+ /* Check polling for MMRF runtime update */
+ FT_SEND_MSG(MOD_FT, MOD_FT, PS_NVRAM_SAP, MSG_ID_NVRAM_WRITE_CNF, &ilm_ptr);
+}
+void FT_Nvram_SendReadCommandToNvram(kal_uint16 lid, kal_uint16 rid, kal_uint8 ftAccessId)
+{
+ nvram_read_cnf_struct cnf_result;
+ peer_buff_struct *peer_buff = NULL;
+ kal_uint8 *pdu_ptr;
+ kal_uint16 totalRID;
+ kal_uint16 pdu_length;
+
+ cnf_result.file_idx = lid;
+ cnf_result.para = rid;
+ cnf_result.length = 0;
+ cnf_result.access_id = ftAccessId;
+ cnf_result.result = nvram_get_info(lid, & totalRID, &pdu_length);
+ if( NVRAM_ERRNO_SUCCESS == cnf_result.result )
+ {
+ if( NULL != (peer_buff=construct_peer_buff(pdu_length, 0, 0, TD_CTRL)) )
+ {
+ pdu_ptr = get_peer_buff_pdu(peer_buff, &pdu_length);
+ cnf_result.length = pdu_length;
+ /* call secure API to access nvram item */
+ cnf_result.result = nvram_external_secure_read_data(lid, rid, pdu_ptr, pdu_length, NULL);
+ }
+ else
+ {
+ cnf_result.result = 0xFA;
+ }
+ }
+ MD_TRC_FT_NVRAM_CALL_READ_NVRAM_API(cnf_result.result);
+
+ if ( NVRAM_ERRNO_SUCCESS != cnf_result.result )
+ {
+ cnf_result.length = 0;
+ peer_buff = NULL;
+ free_peer_buff(peer_buff);
+ FT_Nvram_SendReadResponseToHost(&cnf_result, peer_buff, KAL_TRUE);
+ }
+ else
+ {
+ FT_Nvram_ReadNvramConfirmHandler(&cnf_result, peer_buff);
+ }
+}
+/*******************************************************************************
+ * FUNCTION
+ * FT_Nvram_WriteNvramHandler()
+ *
+ * DESCRIPTION
+ * Handle the write request of NVRAM
+ *
+ * CALLS
+ * None
+ *
+ * PARAMETERS
+ *
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_Nvram_WriteNvramHandler(ft_nvram_write_req_struct_T* req, peer_buff_struct* peer_buff, kal_uint8 accessId)
+{
+ /* Duplicate the message to MMRF for runtime update */
+ FT_Mmrf_UpdateRuntimeHandler(peer_buff, req->file_idx, req->para);
+ FT_Nvram_SendWriteCommandToNvram(peer_buff, req->file_idx, req->para, accessId, KAL_TRUE);
+}
+/*******************************************************************************
+ * FUNCTION
+ * FT_Nvram_ReadNvramHandler()
+ *
+ * DESCRIPTION
+ * Handle the read request of FT to NVRAM
+ *
+ * CALLS
+ * None
+ *
+ * PARAMETERS
+ *
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_Nvram_ReadNvramHandler(ft_nvram_read_req_struct_T* req, kal_uint8 accessId)
+{
+ FT_Nvram_SendReadCommandToNvram(req->file_idx, req->para, accessId);
+}
+void FT_Nvram_SendReadResponseToHost(nvram_read_cnf_struct* nvramReadCnf, peer_buff_struct* nvramReadCnfPeerBuf, kal_bool holdBufferForRelay)
+{
+ ilm_struct ilm_ptr;
+ ft_nvram_read_cnf_struct_T *ft_cnf;
+
+ MD_TRC_FT_NVRAM_SEND_READ_RESPONSE_TO_HOST(holdBufferForRelay);
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_nvram_read_cnf_struct_T));
+ ft_cnf = (ft_nvram_read_cnf_struct_T *)ilm_ptr.local_para_ptr;
+ ft_cnf->header.ft_msg_id = FT_NVRAM_READ_CNF_ID;
+ ft_cnf->file_idx = nvramReadCnf->file_idx;
+ ft_cnf->para = nvramReadCnf->para;
+ /* Check the FILE index to SIM lock */
+ if( nvram_test_lock() && (NVRAM_EF_SML_LID == nvramReadCnf->file_idx) )
+ {
+ ft_cnf->status = 0xFF;
+ ilm_ptr.peer_buff_ptr = NULL;
+ free_peer_buff(nvramReadCnfPeerBuf);
+ }
+ else
+ {
+ ft_cnf->status = nvramReadCnf->result;
+ ilm_ptr.peer_buff_ptr = nvramReadCnfPeerBuf;
+ }
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+/*******************************************************************************
+ * FUNCTION
+ * FT_Nvram_ReadNvramConfirmHandler
+ *
+ * DESCRIPTION
+ * Handle the confirmation of reading
+ *
+ * CALLS
+ *
+ *
+ * PARAMETERS
+ * local_para_struct * local_para_ptr, //( force to nvram_read_cnf_struct* cnf )
+ * peer_buff_struct * peer_buff_ptr
+ *
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_Nvram_ReadNvramConfirmHandler(nvram_read_cnf_struct* nvramReadCnf, peer_buff_struct* nvramReadCnfPeerBuf)
+{
+ ft_gl_token = ft_gl_nvram_token;
+ FT_Nvram_SendReadResponseToHost(nvramReadCnf, nvramReadCnfPeerBuf, KAL_TRUE);
+}
+void FT_Nvram_SendWriteResponseToHost(nvram_write_cnf_struct* nvramWriteCnf)
+{
+ ilm_struct ilm_ptr;
+ ft_nvram_write_cnf_struct_T *ptrMsg ;
+
+ MD_TRC_FT_NVRAM_SEND_WRITE_RESPONSE_TO_HOST();
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_nvram_write_cnf_struct_T));
+ ptrMsg = (ft_nvram_write_cnf_struct_T *)ilm_ptr.local_para_ptr;
+ ptrMsg->header.ft_msg_id = FT_NVRAM_WRITE_CNF_ID;
+ ptrMsg->file_idx = nvramWriteCnf->file_idx;
+ ptrMsg->para = nvramWriteCnf->para;
+ ptrMsg->status = nvramWriteCnf->result;
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+}
+/*******************************************************************************
+ * FUNCTION
+ * FT_Nvram_WriteNvramConfirmHandler
+ *
+ * DESCRIPTION
+ * Handle the confirmation of writting
+ *
+ * CALLS
+ *
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_Nvram_WriteNvramConfirmHandler(nvram_write_cnf_struct* nvramWriteCnf)
+{
+ FT_Nvram_SendWriteResponseToHost(nvramWriteCnf);
+}
+kal_bool FT_Nvram_IsModNvramRespnose(ilm_struct* ilm_ptr)
+{
+ if(ilm_ptr->msg_id == MSG_ID_NVRAM_WRITE_CNF ||
+ ilm_ptr->msg_id == MSG_ID_NVRAM_CREATE_IMAGE_CNF ||
+ ilm_ptr->msg_id == MSG_ID_NVRAM_VERIFY_IMAGE_CNF ||
+ ilm_ptr->msg_id == MSG_ID_NVRAM_RESET_CNF ||
+ ilm_ptr->msg_id == MSG_ID_NVRAM_WRITE_IMEI_CNF ||
+ ilm_ptr->msg_id == MSG_ID_NVRAM_SET_LOCK_CNF ||
+ ilm_ptr->msg_id == MSG_ID_NVRAM_SDS_CNF ||
+ ilm_ptr->msg_id == MSG_ID_NVRAM_BIN_REGION_CNF)
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+#endif // #if defined(__MOD_NVRAM__) && !defined(NVRAM_NOT_PRESENT)
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_nvram_sec.c b/mcu/middleware/meta/ft/src/ft_fnc_nvram_sec.c
new file mode 100644
index 0000000..d2e73cc
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_nvram_sec.c
@@ -0,0 +1,322 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_nvram.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FT NVRAM security mechanism
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#if defined(__NVRAM_SECRET_DATA__)
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_fnc_nvram.h"
+#include "ft_fnc_misc.h"
+#include "svc_sap.h"
+#include "nvram_msgid.h"
+#include "ft_msgid.h"
+#include "ft_fnc_mmrf.h"
+/**************************************************************************
+ * NVRAM header
+ *************************************************************************/
+#include "nvram_defs.h"
+#include "nvram_enums.h"
+#include "nvram_interface.h"
+#include "nvram_data_items.h"
+#include "ft_nvram_def.h"
+#include "nvram_struct.h"
+#include "rc4.h"
+/*******************************************************************************
+ * FUNCTION
+ * FT_NvramSec_WriteNvramHandler()
+ *
+ * DESCRIPTION
+ * Handle the write request of NVRAM
+ *
+ * CALLS
+ * None
+ *
+ * PARAMETERS
+ *
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+kal_uint16 g_u2_ft_nvram_pdu_length = 0;
+kal_uint8 *p_g_u1_ft_nvram_pdu_ptr = NULL;
+peer_buff_struct *p_g_pbs_ft_nvram = NULL;
+void FT_NvramSec_WriteNvramHandler(ft_nvram_write_req_struct_T* req, peer_buff_struct* peer_buff, kal_uint8 accessId)
+{
+ //ilm_struct ilm_ptr;
+ //nvram_write_req_struct *nvram_ptr_loc_para;
+ kal_uint16 pdu_length;
+ kal_uint8 *pdu_ptr = get_peer_buff_pdu( peer_buff, &pdu_length );
+ kal_bool bPassCheck = KAL_FALSE;
+ kal_int32 err_code = 0xFE;
+ kal_uint8 key[256]; // at most 256 bytes
+ kal_int32 real_key_len;
+ real_key_len = custom_nvram_get_database_key(key, sizeof(key));
+ if(req->msg_num == 2 && real_key_len >0) // we must wait until we collect all
+ {
+ if(req->msg_idx == 0) // allocate a peer buffer to store it.
+ {
+ if(p_g_pbs_ft_nvram != NULL) // free previous buffer
+ {
+ free_peer_buff(p_g_pbs_ft_nvram);
+ p_g_pbs_ft_nvram = NULL;
+ }
+ // allocate a new peer buffer
+ if( NULL != (p_g_pbs_ft_nvram=construct_peer_buff(pdu_length, 0, 0, TD_CTRL)) )
+ {
+ p_g_u1_ft_nvram_pdu_ptr = get_peer_buff_pdu( p_g_pbs_ft_nvram, &g_u2_ft_nvram_pdu_length );
+ kal_mem_cpy(p_g_u1_ft_nvram_pdu_ptr, pdu_ptr , pdu_length);
+ p_g_pbs_ft_nvram->pdu_len = pdu_length;
+ }
+ return; // wait for next message
+ }
+ else // the second message with encrpted data
+ {
+ kal_int32 i;
+ RC4_CNXT cnxt;
+ kal_uint8 *output_data = (kal_uint8*) get_ctrl_buffer(g_u2_ft_nvram_pdu_length); // since at most 2k bytes
+ if(p_g_u1_ft_nvram_pdu_ptr!=NULL)
+ {
+ // get the key
+ //real_key_len = custom_nvram_get_database_key(key, sizeof(key));
+ if(real_key_len >0) // get the key
+ {
+ // deciphered the input data
+ che_rc4_set_key((RC4_CNXT *)&cnxt, (kal_uint32)real_key_len, (kal_uint8 *)key);
+ che_rc4((RC4_CNXT *)&cnxt, p_g_u1_ft_nvram_pdu_ptr , g_u2_ft_nvram_pdu_length, key, real_key_len, CHE_MODE_NULL, output_data);
+ for(i=0; i<g_u2_ft_nvram_pdu_length; i++)
+ {
+ if(output_data[i] != pdu_ptr[i])
+ {
+ err_code = 0xFD;
+ break;
+ }
+ }
+ if(i == g_u2_ft_nvram_pdu_length)
+ {
+ bPassCheck = true;
+ }
+ }
+ }
+ else
+ {
+ err_code = 0xFC;
+ }
+ free_ctrl_buffer(output_data);
+ }
+ }
+ else
+ {
+ if(real_key_len == 0) // sec not ON
+ bPassCheck = true;
+ }
+ if(!bPassCheck)
+ {
+ // invoke:
+ nvram_write_cnf_struct cnf_result;
+ cnf_result.file_idx = req->file_idx;
+ cnf_result.para = req->para;
+ cnf_result.result = err_code;
+ // allocate a peer buffer to stored the output data for debug
+ FT_WriteTo_NVRAM_CNF(&cnf_result);
+ return;
+ }
+ if(real_key_len >0 &&
+ req->msg_num == 2 &&
+ p_g_pbs_ft_nvram != NULL) // re-assign the pdu_ptr, and free the buffer
+ {
+ kal_mem_cpy(pdu_ptr, p_g_u1_ft_nvram_pdu_ptr,pdu_length);
+ free_peer_buff(p_g_pbs_ft_nvram);
+ p_g_pbs_ft_nvram = NULL;
+ }
+ /* Duplicate the message to MMRF for runtime update */
+ FT_Mmrf_UpdateRuntimeHandler(peer_buff, req->file_idx, req->para);
+ FT_Nvram_SendWriteCommandToNvram(peer_buff, req->file_idx, req->para, accessId, KAL_TRUE);
+}
+/*******************************************************************************
+ * FUNCTION
+ * FT_NvramSec_ReadNvramHandler()
+ *
+ * DESCRIPTION
+ * Handle the read request of FT to NVRAM
+ *
+ * CALLS
+ * None
+ *
+ * PARAMETERS
+ *
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_NvramSec_ReadNvramHandler(ft_nvram_read_req_struct_T* req, kal_uint8 accessId)
+{
+ //ilm_struct ilm_ptr;
+ //nvram_read_req_struct *ptrMsg;
+ kal_uint8 key[256]; // at most 256 bytes
+ kal_int32 real_key_len;
+ kal_uint8 input_data[4];
+ kal_uint8 output_data[4];
+ kal_uint8 i;
+ RC4_CNXT cnxt;
+ kal_uint32 err_code = 0xFE;
+ kal_bool bPassCheck = KAL_FALSE;
+ real_key_len = custom_nvram_get_database_key(key, sizeof(key));
+ kal_mem_set(output_data, 0x0, sizeof(output_data));
+ // make sure if the authenticaion pass
+ if(req->ciphered_data_valid && real_key_len > 0 ) // the load need to be checked, and user send ciphered data
+ {
+ kal_mem_cpy(input_data, &(req->file_idx), 2);
+ kal_mem_cpy(input_data+2, &(req->para), 2);
+ // deciphered the input data
+ che_rc4_set_key((RC4_CNXT *)&cnxt, (kal_uint32)real_key_len, (kal_uint8 *)key);
+ che_rc4((RC4_CNXT *)&cnxt, input_data , 4, key, real_key_len, CHE_MODE_NULL, output_data);
+ for(i=0; i<4; i++)
+ {
+ if(output_data[i] != req->ciphered_data[i])
+ {
+ err_code = 0xFD;
+ break;
+ }
+ }
+ if(i == 4)
+ bPassCheck = KAL_TRUE;
+ }
+ else // ciphered data invalid
+ {
+ if(real_key_len == 0) // no need to checked
+ bPassCheck = KAL_TRUE;
+ else // need check, but user doesn't send data
+ err_code = 0xFB;
+ }
+ if(!bPassCheck)
+ {
+ // invoke:
+ kal_uint16 pdu_length_new = 0;
+ kal_uint8 *pdu_ptr_new;
+ peer_buff_struct *peer_buff_new;
+ nvram_read_cnf_struct cnf_result;
+ cnf_result.file_idx = req->file_idx;
+ cnf_result.para = req->para;
+ cnf_result.result = err_code;
+ cnf_result.access_id = 0;
+ // allocate a peer buffer to stored the output data for debug
+
+ if( NULL != (peer_buff_new=construct_peer_buff(4, 0, 0, TD_CTRL)) )
+ {
+ pdu_ptr_new = get_peer_buff_pdu( peer_buff_new, &pdu_length_new );
+ kal_mem_cpy(pdu_ptr_new, output_data , 4);
+ peer_buff_new->pdu_len = 4;
+ }
+ FT_ReadFrom_NVRAM_CNF(&cnf_result, peer_buff_new);
+ return;
+ }
+ FT_Nvram_SendReadCommandToNvram(req->file_idx, req->para, accessId);
+}
+#endif // #if defined(__NVRAM_SECRET_DATA__)
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_util.c b/mcu/middleware/meta/ft/src/ft_fnc_util.c
new file mode 100644
index 0000000..1ecceed
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_util.c
@@ -0,0 +1,1131 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_fnc_util.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Factory testing function library (Category: Utility Commands)
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+/*************************************************************************
+* Include Statements for KAL
+ *************************************************************************/
+#include "ctrl_buff_pool.h"
+#include "svc_sap.h"
+#include "ft_msgid.h"
+/**************************************************************************
+ * HAL header
+ *************************************************************************/
+#ifndef L1_SIM
+#include "dcl.h"
+#include "device.h"
+#include "drv_features.h"
+#include "fs_gprot.h"
+#endif //#ifndef L1_SIM
+#include "tst_def.h"
+/**************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#ifndef L1_SIM
+#include "ft_fnc_fat.h"
+#include "ft_fnc_misc.h"
+#include "ft_fnc_misc_ex.h"
+#endif //#ifndef L1_SIM
+#include "ft_fnc_l1rf.h"
+#include "ft_fnc_wcdma.h"
+#include "ft_fnc_lterf.h"
+#include "ft_fnc_tdscdma.h"
+#include "ft_fnc_mmrf.h"
+kal_uint32 FT_UtilCheckFunctionSupported(kal_uint32 query_op_code);
+/**************************************************************************
+ * Custom header
+ *************************************************************************/
+#ifndef L1_SIM
+#include "meta_customize.h"
+#include "custom_equipment.h"
+#endif // #ifndef L1_SIM
+
+kal_uint32 FT_REQUIRED_META_DLL_MAIN_VER = 6;
+kal_uint32 FT_REQUIRED_META_DLL_MINOR_VER = 944;
+kal_uint32 FT_REQUIRED_META_DLL_BUILD_NUM = 0;
+kal_uint32 FT_REQUIRED_VERSION_UNKNOWN = 0xFFFFFFFF;
+kal_uint32 FT_REQUIRED_CTRL_BUFF_MAXSIZE = 35536;
+/*******************************************************************************
+ *
+ * FAT functionality
+ *
+ *******************************************************************************/
+#ifndef L1_SIM /* xl1sim not support FAT */
+/**
+ * Get Path for requested size
+ */
+kal_int16 FT_GetAvailableDrive(kal_int32 size)
+{
+#if !defined(__LOW_COST_SUPPORT_ULC__)
+ kal_int16 drv_letter = -1;
+ kal_int16 i = 0;
+ kal_uint32 dev[4] = {FS_DRIVE_I_SYSTEM, FS_DRIVE_V_NORMAL, FS_DRIVE_V_REMOVABLE, FS_DRIVE_V_EXTERNAL};
+ kal_wchar *pathname = NULL;
+ pathname = (kal_wchar*)get_ctrl_buffer(FT_FAT_MAX_FULLPATH);
+ if(pathname)
+ {
+ for(i=0;i<4;i++)
+ {
+ drv_letter = FS_GetDrive(dev[i], 1, FS_NO_ALT_DRIVE);
+ if(drv_letter > 0)
+ {
+ kal_wsprintf(pathname, "%c:\\", drv_letter);
+ if(size < FT_GetDiskFreeSpace(pathname))
+ {
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ ASSERT(0);
+ }
+ free_ctrl_buffer(pathname);
+ return drv_letter;
+#else // #if !defined(__LOW_COST_SUPPORT_ULC__)
+ return -1;
+#endif // #if defined(__LOW_COST_SUPPORT_ULC__)
+}
+#endif //#ifndef L1_SIM
+/*************************************************************************
+ * FUNCTION
+ * ft_get_ctrlbuf_max_size
+ *
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ * 0: Could not target the maximal size
+ * else: maximal size supported.
+ *
+ * GLOBALS AFFECTED
+ *
+ *************************************************************************/
+kal_uint32 ft_get_ctrlbuf_max_size( void )
+{
+#ifndef L1_SIM
+ kal_int16 i=RPS_CREATED_CTRL_BUFF_POOLS-1;
+
+ /* Total entries defined at adaptation\include\ctrl_buff_pool.h
+ RPS_CREATED_CTRL_BUFF_POOLS = 14
+ For each buffer associated with non-zero entries count, it should have been created,
+ and pool_id always non-zero. */
+ while ( (ctrl_buff_pool_info_g[i].pool_id==0) && (i >= 0) )
+ i--;
+
+ /* Somehow, if table corrupted, must return 0 */
+ if ( i<0 )
+ return 0;
+
+ return (ctrl_buff_pool_info_g[i].size);
+#else // #ifndef L1_SIM
+ return FT_REQUIRED_CTRL_BUFF_MAXSIZE;
+#endif // #ifdef L1_SIM
+}
+
+/*******************************************************************************
+ *
+ * FT task check if function exist
+ *
+ *******************************************************************************/
+kal_uint8 FT_UTIL_SendCnf(const FT_UTILITY_COMMAND_CNF *cnf, peer_buff_struct *p_peer_buff) {
+
+ ilm_struct ilm_ptr;
+ FT_UTILITY_COMMAND_CNF *ptrMsg;
+
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(FT_UTILITY_COMMAND_CNF));
+
+ // if ptrMsg != NULL
+ ptrMsg = (FT_UTILITY_COMMAND_CNF *)ilm_ptr.local_para_ptr;
+
+ // assign primitive id
+ ptrMsg->header.ft_msg_id = FT_UTILITY_COMMAND_CNF_ID;
+
+ // assign return structure
+ ptrMsg->type = cnf->type;
+ ptrMsg->result = cnf->result;
+ ptrMsg->status = cnf->status;
+
+ // assign peer buffer
+ if( NULL != p_peer_buff ) {
+ ilm_ptr.peer_buff_ptr = p_peer_buff;
+ }
+
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+ return 0;
+}
+#ifndef L1_SIM /* xl1sim no device cmd */
+void ft_util_check_if_ulc_support(FT_UTILITY_COMMAND_CNF *cnf)
+{
+#if defined(__LOW_COST_SUPPORT_ULC__)
+ cnf->status = FT_CNF_OK;
+#else
+ cnf->status = FT_CNF_FAIL;
+#endif
+}
+void ft_util_watch_dog_start(FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf,peer_buff_struct *peer_buff_ret)
+{
+ DCL_HANDLE dcl_wdt_handle;
+ WDT_CTRL_SET_VALUE_T interval;
+ WDT_CTRL_ENABLE_T enable;
+ dcl_wdt_handle = DclWDT_Open(DCL_WDT, FLAGS_NONE);
+ if(DCL_HANDLE_INVALID != dcl_wdt_handle) /*DCL_HANDLE_INVALID (-1) define@dcl.h*/
+ {
+ // set interval
+ interval.u2Value = req->cmd.WatchDog.interval;
+ DclWDT_Control(dcl_wdt_handle, WDT_CMD_SET_VALUE, (DCL_CTRL_DATA_T*)&interval);
+ // send confirm first
+ cnf->status = FT_CNF_OK;
+ FT_UTIL_SendCnf(cnf,peer_buff_ret);
+ kal_sleep_task(50);
+ // disable all interrupt mask
+ SaveAndSetIRQMask();
+ // restart timer
+ DclWDT_Control(dcl_wdt_handle, WDT_CMD_RESTART, 0);
+ // enable watch dog count down
+ enable.fgEnable = DCL_TRUE;
+ DclWDT_Control(dcl_wdt_handle, WDT_CMD_ENABLE, (DCL_CTRL_DATA_T*)&enable);
+ DclWDT_Close(dcl_wdt_handle);
+ Custom_META_USBVirtualComDisconnect();
+ while(1);
+ }else
+ {
+ cnf->status = FT_CNF_FAIL;
+ }
+}
+#endif //#ifndef L1_SIM
+kal_int8 ft_util_check_if_func_exist(const FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf)
+{
+ kal_uint32 query_ft_msg_id = req->cmd.CheckIfFuncExist.query_ft_msg_id;
+ kal_uint32 query_op_code = req->cmd.CheckIfFuncExist.query_op_code;
+ cnf->status = FT_CNF_FAIL;
+ switch(query_ft_msg_id) {
+#ifndef L1_SIM
+ case FT_REG_READ_ID:
+ case FT_REG_WRITE_ID:
+ case FT_IS_ALIVE_REQ_ID:
+ case FT_POWER_OFF_REQ_ID:
+ case FT_NVRAM_GET_DISK_INFO_REQ_ID:
+ case FT_NVRAM_RESET_REQ_ID:
+ case FT_NVRAM_LOCK_REQ_ID:
+ case FT_NVRAM_READ_REQ_ID:
+ case FT_NVRAM_WRITE_REQ_ID:
+ case FT_VER_INFO_REQ_ID:
+ case FT_ADC_GETMEADATA_ID:
+ {
+ cnf->status = FT_CNF_OK;
+ break;
+ }
+#if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+ case FT_RF_TEST_REQ_ID:
+ {
+ FT_RfCheckFunctionSupported(query_op_code);
+ return 1; // does not reply message immediately
+ }
+#endif // #if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(__UL1_TASK_DISABLE__)
+ case FT_URF_TEST_REQ_ID:
+ {
+ FT_UL1RfCheckFunctionSuppported(query_op_code);
+ return 1; // does not reply message immediately
+ }
+#endif // #if !defined(__UL1_TASK_DISABLE__)
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+
+ case FT_FAT_OPERATION_ID:
+ if( FT_FAT_OP_OPEN<=query_op_code && FT_FAT_OP_END>query_op_code ) {
+ cnf->status = FT_CNF_OK;
+ }
+ break;
+ case FT_UTILITY_COMMAND_REQ_ID:
+ {
+ cnf->status = FT_UtilCheckFunctionSupported(query_op_code);
+ break;
+ }
+ case FT_MISC_CMD_REQ_ID:
+ {
+ cnf->status = FT_MiscCheckFunctionSupported(query_op_code);
+ break;
+ }
+ case FT_MISC_EX_CMD_REQ_ID:
+ {
+ cnf->status = FT_MiscExCheckFunctionSupported(query_op_code);
+ break;
+ }
+#if defined(__LTE_RAT__)
+#if !defined(__EL1_TASK_DISABLE__)
+ case FT_ERF_TEST_REQ_ID:
+ {
+ FT_ErfCheckFunctionSupported(query_op_code);
+ return 1; // does not reply message immediately
+ }
+#endif // #if !defined(__EL1_TASK_DISABLE__)
+#endif // #if defined(__LTE_RAT__)
+ case FT_MMRF_TEST_REQ_ID:
+ {
+ FT_MmrfCheckFunctionSupported(query_op_code);
+ return 1; // does not reply message immediately
+ }
+#else //#ifndef L1_SIM
+ case FT_IS_ALIVE_REQ_ID:
+ case FT_VER_INFO_REQ_ID:
+ {
+ cnf->status = FT_CNF_OK;
+ break;
+ }
+#if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+ case FT_RF_TEST_REQ_ID:
+ {
+ FT_RfCheckFunctionSupported(query_op_code);
+ return 1; // does not reply message immediately
+ }
+#endif // #if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(__UL1_TASK_DISABLE__)
+ case FT_URF_TEST_REQ_ID:
+ {
+ FT_UL1RfCheckFunctionSuppported(query_op_code);
+ return 1; // does not reply message immediately
+ }
+#endif // #if !defined(__UL1_TASK_DISABLE__)
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+
+ case FT_UTILITY_COMMAND_REQ_ID:
+ {
+ cnf->status = FT_UtilCheckFunctionSupported(query_op_code);
+ break;
+ }
+#if defined(__LTE_RAT__)
+ case FT_ERF_TEST_REQ_ID:
+ {
+ FT_ErfCheckFunctionSupported(query_op_code);
+ return 1; // does not reply message immediately
+ }
+#endif // #if defined(__LTE_RAT__)
+ case FT_MMRF_TEST_REQ_ID:
+ {
+ FT_MmrfCheckFunctionSupported(query_op_code);
+ return 1; // does not reply message immediately
+ }
+#endif //#ifndef L1_SIM
+ case FT_GET_SLA_STATUS_REQ_ID:
+ case FT_GET_SLA_PARA_REQ_ID:
+ case FT_VERIFY_SLA_RND_REQ_ID:
+ case FT_CHECK_SLA_VER_REQ_ID:
+ {
+ cnf->status = FT_CNF_OK;
+ break;
+ }
+ default:
+ cnf->status = FT_CNF_FAIL;
+ break;
+ }
+
+ // assign return structure
+ cnf->result.CheckIfFuncExist.query_ft_msg_id = query_ft_msg_id;
+ cnf->result.CheckIfFuncExist.query_op_code = query_op_code;
+ return 0;
+}
+
+#ifndef L1_SIM /* xl1sim not support */
+void ft_util_check_if_isp_support(FT_UTILITY_COMMAND_CNF *cnf) {
+ /*
+#if defined(ISP_SUPPORT) //&& !defined(YUV_SENSOR_SUPPORT)
+cnf->status = FT_CNF_OK;
+#else
+cnf->status = FT_CNF_FAIL;
+#endif
+*/
+ if(custom_ft_util_check_if_isp_support())
+ cnf->status = FT_CNF_OK;
+ else
+ cnf->status = FT_CNF_FAIL;
+}
+#endif //#ifndef L1_SIM
+void ft_util_check_if_smart_phone_modem_supported(FT_UTILITY_COMMAND_CNF *cnf)
+{
+#if defined(__SMART_PHONE_MODEM__)
+ cnf->status = FT_CNF_OK;
+#else
+ cnf->status = FT_CNF_FAIL;
+#endif
+}
+#ifndef L1_SIM /* xl1sim no power/deivce control */
+void ft_util_query_rtc(FT_UTILITY_COMMAND_CNF *cnf)
+{
+ // HAL modification
+ //RTC_GetTime(&cnf->result.rtc);
+ DCL_HANDLE rtc_handle;
+ RTC_CTRL_GET_TIME_T rtc_cmd_data3; // New Declaration
+ cnf->status = FT_CNF_OK;
+ rtc_handle = DclRTC_Open(DCL_RTC, FLAGS_NONE);
+ if(DclRTC_Control(rtc_handle, RTC_CMD_GET_TIME, (DCL_CTRL_DATA_T *)&rtc_cmd_data3) != STATUS_OK)
+ {
+ cnf->status = FT_CNF_FAIL;
+ }
+ cnf->result.rtc.rtc_year = rtc_cmd_data3.u1Year;
+ cnf->result.rtc.rtc_wday = rtc_cmd_data3.u1WDay;
+ cnf->result.rtc.rtc_mon = rtc_cmd_data3.u1Mon;
+ cnf->result.rtc.rtc_day = rtc_cmd_data3.u1Day;
+ cnf->result.rtc.rtc_hour = rtc_cmd_data3.u1Hour;
+ cnf->result.rtc.rtc_min = rtc_cmd_data3.u1Min;
+ cnf->result.rtc.rtc_sec = rtc_cmd_data3.u1Sec;
+ DclRTC_Close(rtc_handle);
+}
+void ft_util_query_itc_pcl(FT_UTILITY_COMMAND_CNF *cnf)
+{
+ // Phase out on UMOLY
+ cnf->result.rf_pcl = 0xFFFFFFFF;
+ cnf->status = FT_CNF_OK;
+}
+void ft_util_query_pmic_id(FT_UTILITY_COMMAND_CNF *cnf)
+{
+ cnf->result.pmic_id = FT_MT6326;
+ cnf->status = FT_CNF_OK;
+}
+
+void ft_util_set_led_light_level(FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf)
+{
+#if(!defined(__L1_STANDALONE__))
+ kal_uint8 level=0;
+ level=req->cmd.LEDLevel.led_light_level;
+ if(custom_cfg_gpio_set_level(GPIO_DEV_LED_KEY,level))
+ cnf->status = FT_CNF_OK;
+ else
+ cnf->status = FT_CNF_FAIL;
+#endif
+}
+void ft_util_set_vibrator_onoff(FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf)
+{
+#if(!defined(__L1_STANDALONE__))
+ kal_uint8 onoff=0;
+ onoff=req->cmd.VibrOnOff.onoff;
+ if(custom_cfg_gpio_set_level(GPIO_DEV_VIBRATOR,onoff))
+ cnf->status = FT_CNF_OK;
+ else
+ cnf->status = FT_CNF_FAIL;
+#endif
+}
+void ft_util_set_lcd_light_level(FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf)
+{
+#if(!defined(__L1_STANDALONE__))
+ kal_uint8 level=0;
+ kal_uint8 led_type;
+ level=req->cmd.LCDLevel.lcd_light_level;
+ led_type = req->cmd.LCDLevel.lcd_type;
+ if(level>5) level = 5;
+ if(led_type==0)
+ {
+ if(custom_cfg_gpio_set_level(GPIO_DEV_LED_MAINLCD,level))
+ cnf->status = FT_CNF_OK;
+ else
+ cnf->status = FT_CNF_FAIL;
+ }
+ else if(led_type==1)
+ {
+ if(custom_cfg_gpio_set_level(GPIO_DEV_LED_SUBLCD,level))
+ cnf->status = FT_CNF_OK;
+ else
+ cnf->status = FT_CNF_FAIL;
+
+ }
+#endif
+}
+#endif //#ifndef L1_SIM
+void ft_util_check_vers(FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf, peer_buff_struct **pp_peer_buff_ret)
+{
+ META_UTIL_CHECK_TARGET_VER_CNF_T *p_dt = NULL;
+ kal_uint16 pdu_length = 0;
+
+ // allocate peer buffer
+ if(NULL == (*pp_peer_buff_ret = construct_peer_buff(sizeof(META_UTIL_CHECK_TARGET_VER_CNF_T), 0, 0, TD_CTRL)))
+ {
+ cnf->status = FT_CNF_FAIL;
+ return;
+ }
+
+ p_dt = (META_UTIL_CHECK_TARGET_VER_CNF_T *)get_peer_buff_pdu(*pp_peer_buff_ret, &pdu_length);
+ kal_mem_set(p_dt, 0, sizeof(META_UTIL_CHECK_TARGET_VER_CNF_T));
+ p_dt->m_bCheckPass = KAL_TRUE;
+
+ if(req->cmd.m_rCheckMetaVerReq.m_eVerType == META_VERSION_META_DLL_UTIL_VER ||
+ req->cmd.m_rCheckMetaVerReq.m_eVerType == META_VERSION_USER_DEFINE)
+ {
+ // checkin
+ // main version first, if >, pass the check!, if < fail,
+ // if main version is the same, check minor version
+ // if minor version the same, check build number
+
+ if(req->cmd.m_rCheckMetaVerReq.m_u4MainVersion < FT_REQUIRED_META_DLL_MAIN_VER)
+ {
+ p_dt->m_bCheckPass = KAL_FALSE;
+ }
+ else if(req->cmd.m_rCheckMetaVerReq.m_u4MainVersion == FT_REQUIRED_META_DLL_MAIN_VER)
+ {
+ if(req->cmd.m_rCheckMetaVerReq.m_u4MinorVersion < FT_REQUIRED_META_DLL_MINOR_VER)
+ {
+ p_dt->m_bCheckPass = KAL_FALSE;
+ }
+ else if(req->cmd.m_rCheckMetaVerReq.m_u4MinorVersion == FT_REQUIRED_META_DLL_MINOR_VER)
+ {
+ if(req->cmd.m_rCheckMetaVerReq.m_u4BuildNum < FT_REQUIRED_META_DLL_BUILD_NUM)
+ p_dt->m_bCheckPass = KAL_FALSE;
+ }
+ }
+ // assign the target version information
+ p_dt->m_u4TargetMainVersion = FT_REQUIRED_META_DLL_MAIN_VER;
+ p_dt->m_u4TargetMinorVersion = FT_REQUIRED_META_DLL_MINOR_VER;
+ p_dt->m_u4TargetBuildNum = FT_REQUIRED_META_DLL_BUILD_NUM;
+ }
+ else // other type version check // so far, none, just assign version info to 0xFFFFFFFF
+ {
+ // in this case: version check pass
+ p_dt->m_u4TargetMainVersion = FT_REQUIRED_VERSION_UNKNOWN;
+ p_dt->m_u4TargetMinorVersion = FT_REQUIRED_VERSION_UNKNOWN;
+ p_dt->m_u4TargetBuildNum = FT_REQUIRED_VERSION_UNKNOWN;
+ }
+ cnf->status = FT_CNF_OK;
+}
+void ft_util_set_check_paras(FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf)
+{
+ cnf->status = FT_CNF_OK;
+}
+#ifndef L1_SIM /* xl1sim no power control */
+void ft_util_reboot_to_normal_mode(FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf)
+{
+ DCL_HANDLE handle;
+ handle=DclPW_Open(DCL_PW, FLAGS_NONE);
+ /* RCT_PDN2 bit1: make sure the the next boot is IDLE (normal mode) */
+ DclPW_Control(handle,PW_CMD_SET_SWITCH_TO_IDLE,NULL);
+ DclPW_Close(handle);
+ // enable watchdog timer
+ ft_util_watch_dog_start(req, cnf, NULL);
+}
+void ft_util_get_vpa_voltage_list(const FT_UTILITY_COMMAND_REQ *req, FT_UTILITY_COMMAND_CNF *cnf, peer_buff_struct **peer_buff_ret)
+{
+ DCL_HANDLE handle;
+ PMU_CTRL_VPA_GET_VOLTAGE_LIST voltageList;
+ handle=DclPMU_Open(DCL_PMU, FLAGS_NONE);
+ if(DclPMU_Control(handle, VPA_GET_VOLTAGE_LIST, (DCL_CTRL_DATA_T *)&voltageList) != STATUS_OK)
+ {
+ cnf->status = FT_CNF_FAIL;
+ }
+ else
+ {
+ cnf->status = FT_CNF_OK;
+ }
+ DclPMU_Close(handle);
+ if(cnf->status == FT_CNF_OK)
+ {
+ if( NULL != (*peer_buff_ret=construct_peer_buff(sizeof(FtUtilCmdCnfVpaVoltageList), 0, 0, TD_CTRL)) )
+ {
+ kal_uint32 i;
+ FtUtilCmdCnfVpaVoltageList * pdu_ptr = get_peer_buff_pdu( *peer_buff_ret, &((*peer_buff_ret)->pdu_len) );
+ if(pdu_ptr != NULL)
+ {
+ kal_mem_set(pdu_ptr, 0, sizeof(FtUtilCmdCnfVpaVoltageList));
+ for(i=0;i<voltageList.number;i++)
+ {
+ /******************************************************
+ * if the voltage is valid, pass the information to PC
+ *****************************************************/
+ if(voltageList.pVoltageList[i] != PMU_VOLT_INVALID)
+ {
+ pdu_ptr->voltageList[pdu_ptr->validNumber] = voltageList.pVoltageList[i];
+ pdu_ptr->registerValue[pdu_ptr->validNumber] = i;
+ pdu_ptr->validNumber++;
+ }
+ }
+ }
+ else
+ {
+ ASSERT(pdu_ptr);
+ }
+ }
+ else
+ {
+ ASSERT(0);
+ }
+ }
+}
+#endif //#ifndef L1_SIM
+#ifndef L1_SIM
+void FT_UtilityCommand(ilm_struct *ptrMsg) {
+
+ FT_UTILITY_COMMAND_REQ *p_req=(FT_UTILITY_COMMAND_REQ *)ptrMsg->local_para_ptr;
+ FT_UTILITY_COMMAND_CNF cnf;
+ peer_buff_struct *peer_buff_ret = NULL;
+
+ kal_mem_set(&cnf, '\0', sizeof(cnf));
+ cnf.type = p_req->type;
+ cnf.status = FT_CNF_FAIL;
+ peer_buff_ret = NULL;
+
+ switch(p_req->type) {
+ case FT_UTILCMD_CHECK_IF_FUNC_EXIST:
+ if(ft_util_check_if_func_exist(p_req, &cnf))
+ {
+ return;
+ }
+ break;
+ case FT_UTILCMD_CHECK_IF_ISP_SUPPORT:
+ ft_util_check_if_isp_support(&cnf);
+ break;
+ case FT_UTILCMD_ENABLE_WATCHDOG_TIMER:
+ ft_util_watch_dog_start(p_req, &cnf,peer_buff_ret);
+ break;
+ case FT_UTILCMD_CHECK_IF_ACOUSTIC16_SUPPORT:
+ cnf.status = FT_CNF_OK;
+ break;
+ case FT_UTILCMD_CHECK_IF_LOW_COST_SINGLE_BANK_FLASH:
+#ifdef _LOW_COST_SINGLE_BANK_FLASH_
+ cnf.status = FT_CNF_OK;
+#endif
+ break;
+ case FT_UTILCMD_QUERY_PMIC_ID:
+ ft_util_query_pmic_id(&cnf);
+ break;
+ case FT_UTILCMD_LED_LIGHT_LEVEL:
+ ft_util_set_led_light_level(p_req,&cnf);
+ break;
+ case FT_UTILCMD_VIBRATOR_ONOFF:
+ ft_util_set_vibrator_onoff(p_req,&cnf);
+ break;
+ case FT_UTILCMD_QUERY_LOCAL_TIME:
+ ft_util_query_rtc(&cnf);
+ break;
+ case FT_UTILCMD_CHECK_IF_DRC_SUPPORT:
+#if defined(DRC_ENABLED)
+ cnf.status = FT_CNF_OK;
+#endif
+ break;
+ case FT_UTILCMD_MAIN_SUB_LCD_LIGHT_LEVEL:
+ ft_util_set_lcd_light_level(p_req, &cnf);
+ break;
+ case FT_UTILCMD_CHECK_IF_ULC_FAT_SUPPORT:
+ ft_util_check_if_ulc_support(&cnf);
+ break;
+ case FT_UTILCMD_CHECK_IF_SMART_PHONE_MODEM_SUPPORT:
+ ft_util_check_if_smart_phone_modem_supported(&cnf);
+ break;
+ case FT_UTILCMD_CHECK_TARGET_META_REQUIRED_VERS:
+ ft_util_check_vers(p_req,&cnf,&peer_buff_ret);
+ break;
+ case FT_UTILCMD_SET_TARGET_CHECK_PARAS:
+ ft_util_set_check_paras(p_req,&cnf);
+ break;
+ case FT_UTILCMD_CHECK_IF_TARGET_NV_SEC_ON:
+ cnf.result.m_bNVSecOn = KAL_FALSE;
+ cnf.status = FT_CNF_OK;
+ break;
+ case FT_UTILCMD_REBOOT_TO_NORMAL_MODE:
+ ft_util_reboot_to_normal_mode(p_req, &cnf);
+ break;
+ case FT_UTILCMD_QUERY_TARGET_OPTION_INFO:
+ {
+ cnf.result.m_u4TargetOptionInfo = 0; // reset to 0
+#ifdef LIPTON_BB
+ cnf.result.m_u4TargetOptionInfo |= META_LIPTON_OPTION_ON; // 0x00000001
+#endif // #ifdef LIPTON_BB
+#ifdef __TC01__
+ cnf.result.m_u4TargetOptionInfo |= META_TC01_OPTION_ON; // 0x00000002
+#endif // #ifdef __TC01__
+#if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+ if(KAL_TRUE == TL1_IS_3G_TDD_EXIST())
+ {
+ cnf.result.m_u4TargetOptionInfo |= META_AST_TD_OPTION_ON; // 0x00000004
+ }
+#endif // #if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+ cnf.status = FT_CNF_OK;
+ break;
+ }
+ case FT_UTILCMD_QUERY_VPA_VOLTAGE_LIST:
+ {
+ ft_util_get_vpa_voltage_list(p_req, &cnf, &peer_buff_ret);
+ break;
+ }
+ case FT_UTILCMD_QUERY_DRIVE_AVAILABLE_FOR_FILE_SIZE:
+ {
+ cnf.status = FT_CNF_OK;
+ cnf.result.driveLetter = FT_GetAvailableDrive(p_req->cmd.requestedFileSize);
+ break;
+ }
+ case FT_UTILCMD_QUERY_MAX_CTRL_BUFFER_SIZE:
+ {
+ cnf.status = FT_CNF_OK;
+ /*
+ * prevent from customization error
+ */
+ if(ft_get_ctrlbuf_max_size() <= Custom_META_ControlBufferSize())
+ {
+ cnf.result.maxControlBufferSize = ft_get_ctrlbuf_max_size();
+ }
+ else
+ {
+ /*
+ * Keep the original performance
+ */
+ if(Custom_META_ControlBufferSize() < 2048)
+ {
+ cnf.result.maxControlBufferSize = 2048;
+ }
+ else
+ {
+ cnf.result.maxControlBufferSize = Custom_META_ControlBufferSize();
+ }
+ }
+ break;
+ }
+ case FT_UTILCMD_QUERY_ADC_MODULE_SUPPORT:
+ {
+ cnf.status = FT_CNF_OK;
+#if defined(DRV_ADC_NOT_EXIST)||defined(DRV_ADC_OFF)
+ cnf.result.module_support = KAL_FALSE;
+#else
+ cnf.result.module_support = KAL_TRUE;
+#endif // #if defined(DRV_ADC_NOT_EXIST)||defined(DRV_ADC_OFF)
+ break;
+ }
+ case FT_UTILCMD_QUERY_RTC_MODULE_SUPPORT:
+ {
+ cnf.status = FT_CNF_OK;
+#if defined(DRV_RTC_OFF)||defined(DRV_RTC_NOT_EXIST)
+ cnf.result.module_support = KAL_FALSE;
+#else
+ cnf.result.module_support = KAL_TRUE;
+#endif // #if defined(DRV_RTC_NOT_EXIST)||defined(DRV_RTC_OFF)
+ break;
+ }
+ case FT_UTILCMD_QUERY_META_MODE_TRACE:
+ {
+#if defined(__TST_META_MODE_TRACE_ENABLE__)
+ cnf.result.trace_mode = 0;
+ cnf.status = FT_CNF_OK;
+#else
+ cnf.status = FT_CNF_FAIL;
+#endif // #if defined(__TST_META_MODE_TRACE_ENABLE__)
+ break;
+ }
+ case FT_UTILCMD_ENABLE_META_MODE_TRACE:
+ {
+ cnf.status = FT_CNF_FAIL;
+ break;
+ }
+ case FT_UTILCMD_QUERY_MODEM_MODE:
+ {
+ kal_uint8 boot_mode = kal_query_boot_mode();
+ cnf.result.modem_mode = boot_mode;
+ cnf.status = FT_CNF_OK;
+ }
+ default:
+ break;
+ }
+ FT_UTIL_SendCnf(&cnf, peer_buff_ret);
+}
+#else //#ifndef L1_SIM
+void FT_UtilityCommand(ilm_struct *ptrMsg) {
+
+ FT_UTILITY_COMMAND_REQ *p_req=(FT_UTILITY_COMMAND_REQ *)ptrMsg->local_para_ptr;
+ FT_UTILITY_COMMAND_CNF cnf;
+ peer_buff_struct *peer_buff_ret = NULL;
+
+ kal_mem_set(&cnf, '\0', sizeof(cnf));
+ cnf.type = p_req->type;
+ cnf.status = FT_CNF_FAIL;
+ peer_buff_ret = NULL;
+
+ switch(p_req->type) {
+ case FT_UTILCMD_CHECK_IF_FUNC_EXIST:
+ if(ft_util_check_if_func_exist(p_req, &cnf))
+ {
+ return;
+ }
+ break;
+ case FT_UTILCMD_CHECK_IF_SMART_PHONE_MODEM_SUPPORT:
+ ft_util_check_if_smart_phone_modem_supported(&cnf);
+ break;
+ case FT_UTILCMD_CHECK_TARGET_META_REQUIRED_VERS:
+ ft_util_check_vers(p_req,&cnf,&peer_buff_ret);
+ break;
+ case FT_UTILCMD_SET_TARGET_CHECK_PARAS:
+ ft_util_set_check_paras(p_req,&cnf);
+ break;
+ case FT_UTILCMD_QUERY_MAX_CTRL_BUFFER_SIZE:
+ {
+ cnf.status = FT_CNF_OK;
+ cnf.result.maxControlBufferSize = ft_get_ctrlbuf_max_size();
+ break;
+ }
+ default:
+ break;
+ }
+ FT_UTIL_SendCnf(&cnf, peer_buff_ret);
+}
+#endif //#ifndef L1_SIM
+kal_uint32 FT_UtilCheckFunctionSupported(kal_uint32 query_op_code)
+{
+ kal_uint32 cnf_code;
+ if( FT_UTILCMD_END > query_op_code )
+ {
+ switch(query_op_code)
+ {
+ // obsolete
+ case FT_UTILCMD_BT_POWER_ON:
+ cnf_code = FT_CNF_FAIL;
+ break;
+ case FT_UTILCMD_QUERY_BT_WIFI_SINGLE_ANTENNA_CAP:
+ case FT_UTILCMD_SET_ANTENNA_PATH_TO_BT:
+ case FT_UTILCMD_SET_ANTENNA_PATH_TO_WIFI:
+ cnf_code = FT_CNF_FAIL;
+ break;
+ case FT_UTILCMD_QUERY_LIMITED_STATE:
+ {
+ cnf_code = FT_CNF_FAIL;
+ break;
+ }
+#if !defined(__TST_META_MODE_TRACE_ENABLE__)
+ case FT_UTILCMD_QUERY_META_MODE_TRACE:
+ case FT_UTILCMD_ENABLE_META_MODE_TRACE:
+ {
+ cnf_code = FT_CNF_FAIL;
+ break;
+ }
+#endif // #if !defined(__TST_META_MODE_TRACE_ENABLE__)
+ case FT_UTILCMD_RF_ITC_PCL:
+ {
+ cnf_code = FT_CNF_FAIL;
+ break;
+ }
+ default:
+ cnf_code = FT_CNF_OK;
+ break;
+ }
+ }
+ else
+ {
+ cnf_code = FT_CNF_FAIL;
+ }
+ return cnf_code;
+}
diff --git a/mcu/middleware/meta/ft/src/ft_fnc_wcdma.c b/mcu/middleware/meta/ft/src/ft_fnc_wcdma.c
new file mode 100644
index 0000000..2f5cc6c
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_fnc_wcdma.c
@@ -0,0 +1,351 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_fnc_wcdma.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * WCDMA Function
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(__UL1_TASK_DISABLE__)
+
+/*************************************************************************
+* Include Statements for KAL
+ *************************************************************************/
+
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "md_sap.h"
+#include "svc_sap.h"
+#include "ft_msgid.h"
+
+#include "ul1tst_public.h"
+
+
+/*************************************************************************
+* Include Statements for MAUI
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_public.h"
+#include "ft_fnc_wcdma.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+void FT_FtURfTestReq( ilm_struct *ptrMsg )
+{
+ ilm_struct urfMessage;
+ FT_CONSTRUCT_CC_MSG(ptrMsg, &urfMessage);
+ FT_SEND_MSG(MOD_FT, MOD_UL1, FT_UL1TST_SAP, MSG_ID_FT_TO_UL1TST, &urfMessage);
+}
+void FT_UL1TST_SEND_CNF_BACK(ilm_struct *ptrMsg_ul1tst)
+{
+ ft_urf_test_cnf_T *ptrMsg;
+ ptrMsg = (ft_urf_test_cnf_T *)ptrMsg_ul1tst->local_para_ptr;
+ if(ptrMsg->type == URF_TEST_CMD_CHECK_IF_FUNC_EXIST )
+ {
+ FT_UTILITY_COMMAND_CNF cnf;
+ kal_mem_set(&cnf, '\0', sizeof(cnf));
+ cnf.status = (ptrMsg->param.CheckIfFuncExist.result==1)?FT_CNF_OK:FT_CNF_FAIL;
+ cnf.result.CheckIfFuncExist.query_ft_msg_id = ptrMsg->header.ft_msg_id;
+ cnf.result.CheckIfFuncExist.query_op_code = ptrMsg->param.CheckIfFuncExist.query_op_code;
+ FT_UTIL_SendCnf(&cnf, NULL);
+ return;
+ }
+ FT_SEND_MSG_TO_PC(ptrMsg_ul1tst);
+}
+void FT_UL1RfCheckFunctionSuppported(kal_uint32 query_op_code)
+{
+ ilm_struct ilm_ptr;
+ ft_urf_test_req_T *ptrMsg;
+ FT_ALLOC_OTHER_CC_MSG( &ilm_ptr, sizeof(ft_urf_test_req_T) );
+ // local parameter
+ ptrMsg = (ft_urf_test_req_T *)ilm_ptr.local_para_ptr;
+ ptrMsg->header.ft_msg_id = FT_URF_TEST_REQ_ID;
+ ptrMsg->type = URF_TEST_CMD_CHECK_IF_FUNC_EXIST;
+ ptrMsg->param.query_op_code = (URfTestCmdType)query_op_code;
+ FT_SEND_MSG(MOD_FT, MOD_UL1, FT_UL1TST_SAP, MSG_ID_FT_TO_UL1TST, &ilm_ptr);
+}
+#endif // #ifndef (__UL1_TASK_DISABLE__)
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
diff --git a/mcu/middleware/meta/ft/src/ft_main.c b/mcu/middleware/meta/ft/src/ft_main.c
new file mode 100644
index 0000000..1b505a5
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_main.c
@@ -0,0 +1,1887 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ft_main.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#ifndef L1_SIM
+#include "task_config.h"
+#endif // #ifndef L1_SIM
+#include "syscomp_config.h"
+#include "md_mw_sap.h"
+#include "mmrf_msgid.h"
+#include "mmrf_msg_interface.h"
+#include "svc_sap.h"
+#include "ft_msgid.h"
+//#include "wndrv_msgid.h"
+#include "l1hisr_msgid.h"
+#include "sim_public_msgid.h"
+#ifdef L1_SIM
+#include "simul_public.h"
+#endif
+/*************************************************************************
+ * System Service header
+ *************************************************************************/
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_public_defs.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+//MSBB remove #include "fctycomp_config.h"
+#include "stdio.h"
+#ifndef L1_SIM
+#include "init.h"
+#endif // #ifndef L1_SIM
+/*************************************************************************
+ * NVRAM header
+ *************************************************************************/
+#ifndef L1_SIM
+#include "nvram_data_items.h"
+#include "ft_nvram_def.h"
+#include "nvram_struct.h"
+#include "nvram_enums.h"
+#include "nvram_msgid.h"
+#endif // #ifndef L1_SIM
+/*************************************************************************
+ * Custom header
+ *************************************************************************/
+#ifndef L1_SIM
+#include "custom_nvram_config.h"
+#include "custom_equipment.h"
+#endif // #ifndef L1_SIM
+/*************************************************************************
+ * HAL header
+ *************************************************************************/
+#ifndef L1_SIM
+#if !defined(__L1_STANDALONE__)
+#include "device.h" // for GPIO_DEV_LED_MAINLCD and LED_LIGHT_LEVEL5
+#endif
+#endif // #ifndef L1_SIM
+/*************************************************************************
+ * FT header
+ *************************************************************************/
+#include "ft_msg.h"
+#include "ft_mem.h"
+#include "ft_private.h"
+#ifndef L1_SIM
+#include "ft_customize.h"
+#endif // #ifndef L1_SIM
+#include "ft_fnc_l1rf.h"
+#ifndef L1_SIM
+#include "ft_fnc_misc.h"
+#include "ft_fnc_misc_ex.h"
+#include "ft_fnc_custom.h"
+#include "ft_fnc_aux.h"
+#endif // #ifndef L1_SIM
+#include "ft_fnc_wcdma.h"
+#include "ft_fnc_tdscdma.h"
+#ifndef L1_SIM
+#include "ft_fnc_fat.h"
+#include "ft_fnc_nvram.h"
+#endif // #ifndef L1_SIM
+#include "ft_fnc_lterf.h"
+#include "ft_fnc_mmrf.h"
+#include "ft_fnc_nrf.h"
+#include "ft_fnc_l4.h"
+#ifndef L1_SIM
+#include "ft_fnc_c2krf.h"
+fp_nvram_read_handler_t FT_ReadFrom_NVRAM = FT_Nvram_ReadNvramHandler;
+fp_nvram_write_handler_t FT_WriteTo_NVRAM = FT_Nvram_WriteNvramHandler;
+fp_nvram_read_confirm_handler_t FT_ReadFrom_NVRAM_CNF = FT_Nvram_ReadNvramConfirmHandler;
+fp_nvram_write_confirm_handler_t FT_WriteTo_NVRAM_CNF = FT_Nvram_WriteNvramConfirmHandler;
+#endif // #ifndef L1_SIM
+/*************************************************************************
+ * SIM header
+ *************************************************************************/
+#ifndef L1_SIM
+#include "ps2sim_struct.h"
+#endif // #ifndef L1_SIM
+/*************************************************************************
+ * SLA header
+ *************************************************************************/
+#include "meta_sec_support.h"
+/*************************************************************************
+ * Function declaration
+ *************************************************************************/
+void FT_Task(task_entry_struct * task_entry_ptr);
+kal_bool FT_Init(void);
+extern void L1T_DispatchReports(void);
+kal_uint16 ft_gl_token=0;
+kal_uint16 ft_gl_rf_token;
+kal_uint16 ft_gl_l4aud_token;
+kal_uint16 ft_gl_l4aud_ind_token;
+kal_uint16 ft_gl_nvram_token;
+kal_uint16 ft_gl_customer_token;
+kal_uint16 ft_gl_l4aud_current_volume = 3;
+peer_buff_struct *ft_gl_l4aud_peer_buf = NULL;
+extern kal_uint8 ft_gl_sim_cmd_type; // sim cmd type from ft_fnc_misc.c
+
+kal_char g_FT_debug_buf[128];
+kal_uint16 FT_GetGolbalToken(void)
+{
+ return ft_gl_token;
+}
+/*************************************************************************
+ * FUNCTION
+ * ft_create
+ *
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ *
+ *************************************************************************/
+kal_bool ft_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct ft_handler_info =
+ {
+ FT_Task, /* task entry function */
+ FT_Init, /* task initialization function */
+ NULL /* task configuration function */
+ };
+
+ *handle = (comptask_handler_struct *)&ft_handler_info;
+ return KAL_TRUE;
+}
+
+#ifdef L1_SIM
+extern kal_status gs_read_message(module_type, void *, kal_uint16, kal_bool);
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+
+
+/*******************************************************************************
+ * FUNCTION
+ * FT_InitCalibrationData
+ *
+ * DESCRIPTION
+ * The calibration data fetch in power-on stage
+ *
+ * CALLS
+ *
+ * PARAMETERS
+ * None
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+void FT_InitCalibrationData(task_entry_struct *task_entry_ptr)
+{
+#ifndef L1_SIM
+ nvram_startup_req_struct *ptrMsg;
+ ptrMsg = (nvram_startup_req_struct*)construct_local_para(sizeof(nvram_startup_req_struct), TD_CTRL);
+ if(NULL == ptrMsg)
+ {
+ ASSERT(0);
+ }
+ ptrMsg->poweron_mode=NVRAM_POWERON_NORMAL;
+ msg_send5(MOD_FT, MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_STARTUP_REQ, (local_para_struct*)ptrMsg);
+#endif // #ifndef L1_SIM
+}
+
+/*******************************************************************************
+*
+* Local Functions
+*
+*******************************************************************************/
+#ifdef L1_CATCHER
+void Trc_Init(void);
+#endif
+static void FT_Initialization(task_entry_struct *task_entry_ptr)
+{
+ // active module ID in task_active_module_g
+ kal_set_active_module_id(MOD_FT);
+#ifndef L1_SIM
+ FtInitMemoryPool();
+ // custom init
+ FT_CustomInit();
+#if !defined(__L1_STANDALONE__)
+ // enable main LCD backlight
+ custom_cfg_gpio_set_level(GPIO_DEV_LED_MAINLCD, LED_LIGHT_LEVEL5);
+#endif // #if !defined(__L1_STANDALONE__)
+#endif // #ifndef L1_SIM
+#ifdef L1_CATCHER
+ // L1 logging initialization
+ Trc_Init();
+#endif // #ifdef L1_CATCHER
+ FT_InitCalibrationData(task_entry_ptr);
+ FT_InitFtData();
+#if ( defined(__HSDPA_SUPPORT__) || defined(__HSUPA_SUPPORT__) ) && defined(__MODEM_CARD__)
+ /// clear USB download RTC bit for HSPA data card project
+ INT_SetCmdToSys(SYS_CMD_CLR_DL_FLAG);
+#endif // #if ( defined(__HSDPA_SUPPORT__) || defined(__HSUPA_SUPPORT__) ) && defined(__MODEM_CARD__)
+}
+
+extern kal_bool Custom_META_IsSecureOperation(ilm_struct* ptrMsg);
+
+#ifndef L1_SIM
+void FT_DispatchMessage(ilm_struct* ptrMsg)
+{
+ FT_H *ft_header;
+ ft_header=(FT_H *)(ptrMsg->local_para_ptr);
+ /* process messages with specific message ID */
+ switch(ptrMsg->msg_id)
+ {
+ case MSG_ID_FT_CAL_DATA_ADD_ONE_REQ:
+ {
+ FT_Misc_CalDataInTargetAddOneRequestHandler(ptrMsg);
+ return;
+ }
+ case MSG_ID_MMRF_UPDATE_RUNTIME_CNF:
+ {
+ FT_Mmrf_UpdateRuntimeConfirmHandler(ptrMsg);
+ return;
+ }
+ default:
+ break;
+ }
+ /* process message with specific source module ID */
+#if !defined(__DHL_MODULE__)
+ if(ptrMsg->src_mod_id == MOD_TST_READER)
+#else
+ if(ptrMsg->src_mod_id == MOD_DHL)
+#endif // #if !defined(__DHL_MODULE__)
+ {
+ ft_gl_token=ft_header->token;
+#ifdef __META_SLA_ENHANCEMENT__
+ if (FT_MetaSLA_Is_Enabled() && !MetaSLA_Is_Verified())
+ {
+ if(KAL_TRUE == Custom_META_IsSecureOperation(ptrMsg))
+ {
+ dhl_print(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_FT,"[SLA] msg id:%d is dropped since SLA is not verified", ft_header->ft_msg_id);
+ return;
+ }
+ }
+#endif // #ifdef __META_SLA_ENHANCEMENT__
+
+ switch (ft_header->ft_msg_id)
+ {
+ /********************************************
+ * L1 RF test functionality
+ ********************************************/
+#if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+ case FT_RF_TEST_REQ_ID:
+ {
+ FT_Rf_Operation(ptrMsg);
+ break;
+ }
+#endif // #if !defined(__LTE_SM__)&&defined(__MTK_GL1_GSM__)
+ /********************************************
+ * BB test functionality
+ ********************************************/
+ case FT_REG_READ_ID:
+ {
+ FT_FtRegisterRead((ft_RegisterRead_req_T*)ptrMsg->local_para_ptr,FT_BaseBandReg);
+ break;
+ }
+ case FT_REG_WRITE_ID:
+ {
+ FT_FtRegisterWrite((ft_RegisterWrite_req_T*)ptrMsg->local_para_ptr,FT_BaseBandReg);
+ break;
+ }
+ case FT_PMIC_REG_READ_ID:
+ {
+ FT_FtPMICRegisterRead((ft_PMICRegisterRead_req_T*)ptrMsg->local_para_ptr,FT_PMICReg);
+ break;
+ }
+ case FT_PMIC_REG_WRITE_ID:
+ {
+ FT_FtPMICRegisterWrite((ft_PMICRegisterWrite_req_T*)ptrMsg->local_para_ptr,FT_PMICReg);
+ break;
+ }
+ case FT_ADC_GETMEADATA_ID:
+ {
+ FT_FtADC_GetMeaData((ft_FtADC_GetMeaData_req_T*)ptrMsg->local_para_ptr);
+ break;
+ }
+ /********************************************
+ * UL1 RF test functionality
+ ********************************************/
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(__UL1_TASK_DISABLE__)
+ case FT_URF_TEST_REQ_ID:
+ {
+ FT_FtURfTestReq( ptrMsg );
+ break;
+ }
+#endif // #if !defined(__UL1_TASK_DISABLE__)
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+ /********************************************
+ *
+ * NVRAM functionality
+ *
+ ********************************************/
+ case FT_NVRAM_GET_DISK_INFO_REQ_ID:
+ {
+ ilm_struct ilm_ptr;
+ FT_NVRAM_GET_DISK_INFO_CNF *ptr_loc_para;
+ // store nvram token id, because any of NVRAM command won't return immediately.
+ ft_gl_nvram_token = ft_header->token;
+ FT_ALLOC_OTHER_MSG(&ilm_ptr,sizeof(FT_NVRAM_GET_DISK_INFO_CNF));
+ ptr_loc_para=(FT_NVRAM_GET_DISK_INFO_CNF *)(ilm_ptr.local_para_ptr);
+ /* if ptr_ilm != NULL*/
+ ptr_loc_para->header.ft_msg_id=FT_NVRAM_GET_DISK_INFO_CNF_ID;
+#if defined(__MOD_NVRAM__)
+ if(nvram_get_disk_file_info(&(ptr_loc_para->diskfilesize), &(ptr_loc_para->freespace), &(ptr_loc_para->overhead))) {
+ ptr_loc_para->status = 0;
+ }
+ else {
+ ptr_loc_para->diskfilesize = 0;
+ ptr_loc_para->freespace = 0;
+ ptr_loc_para->overhead = 0;
+ ptr_loc_para->status = 1;
+ }
+#endif // #if defined(__MOD_NVRAM__)
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+ break;
+ }
+ case FT_NVRAM_RESET_REQ_ID:
+ {
+ ilm_struct ptr_ilm;
+ nvram_reset_req_struct *ptr_loc_para;
+ // store nvram token id, because any of NVRAM command won't return immediately.
+ ft_gl_nvram_token = ft_header->token;
+ FT_ALLOC_OTHER_MSG(&ptr_ilm,sizeof( nvram_reset_req_struct));
+ /* if ptr_ilm != NULL*/
+ ptr_loc_para=(nvram_reset_req_struct *)(ptr_ilm.local_para_ptr);
+
+ if( ((ft_nvram_reset_req_struct_T*)ptrMsg->local_para_ptr)->reset_category == 0) // reset all
+ {
+
+ ptr_loc_para->reset_category= NVRAM_RESET_ALL;
+ }
+ else if( ((ft_nvram_reset_req_struct_T*)ptrMsg->local_para_ptr)->reset_category == 3) // reset certain
+ {
+
+ ptr_loc_para->reset_category= NVRAM_RESET_CERTAIN;
+ }
+ else if( ((ft_nvram_reset_req_struct_T*)ptrMsg->local_para_ptr)->reset_category == 4) // reset factory
+ {
+ ptr_loc_para->reset_category= NVRAM_RESET_FACTORY;
+ }
+ else
+ {
+ destroy_ilm(&ptr_ilm);
+ break; // directly break!, Let PC side timeout!
+ }
+ ptr_loc_para->app_id = NVRAM_APP_RESERVED;
+ ptr_loc_para->LID=((ft_nvram_reset_req_struct_T*)ptrMsg->local_para_ptr)->file_idx;
+ FT_SEND_MSG(MOD_FT, MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_RESET_REQ, &ptr_ilm);
+ break;
+ }
+ case FT_NVRAM_READ_REQ_ID:
+ {
+ ft_gl_nvram_token = ft_header->token;
+ FT_ReadFrom_NVRAM((ft_nvram_read_req_struct_T*)ptrMsg->local_para_ptr, 0);
+ break;
+ }
+ case FT_NVRAM_WRITE_REQ_ID:
+ {
+ ft_gl_nvram_token = ft_header->token;
+ FT_WriteTo_NVRAM((ft_nvram_write_req_struct_T*)ptrMsg->local_para_ptr, ptrMsg->peer_buff_ptr, 0);
+ break;
+ }
+ case FT_NVRAM_LOCK_REQ_ID:
+ {
+ ilm_struct ptr_ilm;
+ nvram_set_lock_req_struct *ptr_loc_para;
+ ft_nvram_lock_req_struct_T *ptr_msg = (ft_nvram_lock_req_struct_T *)(ptrMsg->local_para_ptr);
+ // store nvram token id, because NVRAM command won't return immediately.
+ ft_gl_nvram_token = ft_header->token;
+ FT_ALLOC_OTHER_MSG(&ptr_ilm, sizeof(nvram_set_lock_req_struct));
+ /* if ptr_ilm != NULL*/
+ ptr_loc_para=(nvram_set_lock_req_struct *)(ptr_ilm.local_para_ptr);
+ // if OTP lock or NVRAM lock
+ if( NVRAM_LOCK_OTP == ptr_msg->lock_en ) {
+ ptr_loc_para->lock_en = NVRAM_LOCK_OTP;
+ }
+ else {
+ ptr_loc_para->lock_en = NVRAM_LOCK_ENABLE;
+ }
+ FT_SEND_MSG(MOD_FT, MOD_NVRAM, PS_NVRAM_SAP, MSG_ID_NVRAM_SET_LOCK_REQ, &ptr_ilm);
+ break;
+ }
+ /********************************************
+ *
+ * FAT functionality
+ *
+ ********************************************/
+ case FT_FAT_OPERATION_ID:
+ {
+ FT_FAT_Operation((FT_FAT_OPERATION *)ptrMsg->local_para_ptr, ptrMsg->peer_buff_ptr);
+ break;
+ }
+ /********************************************
+ *
+ * Version Info functionality
+ *
+ ********************************************/
+ case FT_VER_INFO_REQ_ID:
+ {
+ FT_GetVersionInfo();
+ break;
+ }
+ /********************************************
+ *
+ * FT task test alive
+ *
+ ********************************************/
+ case FT_IS_ALIVE_REQ_ID:
+ {
+ FT_TestAlive();
+ break;
+ }
+ /********************************************
+ *
+ * FT task Power Off
+ *
+ ********************************************/
+ case FT_POWER_OFF_REQ_ID:
+ {
+ FT_PowerOff();
+ break;
+ }
+ /********************************************
+ *
+ * FT task utility command
+ *
+ ********************************************/
+ case FT_UTILITY_COMMAND_REQ_ID:
+ {
+ FT_UtilityCommand(ptrMsg);
+ break;
+ }
+ /********************************************
+ *
+ * Misc utility command
+ *
+ ********************************************/
+ case FT_MISC_CMD_REQ_ID:
+ {
+ FT_MISC_Operation(ptrMsg);
+ break;
+ }
+ /********************************************
+ *
+ * Misc EX utility command
+ *
+ ********************************************/
+ case FT_MISC_EX_CMD_REQ_ID:
+ {
+ FT_MISC_EX_Operation(ptrMsg);
+ break;
+ }
+ case FT_CUSTOM_REQ_ID:
+ {
+ // send message to FTC task
+ ft_gl_customer_token = ft_header->token;
+ FT_Custom_Operation(ptrMsg);
+ break;
+ }
+#if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+ case FT_AUX_REQ_ID:
+ {
+ if(KAL_TRUE == TL1_IS_3G_TDD_EXIST()) //20130206
+ {
+ // send message to FTA task
+ ft_gl_customer_token = ft_header->token;
+ FT_Aux_Operation(ptrMsg);
+ }
+ else
+ {
+ sprintf(g_FT_debug_buf, "[FT_DispatchMessage][FT_AUX_REQ_ID] HW TDD does not exist.");
+ tst_sys_trace(g_FT_debug_buf);
+ }
+ break;
+ }
+#endif // #if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+#if defined(__LTE_RAT__) || defined(L1_SIM)
+ case FT_ERF_TEST_REQ_ID:
+ {
+ FT_Erf_Operation(ptrMsg);
+ break;
+ }
+ case FT_PHY_TOOL_REQ_ID:
+ {
+ FT_PhyTool_Operation(ptrMsg);
+ break;
+ }
+#endif // #if defined(__LTE_RAT__)
+
+#if defined(__C2K_RAT__)
+ case FT_CRF_TEST_REQ_ID:
+ {
+ FT_Crf_Operation(ptrMsg);
+ break;
+ }
+#endif // #if defined(__C2K_RAT__)
+
+ case FT_MMRF_TEST_REQ_ID:
+ {
+ FT_Mmrf_Operation(ptrMsg);
+ break;
+ }
+
+ case FT_NRF_TEST_REQ_ID:
+ {
+ FT_Nrf_Operation(ptrMsg);
+ break;
+ }
+#if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT) || defined(DUMMY_PROTOCOL)
+ case FT_L4_ATCMD_REQ_ID:
+ {
+ FT_L4_Operation(ptrMsg);
+ break;
+ }
+#endif // #if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT)
+
+ case FT_GET_SLA_STATUS_REQ_ID:
+ {
+ FT_GetSlaStatus();
+ break;
+ }
+
+ case FT_CHECK_SLA_VER_REQ_ID:
+ {
+ FT_CheckSlaVer((FT_CHECK_SLA_VER_REQ *)ptrMsg->local_para_ptr);
+ break;
+ }
+
+ case FT_GET_SLA_PARA_REQ_ID:
+ {
+ FT_GetSlaPara();
+ break;
+ }
+
+ case FT_VERIFY_SLA_RND_REQ_ID:
+ {
+ FT_VerifySla((FT_VERIFY_SLA_RND_REQ *)ptrMsg->local_para_ptr);
+ break;
+ }
+
+ default:
+ {
+ dhl_print(TRACE_INFO, DHL_USER_FLAG_NONE, MOD_FT,"[SLA] unknown msg id:%d", ft_header->ft_msg_id);
+ FT_SendDeniedMsgIdCnf(ft_header->ft_msg_id, FT_CNF_NOT_SUPPORTED);
+ break;
+ }
+ }
+ }
+ else if( (ptrMsg->src_mod_id == MOD_FTC) )
+ {
+ ft_gl_token = ft_gl_customer_token;
+ FT_Handle_FTC_CNF(ptrMsg);
+ ptrMsg->peer_buff_ptr=NULL; /* make sure the TST will release the mem*/
+ }
+
+#if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+ else if( (ptrMsg->src_mod_id == MOD_FTA) )
+ {
+ ft_gl_token = ft_gl_customer_token;
+ FT_Handle_FTA_CNF(ptrMsg);
+ ptrMsg->peer_buff_ptr=NULL; /* make sure the TST will release the mem*/
+ }
+#endif // #if defined(__UMTS_TDD128_MODE__) && defined(__AST_TL1_TDD__)
+#if defined(__MOD_NVRAM__)
+ else if( KAL_TRUE == FT_Nvram_IsModNvramRespnose(ptrMsg) )
+ {
+ switch (ptrMsg->msg_id)
+ {
+ case MSG_ID_NVRAM_WRITE_CNF:
+ {
+ nvram_write_cnf_struct* msg_ptr = NULL;
+ ft_gl_token = ft_gl_nvram_token;
+ msg_ptr=(nvram_write_cnf_struct*)ptrMsg->local_para_ptr;
+ /* Check MMRF runtime update */
+ if( KAL_FALSE == FT_Mmrf_PollUpdateRuntimeReady() )
+ {
+ hold_local_para(ptrMsg->local_para_ptr);
+ FT_SEND_MSG(MOD_FT, MOD_FT, PS_NVRAM_SAP, MSG_ID_NVRAM_WRITE_CNF, ptrMsg);
+ break;
+ }
+ FT_WriteTo_NVRAM_CNF(msg_ptr);
+ break;
+ }
+ case MSG_ID_NVRAM_RESET_CNF:
+ {
+ nvram_reset_cnf_struct* msg_ptr;
+ ilm_struct ilm_ptr;
+ ft_nvram_reset_cnf_struct_T* pMsg;
+ ft_gl_token = ft_gl_nvram_token;
+ msg_ptr=(nvram_reset_cnf_struct*)ptrMsg->local_para_ptr;
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_nvram_reset_cnf_struct_T));
+ pMsg=(ft_nvram_reset_cnf_struct_T*)ilm_ptr.local_para_ptr;
+ pMsg->header.ft_msg_id=FT_NVRAM_RESET_CNF_ID;
+ pMsg->status = msg_ptr->result;
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+ break;
+ }
+ case MSG_ID_NVRAM_SET_LOCK_CNF:
+ {
+ nvram_set_lock_cnf_struct* msg_ptr;
+ ilm_struct ilm_ptr;
+ ft_nvram_lock_cnf_struct_T* pMsg;
+ ft_gl_token = ft_gl_nvram_token;
+ msg_ptr=(nvram_set_lock_cnf_struct*)ptrMsg->local_para_ptr;
+ FT_ALLOC_MSG(&ilm_ptr, sizeof(ft_nvram_lock_cnf_struct_T));
+ pMsg=(ft_nvram_lock_cnf_struct_T*)ilm_ptr.local_para_ptr;
+ pMsg->header.ft_msg_id=FT_NVRAM_LOCK_CNF_ID;
+ pMsg->status = msg_ptr->result;
+ FT_SEND_MSG_TO_PC(&ilm_ptr);
+ break;
+ }
+#if defined(__MTK_INTERNAL__)
+ case MSG_ID_NVRAM_WRITE_IMEI_CNF:
+ {
+ nvram_write_imei_cnf_struct* msg_ptr;
+ FT_MISC_CNF misc_cnf;
+ msg_ptr=(nvram_write_imei_cnf_struct*)ptrMsg->local_para_ptr;
+ misc_cnf.type = FT_MISC_OP_SET_IMEI_VALUE;
+ if(msg_ptr->result == NVRAM_ERRNO_SUCCESS)
+ {
+ misc_cnf.result.m_u2RecordIndex = msg_ptr->record_index;
+ misc_cnf.status = FT_CNF_OK;
+ }
+ else
+ {
+ misc_cnf.result.m_u2RecordIndex = msg_ptr->result;
+ misc_cnf.status = FT_CNF_FAIL;
+ }
+ FT_MISC_SendCnf(&misc_cnf, NULL);
+ break;
+ }
+#endif //#if defined(__MTK_INTERNAL__)
+ case MSG_ID_NVRAM_SDS_CNF:
+ case MSG_ID_NVRAM_BIN_REGION_CNF:
+ {
+ FT_MiscEx_NvramConfirmHandler(ptrMsg);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#endif // end of #if defined(__MOD_NVRAM__)
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(__UL1_TASK_DISABLE__)
+ else if( (ptrMsg->src_mod_id == MOD_UL1) )
+ {
+ FT_UL1TST_SEND_CNF_BACK(ptrMsg);
+ }
+#endif // #if !defined(__UL1_TASK_DISABLE__)
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+ else if( (ptrMsg->src_mod_id == MOD_L1) )
+ {
+ FT_Rf_ConfirmHandler(ptrMsg);
+ }
+#endif // #if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+#ifndef SIM_NOT_PRESENT
+ else if( (ptrMsg->src_mod_id == MOD_SIM) && (ft_gl_sim_cmd_type != FT_MISC_OP_CHECK_GEMINI_PLUS_SIM_INSERTED))
+ {
+ switch (ptrMsg->msg_id)
+ {
+ case MSG_ID_SIM_RESET_CNF:
+ {
+ FT_MISC_CNF misc_cnf;
+ sim_reset_cnf_struct *msg_ptr;
+ msg_ptr=(sim_reset_cnf_struct*)ptrMsg->local_para_ptr;
+ misc_cnf.type = FT_MISC_OP_CHECK_SIM1_INSERTED;
+ misc_cnf.result.m_u1SIMInserted = (kal_bool)msg_ptr->is_sim_inserted; // get SIM inserted status here. 1:insert , 0: not insert
+ misc_cnf.status = FT_CNF_OK;
+ FT_MISC_SendCnf(&misc_cnf, NULL);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+#ifdef __GEMINI__
+ else if((ptrMsg->src_mod_id == MOD_SIM_2) && (ft_gl_sim_cmd_type != FT_MISC_OP_CHECK_GEMINI_PLUS_SIM_INSERTED))
+ {
+ switch (ptrMsg->msg_id)
+ {
+ case MSG_ID_SIM_RESET_CNF:
+ {
+ FT_MISC_CNF misc_cnf;
+ sim_reset_cnf_struct *msg_ptr;
+ msg_ptr=(sim_reset_cnf_struct*)ptrMsg->local_para_ptr;
+ misc_cnf.type = FT_MISC_OP_CHECK_SIM2_INSERTED;
+ misc_cnf.result.m_u1SIMInserted = (kal_bool)msg_ptr->is_sim_inserted; // get SIM inserted status here. 1:insert , 0: not insert
+ misc_cnf.status = FT_CNF_OK;
+ FT_MISC_SendCnf(&misc_cnf, NULL);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#endif // __GEMINI__
+#ifdef GEMINI_PLUS
+ else if((ptrMsg->src_mod_id >= MOD_SIM) && (ptrMsg->src_mod_id < MOD_SIM + GEMINI_PLUS) &&
+ (ft_gl_sim_cmd_type == FT_MISC_OP_CHECK_GEMINI_PLUS_SIM_INSERTED))
+ {
+ switch (ptrMsg->msg_id)
+ {
+ case MSG_ID_SIM_RESET_CNF:
+ {
+ FT_MISC_CNF misc_cnf;
+ sim_reset_cnf_struct *msg_ptr;
+ msg_ptr=(sim_reset_cnf_struct*)ptrMsg->local_para_ptr;
+ misc_cnf.type = FT_MISC_OP_CHECK_GEMINI_PLUS_SIM_INSERTED;
+ misc_cnf.result.m_u1SIMInserted = (kal_bool)msg_ptr->is_sim_inserted; // get SIM inserted status here. 1:insert , 0: not insert
+ misc_cnf.status = FT_CNF_OK;
+ FT_MISC_SendCnf(&misc_cnf, NULL);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#endif // GEMINI_PLUS
+#endif // SIM_NOT_PRESENT
+#if defined(__LTE_RAT__)
+ else if( MOD_EL1== ptrMsg->src_mod_id )
+ {
+ FT_Erf_ConfirmHandler(ptrMsg);
+ }
+#endif // #if defined(__LTE_RAT__)
+
+#if defined(__C2K_RAT__)
+ else if( MOD_CL1TST == ptrMsg->src_mod_id )
+ {
+ FT_Crf_ConfirmHandler(ptrMsg);
+ }
+#endif // #if defined(__C2K_RAT__)
+
+ else if( MOD_MMRF_XL1TST == ptrMsg->src_mod_id )
+ {
+ FT_Mmrf_ConfirmHandler(ptrMsg);
+ }
+
+#if defined(__MD97__)
+ else if( MOD_NL1 == ptrMsg->src_mod_id )
+ {
+ FT_Nrf_ConfirmHandler(ptrMsg);
+ }
+#endif // #if !defined(__MD97__)
+
+#if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT) || defined(DUMMY_PROTOCOL)
+ else if( MOD_L4C == ptrMsg->src_mod_id )
+ {
+ FT_L4_Operation(ptrMsg);
+ }
+#endif // #if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT)
+
+}
+#else
+void FT_DispatchMessage(ilm_struct* ptrMsg)
+{
+ FT_H *ft_header;
+ ft_header=(FT_H *)(ptrMsg->local_para_ptr);
+ /* process messages with specific message ID */
+ switch(ptrMsg->msg_id)
+ {
+ case MSG_ID_MMRF_UPDATE_RUNTIME_CNF:
+ {
+ FT_Mmrf_UpdateRuntimeConfirmHandler(ptrMsg);
+ return;
+ }
+ default:
+ break;
+ }
+ /* process message with specific source module ID */
+#if !defined(__DHL_MODULE__)
+ if(ptrMsg->src_mod_id == MOD_TST_READER)
+#else
+ if(ptrMsg->src_mod_id == MOD_DHL)
+#endif // #if !defined(__DHL_MODULE__)
+ {
+ ft_gl_token=ft_header->token;
+ switch (ft_header->ft_msg_id)
+ {
+ /********************************************
+ * L1 RF test functionality
+ ********************************************/
+#if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+ case FT_RF_TEST_REQ_ID:
+ {
+ FT_Rf_Operation(ptrMsg);
+ break;
+ }
+#endif // #if !defined(__LTE_SM__)&&defined(__MTK_GL1_GSM__)
+ /********************************************
+ * UL1 RF test functionality
+ ********************************************/
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(__UL1_TASK_DISABLE__)
+ case FT_URF_TEST_REQ_ID:
+ {
+ FT_FtURfTestReq( ptrMsg );
+ break;
+ }
+#endif // #if !defined(__UL1_TASK_DISABLE__)
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+ /********************************************
+ *
+ * Version Info functionality
+ *
+ ********************************************/
+ case FT_VER_INFO_REQ_ID:
+ {
+ FT_GetVersionInfo();
+ break;
+ }
+ /********************************************
+ *
+ * FT task test alive
+ *
+ ********************************************/
+ case FT_IS_ALIVE_REQ_ID:
+ {
+ FT_TestAlive();
+ break;
+ }
+ /********************************************
+ *
+ * FT task utility command
+ *
+ ********************************************/
+ case FT_UTILITY_COMMAND_REQ_ID:
+ {
+ FT_UtilityCommand(ptrMsg);
+ break;
+ }
+#if defined(__LTE_RAT__) || defined(L1_SIM)
+ case FT_ERF_TEST_REQ_ID:
+ {
+ FT_Erf_Operation(ptrMsg);
+ break;
+ }
+#endif // #if defined(__LTE_RAT__)
+ case FT_MMRF_TEST_REQ_ID:
+ {
+ FT_Mmrf_Operation(ptrMsg);
+ break;
+ }
+
+ case FT_NRF_TEST_REQ_ID:
+ {
+ FT_Nrf_Operation(ptrMsg);
+ break;
+ }
+
+#if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT) || defined(DUMMY_PROTOCOL)
+ case FT_L4_ATCMD_REQ_ID:
+ {
+ FT_L4_Operation(ptrMsg);
+ }
+#endif // #if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT)
+ default:
+ break;
+ }
+ }
+#if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(__UL1_TASK_DISABLE__)
+ else if( (ptrMsg->src_mod_id == MOD_UL1) )
+ {
+ FT_UL1TST_SEND_CNF_BACK(ptrMsg);
+ }
+#endif // #if !defined(__UL1_TASK_DISABLE__)
+#endif // #if defined(__UMTS_RAT__) && defined(__MTK_UL1_FDD__)
+#if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+ else if( (ptrMsg->src_mod_id == MOD_L1) )
+ {
+ FT_Rf_ConfirmHandler(ptrMsg);
+ }
+#endif // #if !defined(L1_NOT_PRESENT) && !defined(__L1_TASK_DISABLE__) && !defined(DUMMYL1)
+#if defined(__LTE_RAT__)
+ else if( MOD_EL1== ptrMsg->src_mod_id )
+ {
+ FT_Erf_ConfirmHandler(ptrMsg);
+ }
+#endif // #if defined(__LTE_RAT__)
+
+ else if( MOD_MMRF_XL1TST == ptrMsg->src_mod_id )
+ {
+ FT_Mmrf_ConfirmHandler(ptrMsg);
+ }
+#if defined(__MD97__)
+ else if( MOD_NL1 == ptrMsg->src_mod_id )
+ {
+ FT_Nrf_ConfirmHandler(ptrMsg);
+ }
+#endif // #if !defined(__MD97__)
+#if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT) || defined(DUMMY_PROTOCOL)
+ else if( MOD_L4C == ptrMsg->src_mod_id )
+ {
+ FT_L4_Operation(ptrMsg);
+ }
+#endif // #if !defined(__L4_TASK_DISABLE__) && !defined(L4_NOT_PRESENT)
+}
+#endif // #ifndef L1_SIM
+/*******************************************************************************
+ * FUNCTION
+ * FT_Task
+ *
+ * DESCRIPTION
+ * Entry point for the factory testing task. The function performs initialisation,
+ * then sits in an infinite loop reading messages or reports and dispatching
+ * them.
+ *
+ * CALLS
+ *
+ * PARAMETERS
+ * None
+ *
+ * RETURNS
+ * None
+ *
+ * GLOBALS AFFECTED
+ * None
+ *******************************************************************************/
+
+#define META_Version_Check_Fail 0
+#define META_Version_Check_Required 0
+
+void FT_Task(task_entry_struct * task_entry_ptr)
+{
+ ilm_struct current_ilm;
+ FT_Initialization(task_entry_ptr);
+ while ( 1 )
+ {
+#ifndef L1_SIM
+ msg_receive_extq(¤t_ilm );
+#else
+ gs_read_message(MOD_FT, ¤t_ilm, sizeof(current_ilm), KAL_TRUE);
+#endif //#ifndef L1_SIM
+ FT_DispatchMessage(¤t_ilm );
+ destroy_ilm(¤t_ilm);
+ }
+}
+kal_eventgrpid MMRF_UPDATE_RUNTIME_EVENT;
+kal_bool FT_Init(void)
+{
+ MMRF_UPDATE_RUNTIME_EVENT = kal_create_event_group("MMRF_UPD");
+ return KAL_TRUE;
+}
diff --git a/mcu/middleware/meta/ft/src/ft_mem.c b/mcu/middleware/meta/ft/src/ft_mem.c
new file mode 100644
index 0000000..4c46a86
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_mem.c
@@ -0,0 +1,138 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_mem.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * Factory testing memory management functions
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+/*************************************************************************
+ * Include Statements for KAL
+ *************************************************************************/
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+/*************************************************************************
+ * Include Statements FT
+ *************************************************************************/
+#include "ft_mem.h"
+#include "meta_customize.h"
+/*************************************************************************
+ * FT memory global variable
+ *************************************************************************/
+KAL_ADM_ID ft_ext_mem_pool_id = 0;
+void FtInitMemoryPool(void)
+{
+ ft_ext_mem_pool_id = kal_adm_create(
+ Custom_META_GetCustomMemoryPool(),
+ Custom_META_GetCustomMemoryPoolSize(),
+ (kal_uint32*)Custom_META_GetCustomMemoryPoolArrangement(),
+ KAL_FALSE
+ );
+}
+void* FtAllocExtMemory(kal_uint32 size)
+{
+ if(ft_ext_mem_pool_id > 0)
+ {
+ return kal_adm_alloc(ft_ext_mem_pool_id, size);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+void FtFreeExtMemory(void* ptr)
+{
+ if(ft_ext_mem_pool_id > 0)
+ {
+ kal_adm_free(ft_ext_mem_pool_id, ptr);
+ }
+}
+kal_uint32 FtGetLeftExtMemory(void)
+{
+ if(ft_ext_mem_pool_id > 0)
+ {
+ return kal_adm_get_max_alloc_size(ft_ext_mem_pool_id);
+ }
+ else
+ {
+ return 0;
+ }
+}
diff --git a/mcu/middleware/meta/ft/src/ft_report.c b/mcu/middleware/meta/ft/src/ft_report.c
new file mode 100644
index 0000000..71b4720
--- /dev/null
+++ b/mcu/middleware/meta/ft/src/ft_report.c
@@ -0,0 +1,149 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ft_report.c
+ *
+ * Project:
+ * --------
+ * MTK6208
+ *
+ * Description:
+ * ------------
+ * Functions to handle L1 report
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#include "ft_msg.h"
+#include "ft_private.h"
+#include "ft_report.h"
+
diff --git a/mcu/middleware/meta/ftc/ftc_main.c b/mcu/middleware/meta/ftc/ftc_main.c
new file mode 100644
index 0000000..d85ccf3
--- /dev/null
+++ b/mcu/middleware/meta/ftc/ftc_main.c
@@ -0,0 +1,281 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ftc_main.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+/*************************************************************************
+* Include Statements for KAL
+ *************************************************************************/
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "task_config.h"
+#include "syscomp_config.h"
+#include "md_mw_sap.h"
+#include "ft_msgid.h"
+/*************************************************************************
+* Include Statements for MAUI
+ *************************************************************************/
+//MSBB remove #include "fctycomp_config.h"
+#include "ft_msg_common.h"
+#include "ftc_msg.h"
+#include "ftc_private.h"
+// added in RHR first round
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "kal_public_defs.h"
+/*************************************************************************
+* Function declaration
+ *************************************************************************/
+void FTC_Task(task_entry_struct * task_entry_ptr);
+
+//#pragma arm section zidata = "NONCACHEDZI", rwdata = "NONCACHEDRW"
+//#pragma arm section zidata, rwdata
+
+/*************************************************************************
+* FUNCTION
+* ft_create
+*
+* DESCRIPTION
+*
+* PARAMETERS
+*
+* RETURNS
+* None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool
+ftc_create(comptask_handler_struct **handle)
+{
+ static const comptask_handler_struct ftc_handler_info =
+ {
+ FTC_Task, /* task entry function */
+ NULL, /* task initialization function */
+ NULL /* task configuration function */
+ };
+ *handle = (comptask_handler_struct *)&ftc_handler_info;
+ return KAL_TRUE;
+}
+/*******************************************************************************
+*
+* Local Functions
+*
+*******************************************************************************/
+void FTC_ALLOC_MSG(ilm_struct* ilm_ptr, kal_uint16 size)
+{
+ ilm_ptr->local_para_ptr = NULL;
+ ilm_ptr->peer_buff_ptr = NULL;
+ if( 0 < size ) {
+ if( NULL == (ilm_ptr->local_para_ptr=construct_local_para(size, TD_RESET)) ) {
+ ASSERT(0); // assert it!
+ }
+ }
+}
+void FTC_SEND_MSG(module_type src_mod,
+ module_type dest_mod,
+ sap_type sap,
+ msg_type msg,
+ ilm_struct *ilm_ptr)
+{
+ msg_send6(src_mod, dest_mod, sap, msg, ilm_ptr->local_para_ptr, ilm_ptr->peer_buff_ptr);
+}
+void FTC_DispatchMessage(ilm_struct* ptrMsg)
+{
+ if( (ptrMsg->src_mod_id == MOD_FT) )
+ {
+ if(ptrMsg->peer_buff_ptr == NULL)
+ {
+ return;
+ }
+ switch (ptrMsg->msg_id)
+ {
+ case MSG_ID_FTC_BASIC_REQ:
+ {
+ // do the echo operation (This is the sample code, please extend the customization in this switch case
+ ftc_basic_cnf_struct *ftc_ptr_loc_para;
+ ilm_struct ilm_ptr;
+ FTC_ALLOC_MSG(&ilm_ptr, sizeof(ftc_basic_cnf_struct));
+ ftc_ptr_loc_para=(ftc_basic_cnf_struct *)(ilm_ptr.local_para_ptr);
+ ftc_ptr_loc_para->status = FTC_CNF_OK;
+ hold_peer_buff(ptrMsg->peer_buff_ptr);
+ ilm_ptr.peer_buff_ptr = ptrMsg->peer_buff_ptr;
+ FTC_SEND_MSG(MOD_FTC ,MOD_FT, FTC_FT_SAP, MSG_ID_FTC_BASIC_CNF, &ilm_ptr);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else if( (ptrMsg->src_mod_id == MOD_NVRAM) )
+ {
+ }
+}
+/*******************************************************************************
+* FUNCTION
+* FT_Task
+*
+* DESCRIPTION
+* Entry point for the factory testing task. The function performs initialisation,
+* then sits in an infinite loop reading messages or reports and dispatching
+* them.
+*
+* CALLS
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* None
+*
+* GLOBALS AFFECTED
+* None
+*******************************************************************************/
+void FTC_Task(task_entry_struct * task_entry_ptr)
+{
+ ilm_struct current_ilm;
+ while ( 1 )
+ {
+ msg_receive_extq(¤t_ilm);
+ FTC_DispatchMessage(¤t_ilm);
+ destroy_ilm(¤t_ilm);
+ }
+}
diff --git a/mcu/middleware/meta/ftc/ftc_private.h b/mcu/middleware/meta/ftc/ftc_private.h
new file mode 100644
index 0000000..39bf537
--- /dev/null
+++ b/mcu/middleware/meta/ftc/ftc_private.h
@@ -0,0 +1,80 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+* Modification Notice:
+* --------------------------
+* This software is modified by MediaTek Inc. and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*******************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * ftc_private.h
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * FTC private stuff
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+
+#ifndef FTC_PRIVATE_H
+#define FTC_PRIVATE_H
+
+#define FTC_CNF_OK 0
+#define FTC_CNF_FAIL 1
+
+#endif