[Feature][ZXW-452]merge P54U02 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: I17e6795ab66e2b9d1cbbfec4b7c0028d666e177d
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/dma_ch_cfg.h b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/dma_ch_cfg.h
old mode 100644
new mode 100755
index 60ac634..8d7a2d5
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/dma_ch_cfg.h
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/dma_ch_cfg.h
@@ -77,7 +77,7 @@
 	

 	DMA_CHANNEL_CONFIG(DMA_CH_EMBMS,		false,	false),

 	#if 1	/* only ps core used */	

-	DMA_CHANNEL_CONFIG(DMA_CH_USIM1,		false,	false),

+	DMA_CHANNEL_CONFIG(DMA_CH_USIM1,		false,	true),

 	#endif	

 	DMA_CHANNEL_CONFIG(DMA_CH_M2M_TX,		false,	true),

 	DMA_CHANNEL_CONFIG(DMA_CH_M2M_RX,		false,	true),

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
old mode 100644
new mode 100755
index 751bb7d..0702a4e
--- 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
@@ -378,7 +378,7 @@
 	.quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION  \
 		| DW_MCI_QUIRK_UNALIGN_DMA_SZ | DW_MCI_QUIRK_UNALIGN_DMA_START,
 	.caps	= (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |MMC_CAP_UHS_SDR50 |MMC_CAP_NONREMOVABLE),
-	.bus_hz = 26*1000*1000,
+	.bus_hz = 50*1000*1000,
 	//.caps	= (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_NONREMOVABLE),
 	.pm_caps = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY,
 	//.init = sdmmc_init,
@@ -948,7 +948,7 @@
 static struct gpio_keys_button zx29_keypad_int[] = {
 	#if 1
 	{
-		.active_low	= 1,				/*是否低电平有效。1: 按下为低电平  0: 按下为高电平*/
+		.active_low	= 1,				/*ÊÇ·ñµÍµçƽÓÐЧ¡£1: °´ÏÂΪµÍµçƽ  0: °´ÏÂΪ¸ßµçƽ*/
 		.desc       = "kpd_power",
 		.code       = KEY_POWER         /* power: 116 */,
 		.use_pmu_pwron = 1,             /*true: use pmu pwron interrupt fase: use zx297520v2 ext int*/
@@ -1487,15 +1487,11 @@
 	/*
 	  *i2c devices on bus 1
 	  */
-//xf.li@20230626 add for T106BUG-26 start
-#if 0
 	devices_num = ARRAY_SIZE(zx29_i2c1_devices);
 	if (devices_num){
 		ret = i2c_register_board_info(1,zx29_i2c1_devices, devices_num);
 		if(ret)
 			BUG();
 	}
-#endif
-//xf.li@20230626 add for T106BUG-26 end
 }
 #endif
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 73f76ac..c6a0602 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=(0x10cf+4777-0x2378);if(!user_mode(regs)){preempt_disable();if(
-kprobe_running()&&kprobe_fault_handler(regs,fsr))ret=(0x2526+92-0x2581);
+ret=(0x12ad+3367-0x1fd4);if(!user_mode(regs)){preempt_disable();if(
+kprobe_running()&&kprobe_fault_handler(regs,fsr))ret=(0x12cf+1682-0x1960);
 preempt_enable();}return ret;}
 #else
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){return
-(0x68+5818-0x1722);}
+(0x1bf2+2048-0x23f2);}
 #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!=(0xa93+6427-0x23ad))printk(
+pgd,addr);if(PTRS_PER_PUD!=(0x824+35-0x846))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!=(0x102d+1714-0x16de))printk(
+}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x364+38-0x389))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,21 +47,21 @@
 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((0xadb+4004-0x1a7f));printk("\n");}
+pte_unmap(pte);}while((0x272+8475-0x238d));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(
-(0x693+5051-0x1a4d));printk(KERN_ALERT
+(0x1545+4125-0x2561));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((0x19a0+1715-0x2053));
-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;
+addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0xc84+590-0xed2));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;
 #ifdef CONFIG_DEBUG_USER
 if(((user_debug&UDBG_SEGV)&&(sig==SIGSEGV))||((user_debug&UDBG_BUS)&&(sig==
 SIGBUS))){printk(KERN_DEBUG
@@ -69,12 +69,12 @@
 ,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=
-(0x1884+305-0x19a7);si.si_signo=sig;si.si_errno=(0x184c+3084-0x2458);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(
-tsk,addr,fsr,SIGSEGV,SEGV_MAPERR,regs);else __do_kernel_fault(mm,addr,fsr,regs);
-}
+(0x1100+1036-0x14fe);si.si_signo=sig;si.si_errno=(0x1804+3286-0x24da);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(tsk,addr,fsr,SIGSEGV,SEGV_MAPERR,regs);else __do_kernel_fault(mm
+,addr,fsr,regs);}
 #ifdef CONFIG_MMU
 #define VM_FAULT_BADMAP		65536
 #define VM_FAULT_BADACCESS	131072
@@ -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:(0x27b+5387-0x1786));if(
-notify_page_fault(regs,fsr))return(0x412+4514-0x15b4);tsk=current;mm=tsk->mm;if(
+FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0x6c0+4256-0x1760));if(
+notify_page_fault(regs,fsr))return(0xdeb+2245-0x16b0);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,23 +101,23 @@
 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(0xd4d+1889-0x14ae);perf_sw_event(
-PERF_COUNT_SW_PAGE_FAULTS,(0x173b+2031-0x1f29),regs,addr);if(!(fault&
+fatal_signal_pending(current))return(0xba1+1906-0x1313);perf_sw_event(
+PERF_COUNT_SW_PAGE_FAULTS,(0x187+8029-0x20e3),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,(0x289+5023-0x1627),regs,
+maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x741+2004-0xf14),regs,
 addr);}else{tsk->min_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
-(0xfec+801-0x130c),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
+(0xd8b+267-0xe95),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(0x1547+4065-0x2528);
-if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0xb6a+5412-0x208e);}if(!
+VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x130f+2815-0x1e0e);
+if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0x317+4165-0x135c);}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
-(0x1548+205-0x1615);no_context:__do_kernel_fault(mm,addr,fsr,regs);return
-(0x44c+6307-0x1cef);}
+(0xe18+1192-0x12c0);no_context:__do_kernel_fault(mm,addr,fsr,regs);return
+(0x1393+593-0x15e4);}
 #else					
 static int do_page_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
-){return(0xefa+4246-0x1f90);}
+){return(0x1f8+6958-0x1d26);}
 #endif					
 #ifdef CONFIG_MMU
 static int __kprobes do_translation_fault(unsigned long addr,unsigned int fsr,
@@ -130,21 +130,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=(0x1d5+278-0x2eb);
+index=(0xce3+5951-0x2422);
 #else
-index=(addr>>SECTION_SHIFT)&(0x14fa+1753-0x1bd2);
+index=(addr>>SECTION_SHIFT)&(0xe8a+4619-0x2094);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0xc0c+6216-0x2454);bad_area:do_bad_area(addr,fsr,regs);return
-(0x193a+2083-0x215d);}
+(0x115+9321-0x257e);bad_area:do_bad_area(addr,fsr,regs);return
+(0x494+8636-0x2650);}
 #else					
 static int do_translation_fault(unsigned long addr,unsigned int fsr,struct 
-pt_regs*regs){return(0x751+3133-0x138e);}
+pt_regs*regs){return(0xe3b+3297-0x1b1c);}
 #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(0x36d+6227-0x1bc0);}static int do_bad(unsigned long addr,unsigned int fsr
-,struct pt_regs*regs){return(0x90a+6430-0x2227);}struct fsr_info{int(*fn)(
+return(0x8e3+6172-0x20ff);}static int do_bad(unsigned long addr,unsigned int fsr
+,struct pt_regs*regs){return(0x173a+1692-0x1dd5);}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
@@ -153,21 +153,21 @@
 #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<(0x10e4+4307-0x21b7)||nr>=
+pt_regs*),int sig,int code,const char*name){if(nr<(0xc0a+725-0xedf)||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(
-(0xaba+2616-0x14f2));struct addr_info{struct list_head node;unsigned long vaddr;
+(0x439+4334-0x1527));struct addr_info{struct list_head node;unsigned long vaddr;
 unsigned long kaddr;unsigned long page_index;};enum modem_access_technology{GSM=
-(0x858+1778-0xf4a),UTRAN=(0x7bb+6127-0x1fa9),LTE=(0x758+1563-0xd71),COM=
-(0x2022+1256-0x2507),NR_MODEM_ACCESS=(0x468+7954-0x2376)};struct list_head 
+(0x13e8+346-0x1542),UTRAN=(0xdb5+5486-0x2322),LTE=(0x370+7689-0x2177),COM=
+(0x12c8+4192-0x2325),NR_MODEM_ACCESS=(0x3ab+1812-0xabb)};struct list_head 
 modem_page_list[NR_MODEM_ACCESS]={LIST_HEAD_INIT(modem_page_list[
-(0x7b1+7792-0x2621)]),LIST_HEAD_INIT(modem_page_list[(0xf8+8818-0x2369)]),
-LIST_HEAD_INIT(modem_page_list[(0x1365+1369-0x18bc)]),LIST_HEAD_INIT(
-modem_page_list[(0x730+7892-0x2601)]),};unsigned int page_used[
-(0x7c9+3414-0x14f7)];struct completion page_completion[(0x58a+6492-0x1ebe)*
-(0xaf1+881-0xe42)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
+(0xc2+7787-0x1f2d)]),LIST_HEAD_INIT(modem_page_list[(0x13e2+4770-0x2683)]),
+LIST_HEAD_INIT(modem_page_list[(0x564+4401-0x1693)]),LIST_HEAD_INIT(
+modem_page_list[(0x199+2282-0xa80)]),};unsigned int page_used[
+(0x1390+4072-0x2350)];struct completion page_completion[(0x88d+6027-0x1ff0)*
+(0x15b2+252-0x168e)];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(
@@ -181,29 +181,29 @@
 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=(0xf1a+3533-0x1ce7);unsigned 
+shrink_modem_mem(unsigned int access_type){int i=(0x696+4084-0x168a);unsigned 
 long vaddr;struct addr_info*addr,*tmp_addr;struct list_head tmp_page_list;for(i=
-(0x56c+6679-0x1f83);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){
+(0xf+934-0x3b5);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=
-(0x580+4899-0x18a3);page_used[addr->page_index/BITS_PER_LONG]&=~(
-(0x9f5+898-0xd76)<<(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(
+(0x173f+3119-0x236e);page_used[addr->page_index/BITS_PER_LONG]&=~(
+(0x1d3+6472-0x1b1a)<<(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"
 ,addr);}flush_cache_vunmap(vaddr,vaddr+PAGE_SIZE);unmap_page_range(vaddr,vaddr+
 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,
-(0x17e1+476-0x19bc));local_irq_restore(flags);
+(0xadf+892-0xe5a));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(0xd2c+3230-0x19ca);}static int sync_pgd(unsigned long addr,
+pfn);}}}return(0xa62+3255-0x1719);}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))
@@ -211,13 +211,13 @@
 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=(0xd1b+530-0xf2d);
+index=(0x1dd0+1484-0x239c);
 #else
-index=(addr>>SECTION_SHIFT)&(0xf92+585-0x11da);
+index=(addr>>SECTION_SHIFT)&(0x3ba+3661-0x1206);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0x126+7918-0x2014);bad_area:do_bad_area(addr,fsr,regs);return
-(0x82b+6613-0x2200);}unsigned long*read_code_file(unsigned long page_index){
+(0x8b1+6087-0x2078);bad_area:do_bad_area(addr,fsr,regs);return
+(0xd2d+3946-0x1c97);}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"
@@ -226,23 +226,23 @@
 "\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<(0x2090+1030-0x2496)){panic(
+char*)code_buf,PAGE_SIZE,&pos);if(result<(0xf9+502-0x2ef)){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,
-(0x173c+2863-0x226a));local_irq_restore(flags);
+(0x999+3702-0x180e));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)!=(0x1e14+866-0x2176)
+unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0x5c6+5202-0x1a18)
 ){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)&
-(0x901+4096-0x1900)){wait_for_completion(&page_completion[page_index]);sync_pgd(
+(0x871+1586-0xea2)){wait_for_completion(&page_completion[page_index]);sync_pgd(
 vaddr,fsr,regs);return;}else page_used[page_index/BITS_PER_LONG]|=(
-(0xd62+5269-0x21f6)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
+(0x4dc+1329-0xa0c)<<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.
@@ -260,46 +260,46 @@
 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!=(0xb14+714-0xdde)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0xb54+2091-0x137f)&&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=(0xafc+1724-0x11b8);
+,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0x12fb+4902-0x2621);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,fsr,(0x1352+1151-0x17d1));}void __init hook_ifault_code(int nr,int(*fn)(
+info,fsr,(0x45b+1782-0xb51));}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<(0x48f+3595-0x129a)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
+(nr<(0x188d+151-0x1924)||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!=(0x107b+4992-0x23fb)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x13b1+565-0x15e6)&&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=(0xde3+1588-0x1417);
+,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0xd47+4901-0x206c);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,ifsr,(0x359+1054-0x777));}
+info,ifsr,(0xfb2+3290-0x1c8c));}
 #ifndef CONFIG_ARM_LPAE
 static int __init exceptions_init(void){if(cpu_architecture()>=CPU_ARCH_ARMv6){
-hook_fault_code((0x20cf+293-0x21f0),do_translation_fault,SIGSEGV,SEGV_MAPERR,
+hook_fault_code((0x654+6496-0x1fb0),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((0x1680+311-0x17b4),
+);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0x643+2473-0xfe9),
 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((0xb40+1730-0x11fc),do_bad,SIGSEGV,SEGV_MAPERR,
+);hook_fault_code((0x10f9+3556-0x1ed7),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=(0xadb+1615-0x112a);for(index=(0x1d75+783-0x2084);index<
-(0xfc1+2383-0x18e8)*(0x1320+4998-0x2686);index++)init_completion(&
-page_completion[index]);
+int index=(0xb70+6003-0x22e3);for(index=(0x67c+2578-0x108e);index<
+(0x154d+97-0x1586)*(0xf56+2316-0x1842);index++)init_completion(&page_completion[
+index]);
 #endif
-return(0x1c57+1935-0x23e6);}arch_initcall(exceptions_init);
+return(0x332+635-0x5ad);}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 f8b5c94..5a45243 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
@@ -76,36 +76,37 @@
 mmp_AmrEncClose(VOID*pCodecContext);extern UINT8 zDrvEdcp_IsBusy(int EdcpNum);
 extern SINT32 zDrvVp_AudioDataWrite(const VOID*pBuf,UINT32 uiLen);extern SINT32 
 zDrvVp_AudioDataOpen(UINT32 audioType,UINT32 sampleRate);extern SINT32 
-zDrvVp_AudioDataClose(void);extern SINT32 zDrvVp_GetVpLoop_Wrap(VOID);typedef 
-struct cpko_section{unsigned int cpko_text_start;unsigned int cpko_rodata_start;
+zDrvVp_AudioDataClose(void);extern SINT32 zDrvVp_GetVpLoop_Wrap(VOID);extern 
+VOID zDrvVp_Status(UINT32*sample_rate,UINT32*voice_status);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(0x171+4684-0x13bd);}extern unsigned int SysEntry(void);static int 
+return(0x316+6712-0x1d4e);}extern unsigned int SysEntry(void);static int 
 ko_Main_Thread(void*data){struct sched_param param={.sched_priority=
-MAX_USER_RT_PRIO/(0x73+9710-0x265f)-(0x67a+3427-0x13da)};int ret=
-(0xd57+70-0xd9d);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry();if
-(ret!=(0x13f8+3144-0x2040))panic("Main_Thread\n");param.sched_priority=
-MAX_USER_RT_PRIO-(0x267+6787-0x1cbc);sched_setscheduler(kthreadd_task,SCHED_FIFO
-,&param);return(0x14f0+1755-0x1bcb);}int zte_modem_ko_start(void){kthread_run(
+MAX_USER_RT_PRIO/(0xe6b+2120-0x16b1)-(0x1975+1578-0x1f9c)};int ret=
+(0x3a0+6131-0x1b93);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry()
+;if(ret!=(0x1419+3950-0x2387))panic("Main_Thread\n");param.sched_priority=
+MAX_USER_RT_PRIO-(0x10ed+82-0x1111);sched_setscheduler(kthreadd_task,SCHED_FIFO,
+&param);return(0x227+8075-0x21b2);}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(0x1fa0+1069-0x23cd);}static void cpko_sectioninfo_set(void){int ret;
-struct file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x1e57+1652-0x24cb);struct 
+return(0x890+7748-0x26d4);}static void cpko_sectioninfo_set(void){int ret;struct
+ file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x1570+4436-0x26c4);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"
-,(0x12f9+2130-0x1b4b),(0x5f9+6793-0x2082));if(IS_ERR(fp)||fp==NULL)panic(
+,(0x294+1512-0x87c),(0xe06+3271-0x1acd));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<=(0x5f5+5890-0x1cf7))panic(
+cpko_section_layout),&cpko_pos);if(ret<=(0x3ca+7257-0x2023))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",
-(0xa83+3340-0x178f),(0x5c5+7296-0x2245));if(IS_ERR(fp)||fp==NULL)panic(
+(0x9ca+4617-0x1bd3),(0x659+7219-0x228c));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=(0xeec+1627-0x1547);
+ra_pages=(0xac6+6080-0x2286);
 #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)
@@ -125,7 +126,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={(0xb25+3026-0x16f7)};callback.
+cpko_start(void){struct cpps_callbacks callback={(0x5b7+4236-0x1643)};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.
@@ -189,6 +190,7 @@
 mmp_AmrDecClose;callback.mmp_AmrEncClose=mmp_AmrEncClose;callback.
 zDrvVp_AudioDataOpen=zDrvVp_AudioDataOpen;callback.zDrvVp_AudioDataWrite=
 zDrvVp_AudioDataWrite;callback.zDrvVp_AudioDataClose=zDrvVp_AudioDataClose;
+callback.zDrvVp_Status=zDrvVp_Status;
 #endif	
 callback.psm_ModemDevSleep=psm_ModemDevSleep;callback.psm_ModemSleepCheck=
 psm_ModemSleepCheck;callback.psm_ModemSleepTimeGet=psm_ModemSleepTimeGet;
@@ -196,5 +198,5 @@
 psm_GetModemSleepFlagStatus=psm_GetModemSleepFlagStatus;
 #endif
 cpps_callbacks_register(&callback);cpko_sectioninfo_set();zte_modem_ko_start();
-return(0x6aa+3593-0x14b3);}static int cpko_stop(void){return(0xaf3+1843-0x1226);
+return(0x1997+168-0x1a3f);}static int cpko_stop(void){return(0x636+5784-0x1cce);
 }module_init(cpko_start);module_exit(cpko_stop);
diff --git a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/nand_base.c b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/nand_base.c
index edb5c5a..eda11e2 100755
--- a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/nand_base.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/nand_base.c
@@ -1731,7 +1731,6 @@
 	int ret;
 	
 	nand_get_device(chip, mtd, FL_READING);
-	mutex_lock(&otpMutex);
 	
 	/*ops.len = len;
 	ops.datbuf = buf;
@@ -1746,7 +1745,6 @@
 	//*retlen = ops.retlen;
 	*retlen = chip->ops.retlen;
 
-	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);
 	return ret;
 }
@@ -2017,7 +2015,6 @@
 		return -EINVAL;
 	}
 	nand_get_device(chip, mtd, FL_READING);
-	mutex_lock(&otpMutex);
 
 	switch (ops->mode) {
 	case MTD_OPS_PLACE_OOB:
@@ -2034,7 +2031,6 @@
 	else
 		ret = nand_do_read_ops(mtd, from, ops);
 out:
-	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);
 	return ret;
 }
@@ -2481,14 +2477,12 @@
 	int ret;
 		
 	nand_get_device(chip, mtd, FL_WRITING);
-	mutex_lock(&otpMutex);
 	ops.len = len;
 	ops.datbuf = (uint8_t *)buf;
 	ops.oobbuf = NULL;
 	ops.mode = 0;
 	ret = nand_do_write_ops(mtd, to, &ops);
 	*retlen = ops.retlen;
-	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);
 		
 	return ret;
@@ -2606,7 +2600,6 @@
 	}
 
 	nand_get_device(chip, mtd, FL_WRITING);
-	mutex_lock(&otpMutex);
 
 	switch (ops->mode) {
 	case MTD_OPS_PLACE_OOB:
@@ -2623,7 +2616,6 @@
 	else
 		ret = nand_do_write_ops(mtd, to, ops);
 out:
-	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);	
 	return ret;
 }
@@ -2707,7 +2699,6 @@
 
 	/* Grab the lock and see if the device is available */
 	nand_get_device(chip, mtd, FL_ERASING);
-	mutex_lock(&otpMutex);
 
 	/* Shift to get first page */
 	page = (int)(instr->addr >> chip->page_shift);
@@ -2817,7 +2808,6 @@
 	ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
 
 	/* Deselect and wake up anyone waiting on the device */
-	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);
 
 	/* Do call back function */
diff --git a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/spi_nand.c b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/spi_nand.c
index 0cc1f5b..0376155 100755
--- a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/spi_nand.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/spi_nand.c
@@ -47,6 +47,8 @@
 
 static struct wake_lock nand_wake_lock;
 
+extern struct mutex otpMutex;
+
 #if SPI_NAND_DEBUG
 #define spi_nand_debug(fmt,args...)    printk (fmt ,##args)
 #else
@@ -775,7 +777,7 @@
     .offs = 4,
     .len = 4,
     .veroffs = 20,
-    .maxblocks = 16,
+    .maxblocks = 12,
     .pattern = bbt_pattern,
 };
 
@@ -787,7 +789,7 @@
     .offs = 4,
     .len = 4,
     .veroffs = 20,
-    .maxblocks = 16,
+    .maxblocks = 12,
     .pattern = mirror_pattern,
 };
 
@@ -846,6 +848,7 @@
     wake_lock(&nand_wake_lock);
 	zx_cpuidle_set_busy(IDLE_FLAG_FLASH);
 	soft_spin_lock(NAND_SFLOCK);
+	mutex_lock(&otpMutex);
 
 	ctrl->lock();
 }
@@ -855,7 +858,8 @@
 	struct spi_nand_ctrl_ops *ctrl = spi_nand->ctrl;
 
 	ctrl->unlock();	
-	
+
+	mutex_unlock(&otpMutex);
     soft_spin_unlock(NAND_SFLOCK);
 	zx_cpuidle_set_free(IDLE_FLAG_FLASH);
 	wake_unlock(&nand_wake_lock);//NEED CHECK
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.c
index d966cb0..a9c7fb5 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.c
@@ -20,6 +20,7 @@
 #include "sdio_host.h"
 #include "rwnx_defs.h"
 #include "rwnx_platform.h"
+#include "rwnx_msg_tx.h"
 #ifdef CONFIG_INGENIC_T20
 #include "mach/jzmmc.h"
 #endif /* CONFIG_INGENIC_T20 */
@@ -149,6 +150,7 @@
             count++;
             if (count < 30)
                 udelay(200);
+                //usleep_range(150, 200);
             else if(count < 40)
                 msleep(2);
             else
@@ -332,6 +334,11 @@
     struct aic_sdio_dev *sdiodev = NULL;
 
     sdio_dbg("%s\n", __func__);
+	if (timer_pending(&g_rwnx_plat->sdiodev->tp_timer)) {
+		printk("%s del_timer\n", __func__);
+		del_timer_sync(&g_rwnx_plat->sdiodev->tp_timer);
+	}
+	cancel_work_sync(&g_rwnx_plat->sdiodev->tp_work);
     host = func->card->host;
     host->caps &= ~MMC_CAP_NONREMOVABLE;
     bus_if = dev_get_drvdata(&func->dev);
@@ -343,6 +350,8 @@
     if (!sdiodev) {
         return;
     }
+
+	
     sdiodev->bus_if->state = BUS_DOWN_ST;
     aicwf_sdio_release(sdiodev);
     aicwf_sdio_func_deinit(sdiodev);
@@ -1826,6 +1835,75 @@
     sdio_release_host(sdiodev->func);
 }
 
+extern void set_txpwr_ctrl(struct aic_sdio_dev *sdiodev, s8_l value);
+#if 0
+static void set_txpwr_ctrl(struct aic_sdio_dev *sdiodev, s8_l value)
+{
+	nvram_info.txpwr_loss.loss_enable = 1;
+	if (value > TEMP_THD_1 && value <= TEMP_THD_2) {
+		if (sdiodev->range == 0) {
+			nvram_info.txpwr_loss.loss_value += -TEMP_STEP_1;
+			sdiodev.range = 1;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		} else if (sdiodev->range == 1) {
+			continue;
+		} else if (sdiodev->range == 2) {
+			nvram_info.txpwr_loss.loss_value += TEMP_STEP_1;
+			sdiodev.range = 1;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		}
+	} else if (value > TEMP_THD_2) {
+		if (sdiodev->range == 0) {
+			nvram_info.txpwr_loss.loss_value += -TEMP_STEP_2;
+			sdiodev.range = 2;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		} else if (sdiodev->range == 1) {
+			nvram_info.txpwr_loss.loss_value += -TEMP_STEP_1;
+			sdiodev.range = 2;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		} else {
+			continue;
+		}
+	} else {
+		if (sdiodev->range == 0) {
+			continue;
+		} else if (sdiodev->range == 1) {
+			nvram_info.txpwr_loss.loss_value += TEMP_STEP_1;
+			sdiodev.range = 0;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		} else if (sdiodev->range == 2) {
+			nvram_info.txpwr_loss.loss_value += TEMP_STEP_2;
+			sdiodev.range = 0;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		}
+	}
+}
+#endif
+void aicwf_temp_worker(struct work_struct *work)
+{
+	struct rwnx_hw *rwnx_hw;
+	struct mm_set_vendor_hwconfig_cfm cfm;
+	struct aic_sdio_dev *sdiodev = container_of(work, struct aic_sdio_dev, tp_work);
+	rwnx_hw = sdiodev->rwnx_hw;
+	rwnx_send_get_temp_req(rwnx_hw, &cfm);
+	set_txpwr_ctrl(sdiodev, cfm.chip_temp_cfm.degree);
+	mod_timer(&sdiodev->tp_timer, jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL));
+}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
+static void aicwf_temp_timer(ulong data)
+#else
+static void aicwf_temp_timer(struct timer_list *t)
+#endif
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
+	struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *) data;
+#else
+	struct aic_sdio_dev *sdiodev = from_timer(sdiodev, t, tp_timer);
+#endif
+	if (!work_pending(&sdiodev->tp_work))
+		schedule_work(&sdiodev->tp_work);
+	return;
+}
 void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev)
 {
     int ret;
@@ -1869,6 +1947,17 @@
     init_waitqueue_head(&tx_priv->cmd_txdone_wait);
     atomic_set(&tx_priv->tx_pktcnt, 0);
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
+		init_timer(&sdiodev->tp_timer);
+		sdiodev->tp_timer.data = (ulong) sdiodev;
+		sdiodev->tp_timer.function = aicwf_temp_timer;
+		//sdiodev->tp_timer.expires  = jiffies + msecs_to_jiffies(TEMP_GET_INTERVAL);
+#else
+		timer_setup(&sdiodev->tp_timer, aicwf_temp_timer, 0);
+#endif
+		INIT_WORK(&sdiodev->tp_work, aicwf_temp_worker);
+		mod_timer(&sdiodev->tp_timer, jiffies + msecs_to_jiffies(10 * 1000));
+		sdiodev->range = 0;
 #if defined(CONFIG_SDIO_PWRCTRL)
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
     init_timer(&sdiodev->timer);
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.h b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.h
index 1fac4d6..9a10cd4 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.h
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.h
@@ -39,6 +39,11 @@
 #define SDIO_SLEEP_ST                    0
 #define SDIO_ACTIVE_ST                   1
 
+#define TEMP_GET_INTERVAL                (60 * 1000)   //time interval
+#define TEMP_THD_1                       80            //temperature 1 (¡æ)
+#define TEMP_THD_2                       100           //temperature 2 (¡æ)
+#define TEMP_STEP_1                      4             //step (dB)
+#define TEMP_STEP_2                      8             //step (dB)
 #define DATA_FLOW_CTRL_THRESH 2
 #ifdef CONFIG_TX_NETIF_FLOWCTRL
 #define AICWF_SDIO_TX_LOW_WATER          100
@@ -79,6 +84,9 @@
     u8 flowctrl;
     spinlock_t tx_flow_lock;
 #endif
+	struct timer_list tp_timer;
+	struct work_struct tp_work;
+	u8 range;
     #if defined(CONFIG_SDIO_PWRCTRL)
     //for sdio pwr ctrl
     struct timer_list timer;
@@ -92,6 +100,7 @@
 int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val);
 void aicwf_sdio_hal_irqhandler(struct sdio_func *func);
 void aicwf_sdio_hal_irqhandler_func2(struct sdio_func *func);
+void aicwf_temp_worker(struct work_struct *work);
 
 #if defined(CONFIG_SDIO_PWRCTRL)
 void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration);
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/lmac_msg.h b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/lmac_msg.h
old mode 100644
new mode 100755
index c760389..5ddbf70
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/lmac_msg.h
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/lmac_msg.h
@@ -382,8 +382,8 @@
 
     MM_APM_STALOSS_IND,
 
-    MM_SET_TXOP_REQ,
-    MM_SET_TXOP_CFM,
+    MM_SET_VENDOR_HWCONFIG_REQ,
+    MM_SET_VENDOR_HWCONFIG_CFM,
 
 	MM_GET_FW_VERSION_REQ,
     MM_GET_FW_VERSION_CFM,
@@ -1309,7 +1309,7 @@
 typedef struct
 {
     u8_l loss_enable;
-    u8_l loss_value;
+    s8_l loss_value;
 } txpwr_loss_conf_t;
 typedef struct
 {
@@ -1857,6 +1857,21 @@
     u8_l  cfe_en;
 };
 
+struct mm_get_chip_temp_req
+{
+    u32_l hwconfig_id;
+};
+struct mm_get_chip_temp_cfm
+{
+    s8_l degree;
+};
+struct mm_set_vendor_hwconfig_cfm
+{
+    u32_l hwconfig_id;
+    union {
+        struct mm_get_chip_temp_cfm chip_temp_cfm;
+    };
+};
 struct mm_get_fw_version_cfm
 {
     u8_l fw_version_len;
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_cmds.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_cmds.c
index eec2fb0..2050181 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_cmds.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_cmds.c
@@ -25,6 +25,7 @@
 #else
 #include "aicwf_usb.h"
 #endif
+#include  "pub_debug_info.h"
 /**
  *
  */
@@ -122,6 +123,7 @@
 {
     int ret = 0;
     printk(KERN_ERR "wlan error reset flow.\n");
+	sc_debug_info_record(MODULE_ID_AP_WIFI,"rwnx start_system_reset \n");
     char *event_string = "DHDISDOWN=1";
     char *envp[] = { event_string, NULL };
     printk(KERN_ERR "send event.\n");	
@@ -213,8 +215,9 @@
 		//printk("defer push: tkn=%d\r\n", cmd->tkn);
 	}
 
-    spin_unlock_bh(&cmd_mgr->lock);
+    //spin_unlock_bh(&cmd_mgr->lock);
     if (!defer_push) {
+	spin_unlock_bh(&cmd_mgr->lock);
         printk("queue:id=%x, param_len=%u\n",cmd->a2e_msg->id, cmd->a2e_msg->param_len);
         #ifdef AICWF_SDIO_SUPPORT
         aicwf_set_cmd_tx((void *)(sdiodev), cmd->a2e_msg, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len);
@@ -225,12 +228,16 @@
 
         kfree(cmd->a2e_msg);
     } else {
+	if(cmd_mgr->queue_sz <= 1){
+		spin_unlock_bh(&cmd_mgr->lock);
         #ifdef CMD_WORKQUEUE
 		WAKE_CMD_WORK(cmd_mgr);
         #else
         //tasklet_schedule(&cmd_mgr->cmd_tasklet);
         complete(&cmd_mgr->cmdproc_trgg);
         #endif
+	} else
+		spin_unlock_bh(&cmd_mgr->lock);
 		return 0;
 	}
 
@@ -247,6 +254,7 @@
         unsigned long tout = msecs_to_jiffies(RWNX_80211_CMD_TIMEOUT_MS * cmd_mgr->queue_sz);
         if (!wait_for_completion_timeout(&cmd->complete, tout)) {
             printk(KERN_CRIT"cmd timed-out\n");
+			sc_debug_info_record(MODULE_ID_AP_WIFI,"rwnx cmd timed-out \n");
             #ifdef AICWF_SDIO_SUPPORT
             ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_WAKEUP_REG, 2);
             if (ret < 0) {
@@ -549,7 +557,7 @@
     bool found = false;
 
    // RWNX_DBG(RWNX_FN_ENTRY_STR);
-   if(!(msg->id == 73))
+   if(!(msg->id == 73) && !(msg->id == 74))
    printk("msgind: %d, sz=%d\n", msg->id, cmd_mgr->queue_sz);
 #ifdef CREATE_TRACE_POINTS
     trace_msg_recv(msg->id);
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_main.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_main.c
index 537334d..a6f44de 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_main.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_main.c
@@ -47,7 +47,7 @@
 #ifdef AICWF_USB_SUPPORT
 #include "aicwf_usb.h"
 #endif
-
+#include  "pub_debug_info.h"
 //static u8 wifi_mac_addr[6] = {0};
 
 u8 chip_sub_id;
@@ -1696,6 +1696,17 @@
                 bytes_written = -EINVAL;
                 break;
             }
+        }  else if (strcasecmp(argv[0], "SET_TXPWR_LOSS") == 0) {
+            if (argc > 1) {
+                s8_l func = (s8_l)command_strtoul(argv[1], NULL, 10);
+                printk("set txpwr loss: %d\n", func);
+                set_txpwr_loss_ofst(func);
+                rwnx_send_txpwr_lvl_req(p_rwnx_hw);
+            } else {
+                printk("wrong args\n");
+                bytes_written = -EINVAL;
+                break;
+            }
         }
         #ifdef CONFIG_RFTEST_USB_BT
         else if (strcasecmp(argv[0], "BT_RESET") == 0) {
@@ -7260,7 +7271,7 @@
     0x00ffcc85,
     0x00ffcd70,
     0x00ffcd80,
-    0x00ffce70,
+    0x00ffcd90,
     0x00ffce80,
     0x00ffce93,
     0x00ffcf90,
@@ -7282,6 +7293,105 @@
     0x00ffc790,
     #endif
 };
+const uint32_t txgain_map_h[96] =
+{
+    0xffd888, //11
+    0xffd979, //12
+    0xffd988, //13
+    0xffda79, //14
+    0xffda88, //15
+    0xffdb79, //16
+    0xffdb88, //17
+    0xffdc72, //18
+    0xffdc80, //19
+    0xffdd80, //20
+    0xffde66, //21
+    0xffde72, //22
+    0xffde80, //23
+    0xffdf79, //24
+    0xffdf88, //25
+    0xffdf98, //26
+    0xffd079, //-5
+    0xffd088, //-4
+    0xffd179, //-3
+    0xffd188, //-2
+    0xffd288, //-1
+    0xffd36c, //0
+    0xffd379, //1
+    0xffd388, //2
+    0xffd479, //3
+    0xffd488, //4
+    0xffd579, //5
+    0xffd588, //6
+    0xffd679, //7
+    0xffd688, //8
+    0xffd779, //9
+    0xffd879, //10
+    0xffc879, //8
+    0xffc96b, //9
+    0xffc979, //10
+    0xffca6b, //11
+    0xffca79, //12
+    0xffcc56, //13
+    0xffcc60, //14
+    0xffcc6b, //15
+    0xffcc79, //16
+    0xffcd72, //17
+    0xffce60, //18
+    0xffce72, //19
+    0xffcf72, //20
+    0xffcf80, //21
+    0xffcf90, //22
+    0xffcf90, //23
+    0xffc079, //-8
+    0xffc16b, //-7
+    0xffc179, //-6
+    0xffc26b, //-5
+    0xffc279, //-4
+    0xffc36b, //-3
+    0xffc379, //-2
+    0xffc46b, //-1
+    0xffc479, //0
+    0xffc56b, //1
+    0xffc579, //2
+    0xffc66b, //3
+    0xffc679, //4
+    0xffc76b, //5
+    0xffc779, //6
+    0xffc86b, //7
+    0xffc879, //8
+    0xffc96b, //9
+    0xffc979, //10
+    0xffca6b, //11
+    0xffca79, //12
+    0xffcc56, //13
+    0xffcc60, //14
+    0xffcc6b, //15
+    0xffcc79, //16
+    0xffcd72, //17
+    0xffce60, //18
+    0xffce72, //19
+    0xffcf72, //20
+    0xffcf80, //21
+    0xffcf90, //22
+    0xffcf90, //23
+    0xffc079, //-8
+    0xffc16b, //-7
+    0xffc179, //-6
+    0xffc26b, //-5
+    0xffc279, //-4
+    0xffc36b, //-3
+    0xffc379, //-2
+    0xffc46b, //-1
+    0xffc479, //0
+    0xffc56b, //1
+    0xffc579, //2
+    0xffc66b, //3
+    0xffc679, //4
+    0xffc76b, //5
+    0xffc779, //6
+    0xffc86b, //7
+};
 
 u32 wifi_txgain_table_24g_8800dcdw[32] =
 {
@@ -7626,7 +7736,7 @@
         u32 patch_tbl_wifisetting_u02_num = sizeof(patch_tbl_wifisetting_u02)/sizeof(u32)/2;
         u32 ldpc_cfg_size = sizeof(ldpc_cfg_ram);
         u32 agc_cfg_size = sizeof(agc_cfg_ram);
-        u32 txgain_cfg_size = sizeof(txgain_map);
+        u32 txgain_cfg_size, *txgain_cfg_array;
 
 
         struct dbg_mem_read_cfm cfm;
@@ -7703,14 +7813,25 @@
         }
 
         #if !defined(CONFIG_FPGA_VERIFICATION)
-        ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, txgain_cfg_addr, txgain_cfg_size, txgain_map);
+        if ((IS_CHIP_ID_H())) {
+            txgain_cfg_size = sizeof(txgain_map_h);
+            txgain_cfg_array = (u32 *)txgain_map_h;
+        } else {
+            txgain_cfg_size = sizeof(txgain_map);
+            txgain_cfg_array = (u32 *)txgain_map;
+        }
+        ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, txgain_cfg_addr, txgain_cfg_size, txgain_cfg_array);
         if (ret) {
             printk("txgain upload fail: %x, err:%d\r\n", txgain_cfg_addr, ret);
         }
 	if ((chip_sub_id == 0) && (chip_mcu_id == 0)) {
 		ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC);
-        }else{
+	} else if (chip_sub_id == 1) {
 		ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC_U02);
+	} else if (chip_sub_id == 2) {
+		ret = aicwf_patch_table_load(rwnx_hw, RWNX_MAC_PATCH_TABLE_8800DC_H_U02);
+	} else {
+		printk("unsupported id: %d\n", chip_sub_id);
                 }
 	if (ret) {
 	    printk("patch_tbl upload fail: err:%d\r\n", ret);
@@ -7951,19 +8072,78 @@
         }
     }
 }
+extern int aicwf_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
+extern int aicwf_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
 
-static void rf_config(struct rwnx_hw *rwnx_hw)
+int rf_config(struct rwnx_hw *rwnx_hw)
 {
-    #if 0
-    int ret;
-    ret = rwnx_send_dbg_mem_mask_write_req(rwnx_hw,
-                rf_tbl_masked[0][0], rf_tbl_masked[0][1], rf_tbl_masked[0][2]);
-    if (ret) {
-        printk("rf config %x write fail: %d\n", rf_tbl_masked[0][0], ret);
+	int ret =0;
+	struct mm_set_rf_calib_cfm cfm;
+    if ((ret = rwnx_send_txpwr_lvl_req(rwnx_hw))) {
+        return -1;
     }
+
+    if ((ret = rwnx_send_txpwr_ofst_req(rwnx_hw))) {
+        return -1;
+    }
+	if (testmode == 0) {
+		if (IS_CHIP_ID_H()) {
+			if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0,    1, (u8_l *)wifi_txgain_table_24g_8800dcdw_h, 128)))
+				return -1;
+			if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16,    1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw_h, 128)))
+				return -1;
+		} else {
+			if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0,	1, (u8_l *)wifi_txgain_table_24g_8800dcdw, 128)))
+				return -1;
+			if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16,	1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw, 128)))
+				return -1;
+		}
+		if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0,	0, (u8_l *)wifi_rxgain_table_24g_20m_8800dcdw, 256)))
+			return -1;
+		if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32,  0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
+			return -1;
+		if ((ret = rwnx_send_rf_calib_req(rwnx_hw, &cfm))) {
+			return -1;
+		}
+
+	}else if (testmode == 1) {
+		if (chip_sub_id >= 1) {
+#ifdef CONFIG_DPD
+#ifndef CONFIG_FORCE_DPD_CALIB
+            if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
+                printk("%s load dpd bin\n", __func__);
+                ret = aicwf_dpd_result_load_8800dc(rwnx_hw, &dpd_res);
+    if (ret) {
+                    printk("load dpd bin fail: %d\n", ret);
+                    return ret;
+    }
+            }
     #endif
+            if (dpd_res.bit_mask[1]) {
+                ret = aicwf_dpd_result_apply_8800dc(rwnx_hw, &dpd_res);
+                if (ret) {
+                    printk("apply dpd bin fail: %d\n", ret);
+                    return ret;
 }
-extern int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw);
+            }
+#else
+            {
+                ret = aicwf_misc_ram_init_8800dc(rwnx_hw);
+                if (ret) {
+                    printk("misc ram init fail: %d\n", ret);
+                    return ret;
+                }
+            }
+#endif
+	   		ret = rwnx_send_rf_calib_req(rwnx_hw, &cfm);
+			if (ret) {
+				printk("rf calib req fail: %d\n", ret);
+		   		return -1;
+	   		}
+	   }
+	}
+	return 0;
+}
 static int start_from_bootrom(struct rwnx_hw *rwnx_hw)
 {
     int ret = 0;
@@ -8022,6 +8202,7 @@
 
     if (!wiphy) {
         dev_err(rwnx_platform_get_dev(rwnx_plat), "Failed to create new wiphy\n");
+		sc_debug_info_record(MODULE_ID_AP_WIFI,"rwnx cfg80211 wiphy_new failed \n");
         ret = -ENOMEM;
         goto err_out;
     }
@@ -8222,52 +8403,14 @@
 #endif
     tasklet_init(&rwnx_hw->task, rwnx_task, (unsigned long)rwnx_hw);
 
-    rf_config(rwnx_hw);
-    if ((ret = rwnx_send_txpwr_lvl_req(rwnx_hw))) {
-        goto err_platon;
-    }
-
-    if ((ret = rwnx_send_txpwr_ofst_req(rwnx_hw))) {
-        goto err_platon;
-    }
+    if (ret = rf_config(rwnx_hw))
 
 
-    if (testmode == 0) {
-		if (IS_CHIP_ID_H()) {
-			if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0,    1, (u8_l *)wifi_txgain_table_24g_8800dcdw_h, 128)))
+
 				goto err_lmac_reqs;
-			if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16,    1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw_h, 128)))
-				goto err_lmac_reqs;
-		} else {
-		if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0,	1, (u8_l *)wifi_txgain_table_24g_8800dcdw, 128)))
-            goto err_lmac_reqs;
 
-        if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16,	1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw, 128)))
-			goto err_lmac_reqs;
-		}
-		if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0,	0, (u8_l *)wifi_rxgain_table_24g_20m_8800dcdw, 256)))
-            goto err_lmac_reqs;
 
-		if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32,  0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
-            goto err_lmac_reqs;
 
-	}else if (testmode == 1) {
-		if (chip_sub_id == 1) {
-            #ifdef CONFIG_DPD
-            if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
-                printk("%s load dpd bin\n", __func__);
-                ret = aicwf_fdrv_dpd_result_load_8800dc(rwnx_hw);
-                if (ret) {
-                    printk("load dpd bin fail: %d\n", ret);
-                    return ret;
-                }
-            }
-            #endif
-        }
-	}
-        if ((ret = rwnx_send_rf_calib_req(rwnx_hw, &cfm))) {
-            goto err_lmac_reqs;
-    }
 
     if ((ret = rwnx_send_get_macaddr_req(rwnx_hw, (struct mm_get_mac_addr_cfm *)mac_addr_efuse)))
         goto err_lmac_reqs;
@@ -8408,7 +8551,10 @@
     flush_workqueue(rwnx_hw->apmStaloss_wq);
     destroy_workqueue(rwnx_hw->apmStaloss_wq);
     rwnx_wdev_unregister(rwnx_hw);
+    if(rwnx_hw->wiphy && rwnx_hw->wiphy->registered){
+        printk("%s wiphy_unregister \r\n", __func__);
     wiphy_unregister(rwnx_hw->wiphy);
+    }
     rwnx_radar_detection_deinit(&rwnx_hw->radar);
     rwnx_platform_off(rwnx_hw, NULL);
     kmem_cache_destroy(rwnx_hw->sw_txhdr_cache);
@@ -8459,6 +8605,7 @@
 
 	if ((wait_for_completion_timeout(&hostif_register_done, msecs_to_jiffies(REGISTRATION_TIMEOUT)) == 0) || rwnx_driver_err) {
 		printk("register_driver timeout or error\n");
+		sc_debug_info_record(MODULE_ID_AP_WIFI,"rwnx register_driver timeout or error \n");
 #ifdef AICWF_SDIO_SUPPORT
         aicwf_sdio_exit();
 #endif /* AICWF_SDIO_SUPPORT */
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_msg_tx.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_msg_tx.c
old mode 100644
new mode 100755
index 3b7a2eb..1a031e0
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_msg_tx.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_msg_tx.c
@@ -410,6 +410,24 @@
     return rwnx_send_msg(rwnx_hw, start_req_param, 1, MM_START_CFM, NULL);
 }
 
+rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_hwconfig_cfm *cfm)
+{
+	int error;
+	struct mm_get_chip_temp_req *req;
+	RWNX_DBG(RWNX_FN_ENTRY_STR);
+	req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_chip_temp_req));
+	if (!req)
+		return -ENOMEM;
+	req->hwconfig_id = 5;
+	error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, cfm);
+	if (!error) {
+		printk("get_chip_temp degree=%d\n", cfm->chip_temp_cfm.degree);
+	} else {
+		printk("get_chip_temp err=%d\n", error);
+		return error;
+	}
+	return error;
+}
 int rwnx_send_version_req(struct rwnx_hw *rwnx_hw, struct mm_version_cfm *cfm)
 {
     void *void_param;
@@ -1057,29 +1075,12 @@
 	return error;
 }
 
-int rwnx_send_txop_req(struct rwnx_hw *rwnx_hw, uint16_t *txop, u8_l long_nav_en, u8_l cfe_en)
-{
-    struct mm_set_txop_req *req;
-    int error;
 
     /* Build the MM_SET_TXOP_REQ message */
-    req = rwnx_msg_zalloc(MM_SET_TXOP_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_txop_req));
 
-    if (!req) {
-        return -ENOMEM;
-    }
 
-    req->txop_bk = txop[0];
-    req->txop_be = txop[1];
-    req->txop_vi = txop[2];
-    req->txop_vo = txop[3];
-    req->long_nav_en = long_nav_en;
-    req->cfe_en = cfe_en;
     /* Send the MM_SET_TXOP_REQ  message to UMAC FW */
-    error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_TXOP_CFM, NULL);
 
-    return error;
-}
 
 int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm)
 {
@@ -1132,8 +1133,19 @@
         rwnx_msg_free(rwnx_hw, txpwr_lvl_req);
         return 0;
     } else {
+
+	if (txpwr_loss->loss_enable == 1) {
+		printk("%s:loss_value:%d\r\n", __func__, txpwr_loss->loss_value);
+        for (i = 0; i <= 11; i++)
+            txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[i] += txpwr_loss->loss_value;
+        for (i = 0; i <= 9; i++)
+            txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[i] += txpwr_loss->loss_value;
+        for (i = 0; i <= 11; i++)
+            txpwr_lvl_v2->pwrlvl_11ax_2g4[i] += txpwr_loss->loss_value;
+	}
         printk("%s:enable:%d\r\n",               __func__, txpwr_lvl_v2->enable);
         printk("%s:lvl_11b_11ag_1m_2g4:%d\r\n",  __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[0]);
+#if 0
         printk("%s:lvl_11b_11ag_2m_2g4:%d\r\n",  __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[1]);
         printk("%s:lvl_11b_11ag_5m5_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[2]);
         printk("%s:lvl_11b_11ag_11m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]);
@@ -1167,17 +1179,9 @@
         printk("%s:lvl_11ax_mcs9_2g4:%d\r\n",    __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[9]);
         printk("%s:lvl_11ax_mcs10_2g4:%d\r\n",   __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[10]);
         printk("%s:lvl_11ax_mcs11_2g4:%d\r\n",   __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[11]);
+#endif
 
-	if (txpwr_loss->loss_enable == 1) {
-		printk("%s:loss_value:%d\r\n", __func__, txpwr_loss->loss_value);
 
-        for (i = 0; i <= 11; i++)
-            txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[i] += txpwr_loss->loss_value;
-        for (i = 0; i <= 9; i++)
-            txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[i] += txpwr_loss->loss_value;
-        for (i = 0; i <= 11; i++)
-            txpwr_lvl_v2->pwrlvl_11ax_2g4[i] += txpwr_loss->loss_value;
-	}
         if ((testmode == 0) && (chip_sub_id == 0)) {
             txpwr_lvl_req->txpwr_lvl.enable         = txpwr_lvl_v2->enable;
             txpwr_lvl_req->txpwr_lvl.dsss           = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_msg_tx.h b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_msg_tx.h
old mode 100644
new mode 100755
index f8efc60..85cec48
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_msg_tx.h
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_msg_tx.h
@@ -17,6 +17,7 @@
 
 int rwnx_send_reset(struct rwnx_hw *rwnx_hw);
 int rwnx_send_start(struct rwnx_hw *rwnx_hw);
+int rwnx_send_get_temp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_hwconfig_cfm *cfm);
 int rwnx_send_version_req(struct rwnx_hw *rwnx_hw, struct mm_version_cfm *cfm);
 int rwnx_send_add_if(struct rwnx_hw *rwnx_hw, const unsigned char *mac,
                      enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm);
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.c
index 2129cf7..e1703a4 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.c
@@ -110,6 +110,53 @@
     },
 };
 
+extern u8 chip_id;
+void set_txpwr_ctrl(struct aic_sdio_dev *sdiodev, s8_l value)
+{
+	if (!IS_CHIP_ID_H()) {
+		printk("%s  !h\n", __func__);
+		return;
+	}
+	nvram_info.txpwr_loss.loss_enable = 1;
+	if (value > TEMP_THD_1 && value <= TEMP_THD_2) {
+		if (sdiodev->range == 0) {
+			nvram_info.txpwr_loss.loss_value += -TEMP_STEP_1;
+			sdiodev->range = 1;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		} else if (sdiodev->range == 1) {
+			return;
+		} else if (sdiodev->range == 2) {
+			nvram_info.txpwr_loss.loss_value += TEMP_STEP_1;
+			sdiodev->range = 1;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		}
+	} else if (value > TEMP_THD_2) {
+		if (sdiodev->range == 0) {
+			nvram_info.txpwr_loss.loss_value += -TEMP_STEP_2;
+			sdiodev->range = 2;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		} else if (sdiodev->range == 1) {
+			nvram_info.txpwr_loss.loss_value += -TEMP_STEP_1;
+			sdiodev->range = 2;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		} else {
+			return;
+		}
+	} else {
+		if (sdiodev->range == 0) {
+			return;
+		} else if (sdiodev->range == 1) {
+			nvram_info.txpwr_loss.loss_value += TEMP_STEP_1;
+			sdiodev->range = 0;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		} else if (sdiodev->range == 2) {
+			nvram_info.txpwr_loss.loss_value += TEMP_STEP_2;
+			sdiodev->range = 0;
+			rwnx_send_txpwr_lvl_req(sdiodev->rwnx_hw);
+		}
+	}
+	return;
+}
 
 #ifdef VENDOR_SPECIFIED_FW_PATH
 int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device)
@@ -127,8 +174,11 @@
         *fw_buf = NULL;
         return -1;
     }
-
+#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
 	if(strcmp(name, FW_DPDRESULT_NAME_8800DC) == 0) {
+#else
+	if(0) {
+#endif
 		len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", VENDOR_SPECIFIED_DPD_PATH, name);
 	} else {
     len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", VENDOR_SPECIFIED_FW_PATH, name);
@@ -425,6 +475,9 @@
 }
 #endif
 
+#ifdef CONFIG_DPD
+rf_misc_ram_lite_t dpd_res = {0,};
+#endif
 int aicwf_patch_table_load(struct rwnx_hw *rwnx_hw, char *filename)
 {
     int err = 0;
@@ -703,6 +756,7 @@
     *txpwr_lvl_v2 = nvram_info.txpwr_lvl_v2;
     printk("%s:enable:%d\r\n",               __func__, txpwr_lvl_v2->enable);
     printk("%s:lvl_11b_11ag_1m_2g4:%d\r\n",  __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[0]);
+#if 0
     printk("%s:lvl_11b_11ag_2m_2g4:%d\r\n",  __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[1]);
     printk("%s:lvl_11b_11ag_5m5_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[2]);
     printk("%s:lvl_11b_11ag_11m_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]);
@@ -736,6 +790,7 @@
     printk("%s:lvl_11ax_mcs9_2g4:%d\r\n",    __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[9]);
     printk("%s:lvl_11ax_mcs10_2g4:%d\r\n",   __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[10]);
     printk("%s:lvl_11ax_mcs11_2g4:%d\r\n",   __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[11]);
+#endif
 }
 void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss)
 {
@@ -744,6 +799,12 @@
     printk("%s:loss_enable:%d\r\n",     __func__, txpwr_loss->loss_enable);
     printk("%s:loss_value:%d\r\n",      __func__, txpwr_loss->loss_value);
 }
+void set_txpwr_loss_ofst(s8_l value)
+{
+    nvram_info.txpwr_loss.loss_enable = 1;
+    nvram_info.txpwr_loss.loss_value += value;
+    printk("%s:value:%d\r\n",      __func__, value);
+}
 void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst)
 {
     txpwr_ofst->enable       = nvram_info.txpwr_ofst.enable;
@@ -1551,13 +1612,32 @@
     return ret;
 }
 
+int aicwf_plat_patch_load_8800dc(struct rwnx_hw *rwnx_hw)
+{
+    int ret = 0;
+#if !defined(CONFIG_FPGA_VERIFICATION)
+    if (chip_sub_id == 0) {
+        ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2);
+    } else if (chip_sub_id == 1) {
+        ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_U02);
+    } else if (chip_sub_id == 2) {
+        ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_8800DC_H_U02);
+    } else {
+        printk("%s: unsupported id: %d\n", __func__, chip_sub_id);
+    }
+#endif
+    return ret;
+}
 /**
  * rwnx_plat_patch_load() - Load patch code
  *
  * @rwnx_hw: Main driver data
  */
- uint32_t dpd_res[DPD_RESULT_SIZE_8800DC / 4] = {0,};
-extern int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, uint32_t *dpd_res);
+#ifdef CONFIG_DPD
+extern int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw,  rf_misc_ram_lite_t *dpd_res);
+extern int aicwf_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
+extern int aicwf_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
+#endif
 static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
 {
     int ret = 0;
@@ -1566,81 +1646,93 @@
     if (testmode == 0) {
         #if !defined(CONFIG_FPGA_VERIFICATION)
         if (chip_sub_id == 0) {
-        ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR_U01, RWNX_MAC_PATCH_NAME2);
-        } else if (chip_sub_id == 1) {
-            ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_U02);
+            aicwf_plat_patch_load_8800dc(rwnx_hw);
+        } else if (chip_sub_id >= 1) {
+            aicwf_plat_patch_load_8800dc(rwnx_hw);
+			if (ret) {
+				printk("patch load fail: %d\n", ret);
+				return ret;
+			}
 #ifdef CONFIG_DPD
 #ifdef CONFIG_FORCE_DPD_CALIB
 		if (1) {
 			printk("dpd calib & write\n");
-			ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res[0]);
+			ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res);
 			if (ret) {
 				printk("dpd calib fail: %d\n", ret);
 				return ret;
 			}
-			ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
-			if (ret) {
-				printk("file write fail: %d\n", ret);
-				return ret;
-			}
 		}
 #else
 		if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
 			printk("dpd bin load\n");
-			ret = aicwf_dpd_result_load_8800dc(rwnx_hw);
+			ret = aicwf_dpd_result_load_8800dc(rwnx_hw, &dpd_res);;
 			if (ret) {
 				printk("load dpd bin fail: %d\n", ret);
 				return ret;
 			}
+			ret = aicwf_dpd_result_apply_8800dc(rwnx_hw, &dpd_res);
+			if (ret) {
+				printk("apply dpd bin fail: %d\n", ret);
+				return ret;
+			}
 		}
 #endif
 		else
 #endif
 		{
-			aicwf_misc_ram_init_8800dc(rwnx_hw);
+			ret = aicwf_misc_ram_init_8800dc(rwnx_hw);
+			if (ret) {
+				printk("misc ram init fail: %d\n", ret);
+				return ret;
+			}
 		}
         } else {
             printk("unsupported id: %d\n", chip_sub_id);
         }
         #endif
     } else if (testmode == 1) {
-    	ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_U02);
 			printk("patch load\n");
+		aicwf_plat_patch_load_8800dc(rwnx_hw);
+		if (ret) {
+			printk("patch load fail: %d\n", ret);
+			return ret;
+		}
 #ifdef CONFIG_DPD
 #ifdef CONFIG_FORCE_DPD_CALIB
 			if (1) {
 				printk("dpd calib & write\n");
-				ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res[0]);
+				ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res);
 				if (ret) {
 					printk("dpd calib fail: %d\n", ret);
 					return ret;
 				}
-				ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
-				if (ret) {
-					printk("file write fail: %d\n", ret);
-					return ret;
-				}
 			}
 #endif
 #endif
+		printk("%s load rftest bin\n", __func__);
         if (chip_sub_id == 0) {
         ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR_U01, RWNX_MAC_RF_PATCH_NAME);
         }
         if (!ret) {
             ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_LMAC_FW_ADDR, RWNX_MAC_FW_RF_BASE_NAME);
         	}
+		if (ret) {
+			printk("rftest bin load fail: %d\n", ret);
+			return ret;
+		}
         }
 	else if (testmode == 4) {
-                #ifdef CONFIG_DPD
+                #if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
 					if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 0) {
 						printk("patch load\n");
-						ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_U02);
+						aicwf_plat_patch_load_8800dc(rwnx_hw);
 						if (ret) {
 							printk("load patch bin fail: %d\n", ret);
 							return ret;
 						}
 						printk("dpd calib & write\n");
-						ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res[0]);
+						ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res);
 						if (ret) {
 							printk("dpd calib fail: %d\n", ret);
 							return ret;
@@ -1668,6 +1760,12 @@
             printk("load rftest bin fail: %d\n", ret);
             return ret;
         }
+    } else if (chip_sub_id == 2) {
+        ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_CALIB_ADDR, RWNX_MAC_CALIB_NAME_8800DC_H_U02);
+        if (ret) {
+            printk("load calib bin fail: %d\n", ret);
+            return ret;
+        }
     }
     return ret;
 }
@@ -1694,38 +1792,19 @@
         return 1;
     }
 }
-EXPORT_SYMBOL(is_file_exist);
-int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw)
+
+#endif
+int aicwf_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw)
 {
     int ret = 0;
     uint32_t cfg_base = 0x10164;
     struct dbg_mem_read_cfm cfm;
     uint32_t misc_ram_addr;
-	printk("%s\n", __func__);
+    uint32_t misc_ram_size = 12;
+    int i;
     if (testmode == 1) {
         cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
     }
-    if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) {
-        printk("rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
-        return ret;
-    }
-    misc_ram_addr = cfm.memdata;
-    ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, misc_ram_addr, FW_DPDRESULT_NAME_8800DC);
-    if (ret) {
-        printk("load calib bin fail: %d\n", ret);
-        return ret;
-    }
-    return ret;
-}
-#endif
-int aicwf_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw)
-{
-    int ret = 0;
-    const uint32_t cfg_base = 0x10164;
-    struct dbg_mem_read_cfm cfm;
-    uint32_t misc_ram_addr;
-    uint32_t misc_ram_size = 12;
-    int i;
     ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
     if (ret) {
         printk("rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
@@ -1743,7 +1822,7 @@
     return ret;
 }
 #ifdef CONFIG_DPD
-int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, uint32_t *dpd_res)
+int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
 {
     int ret = 0;
     uint32_t fw_addr, boot_type;
@@ -1765,7 +1844,7 @@
         const uint32_t cfg_base = 0x10164;
         struct dbg_mem_read_cfm cfm;
         uint32_t misc_ram_addr;
-        uint32_t misc_ram_size = DPD_RESULT_SIZE_8800DC;
+        uint32_t ram_base_addr, ram_word_cnt;
         int i;
         ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
         if (ret) {
@@ -1773,24 +1852,51 @@
             return ret;
         }
         misc_ram_addr = cfm.memdata;
-        for (i = 0; i < (misc_ram_size / 4); i++) {
-            ret = rwnx_send_dbg_mem_read_req(rwnx_hw, misc_ram_addr + i * 4, &cfm);
+        ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
+        ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4;
+        for (i = 0; i < ram_word_cnt; i++) {
+            ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm);
             if (ret) {
-                 printk("rf misc ram[0x%x] rd fail: %d\n",  misc_ram_addr + i * 4, ret);
+                printk("bit_mask[0x%x] rd fail: %d\n",  ram_base_addr + i * 4, ret);
                 return ret;
             }
-            dpd_res[i] = cfm.memdata;
+            dpd_res->bit_mask[i] = cfm.memdata;
+        }
+        ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
+        ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high) / 4;
+        for (i = 0; i < ram_word_cnt; i++) {
+            ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm);
+            if (ret) {
+                printk("bit_mask[0x%x] rd fail: %d\n",  ram_base_addr + i * 4, ret);
+                return ret;
+            }
+            dpd_res->dpd_high[i] = cfm.memdata;
+        }
+        ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
+        ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res) / 4;
+        for (i = 0; i < ram_word_cnt; i++) {
+            ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm);
+            if (ret) {
+                printk("bit_mask[0x%x] rd fail: %d\n",  ram_base_addr + i * 4, ret);
+                return ret;
+            }
+            dpd_res->loft_res[i] = cfm.memdata;
         }
     }
     return ret;
 }
-int aicwf_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw)
+int aicwf_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
 {
-	printk("%s\n", __func__);
     int ret = 0;
     uint32_t cfg_base = 0x10164;
     struct dbg_mem_read_cfm cfm;
     uint32_t misc_ram_addr;
+    uint32_t ram_base_addr, ram_byte_cnt;
+    printk("bit_mask[1]=%x\n", dpd_res->bit_mask[1]);
+    if (dpd_res->bit_mask[1] == 0) {
+        printk("void dpd_res, bypass it.\n");
+        return 0;
+    }
 	if (testmode == 1) {
 		cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
 	}
@@ -1799,11 +1905,52 @@
         return ret;
     }
     misc_ram_addr = cfm.memdata;
-    ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, misc_ram_addr, FW_DPDRESULT_NAME_8800DC);
+    printk("misc_ram_addr: %x\n", misc_ram_addr);
+    printk("bit_mask[0]=%x\n", dpd_res->bit_mask[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved);
+    ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->bit_mask[0]);
     if (ret) {
-        printk("load calib bin fail: %d\n", ret);
+        printk("bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
         return ret;
     }
+    printk("dpd_high[0]=%x\n", dpd_res->dpd_high[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high);
+    ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->dpd_high[0]);
+    if (ret) {
+        printk("dpd_high wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
+        return ret;
+    }
+    printk("loft_res[0]=%x\n", dpd_res->loft_res[0]);
+    ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
+    ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res);
+    ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->loft_res[0]);
+    if (ret) {
+        printk("loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
+        return ret;
+    }
+    return ret;
+}
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
+{
+    int ret = 0;
+    int size;
+    u32 *dst=NULL;
+    char *filename = FW_DPDRESULT_NAME_8800DC;
+    printk("dpd_res file path:%s \r\n", filename);
+    size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
+    if (size <= 0) {
+        printk("wrong size of dpd_res file\n");
+        dst = NULL;
+        return -1;
+    }
+    printk("### Load file done: %s, size=%d, dst[0]=%x\n", filename, size, dst[0]);
+    memcpy((u8 *)dpd_res, (u8 *)dst, sizeof(rf_misc_ram_lite_t));
+    if (dst) {
+        rwnx_release_firmware_common(&dst);
+    }
     return ret;
 }
 int aicwf_dpd_result_write_8800dc(void *buf, int buf_len)
@@ -1846,6 +1993,7 @@
 	fp = NULL;
     return 0;
 }
+#endif /* !CONFIG_FORCE_DPD_CALIB */
 #endif
 
 #if 0
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.h b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.h
index a5883de..f911763 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.h
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.h
@@ -43,21 +43,49 @@
 #endif
 #define RWNX_MAC_CALIB_BASE_NAME_8800DC        "fmacfw_calib_8800dc"
 #define RWNX_MAC_CALIB_NAME_8800DC_U02          RWNX_MAC_CALIB_BASE_NAME_8800DC"_u02.bin"
+#define RWNX_MAC_CALIB_NAME_8800DC_H_U02        RWNX_MAC_CALIB_BASE_NAME_8800DC"_h_u02.bin"
 
+#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
+#define FW_DPDRESULT_NAME_8800DC        "aic_dpdresult_8800dc.bin"
+#endif
 #ifdef CONFIG_DPD
 #define ROM_FMAC_CALIB_ADDR            0x00130000
-#define FW_DPDRESULT_NAME_8800DC        "aic_dpdresult_8800dc.bin"
-#define DPD_RESULT_SIZE_8800DC 1880
 #define FW_PATH_MAX_LEN 200
-int aicwf_dpd_result_write_8800dc(void *buf, int buf_len);
 int is_file_exist(char* name);
+typedef struct {
+    uint32_t bit_mask[3];
+    uint32_t reserved;
+    uint32_t dpd_high[96];
+    uint32_t dpd_11b[96];
+    uint32_t dpd_low[96];
+    uint32_t idac_11b[48];
+    uint32_t idac_high[48];
+    uint32_t idac_low[48];
+    uint32_t loft_res[18];
+    uint32_t rx_iqim_res[16];
+} rf_misc_ram_t;
+typedef struct {
+    uint32_t bit_mask[4];
+    uint32_t dpd_high[96];
+    uint32_t loft_res[18];
+} rf_misc_ram_lite_t;
+#define MEMBER_SIZE(type, member)   sizeof(((type *)0)->member)
+#define DPD_RESULT_SIZE_8800DC      sizeof(rf_misc_ram_lite_t)
+extern rf_misc_ram_lite_t dpd_res;
+#endif
+#ifdef CONFIG_DPD
+#ifndef CONFIG_FORCE_DPD_CALIB
+int aicwf_dpd_result_write_8800dc(void *buf, int buf_len);
+#endif
 #endif
 #define RWNX_MAC_PATCH_BASE_NAME        "fmacfw_patch_8800dc"
 #define RWNX_MAC_PATCH_NAME2 RWNX_MAC_PATCH_BASE_NAME".bin"
 #define RWNX_MAC_PATCH_NAME2_U02 RWNX_MAC_PATCH_BASE_NAME"_u02.bin"
+#define RWNX_MAC_PATCH_NAME2_8800DC_H_U02 RWNX_MAC_PATCH_BASE_NAME"_h_u02.bin"
 #define RWNX_MAC_PATCH_TABLE_NAME_8800DC "fmacfw_patch_tbl_8800dc"
 #define RWNX_MAC_PATCH_TABLE_8800DC RWNX_MAC_PATCH_TABLE_NAME_8800DC ".bin"
 #define RWNX_MAC_PATCH_TABLE_8800DC_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_u02.bin"
+#define RWNX_MAC_PATCH_TABLE_8800DC_H_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_h_u02.bin"
 #define RWNX_MAC_RF_PATCH_BASE_NAME     "fmacfw_rf_patch"
 #define RWNX_MAC_RF_PATCH_NAME RWNX_MAC_RF_PATCH_BASE_NAME".bin"
 
@@ -165,6 +193,7 @@
 void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss);
 void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst);
 void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap);
+void set_txpwr_loss_ofst(s8_l value);
 #endif
 int aicwf_patch_table_load(struct rwnx_hw *rwnx_hw, char *filename);
 int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device);
@@ -175,5 +204,6 @@
     return rwnx_plat->pci_dev->irq;
 }
 int aicwf_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
+int aicwf_plat_patch_load_8800dc(struct rwnx_hw *rwnx_hw);
 
 #endif /* _RWNX_PLATFORM_H_ */
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_strs.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_strs.c
old mode 100644
new mode 100755
index 32cc0e9..bd5502b
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_strs.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_strs.c
@@ -128,8 +128,8 @@
         [MSG_I(MM_SET_STACK_START_REQ)] = "MM_SET_STACK_START_REQ",
         [MSG_I(MM_SET_STACK_START_CFM)] = "MM_SET_STACK_START_CFM",
         [MSG_I(MM_APM_STALOSS_IND)]     = "MM_APM_STALOSS_IND",
-        [MSG_I(MM_SET_TXOP_REQ)]        = "MM_SET_TXOP_REQ",
-        [MSG_I(MM_SET_TXOP_CFM)]        = "MM_SET_TXOP_CFM",
+        [MSG_I(MM_SET_VENDOR_HWCONFIG_REQ)]        = "MM_SET_VENDOR_HWCONFIG_REQ",
+        [MSG_I(MM_SET_VENDOR_HWCONFIG_CFM)]        = "MM_SET_VENDOR_HWCONFIG_CFM",
         [MSG_I(MM_GET_FW_VERSION_REQ)]  = "MM_GET_FW_VERSION_REQ",
         [MSG_I(MM_GET_FW_VERSION_CFM)]  = "MM_GET_FW_VERSION_CFM",
 };
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_tx.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_tx.c
index 37a3046..4c79e91 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_tx.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_tx.c
@@ -1476,7 +1476,7 @@
     #else
     desc = &txhdr->desc;
     #endif
-
+	desc->host.ethertype = 0;
     desc->host.staid = (sta) ? sta->sta_idx : 0xFF;
     desc->host.vif_idx = vif->vif_index;
     desc->host.tid = 0xFF;
@@ -1910,7 +1910,7 @@
 	#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
         cfg80211_mgmt_tx_status(&sw_txhdr->rwnx_vif->wdev,
 	#else
-	if (sw_txhdr->rwnx_vif->up && sw_txhdr->rwnx_vif->ndev)
+	if (sw_txhdr->rwnx_vif->up && sw_txhdr->rwnx_vif->ndev && sw_txhdr->rwnx_vif->ndev->reg_state == NETREG_REGISTERED)
         cfg80211_mgmt_tx_status(sw_txhdr->rwnx_vif->ndev,
 	#endif
                                 (unsigned long)skb,
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 4dd2a9d..b940957 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
@@ -427,7 +427,8 @@
 	if(g_zvnet_skb_xmit_queue.qlen >= ZVNET_XMIT_MAX_QUEUE_NUM){

 		net->stats.tx_errors++;

 		net->stats.tx_dropped++;

-		zv_err("write err, qlen:%d!", g_zvnet_skb_xmit_queue.qlen);

+		if(printk_ratelimit())

+			zv_err("write err, qlen:%d!", g_zvnet_skb_xmit_queue.qlen);

 		kfree_skb(skb);

 		return NET_XMIT_SUCCESS;

 	}

diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/ddr/zx-ddr.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/ddr/zx-ddr.c
old mode 100644
new mode 100755
index c15e1dd..8e01933
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/ddr/zx-ddr.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/ddr/zx-ddr.c
@@ -30,7 +30,7 @@
 

 #ifdef CONFIG_DDR_ZX29_MODULE

 

-#define DDR_TEST_SIZE	(0x8000)//32k

+#define DDR_TEST_SIZE	(0xf000)//32k 

 

 extern int ddr_get_info(struct flash_ddr_info *info);

 extern bool zx29_dma_filter_fn(struct dma_chan *chan, void *param);

@@ -68,9 +68,9 @@
 	temp_config.dest_addr	= dst_addr;	

 	temp_config.count		= size;

 	temp_config.dma_control.tran_mode 		= TRAN_MEM_TO_MEM;

-	temp_config.dma_control.src_burst_size 	= DMA_BURST_SIZE_8BIT;

+	temp_config.dma_control.src_burst_size 	= DMA_BURST_SIZE_64BIT;

 	temp_config.dma_control.src_burst_len 	= DMA_BURST_LEN_16;

-	temp_config.dma_control.dest_burst_size = DMA_BURST_SIZE_8BIT;

+	temp_config.dma_control.dest_burst_size = DMA_BURST_SIZE_64BIT;

 	temp_config.dma_control.dest_burst_len 	= DMA_BURST_LEN_16;

 	temp_config.dma_control.irq_mode 		= DMA_ALL_IRQ_ENABLE;

 	

@@ -224,17 +224,23 @@
 		return 1;

 	}

 	ddr.result =result_info; 

-	ddr.size = size;

-	ddr_dma_config(ddrtest_phy_addr, ddrtest_phy_addr+size, size);

+

+	if(size>=0x10000)

+		ddr.size = 0xfffc;	

+	else

+		ddr.size = size;

+	

+	ddr_dma_config(ddrtest_phy_addr, ddrtest_phy_addr+size, ddr.size);

 	ddr_dma_start(&ddr, noncache_dma_cb);

 	

 	while(!zx_noncache_dma_flag);

 	

-	for(addr1=(unsigned int)vir_addr,addr2=(unsigned int)vir_addr+size; addr1<(unsigned int)vir_addr+size; addr1+=4,addr2+=4) {

+	for(addr1=(unsigned int)vir_addr,addr2=(unsigned int)vir_addr+size; addr1<(unsigned int)vir_addr+ddr.size; addr1+=4,addr2+=4) {

 		if(zx_read_reg(addr1) != zx_read_reg(addr2)) {

 			

-			pr_info("addr:0x%x cacheable_dma failed.    \n", addr1);

+			pr_info("addr:0x%x noncache_dma failed.    \n", addr1);

 			sprintf(result_info->noncache_dma, "addr:0x%x noncache_dma failed", addr1);

+

 			dma_free_coherent(NULL, 2*size, vir_addr, ddrtest_phy_addr );

 			dma_release_channel(ddrtest_chan);	

 			return 1;

@@ -331,14 +337,19 @@
 		return 1;

 	}

 	ddr.result =result_info; 

-	ddr.size = size;	

-	ddr_dma_config(ddrtest_phy_addr, ddrtest_phy_addr+size, size);

+

+	if(size>=0x10000)

+		ddr.size = 0xfffc;	

+	else

+		ddr.size = size;

+	

+	ddr_dma_config(ddrtest_phy_addr, ddrtest_phy_addr+size, ddr.size );

 	ddr_dma_start(&ddr, cacheable_dma_cb);

 		

 	while(!zx_cacheable_dma_flag);

 	

 	dma_sync_single_for_cpu(NULL,ddrtest_phy_addr+size , size,DMA_BIDIRECTIONAL);

-	for(addr1=(unsigned int)ddrtest_buffer, addr2=(unsigned int)ddrtest_buffer+size; addr1<(unsigned int)ddrtest_buffer+size; addr1+=4, addr2+=4 ){

+	for(addr1=(unsigned int)ddrtest_buffer, addr2=(unsigned int)ddrtest_buffer+size; addr1<(unsigned int)ddrtest_buffer+ddr.size ; addr1+=4, addr2+=4 ){

 		if(zx_read_reg(addr1) != zx_read_reg(addr2)) {

 			

 			pr_info("addr:0x%x cacheable_dma failed. \n", addr1);

@@ -444,17 +455,22 @@
 

 	time1= ioread32(CLOCKDELAY_BASE+CUR_VALUE);

 	ddr.result =result_info; 

-	ddr.size = size;	

+

+	if(size>=0x10000)

+		ddr.size = 0xffff;	

+	else

+		ddr.size = size;	

+	

 	for(cnt=0; cnt<1000;cnt++){

 		//a to b 

 		zx_cacheable_dma_flag=0;

-		ddr_dma_config(ddrtest_phy_addr, ddrtest_phy_addr+size, size);

+		ddr_dma_config(ddrtest_phy_addr, ddrtest_phy_addr+size, ddr.size);

 		ddr_dma_start(&ddr,cacheable_speed_cb);

 		while(!zx_cacheable_dma_flag);

 		

 		//b to a

 		zx_cacheable_dma_flag=0;

-		ddr_dma_config(ddrtest_phy_addr+size, ddrtest_phy_addr, size);

+		ddr_dma_config(ddrtest_phy_addr+size, ddrtest_phy_addr, ddr.size);

 		ddr_dma_start(&ddr,cacheable_speed_cb);

 		while(!zx_cacheable_dma_flag);

 		zx_cacheable_dma_flag=0;

diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-cpuidle.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-cpuidle.c
index a2a3154..4713916 100755
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-cpuidle.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/power/zx-cpuidle.c
@@ -305,7 +305,7 @@
 {
 	unsigned int temp_count;
 
-	if (idle_debug_mask & DEBUG_WAKE_LOCK) 
+	if(pm_get_mask_info()&PM_SLEEP_FLAG_PRINT) //if (idle_debug_mask & DEBUG_WAKE_LOCK) 
 		pm_debug_wakelocks();
 	
 	if(pm_get_wakeup_count(&temp_count, false))
@@ -508,7 +508,7 @@
 	
 	clock_event_handler();
 	
-	pm_ram_log(" @@sleep exit:sleep_count=%d,real_idle_time=%lld,jiffies:%u\n",sleep_count, idle_time, jiffies);
+	pm_ram_log(" @@sleep exit:sleep_count=%u,real_idle_time=%lld,jiffies:%u\n",sleep_count, idle_time, jiffies);
 	
 IRQ_LOCK_EXIT:
 	#ifdef CONFIG_ZX_PM_DEBUG
@@ -658,7 +658,7 @@
 	psm_TimeCompensate(idle_time);
 	#endif
 
-	pm_ram_log(" @@sleep exit:sleep_count=%d,real_idle_time=%lld,jiffies:%u\n",sleep_count, idle_time, jiffies);
+	pm_ram_log(" @@sleep exit:sleep_count=%u,real_idle_time=%lld,jiffies:%u\n",sleep_count, idle_time, jiffies);
 
 	#ifdef CONFIG_ZX_RAM_CONSOLE 
 	pm_uart_mod_timer();
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 8a731f1..93e7d4f 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
@@ -258,6 +258,16 @@
 }
 EXPORT_SYMBOL(pm_psm_flag_print);
 
+void pm_cppsmsleeptime_print(u32 gsm_sleetime, u32 ps_sleetime)
+{
+	#ifdef CONFIG_CPU_IDLE
+	#ifndef CONFIG_ARCH_ZX297520V3_CAP
+	printk("\n gsmsleep: %u;  pssleep:%u \n ", gsm_sleetime, ps_sleetime);	
+	#endif
+	#endif
+}
+EXPORT_SYMBOL(pm_cppsmsleeptime_print);
+
 u32 print_cnt=0;
 
 void pm_idle_sram_print(void)
diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc-strategy.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc-strategy.c
index 5b0568f..bf90b0b 100755
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc-strategy.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc-strategy.c
@@ -28,11 +28,6 @@
 /****************************************************************************

 *                                           Types

 ****************************************************************************/

-typedef struct _T_TscPhy_Strategy

-{

-	char name[32];

-	volatile u32 flag;

-}T_TscP_Strategy;

 

 /*******************************************************************************

 *                                       Global Variables                                      *

@@ -43,7 +38,7 @@
 1: imite rate ÖÁÉÙ·¢Éú¹ýÒ»´Î;

 0: limite rateûÓз¢Éú¹ý

 */

-static  volatile u32 ps_rate_flag=0;

+//static  volatile u32 ps_rate_flag=0;

 /*

 µ÷ÓÃЭÒéÕ»»Øµ÷ǰÏȼì²â²ßÂÔÊÇ·ñÖ´Ðйý

 ÔÚ·¢Õý³£×¤Áô´ëʩ֮ǰ£¬Ïȼì²â֮ǰµÄ״̬ÊDz»ÊÇany resident

@@ -52,7 +47,7 @@
 1: any resident ÖÁÉÙ·¢Éú¹ýÒ»´Î;

 0: any resident ûÓз¢Éú¹ý

 */

-static  volatile u32 any_resident_flag=0;

+//static  volatile u32 any_resident_flag=0;

 

 /*

 µ÷Óõ÷ƵÊÇ·ñÖ´Ðйý

@@ -60,7 +55,7 @@
 1: tsc dfs ÖÁÉÙ·¢Éú¹ýÒ»´Î;

 0: tsc dfs ûÓз¢Éú¹ý

 */

-static  volatile u32 ps_freq_flag=0;

+//static  volatile u32 ps_freq_flag=0;

 

 struct timer_list timer_tsctrl;

 static int temp_percent = 0;

@@ -70,17 +65,22 @@
 typedef void (*T_Probe_Strategy)(u32 probe_num,int temperature );

 T_Probe_Strategy g_probe_strategy[PROBE_MAX]={0,};

 

-T_TscP_Strategy g_phy_Strategy[STRATEGY_PHY_NUM]={

-	{"lte downrate1",   0},

-	{"lte downrate2",   0},

-	{"w downrate1",    0},

-	{"w downrate2",    0},

-	{"lte up_tansmitepower1",  0},

-	{"lte up_tansmitepower2",  0},

-	{"w up_tansmitepower1",  0},

-	{"w up_tansmitepower2",  0},

+T_TscP_Strategy g_ps_Strategy[STRATEGY_PS_NUM]={

+	{"ps anyresident: ",   0},

+	{"ps rate limit: ",   0},

+	{"ps freq 312M: ",   0},

 };

 

+T_TscP_Strategy g_phy_Strategy[STRATEGY_PHY_NUM]={

+	{"lte downrate1 limit: ",   0},

+	{"lte downrate2 limit: ",   0},

+	{"w downrate1 limit: ",    0},

+	{"w downrate2 limit: ",    0},

+	{"lte up_tansmitepower1 limit: ",  0},

+	{"lte up_tansmitepower2 limit: ",  0},

+	{"w up_tansmitepower1 limit: ",  0},

+	{"w up_tansmitepower2 limit: ",  0},

+};

 

 u8 g_bit_probe[PROBE_MAX]={

 	BIT_PROBE_ADC1,

@@ -591,32 +591,35 @@
 			/*USER*/

 			if(tsc_read_reg(TSCTRL_SHUTDOWN)!=0){

 				/*user strategy start*/

+				tsc_set_reg_bits(TSCTRL_AP,BIT_SHUTDOWN,BITS_FOR_APPIRAM,STRTEGY_START);			

+				

 				if(g_tsc_print_log_debug)

 					tsc_print_log("user strategy start reserve \n")

 			}

 			else{

 				//tsc_print_log("user strategy stop reserve \n")

+				tsc_set_reg_bits(TSCTRL_AP,BIT_SHUTDOWN,BITS_FOR_APPIRAM,STRTEGY_STOP);						

 			}

 		}

 			

 		/*PS_ANYRESIDENT*/

 		if(tsc_read_reg(TSCTRL_PS_ANYRESIDENT)==0){

-			if(any_resident_flag){

+			if(g_ps_Strategy[STRATEGY_PS_ANYRESIDENT].flag){

 				tsctrl_callback_dispatch(PS_STRATEGY_ANYRESIDENT,false); /*È¥ÈÎÒâפÁô,Ò²¾ÍÊÇÕý³£×¤Áô*/

 				tsc_set_reg_bits(TSCTRL_PS,BIT_PS_ANYRESIDENT,BITS_FOR_PSIRAM,false);

 				tsctrl_print_temp();

 				sc_debug_info_record(MODULE_ID_AP_TSC, "AnyResident stop\n");

 				tsc_print_log("AnyResident  stop!\n");

-				any_resident_flag=0;

+				g_ps_Strategy[STRATEGY_PS_ANYRESIDENT].flag=0;

 			}

 		}else{		

-			if(!any_resident_flag){

+			if(!g_ps_Strategy[STRATEGY_PS_ANYRESIDENT].flag){

 				tsctrl_callback_dispatch(PS_STRATEGY_ANYRESIDENT,true);/*ÈÎÒâפÁô*/

 				tsc_set_reg_bits(TSCTRL_PS,BIT_PS_ANYRESIDENT,BITS_FOR_PSIRAM,true);

 				tsctrl_print_temp();

 				sc_debug_info_record(MODULE_ID_AP_TSC, "AnyResident start!\n");

 				tsc_print_log("AnyResident  start!\n");

-				any_resident_flag=1;

+				g_ps_Strategy[STRATEGY_PS_ANYRESIDENT].flag=1;

 			}

 		}

 		

@@ -651,33 +654,33 @@
 		if(TsNvData.Modemrate_En == 0xB2) {

 			//ЭÒéÕ»ËÙÂʲßÂÔ

 			if(tsc_read_reg(TSCTRL_PS_RATE)==0){

-				if(ps_rate_flag!=0){

+				if(g_ps_Strategy[STRATEGY_PS_RATE].flag!=0){

 					tsctrl_callback_dispatch(PS_STRATEGY_RATE,STRTEGY_STOP);//STOP		

 					tsc_set_reg_bits(TSCTRL_PS,BIT_PS_RATE,BITS_FOR_PSIRAM,STRTEGY_STOP);

 					tsctrl_print_temp();

 					sc_debug_info_record(MODULE_ID_AP_TSC, "ps modem rate limit  stop!\n");

 					tsc_print_log("ps modem rate limit  stop!\n");

-					ps_rate_flag=0;

+					g_ps_Strategy[STRATEGY_PS_RATE].flag=0;

 				}

 			}

 			else if(((tsc_read_reg(TSCTRL_PS_RATE)&0x1000)==0x1000)||((tsc_read_reg(TSCTRL_PS_RATE)&0x0100)==0x0100)||((tsc_read_reg(TSCTRL_PS_RATE)&0x0010)==0x0010)||((tsc_read_reg(TSCTRL_PS_RATE)&0x0001)==0x0001))

 			{		

-				if(ps_rate_flag!=1){

+				if(g_ps_Strategy[STRATEGY_PS_RATE].flag!=1){

 					tsctrl_callback_dispatch(PS_STRATEGY_RATE,STRTEGY_START);//START		

 					tsc_set_reg_bits(TSCTRL_PS,BIT_PS_RATE,BITS_FOR_PSIRAM,STRTEGY_START);

 					tsctrl_print_temp();

 					sc_debug_info_record(MODULE_ID_AP_TSC, "ps modem rate limit  start!\n");

 					tsc_print_log("ps modem rate limit  start!\n");

-					ps_rate_flag=1;

+					g_ps_Strategy[STRATEGY_PS_RATE].flag=1;

 				}

 			}else{	

-				if(ps_rate_flag!=2){

+				if(g_ps_Strategy[STRATEGY_PS_RATE].flag!=2){

 					tsctrl_callback_dispatch(PS_STRATEGY_RATE,STRTEGY_HOLD);//HOLD			

 					tsc_set_reg_bits(TSCTRL_PS,BIT_PS_RATE,BITS_FOR_PSIRAM,STRTEGY_HOLD);

 					tsctrl_print_temp();

 					sc_debug_info_record(MODULE_ID_AP_TSC, "ps modem rate limit  hold!\n");

 					tsc_print_log("ps modem rate limit  hold!\n");

-					ps_rate_flag=2;

+					g_ps_Strategy[STRATEGY_PS_RATE].flag=2;

 				}

 			}

 			

@@ -736,7 +739,7 @@
 			//tsc_print_log("CPU_FRE:zx_getspeed(0)=%d\n",zx_getspeed(0));

 

 			if(tsc_read_reg(TSCTRL_DFS)==0){

-				if(ps_freq_flag){

+				if(g_ps_Strategy[STRATEGY_PS_DFS].flag){

 					//tsc_print_log("CPU_FREQ0:zx_getspeed(0)=%d\n",zx_getspeed(0));

 //					if(zx_getspeed(0) != 624000 )

 //						zx29_set_frequency(1,0); //zDrvPow_SetArmPsCoreFreq(CLK624M);

@@ -746,10 +749,10 @@
 					tsctrl_print_temp();

 					sc_debug_info_record(MODULE_ID_AP_TSC, "ps freq 624M start\n" );

 					tsc_print_log("ps freq 624M start\n");

-					ps_freq_flag=0;

+					g_ps_Strategy[STRATEGY_PS_DFS].flag=0;

 				}	

 			}else{

-				if(!ps_freq_flag){

+				if(!g_ps_Strategy[STRATEGY_PS_DFS].flag){

 					//tsc_print_log("CPU_FREQ1:zx_getspeed(0)=%d\n",zx_getspeed(0));	

 					//zx29_set_frequency(0,1); //zDrvPow_SetArmPsCoreFreq(CLK312M);

 					cpufreq_powersave();

@@ -757,7 +760,7 @@
 					tsctrl_print_temp();

 					sc_debug_info_record(MODULE_ID_AP_TSC, "ps freq 312M start\n" );

 					tsc_print_log("ps freq 312M start\n");

-					ps_freq_flag=1;

+					g_ps_Strategy[STRATEGY_PS_DFS].flag=1;

 				}

 			}	

 			#endif

@@ -772,18 +775,27 @@
 	{

 		if(TsNvData.Modemrate_En == 0xB2){

 			 /*stop ps ËùÓвßÂÔ*/ 

-			if(ps_rate_flag!=0){

+			if(g_ps_Strategy[STRATEGY_PS_RATE].flag!=0){

 				tsctrl_callback_dispatch(PS_STRATEGY_RATE,STRTEGY_STOP);//STOP

 				tsc_set_reg_bits(TSCTRL_PS,BIT_PS_RATE,BITS_FOR_PSIRAM,STRTEGY_STOP);

-				ps_rate_flag=0;

+				g_ps_Strategy[STRATEGY_PS_RATE].flag=0;

 			}

 		}

 		

-		if(any_resident_flag){

+		if(g_ps_Strategy[STRATEGY_PS_ANYRESIDENT].flag){

 			tsctrl_callback_dispatch(PS_STRATEGY_ANYRESIDENT,false); /*È¥ÈÎÒâפÁô,Ò²¾ÍÊÇÕý³£×¤Áô*/

 			tsc_set_reg_bits(TSCTRL_PS,BIT_PS_ANYRESIDENT,BITS_FOR_PSIRAM,false);

-			any_resident_flag=0;

+			g_ps_Strategy[STRATEGY_PS_ANYRESIDENT].flag=0;

 		}

+		

+		if(TsNvData.Dfs_En == 0xB2) {

+			if(g_ps_Strategy[STRATEGY_PS_DFS].flag){

+				tsc_set_reg_bits(TSCTRL_PS,BIT_PS_FREQ,BITS_FOR_PSIRAM,false);

+				cpufreq_normal();

+				g_ps_Strategy[STRATEGY_PS_DFS].flag=0;

+			}		

+		}

+		

 		//stop WIFI ½µËÙ 

 		if(TsNvData.Wifi_RateLmite_En == 0xB2){

 			tsctrl_callback_dispatch(WIFI_STRATEGY,STRTEGY_STOP);//STOP		

@@ -798,6 +810,7 @@
 		//stop ÎïÀí²ãËùÓвßÂÔ

 		for(i=0;i<STRATEGY_PHY_NUM;i++){		

 			tsc_set_reg_bits(TSCTRL_PHY,(BIT_LIMIT_LTE_DOWNRATE1+i),BITS_FOR_PHYIRAM,STRTEGY_STOP);

+			g_phy_Strategy[i].flag=0;

 		} 

 

 		//sc_debug_info_record(MODULE_ID_AP_TSC, "close all strategy!\n");

@@ -947,7 +960,7 @@
  ********************************************************************************/

 u32 zDrvTsCtrl_DfsEn(void)

 {

-	if(ps_freq_flag)

+	if(g_ps_Strategy[STRATEGY_PS_DFS].flag)

 		return 1;

 	else

 		return 0;

diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.c
index 33deebc..5d3bbba 100755
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.c
@@ -25,6 +25,11 @@
 #include <linux/cp_types.h>

 #include "NvParam_drv.h"

 #include "pub_debug_info.h"

+#include <linux/miscdevice.h>	/* For handling misc devices */

+#include <linux/fs.h>		/* For file operations */

+#include <linux/uaccess.h>

+#include <linux/syscalls.h>/*For sys_open operation*/

+

 

 #ifdef RFC_DCXO_EN //jingti

 #define IRAM_TEMPCOMP_DAC (IRAM_BASE_ADDR_SLAVE_AFC+0x8)  //high16bit: the ADC value of temp	

@@ -70,6 +75,8 @@
 

 extern int ts_temp_value_table[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER];

 extern volatile u32 ts_adc_flag;

+extern T_TscP_Strategy g_ps_Strategy[STRATEGY_PS_NUM];

+extern T_TscP_Strategy g_phy_Strategy[STRATEGY_PHY_NUM];

 

 int  ts_temp_value_tableRfd[TS_ADC_TEMP_NUMBER][TS_ADC_TEMP_VOLTAGE_NUMBER]={

 {

@@ -256,6 +263,42 @@
  }

  

  zte_tsc_attr(tsc_value);

+

+  static ssize_t tsc_strategy_status_show(struct kobject *kobj, struct kobj_attribute *attr,

+			   char *buf)

+ {

+	 char *s = buf;

+	 unsigned int i;

+	 int ret, size = 0;

+	 

+	for(i=0; i<STRATEGY_PS_NUM;i++){

+		ret = sprintf(s, "%s", g_ps_Strategy[i].name);

+		size += ret;

+		s += ret;

+		ret = sprintf(s, "%d\n", g_ps_Strategy[i].flag);

+		size += ret;

+		s += ret;

+	}

+	for(i=0; i<STRATEGY_PHY_NUM;i++){

+		ret = sprintf(s, "%s", g_phy_Strategy[i].name);

+		size += ret;

+		s += ret;

+		ret = sprintf(s, "%d\n", g_phy_Strategy[i].flag);

+		size += ret;

+		s += ret;

+	}	

+	return size;

+}

+ 

+ static ssize_t tsc_strategy_status_store(struct kobject *kobj, struct kobj_attribute *attr,

+				const char *buf, size_t n)

+ {

+	 int error = 0;

+	 return error;

+ }

+ 

+ zte_tsc_attr(tsc_strategy_status);

+ 

  

 

   static ssize_t tsc_print_log_show(struct kobject *kobj, struct kobj_attribute *attr,

@@ -292,6 +335,7 @@
 	 &tsc_percent_attr.attr,

 	 &tsc_ptscCtrlEn_attr.attr,

 	 &tsc_print_log_attr.attr,

+	 &tsc_strategy_status_attr.attr,

 	 

 	 NULL,

  };

@@ -301,7 +345,93 @@
 	 .attrs = g,

  };

 

-#if 1

+ /********************************************************************************

+ * Function:

+ * Description: 

+ * Parameters: 

+ * Returns: 

+ * Others:

+ ********************************************************************************/

+

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

+{

+	return 0; 

+}

+

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

+{

+	return 0;

+}

+static long zx_tsc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

+{

+	int ret=0;

+	u8 thresh[THRESHOLD_NUM+1]={0};

+	

+	switch(cmd)

+	{

+		case ZX_TSC_SET_THRESHOLD:

+			ret= copy_from_user(thresh, (u8*)arg, sizeof(thresh));

+			if(ret)

+				printk("zx_tsc_ioctl copy_from_user ret=%d\n", ret);

+			

+			if(thresh[0] >= PROBE_MAX){

+				printk("set error probe num\n");

+				return -1;

+			}

+			memcpy((unsigned char *)(&TsNvData.Threshods[thresh[0]]), thresh+1, THRESHOLD_NUM*sizeof(u8));

+			memcpy((void*)TSCTRL_IRAM_NV, &TsNvData, sizeof(TsNvData));	

+			break;

+			

+		case ZX_TSC_GET_THRESHOLD:

+			ret= copy_from_user(thresh, (u8*)arg, sizeof(thresh));

+			if(ret)

+				printk("zx_tsc_ioctl copy_from_user ret1=%d\n", ret);

+			

+			if(thresh[0] >= PROBE_MAX){

+				printk("get error probe num\n");

+				return -1;

+			}

+						

+			ret= copy_to_user((u8*)arg+1, (unsigned char *)(&TsNvData.Threshods[thresh[0]]), THRESHOLD_NUM*sizeof(u8));

+			if(ret)

+				printk("zx_tsc_ioctl copy_to_user ret=%d\n", ret);			

+			break;

+			

+		case ZX_TSC_SET_DECTET_EN:

+			ret= copy_from_user(&TsNvData.DetectEn, (u8*)arg, sizeof(u8));

+			if(ret)

+				printk("zx_tsc_ioctl copy_from_user ret=%d\n", ret);

+			

+			memcpy((void*)TSCTRL_IRAM_NV, &TsNvData, sizeof(TsNvData));

+			tsc_set_detect_en(TsNvData.DetectEn);

+			break;

+			

+		case ZX_TSC_GET_DECTET_EN:			

+			ret= copy_to_user((u8*)arg, (unsigned char *)&TsNvData.DetectEn, sizeof(u8));

+			if(ret)

+				printk("zx_tsc_ioctl copy_to_user ret=%d\n", ret);			

+			break;

+			

+		default:

+			break;		

+	}

+

+	return ret;

+}

+

+ static const struct file_operations zx_tsc_fops = {

+	.owner		= THIS_MODULE,

+	.unlocked_ioctl	= zx_tsc_ioctl,

+	.open		= zx_tsc_open,

+	.release	= zx_tsc_close,

+};

+

+static struct miscdevice zx_tsc_miscdev = {

+	.minor		= MISC_DYNAMIC_MINOR,

+	.name		= "zx_tsc",

+	.fops		= &zx_tsc_fops,

+};

+

 

 /********************************************************************************

  * Function:

@@ -626,6 +756,8 @@
 		TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_3,TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_4,TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_5,\

 		TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_6,TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_7,\

 		TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_8,TsNvData.Threshods[PROBE_ADCRF].THROSHOLD_9);

+

+	memcpy((void*)TSCTRL_IRAM_NV, &TsNvData, sizeof(TsNvData));

 	

     if(TsNvData.DetectEn != 0xB2){

 		zDrvTsc_SetTscEn(0);//need		

@@ -644,6 +776,12 @@
 		}

  //   }

 

+ 	ret = misc_register(&zx_tsc_miscdev);

+	if (ret != 0) {

+		printk(KERN_ERR"tsc cannot register miscdev on(err=%d)\n", ret);

+		return ret;

+	}

+

 	printk("zx_tsc_init  end.\n");

  

 	 return 0;

@@ -715,4 +853,3 @@
 }

 EXPORT_SYMBOL(zDrvTsc_GetTscEn);

 

-#endif

diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.h b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.h
index 6c78c59..cad1254 100755
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.h
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/tsc/zx-tsc.h
@@ -12,6 +12,7 @@
 /****************************************************************************
 * 	                                        Include files
 ****************************************************************************/
+#include <linux/ioctl.h>
 
 
 /****************************************************************************
@@ -68,16 +69,43 @@
 	STRTEGY_MAX,
  } Ts_TsCtrlStrategy; 
 
+typedef struct _T_TscPhy_Strategy
+{
+	char name[32];
+	volatile u32 flag;
+}T_TscP_Strategy;
+
+
 /****************************************************************************
 * 	                                           macro define
 ****************************************************************************/
-//#define tsc_read_reg(addr)                       (*(volatile unsigned long*)(addr))
-//#define	tsc_write_reg(addr, val)                 ((*(volatile unsigned long*)(addr)) = val)
+#define ZX_TSC_DEV    "/dev/zx_tsc"
+
+#define ZX_TSC_IOC_MAGIC     'W'
+/*ioctl cmd usd by device*/
+#define ZX_TSC_SET_THRESHOLD         	_IOW(ZX_TSC_IOC_MAGIC, 1, char *)
+#define ZX_TSC_GET_THRESHOLD          _IOW(ZX_TSC_IOC_MAGIC, 2, char *)
+
+#define ZX_TSC_SET_DECTET_EN         	_IOW(ZX_TSC_IOC_MAGIC, 3, char *)
+#define ZX_TSC_GET_DECTET_EN          _IOW(ZX_TSC_IOC_MAGIC, 4, char *)
+
+
+
+
+
 
 #define tsc_read_reg 							zx_read_reg
 #define tsc_write_reg							zx_write_reg
 /**/
+
+#define  STRATEGY_PS_ANYRESIDENT  			0
+#define  STRATEGY_PS_RATE  					1
+#define  STRATEGY_PS_DFS  					2
+#define  STRATEGY_PS_NUM  					3
+
+#define  THRESHOLD_NUM  			11
 #define  STRATEGY_PHY_NUM  					8
+
 #define  BITS_FOR_PHYIRAM				    1
 /*TSCTRL_PHY iram ÿһbit±íʾPHYµÄÒ»¸ö²ßÂÔÊÇ·ñÖ´ÐÐ*/
 #define  BIT_LIMIT_LTE_DOWNRATE1  			0
@@ -95,7 +123,7 @@
 #define  BIT_PS_RATE  						0
 #define  BIT_PS_ANYRESIDENT  				4
 #define  BIT_PS_FREQ  						8
-#define  BIT_SHUTDOWN  						12
+
 /**/
 //#define  STRATEGY_PERIP_NUM  	2
 #define  BITS_FOR_PEPIPIRAM				    4
@@ -104,11 +132,12 @@
 #define  BIT_CHHRGER	 					4
 #define  BIT_APRATE	 						8
 
+
 /**/
 //#define  STRATEGY_AP_NUM  	2
 #define  BITS_FOR_APPIRAM				    4
 /*TSCTRL_AP iram ÿËÄbit±íʾAPµÄÒ»¸ö²ßÂÔÊÇ·ñÖ´ÐÐ*/
-		
+#define  BIT_SHUTDOWN	 				    0		
 
 /*TSCTRL_PHY iramInfo:ÿһbit±íʾPHYµÄÒ»¸ö²ßÂÔÊÇ·ñÖ´ÐÐ
 bit0:limit_ltedownrate1	  1:ÏÞÖÆlteÏÂÐÐËÙÂÊ1£»0:Í£Ö¹ÏÞÖÆlteÏÂÐÐËÙÂÊ1
@@ -166,7 +195,10 @@
 #define  TSCTRL_TEMP_PERCENT				(IRAM_TSC_BASE+0x11c)  /*APrate ,g_tempPercent*/
 
 
-#define PS_CORE_SEL_REG             (ZX_MATRIX_CRM_BASE+0x20)/*ps core clk sel*/
+#define TSCTRL_IRAM_NV		(IRAM_TSC_BASE+0x200)  /*TSC NV: size-0x140*/
+
+
+#define PS_CORE_SEL_REG      (ZX_MATRIX_CRM_BASE+0x20)/*ps core clk sel*/
 
 /**/
 #define  PROBE_NUM  	PROBE_MAX
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.c b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.c
index 877a5e4..2d36263 100755
--- a/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.c
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.c
@@ -705,16 +705,16 @@
 	pbrpc_ctx->chn.core_id = CAP_ID;

 	pbrpc_ctx->chn.channel_id = ICP_CHN_BINDER_RPC;

 	pbrpc_ctx->chn.channel_size = ICP_CHN_BINDER_RPC_SIZE;

-	

-	if(brpc_chn_create(pbrpc_ctx)) {

-		brpc_err("brpc_chn_create fail.");

-		return -1;

-	}

 

 	if(brpc_agent_create(pbrpc_ctx)) {

 		brpc_err("brpc_agent_create fail.");

 		return -1;

 	}

+	

+	if(brpc_chn_create(pbrpc_ctx)) {

+		brpc_err("brpc_chn_create fail.");

+		return -1;

+	}	

 

 	if(NULL != cb) {

 		memset(cb, 0, sizeof(struct binder_rpc_operations_struct));

diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/voice_buffer_dev.c b/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/voice_buffer_dev.c
index be78b0a..843b1de 100755
--- a/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/voice_buffer_dev.c
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/voice_buffer_dev.c
@@ -15,6 +15,7 @@
 #include <linux/wakelock.h>
 #include <linux/wakelock.h>
 #include <asm/atomic.h>
+#include <linux/volte_drv.h>
 
 #define MAX_BUF_SIZE	     640
 #define MAX_BUF_NUM        3
@@ -41,6 +42,8 @@
 struct voice_buffer_dev *voicebuffdev = NULL;
 static const char voice_buffer_shortname[] = "voice_buffer_dev";
 
+extern void zDrvVp_Status(unsigned int *sample_rate, unsigned int *voice_status);
+
 static int voice_buffer_open(struct inode * ip, struct file * fp);
 static int voice_buffer_release(struct inode *ip, struct file *fp);
 static ssize_t voice_buffer_read(struct file *fp, char __user *buf, size_t count, loff_t *pos);
@@ -179,7 +182,7 @@
 	if (true == isEmpty) {
 		if (voicebuff_ratelimit())
 			pr_info("voicebuffer_ulqueue_read ulqueue is empty\n");
-		memset(buf,0, size);// add for repeat play old data
+		memset(buf,0, size);// avoid to repeat play old data
 		mutex_unlock(&queue->quelock);
 		return -ENODATA;
 	} else {
@@ -299,7 +302,30 @@
 
 static long voice_buffer_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 {
-	return 0;
+	int ret = 0;
+	void __user *argp = (void __user *) arg;
+
+	switch (cmd) {
+    	case VOICE_IOCTL_GET_FS: {
+    		int fs = 0;
+
+    		CPPS_FUNC(cpps_callbacks, zDrvVp_Status)(&fs, NULL);
+    		pr_info("voice_buffer_ioctl  zDrvVp_Status fs=%d!\n", fs);
+
+    		if (copy_to_user(argp, &fs, sizeof(fs))) {
+    			pr_err("voice_buffer_ioctl  zDrvVp_Status copy_to_user err!\n");
+    			return -EFAULT;
+    		}
+
+    		break;
+    	}
+        default: {
+    		pr_info("voice_buffer_ioctl  invalid cmd!\n");
+    		break;
+    	}
+	}
+
+    return ret;
 }
 
 static int voice_buffer_fasync(int fd, struct file *filp, int on)
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
index 1b37e4b..8426431 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
@@ -37,7 +37,7 @@
 
  struct adb_dev *g_adb_agent;
 ssize_t adb_server_write2usb( const char *buf,size_t count);
-extern void usb_rpmsg_notify_ap(usb_rpmsg_cmd *notify, int has_param);
+extern int usb_rpmsg_notify_ap(usb_rpmsg_cmd *notify, int has_param);
 extern int usb_get_adb_agent(void);
 
 void adb_recv_from_ap(void *buf, unsigned int len)
@@ -70,6 +70,7 @@
 #endif
 	
 	adb_server_write2usb((char *)buf, len);
+	g_adb_agent->set_test = 0;
 } 
 #if 0
 static ssize_t adb_server_read(struct file *fp, char __user *buf,
@@ -231,7 +232,11 @@
 		}
 		total_cnt -= transfer_cnt;
 		tmp += transfer_cnt;
-		
+		if(g_adb_agent->agt_error){
+			printk("adb_rpmsg_write2ap, agt_error break, trans len left:%d\n", total_cnt);
+			ret = -1;
+			break;
+		}
 	}
 	atomic_set(&g_adb_agent->write_busy, 0);
 	
@@ -262,8 +267,16 @@
 #endif
 	}
 #endif
-	if (adb_lock(&g_adb_agent->write_excl))
+	if (adb_lock(&g_adb_agent->write_excl)){
+		printk("adb_write write_excl lock fail\n");
 		return -EBUSY;
+	}
+	
+	if(g_adb_agent->agent_start == 0 || g_adb_agent->agent_state == 0){
+		printk("adb_write dev->agt_error\n");
+		adb_unlock(&g_adb_agent->write_excl);
+		return -EIO;		
+	}
 	
 	while (count > 0) {
 		if (g_adb_agent->agt_error) {
@@ -275,16 +288,18 @@
 		/* get an idle tx request to use */
 		req = NULL;
 	USBSTACK_DBG("adb_server_write2usb waiting write_wq, agt_error:%d, txempty:%d\n",g_adb_agent->agt_error, list_empty(&g_adb_agent->tx_idle));
+		atomic_set(&g_adb_agent->agt_write_flag, 1);
 		ret = wait_event_interruptible(g_adb_agent->write_wq,
 			(req = adb_req_get(g_adb_agent, &g_adb_agent->tx_idle)) || g_adb_agent->agt_error);
 
 			USBSTACK_DBG("adb_server_write2usb req:0x%x\n", req);
+		atomic_set(&g_adb_agent->agt_write_flag, 0);	
 		if (ret < 0) {
 			r = ret;
 			break;
 		}
-		if(g_adb_agent->agt_error){
-			printk("get agt_error err, break write\n");
+		if(g_adb_agent->agt_error || (g_adb_agent->adb_ready == 0) || (g_adb_agent->agent_state == 0)){
+			printk("write2usb get agt_error err, break write\n");
 			r = -EIO;
 			break;			
 		}
@@ -296,8 +311,13 @@
 				xfer = count;
 			memcpy(req->buf, buf, xfer);
 			adb_rpmsg_write2ap(NULL, 0);
-			
+			if(g_adb_agent->agt_error){
+				printk("after write2ap get agt_error err, break write\n");
+				r = -EIO;
+				break;			
+			}			
 			req->length = xfer;
+			//printk("adb_server_write2usb, req:%x, datalen:%d\n", req, req->length);
 			ret = usb_ep_queue(g_adb_agent->ep_in, req, GFP_ATOMIC);
 			if (ret < 0) {
 				printk("adb_write: xfer agt_error %d\n", ret);
@@ -369,10 +389,13 @@
 	g_adb_agent->agent_start = 0;
 	g_adb_agent->agent_state = 0;
 	g_adb_agent->agt_error = 1;
-	
-	if(atomic_read(&g_adb_agent->write_busy)){
+	printk("adb_agent_close,agt_write_flag:%d, write_busy:%d\n", atomic_read(&g_adb_agent->agt_write_flag), atomic_read(&g_adb_agent->write_busy));
+	if(atomic_read(&g_adb_agent->write_busy) || atomic_read(&g_adb_agent->agt_write_flag)){
+		printk("adb_agent_close, write_busy is 1\n");
 		atomic_set(&g_adb_agent->write_busy, 0);
 		wake_up(&g_adb_agent->agt_write_wq);
+		wake_up(&g_adb_agent->write_wq);
+		g_adb_agent->set_test |= 0x4;
 	}
 #if 0	
 	g_adb_agent->rx_done = 1;
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/android.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/android.c
index a5fa3db..c6601b5 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/android.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/android.c
@@ -83,6 +83,9 @@
 
 #define pr_err		USB_DEBUG
 
+#ifdef _USE_VEHICLE_DC
+void usb_check_plugin_msg_sent(void);
+#endif
 
 static const char longname[] = "Gadget Android";
 
@@ -2532,6 +2535,9 @@
 		}
 		android_enable(dev);
 		dev->enabled = true;
+#ifdef _USE_VEHICLE_DC		
+		usb_check_plugin_msg_sent();
+#endif
 		usb_record_dbginfo(USB_DEV_ENABLE, 0, 0);
 	} else if (!enabled && dev->enabled) {
 		USB_DEBUG("USB DISENABLE");
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
index 3a506fc..a2ae7c9 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
@@ -71,6 +71,8 @@
 	atomic_t write_busy;
 	atomic_t agt_read_flag;
 	atomic_t adb_read_flag;
+	atomic_t agt_write_flag;
+	int set_test;
 	int agt_error;
 	char   *rx2agt_buf;
 	struct task_struct	*rpmsg_thread;	
@@ -619,7 +621,7 @@
 		}
 
 	}
-	if(atomic_read(&_adb_dev->read_excl))
+	if(atomic_read(&_adb_dev->read_excl) || atomic_read(&_adb_dev->open_excl))
 		adb_unlock(&_adb_dev->open_excl);
 	
 #ifdef _USE_VEHICLE_DC	
@@ -700,7 +702,14 @@
 	dev->error = 1;
 
 	wake_up(&dev->read_wq);
-
+#ifdef _USE_VEHICLE_DC
+	if(atomic_read(&dev->agt_write_flag)){
+		printk("adb_function_unbind, agt_write_flag set, wakeup write_wq\n");
+		atomic_set(&dev->write_busy, 0);
+		wake_up(&dev->write_wq);
+		dev->set_test |= 2;
+	}
+#endif	
 	adb_request_free(dev->rx_req, dev->ep_out);
 	while ((req = adb_req_get(dev, &dev->tx_idle)))
 		adb_request_free(req, dev->ep_in);
@@ -790,10 +799,22 @@
 
 
 #ifdef _USE_VEHICLE_DC
-	adb_server_plug_notify(USB_RPMSG_NOTIFY_ADB_OFFLINE);
+	printk("adb_function_disable, notify adb offline\n");
+
 	dev->agent_start = 0;
 	dev->agent_state = 0;
-	dev->agt_error = 0;	
+	adb_server_plug_notify(USB_RPMSG_NOTIFY_ADB_OFFLINE);
+	if(atomic_read(&dev->write_busy) == 1){
+	printk("adb_function_disable, clear agt_write_wq\n");
+		atomic_set(&dev->write_busy, 0);
+			printk("adb_function_disable, clear write_wq\n");
+			dev->agt_error = 1;
+			wake_up(&dev->write_wq);
+			
+		wake_up(&dev->agt_write_wq);
+		dev->set_test |= 1;
+	}
+	dev->agt_error = 0;		
 #endif	
 	
 	schedule_work(&dev->offline_inform);
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
index 15de73e..c042a78 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
@@ -35,7 +35,10 @@
 	int switch_mode = 0;

 	int simulate_plug = 0;

 	struct work_struct switch_usbmode;

-extern void usb_plug_notify_ap(e_usb_rpmsg_cmd_type plug_type);

+extern int usb_plug_notify_ap(e_usb_rpmsg_cmd_type plug_type);

+	struct delayed_work plug_notify_dwork;

+	int usb_rpmsg_ser_inited = 0;

+	int usb_plugin_msg_sent = 0;

 

 #endif

 

@@ -378,6 +381,31 @@
 	

 	usb_notify_up(switch_mode, NULL);

 }

+int usb_plug_notify_cap_work(struct work_struct *data)

+{	

+	int ret = 0;

+	printk("----usb_plug_notify_cap_work start\n");

+	ret = usb_plug_notify_ap(((usb_plug == 1) ? USB_RPMSG_USB_PLUG_IN : USB_RPMSG_USB_PLUG_OUT));

+	if(ret){

+		printk("usb_plug_notify_cap_work, notify plug:%d, fail, ret:%d\n", usb_plug, ret);

+	}

+}

+void usb_check_plugin_msg_sent(void)

+{

+	if(usb_gpio_detect_enable == 0){

+		printk("usb_check_plugin_msg_sent, only for usb plug,\n");

+		return;

+	}

+	if(usb_plugin_msg_sent){

+		printk("usb_check_plugin_msg_sent, already sent do nothing\n");

+		return;

+	}

+	usb_plugin_msg_sent = 1;

+	printk("usb_check_plugin_msg_sent, do send\n");

+	schedule_delayed_work(&plug_notify_dwork, 0);	

+

+}

+EXPORT_SYMBOL_GPL(usb_check_plugin_msg_sent);

 #endif

 int usb_do_reject_cdrom(void)

 {

@@ -618,12 +646,13 @@
 #ifdef _USE_VEHICLE_DC

 		cur_usbmode = get_usb_enum_mode();

 		adb_agent_state =value;

-		if(cur_usbmode == 0){

+		//if(cur_usbmode == 0){

 			adb_enable_rpmsg_agent(adb_agent_state);

 			

-		}else{

-			printk("---none adb, switch is forbidern\n");

-		}

+		//}else{

+			//printk("---none adb, switch is forbidern\n");

+			printk("---cur_usbmode:%d, adb_agent_state:%d\n",  cur_usbmode, adb_agent_state);

+		//}

 #endif

 	  }	

 	

@@ -788,6 +817,8 @@
 	

    INIT_WORK(&switch_usbmode, usb_switch_mode_work);  

 		

+	INIT_DELAYED_WORK(&plug_notify_dwork, usb_plug_notify_cap_work);

+	usb_rpmsg_ser_inited = 1;		

 #endif

    return ret;

 }

@@ -824,8 +855,15 @@
 			strcpy(buf,"USBEVENT=usb_device_in");

 			action = KOBJ_ADD;

 			usb_plug = 1;

-#ifdef _USE_VEHICLE_DC			

-			usb_plug_notify_ap(USB_RPMSG_USB_PLUG_IN);

+#ifdef _USE_VEHICLE_DC

+			if(usb_rpmsg_ser_inited){

+				if(usb_plug_notify_ap(USB_RPMSG_USB_PLUG_IN)){

+					//delay 1 second

+					//schedule_delayed_work(&plug_notify_dwork, 200);	

+					printk("plugin msg send fail\n");

+				}

+				

+			}

 #endif

 			usb_record_dbginfo(USB_DEV_PLUGIN, 0, 0);

 			break;

@@ -837,7 +875,10 @@
 			action = KOBJ_REMOVE;

 			usb_plug = 0;

 #ifdef _USE_VEHICLE_DC

-			usb_plug_notify_ap(USB_RPMSG_USB_PLUG_OUT);

+			if(usb_plug_notify_ap(USB_RPMSG_USB_PLUG_OUT)){

+				//delay 1 second

+				//schedule_delayed_work(&plug_notify_dwork, 200);

+			}

 #endif

 			usb_record_dbginfo(USB_DEV_PLUGOUT, 0, 0);

 			break;

diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_rpmsg_server.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_rpmsg_server.c
index 702cbbf..c7daeda 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_rpmsg_server.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_rpmsg_server.c
@@ -72,7 +72,7 @@
 int usb_rpmsg2ap(void *buf, unsigned int len);
 
 
-void usb_rpmsg_notify_ap(usb_rpmsg_cmd *notify, int has_param)
+int usb_rpmsg_notify_ap(usb_rpmsg_cmd *notify, int has_param)
 {
 	usb_rpmsg_cmd *t_data = NULL;
 	
@@ -83,17 +83,17 @@
 		memcpy(t_data->param, notify->param, strlen(notify->param));
 	}
 	printk("---usb_rpmsg_notify_ap, datalen:%d\n", strlen(usb_resp));
-	usb_rpmsg2ap(usb_resp, strlen(usb_resp));
+	return usb_rpmsg2ap(usb_resp, strlen(usb_resp));
 }
 EXPORT_SYMBOL_GPL(usb_rpmsg_notify_ap);
 
-void usb_plug_notify_ap(e_usb_rpmsg_cmd_type plug_type)
+int usb_plug_notify_ap(e_usb_rpmsg_cmd_type plug_type)
 {
 	usb_rpmsg_cmd notify; 
 	memset(&notify, 0, sizeof(notify));
 	notify.cmd = plug_type;
 	printk("----usb_plug_notify_ap, type:%d\n", plug_type);
-	usb_rpmsg_notify_ap(&notify, 0);
+	return usb_rpmsg_notify_ap(&notify, 0);
 }
 EXPORT_SYMBOL_GPL(usb_plug_notify_ap);
 
@@ -270,6 +270,7 @@
 		}
 			
 		
+		atomic_set(&rpmsg_flag, 0);
 		if(kthread_should_stop())
 		{
 			printk("unbind thread stop");
@@ -278,7 +279,6 @@
 		
 		//printk("usb_rpmsg_thread: now usb_dispatch_cmd\n");
 
-		atomic_set(&rpmsg_flag, 0);
 		t_cmd = (usb_rpmsg_cmd *)usb_msg;
 		//android_set_rpmsg_resp(t_cmd->cmd, usb_resp);
 		usb_dispatch_cmd(usb_msg, 4+ strlen(t_cmd->param));
diff --git a/ap/os/linux/linux-3.4.x/fs/exec.c b/ap/os/linux/linux-3.4.x/fs/exec.c
index cde8181..7200df0 100755
--- a/ap/os/linux/linux-3.4.x/fs/exec.c
+++ b/ap/os/linux/linux-3.4.x/fs/exec.c
@@ -2327,7 +2327,7 @@
 	 * user ramdump entry
 	 */
 #ifdef CONFIG_RAMDUMP
-	if(sysctl_ramdump_on_user)
+	if(sysctl_ramdump_on_user && (signr != SIGQUIT))
 		panic("User ramdump enabled, user panic\n");//ramdump_entry();
 	else
 		printk("User ramdump disabled, current process is: %s, pid is %i!\n", current->comm, current->pid);
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 c233e66..698a636 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
@@ -757,6 +757,8 @@
     int (*zDrvVp_AudioDataOpen)(unsigned int, unsigned int);
     int (*zDrvVp_AudioDataWrite)(const void *, unsigned int);
     int (*zDrvVp_AudioDataClose)(void);
+
+    void (*zDrvVp_Status)(unsigned int *, unsigned int *);
     
 	unsigned char (*zDrvEdcp_IsBusy)(int);
 };
diff --git a/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h b/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h
index 3f3ec4e..dced20d 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h
@@ -45,7 +45,8 @@
 extern spinlock_t sock_socket_table_lock;

 extern spinlock_t sock_release_table_lock;

 extern spinlock_t sock_release_lock;

-extern spinlock_t  sock_release_peer_lock;

+extern spinlock_t sock_release_peer_lock;

+extern spinlock_t sock_socketaddr_table_lock;

 typedef enum _soc_msg_type

 {

 	MSG_TYPE_FIND = 0,

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 27e6d17..114b561 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
@@ -96,6 +96,8 @@
 #define VOICE_IOCTL_GET_PATH	_IOR('v', 19, int) 
 #endif
 
+#define VOICE_IOCTL_GET_FS	_IOR('v', 20, int)
+
 #ifdef __KERNEL__
 #define  print_audio(fmt, ...)  \
 		printk(fmt, ##__VA_ARGS__)
diff --git a/ap/os/linux/linux-3.4.x/init/do_mounts.c b/ap/os/linux/linux-3.4.x/init/do_mounts.c
index 580705c..1e5b080 100755
--- a/ap/os/linux/linux-3.4.x/init/do_mounts.c
+++ b/ap/os/linux/linux-3.4.x/init/do_mounts.c
@@ -389,18 +389,12 @@
 		       "explicit textual name for \"root=\" boot option.\n");
 #endif
 #ifdef CONFIG_FLAGS_UTILS
-	extern int flags_get(T_FLAGS_INFO *p_flags_info);
-	extern int flags_set(T_FLAGS_INFO *p_flags_info);
-	T_FLAGS_INFO flags_info;
-	int ret;
-	if (ret = flags_get(&flags_info) < 0)
-		panic("VFS: Unable get flags");
-	flags_info.boot_fota_flag.boot_to = (flags_info.boot_fota_flag.boot_to == DUAL_SYSTEM) ?
-		DUAL_SYSTEM2 : DUAL_SYSTEM;
-	if (ret = flags_set(&flags_info) < 0)
-		panic("VFS: Unable set flags");
+	extern int flags_sys_switch(void);
+	printk(KERN_EMERG "VFS: Unable to mount root fs on %s", b);
+	if (flags_sys_switch() < 0)
+		panic("VFS: flags_sys_switch fail");
 	else
-		kernel_restart("VFS: Switch to others system, please reset machine");
+		kernel_restart("VFS: Switch to another system, please reset machine");
 #endif
 		panic("VFS: Unable to mount root fs on %s", b);
 	}
diff --git a/ap/os/linux/linux-3.4.x/init/main.c b/ap/os/linux/linux-3.4.x/init/main.c
old mode 100644
new mode 100755
index 482385f..8570e3a
--- a/ap/os/linux/linux-3.4.x/init/main.c
+++ b/ap/os/linux/linux-3.4.x/init/main.c
@@ -81,6 +81,11 @@
 #include <asm/smp.h>
 #endif
 
+#ifdef CONFIG_FLAGS_UTILS
+#include <linux/reboot.h>
+#include "pub_flags.h"
+#endif
+
 static int kernel_init(void *);
 
 extern void init_IRQ(void);
@@ -867,6 +872,17 @@
 	run_init_process("/bin/init");
 	run_init_process("/bin/sh");
 #endif
+#ifdef CONFIG_FLAGS_UTILS
+{
+	extern int flags_sys_switch(void);
+	printk(KERN_EMERG "No init found.  Try passing init= option to kernel. "
+	      "See Linux Documentation/init.txt for guidance.");
+	if (flags_sys_switch() < 0)
+		panic("init: flags_sys_switch fail");
+	else
+		kernel_restart("init: Switch to another system, please reset machine");
+}
+#endif
 	panic("No init found.  Try passing init= option to kernel. "
 	      "See Linux Documentation/init.txt for guidance.");
 }
diff --git a/ap/os/linux/linux-3.4.x/kernel/exit.c b/ap/os/linux/linux-3.4.x/kernel/exit.c
old mode 100644
new mode 100755
index 320ab35..c2fbc09
--- a/ap/os/linux/linux-3.4.x/kernel/exit.c
+++ b/ap/os/linux/linux-3.4.x/kernel/exit.c
@@ -59,6 +59,11 @@
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 
+#ifdef CONFIG_FLAGS_UTILS
+#include <linux/reboot.h>
+#include "pub_flags.h"
+#endif
+
 static void exit_mm(struct task_struct * tsk);
 
 static void __unhash_process(struct task_struct *p, bool group_dead)
@@ -714,6 +719,16 @@
 	if (unlikely(pid_ns->child_reaper == father)) {
 		write_unlock_irq(&tasklist_lock);
 		if (unlikely(pid_ns == &init_pid_ns)) {
+#ifdef CONFIG_FLAGS_UTILS
+			extern int flags_sys_switch(void);
+			printk(KERN_EMERG "Attempted to kill init! exitcode=0x%08x\n",
+				father->signal->group_exit_code ?:
+					father->exit_code);
+			if (flags_sys_switch() < 0)
+				panic("init: flags_sys_switch fail");
+			else
+				kernel_restart("init: Switch to another system, please reset machine");
+#endif
 			panic("Attempted to kill init! exitcode=0x%08x\n",
 				father->signal->group_exit_code ?:
 					father->exit_code);
diff --git a/ap/os/linux/linux-3.4.x/lib/flags_utils/flags_utils.c b/ap/os/linux/linux-3.4.x/lib/flags_utils/flags_utils.c
index 9fbbaa0..7dde200 100755
--- a/ap/os/linux/linux-3.4.x/lib/flags_utils/flags_utils.c
+++ b/ap/os/linux/linux-3.4.x/lib/flags_utils/flags_utils.c
@@ -508,3 +508,61 @@
 }

 EXPORT_SYMBOL(flags_set);

 

+int flags_sys_switch(void)

+{

+	T_FLAGS_INFO flags_info = {0};

+	int ret = -1;

+

+	ret = flags_get(&flags_info);

+	if (ret < 0)

+	{

+		flags_err("flags switch flags_get fail\n");

+		return ret;

+	}

+

+	if (flags_info.boot_fota_flag.boot_to == DUAL_SYSTEM)

+	{

+		flags_info.boot_fota_flag.boot_to = DUAL_SYSTEM2;  //A->B

+		flags_info.boot_fota_flag.system.status = DUALSYSTEM_STATUS_UNBOOTABLE;

+		//flags_info("flags switch system A to system B\n");

+	}

+	else

+	{

+		flags_info.boot_fota_flag.boot_to = DUAL_SYSTEM;   //B->A

+		flags_info.boot_fota_flag.system2.status = DUALSYSTEM_STATUS_UNBOOTABLE;

+		//flags_info("flags switch system B to system A\n");

+	}

+	flags_info.boot_fota_flag.fota_status = 1;   //nvserver update flag

+	ret = flags_set(&flags_info);

+	if (ret < 0)

+	{

+		flags_err("flags switch flags_set fail\n");

+		return ret;

+	}

+	

+	return ret;

+}

+EXPORT_SYMBOL(flags_sys_switch);

+

+int flags_set_nvroflag(unsigned int flag)

+{

+	T_FLAGS_INFO t_flag = {0};

+

+	if (flags_get(&t_flag) != 0)

+		return -1;

+	if (t_flag.nvro_flag == flag)

+		return 0;

+	if ((flag == NVRO_RESTORING) || (flag == NVRO_BACKING_UP))

+	{

+		if (t_flag.nvro_flag != NVRO_BACKED_UP)

+		{

+			flags_err("[error]flags nvro only NVRO_BACKED_UP switch to NVRO_RESTORING/NVRO_BACKING_UP\n");

+			return -1;

+		}

+	}

+	t_flag.nvro_flag = flag;

+

+	return flags_set(&t_flag);

+}

+EXPORT_SYMBOL(flags_set_nvroflag);

+

diff --git a/ap/os/linux/linux-3.4.x/log b/ap/os/linux/linux-3.4.x/log
deleted file mode 100644
index c4015ec..0000000
--- a/ap/os/linux/linux-3.4.x/log
+++ /dev/null
@@ -1 +0,0 @@
-bitbake:未找到命令
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 1474611..637d373 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
@@ -300,7 +300,11 @@
         //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))
diff --git a/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c b/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c
index a42bfc2..8b225b6 100755
--- a/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c
+++ b/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c
@@ -80,6 +80,9 @@
 DEFINE_SPINLOCK(sock_release_peer_lock);

 EXPORT_SYMBOL_GPL(sock_release_peer_lock);

 

+DEFINE_SPINLOCK(sock_socketaddr_table_lock);

+EXPORT_SYMBOL_GPL(sock_socketaddr_table_lock);

+

 static struct dentry *ipcsocket_debugfs_dir_entry_root;

 static struct dentry *ipcsocket_debugfs_dir_entry_proc;

 

@@ -622,15 +625,15 @@
 {

 	struct sock_sunaddr_info *p;

 	struct hlist_node *pos,*n;

-	

+	spin_lock(&sock_socketaddr_table_lock);

 	hlist_for_each_entry_safe(p, pos, n, &g_sunaddr_info, hlist_node) {

 		if((p->sockaddr.sun_family == psockaddr_un->sun_family) \

 			&&(0 == memcmp(p->sockaddr.sun_path, psockaddr_un->sun_path, UNIX_PATH_MAX))){			

-						

+			spin_unlock(&sock_socketaddr_table_lock);			

 			return true;

 		}

 	}

-	

+	spin_unlock(&sock_socketaddr_table_lock);

 	return false;

 }

 

@@ -653,7 +656,9 @@
 	memcpy(&psock_sunaddr_info->sockaddr, psockaddr_un, sizeof(struct sockaddr_un));	

 		

 	INIT_HLIST_NODE(&psock_sunaddr_info->hlist_node);

-	hlist_add_head(&psock_sunaddr_info->hlist_node, &g_sunaddr_info);	

+	spin_lock(&sock_socketaddr_table_lock);

+	hlist_add_head(&psock_sunaddr_info->hlist_node, &g_sunaddr_info);

+	spin_unlock(&sock_socketaddr_table_lock);

 }

 

 static int sock_soc_del_ipc_sunaddr(struct sockaddr_un *psockaddr_un)

@@ -661,6 +666,7 @@
 	struct sock_sunaddr_info *p;

 	struct hlist_node *pos,*n;

 	int ret;

+	spin_lock(&sock_socketaddr_table_lock);

 	hlist_for_each_entry_safe(p, pos, n, &g_sunaddr_info, hlist_node) {		

 		if(psockaddr_un->sun_path[0]){

 			ret = strncmp(p->sockaddr.sun_path, psockaddr_un->sun_path, strlen(psockaddr_un->sun_path));

@@ -672,10 +678,12 @@
 			hlist_del(&p->hlist_node);			

 			kfree(p);

 			sk_soc_info("sun_path=%s, del sucess.", psockaddr_un->sun_path);

+			spin_unlock(&sock_socketaddr_table_lock);

 			return 0;

 		}

 	}

 	sk_soc_info("sun_path=%s, del failed", psockaddr_un->sun_path);

+	spin_unlock(&sock_socketaddr_table_lock);

 	return -1;

 }

 

diff --git a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
index c2d1e93..e63e597 100755
--- a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
+++ b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
@@ -478,7 +478,8 @@
 	struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
 	struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
 
-	if (re) {
+	//BDSA-2023-1941
+	if (re && x->replay_esn && x->preplay_esn) {
 		struct xfrm_replay_state_esn *replay_esn;
 		replay_esn = nla_data(re);
 		memcpy(x->replay_esn, replay_esn,