📄 3c90x.c
字号:
)
{
PNIC_INFORMATION pAdapter = Adapter;
MediaStatus_g = 0;
NIC_COMMAND(pAdapter,COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_4);
MediaStatus_g = NIC_READ_PORT_USHORT(pAdapter,MEDIA_STATUS_REGISTER);
NIC_DELAY(10);
if(MediaStatus_g & MEDIA_STATUS_TX_IN_PROGRESS)
{ pAdapter->WaitCases = CHECK_TRANSMIT_IN_PROGRESS;
TimeOutCount = jiffies + HZ; //max = 1s
if(!InWaitTimer)
{ WaitTimer.expires = RUN_AT(HZ/100);
add_timer(&WaitTimer);
InWaitTimer = TRUE;
}
while(TimeOutCount > jiffies) ;
if(!(MediaStatus_g & MEDIA_STATUS_TX_IN_PROGRESS))
{ pAdapter->Hardware.Status = HARDWARE_STATUS_FAILURE;
DBGPRINT_ERROR(("CheckTransmitInProgress: Transmit still in progress\n"));
return FALSE;
}
}
return TRUE;
}
/*++
Routine Name:
TestPacket
Routine Description:
This function is called by TryLoopback to determine if a packet can
successfully be loopbacked for 10Base-2 and AUI.
Arguments:
IN PNIC_INFORMATION Adapter
Return Value:
BOOLEAN
--*/
BOOLEAN
TestPacket(
IN PNIC_INFORMATION Adapter
)
{
PNIC_INFORMATION pAdapter = Adapter;
BOOLEAN ReturnValue = FALSE;
USHORT MacControl = 0;
ULONG PacketStatus = 0;
NIC_COMMAND(
pAdapter,
COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_3);
MacControl = NIC_READ_PORT_USHORT(
pAdapter,
MAC_CONTROL_REGISTER);
//
// Enable full duplex
//
NIC_WRITE_PORT_USHORT(
pAdapter,
MAC_CONTROL_REGISTER,
(USHORT)(MacControl | MAC_CONTROL_FULL_DUPLEX_ENABLE));
//
// Write UpListPointer to UpListPointer register and unstall
//
NIC_COMMAND_WAIT(pAdapter, COMMAND_UP_STALL);
NIC_WRITE_PORT_ULONG(
pAdapter,
UP_LIST_POINTER_REGISTER,
pAdapter->HeadUPDVirtual->UPDPhysicalAddress);
NIC_COMMAND(pAdapter, COMMAND_UP_UNSTALL);
//
// Enable receive and transmit and setup our packet filter
//
NIC_COMMAND_WAIT(pAdapter, COMMAND_TX_ENABLE);
NIC_COMMAND_WAIT(pAdapter, COMMAND_RX_ENABLE);
NIC_COMMAND_WAIT(pAdapter, COMMAND_SET_RX_FILTER +
RX_FILTER_INDIVIDUAL);
//
// Create single DPD and download
//
if (!DownloadSelfDirected(pAdapter)) {
return FALSE;
}
//
// Check if transmit is still in progress
//
if (!CheckTransmitInProgress(pAdapter))
return FALSE;
//
// Reset the transmitter to get rid of any TxStatus we haven't seen yet
//
NIC_COMMAND_WAIT(pAdapter, COMMAND_TX_RESET | TX_RESET_MASK_NETWORK_RESET);
//
// Check UpListPtr to see if it has changed to see if upload complete
//
UpListPointer_g = NIC_READ_PORT_ULONG(pAdapter,UP_LIST_POINTER_REGISTER);
NIC_DELAY(100);
if(UpListPointer_g == pAdapter->HeadUPDVirtual->UPDPhysicalAddress)
{ pAdapter->WaitCases = AUTONEG_TEST_PACKET;
TimeOutCount = jiffies + HZ; //max =1s
while(TimeOutCount > jiffies) ;
if(UpListPointer_g != pAdapter->HeadUPDVirtual->UPDPhysicalAddress)
{ DBGPRINT_ERROR(("TestPacket: UPD not finished\n"));
return FALSE;
}
}
//
// Check RxStatus. If we've got a packet without any errors, this
// connector is okay.
//
PacketStatus = pAdapter->HeadUPDVirtual->UpPacketStatus;
if (!(PacketStatus & UP_PACKET_STATUS_ERROR) &&
(PacketStatus & UP_PACKET_STATUS_COMPLETE)) {
ReturnValue = TRUE; // Received a good packet
}
//
// The following cleans up after the test we just ran
//
NIC_WRITE_PORT_ULONG(pAdapter, UP_LIST_POINTER_REGISTER, 0);
NIC_WRITE_PORT_ULONG(pAdapter, DOWN_LIST_POINTER_REGISTER, 0);
pAdapter->HeadUPDVirtual->UpPacketStatus = 0;
//
// Reset the receiver to wipe anything we haven't seen yet
//
NIC_COMMAND_WAIT(pAdapter, COMMAND_RX_RESET | RX_RESET_MASK_NETWORK_RESET);
NIC_COMMAND(
pAdapter,
COMMAND_ACKNOWLEDGE_INTERRUPT +
INTSTATUS_ACKNOWLEDGE_ALL);
//
// Get out of loopback mode
//
NIC_COMMAND(
pAdapter,
COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_3);
MacControl = NIC_READ_PORT_USHORT(pAdapter, MAC_CONTROL_REGISTER);
NIC_WRITE_PORT_USHORT(
pAdapter,
MAC_CONTROL_REGISTER,
(USHORT)(MacControl & ~MAC_CONTROL_FULL_DUPLEX_ENABLE));
return ReturnValue;
}
/*++
Routine Name:
GetLinkSpeed
Routine Description:
Determine from the MII AutoNegotiationAdvertisement and
AutoNegotiationPartnerAbility registers whether the
current linkspeed is 10Mbits or 100Mbits.
Arguments:
IN PNIC_INFORMATION Adapter,
OUT PBOOLEAN handles100Mbitptr
Return Value:
BOOLEAN
--*/
BOOLEAN
GetLinkSpeed(
IN PNIC_INFORMATION Adapter,
OUT PBOOLEAN handles100Mbitptr
)
{
PNIC_INFORMATION pAdapter = Adapter;
BOOLEAN PhyResponding;
USHORT PhyAnlpar;
USHORT PhyAner;
USHORT PhyAnar;
USHORT PhyStatus;
PhyResponding = ReadMIIPhy(pAdapter, MII_PHY_ANER, &PhyAner);
if (!PhyResponding)
return FALSE;
PhyResponding = ReadMIIPhy(pAdapter, MII_PHY_ANLPAR, &PhyAnlpar);
if (!PhyResponding)
return FALSE;
PhyResponding = ReadMIIPhy(pAdapter, MII_PHY_ANAR, &PhyAnar);
if (!PhyResponding)
return FALSE;
PhyResponding = ReadMIIPhy(pAdapter, MII_PHY_STATUS, &PhyStatus);
if (!PhyResponding)
return FALSE;
//
// Check to see if we've completed auto-negotiation.
//
if (!(PhyStatus & MII_STATUS_AUTO_DONE))
return FALSE;
if ((PhyAnar & MII_ANAR_100TXFD) &&
(PhyAnlpar & MII_ANLPAR_100TXFD)) {
pAdapter->Hardware.MIIPhyUsed = MII_100TXFD;
*handles100Mbitptr = TRUE;
pAdapter->Hardware.FullDuplexEnable = TRUE;
}
else if ((PhyAnar & MII_ANAR_100TX) && (PhyAnlpar & MII_ANLPAR_100TX)) {
pAdapter->Hardware.MIIPhyUsed = MII_100TX ;
*handles100Mbitptr = TRUE;
pAdapter->Hardware.FullDuplexEnable = FALSE;
}
else if ((PhyAnar & MII_ANAR_10TFD) && (PhyAnlpar & MII_ANLPAR_10TFD)) {
pAdapter->Hardware.MIIPhyUsed = MII_10TFD ;
pAdapter->Hardware.FullDuplexEnable = TRUE;
*handles100Mbitptr = FALSE;
}
else if ((PhyAnar & MII_ANAR_10T) && (PhyAnlpar & MII_ANLPAR_10T)) {
pAdapter->Hardware.MIIPhyUsed = MII_10T ;
pAdapter->Hardware.FullDuplexEnable = FALSE;
*handles100Mbitptr = FALSE;
}
else if (!(PhyAner & MII_ANER_LPANABLE)) {
//
// Link partner is not capable of auto-negotiation. Fall back to 10HD.
//
pAdapter->Hardware.MIIPhyUsed = MII_10T ;
pAdapter->Hardware.FullDuplexEnable = FALSE;
*handles100Mbitptr = FALSE;
}
else
return FALSE;
return TRUE;
}
/*++
Routine Name:
tc90x_FreeAdapterResources.
Routine Description:
This routine frees up the adapter resources.
Arguments:
Device - Pointer to the device structure.
Return Value:
None
--*/
VOID
tc90x_FreeAdapterResources(
IN PNIC_INFORMATION Adapter
)
{
PNIC_INFORMATION pAdapter = Adapter;
PDEVICE device = pAdapter->Device;
PUPD_LIST_ENTRY currentUPDVirtual = pAdapter->HeadUPDVirtual;
DBGPRINT_FUNCTION(("FreeAdapterResources: IN\n"));
if (pAdapter->ResourcesReserved & NIC_INTERRUPT_REGISTERED) {
DBGPRINT_INITIALIZE(("Releasing interrupt\n"));
free_irq(device->irq, device);
pAdapter->ResourcesReserved &= ~NIC_INTERRUPT_REGISTERED;
}
if (pAdapter->ResourcesReserved & WAIT_TIMER_REGISTERED) {
DBGPRINT_INITIALIZE((KERN_CRIT "Releasing WaitTimer\n"));
if (del_timer(&WaitTimer))
/* Timer has already been queued. */
DBGPRINT_ERROR(("WaitTimer already queued\n"));
pAdapter->ResourcesReserved &= ~WAIT_TIMER_REGISTERED;
}
if (pAdapter->ResourcesReserved & NIC_TIMER_REGISTERED) {
DBGPRINT_INITIALIZE((KERN_CRIT "Releasing Timers\n"));
if (del_timer(&pAdapter->Resources.Timer)) {
//
// Timer has already been queued.
//
DBGPRINT_ERROR(("Timer already queued\n"));
}
pAdapter->ResourcesReserved &= ~NIC_TIMER_REGISTERED;
if (del_timer(&WaitTimer))
DBGPRINT_ERROR(("WaitTimer already queued\n"));
}
if (pAdapter->ResourcesReserved & NIC_SHARED_MEMORY_ALLOCATED) {
DBGPRINT_INITIALIZE((KERN_CRIT "Releasing memory\n"));
currentUPDVirtual = pAdapter->HeadUPDVirtual;
//
// Release the SKBs allocated
//
while (1) {
if (currentUPDVirtual->SocketBuffer)
#if LINUX_VERSION_CODE >= 0x20200
dev_kfree_skb(
currentUPDVirtual->SocketBuffer
);
#else
dev_kfree_skb(
currentUPDVirtual->SocketBuffer,
GFP_ATOMIC
);
#endif
currentUPDVirtual = currentUPDVirtual->Next;
if (currentUPDVirtual == pAdapter->HeadUPDVirtual)
break;
}
kfree(pAdapter->Resources.SharedMemoryVirtual);
pAdapter->ResourcesReserved &= ~NIC_SHARED_MEMORY_ALLOCATED;
}
if (pAdapter->ResourcesReserved & NIC_IO_PORT_REGISTERED) {
DBGPRINT_INITIALIZE((KERN_CRIT "Releasing IO port region\n"));
release_region(device->base_addr, 0x80);
pAdapter->ResourcesReserved &= ~NIC_IO_PORT_REGISTERED;
}
DBGPRINT_FUNCTION(("FreeAdapterResources: OUT\n"));
}
/*++
RoutineName:
tc90x_RegisterAdapter.
Routine Description:
This routine registers the adapter resources with Linux.
Arguments:
Device - Pointer to the device structure.
Return Value:
NIC_STATUS_SUCCESS if the adapter resources could be registered.
NIC_STATUS_FAILURE if the adapter resources could not be registered.
--*/
NIC_STATUS
tc90x_RegisterAdapter(
IN PNIC_INFORMATION Adapter
)
{
PNIC_INFORMATION pAdapter = Adapter;
PDEVICE device = pAdapter->Device;
DBGPRINT_FUNCTION(("RegisterAdapter: IN\n"));
//
// Use the now-standard shared IRQ implementation.
//
DBGPRINT_INITIALIZE(("SA_SHIRQ registering IRQ %x\n", device->irq));
if (request_irq(
device->irq,
&NICInterrupt,
SA_SHIRQ,
device->name,
device)) {
DBGPRINT_ERROR(("RegisterAdapter: IRQ registration failed\n"));
return NIC_STATUS_FAILURE;
}
pAdapter->ResourcesReserved|= NIC_INTERRUPT_REGISTERED;
DBGPRINT_FUNCTION(("RegisterAdapter: OUT\n"));
return NIC_STATUS_SUCCESS;
}
/*++
Routine Name:
tc90x_GetAdapterProperties.
Routine Description:
This routine sets up the adapter.
Arguments:
Device - Pointer to the device structure.
Return Value:
NIC_STATUS_SUCCESS if the adapter could be set up successfully.
NIC_STATUS_FAILURE if the adpater could not be set up successfully.
--*/
NIC_STATUS
tc90x_GetAdapterProperties(
IN PNIC_INFORMATION Adapter
)
{
PNIC_INFORMATION pAdapter = Adapter;
PDEVICE device = pAdapter->Device;
NIC_STATUS nicStatus;
USHORT eepromValue;
USHORT intStatus;
COMPATABILITY_WORD compatability;
SOFTWARE_INFORMATION_1 information1;
SOFTWARE_INFORMATION_2 information2;
CAPABILITIES_WORD capabilities;
UCHAR value, index;
DBGPRINT_FUNCTION(("GetAdapterProperties: IN \n"));
//
// Check the ASIC type. Udp checksum should not be used in
// pre-Tornado cards- JRR
//
if ((pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9055) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9004) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9005) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9006) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9058) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_900A) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_905A) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_4500) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_7646) ||
(pAdapter->Hardware.DeviceId == NIC_PCI_DEVICE_ID_9800)) {
pAdapter->Hardware.BitsInHashFilter = 0x40;
}
else {
pAdapter->Hardware.BitsInHashFilter = 0x100;
pAdapter->Hardware.UDPChecksumErrDone = TRUE;
}
pAdapter->Hardware.Status = HARDWARE_STATUS_WORKING;
pAdapter->Hardware.LinkSpeed = LINK_SPEED_100;
//
// Make sure we can see the adapter. Set up for window 7, and make
// sure the window number gets reflected in status.
//
NIC_COMMAND(
pAdapter,
COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_7);
intStatus = NIC_READ_PORT_USHORT(
pAdapter,
INTSTATUS_COMMAND_REGISTER);
DBGPRINT_INITIALIZE(("intStatus =%x\n", intStatus));
DBGPRINT_INITIALIZE(("ioBase =%x\n", (INT)pAdapter->IoBaseAddress));
if ((intStatus & REGISTER_WINDOW_MASK) !=
(REGISTER_WINDOW_7 << 13)) {
DBGPRINT_ERROR(("SetupAdapter: Window selection failure\n"));
DBGPRINT_INITIALIZE(("SetupAdapter: Out with error\n"));
return NIC_STATUS_FAILURE;
}
//
// ----------------- Read the compatability level ----------
//
nicStatus = tc90x_ReadEEPROM(
pAdapter,
EEPROM_COMPATABILITY_WORD,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -