📄 dm9isa.cpp
字号:
//[#endif]
#endif
WNextLine();
WNextLine();
//[(Since "nResetCounts==0")]-(AS dmfe_open)
//(+)2008-01-10 Joseph Chang
#if 1
//#ifdef IMPL_GIGABIT_ETHERNET
//#endif
for(int j=0; j<100; j++) //[_Joseph: If still not link, This is to wait max 30ms until link OK!]
{
if ( DeviceReadPhy(0, 0x1)&0x0004 ) //wLinkState =
break;
NdisMSleep(uSec300);
}
WPrintf(TEXT("Chk_InitialHardware: Link rapid (for 30ms): %d.%d mSec"), (j*300)/1000, (((j*300)+50)/100)%10);
WNextLine();
WNextLine();
#endif
//(-)2008-01-10 Joseph Chang
if (nResetCounts==0) nTxCnt= nRxCnt= 0; // Counter
FUNCTION_LEAVE_MSG();
}
#define ATO_COUNT 1
#define TTL_COUNT 1
/*
void DM9ISA::InitialLinkProg(int n){}
*/
void DM9ISA::DeviceResetPHYceiver(void)
{
return;
}
/********************************************************************************
*
* Devcie handler routines
*
********************************************************************************/
#ifdef IMPL_DEVICE_ISR
void DM9ISA::DeviceIsr(
U32 uState)
{
//(+)2008-01-10 Joseph Chang
//#ifdef IMPL_GIGABIT_ETHERNET
//#endif
#if 0
if ( uState & MAKE_MASK1(5) ) // MAKE_MASK1(5)=DM9KS_LINK_INTR=0x20
{
for(int i=0; i<500; i++) /*wait link OK, waiting time =0.5s */
{
DeviceReadPhy(0, 0x1);
if ( DeviceReadPhy(0, 0x1)&0x0004 ) //wLinkState =
break;
else
//for GIGA-RICHARD, WIST-JUDES-RON
_DeviceWritePhy(0, MIIADDR_SCFG, 0x0); /* 20.4=0 Auto-MDIX mode */
NdisMSleep(mSec1);
}
DEBUG_PRINTF(TEXT("JJ_GIGABIT_LINK_CHANGE: Re-Link rapid: %d usec \r\n"), (i*1000));
}
#endif
//(-)2008-01-10 Joseph Chang
}
#endif
#ifdef IMPL_STORE_AND_INDICATION
void DM9ISA::DeviceOnTimer(void)
{
int val = m_RQStandby.Size();
PCQUEUE_GEN_HEADER pcurr;
for(;(pcurr=m_RQStandby.Dequeue());m_RQueue.Enqueue(pcurr))
{
DeviceReceiveIndication(
0,CQueueGetUserPointer(pcurr),pcurr->nLength);
} // of for RQStandby loop
}
#endif
int DM9ISA::DeviceOnSetupFilter(
U32 uFilter)
{
int n;
U8 sz[8];
U32 hashval;
U32 newmode;
_PSTR(_T("DeviceOnSetupFilter: DeviceOnSetupFilter(0x%08X)-Sta \r\n"), uFilter);
/*
//
// Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER).
//
#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
#define NDIS_PACKET_TYPE_SMT 0x00000040
#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
#define NDIS_PACKET_TYPE_GROUP 0x00001000
#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000
#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000
#define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000
*/
// save old op mode
newmode = m_szCurrentSettings[SID_OP_MODE];
// clear filter related bits,
// pass all multicast<3> and promiscuous<1>
newmode &= ~MAKE_MASK2(3,1);
// zero input means one reset request
if(!(m_szCurrentSettings[SID_GEN_CURRENT_PACKET_FILTER]=uFilter))
{
// not-occur-until
/* 1. set unicast */
// retrive node address
GetMacAddress(&sz[0]);
// set node address
for(n=0;n<ETH_ADDRESS_LENGTH;n++)
DeviceWritePort(DM9_PAR0+n,(U32)sz[n]);
/* 2. clear multicast list and count */
m_nMulticasts = 0;
memset((void*)&m_szMulticastList,0,sizeof(m_szMulticastList));
/* 3. clear hash table */
// clear hash table
memset((void*)(&sz[0]),0,sizeof(sz));
for(n=0;n<sizeof(sz);n++)
DeviceWritePort(DM9_MAR0+n,(U32)sz[n]);
return uFilter;
}
// if promiscuous mode<1> is requested,
// just set this bit and return
if( (uFilter & NDIS_PACKET_TYPE_PROMISCUOUS) )
{
// not-occur-until
// add promiscuous<1>
newmode |= MAKE_MASK(1);
DeviceWritePort(DM9_RXCR, m_szCurrentSettings[SID_OP_MODE]=newmode);
_PSTR(_T("--------------------------------------\r\n"));
_PSTR(_T("Func=DM9ISA::DeviceOnSetupFilter('NDIS_PACKET_TYPE_PROMISCUOUS')\r\n"));
_RPT_WREG(RN_RXCR, DM9_RXCR, m_szCurrentSettings[SID_OP_MODE]);
_PSTR(_T("--------------------------------------\r\n"));
return uFilter;
}
// if pass all multicast<3> is requested,
if(uFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) newmode |= MAKE_MASK(3);
// prepare new hash table
memset((void*)(&sz[0]),0,sizeof(sz));
// if broadcast, its hash value is known as 63.
if(uFilter & NDIS_PACKET_TYPE_BROADCAST) sz[7] |= 0x80;
if(uFilter & NDIS_PACKET_TYPE_MULTICAST)
for(n=0;n<m_nMulticasts;n++)
{
hashval= DeviceCalculateCRC32(&m_szMulticastList[n][0],ETH_ADDRESS_LENGTH,FALSE) & 0x3f;
sz[hashval/8] |= 1 << (hashval%8);
} // of calculate hash table
// submit the new hash table
for(n=0;n<sizeof(sz);n++)
DeviceWritePort(DM9_MAR0+n,(U32)sz[n]);
DeviceWritePort(DM9_RXCR, m_szCurrentSettings[SID_OP_MODE]=newmode);
_PSTR(_T("--------------------------------------\r\n"));
//. _RPT_STR(_T("Func=DM9ISA::DeviceOnSetupFilter('~NDIS_PACKET_TYPE_PROMISCUOUS')\r\n"));
_RPT_WREG(RN_RXCR, DM9_RXCR, m_szCurrentSettings[SID_OP_MODE]);
//Ke. DeviceCheckLink();
_PSTR(_T("--------------------------------------\r\n"));
return uFilter;
}
void DM9ISA::DeviceInterruptEventHandler(
U32 uValue)
{
// check RX activities
if(uValue & 0x01) Dm9LookupRxBuffers();
// return if not TX latch
if(!(uValue & 0x02)) return;
U32 nsr;
nsr = DeviceReadPort(DM9_NSR);
//JJ-DBG.CPP (migrated to _DeviceSend(-) to test!)
if (nsr & 0x0c)
{
#if 0
nTxSramReadPoint= (((U16)DeviceReadPort(DM9_TRAH) << 8 ) | (U16)DeviceReadPort(DM9_TRAL));
if (nTxSramReadPoint != nTxMemoryWrAddr) //ERROR;
NKDbgPrintfW(TEXT("[TxSramReadPoint Err]= ChipWrAdr %d, SramReadPt %d \r\n"),
nTxMemoryWrAddr, nTxSramReadPoint);
else
WPrintf(TEXT("[TxRamRPoint OK]= ChipWrAdr %d, SramReadPt %d \r\n"),
nTxMemoryWrAddr, nTxSramReadPoint);
#endif
// check TX-END2
if(nsr & 0x08)
{
//JJ-DBG.CPP
WPutChar('x'); // Interrupt -TX Packet2 Complete
WPutChar(0x30+m_nTxPendings);
m_nTxPendings--;
DeviceSendCompleted(m_TQWaiting.Dequeue());
}
// check TX-END1
if(nsr & 0x04)
{
//JJ-DBG.CPP
WPutChar('+'); // Interrupt -TX Packet1 Complete
WPutChar(0x30+m_nTxPendings);
m_nTxPendings--;
DeviceSendCompleted(m_TQWaiting.Dequeue());
}
// report tx available now
NdisMSendResourcesAvailable(m_pUpper->GetNdisMiniportAdapterHandle()); //when if( nsr & 0x0C )
}
}
U32 DM9ISA::DeviceHardwareStatus(void)
{
return m_nTxPendings?0:NIC_HW_TX_IDLE;
}
int DM9ISA::DeviceSend(
PCQUEUE_GEN_HEADER pObject)
{
PCQUEUE_GEN_HEADER pcurr;
if(pObject) m_TQStandby.Enqueue(pObject);
/* increment counter */
//JJ-DBG.CPP (to check)
m_nTxPendings++;
/* get first pkt in queue */
m_TQWaiting.Enqueue(pcurr= m_TQStandby.Dequeue());
/* fill data */
WPutChar('('); // Fill-Data
WPutChar(0x30+m_nTxPendings);
nTxCnt++;
ISA_TxFIFO_Begin();
DeviceWriteData((PBYTE)CQueueGetUserPointer(pcurr), pcurr->usLength);
DeviceWritePort(DM9_TXLENH, HIGH_BYTE(pcurr->usLength));
DeviceWritePort(DM9_TXLENL, LOW_BYTE(pcurr->usLength));
// TXCR<0>, issue TX request
DeviceWritePort(DM9_TXCR, MAKE_MASK(0));
ISA_TxFIFO_End();
//JJ-DBG.CPP
#if 1
WPutChar(')'); // TX-complete
while (DeviceReadPort(DM9_TXCR) & MAKE_MASK(0)) ;
//if (nsr & 0x0c)
//{
nTxSramReadPoint= (((U16)DeviceReadPort(DM9_TRAH) << 8 ) | (U16)DeviceReadPort(DM9_TRAL));
if (nTxSramReadPoint != nTxMemoryWrAddr) //ERROR;
//NKDbgPrintfW(TEXT("[TxRamRPt Err]= ChipWAdr %d, RamRPt %d \r\n"),
// nTxMemoryWrAddr, nTxSramReadPoint);
WPrintf(WSTR("TC=%d %d[%d,%d]\r\n"), nTxCnt, nToWrAddr%100,
nTxMemoryWrAddr%100, nTxSramReadPoint%100);
else
//WPrintf(TEXT("[OK]= ChipWAdr %d, RamRPt %d \r\n"),
// nTxMemoryWrAddr, nTxSramReadPoint);
WPrintf(WSTR("TC=%d [OK%d,%d]\r\n"),
nTxCnt, nTxMemoryWrAddr%100, nTxSramReadPoint%100);
//}
#endif
return 0;
} // pcurr
void DM9ISA::ISA_TxFIFO_Begin()
{
//JJ-DBG.CPP
nTxMemoryWrAddr= (((U16)DeviceReadPort(DM9_MDWAH) << 8 ) | (U16)DeviceReadPort(DM9_MDWAL));
nTxSramReadPoint= (((U16)DeviceReadPort(DM9_TRAH) << 8 ) | (U16)DeviceReadPort(DM9_TRAL));
// [NextLine, Only for DM9003,D9013]
if (((m_pUpper->m_Bag.m_pLowerId==DM9003_CHIP_ID)||
(m_pUpper->m_Bag.m_pLowerId==DM9013_CHIP_ID)))
; //WNextLine();
else
WPrintf(TEXT("[TC=%d S%d,%d]"), nTxCnt, nTxMemoryWrAddr%100, nTxSramReadPoint%100); // "\r\n"
}
void DM9ISA::ISA_TxFIFO_End()
{
}
int DM9ISA::Dm9LookupRxBuffers(void)
{
if(!m_mutexRxValidate.TryLock()) return 0;
int counts=0;
int errors=0;
U32 desc;
PDM9_RX_DESCRIPTOR pdesc;
U32 calcRxCnt;
#ifdef IMPL_STORE_AND_INDICATION
PCQUEUE_GEN_HEADER pcurr;
#else
U8 szbuffer[DRIVER_BUFFER_SIZE];
#endif
for(pdesc=(PDM9_RX_DESCRIPTOR)&desc;;)
{
CHECK_SHUTDOWN();
// probe first byte
desc = DeviceReadDataWithoutIncrement();
// check if packet available, 01h means available, 00h means no data
if(pdesc->bState != 0x01) break;
// get the data descriptor again
desc = DeviceReadData();
//[Extra-for check]
//if (pdesc->bState != 0x01)
// ; // na
//else
if (pdesc->nLength > DRIVER_BUFFER_SIZE)
calcRxCnt= 0xF9F9; // na
else if (pdesc->bStatus & MAKE_MASK4(3,2,1,0))
calcRxCnt= 0xF2F2; // na
else
calcRxCnt= nRxCnt+1;
if ((pdesc->bStatus&0xFF)==MAKE_MASK1(6))
;
else
WPrintf(WSTR("#[%02X%02X,L=%X RC=%d] \r\n"), pdesc->bStatus,pdesc->bState,pdesc->nLength,calcRxCnt);
// read out the data to buffer
// Performance issue: maybe we may discard the data
// just add the rx address.
// if the length is greater than buffer size, ...
if((pdesc->nLength > DRIVER_BUFFER_SIZE))
{
DeviceIndication(AID_LARGE_INCOME_PACKET);
break;
}
#ifdef IMPL_STORE_AND_INDICATION
if(!(pcurr=m_RQueue.Dequeue()))
{
RETAILMSG(TRUE,(TEXT("Queue overflow")));
BREAK;
// packet will lost!!
break;
}
DeviceReadData((PBYTE)CQueueGetUserPointer(pcurr),pcurr->nLength=pdesc->nLength);
#else
DeviceReadData((PBYTE)&szbuffer,pdesc->nLength);
#endif
// check status, as specified in DM9_RXSR,
// the following bits are error
// <3> PLE
// <2> AE
// <1> CE
// <0> FOE
if(pdesc->bStatus & MAKE_MASK4(3,2,1,0))
{
errors++;
#ifdef IMPL_STORE_AND_INDICATION
m_RQueue.Enqueue(pcurr);
#endif
continue;
} // of error happens
nRxCnt++;
counts++;
#ifdef IMPL_STORE_AND_INDICATION
m_RQStandby.Enqueue(pcurr);
#else
DeviceReceiveIndication(
0,
(PVOID)&szbuffer,
pdesc->nLength);
#endif
} // of forever read loop
REPORT(TID_GEN_RCV_OK, counts);
REPORT(TID_GEN_RCV_ERROR, errors);
m_mutexRxValidate.Release();
#ifdef IMPL_STORE_AND_INDICATION
if (!m_RQStandby.IsQueueEmpty()) DeviceSetTimer(5);
#endif
return counts;
}
BOOL DM9ISA::DeviceQueryTxResources(void)
{
#ifdef _DEBUG
SETFNAME("DM9ISA::DeviceQueryTxResources()");
FUNCTION_ENTER_MSG();
if (m_nTxPendings < m_nMaxTxPending)
{
FUNCTION_LEAVE_MSG();
return TRUE;
}
else
{
FUNCTION_LEAVE_MSG();
return FALSE;
}
#else
return (m_nTxPendings < m_nMaxTxPending);
#endif
}
void DM9ISA::DeviceHalt(void)
{
// nothing to do
}
//[Sample Program:]
//#if DBG
// NdisGetCurrentSystemTime(&TS);
// NdisGetCurrentSystemTime(&TE);
// TD.QuadPart = TE.QuadPart - TS.QuadPart;
// TD.QuadPart /= 10000; DBGPRINT(MP_WARN, ("Init time = %d ms\n", TD.LowPart)); // Convert to ms
//#endif
int DM9ISA::LnkStat_WaitLinkUp(void)
// check if link established
{
BOOL Result;
LARGE_INTEGER TS, TE, TD;
WORD cnt= 0;
int msResult= 0;
TD.QuadPart= 0;
NdisGetCurrentSystemTime(&TS); //then = GetTimes();
while (! (Result=(DeviceReadPort(DM9_NSR) & MAKE_MASK(6))) ){
cnt++;
NdisMSleep(mSec1); //NdisMSleep(mSec100); [* Wait 1ms *] [* Wait 100ms *]
NdisGetCurrentSystemTime(&TE);
TD.QuadPart = TE.QuadPart - TS.QuadPart;
TD.QuadPart /= 10000; // Convert to ms
if (TD.QuadPart>2000) /* 2sec */
break;
}
if (Result){
msResult= (int) TD.QuadPart;
WPrintf(_T(" [%dms].LnkUp"), TD.QuadPart);
WNextLine();
}
return msResult;
}
int DM9ISA::OP_GetMaxTxPending()
{
return m_nMaxTxPending;
}
void DM9ISA::OP_SetLinkMode(int linkMode)
{
WORD wData = 0;
LARGE_INTEGER TS, TE, TD;
wData= DEV_LSMode(linkMode);
DeviceWritePort(0x1f, 0x01); //DM9_GPR (NetWriteReg(pNic, DM9_GPR, bGEPIO0); /* Power Down PHY */)
/* check if link terminated */
#if 1
TD.QuadPart= 0;
NdisGetCurrentSystemTime(&TS); //then = GetTimes();
while (1){
NdisGetCurrentSystemTime(&TE);
TD.QuadPart = TE.QuadPart - TS.QuadPart;
TD.QuadPart /= 10000;
if (TD.QuadPart>15) /* 15ms*/
break;
}
#endif
//. _PSTR(_T("[%s]----------------[%dms] \r\n"),LinkNameTbl[linkMode], TD.QuadPart);
#ifdef IMPL_TST_FORCE_100H
DeviceWritePhy(0, 0, PARAM_100H/*PARAM_10H*/);
#else
DeviceWritePhy(0, 0, wData); // (NetWritePHY(pNic, MIIADDR_CONTROL, wData); /* link mode */)
#endif
DeviceWritePort(0x1f, 0x00); //DM9_GPR (NetWriteReg(pNic, DM9_GPR, 0); /* Enable PHY */)
NdisMSleep(mSec10); //[* 10msec *]
}
BOOL DM9ISA::OP_ShowLinkMode()
{
WORD rData, monitor;
LPWSTR a,b,c,d;
//Show_A.N.
rData= DeviceReadPhy(0, MIIADDR_SPSTAT); //* 17.[15:12]=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -