Example #1
0
static long eemcs_ipc_ioctl( struct file *fp, unsigned int cmd, unsigned long arg)
{
    eemcs_ipc_node_t *curr_node = (eemcs_ipc_node_t *)fp->private_data;
    int ret = 0;

    DEBUG_LOG_FUNCTION_ENTRY;

    switch(cmd)
    {
        case CCCI_IPC_RESET_RECV:
            DBGLOG( IPCD, TRA,"CCCI_IPC_RESET_RECV: Clean device(%d)", curr_node->ipc_node_id );
            skb_queue_purge(&curr_node->rx_skb_list);
            atomic_set(&curr_node->rx_pkt_cnt, 0);
            ret = 0;
            break;
        case CCCI_IPC_RESET_SEND:
            DBGLOG( IPCD, TRA,"CCCI_IPC_RESET_SEND: Wakeup device(%d)", curr_node->ipc_node_id );
            wake_up(&curr_node->tx_waitq);
            ret = 0;
            break;
        case CCCI_IPC_WAIT_MD_READY:
            if (check_device_state() != EEMCS_BOOTING_DONE){
                DBGLOG(IPCD,TRA,"CCCI_IPC_WAIT_MD_READY: MD not ready(sta=%d)", check_device_state());
                wait_event_interruptible(eemcs_ipc_inst.state_waitq,(check_device_state() == EEMCS_BOOTING_DONE));
            }
            ret = 0;
			
            DBGLOG(IPCD,TRA,"CCCI_IPC_WAIT_MD_READY ok");
            break;
        case CCCI_IPC_KERN_WRITE_TEST:
            {
                int node_id;
                ipc_ilm_t ilm = {AP_MOD_WMT, MD_MOD_L4C, 0, 0, NULL, NULL};
        		if(copy_from_user(&node_id, (void __user *)arg, sizeof(unsigned int))) {
    				DBGLOG(IPCD, ERR, "CCCI_IPC_KERN_WRITE_TEST: copy_from_user fail!");
    				ret = -EFAULT;
                    break;
    			} 
                DBGLOG(IPCD, TRA,"CCCI_IPC_KERN_WRITE_TEST: %d", node_id);

                ret = eemcs_ipc_kern_write(&ilm);
                if (ret > 0 ){
                    ret = 0;
                }

                break;
            }
        default:
            DBGLOG(IPCD,ERR,"unsupport ioctrl(%d)\n", cmd);
            ret=-EINVAL;
            break;           
    }

    DEBUG_LOG_FUNCTION_LEAVE;
    return ret;
}
Example #2
0
int ccci_df_to_ccci_send_msg(CCCI_CHANNEL_T ch, unsigned int msg, unsigned int reserv){
    struct sk_buff *new_skb;
    CCCI_BUFF_T    *pccci_h;
    KAL_UINT32 port_id;
    KAL_INT32 ret;

    DEBUG_LOG_FUNCTION_ENTRY;
    if ((check_device_state() != EEMCS_BOOTING_DONE) || md_wdt_timeout_isr) {//modem not ready
        DBGLOG(CCCI, ERR, "CH%d send ccci msg(%d) fail when modem not ready", ch, msg);
        return -ENODEV;
    }
	
    new_skb = ccci_cdev_mem_alloc(sizeof(CCCI_BUFF_T), GFP_ATOMIC);
    if(new_skb == NULL){
        DBGLOG(CCCI, ERR, "[TX]CH%d alloc skb fail", ch);   
        return -ENOMEM;
    }

    pccci_h = (CCCI_BUFF_T *)skb_put(new_skb, sizeof(CCCI_BUFF_T)) ;
    memset(pccci_h, 0, sizeof(CCCI_BUFF_T));
    pccci_h->data[0]  = CCCI_MAGIC_NUM;
    pccci_h->data[1]  = msg;
    pccci_h->reserved = reserv;

#if defined (DBG_FEATURE_ADD_CCCI_SEQNO)
    if (ch == CCCI_FORCE_RESET_MODEM_CHANNEL) {
    	pccci_h->channel = (CCCI_FORCE_RESET_MODEM_CHANNEL&0xFFFF);
    	pccci_h->seq_num = (CCCI_FORCE_RESET_MODEM_CHANNEL&0x7FFF0000) >> 16;
    	pccci_h->assert_bit = (CCCI_FORCE_RESET_MODEM_CHANNEL&0x80000000) >> 31;
    } 
Example #3
0
/*
 * @brief Check if a incomming buffer is a xBoot command.
 * @param
 *     skb [in] The incomming socket buffer.
 * @return If a incomming buffer is a xBoot command, true is returned.
 *         Otherwise, false is returned.
 */
int is_xboot_command(struct sk_buff *skb)
{
    int result = false;
    XBOOT_CMD *p_xcmd = NULL;

    DEBUG_LOG_FUNCTION_ENTRY;
    if (check_device_state() >= EEMCS_MOLY_HS_P1) {
        DBGLOG(CCCI, DBG, "Current EEMCS state is %d. Should not received a xBoot command !!", check_device_state());
    } else {
        p_xcmd = (XBOOT_CMD *)skb->data;
        if (p_xcmd->magic == (KAL_UINT32)MAGIC_MD_CMD)
            result = true;
        else
            DBGLOG(CCCI, DBG, "This is not a xBoot command (0x%X)(0x%X)(0x%X)",
                p_xcmd->magic, p_xcmd->msg_id, p_xcmd->status);
    }
    DEBUG_LOG_FUNCTION_LEAVE;
    return result;
}
/* 
 * @brief                 Check if EEMCS currently in exception state.
 * @param mode[out]       one of following exception mode is stored in this parameter
 *                            EEMCS_EX_NONE
 *                            EEMCS_EX_INIT
 *                            EEMCS_EX_DHL_DL_RDY
 *                            EEMCS_EX_INIT_DONE
 * @return true           indicateds EEMCS is in exception state; otherwise false.
 */
kal_bool is_exception_mode(EEMCS_EXCEPTION_STATE *mode)
{
    kal_bool ret = false;
    KAL_UINT32 state = EEMCS_INVALID;

    DEBUG_LOG_FUNCTION_ENTRY;

    state = check_device_state();
    if(EEMCS_EXCEPTION == state)
    {
        if(NULL != mode)
            *mode = get_exception_mode();
        ret = true;
    }
    else
    {
        if(NULL != mode)
            *mode = EEMCS_EX_NONE;
    }
    
    DEBUG_LOG_FUNCTION_LEAVE;
    return ret;
}
Example #5
0
int ccci_df_to_ccci_callback(unsigned int rxq_no)
{
    int ret, hc_ret;
    bool is_xcmd = false;
    struct sk_buff * skb = NULL;
    CCCI_BUFF_T *ccci_h  = NULL;
    XBOOT_CMD *p_xcmd = NULL;
    KAL_UINT32   port_id = CCCI_PORT_CTRL;
    static KAL_UINT32 rx_err_cnt[CCCI_PORT_NUM_MAX] = {0};
#ifdef __EEMCS_EXPT_SUPPORT__
    EEMCS_EXCEPTION_STATE mode = EEMCS_EX_INVALID;
#endif
#if defined (DBG_FEATURE_ADD_CCCI_SEQNO)
    KAL_INT16 channel, seq_num, assert_bit;
#endif

    DEBUG_LOG_FUNCTION_ENTRY;
    /* Step 1. read skb from swq */
    skb = hif_dl_read_swq(rxq_no);
    if(skb == NULL) {
    	DBGLOG(CCCI, DBG, "ccci_df_to_ccci_callback read NULL skb on %d", rxq_no);
    	if(is_exception_mode(&mode))
    		return KAL_FAIL;
    	else
    		KAL_ASSERT(NULL != skb);
    }

    /* Step 2. call handle complete */
    hc_ret = hif_dl_pkt_handle_complete(rxq_no);
    KAL_ASSERT(0 == hc_ret);

    wake_lock_timeout(&eemcs_wake_lock, HZ/2); // Using 0.5s wake lock

	/* Step 3. buffer type */
    if (rxq_no == RXQ_Q0) {
        //is_xcmd = is_xboot_command(skb);
        p_xcmd = (XBOOT_CMD *)skb->data;
	    if (p_xcmd->magic == (KAL_UINT32)MAGIC_MD_CMD) {
			if (check_device_state() >= EEMCS_MOLY_HS_P1) {
        		DBGLOG(CCCI, ERR, "can't recv xBoot cmd when EEMCS state=%d", check_device_state());
    		} else {
    			is_xcmd = true;
	    	}
	    }
    }

    if (is_xcmd) {
        /* Step 4. callback to xBoot */
    	CDEV_LOG(port_id, CCCI, INF, "XBOOT_CMD: 0x%08X, 0x%08X, 0x%08X, 0x%08X",\
        	p_xcmd->magic, p_xcmd->msg_id, p_xcmd->status, p_xcmd->reserved[0]);
    	ret = ccci_port_info[port_id].ch.rx_cb(skb, 0);
    } else {
    	ccci_h = (CCCI_BUFF_T *)skb->data;
    	port_id = ccci_ch_to_port(ccci_h->channel);		
    	CDEV_LOG(port_id, CCCI, INF, "CCCI_H: 0x%08X, 0x%08X, 0x%08X, 0x%08X",\
        	ccci_h->data[0],ccci_h->data[1],ccci_h->channel, ccci_h->reserved);

    	/*check rx sequence number for expect*/
    	#if defined (DBG_FEATURE_ADD_CCCI_SEQNO)
    	channel = ccci_h->channel;
    	seq_num = ccci_h->seq_num;
    	assert_bit = ccci_h->assert_bit;	
    	DBGLOG(CCCI, DBG, "Port%d CCCI_H: data[0]=0x%08X, data[1]=0x%08X, ch=0x%02X, seqno=0x%02X, assert=%d, resv=0x%08X(0x%08X, 0x%08X, 0x%08X)",\
        	port_id, ccci_h->data[0],ccci_h->data[1],ccci_h->channel, ccci_h->seq_num, \
        	ccci_h->assert_bit, ccci_h->reserved, channel, seq_num, assert_bit);
		
    	if(((seq_num - ccci_seqno_tbl[channel].seqno[RX]) & 0x7FFF) != 1 && assert_bit) {
            DBGLOG(CCCI, ERR, "Port%d seqno out-of-order(0x%02X->0x%02X): data[0]=0x%08X, data[1]=0x%08X, ch=0x%02X, seqno=0x%02X, assert=%d, resv=0x%08X", \							
				port_id, seq_num, ccci_seqno_tbl[channel].seqno[RX], ccci_h->data[0], ccci_h->data[1], \
				ccci_h->channel, ccci_h->seq_num, ccci_h->assert_bit, ccci_h->reserved);						
            hif_force_md_assert_swint();
    	}					
    	ccci_seqno_tbl[channel].seqno[RX] = seq_num;
    	#endif
		
        /* Step 4. callback to CCCI device */       
        if(NULL != ccci_port_info[port_id].ch.rx_cb){
            #ifdef __EEMCS_EXPT_SUPPORT__
            if(is_exception_mode(&mode))
            {
                if(!is_valid_exception_port(port_id, true))
                {
                    ret = KAL_FAIL;
                    dev_kfree_skb(skb);
                    eemcs_ccci_release_rx_skb(port_id, 1, skb);
                    eemcs_expt_ccci_rx_drop(port_id);
                    DBGLOG(CCCI, ERR, "PKT DROP when PORT%d(rxq=%d) at md exception", \
						port_id, rxq_no);
                    goto _end;
                } else {
                    ret = ccci_port_info[port_id].ch.rx_cb(skb, 0);
                }
            }
            else
            #endif      
            {
                ret = ccci_port_info[port_id].ch.rx_cb(skb, 0);
            }
            rx_err_cnt[port_id] = 0;
        } else { 
            ret = KAL_FAIL;
            dev_kfree_skb(skb);
            eemcs_ccci_release_rx_skb(port_id, 1, skb);
            if (rx_err_cnt[port_id]%20 == 0) {
            	DBGLOG(CCCI, ERR, "PKT DROP when PORT%d rx callback(ch=%d) not registered", \
					port_id, ccci_h->channel);
            }
            rx_err_cnt[port_id]++;
            eemcs_update_statistics(0, port_id, RX, DROP);
			
        }
        eemcs_update_statistics(0, port_id, RX, NORMAL);
    }
    
_end:    
    DEBUG_LOG_FUNCTION_LEAVE;
    return ret;
}
Example #6
0
static ssize_t eemcs_ipc_write(struct file *fp, const char __user *buf, size_t in_sz, loff_t *ppos)
{
    ssize_t ret   = 0;
    eemcs_ipc_node_t *curr_node = (eemcs_ipc_node_t *)fp->private_data;
    KAL_UINT8 node_id = curr_node->ipc_node_id;/* node_id */
    KAL_UINT8 port_id = eemcs_ipc_inst.eemcs_port_id; /* port_id */
    KAL_UINT32 p_type, control_flag;    
    struct sk_buff *new_skb;
    CCCI_BUFF_T *ccci_header;
    ipc_ilm_t *ilm=NULL;
    IPC_MSGSVC_TASKMAP_T *id_map;
    size_t count = in_sz;
    size_t skb_alloc_size;
    
    DEBUG_LOG_FUNCTION_ENTRY;        
    DBGLOG(IPCD,TRA,"ipc_write: deivce=%s iminor=%d len=%d", curr_node->dev_name, node_id, count);

    p_type = ccci_get_port_type(port_id);
    if(p_type != EX_T_USER) 
    {
        DBGLOG(IPCD,ERR,"PORT%d refuse port(%d) access user port", port_id, p_type);
        ret=-EINVAL;
        goto _exit;                    
    }

    control_flag = ccci_get_port_cflag(port_id);	
    if (check_device_state() == EEMCS_EXCEPTION) {//modem exception		
        if ((control_flag & TX_PRVLG2) == 0) {
            DBGLOG(CHAR, DEF, "[TX]PORT%d write fail when modem exception", port_id);
            return -ETXTBSY;
        }
    } else if (check_device_state() != EEMCS_BOOTING_DONE) {//modem not ready
        if ((control_flag & TX_PRVLG1) == 0) {
            DBGLOG(CHAR, DEF, "[TX]PORT%d write fail when modem not ready", port_id);
            return -ENODEV;
        }
    }

    if((control_flag & EXPORT_CCCI_H) && (count < sizeof(CCCI_BUFF_T)))
    {
        DBGLOG(IPCD,ERR,"invalid wirte_len(%d) of PORT%d", count, port_id);
        ret=-EINVAL;
        goto _exit;            
    }

    if(control_flag & EXPORT_CCCI_H){
        if(count > (MAX_TX_BYTE+sizeof(CCCI_BUFF_T))){
            DBGLOG(IPCD,WAR,"PORT%d wirte_len(%d)>MTU(%d)!", port_id, count, MAX_TX_BYTE);
            count = MAX_TX_BYTE+sizeof(CCCI_BUFF_T);
        }
        skb_alloc_size = count - sizeof(CCCI_BUFF_T);
    }else{
        if(count > MAX_TX_BYTE){
            DBGLOG(IPCD,WAR,"PORT%d wirte_len(%d)>MTU(%d)!", port_id, count, MAX_TX_BYTE);
            count = MAX_TX_BYTE;
        }
        skb_alloc_size = count;
    }

	if (ccci_ch_write_space_alloc(eemcs_ipc_inst.ccci_ch.tx)==0){
        DBGLOG(IPCD,WAR,"PORT%d write return 0)", port_id);
        ret = -EAGAIN;
        goto _exit;
	}	
    
    new_skb = ccci_ipc_mem_alloc(skb_alloc_size + CCCI_IPC_HEADER_ROOM);
    if(NULL == new_skb)
    {
        DBGLOG(IPCD,ERR,"PORT%d alloct tx memory fail", port_id);
        ret = -ENOMEM;
        goto _exit;            
    }
    
    /* reserve SDIO_H header room */
    #ifdef CCCI_SDIO_HEAD
    skb_reserve(new_skb, sizeof(SDIO_H));
    #endif

    ccci_header = (CCCI_BUFF_T *)skb_put(new_skb, sizeof(CCCI_BUFF_T)) ;

    if(copy_from_user(skb_put(new_skb, count), buf, count))
    {
        DBGLOG(IPCD, ERR, "[TX]PORT%d copy_from_user(len=%d, %p->%p) fail", \
		port_id, count, buf, new_skb->data);
        dev_kfree_skb(new_skb);
        ret = -EFAULT;
        goto _exit;
    }

    ilm = (ipc_ilm_t*)((char*)ccci_header + sizeof(CCCI_BUFF_T));
    /* Check IPC extq_id */
	if ((id_map=local_MD_id_2_unify_id(ilm->dest_mod_id))==NULL)
	{
		DBGLOG(IPCD,ERR,"Invalid dest_mod_id=%d",ilm->dest_mod_id);
		dev_kfree_skb(new_skb);
		ret=-EINVAL;
		goto _exit;
	}
    
    /* user bring down the payload only */
    ccci_header->data[1]    = count + sizeof(CCCI_BUFF_T);
    ccci_header->reserved   = id_map->extq_id;
    ccci_header->channel    = eemcs_ipc_inst.ccci_ch.tx;

    DBGLOG(IPCD,TRA,"ipc_write: PORT%d CCCI_MSG(0x%08X, 0x%08X, %02d, 0x%08X)", 
                    port_id, 
                    ccci_header->data[0], ccci_header->data[1],
                    ccci_header->channel, ccci_header->reserved);

  
    ret = ccci_ch_write_desc_to_q(ccci_header->channel, new_skb);

	if (KAL_SUCCESS != ret) {
		DBGLOG(IPCD,ERR,"PORT%d PKT DROP of ch%d!", port_id, ccci_header->channel);
		dev_kfree_skb(new_skb);
        ret = -EAGAIN;
	} else {
        atomic_inc(&curr_node->tx_pkt_cnt);
        wake_up(&curr_node->tx_waitq); /* wake up tx_waitq for notify poll_wait of state change */
	}

_exit:
    DEBUG_LOG_FUNCTION_LEAVE;
    if(!ret){
        return count;
    }
    return ret;
}
ssize_t eemcs_ipc_kern_write(ipc_ilm_t *in_ilm){
    ssize_t ret   = 0;
    eemcs_ipc_node_t *curr_node = NULL;
    KAL_UINT8 node_id = 0;
    KAL_UINT8 port_id = eemcs_ipc_inst.eemcs_port_id; /* port_id */
    KAL_UINT32 p_type, control_flag;    
    struct sk_buff *new_skb;
    CCCI_BUFF_T *ccci_header;
    ipc_ilm_t *ilm=NULL;
    IPC_MSGSVC_TASKMAP_T *id_map;
    size_t count = sizeof(ipc_ilm_t);
    size_t skb_alloc_size;
    char * addr;
    int i = 0;
    DEBUG_LOG_FUNCTION_ENTRY;
    
    // src module id check
    node_id =(KAL_UINT8) (in_ilm->src_mod_id & (~AP_UNIFY_ID_FLAG)); // source id is ap side txq_id
    if (node_id >= EEMCS_IPCD_MAX_NUM){
        DBGLOG(IPCD, ERR, "invalid src_mod_id=0x%x", in_ilm->src_mod_id);
        ret = -EINVAL;
        goto _exit;
    }
    curr_node = (eemcs_ipc_node_t *)&eemcs_ipc_inst.ipc_node[node_id];
    node_id = curr_node->ipc_node_id;/* node_id */
    if (atomic_read(&curr_node->dev_state) != IPCD_KERNEL){
        DBGLOG(IPCD, ERR, "invalid dev_state(not IPCD_KERNEL), src_mod_id=0x%x", in_ilm->src_mod_id);
        ret = -EINVAL;
        goto _exit;
    }

    p_type = ccci_get_port_type(port_id);
    if(p_type != EX_T_USER) 
    {
        DBGLOG(IPCD, ERR, "PORT%d refuse port(%d) access user port", port_id, p_type);
        ret=-EINVAL;
        goto _exit;                    
    }
	
    control_flag = ccci_get_port_cflag(port_id);
    if (check_device_state() == EEMCS_EXCEPTION) {//modem exception		
        if ((control_flag & TX_PRVLG2) == 0) {
            DBGLOG(IPCD, TRA, "[TX]PORT%d kernel write fail when modem exception", port_id);
            return -ETXTBSY;
        }
    } else if (check_device_state() != EEMCS_BOOTING_DONE) {//modem not ready
        if ((control_flag & TX_PRVLG1) == 0) {
            DBGLOG(IPCD, TRA, "[TX]PORT%d kernel write fail when modem not ready", port_id);
            return -ENODEV;
        }
    }

    DBGLOG(IPCD, INF, "[TX][KERN]iminor=%d src=0x%x dest=0x%x sap=0x%x msg_id=0x%x local_ptr=%#X peer_ptr=%#X",\
                node_id, \
                (unsigned int)in_ilm->src_mod_id, (unsigned int)in_ilm->dest_mod_id, \
                (unsigned int)in_ilm->sap_id, (unsigned int)in_ilm->msg_id, \
                (unsigned int)in_ilm->local_para_ptr, (unsigned int)in_ilm->peer_buff_ptr);

    if(in_ilm->local_para_ptr != NULL){
        count = sizeof(ipc_ilm_t) + in_ilm->local_para_ptr->msg_len;		
        DBGLOG(IPCD, DBG, "[TX][KERN]ilm_len=%d local_len=%d msg_len=%d", \
		sizeof(ipc_ilm_t), sizeof(local_para_struct), count);
    }
	
    if((control_flag & EXPORT_CCCI_H) && (count < sizeof(CCCI_BUFF_T)))
    {
        DBGLOG(IPCD, ERR, "invalid wirte_len(%d) of PORT%d", count, port_id);
        ret=-EINVAL;
        goto _exit;            
    }

    if(control_flag & EXPORT_CCCI_H){
        if(count > (MAX_TX_BYTE+sizeof(CCCI_BUFF_T))){
            DBGLOG(IPCD, WAR, "PORT%d wirte_len(%d)>MTU(%d)", port_id, count, MAX_TX_BYTE);
            count = MAX_TX_BYTE+sizeof(CCCI_BUFF_T);
        }
        skb_alloc_size = count - sizeof(CCCI_BUFF_T);
    }else{
        if(count > MAX_TX_BYTE){
            DBGLOG(IPCD, WAR, "PORT%d wirte_len(%d)>MTU(%d)", port_id, count, MAX_TX_BYTE);
            count = MAX_TX_BYTE;
        }
        skb_alloc_size = count;
    }

    if (ccci_ch_write_space_alloc(eemcs_ipc_inst.ccci_ch.tx)==0){
        DBGLOG(IPCD, WAR, "PORT%d write return 0)", port_id);
        ret = -EAGAIN;
        goto _exit;
    }	
    
    new_skb = ccci_ipc_mem_alloc(skb_alloc_size + CCCI_IPC_HEADER_ROOM, GFP_ATOMIC);
    if(NULL == new_skb)
    {
        DBGLOG(IPCD, ERR, "[TX]PORT%d alloc skb fail", port_id);
        ret = -ENOMEM;
        goto _exit;            
    }
    
    /* reserve SDIO_H header room */
    #ifdef CCCI_SDIO_HEAD
    skb_reserve(new_skb, sizeof(SDIO_H));
    #endif

    ccci_header = (CCCI_BUFF_T *)skb_put(new_skb, sizeof(CCCI_BUFF_T)) ;

    memcpy(skb_put(new_skb, sizeof(ipc_ilm_t)), in_ilm, sizeof(ipc_ilm_t));

    count = in_ilm->local_para_ptr->msg_len;
    memcpy(skb_put(new_skb, count), in_ilm->local_para_ptr, count);

    ilm = (ipc_ilm_t*)((char*)ccci_header + sizeof(CCCI_BUFF_T));
    for (i=0; i<count+sizeof(ipc_ilm_t); i++) {
        addr = (char *)ilm;
        DBGLOG(IPCD, DBG, "%p=%x", (addr+i), *(addr+i));
    }
    /* Check IPC extq_id */
    if ((id_map=local_MD_id_2_unify_id(ilm->dest_mod_id))==NULL)
    {
        DBGLOG(IPCD,ERR,"Invalid dest_mod_id=%d",ilm->dest_mod_id);
        dev_kfree_skb(new_skb);
        ret=-EINVAL;
        goto _exit;
    }
    
    /* user bring down the payload only */
    ccci_header->data[1]    = count + sizeof(CCCI_BUFF_T);
    ccci_header->reserved   = id_map->extq_id;
    ccci_header->channel    = eemcs_ipc_inst.ccci_ch.tx;

    DBGLOG(IPCD, DBG, "[TX][KERN]PORT%d CCCI_MSG(0x%08X, 0x%08X, %02d, 0x%08X)", 
                    port_id, 
                    ccci_header->data[0], ccci_header->data[1],
                    ccci_header->channel, ccci_header->reserved);

  
    ret = ccci_ch_write_desc_to_q(ccci_header->channel, new_skb);

    if (KAL_SUCCESS != ret) {
        DBGLOG(IPCD, ERR, "PKT DROP of ch%d!",ccci_header->channel);
        dev_kfree_skb(new_skb);
        ret = -EAGAIN;
    } else {
        atomic_inc(&curr_node->tx_pkt_cnt);
        wake_up(&curr_node->tx_waitq); /* wake up tx_waitq for notify poll_wait of state change */
    }

_exit:
    DEBUG_LOG_FUNCTION_LEAVE;
    if(!ret){
        return count;
    }
    return ret;    
}
Example #8
0
static long eemcs_cdev_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
{
    eemcs_cdev_node_t *curr_node = (eemcs_cdev_node_t *)fp->private_data;
    KAL_UINT8 port_id = curr_node->eemcs_port_id; /* port_id */
    int ret = 0;
    unsigned int sim_type;
    unsigned int enable_sim_type;

    DEBUG_LOG_FUNCTION_ENTRY;
    if(port_id > END_OF_CCCI_CDEV)
    {
        DBGLOG(CHAR, ERR, "ccci ioctl fail: unknown Port id=%d", port_id);
        ret = -ENOTTY;
        goto _exit;                    
    }

    switch(cmd)
    {
        case CCCI_IOC_GET_MD_STATE:
        {
            KAL_UINT32  eemcs_state, md_state;

            eemcs_state = check_device_state();
            if(eemcs_state == EEMCS_BOOTING_DONE ){
				md_state = MD_STATE_READY;
            }else if(eemcs_state == EEMCS_EXCEPTION){
				md_state = MD_STATE_EXPT;
            }else if(eemcs_state <= EEMCS_INIT){
				md_state = MD_STATE_INVALID;
            }else{
				 md_state = MD_STATE_INIT;
            }
            ret = put_user((unsigned int)md_state, (unsigned int __user *)arg);
            DBGLOG(CHAR, DBG, "CCCI_IOC_GET_MD_STATE(md_s=%d, eemcs_s=%d) by %s(%d)", md_state, eemcs_state, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
            }
            break;

        case CCCI_IOC_SET_EXCEPTION_DATA:
        {
            DBGLOG(CHAR, ERR, "CCCI_IOC_SET_EXCEPTION_DATA by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id);
#if 0
            extern EX_LOG_T md_ex_log;
            void __user *argp = (void __user *)arg;
            if(copy_from_user(&md_ex_log,argp,MD_EX_LOG_SIZE))
            {
                 DBGLOG(PORT,ERR,"copy_from_user failed.");
                 return -EFAULT;
            }
            md_exception(&md_ex_log);
#endif		
        }
        break;

        case CCCI_IOC_SET_HEADER:
        {
            KAL_UINT32 ori_port_flag = 0;
            KAL_UINT32 new_port_flag = 0;
            //port->control_flag |=PORT_EXPORT_CCIF_BUFFER;
            ori_port_flag = ccci_get_port_cflag(port_id);
            ccci_set_port_type(port_id, (ori_port_flag|EXPORT_CCCI_H));
            new_port_flag = ccci_get_port_cflag(port_id);
            DBGLOG(CHAR, DBG, "CCCI_IOC_SET_HEADER(%d, %d) by %s(%d)", ori_port_flag, new_port_flag,\
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
        }
        break;

        case CCCI_IOC_CLR_HEADER:
        {
            //port->control_flag &=(~PORT_EXPORT_CCIF_BUFFER);
            KAL_UINT32 ori_port_flag = 0;
            KAL_UINT32 new_port_flag = 0;

            ori_port_flag = ccci_get_port_cflag(port_id);
            ccci_set_port_type(port_id, (ori_port_flag&(~EXPORT_CCCI_H)));
            new_port_flag = ccci_get_port_cflag(port_id);
            DBGLOG(CHAR, DBG, "CCCI_IOC_CLR_HEADER(%d, %d) by %s(%d)", ori_port_flag, new_port_flag, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
            
        }
        break;

        /* This ioctl will be issued from RILD */
        case CCCI_IOC_ENTER_DEEP_FLIGHT:
        case CCCI_IOC_SEND_STOP_MD_REQUEST: 
        {
            DBGLOG(CHAR, INF, "IOTCL CCCI_IOC_ENTER_DEEP_FLIGHT by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            change_device_state(EEMCS_GATE);
            eemcs_power_off_md(0, 0);
            /* mtlte_sys_sdio_remove */
            eemcs_cdev_msg(CCCI_PORT_CTRL, CCCI_MD_MSG_ENTER_FLIGHT_MODE, 0);
           
        }
        break;

        case CCCI_IOC_LEAVE_DEEP_FLIGHT:
        case CCCI_IOC_SEND_START_MD_REQUEST:
        {
            DBGLOG(CHAR, INF, "CCCI_IOC_LEAVE_DEEP_FLIGHT by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            eemcs_cdev_msg(CCCI_PORT_CTRL, CCCI_MD_MSG_LEAVE_FLIGHT_MODE, 0);
        }
        break;

        case CCCI_IOC_FORCE_MD_ASSERT:
        {
            DBGLOG(CHAR, INF, "CCCI_IOC_FORCE_MD_ASSERT by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            /* force md assert channel is 20090215 */
            eemcs_cdev_write_force_md_rst();
            //CCCI_INIT_MAILBOX(&buff, 0);
            //ret = ccci_write_force(CCCI_FORCE_RESET_MODEM_CHANNEL, &buff);
        }
        break;

        case CCCI_IOC_MD_RESET:
        {
            DBGLOG(CHAR, INF, "CCCI_IOC_MD_RESET by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            eemcs_md_reset();
        }
        break;

        case CCCI_IOC_CHECK_STATE:
        {
            KAL_UINT32  state;
            state = check_device_state();
            DBGLOG(CHAR, INF, "CCCI_IOC_CHECK_STATE(%d) by %s(%d)", state, ccci_cdev_name[PORT2IDX(port_id)], port_id); 
            ret = put_user((unsigned int)state, (unsigned int __user *)arg);
        }
        break;
         
#ifdef IT_TESTING_PURPOSE   
        case CCCI_IOC_PURGE_SKBQ:
        {
            struct sk_buff *skb;
            while ((skb = skb_dequeue(&eemcs_cdev_inst.cdev_node[PORT2IDX(port_id)].rx_skb_list)) != NULL) {
				dev_kfree_skb(skb);	
				eemcs_ccci_release_rx_skb(port_id, 1, skb);
            }
            atomic_set(&eemcs_cdev_inst.cdev_node[PORT2IDX(port_id)].rx_pkt_cnt, 0);
            DBGLOG(CHAR, INF, "CCCI_IOC_PURGE_SKBQ by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id);         
        }
        break;
#endif

        case CCCI_IOC_GET_EXT_MD_POST_FIX:
        {
            eemcs_boot_get_ext_md_post_fix((char*) arg);
            DBGLOG(CHAR, INF, "CCCI_IOC_GET_MD_POSTFIX(%s) by %s(%d)", (char*)arg, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
        }
        break;

        case CCCI_IOC_SET_BOOT_STATE:
        {
            KAL_UINT32  state = 0;
            get_user(state, (unsigned int __user *)arg);
            state = eemcs_boot_reset_test(state);
            DBGLOG(CHAR, INF, "CCCI_IOC_SET_BOOT_STATE(%d) by %s(%d)", state, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
        }
        break;

        case CCCI_IOC_GET_BOOT_STATE:
        {
            KAL_UINT32  state = 0;
            
            state = eemcs_boot_get_state();
            ret = put_user((unsigned int)state, (unsigned int __user *)arg);
            DBGLOG(CHAR, INF, "CCCI_IOC_GET_BOOT_STATE(%d) by %s(%d)", state, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
        }
        break;
       
        case CCCI_IOC_GET_MD_IMG_EXIST:
        {
            unsigned int *md_img_exist_list = eemcs_get_md_img_exist_list();
            DBGLOG(CHAR, INF,"CCCI_IOC_GET_MD_IMG_EXIST by %s(%d)", ccci_cdev_name[PORT2IDX(port_id)], port_id);
            if (copy_to_user((void __user *)arg, md_img_exist_list,(unsigned int)eemcs_get_md_img_exist_list_size())) {
				DBGLOG(CHAR, ERR, "CCCI_IOC_GET_MD_IMG_EXIST: copy_to_user fail");
				ret= -EFAULT;
            }
        }
        break;
            
        case CCCI_IOC_GET_MD_TYPE:
        {
            int md_type = get_ext_modem_support(eemcs_get_md_id());
            DBGLOG(CHAR, INF, "CCCI_IOC_GET_MD_TYPE(%d) by %s(%d)", md_type, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
            ret = put_user((unsigned int)md_type, (unsigned int __user *)arg);
        }
        break;
            
        case CCCI_IOC_RELOAD_MD_TYPE:
        {
            int md_type = 0;
    		if(copy_from_user(&md_type, (void __user *)arg, sizeof(unsigned int))) {
				DBGLOG(CHAR, ERR, "CCCI_IOC_RELOAD_MD_TYPE: copy_from_user fail!");
				ret = -EFAULT;
                break;
			} 
            
            if (md_type >= modem_lwg && md_type <= modem_ltg){
                DBGLOG(CHAR, INF, "CCCI_IOC_RELOAD_MD_TYPE(%d) by %s(%d)", md_type, \
					ccci_cdev_name[PORT2IDX(port_id)], port_id);
			    ret = set_ext_modem_support(eemcs_get_md_id(), md_type);
            }
            else{
                DBGLOG(CHAR, ERR, "CCCI_IOC_RELOAD_MD_TYPE fail: invalid md type(%d)", md_type);
                ret = -EFAULT;
            }
            eemcs_set_reload_image(true);
	    }
        break;

        case CCCI_IOC_STORE_MD_TYPE:
        {
            unsigned int md_type_saving = 0;
			//DBGLOG(CHAR, INF, "IOC_STORE_MD_TYPE ioctl by %s!",  current->comm);
			if(copy_from_user(&md_type_saving, (void __user *)arg, sizeof(unsigned int))) {
				DBGLOG(CHAR, ERR, "CCCI_IOC_STORE_MD_TYPE: copy_from_user fail!");
				ret = -EFAULT;
                break;
			}
			
			DBGLOG(CHAR, DBG, "CCCI_IOC_STORE_MD_TYPE(%d) by %s(%s,%d)", md_type_saving, current->comm,\
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
			if (md_type_saving >= modem_lwg && md_type_saving <= modem_ltg){
				if (md_type_saving != get_ext_modem_support(eemcs_get_md_id())){
					DBGLOG(CHAR, INF, "CCCI_IOC_STORE_MD_TYPE(%d->%d)", md_type_saving, get_ext_modem_support(eemcs_get_md_id()));
				}
				//Notify md_init daemon to store md type in nvram
				eemcs_cdev_msg(CCCI_PORT_CTRL, CCCI_MD_MSG_STORE_NVRAM_MD_TYPE, md_type_saving);
			}
			else {
				DBGLOG(CHAR, ERR, "CCCI_IOC_STORE_MD_TYPE fail: invalid md type(%d)", md_type_saving);
                ret = -EFAULT;
			}
			
	    }
		break;
           
        case CCCI_IOC_GET_MD_EX_TYPE:
        {
            int md_expt_type = get_md_expt_type();
            DBGLOG(CHAR, INF, "CCCI_IOC_GET_MD_EX_TYPE(%d) by %s(%d)", md_expt_type, \
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
			ret = put_user((unsigned int)md_expt_type, (unsigned int __user *)arg);
        }
        break;
		
        case CCCI_IOC_DL_TRAFFIC_CONTROL:
        {
            unsigned int traffic_control = 0;
            
            if(copy_from_user(&traffic_control, (void __user *)arg, sizeof(unsigned int))) {
                DBGLOG(CHAR, ERR, "CCCI_IOC_DL_TRAFFIC_CONTROL: copy_from_user fail!");
                ret = -EFAULT;
                break;
            }
			
            DBGLOG(CHAR, INF, "CCCI_IOC_DL_TRAFFIC_CONTROL(%d) by %s(%d)", traffic_control,\
				ccci_cdev_name[PORT2IDX(port_id)], port_id);
            if(traffic_control == 1)
            {
                ccci_cdev_turn_on_dl_q(port_id);
            }
            else if(traffic_control == 0)
            {
                ccci_cdev_turn_off_dl_q(port_id);
            }
            else 
            {
                DBGLOG(CHAR, ERR, "CCCI_IOC_DL_TRAFFIC_CONTROL fail: Unknown value(0x%x)", traffic_control);
                ret = -EFAULT;
            }
	    }
        break;    

		case CCCI_IOC_GET_SIM_TYPE: 		//for regional phone boot animation
		{
			get_sim_type(eemcs_get_md_id(), &sim_type);
			ret = put_user((unsigned int)sim_type, (unsigned int __user *)arg);
		}
		break;
		
		case CCCI_IOC_ENABLE_GET_SIM_TYPE:	//for regional phone boot animation
		{
			if(copy_from_user(&enable_sim_type, (void __user *)arg, sizeof(unsigned int))) {
				DBGLOG(CHAR, ERR, "CCCI_IOC_ENABLE_GET_SIM_TYPE: copy_from_user fail!\n");
				ret = -EFAULT;
			} else {
				enable_get_sim_type(eemcs_get_md_id(), enable_sim_type);
			}
		}
		break;          

        default:
            DBGLOG(CHAR, ERR, "Unknown ioctl(0x%x) by %s(%d)", cmd, ccci_cdev_name[PORT2IDX(port_id)], port_id);
            ret = -EFAULT;
        	break;
    }

_exit:
    DEBUG_LOG_FUNCTION_LEAVE;
    return ret;
}