📄 rtl8139.c
字号:
//
WRITE_PORT_ULONG(
RTL_TSD_X(i),
(DWORD)(dwLength) | (0x00 << 16));
return 0x00;
} // RTL8139SendFrame()
////////////////////////////////////////////////////////////////////////////////
// RTL8139GetPendingInts()
// EDBG only cares about INTR_TYPE_RX, we handle all others internally.
//
DWORD
RTL8139GetPendingInts(void)
{
USHORT dwISR;
DWORD dwReturn;
PRINTF (0, ("RTL8139GetPendingInts()..\r\n"));
PRINTF (0, ("%% "));
dwISR = READ_PORT_USHORT(RTL_ISR);
if (dwISR & 0x04)
PurgeTxDescriptors();
if (dwISR & 0x01)
dwReturn = INTR_TYPE_RX;
else
dwReturn = 0x00;
////////////////////////////////////////////////////////////////////////////
// If RX FIFO overflow or RX Buffer overflow then reset the
// chip [???] Too servere ???
//
if (dwISR & 0x0050)
{
USHORT usDummy[3];
PRINTF (1, ("ISR[0x%x] >> RX overflow.. Reset <<\r\n", dwISR));
RTL8139DisableInts();
RTL8139Init(
(PBYTE)sRTL8139.dwBaseIO,
sRTL8139.dwMemOffset,
usDummy);
RTL8139EnableInts();
return 0x00;
}
WRITE_PORT_USHORT(
RTL_ISR,
0xffff);
return dwReturn;
} // RTL8139GetPendingInts()
////////////////////////////////////////////////////////////////////////////////
// RTL8139ReadEEPROM()
//
BOOL
RTL8139ReadEEPROM (UINT16 uiEEPROMAddress , UINT16 *pwVal)
{
PRINTF (1, ("RTL8139ReadEEPROM() not implemented..\r\n"));
return FALSE;
} // RTL8139ReadEEPROM()
////////////////////////////////////////////////////////////////////////////////
// RTL8139WriteEEPROM()
//
BOOL
RTL8139WriteEEPROM(UINT16 uiEEPROMAddress, UINT16 uiData)
{
PRINTF (1, ("RTL8139WriteEEPROM() not implemented..\r\n"));
return FALSE;
} // RTL8139WriteEEPROM()
////////////////////////////////////////////////////////////////////////////////
// RTL8139SetOptions()
//
DWORD
RTL8139SetOptions(DWORD dwOptions)
{
PRINTF (1, ("RTL8139SetOptions() not implemented..\r\n"));
return 0x00;
} // RTL8139SetOptions()
////////////////////////////////////////////////////////////////////////////////
// RTL8139HWSetMCRegs()
//
// Description:
//
// This function is used to set the multicast registers.
//
// Arguments:
//
// pucMulticastRegs :: If not null then use this instead of 0xFF or 0x00
// depending on bAllMulticast below.
//
// bAllMulticast :: TRUE == Set all to 0xff :: FALSE = Set all to 0x00
//
// Return value:
//
//
void
RTL8139HWSetMCRegs(PUCHAR pucMulticastRegs, BOOL bAllMulticast)
{
DWORD i;
if (pucMulticastRegs)
{
DWORD dwMulticast0To3 = 0x00;
DWORD dwMulticast4To7 = 0x00;
EdbgOutputDebugString(
"RTL8139:: MulticastRegs set to : %x-%x-%x-%x-%x-%x-%x-%x\r\n",
pucMulticastRegs[0],
pucMulticastRegs[1],
pucMulticastRegs[2],
pucMulticastRegs[3],
pucMulticastRegs[4],
pucMulticastRegs[5],
pucMulticastRegs[6],
pucMulticastRegs[7]);
for (i = 0 ; i < 4 ; i++)
dwMulticast0To3 = dwMulticast0To3 +
(pucMulticastRegs[i] << (8 * i));
for (i = 4 ; i < 8 ; i++)
dwMulticast4To7 = dwMulticast4To7 +
(pucMulticastRegs[i] << (8 * (i - 4)));
WRITE_PORT_ULONG(RTL_MAR0, dwMulticast0To3);
WRITE_PORT_ULONG(RTL_MAR4, dwMulticast4To7);
}
else
{
DWORD dwMulticastRegs;
if (bAllMulticast)
{
dwMulticastRegs = 0xffffffff;
EdbgOutputDebugString("RTL8139:: RTL8139HWSetMCRegs():: Set all to 0xff\r\n");
}
else
{
dwMulticastRegs = 0x00;
EdbgOutputDebugString("RTL8139:: RTL8139HWSetMCRegs():: Set all to 0x00\r\n");
}
WRITE_PORT_ULONG(RTL_MAR0, dwMulticastRegs);
WRITE_PORT_ULONG(RTL_MAR4, dwMulticastRegs);
}
} // RTL8139HWSetMCRegs()
////////////////////////////////////////////////////////////////////////////////
// RTL8139CurrentPacketFilter()
//
// Description:
//
// This function is called to set the h/w filter.
// We support:
// PROMISCUOUS, ALL MULTICAST, BROADCAST, DIRECTED.
//
// Arguments:
//
// dwFilter:: The filter mode
//
// Return value:
//
// TRUE if successful, FALSE otherwise.
//
void
RTL8139CurrentPacketFilter(DWORD dwFilter)
{
if (dwFilter & (PACKET_TYPE_ALL_MULTICAST | PACKET_TYPE_PROMISCUOUS))
{
//
// Need all multicast..
//
RTL8139HWSetMCRegs(NULL, TRUE);
}
else
{
//
// No longer need "all multicast".
// When we do support MULTICAST LIST then we should copy the list
// to the h/w here..
//
UCHAR pucMulticastList[MAX_MULTICAST_LIST][6];
memcpy(
pucMulticastList,
&(g_pucMulticastList[0][0]),
g_dwMulticastListInUse * 6);
RTL8139MulticastList(
&(pucMulticastList[0][0]),
g_dwMulticastListInUse);
}
//
// The multicast bit in the RCR should be on if multicast/all multicast packets
// (or is promiscuous) is needed.
//
if(dwFilter &
(PACKET_TYPE_ALL_MULTICAST | PACKET_TYPE_MULTICAST | PACKET_TYPE_PROMISCUOUS))
{
g_dwRCR |= RX_MULTICAST;
}
else
{
g_dwRCR &= ~RX_MULTICAST;
}
//
// The promiscuous physical bit in the RCR should be on if ANY
// protocol wants to be promiscuous.
//
if (dwFilter & PACKET_TYPE_PROMISCUOUS)
{
g_dwRCR |= RX_PROMISCUOUS;
}
else
{
g_dwRCR &= ~RX_PROMISCUOUS;
}
//
// The broadcast bit in the RCR should be on if ANY protocol wants
// broadcast packets (or is promiscuous).
//
if
(
dwFilter & (PACKET_TYPE_BROADCAST |
PACKET_TYPE_PROMISCUOUS)
)
{
g_dwRCR |= RX_BROADCAST;
}
else
{
g_dwRCR &= ~RX_BROADCAST;
}
//
// EDBG always receive directed and broadcast & directed as a minimum.
//
g_dwRCR |= (RX_BROADCAST & RX_UNICAST);
g_dwNdisFilter = dwFilter;
EdbgOutputDebugString("RTL8139:: Set Ndis filter [0x%x] -> [0x%x]\r\n",
dwFilter,
g_dwRCR);
//
// Burn it to h/w..
//
WRITE_PORT_ULONG (RTL_RCR, g_dwRCR);
} // RTL8139CurrentPacketFilter()
////////////////////////////////////////////////////////////////////////////////
// RTL8139ComputeCrc()
//
// Description:
//
// Runs the AUTODIN II CRC algorithm on buffer Buffer of length Length.
//
// Arguments:
//
// Buffer - the input buffer
// Length - the length of Buffer
//
// Return value:
//
// The 32-bit CRC value.
//
// Note:
//
// This function is adopted from netcard\ne2000 miniport driver.
//
ULONG
RTL8139ComputeCrc(
IN PUCHAR Buffer,
IN UINT Length)
{
ULONG Crc, Carry;
UINT i, j;
UCHAR CurByte;
Crc = 0xffffffff;
for (i = 0; i < Length; i++) {
CurByte = Buffer[i];
for (j = 0; j < 8; j++) {
Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
Crc <<= 1;
CurByte >>= 1;
if (Carry) {
Crc = (Crc ^ 0x04c11db6) | Carry;
}
}
}
return Crc;
} // RTL8139ComputeCrc()
////////////////////////////////////////////////////////////////////////////////
// RTLGetMulticastBit()
//
// Description:
//
// For a given multicast address, returns the byte and bit in the card
// multicast registers that it hashes to. Calls RTL8139ComputeCrc() to
// determine the CRC value.
//
// Arguments:
//
// Address - the address
// Byte - the byte that it hashes to
// Value - will have a 1 in the relevant bit
//
// Return value:
//
// None.
//
// Note:
//
// This function is adopted from netcard\ne2000 miniport driver.
//
VOID
RTLGetMulticastBit(
IN UCHAR Address[6],
OUT UCHAR * Byte,
OUT UCHAR * Value
)
{
ULONG Crc;
UINT BitNumber;
//
// First compute the CRC.
//
Crc = RTL8139ComputeCrc(Address, 6);
//
// The bit number is now in the 6 most significant bits of CRC.
//
BitNumber = (UINT)((Crc >> 26) & 0x3f);
*Byte = (UCHAR)(BitNumber / 8);
*Value = (UCHAR)((UCHAR)1 << (BitNumber % 8));
} // RTLGetMulticastBit()
////////////////////////////////////////////////////////////////////////////////
// RTL8139MulticastList()
//
// Description:
//
// This function is used to insert multicast addresses to the h/w.
//
// Arguments:
//
// pucMulticastAddresses :: The list of multicast addressses.
// dwNoOfAddresses :: The number of addresses in the list.
//
// Return value:
//
// TRUE if successful, FALSE otherwise.
//
BOOL
RTL8139MulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
UCHAR NicMulticastRegs[8]; // contents of card multicast registers
UINT i;
UCHAR Byte, Bit;
#if 0
EdbgOutputDebugString(
"RTL8139:: RTL8139MulticastList() set [%d] multicast list addrs.\r\n",
dwNoOfAddresses);
#endif
//
// Make sure it's below max list we can handle..
//
if (dwNoOfAddresses > MAX_MULTICAST_LIST)
{
EdbgOutputDebugString(
"RTL8139:: RTL8139MulticastList exceeds max list..\r\n");
return FALSE;
}
//
// Remember these addresses as we may need them again when filter
// is switched from All Multicast to multicast.
//
memset(
g_pucMulticastList,
0x00,
MAX_MULTICAST_LIST * 6);
memcpy(
g_pucMulticastList,
pucMulticastAddresses,
dwNoOfAddresses * 6);
g_dwMulticastListInUse = dwNoOfAddresses;
#if 0
for (i = 0 ; i < dwNoOfAddresses ; i++)
{
EdbgOutputDebugString(
"RTL8139:: Multicast[%d] = %x-%x-%x-%x-%x-%x\r\n",
i,
pucMulticastAddresses[6*i + 0],
pucMulticastAddresses[6*i + 1],
pucMulticastAddresses[6*i + 2],
pucMulticastAddresses[6*i + 3],
pucMulticastAddresses[6*i + 4],
pucMulticastAddresses[6*i + 5]);
}
#endif
//
// If we are already in Multicast or Promiscuous mode, then no
// need to set this..
//
if (g_dwNdisFilter & (PACKET_TYPE_PROMISCUOUS |
PACKET_TYPE_ALL_MULTICAST))
{
return TRUE;
}
//
// First turn all bits off.
//
for (i=0; i<8; i++)
NicMulticastRegs[i] = 0;
//
// Now turn on the bit for each address in the multicast list.
//
for (i=0 ; i<dwNoOfAddresses; i++)
{
RTLGetMulticastBit(&pucMulticastAddresses[6*i], &Byte, &Bit);
NicMulticastRegs[Byte] |= Bit;
}
#if 0
EdbgOutputDebugString(
"RTL8139:: MulticastRegs = %x-%x-%x-%x-%x-%x-%x-%x\r\n",
NicMulticastRegs[0],
NicMulticastRegs[1],
NicMulticastRegs[2],
NicMulticastRegs[3],
NicMulticastRegs[4],
NicMulticastRegs[5],
NicMulticastRegs[6],
NicMulticastRegs[7]);
#endif
//
// Finally, burn that in the h/w..
//
RTL8139HWSetMCRegs(NicMulticastRegs, FALSE);
return TRUE;
} // RTL8139MulticastList()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -