1522 lines
41 KiB
C
1522 lines
41 KiB
C
|
/*+
|
|||
|
* file: srom.c
|
|||
|
*
|
|||
|
* Copyright (C) 1992-1995 by
|
|||
|
* Digital Equipment Corporation, Maynard, Massachusetts.
|
|||
|
* All rights reserved.
|
|||
|
*
|
|||
|
* This software is furnished under a license and may be used and copied
|
|||
|
* only in accordance of the terms of such license and with the
|
|||
|
* inclusion of the above copyright notice. This software or any other
|
|||
|
* copies thereof may not be provided or otherwise made available to any
|
|||
|
* other person. No title to and ownership of the software is hereby
|
|||
|
* transferred.
|
|||
|
*
|
|||
|
* The information in this software is subject to change without notice
|
|||
|
* and should not be construed as a commitment by digital equipment
|
|||
|
* corporation.
|
|||
|
*
|
|||
|
* Digital assumes no responsibility for the use or reliability of its
|
|||
|
* software on equipment which is not supplied by digital.
|
|||
|
*
|
|||
|
*
|
|||
|
* Abstract: This file contains the code to access the onboard ROM of
|
|||
|
* adapters based on DEC's DC21X4 Ethernet Controller.
|
|||
|
*
|
|||
|
* Author: Philippe klein
|
|||
|
*
|
|||
|
* Revision History:
|
|||
|
*
|
|||
|
* 05-Oct-95 phk Modified Miniport version
|
|||
|
* 10-Jan-95 phk Add ParseSRom
|
|||
|
* 29-Nov-95 phk Add parsing for SROM format V3
|
|||
|
*
|
|||
|
-*/
|
|||
|
|
|||
|
#include <precomp.h>
|
|||
|
|
|||
|
#define SROM_93LC46B_SIZE 64 //words
|
|||
|
#define SROM_93LC46B_MAX_CYCLES 25
|
|||
|
#define SROM_93LC46B_ADDRESS_MSB 5
|
|||
|
#define SROM_93LC46B_DATA_MSB 15
|
|||
|
#define SROM_93LC46B_DATA_BIT 3
|
|||
|
|
|||
|
#define SROM_93LC46B_VALID_BITMASK 0x8
|
|||
|
|
|||
|
#define SROM_93LC46B_DELAY (10)
|
|||
|
|
|||
|
#define CSR_READ 0x4000
|
|||
|
#define CSR_WRITE 0x2000
|
|||
|
#define SEL_SROM 0x0800
|
|||
|
#define DATA_1 0x0004
|
|||
|
#define DATA_0 0x0000
|
|||
|
#define CLK 0x0002
|
|||
|
#define CS 0x0001
|
|||
|
|
|||
|
#define DISABLE_AUTOSENSE 0x8000
|
|||
|
|
|||
|
#define EXT 0x40
|
|||
|
#define DC21X4_MEDIA 0x3F
|
|||
|
|
|||
|
|
|||
|
#define MODE 0x0071
|
|||
|
#define SENSE_BN 0x000E
|
|||
|
#define SENSE_DIS 0x8000
|
|||
|
#define DEFAULT 0x4000
|
|||
|
#define POLARITY 0x0080
|
|||
|
|
|||
|
#define SENSE_SHIFT 1
|
|||
|
#define MODE_SHIFT 18
|
|||
|
|
|||
|
#define SROM_LEGACY 0x00
|
|||
|
#define SROM_V1 0x01
|
|||
|
#define SROM_V2 0x02
|
|||
|
#define SROM_V3 0x03
|
|||
|
|
|||
|
#define SROM_SIZE (SROM_93LC46B_SIZE*2)
|
|||
|
|
|||
|
#define SROM_IEEE_LEN 32
|
|||
|
#define TEST_PATTERN 0xAA5500FF
|
|||
|
#define SROM_TIMEOUT 50
|
|||
|
|
|||
|
#define ZX312_SIGNATURE 0x0095C000
|
|||
|
|
|||
|
#define GET_MODE(_command) \
|
|||
|
( (*(UNALIGNED ULONG *)(_command) & MODE) << MODE_SHIFT )
|
|||
|
|
|||
|
#define IF_DEFAULT_MEDIA(_command) \
|
|||
|
( *(UNALIGNED ULONG *)(_command) & DEFAULT )
|
|||
|
|
|||
|
#define GET_POLARITY(_command) \
|
|||
|
( (*(UNALIGNED ULONG *)(_command) & POLARITY) ? 0xffffffff : 0 )
|
|||
|
|
|||
|
#define GET_SENSE_MASK(_command) \
|
|||
|
((*(UNALIGNED ULONG *)(_command) & SENSE_DIS) ? \
|
|||
|
0 : (ULONG)(1 << ((*(UNALIGNED ULONG *)(_command) & SENSE_BN)>> SENSE_SHIFT )))
|
|||
|
|
|||
|
#pragma pack(1)
|
|||
|
typedef struct _SROM_ID_BLOCK{
|
|||
|
|
|||
|
USHORT VendorID;
|
|||
|
USHORT SysID;
|
|||
|
USHORT Reserved[6];
|
|||
|
USHORT ID_Checksum;
|
|||
|
UCHAR FormatVersion;
|
|||
|
UCHAR AdapterCount;
|
|||
|
UCHAR NetworkAddress[ETH_LENGTH_OF_ADDRESS];
|
|||
|
|
|||
|
} SROM_ID_BLOCK, *PSROM_ID_BLOCK;
|
|||
|
|
|||
|
typedef struct _ADAPTER_ENTRIES{
|
|||
|
|
|||
|
UCHAR DeviceNumber;
|
|||
|
USHORT Offset;
|
|||
|
|
|||
|
} ADAPTER_ENTRIES, *PADAPTER_ENTRIES;
|
|||
|
|
|||
|
#pragma pack()
|
|||
|
|
|||
|
#define DE500_STR 0x1D
|
|||
|
#define BOARD_SIGNATURE(_srom) \
|
|||
|
((*(UNALIGNED ULONG *)&(_srom)[DE500_STR] == *(PULONG)&DE500Strng[0]) && \
|
|||
|
(*(UNALIGNED ULONG *)&(_srom)[DE500_STR+sizeof(ULONG)] == *(PULONG)&DE500Strng[sizeof(ULONG)]))
|
|||
|
|
|||
|
// PHY Parsing definitions
|
|||
|
|
|||
|
#define EXTENDED_FORMAT 0x80
|
|||
|
|
|||
|
#define LENGTH 0x7f
|
|||
|
#define TYPE_0 0x0
|
|||
|
#define TYPE_1 0x1
|
|||
|
#define TYPE_2 0x2
|
|||
|
#define TYPE_3 0x3
|
|||
|
|
|||
|
#define MEDIA_CAPABILITIES_MASK 0xf800
|
|||
|
#define NWAY_ADVERTISEMENT_MASK 0x03e0
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#pragma NDIS_PAGABLE_FUNCTION(DC21X4ReadSerialRom)
|
|||
|
|
|||
|
/*+
|
|||
|
*
|
|||
|
* DC21X4ReadSerialRom
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Read the Dc21X4 Serial Rom to retrieve the adapter information
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* Status
|
|||
|
*
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
NDIS_STATUS
|
|||
|
DC21X4ReadSerialRom (
|
|||
|
IN PDC21X4_ADAPTER Adapter
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
UNALIGNED UCHAR *EthAddress;
|
|||
|
UCHAR IdProm[SROM_IEEE_LEN *2];
|
|||
|
|
|||
|
ULONG Value;
|
|||
|
INT Time;
|
|||
|
UINT i;
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("DC21X4ReadSerialROM\n");
|
|||
|
#endif
|
|||
|
|
|||
|
//Read the Station Address
|
|||
|
|
|||
|
switch (Adapter->AdapterType) {
|
|||
|
|
|||
|
case NdisInterfacePci:
|
|||
|
|
|||
|
// Read the Network Address from the PCI board ID ROM
|
|||
|
// through DC21X4's Serial ROM port
|
|||
|
|
|||
|
switch (Adapter->DeviceId) {
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
return DC21X4ParseSRom(Adapter);
|
|||
|
|
|||
|
case DC21040_CFID:
|
|||
|
|
|||
|
Adapter->MediaCapable =
|
|||
|
(MEDIUM_10BT | MEDIUM_10B2 | MEDIUM_10B5);
|
|||
|
|
|||
|
//Initialize DC21040s ID_PROM pointer
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
0
|
|||
|
);
|
|||
|
|
|||
|
// Read the 32 bytes of the Ethernet ID PROM
|
|||
|
|
|||
|
for (i = 0; i < SROM_IEEE_LEN; i++) {
|
|||
|
|
|||
|
Time = SROM_TIMEOUT;
|
|||
|
|
|||
|
do {
|
|||
|
NdisStallExecution(1*MILLISECOND); // Wait 1 ms
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
&Value
|
|||
|
);
|
|||
|
}
|
|||
|
while ((Value & DC21X4_IDPROM_DATA_UNVALID) && ((Time--)>0));
|
|||
|
if (Time > 0) {
|
|||
|
IdProm[i] = (UCHAR)(Value & DC21X4_IDPROM_DATA);
|
|||
|
}
|
|||
|
else {
|
|||
|
return NDIS_STATUS_FAILURE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
EthAddress = &IdProm[0];
|
|||
|
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case NdisInterfaceEisa:
|
|||
|
|
|||
|
Adapter->MediaCapable =
|
|||
|
(MEDIUM_10BT | MEDIUM_10B2 | MEDIUM_10B5);
|
|||
|
|
|||
|
// Read the 32 bytes of the Ethernet ID PROM
|
|||
|
|
|||
|
for (i = 0; i < SROM_IEEE_LEN; i++) {
|
|||
|
|
|||
|
NdisRawReadPortUchar(
|
|||
|
Adapter->PortOffset + EISA_ID_PROM_OFFSET,
|
|||
|
&IdProm[i]
|
|||
|
);
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("Eisa: IDROM @%x %x r\n",
|
|||
|
Adapter->PortOffset + EISA_ID_PROM_OFFSET, IdProm[i]);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
// Duplicate the ID Prom data in the 32 upper bytes of
|
|||
|
// the array to cover the case where the 2 test patterns
|
|||
|
// rap around the 32 bytes block
|
|||
|
|
|||
|
MOVE_MEMORY (
|
|||
|
&IdProm[SROM_IEEE_LEN],
|
|||
|
&IdProm[0],
|
|||
|
SROM_IEEE_LEN
|
|||
|
);
|
|||
|
|
|||
|
//Align on the test patterns
|
|||
|
|
|||
|
for (i=4; i <= SROM_IEEE_LEN*2; i++) {
|
|||
|
|
|||
|
if ( (*(UNALIGNED ULONG *)&IdProm[i-4] == TEST_PATTERN) &&
|
|||
|
(*(UNALIGNED ULONG *)&IdProm[i] == TEST_PATTERN)
|
|||
|
) break;
|
|||
|
}
|
|||
|
|
|||
|
if ( i >= SROM_IEEE_LEN ) {
|
|||
|
// The test patterns were not found
|
|||
|
Adapter->PermanentAddressValid = FALSE;
|
|||
|
return NDIS_STATUS_SUCCESS;
|
|||
|
}
|
|||
|
else {
|
|||
|
EthAddress = &IdProm[i+4];
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (IS_NULL_ADDRESS(EthAddress)) {
|
|||
|
Adapter->PermanentAddressValid = FALSE;
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("SROM: NULL Burnt_In Ethernet Address\n");
|
|||
|
#endif
|
|||
|
}
|
|||
|
else if ((*(PULONG)EthAddress & 0xFFFFFF) == ZX312_SIGNATURE) {
|
|||
|
// Zynx ZX312 Rev3's SROM does not contain a checksum
|
|||
|
Adapter->PermanentAddressValid = TRUE;
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("SROM: ZX312 Rev3\n");
|
|||
|
#endif
|
|||
|
}
|
|||
|
else {
|
|||
|
Adapter->PermanentAddressValid =
|
|||
|
VerifyChecksum(EthAddress);
|
|||
|
#if __DBG
|
|||
|
if (!Adapter->PermanentAddressValid)
|
|||
|
DbgPrint ("SROM: Invalid CheckSum\n");
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
if (Adapter->PermanentAddressValid) {
|
|||
|
MOVE_MEMORY (
|
|||
|
&Adapter->PermanentNetworkAddress[0],
|
|||
|
EthAddress,
|
|||
|
ETH_LENGTH_OF_ADDRESS
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//Sia values
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[0] = DC21040_SIA0_10BT;
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21040_SIA1_10BT;
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[2] = DC21040_SIA2_10BT;
|
|||
|
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[0] = DC21040_SIA0_10B2;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[1] = DC21040_SIA1_10B2;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[2] = DC21040_SIA2_10B2;
|
|||
|
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[0] = DC21040_SIA0_10B5;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[1] = DC21040_SIA1_10B5;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[2] = DC21040_SIA2_10B5;
|
|||
|
|
|||
|
return NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#pragma NDIS_PAGABLE_FUNCTION(VerifyChecksum)
|
|||
|
|
|||
|
/*+
|
|||
|
*
|
|||
|
* VerifyChecksum
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* Verify the checksum of an Ethernet Address
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter - The adapter which is being verified.
|
|||
|
*
|
|||
|
* EthAddress - A pointer to the address to be checked
|
|||
|
* This 6_byte Ethernet address is followed
|
|||
|
* by a zero byte, followed by a value such
|
|||
|
* that the sum of a checksum on the Ethernet
|
|||
|
* address and this value is 0xff.
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* TRUE if success
|
|||
|
*
|
|||
|
-*/
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
VerifyChecksum(
|
|||
|
IN UNALIGNED UCHAR *EthAddress
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
UINT i;
|
|||
|
UCHAR CheckSum[2];
|
|||
|
ULONG Sum = 0;
|
|||
|
|
|||
|
// The checksum yields from the polynom:
|
|||
|
// 10 2 9 8
|
|||
|
// (B[0]*2 + B[1]*2 + B[2]*2 + B[3]*2 + B[4]*2 + B[5]) mod (2**16-1)
|
|||
|
|
|||
|
for (i=0; i<= 2; i++) {
|
|||
|
|
|||
|
Sum *= 2;
|
|||
|
|
|||
|
if (Sum > 0xffff) Sum -= 0xffff;
|
|||
|
|
|||
|
Sum += (*(EthAddress+(2*i)) << 8) + *(EthAddress+(2*i)+1);
|
|||
|
|
|||
|
if (Sum > 0xffff) Sum -= 0xffff;
|
|||
|
}
|
|||
|
|
|||
|
if (Sum >= 0xffff) {
|
|||
|
Sum = 0;
|
|||
|
}
|
|||
|
|
|||
|
CheckSum[0] = (UCHAR)(Sum / 0x100);
|
|||
|
CheckSum[1] = (UCHAR)(Sum % 0x100);
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint(" CheckSum = %02x %02x\n",CheckSum[0],CheckSum[1]);
|
|||
|
#endif
|
|||
|
return (*(UNALIGNED USHORT *)CheckSum == *(UNALIGNED USHORT *)(EthAddress + 6)) ;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*+
|
|||
|
* DC21X4ParseExtendedBlock
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* This routine is called by the SROM Parser and takes care of the
|
|||
|
* parsing of the info block with Extended format (EXT=1) in the 21140's
|
|||
|
* info leaf.
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter - Pointer to the Data Structure
|
|||
|
* MediaBlock - Pointer to the Serial Rom data.
|
|||
|
* GeneralPurposeCtrl - Value of the General Purpose Ctrl
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* None
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4ParseExtendedBlock(
|
|||
|
IN PDC21X4_ADAPTER Adapter,
|
|||
|
IN OUT UNALIGNED UCHAR **MediaBlock,
|
|||
|
IN USHORT GeneralPurposeCtrl,
|
|||
|
OUT PUCHAR PMediaCode
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
UNALIGNED UCHAR *DataBytePtr;
|
|||
|
UNALIGNED USHORT *DataWordPtr;
|
|||
|
UNALIGNED UCHAR *EndOfBlock;
|
|||
|
|
|||
|
UCHAR MediaCode;
|
|||
|
|
|||
|
INT i;
|
|||
|
INT PhyNumber;
|
|||
|
UCHAR Length;
|
|||
|
UCHAR Type;
|
|||
|
USHORT External;
|
|||
|
|
|||
|
DataBytePtr = (UNALIGNED CHAR *)(*MediaBlock);
|
|||
|
|
|||
|
Length = (*(DataBytePtr++) & LENGTH);
|
|||
|
EndOfBlock = DataBytePtr + Length;
|
|||
|
|
|||
|
Type = *(DataBytePtr++);
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Block Length =%02x\n", Length);
|
|||
|
DbgPrint("Block Type =%02x\n", Type);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
switch (Type) {
|
|||
|
|
|||
|
case TYPE_0:
|
|||
|
|
|||
|
DC21X4ParseFixedBlock(
|
|||
|
Adapter,
|
|||
|
&DataBytePtr,
|
|||
|
GeneralPurposeCtrl,
|
|||
|
PMediaCode
|
|||
|
);
|
|||
|
break;
|
|||
|
|
|||
|
case TYPE_1:
|
|||
|
case TYPE_3:
|
|||
|
|
|||
|
PhyNumber = (INT) *(DataBytePtr++);
|
|||
|
if (PhyNumber >= MAX_PHY_TABLE) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("PhyNumber =%02x Out of RANGE!!!\n", PhyNumber);
|
|||
|
#endif
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//General Purpose Control
|
|||
|
Adapter->Phy[PhyNumber].GeneralPurposeCtrl = GeneralPurposeCtrl;
|
|||
|
|
|||
|
//General Purpose Data
|
|||
|
|
|||
|
Adapter->Phy[PhyNumber].GepSequenceLength = (INT) *(DataBytePtr++);
|
|||
|
|
|||
|
if (Adapter->Phy[PhyNumber].GepSequenceLength > MAX_GPR_SEQUENCE) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("GepSequence =%02x Out of RANGE!!!\n",
|
|||
|
Adapter->Phy[PhyNumber].GepSequenceLength );
|
|||
|
#endif
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
switch (Type) {
|
|||
|
|
|||
|
case TYPE_1:
|
|||
|
|
|||
|
//GepSequence Length in bytes
|
|||
|
|
|||
|
for (i=0; i < Adapter->Phy[PhyNumber].GepSequenceLength; i++) {
|
|||
|
Adapter->Phy[PhyNumber].GepSequence[i] = *(DataBytePtr++);
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case TYPE_3:
|
|||
|
|
|||
|
//GepSequence Length in words
|
|||
|
|
|||
|
for (i=0; i < Adapter->Phy[PhyNumber].GepSequenceLength; i++) {
|
|||
|
Adapter->Phy[PhyNumber].GepSequence[i] = *(UNALIGNED USHORT *)(DataBytePtr);
|
|||
|
DataBytePtr += sizeof(USHORT);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// Reset sequence
|
|||
|
|
|||
|
Adapter->Phy[PhyNumber].ResetSequenceLength = (INT) *(DataBytePtr++);
|
|||
|
|
|||
|
if (Adapter->Phy[PhyNumber].ResetSequenceLength > MAX_RESET_SEQUENCE) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("ResetSequence =%02x Out of RANGE!!!\n",
|
|||
|
Adapter->Phy[PhyNumber].ResetSequenceLength );
|
|||
|
#endif
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
for (i=0; i < Adapter->Phy[PhyNumber].ResetSequenceLength; i++) {
|
|||
|
Adapter->Phy[PhyNumber].ResetSequence[i] = *(DataBytePtr++);
|
|||
|
}
|
|||
|
|
|||
|
// Capabilities,Nway,FullDuplex & TxmThreshold
|
|||
|
|
|||
|
DataWordPtr = (UNALIGNED USHORT *) DataBytePtr;
|
|||
|
|
|||
|
Adapter->Phy[PhyNumber].MediaCapabilities =
|
|||
|
(*(DataWordPtr++) & MEDIA_CAPABILITIES_MASK);
|
|||
|
Adapter->Phy[PhyNumber].NwayAdvertisement =
|
|||
|
(*(DataWordPtr++) & NWAY_ADVERTISEMENT_MASK);
|
|||
|
Adapter->Phy[PhyNumber].FullDuplexBits =
|
|||
|
(*(DataWordPtr++) & MEDIA_CAPABILITIES_MASK);
|
|||
|
Adapter->Phy[PhyNumber].TxThresholdModeBits =
|
|||
|
(*(DataWordPtr++) & MEDIA_CAPABILITIES_MASK);
|
|||
|
Adapter->Phy[PhyNumber].Present = TRUE;
|
|||
|
|
|||
|
Adapter->PhyMediumInSrom = TRUE;
|
|||
|
|
|||
|
DataBytePtr = (UNALIGNED UCHAR *) DataWordPtr;
|
|||
|
|
|||
|
// GEP Interrupt
|
|||
|
|
|||
|
switch (Type) {
|
|||
|
|
|||
|
case TYPE_3:
|
|||
|
|
|||
|
Adapter->Phy[PhyNumber].GepInterruptMask =
|
|||
|
*(DataBytePtr++) << DC21X4_GEP_INTERRUPT_BIT_SHIFT;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("PHY Number= %02x\n", PhyNumber);
|
|||
|
DbgPrint("GPR Sequence Length= %d\n", Adapter->Phy[PhyNumber].GepSequenceLength);
|
|||
|
for (i=0; i < Adapter->Phy[PhyNumber].GepSequenceLength; i++) {
|
|||
|
DbgPrint("GPR Sequence[%d]=%02x\n", i, Adapter->Phy[PhyNumber].GepSequence[i]);
|
|||
|
}
|
|||
|
DbgPrint("RESET Sequence Length= %d\n", Adapter->Phy[PhyNumber].ResetSequenceLength);
|
|||
|
for (i=0; i < Adapter->Phy[PhyNumber].ResetSequenceLength; i++) {
|
|||
|
DbgPrint("RESET Sequence[%d]=%02x\n", i, Adapter->Phy[PhyNumber].ResetSequence[i]);
|
|||
|
}
|
|||
|
DbgPrint("Media Capabilities= %04x\n", Adapter->Phy[PhyNumber].MediaCapabilities);
|
|||
|
DbgPrint("NWAY Advertisement= %04x\n", Adapter->Phy[PhyNumber].NwayAdvertisement);
|
|||
|
DbgPrint("FD Bit map= %02x\n",Adapter->Phy[PhyNumber].FullDuplexBits);
|
|||
|
DbgPrint("TTM Bit map= %02x\n",Adapter->Phy[PhyNumber].TxThresholdModeBits);
|
|||
|
DbgPrint("GEP Interrupt mask = %01x\n",Adapter->Phy[PhyNumber].GepInterruptMask);
|
|||
|
#endif
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case TYPE_2:
|
|||
|
|
|||
|
MediaCode = *(DataBytePtr) & DC21X4_MEDIA;
|
|||
|
if (MediaCode >= MAX_MEDIA_TABLE) {
|
|||
|
break;
|
|||
|
}
|
|||
|
Adapter->MediaCapable |= 1 << MediaCode;
|
|||
|
External = *(DataBytePtr++) & EXT;
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: Media Code= %02x\n", MediaCode);
|
|||
|
DbgPrint("SRom: Media Capable= %02x\n", Adapter->MediaCapable);
|
|||
|
#endif
|
|||
|
|
|||
|
DataWordPtr = (UNALIGNED USHORT *)DataBytePtr;
|
|||
|
|
|||
|
if (External) {
|
|||
|
|
|||
|
// EXT bit is set :
|
|||
|
// overwrite the SIA Registers default values
|
|||
|
// with the values stored into the SROM
|
|||
|
|
|||
|
Adapter->Media[MediaCode].SiaRegister[0] =
|
|||
|
((ULONG)*(DataWordPtr++) & 0xFFFF);
|
|||
|
Adapter->Media[MediaCode].SiaRegister[1] =
|
|||
|
((ULONG)*(DataWordPtr++) & 0xFFFF);
|
|||
|
Adapter->Media[MediaCode].SiaRegister[2] =
|
|||
|
((ULONG)*(DataWordPtr++) & 0xFFFF);
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: EXT= 1:\n");
|
|||
|
DbgPrint("SRom: SiaReg[0]= %08x\n",Adapter->Media[MediaCode].SiaRegister[0]);
|
|||
|
DbgPrint("SRom: SiaReg[1]= %08x\n",Adapter->Media[MediaCode].SiaRegister[1]);
|
|||
|
DbgPrint("SRom: SiaReg[2]= %08x\n",Adapter->Media[MediaCode].SiaRegister[2]);
|
|||
|
#endif
|
|||
|
}
|
|||
|
Adapter->Media[MediaCode].GeneralPurposeCtrl =
|
|||
|
((ULONG)*(DataWordPtr++) & 0xFFFF);
|
|||
|
Adapter->Media[MediaCode].GeneralPurposeData =
|
|||
|
((ULONG)*(DataWordPtr) & 0xFFFF);
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: Gep Ctrl = %08x\n",Adapter->Media[MediaCode].GeneralPurposeCtrl);
|
|||
|
DbgPrint("SRom: Gep Data = %08x\n",Adapter->Media[MediaCode].GeneralPurposeData);
|
|||
|
#endif
|
|||
|
|
|||
|
*PMediaCode = MediaCode;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Type =%02x unknown... skipping\n", Type );
|
|||
|
#endif
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
*MediaBlock = EndOfBlock;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*+
|
|||
|
* DC21X4ParseFixedBlock
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* This routine is called by the SROM Parser and takes care of the
|
|||
|
* parsing of the info block with fixed format (EXT=0) in the 21140's
|
|||
|
* info leaf.
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter - Pointer to the Data Structure
|
|||
|
* DataBytePtr - Pointer to the Serial Rom data.
|
|||
|
* GeneralPurposeCtrl - Value of the General Purpose Ctrl
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* None.
|
|||
|
*
|
|||
|
-*/
|
|||
|
extern
|
|||
|
VOID
|
|||
|
DC21X4ParseFixedBlock(
|
|||
|
IN PDC21X4_ADAPTER Adapter,
|
|||
|
IN OUT UNALIGNED UCHAR **MediaBlock,
|
|||
|
IN USHORT GeneralPurposeCtrl,
|
|||
|
OUT PUCHAR PMediaCode
|
|||
|
)
|
|||
|
{
|
|||
|
UNALIGNED UCHAR *DataBytePtr;
|
|||
|
UCHAR MediaCode;
|
|||
|
|
|||
|
DataBytePtr = (UNALIGNED CHAR *)(*MediaBlock);
|
|||
|
|
|||
|
MediaCode = *(DataBytePtr) & DC21X4_MEDIA;
|
|||
|
|
|||
|
if (MediaCode >= MAX_MEDIA_TABLE) {
|
|||
|
DataBytePtr += ((2*sizeof(DataBytePtr)) + sizeof(USHORT));
|
|||
|
*MediaBlock = DataBytePtr;
|
|||
|
return ;
|
|||
|
}
|
|||
|
Adapter->MediaCapable |= 1 << MediaCode;
|
|||
|
|
|||
|
Adapter->Media[MediaCode].GeneralPurposeCtrl =
|
|||
|
(ULONG)GeneralPurposeCtrl;
|
|||
|
Adapter->Media[MediaCode].GeneralPurposeData =
|
|||
|
(ULONG)(*(++DataBytePtr) & 0xFF);
|
|||
|
Adapter->Media[MediaCode].Mode =
|
|||
|
GET_MODE(++DataBytePtr);
|
|||
|
Adapter->Media[MediaCode].Polarity =
|
|||
|
GET_POLARITY(DataBytePtr);
|
|||
|
Adapter->Media[MediaCode].SenseMask =
|
|||
|
GET_SENSE_MASK(DataBytePtr);
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("Media Code= %02x\n", MediaCode);
|
|||
|
DbgPrint("Media Capable= %02x\n", Adapter->MediaCapable);
|
|||
|
DbgPrint("GPData= %02x\n",Adapter->Media[MediaCode].GeneralPurposeData);
|
|||
|
DbgPrint("Mode= %02x\n",Adapter->Media[MediaCode].Mode);
|
|||
|
DbgPrint("Polarity= %x\n",Adapter->Media[MediaCode].Polarity);
|
|||
|
DbgPrint("Sense Mask= %x\n",Adapter->Media[MediaCode].SenseMask);
|
|||
|
#endif
|
|||
|
|
|||
|
Adapter->Media[MediaCode].Mode |=
|
|||
|
(Adapter->Media[MediaCode].Mode & DC21X4_TXM_THRESHOLD_MODE)?
|
|||
|
Adapter->Threshold10Mbps : Adapter->Threshold100Mbps;
|
|||
|
|
|||
|
if ( Adapter->Media[MediaCode].SenseMask
|
|||
|
&& MediaCode != Medium10BaseTFd
|
|||
|
&& MediaCode != Medium100BaseTxFd
|
|||
|
&& MediaCode != Medium100BaseFxFd){
|
|||
|
|
|||
|
//Add the media code to the MediaPrecedence table
|
|||
|
Adapter->MediaPrecedence[Adapter->MediaCount++] = MediaCode;
|
|||
|
}
|
|||
|
|
|||
|
// Check if default media
|
|||
|
if (IF_DEFAULT_MEDIA(DataBytePtr)) {
|
|||
|
Adapter->DefaultMediumFlag = TRUE;
|
|||
|
Adapter->DefaultMedium = MediaCode;
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: Default Media = %04x\n",MediaCode);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
*PMediaCode = MediaCode;
|
|||
|
|
|||
|
DataBytePtr += sizeof(USHORT);
|
|||
|
*MediaBlock = DataBytePtr;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#pragma NDIS_PAGABLE_FUNCTION(DC21X4ParseSRom)
|
|||
|
|
|||
|
/*
|
|||
|
* DC21X4ParseSRom
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* ParseSRom parses the Serial ROM to retrieve the Ethernet Station
|
|||
|
* address of the adapter and the adapter's media specific information
|
|||
|
*
|
|||
|
* Adapter - pointer to adapter structure
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* Ndis Status
|
|||
|
*
|
|||
|
-*/
|
|||
|
|
|||
|
|
|||
|
NDIS_STATUS
|
|||
|
DC21X4ParseSRom(
|
|||
|
IN PDC21X4_ADAPTER Adapter
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
PSROM_ID_BLOCK SRomIdBlock;
|
|||
|
UNALIGNED ADAPTER_ENTRIES *AdapterEntry;
|
|||
|
UNALIGNED UCHAR *DataBytePtr;
|
|||
|
UNALIGNED USHORT *DataWordPtr;
|
|||
|
PUCHAR SRomData;
|
|||
|
|
|||
|
USHORT GeneralPurposeCtrl;
|
|||
|
USHORT MediaCount;
|
|||
|
USHORT MediaType;
|
|||
|
UCHAR MediaCode;
|
|||
|
ULONG Offset = 0;
|
|||
|
INT Index = 0;
|
|||
|
INT i;
|
|||
|
|
|||
|
BOOLEAN ExtendedFormat;
|
|||
|
|
|||
|
ULONG CheckSum;
|
|||
|
UCHAR Tmp[ETH_LENGTH_OF_ADDRESS];
|
|||
|
|
|||
|
UCHAR DC21140Leaf [] = {
|
|||
|
0x00,0x08, // AutoSense
|
|||
|
0x1f, // General Purpose Ctrl
|
|||
|
0x04, // Media Count
|
|||
|
0x00,0x0b,0x8e,0x00, // Tp
|
|||
|
0x03,0x1b,0x6d,0x00, // 100BaseTx
|
|||
|
0x04,0x03,0x8e,0x00, // TpFd
|
|||
|
0x05,0x1b,0x6d,0x00 // 100BaseTxFd
|
|||
|
};
|
|||
|
|
|||
|
UCHAR DE500Strng[] = {"DE500-XA"};
|
|||
|
|
|||
|
|
|||
|
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
|
|||
|
|
|||
|
|
|||
|
// Allocate space to dump the whole SROM
|
|||
|
|
|||
|
ALLOC_MEMORY (&NdisStatus, &SRomData, SROM_SIZE);
|
|||
|
if (NdisStatus != NDIS_STATUS_SUCCESS) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint ( "SROM ALLOC_MEMORY FAILED\n");
|
|||
|
#endif
|
|||
|
return NdisStatus;
|
|||
|
}
|
|||
|
|
|||
|
// Read the whole ROM
|
|||
|
|
|||
|
if (DC21X4ReadSRom(
|
|||
|
Adapter,
|
|||
|
&Offset,
|
|||
|
SROM_SIZE,
|
|||
|
SRomData)) {
|
|||
|
|
|||
|
SRomIdBlock = (PSROM_ID_BLOCK)SRomData;
|
|||
|
}
|
|||
|
else {
|
|||
|
#if __DBG
|
|||
|
DbgPrint ( "ReadSRom failed\n");
|
|||
|
#endif
|
|||
|
FREE_MEMORY(SRomData, SROM_SIZE);
|
|||
|
return NDIS_STATUS_HARD_ERRORS;
|
|||
|
}
|
|||
|
|
|||
|
// Check the Checksum
|
|||
|
|
|||
|
CheckSum = CRC32(SRomData,SROM_SIZE-2) & 0xFFFF;
|
|||
|
if (CheckSum != *(PUSHORT)&SRomData[SROM_SIZE-2]) {
|
|||
|
|
|||
|
// Check if the SROM is a "legacy" formated SROM
|
|||
|
// containing only the network address
|
|||
|
|
|||
|
if ((Adapter-> DeviceId == DC21140_CFID)
|
|||
|
&& !IS_NULL_ADDRESS(SRomData)
|
|||
|
&& VerifyChecksum(SRomData)
|
|||
|
) {
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint ( "Legacy SRom...\n");
|
|||
|
#endif
|
|||
|
MOVE_MEMORY (
|
|||
|
&Adapter->PermanentNetworkAddress[0],
|
|||
|
&SRomData[0],
|
|||
|
ETH_LENGTH_OF_ADDRESS
|
|||
|
);
|
|||
|
|
|||
|
Adapter->PermanentAddressValid = TRUE;
|
|||
|
|
|||
|
SRomIdBlock->FormatVersion = SROM_LEGACY;
|
|||
|
DataBytePtr = &DC21140Leaf[0];
|
|||
|
}
|
|||
|
|
|||
|
else {
|
|||
|
#if __DBG
|
|||
|
DbgPrint ( "Invalid SROM Checksum - Expected:%04x Read:%04x\n",
|
|||
|
CheckSum,*(PUSHORT)&SRomData[SROM_SIZE-2]);
|
|||
|
#endif
|
|||
|
FREE_MEMORY(SRomData, SROM_SIZE);
|
|||
|
return NDIS_STATUS_SOFT_ERRORS;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Check the SROM Version
|
|||
|
|
|||
|
switch (SRomIdBlock->FormatVersion) {
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("SRom: Unsupported Format Version (%x)!\n",
|
|||
|
SRomIdBlock->FormatVersion);
|
|||
|
#endif
|
|||
|
FREE_MEMORY(SRomData, SROM_SIZE);
|
|||
|
return NDIS_STATUS_SOFT_ERRORS;
|
|||
|
|
|||
|
case SROM_V1:
|
|||
|
case SROM_V3:
|
|||
|
|
|||
|
// Parse the Adapter Device Number.
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("SRom: Version: %2x\n",SRomIdBlock->FormatVersion );
|
|||
|
DbgPrint ("SRom: Adapter Count: %2x\n", SRomIdBlock->AdapterCount);
|
|||
|
DbgPrint ("SRom: Network Base Address: %02x-%02x-%02x-%02x-%02x-%02x\n",
|
|||
|
SRomIdBlock->NetworkAddress[0],SRomIdBlock->NetworkAddress[1],
|
|||
|
SRomIdBlock->NetworkAddress[2],SRomIdBlock->NetworkAddress[3],
|
|||
|
SRomIdBlock->NetworkAddress[4],SRomIdBlock->NetworkAddress[5]);
|
|||
|
#endif
|
|||
|
|
|||
|
AdapterEntry = (PADAPTER_ENTRIES)&SRomData[sizeof(SROM_ID_BLOCK)];
|
|||
|
|
|||
|
if ((INT)SRomIdBlock->AdapterCount > 1) {
|
|||
|
|
|||
|
// Parse the Adapter's Device Number.
|
|||
|
for (; Index < (INT)SRomIdBlock->AdapterCount; Index++,AdapterEntry++) {
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("SRom: DeviceNumber, %2x\n",AdapterEntry->DeviceNumber );
|
|||
|
DbgPrint ("SRom: Offset, %4x\n", AdapterEntry->Offset);
|
|||
|
#endif
|
|||
|
if (AdapterEntry->DeviceNumber == (UCHAR)Adapter->SlotNumber) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (Index == (INT)SRomIdBlock->AdapterCount) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: Adapter's Device Number %d not found in SROM\n",
|
|||
|
Adapter->SlotNumber);
|
|||
|
#endif
|
|||
|
FREE_MEMORY(SRomData, SROM_SIZE);
|
|||
|
return NDIS_STATUS_ADAPTER_NOT_FOUND;
|
|||
|
}
|
|||
|
|
|||
|
// Check if the Station Address is a NULL Address
|
|||
|
|
|||
|
if IS_NULL_ADDRESS(SRomIdBlock->NetworkAddress) {
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("SRom: NULL Network Address\n");
|
|||
|
#endif
|
|||
|
Adapter->PermanentAddressValid = FALSE;
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
if (Index !=0) {
|
|||
|
|
|||
|
// Add the adapter index to the base network Address
|
|||
|
// (The carry is propagated to the 3 lower bytes
|
|||
|
// of the address only (the 3 upper bytes are the vendor id))
|
|||
|
|
|||
|
for (i=0;i<3;i++) {
|
|||
|
Tmp[i] = SRomIdBlock->NetworkAddress[ETH_LENGTH_OF_ADDRESS-(i+1)];
|
|||
|
}
|
|||
|
*(UNALIGNED ULONG *)&Tmp[0] += Index;
|
|||
|
for (i=0;i<3;i++) {
|
|||
|
SRomIdBlock->NetworkAddress[ETH_LENGTH_OF_ADDRESS-(i+1)] = Tmp[i];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("SRom: Network Address: %02x-%02x-%02x-%02x-%02x-%02x\n",
|
|||
|
SRomIdBlock->NetworkAddress[0],SRomIdBlock->NetworkAddress[1],
|
|||
|
SRomIdBlock->NetworkAddress[2],SRomIdBlock->NetworkAddress[3],
|
|||
|
SRomIdBlock->NetworkAddress[4],SRomIdBlock->NetworkAddress[5]);
|
|||
|
#endif
|
|||
|
MOVE_MEMORY (
|
|||
|
&Adapter->PermanentNetworkAddress[0],
|
|||
|
SRomIdBlock->NetworkAddress,
|
|||
|
ETH_LENGTH_OF_ADDRESS
|
|||
|
);
|
|||
|
|
|||
|
Adapter->PermanentAddressValid = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//Parse the Media Info Blocks.
|
|||
|
|
|||
|
DataBytePtr = &(SRomData[AdapterEntry->Offset]);
|
|||
|
|
|||
|
case SROM_LEGACY:
|
|||
|
|
|||
|
Adapter->MediaCapable = 0;
|
|||
|
|
|||
|
switch (Adapter-> DeviceId) {
|
|||
|
|
|||
|
case DC21041_CFID:
|
|||
|
|
|||
|
// Initialize the Media table with the default values.
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[0] = DC21041_SIA0_10BT;
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21041_SIA1_10BT;
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[2] = DC21041_SIA2_10BT;
|
|||
|
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[0] = DC21041_SIA0_10B2;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[1] = DC21041_SIA1_10B2;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[2] = DC21041_SIA2_10B2;
|
|||
|
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[0] = DC21041_SIA0_10B5;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[1] = DC21041_SIA1_10B5;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[2] = DC21041_SIA2_10B5;
|
|||
|
|
|||
|
MediaType = *(UNALIGNED USHORT *)DataBytePtr;
|
|||
|
DataBytePtr += sizeof(USHORT);
|
|||
|
|
|||
|
MediaCount = *(DataBytePtr++);
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: MediaType= %04x \n", MediaType);
|
|||
|
DbgPrint("SRom: Media Count= %d \n", MediaCount);
|
|||
|
#endif
|
|||
|
for (Index=0; Index < MediaCount; Index++) {
|
|||
|
|
|||
|
MediaCode = *DataBytePtr & DC21X4_MEDIA;
|
|||
|
|
|||
|
if (MediaCode >= MAX_MEDIA_TABLE) {
|
|||
|
DataBytePtr += (sizeof(DataBytePtr)
|
|||
|
+ ((*DataBytePtr & EXT) ? (3 * sizeof(DataWordPtr)):0));
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
Adapter->MediaCapable |= 1 << MediaCode;
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: Media Code= %02x\n", MediaCode);
|
|||
|
DbgPrint("SRom: Media Capable= %02x\n", Adapter->MediaCapable);
|
|||
|
#endif
|
|||
|
|
|||
|
if (*(DataBytePtr++) & EXT) {
|
|||
|
|
|||
|
// EXT bit is set :
|
|||
|
// overwrite the SIA Registers default values
|
|||
|
// with the values stored into the SROM
|
|||
|
|
|||
|
DataWordPtr = (UNALIGNED USHORT *) DataBytePtr;
|
|||
|
Adapter->Media[MediaCode].SiaRegister[0] =
|
|||
|
((ULONG)*(DataWordPtr++) & 0xFFFF);
|
|||
|
Adapter->Media[MediaCode].SiaRegister[1] =
|
|||
|
((ULONG)*(DataWordPtr++) & 0xFFFF);
|
|||
|
Adapter->Media[MediaCode].SiaRegister[2] =
|
|||
|
((ULONG)*(DataWordPtr++) & 0xFFFF);
|
|||
|
DataBytePtr = (UNALIGNED UCHAR *) DataWordPtr;
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: EXT= 1:\n");
|
|||
|
DbgPrint("SRom: SiaReg[0]= %08x\n",Adapter->Media[MediaCode].SiaRegister[0]);
|
|||
|
DbgPrint("SRom: SiaReg[1]= %08x\n",Adapter->Media[MediaCode].SiaRegister[1]);
|
|||
|
DbgPrint("SRom: SiaReg[2]= %08x\n",Adapter->Media[MediaCode].SiaRegister[2]);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case DC21140_CFID:
|
|||
|
|
|||
|
switch (SRomIdBlock->FormatVersion) {
|
|||
|
|
|||
|
case SROM_LEGACY:
|
|||
|
case SROM_V1:
|
|||
|
|
|||
|
if (Adapter->RevisionNumber == DC21140_REV1_1) {
|
|||
|
Adapter->DynamicAutoSense = BOARD_SIGNATURE(SRomData);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
//MediaType
|
|||
|
|
|||
|
MediaType = *(UNALIGNED USHORT *)DataBytePtr;
|
|||
|
Adapter->DynamicAutoSense = ((MediaType & DISABLE_AUTOSENSE) == 0);
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: MediaType= %04x \n", MediaType);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: Dynamic Autosense %s\n",
|
|||
|
Adapter->DynamicAutoSense? "Enabled":"Disabled");
|
|||
|
#endif
|
|||
|
|
|||
|
DataBytePtr += sizeof(USHORT);
|
|||
|
|
|||
|
GeneralPurposeCtrl = (((USHORT)*(DataBytePtr++) & 0xFF)|(0x100));
|
|||
|
|
|||
|
MediaCount = *(DataBytePtr++);
|
|||
|
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: General Purpose Control= %08x \n", GeneralPurposeCtrl);
|
|||
|
DbgPrint("SRom: MediaCount= %d \n", MediaCount);
|
|||
|
#endif
|
|||
|
for (Index=0; Index < MediaCount; Index++) {
|
|||
|
|
|||
|
ExtendedFormat = (*DataBytePtr & EXTENDED_FORMAT);
|
|||
|
|
|||
|
if ((SRomIdBlock->FormatVersion == SROM_V3) && ExtendedFormat) {
|
|||
|
DC21X4ParseExtendedBlock(
|
|||
|
Adapter,
|
|||
|
&DataBytePtr,
|
|||
|
GeneralPurposeCtrl,
|
|||
|
&MediaCode
|
|||
|
);
|
|||
|
}
|
|||
|
else {
|
|||
|
DC21X4ParseFixedBlock(
|
|||
|
Adapter,
|
|||
|
&DataBytePtr,
|
|||
|
GeneralPurposeCtrl,
|
|||
|
&MediaCode
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (!Adapter->DefaultMediumFlag && Adapter->MediaCount>0) {
|
|||
|
Adapter->DefaultMedium =
|
|||
|
Adapter->MediaPrecedence[Adapter->MediaCount-1];
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case DC21142_CFID:
|
|||
|
|
|||
|
if (SRomIdBlock->FormatVersion < SROM_V3) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("SRom: Unsupported Format Version (%x)!\n",
|
|||
|
SRomIdBlock->FormatVersion);
|
|||
|
#endif
|
|||
|
FREE_MEMORY(SRomData, SROM_SIZE);
|
|||
|
return NDIS_STATUS_SOFT_ERRORS;
|
|||
|
}
|
|||
|
|
|||
|
// Initialize the Media table with the default values.
|
|||
|
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[0] = DC21142_SIA0_10BT;
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[1] = DC21142_SIA1_10BT;
|
|||
|
Adapter->Media[Medium10BaseT].SiaRegister[2] = DC21142_SIA2_10BT;
|
|||
|
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[0] = DC21142_SIA0_10B2;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[1] = DC21142_SIA1_10B2;
|
|||
|
Adapter->Media[Medium10Base2].SiaRegister[2] = DC21142_SIA2_10B2;
|
|||
|
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[0] = DC21142_SIA0_10B5;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[1] = DC21142_SIA1_10B5;
|
|||
|
Adapter->Media[Medium10Base5].SiaRegister[2] = DC21142_SIA2_10B5;
|
|||
|
|
|||
|
|
|||
|
MediaType = *(UNALIGNED USHORT *)DataBytePtr;
|
|||
|
|
|||
|
Adapter->DynamicAutoSense = ((MediaType & DISABLE_AUTOSENSE) == 0);
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: Dynamic Autosense %s\n",
|
|||
|
Adapter->DynamicAutoSense? "Enabled":"Disabled");
|
|||
|
#endif
|
|||
|
DataBytePtr += sizeof(USHORT);
|
|||
|
MediaCount = *(DataBytePtr++);
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: MediaType= %04x \n", MediaType);
|
|||
|
DbgPrint("SRom: MediaCount= %d \n", MediaCount);
|
|||
|
#endif
|
|||
|
|
|||
|
for (Index=0; Index < MediaCount; Index++) {
|
|||
|
|
|||
|
DC21X4ParseExtendedBlock(
|
|||
|
Adapter,
|
|||
|
(PVOID)&DataBytePtr,
|
|||
|
(USHORT)NULL,
|
|||
|
&MediaCode
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
if (!Adapter->DefaultMediumFlag && Adapter->MediaCount>0) {
|
|||
|
Adapter->DefaultMedium =
|
|||
|
Adapter->MediaPrecedence[Adapter->MediaCount-1];
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
NdisStatus = NDIS_STATUS_DEVICE_FAILED;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( (MediaCount == 1)
|
|||
|
&& Adapter->MediaCapable
|
|||
|
&& !Adapter->PhyMediumInSrom
|
|||
|
) {
|
|||
|
|
|||
|
//Force MediaType to the single supported medium
|
|||
|
#if __DBG
|
|||
|
DbgPrint("SRom: One single supported medium: Force MediaType %04x to ",Adapter->MediaType);
|
|||
|
#endif
|
|||
|
Adapter->MediaType &= ~(MEDIA_MASK | MEDIA_AUTOSENSE);
|
|||
|
Adapter->MediaType |= MediaCode;
|
|||
|
#if __DBG
|
|||
|
DbgPrint("%04x\n",Adapter->MediaType);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
//if no 10Base port is populated, switch Port_Select to 100Base
|
|||
|
|
|||
|
if (!(Adapter->MediaCapable & (MEDIUM_10BT | MEDIUM_10B2 | MEDIUM_10B5))) {
|
|||
|
Adapter->OperationMode |= DC21X4_PORT_SELECT;
|
|||
|
}
|
|||
|
|
|||
|
FREE_MEMORY(SRomData, SROM_SIZE);
|
|||
|
return NdisStatus;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#pragma NDIS_PAGABLE_FUNCTION(DC21X4ReadSRom)
|
|||
|
|
|||
|
/*
|
|||
|
* DC21X4ReadSRom
|
|||
|
*
|
|||
|
* Routine Description:
|
|||
|
*
|
|||
|
* ReadSRom is called by DC21X4RegisterAdapter to read the onboard ROM
|
|||
|
* for the network address and other parameters.
|
|||
|
* This routine reads the required number of bytes from the given
|
|||
|
* offset in the ROM.
|
|||
|
*
|
|||
|
* Arguments:
|
|||
|
*
|
|||
|
* Adapter -
|
|||
|
*
|
|||
|
* Offset - byte offset into SROM to start reading from. Must
|
|||
|
* be word aligned
|
|||
|
* Len - number of bytes to read
|
|||
|
* Data - pointer to buffer to read data into.
|
|||
|
* if NULL, don't return data
|
|||
|
*
|
|||
|
* Return Value:
|
|||
|
*
|
|||
|
* TRUE if success, FALSE if hardware failure encountered.
|
|||
|
*
|
|||
|
-*/
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
DC21X4ReadSRom(
|
|||
|
IN PDC21X4_ADAPTER Adapter,
|
|||
|
IN OUT PULONG Offset,
|
|||
|
IN USHORT Len,
|
|||
|
OUT PUCHAR Buffer
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
INT i;
|
|||
|
INT j;
|
|||
|
ULONG Dbit;
|
|||
|
ULONG Dout;
|
|||
|
USHORT WOffset;
|
|||
|
USHORT WLen;
|
|||
|
USHORT WData;
|
|||
|
|
|||
|
// Make sure the ROM_Address is EVEN.
|
|||
|
|
|||
|
if (*Offset & 1)
|
|||
|
{
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("ReadSRom failure - Offset not word aligned\n");
|
|||
|
#endif
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
// Round up the length to multiple of words.
|
|||
|
WLen = (Len + 1) / 2;
|
|||
|
|
|||
|
// Convert the ROM_Address byte offset to word offset
|
|||
|
WOffset = (USHORT)(*Offset >> 1);
|
|||
|
|
|||
|
// Make sure the requested read does not exceed the ROM size
|
|||
|
|
|||
|
if ( (WOffset + WLen) > SROM_93LC46B_SIZE) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("ReadSRom warning - address range excedes ROM size\n");
|
|||
|
#endif
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Switch CSR to work with new SROM interface
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM
|
|||
|
);
|
|||
|
|
|||
|
// Make sure SROM is in idle state
|
|||
|
// (deliver it enough clocks with CS set, Din = 0).
|
|||
|
|
|||
|
for (i = 0; i < SROM_93LC46B_MAX_CYCLES; i++) {
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | CLK
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
|
|||
|
// Read the data
|
|||
|
|
|||
|
for (j = 0; j < WLen; j++,WOffset++) {
|
|||
|
|
|||
|
//Output the READ command to the SROM
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | DATA_1
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | CLK | DATA_1
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | DATA_1
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | DATA_1
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | CLK | DATA_1
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | DATA_1
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | DATA_0
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | CLK | DATA_0
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | DATA_0
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
|
|||
|
// Output the WORD Address of the SROM
|
|||
|
|
|||
|
for (i = SROM_93LC46B_ADDRESS_MSB; i>= 0; i--) {
|
|||
|
|
|||
|
Dbit = (USHORT)((WOffset >> i) & 1) << 2;
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | Dbit
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | CLK | Dbit
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | Dbit
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Verify that the SROM output data became now 0.
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
&Dout
|
|||
|
);
|
|||
|
|
|||
|
if (Dout & SROM_93LC46B_VALID_BITMASK) {
|
|||
|
#if __DBG
|
|||
|
DbgPrint ("ReadSRom failure - SROM didn't become busy in read command\n");
|
|||
|
#endif
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
// Read the data from the SROM
|
|||
|
|
|||
|
WData = 0;
|
|||
|
for (i = SROM_93LC46B_DATA_MSB; i >= 0; i--) {
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS | CLK
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
DC21X4_READ_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
&Dout
|
|||
|
);
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM | CS
|
|||
|
);
|
|||
|
|
|||
|
WData |= ((Dout >> SROM_93LC46B_DATA_BIT) & 1) << i;
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
#if _DBG
|
|||
|
DbgPrint("Data = %04x\n",WData);
|
|||
|
#endif
|
|||
|
|
|||
|
// Put our read data in user buffer
|
|||
|
|
|||
|
if (Buffer) {
|
|||
|
|
|||
|
if (Len >= 2) {
|
|||
|
|
|||
|
*(PUSHORT)Buffer = WData;
|
|||
|
Buffer += 2;
|
|||
|
Len -= 2;
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
// Least significant byte only is copied
|
|||
|
*Buffer = WData & 0xff;
|
|||
|
Buffer++;
|
|||
|
Len--;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//Negate the chip select (CS) to end the SROM command
|
|||
|
|
|||
|
DC21X4_WRITE_PORT(
|
|||
|
DC21X4_IDPROM,
|
|||
|
CSR_WRITE | SEL_SROM
|
|||
|
);
|
|||
|
|
|||
|
NdisStallExecution(SROM_93LC46B_DELAY);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
*Offset = WOffset << 1;
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|
|||
|
|