void mtlte_df_UL_swq_drop_skb(MTLTE_DF_TX_QUEUE_TYPE qno)
{

	struct sk_buff *skb ;
	KAL_DBGPRINT(KAL, DBG_INFO,("====> %s, qno: %d\n",KAL_FUNC_NAME, qno)) ;	

    while(mtlte_df_UL_pkt_in_swq(qno))
    {
        skb = skb_dequeue(&(lte_df_core.ul_xmit_wait_queue[qno])) ; 
	    if (skb){				
		    dev_kfree_skb(skb); 
	    }
    }

	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;

}
Example #2
0
static int mtlte_sys_sdio_sleep_thread(unsigned int data) 
{	
	KAL_DBGPRINT(KAL, DBG_LOUD,("[INT] mtlte_sys_sdio_kick_thread <==========>\r\n")) ;
	
	lte_dev.sdio_thread_kick = 0 ;
	wait_event_interruptible( lte_dev.sdio_thread_wq, lte_dev.sdio_thread_kick);
	return 0 ;
}
Example #3
0
static int mtlte_sys_sdio_kick_thread(unsigned int data) 
{	
	KAL_DBGPRINT(KAL, DBG_LOUD,("[INT] mtlte_sys_sdio_kick_thread <==========>\r\n")) ;
	
	lte_dev.sdio_thread_kick = 1 ;
	wake_up_all(&lte_dev.sdio_thread_wq);
	return 0 ;
}
int mtlte_check_excetion_int(unsigned int swint_status)
{
    int i;
    
    if(swint_status & D2H_INT_except_init)
    {
        KAL_DBGPRINT(KAL, DBG_ERROR,("[exception] MT6290m modem assertion!!  Start assertion dump flow... \r\n")) ;
        
        if(lte_expt_priv.cb_ccci_expt_int){
            lte_expt_priv.cb_ccci_expt_int(EX_INIT);
        }else{
            KAL_DBGPRINT(KAL, DBG_ERROR,("[exception] there is no ccci callback function !!\r\n")) ;
            KAL_ASSERT(0) ;
        }

        if (mtlte_hif_expt_mode_init() != KAL_SUCCESS){
			return KAL_FAIL ; 
		}	

        // eemcs_ccci_ex_ind (DHL_DL_RDY)
        lte_expt_priv.cb_ccci_expt_int(EX_DHL_DL_RDY);
        
        // [SDIO] Active DHL_DL queue & Enable DHL_DL related DLQ interrupt
        for(i=0; i<RXQ_NUM; i++)
        {
            if( 1 == lte_expt_priv.non_stop_dlq[i] )
            {
                mtlte_hif_expt_restart_que(1, i);   
            }
        }

        mtlte_hif_expt_unmask_swint();
        mtlte_hif_expt_enable_interrupt();

        KAL_DBGPRINT(KAL, DBG_ERROR,("[exception] Start to transfer remain DHL DL pkt... \r\n")) ;
        
    }
    else if(swint_status & D2H_INT_except_clearQ_done)
    {
        KAL_DBGPRINT(KAL, DBG_ERROR,("[exception] DHL DL pkt transfer Done, Start reset to exception que ... \r\n")) ;
        mtlte_hif_expt_set_reset_allQ_bit();
    }

    return KAL_SUCCESS;
}
int mtlte_df_probe(void)
{
	unsigned int i ;
#if	USE_MULTI_QUE_DISPATCH    
    char rxq_work_name[RXQ_NUM][50];
#endif

	KAL_DBGPRINT(KAL, DBG_INFO,("====> %s\n",KAL_FUNC_NAME)) ;	

	for (i=0; i<TXQ_NUM ; i++){
		skb_queue_head_init(&lte_df_core.ul_xmit_wait_queue[i]);
	}

	skb_queue_head_init(&lte_df_core.ul_xmit_free_queue);
	
	for (i=0; i<RXQ_NUM ; i++){
		lte_df_core.dl_pkt_in_use[i] = 0 ;
		skb_queue_head_init(&lte_df_core.dl_recv_wait_queue[i]);
	}

#if BUFFER_POOL_FOR_EACH_QUE
    for (i=0; i<RXQ_NUM ; i++){
        skb_queue_head_init(&lte_df_core.dl_buffer_pool_queue[i]);
        mtlte_df_DL_prepare_skb_for_swq(i) ;
        KAL_RAWPRINT(("The DL Buffer Pool packet of RXQ%d is %d\r\n", i, lte_df_core.dl_buffer_pool_queue[i].qlen)) ;
        KAL_RAWPRINT(("The skb size of RXQ%d is %d\r\n", i, lte_df_core.df_skb_alloc_size[i])) ;
    }
#else
    skb_queue_head_init(&lte_df_core.dl_buffer_pool_queue);
	mtlte_df_DL_prepare_skb_for_swq() ;
    KAL_RAWPRINT(("The DL Buffer Pool packet is %d\r\n", lte_df_core.dl_buffer_pool_queue.qlen)) ;
#endif

#if FORMAL_DL_FLOW_CONTROL
    for (i=0; i<RXQ_NUM ; i++){
        lte_df_core.fl_ctrl_full[i] = false;
        atomic_set(&lte_df_core.fl_ctrl_counter[i], 0);
    }
#endif

	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;

	return KAL_SUCCESS ; 
}
void mtlte_df_DL_fl_ctrl_print_status(MTLTE_DF_RX_QUEUE_TYPE qno)
{
    KAL_DBGPRINT(KAL, DBG_ERROR,("====> status of DLQ%d \n",qno)) ;
    KAL_DBGPRINT(KAL, DBG_ERROR,("      fl_ctrl_enable = %d \n",lte_df_core.fl_ctrl_enable[qno])) ;
    KAL_DBGPRINT(KAL, DBG_ERROR,("      fl_ctrl_free_skb = %d \n",lte_df_core.fl_ctrl_free_skb[qno])) ;
    KAL_DBGPRINT(KAL, DBG_ERROR,("      fl_ctrl_limit = %d \n",lte_df_core.fl_ctrl_limit[qno])) ;
    KAL_DBGPRINT(KAL, DBG_ERROR,("      fl_ctrl_threshold = %d \n",lte_df_core.fl_ctrl_threshold[qno])) ;
    KAL_DBGPRINT(KAL, DBG_ERROR,("      fl_ctrl_full = %d \n",lte_df_core.fl_ctrl_full[qno])) ;
    KAL_DBGPRINT(KAL, DBG_ERROR,("      fl_ctrl_counter = %d \n", atomic_read(&lte_df_core.fl_ctrl_counter[qno]))) ;
    KAL_DBGPRINT(KAL, DBG_ERROR,("      fl_ctrl_record = %d \n",lte_df_core.fl_ctrl_record[qno])) ;
}
static inline int mtlte_df_UL_kick_proccess(void)
{	
	KAL_DBGPRINT(KAL, DBG_INFO,("<====> %s\n",KAL_FUNC_NAME)) ;	
	
	if (lte_df_core.kick_hif_process.callback_func){
		return lte_df_core.kick_hif_process.callback_func(lte_df_core.kick_hif_process.private_data) ;
	}else{
		return KAL_FAIL ;
	}
	
}
int mtlte_df_deinit(void)
{
	KAL_DBGPRINT(KAL, DBG_INFO,("====> %s\n",KAL_FUNC_NAME)) ;	

#if	USE_MULTI_QUE_DISPATCH
    for (i=0; i<RXQ_NUM ; i++){
	    destroy_workqueue(lte_df_core.rxq_dispatch_work_queue[i]);
    }
#else
	destroy_workqueue(lte_df_core.dl_dispatch_work_queue);
#endif

    destroy_workqueue(lte_df_core.dl_reload_work_queue);

    KAL_DESTROYMUTEX(&lte_df_core.dl_pkt_lock) ;
	
	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;

	return KAL_SUCCESS ; 
}
/* DL data traffic APIs */
void inline mtlte_df_DL_dispatch_rx_work(void)
{	
    unsigned int rx_q_num = 0;
    //unsigned int pkt_in_qum = 0;
    
    KAL_DBGPRINT(KAL, DBG_INFO,("====> %s\n",KAL_FUNC_NAME)) ;

    for(rx_q_num=0; rx_q_num<RXQ_NUM; rx_q_num++){ 
        
        while(1){
            //KAL_DBGPRINT(KAL, DBG_ERROR,("pkt in que %d = %d \n",rx_q_num, pkt_in_qum)) ;
            if( skb_queue_empty(&lte_df_core.dl_recv_wait_queue[rx_q_num]) ){
                break;
            }else{
                lte_df_core.cb_handle[rx_q_num].callback_func(rx_q_num) ;
            }
        }       
	}
    
	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;
}
/* DL data traffic APIs */
void inline mtlte_df_DL_dispatch_rxque_work(struct work_struct *work)
{	
    unsigned int rx_q_num ;
    rxq_dispatch_work_t *rxq_work_now;

    rxq_work_now = container_of(work, rxq_dispatch_work_t, rxq_dispatch_work);
    rx_q_num = rxq_work_now->rxq_num;
    
    KAL_DBGPRINT(KAL, DBG_INFO,("====> %s, rxq%d \n",KAL_FUNC_NAME, rx_q_num)) ;

        
    while(1){
        if( skb_queue_empty(&lte_df_core.dl_recv_wait_queue[rx_q_num]) ){
            break;
        }else{
            lte_df_core.cb_handle[rx_q_num].callback_func(rx_q_num) ;
        }
    }       
    
	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;
}
static void mtlte_df_DL_reload_work(struct work_struct *work)
{	
#if BUFFER_POOL_FOR_EACH_QUE
    KAL_UINT32 qno;

	KAL_DBGPRINT(KAL, DBG_INFO,("====> %s\n",KAL_FUNC_NAME)) ;      

    for(qno=0; qno<RXQ_NUM; qno++){
	    mtlte_df_DL_prepare_skb_for_swq(qno);
    }

	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;
#else
	KAL_DBGPRINT(KAL, DBG_INFO,("====> %s\n",KAL_FUNC_NAME)) ;		

	mtlte_df_DL_prepare_skb_for_swq(); 

	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;
#endif    
	return ;

}
int mtlte_expt_reset_inform_hif(void)
{
    
    if(lte_expt_priv.cb_ccci_expt_int){
            lte_expt_priv.cb_ccci_expt_int(EX_INIT_DONE);
    }else{
            KAL_DBGPRINT(KAL, DBG_ERROR,("[exception] there is no ccci callback function !!\r\n")) ;
            KAL_ASSERT(0) ;
            return KAL_FAIL;
    }

    return KAL_SUCCESS;
}
void mtlte_df_DL_set_skb_alloc_size_depth(MTLTE_DF_TX_QUEUE_TYPE qno, unsigned int alloc_size, unsigned int pool_depth)
{
    if(alloc_size == 0){
        lte_df_core.df_skb_alloc_size[qno] = DEV_MAX_PKT_SIZE;
    }else if(alloc_size > DEV_MAX_PKT_SIZE){
        lte_df_core.df_skb_alloc_size[qno] = DEV_MAX_PKT_SIZE;
        KAL_DBGPRINT(KAL, DBG_ERROR,("[SDIO][WARN] Set skb allocate size to %d of DLQ%d is Invaild, which is bigger than DEV_MAX_PKT_SIZE %d \n", alloc_size, qno, DEV_MAX_PKT_SIZE)) ; 
    }else{
        lte_df_core.df_skb_alloc_size[qno] = alloc_size;
    }
    
    KAL_DBGPRINT(KAL, DBG_ERROR,("[SDIO][INFO] Set skb allocate size of DLQ%d = %d \n", qno, lte_df_core.df_skb_alloc_size[qno])) ; 


    if(pool_depth == 0){
        lte_df_core.df_buffer_pool_depth[qno] = MT_LTE_DL_BUFF_POOL_TH;
    }else{
        lte_df_core.df_buffer_pool_depth[qno] = pool_depth;
    }

    KAL_DBGPRINT(KAL, DBG_ERROR,("[SDIO][INFO] Set skb pool depth of DLQ%d = %d \n", qno, lte_df_core.df_buffer_pool_depth[qno])) ; 

}
int mtlte_df_remove_phase1(void)
{	
#if	USE_MULTI_QUE_DISPATCH
	int i ;
#endif

	KAL_DBGPRINT(KAL, DBG_INFO,("====> %s\n",KAL_FUNC_NAME)) ;	

#if	USE_MULTI_QUE_DISPATCH
    for (i=0; i<RXQ_NUM ; i++){
        flush_workqueue(lte_df_core.rxq_dispatch_work_queue[i]);
    }
#else
    flush_workqueue(lte_df_core.dl_dispatch_work_queue);
#endif

	flush_workqueue(lte_df_core.dl_reload_work_queue);

	KAL_RAWPRINT(("[REMOVE] All queue work is flushed ~~ \r\n")) ;

	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;

	return 0 ; 
}
int mtlte_df_swint_handle(unsigned int swint_status)
{
    mtlte_check_excetion_int(swint_status);
    
    if(swint_status & 0xFF030000){
        if(lte_df_core.cb_sw_int == NULL){
            KAL_DBGPRINT(KAL, DBG_ERROR,("the sw interrupt callback func has no be registed!! \n")) ;
            return KAL_FAIL ; 
        }
        else{
            lte_df_core.cb_sw_int(swint_status);
        }
    }
    return KAL_SUCCESS ; 
}
void inline mtlte_df_DL_prepare_skb_for_swq(MTLTE_DF_TX_QUEUE_TYPE qno)
{	
	struct sk_buff *skb_tmp ;
	unsigned cnt=0 ;

	while(lte_df_core.dl_buffer_pool_queue[qno].qlen<lte_df_core.df_buffer_pool_depth[qno]){
		skb_tmp = dev_alloc_skb(lte_df_core.df_skb_alloc_size[qno]) ;
		if (skb_tmp){
			cnt++ ;
			skb_queue_tail(&lte_df_core.dl_buffer_pool_queue[qno], skb_tmp) ;
		}else{
			break ;
		}
	}
	KAL_DBGPRINT(KAL, DBG_INFO,("Reload %d skbs for DL buffer pool, the pool len is %d\n",cnt, lte_df_core.dl_buffer_pool_queue[qno].qlen)) ;			
}
void inline mtlte_df_DL_prepare_skb_for_swq(void)
{	
	struct sk_buff *skb_tmp ;
	unsigned cnt=0 ;
	
	while(lte_df_core.dl_buffer_pool_queue.qlen<MT_LTE_DL_BUFF_POOL_TH){
		skb_tmp = dev_alloc_skb(DEV_MAX_PKT_SIZE) ;
		if (skb_tmp){
			cnt++ ;
			skb_queue_tail(&lte_df_core.dl_buffer_pool_queue, skb_tmp) ;
		}else{
			break ;
		}
	}
	KAL_DBGPRINT(KAL, DBG_INFO,("Reload %d skbs for DL buffer pool, the pool len is %d\n",cnt, lte_df_core.dl_buffer_pool_queue.qlen)) ;			
}
Example #18
0
inline void mtlte_sys_disable_int_isr(struct sdio_func *func)
{
	int err_ret ;
	unsigned int value ;

	KAL_DBGPRINT(KAL, DBG_LOUD,("[INT] mtlte_sys_disable_int_isr <==========>\r\n")) ;

	value = W_INT_EN_CLR ; 
	sdio_claim_host(func);	
	err_ret = sdio_writesb(func,SDIO_IP_WHLPCR, &value, 4);
	sdio_release_host(func);
	if (err_ret){
		KAL_RAWPRINT(("[ISR] XXXXXX mtlte_sys_disable_int_isr fail, %d \n", err_ret )); 
		return ;
	}

}
Example #19
0
static 
int mtlte_sys_sdio_probe( struct sdio_func *func, const struct sdio_device_id *id)
{
	int ret ; 
	//char net_mac[6] ;
#ifdef MT_LTE_AUTO_CALIBRATION	
  #ifndef NATIVE_AUTOK
	int lte_autok_finish_next;
  #endif
	BOOTMODE btmod;
#endif

    unsigned int orig_WHCR = 0;
    unsigned int changed_WHCR = 0;
    unsigned int orig_WPLRCR = 0;
    unsigned int changed_WPLRCR = 0;
    
    KAL_RAWPRINT(("[PROBE] =======> mt_lte_sdio_probe\n")); 

#ifdef MT_LTE_AUTO_CALIBRATION
    mtlte_sdio_probe_done = 0;
#endif

    LTE_WD_timeout_indicator = 0;
    
	lte_dev.card_exist = 1 ;
	lte_dev.sdio_thread_kick = 0 ;   
    lte_dev.sdio_thread_kick_isr = 0 ; 
    lte_dev.sdio_thread_kick_own_timer = 0 ; 
	lte_dev.sdio_thread_state = SDIO_THREAD_IDLE ; 
	lte_dev.sdio_func = func ;

    /*  Because MT7208 SDIO device add the r/w busy function, 
            We only can use block read at Tx/Rx port.  
            This  quirk is force host to use block access if the transfer byte is equal to n*block size  */
//	    func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;

    /*  Because MT7208 SDIO device not support read 512 byte in data block 
            This  quirk is set byte mode size to max 511 byte  */
    func->card->quirks |= MMC_QUIRK_BROKEN_BYTE_MODE_512;

    /* enable the sdio device function */
	if ((ret = sdio_open_device(func)) != KAL_SUCCESS){
		KAL_RAWPRINT(("[PROBE] XXXXXX mt_lte_sdio_probe -sdio_open_device fail \n")); 
		goto OPEN_FAIL ;
	}
	
#ifdef MT_LTE_AUTO_CALIBRATION
    btmod = get_boot_mode();
    printk("btmod = %d\n", btmod);
    if ((btmod!=META_BOOT) && (btmod!=FACTORY_BOOT) && (btmod!=ATE_FACTORY_BOOT))
    {
#ifndef NATIVE_AUTOK 
        lte_autok_finish = 0;
        lte_autok_finish_next = lte_autok_finish + 1;
    //    KAL_RAWPRINT(("[AUTOK] =======> mtlte_sys_trigger_auto_calibration\n"));
        mtlte_sys_trigger_auto_calibration(NULL);
    //	KAL_RAWPRINT(("lte_autok_finish = %d\n", lte_autok_finish));
    
        while (lte_autok_finish_next != lte_autok_finish){
            KAL_SLEEP_MSEC(50);
        }
#else
      //wait_sdio_autok_ready((void*)lte_dev.sdio_func->card->host);
      wait_sdio_autok_ready((void*)lte_dev.sdio_func->card->host, force_autok);
      force_autok = 0;

#endif
      
    //	KAL_RAWPRINT(("lte_autok_finish = %d\n", lte_autok_finish));
    }
#endif

#ifdef MT_LTE_ONLINE_TUNE_SUPPORT
    ot_set_dev_sleep_sts((void*)lte_dev.sdio_func->card->host, 0);
    ot_dev_wakeup( (void*)lte_dev.sdio_func->card->host );
#endif


	mtlte_hif_register_hif_to_sys_wake_callback(mtlte_sys_sdio_kick_thread, 0) ;
    mtlte_hif_register_hif_to_sys_sleep_callback(mtlte_sys_sdio_sleep_thread, 0) ;
	
	if ((ret = mtlte_hif_sdio_probe()) != KAL_SUCCESS){
		KAL_RAWPRINT(("[PROBE] XXXXXX mt_lte_sdio_probe -mtlte_hif_sdio_probe fail \n")); 
		goto HIF_PROBE_FAIL ;
	}
		
	
	/* sync with the Device FW */
#if 1 
	if ((ret = mtlte_hif_sdio_wait_FW_ready()) != KAL_SUCCESS){
		KAL_RAWPRINT(("[PROBE] XXXXXX mt_lte_sdio_probe -mtlte_hif_sdio_wait_FW_ready fail \n")); 
		goto HIF_PROBE_FAIL ;
	}	
#endif

	/* do the data flow layer probing */
	if ((ret = mtlte_df_probe()) != KAL_SUCCESS){
		KAL_RAWPRINT(("[PROBE] XXXXXX mt_lte_sdio_probe -mtlte_df_probe fail \n")); 
		goto DF_PROBE_FAIL ;
	}

    if ((ret = mtlte_expt_probe()) != KAL_SUCCESS){
		KAL_RAWPRINT(("[INIT] XXXXXX lte_sdio_driver_init -sdio_register_driver fail \n")); 
		goto DF_PROBE_FAIL ; 
    }

    KAL_DBGPRINT(KAL, DBG_ERROR,("[%s] set the WPLRCR for NEW FPGA... \n",KAL_FUNC_NAME)) ;
    
    /* Set the Default value of RX MAX Report Num due MT6290 SDIO HW's flexibility */
    sdio_func1_rd(SDIO_IP_WHCR, &orig_WHCR, 4);
    changed_WHCR = orig_WHCR | RPT_OWN_RX_PACKET_LEN;
    sdio_func1_wr(SDIO_IP_WHCR, &changed_WHCR, 4);

    sdio_func1_rd(SDIO_IP_WPLRCR, &orig_WPLRCR, 4);
    changed_WPLRCR = orig_WPLRCR;
    changed_WPLRCR &= (~(RX_RPT_PKT_LEN(0)));
    changed_WPLRCR |= MT_LTE_RXQ0_MAX_PKT_REPORT_NUM<<(8*0);
    changed_WPLRCR &= (~(RX_RPT_PKT_LEN(1)));
    changed_WPLRCR |= MT_LTE_RXQ1_MAX_PKT_REPORT_NUM<<(8*1);
    changed_WPLRCR &= (~(RX_RPT_PKT_LEN(2)));
    changed_WPLRCR |= MT_LTE_RXQ2_MAX_PKT_REPORT_NUM<<(8*2);
    changed_WPLRCR &= (~(RX_RPT_PKT_LEN(3)));
    changed_WPLRCR |= MT_LTE_RXQ3_MAX_PKT_REPORT_NUM<<(8*3);

    sdio_func1_wr(SDIO_IP_WPLRCR, &changed_WPLRCR, 4);	

#if EMCS_SDIO_DRVTST		
	if ((ret = mtlte_dev_test_probe(LTE_TEST_DEVICE_MINOR, &func->dev)) != KAL_SUCCESS){
		KAL_RAWPRINT(("[PROBE] XXXXXX mt_lte_sdio_probe -mtlte_dev_test_probe %d fail \n", LTE_TEST_DEVICE_MINOR)); 
		goto PROBE_TEST_DRV_FAIL ;
	}
#endif	
    
	/* Sync with FW */
	//TODO5:
	
	/* start the kthread */
	lte_dev.sdio_thread = kthread_run(mtlte_sys_sdio_thread, &lte_dev, "mt_sdio_kthread");
    if (IS_ERR(lte_dev.sdio_thread)) {
        ret = -EBUSY ;
        KAL_RAWPRINT(("[PROBE] XXXXXX mt_lte_sdio_probe -kthread_run fail \n")); 
        goto CREATE_THREAD_FAIL;
    }	

	/* Enable the SDIO TXRX handle process */
	mtlte_hif_sdio_txrx_proc_enable(1) ;
	KAL_RAWPRINT(("[PROBE] mtlte_hif_sdio_txrx_proc_enable enalbe it. \n")); 

    // Test the WHISR read before enable interrupt for 6575 debug
    //mtlte_hif_sdio_get_driver_own();
    //sdio_func1_rd(SDIO_IP_WHISR, hif_sdio_handler.enh_whisr_cache,sizeof(sdio_whisr_enhance));

    /* enable the sdio interrupt service */  
    if ((ret = mtlte_sys_sdio_setup_irq(func)) != KAL_SUCCESS){
		KAL_RAWPRINT(("[PROBE] XXXXXX mt_lte_sdio_probe -mtlte_sys_sdio_setup_irq fail \n")); 
        goto SETUP_IRQ_FAIL;
    }

#ifdef MT_LTE_AUTO_CALIBRATION
        mtlte_sdio_probe_done = 1;
#endif
	KAL_RAWPRINT(("[PROBE] <======= mt_lte_sdio_probe\n")); 	
	
	return ret ;

SETUP_IRQ_FAIL:
	kthread_stop(lte_dev.sdio_thread); 	
CREATE_THREAD_FAIL:

#if EMCS_SDIO_DRVTST		
	mtlte_dev_test_detach(LTE_TEST_DEVICE_MINOR) ;
PROBE_TEST_DRV_FAIL:
#endif

	mtlte_df_remove_phase1() ;
	mtlte_df_remove_phase2() ;
DF_PROBE_FAIL:
	mtlte_hif_sdio_remove_phase1() ;
	mtlte_hif_sdio_remove_phase2() ;
HIF_PROBE_FAIL:
	sdio_close_device(func) ;
OPEN_FAIL:

	KAL_RAWPRINT(("[PROBE FAIL] <======= mt_lte_sdio_probe\n")); 	
	
	return -ENODEV ;
}
int mtlte_df_DL_enswq_buf(MTLTE_DF_RX_QUEUE_TYPE qno ,  void *buf, unsigned int len)
{
	int ret = KAL_SUCCESS ; 
	struct sk_buff *skb = NULL; 
	
	KAL_DBGPRINT(KAL, DBG_INFO,("====> %s , qno: %d\n",KAL_FUNC_NAME, qno)) ;	

#if BUFFER_POOL_FOR_EACH_QUE
    if(len > lte_df_core.df_skb_alloc_size[qno]){
        KAL_DBGPRINT(KAL, DBG_ERROR,("[SDIO][ERR] lte_df_core.df_skb_alloc_size[%d] = %d, packet this time = %d \n", qno, lte_df_core.df_skb_alloc_size[qno], len)) ;
        KAL_DBGPRINT(KAL, DBG_ERROR,("[SDIO][ERR] First 64byte of this error packet = ")) ;
        KAL_DBGPRINT(KAL, DBG_ERROR, ("0x%08x, 0x%08x, 0x%08x, 0x%08x,  ", *(unsigned int *)(buf+0), *(unsigned int *)(buf+4), *(unsigned int *)(buf+8), *(unsigned int *)(buf+12))) ;
        KAL_DBGPRINT(KAL, DBG_ERROR, ("0x%08x, 0x%08x, 0x%08x, 0x%08x,  ", *(unsigned int *)(buf+16), *(unsigned int *)(buf+20), *(unsigned int *)(buf+24), *(unsigned int *)(buf+28))) ;
        KAL_DBGPRINT(KAL, DBG_ERROR, ("0x%08x, 0x%08x, 0x%08x, 0x%08x,  ", *(unsigned int *)(buf+32), *(unsigned int *)(buf+36), *(unsigned int *)(buf+40), *(unsigned int *)(buf+44))) ;
        KAL_DBGPRINT(KAL, DBG_ERROR, ("0x%08x, 0x%08x, 0x%08x, 0x%08x,  ", *(unsigned int *)(buf+48), *(unsigned int *)(buf+52), *(unsigned int *)(buf+56), *(unsigned int *)(buf+60))) ;
    }
    KAL_ASSERT(len <= lte_df_core.df_skb_alloc_size[qno]) ;
#else
	KAL_ASSERT(len <= DEV_MAX_PKT_SIZE) ;
#endif

	if (lte_df_core.cb_handle[qno].callback_func == NULL){
		return KAL_SUCCESS ;
	}

#if BUFFER_POOL_FOR_EACH_QUE
    if ((skb = skb_dequeue(&lte_df_core.dl_buffer_pool_queue[qno])) == NULL ){
		KAL_DBGPRINT(KAL, DBG_WARN,("mtlte_df_DL_enswq_buf skb_dequeue no skb\n")) ;
		return KAL_FAIL ;
	}
#else
	if ((skb = skb_dequeue(&lte_df_core.dl_buffer_pool_queue)) == NULL ){
		KAL_DBGPRINT(KAL, DBG_WARN,("mtlte_df_DL_enswq_buf skb_dequeue no skb\n")) ;
		return KAL_FAIL ;
	}
#endif

	memcpy(skb_put(skb, len), buf, len) ;

    KAL_MUTEXLOCK(&lte_df_core.dl_pkt_lock);    
        
    //NOTICE : try to set in_use number before really enqueue skb, to avoid in_use number <0 assert
    lte_df_core.dl_pkt_in_use[qno] ++ ;

	skb_queue_tail(&lte_df_core.dl_recv_wait_queue[qno], skb) ;

    KAL_MUTEXUNLOCK(&lte_df_core.dl_pkt_lock);

#if FORMAL_DL_FLOW_CONTROL
    if(true == lte_df_core.fl_ctrl_enable[qno]){
        atomic_inc(&lte_df_core.fl_ctrl_counter[qno]);
        if(atomic_read(&lte_df_core.fl_ctrl_counter[qno]) >= lte_df_core.fl_ctrl_limit[qno]){
            lte_df_core.fl_ctrl_full[qno] = true;
        }
        // record the largest counter ever
        if(atomic_read(&lte_df_core.fl_ctrl_counter[qno]) > lte_df_core.fl_ctrl_record[qno]){
            lte_df_core.fl_ctrl_record[qno] = atomic_read(&lte_df_core.fl_ctrl_counter[qno]);
        }
    }
#endif

#if (USE_QUE_WORK_DISPATCH_RX || DISPATCH_AFTER_ALL_SKB_DONE)   
#else
	KAL_DBGPRINT(KAL, DBG_INFO,("RXQ %d callback , and the private data is %d\r\n",qno, lte_df_core.cb_handle[qno].private_data)) ;	
	//lte_df_core.cb_handle[qno].callback_func(lte_df_core.cb_handle[qno].private_data) ;
	lte_df_core.cb_handle[qno].callback_func(qno) ;
#endif		

	KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;
	return ret ;
}
/* DL data traffic APIs */
void mtlte_df_DL_rx_callback(MTLTE_DF_RX_QUEUE_TYPE qno)
{	
    KAL_DBGPRINT(KAL, DBG_INFO,("====> %s\n",KAL_FUNC_NAME)) ;	
	lte_df_core.cb_handle[qno].callback_func(qno) ;
    KAL_DBGPRINT(KAL, DBG_INFO,("<==== %s\n",KAL_FUNC_NAME)) ;
}