📄 rndisdev.c
字号:
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 + -