📄 drv8139.c
字号:
//receive fifo overflow! printf("[LanInit]: MSR[0x%x].\n", value8) ;
microsleep(10000);
i++;
if(i > 5)
break;
}
while((value8 & 0x4)); //0000 0100(MSR:Inverse of Link status. 0 = Link OK. 1 = Link Fail.)
//while((value8 & 0x4) == 0); //0000 0100(MSR:Inverse of Link status. 0 = Link OK. 1 = Link Fail.)
IoWriteReg8(CR, 0xc); //Enable Transmit/Receive(RE/TE in Command Register)
value = IoReadReg32(TCR);
value |= 7<<8; //normal, CRC, size of Tx DMA is 2k
value &= 0xfff8ffff;
IoWriteReg32(TCR, value); //set TCR
// receive Configuration register
value = IoReadReg32(RCR);
value &= 0xffff0000;
//value |= 0x569e;//size of receive buffer is 8k+16, size of Rx DMA is unlimited, wrap, Rx FIFO threshold is 16
#ifndef RECV_BUF_64K
value |= 0xd69e;//1101 0110 1001 1110:size of receive buffer is 32k+16, size of Rx DMA is 1024 bytes, wrap, Rx FIFO threshold is 1024 bytes
#else
value |= 0xde9e;//1101 1110 1001 1110:size of receive buffer is 64k+16
//#error "RECV_BUF_64K"
#endif
IoWriteReg32(RCR, value); //set RCR
// printf("[LanInit]: set RCR = 0x%.8x.\n", value) ;
/***************************************************************************/
value = IoReadReg16(IMR);
value |= 0x807f;//enable system error interrupt
//value |= 0x7f;//disable system error interrupt
IoWriteReg16(IMR, value);// 0xe07f //enable IMR
// printf("IoWriteReg16 successfully\n");
//-----------------------------------------------------------------
// Init multicast address buffer
for (i = 0; i < MULTICAST_ADDR_NUM; ++ i)
{
g_multi_addr[i].addr.word1 = 0xffff ;
g_multi_addr[i].addr.word2 = 0xffff ;
g_multi_addr[i].addr.word3 = 0xffff ;
g_multi_addr[i].is_used = 0 ;
}
/***************************************************************************/
//-----------------------------------------------------------------
printf("[LanInit]: init finish!\n") ;
//IoWriteReg16(BMCR, 0x0);
}
/****************************************************************************
* function name: SetupLanParams
* design date:2001-5-8,
* function description: Allocate transmit and receive buffers
* call: bzero
* called: pNA+
* input parameter: no_of_packet == number of packet
* output parameter: freeMemPtr = pointer to start address of free memory
* return value: no
* change record: no
*****************************************************************************/
UCHAR *SetupLanParams(ULONG no_of_packets, UCHAR *freeMemPtr)
{
int i;
// Determine number of buffers and descriptors.
TxNumHdrs = no_of_packets / 2;
RxNumHdrs = no_of_packets - TxNumHdrs;
// Allocate transmit headers.
freeMemPtr = ALIGN((int)freeMemPtr, 64);
TxHeaders = (LAN_TX_HDR *)freeMemPtr;
freeMemPtr += (TxNumHdrs * sizeof(LAN_TX_HDR));
// Allocate receive headers.
freeMemPtr = ALIGN((int)freeMemPtr, 64);
RxHeaders = (LAN_RX_BUF *)freeMemPtr;
freeMemPtr += (RxNumHdrs * sizeof(LAN_RX_BUF));
// Allocate transmit descriptors.
for(i = 0; i < NUM_TX_DESC; i++)
{
TxDesc[i] = ALIGN((int)freeMemPtr, 64);
bzero((UCHAR *)TxDesc[i], TX_BUF_SIZE);
freeMemPtr += TX_BUF_SIZE;
}
RxRing = ALIGN((int)freeMemPtr, 64);
bzero((UCHAR *)RxRing, RX_BUF_SIZE + TX_BUF_SIZE);
freeMemPtr += RX_BUF_SIZE + TX_BUF_SIZE;
/*
printf("[SetupLanParams]: TxNumHdrs[%d], RxNumHdrs[%d].\n", TxNumHdrs, RxNumHdrs) ;
printf("[SetupLanParams]: TxHeaders [0x%x], RxHeaders [0x%x]\n", TxHeaders, RxHeaders) ;
printf("[SetupLanParams]: ") ;
for(i = 0; i < NUM_TX_DESC; i++)
{
printf(" TxDesc[%d]: 0x%x", i, TxDesc[i]) ;
}
printf ("\n") ;
printf("[SetupLanParams]: RxRing[0x%x].\n", RxRing) ;
*/
return freeMemPtr;
}
/****************************************************************************
* function name: InitTxDescRxRing
* design date:2001-5-8,
* function description: Initialize 8139 receive buffer and transmit descriptors.
* call: no
* called: SetupLanParams, InitBuffers
* input parameter: ptr = pointer to the address to zero
* length = length of memory to be zeroed
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
void InitTxDescRxRing()
{
int i;
for(i = 0; i < NUM_TX_DESC; i++)
{
IoWriteReg32(TSAD0 + i * 4, (ULONG)TxDesc[i]);
}
IoWriteReg32(RBSTART, (ULONG)RxRing);
CurDescId = 0;
RxOffset = 0;
}
/****************************************************************************
* function name: InitBuffers
* design date:2001-5-8,
* function description: Initialize receive buffer and transmit descriprot
* call: bzero
* called: ni_init
* input parameter: no
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
static void InitBuffers(void)
{
int i;
//Zero out the transmit headers
bzero((UCHAR *)TxHeaders, sizeof(LAN_TX_HDR) * TxNumHdrs);
//Link transmit headers in a free list
TxHdrFreeHead = &TxHeaders[0];
for (i = 0; i < (TxNumHdrs - 1); ++i)
TxHeaders[i].next = &TxHeaders[i + 1];
TxHeaders[TxNumHdrs - 1].next = NULL;
//Initialize the list of queued transmit headers to empty.
TxHdrOutHead = TxHdrOutTail = NULL;
//Zero out the receive headers
bzero((UCHAR *)RxHeaders, sizeof(LAN_RX_BUF) * RxNumHdrs);
//Link receive headers in a free list
RxPktFreeHead = &RxHeaders[0];
for (i = 0; i < (RxNumHdrs - 1); ++i)
RxHeaders[i].next = &RxHeaders[i + 1];
RxHeaders[RxNumHdrs - 1].next = NULL;
//Initialize the list of queued transmit headers to empty.
RxPktList = NULL;
FreeRxPktCount = RxNumHdrs;
InitTxDescRxRing();
}
/****************************************************************************
* function name: LanChipReset
* design date:2001-5-8,
* function description: Reset the LAN chip
* call: IoWriteReg8
* called: LanInit
* input parameter: no
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
//Reset: Setting to 1 forces the RTL8139D(L) to a software reset state
//which disables the transmitter and receiver, reinitializes the FIFOs,
//resets the system buffer pointer to the initial value
//(after reset: Tx buffer is at TSAD0, Rx buffer is empty).
//The values of IDR0-5 and MAR0-7 and PCI configuration space will have no changes.
static void LanChipReset(void)
{
IoWriteReg8(CR, 0x10); //Software Reset
//Must wait for minimum of 50 PCI clock cycles.
microsleep(10);
}
/****************************************************************************
* function name: tmIntInit
* design date:2001-5-8,
* function description: install interrupt handler, open network interrupt
* call: no
* called: ni_init
* input parameter: no
* output parameter: no
* return value: no
* change record: no
*****************************************************************************/
static long tmIntInit(void)
{
tmLibdevErr_t tm_err;
intInstanceSetup_t iisetup;
iisetup.enabled = True; //Install the interrupt service routine.
iisetup.handler = ni_isr;
iisetup.priority = intPRIO_6;//intPRIO_6; //priority
iisetup.level_triggered = True;//False;
tm_err = intOpen(V_LAN);
if(tm_err != TMLIBDEV_OK)
return False;
tm_err = intInstanceSetup(V_LAN, &iisetup);
if(tm_err != TMLIBDEV_OK)
{
intClose(V_LAN);
return False;
}
return True;
}
/****************************************************************************
* function name: ni_init
* design date:2001-5-8,
* function description: Initialize the network interface.
* call: tmIntInit,LanInit,InitBuffers
* called: ni_init
* input parameter: no
* output parameter: no
* return value: Pointer to hardware address of NI or -1 if failure
* change record: no
*****************************************************************************/
static long ni_init(void)
{
int i;
Bool ien;
//add by zhengkun
ArpReqFlag = 0;
intClear(V_LAN);
if(!tmIntInit())
{
DP8139("Int init fail!\n");
return -1;
}
// Get the Ethernet Address. This is set in bpdialog.c.
// This is an interim solution till I get the roms working.
//Initialize MIB variables.
InErrors = outerrors = 0;
InOctets = OutOctets = 0;
InUcastPkts = OutUcastPkts = 0;
innucastpkts = outnucastpkts = 0;
ifadminstatus = 1; //up
InUnknownProtos = 0;
lc_err = 0;
InitBuffers(); //Initialize the receive buffers and transmit headers.
LanInit(); //Initialize Lan chip in Ethernet mode in stopped mode.
for(i = 0; i < 6; ++i)
OurAddress.byte[i] = SelfAddr[i];
//InitBuffers(); //Initialize the receive buffers and transmit headers.
// intRESTORE_IEN(ien);
intRaise(V_LAN);
//No errors if we got here, so return pointer to Ethernet address.
//for(i = 0; i < 6; ++i)
// DP8139("OurAddress.byte[%d] = %x\n", i, OurAddress.byte[i]);
return (long)&OurAddress; //the NI Ethernet physical address
}
/****************************************************************************
* function name: ni_send
* design date:?2001-5-8,
* function description: Send a packet to another node.
* call: TxFillDesc
* called: NiLan
* input parameter: hwa_ptr = pointer to the destination hardware address
* pkb_ptr = pointer to packet (msg block triplet)
* len = number of bytes in packet buffer
* type = flag indicating either IP, ARP, or RARP
* output parameter: no
* return value: 0
* change record: no
*****************************************************************************/
#pragma pack(1)
struct taga
{
char a ;
int b ;
}af ;
#pragma pack()
static long ni_send(char *hwa_p, char *pkb_p, USHORT len, USHORT type)
{
LAN_TX_HDR *tx_hdr;
mblk_t *msgBlk;
int i;
Bool ien;
//Try to keep the transmit descriptors full.
TxFillDesc();
if(hwa_p[0] & 1)
outnucastpkts++;
else
OutUcastPkts++;
//Compute the # of descriptors required to send this frame.
msgBlk = (mblk_t *)pkb_p;
if(len == 0)
{
NiFuncs.freemsg(msgBlk);
return 0;
}
len += 14;
/*---------------------------------------------------------------------*/
/* Update record of total bytes sent. */
/*---------------------------------------------------------------------*/
OutOctets += len;
//Obtain transmit header from free list. If none available, we
//can't send the packet. Just return the triplet.
intClear(V_LAN);
tx_hdr = TxHdrFreeHead;
if(tx_hdr == (LAN_TX_HDR *)NULL)
{
intRaise(V_LAN);
outerrors++;
NiFuncs.freemsg(msgBlk);
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -