📄 recv_main.c
字号:
for (i = 0; i < 6; i++)
*(pPkt->pDataBuffer)--;
/* Use our re-entrancy gate to call EMAC functions */
OUREMAC_enter();
i = EMAC_sendPacket( hEMAC, pPkt );
OUREMAC_exit();
if(i)
{
LOG_printf(&logTrace, "EMAC_sendPacket() returned error %08x\n",i);
break;
}
/* Bump the TX count */
TxCount++;
}
}
printf("Sent %d packets, received %d packets\n",
TxCount, RxCount);
/*
// Close EMAC
*/
close_emac:
/* Since we're done, we leave the interrupt disabled */
C64_disableIER( EMAC_INT_FLAG );
printf("Calling EMAC_close()\n");
i = EMAC_close( hEMAC );
hEMAC = 0;
if(i)
{
printf("Returned error %08x\n",i);
goto exit;
}
exit:
for(;;);
}
/*
// HwInt
//
// Interrupt service routine called as a result of
// the EMAC hardware interrupt.
*/
void HwInt(void)
{
Uint32 i;
/*
// Since our ISR is left masked by the INT dispacher, and ISR has
// a higher priority than any task, we can simply call the sevice
// function without re-entrancy concerns.
*/
if( hEMAC )
{
i = EMAC_serviceCheck( hEMAC );
if( i ) {
LOG_printf(&logTrace, "EMAC_serviceCheck() returned error %08x\n", i);
return;
}
}
return;
}
/*
// TimerTick
//
// Timer tick service routine - called from 100mS PRD
*/
void TimerTick(void)
{
/* Keep track of time for our local timeout loops */
LocalTicks++;
/* Poll the EMAC */
if( hEMAC )
{
OUREMAC_enter();
EMAC_timerTick( hEMAC );
OUREMAC_exit();
}
}
/*
// GetPacket - Get empty packet for RX.
//
// This function is called from the EMAC module to get an
// empty packet buffer. We need to return a packet buffer to the
// EMAC or return NULL if there are no buffers available.
*/
static EMAC_Pkt *GetPacket( Handle hApplication )
{
EMAC_Pkt *pPkt;
/* Verify our handle came back OK. We don't use it in this example */
if( (Uint32)hApplication != 0x12345678 )
{
LOG_printf(&logTrace, "GetPacket: Bad App Handle!");
return(0);
}
/* Pop a packet off our local free queue */
pPkt = pqPop(&FreeQueue);
if( pPkt )
{
/*
// Here we tell the EMAC what offset to use by setting
// the DataOffset field in the packet.
*/
pPkt->DataOffset = 0;
/*
// IMPORTANT: If our data packet were in EXTERNAL memory,
// we would have to invalidated it from the CACHE before
// returning it to the EMAC module!!!
//
// We should probably do the clean operation right here.
// However, we are most likely inside an ISR right now.
// It may be better to invalidate the buffer before it
// is pushed on the FreeQueue.
*/
}
return( pPkt );
}
/*
// FreePacket - Free packet that originated from TX or GetPacket().
//
// This function is called from the EMAC module to free a
// packet buffer after a TX operation (or RX in the case of
// a RX shutdown).
//
*/
static void FreePacket( Handle hApplication, EMAC_Pkt *pPKT )
{
/* Verify our handle came back OK. We don't use it in this example */
if( (Uint32)hApplication != 0x12345678 )
{
LOG_printf(&logTrace, "FreePacket(): Bad App Handle!");
return;
}
pqPush( &FreeQueue, pPKT );
}
/*
// RxPacket - Reveived packet from the Network.
//
// This function is called by the EMAC to indicate a receive. Here
// we just push the packet onto our receive queue.
//
// This function returns a free packet to replace the RX packet on
// the EMAC queue. If there are no free packets available, we
// return NULL.
*/
static EMAC_Pkt *RxPacket( Handle hApplication, EMAC_Pkt *pPKT )
{
/* Verify our handle came back OK. We don't use it in this example */
if( (Uint32)hApplication != 0x12345678 )
{
LOG_printf(&logTrace, "RxPacket: Bad App Handle!");
return(0);
}
/* Push this packet onto our local receive queue */
pqPush( &RxQueue, pPKT );
/* We must return a free packet to replace the one we were given */
return( GetPacket(hApplication) );
}
/*
// StatusUpdate - The EMAC or MDIO status has changed
*/
static void StatusUpdate( Handle hApplication )
{
uint retval;
/* Verify our handle came back OK. We don't use it in this example */
if( (Uint32)hApplication != 0x12345678 )
{
LOG_printf(&logTrace, "StatusUpdate: Bad App Handle!");
return;
}
/*
// The status update function is called for a variety of
// reasons, including LINK change events and EMAC errors.
// We'll get the current status here. Note we
// do not start sending packets until we have a good link.
//
// NOTE: We call back into the EMAC without any reentrancy
// concerns. This because we are a callback function
// that was called from EMAC. Thus the reentrancy
// protection is still active!
*/
retval = EMAC_getStatus( hEMAC, &status );
//LOG_printf(&logTrace, "EMAC_getPacket returned %d", retval);
LinkStatus = status.MdioLinkStatus;
if( !LinkStatus )
LOG_printf(&logTrace, "Link Status: %s\n",LinkStr[LinkStatus]);
else if( LinkStatus <= 5 )
LOG_printf(&logTrace, "Link Status : %s on PHY number %d",
LinkStr[LinkStatus],status.PhyDev);
LOG_printf(&logTrace, "Packets Held : %d-RX %d-TX",
status.RxPktHeld, status.TxPktHeld);
if( status.FatalError )
LOG_printf(&logTrace, "Fatal Error: %d", status.FatalError);
}
/*
// StatisticsUpdate - The EMAC statistics are in danger of overflow
*/
static void StatisticsUpdate( Handle hApplication )
{
/* Verify our handle came back OK. We don't use it in this example */
if( (Uint32)hApplication != 0x12345678 )
{
LOG_printf(&logTrace, "StatisticsUpdate: Bad App Handle!");
return;
}
/*
// Here we could call the EMAC_getStatistics() function and pass
// them to whoever wants them. This example app doesn't have
// anything to do with them so we do nothing.
*/
}
/*--------------------------------------------------------------------*\
* pqPop()
*
* Pop a desc buffer off a queue
\*--------------------------------------------------------------------*/
static EMAC_Pkt *pqPop( PKTQ *pq )
{
EMAC_Pkt *pPktHdr;
OUREMAC_enter();
pPktHdr = pq->pHead;
if( pPktHdr )
{
pq->pHead = pPktHdr->pNext;
pq->Count--;
pPktHdr->pPrev = pPktHdr->pNext = 0;
}
OUREMAC_exit();
return( pPktHdr );
}
/*--------------------------------------------------------------------*\
* pqPush()
*
* Push a desc buffer onto a queue
\*--------------------------------------------------------------------*/
static void pqPush( PKTQ *pq, EMAC_Pkt *pPktHdr )
{
OUREMAC_enter();
pPktHdr->pNext = 0;
if( !pq->pHead )
{
// Queue is empty - Initialize it with this one packet
pq->pHead = pPktHdr;
pq->pTail = pPktHdr;
}
else
{
// Queue is not empty - Push onto END
pq->pTail->pNext = pPktHdr;
pq->pTail = pPktHdr;
}
pq->Count++;
OUREMAC_exit();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -