📄 func03.cpp
字号:
// DM9013.cpp: implementation of the DM9013 class.
//
// Copyright (c) 2000-2007 Davicom Inc. All rights reserved.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FUNC03.h"
#include "FUNC13.h"
#include "ver.h" //[chip]
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
DM9003::DM9003(NIC_DRIVER_OBJECT *pUpper,PVOID pVoid) : DM9000(pUpper,pVoid)
{
}
DM9003::~DM9003()
{
}
DWORD DM9003::GetDriverChipID()
{
return DM9003_CHIP_ID;
}
LPCTSTR DM9003::GetDriverVersion(void)
{
return DM9003_DRIVER_VERSION;
}
void DM9003::InitialHardware(int nResetCounts)
{
U32 val;
// reset member varialbes
m_uLastAddressPort = (U32)-1;
// software reset the device
DeviceWritePort(DM9_NCR, 0x01);
NdisStallExecution(20); // 20 us
// read the io orgnization
// ISR<7:6> == x1, dword
// ISR<7:6> == 0x, word
// ISR<7:6> == 10, byte mode
val = DeviceReadPort(DM9_ISR);
//if(val & MAKE_MASK(6))
//{
// m_nIoMode = DWORD_MODE;
// m_nIoMaxPad = 3;
//} else
if(!(val & MAKE_MASK(7)))
{
m_nIoMode = WORD_MODE;
m_nIoMaxPad = 1;
}
else
{
m_nIoMode = BYTE_MODE;
m_nIoMaxPad = 0;
}
// v3.2.9
//m_nMaxTxPending = (DeviceReadPort(DM9_CHIPREV) >= 0x10)?2:1;
m_nMaxTxPending = 2;
m_nTxPendings = 0;
// set the clearing method of TX packet complete status
DeviceWritePort(DM9_NSR, 0x0C); // (1<<5) For DM9013 only
// 0x00 For DM9003
// 0x0C For DM9003 (JJ)
// enable flow control [Extra for DM9003/DM9013]
// Extra=
DeviceWritePort(DM9_FCR, 0x20);
DeviceWritePhy(0,4,(DeviceReadPhy(0,4)|(1<<10)));
DeviceWritePhy(1,4,(DeviceReadPhy(1,4)|(1<<10)));
// Enable memory chain
DeviceWritePort(DM9_IMR, (1<<7));
// Switch config
SwitchConfig();
#ifdef IMPL_STORE_AND_INDICATION
// ..m . ,df; ,. ,. b,. fg,b,.fr n,. n ...
if(nResetCounts) return;
/* init rx buffers */
U32 m,uaddr;
if(!(uaddr = (U32)malloc(sizeof(DATA_BLOCK)*
(m=m_szConfigures[CID_RXBUFFER_NUMBER]*2))))
THROW((ERR_STRING("DM9013::InitialHardware - Insufficient memory\r\n")));
for(;m--;uaddr+=sizeof(DATA_BLOCK))
m_RQueue.Enqueue((PCQUEUE_GEN_HEADER)uaddr);
/* set indication timer */
DeviceInitializeTimer();
#endif
WNextLine();
m_CHIPMsgCtrl= FALSE; // TO BE FALSE
WPrintf(_T("[#03]\r\n"));
WPrintf(_T("[#03]\r\n"));
WPrintf(_T("[#03]\r\n"));
WPrintf(_T("[#03]\r\n"));
WPrintf(_T("[#03]\r\n"));
WNextLine();
//////////////
// Per-PHY
//////////////
#if 0
// REG MIIADDR_SCFG.4= 20.4
m_auto_mdix_flgb= !(DeviceReadPhy(0, MIIADDR_SCFG)&MAKE_MASK1(4)); // MAKE_MASK1(4)==0x0010
//...
// REG MIIADDR_SCFG.4= 20.4
m_auto_mdix_flgb= !(DeviceReadPhy(1, MIIADDR_SCFG)&MAKE_MASK1(4)); // MAKE_MASK1(4)==0x0010
//...
#endif
#if 1
#if 0
//PHY-0
/* MYLinkProcess= */
ISA_LinkUp();
//PHY-1
/* MYLinkProcess |= */
ISA_LinkUp();
#endif
#if 1
m_n4HangCounts= 3; // Trick! Especial for DM9003 that not succeed here, but 4Hang DIRECT succesed!
#else
/* MYLinkProcess= */
if (MYLinkProcess) // Trick!
m_n4HangCounts= 1; // to show -> OP_ShowLinkMode() in check 4 hang!
#endif
#endif
WNextLine();
WNextLine();
//(+)2008-01-10 Joseph Chang
int j;
//PHY-0
for(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(WSTR("PHY0: Link rapid (for 30ms): %d.%d mSec \r\n"), (j*300)/1000, (((j*300)+50)/100)%10);
//PHY-1
for(j=0; j<100; j++) { //[_Joseph: If still not link, This is to wait max 30ms until link OK!]
if ( DeviceReadPhy(1, 0x1)&0x0004 ) //wLinkState =
break;
NdisMSleep(uSec300);
}
WPrintf(WSTR("PHY1: Link rapid (for 30ms): %d.%d mSec \r\n"), (j*300)/1000, (((j*300)+50)/100)%10);
WNextLine();
WNextLine();
//(-)2008-01-10 Joseph Chang
//(+)2008-04-22 Joseph Chang
#if 0
// Ray+
DeviceWritePort(DM9_PIndex, 0); //P0
DeviceWritePort(DM9_VLAN_TAGL, 2); // -----> see VLAN Mapping Table 0xb2
DeviceWritePort(DM9_PIndex, 1); //P1
DeviceWritePort(DM9_VLAN_TAGL, 2); // -----> see VLAN Mapping Table 0xb2, too
DeviceWritePort(DM9_PIndex, 3); //Processor
DeviceWritePort(DM9_VLAN_TAGL, 1); // -------> see VLAN Mapping Table 0xb1
DeviceWritePort(0xb1, 0x03); // Mapping to port 1 & port 0 (i.e. Mapping Table 0xb1)
DeviceWritePort(0xb2, 0x08); // Mapping to processor (i.e. Mapping Table 0xb2)
WPrintf(WSTR("[TEST].[TEST].[TEST] DM9003: Test VLAN! \r\n"));
#endif
//(-)2008-04-22 Joseph Chang
if (nResetCounts==0) nTxCnt= nRxCnt= 0; // Counter
}
void DM9003::SwitchConfig()
{
/* switch control */
#if 0
SwitchVlanSetup(1); /* 0:port-base, 1:Tag-base */
#endif
#if 0
SwitchQosSetup(0); /* 0:port, 1:Tag, 2:TOS */
#endif
#if 0
/* Bandwidth control
Device_BW_control(db,port_no, bw_type, bit7-4, bit3-0)
bw_type(reg61H.[3]): 0:control with Ingress and Egress separately
1:control with Ingress or Egress
bit7-4 and bit 3-0:refer to reg66H and reg67H
If bw_type=1, bit7-4 must be "0".
*/
SwitchBandwidthControl(1,0,0,2);
SwitchBandwidthControl(0,0,2,0);
#endif
}
WORD DM9003::DeviceReadPhy(DWORD dwRegister, DWORD dwOffset)
{
WORD wHighbyte,wLowbyte;
// assign the phy register offset, internal phy(0x40) plus phy offset
//---DM9000---
//DeviceWritePort(DM9_EPADDR,(0x40|(dwOffset&0x3F)));
//---DM9013 ---
DeviceWritePort(DM9_EPADDR,((dwRegister<<6)|(dwOffset&0x3F)));
// issue PHY select<3> and PHY read command<2>
DeviceWritePort(DM9_EPCNTL,((1<<3)|(1<<2)) );
// wait until status bit<0> cleared
DevicePolling(DM9_EPCNTL,(1<<0),0x00);
// stop command
DeviceWritePort(DM9_EPCNTL,0);
// retrive data
wLowbyte = (WORD)DeviceReadPort(DM9_EPLOW);
wHighbyte = (WORD)DeviceReadPort(DM9_EPHIGH);
return ((wHighbyte<<8) | wLowbyte);
}
WORD DM9003::DeviceWritePhy(DWORD dwRegister, DWORD dwOffset, WORD wValue)
{
// assign the phy register offset, internal phy(0x40) plus phy offset
//---DM9000---
//DeviceWritePort(DM9_EPADDR,(0x40|(dwOffset&0x3F)));
//---DM9013---
DeviceWritePort(DM9_EPADDR,((dwRegister<<6)|(dwOffset&0x3F)));
// put data
DeviceWritePort(DM9_EPLOW, LOW_BYTE(wValue));
DeviceWritePort(DM9_EPHIGH,HIGH_BYTE(wValue));
// issue PHY select<3> and write command<1>
DeviceWritePort(DM9_EPCNTL,((1<<3)|(1<<1)) );
// wait until status bit<0> cleared
DevicePolling(DM9_EPCNTL,(1<<0),0x00);
// stop command
DeviceWritePort(DM9_EPCNTL,0);
return wValue;
}
/*******************************************************************
*
* dm9003/dm9013 over-write function (new)
*
*******************************************************************/
WORD DM9003::DeviceCheckLink(void)
{
WORD wLinkState=0;
//#ifdef TARGET_DM9013
WORD /*wPHY0,*/ wPHY1;
//#endif
WPrintf(WSTR(" +")); // dbg
wLinkState = DeviceReadPhy(0, 0x1);
wLinkState = DeviceReadPhy(0, 0x1);
//#ifdef TARGET_DM9013
wPHY1 = DeviceReadPhy(1, 0x1);
wPHY1 = DeviceReadPhy(1, 0x1);
wLinkState |= wPHY1;
//#endif
SetConnectionStatus((wLinkState&0x4)?TRUE:FALSE); //(true);
//DEBUG_PRINTF(TEXT("[DM9ISA]Link=%d\r\n"), (wLinkState&0x4));
return wLinkState;
}
// <== DM9013 only ? For a notice!
//void DM9013::DeviceInterruptEventHandler(U32 uValue)
//{
// DeviceWritePort(DM9_NSR, nsr); //clear <== DM9013 add
//}
int DM9003::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
//#endif
U8 szbuffer[DRIVER_BUFFER_SIZE];
for(pdesc=(PDM9_RX_DESCRIPTOR)&desc;;) // of forever read loop
{
CHECK_SHUTDOWN();
desc= DeviceReadDataWithoutIncrement(); // probe first byte
if(pdesc->bState != 0x01) break; // check if packet available, or no data
desc = DeviceReadData(); // get the data descriptor again
//[Extra-for check]
// if (pdesc->bState != 0x01) ; // na
// else
if (pdesc->nLength > DRIVER_BUFFER_SIZE)
calcRxCnt= 0xF9F9; // na
else if (pdesc->bStatus & MAKE_MASK1(1))
calcRxCnt= 0xF2F2; // na
else
calcRxCnt= nRxCnt+1;
if ((pdesc->bStatus&0xF2)==MAKE_MASK1(6))
; // multi-cast(bit[6]).. && no bit[7],bit[5],bit[4], & "bit[1] CE"
else // ~bit[6] || ( bit[7] | bit[5] | bit[4] | bit[1] CE)
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
//#endif
DeviceReadData((PBYTE)&szbuffer,pdesc->nLength);
// check status, as specified in DM9_RXSR,
// the following bits are error
// bit[1] CE
// Not Error: {bit[3:2] from which port (00: P0, 01: P1, 10: P2, 11: na), bit[0] reserved}
if(pdesc->bStatus & MAKE_MASK2(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
//#endif
DeviceReceiveIndication(0, (PVOID)&szbuffer, pdesc->nLength);
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -