📄 lan8xx.c
字号:
ETHER(E_SCC1_BASE).iaddr2 = 0;
ETHER(E_SCC1_BASE).iaddr3 = 0;
ETHER(E_SCC1_BASE).iaddr4 = 0;
ETHER(E_SCC1_BASE).taddr_h = 0;
ETHER(E_SCC1_BASE).taddr_m = 0;
ETHER(E_SCC1_BASE).taddr_l = 0;
ETHER(E_SCC1_BASE).tfbd_ptr = E_BuffDescOffset(TxFirstBdPtr);
ETHER(E_SCC1_BASE).tlbd_ptr = E_BuffDescOffset(RxFirstBdPtr);
TxLastBdPtr->status = WRAP;
/*---------------------------------------------------------------------*/
/* Send command to re-initialize transmit and receive parameters. */
/*---------------------------------------------------------------------*/
CPM_CMD(INIT_RX_TX_PARAMS|SCC1_CH_NUM); /* Changed by szg */
/*---------------------------------------------------------------------*/
/* Clear previous events and set up the interrupt mask registers. */
/*---------------------------------------------------------------------*/
E_SCC1EventReg = 0xFFFF;
E_SCC1MaskReg = 0x001E;
SPLX(E_CP_IntMaskReg |= EN_SCC1;)
/*---------------------------------------------------------------------*/
/* Put the Ethernet sync pattern in the synchronization register. */
/*---------------------------------------------------------------------*/
E_SCC1DataSyncReg = 0xD555;
/*---------------------------------------------------------------------*/
/* Set SCC1 General and Protocol-Specific Mode Registers. */
/*---------------------------------------------------------------------*/
E_SCC1GenModeReg_l = TX_CLK_INVERT + ETHER_PREAM_LGTH + ETHER_PREAM_PAT
+ ETHER_MODE;
E_SCC1GenModeReg_h = 0x00000000;
#if (GDPP_FULL_DUPLEX==YES)
E_SCC1ProtoModeReg = SINGLE_PADDR + CCITT_CRC + FULL_DUPLEX+ //change by cm
RCV_BROADCASTS + IGNORE_22_BITS;
#else
E_SCC1ProtoModeReg = SINGLE_PADDR + CCITT_CRC +
RCV_BROADCASTS + IGNORE_22_BITS;
#endif
#ifdef MBX8xx
/*---------------------------------------------------------------------*/
/* Configure port C to enable !RTS (TENA) */
/*---------------------------------------------------------------------*/
E_PortCPinAssgmntReg |= PC15;
/*E_PortCDataDirReg |= PC15; */
E_PortCDataDirReg &= ~(PC15);
#endif
#if (ADS8xx || SBC8xx)
/*---------------------------------------------------------------------*/
/* Configure port B to enable !RTS(TENA). */
/*---------------------------------------------------------------------*/
E_PortBPinAssgmntReg |= BIT12;
E_PortBDataDirReg |= BIT12;
#endif
/*---------------------------------------------------------------------*/
/* Enable the transmitter and receiver. */
/*---------------------------------------------------------------------*/
E_SCC1GenModeReg_l = TX_CLK_INVERT + ETHER_PREAM_LGTH + ETHER_PREAM_PAT
+ ENABLE_RVR + ENABLE_TMT + ETHER_MODE;
}
/***********************************************************************/
/* InitBuffers: Initialize driver's pools of receive buffers and */
/* transmit headers */
/* */
/***********************************************************************/
static void InitBuffers(void)
{
UINT i;
RX_BUFF *rxb_ptr, *next_rxb_ptr;
/*---------------------------------------------------------------------*/
/* Zero out the transmit headers and the receive buffers. */
/*---------------------------------------------------------------------*/
clear(TxHeaders, sizeof(TX_HDR)*NrTxHdrs);
clear(RxBuffs, sizeof(RxBuffs));
/*---------------------------------------------------------------------*/
/* Link the transmit headers together in the free list. */
/*---------------------------------------------------------------------*/
TxhFreeHead = &TxHeaders[0];
for (i = 0; i < NrTxHdrs - 1; i++)
TxHeaders[i].next = &TxHeaders[i + 1];
TxHeaders[NrTxHdrs - 1].next = NULL;
/*---------------------------------------------------------------------*/
/* Initialize the list of queued transmit headers to empty. */
/*---------------------------------------------------------------------*/
TxhOutHead = NULL;
TxhOutTail = NULL;
/*---------------------------------------------------------------------*/
/* Link the receive buffers together in the free list. Note that */
/* each receive buffer must be longword aligned. */
/*---------------------------------------------------------------------*/
RxbFreeHead = (RX_BUFF *)ALIGN(((ULONG)RxBuffs), 4);
rxb_ptr = RxbFreeHead;
for (i = 0; i < NR_RXBUFFS - 1; i++)
{
next_rxb_ptr =
(RX_BUFF *)ALIGN((((ULONG)rxb_ptr) + sizeof(RX_BUFF)), 4);
rxb_ptr->next = next_rxb_ptr;
rxb_ptr = next_rxb_ptr;
}
rxb_ptr->next = NULL;
}
/***********************************************************************/
/* AssignRxBuffers: Beginning with the first receive buffer descriptor */
/* used to receive a packet since this function last */
/* assigned a buffer, reassign buffers to "used" receive */
/* buffer descriptors, and mark them as EMPTY; available */
/* to be used again by the SCC1. */
/* */
/***********************************************************************/
static void AssignRxBuffers(void)
{
ULONG old_level;
RX_BUFF *BufPtr;
for (;;)
{
old_level = splx(MAX_ILEV);
/*-----------------------------------------------------------------*/
/* Exit if no receive buffer descriptors are in "unused" state. */
/*-----------------------------------------------------------------*/
if (RxUsedPtr->address != NULL)
{
splx(old_level);
break;
}
/*-----------------------------------------------------------------*/
/* Exit if no buffer envelopes are free to give out right now. */
/*-----------------------------------------------------------------*/
if ((BufPtr = RxbFreeHead) == NULL)
{
splx(old_level);
break;
}
else
RxbFreeHead = BufPtr->next;
/*-----------------------------------------------------------------*/
/* Assign packet, prepare descriptor, and advance pointer. */
/*-----------------------------------------------------------------*/
RxUsedPtr->address = BufPtr;
RxUsedPtr->length = 0;
if (RxUsedPtr >= RxLastBdPtr)
{
RxUsedPtr->status = EMPTY + LOG_EVENT + WRAP;
RxUsedPtr = RxFirstBdPtr;
}
else
{
RxUsedPtr->status = EMPTY + LOG_EVENT;
RxUsedPtr++;
}
splx(old_level);
}
}
/***********************************************************************/
/* ReclaimTxFrames: Reclaim transmit Frames which have been sent out */
/* by SCC1. */
/* */
/* OUTPUTS: TxUsedPtr is updated */
/* NOTES: TxUsedPtr points to the first buffer descriptor of the */
/* next frame to be reclaimed. */
/* */
/***********************************************************************/
static void ReclaimTxFrames(void)
{
ULONG i, old_level;
TX_HDR *TxhPtr;
BuffDescType *TxUsedLIFPtr; /* points to last BD in the frame started */
/* by TxUsedPtr */
for (;;)
{
old_level = splx(MAX_ILEV);
/*-----------------------------------------------------------------*/
/* If an ISR came and reclaimed everything already get out! */
/*-----------------------------------------------------------------*/
if ((TxUsedPtr == TxNewPtr) && (TxFreeBDs == NrTxBds))
{
splx(old_level);
return;
}
/*-----------------------------------------------------------------*/
/* Set TxUsedLIFPtr to point to the last BD for the frame which */
/* begins with *TxUsedPtr */
/*-----------------------------------------------------------------*/
TxUsedLIFPtr = TxUsedPtr;
i = 0;
while (!(TxUsedLIFPtr->status & LAST_IN_FRAME))
{
IncTxBDptr(TxUsedLIFPtr);
if (i++ > NrTxBds)
{
/*---------------------------------------------------------*/
/* The current frame in the BD pool does not have the last */
/* in frame bit set. This can only mean the BD pool is in */
/* an unknown state. Perform a clean-up and restart the */
/* transmitter. */
/*---------------------------------------------------------*/
CleanUpTx();
splx(old_level);
return;
}
}
/*-----------------------------------------------------------------*/
/* If the last buffer in the current frame has not been sent we */
/* cannot reclaim the buffers and should exit the loop. */
/*-----------------------------------------------------------------*/
if (TxUsedLIFPtr->status & READY)
{
splx(old_level);
return;
}
/*-----------------------------------------------------------------*/
/* Frame has been sent. Set TxhPtr to point to the transmit */
/* header associated with the frame, and return the message block */
/* triplet. */
/*-----------------------------------------------------------------*/
TxhPtr = (TX_HDR *) TxUsedPtr->address;
if ((TxUsedPtr->length != 14) || (TxhPtr == NULL))
{
/*---------------------------------------------------------*/
/* We only add headers with a 14 byte size, so anything */
/* else means the BD pool is out of sync with our idea of */
/* the current state. Clean up all the BDs and restart the */
/* transmitter. */
/*---------------------------------------------------------*/
CleanUpTx();
splx(old_level);
return;
}
if (!TxhPtr->NoRetFlag)
Ni_funcs.freemsg( ((TX_HDR *)(TxUsedPtr->address))->msg_ptr);
/*-----------------------------------------------------------------*/
/* Advance TxUsedLIFPtr to point to the next BD following this */
/* frame. Then loop through all the BDs in this frame, zeroing the */
/* address, collecting error statistics, and increasing the number */
/* of Free Tx BDs. */
/*-----------------------------------------------------------------*/
IncTxBDptr(TxUsedLIFPtr);
do
{
TxUsedPtr->address = NULL;
/*-------------------------------------------------------------*/
/* If an outbound buffer in the frame had an error, update MIB */
/* statics. */
/*-------------------------------------------------------------*/
if (TxUsedPtr->status
& (LATE_COL | AT_RETRY_LIMIT | UNDERRUN | CARRIER_LOST))
outerrors++;
/*-------------------------------------------------------------*/
/* Advance TxUsedPtr address and the free BD counter */
/*-------------------------------------------------------------*/
IncTxBDptr(TxUsedPtr);
TxFreeBDs++;
if (TxFreeBDs > NrTxBds)
{
/*---------------------------------------------------------*/
/* The number of Free BDs should never be more than the */
/* total number of BDs. If this happens, clean up the Tx */
/* BDs and restart the transmitter. */
/*---------------------------------------------------------*/
CleanUpTx();
splx(old_level);
return;
}
} while (TxUsedPtr != TxUsedLIFPtr);
/*-----------------------------------------------------------------*/
/* Finally, return the transmit header to the free list. */
/*-----------------------------------------------------------------*/
TxhPtr->next = TxhFreeHead;
TxhFreeHead = TxhPtr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -