⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rndisdev.c

📁 基于TI DSP/BIOS的usb网卡的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    struct usb_ep_general * ep = &( dev->out_ep );
    struct generic_trans * trans = ep->trans;    
    struct rndis_packet_msg_type * msg = ( struct rndis_packet_msg_type *)trans->dataBuffer;
    u8 len, bufs, ep_last;

    ep_last = Hal4D13_GetEndpointStatusWInteruptClear( ep->index );   
    if(( ep_last & 0x60 ) == 0x60 )
        bufs = 2;
    else
        bufs = 1;

    while( bufs )
    {
        if( ep->status == EP_STATUS_IDLE )
        { /*begin packet receive*/
            len = Hal4D13_ReadEndpoint( ep->index, trans->dataBuffer, BULK_PACKET_SIZE );     
            if( ( len >= sizeof( struct rndis_packet_msg_type ))
                && ( msg->MessageType == REMOTE_NDIS_PACKET_MSG )
                && ( msg->MessageLength > sizeof( struct rndis_packet_msg_type ) )
                && ( msg->MessageLength < MAX_PACKET_BUFFER_SIZE )
                && ( msg->DataLength > ETH_HLEN ) 
                && ( msg->DataLength < USB_RNDIS_MTU ) )
            {
                if( len < BULK_PACKET_SIZE )
                { /*packet receive over*/
                    rndisdev_on_rxpacket( dev, trans->dataBuffer + msg->DataOffset + 8, msg->DataLength );
                    ep->status = EP_STATUS_IDLE;
                }
                else
                { /*start proceeding receive*/               
                    ep->status = EP_STATUS_OUT;
                    trans->dataLength = msg->MessageLength;
                    trans->transmitLength = len;                
                }           
            }  
            else
                ep->status = EP_STATUS_IDLE;
        }
        else if( ep->status == EP_STATUS_OUT )
        { /*packet receive in process*/
            len = Hal4D13_ReadEndpoint( ep->index, trans->dataBuffer + trans->transmitLength, BULK_PACKET_SIZE );       
            trans->transmitLength += len;
            if( ( len < BULK_PACKET_SIZE ) || ( trans->transmitLength >= trans->dataLength ) )
            { /*out transmit end*/
                rndisdev_on_rxpacket( dev, trans->dataBuffer + msg->DataOffset + 8, msg->DataLength );
                ep->status = EP_STATUS_IDLE;
            }      
        }
        else
        {
            Hal4D13_ReadEndpoint( ep->index, BufferTmp, BULK_PACKET_SIZE );  
            ep->status = EP_STATUS_IDLE;
        }

        bufs --;
        if( bufs == 1 )
            ep_last = Hal4D13_GetEndpointStatusWInteruptClear( ep->index ); // Clear interrupt flag 
    }
}

int usb_eth_send( struct ei_device * ei_local, PKT_Handle hPkt )
{
    struct rndis_dev * dev = ( struct rndis_dev *)ei_local->data;
    struct net_device_stats1 * state = & dev->stats;

    if( ! queue_tx_msg( dev, hPkt ) )
    {
        state->tx_errors ++;
        state->tx_dropped ++;    
    }

    free_skb( hPkt );  

    if( semUsbIrq )
        SEM_post( semUsbIrq );

    return 0;
}

