📄 netdrv.cpp
字号:
outportb(RSAR1ADD,0x40); // page is from 0x40 ~ 0x7f
// set the data length. 16kbytes.
outportb(RBCR0ADD,0x00);
outportb(RBCR1ADD,0x40); // 0x2000 words.
// start remote DMA to write.
outportb(CRADD,0x12);
for ( i = 0; i < 0x2000; i++ )
outport( DATAPORTADD, i );
// wait for DMA to complete.
i = 0;
while(1)
{
tempc = inportb(ISRADD);
if ( tempc & 0x40 )
{
MacState.RemoteDMACompleteTimes++;
break;
}
wait(1);
if ( i++ > NET_TMO_DMA )
break;
}
if ( i > NET_TMO_DMA )
return( NET_ERROR_DMATMO );
// clear the interrupt.
outportb(ISRADD,0xff);
// following a few lines to read out the result.
// set byte offset.
outportb(RSAR0ADD,0);
// set the page.
outportb(RSAR1ADD,0x40);
// set the data length. 16kbytes.
outportb(RBCR0ADD,0x00);
outportb(RBCR1ADD,0x40);
// start remote DMA to read.
outportb( CRADD,0x0a );
for ( i = 0 ; i < 0x2000; i++ )
{
tempus = inport(DATAPORTADD);
if ( i != tempus )
return_value = NET_ERROR_DMAERR;
}
// wait for DMA to complete.
i = 0;
while(1)
{
tempc = inportb(ISRADD);
if ( tempc & 0x40 )
{
MacState.RemoteDMACompleteTimes++;
break;
}
wait(1);
if ( i++ > NET_TMO_DMA )
break;
}
if ( i > NET_TMO_DMA )
return( NET_ERROR_DMATMO );
// clear the interrupt.
outportb(ISRADD,0xff);
ABORTDMA
return( return_value );
}
/*
Name: InitMacCntlr
Description: Initialize MAC controller of 88796
Parameters: A string witch holds MAC address.
Return: mode - 0, loop; 1, normal.
Only the work mode is set, the intrrupt routines
are not set anyway.
Test and revisioin: Ason. 2001.5
*/
void InitMacCntlr(UCHAR *mac_addr, INT16 mode)
{
UCHAR tempc;
// Step 1, turn to page 0 and set all those
// important things in page 0,
SETTOPAGE0
// step 1.1
// 0x21, stop the controller and abort remote DMA.
outportb(CRADD,0x21);
wait(3);
// step 1.2 clear all interrupt and disable all interrupt.
outportb(ISRADD,0xff);
// the reset bit will not generate interrupt actually in 796
outportb(IMRADD,0x00);
// step 1.3
// 0x03, DCR. 16-bit DMA transfering, byte order 68K
// Dual 16-bit DMA mode, remote DMA is not always complete,
outportb(DCRADD,0x03);
// step 1.4
// 0x00, TCR. CRC appended by Transmitter.
// No loop back.
// Half duplex, PAD enabled, Retransmite in
// later collision, 88796 loop back.
if ( 0 == mode )
outportb(TCRADD,0x22);
else
outportb(TCRADD,0x20);
TcrSaver = 0x20;
// step 1.5
// 0x24, RCR. Packets with receive errors are rejected.
// reject runt packet.
// accept broadcast.
// not check multicast packet. !!!
// Non promiscuous mode.
// normal mode.
// Low active interrupt.
outportb(RCRADD,0x44);
// step 1.6
// DMA registers.
// PSTARD set to 0x46. Attention, this is start address for receiving.
outportb(PSTARTADD,0x46);
// PSTOP set to 0x80.
outportb(PSTOPADD,0x80);
// BNRY set to 0x46. Same as PSTARD.
outportb(BNRYADD,0x46);
// TSR, This is no use actually.
outportb(TSRADD,0x40);
// TBCR0
outportb(TBCR0ADD,0x00);
// TBCR1
outportb(TBCR1ADD,0x00);
// ISR, clear all ISR.
outportb(ISRADD,0xff);
// RSAR0ADD,
outportb(RSAR0ADD,0x00);
// RSAR1ADD,
outportb(RSAR1ADD,0x40);
// RBCR0ADD.
outportb(RBCR0ADD,0x00);
// RBCR1ADD.
outportb(RBCR1ADD,0x00);
// 1.7 Gap registers?
// outportb(IFGS1ADD,0x00);
// outportb(IFGS2ADD,0x00);
// outportb(IFGADD,0x00);
// 1.8 TPSRADD.
outportb( TPSRADD,WritePage );
// now, change to page 1.
SETTOPAGE1
// step 2.1
// CURR
outportb(CPRADD,0x47);
// step 2.2
// MAC Address 00001b182202 plus bednumber.
outportb(PARA0ADD,*mac_addr);
outportb(PARA1ADD,*(mac_addr+1));
outportb(PARA2ADD,*(mac_addr+2));
outportb(PARA3ADD,*(mac_addr+3));
outportb(PARA4ADD,*(mac_addr+4));
outportb(PARA5ADD,*(mac_addr+5));
// step 2.3
// multicast address, don't use multicast.
outportb(MAR0ADD,0x00);
outportb(MAR1ADD,0x00);
outportb(MAR2ADD,0x00);
outportb(MAR3ADD,0x00);
outportb(MAR4ADD,0x00);
outportb(MAR5ADD,0x00);
outportb(MAR6ADD,0x00);
outportb(MAR7ADD,0x00);
ReadPage = 0x47; // read page should be same with current page.
WritePage = 0x40; // actually, this will not change.
}
/*
Name: SetIntRt
Description: open interrupt and let NIC to work.
Parameters: None.
Return: None.
Test and revisioin: Ason. 2001.5
*/
void SetIntRt(void)
{
CHAR tempc;
UINT16 temps;
// enable the MAC controller in terrupt.
// first of all, set to page 0.
SETTOPAGE0
// set all IMR.
outportb(IMRADD,0x3f); // a reserve bit, and don't generate interrupt
// when remote DMA is finished.
ImrSaver = 0x3f;
// clear all interrupt once more.
SETTOPAGE0
outportb(ISRADD,0xff);
// clear CPU IMR.
temps = *( (UINT16 *) ( IMR_ADDR ));
temps &= 0xffef;
*( (UINT16 *) ( IMR_ADDR )) = temps;
// start the controller.
STARTCNTLR
}
/*
Name: OnReceive
Description: The interrupt routine when a packet is received.
Parameters: None.
Return: None.
Test and revisioin: Ason. 2001.5
*/
void OnReceive(void)
{
UCHAR tempc;
UCHAR regtemp;
MacState.Rcv.PacketReceived++;
// read the state in.
SETTOPAGE0
regtemp = inportb(RSRADD);
if ( regtemp & 0x01 )
MacState.Rcv.PacketReceivedIntact++;
if ( regtemp & 0x02 )
MacState.Rcv.PacketReceviedCRCErr++;
if ( regtemp & 0x04 )
MacState.Rcv.PacketReceviedFAEErr++;
if ( regtemp & 0x08 )
MacState.Rcv.PacketReceivedFIFOErr++;
if ( regtemp & 0x10 )
MacState.Rcv.PacketReceivedMissErr++;
if ( regtemp & 0x20 )
MacState.Rcv.PacketReceivedBMpTimes++;
if ( regtemp & 0x40 )
MacState.Rcv.PacketReceivedDisabled++;
ReceiveIntHappen = 1;
}
/*
Name: GetVBBuffer
Description: Allocate a piece of viewbed buffer for receiving packet.
Parameters: None.
Return: Valid point if success, else NULL.
Test and revision:
Ason. 2001.9.12. <E>
*/
void *GetVBBuffer(void)
{
return( RcvLoopBuf );
}
/*
Name: ReleaseVBBuffer
Description: Deallocate a piece of viewbed buffer as not used.
Parameters: Pointer points to the buffer.
Return: None.
Test and revision:
Ason. 2001.9.12. <E>
*/
void ReleaseVBBuffer( void *bufp )
{
}
/*
Name: OnTransmit
Description: The interrupt routine core when a packet is transmit.
Parameters: None.
Return: None.
Test and revisioin: Ason. 2001.5
*/
void OnTransmit(void)
{
UCHAR tempc,regtemp;
MacState.Tmt.TransmitTimes++;
// read the state in.
SETTOPAGE0
regtemp = inportb(TSRADD);
if ( regtemp & 0x80 )
MacState.Tmt.TransmitOWCErr++;
if ( regtemp & 0x08 )
MacState.Tmt.TransmitABTErr++;
if ( regtemp & 0x02 )
MacState.Tmt.TransmitColTimes++;
if ( regtemp & 0x01 )
MacState.Tmt.TransmitPTXTimes++;
TransmitHappen = 1;
PacketDelivered = 1;
}
/*
Name: OnReceiveWithError
Description: The interrupt routine core when a packet is received,
but error is found.
Parameters: None.
Return: None.
Test and revisioin: Ason. 2001.5
*/
void OnReceiveWithError(void)
{
UCHAR tempc,regtemp;
MacState.Rcv.PacketReceivedWithError++;
// read the state in.
SETTOPAGE0
regtemp = inportb(RSRADD);
if ( regtemp & 0x02 )
MacState.Rcv.PacketReceviedCRCErr++;
if ( regtemp & 0x04 )
MacState.Rcv.PacketReceviedFAEErr++;
if ( regtemp & 0x08 )
MacState.Rcv.PacketReceivedFIFOErr++;
if ( regtemp & 0x10 )
MacState.Rcv.PacketReceivedMissErr++;
if ( regtemp & 0x40 )
MacState.Rcv.PacketReceivedDisabled++;
}
/*
Name: OnTransmitWithError
Description: The interrupt routine core when a packet is transmitted,
but an error is found.
Parameters: None.
Return: None.
Test and revisioin: Ason. 2001.5
*/
void OnTransmitWithError(void)
{
UCHAR tempc,regtemp;
MacState.Tmt.TransmitTimesWithError++;
// read the state in.
SETTOPAGE0
regtemp = inportb(TSRADD);
if ( regtemp & 0x80 )
MacState.Tmt.TransmitOWCErr++;
if ( regtemp & 0x08 )
MacState.Tmt.TransmitABTErr++;
if ( regtemp & 0x02 )
MacState.Tmt.TransmitColTimes++;
PacketDelivered = 1;
}
/*
Name: RecoverFromBufShortage
Descriptioin: This routine will be used to recover from
the buffer shortage error. please refer to 796 data sheet.
Parameters: None.
Return: None.
Test and revision:
Ason. 2001.8
*/
void RecoverFromBufShortage(void)
{
BOOL txp;
BOOL resend;
UCHAR tempc;
// following lines are according to 88796 data sheet which
// says very detailed about what to do when buffer overflows.
// I change a little with throwing away all the packets waiting
// on the buffer link and make buffer empty.
// step 1, save TXP in
tempc = inportb(CRADD);
if ( tempc & 0x04 )
txp = TRUE;
else
txp = FALSE;
// step 2, stop 796
outportb(CRADD,0x21);
// step 3. wait for at least 1.5 ms.
wait(2);
// step 4, clear RBCR0 and RBCR1.
SETTOPAGE0
outportb(RBCR0ADD,0x00);
outportb(RBCR1ADD,0x00);
// step 5
if ( TRUE == txp )
{
tempc = inportb(ISRADD);
if ( ( tempc & 0x02 ) || ( tempc & 0x08 ) )
resend = FALSE;
else
resend = TRUE;
}
else
{
resend = FALSE;
}
// step 6 loop, i know, this will shut the data link from out side.
tempc = TcrSaver & 0xf9;
tempc = TcrSaver | 0x02;
outportb( TCRADD, tempc );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -