예제 #1
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;
    } 
예제 #2
0
static void eemcs_cdev_write_force_md_rst(void)
{
	struct sk_buff *new_skb;
	CCCI_BUFF_T *ccci_header;
	int ret;
	new_skb = ccci_cdev_mem_alloc(CCCI_CDEV_HEADER_ROOM);
	while(NULL == new_skb)
	{
	  new_skb = ccci_cdev_mem_alloc(CCCI_CDEV_HEADER_ROOM);
	}
	/* reserve SDIO_H header room */
	skb_reserve(new_skb, sizeof(SDIO_H)); 
	ccci_header = (CCCI_BUFF_T *)skb_put(new_skb, sizeof(CCCI_BUFF_T)) ; 
	ccci_header->data[0]= CCCI_MAGIC_NUM; /* message box magic */
	ccci_header->data[1]= 0;              /* message ID */
	ccci_header->channel = CCCI_FORCE_RESET_MODEM_CHANNEL;      /* reset channel number */
	ret = ccci_cdev_write_desc_to_q(CCCI_FORCE_RESET_MODEM_CHANNEL, new_skb);
}
예제 #3
0
static ssize_t eemcs_cdev_write(struct file *fp, const char __user *buf, size_t in_sz, loff_t *ppos)
{
    ssize_t ret   = -EINVAL;
    eemcs_cdev_node_t *curr_node = (eemcs_cdev_node_t *)fp->private_data;
    KAL_UINT8 port_id = curr_node->eemcs_port_id; /* port_id */
    KAL_UINT32 p_type, control_flag;    
    struct sk_buff *new_skb;
    CCCI_BUFF_T *ccci_header;
    size_t count = in_sz;
    
    DEBUG_LOG_FUNCTION_ENTRY;        
    DBGLOG(CHAR, DBG, "eemcs_cdev_write: %s(%d), len=%d",curr_node->cdev_name,port_id,count);

    p_type = ccci_get_port_type(port_id);
	if(curr_node->ccci_ch.tx == CH_DUMMY){
		/* if ccci channel is assigned to CH_DUMMY means tx packets should be dropped ex. muxreport port */
        DBGLOG(CHAR, ERR, "PORT%d is assigned to CH_DUMMY ccci channel !!PKT DROP!!", port_id);
        ret = -EINVAL;
        goto _exit;                    
	}

    if(p_type != EX_T_USER) 
    {
        DBGLOG(CHAR, ERR, "PORT%d refuse p_type(%d) access user port", port_id, p_type);
        ret = -EINVAL;
        goto _exit;                    
    }
    if(!eemcs_device_ready() && ((port_id==CCCI_PORT_META)||(port_id==CCCI_PORT_MD_LOG)))
    {
        ret= - ENODEV;
        DBGLOG(CHAR, DEF, "device not ready!");
		return ret;
    }
    control_flag = ccci_get_port_cflag(port_id);
    if((control_flag & EXPORT_CCCI_H) && (count < sizeof(CCCI_BUFF_T)))
    {
        DBGLOG(CHAR, WAR, "PORT%d wirte len not support(%d) by emcs!", port_id, count);
        ret = -EINVAL;
        goto _exit;            
    }

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

__blocking_IO:
	if (ccci_cdev_write_space_alloc(curr_node->ccci_ch.tx)==0){
        if (fp->f_flags & O_NONBLOCK) {
            ret = -EAGAIN;
            DBGLOG(CHAR, WAR, "PORT%d ccci_cdev_write_space_alloc return 0)", port_id);
            goto _exit;
        }else{ // Blocking IO
            DBGLOG(CHAR, TRA, "PORT%d Enter Blocking I/O wait", port_id);
            ret = ccci_cdev_write_wait(curr_node->ccci_ch.tx);
        	if(ret == -ERESTARTSYS) {
				DBGLOG(CHAR, WAR, "PORT%d Interrupted,return ERESTARTSYS", port_id);
				ret = -EINTR;
				goto _exit;
			}
            goto __blocking_IO;
        }
	}	
    
    new_skb = ccci_cdev_mem_alloc(count + CCCI_CDEV_HEADER_ROOM);
    if(NULL == new_skb)
    {
        ret = -ENOMEM;
        DBGLOG(CHAR, ERR, "PORT%d alloct tx memory fail(%d)", port_id, ret);
        goto _exit;  
    }
    
    /* reserve SDIO_H header room */
    skb_reserve(new_skb, sizeof(SDIO_H));

    if(control_flag & EXPORT_CCCI_H){
        ccci_header = (CCCI_BUFF_T *)new_skb->data;
    }else{
        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(CHAR, ERR, "PORT%d fail copy data from user space(%d)", port_id, count);
        dev_kfree_skb(new_skb);
        ret=-EFAULT;
        goto _exit;
    }

    if(control_flag & EXPORT_CCCI_H)
    {
        /* user bring down the ccci header */
        if(count == sizeof(CCCI_BUFF_T)){

		DBGLOG(CHAR, DBG, "eemcs_cdev_write: PORT%d, CCCI_MSG(0x%x, 0x%x, 0x%x, 0x%x)", 
                    port_id, 
                    ccci_header->data[0], ccci_header->data[1],
                    ccci_header->channel, ccci_header->reserved);

            ccci_header->data[0]= CCCI_MAGIC_NUM;
        }else{
            ccci_header->data[1]= count; 
        }

        if(ccci_header->channel != curr_node->ccci_ch.tx){
            DBGLOG(CHAR, WAR, "PORT%d Tx CCCI channel not match (%d) vs (%d)!! will correct by char_dev",\
				port_id, ccci_header->channel, curr_node->ccci_ch.tx);
        }
    }
    else
    {
        /* user bring down the payload only */
        ccci_header->data[1]    = count + sizeof(CCCI_BUFF_T);
        ccci_header->reserved   = 0;
    }
    ccci_header->channel = curr_node->ccci_ch.tx;
    
	DBGLOG(CHAR, DBG, "eemcs_cdev_write: PORT%d, CCCI_MSG(0x%x, 0x%x, 0x%x, 0x%x)", 
                    port_id, 
                    ccci_header->data[0], ccci_header->data[1],
                    ccci_header->channel, ccci_header->reserved);

/* 20130816 ian add aud dump */
    {
        char *ptr = (char *)new_skb->data;
        ptr+=sizeof(CCCI_BUFF_T);
        /* dump 32 byte of the !!!CCCI DATA!!! part */

		CDEV_LOG(port_id, CHAR, INF, "[DUMP]PORT%d eemcs_cdev_write\n\
		[00..07](0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)\n\
		[08..15](0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)\n\
		[16..23](0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)\n\
		[24..31](0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)(0x%02x)",\
		port_id,\
		(int)*(ptr+0),(int)*(ptr+1),(int)*(ptr+2),(int)*(ptr+3),(int)*(ptr+4),(int)*(ptr+5),(int)*(ptr+6),(int)*(ptr+7),\
		(int)*(ptr+8),(int)*(ptr+9),(int)*(ptr+10),(int)*(ptr+11),(int)*(ptr+12),(int)*(ptr+13),(int)*(ptr+14),(int)*(ptr+15),\
		(int)*(ptr+16),(int)*(ptr+17),(int)*(ptr+18),(int)*(ptr+19),(int)*(ptr+20),(int)*(ptr+21),(int)*(ptr+22),(int)*(ptr+23),\
		(int)*(ptr+24),(int)*(ptr+25),(int)*(ptr+26),(int)*(ptr+27),(int)*(ptr+28),(int)*(ptr+29),(int)*(ptr+30),(int)*(ptr+31));

    }
  
    ret = ccci_cdev_write_desc_to_q(curr_node->ccci_ch.tx, new_skb);

	if (KAL_SUCCESS != ret) {
		DBGLOG(CHAR, ERR, "Pkt drop of ch%d!",curr_node->ccci_ch.tx);
		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 */
	}

#if 0    
    20130102 note that 
    ret = que_wakeup_transfer(port->txq_id);
    if(ret)
    {
        DBGLOG(PORT,ERR,"PORT(%d) fail wake when write(%d)", port->id, ret);
        goto _exit;
    }   
    ret = wait_event_interruptible(port->write_waitq, port->tx_pkt_id == port->tx_pkt_id_done);
    if(ret == -ERESTARTSYS)
    {
      // TODO: error handling .....
      DBGLOG(PORT,ERR,"PORT(%d) fail wait write done event successfully", port->id);
    }
#endif
_exit:
    DEBUG_LOG_FUNCTION_LEAVE;
    if(!ret){
        return count;
    }

    ccci_cdev_write_space_release(curr_node->ccci_ch.tx);
    return ret;
}