static void config_endpoint()
{   
    Hal4D13_SetEndpointConfig( D13REG_EPCNFG_FIFO_EN | D13REG_EPCNFG_NONISOSZ_64, 
        EPINDEX4EP0_CONTROL_OUT );
    Hal4D13_SetEndpointConfig( D13REG_EPCNFG_FIFO_EN | D13REG_EPCNFG_IN_EN | D13REG_EPCNFG_NONISOSZ_64, 
        EPINDEX4EP0_CONTROL_IN );
    Hal4D13_SetEndpointConfig( D13REG_EPCNFG_FIFO_EN | D13REG_EPCNFG_IN_EN | D13REG_EPCNFG_NONISOSZ_16, 
        EPINDEX4EP01 );
    Hal4D13_SetEndpointConfig( D13REG_EPCNFG_FIFO_EN | D13REG_EPCNFG_IN_EN | D13REG_EPCNFG_NONISOSZ_64 | D13REG_EPCNFG_DBLBUF_EN, 
        EPINDEX4EP02 );
    Hal4D13_SetEndpointConfig( D13REG_EPCNFG_FIFO_EN | D13REG_EPCNFG_NONISOSZ_64 | D13REG_EPCNFG_DBLBUF_EN, EPINDEX4EP03 );

    /*disable all of the other left endpoints*/
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP04 );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP05 );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP06 );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP07 );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP08 );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP09 );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP0A );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP0B );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP0C );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP0D );
    Hal4D13_SetEndpointConfig( 0, EPINDEX4EP0E ); 

    //set interrupt enable flag
    Hal4D13_SetIntEnable( D13REG_INTSRC_EP0OUT | D13REG_INTSRC_EP0IN
        | D13REG_INTSRC_EP01 | D13REG_INTSRC_EP02 | D13REG_INTSRC_EP03
        | D13REG_INTSRC_BUSRESET | D13REG_INTSRC_RESUME | D13REG_INTSRC_SUSPEND );

    Hal4D13_SetDevConfig(
        D13REG_DEVCNFG_NOLAZYCLOCK | 
        D13REG_DEVCNFG_WAKEUPBY_CS | 
        D13REG_DEVCNFG_INTPOL );
}

//interrupt endpoint interupt envent handler
static void ep_status_handle( struct rndis_dev * dev )
{
    struct usb_ep_general * ep = & dev->status_ep;
    Hal4D13_GetEndpointStatusWInteruptClear( ep->index );     
}

static int rndisdev_control_ack ( struct rndis_dev * dev )
{
    struct usb_ep_general * ep = & dev->status_ep;
    le32  buf[2];  //data buf

    buf[0] = constant_cpu_to_le32 ( 1 );
    buf[1] = constant_cpu_to_le32 ( 0 );

    ep->status = EP_STATUS_IN;
    Hal4D13_WriteEndpoint( ep->index, ( u8 *)buf, 8 ); //ack

    return 0;
}

static u32 isp1181b_irq_handle()
{
    u32 irqs;
    u32 res = 0;
    struct rndis_dev * dev = & ethdev;

    irqs = Hal4D13_ReadInterruptRegister();    
    if( irqs & D13REG_INTSRC_BUSRESET )
    {        
        config_endpoint();
        res ++;
    }   

    if( irqs & D13REG_INTSRC_RESUME )
    {
        Hal4D13_LockDevice( 0xAA37 ); //unlock isp1181
        res ++;
    }

    if( irqs & D13REG_INTSRC_SUSPEND )
    {
        rndis_setstate( rndis_dev_index, RNDIS_UNINITIALIZED );
        res ++;     
    }

    if( irqs & D13REG_INTSRC_EP0IN )
    {
        ep_ctl_in_handle( dev );
        res ++;
    }
    if( irqs & D13REG_INTSRC_EP0OUT )
    {
        ep_ctl_out_handle( dev );
        res ++;
    }
    if( irqs & D13REG_INTSRC_EP01 )
    {
        ep_status_handle( dev );    
        res ++;
    }
    if( irqs & D13REG_INTSRC_EP02 )
    {       
        //Hal4D13_GetEndpointStatusWInteruptClear( dev->in_ep.index );
        ep_in_handle( dev );
        res ++;
    }
    if( irqs & D13REG_INTSRC_EP03 )
    {
        ep_out_handle( dev );   
        res ++;
    }
    return res;
}

void isp1181b_int()
{
    if( semUsbIrq )
        SEM_post( semUsbIrq );
}

static void isp1181_reset()
{
    Hal4D13_ResetDevice();         //reset chip
    Hal4D13_SetDevConfig( D13REG_DEVCNFG_NOLAZYCLOCK );
    config_endpoint();      
    Hal4D13_SetMode( D13REG_MODE_INT_EN | D13REG_MODE_SOFTCONNECT );
    IRQ_enable( IRQ_EVT_EXTINT5 ); //enable dsp interrupt

    //clear undetermined status
    Hal4D13_ReadInterruptRegister();
    Hal4D13_GetEndpointStatusWInteruptClear( EPINDEX4EP0_CONTROL_IN );   
    Hal4D13_GetEndpointStatusWInteruptClear( EPINDEX4EP0_CONTROL_OUT );   
    Hal4D13_GetEndpointStatusWInteruptClear( EPINDEX4EP01 );   
    Hal4D13_GetEndpointStatusWInteruptClear( EPINDEX4EP02 );   
    Hal4D13_GetEndpointStatusWInteruptClear( EPINDEX4EP03 );       
    Hal4D13_WriteEndpoint( EPINDEX4EP0_CONTROL_IN, 0, 0 );
}

void run_usb( void );

int usb_eth_init( struct ei_device * ei_local )
{
    //init data structure
    memset( & ethdev, 0, sizeof( struct rndis_dev ));
    LoopBuffInit(& ethdev.tx_queue, TX_QUEUE_SIZE, txQueueBuffer );
    ethdev.ctrl_ep.trans = & ctrltrans;
    ethdev.in_ep.trans = & intrans;
    ethdev.out_ep.trans = & outtrans;
    ethdev.ctrl_ep.index = EPINDEX4EP0_CONTROL_OUT;       
    ethdev.status_ep.index = EPINDEX4EP01;
    ethdev.in_ep.index = EPINDEX4EP02;
    ethdev.out_ep.index = EPINDEX4EP03;    
    ethdev.cdc_filter = DEFAULT_FILTER;       
    ethdev.config = 0;
    ethdev.usbstate = USB_STATE_DEFAULT;
    ethdev.ctrl_ep.status = EP_STATUS_IDLE;
    ethdev.in_ep.status = EP_STATUS_IDLE;
    ethdev.out_ep.status = EP_STATUS_IDLE;   
    ethdev.status_ep.status = EP_STATUS_IDLE;
    ethdev.mtu = USB_RNDIS_MTU; 
    memcpy( ethdev.mac, rndis_mac, 6 ); //init host size mac   
    ethdev.net = ei_local;
    ethdev.lock = usb_lock_create();
    ei_local->data = & ethdev;          

    //init rndis structure
    rndis_init();
    rndis_dev_index = rndis_register ( rndisdev_control_ack );
    rndis_set_host_mac ( rndis_dev_index, ethdev.mac );
    rndis_set_param_dev ( rndis_dev_index, & ethdev, & ethdev.stats, & ethdev.cdc_filter );
    rndis_set_param_vendor ( rndis_dev_index, VENDOR_NUM, MANUFACTURER_STRING );
    rndis_set_param_medium ( rndis_dev_index, NDIS_MEDIUM_802_3, 100000 );  //bsp

    //set hardware
    semUsbIrq = SEM_create( 0, NULL );
    isp1181_reset();  
    return 0; 
}

//dummy function
int usb_eth_set_promisc( struct ei_device * ei_local ){   return 0; }
int usb_eth_raw_send( struct ei_device * ei_local, char * buf, unsigned int len ){ return 0; }

//usb module control entry function
void run_usb( void )
{
    int len;
    while( 1 )
    {
        if( semUsbIrq )
        {
            //if( SEM_pend( semUsbIrq, 1 ) == TRUE )              
            SEM_pend( semUsbIrq, SYS_FOREVER );
            while( isp1181b_irq_handle());
            if(( ethdev.in_ep.status == EP_STATUS_IDLE ) && ( rndis_getstate( rndis_dev_index ) != RNDIS_UNINITIALIZED ) )
            {
                len = dequeue_tx_msg( & ethdev , BufferTmp );  
                if( len )
                {
                    ethdev.in_ep.status = EP_STATUS_IN;
                    rndisdev_prepare_trans( ethdev.in_ep.trans, BufferTmp, len ); 
                    ep_in_handle(& ethdev );
                }               
            }
        }
        else
            TSK_sleep( 10 ); //if not ready, sleep
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -