📄 dm9000end.c
字号:
return (ERROR);
}
/*
* If you need clusters to store received packets into then get them
* here ahead of time.
*/
if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool,
(END_BUFSIZ), FALSE))
== NULL)
{
printf("Could not init Memory setup complete!\n");
return (ERROR);
}
return OK;
}
/*******************************************************************************
*
* dm9000Start - start the device
*
* This function calls BSP functions to connect interrupts and start the
* device running in interrupt mode.
*
* RETURNS: OK or ERROR
*
*/
static STATUS dm9000Start( END_DEVICE * pDrvCtrl ) /* device ID */
{
STATUS result;
/* sysEndIsrLink.arg = (int)pDrvCtrl;*/
/*
SYS_INT_CONNECT (pDrvCtrl, dm9000Int, (int)pDrvCtrl, &result);
*/
result = intConnect(IV_IRQ1,dm9000Int,(int)pDrvCtrl);/*IV_IRQ1*/
/*result = intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec), \
dm9000Int, 0);*/
if (result == ERROR)
{
printf("interrupt connect error\n");
return ERROR;
}
/* SYS_INT_ENABLE (pDrvCtrl);*/
/* sysIntEnablePIC (pDrvCtrl->ilevel);*/
/* TODO - start the device, enabling interrupts */
/* Activate DM9000 */
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0x05, DM9000_REG05 | 1);
DM9000A_write_reg(0xff, DM9000_REGFF);
return (OK);
}
/*******************************************************************************
*
* dm9000Int - handle controller interrupt
*
* This routine is called at interrupt level in response to an interrupt from
* the controller.
*
* RETURNS: N/A.
*/
UINT32 EnterInterCount = 0;
static void dm9000Int( END_DEVICE *pDrvCtrl ) /* interrupting device */
{
UCHAR stat, reg_save, isr_status, nsr_status; /* tx_status, */
/*if( !PIC_CHECK_EXT1() )
return;
PIC_CLEAR_EXT1();*/
/* TODO */
/* Save previous register address */
/*2007-4-18 shengdegang modify remove sysIntEnablePIC*/
sysIntDisablePIC (pDrvCtrl->ilevel);
/*end*/
/*2007-4-11 shengdegang modify*/
reg_save = DM9000_IN_ADDR();
/* Disable all interrupt */
/*DM9000_OUT_CHAR( 0x05, 0x00 );*/
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xff,0x80);
/* DM9000_OUT_CHAR( 0xff, 0x80 );*/
/* Read the device status register */
/*2007-4-19 shengdegang remove*/
stat = dm9000StatusRead (pDrvCtrl);
/*end*/
/* Clear NSR status */
/*2007-4-11 shengdegang modify*/
nsr_status=DM9000A_read_reg(0x1);
/* DM9000_IN_CHAR( 0x01, nsr_status );*/
/* Clear ISR status */
/*2007-4-11 shengdegang modify*/
isr_status=DM9000A_read_reg(0xfe);
/* DM9000_IN_CHAR( 0xfe, isr_status );*/
/*2007-4-11 shengdegang modify*/
#if 1
DM9000A_write_reg(0xfe, isr_status);
#endif
/* DM9000_OUT_CHAR( 0xfe, isr_status );*/
if( (!(nsr_status & 0x40)) || (pDrvCtrl->device_wait_reset == 1) )
{
printf("the interrupt can dispose!\n");
netJobAdd ((FUNCPTR) muxError, (int) &(pDrvCtrl->end),
(int) &(pDrvCtrl->err), 0, 0, 0);
netJobAdd ((FUNCPTR)dm9000needreset, (int)(pDrvCtrl),
0, 0, 0, 0);
goto intRet;
}
/*
* enable interrupts, clear receive and/or transmit interrupts, and clear
* any errors that may be set.
*/
/* TODO - Check for errors */
/* Have netTask handle any input packets */
if( (isr_status & 1 ))/*&&(stat & DM9000_RXON) )*/
{
if ( pDrvCtrl->rxHandling != TRUE )
{
pDrvCtrl->rxHandling = TRUE;
/*dm9000HandleRcvInt(pDrvCtrl);*/
netJobAdd ((FUNCPTR)dm9000HandleRcvInt, (int)pDrvCtrl,
0,0,0,0);
#if 0
DRV_SP( DRV_PK,"^" );
#endif
}
}
/* TODO - handle transmit interrupts */
if( isr_status & 2 )
{
/* Trnasmit Interrupt check */
/*DM9000_IN_CHAR( 0x01, tx_status ); Got TX status */
/*if( tx_status & 0xc) */
if( pDrvCtrl->tx_pkt_cnt > 0 )
{
/* One packet sent complete */
pDrvCtrl->tx_pkt_cnt--;
/* Queue packet check & send */
if( pDrvCtrl->tx_pkt_cnt > 0)
{
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xfc, pDrvCtrl->queue_pkt_len & 0xff);
DM9000A_write_reg(0xfd, (pDrvCtrl->queue_pkt_len >> 8) & 0xff);
DM9000A_write_reg(0x2, 0x1);
}
}
}
intRet:
/* Re-enable interrupt mask */
/* DM9000_OUT_CHAR( 0xff, 0x83 );*/
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xff, 0x83);
/*DM9000_OUT_CHAR( 0x05, 0x11 );*/
/* Restore previous register address */
DM9000_OUT_ADDR( reg_save );
/*2007-4-18 shengdegang modify remove sysIntEnablePIC*/
sysIntEnablePIC (pDrvCtrl->ilevel);
/*end*/
}
/*******************************************************************************
*
* dm9000PacketGet - get next received message
*
* Get next received message. Returns NULL if none are
* ready.
*
* RETURNS: ptr to next packet, or NULL if none ready.
*/
STATUS dm9000PacketGet( END_DEVICE *pDrvCtrl)
{
UCHAR rxbyte;
/* UWORD RxStatus,RxLen;
unsigned char temp[10];*/
/* TODO - get next received packet */
/* Check packet ready or not */
/*2007-4-11 shengdegang modify*/
rxbyte=DM9000A_read_reg(0xf0);
/* printf("get packet the rxbyte is %x\n",rxbyte);*/
/*2007-4-11 shengdegang modify */
/*只需读一次F0H*/
rxbyte=DM9000A_read_reg(0xf0);
/* printf("get packet the rxbyte1 is %x\n",rxbyte);*/
/*modify end*/
/* DM9000_IN_CHAR( 0xf0, rxbyte ); *//* Dummy read */
/* DM9000_IN_CHAR( 0xf0, rxbyte ); *//* Got most updated data */
/* packet ready to receive check */
/* if( (rxbyte&0x01) == DM9000_PKT_RDY )*/
if( rxbyte == DM9000_PKT_RDY )
{
return OK;
}
/*2007-4-18 shengdegang add */
/* tempaddr = *DM9000A_Addr_PORT;
printf("error read address 0x%x\n",tempaddr);*/
#if 0
DM9000A_write_reg(0x05, 0x00);
DM9000A_write_reg(0xfe, 0x0f);
DM9000A_write_reg(0xff, 0x80);
dm9000Reset( pDrvCtrl );
dm9000Config( pDrvCtrl );
/*add end*/
#endif
return ERROR;
}
/*******************************************************************************
*
* dm9000Recv - process the next incoming packet
*
* Handle one incoming packet. The packet is checked for errors.
*
* RETURNS: N/A.
*/
static STATUS dm9000Recv( END_DEVICE *pDrvCtrl, /* device structure */
char* pData ) /* packet to process */
{
char* pClusterData;
M_BLK_ID pMblk;
char* pNewCluster;
CL_BLK_ID pClBlk;
PKT skb;
/* char i,temp1[20];*/
/* TODO - Packet must be checked for errors. */
/* Add one to our unicast data.
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); */
/*
* We implicitly are loaning here, if copying is necessary this
* step may be skipped, but the data must be copied before being
* passed up to the protocols.
*/
pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);
if (pNewCluster == NULL)
{
printf ("the pNewCluster is NULL!\n");
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
/* Grab a cluster block to marry to the cluster we received. */
if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)
{
printf ("Out of Cluster Blocks!\n");
netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
/*
* OK we've got a spare, let's get an M_BLK_ID and marry it to the
* one in the ring.
*/
if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
{
printf ("Out of M Blocks!\n");
netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);
netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);
/* align IP header at 32-bit boundary, this is reqired by VxWorks
** TCP/IP stack
*/
pClusterData = (char*)((((unsigned long)pNewCluster + 1) & (~1)) | 2 );
/* move packet from Ethernet on-board SRAM to the mbuf pre-allocated
** in system memory
*/
skb.pData = pClusterData;
skb.len = 0;
if( dmfe_packet_receive( (PKT*)(&skb), pDrvCtrl ) )
{
printf("no data!\n");
mBlkFree (pDrvCtrl->end.pNetPool, pMblk);
netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);
netClFree (pDrvCtrl->end.pNetPool, pNewCluster);
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
goto cleanRXD;
}
#if 1
/*pCluster = END_CACHE_PHYS_TO_VIRT (pData); */
/* Join the cluster to the MBlock */
/*netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);*/
netClBlkJoin (pClBlk, pNewCluster, skb.len, NULL, 0, 0, 0);
netMblkClJoin (pMblk, pClBlk);
/*netMblkToBufCopy();*/
pMblk->mBlkHdr.mData = pClusterData;
pMblk->mBlkHdr.mLen = skb.len;
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkPktHdr.len = skb.len;
/* make the packet data coherent */
END_CACHE_INVALIDATE (pMblk->mBlkHdr.mData, skb.len);
/* TODO - Done with processing, clean up and pass it up. */
/* Call the upper layer's receive routine. */
END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);
/* DM9000_OUT_CHAR( 0x05, DM9000_REG05 ); */ /* RX disable */
/*DM9000_OUT_CHAR( 0xff, 80 ); */ /* disable TX/RX interrupt mask */
END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);
/* i=1;
if (pDrvCtrl->end.receiveRtn)
i = pDrvCtrl->end.receiveRtn(&pDrvCtrl->end, pMblk);*/
#endif
/*DM9000_OUT_CHAR( 0x05, DM9000_REG05 | 1 ); */ /* RX enable */
/*DM9000_OUT_CHAR( 0xff, DM9000_REGFF ); */ /* Enable TX/RX interrupt mask */
/*DM9000A_write_reg( 0xff, 0x83 );*/
return (OK);
cleanRXD:
return (ERROR);
}
/*******************************************************************************
*
* dm9000HandleRcvInt - task level interrupt service for input packets
*
* This routine is called at task level indirectly by the interrupt
* service routine to do any message received processing.
*
* The double loop is to protect against a race condition where the interrupt
* code see rxHandling as TRUE, but it is then turned off by task code.
* This race is not fatal, but does cause occassional delays until a second
* packet is received and then triggers the netTask to call this routine again.
*
* RETURNS: N/A.
*/
static void dm9000HandleRcvInt( END_DEVICE *pDrvCtrl ) /* interrupting device */
{
/* unsigned char temp[8];*/
/* DRV_LOG (0xFFFF, "dm9000HandleRcvInt()_IN", 1, 2, 3, 4, 5, 6);*/
/* do*/
/* {*/
pDrvCtrl->rxHandling = TRUE;
/* DM9000A_write_reg( 0xff, 0x80 );*/
while (OK==dm9000PacketGet (pDrvCtrl))
{
if(dm9000Recv (pDrvCtrl, (char*)NULL ) == ERROR)
{
printf("get recv packet error SDG\n");
break;
}
}
pDrvCtrl->rxHandling = FALSE;
/* }while (dm9000PacketGet (pDrvCtrl) != NULL); */
/* DRV_LOG (0xFFFF, "dm9000HandleRcvInt()_OUT", 1, 2, 3, 4, 5, 6);*/
}
/*******************************************************************************
*
* dm9000Send - the driver send routine
*
* This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.
* The buffer must already have the addressing information properly installed
* in it. This is done by a higher layer. The last arguments are a free
* routine to be called when the device is done with the buffer and a pointer
* to the argument to pass to the free routine.
*
* RETURNS: OK, ERROR, or END_ERR_BLOCK.
*/
static STATUS dm9000Send( END_DEVICE * pDrvCtrl, /* device ptr */
M_BLK_ID pMblk ) /* data to send */
{
int oldLevel = 0;
BOOL freeNow = TRUE;
PKT skb;
int len;
/*
* Obtain exclusive access to transmitter. This is necessary because
* we might have more than one stack transmitting at once.
*/
pDrvCtrl->flags=0x2;
if (!((pDrvCtrl->flags) & DM9000_POLLING))
{
printf("is DM9000_POLLING send!\n");
END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);
}
/* This is the normal case where all the data is in one M_BLK_ID */
/* Set pointers in local structures to point to data. */
/*
* If no buffers are available,
* release the semaphore and return END_ERR_BLOCK.
* Do not free packet
*/
/* place a transmit request */
/*if (!((pDrvCtrl->flags) & DM9000_POLLING))*/
oldLevel = intLock (); /* protect dm9000Int */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -