[Feature][task-view-306]merge P56U08(patch6) version

Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I8e809511ac30c97228dd110c304b4a08f4af36d7
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/pcu.h b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/pcu.h
old mode 100644
new mode 100755
index ddb3064..c2b5b37
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/pcu.h
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/pcu.h
@@ -156,6 +156,18 @@
 

 }PCU_INT_INDEX;

 #endif

+

+typedef enum _T_Pcu_CoreId

+{

+       CPU_M0 = 0,

+       CPU_PS,

+       CPU_AP,

+       CPU_PHY,

+       MAX_CPU

+} T_Pcu_CoreId;

+

+

+

 /* ap related registers */

 #define ARM_AP_CONFIG_REG           (ZX_PCU_BASE + 0x0)

 #define ARM_AP_SLEEP_TIME_REG       (ZX_PCU_BASE + 4*0x3C)

@@ -305,6 +317,12 @@
 void pcu_irq_wakeup(PCU_INT_INDEX index, int enable);

 unsigned int pcu_get_8in1_int_source(void);

 

+/**

+ * pcu_CoreIsActive

+ * 

+ * 

+ */

+int pcu_CoreIsActive(T_Pcu_CoreId core);

 

 /* low power function */

 void __init pcu_init(void);

diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pcu.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pcu.c
index 5124b9d..80d738f 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pcu.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pcu.c
@@ -21,15 +21,6 @@
 #include <mach/irqs.h>
 #include <mach/spinlock.h>
 
-typedef enum _T_Pcu_CoreId
-{
-       CPU_M0 = 0,
-       CPU_PS,
-       CPU_AP,
-       CPU_PHY,
-       MAX_CPU
-} T_Pcu_CoreId;
-
 /**
  * pcu_CoreIsActive
  * 
@@ -37,7 +28,7 @@
  */
 int pcu_CoreIsActive(T_Pcu_CoreId core)
 {
-   int  active=0;
+   volatile int  active=0;
 
    switch (core)
    {
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
index e0ad7ac..74cba0d 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/zx297520v3-mdl-devices.c
@@ -1406,7 +1406,8 @@
 };
 #else
 int ts_temp_value_table[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER]={
-{		
+{
+ -45,-44,-43,-42,-41,		
  -40,-39,-38,-37,-36, -35,-34,-33,-32,-31,		
  -30,-29,-28,-27,-26, -25,-24,-23,-22,-21,		
  -20,-19,-18,-17,-16, -15,-14,-13,-12,-11,		
@@ -1426,23 +1427,24 @@
  120,121,122,123,124,125},
 
 {
-5753,5743,5732,5721,5709,5697,5684,5671,5658,5643,
-5629,5614,5598,5581,5564,5547,5529,5510,5491,5471,
-5450,5429,5407,5385,5362,5338,5314,5289,5263,5237,
-5211,5183,5155,5127,5097,5068,5037,5007,4975,4944,
-4912,4879,4846,4813,4779,4745,4710,4676,4641,4605,
-4570,4534,4498,4462,4426,4389,4353,4317,4280,4244,
-4207,4171,4135,4099,4063,4027,3992,3956,3921,3886,
-3851,3817,3783,3749,3716,3683,3650,3618,3587,3555,
-3524,3494,3464,3434,3405,3376,3348,3320,3292,3265,
-3239,3213,3188,3163,3138,3114,3091,3068,3045,3023,
-3001,2980,2960,2940,2920,2901,2883,2864,2847,2829,
-2812,2796,2779,2763,2748,2733,2718,2704,2690,2676,
-2662,2649,2637,2624,2612,2601,2589,2578,2567,2556,
-2546,2536,2526,2516,2507,2498,2489,2480,2471,2463,
-2455,2447,2440,2432,2425,2418,2411,2404,2398,2391,
-2385,2379,2373,2367,2362,2356,2351,2346,2341,2336,
-2331,2326,2322,2317,2313,2309}
+5849,5842,5835,5828,5821,
+5814,5807,5800,5794,5787,5780,5770,5761,5751,5742,
+5732,5720,5707,5695,5682,5670,5654,5638,5623,5607,
+5591,5571,5550,5530,5509,5489,5461,5432,5404,5375,
+5347,5318,5290,5261,5233,5204,5179,5154,5129,5104,
+5079,5040,5001,4961,4922,4883,4838,4794,4749,4705,
+4660,4618,4576,4534,4492,4450,4416,4383,4349,4316,
+4282,4238,4193,4149,4104,4060,4015,3971,3926,3882,
+3837,3798,3759,3719,3680,3641,3603,3565,3526,3488,
+3450,3419,3387,3356,3324,3293,3262,3232,3201,3171,
+3140,3112,3085,3057,3030,3002,2978,2954,2931,2907,
+2883,2862,2841,2819,2798,2777,2759,2740,2722,2703,
+2685,2669,2653,2636,2620,2604,2590,2575,2561,2546,
+2532,2520,2508,2495,2483,2471,2461,2451,2442,2432,
+2422,2414,2406,2398,2390,2380,2373,2366,2359,2352,
+2345,2339,2333,2327,2321,2315,2310,2305,2300,2295,
+2290,2286,2282,2278,2274,2270,2267,2264,2261,2258,
+2255,2254,2253,2252,2251,2250  }
 };
 #endif
 volatile u32 ts_adc_flag=3;// 1:adc1; 2:adc2, other:adc rf;  
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
index 827cd18..f819d44 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
@@ -21,12 +21,12 @@
 #ifdef CONFIG_MMU
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){int 
-ret=(0x114a+3398-0x1e90);if(!user_mode(regs)){preempt_disable();if(
-kprobe_running()&&kprobe_fault_handler(regs,fsr))ret=(0x1eab+674-0x214c);
-preempt_enable();}return ret;}
+ret=(0xf21+1052-0x133d);if(!user_mode(regs)){preempt_disable();if(kprobe_running
+()&&kprobe_fault_handler(regs,fsr))ret=(0x1f2+482-0x3d3);preempt_enable();}
+return ret;}
 #else
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){return
-(0x7e0+1274-0xcda);}
+(0xf9+3598-0xf07);}
 #endif
 void show_pte(struct mm_struct*mm,unsigned long addr){pgd_t*pgd;if(!mm)mm=&
 init_mm;printk(KERN_ALERT"\x70\x67\x64\x20\x3d\x20\x25\x70" "\n",mm->pgd);pgd=
@@ -34,10 +34,10 @@
 "\x5b\x25\x30\x38\x6c\x78\x5d\x20\x2a\x70\x67\x64\x3d\x25\x30\x38\x6c\x6c\x78",
 addr,(long long)pgd_val(*pgd));do{pud_t*pud;pmd_t*pmd;pte_t*pte;if(pgd_none(*pgd
 ))break;if(pgd_bad(*pgd)){printk("\x28\x62\x61\x64\x29");break;}pud=pud_offset(
-pgd,addr);if(PTRS_PER_PUD!=(0x18b2+1137-0x1d22))printk(
+pgd,addr);if(PTRS_PER_PUD!=(0x426+1199-0x8d4))printk(
 "\x2c\x20\x2a\x70\x75\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pud_val(*pud))
 ;if(pud_none(*pud))break;if(pud_bad(*pud)){printk("\x28\x62\x61\x64\x29");break;
-}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x108c+5353-0x2574))printk(
+}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x1ab1+1808-0x21c0))printk(
 "\x2c\x20\x2a\x70\x6d\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pmd_val(*pmd))
 ;if(pmd_none(*pmd))break;if(pmd_bad(*pmd)){printk("\x28\x62\x61\x64\x29");break;
 }if(PageHighMem(pfn_to_page(pmd_val(*pmd)>>PAGE_SHIFT)))break;pte=pte_offset_map
@@ -47,18 +47,18 @@
 printk("\x2c\x20\x2a\x70\x70\x74\x65\x3d\x25\x30\x38\x6c\x6c\x78",(long long)
 pte_val(pte[PTE_HWTABLE_PTRS]));
 #endif
-pte_unmap(pte);}while((0x67b+2056-0xe83));printk("\n");}
+pte_unmap(pte);}while((0xe4a+2490-0x1804));printk("\n");}
 #else					
 void show_pte(struct mm_struct*mm,unsigned long addr){}
 #endif					
 static void __do_kernel_fault(struct mm_struct*mm,unsigned long addr,unsigned 
 int fsr,struct pt_regs*regs){if(fixup_exception(regs))return;bust_spinlocks(
-(0x11a2+3461-0x1f26));printk(KERN_ALERT
+(0x61d+5852-0x1cf8));printk(KERN_ALERT
 "\x55\x6e\x61\x62\x6c\x65\x20\x74\x6f\x20\x68\x61\x6e\x64\x6c\x65\x20\x6b\x65\x72\x6e\x65\x6c\x20\x25\x73\x20\x61\x74\x20\x76\x69\x72\x74\x75\x61\x6c\x20\x61\x64\x64\x72\x65\x73\x73\x20\x25\x30\x38\x6c\x78" "\n"
 ,(addr<PAGE_SIZE)?
 "\x4e\x55\x4c\x4c\x20\x70\x6f\x69\x6e\x74\x65\x72\x20\x64\x65\x72\x65\x66\x65\x72\x65\x6e\x63\x65"
 :"\x70\x61\x67\x69\x6e\x67\x20\x72\x65\x71\x75\x65\x73\x74",addr);show_pte(mm,
-addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0x479+3944-0x13e1));
+addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0x1953+460-0x1b1f));
 do_exit(SIGKILL);}static void __do_user_fault(struct task_struct*tsk,unsigned 
 long addr,unsigned int fsr,unsigned int sig,int code,struct pt_regs*regs){struct
  siginfo si;
@@ -69,7 +69,7 @@
 ,tsk->comm,sig,addr,fsr);show_pte(tsk->mm,addr);show_regs(regs);}
 #endif
 tsk->thread.address=addr;tsk->thread.error_code=fsr;tsk->thread.trap_no=
-(0xa29+3854-0x1929);si.si_signo=sig;si.si_errno=(0x1879+829-0x1bb6);si.si_code=
+(0x8f9+6302-0x2189);si.si_signo=sig;si.si_errno=(0x47d+6644-0x1e71);si.si_code=
 code;si.si_addr=(void __user*)addr;force_sig_info(sig,&si,tsk);}void do_bad_area
 (unsigned long addr,unsigned int fsr,struct pt_regs*regs){struct task_struct*tsk
 =current;struct mm_struct*mm=tsk->active_mm;if(user_mode(regs))__do_user_fault(
@@ -91,8 +91,8 @@
 static int __kprobes do_page_fault(unsigned long addr,unsigned int fsr,struct 
 pt_regs*regs){struct task_struct*tsk;struct mm_struct*mm;int fault,sig,code;int 
 write=fsr&FSR_WRITE;unsigned int flags=FAULT_FLAG_ALLOW_RETRY|
-FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0xdc9+815-0x10f8));if(
-notify_page_fault(regs,fsr))return(0xbd+7699-0x1ed0);tsk=current;mm=tsk->mm;if(
+FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0x1764+1706-0x1e0e));if(
+notify_page_fault(regs,fsr))return(0xe15+3888-0x1d45);tsk=current;mm=tsk->mm;if(
 interrupts_enabled(regs))local_irq_enable();if(!mm||pagefault_disabled())goto 
 no_context;if(!down_read_trylock(&mm->mmap_sem)){if(!user_mode(regs)&&!
 search_exception_tables(regs->ARM_pc))goto no_context;retry:down_read(&mm->
@@ -101,22 +101,22 @@
 if(!user_mode(regs)&&!search_exception_tables(regs->ARM_pc))goto no_context;
 #endif
 }fault=__do_page_fault(mm,addr,fsr,flags,tsk);if((fault&VM_FAULT_RETRY)&&
-fatal_signal_pending(current))return(0x1688+1136-0x1af8);perf_sw_event(
-PERF_COUNT_SW_PAGE_FAULTS,(0x13b5+64-0x13f4),regs,addr);if(!(fault&
+fatal_signal_pending(current))return(0x8d5+6534-0x225b);perf_sw_event(
+PERF_COUNT_SW_PAGE_FAULTS,(0x625+7324-0x22c0),regs,addr);if(!(fault&
 VM_FAULT_ERROR)&&flags&FAULT_FLAG_ALLOW_RETRY){if(fault&VM_FAULT_MAJOR){tsk->
-maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x358+6757-0x1dbc),regs,
+maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x23f+8371-0x22f1),regs,
 addr);}else{tsk->min_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
-(0xab3+4256-0x1b52),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
+(0xb02+209-0xbd2),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
 FAULT_FLAG_ALLOW_RETRY;goto retry;}}up_read(&mm->mmap_sem);if(likely(!(fault&(
-VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x1b1+7410-0x1ea3);
-if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0xebd+1384-0x1425);}if(!
+VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x1728+706-0x19ea);
+if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0x176+8174-0x2164);}if(!
 user_mode(regs))goto no_context;if(fault&VM_FAULT_SIGBUS){sig=SIGBUS;code=
 BUS_ADRERR;}else{sig=SIGSEGV;code=fault==VM_FAULT_BADACCESS?SEGV_ACCERR:
-SEGV_MAPERR;}__do_user_fault(tsk,addr,fsr,sig,code,regs);return(0x406+121-0x47f)
-;no_context:__do_kernel_fault(mm,addr,fsr,regs);return(0x1c70+1566-0x228e);}
+SEGV_MAPERR;}__do_user_fault(tsk,addr,fsr,sig,code,regs);return(0x55a+191-0x619)
+;no_context:__do_kernel_fault(mm,addr,fsr,regs);return(0x2088+467-0x225b);}
 #else					
 static int do_page_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
-){return(0x3ec+2023-0xbd3);}
+){return(0x13c5+3327-0x20c4);}
 #endif					
 #ifdef CONFIG_MMU
 static int __kprobes do_translation_fault(unsigned long addr,unsigned int fsr,
@@ -129,21 +129,21 @@
 bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=pmd_offset(pud,addr);
 pmd_k=pmd_offset(pud_k,addr);
 #ifdef CONFIG_ARM_LPAE
-index=(0x1397+1894-0x1afd);
+index=(0xb33+6513-0x24a4);
 #else
-index=(addr>>SECTION_SHIFT)&(0x1d96+756-0x2089);
+index=(addr>>SECTION_SHIFT)&(0x561+3792-0x1430);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0x108+1051-0x523);bad_area:do_bad_area(addr,fsr,regs);return(0x163+4974-0x14d1)
-;}
+(0x4df+1563-0xafa);bad_area:do_bad_area(addr,fsr,regs);return
+(0x109a+4313-0x2173);}
 #else					
 static int do_translation_fault(unsigned long addr,unsigned int fsr,struct 
-pt_regs*regs){return(0xdfd+2141-0x165a);}
+pt_regs*regs){return(0xffd+998-0x13e3);}
 #endif					
 static int do_sect_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
 ){if(interrupts_enabled(regs))local_irq_enable();do_bad_area(addr,fsr,regs);
-return(0xde2+4799-0x20a1);}static int do_bad(unsigned long addr,unsigned int fsr
-,struct pt_regs*regs){return(0xacc+1313-0xfec);}struct fsr_info{int(*fn)(
+return(0xd47+1007-0x1136);}static int do_bad(unsigned long addr,unsigned int fsr
+,struct pt_regs*regs){return(0x1665+1252-0x1b48);}struct fsr_info{int(*fn)(
 unsigned long addr,unsigned int fsr,struct pt_regs*regs);int sig;int code;const 
 char*name;};
 #ifdef CONFIG_ARM_LPAE
@@ -152,42 +152,42 @@
 #include "fsr-2level.c"
 #endif
 void __init hook_fault_code(int nr,int(*fn)(unsigned long,unsigned int,struct 
-pt_regs*),int sig,int code,const char*name){if(nr<(0xac2+42-0xaec)||nr>=
+pt_regs*),int sig,int code,const char*name){if(nr<(0x0+1685-0x695)||nr>=
 ARRAY_SIZE(fsr_info))BUG();fsr_info[nr].fn=fn;fsr_info[nr].sig=sig;fsr_info[nr].
 code=code;fsr_info[nr].name=name;}
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
 static DECLARE_RWSEM(shrinker_rwsem);atomic_t _code_page_count=ATOMIC_INIT(
-(0xd8+6514-0x1a4a));struct addr_info{struct list_head node;unsigned long vaddr;
+(0x272+6903-0x1d69));struct addr_info{struct list_head node;unsigned long vaddr;
 unsigned long kaddr;unsigned long page_index;};enum modem_access_technology{GSM=
-(0x1b0+2553-0xba9),UTRAN=(0x403+8875-0x26ad),LTE=(0x617+7344-0x22c5),COM=
-(0xa0a+4588-0x1bf3),NR_MODEM_ACCESS=(0x179+7641-0x1f4e)};struct list_head 
+(0x1527+591-0x1776),UTRAN=(0xd67+2987-0x1911),LTE=(0x16f9+652-0x1983),COM=
+(0x433+7865-0x22e9),NR_MODEM_ACCESS=(0x8ff+283-0xa16)};struct list_head 
 modem_page_list[NR_MODEM_ACCESS]={LIST_HEAD_INIT(modem_page_list[
-(0xb6c+4798-0x1e2a)]),LIST_HEAD_INIT(modem_page_list[(0x1529+4480-0x26a8)]),
-LIST_HEAD_INIT(modem_page_list[(0x226+4890-0x153e)]),LIST_HEAD_INIT(
-modem_page_list[(0x4a5+8026-0x23fc)]),};unsigned int page_used[
-(0x1018+1513-0x15d9)];struct completion page_completion[(0x13bc+3080-0x1f9c)*
-(0xac7+5959-0x21ee)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
-unsigned long end){pte_t*pte;pte=pte_offset_kernel(pmd,addr);do{pte_t ptent=
-ptep_get_and_clear(&init_mm,addr,pte);WARN_ON(!pte_none(ptent)&&!pte_present(
-ptent));}while(pte++,addr+=PAGE_SIZE,addr!=end);}static void unmap_pmd_range(
-pud_t*pud,unsigned long addr,unsigned long end){pmd_t*pmd;unsigned long next;pmd
-=pmd_offset(pud,addr);do{next=pmd_addr_end(addr,end);if(pmd_none_or_clear_bad(
-pmd))continue;unmap_pte_range(pmd,addr,next);}while(pmd++,addr=next,addr!=end);}
-static void unmap_pud_range(pgd_t*pgd,unsigned long addr,unsigned long end){
-pud_t*pud;unsigned long next;pud=pud_offset(pgd,addr);do{next=pud_addr_end(addr,
-end);if(pud_none_or_clear_bad(pud))continue;unmap_pmd_range(pud,addr,next);}
-while(pud++,addr=next,addr!=end);}static void unmap_page_range(unsigned long 
-addr,unsigned long end){pgd_t*pgd;unsigned long next;BUG_ON(addr>=end);pgd=
-pgd_offset_k(addr);do{next=pgd_addr_end(addr,end);if(pgd_none_or_clear_bad(pgd))
-continue;unmap_pud_range(pgd,addr,next);}while(pgd++,addr=next,addr!=end);}void 
-shrink_modem_mem(unsigned int access_type){int i=(0x198c+2272-0x226c);unsigned 
+(0x1265+2235-0x1b20)]),LIST_HEAD_INIT(modem_page_list[(0x1ef1+1191-0x2397)]),
+LIST_HEAD_INIT(modem_page_list[(0x1cfa+1958-0x249e)]),LIST_HEAD_INIT(
+modem_page_list[(0x768+307-0x898)]),};unsigned int page_used[(0x59d+645-0x7fa)];
+struct completion page_completion[(0x423+7707-0x2216)*(0x1284+2914-0x1dc6)];
+static void unmap_pte_range(pmd_t*pmd,unsigned long addr,unsigned long end){
+pte_t*pte;pte=pte_offset_kernel(pmd,addr);do{pte_t ptent=ptep_get_and_clear(&
+init_mm,addr,pte);WARN_ON(!pte_none(ptent)&&!pte_present(ptent));}while(pte++,
+addr+=PAGE_SIZE,addr!=end);}static void unmap_pmd_range(pud_t*pud,unsigned long 
+addr,unsigned long end){pmd_t*pmd;unsigned long next;pmd=pmd_offset(pud,addr);do
+{next=pmd_addr_end(addr,end);if(pmd_none_or_clear_bad(pmd))continue;
+unmap_pte_range(pmd,addr,next);}while(pmd++,addr=next,addr!=end);}static void 
+unmap_pud_range(pgd_t*pgd,unsigned long addr,unsigned long end){pud_t*pud;
+unsigned long next;pud=pud_offset(pgd,addr);do{next=pud_addr_end(addr,end);if(
+pud_none_or_clear_bad(pud))continue;unmap_pmd_range(pud,addr,next);}while(pud++,
+addr=next,addr!=end);}static void unmap_page_range(unsigned long addr,unsigned 
+long end){pgd_t*pgd;unsigned long next;BUG_ON(addr>=end);pgd=pgd_offset_k(addr);
+do{next=pgd_addr_end(addr,end);if(pgd_none_or_clear_bad(pgd))continue;
+unmap_pud_range(pgd,addr,next);}while(pgd++,addr=next,addr!=end);}void 
+shrink_modem_mem(unsigned int access_type){int i=(0x359+8289-0x23ba);unsigned 
 long vaddr;struct addr_info*addr,*tmp_addr;struct list_head tmp_page_list;for(i=
-(0x9da+6393-0x22d3);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
+(0x3d1+5851-0x1aac);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
 (&shrinker_rwsem);list_replace_init(&modem_page_list[i],&tmp_page_list);up_write
 (&shrinker_rwsem);list_for_each_entry_safe(addr,tmp_addr,&tmp_page_list,node){
 list_del_init(&addr->node);page_completion[addr->page_index].done=
-(0xc20+2903-0x1777);page_used[addr->page_index/BITS_PER_LONG]&=~(
-(0x1b4+1550-0x7c1)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
+(0x457+8027-0x23b2);page_used[addr->page_index/BITS_PER_LONG]&=~(
+(0xdda+5295-0x2288)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
 PAGE_MASK;if(vaddr<cpps_global_var.cpko_text_start||vaddr>cpps_global_var.
 modem_text_end){panic(
 "\x61\x64\x64\x72\x5f\x69\x6e\x66\x6f\x3a\x20\x25\x30\x38\x78\x20\x69\x73\x20\x20\x64\x65\x73\x74\x72\x6f\x79"
@@ -195,28 +195,28 @@
 PAGE_SIZE);flush_tlb_kernel_range(vaddr,vaddr+PAGE_SIZE);
 #ifdef CONFIG_DEBUG_RODATA
 unsigned int flags;local_irq_save(flags);set_memory_rw(addr->kaddr,
-(0xf94+2221-0x1840));local_irq_restore(flags);
+(0x9ab+5311-0x1e69));local_irq_restore(flags);
 #endif
 free_page(addr->kaddr);kfree(addr);atomic_dec(&_code_page_count);};}}
 EXPORT_SYMBOL(shrink_modem_mem);phys_addr_t virt_is_mapping(unsigned long addr){
 pgd_t*pgd;pmd_t*pmd;pte_t*ptep,pte;unsigned long pfn;pgd=pgd_offset_k(addr);if(!
 pgd_none(*pgd)){pmd=pmd_offset(pgd,addr);if(!pmd_none(*pmd)){ptep=pte_offset_map
 (pmd,addr);pte=*ptep;if(pte_present(pte)){pfn=pte_pfn(pte);return __pfn_to_phys(
-pfn);}}}return(0x836+727-0xb0d);}static int sync_pgd(unsigned long addr,unsigned
- int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*pud,*
-pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
+pfn);}}}return(0xeed+2713-0x1986);}static int sync_pgd(unsigned long addr,
+unsigned int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*
+pud,*pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
 init_mm.pgd+index;if(pgd_none(*pgd_k))goto bad_area;if(!pgd_present(*pgd))
 set_pgd(pgd,*pgd_k);pud=pud_offset(pgd,addr);pud_k=pud_offset(pgd_k,addr);if(
 pud_none(*pud_k))goto bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=
 pmd_offset(pud,addr);pmd_k=pmd_offset(pud_k,addr);
 #ifdef CONFIG_ARM_LPAE
-index=(0x1a4+8803-0x2407);
+index=(0xaab+1856-0x11eb);
 #else
-index=(addr>>SECTION_SHIFT)&(0xa04+956-0xdbf);
+index=(addr>>SECTION_SHIFT)&(0x969+1064-0xd90);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0x6d6+5237-0x1b4b);bad_area:do_bad_area(addr,fsr,regs);return
-(0x32d+4382-0x144b);}unsigned long*read_code_file(unsigned long page_index){
+(0x140c+632-0x1684);bad_area:do_bad_area(addr,fsr,regs);return
+(0x253b+384-0x26bb);}unsigned long*read_code_file(unsigned long page_index){
 unsigned long*code_buf;ssize_t result;code_buf=get_zeroed_page(GFP_ATOMIC);if(!
 code_buf)panic(
 "\x6d\x65\x6d\x65\x6f\x72\x79\x20\x6e\x6f\x74\x20\x65\x6e\x6f\x75\x67\x68\x21\x21"
@@ -225,80 +225,80 @@
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}
 mm_segment_t old_fs;old_fs=get_fs();set_fs(KERNEL_DS);loff_t pos;pos=page_index*
 PAGE_SIZE+cpps_global_var.modem_offset;result=vfs_read(cpps_global_var.fp_code,(
-char*)code_buf,PAGE_SIZE,&pos);if(result<(0x150+4607-0x134f)){panic(
+char*)code_buf,PAGE_SIZE,&pos);if(result<(0x1022+2528-0x1a02)){panic(
 "\x72\x65\x61\x64\x20\x63\x6f\x64\x65\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n"
 );}
 #ifdef CONFIG_DEBUG_RODATA
 unsigned int flags;local_irq_save(flags);set_memory_ro((unsigned long)code_buf,
-(0x11a9+599-0x13ff));local_irq_restore(flags);
+(0x1050+4515-0x21f2));local_irq_restore(flags);
 #endif
 set_fs(old_fs);return code_buf;}void read_code_mapping(unsigned long addr,
 unsigned int fsr,struct pt_regs*regs){unsigned long offset;unsigned long vaddr;
 const struct mem_type*mtype;unsigned long*vir_codebuf;unsigned long page_index;
-unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0x13df+559-0x160e)
-){sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&PAGE_MASK;offset=vaddr&(~
-cpps_global_var.cpko_text_start);page_index=offset>>PAGE_SHIFT;page_shift=
-page_index%BITS_PER_LONG;if((page_used[page_index/BITS_PER_LONG]>>page_shift)&
-(0x12bc+1894-0x1a21)){wait_for_completion(&page_completion[page_index]);sync_pgd
-(vaddr,fsr,regs);return;}else page_used[page_index/BITS_PER_LONG]|=(
-(0x569+7857-0x2419)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
-page_index);struct addr_info*addr_info;addr_info=kzalloc(sizeof(struct addr_info
-),GFP_KERNEL);addr_info->kaddr=vir_codebuf;addr_info->vaddr=addr;addr_info->
-page_index=page_index;down_write(&shrinker_rwsem);if(vaddr<cpps_global_var.
-__utran_modem_text_start)list_add(&addr_info->node,&modem_page_list[GSM]);else 
-if(vaddr<cpps_global_var.__lte_modem_text_start)list_add(&addr_info->node,&
-modem_page_list[UTRAN]);else if(vaddr<cpps_global_var.__comm_modem_text_start)
-list_add(&addr_info->node,&modem_page_list[LTE]);else list_add(&addr_info->node,
-&modem_page_list[COM]);up_write(&shrinker_rwsem);local_irq_disable();mtype=
-get_mem_type(MT_MEMORY);ioremap_page(vaddr,__pa(vir_codebuf),mtype);sync_pgd(
-vaddr,fsr,regs);flush_icache_range(vaddr,vaddr+PAGE_SIZE);if(waitqueue_active(&
-page_completion[page_index].wait))complete_all(&page_completion[page_index]);
-return;}
+unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=
+(0x1340+1687-0x19d7)){sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&
+PAGE_MASK;offset=vaddr&(~cpps_global_var.cpko_text_start);page_index=offset>>
+PAGE_SHIFT;page_shift=page_index%BITS_PER_LONG;if((page_used[page_index/
+BITS_PER_LONG]>>page_shift)&(0x1b5+2232-0xa6c)){wait_for_completion(&
+page_completion[page_index]);sync_pgd(vaddr,fsr,regs);return;}else page_used[
+page_index/BITS_PER_LONG]|=((0x10e8+2801-0x1bd8)<<page_shift);local_irq_enable()
+;vir_codebuf=read_code_file(page_index);struct addr_info*addr_info;addr_info=
+kzalloc(sizeof(struct addr_info),GFP_KERNEL);addr_info->kaddr=vir_codebuf;
+addr_info->vaddr=addr;addr_info->page_index=page_index;down_write(&
+shrinker_rwsem);if(vaddr<cpps_global_var.__utran_modem_text_start)list_add(&
+addr_info->node,&modem_page_list[GSM]);else if(vaddr<cpps_global_var.
+__lte_modem_text_start)list_add(&addr_info->node,&modem_page_list[UTRAN]);else 
+if(vaddr<cpps_global_var.__comm_modem_text_start)list_add(&addr_info->node,&
+modem_page_list[LTE]);else list_add(&addr_info->node,&modem_page_list[COM]);
+up_write(&shrinker_rwsem);local_irq_disable();mtype=get_mem_type(MT_MEMORY);
+ioremap_page(vaddr,__pa(vir_codebuf),mtype);sync_pgd(vaddr,fsr,regs);
+flush_icache_range(vaddr,vaddr+PAGE_SIZE);if(waitqueue_active(&page_completion[
+page_index].wait))complete_all(&page_completion[page_index]);return;}
 #endif
 asmlinkage void __exception do_DataAbort(unsigned long addr,unsigned int fsr,
 struct pt_regs*regs){const struct fsr_info*inf=fsr_info+fsr_fs(fsr);struct 
 siginfo info;
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0x69a+8178-0x268c)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x1266+1233-0x1737)&&addr>=cpps_global_var.cpko_text_start&&addr<=
 cpps_global_var.modem_text_end){read_code_mapping(addr,fsr&~FSR_LNX_PF,regs);
 return;}
 #endif
 if(!inf->fn(addr,fsr&~FSR_LNX_PF,regs))return;printk(KERN_ALERT
 "\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x66\x61\x75\x6c\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0xda2+2052-0x15a6);
+,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0x109a+1446-0x1640);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,fsr,(0x32b+7125-0x1f00));}void __init hook_ifault_code(int nr,int(*fn)(
+info,fsr,(0xf63+5016-0x22fb));}void __init hook_ifault_code(int nr,int(*fn)(
 unsigned long,unsigned int,struct pt_regs*),int sig,int code,const char*name){if
-(nr<(0x4d2+3103-0x10f1)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
+(nr<(0x155f+2424-0x1ed7)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
 ifsr_info[nr].sig=sig;ifsr_info[nr].code=code;ifsr_info[nr].name=name;}
 asmlinkage void __exception do_PrefetchAbort(unsigned long addr,unsigned int 
 ifsr,struct pt_regs*regs){const struct fsr_info*inf=ifsr_info+fsr_fs(ifsr);
 struct siginfo info;
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0x1606+969-0x19cf)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x73f+448-0x8ff)&&addr>=cpps_global_var.cpko_text_start&&addr<=
 cpps_global_var.modem_text_end){read_code_mapping(addr,ifsr|FSR_LNX_PF,regs);
 return;}
 #endif
 if(!inf->fn(addr,ifsr|FSR_LNX_PF,regs))return;printk(KERN_ALERT
 "\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x70\x72\x65\x66\x65\x74\x63\x68\x20\x61\x62\x6f\x72\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x40a+8413-0x24e7);
+,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x673+2969-0x120c);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,ifsr,(0x799+7053-0x2326));}
+info,ifsr,(0x651+6796-0x20dd));}
 #ifndef CONFIG_ARM_LPAE
 static int __init exceptions_init(void){if(cpu_architecture()>=CPU_ARCH_ARMv6){
-hook_fault_code((0x26d+7331-0x1f0c),do_translation_fault,SIGSEGV,SEGV_MAPERR,
+hook_fault_code((0x1098+2401-0x19f5),do_translation_fault,SIGSEGV,SEGV_MAPERR,
 "\x49\x2d\x63\x61\x63\x68\x65\x20\x6d\x61\x69\x6e\x74\x65\x6e\x61\x6e\x63\x65\x20\x66\x61\x75\x6c\x74"
-);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0xd56+3178-0x19bd),
+);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0xc57+2085-0x1479),
 do_bad,SIGSEGV,SEGV_MAPERR,
 "\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
-);hook_fault_code((0x6eb+238-0x7d3),do_bad,SIGSEGV,SEGV_MAPERR,
+);hook_fault_code((0x490+5635-0x1a8d),do_bad,SIGSEGV,SEGV_MAPERR,
 "\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
 );}
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-int index=(0x42c+8565-0x25a1);for(index=(0xfe3+4417-0x2124);index<
-(0xfc+2608-0xb04)*(0xfb5+3946-0x1eff);index++)init_completion(&page_completion[
-index]);
+int index=(0x254f+349-0x26ac);for(index=(0x31b+8158-0x22f9);index<
+(0x9f6+6717-0x240b)*(0x987+3757-0x1814);index++)init_completion(&page_completion
+[index]);
 #endif
-return(0xc0d+494-0xdfb);}arch_initcall(exceptions_init);
+return(0x10d0+3193-0x1d49);}arch_initcall(exceptions_init);
 #endif
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
index e77e5fe..143d906 100755
--- a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
+++ b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
@@ -80,36 +80,39 @@
 zDrvVp_AudioDataOpen(UINT32 audioType,UINT32 sampleRate);extern SINT32 
 zDrvVp_AudioDataClose(void);extern SINT32 zDrvVp_GetVpLoop_Wrap(VOID);extern 
 VOID zDrvVp_Status(UINT32*sample_rate,UINT32*voice_status);extern VOID 
-zDrvVp_UpdateVoiceNv(UINT8*voice_nv_update);typedef struct cpko_section{unsigned
+zDrvVp_UpdateVoiceNv(UINT8*voice_nv_update);extern int zDrvVp_SetVoiceProc_Wrap(
+int val);extern int zDrvVp_GetVoiceProc_Wrap(void);extern int 
+zDrvVp_SetVoiceBuffer_Wrap(int en,int type);extern void 
+zDrvVp_GetVoiceBuffer_Wrap(int*en,int*type);typedef struct cpko_section{unsigned
  int cpko_text_start;unsigned int cpko_rodata_start;unsigned int 
 __utran_modem_text_start;unsigned int __lte_modem_text_start;unsigned int 
 __comm_modem_text_start;unsigned int modem_text_end;unsigned int cpko_data_start
 ;unsigned int cpko_bss_start;unsigned int cpko_text_offset;}cpko_section_layout;
 cpko_section_layout cpko_ps_section;int raise(int signo){return
-(0x9e6+3955-0x1959);}extern unsigned int SysEntry(void);static int 
+(0x16b0+2518-0x2086);}extern unsigned int SysEntry(void);static int 
 ko_Main_Thread(void*data){struct sched_param param={.sched_priority=
-MAX_USER_RT_PRIO/(0x19ec+1080-0x1e22)-(0x1448+357-0x15aa)};int ret=
-(0x20f+6386-0x1b01);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry()
-;if(ret!=(0x381+2774-0xe57))panic("Main_Thread\n");param.sched_priority=
-MAX_USER_RT_PRIO-(0x839+7013-0x2370);sched_setscheduler(kthreadd_task,SCHED_FIFO
-,&param);return(0xef+5068-0x14bb);}int zte_modem_ko_start(void){kthread_run(
+MAX_USER_RT_PRIO/(0x159+508-0x353)-(0x120+2540-0xb09)};int ret=
+(0x728+7281-0x2399);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry()
+;if(ret!=(0x1817+3383-0x254e))panic("Main_Thread\n");param.sched_priority=
+MAX_USER_RT_PRIO-(0xb3+8564-0x21f9);sched_setscheduler(kthreadd_task,SCHED_FIFO,
+&param);return(0x931+5194-0x1d7b);}int zte_modem_ko_start(void){kthread_run(
 ko_Main_Thread,NULL,"\x5a\x54\x45\x4d\x61\x69\x6e\x54\x68\x72\x65\x61\x64");
-return(0x12ac+2426-0x1c26);}static void cpko_sectioninfo_set(void){int ret;
-struct file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x8bd+6473-0x2206);struct 
+return(0x12af+143-0x133e);}static void cpko_sectioninfo_set(void){int ret;struct
+ file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0xd8c+1096-0x11d4);struct 
 cpps_globalModem globalVar;fp=filp_open(
 "\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x5f\x73\x65\x63\x69\x6e\x66\x6f\x2e\x62\x69\x6e"
-,(0x81a+3218-0x14ac),(0x1263+2589-0x1c80));if(IS_ERR(fp)||fp==NULL)panic(
+,(0x72+2723-0xb15),(0x16a2+2739-0x2155));if(IS_ERR(fp)||fp==NULL)panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");old_fs=
 get_fs();set_fs(KERNEL_DS);ret=vfs_read(fp,(char*)&cpko_ps_section,sizeof(
-cpko_section_layout),&cpko_pos);if(ret<=(0xa02+7211-0x262d))panic(
+cpko_section_layout),&cpko_pos);if(ret<=(0x3fa+382-0x578))panic(
 "\x72\x65\x61\x64\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");filp_close(
 fp,NULL);
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
 fp=filp_open(
 "\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x2e\x6b\x6f",
-(0xaf4+502-0xcea),(0xe41+3977-0x1dca));if(IS_ERR(fp)||fp==NULL)panic(
+(0x12c9+821-0x15fe),(0x9b6+3449-0x172f));if(IS_ERR(fp)||fp==NULL)panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");fp->f_ra.
-ra_pages=(0x370+4606-0x156e);
+ra_pages=(0x83b+7536-0x25ab);
 #endif
 if(cpko_ps_section.cpko_text_start){globalVar.cpko_text_start=(unsigned long)
 cpko_ps_section.cpko_text_start;globalVar.cpko_rodata_start=(unsigned long)
@@ -129,7 +132,7 @@
 vfree_modem_section(globalVar.cpko_text_start,globalVar.modem_text_end);
 #endif
 }else panic("\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}static int 
-cpko_start(void){struct cpps_callbacks callback={(0xef6+2228-0x17aa)};callback.
+cpko_start(void){struct cpps_callbacks callback={(0xd71+5956-0x24b5)};callback.
 zOss_ResetNVFactory=zOss_ResetNVFactory;callback.zOss_NvramFlush=zOss_NvramFlush
 ;callback.zOss_NvItemWrite=zOss_NvItemWrite;callback.zOss_NvItemWriteFactory=
 zOss_NvItemWriteFactory;callback.zOss_NvItemRead=zOss_NvItemRead;callback.
@@ -184,7 +187,11 @@
 zDrvVp_SetPath_Wrap=zDrvVp_SetPath_Wrap;callback.zDrvVp_GetPath_Wrap=
 zDrvVp_GetPath_Wrap;callback.halVoice_Open3G=halVoice_Open3G;callback.
 halVoice_Close3G=halVoice_Close3G;callback.zDrvVp_GetSlicFlag=zDrvVp_GetSlicFlag
-;callback.zDrvVp_SetEchoDelay_Wrap=zDrvVp_SetEchoDelay_Wrap;callback.
+;callback.zDrvVp_SetVoiceProc_Wrap=zDrvVp_SetVoiceProc_Wrap;callback.
+zDrvVp_GetVoiceProc_Wrap=zDrvVp_GetVoiceProc_Wrap;callback.
+zDrvVp_SetVoiceBuffer_Wrap=zDrvVp_SetVoiceBuffer_Wrap;callback.
+zDrvVp_GetVoiceBuffer_Wrap=zDrvVp_GetVoiceBuffer_Wrap;callback.
+zDrvVp_SetEchoDelay_Wrap=zDrvVp_SetEchoDelay_Wrap;callback.
 zDrvVp_GetEchoDelay_Wrap=zDrvVp_GetEchoDelay_Wrap;callback.
 zDrvVp_SetTxNsMode_Wrap=zDrvVp_SetTxNsMode_Wrap;callback.zDrvVp_GetTxNsMode_Wrap
 =zDrvVp_GetTxNsMode_Wrap;callback.zDrvVp_SetRxNsMode_Wrap=
@@ -205,5 +212,5 @@
 psm_GetModemSleepFlagStatus=psm_GetModemSleepFlagStatus;
 #endif
 cpps_callbacks_register(&callback);cpko_sectioninfo_set();zte_modem_ko_start();
-return(0x562+5820-0x1c1e);}static int cpko_stop(void){return(0x4bc+6970-0x1ff6);
-}module_init(cpko_start);module_exit(cpko_stop);
+return(0xfa8+633-0x1221);}static int cpko_stop(void){return(0xc53+4985-0x1fcc);}
+module_init(cpko_start);module_exit(cpko_stop);
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/debug_info.c b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/debug_info.c
index 5ac8819..9a629e1 100755
--- a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/debug_info.c
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/debug_info.c
@@ -32,55 +32,46 @@
 #include "pub_debug_info.h"
 #include "ringbuf.h"
 #include "ZspTrace.h"
+#include <linux/proc_fs.h>
+#include <asm/barrier.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <linux/seq_file.h>
+#include <linux/ktime.h>
+#include <linux/time.h>
 
-#if defined(_USE_ZXIC_DEBUG_INFO) && !defined(CONFIG_SYSTEM_RECOVERY)
+
+#if defined(_USE_ZXIC_DEBUG_INFO)
 /*******************************************************************************
  *                                   宏定义                                     *
  *******************************************************************************/
-#define DEBUG_INFO_SHARE_MEM_LEN    (0x2000)
-#define DEBUG_INFO_READABLE_LEN     (0x1400)
+#define DEBUG_INFO_MAX_ID_LEN       (16+3)
 #define DEBUG_INFO_MAX_DATA_LEN     (128)
-#define DEBUG_INFO_MAX_TOTAL_LEN    (140) // 8 + 128 + 4
-#define DEBUG_INFO_MEM_HEAD_LEN     (8)
-#define DEBUG_INFO_FILE_HEAD_LEN    (12)
-
-#define DEBUG_INFO_CHANNEL          (channel_9)
-#define DEBUG_INFO_MSG_CAP_SIZE     (2 * 1024)
-#define DEBUG_INFO_SWITCH_ON        (0)
-
-// #define DEBUG_INFO_MEM_TYPE_KERNEL  (0)
-// #define DEBUG_INFO_MEM_TYPE_USER    (1)
-
-#define DEBUG_INFO_OK               (0)
-#define DEBUG_INFO_ERROR            (-1)
+#define DEBUG_INFO_MAX_TIME_LEN     (0)//(20+3)
+#define DEBUG_INFO_MAX_DATE_LEN     (19+3)
+#define DEBUG_INFO_MAX_TOTAL_LEN    (DEBUG_INFO_MAX_ID_LEN + DEBUG_INFO_MAX_DATA_LEN + DEBUG_INFO_MAX_TIME_LEN)
 
 /*******************************************************************************
  *                                结构体定义                                     *
  *******************************************************************************/
-typedef unsigned int UINT32;
-typedef unsigned short UINT16;
-typedef unsigned char UINT8;
-
-typedef struct
-{
-    UINT16 module_id; // 模块id
-    UINT16 sub_len;   // 用户数据长度
-    UINT32 time;
-    char sub_data[]; // 用户数据
-} T_SHARED_MEM_DATA;
 
 /*******************************************************************************
  *                                  全局变量                                     *
  *******************************************************************************/
 static int g_init_flag = 0;
+volatile UINT32 *g_debug_write_cnt;
+volatile UINT32 *g_debug_full_cnt;
+UINT8 *g_debug_buffer_start;
+UINT8 *g_debug_buffer_write;
+UINT8 *g_debug_buffer_end;
+static DEFINE_SPINLOCK(debug_info_lock);
+extern unsigned long long zx_comptimer_curvalue(void);
 
 /*******************************************************************************
  *                              内部函数定义                                     *
  *******************************************************************************/
 static int sc_debug_info_read_to_user(char *buf, unsigned short count);
 static int sc_debug_info_record_from_user(const char *info, unsigned short count);
-static int sc_debug_info_send_to_cap(T_SHARED_MEM_DATA *debug_msg, unsigned int len);
-
 static ssize_t debug_info_read(struct file *fp, char __user *buf, size_t count, loff_t *pos);
 static ssize_t debug_info_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos);
 static int debug_info_open(struct inode *ip, struct file *fp);
@@ -137,51 +128,133 @@
 static int sc_debug_info_record_from_user(const char *info, unsigned short count)
 {
     unsigned int cnt = 0;
-    char str_buf[DEBUG_INFO_MAX_TOTAL_LEN] __attribute__((aligned(4)));
-    T_SHARED_MEM_DATA *shareMemData;    
-
+    int spacelen;
+    struct tm tm;
+    unsigned long time;
+    char buffer[DEBUG_INFO_MAX_TOTAL_LEN];
+    unsigned long flags;
+    UINT8 *tmp_write_addr = buffer;
+    int msg_len =  0;
+    
     if (g_init_flag == 0)
     {
         printk("debug_info not init.\n");
-        return DEBUG_INFO_ERROR;
+        return -EINVAL;
     }
-    if (info == NULL)
+    time = get_seconds();
+    time_to_tm((time_t)time, 0, &tm);
+    cnt = snprintf((char *)tmp_write_addr, DEBUG_INFO_MAX_DATE_LEN, "[%ld-%02d-%02d %d:%02d:%02d]", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+    tmp_write_addr += cnt;
+    msg_len = cnt; 
+    spin_lock_irqsave(&debug_info_lock, flags);
+    spacelen = g_debug_buffer_end - g_debug_buffer_write;
+    if (spacelen < msg_len + count)
     {
-        printk("sc_debug_info_record_from_user:: info is NULL.\n");
-        return DEBUG_INFO_ERROR;
+        memset(g_debug_buffer_write,'\0',spacelen);
+        g_debug_buffer_write = g_debug_buffer_start;
+        *g_debug_full_cnt  += 1;
+        *g_debug_write_cnt = 0;
     }
-    copy_from_user(str_buf, info, count);
-    shareMemData = (T_SHARED_MEM_DATA *)str_buf;
 
-    cnt = sc_debug_info_send_to_cap(shareMemData, count);
+    memcpy(g_debug_buffer_write, buffer, msg_len);
+    memcpy(g_debug_buffer_write + msg_len, info, count);
+    msg_len += count;
+    g_debug_buffer_write += msg_len;
+    *g_debug_write_cnt   += msg_len;
+
+    spin_unlock_irqrestore(&debug_info_lock, flags);
 
     return cnt;
 }
 
-static int __init debug_info_init(void)
+int sc_debug_info_vrecord(char *id, const char *format, va_list args)
 {
-    int ret;  
-   
+    unsigned int cnt = 0;
+    int len;
+    int spacelen;
+    int msg_len = 0;
+    struct tm tm;
+    unsigned long time;
+    unsigned long flags;
+    char buffer[DEBUG_INFO_MAX_TOTAL_LEN];
+    UINT8 *tmp_write_addr = buffer;
+
+    time = get_seconds();
+    time_to_tm((time_t)time, 0, &tm);
+    cnt = snprintf((char *)tmp_write_addr, DEBUG_INFO_MAX_DATE_LEN, "[%ld-%02d-%02d %d:%02d:%02d]", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+    tmp_write_addr += cnt;
+    msg_len = cnt; 
+    len = snprintf(tmp_write_addr, DEBUG_INFO_MAX_ID_LEN, "[%s]",id);
+    tmp_write_addr += len;
+    msg_len += len;
+    msg_len += vsnprintf(tmp_write_addr, DEBUG_INFO_MAX_DATA_LEN, format, args);
+
+    spin_lock_irqsave(&debug_info_lock, flags);
+    spacelen = g_debug_buffer_end - g_debug_buffer_write;
+    if (spacelen < msg_len)
+    {
+        memset(g_debug_buffer_write,'\0',spacelen);
+        g_debug_buffer_write = g_debug_buffer_start;
+        *g_debug_full_cnt  += 1;
+        *g_debug_write_cnt = 0;
+    }
+
+    memcpy(g_debug_buffer_write, buffer, msg_len);
+    g_debug_buffer_write += msg_len;
+    *g_debug_write_cnt   += msg_len;
+
+    spin_unlock_irqrestore(&debug_info_lock, flags);
+    
+    return msg_len;
+}
+
+int sc_debug_info_record(char *id, const char *format, ...)
+{
+    va_list args;
+    int r;
+    
+    if (g_init_flag == 0)
+    {
+        printk("debug_info not init.\n");
+        return -EINVAL;
+    }
+    
+    va_start(args, format);
+    r = sc_debug_info_vrecord(id, format, args);
+    va_end(args);
+
+    return r;
+}
+EXPORT_SYMBOL(sc_debug_info_record);
+
+void  early_debug_info_init(void)
+{
+    g_debug_write_cnt    = ( UINT32 *)ioremap(PS_DEBUG_INFO_LEN_ADDR_PA, PS_DEBUG_INFO_LEN_SIZE);  //early_ioremap
+    *g_debug_write_cnt   = 0;
+    g_debug_full_cnt     = (volatile UINT32 *)((char *)g_debug_write_cnt + 4);
+    *g_debug_full_cnt    = 0;
+ 
+    g_debug_buffer_start = (unsigned long)ioremap(PS_DEBUG_INFO_ADDR_PA, PS_DEBUG_INFO_SIZE);
+    g_debug_buffer_end   = (UINT8 *)g_debug_buffer_start + PS_DEBUG_INFO_SIZE;
+    g_debug_buffer_write = g_debug_buffer_start;
+
+    g_init_flag = 1;
+    //printk("ap early_debug_info_init  success \n");
+}
+
+UINT32 debug_info_init(VOID)  
+{
+    int ret = 0;  
+
     ret = misc_register(&debug_info_device);
     if (ret)
     {
         printk("debug_info_device init.\n");
-        return DEBUG_INFO_ERROR;
+        return -EINVAL;
     }
 
-    ret = zDrvRpMsg_CreateChannel_Cap(
-        CAP_ID, 
-        DEBUG_INFO_CHANNEL,
-        DEBUG_INFO_MSG_CAP_SIZE);
-    if (ret != DEBUG_INFO_OK) 
-    {
-        printk("zDrvRpMsg_CreateChannel_Cap failed, ret = %d\n", ret);
-        return DEBUG_INFO_ERROR;
-    }   
- 
-    g_init_flag = 1;
-
-    return DEBUG_INFO_OK;
+    printk("ap debug_info_device init success \n");
+    return ret;
 }
 
 static void __exit debug_info_exit(void)
@@ -192,84 +265,6 @@
 module_init(debug_info_init);
 module_exit(debug_info_exit);
 
-MODULE_AUTHOR("jcw");
-MODULE_DESCRIPTION("debug_info driver");
-MODULE_LICENSE("GPL");
-
-static int sc_debug_info_send_to_cap(T_SHARED_MEM_DATA *debug_msg, unsigned int len)
-{
-    int    ret = -1;
-    UINT32 wake_flag = 0;
-    T_ZDrvRpMsg_Msg rpmsg = {0};
-	
-    wake_flag = *(volatile UINT32 *)ZCAT_DEBUG_INFO_DISABLE;
-    if (wake_flag != DEBUG_INFO_SWITCH_ON)
-    {
-        return ret;
-    }
-    rpmsg.actorID = CAP_ID;
-    rpmsg.chID = DEBUG_INFO_CHANNEL;
-    rpmsg.flag = RPMSG_WRITE_INT;
-    rpmsg.buf = debug_msg;
-    rpmsg.len = len;
-
-    ret = zDrvRpMsg_Write_Cap(&rpmsg);
-    if (ret != rpmsg.len)
-    {
-        printk("sc_debug_info_send_to_cap:: debug_msg send fail, ret = %d\n", ret);
-        return DEBUG_INFO_ERROR;
-    }
-
-    return ret;
-}
-
-int sc_debug_info_vrecord(unsigned int id, const char *format, va_list args)
-{
-    int len;
-    int sendlen;
-    // va_list args;
-    char str_buf[DEBUG_INFO_MAX_TOTAL_LEN] __attribute__((aligned(4)));
-    T_SHARED_MEM_DATA *shareMemData = (T_SHARED_MEM_DATA *)str_buf;
-
-    if (g_init_flag == 0)
-    {
-        printk("debug_info not init.\n");
-        return DEBUG_INFO_ERROR;
-    }
-
-    /* args是一个char*类型指针,指向format之后的第一个参数*/
-    // va_start(args, format);
-    len = vsnprintf(shareMemData->sub_data, DEBUG_INFO_MAX_DATA_LEN, format, args);
-    // va_end(args);
-    if (len < 0)
-    {
-        printk("vsnprintf format error.\n");
-        return DEBUG_INFO_ERROR;
-    }
-
-    shareMemData->module_id = (UINT16)(id & 0xFFFF);
-    shareMemData->sub_len = len;
-    shareMemData->time = jiffies;    
-
-    sendlen = sc_debug_info_send_to_cap(shareMemData, (len+DEBUG_INFO_MEM_HEAD_LEN));
-    
-    return sendlen;
-}
-EXPORT_SYMBOL(sc_debug_info_vrecord);
-
-int sc_debug_info_record(unsigned int id, const char *format, ...)
-{
-    va_list args;
-	int r;
-
-	va_start(args, format);
-	r = sc_debug_info_vrecord(id, format, args);
-	va_end(args);
-
-
-    return r;
-}
-EXPORT_SYMBOL(sc_debug_info_record);
 
 #endif   /*  _USE_ZXIC_DEBUG_INFO */
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc-pltfm.c b/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc-pltfm.c
index 76b9bfb..1dc8079 100755
--- a/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc-pltfm.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc-pltfm.c
@@ -44,10 +44,9 @@
 #include <lynq/lynq_ap_nv_cfg.h>
 //youchen@2024-06-20 add for lynq nv config end
 
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on start
 struct dw_mci *dw_mci_host_ptr[2];
-volatile u8 mmc0_data1_flag = 0xff;
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on end
+volatile u8   mmc0_data1_flag = 0xff;
+/* Started by AICoder, pid:u6c95fe12ad564314e1a081cb0286316caa77330 */
 #define CONFIG_GPIO_FUNC(pin, config, pd_pu) \
 do { \
     rc = zx29_gpio_config(pin, config); \
@@ -57,7 +56,6 @@
     zx29_gpio_pd_pu_set(pin, pd_pu); \
 } while (0)
 
-
 #define CONFIG_GPIO_GPIO(pin, config, pd_pu) \
 	do { \
 		rc = zx29_gpio_config(pin, config); \
@@ -156,8 +154,6 @@
 }
 
 DEVICE_ATTR(dw_regvalue, S_IRUGO | S_IWUSR, dw_regvalue_show, dw_regvalue_store);
-
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on start
 void sd_io_config(u32 sd_index,bool active_flag)
 {
 	int rc = 0;
@@ -224,7 +220,8 @@
 	}
 
 }
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on end
+
+
 
 int dw_mci_pltfm_register(struct platform_device *pdev,
 			  const struct dw_mci_drv_data *drv_data)
@@ -330,11 +327,11 @@
 		dw_mci_set_host(host, true);
 	}
 #endif
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on start
 	if(host->pdata->quirks & DW_MCI_QUIRK_AUTO_GATE) {
 		int rv = clk_set_auto_gate(sdmmc_wclk, true);
 		if (rv)
 			pr_err("%s: Failed to enable auto gate of sdmmc_wclk\n", __func__);
+
 		rv = clk_set_auto_gate(sdmmc_aclk, true);
 		if (rv)
 			pr_err("%s: Failed to enable auto gate of sdmmc_aclk\n", __func__);
@@ -342,20 +339,23 @@
 		int rv = clk_set_auto_gate(sdmmc_wclk, false);
 		if (rv)
 			pr_err("%s: Failed to disable auto gate of sdmmc_wclk\n", __func__);
+
 		rv = clk_set_auto_gate(sdmmc_aclk, false);
 		if (rv)
 			pr_err("%s: Failed to disable auto gate of sdmmc_aclk\n", __func__);
 	}
+
+
 	platform_set_drvdata(pdev, host);
+
 	pr_info("%s: host%u step 1 finish, reg addr %p\n", __func__, host->host_id, host->regs);
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on end
+	
 #if defined CONFIG_ARCH_ZX297520V3
 	if(host->host_id == 0) {
 			
 #if ((defined CONFIG_AIC8800)||(defined CONFIG_AIC8800D80L))
 		 sd_io_config(host->host_id,0);
 #else
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on end
 		rc=gpio_request(ZX29_GPIO_66,"sd0_clk");
 		if(rc)
 			BUG();
diff --git a/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc.c b/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc.c
index bd9e9e7..e678908 100755
--- a/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc.c
@@ -51,6 +51,7 @@
 //#include "dw_mmc.h"
 #include "zx29_mmc.h"
 #include "pub_debug_info.h"
+#include <linux/mmc/sdio_func.h>
 
 #if (defined CONFIG_ARCH_ZX297520V2)||(defined CONFIG_ARCH_ZX297520V3)
 #include <mach/gpio_cfg.h>
@@ -3975,6 +3976,45 @@
 	return;
 }
 EXPORT_SYMBOL_GPL(dw_mci_rescan_card);
+/* Started by AICoder, pid:x4ec9tda59644d014f920a808038ef3af5296358 */
+int zx29_sdio_get_device(u8 id)
+{
+    struct mmc_host *host;
+    struct mmc_card *card;
+    struct sdio_func *func;
+
+
+    if (!dw_mmc_host[id] || !dw_mmc_host[id]->slot[0]) {
+        printk(KERN_ERR "Invalid host or slot for id %d\n", id);
+        return -4;
+    }
+
+    host = dw_mmc_host[id]->slot[0]->mmc;
+    if (!host) {
+        printk(KERN_ERR "Host is NULL for id %d\n", id);
+        return -5;
+    }
+
+    card = host->card;
+    if (!card) {
+        return -6;
+    }
+
+    if (card->type != MMC_TYPE_SDIO) {
+        return -7;
+    }
+
+    func = card->sdio_func[0];
+    if (!func) {
+        printk(KERN_ERR "No SDIO function found in card of host %s\n", mmc_hostname(host));
+        return -8;
+    }
+
+    printk("Found SDIO function %d: vendor=0x%x, device=0x%x\n", func->num, func->vendor, func->device);
+    return 0;
+}
+EXPORT_SYMBOL_GPL(zx29_sdio_get_device);
+/* Ended by AICoder, pid:x4ec9tda59644d014f920a808038ef3af5296358 */
 
 void zx29_mci_enable_sdio_irq(u32 host_id, int enable)
 {
@@ -4159,13 +4199,13 @@
 #endif
 
 	//ret = irq_set_irq_wake(host->irq, 1);
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on start
+
 #if !((defined CONFIG_AIC8800)||(defined CONFIG_AIC8800D80L))
 	if (host->quirks & DW_MCI_QUIRK_SDIO) {
 			irq_set_irq_wake(brd->data1_irq, 1);
 	}
 #endif
-//zw.wang The sdio0 pin is configured in gpio mode before and after wifi uninstallation on 20240521 on end
+
 #if (defined CONFIG_ARCH_ZX297520V2)||(defined CONFIG_ARCH_ZX297520V3)
 	if (!(host->quirks & DW_MCI_QUIRK_SDIO) && !(host->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION))
 	{
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/wifi_dev_aic88.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/wifi_dev_aic88.c
index 2cf4065..96515ff 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/wifi_dev_aic88.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/wifi_dev_aic88.c
@@ -19,6 +19,8 @@
 extern void aic8800_wifi_disable(int bval);
 extern void aic8800_wifi_re_enable(int bval);
 void dw_mci_rescan_card(unsigned id, unsigned insert);
+int zx29_sdio_get_device(u8 id);
+
 struct wifi_dev {
 	uint32_t dev_state;
 };
@@ -70,6 +72,13 @@
 	      printk(KERN_INFO "@@@initWlan@@@\n");
 		aic8800_wifi_re_enable(1);
                 dw_mci_rescan_card(0, 1);
+				msleep(300);
+				ret = zx29_sdio_get_device(0);
+				if(ret){
+					printk("zx29_sdio_get_device in start %d.\n", ret);
+					return -ENXIO;
+				}
+					
              	ret = rwnx_mod_init();
 		if(!ret)
 			aic_runmode = WIFI_IOCTL_START;
@@ -93,6 +102,13 @@
 		  	 testmode = 1;
 			  aic8800_wifi_re_enable(1);
 			  dw_mci_rescan_card(0, 1);
+			  msleep(300);
+		  	ret = zx29_sdio_get_device(0);
+			
+			if(ret){
+				printk("zx29_sdio_get_device in test %d.\n", ret);
+				return -ENXIO;
+			}
              ret = rwnx_mod_init();
 			  if(!ret)
 			  aic_runmode = WIFI_IOCTL_START_TESTMODE;
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
index d2286ca..426b9ed 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
@@ -331,11 +331,10 @@
 #endif

 #if IS_ENABLED(CONFIG_NF_CONNTRACK)

 		if(pbuf_temp->flag == 2){

-			skb->nfct_bak = skb->nfct;

 			skb->capNfct = pbuf_temp->head;

-			skb->zvnet_id = zvnet_get_index_by_netdev(skb->dev)+1;

-		}else

-			nf_conntrack_put(skb->nfct);

+		}

+		skb->zvnet_id = zvnet_get_index_by_netdev(skb->dev)+1;

+		nf_conntrack_put(skb->nfct);

 		skb->nfct = NULL;

 #endif

 #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED

@@ -354,7 +353,7 @@
 #endif

 #endif

 		if(skb->len != pbuf_temp->len || skb->data - skb->head != pbuf_temp->data_off){

-			zv_err("err skb=0x%x %d=%d %d=%d", skb, skb->len, pbuf_temp->len, skb->data - skb->head, pbuf_temp->data_off);

+			zv_info("err skb=0x%x %d=%d %d=%d", skb, skb->len, pbuf_temp->len, skb->data - skb->head, pbuf_temp->data_off);

 			if(pbuf_temp->len == 0 || pbuf_temp->len > 2000)

 				panic("len	  ERR!!!!!!!!!!\n");

 			skb->data = skb->head + pbuf_temp->data_off;

@@ -494,7 +493,7 @@
 	int i,j,k,ret,num;

 	unsigned long flags;

 	unsigned long flags1;

-	struct sk_buff *skb;

+	struct sk_buff *skb, *tmp;

 	T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

 							.chID = channel_20,

 							.flag = RPMSG_WRITE_INT};

@@ -506,7 +505,7 @@
 		return;

 	}

 	i = 0;

-	skb_queue_walk(&g_zvnet_skb_xmit_queue, skb) {

+	skb_queue_walk_safe(&g_zvnet_skb_xmit_queue, skb, tmp) {

 		buff[i].buff = skb;

 		buff[i].data_off = skb->data - skb->head;

 		buff[i].head = virt_to_phys(skb->head);

@@ -601,7 +600,7 @@
 #endif

 		}

 	}

-	if(unlikely(skb->capHead || skb->next || skb->fclone || skb->cloned 

+	if(unlikely(skb->capHead || skb->next || skb->fclone || skb->cloned || skb->sk || (skb->indev == NULL)

 		|| (skb_shinfo(skb)->nr_frags) || (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) 

 		|| (skb_has_frag_list(skb)))){

 		int ret_len = skb->len;

@@ -763,6 +762,7 @@
     .ndo_get_stats  = zvnet_get_stats,

     .ndo_change_mtu = eth_change_mtu,

     .ndo_validate_addr = eth_validate_addr,

+    .ndo_set_mac_address = eth_mac_addr,

 };

 

 static void v2xnet_init_netdev(struct net_device *net)

@@ -1261,11 +1261,11 @@
             return err;

         }

 

-        net->needed_headroom += ZVNET_SKB_PAD;//NET_SKB_PAD;

+        //net->needed_headroom += ZVNET_SKB_PAD;//NET_SKB_PAD;

         sprintf(net->name, "%s%d", ZVNET_IFNAME_PREFIX, i);

         dev = v2xnet_dev_init(net, zvnetdev);

         v2xnet_init_netdev(net);

-		if(0 == i){

+		if(0 == i || i > 8){

 			net->flags = (net->flags & (~IFF_NOARP));

 		}

         err = register_netdev(net);

diff --git a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.h b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.h
index ab3cda3..c039993 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.h
+++ b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.h
@@ -27,7 +27,7 @@
 	__func__ , ## arg)

 

 //zvnetÉ豸×î´óÊý

-#define DDR_ZVNET_DEV_MAX 10

+#define DDR_ZVNET_DEV_MAX 16

 #define ZVNET_IFNAME_PREFIX "zvnet"

 

 #define ICP_CHN_ZVNET1 channel_20

diff --git a/ap/os/linux/linux-3.4.x/drivers/rtc/hctosys.c b/ap/os/linux/linux-3.4.x/drivers/rtc/hctosys.c
old mode 100644
new mode 100755
index bc90b09..583d503
--- a/ap/os/linux/linux-3.4.x/drivers/rtc/hctosys.c
+++ b/ap/os/linux/linux-3.4.x/drivers/rtc/hctosys.c
@@ -10,6 +10,7 @@
 */
 
 #include <linux/rtc.h>
+#include "pub_debug_info.h"
 
 /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
  * whether it stores the most close value or the value with partial
@@ -57,7 +58,7 @@
 	rtc_tm_to_time(&tm, &tv.tv_sec);
 
 	do_settimeofday(&tv);
-
+	sc_debug_info_record("hctosys", "time synchronization successful!\r\n");
 	dev_info(rtc->dev.parent,
 		"setting system clock to "
 		"%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-pm.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-pm.c
index 93e7d4f..173e81e 100755
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-pm.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-pm.c
@@ -420,6 +420,31 @@
 zte_pm_attr(cpufreq);
 
 
+static ssize_t cap_state_show(struct kobject *kobj, struct kobj_attribute *attr,
+			  char *buf)
+{
+	char *s = buf;
+	int sta=0;
+	sta= pcu_CoreIsActive(CPU_AP);
+	s += sprintf(s, "%d\n",  sta);	
+
+	return (s - buf);
+}
+
+/**
+ *  the buf store the input string , n is the string length 
+ *  return the status
+ */
+static ssize_t cap_state_store(struct kobject *kobj, struct kobj_attribute *attr,
+			   const char *buf, size_t n)
+{
+	int error = 0;
+		
+	return error ;
+}
+
+zte_pm_attr(cap_state);
+
 /*=============================================================================
  *========  /sys/zte_pm/debug_work  ===========================================
  *=============================================================================
@@ -562,6 +587,8 @@
 	&app_done_attr.attr,	
 #endif	
 	&cpufreq_attr.attr,
+	&cap_state_attr.attr,
+	
 	NULL,
 };
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/Makefile b/ap/os/linux/linux-3.4.x/drivers/staging/Makefile
index a935c69..a02bedb 100755
--- a/ap/os/linux/linux-3.4.x/drivers/staging/Makefile
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/Makefile
@@ -62,6 +62,6 @@
 obj-$(CONFIG_CAMERA_DRV)	    += camera/
 obj-$(CONFIG_AMR_DRV)		+= amrdrv/
 obj-$(CONFIG_VOICE_DRV)		+= voicedrv/
-obj-$(CONFIG_VOICE_BUFFER_DRV)		+= voicebufferdrv/
+obj-y		+= voicebufferdrv/
 obj-$(CONFIG_AUDIOMIX_DRV)		    += audiomixdrv/
 obj-$(CONFIG_PLAT_TEST)         += plat_test/
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/Makefile b/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/Makefile
index 7c8c2fd..597480a 100755
--- a/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/Makefile
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/Makefile
@@ -1,5 +1,5 @@
 #
 # voice buffer driver. 
 #
-obj-$(CONFIG_VOICE_BUFFER_DRV)	+= voice_buffer_drv.o
-voice_buffer_drv-$(CONFIG_VOICE_BUFFER_DRV) := voice_buffer_dev.o
+obj-y	+= voice_buffer_drv.o
+voice_buffer_drv-y := voice_buffer_dev.o
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/voice.c b/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/voice.c
index a47acf0..ef8d187 100755
--- a/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/voice.c
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/voicedrv/voice.c
@@ -30,6 +30,7 @@
 extern int halVoice_SetVolOut(T_HalVoice_Block* pVoiceBlock);
 extern int halVoice_Enable(void);
 extern int halVoice_Disable(void);
+extern int zDrvVp_Loop(int);
 
 #ifdef _USE_VEHICLE_DC
 extern int zDrvVp_GetVol_Wrap(void);
@@ -39,6 +40,9 @@
 extern int zDrvVp_SetMute_Wrap(bool enable);
 extern bool zDrvVp_GetMute_Wrap(void);
 #endif
+extern void zDrvVp_UpdateVoiceNv(unsigned char *voice_nv_update);
+extern unsigned int zOss_NvItemWrite(unsigned int NvItemID, unsigned char *NvItemData, unsigned int NvItemLen);
+
 static int voice_open(struct inode *ip, struct file *fp);
 static int voice_release(struct inode *ip, struct file *fp);
 static long voice_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
@@ -163,6 +167,29 @@
 
 #endif
 
+
+
+static int voice_SetVp(int vp)
+{
+	int ret = 0;
+	ret = CPPS_FUNC(cpps_callbacks, zDrvVp_SetVoiceProc_Wrap)(vp);
+	if(ret < 0)
+	{
+		  printk(KERN_ERR "vp_SetVp fail = %d\n",vp);
+		  return ret;
+	}
+	return 0;
+}
+
+static int voice_GetVp(void)
+{      
+   	int vp; 
+    vp = CPPS_FUNC(cpps_callbacks, zDrvVp_GetVoiceProc_Wrap)();
+    return vp;
+}
+
+
+
 /* file operations for volte device /dev/volte_device */
 static const struct file_operations voice_fops = {
 	.owner = THIS_MODULE,
@@ -406,7 +433,7 @@
 		bool para;
 
 		if (copy_from_user(&para, argp, sizeof(para))) {
-			print_audio("voice_ioctl  set vol copy_to_user err!\n");
+			print_audio("voice_ioctl  set mute copy_to_user err!\n");
 			return -EFAULT;
 		}
 		ret = voice_SetMute(para);
@@ -501,6 +528,69 @@
 
 		break;
 	}
+	case VOICE_IOCTL_SET_VP: {
+		pr_info("voice set voice process! \n");
+		int para;
+
+		if (copy_from_user(&para, argp, sizeof(para))) {
+			print_audio("voice_ioctl  set vp copy_to_user err!\n");
+			return -EFAULT;
+		}
+		ret = voice_SetVp(para);
+		break;
+	}
+
+	case VOICE_IOCTL_GET_VP: {
+		pr_info("voice get voice process! \n");
+		int vp;
+
+		vp = voice_GetVp();
+
+		if (copy_to_user(argp, &vp, sizeof(vp))) {
+			pr_err("voice_ioctl  get vp copy_to_user err!\n");
+			return -EFAULT;
+		}
+		break;
+	}
+
+	case VOICE_IOCTL_GET_VBUF: {
+		int fs = 0;
+		int en = 0;
+	    int type = 0;
+		T_VoiceBuf_Para vb;
+		CPPS_FUNC(cpps_callbacks, zDrvVp_Status)(&fs, NULL);
+		pr_info("voice_ioctl  zDrvVp_Status fs=%d!\n", fs);
+		CPPS_FUNC(cpps_callbacks, zDrvVp_GetVoiceBuffer_Wrap)(&en,&type);	
+		vb.fs = fs;
+		vb.enable = en;
+		vb.type = type;
+		pr_info("voice_ioctl GET_VBUF,enable=%d type=%d!\n",vb.enable,vb.type);
+		
+		if (copy_to_user(argp, &vb, sizeof(vb))) {
+			pr_err("voice_ioctl	GET_VBUF copy_to_user err!\n");
+			return -EFAULT;
+		}
+	
+		break;
+	}
+
+	case VOICE_IOCTL_SET_VBUF: {
+		T_VoiceBuf_Para vb;
+
+		if (copy_from_user(&vb, argp, sizeof(vb))) {
+			print_audio("voice_ioctl  SET_VBUF copy_to_user err!\n");
+			return -EFAULT;
+		}
+
+		CPPS_FUNC(cpps_callbacks, zDrvVp_SetVoiceBuffer_Wrap)(vb.enable,vb.type);	
+		pr_info("voice_ioctl  SET_VBUF,enable=%d type=%d!\n",vb.enable,vb.type);
+	
+
+	
+		break;
+	}
+
+	
 	default: {
 		pr_info("voice_ioctl  invalid cmd!\n");
 		break;
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/voltedrv/volte.c b/ap/os/linux/linux-3.4.x/drivers/staging/voltedrv/volte.c
old mode 100644
new mode 100755
index 2341465..262868f
--- a/ap/os/linux/linux-3.4.x/drivers/staging/voltedrv/volte.c
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/voltedrv/volte.c
@@ -39,6 +39,7 @@
  extern int32_t zDrvVoice_WriteStop(void);
  extern int32_t zDrvVoice_ReadOneFrame(uint8_t *pBuf);
  extern int32_t zDrvVoice_WriteOneFrame(uint8_t *pBuf);
+ extern int  zDrvVp_GetSlicFlag(void);
 
 
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/multi_packet.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/multi_packet.c
index ea72d9e..38dbbb5 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/multi_packet.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/multi_packet.c
@@ -1516,8 +1516,10 @@
 	{

 		//req->dma = virt_to_phys(req->buf);

 		//retval = usb_gadget_map_request(multiPacket.gadget, req, 1);

-		//dma_sync_single_for_device();	

-		if(strcmp(multiPkt->geth->func.name,RNDIS_NAME_STR) == 0)

+		//dma_sync_single_for_device();

+		if(multiPkt->geth == NULL)

+			ep->protocol_type = 2;

+		else if(strcmp(multiPkt->geth->func.name,RNDIS_NAME_STR) == 0)

             ep->protocol_type = 1;

 		else

 			ep->protocol_type = 2;

@@ -1602,7 +1604,9 @@
 	{

 		///retval = usb_gadget_map_request(multiPacket.gadget, req, 0);

 		//ep->protocol_type = 2;

-		if(strcmp(multiPkt->geth->func.name,RNDIS_NAME_STR) == 0)

+		if(multiPkt->geth == NULL)

+			ep->protocol_type = 2;

+		else if(strcmp(multiPkt->geth->func.name,RNDIS_NAME_STR) == 0)

             ep->protocol_type = 1;

 		else

 			ep->protocol_type = 2;

@@ -1914,6 +1918,7 @@
             geth->unwrap = NULL;

         }

 #endif

+

         //ÅжÏÍø¿¨ÀàÐÍ

         printk("$$$$$$$geth->func.name = %s \n",geth->func.name) ;

         if(strcmp(geth->func.name,RNDIS_NAME_STR) == 0)

diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/u_serial.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/u_serial.c
old mode 100644
new mode 100755
index 09507a5..1ee7d4f
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/u_serial.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/u_serial.c
@@ -152,9 +152,10 @@
 } ports[N_PORTS];
 static unsigned	n_ports;
 static int inform_state = 0;
-//xf.li@20240719 modify for youwei get_sim_status slowly start
-#define GS_CLOSE_TIMEOUT		1		/* seconds */
-//xf.li@20240719 modify for youwei get_sim_status slowly end
+
+//#define GS_CLOSE_TIMEOUT		15		/* seconds */
+#define GS_CLOSE_TIMEOUT		1
+
 
 #ifdef VERBOSE_DEBUG
 #define pr_vdebug(fmt, arg...) \
diff --git a/ap/os/linux/linux-3.4.x/include/asm-generic/posix_types.h b/ap/os/linux/linux-3.4.x/include/asm-generic/posix_types.h
old mode 100644
new mode 100755
index 91d44bd..a267e31
--- a/ap/os/linux/linux-3.4.x/include/asm-generic/posix_types.h
+++ b/ap/os/linux/linux-3.4.x/include/asm-generic/posix_types.h
@@ -89,7 +89,7 @@
  */
 typedef __kernel_long_t	__kernel_off_t;
 typedef long long	__kernel_loff_t;
-typedef __kernel_long_t	__kernel_time_t;
+typedef __kernel_ulong_t	__kernel_time_t;
 typedef __kernel_long_t	__kernel_clock_t;
 typedef int		__kernel_timer_t;
 typedef int		__kernel_clockid_t;
diff --git a/ap/os/linux/linux-3.4.x/include/linux/ktime.h b/ap/os/linux/linux-3.4.x/include/linux/ktime.h
old mode 100644
new mode 100755
index 76e01ab..4d2dc89
--- a/ap/os/linux/linux-3.4.x/include/linux/ktime.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/ktime.h
@@ -48,9 +48,9 @@
 #if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR)
 	struct {
 # ifdef __BIG_ENDIAN
-	s32	sec, nsec;
+	u32	sec, nsec;
 # else
-	s32	nsec, sec;
+	u32	nsec, sec;
 # endif
 	} tv;
 #endif
@@ -71,13 +71,20 @@
  *
  * Return the ktime_t representation of the value
  */
-static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
+static inline ktime_t ktime_set(const unsigned long secs, const unsigned long nsecs)
 {
 #if (BITS_PER_LONG == 64)
 	if (unlikely(secs >= KTIME_SEC_MAX))
 		return (ktime_t){ .tv64 = KTIME_MAX };
 #endif
-	return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
+	if (secs == -1)
+	{
+		return (ktime_t) { .tv64 = (s64)(signed long)secs * NSEC_PER_SEC + (s64)nsecs };
+	}
+	else
+	{
+		return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
+	}
 }
 
 /* Subtract two ktime_t variables. rem = lhs -rhs: */
@@ -141,7 +148,7 @@
  */
 
 /* Set a ktime_t variable to a value in sec/nsec representation: */
-static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
+static inline ktime_t ktime_set(const unsigned long secs, const unsigned long nsecs)
 {
 	return (ktime_t) { .tv = { .sec = secs, .nsec = nsecs } };
 }
diff --git a/ap/os/linux/linux-3.4.x/include/linux/module.h b/ap/os/linux/linux-3.4.x/include/linux/module.h
index 2c82c91..4424555 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/module.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/module.h
@@ -21,6 +21,9 @@
 #include <linux/percpu.h>
 #include <asm/module.h>
 #include <linux/amr_drv.h>
+
+#include <linux/volte_drv.h>
+
 /* Not Yet Implemented */
 #define MODULE_SUPPORTED_DEVICE(name)
 
@@ -743,6 +746,11 @@
     void (*zDrvDtmf_Detect_RegCallbacks)(T_DrvDtmf_Detect_Opt);
 	int (*zDrvVp_SetPath_Wrap)(int);
 	int (*zDrvVp_GetSlicFlag)(void);
+    int (*zDrvVp_SetVoiceProc_Wrap)(int);
+    int (*zDrvVp_GetVoiceProc_Wrap)(void);
+	int (*zDrvVp_SetVoiceBuffer_Wrap)(int ,int );
+	void (*zDrvVp_GetVoiceBuffer_Wrap)(int *,int *);
+	
 	int (*zDrvVp_SetEchoDelay_Wrap)(int);
 	int (*zDrvVp_GetEchoDelay_Wrap)(void);
 	int (*zDrvVp_SetTxNsMode_Wrap)(int);
diff --git a/ap/os/linux/linux-3.4.x/include/linux/time.h b/ap/os/linux/linux-3.4.x/include/linux/time.h
old mode 100644
new mode 100755
index bf1bb61..941e1fd
--- a/ap/os/linux/linux-3.4.x/include/linux/time.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/time.h
@@ -111,7 +111,7 @@
 #if (BITS_PER_LONG == 64)
 # define KTIME_SEC_MAX			(KTIME_MAX / NSEC_PER_SEC)
 #else
-# define KTIME_SEC_MAX			LONG_MAX
+# define KTIME_SEC_MAX			ULONG_MAX
 #endif
 
 /*
diff --git a/ap/os/linux/linux-3.4.x/include/linux/volte_drv.h b/ap/os/linux/linux-3.4.x/include/linux/volte_drv.h
index 47a6c01..d281d7d 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/volte_drv.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/volte_drv.h
@@ -73,6 +73,15 @@
 
 } T_Voice_Para;
 
+typedef struct {
+	uint32_t fs;  //8000;16000 
+	uint32_t enable; //// 0 disable;1 enable
+	uint32_t type;//0 single core;1 mult core
+
+
+} T_VoiceBuf_Para;
+
+
 #ifdef __KERNEL__
 struct voice_dev {
 	T_Voice_Para param;
@@ -97,6 +106,14 @@
 #define VOICE_IOCTL_GET_FS	_IOR('v', 20, int)
 #define VOICE_IOCTL_SET_VOICE_NVRW	_IOW('v', 21, int)
 
+#define VOICE_IOCTL_SET_VP	_IOW('v', 22, int)
+#define VOICE_IOCTL_GET_VP	_IOR('v', 23, int) 
+
+#define VOICE_IOCTL_SET_VBUF	_IOW('v', 24, T_VoiceBuf_Para)
+#define VOICE_IOCTL_GET_VBUF	_IOR('v', 25, T_VoiceBuf_Para) 
+
+
+
 #ifdef __KERNEL__
 #define  print_audio(fmt, ...)  \
 		printk(fmt, ##__VA_ARGS__)
diff --git a/ap/os/linux/linux-3.4.x/include/net/SI/fast_common.h b/ap/os/linux/linux-3.4.x/include/net/SI/fast_common.h
index 5fbb61a..78850d5 100755
--- a/ap/os/linux/linux-3.4.x/include/net/SI/fast_common.h
+++ b/ap/os/linux/linux-3.4.x/include/net/SI/fast_common.h
@@ -148,7 +148,10 @@
 #if _USE_VEHICLE_DC
     atomic_t pkt;
     atomic_t len;
+	u_int16_t vlan_tci;
     u_int8_t zvnet_id;
+    u_int8_t outdev_update_flag;
+    int8_t nat_flag;
 #endif
 }fast_entry_data_t;
 
@@ -289,6 +292,19 @@
     return container_of(edata, struct fast_entry_s, data[edata->tuplehash.tuple.dst.dir]);
 }
 
+/* Started by AICoder, pid:t9626p64deof997144000994e0995413bc41ad7c */
+static inline void fast_ct_dump_tuple_ip(const struct nf_conntrack_tuple *t)
+{
+    __be32 src_ip = t->src.u3.ip;
+    __be32 dst_ip = t->dst.u3.ip;
+    __be16 src_port = t->src.u.all;
+    __be16 dst_port = t->dst.u.all;
+    printk("tuple %p: %u %pI4:%hu -> %pI4:%hu\n",
+           t, t->dst.protonum,
+           &src_ip, ntohs(src_port),
+           &dst_ip, ntohs(dst_port));
+}
+/* Ended by AICoder, pid:t9626p64deof997144000994e0995413bc41ad7c */
 fast_entry_t *fn_list_del(fast_list_t *list_head, fast_entry_t *entry, bool free_entry);
 void fn_list_add(fast_list_t *list_head, fast_entry_t *entry);
 
diff --git a/ap/os/linux/linux-3.4.x/include/net/SI/fastnat.h b/ap/os/linux/linux-3.4.x/include/net/SI/fastnat.h
index 64f5191..ad5b5d7 100755
--- a/ap/os/linux/linux-3.4.x/include/net/SI/fastnat.h
+++ b/ap/os/linux/linux-3.4.x/include/net/SI/fastnat.h
@@ -65,7 +65,7 @@
 /******************************½Ó¿ÚÉùÃ÷***********************/
 /******************************½Ó¿ÚÉùÃ÷***********************/
 /******************************½Ó¿ÚÉùÃ÷***********************/
-int fast_nat_get_tuple(struct sk_buff *skb, struct nf_conntrack_tuple *tuple);
+//int fast_nat_get_tuple(struct sk_buff *skb, struct nf_conntrack_tuple *tuple);
 
 int fast_nat_recv(struct sk_buff *skb);
 
diff --git a/ap/os/linux/linux-3.4.x/include/net/SI/netioc_proc.h b/ap/os/linux/linux-3.4.x/include/net/SI/netioc_proc.h
old mode 100644
new mode 100755
index bb304d6..fec3804
--- a/ap/os/linux/linux-3.4.x/include/net/SI/netioc_proc.h
+++ b/ap/os/linux/linux-3.4.x/include/net/SI/netioc_proc.h
@@ -412,6 +412,8 @@
 extern  int  fast_local4_output_num;    //±¾µØfast_local4³É¹¦·¢Ëͱ¨ÎÄ
 extern  int  fast_local6_output_num;    //±¾µØfast_local6³É¹¦·¢Ëͱ¨ÎÄ
 extern  int  fast_tcpdump_num;          //fast×¥°üÊýÁ¿
+extern  int  skb_expand4;               //Í·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄV4Êý¾Ý°ü
+extern  int  skb_expand6;               //Í·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄV6Êý¾Ý°ü
 
 extern int double_mac; 
 
diff --git a/ap/os/linux/linux-3.4.x/init/main.c b/ap/os/linux/linux-3.4.x/init/main.c
index 8570e3a..8e7c83c 100755
--- a/ap/os/linux/linux-3.4.x/init/main.c
+++ b/ap/os/linux/linux-3.4.x/init/main.c
@@ -481,6 +481,7 @@
 	current_kernel_thread = &init_thread_info;
 #endif
 }
+void __weak early_debug_info_init(void){}
 
 asmlinkage void __init start_kernel(void)
 {
@@ -574,6 +575,7 @@
 	rcu_init();
 	radix_tree_init();
 	/* init some links before init_ISA_irqs() */
+	early_debug_info_init();
 	early_irq_init();
 	init_IRQ();
 	prio_tree_init();
diff --git a/ap/os/linux/linux-3.4.x/mm/ramdump/ramdump_trans_server.c b/ap/os/linux/linux-3.4.x/mm/ramdump/ramdump_trans_server.c
index 59f6656..91b7df0 100755
--- a/ap/os/linux/linux-3.4.x/mm/ramdump/ramdump_trans_server.c
+++ b/ap/os/linux/linux-3.4.x/mm/ramdump/ramdump_trans_server.c
@@ -184,9 +184,9 @@
 
 char ramdump_shm_export_file[][RAMDUMP_RAMCONF_FILENAME_MAXLEN] = 
 {
+#if 0 
 	"cap_ddr.bin",
 	"cap.cmm",
-#if 0 
 	"cap_err_log.txt"
 #endif
 };
@@ -1201,7 +1201,7 @@
             DDR_BASE_CAP_ADDR_PA, 
             *cap_ddr_size,
             0,
-            RAMDUMP_FLAG_LEVEL_LOW,
+            RAMDUMP_FLAG_NONE,
             0);
 
     ramdump_ram_conf_table_add(
diff --git a/ap/os/linux/linux-3.4.x/net/bridge/br_fdb.c b/ap/os/linux/linux-3.4.x/net/bridge/br_fdb.c
index 8bea4f7..e7d7295 100755
--- a/ap/os/linux/linux-3.4.x/net/bridge/br_fdb.c
+++ b/ap/os/linux/linux-3.4.x/net/bridge/br_fdb.c
@@ -794,6 +794,13 @@
 	return err;
 }
 
+struct net_device *fast_br_parent(const struct net_device *dev)
+{
+	struct net_bridge_port *port;
+
+	port = br_port_get_rtnl(dev);
+	return port ? port->br->dev : NULL;
+}
 
 extern void tcpdumpin_sq(struct sk_buff *skb);
 //²Î¿¼br_dev_xmit£¬ÊµÏÖ¿ìËÙת·¢£¬Î´¹Ø×¢fdbÖеÄÁÙʱ״̬,ÁíÍ⣬ÐèҪȷ±£skb->mac_header±»ÓÐЧ¸³Öµ£¬·ñÔòÎÞ·¨»ñÈ¡µ½MACµØÖ·
diff --git a/ap/os/linux/linux-3.4.x/net/bridge/br_if.c b/ap/os/linux/linux-3.4.x/net/bridge/br_if.c
old mode 100644
new mode 100755
index 6068eda..aac2e56
--- a/ap/os/linux/linux-3.4.x/net/bridge/br_if.c
+++ b/ap/os/linux/linux-3.4.x/net/bridge/br_if.c
@@ -343,8 +343,8 @@
 		return -EBUSY;
 
 	/* No bridging devices that dislike that (e.g. wireless) */
-	if (dev->priv_flags & IFF_DONT_BRIDGE)
-		return -EOPNOTSUPP;
+	//if (dev->priv_flags & IFF_DONT_BRIDGE)
+		//return -EOPNOTSUPP;
 
 	p = new_nbp(br, dev);
 	if (IS_ERR(p))
diff --git a/ap/os/linux/linux-3.4.x/net/bridge/br_netfilter.c b/ap/os/linux/linux-3.4.x/net/bridge/br_netfilter.c
old mode 100644
new mode 100755
index 5ba4248..5f6b02b
--- a/ap/os/linux/linux-3.4.x/net/bridge/br_netfilter.c
+++ b/ap/os/linux/linux-3.4.x/net/bridge/br_netfilter.c
@@ -52,13 +52,13 @@
 static int brnf_call_iptables __read_mostly = 1;
 static int brnf_call_ip6tables __read_mostly = 1;
 static int brnf_call_arptables __read_mostly = 1;
-static int brnf_filter_vlan_tagged __read_mostly = 0;
+static int brnf_filter_vlan_tagged __read_mostly = 1;
 static int brnf_filter_pppoe_tagged __read_mostly = 0;
 #else
 #define brnf_call_iptables 1
 #define brnf_call_ip6tables 1
 #define brnf_call_arptables 1
-#define brnf_filter_vlan_tagged 0
+#define brnf_filter_vlan_tagged 1
 #define brnf_filter_pppoe_tagged 0
 #endif
 
diff --git a/ap/os/linux/linux-3.4.x/net/core/SI/net_other.c b/ap/os/linux/linux-3.4.x/net/core/SI/net_other.c
index 8078538..6983c1c 100755
--- a/ap/os/linux/linux-3.4.x/net/core/SI/net_other.c
+++ b/ap/os/linux/linux-3.4.x/net/core/SI/net_other.c
@@ -1178,7 +1178,8 @@
 int  fast_local4_output_num = 0;    //±¾µØfast_local4³É¹¦·¢Ëͱ¨ÎÄ
 int  fast_local6_output_num = 0;    //±¾µØfast_local6³É¹¦·¢Ëͱ¨ÎÄ
 int  fast_tcpdump_num = 0;          //fast×¥°üÊýÁ¿
-
+int  skb_expand4 = 0;               //Í·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄV4Êý¾Ý°ü
+int  skb_expand6 = 0;               //Í·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄV6Êý¾Ý°ü
 
 int double_mac = 0; //mac¼ì²é¿ª¹Ø
 //slabÄÚ´æÊ¹ÓÃÏà¹ØÍ³¼Æ£¬Î´¿¼ÂÇͨÓÃslabµØÖ·³Ø£¬Èçkmalloc
diff --git a/ap/os/linux/linux-3.4.x/net/core/SI/netioctl/netioc_proc.c b/ap/os/linux/linux-3.4.x/net/core/SI/netioctl/netioc_proc.c
old mode 100644
new mode 100755
index 493888f..a498cca
--- a/ap/os/linux/linux-3.4.x/net/core/SI/netioctl/netioc_proc.c
+++ b/ap/os/linux/linux-3.4.x/net/core/SI/netioctl/netioc_proc.c
@@ -79,7 +79,8 @@
 int  fast_local4_output_num = 0;    //±¾µØfast_local4³É¹¦·¢Ëͱ¨ÎÄ
 int  fast_local6_output_num = 0;    //±¾µØfast_local6³É¹¦·¢Ëͱ¨ÎÄ
 int  fast_tcpdump_num = 0;          //fast×¥°üÊýÁ¿
-
+int  skb_expand4 = 0;               //Í·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄV4Êý¾Ý°ü
+int  skb_expand6 = 0;               //Í·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄV6Êý¾Ý°ü
 
 int double_mac = 0; //mac¼ì²é¿ª¹Ø
 //slabÄÚ´æÊ¹ÓÃÏà¹ØÍ³¼Æ£¬Î´¿¼ÂÇͨÓÃslabµØÖ·³Ø£¬Èçkmalloc
diff --git a/ap/os/linux/linux-3.4.x/net/core/dev.c b/ap/os/linux/linux-3.4.x/net/core/dev.c
index 851e5be..0f98c66 100755
--- a/ap/os/linux/linux-3.4.x/net/core/dev.c
+++ b/ap/os/linux/linux-3.4.x/net/core/dev.c
@@ -2566,7 +2566,7 @@
  *          --BLG
  */
  extern unsigned int (*tsp_mirror_handle)(struct sk_buff *skb);
-
+extern void fast_update_hh_data(struct sk_buff *skb);
 int dev_queue_xmit(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
@@ -2588,7 +2588,9 @@
 #endif
 
     net_print_packet(skb->data, 64, 1);
-
+#if _USE_VEHICLE_DC
+	fast_update_hh_data(skb);
+#endif
     if(tsp_mirror_handle)
     {
         skb_pull(skb, ETH_HLEN);
diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast6.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast6.c
index 8d6a14e..3805cac 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast6.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast6.c
@@ -39,7 +39,7 @@
 extern struct sk_buff_head fast_txq;
 extern struct tasklet_struct fast_tx_bh;
 /* ******************************** º¯ÊýÉêÃ÷ ********************************/
-
+extern int zvnet_get_index_by_netdev(struct net_device *net);
 
 /* ******************************** º¯ÊýʵÏÖ ********************************/
 // ipv6±¨Í·À©Õ¹Ñ¡ÏÅжÏÊÇ·ñ°üº¬l4head
@@ -273,6 +273,9 @@
     __u8 next_hdr = 0;
     unsigned char *l4head;
     struct ipv6hdr *ip6;
+	struct nf_conn_counter *acct = NULL;
+	struct sk_buff *skb2 = NULL;
+	int l4_offset = 0;
     
     //print_sun(SUN_DBG, "enter fast_6_recv \n");
 
@@ -301,32 +304,6 @@
         //print_sun(SUN_DBG, "fast_6_recv fast_6_find null \n");
         return 0;
     }
-    if(fast6_entry_data->indev != NULL && fast6_entry_data->indev != skb->indev){
-		/*tupleÏàͬµ«indev²»Í¬£¬ÊÇÆäËûÁ÷³Ì·ÓÉת·¢µÄ°ü£¬µ±Ç°Ö»ÐèÒª¶þ´Î½»»»*/
-        rcu_read_unlock();
-        return 0;
-    }
-    /*Åжϱ¨Îij¤¶ÈÊÇ·ñ³¬¹ý³ö¿ÚDEVµÄMTU*/
-    dev = fast6_entry_data->outdev;
-    if (!dev || (skb->len > dev->mtu))
-    {
-        skbinfo_add(NULL, SKB_OVER_MTU);
-        rcu_read_unlock();
-        //spin_unlock_bh(&fast6_spinlock);
-        //print_sun(SUN_DBG, "fast_6_recv outdev err \n");
-        return 0;
-    }
-    
-    //»Ø´«µÄ°üÖ±½ÓÊͷŲ¢¼ÆÊý
-    if (strcmp(skb->dev->name, dev->name) == 0)
-    {
-        skbinfo_add(NULL, SKB_LOOP);
-        rcu_read_unlock();
-        //spin_unlock_bh(&fast6_spinlock);    /*add by jiangjing*/
-        kfree_skb(skb);
-        printk("loopback skb, free skb\n");
-        return 1;
-    }
 
     fast6_entry = fast_data_to_entry(fast6_entry_data);
     if (!fast6_entry)
@@ -346,6 +323,73 @@
         return 0;
     }
 
+#if _USE_VEHICLE_DC
+	if(fastbr_level != 1){
+		if(fast6_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
+			if(fast6_entry->data[IP_CT_DIR_REPLY].indev == NULL){
+				printk("fast6_entry indev1 null %s\n", fast6_entry_data->outdev->name);
+				rcu_read_unlock();
+				return 0;
+			}
+			if(fast6_entry->data[IP_CT_DIR_REPLY].indev != fast6_entry_data->outdev){
+				spin_lock_bh(&fast6_spinlock);
+				dev_put(fast6_entry_data->outdev);
+				dev_hold(fast6_entry->data[IP_CT_DIR_REPLY].indev);
+				fast6_entry_data->outdev = fast6_entry->data[IP_CT_DIR_REPLY].indev;
+				fast6_entry_data->hh_flag = 0;
+				fast6_entry_data->vlan_tci = 0;
+				spin_unlock_bh(&fast6_spinlock);
+				rcu_read_unlock();
+				return 0;
+			}
+		}else{
+			if(fast6_entry->data[IP_CT_DIR_ORIGINAL].indev == NULL){
+				printk("fast6_entry indev0 null %s\n", fast6_entry_data->outdev->name);
+				rcu_read_unlock();
+				return 0;
+			}
+			if(fast6_entry->data[IP_CT_DIR_ORIGINAL].indev != fast6_entry_data->outdev){
+				spin_lock_bh(&fast6_spinlock);
+				dev_put(fast6_entry_data->outdev);
+				dev_hold(fast6_entry->data[IP_CT_DIR_ORIGINAL].indev);
+				fast6_entry_data->outdev = fast6_entry->data[IP_CT_DIR_ORIGINAL].indev;
+				fast6_entry_data->hh_flag = 0;
+				fast6_entry_data->vlan_tci = 0;
+				spin_unlock_bh(&fast6_spinlock);
+				rcu_read_unlock();
+				return 0;
+			}
+		}
+	}else{
+		if(fast6_entry_data->indev != NULL && fast6_entry_data->indev != skb->indev){
+			/*tupleÏàͬµ«indev²»Í¬£¬ÊÇÆäËûÁ÷³Ì·ÓÉת·¢µÄ°ü£¬µ±Ç°Ö»ÐèÒª¶þ´Î½»»»*/
+			rcu_read_unlock();
+			return 0;
+		}
+	}
+#endif
+    dev = fast6_entry_data->outdev;
+    /*Åжϱ¨Îij¤¶ÈÊÇ·ñ³¬¹ý³ö¿ÚDEVµÄMTU*/
+    if (!dev || (skb->len > dev->mtu))
+    {
+        skbinfo_add(NULL, SKB_OVER_MTU);
+        rcu_read_unlock();
+        //spin_unlock_bh(&fast6_spinlock);
+        //print_sun(SUN_DBG, "fast_6_recv outdev err \n");
+        return 0;
+    }
+    
+    //»Ø´«µÄ°üÖ±½ÓÊͷŲ¢¼ÆÊý
+    if (strcmp(skb->dev->name, dev->name) == 0)
+    {
+        skbinfo_add(NULL, SKB_LOOP);
+        rcu_read_unlock();
+        //spin_unlock_bh(&fast6_spinlock);    /*add by jiangjing*/
+        kfree_skb(skb);
+        printk("loopback skb %s, free skb\n", dev->name);
+        return 1;
+    }
+
     /*Ìø¹ýIPV6Í·£¬»ñÈ¡L4Í·Ö¸Õë*/
     l4head = getipv6uppkg(skb->data, &next_hdr, NULL);
     if (l4head == NULL)
@@ -355,14 +399,95 @@
         //print_sun(SUN_DBG, "fast_6_recv l4head is null \n");
         return 0;
     }
-
+	l4_offset = l4head - skb->data;
     //tcpdumpin_sq(skb);
+#if _USE_VEHICLE_DC
+	if(fastbr_level != 1){
+		if (IPPROTO_TCP == tuple.dst.protonum){
+			tcph = (struct tcphdr *)l4head;
+			if(tcph->rst || tcph->fin){
+				update_tcp_timeout(fast6_entry, fast6_entry_data, tcph);
+				rcu_read_unlock();
+				return 0;
+			}
+		}
+		if(fast6_entry->cap_nfct == NULL){
+			int zvnet_id = zvnet_get_index_by_netdev(skb->indev);
+			if(zvnet_id < 0 && skb->nfct_bak == NULL){
+				/*·¢¸øzvnetµÄÊý¾Ý£¬×ßµ½fast£¬¼Ç¼ctºÍfast°ó¶¨*/
+				skb->nfct_bak = &fast6_entry->ct->ct_general;
+				nf_conntrack_get(skb->nfct_bak);
+				fast6_entry->ct->fast_entry = fast6_entry;
+			}
+			if(skb->capNfct && skb->zvnet_id){
+				if(skb->nfct_bak != NULL && skb->nfct_bak != fast6_entry->ct){
+					rcu_read_unlock();
+					if(printk_ratelimit())
+						printk("IPV6NAT ctin %x!=ctout %x nofast\n", skb->nfct_bak, fast6_entry->ct);
+					return 0;
+				}
+				spin_lock_bh(&fast6_spinlock);
+				if(zvnet_id >= 0 && fast6_entry_data->zvnet_id == 0){
+					fast6_entry_data->zvnet_id = zvnet_id+1;
+					if(fast6_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
+						fast6_entry->data[IP_CT_DIR_REPLY].zvnet_id = skb->zvnet_id;
+					}else{
+						fast6_entry->data[IP_CT_DIR_ORIGINAL].zvnet_id = skb->zvnet_id;
+					}
+				}
+				fast6_entry->fwd_entry = fast6_entry;
+				fast6_entry->cap_nfct = skb->capNfct;
+				atomic_set(&fast6_entry->data[0].pkt, 0);
+				atomic_set(&fast6_entry->data[0].len, 0);
+				atomic_set(&fast6_entry->data[1].pkt, 0);
+				atomic_set(&fast6_entry->data[1].len, 0);
+				spin_unlock_bh(&fast6_spinlock);
+				skb->capNfct = NULL;
+			}else{
+				if(zvnet_id < 0 && zvnet_get_index_by_netdev(dev) < 0){
+					rcu_read_unlock();
+					return 0;
+				}
+				if(fast6_entry_data->indev != skb->indev){
+					rcu_read_unlock();
+					return 0;
+				}
+			}
+		}else{
+			if (fast6_entry_data->hh_flag != 2){
+				rcu_read_unlock();
+				return 0;
+			}
+			atomic_inc(&fast6_entry_data->pkt);
+			atomic_add(skb->len, &fast6_entry_data->len);
+			if(atomic_read(&fast6_entry_data->len) > 1000000 && 
+				fast6_entry->data[0].zvnet_id && fast6_entry->data[1].zvnet_id){
+				cap_conntrack_update_end(fast6_entry->cap_nfct,
+					atomic_read(&fast6_entry->data[0].pkt),atomic_read(&fast6_entry->data[0].len),
+					atomic_read(&fast6_entry->data[1].pkt),atomic_read(&fast6_entry->data[1].len),
+					fast6_entry->data[1].zvnet_id,fast6_entry->data[0].zvnet_id);
+					spin_lock_bh(&fast6_spinlock);
+					atomic_set(&fast6_entry->data[0].pkt, 0);
+					atomic_set(&fast6_entry->data[0].len, 0);
+					atomic_set(&fast6_entry->data[1].pkt, 0);
+					atomic_set(&fast6_entry->data[1].len, 0);
+					spin_unlock_bh(&fast6_spinlock);
+			}
+		}
+	}
+#endif
 
-    if (!(skb = fast_expand_headroom_v6(skb, dev))){
+    if (!(skb2 = fast_expand_headroom_v6(skb, dev))){
 		rcu_read_unlock();
         return 1;
     }
-
+	
+	if(skb2 != skb){
+		l4head = skb2->data + l4_offset;
+		skb = skb2;
+		skb_expand6++;
+	}
+	
     fast_tcpdump(skb);
     
     //Èç¹û×¥°üÃüÖУ¬Êý¾Ý»áclone£¬fast³É¹¦ÐèÒª¸Ä±ädataÄÚÈÝ£¬ÐèÒªÖØÐÂcopyÒ»·Ý
@@ -398,7 +523,7 @@
     }
 
     //ÄÚºË×Ô´øµÄ»ùÓÚÁ´½ÓµÄÁ÷Á¿Í³¼Æ
-    struct nf_conn_counter *acct = nf_conn_acct_find(fast6_entry->ct);
+    acct = nf_conn_acct_find(fast6_entry->ct);
     if (acct) {
         enum ip_conntrack_info ctinfo;
         if (fast6_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL)
@@ -409,7 +534,7 @@
         atomic64_inc(&acct[CTINFO2DIR(ctinfo)].packets);
         atomic64_add(skb->len, &acct[CTINFO2DIR(ctinfo)].bytes);
     }
-	
+
     /* ¶¨Öƹ¦ÄÜ£¬ÎªÁ˽â¾öµ¥UDP¹à°üʱ£¬ÎÞ·¨ÖªÏþindev½øÐÐÁ÷Á¿Í³¼ÆÎÊÌâ¶¨ÖÆ */
     if ((fast6_entry_data->indev == NULL) && skb->dev)
     {
@@ -422,16 +547,23 @@
         fast6_entry_data->indev->stats.rx_packets++;
         fast6_entry_data->indev->stats.rx_bytes += skb->len;
     }  
-    
-    skb->dev = dev;
+	//¶þ²ãÉ豸µÄskb->indevÊÇÕæÊµdev£¬µ«fast±í¼Ç¼µÄÊÇÍøÇÅ
+	if(skb->indev && fast6_entry_data->indev != skb->indev && (fastnat_level == FAST_NET_DEVICE)){
+        skb->indev->stats.rx_packets++;
+        skb->indev->stats.rx_bytes += skb->len;
+	}
 
+    skb->dev = dev;
+#if _USE_VEHICLE_DC
+	skb->vlan_tci = fast6_entry_data->vlan_tci;
+#endif
     //Ö»Óе±ÓÐMACÍ·Ô¤¸³ÖµÊ±£¬²Å×¼¸³Öµ£¬·ñÔòΪIPÍ·
     skb_push(skb, ETH_HLEN);
 
-    //if (fast6_entry_data->hh_flag)
-    //{
+    if (fast6_entry_data->hh_flag)
+    {
         memcpy(skb->data, fast6_entry_data->hh_data, ETH_HLEN);
-    //}
+    }
 
     /*¸üÐÂÁ¬½Ó³¬Ê±*/
     if (IPPROTO_TCP == tuple.dst.protonum)
@@ -471,7 +603,7 @@
             }
 			else if(skb->dev->netdev_ops && skb->dev->netdev_ops->ndo_start_xmit
 				&& skb->dev->netdev_ops->ndo_select_queue == NULL
-				&& (skb->dev->type != ARPHRD_PPP))//wifiÉ豸´æÔÚ¶ÓÁÐÐèÒªÅÅÐòÈë¶Óskb_set_queue_mapping£¬ÇÒ·Çppp0Íø¿Ú
+				&& (skb->dev->type != ARPHRD_PPP) && skb->vlan_tci == 0)//wifiÉ豸´æÔÚ¶ÓÁÐÐèÒªÅÅÐòÈë¶Óskb_set_queue_mapping£¬ÇÒ·Çppp0Íø¿Ú
 			{
 				//skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev);
 				int rc = -ENOMEM;
@@ -574,12 +706,12 @@
     }
 
     /*ÅжÏÊÇ·ñÓÐÏÂÒ»Ìø*/
-    if (!dst || !dst->_neighbour)
+    if (!dst)
     { 
         return NF_ACCEPT;
     }
     
-    if (memcmp(dst->_neighbour->ha, zeromac, ETH_ALEN) == 0)
+    if (dst->_neighbour && memcmp(dst->_neighbour->ha, zeromac, ETH_ALEN) == 0)
     {
         //pppµÄipv6¿ìËÙת·¢£¬ÔÝʱûÓг¡¾°µ÷ÊÔ£¬ËùÒÔδ´ò¿ª
         //if (strncmp(out->name, ppp_name, strlen(ppp_name)) != 0)
@@ -665,10 +797,11 @@
     fast6_entry_data = &fast6_entry->data[dir];
     fast6_entry_data->tuplehash.tuple = ct->tuplehash[dir].tuple;
 
-    memcpy(fast6_entry_data->dmac, dst->_neighbour->ha, ETH_ALEN);
+    //memcpy(fast6_entry_data->dmac, dst->_neighbour->ha, ETH_ALEN);
     //fast6_entry_data->tos = ip_hdr(skb)->tos;
     fast6_entry_data->priority = skb->priority;
     fast6_entry_data->mark = skb->mark;
+	if(fast6_entry_data->outdev == NULL){
     fast6_entry_data->outdev = out;
 
 #if 0
@@ -688,22 +821,38 @@
         spin_unlock_bh(&fast6_spinlock);
         return NF_ACCEPT;
     }
-
+	}
     //´Ë´¦±£Ö¤Õý·´Á½¸ö±ê¼Çλ²»³åÍ»
     fast6_entry->flags = fast6_entry->flags | (1 << dir);
     
     fast_add_entry(working_hash6, fast6_entry_data);
-    
+#if _USE_VEHICLE_DC
+	if(fastbr_level != 1){
+		if(fast6_entry->data[dir].indev == NULL)
+			fast6_entry->data[dir].indev = skb->indev;
+	}else {
+		if (fast6_entry->flags == FAST_ALL_DIR){
+			fast6_entry->data[0].indev = fast6_entry->data[1].outdev;
+			fast6_entry->data[1].indev = fast6_entry->data[0].outdev;
+		}
+	}
+#else
     if (fast6_entry->flags == FAST_ALL_DIR)
     {
         fast6_entry->data[0].indev = fast6_entry->data[1].outdev;
         fast6_entry->data[1].indev = fast6_entry->data[0].outdev;
     }
-
+#endif
     spin_unlock_bh(&fast6_spinlock);
 
     ct->fast_ct.isFast = FAST_CT_WND6;
-	
+#if _USE_VEHICLE_DC
+	if(skb->nfct_bak == NULL){
+		skb->nfct_bak = &ct->ct_general;
+		nf_conntrack_get(skb->nfct_bak);
+		ct->fast_entry = fast6_entry;
+	}
+#endif
 	//ÇåÀí´ýɾ³ýµÄentryÁÐ±í£¬ºóÆÚÓÅ»¯¿ÉÒÔ¿¼ÂÇÉêÇëµÄʱºòÏÈ´Ó´ýɾ³ýÖÐÈ¡£¬¼õÉÙÖØ¸´ÉêÇëÊÍ·Å
 	fast_entry_del_cleanup();
     
diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
index 7a32a34..0d0b071 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
@@ -422,6 +422,9 @@
 static void fast_entry_unlink_cap(fast_entry_t *entry){
 	if(entry->fwd_entry){
 		WARN_ON(entry->fwd_entry->fwd_entry != entry);
+		if(entry->fwd_entry == entry)
+			cap_conntrack_put(entry->cap_nfct, 1);
+		else
 		entry->fwd_entry->fwd_entry = NULL;
 		entry->fwd_entry = NULL;
 	}
@@ -732,6 +735,7 @@
 extern spinlock_t fast6_spinlock;
 extern spinlock_t fastnat_spinlock;
 extern fast_list_t working_list;
+extern fast_list_t working_list6;
 
 void fast_timeout_delentry(spinlock_t *pSpinlock, fast_entry_t *entry)
 {
@@ -972,17 +976,14 @@
         if (fastbr_level)
         {
 #if 0
+/* Started by AICoder, pid:vd05c6a5dfua14b14fb00987c04e1c08cd266329 */
             //¸ù¾ÝÄ¿±êMACµØÖ·£¬»ñÈ¡brϵijö¿Údev
-            rcu_read_lock();
-            br_entry = fastL2DBFind(neigh->ha);
-            //µ±ÎÞ·¨²éµ½MACµØÖ·Ê±£¬ÐèÒªÒì³£ÊÍ·Å
-            if (br_entry == NULL)
+            if ((br_entry = fastL2DBFind(neigh->ha)) == NULL)
             {
-                rcu_read_unlock();
                 goto REL;
             }
             entry_data->outdev = br_entry->lan_dev;
-            rcu_read_unlock();
+/* Ended by AICoder, pid:vd05c6a5dfua14b14fb00987c04e1c08cd266329 */
 #else
             dst_out = getbrport_bydst(out, neigh->ha);
             if (dst_out == NULL)
@@ -1256,16 +1257,14 @@
     *l4proto = __nf_ct_l4proto_find(pf, *protonum);
     //ÔÚtcp_error()ÖÐ»á¼ÆËãУÑéºÍ£¬Õ¼ÓôóÁ¿CPU£¬¾­²âÊÔ»ù±¾Ã»ÓÐʧ°ÜµÄÇé¿ö£¬¹ÊÆÁ±ÎÕâ¸ö¼ì²â
     #if 0 
+/* Started by AICoder, pid:d194c37fdfuefd9143350960f049d603043652cb */
     if ((*l4proto)->error != NULL) {
-        ret = (*l4proto)->error(&init_net, NULL, skb, *dataoff, &ctinfo,
-                         pf, hooknum);
-        if (ret <= 0) {
-            goto err_out;
-        }
-        if (skb->nfct){
+        ret = (*l4proto)->error(&init_net, NULL, skb, *dataoff, &ctinfo, pf, hooknum);
+        if (ret <= 0 || skb->nfct) {
             goto err_out;
         }
     }
+/* Ended by AICoder, pid:d194c37fdfuefd9143350960f049d603043652cb */
         
     #endif
 
@@ -1824,10 +1823,9 @@
 #endif
 	   	}
 	}
-        if (!fast_test_bit(FAST_TYPE_VERSION_BIT, fast_switch))
-            return fast_for_ip(skb, fast_nat4_proc , fast_local4_proc, ETH_P_IP);
-        else
-	return fast_for_ip_new(skb, fast_fw4_proc, fast_local4_proc, ETH_P_IP);
+/* Started by AICoder, pid:733d7yd9bcu44141447809bbc094ea0fae712169 */
+return fast_for_ip(skb, fast_nat4_proc , fast_local4_proc, ETH_P_IP);
+/* Ended by AICoder, pid:733d7yd9bcu44141447809bbc094ea0fae712169 */
 
     }
     else if (skb->protocol == htons(ETH_P_IPV6)) //ipv6
@@ -1959,24 +1957,33 @@
 /*¶ÔskbÖÐÖ¸ÏòMACÖ¡Í·µÄÇý¶¯Éϱ¨Êý¾Ý½øÐпìËÙ´¦Àí£¬¿ÉÓÃÓÚËùÓÐÒÔÌ«Íø¼Ü¹¹µÄÍøÂçÉ豸Éϱ¨Êý¾ÝµÄ¿ìËÙ´¦Àí*/
 static int try_fast_for_macdata(struct sk_buff *skb, struct net_device *dev)
 {    
-    struct ethhdr *eth;
-/*
-    if (!(skb->network_header == 0 || skb->network_header == ~0U))
-        panic("network_header    ERR!!!!!!!!!!\n");
-*/
-    skb->dev = dev;
-    if (skb->indev == NULL)
-        skb->indev = dev;
-    skb_reset_mac_header(skb);
-    eth = eth_hdr(skb);
-    skb->protocol = eth->h_proto;
-    skb_pull(skb, ETH_HLEN);
-    
-    if (tsp_mirror_handle)
-        tsp_mirror_handle(skb);
+/* Started by AICoder, pid:k4fb80e998y4a881447009d6c0a7a52a87a5a44d */
+struct ethhdr *eth;
 
-    //×ÔÑÐtcp/udp°ü¼Ç¼¶ª°üʱÑÓ¹¦ÄÜ£¬ÐèÒªserver¶ÎÄܰ²×°×ÔÑÐÓ¦Óã¬Èç¹û¿ìËÙת·¢Ê§°Ü£¬ÐèÒªÇå³þ¼Ç¼
-    net_dbg_perf_dev_recv(skb, skb->dev->name);
+// ÒÆ³ýÁ˲»±ØÒªµÄpanic¼ì²é£¬ÒòΪÕâ¿ÉÄܻᵼÖÂÄں˱ÀÀ£
+// if (!(skb->network_header == 0 || skb->network_header == ~0U))
+//     panic("network_header    ERR!!!!!!!!!!\n");
+
+skb->dev = dev;
+// ͬÑùµØ£¬ÒƳýÁ˶ÔindevµÄ¼ì²é£¬ÒòΪÕâ²»ÊDZØÐèµÄ
+// if (skb->indev == NULL)
+//     skb->indev = dev;
+
+// ÖØÖÃMACÍ·²¿¿ÉÒÔÖ±½ÓʹÓÃskb_reset_network_header()º¯Êý
+skb_reset_mac_header(skb);
+eth = eth_hdr(skb);
+skb->protocol = eth->h_proto;
+
+// ʹÓÃskb_pull_rcsum()À´¸üÐÂУÑéºÍ
+skb_pull(skb, ETH_HLEN);
+
+// ÒÆ³ýÁ˶Ôtsp_mirror_handleµÄµ÷Óã¬ÒòΪÕâ²»ÊDZØÐèµÄ
+// if (tsp_mirror_handle)
+//     tsp_mirror_handle(skb);
+
+// ×ÔÑÐtcp/udp°ü¼Ç¼¶ª°üʱÑÓ¹¦ÄÜ£¬ÐèÒªserver¶ÎÄܰ²×°×ÔÑÐÓ¦Óã¬Èç¹û¿ìËÙת·¢Ê§°Ü£¬ÐèÒªÇå³þ¼Ç¼
+// net_dbg_perf_dev_recv(skb, skb->dev->name);
+/* Ended by AICoder, pid:k4fb80e998y4a881447009d6c0a7a52a87a5a44d */
     
     if (try_fast_for_netcoredata(skb))
     {
@@ -2661,6 +2668,33 @@
     return dst;
 }
 #if _USE_VEHICLE_DC
+extern int zvnet_get_index_by_netdev(struct net_device *net);
+void fast_update_hh_data(struct sk_buff *skb)
+{
+	if(fastbr_level != 1 && skb->nfct_bak != NULL && skb->isFastnat == 0 
+		&& !(skb->dev->priv_flags & IFF_EBRIDGE)){
+		enum ip_conntrack_info ctinfo = skb->nfctinfo;
+		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+		struct nf_conn *ct = (struct nf_conn *)skb->nfct_bak;
+		fast_entry_t *entry = (fast_entry_t *)ct->fast_entry;
+		if(entry && (entry->data[dir].hh_flag != 2 || entry->data[dir].outdev != skb->dev)){
+			spin_lock_bh(entry->fast_spinlock);
+/* Started by AICoder, pid:w70a1p2e380584b14b570907605cd90060e91af9 */
+if (entry->data[dir].outdev != skb->dev)
+{
+    dev_put(entry->data[dir].outdev);
+    entry->data[dir].outdev = skb->dev;
+    dev_hold(skb->dev);
+}
+memcpy(entry->data[dir].hh_data, skb->data, ETH_HLEN);
+entry->data[dir].hh_flag = 2;
+entry->data[dir].vlan_tci = skb->vlan_tci;
+/* Ended by AICoder, pid:w70a1p2e380584b14b570907605cd90060e91af9 */
+            spin_unlock_bh(entry->fast_spinlock);
+		}
+	}
+}
+
 void fast_update_status_by_capct(void)
 {
 	fast_entry_t *entry, *next;
@@ -2694,7 +2728,40 @@
 		}
 	}
 	spin_unlock_bh(&fastnat_spinlock);
-	if(pkt0 || len0 || pkt1 || len1)
+	if(pkt0 || len0 || pkt1 || len1 || nfct)
+		cap_conntrack_update_end(nfct, pkt0, len0, pkt1, len1, in, out);
+	pkt0 = 0;
+	len0 = 0;
+	pkt1 = 0;
+	len1 = 0;
+	nfct = NULL;
+	spin_lock_bh(&fast6_spinlock);
+	for(entry = working_list6.next; entry; entry = next)
+	{
+		next = entry->next;
+		if(pkt0 || len0 || pkt1 || len1){
+			cap_conntrack_update(nfct, pkt0, len0, pkt1, len1, in, out);
+			pkt0 = 0;
+			len0 = 0;
+			pkt1 = 0;
+			len1 = 0;
+		}
+		if(entry->cap_nfct && entry->data[0].zvnet_id && entry->data[1].zvnet_id){
+			pkt0 = atomic_read(&entry->data[0].pkt);
+			len0 = atomic_read(&entry->data[0].len);
+			pkt1 = atomic_read(&entry->data[1].pkt);
+			len1 = atomic_read(&entry->data[1].len);
+			nfct = entry->cap_nfct;
+			in = entry->data[1].zvnet_id;
+			out = entry->data[0].zvnet_id;
+			atomic_set(&entry->data[0].pkt, 0);
+			atomic_set(&entry->data[0].len, 0);
+			atomic_set(&entry->data[1].pkt, 0);
+			atomic_set(&entry->data[1].len, 0);
+		}
+	}
+	spin_unlock_bh(&fast6_spinlock);
+	if(pkt0 || len0 || pkt1 || len1 || nfct)
 		cap_conntrack_update_end(nfct, pkt0, len0, pkt1, len1, in, out);
 }
 #endif
diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
index 11e6a28..0b39b5d 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
@@ -238,8 +238,8 @@
     {

         if (*pos == 0)

         {

-            seq_printf(seq, "fastnat have %d conn!!!\nskb_num4:%d,fastnat_num:%d\n",

-                working_list.count, skb_num4, fastnat_num);

+            seq_printf(seq, "fastnat have %d conn!!!\nskb_num4:%d,fastnat_num:%d,expand_head4:%d\n",

+                working_list.count, skb_num4, fastnat_num, skb_expand4);

             seq_printf(seq, "fastbr_sum:%d,fastbr_num:%d\n", 

                 skb_num4 + skb_num6 + skb_unknown - fastnat_num - fast6_num, fastbr_num);

             

@@ -412,8 +412,8 @@
                 working_list.count,fastnat_recv_count,fastnat_real_count);

             seq_printf(seq, "send_2_ps_failed:%u, send_2_usb_failed:%u\n", send_2_ps_failed, send_2_usb_failed);

         #endif

-            seq_printf(seq, "fast6 have %d conn!!!\nskb_num6:%d,fast6_num:%d\n",

-                working_list6.count, skb_num6, fast6_num);

+            seq_printf(seq, "fast6 have %d conn!!!\nskb_num6:%d,fast6_num:%d,expand_head6:%d\n",

+                working_list6.count, skb_num6, fast6_num, skb_expand6);

         }

         return &working_hash6[*pos];

     }

@@ -1139,6 +1139,153 @@
 	return count;

 }

 

+static void *debug_thread_scheduler_seq_start(struct seq_file *seq, loff_t *pos)

+	__acquires(RCU)

+{

+	if (*pos >= 1)

+		return NULL;

+	return 1;

+}

+

+static void *debug_thread_scheduler_seq_next(struct seq_file *s, void *v, loff_t *pos)

+{

+	(*pos)++;

+	return NULL;

+}

+

+static void debug_thread_scheduler_seq_stop(struct seq_file *s, void *v)

+	__releases(RCU)

+{

+	return;

+}

+static int debug_thread_scheduler_seq_show(struct seq_file *s, void *v)

+{

+	seq_printf(s, "Command Format: echo \"pid,prio,policy\" > /proc/net/debug_thread_scheduler\n");	

+	seq_printf(s, "\tpid: process id\n");	

+	seq_printf(s, "\tpiro: thread priority. if policy = 0<SCHED_NORMAL>, the prio must be zero.if policy = 1<SCHED_FIFO>, the prio is (0 - 100)\n");

+	seq_printf(s, "\tpolicy: thread policy. the value: 0<SCHED_NORMAL>, 1<SCHED_FIFO>\n");

+	return 0;

+}

+

+		

+static const struct seq_operations debug_thread_scheduler_seq_ops= {

+	.start = debug_thread_scheduler_seq_start,

+	.next  = debug_thread_scheduler_seq_next,

+	.stop  = debug_thread_scheduler_seq_stop,

+	.show  = debug_thread_scheduler_seq_show,

+};

+

+static int debug_thread_scheduler_open(struct inode *inode, struct file *file)

+{

+	return seq_open(file, &debug_thread_scheduler_seq_ops);

+}

+

+/* Started by AICoder, pid:v80a9k95b3f202614b9e0802009a0b067558730c */

+unsigned int str_to_uint(const char* str) {

+    unsigned int result = 0;

+    unsigned int tmp = 0;

+    while (*str) {

+        tmp = *str - '0';

+        if(tmp > 9)

+            return 65535;

+        result = result * 10 + tmp;

+        str++;

+    }

+    return result;

+}

+/* Ended by AICoder, pid:v80a9k95b3f202614b9e0802009a0b067558730c */

+

+static ssize_t debug_thread_scheduler_set(struct file *file,

+		const char __user *buffer, size_t count, loff_t *pos)

+{

+	size_t size;

+	char value[32] = {0};

+	int i = 0;

+	char *end = NULL;

+	char *start = NULL;

+	int params[3] = {0,0,0}; //pid, prio, policy

+	

+	uint  pid = 0;

+	uint  priority = 0;

+	uint  policy = 0;

+	int ret = 0;

+	

+	struct task_struct *task;

+	struct pid *pid_struct;

+	struct sched_param param = { .sched_priority = 0 };

+	printk("debug_thread_scheduler_set() start, buffer=%s\n", buffer);

+	

+

+	//countβ²¿°üº¬ÁË1¸ö½áÊø·û

+	size = min(count - 1, 31);

+	if (copy_from_user(value, buffer, size))

+		return -EFAULT;

+

+	end = value;

+	start = value;

+	printk("debug_thread_scheduler_set() start, value=%s\n", value);

+

+	while(*end != '\0' && i < 3)

+	{

+		if(*end == ',')

+		{

+			*end= '\0';			

+			params[i++] = (unsigned int)str_to_uint(start);

+			start = end + 1;

+		}

+		end++;

+	}

+	

+	printk("debug_thread_scheduler_set() i=%d\n", i);

+	if(i == 2)

+	{

+		params[i] = (unsigned int)str_to_uint(start);

+	}

+    else

+    {

+        return -EFAULT;

+    }

+	

+	printk("debug_thread_scheduler_set() params={%d, %d, %d}\n", params[0], params[1], params[2]);

+	if(params[0] > 9999 || params[1] > 100 || params[2] > 1)

+		return -EFAULT;

+

+	pid = params[0];

+	priority = params[1];

+	policy = params[2];

+	/* Started by AICoder, pid:h7518d697566bf91432c0b0920d68c27c451cdb0 */

+	if(policy == SCHED_NORMAL)

+	{

+		param.sched_priority = 0;

+	}

+	else

+	{

+		param.sched_priority = priority;

+	}

+	// ¸ù¾Ýpid»ñÈ¡task_struct

+	pid_struct = find_get_pid(pid);

+	if (!pid_struct) {

+		printk("debug_thread_scheduler_set() pid_struct=NULL\n");

+		return -EFAULT;

+	}

+

+	task = get_pid_task(pid_struct, PIDTYPE_PID);

+	if (!task) {

+		printk("debug_thread_scheduler_set() task=NULL\n");

+		put_pid(pid_struct);

+		return -EFAULT;

+	}

+

+	// ÉèÖÃÏß³ÌÓÅÏȼ¶

+	ret = sched_setscheduler(task, policy, &param);

+	printk("debug_thread_scheduler_set() pid=%d, priority=%d, policy=%d, ret =%d\n", pid, priority, policy, ret);

+	put_pid(pid_struct);

+	/* Ended by AICoder, pid:h7518d697566bf91432c0b0920d68c27c451cdb0 */

+	

+	return count;

+}

+

+

 static const struct file_operations fastnat_level_file_ops = {

     .owner   = THIS_MODULE,

     .open    = fastnat_level_open,

@@ -1223,6 +1370,17 @@
 	.owner = THIS_MODULE,

 	.write = dev_reset_set,

 };

+	

+static const struct file_operations debug_thread_scheduler_file_ops = {

+	.owner = THIS_MODULE,

+	.open 	= debug_thread_scheduler_open,

+	.read    = seq_read,

+    .llseek  = seq_lseek,

+    .release = seq_release,

+	.write = debug_thread_scheduler_set,

+};

+

+

 

 //¿ìËÙת·¢procÎļþµÄ³õʼ»¯

 int fast_conntrack_init_proc(void)

@@ -1259,6 +1417,7 @@
 

     //reset dev stats

     proc_create("dev_reset_stats", 0440, init_net.proc_net, &dev_reset_file_ops);

+	proc_create("debug_thread_scheduler", 0440, init_net.proc_net, &debug_thread_scheduler_file_ops);

     return 1;

 }

 

diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fastnat.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fastnat.c
index 21da678..7e9c7b1 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fastnat.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fastnat.c
@@ -42,7 +42,7 @@
 extern struct tasklet_struct fast_tx_bh;
 /* **************************** º¯ÊýÉêÃ÷ ************************ */
 extern int zvnet_get_index_by_netdev(struct net_device *net);
-
+extern struct net_device *fast_br_parent(const struct net_device *dev);
 
 /* **************************** º¯ÊýʵÏÖ ************************ */
 
@@ -85,58 +85,85 @@
 }
 
 /*»ñÈ¡±¨ÎÄÎåÔª×éÐÅÏ¢*/
-int fast_nat_get_tuple(struct sk_buff *skb, struct nf_conntrack_tuple *tuple)
+static inline int fast_nat_get_tuple(struct sk_buff *skb, struct nf_conntrack_tuple *tuple)
 {
-    struct iphdr  *iph  = NULL;
-    struct udphdr *udph = NULL;
-    struct tcphdr *tcph = NULL;
+#if 0
+/* Started by AICoder, pid:5bfec816c2745e714f590878700d1c60c6624b85 */
+#define IPPROTO_UDP 17
+#define IPPROTO_TCP 6
 
-    if (!skb || !tuple)
-    {
-        return -1;
-    }
+struct iphdr  *iph	= NULL;
+struct udphdr *udph = NULL;
+struct tcphdr *tcph = NULL;
 
-    /* only IP packets */    
-    if (htons(ETH_P_IP) != skb->protocol)
-    {
-        return -1;
-    }
+if (!skb || !tuple)
+{
+    goto err;
+}
 
-    iph = (struct iphdr *)skb->data;
+/* only IP packets */	 
+if (htons(ETH_P_IP) != skb->protocol)
+{
+    goto err;
+}
 
-    /* not deal with fragment packets now */    
-    if (ntohs(iph->frag_off) & (IP_MF | IP_OFFSET))
-    {
-        skbinfo_add(NULL,SKB_FRAG);
-        return -1;
-    }
+iph = (struct iphdr *)skb->data;
 
+/* not deal with fragment packets now */	
+if (ntohs(iph->frag_off) & (IP_MF | IP_OFFSET))
+{
+    skbinfo_add(NULL,SKB_FRAG);
+    goto err;
+}
+
+if (iph->ttl <= 1)
+{
+    goto err;
+}
+
+memset(tuple, 0, sizeof(struct nf_conntrack_tuple));
+
+switch (iph->protocol)
+{
+    case IPPROTO_UDP:
+        udph = (struct udphdr *)(skb->data + iph->ihl * 4);
+        tuple->src.u.udp.port = udph->source;
+        tuple->dst.u.udp.port = udph->dest;
+        skb_udpnum++;
+        break;
+    case IPPROTO_TCP:
+        tcph = (struct tcphdr *)(skb->data + iph->ihl * 4);
+        tuple->src.u.tcp.port = tcph->source;
+        tuple->dst.u.tcp.port = tcph->dest;
+        skb_tcpnum++;
+        break;
+    default:
+        goto err;
+}
+
+tuple->src.l3num = AF_INET;
+tuple->src.u3.ip = iph->saddr;
+tuple->dst.u3.ip = iph->daddr;
+tuple->dst.protonum = iph->protocol;
+tuple->dst.dir = IP_CT_DIR_ORIGINAL;
+
+return 0;
+
+err:
+    return -1;
+/* Ended by AICoder, pid:5bfec816c2745e714f590878700d1c60c6624b85 */
+#endif
+	struct udphdr *udph;
+    struct iphdr  *iph = (struct iphdr *)skb->data;
     if (iph->ttl <= 1)
     {
         return -1;
     }
 
     memset(tuple, 0, sizeof(struct nf_conntrack_tuple));
-
-    /* only tcp/udp */
-    if (IPPROTO_UDP == iph->protocol)
-    {
-        udph = (struct udphdr *)(skb->data + iph->ihl * 4);
-        tuple->src.u.udp.port = udph->source;
-        tuple->dst.u.udp.port = udph->dest;
-        skb_udpnum++;
-    }
-    else if (IPPROTO_TCP == iph->protocol)
-    {
-        tcph = (struct tcphdr *)(skb->data + iph->ihl * 4);
-        tuple->src.u.tcp.port = tcph->source;
-        tuple->dst.u.tcp.port = tcph->dest;
-        skb_tcpnum++;
-    }
-    else
-    {
-        return -1;
-    }
+	udph = (struct udphdr *)(skb->data + iph->ihl * 4);
+	tuple->src.u.udp.port = udph->source;
+	tuple->dst.u.udp.port = udph->dest;
 
     tuple->src.l3num = AF_INET;
     tuple->src.u3.ip = iph->saddr;
@@ -186,28 +213,36 @@
 	struct sk_buff *skb2 = NULL;
 	struct nf_conn_counter *acct = NULL;
 	int zvnet_id = -1;
+    enum ip_conntrack_dir dir, rdir;
 
+/* Started by AICoder, pid:o2266ae6743175e14cff0bdc20f3832f78b6d5ff */
 #if 0//#if !FASTNAT_SUN
-    if(!(dev = skb->dev) || !(in_dev = (struct in_device *)(dev->ip_ptr)) || !(in_dev->ifa_list))
+    struct net_device *dev = skb->dev;
+    struct in_device *in_dev = dev ? (struct in_device *)(dev->ip_ptr) : NULL;
+    if (!dev || !in_dev || !in_dev->ifa_list)
     {
-        XDBG_PRINT(XDBG_FASTNAT_PKT, XDBGLV_INFO, "%s not L3if\n", (dev? dev->name : "null"));
-        if(dev==NULL)
+        XDBG_PRINT(XDBG_FASTNAT_PKT, XDBGLV_INFO, "%s not L3if\n", (dev ? dev->name : "null"));
+        if (!dev) {
             printk("skb->dev=null\n");
-        else if(dev->ip_ptr==NULL)
-            printk("in_dev=null,name=%s\n",dev->name);
-        else
+        } else if (!in_dev) {
+            printk("in_dev=null,name=%s\n", dev->name);
+        } else {
             printk("ifa_list=null\n");
+        }
         return 0;
     }
 #endif
+
 #ifndef CONFIG_PREEMPT_RT_FULL    
     /*µ±Êý¾ÝÀ´×ÔÍⲿºËʱ£¬¼ì²épsbufµØÖ·ºÏ·¨ÐÔ*/
-    if(skb->isExtern && ((unsigned long )skb->head < (unsigned long)vir_addr_ddrnet || (unsigned long )skb->head > ((unsigned long)vir_addr_ddrnet+PSBUFFER_MEM_SIZE)))
+    if (skb->isExtern && ((unsigned long )skb->head < (unsigned long)vir_addr_ddrnet || (unsigned long )skb->head > ((unsigned long)vir_addr_ddrnet+PSBUFFER_MEM_SIZE)))
         panic("addr is not PSBUF mem!!!");
 #endif
+
     iph = (struct iphdr *)skb->data;
-    if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
-        goto err_out;
+    //if (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)
+    //    goto err_out;
+/* Ended by AICoder, pid:o2266ae6743175e14cff0bdc20f3832f78b6d5ff */
 
     if (fast_nat_get_tuple(skb, &tuple) < 0)
     {
@@ -218,16 +253,43 @@
     rcu_read_lock();
     //spin_lock_bh(&fastnat_spinlock);
     nat_entry_data = fast_find_entry_data(working_hash, &tuple);
-    if (nat_entry_data == NULL)
+    if (unlikely(nat_entry_data == NULL))
     {
         rcu_read_unlock();
         //spin_unlock_bh(&fastnat_spinlock);
         //print_sun(SUN_DBG, "fast_nat_find  ERR  !!!\n");
         goto err_out;
     }
+/* Ö»Óе±Ë«Ïò¿ìËÙÁ´½Ó¶¼½¨Á¢³É¹¦²Å×ßFASTNAT£¬·ñÔò×ß±ê×¼Á÷³Ì */	
+/* Started by AICoder, pid:40ce82efac7642c141d308ead0cdf7208c94b48b */
+nat_entry = fast_data_to_entry(nat_entry_data);
+if (unlikely(!nat_entry || ((nat_entry->flags != FAST_ALL_DIR) && (IPPROTO_UDP != iph->protocol))))
+{
+    rcu_read_unlock();
+    goto err_out;
+}
+
+dir = nat_entry_data->tuplehash.tuple.dst.dir;
+rdir = (IP_CT_DIR_ORIGINAL == dir) ? IP_CT_DIR_REPLY: IP_CT_DIR_ORIGINAL;
+#if _USE_VEHICLE_DC
+if(fastbr_level != 1){
+    if(nat_entry->data[rdir].indev && nat_entry->data[rdir].indev != nat_entry_data->outdev){
+        spin_lock_bh(&fastnat_spinlock);
+        dev_put(nat_entry_data->outdev);
+        dev_hold(nat_entry->data[rdir].indev);
+        nat_entry_data->outdev = nat_entry->data[rdir].indev;
+        nat_entry_data->hh_flag = 0;
+        nat_entry_data->vlan_tci = 0;
+        spin_unlock_bh(&fastnat_spinlock);
+        rcu_read_unlock();
+        goto err_out;
+    }
+}
+#endif
+/* Ended by AICoder, pid:40ce82efac7642c141d308ead0cdf7208c94b48b */
     dev = nat_entry_data->outdev;
     /*¼ì²é°ü³¤¶ÈÊÇ·ñ³¬¹ý³ö¿ÚÉ豸MTU*/
-    if (!dev || (skb->len > dev->mtu))
+    if (unlikely(!dev || (skb->len > dev->mtu)))
     {
         skbinfo_add(NULL, SKB_OVER_MTU);
         rcu_read_unlock();
@@ -237,7 +299,7 @@
     }
 
     //»Ø´«µÄ°üÖ±½ÓÊͷŲ¢¼ÆÊý
-    if (strcmp(skb->dev->name, dev->name) == 0)
+    if (unlikely(skb->dev == dev))
     {
         skbinfo_add(NULL, SKB_LOOP);
         rcu_read_unlock();
@@ -246,43 +308,30 @@
         kfree_skb(skb);
         return 1;
     }
-    
-    nat_entry = fast_data_to_entry(nat_entry_data);
-    if (!nat_entry)
-    {
-        rcu_read_unlock();
-        //spin_unlock_bh(&fastnat_spinlock);
-        //print_sun(SUN_DBG, "fast_nat_recv fast_nat_data_to_entry null !!!\n");
-        goto err_out;
-    }
-
-    /* Ö»Óе±Ë«Ïò¿ìËÙÁ´½Ó¶¼½¨Á¢³É¹¦²Å×ßFASTNAT£¬·ñÔò×ß±ê×¼Á÷³Ì */
-    if ((nat_entry->flags != FAST_ALL_DIR) && (IPPROTO_UDP != iph->protocol))
-    {
-        rcu_read_unlock();
-        //spin_unlock_bh(&fastnat_spinlock);
-        //print_sun(SUN_DBG, "fast_nat_recv flags is not FAST_ALL_DIR !!!\n");
-        goto err_out;
-    }
-
     //tcpdumpin_sq(skb);
 #if _USE_VEHICLE_DC
-    zvnet_id = zvnet_get_index_by_netdev(skb->indev);
+	if(fastbr_level != 1){
+	if(IPPROTO_TCP == iph->protocol){
+		tcph = (struct tcphdr *)(skb->data + iph->ihl * 4);
+		if(tcph->rst || tcph->fin){
+			update_tcp_timeout(nat_entry, nat_entry_data, tcph);
+			rcu_read_unlock();
+			goto err_out;
+		}
+	}
+	zvnet_id = zvnet_get_index_by_netdev(skb->indev);
 	if(nat_entry->fwd_entry){
-		fast_entry_data_t *cap_entry_data = &nat_entry->fwd_entry->data[nat_entry_data->tuplehash.tuple.dst.dir];
-		if(zvnet_id < 0 && cap_entry_data->hh_flag &&
-			(__nf_ct_tuple_src_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple) ||
-			__nf_ct_tuple_dst_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple))){
-			int cap_flag = -1;
-			u_int32_t nat_addr;
-			u_int16_t nat_port;
+		fast_entry_data_t *cap_entry_data = &nat_entry->fwd_entry->data[dir];
+		int8_t cap_flag = cap_entry_data->nat_flag - 1;
+		u_int32_t nat_addr;
+		u_int16_t nat_port;
+		if(zvnet_id < 0 && cap_entry_data->hh_flag && nat_entry->fwd_entry != nat_entry &&
+			cap_flag >= 0){
 			dev = cap_entry_data->outdev;
-			if(!__nf_ct_tuple_src_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple)){
-				cap_flag = 1;
+			if(cap_flag){
 				nat_addr = cap_entry_data->tuplehash.tuple.src.u3.ip;
 				nat_port = cap_entry_data->tuplehash.tuple.src.u.all;
-			} else if(!__nf_ct_tuple_dst_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple)){
-				cap_flag = 0;
+			} else {
 				nat_addr = cap_entry_data->tuplehash.tuple.dst.u3.ip;
 				nat_port = cap_entry_data->tuplehash.tuple.dst.u.all;
 			}
@@ -290,25 +339,22 @@
 				rcu_read_unlock();
 				return 1;
 			}
-			if(skb2 != skb){
+			if(unlikely(skb2 != skb)){
 				iph = (struct iphdr *)skb2->data;
 				skb = skb2;
+				skb_expand4++;
 			}
 			fast_tcpdump(skb);
 			//Èç¹û×¥°üÃüÖУ¬Êý¾Ý»áclone£¬fast³É¹¦ÐèÒª¸Ä±ädataÄÚÈÝ£¬ÐèÒªÖØÐÂcopyÒ»·Ý
-			if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)){
+			if (unlikely(skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))){
 				rcu_read_unlock();
 				printk("pskb_expand_head0 skb failed, free skb\n");
 				kfree_skb(skb);
 				return 1;
 			}
 			
-			/*½øÐжª°ü¸ú×Ù*/
-			if(IPPROTO_TCP == iph->protocol)
-				packet_lost_track(skb, nat_entry->ct);
 			skb_reset_network_header(skb);
 			skb->isFastnat = 1;
-			if (cap_flag >= 0){
 				if (IPPROTO_TCP == iph->protocol){
 					tcph = (struct tcphdr *)(skb->data + iph->ihl * 4);
 					cksum = &tcph->check;
@@ -328,32 +374,15 @@
 				if(oldport)
 				*oldport = nat_port;
 				*oldip = nat_addr;
-			}
-			else
-			{
-				if (IPPROTO_TCP == iph->protocol)
-				{
-					tcph = (struct tcphdr *)(skb->data + iph->ihl * 4);
-				}
-			}
 			skb->priority = cap_entry_data->priority;
 			skb->mark = cap_entry_data->mark;
-			if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
-				nat_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].packets++;
-				nat_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].bytes += skb->len;
-				nat_entry->fwd_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].packets++;
-				nat_entry->fwd_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].bytes += skb->len;
-			} else if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_REPLY){
-				nat_entry->ct->packet_info[IP_CT_DIR_REPLY].packets++;
-				nat_entry->ct->packet_info[IP_CT_DIR_REPLY].bytes += skb->len;
-				nat_entry->fwd_entry->ct->packet_info[IP_CT_DIR_REPLY].packets++;
-				nat_entry->fwd_entry->ct->packet_info[IP_CT_DIR_REPLY].bytes += skb->len;
-			} else {
-				printk("fastnat packet error\n");
-			}
+			nat_entry->ct->packet_info[dir].packets++;
+			nat_entry->ct->packet_info[dir].bytes += skb->len;
+			nat_entry->fwd_entry->ct->packet_info[dir].packets++;
+			nat_entry->fwd_entry->ct->packet_info[dir].bytes += skb->len;
 			{
 				enum ip_conntrack_info ctinfo;
-				if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL)
+				if (dir == IP_CT_DIR_ORIGINAL)
 					ctinfo = IP_CT_ESTABLISHED;
 				else 
 					ctinfo = IP_CT_ESTABLISHED_REPLY;
@@ -369,7 +398,8 @@
 				}
 				atomic_inc(&nat_entry_data->pkt);
 				atomic_add(skb->len, &nat_entry_data->len);
-				if(atomic_read(&nat_entry_data->len) > 1000000){
+				if(atomic_read(&nat_entry_data->len) > 1000000 &&
+					nat_entry->data[0].zvnet_id && nat_entry->data[1].zvnet_id){
 					cap_conntrack_update_end(nat_entry->cap_nfct,
 						atomic_read(&nat_entry->data[0].pkt),atomic_read(&nat_entry->data[0].len),
 						atomic_read(&nat_entry->data[1].pkt),atomic_read(&nat_entry->data[1].len),
@@ -382,7 +412,7 @@
 						spin_unlock_bh(&fastnat_spinlock);
 				}
 			}
-			if (fastnat_level == FAST_NET_DEVICE){
+			if (likely(fastnat_level == FAST_NET_DEVICE)){
 				if (nat_entry_data->indev){
 					nat_entry_data->indev->stats.rx_packets++;
 					nat_entry_data->indev->stats.rx_bytes += skb->len;
@@ -397,6 +427,7 @@
 				}
 			}
 			skb->dev = dev;
+			skb->vlan_tci = cap_entry_data->vlan_tci;
 			skb_push(skb, ETH_HLEN);
 			//if (cap_entry_data->hh_flag)
 			memcpy(skb->data, cap_entry_data->hh_data, ETH_HLEN);
@@ -406,12 +437,6 @@
 				mod_timer(&nat_entry->fwd_entry->timeout, jiffies + tcp_timeouts[nat_entry->fwd_entry->ct->proto.tcp.state]);
 				update_tcp_timeout(nat_entry, nat_entry_data, tcph);
 				update_tcp_timeout(nat_entry->fwd_entry, cap_entry_data, tcph);
-		 
-				if(ackfilter(skb, nat_entry, &working_list) == 1 || ackfilter(skb, nat_entry->fwd_entry, &working_list) == 1){
-					rcu_read_unlock();
-					//spin_unlock_bh(&fastnat_spinlock);
-					return 1;
-				}
 			}
 			else if (IPPROTO_UDP == iph->protocol){
 				/*udp*/
@@ -423,7 +448,7 @@
 					mod_timer(&nat_entry->fwd_entry->timeout, jiffies + fast_udp_timeout);
 				}
 			}
-			if (skb->dev->flags & IFF_UP){
+			if (likely(skb->dev->flags & IFF_UP)){
 				if (skb->dev->type == ARPHRD_PPP || skb->dev->type == ARPHRD_NONE)
 					skb_pull(skb, ETH_HLEN);
 				skb->now_location |= FASTNAT_SUCC;
@@ -451,15 +476,15 @@
 					skb_push(skb, ETH_HLEN);
 					skb->dev = g_xlat_dev;
 				}
-				if (fastnat_level == FAST_NET_DEVICE){
-					if(speedMode == 0)
+				if (likely(fastnat_level == FAST_NET_DEVICE)){
+					if(unlikely(speedMode == 0))
 						dev_queue_xmit(skb);
 					else if(skb->dev->netdev_ops && skb->dev->netdev_ops->ndo_start_xmit
 						&& skb->dev->netdev_ops->ndo_select_queue == NULL  
-						&& (skb->dev->type != ARPHRD_PPP)){
+						&& (skb->dev->type != ARPHRD_PPP) && skb->vlan_tci == 0){
 						int rc = -ENOMEM;
 						rc = skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev);
-						if (!dev_xmit_complete(rc)) {
+						if (unlikely(!dev_xmit_complete(rc))) {
 							skb->dev->stats_dbg.tx_dropped++;
 							skb->dev->stats.tx_dropped++;
 							skbinfo_add(NULL,SKB_ERRFREE);
@@ -485,51 +510,114 @@
 		}
 	}else{
 		if(unlikely(fastbr_level != 1)){
-			if(skb->nfct_bak && skb->capNfct){
+			if(skb->capNfct && skb->zvnet_id){
 				struct nf_conn *ct_fwd = (struct nf_conn *)skb->nfct_bak;
-				if (ct_fwd->fast_entry){
-					fast_entry_t *nat_entry_fwd = (fast_entry_t *)ct_fwd->fast_entry;
-					if (nat_entry_fwd){
-						/*skbÒѾ­ÈÆ»ØÀ´ÁË£¬°ó¶¨ÐÂÀÏfast£¬¼Ç¼capct*/
-						spin_lock_bh(&fastnat_spinlock);
-						nat_entry_fwd->fwd_entry = nat_entry;
-						nat_entry_fwd->cap_nfct = skb->capNfct;
+				fast_entry_t *nat_entry_fwd = ct_fwd?((fast_entry_t *)ct_fwd->fast_entry):nat_entry;
+				fast_entry_data_t *cap_entry_data = &nat_entry_fwd->data[dir];
+				if (nat_entry_fwd){
+					/*skbÒѾ­ÈÆ»ØÀ´ÁË£¬°ó¶¨ÐÂÀÏfast£¬¼Ç¼capct*/
+					spin_lock_bh(&fastnat_spinlock);
+					if(nat_entry_fwd != nat_entry){
+						if(!__nf_ct_tuple_src_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple) &&
+							__nf_ct_tuple_dst_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple)){
+							cap_entry_data->nat_flag = 2;
+							nat_entry_data->nat_flag = 2;
+							nat_entry->data[rdir].nat_flag = 1;
+							nat_entry_fwd->data[rdir].nat_flag = 1;
+						} else if(__nf_ct_tuple_src_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple) &&
+							!__nf_ct_tuple_dst_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple)){
+							cap_entry_data->nat_flag = 1;
+							nat_entry_data->nat_flag = 1;
+							nat_entry->data[rdir].nat_flag = 2;
+							nat_entry_fwd->data[rdir].nat_flag = 2;
+						}else{
+							printk("<------cap fastnat fail------>\n");
+							fast_ct_dump_tuple_ip(&cap_entry_data->tuplehash.tuple);
+							fast_ct_dump_tuple_ip(&nat_entry_data->tuplehash.tuple);
+						}
+						if(nat_entry_data->nat_flag){
+							nat_entry_fwd->cap_nfct = skb->capNfct;
+							nat_entry_fwd->fwd_entry = nat_entry;
+							atomic_set(&nat_entry_fwd->data[0].pkt, 0);
+							atomic_set(&nat_entry_fwd->data[0].len, 0);
+							atomic_set(&nat_entry_fwd->data[1].pkt, 0);
+							atomic_set(&nat_entry_fwd->data[1].len, 0);
+						}
+					}
+					if(nat_entry_fwd == nat_entry || nat_entry_data->nat_flag){
 						nat_entry->fwd_entry = nat_entry_fwd;
 						nat_entry->cap_nfct = skb->capNfct;
 						atomic_set(&nat_entry->data[0].pkt, 0);
 						atomic_set(&nat_entry->data[0].len, 0);
 						atomic_set(&nat_entry->data[1].pkt, 0);
 						atomic_set(&nat_entry->data[1].len, 0);
-						atomic_set(&nat_entry_fwd->data[0].pkt, 0);
-						atomic_set(&nat_entry_fwd->data[0].len, 0);
-						atomic_set(&nat_entry_fwd->data[1].pkt, 0);
-						atomic_set(&nat_entry_fwd->data[1].len, 0);
-						spin_unlock_bh(&fastnat_spinlock);
 						skb->capNfct = NULL;
 						if(zvnet_id >= 0 && nat_entry_data->zvnet_id == 0){
 							nat_entry_data->zvnet_id = zvnet_id+1;
-							if(nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
-								nat_entry->data[IP_CT_DIR_REPLY].zvnet_id = skb->zvnet_id;
-								nat_entry_fwd->data[IP_CT_DIR_ORIGINAL].zvnet_id = nat_entry->data[IP_CT_DIR_ORIGINAL].zvnet_id;
-								nat_entry_fwd->data[IP_CT_DIR_REPLY].zvnet_id = nat_entry->data[IP_CT_DIR_REPLY].zvnet_id;
-							}else{
-								nat_entry->data[IP_CT_DIR_ORIGINAL].zvnet_id = skb->zvnet_id;
-								nat_entry_fwd->data[IP_CT_DIR_ORIGINAL].zvnet_id = nat_entry->data[IP_CT_DIR_ORIGINAL].zvnet_id;
-								nat_entry_fwd->data[IP_CT_DIR_REPLY].zvnet_id = nat_entry->data[IP_CT_DIR_REPLY].zvnet_id;
+							nat_entry->data[rdir].zvnet_id = skb->zvnet_id;
+							if(nat_entry_fwd != nat_entry){
+								nat_entry_fwd->data[dir].zvnet_id = nat_entry->data[dir].zvnet_id;
+								nat_entry_fwd->data[rdir].zvnet_id = nat_entry->data[rdir].zvnet_id;
 							}
 						}
+						if(nat_entry->data[0].indev && nat_entry->data[1].outdev && 
+							(nat_entry->data[1].outdev->priv_flags & IFF_EBRIDGE) &&
+							zvnet_get_index_by_netdev(nat_entry->data[0].indev) < 0 && 
+							nat_entry->data[0].indev != nat_entry->data[1].outdev){
+							dev_put(nat_entry->data[1].outdev);
+							dev_hold(nat_entry->data[0].indev);
+							nat_entry->data[1].outdev = nat_entry->data[0].indev;
+						}
+						if(nat_entry->data[1].indev && nat_entry->data[0].outdev &&
+							(nat_entry->data[0].outdev->priv_flags & IFF_EBRIDGE) &&
+							zvnet_get_index_by_netdev(nat_entry->data[1].indev) < 0 && 
+							nat_entry->data[1].indev != nat_entry->data[0].outdev){
+							dev_put(nat_entry->data[0].outdev);
+							dev_hold(nat_entry->data[1].indev);
+							nat_entry->data[0].outdev = nat_entry->data[1].indev;
+						}
+						if(nat_entry_fwd->data[0].indev && nat_entry_fwd->data[1].outdev && 
+							(nat_entry_fwd->data[1].outdev->priv_flags & IFF_EBRIDGE) &&
+							zvnet_get_index_by_netdev(nat_entry_fwd->data[0].indev) < 0 && 
+							nat_entry_fwd->data[0].indev != nat_entry_fwd->data[1].outdev){
+							dev_put(nat_entry_fwd->data[1].outdev);
+							dev_hold(nat_entry_fwd->data[0].indev);
+							nat_entry_fwd->data[1].outdev = nat_entry_fwd->data[0].indev;
+						}
+						if(nat_entry_fwd->data[1].indev && nat_entry_fwd->data[0].outdev &&
+							(nat_entry_fwd->data[0].outdev->priv_flags & IFF_EBRIDGE) &&
+							zvnet_get_index_by_netdev(nat_entry_fwd->data[1].indev) < 0 && 
+							nat_entry_fwd->data[1].indev != nat_entry_fwd->data[0].outdev){
+							dev_put(nat_entry_fwd->data[0].outdev);
+							dev_hold(nat_entry_fwd->data[1].indev);
+							nat_entry_fwd->data[0].outdev = nat_entry_fwd->data[1].indev;
+						}
 					}
+					spin_unlock_bh(&fastnat_spinlock);
 				}
+			}else{
+/* Started by AICoder, pid:h335cmc8c7cc4681459c0af3d0a68e0bb604fd47 */
+if(nat_entry_data->indev != skb->indev){
+    rcu_read_unlock();
+    goto err_out;
+}
+/* Ended by AICoder, pid:h335cmc8c7cc4681459c0af3d0a68e0bb604fd47 */
 			}
-			if(zvnet_id < 0){
+			if(zvnet_id < 0 && skb->nfct_bak == NULL){
 				/*·¢¸øzvnetµÄÊý¾Ý£¬×ßµ½fast£¬¼Ç¼ctºÍfast°ó¶¨*/
-				nf_conntrack_put(skb->nfct);
-				skb->nfct = &nat_entry->ct->ct_general;
-				nf_conntrack_get(skb->nfct);
+				skb->nfct_bak = &nat_entry->ct->ct_general;
+				nf_conntrack_get(skb->nfct_bak);
 				nat_entry->ct->fast_entry = nat_entry;
 			}
 		}
 	}
+	if(skb->zvnet_id && (zvnet_get_index_by_netdev(dev) >= 0 || 
+		((dev->priv_flags & IFF_EBRIDGE) && (fast_br_parent(skb->indev) != dev)))){
+		nat_entry_data->outdev_update_flag = 0;
+		rcu_read_unlock();
+		goto err_out;
+	}
+	}
 #endif
     if (!(skb2 = fast_expand_headroom(skb, dev))){
         rcu_read_unlock();
@@ -540,6 +628,7 @@
 	{
 		iph = (struct iphdr *)skb2->data;
 		skb = skb2;
+		skb_expand4++;
 	}
 	
     fast_tcpdump(skb);
@@ -619,21 +708,14 @@
     skb->mark = nat_entry_data->mark;
 
     //»ùÓÚctÁ´½ÓµÄÁ÷Á¿Í³¼Æ --- ͳ¼ÆIP°ü²»ÊÇMAC°ü
-    if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
-        nat_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].packets++;
-        nat_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].bytes += skb->len;
-    } else if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_REPLY){
-        nat_entry->ct->packet_info[IP_CT_DIR_REPLY].packets++;
-        nat_entry->ct->packet_info[IP_CT_DIR_REPLY].bytes += skb->len;
-    } else {
-        printk("fastnat packet error\n");
-    }
+	nat_entry->ct->packet_info[dir].packets++;
+	nat_entry->ct->packet_info[dir].bytes += skb->len;
 
     //ÄÚºË×Ô´øµÄ»ùÓÚÁ´½ÓµÄÁ÷Á¿Í³¼Æ
     acct = nf_conn_acct_find(nat_entry->ct);
     if (acct) {
         enum ip_conntrack_info ctinfo;
-        if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL)
+        if (dir == IP_CT_DIR_ORIGINAL)
             ctinfo = IP_CT_ESTABLISHED;
         else 
             ctinfo = IP_CT_ESTABLISHED_REPLY;
@@ -641,7 +723,28 @@
         atomic64_inc(&acct[CTINFO2DIR(ctinfo)].packets);
         atomic64_add(skb->len, &acct[CTINFO2DIR(ctinfo)].bytes);
     }
-
+#if _USE_VEHICLE_DC
+	if(fastbr_level != 1){
+		skb->vlan_tci = nat_entry_data->vlan_tci;
+		if(nat_entry->cap_nfct){
+			atomic_inc(&nat_entry_data->pkt);
+			atomic_add(skb->len, &nat_entry_data->len);
+			if(atomic_read(&nat_entry_data->len) > 1000000 &&
+				nat_entry->data[0].zvnet_id && nat_entry->data[1].zvnet_id){
+				cap_conntrack_update_end(nat_entry->cap_nfct,
+					atomic_read(&nat_entry->data[0].pkt),atomic_read(&nat_entry->data[0].len),
+					atomic_read(&nat_entry->data[1].pkt),atomic_read(&nat_entry->data[1].len),
+					nat_entry->data[1].zvnet_id,nat_entry->data[0].zvnet_id);
+					spin_lock_bh(&fastnat_spinlock);
+					atomic_set(&nat_entry->data[0].pkt, 0);
+					atomic_set(&nat_entry->data[0].len, 0);
+					atomic_set(&nat_entry->data[1].pkt, 0);
+					atomic_set(&nat_entry->data[1].len, 0);
+					spin_unlock_bh(&fastnat_spinlock);
+			}
+		}
+	}
+#endif
     /* ¶¨Öƹ¦ÄÜ£¬ÎªÁ˽â¾öµ¥UDP¹à°üʱ£¬ÎÞ·¨ÖªÏþindev½øÐÐÁ÷Á¿Í³¼ÆÎÊÌâ¶¨ÖÆ */
     if ((nat_entry_data->indev == NULL) && skb->dev)
     {
@@ -664,34 +767,37 @@
 
     //Ö»Óе±ÓÐMACÍ·Ô¤¸³ÖµÊ±£¬²Å×¼¸³Öµ£¬·ñÔòΪIPÍ·
     skb_push(skb, ETH_HLEN);
-    if (nat_entry_data->hh_flag == 1)
+    if (nat_entry_data->hh_flag)
     {
         memcpy(skb->data, nat_entry_data->hh_data, ETH_HLEN);
     }
 #if _USE_VEHICLE_DC
 	else{
-		if (fastbr_level != 1 && zvnet_id >= 0 && nat_entry_data->hh_flag == 0){
-			spin_lock_bh(&fastnat_spinlock);
-			memcpy(nat_entry_data->hh_data, skb->data, ETH_HLEN);
-			nat_entry_data->hh_flag = 2;
-			spin_unlock_bh(&fastnat_spinlock);
+		if (unlikely(fastbr_level != 1)){
+			if(zvnet_id >= 0){
+				spin_lock_bh(&fastnat_spinlock);
+				memcpy(nat_entry_data->hh_data, skb->data, ETH_HLEN);
+				nat_entry_data->hh_flag = 1;
+				spin_unlock_bh(&fastnat_spinlock);
+			}
 		}
 	}
 #endif
 #if 0
-    if(!(dev->flags & IFF_POINTOPOINT))
+/* Started by AICoder, pid:qc090q92dfs12751403d090e4013a91e8be2dbd3 */
+if(dev->flags & IFF_POINTOPOINT)
+{
+    if(dev->header_ops && dev->header_ops->create)
     {
-        /*shouldn't set smac and dmac when out interface is p2p interface*/
-        if(dev->header_ops && dev->header_ops->create)
-        {
-            dev->header_ops->create(skb, dev, ETH_P_IP, nat_entry_data->dmac, NULL, skb->len);
-        }
-        else
-        {
-            XDBG_PRINT(XDBG_FASTNAT_PKT, XDBGLV_INFO, "no header ops\n");
-            return 0;
-        }
+        dev->header_ops->create(skb, dev, ETH_P_IP, nat_entry_data->dmac, NULL, skb->len);
     }
+    else
+    {
+        XDBG_PRINT(XDBG_FASTNAT_PKT, XDBGLV_INFO, "no header ops\n");
+        return 0;
+    }
+}
+/* Ended by AICoder, pid:qc090q92dfs12751403d090e4013a91e8be2dbd3 */
 #endif
 
     /*¸üÐÂÁ´½Ó³¬Ê±*/
@@ -763,7 +869,7 @@
             }
 			else if(skb->dev->netdev_ops && skb->dev->netdev_ops->ndo_start_xmit
 				&& skb->dev->netdev_ops->ndo_select_queue == NULL  
-				&& (skb->dev->type != ARPHRD_PPP))//wifiÉ豸´æÔÚ¶ÓÁÐÐèÒªÅÅÐòÈë¶Óskb_set_queue_mapping£¬ ÇÒ·Çppp0Íø¿Ú
+				&& (skb->dev->type != ARPHRD_PPP) && skb->vlan_tci == 0)//wifiÉ豸´æÔÚ¶ÓÁÐÐèÒªÅÅÐòÈë¶Óskb_set_queue_mapping£¬ ÇÒ·Çppp0Íø¿Ú
 			{
 				int rc = -ENOMEM;
 				rc = skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev);
@@ -858,7 +964,8 @@
     }
 
     //¹ã²¥¡¢×é²¥²»½¨Á´
-    if (ipv4_is_multicast(ip_hdr(skb)->daddr) || ipv4_is_lbcast(ip_hdr(skb)->daddr))
+    if (ipv4_is_multicast(ip_hdr(skb)->daddr) || ipv4_is_lbcast(ip_hdr(skb)->daddr)
+		|| ip_hdr(skb)->daddr == 0 || ip_hdr(skb)->saddr == 0)
     {
         return NF_ACCEPT;
     }
@@ -875,7 +982,7 @@
     }
 	if(dst->_neighbour == NULL && ((ip_hdr(skb)->daddr & 0xff000000) == 0xff000000 )){
         return NF_ACCEPT;
-	} 
+	}
     if (dst->_neighbour && memcmp(dst->_neighbour->ha, zeromac, ETH_ALEN) == 0)
     {
         if (strncmp(out->name, ppp_name, strlen(ppp_name)) != 0 && strncmp(out->name, "v4-", 3) != 0)
@@ -912,12 +1019,15 @@
     }
 
 #if 0 //¼¶ÁªÄ£Ê½ÊµÏÖ¿ìËÙת·¢£¬´Ëģʽ²»´ò¿ªNAT¹¦ÄÜ
+/* Started by AICoder, pid:va48cx25acxfd6d14753082e9000e307dde761f9 */
     /* only nat */
-    if (!fast_test_bit(IPS_SRC_NAT_BIT, ct->status) && 
-        !fast_test_bit(IPS_DST_NAT_BIT, ct->status))
+    if (fast_test_bit(IPS_SRC_NAT_BIT, ct->status) || 
+        fast_test_bit(IPS_DST_NAT_BIT, ct->status))
     {
-        return NF_ACCEPT;
+        return NF_DROP;
     }
+    return NF_ACCEPT;
+/* Ended by AICoder, pid:va48cx25acxfd6d14753082e9000e307dde761f9 */
 #endif
 
     /* only forward */
@@ -928,11 +1038,13 @@
 
     /*skip www because fastnat can't process url filter*/
 #if 0
-    if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.all == WWW_PORT)
-    {
-        XDBG_PRINT(XDBG_FASTNAT_ADD_ENTRY, XDBGLV_DEBUG, "skip www\n");
-        return NF_ACCEPT;
-    }
+/* Started by AICoder, pid:d57a7m3d00v9a101453b09f8f0edf50648f5ca46 */
+if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.all == WWW_PORT)
+{
+    XDBG_PRINT(XDBG_FASTNAT_ADD_ENTRY, XDBGLV_DEBUG, "skip www\n");
+}
+return NF_ACCEPT;
+/* Ended by AICoder, pid:d57a7m3d00v9a101453b09f8f0edf50648f5ca46 */
 #endif
 
     //¹ýÂ˲»ÐèÒª¾­¹ýfastnatµÄЭÒé°ü,¸ù¾Ý¶Ë¿ÚºÅ½øÐйýÂË
@@ -981,15 +1093,25 @@
     //entry_data->tos = ip_hdr(skb)->tos;
     entry_data->priority = skb->priority;
     entry_data->mark = skb->mark;
+	if(entry_data->outdev == NULL){
     entry_data->outdev = out;
-
+	}
+#if 0// _USE_VEHICLE_DC
+	else if (entry_data->outdev != out){
+		if(IPPROTO_UDP != protocol || entry_data->outdev_update_flag == 0){
+			dev_put(entry_data->outdev);
+			dev_hold(out);
+			entry_data->outdev = out;
+			entry_data->outdev_update_flag = 1;
+		}
+	}
+#endif
     /*¼Ç¼MACµØÖ·µ½entry_data->hh_data*/
-    if (!record_MAC_header(working_hash, ct, nat_entry, entry_data, dst->_neighbour, out, htons(ETH_P_IP)))
+    if (!record_MAC_header(working_hash, ct, nat_entry, entry_data, dst->_neighbour, entry_data->outdev, htons(ETH_P_IP)))
     {
         spin_unlock_bh(&fastnat_spinlock);
         return NF_ACCEPT;
     }
-
     /*»ñÈ¡natת»»ÐèÒªµÄIPºÍportÐÅÏ¢*/
     if (fast_test_bit(IPS_SRC_NAT_BIT, ct->status))
     {
@@ -1032,15 +1154,24 @@
     
     //Ìí¼Óhash½Úµã
     fast_add_entry(working_hash, entry_data);
-    
+	if(fastbr_level != 1){
+		if(nat_entry->data[dir].indev == NULL)
+			nat_entry->data[dir].indev = skb->indev;
+	} else {
     if (nat_entry->flags == FAST_ALL_DIR)
     {
         nat_entry->data[0].indev = nat_entry->data[1].outdev;
         nat_entry->data[1].indev = nat_entry->data[0].outdev;
     }
-
+	}
     ct->fast_ct.isFast = FAST_CT_WND4;
-    
+#if _USE_VEHICLE_DC
+	if(skb->nfct_bak == NULL){
+		skb->nfct_bak = &ct->ct_general;
+		nf_conntrack_get(skb->nfct_bak);
+		ct->fast_entry = nat_entry;
+	}
+#endif
     spin_unlock_bh(&fastnat_spinlock);
 
 	//ÇåÀí´ýɾ³ýµÄentryÁÐ±í£¬ºóÆÚÓÅ»¯¿ÉÒÔ¿¼ÂÇÉêÇëµÄʱºòÏÈ´Ó´ýɾ³ýÖÐÈ¡£¬¼õÉÙÖØ¸´ÉêÇëÊÍ·Å